]> Shamusworld >> Repos - stargem2/blobdiff - src/v6809.cpp
Change V6808 clock to 64-bit, added possible "don't branch" optimization
[stargem2] / src / v6809.cpp
index 197cdea906a88ae1b653aecc253499be4220e8ae..a8b24fadfb6266463606eaf21619d1fe733d1335 100755 (executable)
@@ -47,6 +47,7 @@
 
 //Small problem with the EA_ macros: ABS macros don't increment the PC!!! !!! FIX !!!
 //Hmm, why not do like we did for READ_ABS*???
+//Because the EA_* macros are usually used as an argument to a function call, that's why.
 #define EA_IMM                         regs.pc++
 #define EA_ZP                          regs.RdMem(regs.pc++)
 #define EA_ZP_X                                (regs.RdMem(regs.pc++) + regs.x) & 0xFF
@@ -3049,34 +3050,60 @@ static void myMemcpy(void * dst, void * src, uint32 size)
 //
 // Function to execute 6809 instructions
 //
-#define NON_DESTRUCTIVE_CLOCK
-#ifdef NON_DESTRUCTIVE_CLOCK
-//static uint32 leftover = 0;
-//#include "log.h"
+//#define DEBUG_ILLEGAL
+#ifdef DEBUG_ILLEGAL
+#include "log.h"
+#include "dis6809.h"
+uint8 btPtr = 0;
+uint8 backTrace[256];
+V6809REGS btRegs[256];
+bool tripped = false;
 #endif
 void Execute6809(V6809REGS * context, uint32 cycles)
 {
-       // This seriously fucks up the leftover counting...
-       if (cycles == 0)
+       // 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;
 
-//WriteLog("V6809: cycles = %u, regs.clock = %u, leftover = %u \n", cycles, regs.clock, leftover);
        myMemcpy(&regs, context, sizeof(V6809REGS));
 
        // Execute here...
-#ifdef NON_DESTRUCTIVE_CLOCK
-//Very odd.. It fucks up when using the following code for a timeslice!
-//     cycles -= regs.clockOverrun;//leftover;
-//     uint64 endCycles = regs.clock + (uint64)(cycles - leftover);
+
+       // 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 endCycles = regs.clock + (uint64)(cycles - regs.clockOverrun);
-//     uint64 endCycles = regs.clock + (uint64)cycles;
-//WriteLog("V6809: endCycles = %u, regs.clock = %u, leftover = %u \n", endCycles, regs.clock, leftover);
 
        while (regs.clock < endCycles)
-#else
-       while (regs.clock < cycles)
-#endif
        {
+#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 i=btPtr; i<btPtr+256; i++)
+               {
+                       Decode6809(btRegs[i & 0xFF].pc);
+// Note that these values are *before* execution, so stale...
+                       WriteLog("\n\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
+                               btRegs[i & 0xFF].a, btRegs[i & 0xFF].b, btRegs[i & 0xFF].cc, btRegs[i & 0xFF].dp, btRegs[i & 0xFF].x, btRegs[i & 0xFF].y, btRegs[i & 0xFF].s, btRegs[i & 0xFF].u, btRegs[i & 0xFF].pc);//*/
+               }
+
+               tripped = true;
+       }
+}
+#endif
 #ifdef __DEBUG__
 //Decode6809(regs.pc);
 static bool disasm = false;
@@ -3198,16 +3225,8 @@ if (disasm) WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04
 #endif
        }
 
-//This is a lame way of doing it, but in the end the simplest--however, it destroys any
-//record of elasped CPU time. Not sure that it's important to keep track, but there it is.
-// Now we use a 64-bit integer, so it won't wrap for about 500 millenia. ;-)
-#ifdef NON_DESTRUCTIVE_CLOCK
-//     leftover = (uint32)(regs.clock - endCycles);
+       // Keep track of how much we overran so we can adjust on the next run...
        regs.clockOverrun = (uint32)(regs.clock - endCycles);
-//WriteLog("V6809: leftover = %u\n", leftover);
-#else
-       regs.clock -= cycles;
-#endif
 
        myMemcpy(context, &regs, sizeof(V6809REGS));
 }