Questions about nestest

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Questions about nestest
by on (#170973)
Hey guys, I am brand new here (and writing my first emulator). I have started with CPU and main memory for writing my emulator, and have starting looking into the nestest rom and the "golden log" from Nintendulator. I have a couple of things that confuse me when looking over this.

First of all, why does the stack pointer start at FD instead of FF in this log? Is there some execution that happens before this log starts?

Second, (and probably related) why do we start at scanline 241? I am also having trouble in general wrapping my head around how the CPU/PPU synchronization works, so that is probably part of the problem here. Why does the cycle count reset every time the scanline count updates?

As I said, I am definitely new at this :D.

I have been lurking here for a while, and have learned a lot from searching and reading what is already here. If my questions have been answered elsewhere, I have been unable to find the answers using the forum search tool.

Thanks in advance!
Re: Questions about nestest
by on (#170974)
fspinolo wrote:
First of all, why does the stack pointer start at FD instead of FF in this log? Is there some execution that happens before this log starts?


On power on, the RST pin is asserted. RESET consists of the following CPU cycles:

1. [READ] read (PC)
2. [READ] read (PC)
3. [READ] read (S), decrement S
4. [READ] read (S), decrement S
5. [READ] read (S), decrement S
6. [WRITE] PC_low = ($FFFC), set interrupt flag
7. [WRITE] PC_high = ($FFFD)

S is actually initialized to $00. But, those 3 decrements cause it to end up at $FD.
Re: Questions about nestest
by on (#170977)
fspinolo wrote:
First of all, why does the stack pointer start at FD instead of FF in this log? Is there some execution that happens before this log starts?

Reset on a 6502 always subtracts 3 from the stack pointer. If the emulator made the arbitrary choice to initialize the stack pointer with $00, subtracting 3 gives $FD.

Quote:
Second, (and probably related) why do we start at scanline 241?

Arbitrary choice, possibly associated with the fact that the PPU asserts the NMI signal at the start of line 241. (NMI tells the CPU that the vertical blanking interval, or vblank, has begun.) But for validation of a 6502 emulator's timing against nestest.log, all you need to worry about is that a change from one scanline to the next is associated with an expected subtraction of 341 (the length of a scanline including both active picture and horizontal blanking) from CYC.

Quote:
Why does the cycle count reset every time the scanline count updates?

Because it counts PPU cycles since the left side of the screen. There are 341 PPU cycles per scanline and 3 PPU cycles for each CPU cycle.*

Quote:
If my questions have been answered elsewhere, I have been unable to find the answers using the forum search tool.

There's also a wiki. Have you looked through there?


* Exceptions: On NTSC systems, when rendering is turned on, every other frame is shorter by one dot to realign the color subcarrier phase. And on PAL NES (but not PAL famiclones), there are 3.2 PPU cycles per CPU cycle. (Source)
Re: Questions about nestest
by on (#170981)
I have read the wiki quite a bit. The parts I am asking about were the parts that I found to be unclear there, and this is probably due mainly to my inexperience with the platform. For example, I learned from my reading about where the RESET vector resides, but I wasn't able to find the information given in this thread about the finer points of what happens when a RESET interrupt is triggered. I also found the information regarding CPU/PPU timing to be a bit cryptic, but I will have to re read it now that you have clarified a bit :)

I am a recently graduated CS student and I decided that writing an emulator would be a cool project to broaden/reinforce my skills. I expected it to be a challenge 8-). Thanks for the replies, this really helped with understanding the output I was seeing in that log. I am getting close to the point where my CPU will be ready for testing, so I wanted to make sure that I am setting myself up for success.
Re: Questions about nestest
by on (#170993)
zeroone wrote:
S is actually initialized to $00.
I was under the impression that S is not initialized; such that asserting /RESET on a already-warm and already-executing 6502 would leave some other random value there.

(It's just that on a cold boot, it's an artifact of the manufacture process that leaves 0 in the register)
Re: Questions about nestest
by on (#171005)
lidnariq wrote:
zeroone wrote:
S is actually initialized to $00.
I was under the impression that S is not initialized; such that asserting /RESET on a already-warm and already-executing 6502 would leave some other random value there.

(It's just that on a cold boot, it's an artifact of the manufacture process that leaves 0 in the register)


It could be. I just took an educated guess. The 6502 might be built to zero-out the registers on power-on. And, if it is, that would consistently result in S being set to $FD after RESET. In addition, a subsequent RESET in the middle of program execution would consistently decrement S by 3 from its current value at that time.

I remember seeing the 6502 RESET discussed on other sites in regards to other early computers like the Apple II. They suggested that the RESET handler should always explicitly set S to some initial value. That does not necessarily imply that the registers are not zeroed at power-on. Rather, it could be intended for actual program resets later on.
Re: Questions about nestest
by on (#171012)
http://wiki.nesdev.com/w/index.php/CPU_power_up_state
Re: Questions about nestest
by on (#171013)
You can't really predict the code position or the state of the stack when the user presses reset, unless your program is locked in an infinite loop and doesn't use the stack or NMI or IRQ. (Though you could theoretically prepare the stack in such a way that you can trace it on reset, maybe? Not sure if this would have much use though.)

I had assumed that when you said "S is actually initialized to $00" you were referring to the emulator used to produce the log, and not necessarily the hardware behaviour, though. Does the hardware do it? (Sadly this is a beyond-the-powerpak kinda test... Maybe somebody's got a handy cartridge they can flash.)

Edit: Ah, lidnariq just provided a relevant link.