diff --git a/src/65c02isa.csv b/src/65c02isa.csv index af8f108..c602e34 100644 --- a/src/65c02isa.csv +++ b/src/65c02isa.csv @@ -35,7 +35,7 @@ OP_JSR,"jsr",ABSOLUTE,3,NULL OP_AND_IZPX,"and",IZPX,2,emul_and OP_NOPI_23,"nop",IMMEDIATE,2,NULL OP_NOPI_24,"nop",IMPLIED,1,NULL -OP_BIT_ZP,"bit",ZP,2,NULL +OP_BIT_ZP,"bit",ZP,2,emul_bit OP_AND_ZP,"and",ZP,2,emul_and OP_ROL_ZP,"rol",ZP,2,emul_rol OP_RMB2_ZP,"rmb2",ZP,2,NULL @@ -43,7 +43,7 @@ OP_PLP,"plp",IMPLIED,1,emul_plp OP_AND_IMM,"and",IMMEDIATE,2,emul_and OP_ROL,"rol",ACCUMULATOR,1,emul_rol OP_NOPI_2C,"nop",IMPLIED,1,NULL -OP_BIT_ABS,"bit",ABSOLUTE,3,NULL +OP_BIT_ABS,"bit",ABSOLUTE,3,emul_bit OP_AND_ABS,"and",ABSOLUTE,3,emul_and OP_ROL_ABS,"rol",ABSOLUTE,3,emul_rol OP_BBR2_REL,"bbr2",ZPR,2,NULL @@ -51,7 +51,7 @@ OP_BMI_REL,"bmi",RELATIVE,2,NULL OP_AND_IZPY,"and",IZPY,2,emul_and OP_AND_IZP,"and",IZP,2,emul_and OP_NOPI_34,"nop",IMPLIED,1,NULL -OP_BIT_ZPX,"bit",ZPX,2,NULL +OP_BIT_ZPX,"bit",ZPX,2,emul_bit OP_AND_ZPX,"and",ZPX,2,emul_and OP_ROL_ZPX,"rol",ZPX,2,emul_rol OP_RMB3_ZP,"rmb3",ZP,2,NULL @@ -59,7 +59,7 @@ OP_SEC,"sec",IMPLIED,1,emul_sec OP_AND_ABSY,"and",ABSOLUTEY,3,emul_and OP_DEC,"dec",ACCUMULATOR,1,NULL OP_NOPI_3C,"nop",IMPLIED,1,NULL -OP_BIT_ABSX,"bit",ABSOLUTEX,3,NULL +OP_BIT_ABSX,"bit",ABSOLUTEX,3,emul_bit OP_AND_ABSX,"and",ABSOLUTEX,3,emul_and OP_ROL_ABSX,"rol",ABSOLUTEX,3,emul_rol OP_BBR3_REL,"bbr3",ZPR,2,NULL @@ -136,7 +136,7 @@ OP_STA_ZP,"sta",ZP,2,emul_sta OP_STX_ZP,"stx",ZP,2,emul_stx OP_SMB0_ZP,"smb0",ZP,2,NULL OP_DEY,"dey",IMPLIED,1,emul_dey -OP_BIT_IMM,"bit",IMMEDIATE,2,NULL +OP_BIT_IMM,"bit",IMMEDIATE,2,emul_bit OP_TXA,"txa",IMPLIED,1,emul_txa OP_NOPI_8C,"nop",IMPLIED,1,NULL OP_STY_ABS,"sty",ABSOLUTE,3,emul_sty diff --git a/src/emulation.c b/src/emulation.c index 3f2fb37..5d70c81 100644 --- a/src/emulation.c +++ b/src/emulation.c @@ -12,6 +12,30 @@ emul_and(rk65c02emu_t *e, void *id, instruction_t *i) instruction_status_adjust_negative(e, e->regs.A); } +/* BIT - check if one or more bits are set */ +void +emul_bit(rk65c02emu_t *e, void *id, instruction_t *i) +{ +/* uint8_t v = instruction_data_read_1(e, (instrdef_t *) id, i); + printf("%x\n", v);*/ + + /* zero flag set if acculumator AND memory equals zero */ + if (e->regs.A & instruction_data_read_1(e, (instrdef_t *) id, i)) + e->regs.P &= ~P_ZERO; + else + e->regs.P |= P_ZERO; + + if (BIT(instruction_data_read_1(e, (instrdef_t *) id, i), 6)) + e->regs.P |= P_SIGN_OVERFLOW; + else + e->regs.P &= ~P_SIGN_OVERFLOW; + + if (BIT(instruction_data_read_1(e, (instrdef_t *) id, i), 7)) + e->regs.P |= P_NEGATIVE; + else + e->regs.P &= ~P_NEGATIVE; +} + /* CLC - clear carry flag */ void emul_clc(rk65c02emu_t *e, void *id, instruction_t *i) diff --git a/test/test_emulation.c b/test/test_emulation.c index 18c6f15..696e31d 100644 --- a/test/test_emulation.c +++ b/test/test_emulation.c @@ -22,6 +22,55 @@ rom_start(rk65c02emu_t *e, const char *name) return true; } +ATF_TC_WITHOUT_HEAD(emul_bit); +ATF_TC_BODY(emul_bit, tc) +{ + rk65c02emu_t e; + bus_t b; + + b = bus_init(); + e = rk65c02_init(&b); + + /* BIT immediate */ + e.regs.A = 0x40; + ATF_REQUIRE(rom_start(&e, "test_emulation_bit_imm.rom")); + ATF_CHECK(!(e.regs.P & P_ZERO)); + ATF_CHECK(e.regs.P & P_SIGN_OVERFLOW); + ATF_CHECK(!(e.regs.P & P_NEGATIVE)); + /* BIT zero page */ + e.regs.A = 0x40; + bus_write_1(&b, 0x10, 0x80); + ATF_REQUIRE(rom_start(&e, "test_emulation_bit_zp.rom")); + ATF_CHECK(e.regs.P & P_ZERO); + ATF_CHECK(!(e.regs.P & P_SIGN_OVERFLOW)); + ATF_CHECK(e.regs.P & P_NEGATIVE); + /* BIT zero page X */ + e.regs.A = 0x40; + e.regs.X = 0x1; + bus_write_1(&b, 0x10, 0x40); + ATF_REQUIRE(rom_start(&e, "test_emulation_bit_zpx.rom")); + ATF_CHECK(!(e.regs.P & P_ZERO)); + ATF_CHECK(e.regs.P & P_SIGN_OVERFLOW); + ATF_CHECK(!(e.regs.P & P_NEGATIVE)); + /* BIT absolute */ + e.regs.A = 0x80; + bus_write_1(&b, 0x2010, 0x80); + ATF_REQUIRE(rom_start(&e, "test_emulation_bit_abs.rom")); + ATF_CHECK(!(e.regs.P & P_ZERO)); + ATF_CHECK(!(e.regs.P & P_SIGN_OVERFLOW)); + ATF_CHECK(e.regs.P & P_NEGATIVE); + /* BIT absolute X */ + e.regs.A = 0x40; + e.regs.X = 0x2; + bus_write_1(&b, 0x2010, 0x80); + ATF_REQUIRE(rom_start(&e, "test_emulation_bit_absx.rom")); + ATF_CHECK(e.regs.P & P_ZERO); + ATF_CHECK(!(e.regs.P & P_SIGN_OVERFLOW)); + ATF_CHECK(e.regs.P & P_NEGATIVE); + + bus_finish(&b); +} + ATF_TC_WITHOUT_HEAD(emul_dex_dey); ATF_TC_BODY(emul_dex_dey, tc) { @@ -424,6 +473,7 @@ ATF_TC_BODY(emul_php_plp, tc) 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_dex_dey); ATF_TP_ADD_TC(tp, emul_clc_sec); ATF_TP_ADD_TC(tp, emul_inx_iny); diff --git a/test/test_emulation_bit_abs.s b/test/test_emulation_bit_abs.s new file mode 100644 index 0000000..39ea483 --- /dev/null +++ b/test/test_emulation_bit_abs.s @@ -0,0 +1,3 @@ +start: bit 0x2010 + stp + diff --git a/test/test_emulation_bit_absx.s b/test/test_emulation_bit_absx.s new file mode 100644 index 0000000..138971c --- /dev/null +++ b/test/test_emulation_bit_absx.s @@ -0,0 +1,3 @@ +start: bit 0x200E,X + stp + diff --git a/test/test_emulation_bit_imm.s b/test/test_emulation_bit_imm.s new file mode 100644 index 0000000..f2f0d77 --- /dev/null +++ b/test/test_emulation_bit_imm.s @@ -0,0 +1,3 @@ +start: bit #0x55 + stp + diff --git a/test/test_emulation_bit_zp.s b/test/test_emulation_bit_zp.s new file mode 100644 index 0000000..6781a30 --- /dev/null +++ b/test/test_emulation_bit_zp.s @@ -0,0 +1,3 @@ +start: bit 0x10 + stp + diff --git a/test/test_emulation_bit_zpx.s b/test/test_emulation_bit_zpx.s new file mode 100644 index 0000000..83409cc --- /dev/null +++ b/test/test_emulation_bit_zpx.s @@ -0,0 +1,3 @@ +start: bit 0xF,X + stp +