1
0
mirror of https://github.com/rkujawa/rk65c02.git synced 2024-12-23 07:30:31 +00:00

Implement emulation of ADC, plug the overflow test.

While here fix numerous test cases, lol.
This commit is contained in:
Radosław Kujawa 2017-01-31 23:08:23 +01:00
parent 2f076f4a16
commit faa824e306
3 changed files with 85 additions and 33 deletions

View File

@ -96,35 +96,35 @@ OP_EOR_ABSX,"eor",ABSOLUTEX,3,emul_eor,false
OP_LSR_ABSX,"lsr",ABSOLUTEX,3,emul_lsr,false OP_LSR_ABSX,"lsr",ABSOLUTEX,3,emul_lsr,false
OP_BBR5_REL,"bbr5",ZPR,2,emul_bbr5,true OP_BBR5_REL,"bbr5",ZPR,2,emul_bbr5,true
OP_RTS,"rts",IMPLIED,1,emul_rts,false 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_63,"nop",IMMEDIATE,2,NULL,false
OP_NOPI_64,"nop",IMPLIED,1,NULL,false OP_NOPI_64,"nop",IMPLIED,1,NULL,false
OP_STZ_ZP,"stz",ZP,2,emul_stz,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_ROR_ZP,"ror",ZP,2,emul_ror,false
OP_RMB6_ZP,"rmb6",ZP,2,emul_rmb6,false OP_RMB6_ZP,"rmb6",ZP,2,emul_rmb6,false
OP_PLA,"pla",IMPLIED,1,emul_pla,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_ROR,"ror",ACCUMULATOR,1,emul_ror,false
OP_NOPI_6C,"nop",IMPLIED,1,NULL,false OP_NOPI_6C,"nop",IMPLIED,1,NULL,false
OP_JMP_IABS,"jmp",IABSOLUTE,3,emul_jmp,true 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_ROR_ABS,"ror",ABSOLUTE,3,emul_ror,false
OP_BBR6_REL,"bbr6",ZPR,2,emul_bbr6,true OP_BBR6_REL,"bbr6",ZPR,2,emul_bbr6,true
OP_BVS_REL,"bvs",RELATIVE,2,emul_bvs,true OP_BVS_REL,"bvs",RELATIVE,2,emul_bvs,true
OP_ADC_IZPY,"adc",IZPY,2,NULL,false OP_ADC_IZPY,"adc",IZPY,2,emul_adc,false
OP_ADC_IZP,"adc",IZP,2,NULL,false OP_ADC_IZP,"adc",IZP,2,emul_adc,false
OP_NOPI_74,"nop",IMPLIED,1,NULL,false OP_NOPI_74,"nop",IMPLIED,1,NULL,false
OP_STZ_ZPX,"stz",ZPX,2,emul_stz,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_ROR_ZPX,"ror",ZPX,2,emul_ror,false
OP_RMB7_ZP,"rmb7",ZP,2,emul_rmb7,false OP_RMB7_ZP,"rmb7",ZP,2,emul_rmb7,false
OP_SEI,"sei",IMPLIED,1,emul_sei,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_PLY,"ply",IMPLIED,1,emul_ply,false
OP_NOPI_7C,"nop",IMPLIED,1,NULL,false OP_NOPI_7C,"nop",IMPLIED,1,NULL,false
OP_JMP_IABSX,"jmp",IABSOLUTEX,3,emul_jmp,true 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_ROR_ABSX,"ror",ABSOLUTEX,3,emul_ror,false
OP_BBR7_REL,"bbr7",ZPR,2,emul_bbr7,true OP_BBR7_REL,"bbr7",ZPR,2,emul_bbr7,true
OP_BRA_REL,"bra",RELATIVE,2,emul_bra,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_CMP_ZPX,"cmp",ZPX,2,emul_cmp,false
OP_DEC_ZPX,"dec",ZPX,2,emul_dec,false OP_DEC_ZPX,"dec",ZPX,2,emul_dec,false
OP_SMB5_ZP,"smb5",ZP,2,emul_smb5,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_CMP_ABSY,"cmp",ABSOLUTEY,3,emul_cmp,false
OP_PHX,"phx",IMPLIED,1,emul_phx,false OP_PHX,"phx",IMPLIED,1,emul_phx,false
OP_STP,"stp",IMPLIED,1,emul_stp,false OP_STP,"stp",IMPLIED,1,emul_stp,false

1 opcode_id mnemonic addressing size emulation modify_pc
96 OP_LSR_ABSX lsr ABSOLUTEX 3 emul_lsr false
97 OP_BBR5_REL bbr5 ZPR 2 emul_bbr5 true
98 OP_RTS rts IMPLIED 1 emul_rts false
99 OP_ADC_IZPX adc IZPX 2 NULL emul_adc false
100 OP_NOPI_63 nop IMMEDIATE 2 NULL false
101 OP_NOPI_64 nop IMPLIED 1 NULL false
102 OP_STZ_ZP stz ZP 2 emul_stz false
103 OP_ADC_ZP adc ZP 2 NULL emul_adc false
104 OP_ROR_ZP ror ZP 2 emul_ror false
105 OP_RMB6_ZP rmb6 ZP 2 emul_rmb6 false
106 OP_PLA pla IMPLIED 1 emul_pla false
107 OP_ADC_IMM adc IMMEDIATE 2 NULL emul_adc false
108 OP_ROR ror ACCUMULATOR 1 emul_ror false
109 OP_NOPI_6C nop IMPLIED 1 NULL false
110 OP_JMP_IABS jmp IABSOLUTE 3 emul_jmp true
111 OP_ADC_ABS adc ABSOLUTE 3 NULL emul_adc false
112 OP_ROR_ABS ror ABSOLUTE 3 emul_ror false
113 OP_BBR6_REL bbr6 ZPR 2 emul_bbr6 true
114 OP_BVS_REL bvs RELATIVE 2 emul_bvs true
115 OP_ADC_IZPY adc IZPY 2 NULL emul_adc false
116 OP_ADC_IZP adc IZP 2 NULL emul_adc false
117 OP_NOPI_74 nop IMPLIED 1 NULL false
118 OP_STZ_ZPX stz ZPX 2 emul_stz false
119 OP_ADC_ZPX adc ZPX 2 NULL emul_adc false
120 OP_ROR_ZPX ror ZPX 2 emul_ror false
121 OP_RMB7_ZP rmb7 ZP 2 emul_rmb7 false
122 OP_SEI sei IMPLIED 1 emul_sei false
123 OP_ADC_ABSY adc ABSOLUTEY 3 NULL emul_adc false
124 OP_PLY ply IMPLIED 1 emul_ply false
125 OP_NOPI_7C nop IMPLIED 1 NULL false
126 OP_JMP_IABSX jmp IABSOLUTEX 3 emul_jmp true
127 OP_ADC_ABSX adc ABSOLUTEX 3 NULL emul_adc false
128 OP_ROR_ABSX ror ABSOLUTEX 3 emul_ror false
129 OP_BBR7_REL bbr7 ZPR 2 emul_bbr7 true
130 OP_BRA_REL bra RELATIVE 2 emul_bra true
215 OP_CMP_ZPX cmp ZPX 2 emul_cmp false
216 OP_DEC_ZPX dec ZPX 2 emul_dec false
217 OP_SMB5_ZP smb5 ZP 2 emul_smb5 false
218 OP_CLD cld IMPLIED 1 NULL emul_cld false
219 OP_CMP_ABSY cmp ABSOLUTEY 3 emul_cmp false
220 OP_PHX phx IMPLIED 1 emul_phx false
221 OP_STP stp IMPLIED 1 emul_stp false

View File

@ -11,6 +11,37 @@ void emul_bbs(rk65c02emu_t *, void *, instruction_t *, uint8_t);
/* Implementation of emulation of instructions follows below */ /* 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 */ /* AND - logical AND */
void void
emul_and(rk65c02emu_t *e, void *id, instruction_t *i) 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; 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 */ /* CLI - clear interrupt disable flag */
void void
emul_cli(rk65c02emu_t *e, void *id, instruction_t *i) emul_cli(rk65c02emu_t *e, void *id, instruction_t *i)

View File

@ -844,7 +844,7 @@ ATF_TC_BODY(emul_jmp, tc)
rom_path("test_emulation_jmp_abs.rom", tc))); rom_path("test_emulation_jmp_abs.rom", tc)));
rk65c02_step(&e, 3); rk65c02_step(&e, 3);
ATF_CHECK(e.regs.PC = 0xC000); ATF_CHECK(e.regs.PC == 0xC000);
/* JMP indirect absolute */ /* JMP indirect absolute */
e.regs.PC = ROM_LOAD_ADDR; e.regs.PC = ROM_LOAD_ADDR;
@ -855,7 +855,7 @@ ATF_TC_BODY(emul_jmp, tc)
bus_write_1(&b, 0x21, 0xC0); bus_write_1(&b, 0x21, 0xC0);
rk65c02_step(&e, 3); rk65c02_step(&e, 3);
ATF_CHECK(e.regs.PC = 0xC000); ATF_CHECK(e.regs.PC == 0xC000);
/* JMP indirect absolute X */ /* JMP indirect absolute X */
e.regs.PC = ROM_LOAD_ADDR; e.regs.PC = ROM_LOAD_ADDR;
@ -867,7 +867,7 @@ ATF_TC_BODY(emul_jmp, tc)
bus_write_1(&b, 0x41, 0xC0); bus_write_1(&b, 0x41, 0xC0);
rk65c02_step(&e, 3); rk65c02_step(&e, 3);
ATF_CHECK(e.regs.PC = 0xC000); ATF_CHECK(e.regs.PC == 0xC000);
} }
ATF_TC_WITHOUT_HEAD(emul_jsr_rts); 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))); rom_path("test_emulation_jsr_rts.rom", tc)));
rk65c02_step(&e, 2); rk65c02_step(&e, 2);
ATF_CHECK(e.regs.PC = 0xC006); ATF_CHECK(e.regs.PC == 0xC006);
rk65c02_start(&e); 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; e.regs.P &= ~P_CARRY;
rk65c02_step(&e, 2); rk65c02_step(&e, 2);
ATF_CHECK(e.regs.PC = 0xC005); ATF_CHECK(e.regs.PC == 0xC005);
rk65c02_step(&e, 2); rk65c02_step(&e, 2);
ATF_CHECK(e.regs.PC = 0xC003); ATF_CHECK(e.regs.PC == 0xC003);
rk65c02_start(&e); rk65c02_start(&e);
/* BCS */ /* BCS */
@ -919,9 +919,9 @@ ATF_TC_BODY(emul_branch, tc)
e.regs.P |= P_CARRY; e.regs.P |= P_CARRY;
rk65c02_step(&e, 2); rk65c02_step(&e, 2);
ATF_CHECK(e.regs.PC = 0xC005); ATF_CHECK(e.regs.PC == 0xC005);
rk65c02_step(&e, 2); rk65c02_step(&e, 2);
ATF_CHECK(e.regs.PC = 0xC003); ATF_CHECK(e.regs.PC == 0xC003);
rk65c02_start(&e); rk65c02_start(&e);
/* BRA */ /* BRA */
@ -930,7 +930,7 @@ ATF_TC_BODY(emul_branch, tc)
rom_path("test_emulation_bra.rom", tc))); rom_path("test_emulation_bra.rom", tc)));
rk65c02_step(&e, 1); rk65c02_step(&e, 1);
ATF_CHECK(e.regs.PC = 0xC004); ATF_CHECK(e.regs.PC == 0xC004);
rk65c02_start(&e); rk65c02_start(&e);
/* BEQ */ /* BEQ */
@ -940,9 +940,9 @@ ATF_TC_BODY(emul_branch, tc)
e.regs.P |= P_ZERO; e.regs.P |= P_ZERO;
rk65c02_step(&e, 2); rk65c02_step(&e, 2);
ATF_CHECK(e.regs.PC = 0xC005); ATF_CHECK(e.regs.PC == 0xC005);
rk65c02_step(&e, 2); rk65c02_step(&e, 2);
ATF_CHECK(e.regs.PC = 0xC003); ATF_CHECK(e.regs.PC == 0xC003);
rk65c02_start(&e); rk65c02_start(&e);
/* BMI */ /* BMI */
@ -952,9 +952,9 @@ ATF_TC_BODY(emul_branch, tc)
e.regs.P |= P_NEGATIVE; e.regs.P |= P_NEGATIVE;
rk65c02_step(&e, 2); rk65c02_step(&e, 2);
ATF_CHECK(e.regs.PC = 0xC005); ATF_CHECK(e.regs.PC == 0xC005);
rk65c02_step(&e, 2); rk65c02_step(&e, 2);
ATF_CHECK(e.regs.PC = 0xC003); ATF_CHECK(e.regs.PC == 0xC003);
rk65c02_start(&e); rk65c02_start(&e);
/* BNE */ /* BNE */
@ -962,11 +962,11 @@ ATF_TC_BODY(emul_branch, tc)
ATF_REQUIRE(bus_load_file(&b, ROM_LOAD_ADDR, ATF_REQUIRE(bus_load_file(&b, ROM_LOAD_ADDR,
rom_path("test_emulation_bne.rom", tc))); rom_path("test_emulation_bne.rom", tc)));
e.regs.P |= P_NEGATIVE; e.regs.P &= ~P_ZERO;
rk65c02_step(&e, 2); rk65c02_step(&e, 2);
ATF_CHECK(e.regs.PC = 0xC005); ATF_CHECK(e.regs.PC == 0xC005);
rk65c02_step(&e, 2); rk65c02_step(&e, 2);
ATF_CHECK(e.regs.PC = 0xC003); ATF_CHECK(e.regs.PC == 0xC003);
rk65c02_start(&e); rk65c02_start(&e);
/* BPL */ /* BPL */
@ -976,9 +976,9 @@ ATF_TC_BODY(emul_branch, tc)
e.regs.P &= ~P_NEGATIVE; e.regs.P &= ~P_NEGATIVE;
rk65c02_step(&e, 2); rk65c02_step(&e, 2);
ATF_CHECK(e.regs.PC = 0xC005); ATF_CHECK(e.regs.PC == 0xC005);
rk65c02_step(&e, 2); rk65c02_step(&e, 2);
ATF_CHECK(e.regs.PC = 0xC003); ATF_CHECK(e.regs.PC == 0xC003);
rk65c02_start(&e); rk65c02_start(&e);
/* BVC */ /* BVC */
@ -988,9 +988,9 @@ ATF_TC_BODY(emul_branch, tc)
e.regs.P &= ~P_SIGN_OVERFLOW; e.regs.P &= ~P_SIGN_OVERFLOW;
rk65c02_step(&e, 2); rk65c02_step(&e, 2);
ATF_CHECK(e.regs.PC = 0xC005); ATF_CHECK(e.regs.PC == 0xC005);
rk65c02_step(&e, 2); rk65c02_step(&e, 2);
ATF_CHECK(e.regs.PC = 0xC003); ATF_CHECK(e.regs.PC == 0xC003);
rk65c02_start(&e); rk65c02_start(&e);
/* BVS */ /* BVS */
@ -1000,11 +1000,23 @@ ATF_TC_BODY(emul_branch, tc)
e.regs.P |= P_SIGN_OVERFLOW; e.regs.P |= P_SIGN_OVERFLOW;
rk65c02_step(&e, 2); rk65c02_step(&e, 2);
ATF_CHECK(e.regs.PC = 0xC005); ATF_CHECK(e.regs.PC == 0xC005);
rk65c02_step(&e, 2); rk65c02_step(&e, 2);
ATF_CHECK(e.regs.PC = 0xC003); ATF_CHECK(e.regs.PC == 0xC003);
rk65c02_start(&e); 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_txa_tya_tax_tay);
ATF_TP_ADD_TC(tp, emul_sta); ATF_TP_ADD_TC(tp, emul_sta);
ATF_TP_ADD_TC(tp, emul_sign_overflow);
return (atf_no_error()); return (atf_no_error());
} }