I've been working on the CPU emulation for the past few weeks and finally got all of the instructions excuting right. Now I need to go back and add the cycles into the core. Just a few questions:
1. What does cycle counting do exactly? Is supposed to be keeping track of time or are they just arbitary numbers used by the system? Originally I had thought that cycle counting was keeping track of time, but now I'm not so sure.
2. What does page crossing mean? Some instructions add cycles if a page is crossed.
On an unrelated side note, what does P: and SL: stand for in the nestest log?
Thanks everyone
1. It's a way to keep track of "time", i.e. 29780 2/3 CPU cycles per PPU frame, but more so it's a way to keep the CPU, PPU, and APU in sync. Cycles are easily handled by only incrementing them on CPU reads and writes (if desired you can run the PPU to catch up at this time).
2. Page crossing means the high byte of an address doesn't match the high byte of another. Some instructions fix the address before completely decoding it.
http://nesdev.com/6502_cpu.txt will give the scenarios when it occurs.
P is the processor status flag register and SL is the PPU scanline. Note that the nestest "golden" log OR's the status flags with 0x20.
CYC actually represents PPU dots, and the PPU outputs three dots for each CPU cycle (unless you're emulating a PAL NES, in which case it outputs an extra dot every fifth CPU cycle). For example, LDA absolute takes four cycles according to your 6502 book, but it takes 12 CYC according to a Nintendulator execution log. As sub_par pointed out, SL refers to scanlines, and each SL is worth 341 CYC.
Why worry about CYC? A lot of games use what are called raster effects, writing values to PPU ports in the middle of the frame to change the appearance of portions of the picture, usually horizontal strips. These range from drawing a status bar (Super Mario Bros.) to warping a road (Rad Racer) to effects in the middle of a scanline (Marble Madness, Pirates!, Final Fantasy). Because the PPU provides very little feedback as to how far down the frame it has rendered, NES games are programmed on the assumption that once the CPU has executed enough cycles to make 341 dots, one scanline has completed. This requires emulators to have "cycle accuracy" if they ever hope of running something like Battletoads.
So should I made a public variable in my cpu class that holds the number of cycles and have it reset once a scanline is done? Or should I be storing the cycles somewhere else?
On a side note, does anyone know how to compare my output with the nestest.log output when the two aren't the exact same? My debug file is similar to the nestest.log file, but it's not exact, so I can't use the usual comparison website that I would use. So far I've been trying to compare output by hand and it's really tedious.
Dartht33bagger wrote:
On a side note, does anyone know how to compare my output with the nestest.log output when the two aren't the exact same? My debug file is similar to the nestest.log file, but it's not exact, so I can't use the usual comparison website that I would use. So far I've been trying to compare output by hand and it's really tedious.
Well, make your output exact then.
What I did was make a short program that parses nestest.log and keeps only PC, A, X, Y, P, S, and CYC. This made it easier for my CPU simulator to spit out a stream in the same format.
Are you writing a NES emulator or just a 6502 emulator? Thanks.
I'm writing a NES emulator. I finished the core and passed all of the nestest up until the illegal opcodes came in (I didn't implement those because I assumed they don't matter for commercial games?).
There are a few unreleased, unlicensed and homebrew games that use illegal opcodes. Puzznic I believe uses the multi byte NOP, and the sound engine used for Driar and Streemerz from the last homebrew competition depends on the LAX and SAX opcode and also a certain trick with the APU sweep units.