mirror of
https://github.com/rkujawa/rk65c02.git
synced 2024-12-22 15:31:12 +00:00
Implement emulation of ADC, plug the overflow test.
While here fix numerous test cases, lol.
This commit is contained in:
parent
2f076f4a16
commit
faa824e306
@ -96,35 +96,35 @@ OP_EOR_ABSX,"eor",ABSOLUTEX,3,emul_eor,false
|
||||
OP_LSR_ABSX,"lsr",ABSOLUTEX,3,emul_lsr,false
|
||||
OP_BBR5_REL,"bbr5",ZPR,2,emul_bbr5,true
|
||||
OP_RTS,"rts",IMPLIED,1,emul_rts,false
|
||||
OP_ADC_IZPX,"adc",IZPX,2,NULL,false
|
||||
OP_ADC_IZPX,"adc",IZPX,2,emul_adc,false
|
||||
OP_NOPI_63,"nop",IMMEDIATE,2,NULL,false
|
||||
OP_NOPI_64,"nop",IMPLIED,1,NULL,false
|
||||
OP_STZ_ZP,"stz",ZP,2,emul_stz,false
|
||||
OP_ADC_ZP,"adc",ZP,2,NULL,false
|
||||
OP_ADC_ZP,"adc",ZP,2,emul_adc,false
|
||||
OP_ROR_ZP,"ror",ZP,2,emul_ror,false
|
||||
OP_RMB6_ZP,"rmb6",ZP,2,emul_rmb6,false
|
||||
OP_PLA,"pla",IMPLIED,1,emul_pla,false
|
||||
OP_ADC_IMM,"adc",IMMEDIATE,2,NULL,false
|
||||
OP_ADC_IMM,"adc",IMMEDIATE,2,emul_adc,false
|
||||
OP_ROR,"ror",ACCUMULATOR,1,emul_ror,false
|
||||
OP_NOPI_6C,"nop",IMPLIED,1,NULL,false
|
||||
OP_JMP_IABS,"jmp",IABSOLUTE,3,emul_jmp,true
|
||||
OP_ADC_ABS,"adc",ABSOLUTE,3,NULL,false
|
||||
OP_ADC_ABS,"adc",ABSOLUTE,3,emul_adc,false
|
||||
OP_ROR_ABS,"ror",ABSOLUTE,3,emul_ror,false
|
||||
OP_BBR6_REL,"bbr6",ZPR,2,emul_bbr6,true
|
||||
OP_BVS_REL,"bvs",RELATIVE,2,emul_bvs,true
|
||||
OP_ADC_IZPY,"adc",IZPY,2,NULL,false
|
||||
OP_ADC_IZP,"adc",IZP,2,NULL,false
|
||||
OP_ADC_IZPY,"adc",IZPY,2,emul_adc,false
|
||||
OP_ADC_IZP,"adc",IZP,2,emul_adc,false
|
||||
OP_NOPI_74,"nop",IMPLIED,1,NULL,false
|
||||
OP_STZ_ZPX,"stz",ZPX,2,emul_stz,false
|
||||
OP_ADC_ZPX,"adc",ZPX,2,NULL,false
|
||||
OP_ADC_ZPX,"adc",ZPX,2,emul_adc,false
|
||||
OP_ROR_ZPX,"ror",ZPX,2,emul_ror,false
|
||||
OP_RMB7_ZP,"rmb7",ZP,2,emul_rmb7,false
|
||||
OP_SEI,"sei",IMPLIED,1,emul_sei,false
|
||||
OP_ADC_ABSY,"adc",ABSOLUTEY,3,NULL,false
|
||||
OP_ADC_ABSY,"adc",ABSOLUTEY,3,emul_adc,false
|
||||
OP_PLY,"ply",IMPLIED,1,emul_ply,false
|
||||
OP_NOPI_7C,"nop",IMPLIED,1,NULL,false
|
||||
OP_JMP_IABSX,"jmp",IABSOLUTEX,3,emul_jmp,true
|
||||
OP_ADC_ABSX,"adc",ABSOLUTEX,3,NULL,false
|
||||
OP_ADC_ABSX,"adc",ABSOLUTEX,3,emul_adc,false
|
||||
OP_ROR_ABSX,"ror",ABSOLUTEX,3,emul_ror,false
|
||||
OP_BBR7_REL,"bbr7",ZPR,2,emul_bbr7,true
|
||||
OP_BRA_REL,"bra",RELATIVE,2,emul_bra,true
|
||||
@ -215,7 +215,7 @@ OP_NOPI_D5,"nop",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,emul_smb5,false
|
||||
OP_CLD,"cld",IMPLIED,1,NULL,false
|
||||
OP_CLD,"cld",IMPLIED,1,emul_cld,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
|
||||
|
|
@ -11,6 +11,37 @@ void emul_bbs(rk65c02emu_t *, void *, instruction_t *, uint8_t);
|
||||
|
||||
/* Implementation of emulation of instructions follows below */
|
||||
|
||||
/* ADC - add with carry */
|
||||
void
|
||||
emul_adc(rk65c02emu_t *e, void *id, instruction_t *i)
|
||||
{
|
||||
uint8_t arg;
|
||||
uint16_t res; /* meh */
|
||||
|
||||
arg = instruction_data_read_1(e, (instrdef_t *) id, i);
|
||||
res = e->regs.A + arg;
|
||||
|
||||
if (e->regs.P & P_CARRY)
|
||||
res++;
|
||||
|
||||
if ((e->regs.A ^ res) & (arg ^ res) & 0x80)
|
||||
e->regs.P |= P_SIGN_OVERFLOW;
|
||||
else
|
||||
e->regs.P &= ~P_SIGN_OVERFLOW;
|
||||
|
||||
/* if the result does not fit into 8 bits then set carry */
|
||||
if (res > 0xFF)
|
||||
e->regs.P |= P_CARRY;
|
||||
else
|
||||
e->regs.P &= ~P_CARRY;
|
||||
|
||||
/* squash the result into accumulator's 8 bits, lol */
|
||||
e->regs.A = (uint8_t) res;
|
||||
|
||||
instruction_status_adjust_zero(e, e->regs.A);
|
||||
instruction_status_adjust_negative(e, e->regs.A);
|
||||
}
|
||||
|
||||
/* AND - logical AND */
|
||||
void
|
||||
emul_and(rk65c02emu_t *e, void *id, instruction_t *i)
|
||||
@ -294,6 +325,13 @@ emul_clc(rk65c02emu_t *e, void *id, instruction_t *i)
|
||||
e->regs.P &= ~P_CARRY;
|
||||
}
|
||||
|
||||
/* CLD - clear decimal flag */
|
||||
void
|
||||
emul_cld(rk65c02emu_t *e, void *id, instruction_t *i)
|
||||
{
|
||||
e->regs.P &= ~P_DECIMAL;
|
||||
}
|
||||
|
||||
/* CLI - clear interrupt disable flag */
|
||||
void
|
||||
emul_cli(rk65c02emu_t *e, void *id, instruction_t *i)
|
||||
|
@ -844,7 +844,7 @@ ATF_TC_BODY(emul_jmp, tc)
|
||||
rom_path("test_emulation_jmp_abs.rom", tc)));
|
||||
|
||||
rk65c02_step(&e, 3);
|
||||
ATF_CHECK(e.regs.PC = 0xC000);
|
||||
ATF_CHECK(e.regs.PC == 0xC000);
|
||||
|
||||
/* JMP indirect absolute */
|
||||
e.regs.PC = ROM_LOAD_ADDR;
|
||||
@ -855,7 +855,7 @@ ATF_TC_BODY(emul_jmp, tc)
|
||||
bus_write_1(&b, 0x21, 0xC0);
|
||||
|
||||
rk65c02_step(&e, 3);
|
||||
ATF_CHECK(e.regs.PC = 0xC000);
|
||||
ATF_CHECK(e.regs.PC == 0xC000);
|
||||
|
||||
/* JMP indirect absolute X */
|
||||
e.regs.PC = ROM_LOAD_ADDR;
|
||||
@ -867,7 +867,7 @@ ATF_TC_BODY(emul_jmp, tc)
|
||||
bus_write_1(&b, 0x41, 0xC0);
|
||||
|
||||
rk65c02_step(&e, 3);
|
||||
ATF_CHECK(e.regs.PC = 0xC000);
|
||||
ATF_CHECK(e.regs.PC == 0xC000);
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(emul_jsr_rts);
|
||||
@ -885,9 +885,9 @@ ATF_TC_BODY(emul_jsr_rts, tc)
|
||||
rom_path("test_emulation_jsr_rts.rom", tc)));
|
||||
|
||||
rk65c02_step(&e, 2);
|
||||
ATF_CHECK(e.regs.PC = 0xC006);
|
||||
ATF_CHECK(e.regs.PC == 0xC006);
|
||||
rk65c02_start(&e);
|
||||
ATF_CHECK(e.regs.PC = 0xC006);
|
||||
ATF_CHECK(e.regs.PC == 0xC006);
|
||||
|
||||
}
|
||||
|
||||
@ -907,9 +907,9 @@ ATF_TC_BODY(emul_branch, tc)
|
||||
|
||||
e.regs.P &= ~P_CARRY;
|
||||
rk65c02_step(&e, 2);
|
||||
ATF_CHECK(e.regs.PC = 0xC005);
|
||||
ATF_CHECK(e.regs.PC == 0xC005);
|
||||
rk65c02_step(&e, 2);
|
||||
ATF_CHECK(e.regs.PC = 0xC003);
|
||||
ATF_CHECK(e.regs.PC == 0xC003);
|
||||
rk65c02_start(&e);
|
||||
|
||||
/* BCS */
|
||||
@ -919,9 +919,9 @@ ATF_TC_BODY(emul_branch, tc)
|
||||
|
||||
e.regs.P |= P_CARRY;
|
||||
rk65c02_step(&e, 2);
|
||||
ATF_CHECK(e.regs.PC = 0xC005);
|
||||
ATF_CHECK(e.regs.PC == 0xC005);
|
||||
rk65c02_step(&e, 2);
|
||||
ATF_CHECK(e.regs.PC = 0xC003);
|
||||
ATF_CHECK(e.regs.PC == 0xC003);
|
||||
rk65c02_start(&e);
|
||||
|
||||
/* BRA */
|
||||
@ -930,7 +930,7 @@ ATF_TC_BODY(emul_branch, tc)
|
||||
rom_path("test_emulation_bra.rom", tc)));
|
||||
|
||||
rk65c02_step(&e, 1);
|
||||
ATF_CHECK(e.regs.PC = 0xC004);
|
||||
ATF_CHECK(e.regs.PC == 0xC004);
|
||||
rk65c02_start(&e);
|
||||
|
||||
/* BEQ */
|
||||
@ -940,9 +940,9 @@ ATF_TC_BODY(emul_branch, tc)
|
||||
|
||||
e.regs.P |= P_ZERO;
|
||||
rk65c02_step(&e, 2);
|
||||
ATF_CHECK(e.regs.PC = 0xC005);
|
||||
ATF_CHECK(e.regs.PC == 0xC005);
|
||||
rk65c02_step(&e, 2);
|
||||
ATF_CHECK(e.regs.PC = 0xC003);
|
||||
ATF_CHECK(e.regs.PC == 0xC003);
|
||||
rk65c02_start(&e);
|
||||
|
||||
/* BMI */
|
||||
@ -952,9 +952,9 @@ ATF_TC_BODY(emul_branch, tc)
|
||||
|
||||
e.regs.P |= P_NEGATIVE;
|
||||
rk65c02_step(&e, 2);
|
||||
ATF_CHECK(e.regs.PC = 0xC005);
|
||||
ATF_CHECK(e.regs.PC == 0xC005);
|
||||
rk65c02_step(&e, 2);
|
||||
ATF_CHECK(e.regs.PC = 0xC003);
|
||||
ATF_CHECK(e.regs.PC == 0xC003);
|
||||
rk65c02_start(&e);
|
||||
|
||||
/* BNE */
|
||||
@ -962,11 +962,11 @@ ATF_TC_BODY(emul_branch, tc)
|
||||
ATF_REQUIRE(bus_load_file(&b, ROM_LOAD_ADDR,
|
||||
rom_path("test_emulation_bne.rom", tc)));
|
||||
|
||||
e.regs.P |= P_NEGATIVE;
|
||||
e.regs.P &= ~P_ZERO;
|
||||
rk65c02_step(&e, 2);
|
||||
ATF_CHECK(e.regs.PC = 0xC005);
|
||||
ATF_CHECK(e.regs.PC == 0xC005);
|
||||
rk65c02_step(&e, 2);
|
||||
ATF_CHECK(e.regs.PC = 0xC003);
|
||||
ATF_CHECK(e.regs.PC == 0xC003);
|
||||
rk65c02_start(&e);
|
||||
|
||||
/* BPL */
|
||||
@ -976,9 +976,9 @@ ATF_TC_BODY(emul_branch, tc)
|
||||
|
||||
e.regs.P &= ~P_NEGATIVE;
|
||||
rk65c02_step(&e, 2);
|
||||
ATF_CHECK(e.regs.PC = 0xC005);
|
||||
ATF_CHECK(e.regs.PC == 0xC005);
|
||||
rk65c02_step(&e, 2);
|
||||
ATF_CHECK(e.regs.PC = 0xC003);
|
||||
ATF_CHECK(e.regs.PC == 0xC003);
|
||||
rk65c02_start(&e);
|
||||
|
||||
/* BVC */
|
||||
@ -988,9 +988,9 @@ ATF_TC_BODY(emul_branch, tc)
|
||||
|
||||
e.regs.P &= ~P_SIGN_OVERFLOW;
|
||||
rk65c02_step(&e, 2);
|
||||
ATF_CHECK(e.regs.PC = 0xC005);
|
||||
ATF_CHECK(e.regs.PC == 0xC005);
|
||||
rk65c02_step(&e, 2);
|
||||
ATF_CHECK(e.regs.PC = 0xC003);
|
||||
ATF_CHECK(e.regs.PC == 0xC003);
|
||||
rk65c02_start(&e);
|
||||
|
||||
/* BVS */
|
||||
@ -1000,11 +1000,23 @@ ATF_TC_BODY(emul_branch, tc)
|
||||
|
||||
e.regs.P |= P_SIGN_OVERFLOW;
|
||||
rk65c02_step(&e, 2);
|
||||
ATF_CHECK(e.regs.PC = 0xC005);
|
||||
ATF_CHECK(e.regs.PC == 0xC005);
|
||||
rk65c02_step(&e, 2);
|
||||
ATF_CHECK(e.regs.PC = 0xC003);
|
||||
ATF_CHECK(e.regs.PC == 0xC003);
|
||||
rk65c02_start(&e);
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(emul_sign_overflow);
|
||||
ATF_TC_BODY(emul_sign_overflow, tc)
|
||||
{
|
||||
rk65c02emu_t e;
|
||||
bus_t b;
|
||||
|
||||
b = bus_init();
|
||||
e = rk65c02_init(&b);
|
||||
|
||||
ATF_REQUIRE(rom_start(&e, "test_emulation_sign_overflow.rom", tc));
|
||||
ATF_CHECK(bus_read_1(&b, 0x20) == 0x0);
|
||||
|
||||
}
|
||||
|
||||
@ -1035,6 +1047,8 @@ ATF_TP_ADD_TCS(tp)
|
||||
ATF_TP_ADD_TC(tp, emul_txa_tya_tax_tay);
|
||||
ATF_TP_ADD_TC(tp, emul_sta);
|
||||
|
||||
ATF_TP_ADD_TC(tp, emul_sign_overflow);
|
||||
|
||||
return (atf_no_error());
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user