From 244b9d22310905ff035f13ecc6d47f802cf49f5a Mon Sep 17 00:00:00 2001 From: alyosha-tas Date: Wed, 3 Apr 2019 19:22:23 -0500 Subject: [PATCH] More MC6809 --- .../CPUs/MC6809/Execute.cs | 108 +++++++++--------- BizHawk.Emulation.Cores/CPUs/MC6809/MC6809.cs | 37 ++++++ .../CPUs/MC6809/Operations.cs | 106 ++++++++++++++--- .../CPUs/MC6809/Tables_Direct.cs | 66 +++++++++++ 4 files changed, 249 insertions(+), 68 deletions(-) diff --git a/BizHawk.Emulation.Cores/CPUs/MC6809/Execute.cs b/BizHawk.Emulation.Cores/CPUs/MC6809/Execute.cs index 5f60b7966d..80a30a1d6b 100644 --- a/BizHawk.Emulation.Cores/CPUs/MC6809/Execute.cs +++ b/BizHawk.Emulation.Cores/CPUs/MC6809/Execute.cs @@ -151,35 +151,35 @@ namespace BizHawk.Emulation.Common.Components.MC6809 case 0x7D: EXT_MEM(TST); break; // TST (Extended) case 0x7E: JMP_EXT_(); break; // JMP (Extended) case 0x7F: EXT_MEM(CLR); break; // CLR (Extended) - case 0x80: REG_OP(ADD8, A); break; // SUBA (Immediate) - case 0x81: REG_OP(ADD8, A); break; // CMPA (Immediate) - case 0x82: REG_OP(ADD8, A); break; // SBCA (Immediate) - case 0x83: REG_OP(ADD8, A); break; // SUBD (Immediate) - case 0x84: REG_OP(ADD8, A); break; // ANDA (Immediate) - case 0x85: REG_OP(ADD8, A); break; // BITA (Immediate) - case 0x86: REG_OP(ADD8, A); break; // LDA (Immediate) + case 0x80: REG_OP_IMD(SUB8, A); break; // SUBA (Immediate) + case 0x81: REG_OP_IMD(CMP8, A); break; // CMPA (Immediate) + case 0x82: REG_OP_IMD(SBC8, A); break; // SBCA (Immediate) + case 0x83: IMD_OP_D(SUB16, D); break; // SUBD (Immediate) + case 0x84: REG_OP_IMD(AND8, A); break; // ANDA (Immediate) + case 0x85: REG_OP_IMD(BIT, A); break; // BITA (Immediate) + case 0x86: REG_OP_IMD(TR, A); break; // LDA (Immediate) case 0x87: ILLEGAL(); break; // ILLEGAL - case 0x88: REG_OP(ADC8, A); break; // EORA (Immediate) - case 0x89: REG_OP(ADC8, A); break; // ADCA (Immediate) - case 0x8A: REG_OP(ADC8, A); break; // ORA (Immediate) - case 0x8B: REG_OP(ADC8, A); break; // ADDA (Immediate) - case 0x8C: REG_OP(ADC8, A); break; // CMPX (Immediate) - case 0x8D: REG_OP(ADC8, A); break; // BSR (Relative) - case 0x8E: REG_OP(ADC8, A); break; // LDX (Immediate) + case 0x88: REG_OP_IMD(XOR8, A); break; // EORA (Immediate) + case 0x89: REG_OP_IMD(ADC8, A); break; // ADCA (Immediate) + case 0x8A: REG_OP_IMD(OR8, A); break; // ORA (Immediate) + case 0x8B: REG_OP_IMD(ADD8, A); break; // ADDA (Immediate) + case 0x8C: REG_OP_IMD(ADC8, A); break; // CMPX (Immediate) + case 0x8D: BSR_(); break; // BSR (Relative) + case 0x8E: REG_OP_LD_16(X); break; // LDX (Immediate) case 0x8F: ILLEGAL(); break; // ILLEGAL - case 0x90: REG_OP(ADD8, A); break; // SUBA (Direct) - case 0x91: REG_OP(ADD8, A); break; // CMPA (Direct) - case 0x92: REG_OP(ADD8, A); break; // SBCA (Direct) - case 0x93: REG_OP(ADD8, A); break; // SUBD (Direct) - case 0x94: REG_OP(ADD8, A); break; // ANDA (Direct) - case 0x95: REG_OP(ADD8, A); break; // BITA (Direct) - case 0x96: REG_OP(ADD8, A); break; // LDA (Direct) - case 0x97: REG_OP(ADD8, A); break; // STA (Direct) - case 0x98: REG_OP(ADC8, A); break; // EORA (Direct) - case 0x99: REG_OP(ADC8, A); break; // ADCA (Direct) - case 0x9A: REG_OP(ADC8, A); break; // ORA (Direct) - case 0x9B: REG_OP(ADC8, A); break; // ADDA (Direct) - case 0x9C: REG_OP(ADC8, A); break; // CMPX (Direct) + case 0x90: DIRECT_MEM_4(SUB8, A); break; // SUBA (Direct) + case 0x91: DIRECT_MEM_4(CMP8, A); break; // CMPA (Direct) + case 0x92: DIRECT_MEM_4(SBC8, A); break; // SBCA (Direct) + case 0x93: DIR_OP_D(SUB16, D); break; // SUBD (Direct) + case 0x94: DIRECT_MEM_4(AND8, A); break; // ANDA (Direct) + case 0x95: DIRECT_MEM_4(BIT, A); break; // BITA (Direct) + case 0x96: DIRECT_MEM_4(TR, A); break; // LDA (Direct) + case 0x97: DIRECT_ST_4(A); break; // STA (Direct) + case 0x98: DIRECT_MEM_4(XOR8, A); break; // EORA (Direct) + case 0x99: DIRECT_MEM_4(ADC8, A); break; // ADCA (Direct) + case 0x9A: DIRECT_MEM_4(OR8, A); break; // ORA (Direct) + case 0x9B: DIRECT_MEM_4(ADD8, A); break; // ADDA (Direct) + case 0x9C: DIR_CMP_16(CMP16, X); break; // CMPX (Direct) case 0x9D: REG_OP(ADC8, A); break; // JSR (Direct) case 0x9E: REG_OP(ADC8, A); break; // LDX (Direct) case 0x9F: REG_OP(ADC8, A); break; // STX (Direct) @@ -215,36 +215,36 @@ namespace BizHawk.Emulation.Common.Components.MC6809 case 0xBD: REG_OP(XOR8, A); break; // JSR (Extended) case 0xBE: REG_OP(XOR8, A); break; // LDX (Extended) case 0xBF: REG_OP(XOR8, A); break; // STX (Extended) - case 0xC0: REG_OP(ADD8, A); break; // SUBB (Immediate) - case 0xC1: REG_OP(ADD8, A); break; // CMPB (Immediate) - case 0xC2: REG_OP(ADD8, A); break; // SBCB (Immediate) - case 0xC3: REG_OP(ADD8, A); break; // ADDD (Immediate) - case 0xC4: REG_OP(ADD8, A); break; // ANDB (Immediate) - case 0xC5: REG_OP(ADD8, A); break; // BITB (Immediate) - case 0xC6: REG_OP(ADD8, A); break; // LDB (Immediate) + case 0xC0: REG_OP_IMD(SUB8, B); break; // SUBB (Immediate) + case 0xC1: REG_OP_IMD(CMP8, B); break; // CMPB (Immediate) + case 0xC2: REG_OP_IMD(SBC8, B); break; // SBCB (Immediate) + case 0xC3: IMD_OP_D(ADD16, D); break; // ADDD (Immediate) + case 0xC4: REG_OP_IMD(AND8, B); break; // ANDB (Immediate) + case 0xC5: REG_OP_IMD(BIT, B); break; // BITB (Immediate) + case 0xC6: REG_OP_IMD(TR, B); break; // LDB (Immediate) case 0xC7: ILLEGAL(); break; // ILLEGAL - case 0xC8: REG_OP(ADC8, A); break; // EORB (Immediate) - case 0xC9: REG_OP(ADC8, A); break; // ADCB (Immediate) - case 0xCA: REG_OP(ADC8, A); break; // ORB (Immediate) - case 0xCB: REG_OP(ADC8, A); break; // ADDB (Immediate) - case 0xCC: REG_OP(ADC8, A); break; // LDD (Immediate) + case 0xC8: REG_OP_IMD(XOR8, B); break; // EORB (Immediate) + case 0xC9: REG_OP_IMD(ADC8, B); break; // ADCB (Immediate) + case 0xCA: REG_OP_IMD(OR8, B); break; // ORB (Immediate) + case 0xCB: REG_OP_IMD(ADD8, B); break; // ADDB (Immediate) + case 0xCC: REG_OP_LD_16D(D); break; // LDD (Immediate) case 0xCD: ILLEGAL(); break; // ILLEGAL - case 0xCE: REG_OP(ADC8, A); break; // LDU (Immediate) + case 0xCE: REG_OP_LD_16(US); break; // LDU (Immediate) case 0xCF: ILLEGAL(); break; // ILLEGAL - case 0xD0: REG_OP(ADD8, B); break; // SUBB (Direct) - case 0xD1: REG_OP(ADD8, B); break; // CMPB (Direct) - case 0xD2: REG_OP(ADD8, B); break; // SBCB (Direct) - case 0xD3: REG_OP(ADD8, B); break; // ADDD (Direct) - case 0xD4: REG_OP(ADD8, B); break; // ANDB (Direct) - case 0xD5: REG_OP(ADD8, B); break; // BITB (Direct) - case 0xD6: REG_OP(ADD8, B); break; // LDB (Direct) - case 0xD7: REG_OP(ADD8, B); break; // STB (Direct) - case 0xD8: REG_OP(ADC8, B); break; // EORB (Direct) - case 0xD9: REG_OP(ADC8, B); break; // ADCB (Direct) - case 0xDA: REG_OP(ADC8, B); break; // ORB (Direct) - case 0xDB: REG_OP(ADC8, B); break; // ADDB (Direct) - case 0xDC: REG_OP(ADC8, B); break; // LDD (Direct) - case 0xDD: REG_OP(ADC8, B); break; // STD (Direct) + case 0xD0: DIRECT_MEM_4(SUB8, B); break; // SUBB (Direct) + case 0xD1: DIRECT_MEM_4(CMP8, B); break; // CMPB (Direct) + case 0xD2: DIRECT_MEM_4(SBC8, B); break; // SBCB (Direct) + case 0xD3: DIR_OP_D(ADD16, D); break; // ADDD (Direct) + case 0xD4: DIRECT_MEM_4(AND8, B); break; // ANDB (Direct) + case 0xD5: DIRECT_MEM_4(BIT, B); break; // BITB (Direct) + case 0xD6: DIRECT_MEM_4(TR, B); break; // LDB (Direct) + case 0xD7: DIRECT_ST_4(B); break; // STB (Direct) + case 0xD8: DIRECT_MEM_4(XOR8, B); break; // EORB (Direct) + case 0xD9: DIRECT_MEM_4(ADC8, B); break; // ADCB (Direct) + case 0xDA: DIRECT_MEM_4(OR8, B); break; // ORB (Direct) + case 0xDB: DIRECT_MEM_4(ADD8, B); break; // ADDB (Direct) + case 0xDC: DIRECT_MEM_4(ADC8, B); break; // LDD (Direct) + case 0xDD: DIRECT_MEM_4(ADC8, B); break; // STD (Direct) case 0xDE: REG_OP(ADC8, B); break; // LDU (Direct) case 0xDF: REG_OP(ADC8, B); break; // STU (Direct) case 0xE0: REG_OP(AND8, B); break; // SUBB (Indexed) diff --git a/BizHawk.Emulation.Cores/CPUs/MC6809/MC6809.cs b/BizHawk.Emulation.Cores/CPUs/MC6809/MC6809.cs index e15ad9c7c8..600954d0eb 100644 --- a/BizHawk.Emulation.Cores/CPUs/MC6809/MC6809.cs +++ b/BizHawk.Emulation.Cores/CPUs/MC6809/MC6809.cs @@ -87,6 +87,10 @@ namespace BizHawk.Emulation.Common.Components.MC6809 public const ushort SET_F_I = 73; public const ushort SET_E = 74; public const ushort ANDCC = 75; + public const ushort CMP8 = 76; + public const ushort SUB16 = 77; + public const ushort ADD16 = 78; + public const ushort CMP16 = 79; public MC6809() { @@ -216,12 +220,33 @@ namespace BizHawk.Emulation.Common.Components.MC6809 case AND8: AND8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; + case ADD8: + ADD8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; + case ADC8: + ADC8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; case OR8: OR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; + case XOR8: + XOR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; + case BIT: + BIT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; case SUB8: SUB8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; + case SBC8: + SUB8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; + case CMP8: + CMP8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; + case TR: + TR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; case SET_ADDR: Regs[cur_instr[instr_pntr++]] = (ushort)((Regs[cur_instr[instr_pntr++]] << 8) | Regs[cur_instr[instr_pntr++]]); break; @@ -347,6 +372,9 @@ namespace BizHawk.Emulation.Common.Components.MC6809 case SBC8: SBC8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; + case CMP8: + CMP8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; case INC16: INC16_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; @@ -356,6 +384,15 @@ namespace BizHawk.Emulation.Common.Components.MC6809 case DEC16: DEC16_Func(cur_instr[instr_pntr++]); break; + case SUB16: + SUB16_Func(cur_instr[instr_pntr++]); + break; + case ADD16: + ADD16_Func(cur_instr[instr_pntr++]); + break; + case CMP16: + CMP16_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; case DEC8: DEC8_Func(cur_instr[instr_pntr++]); break; diff --git a/BizHawk.Emulation.Cores/CPUs/MC6809/Operations.cs b/BizHawk.Emulation.Cores/CPUs/MC6809/Operations.cs index a072f333cd..bd38590322 100644 --- a/BizHawk.Emulation.Cores/CPUs/MC6809/Operations.cs +++ b/BizHawk.Emulation.Cores/CPUs/MC6809/Operations.cs @@ -117,7 +117,7 @@ namespace BizHawk.Emulation.Common.Components.MC6809 { Regs[ALU] = (ushort)(Regs[A] * Regs[B]); D = Regs[ALU]; - FlagC = Regs[B] > 127; + FlagC = Regs[A] > 127; FlagZ = D == 0; } @@ -136,7 +136,7 @@ namespace BizHawk.Emulation.Common.Components.MC6809 Reg16_d += (Regs[src] & 0xF); FlagH = Reg16_d.Bit(4); - + FlagV = (Regs[dest].Bit(7) != Regs[src].Bit(7)) && (Regs[dest].Bit(7) != ans.Bit(7)); FlagN = false; Regs[dest] = ans; @@ -157,16 +157,39 @@ namespace BizHawk.Emulation.Common.Components.MC6809 Reg16_d -= (Regs[src] & 0xF); FlagH = Reg16_d.Bit(4); - FlagN = true; + FlagN = ans > 127; + FlagV = (Regs[dest].Bit(7) != Regs[src].Bit(7)) && (Regs[dest].Bit(7) != ans.Bit(7)); Regs[dest] = ans; } - public void BIT_Func(ushort bit, ushort src) + // same as SUB8 but result not stored + public void CMP8_Func(ushort dest, ushort src) { - FlagZ = !Regs[src].Bit(bit); - FlagH = true; - FlagN = false; + int Reg16_d = Regs[dest]; + Reg16_d -= Regs[src]; + + FlagC = Reg16_d.Bit(8); + FlagZ = (Reg16_d & 0xFF) == 0; + + ushort ans = (ushort)(Reg16_d & 0xFF); + + // redo for half carry flag + Reg16_d = Regs[dest] & 0xF; + Reg16_d -= (Regs[src] & 0xF); + + FlagH = Reg16_d.Bit(4); + FlagN = ans > 127; + FlagV = (Regs[dest].Bit(7) != Regs[src].Bit(7)) && (Regs[dest].Bit(7) != ans.Bit(7)); + } + + public void BIT_Func(ushort dest, ushort src) + { + ushort ans = (ushort)(Regs[dest] & Regs[src]); + + FlagZ = ans == 0; + FlagV = false; + FlagN = ans > 127; } public void SET_Func(ushort bit, ushort src) @@ -253,7 +276,7 @@ namespace BizHawk.Emulation.Common.Components.MC6809 } FlagZ = D == 0; - FlagN = Regs[B] > 127; + FlagN = Regs[A] > 127; } public void CCF_Func(ushort src) @@ -276,7 +299,7 @@ namespace BizHawk.Emulation.Common.Components.MC6809 FlagZ = Regs[dest] == 0; FlagV = false; - FlagN = Regs[B] > 127; + FlagN = Regs[dest] > 127; } public void OR8_Func(ushort dest, ushort src) @@ -285,7 +308,7 @@ namespace BizHawk.Emulation.Common.Components.MC6809 FlagZ = Regs[dest] == 0; FlagV = false; - FlagN = Regs[B] > 127; + FlagN = Regs[dest] > 127; } public void XOR8_Func(ushort dest, ushort src) @@ -293,9 +316,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 Regs[dest] = (ushort)(Regs[dest] ^ Regs[src]); FlagZ = Regs[dest] == 0; - FlagC = false; - FlagH = false; - FlagN = false; + FlagV = false; + FlagN = Regs[dest] > 127; } public void CP8_Func(ushort dest, ushort src) @@ -418,6 +440,7 @@ namespace BizHawk.Emulation.Common.Components.MC6809 Reg16_d += ((Regs[src] & 0xF) + c); FlagH = Reg16_d.Bit(4); + FlagV = (Regs[dest].Bit(7) != Regs[src].Bit(7)) && (Regs[dest].Bit(7) != ans.Bit(7)); FlagN = false; Regs[dest] = ans; @@ -440,7 +463,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 Reg16_d -= ((Regs[src] & 0xF) + c); FlagH = Reg16_d.Bit(4); - FlagN = true; + FlagN = ans > 127; + FlagV = (Regs[dest].Bit(7) != Regs[src].Bit(7)) && (Regs[dest].Bit(7) != ans.Bit(7)); Regs[dest] = ans; } @@ -518,6 +542,60 @@ namespace BizHawk.Emulation.Common.Components.MC6809 } + // D register implied + public void SUB16_Func(ushort src) + { + int Reg16_d = D; + int Reg16_s = Regs[src]; + + Reg16_d -= Reg16_s; + + FlagC = Reg16_d.Bit(16); + FlagZ = (Reg16_d & 0xFFFF) == 0; + + ushort ans = (ushort)(Reg16_d & 0xFFFF); + + FlagN = ans > 0x7FFF; + FlagV = (D.Bit(15) != Regs[src].Bit(15)) && (D.Bit(15) != ans.Bit(15)); + + D = ans; + } + + // D register implied + public void ADD16_Func(ushort src) + { + int Reg16_d = D; + int Reg16_s = Regs[src]; + + Reg16_d += Reg16_s; + + FlagC = Reg16_d.Bit(16); + FlagZ = (Reg16_d & 0xFFFF) == 0; + + ushort ans = (ushort)(Reg16_d & 0xFFFF); + + FlagN = ans > 0x7FFF; + FlagV = (D.Bit(15) != Regs[src].Bit(15)) && (D.Bit(15) != ans.Bit(15)); + + D = ans; + } + + public void CMP16_Func(ushort dest, ushort src) + { + int Reg16_d = Regs[dest]; + int Reg16_s = Regs[src]; + + Reg16_d += Reg16_s; + + FlagC = Reg16_d.Bit(16); + FlagZ = (Reg16_d & 0xFFFF) == 0; + + ushort ans = (ushort)(Reg16_d & 0xFFFF); + + FlagN = ans > 0x7FFF; + FlagV = (Regs[dest].Bit(15) != Regs[src].Bit(15)) && (Regs[dest].Bit(15) != ans.Bit(15)); + } + public void EXG_Func(ushort sel) { ushort src = 0; diff --git a/BizHawk.Emulation.Cores/CPUs/MC6809/Tables_Direct.cs b/BizHawk.Emulation.Cores/CPUs/MC6809/Tables_Direct.cs index 1f9242a311..5291a93845 100644 --- a/BizHawk.Emulation.Cores/CPUs/MC6809/Tables_Direct.cs +++ b/BizHawk.Emulation.Cores/CPUs/MC6809/Tables_Direct.cs @@ -32,6 +32,20 @@ namespace BizHawk.Emulation.Common.Components.MC6809 WR, ADDR, ALU); } + private void DIRECT_ST_4(ushort dest) + { + PopulateCURINSTR(RD_INC_OP, ALU, PC, SET_ADDR, ADDR, DP, ALU, + RD, ALU, ADDR, + WR, ADDR, dest); + } + + private void DIRECT_MEM_4(ushort oper, ushort dest) + { + PopulateCURINSTR(RD_INC_OP, ALU, PC, SET_ADDR, ADDR, DP, ALU, + RD, ALU, ADDR, + oper, dest, ALU); + } + private void EXT_MEM(ushort oper) { PopulateCURINSTR(RD_INC, ALU, PC, @@ -49,6 +63,48 @@ namespace BizHawk.Emulation.Common.Components.MC6809 TR, CC, ALU2); } + private void REG_OP_IMD(ushort oper, ushort dest) + { + PopulateCURINSTR(RD_INC_OP, ALU, PC, oper, dest, ALU); + } + + private void IMD_OP_D(ushort oper, ushort dest) + { + PopulateCURINSTR(RD_INC, ALU, PC, + RD_INC_OP, ALU2, PC, SET_ADDR, ADDR, ALU, ALU2, + oper, ADDR); + } + + private void DIR_OP_D(ushort oper, ushort dest) + { + PopulateCURINSTR(RD_INC_OP, ALU, PC, SET_ADDR, ADDR, DP, ALU, + RD_INC, ALU, ADDR, + RD, ALU2, ADDR, + SET_ADDR, ADDR, ALU, ALU2, + oper, ADDR); + } + + private void DIR_CMP_16(ushort oper, ushort dest) + { + PopulateCURINSTR(RD_INC_OP, ALU, PC, SET_ADDR, ADDR, DP, ALU, + RD_INC, ALU, ADDR, + RD, ALU2, ADDR, + SET_ADDR, ADDR, ALU, ALU2, + oper, dest, ADDR); + } + + private void REG_OP_LD_16(ushort dest) + { + PopulateCURINSTR(RD_INC, ALU, PC, + RD_INC_OP, ALU2, PC, SET_ADDR, dest, ALU, ALU2); + } + + private void REG_OP_LD_16D(ushort dest) + { + PopulateCURINSTR(RD_INC, A, PC, + RD_INC, B, PC); + } + private void EXG_() { PopulateCURINSTR(RD_INC, ALU, @@ -118,6 +174,16 @@ namespace BizHawk.Emulation.Common.Components.MC6809 } } + private void BSR_() + { + PopulateCURINSTR(RD_INC, ALU, PC, + ADD8BR, PC, ALU, + TR, ADDR, PC, + DEC16, SP, + WR_DEC_LO, SP, ADDR, + WR_HI, SP, ADDR); + } + private void LBSR_() { PopulateCURINSTR(RD_INC, ALU, PC,