hi there!
i have written a emulator for the 6502 processor, ie all the opcodes and the addressing modes, trouble is i need to test to see if the results i am getting from the functions are all correct (the processor status, flags, x, y reg, program counter etc ). Does anyone have any test cases i can put against my work?
if nobody has such test cases, anything which will let me know where my code is going right and wrong? eg another simulator allowing me to set values, call functions and then see the results, which i can then compare to mine?
any help you guys can give would greatly be appreciated
thanks
testing my 6502 cpu emulator
6502 emulators
8-Bit (one of the more active posters here) built an emulator for one of his SBC projects. I don't have the link handy but I found it through his writeup on the 6502.org site.
Right now, I'm using a windows program called "6502 Macroassembler & Simulator written by Michal Kowalski, his web page is http://www.pacbell.net/michal_k
Also, a search for Apple II emulators will turn up quite a few 6502 emulators.
Right now, I'm using a windows program called "6502 Macroassembler & Simulator written by Michal Kowalski, his web page is http://www.pacbell.net/michal_k
Also, a search for Apple II emulators will turn up quite a few 6502 emulators.
I remember running a c64 program that would test all opcodes for correct behavior, but I don't remember what it was called or anything. Searching for 'c64 emulator test suite' returns some results, like http://www.zimmers.net/anonftp/pub/cbm/ ... tors/pc64/ (near bottom). I don't know if it's any useful, I haven't tested it, but maybe you can adapt it, or something like it, to run on your emulator.
hi guys, thanks for your replies,
i have done a few test and compared results with the simulator you guys mentioned, the good news is that all my opcodes return the same results as the simulator (for the moment yes but i still have to test with all addressing modes) with the exception of one - SBC, i get the correct value returned in the accumulator but not in the processor status, the algorithm i am using is as follows:
IF (P.D) //decimal mode
t = bcd(A) - bcd(M) - ~P.C
P.V = (t>99 OR t<0) ? 1:0
ELSE
t = A - M - ~P.C
P.V = (t>127 OR t<-128) ? 1:0 // i get an overflow but simulator does not
P.C = (t>=0) ? 1:0 // i get a carry simulator does not
P.N = t.7 // this is fine
P.Z = (t==0) ? 1:0 // this is fine
A = t & 0xFF //this is fine
the values i plug in are as follows:
accumulator = 16;
processor_stat = 32;
the results i get :
accumulator = 225; //overflow was set and carry
processor_stat = 241;
result from simulator:
accumulator = 160; //negative flag was set
processor_stat = 241
if any of you guys can shed some light as to why its going wrong (i spent hours on it couldnt understand why) i would really appreciate it, i have come too far to give up on my work!
i have done a few test and compared results with the simulator you guys mentioned, the good news is that all my opcodes return the same results as the simulator (for the moment yes but i still have to test with all addressing modes) with the exception of one - SBC, i get the correct value returned in the accumulator but not in the processor status, the algorithm i am using is as follows:
IF (P.D) //decimal mode
t = bcd(A) - bcd(M) - ~P.C
P.V = (t>99 OR t<0) ? 1:0
ELSE
t = A - M - ~P.C
P.V = (t>127 OR t<-128) ? 1:0 // i get an overflow but simulator does not
P.C = (t>=0) ? 1:0 // i get a carry simulator does not
P.N = t.7 // this is fine
P.Z = (t==0) ? 1:0 // this is fine
A = t & 0xFF //this is fine
the values i plug in are as follows:
accumulator = 16;
processor_stat = 32;
the results i get :
accumulator = 225; //overflow was set and carry
processor_stat = 241;
result from simulator:
accumulator = 160; //negative flag was set
processor_stat = 241
if any of you guys can shed some light as to why its going wrong (i spent hours on it couldnt understand why) i would really appreciate it, i have come too far to give up on my work!
bruce_lee wrote:
the results i get :
accumulator = 225; //overflow was set and carry
processor_stat = 241;
result from simulator:
accumulator = 160; //negative flag was set
processor_stat = 241
accumulator = 225; //overflow was set and carry
processor_stat = 241;
result from simulator:
accumulator = 160; //negative flag was set
processor_stat = 241
A register = 16, M variable = 225, d flag = 0, c flag = 0
the result should be:
A register = 241, n flag = 1, v flag = 0, z flag = 0, c flag = 0
The logic of what you are doing appears to be correct, but you have to pay careful attention to the width of t, the width of the subtraction operation, whether A and M are being sign extended, and whether the comparisons are signed or unsigned.
One thing that would give the behavior that you see is if t were declared as an unsigned variable. All unsigned values are greater than 0 so the t>=0 comparison would always be true. The t>127 OR t<-128 comparsions, for a 16-bit variable (e.g.) would be equivalent to the comparison unsigned comparsion (t > 127 AND t <= 65535) OR (t >= 0 AND t < 65536-128), which is always true.
Remember, the C flag is based on unsigned subtraction, and the V flag is based on signed subtraction. Here's one (untested) way of doing it (for the d flag = 0 case):
Code: Select all
// Inputs:
//
// A: 8-bit integer
// C: 0 or 1
// M: 8-bit integer
//
// Outputs:
//
// A: 8-bit integer
// C: 0 or 1
// N: 0 or 1
// V: 0 or 1
// Z: 0 or 1
//
// Local variables:
//
// a16: signed 16-bit integer
// m16: signed 16-bit integer
// t: signed 16-bit integer
// when d flag is zero
// signed subtraction
a16 = A
m16 = M
a16 = (a16 & 0x7F) // ensure that 0 <= a16 <= 127
m16 = (m16 & 0x7F) // ensure that 0 <= m16 <= 127
a16 = a16 - (((A & 0x80) == 0) ? 0 : 128) // ensure that -128 <= a16 <= 127
m16 = m16 - (((M & 0x80) == 0) ? 0 : 128) // ensure that -128 <= m16 <= 127
t = a16 - m16 - C
V = (t >= -128 AND t <= 127) ? 0 : 1
// unsigned subtraction
a16 = A
m16 = M
a16 = (a16 & 0x00FF) // ensure that 0 <= a16 <= 255
m16 = (m16 & 0x00FF) // ensure that 0 <= a16 <= 255
t = a16 - m16 - C
A = (t & 0x00FF)
C = (t < 0) ? 0 : 1
N = ((t & 0x0080) == 0) ? 0 : 1
Z = ((t & 0x00FF) == 0) ? 0 : 1
SBC #NUMBER
gives exactly the same results (A register, and N, V, Z, and C flags) as:
ADC #255-NUMBER
assuming that, upon entry, the D flag was 0, and the same value of the A register and C flag were used in each case.