I've been thinking about video timings and I hoped that prompting you after a period of reflection (
allowing two months for Tetris addiction) might be productive. You switched from two phases to four phases because one of the original phases was marginal. Rather than rotating a shift register, I considered one 74x161 (configured to count 14, 15, zero at 28MHz) and one 74x138 to obtain three strobes. However, I have no idea if three phases mesh with your design. I presume no.
Agumander on Thu 2 Jun 2022 wrote:
The biggest hassle from the banking so far has been interrupt handling, where an interrupt comes in and I don't know what bank I'm on because the register is write-only.
Atari's solution to write-only registers is to first write the value to a well know location. If an interrupt occurs and it modifies the same register then the interrupt is able to restore the write-only register - possibly before the main routine modifies register.
If you're banking RAM, it might be useful to reserve one memory location within every bank. Populating the bank number is quite easy: STX bank_latch // STX zp_bank_number // DEX // BNE. The reserved memory location can be used to quickly determine bank number within an interrupt. After an interrupt handler pushes registers, it can read bank number from RAM and then switch to bank zero (or similar) with the original bank number held in the register of your choice. At the end of interrupt, bank number can be restored and then registers can be restored from stack. Useful stack values may be split across two banks but nothing is ambiguous and it all works.
For microcontrollers and games, where the application is larger than the data, it is more important to bank ROM. Interrupts can be written such that RAM bank and ROM bank is always preserved.