diff --git a/src/65c02isa.csv b/src/65c02isa.csv index 07ef7dc..b57f2df 100644 --- a/src/65c02isa.csv +++ b/src/65c02isa.csv @@ -192,35 +192,35 @@ OP_LDA_ABSX,"lda",ABSOLUTEX,3,emul_lda,false OP_LDX_ABSY,"ldx",ABSOLUTEY,3,emul_ldx,false OP_BBS3_REL,"bbs3",ZPR,2,NULL,true OP_CPY_IMM,"cpy",IMMEDIATE,2,NULL,false -OP_CMP_IZPX,"cmp",IZPX,2,NULL,false +OP_CMP_IZPX,"cmp",IZPX,2,emul_cmp,false OP_NOPI_C3,"nop",IMMEDIATE,2,NULL,false OP_NOPI_C4,"nop",IMPLIED,1,NULL,false OP_CPY_ZP,"cpy",ZP,2,NULL,false -OP_CMP_ZP,"cmp",ZP,2,NULL,false +OP_CMP_ZP,"cmp",ZP,2,emul_cmp,false OP_DEC_ZP,"dec",ZP,2,emul_dec,false OP_SMB4_ZP,"smb4",ZP,2,NULL,false OP_INY,"iny",IMPLIED,1,emul_iny,false -OP_CMP_IMM,"cmp",IMMEDIATE,2,NULL,false +OP_CMP_IMM,"cmp",IMMEDIATE,2,emul_cmp,false OP_DEX,"dex",IMPLIED,1,emul_dex,false OP_WAI,"wai",IMPLIED,1,NULL,false OP_CPY_ABS,"cpy",ABSOLUTE,3,NULL,false -OP_CMP_ABS,"cmp",ABSOLUTE,3,NULL,false +OP_CMP_ABS,"cmp",ABSOLUTE,3,emul_cmp,false OP_DEC_ABS,"dec",ABSOLUTE,3,emul_dec,false OP_BBS4_REL,"bbs4",ZPR,2,NULL,true OP_BNE_REL,"bne",RELATIVE,2,NULL,true -OP_CMP_IZPY,"cmp",IZPY,2,NULL,false -OP_CMP_IZP,"cmp",IZP,2,NULL,false +OP_CMP_IZPY,"cmp",IZPY,2,emul_cmp,false +OP_CMP_IZP,"cmp",IZP,2,emul_cmp,false OP_NOPI_D4,"nop",IMPLIED,1,NULL,false OP_NOPI_D5,"nop",ZPX,2,NULL,false -OP_CMP_ZPX,"cmp",ZPX,2,NULL,false +OP_CMP_ZPX,"cmp",ZPX,2,emul_cmp,false OP_DEC_ZPX,"dec",ZPX,2,emul_dec,false OP_SMB5_ZP,"smb5",ZP,2,NULL,false OP_CLD,"cld",IMPLIED,1,NULL,false -OP_CMP_ABSY,"cmp",ABSOLUTEY,3,NULL,false +OP_CMP_ABSY,"cmp",ABSOLUTEY,3,emul_cmp,false OP_PHX,"phx",IMPLIED,1,emul_phx,false OP_STP,"stp",IMPLIED,1,emul_stp,false OP_NOPI_DD,"nop",ABSOLUTE,3,NULL,false -OP_CMP_ABSX,"cmp",ABSOLUTEX,3,NULL,false +OP_CMP_ABSX,"cmp",ABSOLUTEX,3,emul_cmp,false OP_DEC_ABSX,"dec",ABSOLUTEX,3,emul_dec,false OP_BBS5_REL,"bbs5",ZPR,2,NULL,true OP_CPX_IMM,"cpx",IMMEDIATE,2,NULL,false diff --git a/src/emulation.c b/src/emulation.c index 04c3cd7..56c77a0 100644 --- a/src/emulation.c +++ b/src/emulation.c @@ -86,6 +86,24 @@ emul_clv(rk65c02emu_t *e, void *id, instruction_t *i) e->regs.P &= ~P_SIGN_OVERFLOW; } +/* CMP - compare accumulator and memory location */ +void +emul_cmp(rk65c02emu_t *e, void *id, instruction_t *i) +{ + uint8_t val, sr; + + val = instruction_data_read_1(e, (instrdef_t *) id, i); + sr = e->regs.A - val; + + instruction_status_adjust_zero(e, sr); + instruction_status_adjust_negative(e, sr); + + if (e->regs.A < val) + e->regs.P |= P_CARRY; + else + e->regs.P &= ~P_CARRY; +} + /* DEC - decrement memory location/acumulator */ void emul_dec(rk65c02emu_t *e, void *id, instruction_t *i) diff --git a/src/instruction.c b/src/instruction.c index 1a70512..defa70e 100644 --- a/src/instruction.c +++ b/src/instruction.c @@ -233,7 +233,6 @@ uint8_t instruction_data_read_1(rk65c02emu_t *e, instrdef_t *id, instruction_t *i) { uint8_t rv; /* data read from the bus */ -// uint8_t ziaddr; /* indirect zero page address */ uint16_t iaddr; /* indirect address */ rv = 0; diff --git a/test/test_emulation.c b/test/test_emulation.c index 5775f66..154c1f9 100644 --- a/test/test_emulation.c +++ b/test/test_emulation.c @@ -57,6 +57,108 @@ ATF_TC_BODY(emul_bit, tc) bus_finish(&b); } +ATF_TC_WITHOUT_HEAD(emul_cmp); +ATF_TC_BODY(emul_cmp, tc) +{ + rk65c02emu_t e; + bus_t b; + + b = bus_init(); + e = rk65c02_init(&b); + + /* CMP immediate */ + e.regs.A = 0xAA; + rk65c02_dump_regs(&e); + ATF_REQUIRE(rom_start(&e, "test_emulation_cmp_imm.rom", tc)); + rk65c02_dump_regs(&e); + ATF_CHECK(e.regs.P & P_ZERO); + ATF_CHECK(!(e.regs.P & P_CARRY)); + ATF_CHECK(!(e.regs.P & P_NEGATIVE)); + /* CMP zero page */ + e.regs.A = 0xAA; + bus_write_1(&b, 0x10, 0xAB); + rk65c02_dump_regs(&e); + ATF_REQUIRE(rom_start(&e, "test_emulation_cmp_zp.rom", tc)); + rk65c02_dump_regs(&e); + ATF_CHECK(!(e.regs.P & P_ZERO)); + ATF_CHECK(e.regs.P & P_CARRY); + ATF_CHECK(e.regs.P & P_NEGATIVE); + /* CMP zero page X */ + e.regs.A = 0xAA; + e.regs.X = 0x1; + bus_write_1(&b, 0x11, 0xA0); + rk65c02_dump_regs(&e); + ATF_REQUIRE(rom_start(&e, "test_emulation_cmp_zpx.rom", tc)); + rk65c02_dump_regs(&e); + ATF_CHECK(!(e.regs.P & P_ZERO)); + ATF_CHECK(!(e.regs.P & P_CARRY)); + ATF_CHECK(!(e.regs.P & P_NEGATIVE)); + /* CMP indirect zero page */ + e.regs.A = 0x01; + bus_write_1(&b, 0x20, 0x0); + bus_write_1(&b, 0x21, 0x20); + bus_write_1(&b, 0x2000, 0xFF); + rk65c02_dump_regs(&e); + ATF_REQUIRE(rom_start(&e, "test_emulation_cmp_izp.rom", tc)); + rk65c02_dump_regs(&e); + ATF_CHECK(!(e.regs.P & P_ZERO)); + ATF_CHECK(e.regs.P & P_CARRY); + ATF_CHECK(!(e.regs.P & P_NEGATIVE)); + /* CMP indirect zero page X */ + e.regs.A = 0x02; + e.regs.X = 0x02; + bus_write_1(&b, 0x22, 0x0); + bus_write_1(&b, 0x23, 0x20); + bus_write_1(&b, 0x2000, 0x3); + rk65c02_dump_regs(&e); + ATF_REQUIRE(rom_start(&e, "test_emulation_cmp_izpx.rom", tc)); + rk65c02_dump_regs(&e); + ATF_CHECK(!(e.regs.P & P_ZERO)); + ATF_CHECK(e.regs.P & P_CARRY); + ATF_CHECK(e.regs.P & P_NEGATIVE); + /* CMP indirect zero page Y */ + e.regs.A = 0x10; + e.regs.Y = 0x01; + bus_write_1(&b, 0x22, 0x0); + bus_write_1(&b, 0x23, 0x20); + bus_write_1(&b, 0x2000, 0xF); + rk65c02_dump_regs(&e); + ATF_REQUIRE(rom_start(&e, "test_emulation_cmp_izpy.rom", tc)); + rk65c02_dump_regs(&e); + ATF_CHECK(e.regs.P & P_ZERO); + ATF_CHECK(!(e.regs.P & P_CARRY)); + ATF_CHECK(!(e.regs.P & P_NEGATIVE)); + /* CMP absolute */ + e.regs.A = 0xFF; + bus_write_1(&b, 0x2010, 0xFE); + rk65c02_dump_regs(&e); + ATF_REQUIRE(rom_start(&e, "test_emulation_cmp_abs.rom", tc)); + rk65c02_dump_regs(&e); + ATF_CHECK(!(e.regs.P & P_ZERO)); + ATF_CHECK(!(e.regs.P & P_CARRY)); + ATF_CHECK(!(e.regs.P & P_NEGATIVE)); + /* CMP absolute X */ + e.regs.A = 0x55; + e.regs.X = 0x2; + bus_write_1(&b, 0x2012, 0x55); + rk65c02_dump_regs(&e); + ATF_REQUIRE(rom_start(&e, "test_emulation_cmp_absx.rom", tc)); + rk65c02_dump_regs(&e); + ATF_CHECK(e.regs.P & P_ZERO); + ATF_CHECK(!(e.regs.P & P_CARRY)); + ATF_CHECK(!(e.regs.P & P_NEGATIVE)); + /* CMP absolute Y */ + e.regs.A = 0xAA; + e.regs.Y = 0x50; + bus_write_1(&b, 0x2065, 0x55); + rk65c02_dump_regs(&e); + ATF_REQUIRE(rom_start(&e, "test_emulation_cmp_absy.rom", tc)); + rk65c02_dump_regs(&e); + ATF_CHECK(!(e.regs.P & P_ZERO)); + ATF_CHECK(!(e.regs.P & P_CARRY)); + ATF_CHECK(e.regs.P & P_NEGATIVE); +} + ATF_TC_WITHOUT_HEAD(emul_dex_dey); ATF_TC_BODY(emul_dex_dey, tc) { @@ -698,6 +800,7 @@ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, emul_and); ATF_TP_ADD_TC(tp, emul_bit); + ATF_TP_ADD_TC(tp, emul_cmp); ATF_TP_ADD_TC(tp, emul_dec); ATF_TP_ADD_TC(tp, emul_dex_dey); ATF_TP_ADD_TC(tp, emul_clc_sec); diff --git a/test/test_emulation_cmp_abs.s b/test/test_emulation_cmp_abs.s new file mode 100644 index 0000000..903be3f --- /dev/null +++ b/test/test_emulation_cmp_abs.s @@ -0,0 +1,3 @@ +start: cmp 0x2010 + stp + diff --git a/test/test_emulation_cmp_absx.s b/test/test_emulation_cmp_absx.s new file mode 100644 index 0000000..f7a2e68 --- /dev/null +++ b/test/test_emulation_cmp_absx.s @@ -0,0 +1,3 @@ +start: cmp 0x2010,X + stp + diff --git a/test/test_emulation_cmp_absy.s b/test/test_emulation_cmp_absy.s new file mode 100644 index 0000000..89301a3 --- /dev/null +++ b/test/test_emulation_cmp_absy.s @@ -0,0 +1,3 @@ +start: cmp 0x2010,Y + stp + diff --git a/test/test_emulation_cmp_imm.s b/test/test_emulation_cmp_imm.s new file mode 100644 index 0000000..49e1841 --- /dev/null +++ b/test/test_emulation_cmp_imm.s @@ -0,0 +1,3 @@ +start: cmp #0xAA + stp + diff --git a/test/test_emulation_cmp_izp.s b/test/test_emulation_cmp_izp.s new file mode 100644 index 0000000..40b25c0 --- /dev/null +++ b/test/test_emulation_cmp_izp.s @@ -0,0 +1,3 @@ +start: cmp (0x20) + stp + diff --git a/test/test_emulation_cmp_izpx.s b/test/test_emulation_cmp_izpx.s new file mode 100644 index 0000000..d594457 --- /dev/null +++ b/test/test_emulation_cmp_izpx.s @@ -0,0 +1,3 @@ +start: cmp (0x20,X) + stp + diff --git a/test/test_emulation_cmp_izpy.s b/test/test_emulation_cmp_izpy.s new file mode 100644 index 0000000..bcfd0a3 --- /dev/null +++ b/test/test_emulation_cmp_izpy.s @@ -0,0 +1,3 @@ +start: cmp (0x20),Y + stp + diff --git a/test/test_emulation_cmp_zp.s b/test/test_emulation_cmp_zp.s new file mode 100644 index 0000000..6efde1e --- /dev/null +++ b/test/test_emulation_cmp_zp.s @@ -0,0 +1,3 @@ +start: cmp 0x10 + stp + diff --git a/test/test_emulation_cmp_zpx.s b/test/test_emulation_cmp_zpx.s new file mode 100644 index 0000000..29ca8a5 --- /dev/null +++ b/test/test_emulation_cmp_zpx.s @@ -0,0 +1,2 @@ +start: cmp 0x10,X + stp