50 Commits

Author SHA1 Message Date
Tanner Fokkens c0a30de0b2 Fix inc/dec clobbering carry flag, breaking Pokemon Crystal menus
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.
2026-02-06 17:11:15 -08:00
Tanner Fokkens 6b4225aa8f Optimize CGB rendering with LUT-based color lookup
- 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.
2026-02-01 00:58:48 -08:00
Tanner Fokkens 3cbc9337f8 Fix stack corruption in CALL/RET/RST and add STOP instruction support
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.
2026-02-01 00:58:48 -08:00
Tanner Fokkens 9bb5705759 Add Game Boy Color support
- New CGB state management (cgb.c/cgb.h)
  - VRAM banking (VBK register)
  - WRAM banking (SVBK register, banks 1-7)
  - Speed switching (KEY1 register)
  - HDMA transfers (HDMA1-5 registers)
  - CGB palette registers (BCPS/BCPD, OCPS/OCPD)

- CGB rendering (lcd_cgb.c, lcd_mac_cgb.c)
  - Tile attributes from VRAM bank 1
  - Per-tile palettes, H/V flip, priority
  - 8 background and 8 sprite palettes
  - RGB555 to Mac indexed color conversion

- JIT initialization sets A=$11 for CGB mode detection

- UI: "Run as GBC" menu option, .gbc file filter

Working: Tetris DX, Pokemon Gold
Known issues: Crystal, SMB Deluxe, LADX hang at boot
2026-02-01 00:57:25 -08:00
Tanner Fokkens 8a30a2030b Extract compile_daa function, add DAA tests
- 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
2026-01-26 11:06:02 -08:00
Matthew Laux 23f752af23 move timing functions to their own file, LY wait on registers too 2026-01-25 22:16:22 -06:00
Matthew Laux ebb343cdbd support stack in HRAM (fixes DK '94) 2026-01-25 19:03:28 -06:00
Matthew Laux 6972ac5cc3 calculate mid-frame LY read correctly instead of cycling through - fixes Metroid enemies 2026-01-25 17:42:29 -06:00
Matthew Laux dbf619b285 remove sm83 json tests 2026-01-22 01:43:42 -06:00
Matthew Laux 49611878ff split test_exec into files by test categories 2026-01-22 01:42:55 -06:00
Matthew Laux d627b7265b re-add SP range detection, avoid copying lcd pixels twice 2026-01-21 21:20:42 -06:00
Matthew Laux e9000a3c84 rewrite stack for the millionth time 2026-01-15 21:09:57 -06:00
Matthew Laux 814a9ccf0b dmg_write16 instead of two dmg_write for stack ops 2026-01-13 23:40:28 -06:00
Matthew Laux 74f91d802e prepare for dmg_read/write16, rename functions, simplify interop 2026-01-13 22:37:04 -06:00
Matthew Laux 9f91bd7526 add 1x scale, audio refactor and fix wave frequency issue, remove crazy SP detection and always go through dmg_read/write 2026-01-13 21:47:25 -06:00
Matthew Laux c611c553ca fix flag bugs (wow that was hard to find), make DIV better, add color icons 2026-01-12 19:24:03 -06:00
Matthew Laux b69b784bd7 fully remove N and H support 2026-01-08 22:57:37 -06:00
Matthew Laux eab85d0205 optimize ldh 2026-01-08 22:30:28 -06:00
Matthew Laux da0e9dffca use key mappings, load/save key mappings, experiment with interrupt check every 16 scanlines 2026-01-08 10:28:09 -06:00
Matthew Laux a36c1dd72e inline reads/writes for stuff in paged areas 2026-01-07 20:43:55 -06:00
Matthew Laux 5b3ad01b68 move next_pc to d3 2026-01-04 18:11:43 -06:00
Matthew Laux 698fe41688 more efficient context switch into JIT, remove old compiler files, fix vblank flag bug 2026-01-04 17:45:52 -06:00
Matthew Laux 6126315141 conditional call, LRU block cache, MBC support, much more complicated dispatcher :/ 2026-01-03 13:58:29 -06:00
Matthew Laux 578fe34368 fix a couple issues with flags 2025-12-31 20:01:38 -06:00
Matthew Laux 54daa72ad4 add single instruction mode. add test runner for SingleStepTests sm83 tests (thanks claude code) based on existing instruction tests 2025-12-31 18:12:30 -06:00
Matthew Laux 90a3ad1386 fix add -> adc carry (fixes tetris sprite positioning bug) 2025-12-30 03:02:57 -06:00
Matthew Laux 5cecc6cbb1 break out ALU ops and register loads, gets further in tetris now 2025-12-23 18:10:45 -06:00
Matthew Laux 3ee9d50483 rest of the loads, wip direct block chain 2025-12-23 13:47:14 -06:00
Matthew Laux 322f520924 compiler gets to the tetris copyright screen - cycle counting is a dead end 2025-12-20 00:58:10 -06:00
Matthew Laux 1c13db1253 about to try mac vblank thing 2025-12-19 23:17:57 -06:00
Matthew Laux 3d0ef51bb2 split out compile_dmg_*, fix alignment bug for dmg_write, add more instructions, hacky lcd update for jit 2025-12-19 17:05:12 -06:00
Matthew Laux 1e9a822765 conditional return 2025-12-18 21:19:44 -06:00
Matthew Laux 91c0a39bb0 more instructions and tests 2025-12-18 20:51:27 -06:00
Matthew Laux 567041d1c3 ton of compiler improvements and new instructions 2025-12-18 20:16:00 -06:00
Matthew Laux 8a1f31f23a small bug fix 2025-12-18 00:03:43 -06:00
Matthew Laux 28e5bc5c93 add basic compiler support to system6 version, xor a, split a bunch of stuff into different files 2025-12-17 23:28:17 -06:00
Matthew Laux 18b028292e add native test runner, remove useless test counter 2025-12-17 16:43:28 -06:00
Matthew Laux bec8ec0f57 indirect de 2025-12-14 23:23:55 -06:00
Matthew Laux 7edf9403f8 rearrange registers again 2025-12-14 23:09:16 -06:00
Matthew Laux 57f35f2c34 ld (bc), a and ld a, (bc), about to change the register allocation again 2025-12-14 20:03:09 -06:00
Matthew Laux ef37993ace reallocate registers 2025-12-14 19:13:05 -06:00
Matthew Laux 982d7c1a4b unconditional call/ret, might need to change how sp works 2025-12-14 15:08:58 -06:00
Matthew Laux 9b7f3b4e87 jr z/nz/c/nc, move emitters to separate file 2025-12-14 14:14:48 -06:00
Matthew Laux e931a7fb99 unconditional jr, dec a 2025-12-14 00:47:31 -06:00
Matthew Laux 0b8e8c1c60 add jump + dispatcher thing, rename basic_block, remove useless unit tests 2025-12-13 23:20:50 -06:00
Matthew Laux 25e759b456 add ld 16 bit immediate 2025-12-13 18:16:08 -06:00
Matthew Laux ea143ae774 rest of the ld reg, immediate 2025-12-13 17:33:33 -06:00
Matthew Laux 38c54f1cdf split tests into separate files 2025-12-12 17:59:04 -06:00
Matthew Laux c3ff637f6c simplify how returning from the test works 2025-12-12 17:47:36 -06:00
Matthew Laux 6246d78047 add musashi to test compiler without having to use the mac 2025-12-12 17:17:31 -06:00