Reputation:
I finished writing my 6502 emulator and I'm ready to start testing it. I found the nestest ROM with some documentation, but I'm not sure, what the proper way of loading the ROM is. The author says, that emulators should start at 0xC000, which contains 0 when I load the ROM, so I must be doing something wrong.
So right now my loading procedure looks something like this:
clear memory
set PC to 0x8000
open the file
skip first 16 bytes (iNES header)
load the rest of the file into RAM (starting at 0x8000)
set PC to 0xC000
Upvotes: 4
Views: 3002
Reputation: 100632
As per Nick Westgate's comment (hence the instant community wiki), the loading procedure is a bit more complicated than you might naively guess:
For now, you can load 0x4000 bytes starting at offset 0x0010, and map that as ROM into both $8000-$BFFF and $C000-$FFFF of the emulated 6502's memory map.
The 'for now' assumes you're going to write a NES emulator and therefore one day will properly parse the NES-related file format that test is stored in and emulate the NES-specific memory mapping scheme that leads to the mirroring of contents.
Ignore the comment in the post before that you should "[log] your PC (and registers) on every cycle", and the implication of the same in that post and onwards; he means that:
If you've simplified things in your emulator to read and execute each operation atomically and then skip time ahead by the number of cycles you should have spent working then you can probably omit the temporary storage. I suspect the author that generated the sample log had implemented such an emulation. Key clues will be a switch
table indexed by opcode that is not in some way a coroutine, and/or a lookup table of instruction lengths.
Further advice:
The NES doesn't actually use a 6502. It uses a clone that omits decimal mode — the decimal flag simply has no effect. So if you're emulating a 6502, expect test results to vary there.
For other good 6502 tests, see:
I used all three of those to bootstrap my most recent 6502 emulator, plus some self-written cycle-by-cycle tests for things like interrupts that you wouldn't expect code that sits inside a 6502's address space to be able to handle.
I found out a lot later that I had a very minor deviation in decimal handling — minor enough to pass all those tests, but not sufficient to pass an exhaustive 6502 comparison. I conveniently found a better test in the Acorn BBC community, within the archive attached to this post. I elected to run that by:
BCDTEST_beeb
at 0x2900
;JSR 2900h
to address 0x200
;RTS
at 0xffee
, but also make sure you can trap that address;0x200
and keep running until it is at 0x203
;0x84
is 0
. If it is something else, that indicates failure.To get more feedback, any time the PC goes to 0xffee
, output the ASCII character in the A register.
Upvotes: 4