Description of the virtual machine
The scrit are cut in small "chunks" roughly corresponding to lines of code in some kind of BASIC language. Conditions apply until the end of the line as far as I can see (unless there is an ENDIF opcode?) and there is a GOTO instruction to jump to a specific chunk/line.
Datatypes manipulated by the virtual machine are:
- Counters: 16 bit values
- Flags: 8 bit or maybe 1 bit values
- Objects: objects owned or not owned by the player (1 bit values)
Other notions are:
- Hooks: this is really a condition that matches with the last action that was triggered (button or hyperlink), sometimes with a parameter (for example if an action is used from a specific object). Hooks are conditions, if the last activated button does not match with the condition, the remaining code in the script line/chunk is not executed and execution continues with the next one (until an END instruction is reached, or there are no more lines to execute).
TODO
- Review 01, 81 and 82, it does not work correctly. It is unclear if the values are bytes or bits and if they can have initial values (besides what's set by CONDINIT).
- Review 0E, this is used to trigger an event just once at init, but are there any other uses?
- Review exact operation of 7E and 7F
- Find out what AE does
Opcodes
00: Return
"Return" or "End of line". If this is not present at the end of a line, the execution may continue with the next one?
01 xx: CheckFlag
Check if flag number xx is set. This is used for internal flags tracking the game state.
03 xx: HasItem
Check if the player is carrying item xx.
09 xx yyyy: IfEqual
Compare counter xx with value yyyy and continue executing the line if they are equal
0A xx yyyy: IfLess
Compare counter with value and continue if it is less than the value
0C xx yy: Random
Set 8bit variable yy to a random value modulo xx
0D xx yy: Check event
A lot of the conditions start with 0D
. This matches with an event from a button click.
For example, if a room has a button number 1, 0D 01 00
will match that, and the corresponding action will be triggered.
Every button click is matched with conditions in the current room as well as the ones in CONDGEN and/or CONDULTI.
Actions involving objects use the second parameter, for example 0D 68 05
corresponds to action 68 done on object 05.
0E xx: Check global event
Check global events, for example event 00 is the start of the game.
7E: Or
Used to combine multiple conditions (0D, 09, 0A, ...)
7F: And
Used to combine multiple conditions (typically, a hook and a check on a flag or an item).
80 xx: ?
Currently unknown, used in Le Mystère des Lunettes with parameter FF when displaying the inventory screen.
81 xx: Negate value? Increment?
Invert value of flag xx?
82 xx: Clear flag
Clear flag xx (set value to 0)
83 xx: Get item
Add item number x to the player's inventory
85 xx: Remove item
Remove item from the inventory.
87 xx yyyy: Set counter
Set counter xx to value yyyy
89 xx yyyy: Add to counter
Add value yyyy to counter xx
8A xx yyyy: Subtract from counter
Subtract value yyyy from counter xx
8F xx: Go to room
Go to room passed as a parameter (single byte)
90 xx: Go to screen
Go to a screen (in the same room) passed as a parameter.
91 xx: Show global screen
Show one of the global screens (from the unique room in MSGGEN).
93 xx: HomeScreen
Combined with a "Go to room", allows to set the home screen in the new room, which will be displayed if no hook in that room sets another screen.
95 xx yy: Initialize flag
Initialize a "flag" (really an 8 bit counter) with a given value
96: ??
Used for the OK button in Le Mystère des Lunettes
97
Wait for input after showing a global screen. Execution should resume in the current screen after clicking OK in the global message.
TODO: Used in the death sequence of Le Mystère des Lunettes, check that it works correctly there.
A0 xx yyyy
Compare counter xx with value yyyy. This triggers an evaluation of the scripts with matching of the corresponding IfLess/IfEqual operations
AE
Unknown for now.
FA: stop interpreter
Do not test the remaining script lines
FC: Game over
Trigger the "game over" and stop interpreting. This will ask the user if they want to restart from the last saving point or from the start of the adventure.
FD: Continue
Continue execution with the next script line.
FE xx: Goto
Call script number xx in the current room
FF: Winning the game
The game is won if you manage to execute this opcode!