X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fv6809.cpp;fp=src%2Fv6809.cpp;h=648d02b8d2f15ee5632cb545edc1c0e762add828;hb=b4e8ef6c5282d8763d7559370c007fa4c1219a54;hp=494b9f11abf117e749b37ab0c8204882fa5918f8;hpb=af27a070d6a36e5590c5d24ba255300825c25cf9;p=stargem2 diff --git a/src/v6809.cpp b/src/v6809.cpp index 494b9f1..648d02b 100755 --- a/src/v6809.cpp +++ b/src/v6809.cpp @@ -10,11 +10,15 @@ // --- ---------- ------------------------------------------------------------ // JLH 06/15/2006 Added changelog ;-) // JLH 06/15/2006 Scrubbed all BYTE, WORD & DWORD references from the code +// JLH 11/11/2006 Removed all SignedX() references // // Mebbe someday I'll get around to fixing the core to be more like V65C02... +// We have a start... ;-) // +#define __DEBUG__ + #include "v6809.h" #ifdef __DEBUG__ @@ -22,16 +26,69 @@ #include "log.h" // Temporary... #endif +// Various macros + +#define CLR_Z (regs.cc &= ~FLAG_Z) +#define CLR_ZN (regs.cc &= ~(FLAG_Z | FLAG_N)) +#define CLR_ZNC (regs.cc &= ~(FLAG_Z | FLAG_N | FLAG_C)) +#define CLR_V (regs.cc &= ~FLAG_V) +#define CLR_N (regs.cc &= ~FLAG_N) +#define SET_Z(r) (regs.cc = ((r) == 0 ? regs.cc | FLAG_Z : regs.cc & ~FLAG_Z)) +#define SET_N(r) (regs.cc = ((r) & 0x80 ? regs.cc | FLAG_N : regs.cc & ~FLAG_N)) + +//Not sure that this code is computing the carry correctly... Investigate! [Seems to be] +#define SET_C_ADD(a,b) (regs.cc = ((uint8)(b) > (uint8)(~(a)) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C)) +//#define SET_C_SUB(a,b) (regs.cc = ((uint8)(b) >= (uint8)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C)) +#define SET_C_CMP(a,b) (regs.cc = ((uint8)(b) >= (uint8)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C)) +#define SET_ZN(r) SET_N(r); SET_Z(r) +#define SET_ZNC_ADD(a,b,r) SET_N(r); SET_Z(r); SET_C_ADD(a,b) +//#define SET_ZNC_SUB(a,b,r) SET_N(r); SET_Z(r); SET_C_SUB(a,b) +#define SET_ZNC_CMP(a,b,r) SET_N(r); SET_Z(r); SET_C_CMP(a,b) + +//Small problem with the EA_ macros: ABS macros don't increment the PC!!! !!! FIX !!! +#define EA_IMM regs.pc++ +#define EA_ZP regs.RdMem(regs.pc++) +#define EA_ZP_X (regs.RdMem(regs.pc++) + regs.x) & 0xFF +#define EA_ZP_Y (regs.RdMem(regs.pc++) + regs.y) & 0xFF +#define EA_ABS RdMemW(regs.pc) +#define EA_ABS_X RdMemW(regs.pc) + regs.x +#define EA_ABS_Y RdMemW(regs.pc) + regs.y +#define EA_IND_ZP_X RdMemW((regs.RdMem(regs.pc++) + regs.x) & 0xFF) +#define EA_IND_ZP_Y RdMemW(regs.RdMem(regs.pc++)) + regs.y +#define EA_IND_ZP RdMemW(regs.RdMem(regs.pc++)) + +#define READ_IMM regs.RdMem(EA_IMM) +#define READ_ZP regs.RdMem(EA_ZP) +#define READ_ZP_X regs.RdMem(EA_ZP_X) +#define READ_ZP_Y regs.RdMem(EA_ZP_Y) +#define READ_ABS regs.RdMem(EA_ABS); regs.pc += 2 +#define READ_ABS_X regs.RdMem(EA_ABS_X); regs.pc += 2 +#define READ_ABS_Y regs.RdMem(EA_ABS_Y); regs.pc += 2 +#define READ_IND_ZP_X regs.RdMem(EA_IND_ZP_X) +#define READ_IND_ZP_Y regs.RdMem(EA_IND_ZP_Y) +#define READ_IND_ZP regs.RdMem(EA_IND_ZP) + +#define READ_IMM_WB(v) uint16 addr = EA_IMM; v = regs.RdMem(addr) +#define READ_ZP_WB(v) uint16 addr = EA_ZP; v = regs.RdMem(addr) +#define READ_ZP_X_WB(v) uint16 addr = EA_ZP_X; v = regs.RdMem(addr) +#define READ_ABS_WB(v) uint16 addr = EA_ABS; v = regs.RdMem(addr); regs.pc += 2 +#define READ_ABS_X_WB(v) uint16 addr = EA_ABS_X; v = regs.RdMem(addr); regs.pc += 2 +#define READ_ABS_Y_WB(v) uint16 addr = EA_ABS_Y; v = regs.RdMem(addr); regs.pc += 2 +#define READ_IND_ZP_X_WB(v) uint16 addr = EA_IND_ZP_X; v = regs.RdMem(addr) +#define READ_IND_ZP_Y_WB(v) uint16 addr = EA_IND_ZP_Y; v = regs.RdMem(addr) +#define READ_IND_ZP_WB(v) uint16 addr = EA_IND_ZP; v = regs.RdMem(addr) + +#define WRITE_BACK(d) regs.WrMem(addr, (d)) + // Private global variables static V6809REGS regs; +//Let's see if we can nuke this shit. static uint16 addr; // Temporary variables common to all funcs... static uint8 tmp; // Private function prototypes -static int SignedB(uint8); // Return signed byte from unsigned -static int SignedW(uint16); // Return signed word from unsigned static uint16 FetchW(void); static uint16 RdMemW(uint16 addr); static void WrMemW(uint16 addr, uint16 w); @@ -186,22 +243,6 @@ void WrMemW(uint16 addr, uint16 w) regs.WrMem(addr + 1, w & 0xFF); } -// -// return signed byte from unsigned -// -int SignedB(uint8 b) -{ - return (b & 0x80 ? b - 256 : b); -} - -// -// return signed word from unsigned -// -int SignedW(uint16 w) -{ - return (w & 0x8000 ? w - 65536 : w); -} - // // Function to read TFR/EXG post byte // @@ -343,31 +384,38 @@ uint16 DecodeIDX(uint8 code) addr = RdMemW(woff); break; case 5: - woff = DecodeReg(reg) + SignedB(regs.b); +// woff = DecodeReg(reg) + SignedB(regs.b); + woff = DecodeReg(reg) + (int16)(int8)regs.b; addr = RdMemW(woff); break; case 6: - woff = DecodeReg(reg) + SignedB(regs.a); +// woff = DecodeReg(reg) + SignedB(regs.a); + woff = DecodeReg(reg) + (int16)(int8)regs.a; addr = RdMemW(woff); break; case 8: - woff = DecodeReg(reg) + SignedB(regs.RdMem(regs.pc++)); +// woff = DecodeReg(reg) + SignedB(regs.RdMem(regs.pc++)); + woff = DecodeReg(reg) + (int16)(int8)regs.RdMem(regs.pc++); addr = RdMemW(woff); break; case 9: - woff = DecodeReg(reg) + SignedW(FetchW()); +// woff = DecodeReg(reg) + SignedW(FetchW()); + woff = DecodeReg(reg) + FetchW(); addr = RdMemW(woff); break; case 11: - woff = DecodeReg(reg) + SignedW((regs.a << 8) | regs.b); +// woff = DecodeReg(reg) + SignedW((regs.a << 8) | regs.b); + woff = DecodeReg(reg) + ((regs.a << 8) | regs.b); addr = RdMemW(woff); break; case 12: - woff = regs.pc + SignedB(regs.RdMem(regs.pc++)); +// woff = regs.pc + SignedB(regs.RdMem(regs.pc++)); + woff = regs.pc + (int16)(int8)regs.RdMem(regs.pc++); addr = RdMemW(woff); break; case 13: - woff = regs.pc + SignedW(FetchW()); +// woff = regs.pc + SignedW(FetchW()); + woff = regs.pc + FetchW(); addr = RdMemW(woff); break; case 15: @@ -417,13 +465,20 @@ uint16 DecodeIDX(uint8 code) } addr = DecodeReg(reg); break; } case 4: { addr = DecodeReg(reg); break; } - case 5: { addr = DecodeReg(reg) + SignedB(regs.b); break; } - case 6: { addr = DecodeReg(reg) + SignedB(regs.a); break; } - case 8: { addr = DecodeReg(reg) + SignedB(regs.RdMem(regs.pc++)); break; } - case 9: { addr = DecodeReg(reg) + SignedW(FetchW()); break; } - case 11: { addr = DecodeReg(reg) + SignedW((regs.a << 8) | regs.b); break; } - case 12: { addr = regs.pc + SignedB(regs.RdMem(regs.pc++)); break; } - case 13: { addr = regs.pc + SignedW(FetchW()); break; } +// case 5: { addr = DecodeReg(reg) + SignedB(regs.b); break; } + case 5: { addr = DecodeReg(reg) + (int16)(int8)regs.b; break; } +// case 6: { addr = DecodeReg(reg) + SignedB(regs.a); break; } + case 6: { addr = DecodeReg(reg) + (int16)(int8)regs.a; break; } +// case 8: { addr = DecodeReg(reg) + SignedB(regs.RdMem(regs.pc++)); break; } + case 8: { addr = DecodeReg(reg) + (int16)(int8)regs.RdMem(regs.pc++); break; } +// case 9: { addr = DecodeReg(reg) + SignedW(FetchW()); break; } + case 9: { addr = DecodeReg(reg) + FetchW(); break; } +// case 11: { addr = DecodeReg(reg) + SignedW((regs.a << 8) | regs.b); break; } + case 11: { addr = DecodeReg(reg) + ((regs.a << 8) | regs.b); break; } +// case 12: { addr = regs.pc + SignedB(regs.RdMem(regs.pc++)); break; } + case 12: { addr = regs.pc + (int16)(int8)regs.RdMem(regs.pc++); break; } +// case 13: { addr = regs.pc + SignedW(FetchW()); break; } + case 13: { addr = regs.pc + FetchW(); break; } } } } @@ -565,32 +620,41 @@ static void Op10(void) // Page 1 opcode exec_op1[regs.RdMem(regs.pc++)](); } -static void Op11(void) // Page 2 opcode +static void Op11(void) // Page 2 opcode { exec_op2[regs.RdMem(regs.pc++)](); } -static void Op12(void) // NOP +static void Op12(void) // NOP { regs.clock += 2; } -static void Op13(void) // SYNC -{ - regs.clock += 2; +static void Op13(void) // SYNC +{ + // Fix this so it does the right thing (software interrupt!) + regs.clock += 2; } -static void Op16(void) // LBRA + +static void Op16(void) // LBRA { - regs.pc += SignedW(FetchW()); - regs.clock += 5; +// regs.pc += SignedW(FetchW()); + regs.pc += FetchW(); // No need to make signed, both are 16 bit quantities + + regs.clock += 5; } -static void Op17(void) // LBSR + +static void Op17(void) // LBSR { - addr = FetchW(); - regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); - regs.pc += SignedW(addr); - regs.clock += 9; + uint16 word = FetchW(); + regs.WrMem(--regs.s, regs.pc & 0xFF); + regs.WrMem(--regs.s, regs.pc >> 8); +// regs.pc += SignedW(addr); + regs.pc += word; // No need to make signed, both are 16 bit + + regs.clock += 9; } + static void Op19(void) // DAA { if ((regs.cc&0x20) || ((regs.a&0x0F) > 0x09)) // H set or lo nyb too big? @@ -621,7 +685,7 @@ static void Op1C(void) // ANDCC # regs.clock += 3; } -static void Op1D(void) // SEX +static void Op1D(void) // SEX { (regs.b & 0x80 ? regs.a = 0xFF : regs.a = 0x00); @@ -631,7 +695,7 @@ static void Op1D(void) // SEX regs.clock += 2; } -static void Op1E(void) // EXG +static void Op1E(void) // EXG { tmp = regs.RdMem(regs.pc++); addr = ReadEXG(tmp >> 4); @@ -647,100 +711,162 @@ static void Op1F(void) // TFR WriteEXG(tmp&0xF, ReadEXG(tmp>>4)); regs.clock += 7; } -static void Op20(void) // BRA + +static void Op20(void) // BRA { - regs.pc += SignedB(regs.RdMem(regs.pc++)); // Branch always - regs.clock += 3; +// regs.pc += SignedB(regs.RdMem(regs.pc++)); // Branch always + regs.pc += (int16)(int8)regs.RdMem(regs.pc) + 1; // Branch always + + regs.clock += 3; } -static void Op21(void) // BRN + +static void Op21(void) // BRN { - regs.RdMem(regs.pc++); - regs.clock += 3; + regs.RdMem(regs.pc++); + + regs.clock += 3; } -static void Op22(void) // BHI + +static void Op22(void) // BHI { - tmp = regs.RdMem(regs.pc++); - if (!(regs.cc&0x05)) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (!(regs.cc & 0x05)) + regs.pc += word; + + regs.clock += 3; } -static void Op23(void) // BLS + +static void Op23(void) // BLS { - tmp = regs.RdMem(regs.pc++); - if (regs.cc&0x05) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (regs.cc & 0x05) + regs.pc += word; + + regs.clock += 3; } -static void Op24(void) // BCC (BHS) + +static void Op24(void) // BCC (BHS) { - tmp = regs.RdMem(regs.pc++); - if (!(regs.cc&0x01)) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (!(regs.cc & 0x01)) + regs.pc += word; + + regs.clock += 3; } -static void Op25(void) // BCS (BLO) + +static void Op25(void) // BCS (BLO) { - tmp = regs.RdMem(regs.pc++); - if (regs.cc&0x01) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (regs.cc & 0x01) + regs.pc += word; + + regs.clock += 3; } -static void Op26(void) // BNE + +static void Op26(void) // BNE { - tmp = regs.RdMem(regs.pc++); - if (!(regs.cc&0x04)) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (!(regs.cc & 0x04)) + regs.pc += word; + + regs.clock += 3; } -static void Op27(void) // BEQ + +static void Op27(void) // BEQ { - tmp = regs.RdMem(regs.pc++); - if (regs.cc&0x04) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (regs.cc & 0x04) + regs.pc += word; + + regs.clock += 3; } -static void Op28(void) // BVC + +static void Op28(void) // BVC { - tmp = regs.RdMem(regs.pc++); - if (!(regs.cc&0x02)) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (!(regs.cc & 0x02)) + regs.pc += word; + + regs.clock += 3; } -static void Op29(void) // BVS + +static void Op29(void) // BVS { - tmp = regs.RdMem(regs.pc++); - if (regs.cc&0x02) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (regs.cc & 0x02) + regs.pc += word; + + regs.clock += 3; } -static void Op2A(void) // BPL + +static void Op2A(void) // BPL { - tmp = regs.RdMem(regs.pc++); - if (!(regs.cc&0x08)) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (!(regs.cc & 0x08)) + regs.pc += word; + + regs.clock += 3; } -static void Op2B(void) // BMI + +static void Op2B(void) // BMI { - tmp = regs.RdMem(regs.pc++); - if (regs.cc&0x08) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (regs.cc & 0x08) + regs.pc += word; + + regs.clock += 3; } -static void Op2C(void) // BGE + +static void Op2C(void) // BGE { - tmp = regs.RdMem(regs.pc++); - if (!(((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))) + regs.pc += word; + + regs.clock += 3; } -static void Op2D(void) // BLT + +static void Op2D(void) // BLT { - tmp = regs.RdMem(regs.pc++); - if (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)) + regs.pc += word; + + regs.clock += 3; } -static void Op2E(void) // BGT + +static void Op2E(void) // BGT { - tmp = regs.RdMem(regs.pc++); - if (!((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)))) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))) + regs.pc += word; + + regs.clock += 3; } -static void Op2F(void) // BLE + +static void Op2F(void) // BLE { - tmp = regs.RdMem(regs.pc++); - if ((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if ((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))) + regs.pc += word; + + regs.clock += 3; } + static void Op30(void) // LEAX { regs.x = DecodeIDX(regs.RdMem(regs.pc++)); @@ -1394,13 +1520,17 @@ static void Op8C(void) // CMPX # (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag regs.clock += 4; } -static void Op8D(void) // Bregs.s - { - tmp = regs.RdMem(regs.pc++); - regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); - regs.pc += SignedB(tmp); - regs.clock += 7; - } + +static void Op8D(void) // Bregs.s +{ + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + regs.WrMem(--regs.s, regs.pc & 0xFF); + regs.WrMem(--regs.s, regs.pc >> 8); + regs.pc += word; + + regs.clock += 7; +} + static void Op8E(void) // LDX # { regs.x = FetchW(); @@ -2445,95 +2575,153 @@ static void OpFF(void) // STU ABS // Page one opcodes' execute code // -static void Op1021(void) // LBRN +static void Op1021(void) // LBRN { - addr = FetchW(); - regs.clock += 5; + addr = FetchW(); + + regs.clock += 5; } -static void Op1022(void) // LBHI + +static void Op1022(void) // LBHI { - addr = FetchW(); - if (!((regs.cc&0x01)|(regs.cc&0x04))) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if (!((regs.cc & 0x01) | (regs.cc & 0x04))) + regs.pc += word; + + regs.clock += 5; } -static void Op1023(void) // LBLS + +static void Op1023(void) // LBLS { - addr = FetchW(); - if ((regs.cc&0x01)|(regs.cc&0x04)) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if ((regs.cc & 0x01) | (regs.cc & 0x04)) + regs.pc += word; + + regs.clock += 5; } -static void Op1024(void) // LBCC (LBHS) + +static void Op1024(void) // LBCC (LBHS) { - addr = FetchW(); - if (!(regs.cc&0x01)) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if (!(regs.cc & 0x01)) + regs.pc += word; + + regs.clock += 5; } -static void Op1025(void) // LBCS (LBLO) + +static void Op1025(void) // LBCS (LBLO) { - addr = FetchW(); - if (regs.cc&0x01) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if (regs.cc & 0x01) + regs.pc += word; + + regs.clock += 5; } -static void Op1026(void) // LBNE + +static void Op1026(void) // LBNE { - addr = FetchW(); - if (!(regs.cc&0x04)) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if (!(regs.cc & 0x04)) + regs.pc += word; + + regs.clock += 5; } -static void Op1027(void) // LBEQ + +static void Op1027(void) // LBEQ { - addr = FetchW(); - if (regs.cc&0x04) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if (regs.cc & 0x04) + regs.pc += word; + + regs.clock += 5; } -static void Op1028(void) // LBVC + +static void Op1028(void) // LBVC { - addr = FetchW(); - if (!(regs.cc&0x02)) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if (!(regs.cc & 0x02)) + regs.pc += word; + + regs.clock += 5; } -static void Op1029(void) // LBVS + +static void Op1029(void) // LBVS { - addr = FetchW(); - if (regs.cc&0x02) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if (regs.cc & 0x02) + regs.pc += word; + + regs.clock += 5; } -static void Op102A(void) // LBPL + +static void Op102A(void) // LBPL { - addr = FetchW(); - if (!(regs.cc&0x08)) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if (!(regs.cc & 0x08)) + regs.pc += word; + + regs.clock += 5; } -static void Op102B(void) // LBMI + +static void Op102B(void) // LBMI { - addr = FetchW(); - if (regs.cc&0x08) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if (regs.cc & 0x08) + regs.pc += word; + + regs.clock += 5; } -static void Op102C(void) // LBGE + +static void Op102C(void) // LBGE { - addr = FetchW(); - if (!(((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))) + regs.pc += word; + + regs.clock += 5; } -static void Op102D(void) // LBLT + +static void Op102D(void) // LBLT { - addr = FetchW(); - if (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)) + regs.pc += word; + + regs.clock += 5; } -static void Op102E(void) // LBGT + +static void Op102E(void) // LBGT { - addr = FetchW(); - if (!((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)))) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))) + regs.pc += word; + + regs.clock += 5; } -static void Op102F(void) // LBLE + +static void Op102F(void) // LBLE { - addr = FetchW(); - if ((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if ((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))) + regs.pc += word; + + regs.clock += 5; } + static void Op103F(void) // SWI2 (Not yet implemented) { regs.clock += 20; @@ -2846,20 +3034,24 @@ static void Op11BC(void) // CMPS ABS } //temp, for testing... -/*static uint8 backTrace[256]; +#ifdef __DEBUG__ +static uint8 backTrace[256]; static uint16 btPC[256]; static int btPtr = 0;//*/ +#endif static void Op__(void) // Illegal opcode { regs.clock++; // illegal = true; regs.cpuFlags |= V6809_STATE_ILLEGAL_INST; +#ifdef __DEBUG__ /*WriteLog("V6809: Executed illegal opcode %02X at PC=%04X...\n\nBacktrace:\n\n", regs.RdMem(regs.pc - 1), regs.pc - 1); for(int i=0; i<256; i++) { - dpc = btPC[(btPtr+i)&0xFF]; - Decode_6809(); + Decode6809(btPC[(btPtr + i) & 0xFF]); + WriteLog("\n"); }//*/ +#endif } @@ -2884,15 +3076,20 @@ void Execute6809(V6809REGS * context, uint32 cycles) // Execute here... while (regs.clock < cycles) { -/*static bool disasm = false; -if (regs.pc == 0x15BA) disasm = true; -if (disasm) { dpc = regs.pc; Decode_6809(); } -if (regs.pc == 0x164A) disasm = false;//*/ +#ifdef __DEBUG__ +//Decode6809(regs.pc); +static bool disasm = false; +/*//if (regs.pc == 0x15BA) disasm = true; +//if (regs.pc == 0xFE76) disasm = true; +if (regs.x == 0xFED4) disasm = true; +if (disasm) Decode6809(regs.pc); +//if (regs.pc == 0x164A) disasm = false;//*/ //temp, for testing... /*backTrace[btPtr] = regs.RdMem(regs.pc); btPC[btPtr] = regs.pc; -btPtr = (btPtr++) & 0xFF;//*/ +btPtr = (btPtr + 1) & 0xFF;//*/ +#endif exec_op0[regs.RdMem(regs.pc++)](); // Handle any pending interrupts @@ -2901,6 +3098,9 @@ btPtr = (btPtr++) & 0xFF;//*/ if (flags & V6809_ASSERT_LINE_RESET) // *** RESET handler *** { +#ifdef __DEBUG__ +if (disasm) WriteLog("\nV6809: RESET line asserted!\n"); +#endif regs.cc |= (FLAG_F | FLAG_I); // Set F, I regs.dp = 0; // Reset direct page register regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector @@ -2909,6 +3109,9 @@ btPtr = (btPtr++) & 0xFF;//*/ } else if (flags & V6809_ASSERT_LINE_NMI) // *** NMI handler *** { +#ifdef __DEBUG__ +if (disasm) WriteLog("\nV6809: NMI line asserted!\n"); +#endif regs.cc |= FLAG_E; // Set the Entire flag regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs... @@ -2932,8 +3135,14 @@ btPtr = (btPtr++) & 0xFF;//*/ } else if (flags & V6809_ASSERT_LINE_FIRQ) // *** FIRQ handler *** { +#ifdef __DEBUG__ +if (disasm) WriteLog("\nV6809: FIRQ line asserted!\n"); +#endif if (!(regs.cc & FLAG_F)) // Is the FIRQ masked (F == 1)? { +#ifdef __DEBUG__ +if (disasm) WriteLog(" FIRQ taken...\n"); +#endif regs.cc &= ~FLAG_E; // Clear the Entire flag regs.WrMem(--regs.s, regs.pc & 0xFF); // Save PC, CC regs... @@ -2949,8 +3158,14 @@ btPtr = (btPtr++) & 0xFF;//*/ } else if (flags & V6809_ASSERT_LINE_IRQ) // *** IRQ handler *** { +#ifdef __DEBUG__ +if (disasm) WriteLog("\nV6809: IRQ line asserted!\n"); +#endif if (!(regs.cc & FLAG_I)) // Is the IRQ masked (I == 1)? { +#ifdef __DEBUG__ +if (disasm) WriteLog(" IRQ taken...\n"); +#endif regs.cc |= FLAG_E; // Set the Entire flag regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs... @@ -2973,8 +3188,12 @@ btPtr = (btPtr++) & 0xFF;//*/ regs.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)... } } -/*if (disasm) WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n", +#ifdef __DEBUG__ +if (disasm) WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n", + regs.a, regs.b, regs.cc, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/ +/*WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n", regs.a, regs.b, regs.cc, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/ +#endif } myMemcpy(context, ®s, sizeof(V6809REGS));