-
Notifications
You must be signed in to change notification settings - Fork 2.2k
apple2gs: Improve IRQ emulation #14277
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Followup b3f2535: stop clearing LINE_IRQ when jumping to the IRQ vector. Properly written IRQ handlers won't notice any difference, but this fixes the behavior for software which (possibly intentionally) fails to clear an IRQ source; in that case the IRQ should continue to trigger (probably leading to a system hang.) LINE_SO is generally not hooked up, but if it is, it doesn't raise IRQ. Also delete unused G65816_INT_* macros.
All of the VGC and MegaII IRQ sources set their status bits even when the corresponding IRQ is not enabled (this was only implemented for SCB). Clearing enable bits works differently between VGC and MegaII: the MegaII can lower the IRQ line (when all sources are clear), the VGC does not. Neither clears their corresponding status bits. VGCINTCLEAR reads the floating bus. Status bits (and IRQs) are only cleared when writing a zero. ADB reset needs to clear (at least) m_irqmask. Also cleanup CLRVBLINT into do_io().
Reading the C02E/C02F counters resets the SCB status bit in C023 (the same as writing to C032). This behavior is not documented by Apple, but was verified on hardware. Move the relevant logic into a helper, to avoid code duplication.
Ensure that VBL is cleared on scanline 0 and set on scanline 192, even in SHR.
16-bit writes in demos were tripping "unknown switch". No functional change.
|
Regarding the subset of machine_reset(), that's intentional. For reasons of MAME's background as an arcade emulator where the F3 reset key is intended to work even on hardware with no notion of a reset button or switch, machine_reset() is expected to completely fix the machine state regardless of what you'd gotten it into beforehand. In the A2 case, it resets many more things than a normal keyboard reset (Control-Reset or Control-Open Apple-Reset) does. Control-Reset and Control-Open Apple-Reset do not do that. On the schematics, not all that many chips actually see the reset signal. On the II and II Plus only the 6502 and the slots get the reset signal. On the IIe/IIc/IIgs there's more to it than that; HIRES and 80COL are forced off, among many other things, and the language card is forced to a known state. Total Replay inadvertently became a test case for a lot of the corner cases there since you can use Control-Reset to get back to its menu from inside a game. |
|
Does making the 65816 interrupts level-sensitive break anything else? It’s used in several other systems and slot cards. |
|
They are level sensitive on real hardware, and I haven't seen any regressions from this. Still need to check the Acorn Communicator though. |
Yes, I know they’re level-sensitive IRL, but there have been plenty of cases of MAME code depending on load-bearing bugs elsewhere. |
|
There’s a Tube device with a 65816, and some TV games use it as well. |
|
I made a list of potentially affected systems: I have not investigated any of these other than apple2gs* and snes. What level of testing are you looking for here? I could set up a few of these and sanity-check that a couple of roms "appear to still work"-- but unlike apple2gs and snes, I don't own the physical hardware so have no baseline to compare with. |
|
IRQ problems usually manifest as the system simply not booting, so a very quick smoke test is fine. Also, all of the 5A22 hits are SNES, so they're already covered. |
|
sgng was one of my tested carts. It's OK. |
|
Smoke-testing a few systems: Then I backed out the g65816 changes, rebuilt, re-ran problematic systems: |
|
Also FWIW, I had looked at these snes carts: |
|
A little more testing, of slot devices: So, the result of that testing is: |
|
...and I see now that tv965 boots up to "0 001 001 FDX"... |


This PR fixes multiple problems with IRQs:
g65816: fix IRQ to be level triggered
(this one is the impetus for the rest of this PR)
apple2gs in MAME 0.281 does not hang if a programmer <raises hand> makes a error <hand still raised> in an IRQ handler and fails to clear the proper IRQ source. This leads to much hair-pulling later, when real hardware hangs.
apple2gs: improve VGC/MegaII IRQ emulation
There were several subtle errors, which isn't surprising given Apple's scarce documentation. A pile of unit tests revealed exactly how each softswitch works.
apple2gs: implement undocumented MegaII interaction
Reading the MegaII counters clears the VGC's SCB status bit. Strange but true, and inconvenient if you try to measure when SCB IRQs occur using VERTCNT...
apple2gs: improve C019 VBL behavior
The previous change fixed the polarity. Now it triggers on the proper scanline.
apple2gs: remove IOUDIS, fix AN3 and paddle
MegaII C046 includes the AN3 state. Now it matches the DHIRES state. Also stop triggering the paddle when writing to C071-7D ROM, and read the floating bus (verified on hardware.)
Testing:


I wrote a small suite of unit tests to cover all of the above (a lot of comments in the source):
IRQTest_251004.zip
...which exposes many failures in 0.281 (only the first failing subtest of each test is printed):
Everything passes after this PR, matching hardware behavior verified on an Apple IIgs ROM 3:
Because this touches the 65816 core, I also briefly tested the SNES. A handful of carts (and SA-1 carts) continue to work as well as before (which is to say, mostly OK... ctrigger has some graphical errors, and tophant is completely broken.) The NES has good docs & homebrew tests for IRQs... the SNES, less so?
Other than saving programmer sanity by making MAME behave the same as real hardware when given a broken IRQ handler, there is no obvious user-visible change after this PR. Rastan music continues to play as before.
TODO:
adbmicro_p2_out()only touches a subset ofmachine_reset(), this seems wrong?raise_irq(), I have this in a separate WIP PR