Originally posted by WhiteYoshiEggIs this still being worked on? I was just reminded of
a bug I reported a while ago that apparently still occurs with version 1.26.
This is arguably nothing urgent, since a) it's just a visual bug, b) it's ZSNES-only so it's debatable if it's even worth fixing, and c) you've already put so much work into the whole SA-1 system and probably got a lot more important things to do in real life and I don't want to place another burden on you.
That being said, I'd like to at least bring it to your attention once again. (Maybe it's an easy fix, I don't know.) If you're no longer involved, too busy right now or don't care about this bug in particular, let me know.
So, brief summary: calling $00BEB0 (the Map16 updating routine) glitches parallax scrolling for a split second. It only happens in ZSNES, and it's not caused by any other patch.
Originally posted by WhiteYoshiEggHere's how to reproduce it
[2018 version]:
- Get a clean ROM and expand it to 2MB with LM.
- Apply the SA-1 patch (version 1.26).
- Get uberASM.
- In level_code.asm, copy&paste this code to level105.
- Apply uberASM.
- Open the ROM in ZSNES and enter level 105.
- Do something that calls $00BEB0 (collect a coin, hit a question block, get the midway point).
- Notice a brief flicker in the background during that action.
- Disable $00BEB0 (PAR 00BEB06B) and verify the problem is gone (though obviously tiles no longer disappear when collected).
Testcase (BPS)
So far this week I have dedicated entirely at figuring out this bug and apparently there is no way to fix it.
As you might know, SA-1 and SNES communicates though IRQs and when the SA-1 CPU needs to do a certain operation such as storing to WRAM ($7E-$7F), communicating to PPU or any other SNES-side thing, the chip needs to send an IRQ request to SNES and then the S-CPU does what the SA-1 asked for. It's the best method for fast communicating with the both CPUs and warrants full code compatibility between them because if there is something that the S-CPU or SA-1 CPU can't do, it gently asks one of them to do the task though IRQs.
IRQs are also used to communicate between the S-CPU and S-PPU. S-PPU, for example, sends an NMI (which is a non-interruptable IRQ) to the SNES at end of each frame. There's also the V-IRQ, H-IRQ and HV-IRQ whcih are IRQs generated when a certain position of the H-/V- counters reach a certain value. The most classic example is the Status Bar IRQ, that the S-CPU receives at around V-Count = 36 and then the S-CPU does mid-scanline writes (yes, exactly) to change the layer 3 x/y positions, current mode, some cgadsub addresses and a little more, depending if it's a mode 7 fight or not.
ZSNES thought it was a good idea to implement all IRQs in the same way. As well H-DMA and H-Blanks. Looking at the ZSNES source code, on the SA-1 part (sa1proc.asm, sa1regs.asm), when the CPU generates an IRQ simply a flag is set and nothing else. What makes the IRQ actually occur is on the file execute.asm and there you can see a huge fuzz x86 mess code which checks for every single possible IRQ and starts generating them depending on the occasion. However, when a certain interrupt request is received, ZSNES just sets it and leaves the routine. So it literally forgets everything else. Because of that, when SA-1 sends an IRQ to the SNES CPU,
if it's triggered nearby H-blank, all HDMAs are automatically cancelled because ZSNES just "forgets" to execute them. And on the next scanline the HDMA is executed normally, except that everything will be shifted down by one scanline now.
For the next version of SA-1 Pack I'm currently working, I'm completely rewriting the IRQ and NMI routines. And I have attempted to make my IRQs give absolute priority to the PPU IRQs and only later check for SA-1 IRQs. So the risks of eventual scanline glitching would be avoided, which includes real hardware. Especially when there's HDMA involved.
However, ZSNES simply didn't work with the new IRQ controller. Once an IRQ is called, ZSNES does not clear the IRQ flags correctly and there is no way to know when an IRQ was generated by the PPU. Only by the SA-1. Because of that I had to write a custom IRQ controller just for ZSNES and still with all ZSNES-related-hacks that certainly would break other real hardware, it still keeps with that particular glitching. So sadly, I think I have done the maximum possible and the only way to avoid that is simply removing all SA-1 IRQs from the patch and reallocate some of the routines back to the SNES CPU just for better ZSNES compatibility. I might do that as well for the next version.
But don't get surprised: many games like to flicker on the ZSNES. Yoshi's Island Mode 2 levels are a nice example. VLDC9 overworld also has a lot of flickering on ZSNES, for the same reason (poor IRQ implementation).
And oh uh, quadruple post already? ... maybe people are not turned in the forums as it used to be in the past.
GitHub -
Twitter -
YouTube -
SnesLab Discord