6502 CPU Emulation
Asked Answered
D

7

21

It's the weekend, so I relax from spending all week programming by writing a hobby project.

I wrote the framework of a MOS 6502 CPU emulator yesterday, the registers, stack, memory and all the opcodes are implemented. (Link to source below)

I can manually run a series of operations in the debugger I wrote, but I'd like to load a NES rom and just point the program counter at its instructions, I figured that this would be the fastest way to find flawed opcodes.

I wrote a quick NES rom loader and loaded the ROM banks into the CPU memory.

The problem is that I don't know how the opcodes are encoded. I know that the opcodes themselves follow a pattern of one byte per opcode that uniquely identifies the opcode,

0 - BRK
1 - ORA (D,X)
2 - COP b

etc

However I'm not sure where I'm supposed to find the opcode argument. Is it the the byte directly following? In absolute memory, I suppose it might not be a byte but a short.

Is anyone familiar with this CPU's memory model?

EDIT: I realize that this is probably shot in the dark, but I was hoping there were some oldschool Apple and Commodore hackers lurking here.

EDIT: Thanks for your help everyone. After I implemented the proper changes to align each operation the CPU can load and run Mario Brothers. It doesn't do anything but loop waiting for Start, but its a good sign :)

I uploaded the source:

https://archive.codeplex.com/?p=cpu6502

If anyone has ever wondered how an emulator works, its pretty easy to follow. Not optimized in the least, but then again, I'm emulating a CPU that runs at 2mhz on a 2.4ghz machine :)

Diffractometer answered 21/9, 2008 at 18:50 Comment(1)
Hey I'm pretty much in your same situation (at the time of the posting) I'd like to check at your code, but the link seems broken. Do you still have it?Penury
N
13

The opcode takes one byte, and the operands are in the following bytes. Check out the byte size column here, for instance.

Nutting answered 21/9, 2008 at 18:59 Comment(2)
So, I'll have to modify each opcode so it knows how far to look ahead from the PC to get its arguments?Diffractometer
You'll have to keep a table somewhere, yeah. Though it'll never be more than three bytes. Or just hardwire it in the code that does each instruction's work.Nutting
P
4

If you look into references like http://www.atarimax.com/jindroush.atari.org/aopc.html, you will see that each opcode has an encoding specified as:

HEX LEN TIM

The HEX is your 1-byte opcode. Immediately following it is LEN bytes of its argument. Consult the reference to see what those arguments are. The TIM data is important for emulators - it is the number of clock cycles this instruction takes to execute. You will need this to get your timing correct.

These values (LEN, TIM) are not encoded in the opcode itself. You need to store this data in your program loader/executer. It's just a big lookup table. Or you can define a mini-language to encode the data and reader.

Paris answered 21/9, 2008 at 19:3 Comment(2)
I don't think the LEN and TIM are actually encoded in, I think you have to provide that. I already did that with the timing, each opcode is aware of how many cycles its "supposed" to take.Diffractometer
They actually are in many cases. For all the opcodes with an argument bits [4:2] of the opcode define a 3 bit encoding of the addressing mode. I've found it to be consistent: 0=INDIRECT X, 1=ZERO PAGE, 2=IMMEDIATE (sometimes ACCUMULATOR), 3=ABSOLUTE, 4=INDIRECT Y, 5=ZERO PAGE X, 6=ABSOLUTE Y, 7=ABSOLUTE XDingbat
B
1

This book might help: http://www.atariarchives.org/mlb/

Also, try examing any other 6502 aseembler/simulator/debugger out there to see how Assembly gets coded as Machine Language.

Baerman answered 21/9, 2008 at 18:57 Comment(0)
W
1

The 6502 manuals are on the Web, at various history sites. The KIM-1 shipped with them. Maybe more in them than you need to know.

Worden answered 21/9, 2008 at 19:9 Comment(0)
H
1

This is better - 6502 Instruction Set matrix:

https://www.masswerk.at/6502/6502_instruction_set.html

Hydrolyte answered 20/3, 2019 at 15:35 Comment(0)
C
0

The apple II roms included a dissassembler, I think that's what it was called, and it would show you in a nice format the hex opcodes and the 3 character opcode and the operands.

So given how little memory was available, they managed to shove in the operand byte count (always 0, 1 or 2) the 3 character opcode for the entire 6502 instruction set into a really small space, because there's really not that much of it.

If you can dig up an apple II rom, you can just cut and paste from there...

Comber answered 4/2, 2009 at 23:33 Comment(0)
N
0

The 6502 has different addressing modes, the same instruction has several different opcodes depending on it's addressing mode. Take a look at the following links which describes the different ways a 6502 can retrieve data from memory, or directly out of ROM.

http://obelisk.me.uk/6502/addressing.html#IMM

Nigh answered 18/3, 2018 at 15:21 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.