Nintendulator log change

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
HastatusXXI
Posts: 40
Joined: Sat Aug 25, 2018 7:21 am

Nintendulator log change

Post by HastatusXXI »

Hi,
I was looking for a nestest log, since the one I used to test my 6502 emulator disappeared from my computer. I found it in the wiki. However, when I tested my emulator its output and the log provided in the site didn't match. That seemed strange, since I remember it worked like a charm last year. I've just known that the file was changed (by observing cached versions of the page), and the version hosted back then matches my emulator's output. The new version renames CYC as PPU (that's ok, since it refers to PPU dots). However it now adds an unnamed column and CYC (I suppose it means actual CPU cycles). However, I'm unable to match CYC with CPU cycles. Aren't they supposed to be 1/3 of the PPU cipher? On top of that, should I worry about this, since PPU (previously CYC) matches (I mean, in terms of accuracy)?
User avatar
koitsu
Posts: 4201
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: Nintendulator log change

Post by koitsu »

Lots of misinformation being stated here. Let's clarify, with links/references to literally everything:

1. CPU cycles are independent of PPU dots ("cycles"); the two chips (CPU and PPU) are operating independently of one another. On NTSC, for every 1 CPU cycle, 3 PPU dots happen. Reference

2. CPU cycles are pre-defined and can be looked up in any good/decent 6502 reference chart/manual/books/links. An instruction takes N number of cycles, sometimes with some variance (e.g. branch instructions take an extra cycle if the branch is taken, page wrapping costs an extra cycle, etc.). Good materials will disclose this information. See the Wiki for such, or other online resources. Reference

3. CYC in nestest.log refers to CPU cycles, not PPU. It is an incrementing counter. The nestest entry on the wiki page includes documentation (more on that in a moment).

4. PPU in nestest.log consists of two numbers: the PPU X counter and the Y counter (as in X dot and Y scanline position), delimited with a comma and some space padding. See Quietust's post below for details, else for PPU rendering details: Reference

5. The values shown in A/X/Y/P/SP/PPU/CYC are the values **before** the instruction on that line has executed. The reason the first line has CYC:7 is because internally when the CPU starts, it does a bunch of "prep work". There is some variance between 6502 CPU models (MOS 6502 vs. NES vs. others), where some take 9, others take 8 or 7, but the details are here: Ref 1 Ref 2 Ref 3 Ref 4

6. An FYI useful for emulator authors: nestest.log starts at $C000, not at the actual RESET vector value that's in ROM ($C004). I believe what's actually been done is overriding the vector value to contain $C000 (see #5 above). This runs all the tests, with no interactive menu. This is described in the documentation that comes with the nestest ROM but is easily overlooked. All emulator authors should read -- not skim -- the documentation that comes with nestest.

7. nestest documentation has a section called "Final notes" that is incredibly important to read. It is common for emulator authors to get errors/mistakes in an instruction or addressing mode, only to fix the bug and then get an error in an "earlier/previous" test number, which often causes confusion ("33 was failing before, now I fixed that and 32 is failing!!"). Read that section for why.

8. Emulator authors need to understand that nestest is not going to guarantee that all of your opcodes are functioning flawlessly; it (legitimately) assumes that there is a base set of instructions that are working/implemented properly. This has come up repeatedly on the nesdev Discord, where some emulator authors passed some tests but not others, only to find that previously-passing instructions were actually incorrectly implemented. Your emulator = your code = your bugs = you get to figure out why.

Additionals, because they come up all the time:

* For bugs with power-on and/or RESET states of the CPU, or register values/flags/etc., refer to the wiki. Reference

* For issues with the B flag of P (you will encounter this with regards to PHP/PLP/RTI), refer to the wiki or this explanation (see 41:58 onward).

Edit: bunch of additions and fixes.
Last edited by koitsu on Sat Jul 20, 2019 5:41 pm, edited 1 time in total.
User avatar
Quietust
Posts: 1920
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: Nintendulator log change

Post by Quietust »

koitsu wrote:4. PPU in nestest.log is an incrementing counter of PPU dots ("cycles').
Minor correction: there are two values, one for the PPU's X counter and one for its Y counter. Observe that the log's first line has "PPU: 0, 0" while the last one has "PPU:188,233" and that the second number never overflowed (which is good, because I don't count the number of frames rendered) - this means it took 233 full scanlines and 188 additional dots to execute.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
User avatar
koitsu
Posts: 4201
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: Nintendulator log change

Post by koitsu »

Quietust wrote:
koitsu wrote:4. PPU in nestest.log is an incrementing counter of PPU dots ("cycles').
Minor correction: there are two values, one for the PPU's X counter and one for its Y counter. Observe that the log's first line has "PPU: 0, 0" while the last one has "PPU:188,233" and that the second number never overflowed (which is good, because I don't count the number of frames rendered) - this means it took 233 full scanlines and 188 additional dots to execute.
Thank you! 100% right, and very easily overlooked due to space-padding after the comma. I've edited my post to clarify.
HastatusXXI
Posts: 40
Joined: Sat Aug 25, 2018 7:21 am

Re: Nintendulator log change

Post by HastatusXXI »

Thank you very much for your answers! They were quite clarifying.
HastatusXXI
Posts: 40
Joined: Sat Aug 25, 2018 7:21 am

Re: Nintendulator log change

Post by HastatusXXI »

I'm trying to replicate Nintendulator's log (I overlooked some details in the past and this lack of information is making progress difficult). I'm having some trouble with this instruction from nestest (line 5013 of http://www.qmtpro.com/~nes/misc/nestest.log):

Code: Select all

C6C9  0C A9 A9 *NOP $A9A9 = A9                  A:55 X:00 Y:53 P:24 SP:F7 PPU:164,131 CYC:14952
Why is it showing A9 as the content of address A9A9? This address isn't accessed at any time during the test execution. My output shows 00 instead, which I find logical, unless I'm missing something.

Edit: since $A9A9 lies into cartridge memory space I guess I the cartridge is not properly mapped. Please, tell me if I'm wrong.
User avatar
koitsu
Posts: 4201
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: Nintendulator log change

Post by koitsu »

1. The instruction $0C you see labelled as NOP $A9A9 is an invalid opcode, in case that's confusing you at all. It is not quite a "normal" NOP.

2. nestest.nes is mapper 0, 16KB PRG + 8KB CHR, and is thus mapped to $8000-BFFF in addressing space (i.e. 16KB). NES ROM addressing space runs from $8000-FFFF (i.e. 32KB). In the case of 16KB mapper 0 games, $C000-FFFF is a mirror of $8000-BFFF due to how the board circuitry works. The byte at location $E9A9 (value $A9) is thus the same byte as at $A9A9. https://wiki.nesdev.com/w/index.php/NROM outlines this fact (see "Banks" and read closely; NROM-128 = 16KB PRG, NROM-256 = 32KB PRG).
HastatusXXI
Posts: 40
Joined: Sat Aug 25, 2018 7:21 am

Re: Nintendulator log change

Post by HastatusXXI »

koitsu wrote:1. The instruction $0C you see labelled as NOP $A9A9 is an invalid opcode, in case that's confusing you at all. It is not quite a "normal" NOP.

2. nestest.nes is mapper 0, 16KB PRG + 8KB CHR, and is thus mapped to $8000-BFFF in addressing space (i.e. 16KB). NES ROM addressing space runs from $8000-FFFF (i.e. 32KB). In the case of 16KB mapper 0 games, $C000-FFFF is a mirror of $8000-BFFF due to how the board circuitry works. The byte at location $E9A9 (value $A9) is thus the same byte as at $A9A9. https://wiki.nesdev.com/w/index.php/NROM outlines this fact (see "Banks" and read closely; NROM-128 = 16KB PRG, NROM-256 = 32KB PRG).
That was it. I read that section, but I didn't get when mirroring should be applied. I was just mapping PRG-ROM to $C000-FFFF.
Thank you.
HastatusXXI
Posts: 40
Joined: Sat Aug 25, 2018 7:21 am

Re: Nintendulator log change

Post by HastatusXXI »

I have another question. Why is $FF value shown as in memory value after performing STA when A contains $02? I'm referring to line 8981 of http://www.qmtpro.com/~nes/misc/nestest.log

Code: Select all

C68B  8D 15 40  STA $4015 = FF                  A:02 X:FF Y:15 P:25 SP:FB PPU: 86,233 CYC:26520
In this case the accumulator is written to an APU register, but by watching the Donkey Kong log from Nintendulator I observed this also happens with PPU registers. Why is that? Does it have to do with _io_db being filled due to the capacitance issue exposed in the wiki https://wiki.nesdev.com/w/index.php/PPU_registers (this whouldn't explain what's going on with the APU registers...)?
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Nintendulator log change

Post by tepples »

I haven't looked into it in too much detail. But my guess is that STA shows the old value before the store, and it doesn't show the value of MMIO registers ($2000-$401F) because reading those has side effects.
User avatar
Quietust
Posts: 1920
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: Nintendulator log change

Post by Quietust »

tepples wrote:I haven't looked into it in too much detail. But my guess is that STA shows the old value before the store, and it doesn't show the value of MMIO registers ($2000-$401F) because reading those has side effects.
That's exactly what it's doing - Nintendulator's debugger assumes the value $FF whenever it is told to "preview" the value at any memory address for which a special "Debug" (side-effect-free) read handler has not been assigned.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
HastatusXXI
Posts: 40
Joined: Sat Aug 25, 2018 7:21 am

Re: Nintendulator log change

Post by HastatusXXI »

Okay, got it. Thank you both.
User avatar
Quietust
Posts: 1920
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: Nintendulator log change

Post by Quietust »

I've just made an additional update to the nestest reference log to fix 2 things:
1. The "PPU" column now displays the scanline number first and the pixel number second, because I realized it was confusing to have it the other way around (i.e. it was like showing Seconds,Minuntes instead of Minutes,Seconds)
2. The PPU now resets at pixel 21 instead of pixel 0 - my reset logic was originally resetting the APU first, the CPU second, and the PPU last, but that's a problem because the CPU reset code immediately processes the 6502's RESET interrupt and emulates the APU and PPU for 7 CPU cycles.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
Post Reply