Groovie/T7G/Opcodes
< Groovie
Opcodes
NB: This list is not fully up-to-date. The source code contains the most recent version.
The first bit of each opcode is special (it sets "firstbit"), and removed before the opcode is read (e.g. 0x8A in the script is a call to opcode 0x0A).
In the executable, the script is read in and 1 subtracted from it, so in assembly language they appear to start at 0x00.
Meaning of the Imp? column: "y" means opcode fully implemented, "." means stub present, " " means correct number of script bytes skipped, "###" means none of the above). This column is now very out-of-date.
Opcode | Arguments (bytes) | Arguments (description) | Detail | Imp? |
0x01 | 0 | None | NOP: Does nothing | y |
0x02 | 2 | 1 x 16bit | Load an xmi file from a GJD, using reference given in argument, and start sequencer | . |
0x03 | 0 | None | Turn on bit 9 of bitflags | y |
0x04 | 0 | None | Palette fade out | y |
0x05 | 0 | None | Turn on bit 8 of bitflags (Show first frame) | y |
0x06 | 0 | None | Turn on bit 6 of bitflags | y |
0x07 | 0 | None | Turn on bit 7 of bitflags (just audio?) | y |
0x08 | 2 | 1 x 16bit | ??? Set arg1 as the "loop" file to play when current xmidi file finished ??? (arg1 is definitely a reference to an xmidi file) | . |
0x09 | 2 | 1 x 16bit | Play VDX file from a 16bit reference number. Does various things beforehand, depending on arg1 (needs a separate wiki page really...) | . |
0x0A | 0 | None | Turn on bit 5 of bitflags (skip still frames?) | y |
0x0B | 0 | None | Start the input loop | y |
0x0C | 3 | 1 x 8bit, 1 x 16bit | If the character pressed in the keyboard matches the first argument, does something | . |
0x0D | 11 | 5 x 16bit, 1 x 8bit | Mark the rectangle specified by arg1-arg4 as clickable: change the cursor to arg6 if hovering, and go to the address in arg5 if clicked. | y |
0x0E | 2 | 1 x 16bit | Mark the leftmost 100 pixels of game area as clickable: change the cursor to 1 if hovering, and go to the address in the first parameter if clicked. | y |
0x0F | 2 | 1 x 16bit | Mark the rightmost 100 pixels of game area as clickable: change the cursor to 2 if hovering, and go to the address in the first parameter if clicked. | y |
0x10 | 2 | 1 x 16bit | Mark the centremost 240 pixels of game area as clickable: change the cursor to 0 if hovering, and go to the address in the first parameter if clicked. | y |
0x11 | 2 | 1 x 16bit | (Same call as 0x10) | y |
0x12 | 2 | 1 x 16bit | Mark the current position as clickable: change the cursor to 0, and go to the address in the parameter if clicked. | y |
0x13 | 0 | None | End the input loop - wait for mouse/keyboard input | y |
0x14 | 3 (or 2) | 1 x 16bit, 1 x 8bit (or 2 x 8bit) | ??? Load a random number (up to a max value of arg2) into var1 ??? | y |
0x15 | 2 | 1 x 16bit | JMP: Jump to the address specified in the argument | y |
0x16 | Varies | 1 x 16bit (or 1 x 8bit, depending on firstbit), n x 8bit | Reads a string into the script variable specified in the first 2 (or 1) bytes | y |
0x17 | 1 | 1 x 8bit | RET: Returns from function, saving the return value to var 0x102 | y |
0x18 | 2 | 1 x 16bit | CALL: Calls function in argument | y |
0x19 | 2 | 1 x 16bit | Sleep for arg x 3 milliseconds | y |
0x1A | Varies | 1 x 16bit (or 1 x 8bit, dependent on firstbit), n x 8bit, 1 x 16bit | Strcmp then JMP: Compares the string at script variable given in first argument (8bit if firstbit is set, otherwise 16bit) with the string that follows in script (terminated by a character with the firstbit set). If not the same, jump to address in argument following string | y |
0x1B | Varies | 1 x 16bit (or 1 x 8bit), n x 8bit | Obfuscate: Applies XOR to the array of variables that begins in var1 with the following script bytes until one of these bytes has bit 0x80 set | y |
0x1C | 2 | 1 x 16bit | Set bit 1, clear bit 7, set bit 2 if firstbit set. Play VDX | |
0x1D | 4 (or 3, dependent on firstbit) | 2 x 16bit (or 1 x 8bit, 1 x 16bit) | Swap the values of two script variables | y |
0x1E | 1 | 1 x 8bit | NOP: Does nothing | y |
0x1F | 2 (or 1) | 1 x 16bit (or 1 x 8bit) | INC: Unary increment of a script variable pointed by the argument (8bit if firstbit is set, otherwise 16bit) | y |
0x20 | 2 (or 1) | 1 x 16bit (or 1 x 8bit) | DEC: Unary decrement of a script variable pointed by the argument (8bit if firstbit is set, otherwise 16bit) | y |
0x21 | Varies | Varies | Calls [AwkwardFunction awkward function] | ### |
0x22 | 0 | None | Copy the back buffer to the front buffer | y |
0x23 | Varies | 1 x 16bit (or 1 x 8bit, dependent on firstbit), n x 8bit, 1 x 16bit | Strcmp then JMP: same as 0x1A, but jumps on equal rather than not equal | y |
0x24 | 4 (or 3) | 2 x 16bit (or 1 x 8bit, 1 x 16bit) | MOV: Stores the value of the second variable to the first one: var2 = var1 | y |
0x25 | 4 (or 3) | 2 x 16bit (or 1 x 8bit, 1 x 16bit) | ADD: Adds the value of the second variable to the first one | y |
0x26 | Varies | Varies | Calls the other [AwkwardFunction awkward function] to get a VDX file name, finds it and plays it | y |
0x27 | Varies | Varies | Turns on bit 1 of bitflags (and bit 2 if firstbit is set). VDX file name (in a .gjd) follows: find it, then play it | y |
0x28 | 2 | 1 x 16bit | NOP: Does nothing | y |
0x29 | 0 | None | Stops the MIDI playback | . |
0x2A | 0 | None | End script | . |
0x2B | 0 | None | NOP: Does nothing (same call as 0x54) | y |
0x2C | 3 | 1 x 16bit, 1 x 8bit | Sets the action (arg1) and cursor (arg2) for the top hotspot | y |
0x2D | 3 | 1 x 16bit, 1 x 8bit | Sets the action (arg1) and cursor (arg2) for the bottom hotspot | y |
0x2E | 2 (or 1) | 1 x 16bit (or 1 x 8bit) | Load game, getting number of load slot from the script variable in the argument | . |
0x2F | 2 (or 1) | 1 x 16bit (or 1 x 8bit) | Save game, getting number of save slot from the script variable in the argument | . |
0x30 | 2 | 1 x 16bit | Mark the 80 pixels under the game area as clickable: change the cursor to 4 if hovering, and go to the address in the first parameter if clicked. | . |
0x31 | 4 | 2 x 16bit | Sets the MIDI volume. Stops the MIDI playback if the first argument is 0 (volume = 0?) | |
0x32 | 6 (or 5) | 3 x 16bit (or 1 x 8bit, 2 x 16bit) | JNE: Jumps to the address of the third argument when *(var1 - 0x31) != var2 | y |
0x33 | Varies | 1 x 16bit (or 1 x 8bit, depending on firstbit), n x 8bit | Reads a string into the script variable number in the script variable specified in the first 2 (or 1) bytes | ### |
0x34 | Varies | 1 x 16bit (or 1 x 8bit, depending on firstbit), n x 8bit, 1 x 16bit | Check character (in second argument) to see if it's greater than the one in the indicated script variable (in first argument) (NB: if first bit of this char is not set, keep testing additional chars until it is (any match produces a positive result)). On positive, jump to address in final argument. | y |
0x35 | 0 | None | Turn off bit 7 of bitflags (just audio?) | y |
0x36 | Varies | 1 x 16bit (or 1 x 8bit, depending on firstbit), n x 8bit, 1 x 16bit | Check character (in second argument) to see if it's less than the one in the indicated script variable (in first argument) (NB: if first bit of this char is not set, keep testing additional chars until it is (any match produces a positive result)). On positive, jump to address in final argument. | y |
0x37 | 8 | 4 x 16bit | Copy rectangle from the game area into the screen | y |
0x38 | 0 | None | Re-load stored stack pointer | . |
0x39 | Varies | n x 8bit | Obscure swap: swap two script variables, addresses found by (arg1 - 0x30) * 10 + arg2 - 0x30 (and similar with arg3 & 4). Note that if one of the args is 0x23, then instead use the next byte of script - 0x61 as a script variable and use that (without subtracting 0x30) | y |
0x3A | Varies | n x 8bit | Print out string (NB: not null terminated, but "null first bit" terminated) | ### |
0x3B | 12 | 1 x 8bit, 5 x 16bit, 1 x 8bit | If within specified rectangle, get name of saved game, print it out (using sphinx.fnt). arg1 = save game number, arg2-5 = rectangle, arg6 = address to jump if clicked, arg7 = mouse pointer to use. Name of save game stored as first 15bytes of the file, minus 0x30. | . |
0x3C | 0 | None | Check which savegames are valid (i.e. the file opens for reading), store boolean results in script variables 0x001 to 0x00A, and number of valid files in 0x104 | y |
0x3D | 0 | None | Reset script variables 0x000-0x0FF to zero | y |
0x3E | 3 (or 2, dependent on firstbit) | 1 x 16bit, 1 x 8bit (or 2 x 8bit) | Performs var1 %= arg2 | y |
0x3F | variable | String | Load a script (just 1 sub-script is allowed). The filename is specified as a 0 ended character array | y |
0x40 | 4 | 2 x 16bit | Two arguments are screen offset for VDX player | y |
0x41 | 4 (or 3, dependent on firstbit) | 2 x 16bit (or 1 x 8bit, 1 x 16bit) | SUB: Perform var1 -= var2. | y |
0x42 | 1 | 1 x 8bit | Complicated | |
0x43 | 1 | 1 x 8bit | Unloads the sub-script, returns to the main one. The argument number is saved as the script variable 0x102 | y |
0x44 | 2 | 1 x 16bit | Sets the action (arg1) for the right hotspot | y |
0x45 | 2 | 1 x 16bit | Sets the action (arg1) for the left hotspot | y |
0x46 | 0 | None | NOP: Does nothing | y |
0x47 | 0 | None | NOP: Does nothing | y |
0x48 | 1 | 1 x 8bit | NOP: Does nothing | y |
0x49 | 0 | None | NOP: Does nothing | y |
0x4A | 2 | 1 x 16bit | NOP: Does nothing | y |
0x4B | 1 | 1 x 8bit | NOP: Does nothing | y |
0x4C | 0 | None | Saves the current CD (1/2/-1 if none) in variable 0x106 | y |
0x4D | 1 | 1 x 8bit | If arg1 == 2 play vielogo, and stop sequencer & play CD | . |
0x4E | 2 | 1 x 16bit | NOP: Does nothing | y |
0x4F | 2 | 1 x 16bit | NOP: Does nothing | y |
0x50 | 2 | 1 x 16bit | NOP: Does nothing | y |
0x51 | 2 | 1 x 16bit | NOP: Does nothing (Loads argument into memory but it's unused) | y |
0x52 | 1 | 1 x 8bit | Do loads with game area, dirty regions, palette (argument seemingly discarded) | |
0x53 | 10 | 5 x 16bit | Load arg5 if cursor is within rectangle specified by arg1-4 | . |
0x54 | 0 | None | NOP: Does nothing (same call as 0x2B) | y |
0x55 | 2 | 1 x 16bit | NOP: Does nothing (Loads argument into memory but it's unused) | y |
0x56 | 6 | 1 x 32bit, 2 x 8bit | NOP: Does nothing | y |
0x57 | 4 | 1 x 32bit | Turn on bit 5 of bitflags (skip still frames?), then lots more | |
0x58 | Varies | Varies | Calls the other [AwkwardFunction awkward function] | |
0x59 | 3 (or two, dependent on firstbit) | 1 x 16bit, 1 x 8bit (or 2 x 8bit) | NOP: Does nothing | y |