The GB inc/dec instructions must preserve the carry flag and only
modify Z. The JIT was capturing both Z and C from the 68k CCR,
causing dec to incorrectly set carry on borrow (e.g. 0-1=FF).
This broke Pokemon Crystal's xor_a_dec_a helper which returns with
C=0 to signal "no action". The corrupted C=1 caused the scrolling
menu to exit prematurely when pressing down past CANCEL, showing
phantom items and garbage prices.
Fix compile_set_z_flag to merge new Z with old C, and
compile_set_c_flag to merge new C with old Z. Move and/or/xor
immediates to compile_set_zc_flags since they should clear C.
In double speed mode, dmg_sync_hw() halves CPU cycles before adding
to frame_cycles. The timing functions (compile_ly_wait, compile_ly_wait_reg,
compile_halt) compute D2 in PPU-domain units, but only half gets applied
to frame_cycles, causing the target LY to never be reached and an
infinite re-entry loop during game init.
Add effective_double_speed byte to JIT context and emit a runtime check
in all three timing functions to double D2 when double speed is active.
ld sp,hl and ld sp,imm16 computed the native SP pointer using a fixed
base (dmg->main_ram), which always resolved to WRAM bank 1 for the
$D000-$DFFF range. On CGB, this range is switchable (banks 1-7 via
SVBK). Games like Pokemon Crystal that use the SP trick to bulk-copy
data from switchable WRAM to VRAM would read from the wrong bank,
causing VRAM tile corruption.
Use the read page table at runtime instead, which is kept in sync with
the current WRAM bank by cgb_update_wram_bank().
- Add combined cgb_color_lut[16][4] to eliminate per-pixel conditional
branches and multiply operations in final draw functions
- Add tile_decode_cgb[256] LUT to replace 8-iteration bit extraction
loops with 2 table lookups
- Add dirty palette tracking (bg_palette_dirty, obj_palette_dirty) to
skip expensive Color2Index calls when palettes haven't changed
- Replace multiply-based pixel_shift calculation with 4-byte LUT
Also fixes test harness to initialize JIT_CTX_GB_SP for slow path
stack operations.
Major fixes:
- CALL, RET, RST, and their conditional variants now properly check
stack_in_ram before accessing memory via A3. Previously they assumed
A3 was always a valid native pointer, causing memory corruption when
in slow mode (A3 held raw GB SP value like 0xFFFE).
- Fixed initial SP setup to use fast mode with A3 pointing to actual
HRAM memory instead of holding the raw GB SP value.
- STOP instruction now calls runtime handler to check for CGB speed
switch instead of immediately halting. Enables double-speed mode.
- HDMA cancellation: writing to HDMA5 with bit 7=0 while HDMA is active
now cancels the transfer (fixes Pokemon Crystal).
Safety improvements:
- Added src_ptr bounds check to prevent m68k_offsets array overflow
- Added PC validation to reject execution in VRAM/external RAM
- Added PC history ring buffer for crash debugging
Tested: Klax, Link's Awakening DX, Wario Land 3 now boot successfully.
- Move DAA implementation to dedicated compile_daa() function
- Add 5 DAA tests covering addition/subtraction BCD adjustment
- Fix bug where CCR was clobbered after testing N flag