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).