]> Shamusworld >> Repos - stargem2/blobdiff - src/v6809.cpp
Some more fixes to the V6809 core to prevent clock destruction, fixes to
[stargem2] / src / v6809.cpp
index 45e072d1363bff8b92d294049695534eb699b148..197cdea906a88ae1b653aecc253499be4220e8ae 100755 (executable)
@@ -17,7 +17,7 @@
 // We have a start... ;-)
 //
 
-#define __DEBUG__
+//#define __DEBUG__
 
 #include "v6809.h"
 
@@ -46,6 +46,7 @@
 #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 !!!
+//Hmm, why not do like we did for READ_ABS*???
 #define EA_IMM                         regs.pc++
 #define EA_ZP                          regs.RdMem(regs.pc++)
 #define EA_ZP_X                                (regs.RdMem(regs.pc++) + regs.x) & 0xFF
@@ -218,13 +219,6 @@ static uint16 FetchW()
        regs.pc += 2;
        return w;
 }
-//
-// Fetch word function
-//
-/*uint16 FetchW(void)
-{
-       return (uint16)(regs.RdMem(regs.pc++) << 8) | regs.RdMem(regs.pc++);
-}*/
 
 //
 // Read word from memory function
@@ -384,37 +378,30 @@ uint16 DecodeIDX(uint8 code)
                                addr = RdMemW(woff);
                                break;
                        case 5:
-//                             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) + (int16)(int8)regs.a;
                                addr = RdMemW(woff);
                                break;
                        case 8:
-//                             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) + FetchW();
                                addr = RdMemW(woff);
                                break;
                        case 11:
-//                             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 + (int16)(int8)regs.RdMem(regs.pc++);
                                addr = RdMemW(woff);
                                break;
                        case 13:
-//                             woff = regs.pc + SignedW(FetchW());
                                woff = regs.pc + FetchW();
                                addr = RdMemW(woff);
                                break;
@@ -465,19 +452,12 @@ uint16 DecodeIDX(uint8 code)
                    }
                    addr = DecodeReg(reg);  break; }
         case 4:  { addr = DecodeReg(reg);  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; }
                        }
                }
@@ -3069,12 +3049,33 @@ 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"
+#endif
 void Execute6809(V6809REGS * context, uint32 cycles)
 {
+       // This seriously fucks up the leftover counting...
+       if (cycles == 0)
+               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);
+       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__
 //Decode6809(regs.pc);
@@ -3130,8 +3131,8 @@ if (disasm) WriteLog("\nV6809: NMI line asserted!\n");
                        regs.cc |= (FLAG_I | FLAG_F);                           // 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)...
+//                     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 ***
                {
@@ -3152,8 +3153,8 @@ if (disasm) WriteLog("       FIRQ taken...\n");
                                regs.cc |= (FLAG_I | FLAG_F);                   // 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)...
+//                             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 ***
@@ -3197,13 +3198,24 @@ 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);
+       regs.clockOverrun = (uint32)(regs.clock - endCycles);
+//WriteLog("V6809: leftover = %u\n", leftover);
+#else
+       regs.clock -= cycles;
+#endif
+
        myMemcpy(context, &regs, sizeof(V6809REGS));
 }
 
 //
 // Get the clock of the currently executing CPU
 //
-uint32 GetCurrentV6809Clock(void)
+uint64 GetCurrentV6809Clock(void)
 {
        return regs.clock;
 }