// We have a start... ;-)
//
-#define __DEBUG__
+//#define __DEBUG__
#include "v6809.h"
#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
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
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;
}
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; }
}
}
//
// 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(®s, 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);
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 ***
{
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 ***
#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, ®s, sizeof(V6809REGS));
}
//
// Get the clock of the currently executing CPU
//
-uint32 GetCurrentV6809Clock(void)
+uint64 GetCurrentV6809Clock(void)
{
return regs.clock;
}