Some of you emulator authors might be interested in this. It's an execution log of the nestest test ROM (see
http://wiki.nesdev.com/w/index.php/Emulator_tests) with bus cycles included, generated with Nintendulator. So basically the same as the nestest.log that's making rounds, but more detailed. I also removed the PPU cycle counters and included a CPU cycle count instead.
Let me know if you spot any errors in it (I hope I implemented the logging correctly).
I was looking for something like this, thank you very much.
One question, though: would it be possible to put a cycle counter on the bus cycle lines too? I could add them using line numbering but I'd like to be sure, if it's not too much work.
I won't do it right now, but I'll consider it if I'll redo the log at some point. I was thinking about generating logs from some other test ROMs also.
Didn't think it would be very useful to have the cycle counts on the bus cycles because every line equals one cycle.
It would make sure the emulator is updating the clock at the right time. I know for a fact mine isn't - everything happens in the right order, but some events are on the wrong side of a clock increment, overlapping with the bus cycle before or after and leaving a gap on the other side.
Yes, I know, I'm basically saying I'm a terrible programmer, but that's all the more reason for an automated test.
One interesting think would be generating another log, but using a NMI test ROM. I don't remember of its name, it just displays an "E" in the screen, but the middle "-" must be ok. If the NMI timing (or PPU timing?) is wrong, the "E" is glitched.
Any chance?
I made a revision of the log, it now includes also the data that is being read/written. I removed the disassembly so that comparing the data is easier. Sorry, but still no CPU clocks on every line (feel free to make a small tool to mangle the data that way, and share the results if you want
)
NOTE: The log assumes that RAM has been initialized to 0 (there are at least a few cycles that read from uninitialized stack areas).
I noticed that blargg's CPU tests are not good candidates for these types of logs because they have a bunch of hardware dependencies in them. For example they poll $2002 in the beginning which makes the cycle counter and the shown bus data values useless if $2002 reads aren't implemented. Maybe it'd be useful to compile versions of those tests that start at a known address and don't access external hardware (except memory, of course). Such tests would also be easier to run through Visual6502/Visual2A03.
Zepper wrote:
One interesting think would be generating another log, but using a NMI test ROM. I don't remember of its name, it just displays an "E" in the screen, but the middle "-" must be ok. If the NMI timing (or PPU timing?) is wrong, the "E" is glitched.
Any chance?
I think CPU logs of PPU tests would be of limited value, because it'd be hard to notice any problems in PPU emulation from them. And having such logs might only be encouraging people to make Nintendulator emulators rather than NES emulators.
Hmm... good point. Not exactly to me, but to everyone else that puts Nintendulator at the top of everything else. -_-;;
At anyway, I believe test ROMs are the way of getting an emulator more accurate. Any chance of another NMI test ROM?
If you're going to go to the trouble of logging every bus cycle, it would be worth using a test ROM that covered all the page-crossing and dummy read cases. I know blargg's tests do, but they're designed to be verified by the code itself and depend on the PPU or APU, as you said.
Do we have a CPU-only ROM that does this already?
Rahsennor wrote:
If you're going to go to the trouble of logging every bus cycle, it would be worth using a test ROM that covered all the page-crossing and dummy read cases. I know blargg's tests do, but they're designed to be verified by the code itself and depend on the PPU or APU, as you said.
Do we have a CPU-only ROM that does this already?
Sorry to be harsh, but you're kind off the my subject.
Sorry, shutting up now.
Rahsennor wrote:
If you're going to go to the trouble of logging every bus cycle, it would be worth using a test ROM that covered all the page-crossing and dummy read cases. I know blargg's tests do, but they're designed to be verified by the code itself and depend on the PPU or APU, as you said.
Do we have a CPU-only ROM that does this already?
I'm not aware of such a ROM. Recompiling blargg's test ROMs with some small changes would probably be the best option. Really the only thing that would probably have to be removed would be the $2002 reads, since hardware register writes don't affect timing.
Zepper wrote:
Any chance of another NMI test ROM?
Definitely not from me.
thefox wrote:
I'm not aware of such a ROM. Recompiling blargg's test ROMs with some small changes would probably be the best option. Really the only thing that would probably have to be removed would be the $2002 reads, since hardware register writes don't affect timing.
The dummy read test ROMs use clear-on-read flags on the PPU/APU as part of the test. They fail (or worse, lock up) when run on a CPU-only emulator. The timing test ROMs also rely on APU reads.
I was thinking of writing a simple test ROM myself, but I'm probably not qualified for the task.
Oh yeah, I was thinking of different ROMs. Anyways, writing test ROMs that don't have to actually verify the results (just exercise the different scenarios) should be fairly easy. Although many of the dummy read scenarios are probably already covered by the normal tests (when used with bus cycle logs).
Hello all! Sorry for resurrecting such and old thread.
Am I completely misunderstanding the concept of crossing page boundaries, or has the version of Nintendulator which made this trace log wrongly implemented CPU cycle counting for branch instructions?
Code:
My emu
------
$CFFE(F0 05): BEQ $05 | [PC -> $D005] A:0x5A X:0x81 Y:0x69 P:0x27 SP:0xFB CYC:2598
$D005(A9 AA): LDA #$AA A:0x5A X:0x81 Y:0x69 P:0x27 SP:0xFB CYC:2602
Nintendulator log
-----------------
CFFE F0 05 BEQ $D005 A:5A X:81 Y:69 P:27 SP:FB CPUC:2598
D005 A9 AA LDA #$AA A:5A X:81 Y:69 P:27 SP:FB CPUC:2601 <<--------------------
Shouldn't an extra cycle be added at this point because we're branching from CFFE -> D005?
No, because the instruction pointer already points to $D000 by the time the offset is going to be added. (Hence why relative branches have an effective displacement of -126 to +129 bytes)
lidnariq wrote:
No, because the instruction pointer already points to $D000 by the time the offset is going to be added. (Hence why relative branches have an effective displacement of -126 to +129 bytes)
Thank you!
lidnariq wrote:
No, because the instruction pointer already points to $D000 by the time the offset is going to be added. (Hence why relative branches have an effective displacement of -126 to +129 bytes)
Yes. Cycle 3 is the answer.
Code:
CFFE F0 05 BEQ $D005
# address R/W description
--- --------- --- ---------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch operand, increment PC
3 PC R Fetch opcode of next instruction,
If branch is taken, add operand to PCL.
Otherwise increment PC.
4+ PC* R Fetch opcode of next instruction.
Fix PCH. If it did not change, increment PC.
5! PC R Fetch opcode of next instruction,
increment PC.
So, right, PC is at $D000 when adding the operand byte.
You know how I was talking about a language barrier before?
Here's his question, emphasis mine:
blashyrk wrote:
Shouldn't an extra cycle be added at this point because we're branching from CFFE -> D005?
Please reread his question and my answer until you understand that I answered the question correctly.
lidnariq wrote:
Please reread his question and my answer until you understand that I answered the question correctly.
Did
I answer incorrectly? I edited slightly my post to be crystal clear.
Think of it this way: Look at the address of the opcode that would be executed if the branch were not taken. If the taken and not-taken opcode are in the same page, there is no page crossing penalty cycle.
In the present case of a branch at $CFFE, this not-taken instruction is at $D000. The taken instruction is $D005, which is in the same page as $D000.
I am also sorry but I must resurrect this thread. There is something that I simply don't get.
I have been using this log to run my CPU through some tests and I actually don't understand at all what is happening to the "log registers" whenever it calls PHP followed by PHA.
If you look at line 73, the accumulator is set with the value 0x7F. Two lines before, it uses PHP when the Status Register is set at 0x6F, and just after it calls immediately PLA, which is supposed to pull back the same value (0x6F) and store it into the Accumulator...no ?
Unless PHP or PLA are supposed to modify the value in question, is there someone who can explain to me why the log is specifying the value 0x7F for the accumulator in this very specific line ?
EDIT : Same pattern for lines 82/83/84. Stores 0x64, retrieve 0x74. Each time the original value is met again by the use of AND instruction.
lidnariq wrote:
Thank you so much dude. I never saw it specified elsewhere before.
Is there another place we could put that information that would have helped you find it on your own?
lidnariq wrote:
Is there another place we could put that information that would have helped you find it on your own?
No it is put in the right place. The thing is I already read this page before but it was for another reason. I completely forgot about these lines talking about PHP and BRK.
Usually I use this
http://www.obelisk.me.uk/6502/reference.html or the Levanthal's 6502 book.
Once again thank you for your quick help