From 92418b0f1f9821e54fc76f1133283f27a0698fb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Kujawa?= Date: Wed, 1 Feb 2017 14:35:50 +0100 Subject: [PATCH] Add SBC emulation. Of dubious quality. --- src/65c02isa.csv | 18 +++++++++--------- src/emulation.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/65c02isa.csv b/src/65c02isa.csv index a111c7b..71f6d81 100644 --- a/src/65c02isa.csv +++ b/src/65c02isa.csv @@ -224,34 +224,34 @@ OP_CMP_ABSX,"cmp",ABSOLUTEX,3,emul_cmp,false OP_DEC_ABSX,"dec",ABSOLUTEX,3,emul_dec,false OP_BBS5_REL,"bbs5",ZPR,2,emul_bbs5,true OP_CPX_IMM,"cpx",IMMEDIATE,2,emul_cpx,false -OP_SBC_IZPX,"sbc",IZPX,2,NULL,false +OP_SBC_IZPX,"sbc",IZPX,2,emul_sbc,false OP_NOPI_E3,"nop",IMMEDIATE,2,NULL,false OP_NOPI_E4,"nop",IMPLIED,1,NULL,false OP_CPX_ZP,"cpx",ZP,2,emul_cpx,false -OP_SBC_ZP,"sbc",ZP,2,NULL,false +OP_SBC_ZP,"sbc",ZP,2,emul_sbc,false OP_INC_ZP,"inc",ZP,2,emul_inc,false OP_SMB6_ZP,"smb6",ZP,2,emul_smb6,false OP_INX,"inx",IMPLIED,1,emul_inx,false -OP_SBC_IMM,"sbc",IMMEDIATE,2,NULL,false +OP_SBC_IMM,"sbc",IMMEDIATE,2,emul_sbc,false OP_NOP,"nop",IMPLIED,1,emul_nop,false OP_NOPI_EC,"nop",IMPLIED,1,NULL,false OP_CPX_ABS,"cpx",ABSOLUTE,3,emul_cpx,false -OP_SBC_ABS,"sbc",ABSOLUTE,3,NULL,false +OP_SBC_ABS,"sbc",ABSOLUTE,3,emul_sbc,false OP_INC_ABS,"inc",ABSOLUTE,3,emul_inc,false OP_BBS6_REL,"bbs6",ZPR,2,emul_bbs6,true OP_BEQ_REL,"beq",RELATIVE,2,emul_beq,true -OP_SBC_IZPY,"sbc",IZPY,2,NULL,false -OP_SBC_IZP,"sbc",IZP,2,NULL,false +OP_SBC_IZPY,"sbc",IZPY,2,emul_sbc,false +OP_SBC_IZP,"sbc",IZP,2,emul_sbc,false OP_NOPI_F4,"nop",IMPLIED,1,NULL,false OP_NOPI_F5,"nop",ZPX,2,NULL,false -OP_SBC_ZPX,"sbc",ZPX,2,NULL,false +OP_SBC_ZPX,"sbc",ZPX,2,emul_sbc,false OP_INC_ZPX,"inc",ZPX,2,emul_inc,false OP_SMB7_ZP,"smb7",ZP,2,emul_smb7,false OP_SED,"sed",IMPLIED,1,NULL,false -OP_SBC_ABSY,"sbc",ABSOLUTEY,3,NULL,false +OP_SBC_ABSY,"sbc",ABSOLUTEY,3,emul_sbc,false OP_PLX,"plx",IMPLIED,1,emul_plx,false OP_NOPI_FC,"nop",IMPLIED,1,NULL,false OP_NOPI_FD,"nop",ABSOLUTE,3,NULL,false -OP_SBC_ABSX,"sbc",ABSOLUTEX,3,NULL,false +OP_SBC_ABSX,"sbc",ABSOLUTEX,3,emul_sbc,false OP_INC_ABSX,"inc",ABSOLUTEX,3,emul_inc,false OP_BBS7_REL,"bbs7",ZPR,2,emul_bbs7,true diff --git a/src/emulation.c b/src/emulation.c index da18679..f9972ec 100644 --- a/src/emulation.c +++ b/src/emulation.c @@ -790,6 +790,36 @@ emul_ror(rk65c02emu_t *e, void *id, instruction_t *i) instruction_data_write_1(e, (instrdef_t *) id, i, val); } +/* SBC - substract with carry */ +void +emul_sbc(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); +} /* SEC - set the carry flag */ void emul_sec(rk65c02emu_t *e, void *id, instruction_t *i)