...besides the obvious of doing five more writes to register 3?
Or for that matter, is there anything that could cause the MMC1 to ignore a reg3 ($E000-$FFFF) write? And hence ignore a PRG bank switch?
I've got this weird crash happening now in my code, caused by the wrong PRG bank being loaded at the wrong time.
I'm looking at my Nintendulator dump file that I captured leading up to the crash. Specifically within that file, I'm looking at the previous two runs of a certain subroutine before the game crashes. This sub backs up the current PRG bank number in a variable so that it can jump back to he current sub later, then loads 0 into the accumulator, then jumps to the PRG bank-switching sub.
On the second-to-last run before the game crashes, the code executes perfectly fine. I need it to load bank 0, so I load 0 into A and then jump to the switching sub to do my five writes to $E000/four LSRs. Then scrolling down, I look at the next time a pointer is loading from somewhere in ROM and it's loading the correct data, indicating bank 0 is indeed loaded.
Here's the odd part. The next time this same subroutine runs (and again, the last time it runs before the game crashes) I'm again loading in bank 0, and the swapping subroutine also runs perfectly. However, when I scroll down even further and look at the exact same address being read out of ROM via a pointer, I see two $FF values. So I've checked this address in the debugger and found that $FF is the value when bank 1 is loaded. Bank 1, coincidentally, was the previous PRG bank loaded both times before jumping to this sub. It's like it changed the first time, but ignored the writes to $E000 on the second time. About 1 1/2 scanlines later, the game crashes, of course.
My first thought was that I must be screwing up an offset in a write, that's causing some random value to get written to $E000-$FFFF. I've painstakingly looked at every store instruction after this bank swapping subroutine (the one that gets called right before the crash), and I can't find stores to anything besides RAM or non-MMC1 registers numbered $7FFF and lower.
I'm re-reading this now and realizing it must be confusing as hell to anyone else. Here's a snippet from my dump file that might explain it better, I've annotated with some labels and comments:
bank_backup_se:
FF8D LDA $004B = 01 ;;$004B = prg_bank ;;the current PRG bank
;;loaded
FF90 STA $004E = 01 ;;$004E = bank_bak_se ;;the variable that holds
;;the current PRG bank, as I will need to return
;;to it once this group of code is done
FF93 LDA #$00 ;;target bank = bank 0
FF95 STA $004B = 01
FF98 JSR $E82B
swap_PRG_bank:
E82B LDA $004B = 00
E82E AND #$1F
E830 STA $E000 = 40
E833 LSR A
E834 STA $E000 = 40
E837 LSR A
E838 STA $E000 = 40
E83B LSR A
E83C STA $E000 = 40
E83F LSR A
E840 STA $E000 = 40
E843 RTS
FF9B RTS
;;so pretty standard stuff. now... scrolling down to the next immediate
;;instance when something is read out of the current PRG bank...
FED6 LDA $A1AE,Y @ A1BA = B4
FED9 STA $0053 = 50
FEDC LDA $A1AF,Y @ A1BB = A2
FEDF STA $0054 = A3
;;On the next frame, bank_backup_se and swap_PRG_bank run exactly
;;the same. However, the next time I scroll down a couple dozen lines
;;to find the pointer mentioned above...
FED6 LDA $A1AE,Y @ A1BA = FF
FED9 STA $0053 = 50
FEDC LDA $A1AF,Y @ A1BB = FF
FEDF STA $0054 = A3
;;and it's now apparent that I've pissed off the nesdev/6502/MMC1 gods
;;and they are now giving me the big middle finger.
Or for that matter, is there anything that could cause the MMC1 to ignore a reg3 ($E000-$FFFF) write? And hence ignore a PRG bank switch?
I've got this weird crash happening now in my code, caused by the wrong PRG bank being loaded at the wrong time.
I'm looking at my Nintendulator dump file that I captured leading up to the crash. Specifically within that file, I'm looking at the previous two runs of a certain subroutine before the game crashes. This sub backs up the current PRG bank number in a variable so that it can jump back to he current sub later, then loads 0 into the accumulator, then jumps to the PRG bank-switching sub.
On the second-to-last run before the game crashes, the code executes perfectly fine. I need it to load bank 0, so I load 0 into A and then jump to the switching sub to do my five writes to $E000/four LSRs. Then scrolling down, I look at the next time a pointer is loading from somewhere in ROM and it's loading the correct data, indicating bank 0 is indeed loaded.
Here's the odd part. The next time this same subroutine runs (and again, the last time it runs before the game crashes) I'm again loading in bank 0, and the swapping subroutine also runs perfectly. However, when I scroll down even further and look at the exact same address being read out of ROM via a pointer, I see two $FF values. So I've checked this address in the debugger and found that $FF is the value when bank 1 is loaded. Bank 1, coincidentally, was the previous PRG bank loaded both times before jumping to this sub. It's like it changed the first time, but ignored the writes to $E000 on the second time. About 1 1/2 scanlines later, the game crashes, of course.
My first thought was that I must be screwing up an offset in a write, that's causing some random value to get written to $E000-$FFFF. I've painstakingly looked at every store instruction after this bank swapping subroutine (the one that gets called right before the crash), and I can't find stores to anything besides RAM or non-MMC1 registers numbered $7FFF and lower.
I'm re-reading this now and realizing it must be confusing as hell to anyone else. Here's a snippet from my dump file that might explain it better, I've annotated with some labels and comments:
bank_backup_se:
FF8D LDA $004B = 01 ;;$004B = prg_bank ;;the current PRG bank
;;loaded
FF90 STA $004E = 01 ;;$004E = bank_bak_se ;;the variable that holds
;;the current PRG bank, as I will need to return
;;to it once this group of code is done
FF93 LDA #$00 ;;target bank = bank 0
FF95 STA $004B = 01
FF98 JSR $E82B
swap_PRG_bank:
E82B LDA $004B = 00
E82E AND #$1F
E830 STA $E000 = 40
E833 LSR A
E834 STA $E000 = 40
E837 LSR A
E838 STA $E000 = 40
E83B LSR A
E83C STA $E000 = 40
E83F LSR A
E840 STA $E000 = 40
E843 RTS
FF9B RTS
;;so pretty standard stuff. now... scrolling down to the next immediate
;;instance when something is read out of the current PRG bank...
FED6 LDA $A1AE,Y @ A1BA = B4
FED9 STA $0053 = 50
FEDC LDA $A1AF,Y @ A1BB = A2
FEDF STA $0054 = A3
;;On the next frame, bank_backup_se and swap_PRG_bank run exactly
;;the same. However, the next time I scroll down a couple dozen lines
;;to find the pointer mentioned above...
FED6 LDA $A1AE,Y @ A1BA = FF
FED9 STA $0053 = 50
FEDC LDA $A1AF,Y @ A1BB = FF
FEDF STA $0054 = A3
;;and it's now apparent that I've pissed off the nesdev/6502/MMC1 gods
;;and they are now giving me the big middle finger.