X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fv6809.cpp;h=bd929269859d459a100681a8005a65807a74f72e;hb=8ba4c4438d796f83851cd53914dff928193ed658;hp=a6c07fcd40f0ad1899be1e3abc4387b97df9ebe1;hpb=d22f243fc585a46e4c29d00bd32727d9f9f4055c;p=thunder diff --git a/src/v6809.cpp b/src/v6809.cpp old mode 100755 new mode 100644 index a6c07fc..bd92926 --- a/src/v6809.cpp +++ b/src/v6809.cpp @@ -1,10 +1,10 @@ // -// Virtual 6809 v1.4.1 +// Virtual 6809 v1.4.2 // -// by James L. Hammons -// (C) 1997, 2009, 2014 Underground Software +// by James Hammons +// (C) 1997, 2009, 2014, 2023 Underground Software // -// JLH = James L. Hammons +// JLH = James Hammons // // WHO WHEN WHAT // --- ---------- ----------------------------------------------------------- @@ -13,18 +13,11 @@ // JLH 11/11/2006 Removed all SignedX() references // JLH 09/29/2009 Converted V6809 to macro implementation! // JLH 04/17/2014 Misc. cleanups, fixes to missing instructions +// JLH 01/03/2023 Added missing clock cycles to indexed memory accesses // -#define __DEBUG__ - #include "v6809.h" -#ifdef __DEBUG__ -#include "dis6809.h" // Temporary... -#include "log.h" // Temporary... -bool disasm = false;//so we can extern this shit -#endif - #define TEST_DONT_BRANCH_OPTIMIZATION // Various macros @@ -40,16 +33,8 @@ bool disasm = false;//so we can extern this shit #define SET_V(a,b,r) (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x80) >> 7) #define SET_V16(a,b,r) (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x8000) >> 15) #define SET_H(a,b,r) (flagH = (((a) ^ (b) ^ (r)) & 0x10) >> 4) - -//Not sure that this code is computing the carry correctly... Investigate! [Seems to be] -//#define SET_C_ADD(a,b) (flagC = ((uint8_t)(b) > (uint8_t)(~(a)) ? 1 : 0)) -//#define SET_C_SUB(a,b) (regs.cc = ((uint8_t)(b) >= (uint8_t)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C)) -//#define SET_C_CMP(a,b) (flagC = ((uint8_t)(b) >= (uint8_t)(a) ? 1 : 0)) #define SET_ZN(r) SET_N(r); SET_Z(r) #define SET_ZN16(r) SET_N16(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) #define EA_IMM regs.pc++ #define EA_DP (regs.dp << 8) | regs.RdMem(regs.pc++) @@ -153,6 +138,9 @@ static const uint8_t page2Cycles[256] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // $Fx }; +// Cycle counts for PUL/PSHx instructions +static uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; + // Private function prototypes static uint16_t RdMemW(uint16_t addr); @@ -163,7 +151,6 @@ static void WriteEXG(uint8_t, uint16_t); // Set TFR/EXG data static uint16_t DecodeReg(uint8_t); // Decode register data static uint16_t DecodeIDX(uint8_t); // Decode IDX data - // // Read word from memory function // @@ -172,7 +159,6 @@ static inline uint16_t RdMemW(uint16_t addr) return (uint16_t)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1); } - // // Fetch a word from memory function. Increments PC // @@ -182,7 +168,6 @@ static inline uint16_t FetchMemW(uint16_t addr) return (uint16_t)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1); } - // // Write word to memory function // @@ -192,7 +177,6 @@ static inline void WrMemW(uint16_t addr, uint16_t w) regs.WrMem(addr + 1, w & 0xFF); } - // // Function to read TFR/EXG post byte // @@ -240,7 +224,6 @@ static uint16_t ReadEXG(uint8_t code) return retval; } - // // Function to set TFR/EXG data // @@ -271,7 +254,6 @@ static void WriteEXG(uint8_t code, uint16_t data) } } - // // Function to decode register data // @@ -294,17 +276,34 @@ static uint16_t DecodeReg(uint8_t reg) return retval; } - // // Function to decode IDX data // static uint16_t DecodeIDX(uint8_t code) { +/* +Cycle counts are now taken into account here... + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F +90 5 6 5 6 3 4 4 0 4 7 0 7 4 8 0 5 +B0 5 6 5 6 3 4 4 0 4 7 0 7 4 8 0 5 +D0 5 6 5 6 3 4 4 0 4 7 0 7 4 8 0 5 +F0 5 6 5 6 3 4 4 0 4 7 0 7 4 8 0 5 + +80 2 3 2 3 0 1 1 0 1 4 0 4 1 5 0 5 +A0 2 3 2 3 0 1 1 0 1 4 0 4 1 5 0 5 +C0 2 3 2 3 0 1 1 0 1 4 0 4 1 5 0 5 +E0 2 3 2 3 0 1 1 0 1 4 0 4 1 5 0 5 +*/ uint16_t addr, woff; + int16_t offset; uint8_t reg = (code & 0x60) >> 5, idxind = (code & 0x10) >> 4, lo_nyb = code & 0x0F; if (!(code & 0x80)) // Hi bit unset? Then decode 4 bit offset + { addr = DecodeReg(reg) + (idxind ? lo_nyb - 16 : lo_nyb); + regs.clock++; + } else { if (idxind) @@ -321,6 +320,7 @@ static uint16_t DecodeIDX(uint8_t code) case 2: regs.u += 2; break; case 3: regs.s += 2; break; } + regs.clock += 6; break; case 3: switch (reg) @@ -332,45 +332,63 @@ static uint16_t DecodeIDX(uint8_t code) } woff = DecodeReg(reg); addr = RdMemW(woff); + regs.clock += 6; break; case 4: woff = DecodeReg(reg); addr = RdMemW(woff); + regs.clock += 3; break; case 5: woff = DecodeReg(reg) + (int16_t)(int8_t)regs.b; addr = RdMemW(woff); + regs.clock += 4; break; case 6: woff = DecodeReg(reg) + (int16_t)(int8_t)regs.a; addr = RdMemW(woff); + regs.clock += 4; break; case 8: woff = DecodeReg(reg) + (int16_t)(int8_t)regs.RdMem(regs.pc++); addr = RdMemW(woff); + regs.clock += 4; break; case 9: woff = DecodeReg(reg) + FetchMemW(regs.pc); addr = RdMemW(woff); + regs.clock += 7; break; case 11: woff = DecodeReg(reg) + ((regs.a << 8) | regs.b); addr = RdMemW(woff); + regs.clock += 7; break; case 12: // woff = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++); +#if 1 + // I believe this is the correct interpretation + offset = (int16_t)(int8_t)regs.RdMem(regs.pc++); + woff = regs.pc + offset; +#else woff = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc); regs.pc++; +#endif addr = RdMemW(woff); + regs.clock += 4; break; case 13: woff = regs.pc + FetchMemW(regs.pc); addr = RdMemW(woff); + regs.clock += 8; break; case 15: woff = FetchMemW(regs.pc); addr = RdMemW(woff); + regs.clock += 5; break; + default: + addr = 0; } } else @@ -386,6 +404,7 @@ static uint16_t DecodeIDX(uint8_t code) case 2: regs.u++; break; case 3: regs.s++; break; } + regs.clock += 2; break; case 1: addr = DecodeReg(reg); @@ -396,32 +415,71 @@ static uint16_t DecodeIDX(uint8_t code) case 2: regs.u += 2; break; case 3: regs.s += 2; break; } + regs.clock += 3; + break; + case 2: + switch(reg) + { + case 0: regs.x--; break; + case 1: regs.y--; break; + case 2: regs.u--; break; + case 3: regs.s--; break; + } + addr = DecodeReg(reg); + regs.clock += 2; + break; + case 3: + switch(reg) + { + case 0: regs.x -= 2; break; + case 1: regs.y -= 2; break; + case 2: regs.u -= 2; break; + case 3: regs.s -= 2; break; + } + addr = DecodeReg(reg); + regs.clock += 3; + break; + case 4: + addr = DecodeReg(reg); + break; + case 5: + addr = DecodeReg(reg) + (int16_t)(int8_t)regs.b; + regs.clock++; + break; + case 6: + addr = DecodeReg(reg) + (int16_t)(int8_t)regs.a; + regs.clock++; break; - case 2: { switch(reg) - { - case 0: regs.x--; break; - case 1: regs.y--; break; - case 2: regs.u--; break; - case 3: regs.s--; break; - } - addr = DecodeReg(reg); break; } - case 3: { switch(reg) - { - case 0: regs.x--; regs.x--; break; - case 1: regs.y--; regs.y--; break; - case 2: regs.u--; regs.u--; break; - case 3: regs.s--; regs.s--; break; - } - addr = DecodeReg(reg); break; } - case 4: { addr = DecodeReg(reg); break; } - case 5: { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.b; break; } - case 6: { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.a; break; } - case 8: { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.RdMem(regs.pc++); break; } - case 9: { addr = DecodeReg(reg) + FetchMemW(regs.pc); break; } - case 11: { addr = DecodeReg(reg) + ((regs.a << 8) | regs.b); break; } -// case 12: { addr = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++); break; } - case 12: { addr = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc); regs.pc++; break; } - case 13: { addr = regs.pc + FetchMemW(regs.pc); break; } + case 8: + addr = DecodeReg(reg) + (int16_t)(int8_t)regs.RdMem(regs.pc++); + regs.clock++; + break; + case 9: + addr = DecodeReg(reg) + FetchMemW(regs.pc); + regs.clock += 4; + break; + case 11: + addr = DecodeReg(reg) + ((regs.a << 8) | regs.b); + regs.clock += 4; + break; + case 12: +// addr = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++); +#if 1 + // I believe this is the correct interpretation of the above + offset = (int16_t)(int8_t)regs.RdMem(regs.pc++); + addr = regs.pc + offset; +#else + addr = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc); + regs.pc++; +#endif + regs.clock++; + break; + case 13: + addr = regs.pc + FetchMemW(regs.pc); + regs.clock += 5; + break; + default: + addr = 0; } } } @@ -464,72 +522,54 @@ static uint16_t DecodeIDX(uint8_t code) acc = sum & 0xFF; \ SET_ZN(acc) -/* -Old flag handling code: - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry - ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.a = addr & 0xFF; // Set accumulator - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative -*/ - static void Op89(void) // ADCA # { uint16_t m = READ_IMM; OP_ADC_HANDLER(m, regs.a); } - static void Op99(void) // ADCA DP { uint16_t m = READ_DP; OP_ADC_HANDLER(m, regs.a); } - static void OpA9(void) // ADCA IDX { uint16_t m = READ_IDX; OP_ADC_HANDLER(m, regs.a); } - static void OpB9(void) // ADCA ABS { uint16_t m = READ_ABS; OP_ADC_HANDLER(m, regs.a); } - static void OpC9(void) // ADCB # { uint16_t m = READ_IMM; OP_ADC_HANDLER(m, regs.b); } - static void OpD9(void) // ADCB DP { uint16_t m = READ_DP; OP_ADC_HANDLER(m, regs.b); } - static void OpE9(void) // ADCB IDX { uint16_t m = READ_IDX; OP_ADC_HANDLER(m, regs.b); } - static void OpF9(void) // ADCB ABS { uint16_t m = READ_ABS; OP_ADC_HANDLER(m, regs.b); } - /* +-----------------------------------------------------------------+ | Opcode | | Addressing | | | @@ -570,115 +610,83 @@ static void OpF9(void) // ADCB ABS loreg = acc & 0xFF; \ SET_ZN16(acc) -/* -Old flags: - (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.a = addr & 0xFF; // Set accumulator - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag - - dr += addr; - (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - dr &= 0xFFFF; - (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.a = dr>>8; regs.b = dr&0xFF; - regs.clock += 4; -*/ - static void Op3A(void) // ABX { regs.x += (uint16_t)regs.b; } - static void Op8B(void) // ADDA # { uint16_t m = READ_IMM; OP_ADD_HANDLER(m, regs.a); } - static void Op9B(void) // ADDA DP { uint16_t m = READ_DP; OP_ADD_HANDLER(m, regs.a); } - static void OpAB(void) // ADDA IDX { uint16_t m = READ_IDX; OP_ADD_HANDLER(m, regs.a); } - static void OpBB(void) // ADDA ABS { uint16_t m = READ_ABS; OP_ADD_HANDLER(m, regs.a); } - static void OpC3(void) // ADDD # { uint32_t m = READ_IMM16; OP_ADD_HANDLER16(m, regs.a, regs.b); } - static void OpCB(void) // ADDB # { uint16_t m = READ_IMM; OP_ADD_HANDLER(m, regs.b); } - static void OpD3(void) // ADDD DP { uint32_t m = READ_DP16; OP_ADD_HANDLER16(m, regs.a, regs.b); } - static void OpDB(void) // ADDB DP { uint16_t m = READ_DP; OP_ADD_HANDLER(m, regs.b); } - static void OpE3(void) // ADDD IDX { uint32_t m = READ_IDX16; OP_ADD_HANDLER16(m, regs.a, regs.b); } - static void OpEB(void) // ADDB IDX { uint16_t m = READ_IDX; OP_ADD_HANDLER(m, regs.b); } - static void OpF3(void) // ADDD ABS { uint32_t m = READ_ABS16; OP_ADD_HANDLER16(m, regs.a, regs.b); } - static void OpFB(void) // ADDB ABS { uint16_t m = READ_ABS; OP_ADD_HANDLER(m, regs.b); } - /* +-----------------------------------------------------------------+ | Opcode | | Addressing | | | @@ -961,8 +969,6 @@ static void Op25(void) // BLO/CS { // C int16_t offset = (int16_t)(int8_t)READ_IMM; -//if (disasm) -// WriteLog("[offset=%04X,flagC=%08X]", offset, flagC); #ifdef TEST_DONT_BRANCH_OPTIMIZATION regs.pc += offset * flagC; @@ -1745,7 +1751,7 @@ static void Op3C(void) // CWAI static void Op3E(void) // RESET { - regs.cpuFlags |= V6809_ASSERT_LINE_RESET; + regs.cpuFlags |= V6809_LINE_RESET; } static void Op3F(void) // SWI @@ -1810,21 +1816,13 @@ static void Op12() // NOP { } -/* -D3F8: A6 47 LDA (7),U CC=--H----- A=30 B=00 DP=9C X=3C72 Y=CE5C S=BFFF U=BAF0 PC=D3FA -D3FA: 8B 01 ADDA #$01 CC=--H----- A=31 B=00 DP=9C X=3C72 Y=CE5C S=BFFF U=BAF0 PC=D3FC -D3FC: 19 DAA CC=--H----- A=37 B=00 DP=9C X=3C72 Y=CE5C S=BFFF U=BAF0 PC=D3FD -*/ - static void Op19() // DAA { uint16_t result = (uint16_t)regs.a; -// if ((regs.a & 0x0F) > 0x09 || (regs.cc & FLAG_H)) if ((regs.a & 0x0F) > 0x09 || flagH) result += 0x06; -// if ((regs.a & 0xF0) > 0x90 || (regs.cc & FLAG_C) || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09)) if ((regs.a & 0xF0) > 0x90 || flagC || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09)) result += 0x60; @@ -2005,19 +2003,16 @@ static void Op0C(void) // INC DP WRITE_BACK(m); } - static void Op4C(void) // INCA { OP_INC_HANDLER(regs.a); } - static void Op5C(void) // INCB { OP_INC_HANDLER(regs.b); } - static void Op6C(void) // INC IDX { uint8_t m; @@ -2026,7 +2021,6 @@ static void Op6C(void) // INC IDX WRITE_BACK(m); } - static void Op7C(void) // INC ABS { uint8_t m; @@ -2035,7 +2029,6 @@ static void Op7C(void) // INC ABS WRITE_BACK(m); } - /* +-----------------------------------------------------------------+ | Opcode | | Addressing | | | @@ -2060,7 +2053,6 @@ static void Op0E(void) // JMP DP regs.pc = m; } - static void Op17(void) // LBSR { uint16_t word = FetchMemW(regs.pc); @@ -2068,13 +2060,11 @@ static void Op17(void) // LBSR regs.pc += word; } - static void Op39(void) // RTS { PULLS16(regs.pc); } - static void Op3B(void) // RTI { PULLS(regs.cc); @@ -2095,19 +2085,16 @@ static void Op3B(void) // RTI PULLS16(regs.pc); } - static void Op6E(void) // JMP IDX { regs.pc = EA_IDX; } - static void Op7E(void) // JMP ABS { regs.pc = EA_ABS; } - static void Op8D(void) // BSR { uint16_t word = (int16_t)(int8_t)READ_IMM; @@ -2115,7 +2102,6 @@ static void Op8D(void) // BSR regs.pc += word; } - static void Op9D(void) // JSR DP { uint16_t word = EA_DP; @@ -2123,7 +2109,6 @@ static void Op9D(void) // JSR DP regs.pc = word; } - static void OpAD(void) // JSR IDX { uint16_t word = EA_IDX; @@ -2131,7 +2116,6 @@ static void OpAD(void) // JSR IDX regs.pc = word; } - static void OpBD(void) // JSR ABS { uint16_t word = EA_ABS; @@ -2139,7 +2123,6 @@ static void OpBD(void) // JSR ABS regs.pc = word; } - /* +-----------------------------------------------------------------+ | Opcode | | Addressing | | | @@ -2524,16 +2507,6 @@ static void Op3D(void) // MUL flagC = (res >= 0x80 ? 1 : 0); \ m = res -/* - UINT16 r,t; - DIRBYTE(t); - r = -t; - CLR_NZVC; - SET_FLAGS8(0,t,r); - WM(EAD,r); -#define SET_FLAGS8(a,b,r) {SET_N8(r);SET_Z8(r);SET_V8(a,b,r);SET_C8(r);} -#define SET_C8(a) CC|=((a&0x100)>>8) -*/ static void Op00(void) // NEG DP { uint8_t m; @@ -2674,7 +2647,6 @@ static void Op34(void) // PSHS } // Count bits in each nybble to come up with correct cycle counts... - uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]); } @@ -2703,7 +2675,6 @@ static void Op35(void) // PULS PULLS16(regs.pc); // Count bits in each nybble to come up with correct cycle counts... - uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]); } @@ -2732,7 +2703,6 @@ static void Op36(void) // PHSU } // Count bits in each nybble to come up with correct cycle counts... - uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]); } @@ -2761,7 +2731,6 @@ static void Op37(void) // PULU PULLU16(regs.pc); // Count bits in each nybble to come up with correct cycle counts... - uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]); } @@ -2786,14 +2755,6 @@ static void Op37(void) // PULU flagC = (m >> 7) & 0x01; \ m = res -/* - UINT16 t,r; - DIRBYTE(t); - r = (CC & CC_C) | (t << 1); - CLR_NZVC; - SET_FLAGS8(t,t,r); - WM(EAD,r); -*/ static void Op09(void) // ROL DP { uint8_t m; @@ -3255,33 +3216,28 @@ static void Op0D(void) // TST DP OP_TST_HANDLER(m); } - static void Op4D(void) // TSTA { OP_TST_HANDLER(regs.a); } - static void Op5D(void) // TSTB { OP_TST_HANDLER(regs.b); } - static void Op6D(void) // TST IDX { uint8_t m = READ_IDX; OP_TST_HANDLER(m); } - static void Op7D(void) // TST ABS { uint8_t m = READ_ABS; OP_TST_HANDLER(m); } - // // Undocumented Opcodes // @@ -3290,26 +3246,10 @@ static void Op01(void) Op00(); // NEG DP } - -//temp, for testing... -#ifdef __DEBUG__ -static uint8_t backTrace[256]; -static uint16_t 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++) -{ - Decode6809(btPC[(btPtr + i) & 0xFF]); - WriteLog("\n"); -}//*/ -#endif } // @@ -3381,30 +3321,24 @@ static void (* exec_op2[256])() = { Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__ }; - // These are here to save typing a ton of forward declarations... - // Page 1 opcode static void Op10(void) { -// exec_op1[regs.RdMem(regs.pc++)](); uint8_t opcode = regs.RdMem(regs.pc++); exec_op1[opcode](); regs.clock += page1Cycles[opcode]; } - // Page 2 opcode static void Op11(void) { -// exec_op2[regs.RdMem(regs.pc++)](); uint8_t opcode = regs.RdMem(regs.pc++); exec_op2[opcode](); regs.clock += page2Cycles[opcode]; } - // // Internal "memcpy" (so we don't have to link with any external libraries!) // @@ -3416,24 +3350,14 @@ static void myMemcpy(void * dst, void * src, uint32_t size) d[i] = s[i]; } - // // Function to execute 6809 instructions // -//#define DEBUG_ILLEGAL -#ifdef DEBUG_ILLEGAL -#include "log.h" -#include "dis6809.h" -uint8_t btPtr = 0; -uint8_t backTrace[256]; -V6809REGS btRegs[256]; -bool tripped = false; -#endif void Execute6809(V6809REGS * context, uint32_t cycles) { // If this is not in place, the clockOverrun calculations can cause the // V6809 to get stuck in an infinite loop. - if (cycles == 0) + if (cycles == 0) // Nothing to do, so bail! return; myMemcpy(®s, context, sizeof(V6809REGS)); @@ -3452,53 +3376,6 @@ void Execute6809(V6809REGS * context, uint32_t cycles) while (regs.clock < endCycles) { -#ifdef DEBUG_ILLEGAL -if (!tripped) -{ - backTrace[btPtr] = regs.RdMem(regs.pc); - btRegs[btPtr] = regs; - btPtr = (btPtr + 1) & 0xFF; - - if (regs.cpuFlags & V6809_STATE_ILLEGAL_INST) - { - WriteLog("V6809: Executed illegal instruction!!!!\n\nBacktrace:\n\n"); - regs.cpuFlags &= ~V6809_STATE_ILLEGAL_INST; - - for(uint16_t i=btPtr; i 1) - WriteLog("\n\n!!! FLAG OUT OF BOUNDS !!!\n\n"); -#endif -//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 + 1) & 0xFF;//*/ -#endif -// exec_op0[regs.RdMem(regs.pc++)](); uint8_t opcode = regs.RdMem(regs.pc++); exec_op0[opcode](); regs.clock += page0Cycles[opcode]; @@ -3509,22 +3386,18 @@ btPtr = (btPtr + 1) & 0xFF;//*/ // uint32_t flags = context->cpuFlags; uint32_t flags = regs.cpuFlags; - if (flags & V6809_ASSERT_LINE_RESET) // *** RESET handler *** + // *** RESET handler *** + if (flags & V6809_LINE_RESET) { -#ifdef __DEBUG__ -if (disasm) WriteLog("\nV6809: RESET line asserted!\n"); -#endif flagF = flagI = 1; // Set F, I regs.dp = 0; // Reset direct page register regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector - context->cpuFlags &= ~V6809_ASSERT_LINE_RESET; - regs.cpuFlags &= ~V6809_ASSERT_LINE_RESET; + context->cpuFlags &= ~V6809_LINE_RESET; + regs.cpuFlags &= ~V6809_LINE_RESET; } - else if (flags & V6809_ASSERT_LINE_NMI) // *** NMI handler *** + // *** NMI handler *** + else if (flags & V6809_LINE_NMI) { -#ifdef __DEBUG__ -if (disasm) WriteLog("\nV6809: NMI line asserted!\n"); -#endif flagE = 1; // Set Entire flag regs.cc = PACK_FLAGS; // Mash flags back into the CC register @@ -3540,19 +3413,12 @@ if (disasm) WriteLog("\nV6809: NMI line asserted!\n"); flagI = flagF = 1; // Set IRQ/FIRQ suppress flags regs.pc = RdMemW(0xFFFC); // And load PC with the NMI vector regs.clock += 19; -// context->cpuFlags &= ~V6809_ASSERT_LINE_NMI;// Reset the asserted line (NMI)... -// regs.cpuFlags &= ~V6809_ASSERT_LINE_NMI; // Reset the asserted line (NMI)... } - else if (flags & V6809_ASSERT_LINE_FIRQ) // *** FIRQ handler *** + // *** FIRQ handler *** + else if (flags & V6809_LINE_FIRQ) { -#ifdef __DEBUG__ -if (disasm) WriteLog("\nV6809: FIRQ line asserted!\n"); -#endif if (!flagF) // Is the FIRQ masked (F == 1)? { -#ifdef __DEBUG__ -if (disasm) WriteLog(" FIRQ taken...\n"); -#endif flagE = 0; // Clear Entire flag regs.cc = PACK_FLAGS; // Mash flags back into the CC register @@ -3562,20 +3428,13 @@ if (disasm) WriteLog(" FIRQ taken...\n"); flagI = flagF = 1; // Set IRQ/FIRQ suppress flags regs.pc = RdMemW(0xFFF6); // And load PC with the IRQ vector regs.clock += 10; -// context->cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)... -// regs.cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)... } } - else if (flags & V6809_ASSERT_LINE_IRQ) // *** IRQ handler *** + // *** IRQ handler *** + else if (flags & V6809_LINE_IRQ) { -#ifdef __DEBUG__ -if (disasm) WriteLog("\nV6809: IRQ line asserted!\n"); -#endif if (!flagI) // Is the IRQ masked (I == 1)? { -#ifdef __DEBUG__ -if (disasm) WriteLog(" IRQ taken...\n"); -#endif flagE = 1; // Set the Entire flag regs.cc = PACK_FLAGS; // Mash flags back into the CC register @@ -3591,19 +3450,8 @@ if (disasm) WriteLog(" IRQ taken...\n"); flagI = 1; // Specs say that it doesn't affect FIRQ... or FLAG_F [WAS: Set IRQ/FIRQ suppress flags] regs.pc = RdMemW(0xFFF8); // And load PC with the IRQ vector regs.clock += 19; -// Apparently, not done here! -// context->cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)... -// regs.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)... } } -#ifdef __DEBUG__ -if (disasm) WriteLog("CC=%s%s%s%s%s%s%s%s A=%02X B=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n", - (flagE ? "E" : "-"), (flagF ? "F" : "-"), (flagH ? "H" : "-"), (flagI ? "I" : "-"), - (flagN ? "N" : "-"), (flagZ ? "Z" : "-"), (flagV ? "V" : "-"), (flagC ? "C" : "-"), - regs.a, regs.b, 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 } // Keep track of how much we overran so we can adjust on the next run... @@ -3613,7 +3461,6 @@ if (disasm) WriteLog("CC=%s%s%s%s%s%s%s%s A=%02X B=%02X DP=%02X X=%04X Y=%04X S= myMemcpy(context, ®s, sizeof(V6809REGS)); } - // // Get the clock of the currently executing CPU // @@ -3622,7 +3469,6 @@ uint64_t GetCurrentV6809Clock(void) return regs.clock; } - // // Get the PC of the currently executing CPU // @@ -3631,49 +3477,15 @@ uint16_t GetCurrentV6809PC(void) return regs.pc; } - // Set a line of the currently executing CPU void SetLineOfCurrentV6809(uint32_t line) { regs.cpuFlags |= line; } - // Clear a line of the currently executing CPU void ClearLineOfCurrentV6809(uint32_t line) { -#ifdef __DEBUG__ -if (disasm) - WriteLog("V6809: Clearing line %s...", (line == V6809_ASSERT_LINE_IRQ ? "IRQ" : "OTHER")); -#endif regs.cpuFlags &= ~line; } - -#if 0 -FE54: 27 6A BEQ $FEC0 CC=EF-I-Z-- A=39 B=01 DP=00 X=FEE2 Y=F51 -E S=BFFF U=0000 PC=FEC0 -FEC0: 6E A4 JMP ,Y CC=EF-I-Z-- A=39 B=01 DP=00 X=FEE2 Y=F51E S=BFFF - U=0000 PC=F51E -F51E: 86 34 LDA #$34 CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF - U=0000 PC=F520 -F520: B7 C8 0D STA $C80D CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F523 -F523: B7 C8 0F STA $C80F CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F526 -F526: 7F C8 0E CLR $C80EV6809: Clearing line IRQ... CC=EF-I-Z-- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F529 -F529: 86 9C LDA #$9C CC=EF-IN--- A=9C B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F52B -F52B: 1F 8B TFR A,DP CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFF U=0000 PC=F52D -F52D: 10 CE BF FF LDS #$BFFF CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFF U=0000 PC=F531 -F531: BD 13 BD JSR $13BD CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFD U=0000 PC=13BD -13BD: 34 76 PSHS A B X Y U CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFF5 U=0000 PC=13BF -13BF: CE 9C 00 LDU #$9C00 CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFF5 U=9C00 PC=13C2 -13C2: 8E 00 00 LDX #$0000 CC=EF-I-Z-- A=9C B=01 DP=9C X=0000 Y=F51E S=BFF5 U=9C00 PC=13C5 -13C5: 1F 12 TFR X,Y CC=EF-I-Z-- A=9C B=01 DP=9C X=0000 Y=0000 S=BFF5 U=9C00 PC=13C7 -13C7: 1F 10 TFR X,D CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFF5 U=9C00 PC=13C9 -13C9: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFEF U=9C00 PC=13CB -13CB: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFE9 U=9C00 PC=13CD -13CD: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFE3 U=9C00 PC=13CF -13CF: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFDD U=9C00 PC=13D1 -13D1: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFD7 U=9C00 PC=13D3 -13D3: 36 10 PSHU X CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFD5 U=9C00 PC=13D5 -13D5: 11 83 00 00 CMPU #$0000 CC=EF-IN--- A=00 B=00 DP=9C X=0000 Y=000 -#endif