Strange debug problem

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Strange debug problem
by on (#3647)
Doing some debugging and I came across this:

In debugging why Who_Framed_Roger_Rabbit_(U).nes crashes
The game stats are:

NES Game Size: 131088 bytes
Number of 16K Program Banks: 8
Number of 8K CHR Banks: 0
Mapper number: 7
SRAM Enabled: 0
Vertical Mirroring: 0

I found:

emulation starts:

The code loads bank 0 32K into 0x8000
The code loads bank 3 32k into 0x8000
First NMI occurs
Crash on first opcode of 0xe3 with pc of 0xFFA1 (NMI vector).

I assume the rom is bad, but Ubernes plays the rom fine. How could a bad opcode exist in the game if it is not corrupted? How does Ubernes (or any emulator) play a corrupted game? If I ignore the bad opcode (pc++) the game will load, but works strangely.



Any ideas?

by on (#3658)
As you state, NMI vector points to address 0xFFA1, but the opcode there is not 0x3E, but 0x85 (0x85 0x43 (STA $43), to be exact). May your NMI handler be the problem? Check it.
Re: Strange debug problem
by on (#3662)
Emugalaxy wrote:
I assume the rom is bad, but Ubernes plays the rom fine. How could a bad opcode exist in the game if it is not corrupted?

Apart from the "KIL"/"JAM"/"HLT" opcodes, most of which have $2 as the least significant digit, there are no "bad" opcodes, just undocumented opcodes.
Re: Strange debug problem
by on (#3664)
tepples wrote:
Emugalaxy wrote:
I assume the rom is bad, but Ubernes plays the rom fine. How could a bad opcode exist in the game if it is not corrupted?

Apart from the "KIL"/"JAM"/"HLT" opcodes, most of which have $2 as the least significant digit, there are no "bad" opcodes, just undocumented opcodes.

I guess by "bad" here he meant "corrupted" in the sense of a byte dumped incorrectly..

by on (#3692)
Here is my NMI handler:

sPush(pc >> 8);
sPush(pc & 0xFF);
//N V * B D I Z C
//- - 1 0 - - - -
status = 0;
status = (negative_flag << 7) |
(overflow_flag << 6) |
(1 << 5) |
(0 << 4) |
(decimal_flag << 3) |
(interrupt_disabled_flag << 2) |
(zero_flag << 1) | carry_flag;
sPush(status);
interrupt_disabled_flag = 1;
pc = NMI;

Should I add anything? My IRQ handler is virtually identical.

Then I do the switch(cpu_mem[pc]) etc....

The pc is 0xFFA1. The value there is 0x3E. Anyone know the if the game actually does load bank 0 and then 3? Maybe I have an error in my core that is causing the wrong bank number to be calculated? Thanks for the replys

by on (#3693)
If you're doing what I think you're doing, you're reading the NMI vector upon loading the ROM and leaving it as-is, even when the upper PRG bank changes.

If this is the case, this is INCORRECT behaviour - the CPU fetches the appropriate interrupt vector from memory on EVERY INTERRUPT, so it is very much possible to redefine the interrupt vectors at runtime (in this case, by bank switching).

The reason it's failing is because every bank in that game has a different NMI vector, and when the interrupt comes along, it's not in the same bank as you started out with.

by on (#3694)
That was it. Thanks!

I have one other question. I pass all of the nestest.nes tests except for indirect, X. I get a code code 59: 059h - STA didn't store the data where it was supposed to

my STA code is:

case 0x81: STA(indirectX()); count+=6; pc+=2; break;

My indirectX function is:

unsigned short indirectX() {
unsigned short temp = getMem(pc + 1);
temp = (temp + x) & 0xFF;
unsigned short newAddressLSB = getMem(temp);
unsigned short newAddressMSB = getMem(temp+1);
newAddressMSB = newAddressMSB << 8;
return newAddressMSB | newAddressLSB;
}

I can't find anything wrong with this. Any ideas?

by on (#3695)
Nevermind . Fixed it. I wasn't wrapping on zero page.