Implement:
SH_SASSIGN_STRUCTSREF
SH_SASSIGN_GLOBALSREF
SH_STRUCTSREF_NE_STR0
SH_GLOBALSREF_NE_STR0
SH_LOC_LT_IMM_OR_LOC_GE_IMM
Also, fix an bug in A_EMPTY and SH_IF_STRUCT_A_NOT_EMPTY.
Stack traces now list addresses in addition to function names.
Additionally, debugger stack traces number each frame, and the numbers
can be used together with the PRINT-LOCALS function to print the values
of local variables for any frame on the stack.
This is implemented by inserting special opcodes into the game's code.
When the breakpoint handler is finished, it returns the original opcode
so that execute_instruction can continue executing normally.
E.g.
* start xsystem4 with --debug option to drop into debugger immediately
* run (bp "game_main")
* ^d or \exit to close debugger REPL
* ...drop into a debugger REPL again at the game_main function
Print the new v11+ array types properly. Also, print the array rank for
old array types.
The code for reading v11+ ain data is simplified a lot here as well.
The 'lint' type in system 4 is NOT a 64-bit integer type. It is actually
a signed 32-bit integer type that is clamped between 0 and INT32_MAX.
Negative numbers can be assigned to a lint using SH_LOCALASSIGN (or at
least, the unofficial compiler emits such code) but LI_* instructions
always produce a positive result.
I'm guessing System40.exe converts lints to 64-bit integers for doing
arithmetic, and then clamps the result to the 32-bit integer range
before writing back to a variable.
This fixes a bug in Sengoku Rance where units would become invincible in
commander battles after their HP fell below zero.
Replace many instruction arguments with names/values (strings/messages,
local/global variables, structs, functions, etc.) and add labels to jump
targets.
- Create separate directories for source and header files.
- Build code shared between xsystem4 and aindump as a static library.
- Create header dirs gfx/ system4/ and vm/
- Make CG.c/h usable without a running VM