Skip to content

Huc6280 cpu fixes - #136

Merged
mre merged 2 commits into
masterfrom
huc6280-cpu-fixes
Jun 26, 2026
Merged

Huc6280 cpu fixes#136
mre merged 2 commits into
masterfrom
huc6280-cpu-fixes

Conversation

@mre

@mre mre commented Jun 26, 2026

Copy link
Copy Markdown
Owner

So when I tested my TurboGrafx emulator, I noticed that I forgot a few HuC6280 CPU quirks in the 0.10.0 release. Street Fighter II booted to a black screen, and tracking it down turned up three things I forgot to push.

BSR was just missing. Opcode $44, the HuC6280's relative branch-to-subroutine, wasn't decoded at all. It now pushes the return address the same way JSR/RTS do and branches PC-relative, with the fixed 8-cycle cost.

Block transfers clobber A/X/Y when they hit the stack. The TII/TDD/TIN/TIA/TAI microcode saves Y, A and X on the stack while it runs and restores them (as X, A, Y) when it's done. That's normally invisible, but if the destination range overwrites the stack page, the values read back are the copied data, not the original registers. SF2's boot RNG uses exactly this: a TII $2000,$2001,$1FFF smears work RAM across the stack and zeroes the loop counter in X. Without it, the seed is wrong, and it doesn't boot. :(

CLI/SEI/PLP now have the one-instruction delay. The IRQ check was reading the I-flag after the instruction ran. Real hardware recognizes an interrupt at the end of an instruction using the flag value from before it executed, so an enable/disable lags by one instruction. SF2 depends on this when it does a CLI and then jumps straight into the handler's resume point. The check now samples the mask up front and passes it through.

mre added 2 commits June 26, 2026 23:44
Three HuC6280 accuracy fixes that SF2's boot sequence depends on:

- BSR (opcode $44): relative branch-to-subroutine. Pushes the return
  address like JSR, then branches PC-relative. Fixed 8 cycles.
- Block transfers (TII/TDD/TIN/TIA/TAI) save Y/A/X on the stack for the
  duration of the copy and restore them as X/A/Y. A transfer whose
  destination overlaps the stack page therefore clobbers the registers
  exactly as hardware does (SF2's RNG seed relies on this).
- IRQ recognition samples the I-flag from *before* the instruction ran,
  giving CLI/SEI/PLP the real one-instruction delay. check_interrupts /
  is_irq_triggered now take the pre-execution irq_enabled flag.
@mre

mre commented Jun 26, 2026

Copy link
Copy Markdown
Owner Author

I think this change is uncontroversial as it's just a bunch of bugfixes that I found while testing on an actual game. So I'll merge it right away and publish 0.10.1 to unblock the TurboGrafx release.

@mre
mre merged commit 3b0bf4a into master Jun 26, 2026
7 checks passed
@mre
mre deleted the huc6280-cpu-fixes branch June 26, 2026 21:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant