So I've fixed lots of bugs in my CPU and I now have the following test ROMs passing 100%:
- Flubba's NEStress
- Kevtris' nestest
- Blargg's nes_cpu_test5 (official only)
- Blargg's nes_intr_test (official only)
So what would be the next best CPU test ROM to try and get working? I couldn't find any particular "ordering" (on the Wiki or otherwise) of which tests to get working first. I have the following CPU tests available (all Blargg's) that I think would be the best to pick from:
cli_latency
cpu_interrupts_v2
nes_intr_misc
nes_instr_timing (instr_timing - unofficial)
Can someone recommend an order to the above tests? Or just the next best one? Or if there is a different test that I should run that is not shown above please let me know. I'm not limiting myself to the above tests. In fact, the more tests I have the better!
Thanks!
Jonathon
UPDATE: I now have the following additional tests passing:
- Blargg's cpu_timing_test6
- Blargg's branch_timing_tests
- Blargg's nes_intr_timing (instr_timing - official only)
- Blargg's nes_intr_timing (branch_timing)
I think the other CPU test ROMs that I'm failing are due to my incomplete APU module. I think I'm going to forget about more CPU testing and work on finishing my APU next (after a bit of code cleanup).
I think blargg's CPU test are enough to make sure the basic instructions operate correctly.
I'd say the branch timing tests and CPU timing tests are good to do next. Bad CPU timing makes Battletoads shaky.
I am working with some test roms and I have a question.
I am using Kevtris' Nestest and am wondering how to interpret the errors. I assumed they were opcodes, but some of them do not correlate properly with the type of test that's being run and some are just erroneous. I have attached an image of the test running. (I still have some graphical kinks to work out). I'll also type it out to make things easier.
Er Run all tests
OK Branch tests
13 Flag tests
75 Immediate tests
45 Implied tests
48 Stack tests
4D Accumulation tests
70 (Indirect, X) tests
AE Zerospace tests
E8 Absolute tests
05 (Indirect), Y tests
4F Absolute, Y tests
34 Zerospace, X tests
7B Absolute, X tests
http://www.flickr.com/photos/tineras/4824543247/
I can only assume that bad data is being passed into the error spot because of other problems with my code. Can someone clarify how to interpret the errors? Is the data in the 'Er' spot supposed to represend the OpCodes that are not executing properly?
Thanks
There is a
known good log of nestest. Make your emulator spit out a log of the executed instructions in the same format, and then find the first difference.
tepples wrote:
There is a
known good log of nestest. Make your emulator spit out a log of the executed instructions in the same format, and then find the first difference.
Whoops, I was doing something silly and thought that starting at C000 was wrong because the nestest rom would only run if I started at the address pointed to by the IVT. And my log looked MUCH different than the gold version, so I wasn't sure what was going on. Now I realise that I just have another problem to squish.
That being said, I'm still curious to know if there is any relevent information in the error code that is displayed on the screen.?
As I understand it, the test does most of its testing in a subroutine at $C000. When run on an NES, it needs to be started like any other ROM with JMP ($FFFC), but if you don't have most of your I/O (PPU/APU) done, it can still be called as a separate subroutine. This is a log of that subroutine.
tepples wrote:
As I understand it, the test does most of its testing in a subroutine at $C000. When run on an NES, it needs to be started like any other ROM with JMP ($FFFC), but if you don't have most of your I/O (PPU/APU) done, it can still be called as a separate subroutine. This is a log of that subroutine.
Do you know why the Stack Pointer starts out at FD instead of FF?
tineras wrote:
tepples wrote:
As I understand it, the test does most of its testing in a subroutine at $C000. When run on an NES, it needs to be started like any other ROM with JMP ($FFFC), but if you don't have most of your I/O (PPU/APU) done, it can still be called as a separate subroutine. This is a log of that subroutine.
Do you know why the Stack Pointer starts out at FD instead of FF?
- I suppose it's because the stack is at $00, then the CPU decrements 3 on reset. $00 - 3 = $FD.
Zepper wrote:
tineras wrote:
tepples wrote:
As I understand it, the test does most of its testing in a subroutine at $C000. When run on an NES, it needs to be started like any other ROM with JMP ($FFFC), but if you don't have most of your I/O (PPU/APU) done, it can still be called as a separate subroutine. This is a log of that subroutine.
Do you know why the Stack Pointer starts out at FD instead of FF?
- I suppose it's because the stack is at $00, then the CPU decrements 3 on reset. $00 - 3 = $FD.
I did not know that. I will add that piece to my code.
Dwedit wrote:
I think blargg's CPU test are enough to make sure the basic instructions operate correctly.
I'd say the branch timing tests and CPU timing tests are good to do next. Bad CPU timing makes Battletoads shaky.
Cool, thanks Dwedit. I'll work on nes_intr_timing next then.
Zepper wrote:
- I suppose it's because the stack is at $00, then the CPU decrements 3 on reset. $00 - 3 = $FD.
That is exactly correct, and it's how I have implemented my CPU in hardware. In integrated circuits it is typical (and good practice) to clear all flops to '0' on power-up (except in very peculiar cases where you might absolutely have to have a bit set for proper operation).
Pz!
I am happy to report that I am now passing all of the Kevtris NesTest tests (say that three times fast
)
http://www.flickr.com/photos/tineras/4832572513/
However, I'm not sure how to go about accounting for invalid opcodes. Right now I just have a "default" line in my switch statement that just lets me know an invalid opcode has been called and then it just adds 1 to the program counter.
If you guys could point me in the right direction, I'd really appreciate it.
tineras wrote:
However, I'm not sure how to go about accounting for invalid opcodes.
So you're pondering support for unofficial 6502 opcodes, and you're planning to treat them all like $EA NOP.
This is illegal,
you know.
tepples wrote:
tineras wrote:
However, I'm not sure how to go about accounting for invalid opcodes.
So you're pondering support for unofficial 6502 opcodes, and you're planning to treat them all like $EA NOP.
This is illegal,
you know.
If it is not important for making a good emulator, then I am not that concerned about it. I just don't want to run into problems in the future. But I did read somewhere that no games (or almost no games) make use of them.
tepples wrote:
So you're pondering support for unofficial 6502 opcodes, and you're planning to treat them all like $EA NOP.
Isn't that how the 65C02 treats them?
Most games do not make use of illegal opcodes, but the NES CPU behaves exactly like a common 6502 in this regard, meaning that all instructions are there and behave as described, so a few programs do use them.
I remember that a real-time polygon rotation demo used some illegal instructions, but I can't think of any commercial games right now. Still, for NES developers this might be an interesting feature for an emulator to have, as that makes it more like the real console.
At least
Puzznic and Lolo 3 use multi-byte NOPs. These act like BIT, except they don't even set the flags. And I seem to remember some Chinese games use unofficial opcodes and disguised bankswitches to make the init code (which sets up jump tables in RAM) harder for mapper-hacking pirates to trace.
(It's not actually a crime or tort to implement unofficial opcodes. "Illegal" is just a nickname for them, and "you know" is a quote from one of the Zelda games for CD-i.)
And the processor itself doesn't prosecute a program for using "illegal" opcodes, hence the better name of "unofficial".
The only problem with the unofficial opcodes is that
Martin Korth claims they don't always work on certain 6502 based computers.
I couldn't get some of them to work consistently on the NES, which is why they aren't in my CPU test. Yet another reverse-engineering time-sink, but I've learned to just let them be rather than get sucked in.