Page 2 of 3
Re: Setting inesprg to 2 makes game stop running
Posted: Sun Mar 24, 2019 10:55 am
by tokumaru
I'm not an expert in NESASM, but I think you're supposed to use .rsset and .rs for declaring variables... I suspect that having .org $0000 and then .org $8000 in bank 0 is generating a lot of blank ROM data, which gets output to the final ROM, throwing bank sizes and addresses off.
Your NMI is placed after the end of bank 0 and before the start of bank 1. I have no idea how NESASM handles that. The NMI handler should be somewhere within the fixed bank.
As for the reset stubs, they need to be present in every MMC1 bank, not every NESASM bank. The unnecessary stubs and vectors probably aren't causing any problems, but I though I'd point out that you only really need the ones in odd NESASM banks (1 and 3).
You can't have 3 CHR banks. ROM sizes must be powers of 2, so the number of banks needs to be a power of 2 too (1, 2, 4, 8, 16, and so on). Emulators may refuse to load ROMs with weird chip sizes, or map then in inconsistent ways.
Re: Setting inesprg to 2 makes game stop running
Posted: Sun Mar 24, 2019 11:12 am
by Jay John
tokumaru wrote:I'm not an expert in NESASM, but I think you're supposed to use .rsset and .rs for declaring variables... I suspect that having .org $0000 and then .org $8000 in bank 0 is generating a lot of blank ROM data, which gets output to the final ROM, throwing bank sizes and addresses off.
So, instead of doing it like this:
Code: Select all
.bank 0
.org $0000
characterselected = $0001
changescreen = $0002
loadtext = $0003
position = $0004
I should do it like this?
Code: Select all
.bank 0
.org $8000
.rsset $0000
characterselected .rs 0
.rsset $0001
changescreen .rs 0
.rsset $0002
loadtext .rs 0
.rsset $0003
position .rs 0
tokumaru wrote:Your NMI is placed after the end of bank 0 and before the start of bank 1. I have no idea how NESASM handles that. The NMI handler should be somewhere within the fixed bank.
Sorry, that was a mistake I made when I copy and pasted it, the NMI is actually before the .org $9FF0
tokumaru wrote:As for the reset stubs, they need to be present in every MMC1 bank, not every NESASM bank. The unnecessary stubs and vectors probably aren't causing any problems, but I though I'd point out that you only really need the ones in odd NESASM banks (1 and 3).
You can't have 3 CHR banks. ROM sizes must be powers of 2, so the number of banks needs to be a power of 2 too (1, 2, 4, 8, 16, and so on). Emulators may refuse to load ROMs with weird chip sizes, or map then in inconsistent ways.
Alright, so I fixed these, but I'm still not able to load what's on bank 2 and 3.
Re: Setting inesprg to 2 makes game stop running
Posted: Sun Mar 24, 2019 1:28 pm
by tokumaru
How big is the final .NES file, in bytes?
Re: Setting inesprg to 2 makes game stop running
Posted: Sun Mar 24, 2019 4:36 pm
by Jay John
tokumaru wrote:How big is the final .NES file, in bytes?
65552 bytes
Re: Setting inesprg to 2 makes game stop running
Posted: Sun Mar 24, 2019 6:12 pm
by tokumaru
That's correct for 16 bytes + 2x 16KB + 4x 8KB, so it doesn't look like there's any big discrepancy between what you're trying to make and what the assembler is actually outputting.
The best thing to do IMO would be to trace through your program in FCEUX or Mesen... Open the debugger, pause execution and reset, then step through the instructions to see where things go wrong. This will quickly tell you if the MMC1 initialization is working, whether the fixed bank is mapped correctly, whether the bankswitch code is being correctly called...
Re: Setting inesprg to 2 makes game stop running
Posted: Sun Mar 24, 2019 6:45 pm
by lidnariq
Jay John wrote:Code: Select all
ldhormir:
lda #$80
sta $8000
lda #%00011011
sta $8000
lsr a
This may be what's going wrong...
The effect of writing to the MMC1 with the $80s bit set is to
set both "P" bits, which sets a fixed bank at $C000-$FFFF equal to the last bank. You then immediately switch that to the fixed $8000-$BFFF configuration... so your code is probably going haywire here.
You should never need to write to the MMC1's "reset" bit after you actually reset.
Re: Setting inesprg to 2 makes game stop running
Posted: Sun Mar 24, 2019 7:42 pm
by Jay John
tokumaru wrote:That's correct for 16 bytes + 2x 16KB + 4x 8KB, so it doesn't look like there's any big discrepancy between what you're trying to make and what the assembler is actually outputting.
The best thing to do IMO would be to trace through your program in FCEUX or Mesen... Open the debugger, pause execution and reset, then step through the instructions to see where things go wrong. This will quickly tell you if the MMC1 initialization is working, whether the fixed bank is mapped correctly, whether the bankswitch code is being correctly called...
Would a problem like this also affect CHR banks? Because I'm having no problem with these.
Though I feel I haven't described the problem properly.
What happens is: The code seems to run properly through bank 0 and 1, but then I put a JMP in bank 1 to go to a routine that's at the beginning of bank 2, but instead of loading what's in bank 2, it loads what's in bank 0, basically restarting the game, but with the wrong data, making everything look glitched.
I think that the game is loading the part in the memory where the jump leads to, but in bank 0, I've no idea why though.
I've even move the location of the routine in bank 2 and it seems to confirm my theory that that's what's happening, since it loads a different screen that's in bank 0.
Re: Setting inesprg to 2 makes game stop running
Posted: Mon Mar 25, 2019 1:01 am
by koitsu
To solve your problem, you're going to have to step through your code in a debugger. FCEUX can do this, or Mesen. The one advantage (in this case) that Mesen has is that its debugger GUI shows you what PRG bank is actively mapped to what memory range (look at the bottom of the debugger window). Situations like "I ask for PRG bank 2 but I get PRG bank 0!" can 100% be watched/monitored by stepping through your bankswitch routine in the debugger.
The situation would affect CHR banks too, naturally, depending on what you're doing right or wrong. It just happens to be "easier" to figure out CHR bank swap issues because your code still works / nothing crashes, you just get the wrong tiles/pattern table data (for CHR-ROM, that is).
See lidnariq's post first, though. It looks like your mapper bank switch code is faulty.
Re: Setting inesprg to 2 makes game stop running
Posted: Mon Mar 25, 2019 1:56 am
by pwnskar
Jay John wrote:Though I feel I haven't described the problem properly.
What happens is: The code seems to run properly through bank 0 and 1, but then I put a JMP in bank 1 to go to a routine that's at the beginning of bank 2, but instead of loading what's in bank 2, it loads what's in bank 0, basically restarting the game, but with the wrong data, making everything look glitched.
I think that the game is loading the part in the memory where the jump leads to, but in bank 0, I've no idea why though.
I've even move the location of the routine in bank 2 and it seems to confirm my theory that that's what's happening, since it loads a different screen that's in bank 0.
It sounds like your bank 0 and bank 2 have the same program counter, but the example code you posted does not reflect that.
Could it be that you just accidentally mapped bank 0 to be in the address space where you expect your bank 2 to be after init? That you actually have bank 0 mapped both in $8000 and $C000?
Re: Setting inesprg to 2 makes game stop running
Posted: Mon Mar 25, 2019 12:23 pm
by Jay John
lidnariq wrote:This may be what's going wrong...
The effect of writing to the MMC1 with the $80s bit set is to
set both "P" bits, which sets a fixed bank at $C000-$FFFF equal to the last bank. You then immediately switch that to the fixed $8000-$BFFF configuration... so your code is probably going haywire here.
You should never need to write to the MMC1's "reset" bit after you actually reset.
Done it, still nothing though...
koitsu wrote:To solve your problem, you're going to have to step through your code in a debugger. FCEUX can do this, or Mesen. The one advantage (in this case) that Mesen has is that its debugger GUI shows you what PRG bank is actively mapped to what memory range (look at the bottom of the debugger window). Situations like "I ask for PRG bank 2 but I get PRG bank 0!" can 100% be watched/monitored by stepping through your bankswitch routine in the debugger.
The situation would affect CHR banks too, naturally, depending on what you're doing right or wrong. It just happens to be "easier" to figure out CHR bank swap issues because your code still works / nothing crashes, you just get the wrong tiles/pattern table data (for CHR-ROM, that is).
I've been checking debbugers and messing around with the code, and here's a thing I've noticed:
In the reset routine, I load #$80 into x:
Code: Select all
bfind
sei
ldx #$80
txs
stx $8000
jmp start
.dw NMI
.dw bfind
.dw bfind
However if I load #$00 or any binary without the most significant bit the problem now is with the CHR banks not the PRG one.
Re: Setting inesprg to 2 makes game stop running
Posted: Mon Mar 25, 2019 12:29 pm
by lidnariq
Mesen's debugger literally tells you what banks are mapped to CPU and PPU memory. You should really pay attention to that and find where it ceases to be what you believe it should be.
Re: Setting inesprg to 2 makes game stop running
Posted: Mon Mar 25, 2019 1:25 pm
by Jay John
lidnariq wrote:Mesen's debugger literally tells you what banks are mapped to CPU and PPU memory. You should really pay attention to that and find where it ceases to be what you believe it should be.
Already checked it, it's like this at the beginning:
But after a frame it's like this:
That's why I was checking the start and reset code.
Re: Setting inesprg to 2 makes game stop running
Posted: Mon Mar 25, 2019 1:31 pm
by tokumaru
Jay John wrote:But after a frame it's like this
Step trough the code to see when exactly it changes to this.
Re: Setting inesprg to 2 makes game stop running
Posted: Mon Mar 25, 2019 1:42 pm
by Jay John
tokumaru wrote:Jay John wrote:But after a frame it's like this
Step trough the code to see when exactly it changes to this.
Done it it's when it reaches the last "sta $8000".
Code: Select all
ldhormir:
lda #%00011011
sta $8000
lsr a
sta $8000
lsr a
sta $8000
lsr a
sta $8000
lsr a
sta $8000
rts
Re: Setting inesprg to 2 makes game stop running
Posted: Mon Mar 25, 2019 1:49 pm
by lidnariq
What are you trying to get the MMC1 to do? The behavior you're seeing is correct for the value you're writing...