X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fv6809.cpp;fp=src%2Fv6809.cpp;h=b0ef8eb1c6690c3aa4dee6bbd713b62dc8f6d1b7;hb=8dafbf94c7bc84dae635f9dabfc9be5424e49e68;hp=2bb970f2e5045383a02ddaa07d00dbdcc9b83b88;hpb=e3ad811139308bfe8a818cf5e42e7553785fea82;p=stargem2 diff --git a/src/v6809.cpp b/src/v6809.cpp old mode 100755 new mode 100644 index 2bb970f..b0ef8eb --- a/src/v6809.cpp +++ b/src/v6809.cpp @@ -1,29 +1,23 @@ // -// Virtual 6809 v1.4 +// Virtual 6809 v1.4.2 // -// by James L. Hammons -// (c) 1997, 2009 Underground Software +// by James Hammons +// (C) 1997, 2009, 2014, 2023 Underground Software // -// JLH = James L. Hammons +// JLH = James Hammons // // WHO WHEN WHAT -// --- ---------- ------------------------------------------------------------ +// --- ---------- ----------------------------------------------------------- // 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 // 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 @@ -39,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++) @@ -95,7 +81,7 @@ bool disasm = false;//so we can extern this shit static V6809REGS regs; static uint8_t flagE, flagF, flagH, flagI, flagN, flagZ, flagV, flagC; -uint8_t page0Cycles[256] = { +static const uint8_t page0Cycles[256] = { 6, 1, 1, 6, 6, 1, 6, 6, 6, 6, 6, 1, 6, 6, 3, 6, // $0x 1, 1, 2, 2, 1, 1, 5, 9, 1, 2, 3, 1, 3, 2, 8, 7, // $1x 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // $2x @@ -114,7 +100,7 @@ uint8_t page0Cycles[256] = { 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6 // $Fx }; -uint8_t page1Cycles[256] = { +static const uint8_t page1Cycles[256] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $0x 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $1x 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // $2x @@ -133,7 +119,7 @@ uint8_t page1Cycles[256] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 7 // $Fx }; -uint8_t page2Cycles[256] = { +static const uint8_t page2Cycles[256] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $0x 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $1x 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $2x @@ -152,6 +138,9 @@ 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); @@ -191,7 +180,7 @@ static inline void WrMemW(uint16_t addr, uint16_t w) // // Function to read TFR/EXG post byte // -uint16_t ReadEXG(uint8_t code) +static uint16_t ReadEXG(uint8_t code) { uint16_t retval; @@ -238,7 +227,7 @@ uint16_t ReadEXG(uint8_t code) // // Function to set TFR/EXG data // -void WriteEXG(uint8_t code, uint16_t data) +static void WriteEXG(uint8_t code, uint16_t data) { switch (code) { @@ -268,7 +257,7 @@ void WriteEXG(uint8_t code, uint16_t data) // // Function to decode register data // -uint16_t DecodeReg(uint8_t reg) +static uint16_t DecodeReg(uint8_t reg) { uint16_t retval; @@ -290,13 +279,31 @@ uint16_t DecodeReg(uint8_t reg) // // Function to decode IDX data // -uint16_t DecodeIDX(uint8_t code) +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) @@ -313,6 +320,7 @@ 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) @@ -324,43 +332,63 @@ 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++); +// 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 @@ -376,6 +404,7 @@ 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); @@ -386,31 +415,71 @@ 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 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 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 13: { addr = regs.pc + FetchMemW(regs.pc); 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; } } } @@ -421,10 +490,10 @@ uint16_t DecodeIDX(uint8_t code) // // 6809 OPCODE IMPLEMENTATION // -// NOTE: Lots of macros are used here to save a LOT of typing. Also -// helps speed the debugging process. :-) Because of this, combining +// NOTE: Lots of macros are used here to save a LOT of typing. Also +// helps speed the debugging process. :-) Because of this, combining // certain lines may look like a good idea but would end in disaster. -// You have been warned! ;-) +// You have been warned! ;-) // /* @@ -452,16 +521,6 @@ 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; @@ -550,25 +609,6 @@ 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; @@ -928,8 +968,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; @@ -1712,7 +1750,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 @@ -1777,21 +1815,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; @@ -2017,7 +2047,9 @@ static void Op7C(void) // INC ABS static void Op0E(void) // JMP DP { - regs.pc = EA_DP; + // This needs to be separate because of the EA_DP adding to regs.pc. + uint16_t m = EA_DP; + regs.pc = m; } static void Op17(void) // LBSR @@ -2474,16 +2506,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; @@ -2624,7 +2646,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]); } @@ -2653,7 +2674,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]); } @@ -2682,7 +2702,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]); } @@ -2711,7 +2730,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]); } @@ -2736,14 +2754,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; @@ -3227,33 +3237,18 @@ static void Op7D(void) // TST ABS OP_TST_HANDLER(m); } +// // Undocumented Opcodes - +// 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 +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 } // @@ -3330,7 +3325,6 @@ static void (* exec_op2[256])() = { // 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]; @@ -3339,13 +3333,11 @@ static void Op10(void) // 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!) // @@ -3360,84 +3352,29 @@ static void myMemcpy(void * dst, void * src, uint32_t size) // // 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 this is not in place, the clockOverrun calculations can cause the + // V6809 to get stuck in an infinite loop. if (cycles == 0) // Nothing to do, so bail! return; myMemcpy(®s, context, sizeof(V6809REGS)); - UNPACK_FLAGS; // Explode flags register into individual uint8_ts + // Explode flags register into individual uint8_ts + UNPACK_FLAGS; // Execute here... - // Since we can't guarantee that we'll execute the number of cycles passed in - // exactly, we have to keep track of how much we overran the number of cycles - // the last time we executed. Since we already executed those cycles, this time - // through we remove them from the cycles passed in in order to come out - // approximately even. Over the long run, this unevenness in execution times - // evens out. + // Since we can't guarantee that we'll execute the number of cycles passed + // in exactly, we have to keep track of how much we overran the number of + // cycles the last time we executed. Since we already executed those + // cycles, this time through we remove them from the cycles passed in in + // order to come out approximately even. Over the long run, this unevenness + // in execution times evens out. :-) uint64_t endCycles = regs.clock + (uint64_t)(cycles - regs.clockOverrun); 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]; @@ -3448,26 +3385,22 @@ 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; + 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_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 + flagE = 1; // Set Entire flag + regs.cc = PACK_FLAGS; // Mash flags back into the CC register - PUSHS16(regs.pc); // Save all regs... + PUSHS16(regs.pc); // Save all regs... PUSHS16(regs.u); PUSHS16(regs.y); PUSHS16(regs.x); @@ -3476,47 +3409,33 @@ if (disasm) WriteLog("\nV6809: NMI line asserted!\n"); PUSHS(regs.a); PUSHS(regs.cc); - flagI = flagF = 1; // Set IRQ/FIRQ suppress flags - regs.pc = RdMemW(0xFFFC); // And load PC with the NMI vector + 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)? + 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 + flagE = 0; // Clear Entire flag + regs.cc = PACK_FLAGS; // Mash flags back into the CC register PUSHS16(regs.pc); PUSHS(regs.cc); - flagI = flagF = 1; // Set IRQ/FIRQ suppress flags - regs.pc = RdMemW(0xFFF6); // And load PC with the IRQ vector + 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)? + 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 + flagE = 1; // Set the Entire flag + regs.cc = PACK_FLAGS; // Mash flags back into the CC register PUSHS16(regs.pc); PUSHS16(regs.u); @@ -3527,28 +3446,17 @@ if (disasm) WriteLog(" IRQ taken...\n"); PUSHS(regs.a); PUSHS(regs.cc); - 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 + 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... regs.clockOverrun = (uint32_t)(regs.clock - endCycles); - regs.cc = PACK_FLAGS; // Mash flags back into the CC register + regs.cc = PACK_FLAGS; // Mash flags back into the CC register myMemcpy(context, ®s, sizeof(V6809REGS)); } @@ -3577,37 +3485,5 @@ void SetLineOfCurrentV6809(uint32_t 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