I have written a barebones 6502 emulator. The ultimate goal is to write an NES emulator. My 6502 emulator follows the basic fetch execute cycle and all of the opcodes have been implemented. What should my next focus be for working towards creating this emulator?

Does your emulator's CPU match the known-good log of nestest cycle-for-cycle? (See Emulator tests on the wiki.) Make sure each instruction takes the same number of cycles (on NTSC there are three PPU cycles in a CPU cycle, 341 PPU cycles in a scanline, and 262 scanlines in a frame) and produces the same stream of program counter values, and find the first instruction at which they diverge.

Once it does, the next thing to emulate is vertical blank timing. At the start of line 241, bit 7 of $2002 (Vblank flag) becomes 1. It becomes 0 at the start of line 261 or when $2002 is read, whichever comes first. If bit 7 of $2002 rises (goes from 0 to 1) while bit 7 of $2000 (NMI) is turned on, call the NMI handler. Once your CPU is correct, emulating bit 7 of $2000, bit 7 of $2002, and NMI should be enough to get games like Donkey Kong and Mario Bros. to start trying to boot.

The emulator hasn't been tested against the official instructions so I'll probably start working on that next. I see that the files to test with come in .nes format. I'm assuming I just read this file into my emulators memory at the beginning and let her run, correct?

Throwing the entire contents of a NES file at memory address 0000 will never work.

You need to get the NES memory map correct, and understand the very basics of the iNES file format.16 byte header, then PRG data, then CHR data.Throwing the PRG data into address 8000 (for 32K PRG) or C000 (for 16K PRG) might work here.

I have not tested it against any code. It sounds like my next steps are to test this against the suite provided in this thread. Thanks guys, I'll see how that works out and come back with results. What I have done however is create a test function of sorts which validates addressing modes and mnemonic <-> opcode resolution. Basically as a test I fed 0 - 255 as data to the emulator. Could you guys kindly tell me if it looks correct?

Why are $80 and $89 traps? They're 2-byte no-ops, and if you don't emulate them as 2-byte no-ops, you'll break Puzznic and Beauty and the Beast. A lot of the instructions you've listed as "traps" are actually rawther useful. So much so that if you fail to emulate other unofficial instructions, you might break STREEMERZ: Super Strength Emergency Squad Zeta and Driar.

I'm pretty sure tepples that his 6502 emulator at this point is pretty basic and he's not bothering with the illegal ops right now. However, not many of us are prepared to read through 256 lines of that green text to help you out. Hook your CPU up to some basic PPU code and run nestest.nes if you really wanna try it.

I'll go ahead and implement these unofficial opcodes now. They appear to simply be a combination of other opcodes (the items in gray at the link provided by tepples). Is that correct? As for the name "trap"... I just picked something that I thought would describe "illegal opcode" haha. I just pulled it out of the air. What should the proper name be for opcodes that do not exist (Where I have the traps)?

There is no "proper" (official) naming convention for them, and don't let anyone here tell you or make you think otherwise. :-)

I strongly suggest you avoid implementing unofficial opcodes at this time. They should be one of the last things you implement, since your goal as admitted in your first post is to make a NES emulator. You have a lot bigger fish to worry about in the future, trust me -- illegal opcodes are the least of your worries, since only 1 game is known at this time to use them. They should act as "traps" or "suspend emulation" situations, since they indicate broken emulation on your part. Handling them now will do nothing but cause massive confusion when trying to troubleshoot your emulator.

Actually there are about half a dozen games that use unofficial opcodes, listed at the bottom of this page. But otherwise, koitsu is right that unless you're running a test ROM or one of these games, hitting an unofficial opcode means your CPU or mapper emulation is misbehaving.

But there does exist a compromise that does what the user expects. I'd recommend making a switch for pausing on unofficial opcode with these positions:

Always

Once after power cycle

Only on new mappers

Only HLT

For "Only on new mappers", you'd keep track of how stable you think your implementation of each mapper is. It'd act like "Once after each power cycle" until you're certain that a mapper is working correctly. For example, once you think you have most CNROM (#3) games working, you could switch CNROM to "Only HLT" and Puzznic would stop bugging the user.

So aside from working on unofficial opcodees, would you guys say the next step is to run my emu against the nestest suite or begin work on the PPU? I'm not sure if the nestest suite depends on the PPU.

There's part of nestest that requires only a working CPU that can JSR $C000, and part of nestest that also requires a working PPU and controller. The emulator tests page links to a log of the first part running in Nintendulator; if you log A, X, Y, P, S, PC, and elapsed cycles after each instruction, you can compare the value at each instruction to Nintendulator's value and make sure they match. (Hint: 3 CYC units = 1 CPU cycle because CYC counts PPU dots, and CYC is measured mod 341 because that's how long a scanline is.)

Who is online

Users browsing this forum: No registered users and 4 guests

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum