Having a dumb moment with nestest.nes

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
User avatar
iOSBrett
Posts: 38
Joined: Wed Apr 18, 2018 1:09 am
Location: Australia

Having a dumb moment with nestest.nes

Post by iOSBrett » Wed Apr 18, 2018 1:18 am

Hi,

I am writing a NES emulator in Swift just for fun (yes I have read the sticky) and have implemented the CPU part and Mapper 0, no PPU or APU yet.
I want to test the instructions so I have loaded nestest.nes and set PC to 0xC000, it runs about 20 or so instructions before finding an opcode it doesn't know. This bit I can probably fix, but I thought it is probably better to first change all my logs to match those in the existing log file I found (this was hard to track down). I have started doing that and am having a dumb moment, I don't understand a part of the log file. What is the "= 74", "= 52", "= 73" mean after the STX instructions? Isn't this STX mean store what is found at memory location $00 in the X register? In my memory model there is nothing stored at location 0, and the subsequent log of the X register shows it is 0. Can anyone help me understand what is happening here?

Cheers,
Brett

Code: Select all

C000  4C F5 C5  JMP $C5F5                       A:00 X:00 Y:00 P:24 SP:FD CPUC:0
      READ      $C000
      READ      $C001
      READ      $C002
C5F5  A2 00     LDX #$00                        A:00 X:00 Y:00 P:24 SP:FD CPUC:3
      READ      $C5F5
      READ      $C5F6
C5F7  86 00     STX $00 = 74                    A:00 X:00 Y:00 P:26 SP:FD CPUC:5
      READ      $C5F7
      READ      $C5F8
      WRITE     $0000
C5F9  86 10     STX $10 = 52                    A:00 X:00 Y:00 P:26 SP:FD CPUC:8
      READ      $C5F9
      READ      $C5FA
      WRITE     $0010
C5FB  86 11     STX $11 = 73                    A:00 X:00 Y:00 P:26 SP:FD CPUC:11
      READ      $C5FB
      READ      $C5FC
      WRITE     $0011

User avatar
koitsu
Posts: 4216
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: Having a dumb moment with nestest.nes

Post by koitsu » Wed Apr 18, 2018 1:29 am

References: https://wiki.nesdev.com/w/index.php/Emulator_tests and http://www.qmtpro.com/~nes/misc/nestest.txt

The log you're posting should be compared to logs from Nintendulator. STX $00 = 74 is telling you that, at the time the instruction was encountered (but before it had run), the effective address (zero page address $00) contained value $74 (in hexadecimal; the $ is missing but implied).

Here are some more complicated examples which should then become self-explanatory assuming you understand the addressing modes in question, but I'll explain the first two:

Code: Select all

CFDB  A1 80     LDA ($80,X) @ 80 = 0200 = 5A    A:5D X:00 Y:69 P:27 SP:FB CYC:118

DB65  91 33     STA ($33),Y = 0400 @ 0400 = 7F  A:87 X:06 Y:00 P:E5 SP:FB CYC:239

DB7B  6C 00 02  JMP ($0200) = DB7E              A:DB X:07 Y:00 P:E5 SP:FB CYC:326

E2F2  DD 00 06  CMP $0600,X @ 0678 = 81         A:80 X:78 Y:63 P:A5 SP:FB CYC:270
The entry at $CFDB is saying, in English, since indexed indirect addressing is used:

* @ 80 -- indicates the calculated effective address of ($80,X) was $80 (because X=$00, thus $80+X = $80)
* = 0200 -- indicates that the two bytes at $80 and $81 (for the indirect read) were $00 and $02 respectively, hence address $0200
* = 5A -- indicates that address $0200 contained $5A when the instruction was encountered

The entry at $DB65 is saying, in English, since indirect indexed addressing is used:

* = 0400 -- indicates that the two bytes at $33 and $34 (for the indirect read) were $00 and $04 respectively, hence the address $0400
* @ 0400 -- indicates the calculated effective address is $0400 (because Y=$00, thus $0400+Y = $0400).
* = 7F -- indicates that address $0400 contained $7F when the instruction was encountered

You get the idea. This general "real-time debugger" output is helpful for people doing reverse-engineering, since it gives them an idea of what the calculated effective address was (for relevant addressing modes), as well as what that memory location contained. Now you see why this is helpful in ensuring your 6502 CPU emulation is correct.

User avatar
iOSBrett
Posts: 38
Joined: Wed Apr 18, 2018 1:09 am
Location: Australia

Re: Having a dumb moment with nestest.nes

Post by iOSBrett » Wed Apr 18, 2018 2:33 am

Thanks for the very quick reply.

I have definitely read the nestext.txt file quite a few times, which is how I finally worked out how to run it without a PPU. And because I don't have the PPU I have to run it automated, and as a first pass I wanted to compare my log with the log I've seen people talk about, but I couldn't find it. I got the log I posted above from a post on this forum, it is called nestest-bus-cycles.log, I will hunt down one from Nintendulator and have a look at that one.

I am pretty sure I understand the Addressing Modes, and I do follow what you are saying, but I have only just recently learnt all this so I expect my understanding to be incorrect in places, hence the testing.

Looks like you have the same conclusion as me, there is a value $74 at location $00. Having loaded the rom myself and written the Memory mapper I know even without checking that I have nothing but a lot of 0's in the zero page. I have loaded the PRGROM at $C000 and mirrored it at $8000. But if you look at the log, the $74 is never written to the X register anyway.

So I have another question for you, what should be in the zero page after loading nestest.nes? I assume it is only what is written by the rom during execution, but here we are only 3 instructions in.

I really appreciate you taking the time to write the really comprehensive reply.

[EDIT]: I see the log file in the first link, I swear I have looked at that page a million times and never saw the link, that one looks much better. It has $00 instead of $74, which is exactly what I expected. Thanks for pointing out the obvious link to me (not being sarcastic), told you I was having a dumb moment.

Cheers,
Brett

User avatar
thefox
Posts: 3141
Joined: Mon Jan 03, 2005 10:36 am
Location: Tampere, Finland
Contact:

Re: Having a dumb moment with nestest.nes

Post by thefox » Wed Apr 18, 2018 6:45 am

iOSBrett wrote:Looks like you have the same conclusion as me, there is a value $74 at location $00. Having loaded the rom myself and written the Memory mapper I know even without checking that I have nothing but a lot of 0's in the zero page. I have loaded the PRGROM at $C000 and mirrored it at $8000. But if you look at the log, the $74 is never written to the X register anyway.
The log was taken with initial memory contents randomized. Anyway, it's not very useful to try to make your log match the disassembly in the log, simply make sure that the register values (A, X, Y, SP, PC) match. When you want to take it a step further you can also verify that the READ/WRITE cycles match.

There's a more terse log (without disassembly for ease of comparisons) at viewtopic.php?p=155910#p155910
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi

tepples
Posts: 21752
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Having a dumb moment with nestest.nes

Post by tepples » Wed Apr 18, 2018 7:08 am

iOSBrett wrote:as a first pass I wanted to compare my log with the log I've seen people talk about
I agree with thefox: Just compare only program counter and AXYPS values, and you'll at least know where the program went off the rails. Unless nestest is reading uninitialized memory, the program counter and AXYPS values should not depend on initial contents of memory. My first guess is that you're trying to produce the identical disassembly in your emulator in order to be able to use the diff tool included with macOS.* It'd probably be easier to just write your own comparison tool that checks only PC or only PC+AXYPS.


* Assumption based on username and language choice. GNU/Linux and *BSD also include diff. Windows includes the similar fc, and Windows users can also get GNU diff through MSYS, Cygwin, or Windows 10 WSL.

User avatar
koitsu
Posts: 4216
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: Having a dumb moment with nestest.nes

Post by koitsu » Wed Apr 18, 2018 12:54 pm

Also make sure that CPUC (CPU cycles) also matches; there are many "edge cases" to cycle additions on the 65xxx series, such as during page wrapping operations. You can focus on this *after* you get opcodes/addressing modes emulated correctly. This is just one aspect of "timing-accurate" emulation.

As for ZP/RAM contents and so on on power-on (this is different than reset!), others have covered it already. It's also a commonly-discussed-hot-topic around here because there are some games which sort of "depend" on certain power-on values. I can link you to those threads if/when asked. In general, for starters, try initialising ZP/RAM to all zeros, see how the tests fair, then try initializing ZP/RAM to $FF and see how the tests fair. You get the idea.

As for CPU state itself, this is covered: https://wiki.nesdev.com/w/index.php/CPU_power_up_state
PPU has similar for when you get to it: https://wiki.nesdev.com/w/index.php/PPU_power_up_state

User avatar
iOSBrett
Posts: 38
Joined: Wed Apr 18, 2018 1:09 am
Location: Australia

Re: Having a dumb moment with nestest.nes

Post by iOSBrett » Fri Apr 20, 2018 5:38 am

thefox: Ahh that explains the weird values in 0 page.

And I have found it really helpful to compare the dissembled instructions. The 6502 page I used when implementing my emulated CPU had a couple of opcode errors in it, and I added more with my typos. I have had to change at least 5 opcode values that I would not have found with seeing the assembly code.

Debugging the CPU is strangely more fun than the code writing, can't say this is true in the day job though.

User avatar
iOSBrett
Posts: 38
Joined: Wed Apr 18, 2018 1:09 am
Location: Australia

Re: Having a dumb moment with nestest.nes

Post by iOSBrett » Fri Apr 20, 2018 5:40 am

tepples: Assumptions mostly correct.

I had planned on using sublime to do the diff, but it turns out it is not very good at that, so diff it is.
As posted above, using the diff has turned out to be really useful.

User avatar
iOSBrett
Posts: 38
Joined: Wed Apr 18, 2018 1:09 am
Location: Australia

Re: Having a dumb moment with nestest.nes

Post by iOSBrett » Fri Apr 20, 2018 5:44 am

koitsu: Yeah I am leaving the cycles to last, seems that none of my cycles match the log that you sent me. Even the first two instructions I have wrong in terms of number of cycles.

NesTest:

Code: Select all

C000  4C F5 C5  JMP $C5F5                       A:00 X:00 Y:00 P:24 SP:FD CYC:  0
C5F5  A2 00     LDX #$00                        A:00 X:00 Y:00 P:24 SP:FD CYC:  9
Mine:

Code: Select all

C000  4C F5 C5  JMP $C5F5                       A:00 X:00 Y:00 P:24 SP:FD CYC:0
C5F5  A2 00     LDX #$C5F6                      A:00 X:00 Y:00 P:24 SP:FD CYC:3
Thanks for those two links, I have implemented reset, but I didn't know that power on was different. I'll get everything else covered before taking that.

Thanks again to everyone for all the help, this forum is full of friendly and helpful people.

[EDIT]: Just noticed I am applying the wrong addressing mode in the LDX command, however the incorrect cycles are for the JMP command.

tepples
Posts: 21752
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Having a dumb moment with nestest.nes

Post by tepples » Fri Apr 20, 2018 7:55 am

CYC in a Nintendulator log is PPU dots, not CPU cycles. There are three dots in a cycle on NTSC systems and PAL famiclones, and it wraps around from 341 to 0. If you've ever emulated Z80 or LR35902 (Game Boy CPU) before, think of dots as like tstates and cycles as like mcycles.

User avatar
koitsu
Posts: 4216
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: Having a dumb moment with nestest.nes

Post by koitsu » Fri Apr 20, 2018 11:18 am

tepples wrote:CYC in a Nintendulator log is PPU dots, not CPU cycles. There are three dots in a cycle on NTSC systems and PAL famiclones, and it wraps around from 341 to 0. If you've ever emulated Z80 or LR35902 (Game Boy CPU) before, think of dots as like tstates and cycles as like mcycles.
Well that's a wonderfully misnamed field then. Good thing it's documented! :|

User avatar
iOSBrett
Posts: 38
Joined: Wed Apr 18, 2018 1:09 am
Location: Australia

Re: Having a dumb moment with nestest.nes

Post by iOSBrett » Sat Apr 21, 2018 7:53 pm

Oh! In that case my cycles may be correct.

:-)

Post Reply