]> Shamusworld >> Repos - thunder/commitdiff
Replaced old v6809 core with new updated one. :-)
authorShamus Hammons <jlhamm@acm.org>
Thu, 30 Jul 2009 21:26:57 +0000 (21:26 +0000)
committerShamus Hammons <jlhamm@acm.org>
Thu, 30 Jul 2009 21:26:57 +0000 (21:26 +0000)
makefile
src/thunder.cpp
src/v6809.cpp
src/v6809.h

index d0f50c77a5ca82642866676960ae870d82af7cb5..e9dc6f10a72a1cd1b19c9f074ed3c2b790c2efc3 100755 (executable)
--- a/makefile
+++ b/makefile
@@ -56,10 +56,13 @@ LIBS = -L/usr/local/lib `sdl-config $(SDLLIBTYPE)` -lstdc++ -lz $(GLLIB) -lcurse
 INCS = -I. -Isrc -I/usr/local/include
 
 OBJS = \
+       obj/dis6808.o  \
+       obj/dis6809.o  \
        obj/gui.o      \
        obj/log.o      \
        obj/resource.o \
        obj/screen.o   \
+       obj/v6808.o    \
        obj/v6809.o    \
        obj/thunder.o  \
        $(ICON)
index 3a9d8ae3ae84a67965ffd918b0552425e3c32164..ffbfed9574a7ec070ea679c79c0f2668ace9e130 100755 (executable)
@@ -99,18 +99,6 @@ uint8 * gram, * grom;                                                        // Allocate RAM & ROM pointers
 uint8 gram1[0x10000], gram2[0x10000], grom1[0x10000], grom2[0x10000];  // Actual memory
 uint8 grom3[0x8000], grom4[0x8000], data_rom[0x40000], spr_rom[0x80000], voice_rom[0x20000];
 uint8 chr_rom[0x60000];                                                        // Character ROM pointer
-/*
-  gram1 = new uint8[0x10000];
-  grom1 = new uint8[0x10000];
-  gram2 = new uint8[0x10000];
-  grom2 = new uint8[0x10000];
-  chr_rom = new uint8[0x60000];
-  grom3 = new uint8[0x8000];
-  grom4 = new uint8[0x8000];
-  data_rom = new uint8[0x40000];
-  spr_rom = new uint8[0x80000];
-  voice_rom = new uint8[0x20000];
-*/
 
 V6809REGS cpu1, cpu2;
 
@@ -451,25 +439,25 @@ void DisplayBytes(uint16 src, unsigned long dst)
   uint8 cnt;
   unsigned long i;
 
-  printf("%04X: ", src);
+  WriteLog("%04X: ", src);
   cnt = 0;                               // Init counter...
   if (src > dst)  dst += 0x10000;        // That should fix the FFFF bug...
   for(i=src; i<dst; i++)
   {
-    printf("%02X ", (uint8)(looking_at_rom ? RdMem(i) : RdMemB(i)));
+    WriteLog("%02X ", (uint8)(looking_at_rom ? RdMem(i) : RdMemB(i)));
     cnt++;                               // Bump counter...
   }
   for(i=cnt; i<5; i++)                   // Pad the leftover spaces...
   {
-    cout << "   ";
+    WriteLog("   ");
   }
 }
 
 // temp crap...
-uint8 Fetch(void) { return 0; }
-uint16 FetchW(void) { return 0; }
-uint8 FetchB(void) { return 0; }
-uint16 FetchWB(void) { return 0; }
+uint8 Fetch(void) { return RdMem(dpc); }
+uint16 FetchW(void) { return (uint16)((RdMem(dpc) << 8) | RdMem(dpc+1)); }
+uint8 FetchB(void) { return RdMemB(dpc); }
+uint16 FetchWB(void) { return (uint16)((RdMemB(dpc) << 8) | RdMemB(dpc+1)); }
 
 //
 // Decode a 6809 instruction at 'addr'
@@ -626,7 +614,7 @@ void Decode_6809()
       break; }
   }
   DisplayBytes(dpc, (looking_at_rom ? pcr : pcrB));  // Show bytes
-  cout << outbuf << endl;     // display opcode & addressing, etc
+  WriteLog(outbuf); WriteLog("\n");     // display opcode & addressing, etc
   dpc = (looking_at_rom ? pcr : pcrB);  // Advance debug PC
   pcr = pc_save;  pcrB = pcB_save;  // Restore PCs
 }
@@ -1229,26 +1217,30 @@ WriteLog("Executing secondary 'run' command...\n");
 //        iclock = 0;                // Reset instr clock #1...
                                InitGUI();                 // Reset # of coins
 
-/*        cpu1.pc = ((grom1[0xFFFE]<<8) | grom1[0xFFFF]); // Reset 6809 #1
-        if (lbuff[1] != 0)
-        {
-          lbuff[0] = 32;  cpu1.pc = htod(lbuff);
-        }
-        else  cpu1.cc = 0xFF;                         // Set CC register
+#if 0
+                               cpu1.pc = ((grom1[0xFFFE]<<8) | grom1[0xFFFF]); // Reset 6809 #1
+                               if (lbuff[1] != 0)
+                               {
+                               lbuff[0] = 32;  cpu1.pc = htod(lbuff);
+                               }
+                               else  cpu1.cc = 0xFF;                         // Set CC register
 
-        cpu2.pc = ((grom2[0xFFFE]<<8) | grom2[0xFFFF]); // Reset 6809 #2
-        cpu2.cc = 0xFF;                              // Set CC register
-        while(iclock < 8000)  // was 17000, 20000, 5000
-        {
-          Execute6809(&cpu1, 1);  Execute6809(&cpu2, 1);
-        }*/
+                               cpu2.pc = ((grom2[0xFFFE]<<8) | grom2[0xFFFF]); // Reset 6809 #2
+                               cpu2.cc = 0xFF;                              // Set CC register
+                               while(iclock < 8000)  // was 17000, 20000, 5000
+                               {
+                               Execute6809(&cpu1, 1);  Execute6809(&cpu2, 1);
+                               }
+#endif
+#if 0
 WriteLog("--> CPU clock #1: %u\n", cpu1.clock);
-                               // Will *this* help video sync?
+                               // Will *this* help video sync? NO
                                while (cpu1.clock < 8000)                               // was 17000, 20000, 5000
                                {
                                        Execute6809(&cpu1, 1);
                                        Execute6809(&cpu2, 1);
                                }
+#endif
                        }
 
 WriteLog("About to set up screen...\n");
@@ -1270,7 +1262,7 @@ WriteLog("About to set up screen...\n");
                        }
                        SDL_SetPalette(screen, SDL_LOGPAL | SDL_PHYSPAL, colors, 0, 256);
 
-#if 1
+#if 0
        // This confirms that we're getting video to the screen...
        SDL_LockSurface(screen);
 
@@ -1497,6 +1489,12 @@ WriteLog("About to enter main loop...\n");
                                        Execute6809(&cpu2, 10);
                                }
 //                     }
+//F12 is used above, but the values are ignored. So we'll do it here too.
+                               if (keys[SDLK_F12])
+                               {
+                                       cpu1.cpuFlags |= V6809_ASSERT_LINE_RESET;
+                                       cpu2.cpuFlags |= V6809_ASSERT_LINE_RESET;
+                               }
 
 //                             if (enable_cpu)
                                if (true)
@@ -1525,8 +1523,8 @@ WriteLog("About to enter main loop...\n");
                                                Execute6809(&cpu2, 100);
                                        }
 
-                                       cpu1.clock -= 25000;                            // Remove 25K ticks from clock (in case it overflowed)
-                                       cpu2.clock -= 25000;                            // Remove 25K ticks from clock (in case it overflowed)//*/
+//                                     cpu1.clock -= 25000;                            // Remove 25K ticks from clock (in case it overflowed)
+//                                     cpu2.clock -= 25000;                            // Remove 25K ticks from clock (in case it overflowed)//*/
 #endif
                                } // END: enable_cpu
 
index 894476f1f37459295a20cb30275b644e06099327..9c2160f48170d046f6961f2f3c8e5f3ffa1f2e61 100755 (executable)
 //
-// Virtual 6809 v1.2 (Last build: 2/27/2004)
+// Virtual 6809 v1.3
 //
 // by James L. Hammons
+// (c) 1997, 2006 Underground Software
 //
-// (c) 1997,2004 Underground Software
+// JLH = James L. Hammons <jlhamm@acm.org>
+//
+// 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
+//
+
+// Mebbe someday I'll get around to fixing the core to be more like V65C02...
+// We have a start... ;-)
 //
 
 #include "v6809.h"
 
+//#define __DEBUG__
 #ifdef __DEBUG__
 #include "dis6809.h"   // Temporary...
 #include "log.h"               // Temporary...
 #endif
 
+// Various macros
+
+#define CLR_Z                          (regs.cc &= ~FLAG_Z)
+#define CLR_ZN                         (regs.cc &= ~(FLAG_Z | FLAG_N))
+#define CLR_ZNC                                (regs.cc &= ~(FLAG_Z | FLAG_N | FLAG_C))
+#define CLR_V                          (regs.cc &= ~FLAG_V)
+#define CLR_N                          (regs.cc &= ~FLAG_N)
+#define SET_Z(r)                       (regs.cc = ((r) == 0 ? regs.cc | FLAG_Z : regs.cc & ~FLAG_Z))
+#define SET_N(r)                       (regs.cc = ((r) & 0x80 ? regs.cc | FLAG_N : regs.cc & ~FLAG_N))
+
+//Not sure that this code is computing the carry correctly... Investigate! [Seems to be]
+#define SET_C_ADD(a,b)         (regs.cc = ((uint8)(b) > (uint8)(~(a)) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
+//#define SET_C_SUB(a,b)               (regs.cc = ((uint8)(b) >= (uint8)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
+#define SET_C_CMP(a,b)         (regs.cc = ((uint8)(b) >= (uint8)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
+#define SET_ZN(r)                      SET_N(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)
+
+//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
+#define EA_ZP_Y                                (regs.RdMem(regs.pc++) + regs.y) & 0xFF
+#define EA_ABS                         RdMemW(regs.pc)
+#define EA_ABS_X                       RdMemW(regs.pc) + regs.x
+#define EA_ABS_Y                       RdMemW(regs.pc) + regs.y
+#define EA_IND_ZP_X                    RdMemW((regs.RdMem(regs.pc++) + regs.x) & 0xFF)
+#define EA_IND_ZP_Y                    RdMemW(regs.RdMem(regs.pc++)) + regs.y
+#define EA_IND_ZP                      RdMemW(regs.RdMem(regs.pc++))
+
+#define READ_IMM                       regs.RdMem(EA_IMM)
+#define READ_ZP                                regs.RdMem(EA_ZP)
+#define READ_ZP_X                      regs.RdMem(EA_ZP_X)
+#define READ_ZP_Y                      regs.RdMem(EA_ZP_Y)
+#define READ_ABS                       regs.RdMem(EA_ABS);     regs.pc += 2
+#define READ_ABS_X                     regs.RdMem(EA_ABS_X);   regs.pc += 2
+#define READ_ABS_Y                     regs.RdMem(EA_ABS_Y);   regs.pc += 2
+#define READ_IND_ZP_X          regs.RdMem(EA_IND_ZP_X)
+#define READ_IND_ZP_Y          regs.RdMem(EA_IND_ZP_Y)
+#define READ_IND_ZP                    regs.RdMem(EA_IND_ZP)
+
+#define READ_IMM_WB(v)         uint16 addr = EA_IMM;      v = regs.RdMem(addr)
+#define READ_ZP_WB(v)          uint16 addr = EA_ZP;       v = regs.RdMem(addr)
+#define READ_ZP_X_WB(v)                uint16 addr = EA_ZP_X;     v = regs.RdMem(addr)
+#define READ_ABS_WB(v)         uint16 addr = EA_ABS;      v = regs.RdMem(addr); regs.pc += 2
+#define READ_ABS_X_WB(v)       uint16 addr = EA_ABS_X;    v = regs.RdMem(addr); regs.pc += 2
+#define READ_ABS_Y_WB(v)       uint16 addr = EA_ABS_Y;    v = regs.RdMem(addr); regs.pc += 2
+#define READ_IND_ZP_X_WB(v)    uint16 addr = EA_IND_ZP_X; v = regs.RdMem(addr)
+#define READ_IND_ZP_Y_WB(v)    uint16 addr = EA_IND_ZP_Y; v = regs.RdMem(addr)
+#define READ_IND_ZP_WB(v)      uint16 addr = EA_IND_ZP;   v = regs.RdMem(addr)
+
+#define WRITE_BACK(d)          regs.WrMem(addr, (d))
+
 // Private global variables
 
 static V6809REGS regs;
-static uint16 addr;                                                                            // Temporary variables common to all funcs...
+//Let's see if we can nuke this shit.
+static uint16 addr;                                                            // Temporary variables common to all funcs...
 static uint8 tmp;
 
 // Private function prototypes
 
-static int SignedB(uint8);                                                             // Return signed byte from unsigned
-static int SignedW(uint16);                                                            // Return signed word from unsigned
 static uint16 FetchW(void);
 static uint16 RdMemW(uint16 addr);
 static void WrMemW(uint16 addr, uint16 w);
-static uint16 ReadEXG(uint8);                                                          // Read TFR/EXG post byte
-static void WriteEXG(uint8, uint16);                                           // Set TFR/EXG data
-static uint16 DecodeReg(uint8);                                                        // Decode register data
-static uint16 DecodeIDX(uint8);                                                        // Decode IDX data
+static uint16 ReadEXG(uint8);                                  // Read TFR/EXG post byte
+static void WriteEXG(uint8, uint16);                   // Set TFR/EXG data
+static uint16 DecodeReg(uint8);                                        // Decode register data
+static uint16 DecodeIDX(uint8);                                        // Decode IDX data
+
+//static void (* exec_op1[256])();
+//static void (* exec_op2[256])();
+#if 1
 
 // This is here because of the stupid forward declaration rule that C++ forces (the C++ compiler
 // isn't smart enough to know that the identifiers in the arrays are declared later, it doesn't
 // even *try* to see if they're there).
 
-#define FD(x)          static void Op##x();                            // FD -> "Forward Declaration"
+#define FD(x)          static void Op##x();            // FD -> "Forward Declaration"
 #define FE(x)          static void Op10##x();
 #define FF(x)          static void Op11##x();
 
@@ -67,6 +138,12 @@ FF(3F) FF(83) FF(8C) FF(93) FF(9C) FF(A3) FF(AC) FF(B3) FF(BC)
 #undef FE
 #undef FF
 
+#endif
+
+// We can move these down and do away with the forward declarations... !!! FIX !!!
+// Actually, we can't because these are used in a couple of the opcode functions.
+// Have to think about how to fix that...
+
 //
 // Function arrays
 //
@@ -142,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
@@ -167,22 +237,6 @@ void WrMemW(uint16 addr, uint16 w)
        regs.WrMem(addr + 1, w & 0xFF);
 }
 
-//
-// return signed byte from unsigned
-//
-int SignedB(uint8 b)
-{
-       return (b & 0x80 ? b - 256 : b);
-}
-
-//
-// return signed word from unsigned
-//
-int SignedW(uint16 w)
-{
-       return (w & 0x8000 ? w - 65536 : w);
-}
-
 //
 // Function to read TFR/EXG post byte
 //
@@ -289,7 +343,7 @@ uint16 DecodeIDX(uint8 code)
        uint16 addr, woff;
        uint8 reg = (code & 0x60) >> 5, idxind = (code & 0x10) >> 4, lo_nyb = code & 0x0F;
 
-       if (!(code & 0x80))                                                                     // Hi bit unset? Then decode 4 bit offset
+       if (!(code & 0x80))                                                     // Hi bit unset? Then decode 4 bit offset
                addr = DecodeReg(reg) + (idxind ? lo_nyb - 16 : lo_nyb);
        else
        {
@@ -324,31 +378,31 @@ 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;
                        case 15:
@@ -398,13 +452,13 @@ uint16 DecodeIDX(uint8 code)
                    }
                    addr = DecodeReg(reg);  break; }
         case 4:  { addr = DecodeReg(reg);  break; }
-        case 5:  { addr = DecodeReg(reg) + SignedB(regs.b);  break; }
-        case 6:  { addr = DecodeReg(reg) + SignedB(regs.a);  break; }
-        case 8:  { addr = DecodeReg(reg) + SignedB(regs.RdMem(regs.pc++));  break; }
-        case 9:  { addr = DecodeReg(reg) + SignedW(FetchW());  break; }
-        case 11: { addr = DecodeReg(reg) + SignedW((regs.a << 8) | regs.b);  break; }
-        case 12: { addr = regs.pc + SignedB(regs.RdMem(regs.pc++));  break; }
-        case 13: { addr = regs.pc + SignedW(FetchW());  break; }
+        case 5:  { addr = DecodeReg(reg) + (int16)(int8)regs.b;  break; }
+        case 6:  { addr = DecodeReg(reg) + (int16)(int8)regs.a;  break; }
+        case 8:  { addr = DecodeReg(reg) + (int16)(int8)regs.RdMem(regs.pc++);  break; }
+        case 9:  { addr = DecodeReg(reg) + FetchW();  break; }
+        case 11: { addr = DecodeReg(reg) + ((regs.a << 8) | regs.b);  break; }
+        case 12: { addr = regs.pc + (int16)(int8)regs.RdMem(regs.pc++);  break; }
+        case 13: { addr = regs.pc + FetchW();  break; }
                        }
                }
        }
@@ -546,32 +600,41 @@ static void Op10(void)                                                                                    // Page 1 opcode
        exec_op1[regs.RdMem(regs.pc++)]();
 }
 
-static void Op11(void)                                                                                 // Page 2 opcode
+static void Op11(void)                                                 // Page 2 opcode
 {
        exec_op2[regs.RdMem(regs.pc++)]();
 }
 
-static void Op12(void)                                                                                 // NOP
+static void Op12(void)                                                 // NOP
 {
        regs.clock += 2;
 }
 
-static void Op13(void)  // SYNC
+static void Op13(void)                                                 // SYNC
 {
-  regs.clock += 2;
+       // Fix this so it does the right thing (software interrupt!)
+       regs.clock += 2;
 }
-static void Op16(void)  // LBRA
+
+static void Op16(void)                                                 // LBRA
 {
-  regs.pc += SignedW(FetchW());
-  regs.clock += 5;
+//     regs.pc += SignedW(FetchW());
+       regs.pc += FetchW();                                            // No need to make signed, both are 16 bit quantities
+
+       regs.clock += 5;
 }
-static void Op17(void)  // LBSR
+
+static void Op17(void)                                                 // LBSR
 {
-  addr = FetchW();
-  regs.WrMem(--regs.s, regs.pc&0xFF);  regs.WrMem(--regs.s, regs.pc>>8);
-  regs.pc += SignedW(addr);
-  regs.clock += 9;
+       uint16 word = FetchW();
+       regs.WrMem(--regs.s, regs.pc & 0xFF);
+       regs.WrMem(--regs.s, regs.pc >> 8);
+//     regs.pc += SignedW(addr);
+       regs.pc += word;                                                        // No need to make signed, both are 16 bit
+
+       regs.clock += 9;
 }
+
 static void Op19(void)  // DAA
 {
   if ((regs.cc&0x20) || ((regs.a&0x0F) > 0x09))    // H set or lo nyb too big?
@@ -602,7 +665,7 @@ static void Op1C(void)                                                                      // ANDCC #
        regs.clock += 3;
 }
 
-static void Op1D(void)                                                                 // SEX
+static void Op1D(void)                                                 // SEX
 {
        (regs.b & 0x80 ? regs.a = 0xFF : regs.a = 0x00);
 
@@ -612,7 +675,7 @@ static void Op1D(void)                                                                      // SEX
        regs.clock += 2;
 }
 
-static void Op1E(void)                                                                 // EXG
+static void Op1E(void)                                                 // EXG
 {
        tmp = regs.RdMem(regs.pc++);
        addr = ReadEXG(tmp >> 4);
@@ -628,100 +691,162 @@ static void Op1F(void)  // TFR
   WriteEXG(tmp&0xF, ReadEXG(tmp>>4));
   regs.clock += 7;
 }
-static void Op20(void)  // BRA
+
+static void Op20(void)                                                 // BRA
 {
-  regs.pc += SignedB(regs.RdMem(regs.pc++));  // Branch always
-  regs.clock += 3;
+//     regs.pc += SignedB(regs.RdMem(regs.pc++));  // Branch always
+       regs.pc += (int16)(int8)regs.RdMem(regs.pc) + 1;        // Branch always
+
+       regs.clock += 3;
 }
-static void Op21(void)  // BRN
+
+static void Op21(void)                                                 // BRN
 {
-  regs.RdMem(regs.pc++);
-  regs.clock += 3;
+       regs.RdMem(regs.pc++);
+
+       regs.clock += 3;
 }
-static void Op22(void)  // BHI
+
+static void Op22(void)                                                 // BHI
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (!(regs.cc&0x05))  regs.pc += SignedB(tmp);
-  regs.clock += 3;
+       uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
+
+       if (!(regs.cc & 0x05))
+               regs.pc += word;
+
+       regs.clock += 3;
 }
-static void Op23(void)  // BLS
+
+static void Op23(void)                                                 // BLS
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (regs.cc&0x05)  regs.pc += SignedB(tmp);
-  regs.clock += 3;
+       uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
+
+       if (regs.cc & 0x05)
+               regs.pc += word;
+
+       regs.clock += 3;
 }
-static void Op24(void)  // BCC (BHS)
+
+static void Op24(void)                                                 // BCC (BHS)
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (!(regs.cc&0x01))  regs.pc += SignedB(tmp);
-  regs.clock += 3;
+       uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
+
+       if (!(regs.cc & 0x01))
+               regs.pc += word;
+
+       regs.clock += 3;
 }
-static void Op25(void)  // BCS (BLO)
+
+static void Op25(void)                                                 // BCS (BLO)
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (regs.cc&0x01)  regs.pc += SignedB(tmp);
-  regs.clock += 3;
+       uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
+
+       if (regs.cc & 0x01)
+               regs.pc += word;
+
+       regs.clock += 3;
 }
-static void Op26(void)  // BNE
+
+static void Op26(void)                                                 // BNE
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (!(regs.cc&0x04))  regs.pc += SignedB(tmp);
-  regs.clock += 3;
+       uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
+
+       if (!(regs.cc & 0x04))
+               regs.pc += word;
+
+       regs.clock += 3;
 }
-static void Op27(void)  // BEQ
+
+static void Op27(void)                                                 // BEQ
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (regs.cc&0x04)  regs.pc += SignedB(tmp);
-  regs.clock += 3;
+       uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
+
+       if (regs.cc & 0x04)
+               regs.pc += word;
+
+       regs.clock += 3;
 }
-static void Op28(void)  // BVC
+
+static void Op28(void)                                                 // BVC
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (!(regs.cc&0x02))  regs.pc += SignedB(tmp);
-  regs.clock += 3;
+       uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
+
+       if (!(regs.cc & 0x02))
+               regs.pc += word;
+
+       regs.clock += 3;
 }
-static void Op29(void)  // BVS
+
+static void Op29(void)                                                 // BVS
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (regs.cc&0x02)  regs.pc += SignedB(tmp);
-  regs.clock += 3;
+       uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
+
+       if (regs.cc & 0x02)
+               regs.pc += word;
+
+       regs.clock += 3;
 }
-static void Op2A(void)  // BPL
+
+static void Op2A(void)                                                 // BPL
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (!(regs.cc&0x08))  regs.pc += SignedB(tmp);
-  regs.clock += 3;
+       uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
+
+       if (!(regs.cc & 0x08))
+               regs.pc += word;
+
+       regs.clock += 3;
 }
-static void Op2B(void)  // BMI
+
+static void Op2B(void)                                                 // BMI
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (regs.cc&0x08)  regs.pc += SignedB(tmp);
-  regs.clock += 3;
+       uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
+
+       if (regs.cc & 0x08)
+               regs.pc += word;
+
+       regs.clock += 3;
 }
-static void Op2C(void)  // BGE
+
+static void Op2C(void)                                                 // BGE
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (!(((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)))  regs.pc += SignedB(tmp);
-  regs.clock += 3;
+       uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
+
+       if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
+               regs.pc += word;
+
+       regs.clock += 3;
 }
-static void Op2D(void)  // BLT
+
+static void Op2D(void)                                                 // BLT
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))  regs.pc += SignedB(tmp);
-  regs.clock += 3;
+       uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
+
+       if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))
+               regs.pc += word;
+
+       regs.clock += 3;
 }
-static void Op2E(void)  // BGT
+
+static void Op2E(void)                                                 // BGT
 {
-  tmp = regs.RdMem(regs.pc++);
-  if (!((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))))  regs.pc += SignedB(tmp);
-  regs.clock += 3;
+       uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
+
+       if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))))
+               regs.pc += word;
+
+       regs.clock += 3;
 }
-static void Op2F(void)  // BLE
+
+static void Op2F(void)                                                 // BLE
 {
-  tmp = regs.RdMem(regs.pc++);
-  if ((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)))  regs.pc += SignedB(tmp);
-  regs.clock += 3;
+       uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
+
+       if ((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
+               regs.pc += word;
+
+       regs.clock += 3;
 }
+
 static void Op30(void)  // LEAX
 {
   regs.x = DecodeIDX(regs.RdMem(regs.pc++));
@@ -1375,13 +1500,17 @@ static void Op8C(void)  // CMPX #
         (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
         regs.clock += 4;
 }
-static void Op8D(void)  // Bregs.s
-      {
-        tmp = regs.RdMem(regs.pc++);
-        regs.WrMem(--regs.s, regs.pc&0xFF);  regs.WrMem(--regs.s, regs.pc>>8);
-        regs.pc += SignedB(tmp);
-        regs.clock += 7;
-      }
+
+static void Op8D(void)                                                 // Bregs.s
+{
+       uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
+       regs.WrMem(--regs.s, regs.pc & 0xFF);
+       regs.WrMem(--regs.s, regs.pc >> 8);
+       regs.pc += word;
+
+       regs.clock += 7;
+}
+
 static void Op8E(void)  // LDX #
       {
         regs.x = FetchW();
@@ -2426,95 +2555,153 @@ static void OpFF(void)  // STU ABS
 // Page one opcodes' execute code
 //
 
-static void Op1021(void)  // LBRN
+static void Op1021(void)                                               // LBRN
 {
-  addr = FetchW();
-  regs.clock += 5;
+       addr = FetchW();
+
+       regs.clock += 5;
 }
-static void Op1022(void)  // LBHI
+
+static void Op1022(void)                                               // LBHI
 {
-  addr = FetchW();
-  if (!((regs.cc&0x01)|(regs.cc&0x04)))  regs.pc += SignedW(addr);
-  regs.clock += 5;
+       uint16 word = FetchW();
+
+       if (!((regs.cc & 0x01) | (regs.cc & 0x04)))
+               regs.pc += word;
+
+       regs.clock += 5;
 }
-static void Op1023(void)  // LBLS
+
+static void Op1023(void)                                               // LBLS
 {
-  addr = FetchW();
-  if ((regs.cc&0x01)|(regs.cc&0x04))  regs.pc += SignedW(addr);
-  regs.clock += 5;
+       uint16 word = FetchW();
+
+       if ((regs.cc & 0x01) | (regs.cc & 0x04))
+               regs.pc += word;
+
+       regs.clock += 5;
 }
-static void Op1024(void)  // LBCC (LBHS)
+
+static void Op1024(void)                                               // LBCC (LBHS)
 {
-  addr = FetchW();
-  if (!(regs.cc&0x01))  regs.pc += SignedW(addr);
-  regs.clock += 5;
+       uint16 word = FetchW();
+
+       if (!(regs.cc & 0x01))
+               regs.pc += word;
+
+       regs.clock += 5;
 }
-static void Op1025(void)  // LBCS (LBLO)
+
+static void Op1025(void)                                               // LBCS (LBLO)
 {
-  addr = FetchW();
-  if (regs.cc&0x01)  regs.pc += SignedW(addr);
-  regs.clock += 5;
+       uint16 word = FetchW();
+
+       if (regs.cc & 0x01)
+               regs.pc += word;
+
+       regs.clock += 5;
 }
-static void Op1026(void)  // LBNE
+
+static void Op1026(void)                                               // LBNE
 {
-  addr = FetchW();
-  if (!(regs.cc&0x04))  regs.pc += SignedW(addr);
-  regs.clock += 5;
+       uint16 word = FetchW();
+
+       if (!(regs.cc & 0x04))
+               regs.pc += word;
+
+       regs.clock += 5;
 }
-static void Op1027(void)  // LBEQ
+
+static void Op1027(void)                                               // LBEQ
 {
-  addr = FetchW();
-  if (regs.cc&0x04)  regs.pc += SignedW(addr);
-  regs.clock += 5;
+       uint16 word = FetchW();
+
+       if (regs.cc & 0x04)
+               regs.pc += word;
+
+       regs.clock += 5;
 }
-static void Op1028(void)  // LBVC
+
+static void Op1028(void)                                               // LBVC
 {
-  addr = FetchW();
-  if (!(regs.cc&0x02))  regs.pc += SignedW(addr);
-  regs.clock += 5;
+       uint16 word = FetchW();
+
+       if (!(regs.cc & 0x02))
+               regs.pc += word;
+
+       regs.clock += 5;
 }
-static void Op1029(void)  // LBVS
+
+static void Op1029(void)                                               // LBVS
 {
-  addr = FetchW();
-  if (regs.cc&0x02)  regs.pc += SignedW(addr);
-  regs.clock += 5;
+       uint16 word = FetchW();
+
+       if (regs.cc & 0x02)
+               regs.pc += word;
+
+       regs.clock += 5;
 }
-static void Op102A(void)  // LBPL
+
+static void Op102A(void)                                               // LBPL
 {
-  addr = FetchW();
-  if (!(regs.cc&0x08))  regs.pc += SignedW(addr);
-  regs.clock += 5;
+       uint16 word = FetchW();
+
+       if (!(regs.cc & 0x08))
+               regs.pc += word;
+
+       regs.clock += 5;
 }
-static void Op102B(void)  // LBMI
+
+static void Op102B(void)                                               // LBMI
 {
-  addr = FetchW();
-  if (regs.cc&0x08)  regs.pc += SignedW(addr);
-  regs.clock += 5;
+       uint16 word = FetchW();
+
+       if (regs.cc & 0x08)
+               regs.pc += word;
+
+       regs.clock += 5;
 }
-static void Op102C(void)  // LBGE
+
+static void Op102C(void)                                               // LBGE
 {
-  addr = FetchW();
-  if (!(((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)))  regs.pc += SignedW(addr);
-  regs.clock += 5;
+       uint16 word = FetchW();
+
+       if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
+               regs.pc += word;
+
+       regs.clock += 5;
 }
-static void Op102D(void)  // LBLT
+
+static void Op102D(void)                                               // LBLT
 {
-  addr = FetchW();
-  if (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))  regs.pc += SignedW(addr);
-  regs.clock += 5;
+       uint16 word = FetchW();
+
+       if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))
+               regs.pc += word;
+
+       regs.clock += 5;
 }
-static void Op102E(void)  // LBGT
+
+static void Op102E(void)                                               // LBGT
 {
-  addr = FetchW();
-  if (!((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))))  regs.pc += SignedW(addr);
-  regs.clock += 5;
+       uint16 word = FetchW();
+
+       if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))))
+               regs.pc += word;
+
+       regs.clock += 5;
 }
-static void Op102F(void)  // LBLE
+
+static void Op102F(void)                                               // LBLE
 {
-  addr = FetchW();
-  if ((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedW(addr);
-  regs.clock += 5;
+       uint16 word = FetchW();
+
+       if ((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
+               regs.pc += word;
+
+       regs.clock += 5;
 }
+
 static void Op103F(void)  // SWI2 (Not yet implemented)
 {
   regs.clock += 20;
@@ -2827,20 +3014,24 @@ static void Op11BC(void)  // CMPS ABS
 }
 
 //temp, for testing...
-/*static uint8 backTrace[256];
+#ifdef __DEBUG__
+static uint8 backTrace[256];
 static uint16 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++)
 {
-       dpc = btPC[(btPtr+i)&0xFF];
-       Decode_6809();
+       Decode6809(btPC[(btPtr + i) & 0xFF]);
+       WriteLog("\n");
 }//*/
+#endif
 }
 
 
@@ -2858,24 +3049,76 @@ static void myMemcpy(void * dst, void * src, uint32 size)
 //
 // Function to execute 6809 instructions
 //
+//#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)
 {
+       // 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(&regs, context, sizeof(V6809REGS));
 
        // Execute here...
-uint32 clockSave = regs.clock;
-regs.clock = 0;
-       while (regs.clock < cycles)
+
+       // 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);
+
+       while (regs.clock < endCycles)
        {
-/*static bool disasm = false;
-if (regs.pc == 0x15BA) disasm = true;
-if (disasm) { dpc = regs.pc; Decode_6809(); }
-if (regs.pc == 0x164A) disasm = false;//*/
+#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;
+static bool disasm = true;
+if (disasm) Decode6809(regs);
+/*//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++) & 0xFF;//*/
+btPtr = (btPtr + 1) & 0xFF;//*/
+#endif
                exec_op0[regs.RdMem(regs.pc++)]();
 
                // Handle any pending interrupts
@@ -2884,6 +3127,9 @@ btPtr = (btPtr++) & 0xFF;//*/
 
                if (flags & V6809_ASSERT_LINE_RESET)                    // *** RESET handler ***
                {
+#ifdef __DEBUG__
+if (disasm) WriteLog("\nV6809: RESET line asserted!\n");
+#endif
                        regs.cc |= (FLAG_F | FLAG_I);                           // Set F, I
                        regs.dp = 0;                                                            // Reset direct page register
                        regs.pc = RdMemW(0xFFFE);                                       // And load PC with the RESET vector
@@ -2892,6 +3138,9 @@ btPtr = (btPtr++) & 0xFF;//*/
                }
                else if (flags & V6809_ASSERT_LINE_NMI)                 // *** NMI handler ***
                {
+#ifdef __DEBUG__
+if (disasm) WriteLog("\nV6809: NMI line asserted!\n");
+#endif
                        regs.cc |= FLAG_E;                                                      // Set the Entire flag
 
                        regs.WrMem(--regs.s, regs.pc & 0xFF);           // Save all regs...
@@ -2910,13 +3159,19 @@ btPtr = (btPtr++) & 0xFF;//*/
                        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 ***
                {
+#ifdef __DEBUG__
+if (disasm) WriteLog("\nV6809: FIRQ line asserted!\n");
+#endif
                        if (!(regs.cc & FLAG_F))                                        // Is the FIRQ masked (F == 1)?
                        {
+#ifdef __DEBUG__
+if (disasm) WriteLog("       FIRQ taken...\n");
+#endif
                                regs.cc &= ~FLAG_E;                                             // Clear the Entire flag
 
                                regs.WrMem(--regs.s, regs.pc & 0xFF);   // Save PC, CC regs...
@@ -2926,14 +3181,20 @@ btPtr = (btPtr++) & 0xFF;//*/
                                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 ***
                {
+#ifdef __DEBUG__
+if (disasm) WriteLog("\nV6809: IRQ line asserted!\n");
+#endif
                        if (!(regs.cc & FLAG_I))                                        // Is the IRQ masked (I == 1)?
                        {
+#ifdef __DEBUG__
+if (disasm) WriteLog("       IRQ taken...\n");
+#endif
                                regs.cc |= FLAG_E;                                              // Set the Entire flag
 
                                regs.WrMem(--regs.s, regs.pc & 0xFF);   // Save all regs...
@@ -2952,14 +3213,50 @@ btPtr = (btPtr++) & 0xFF;//*/
                                regs.cc |= FLAG_I;                                              // 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!
+// Need to put IRQ handling in somewhere... It shouldn't be cleared here!
                                context->cpuFlags &= ~V6809_ASSERT_LINE_IRQ;    // Reset the asserted line (IRQ)...
                                regs.cpuFlags &= ~V6809_ASSERT_LINE_IRQ;        // Reset the asserted line (IRQ)...
                        }
                }
-/*if (disasm) WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
+#ifdef __DEBUG__
+if (disasm) 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);//*/
+/*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
        }
-regs.clock += clockSave;
+
+       // Keep track of how much we overran so we can adjust on the next run...
+       regs.clockOverrun = (uint32)(regs.clock - endCycles);
 
        myMemcpy(context, &regs, sizeof(V6809REGS));
 }
+
+//
+// Get the clock of the currently executing CPU
+//
+uint64 GetCurrentV6809Clock(void)
+{
+       return regs.clock;
+}
+
+//
+// Get the PC of the currently executing CPU
+//
+uint16 GetCurrentV6809PC(void)
+{
+       return regs.pc;
+}
+
+// Set a line of the currently executing CPU
+void SetLine(uint32 line)
+{
+       regs.cpuFlags |= line;
+}
+
+// Clear a line of the currently executing CPU
+void ClearLine(uint32 line)
+{
+       regs.cpuFlags &= ~line;
+}
index 6ad4424c03eec039f758ba9902eca239e70a7872..9511654fb9ceb3647bffa0a4fbbfd2e74cc50e8c 100755 (executable)
@@ -3,7 +3,7 @@
 //
 // by James L. Hammons
 //
-// (c) 1997, 2004 Underground Software
+// (C) 1997, 2004 Underground Software
 //
 
 #ifndef __V6809_H__
 
 struct V6809REGS
 {
-       uint16 pc;                                      // 6809 PC register
+       uint16 pc;                                              // 6809 PC register
        uint16 x;                                               // 6809 X index register
        uint16 y;                                               // 6809 Y index register
        uint16 s;                                               // 6809 System stack pointer
        uint16 u;                                               // 6809 User stack pointer
-       uint8 cc;                                       // 6809 Condition Code register
+       uint8 cc;                                               // 6809 Condition Code register
        uint8 a;                                                // 6809 A register
        uint8 b;                                                // 6809 B register
-       uint8 dp;                                       // 6809 Direct Page register
-       uint32 clock;                           // 6809 clock
-//uint32 _reserved;//  uint8 (* Fetch)(uint16&);               // Address of uint8 fetch routine
+       uint8 dp;                                               // 6809 Direct Page register
+//     uint32 clock;                                   // 6809 clock (@ 1 MHz, wraps at 71.5 minutes)
+       uint64 clock;                                   // 6809 clock (@ 1 MHz, wraps at 570842 years)
        uint8 (* RdMem)(uint16);                // Address of uint8 read routine
        void (* WrMem)(uint16, uint8);  // Address of uint8 write routine
        uint32 cpuFlags;                                // v6809 IRQ/RESET flags
+       uint32 clockOverrun;
 };
 
 // Function prototypes
 
-void Execute6809(V6809REGS *, uint32);                                 // Function to execute 6809 instructions
+void Execute6809(V6809REGS *, uint32);                 // Function to execute 6809 instructions
+uint64 GetCurrentV6809Clock(void);                             // Get the clock of the currently executing CPU
+uint16 GetCurrentV6809PC(void);                                        // Get the PC of the currently executing CPU
+void SetLine(uint32 line);                                             // Set a line of the currently executing CPU
+void ClearLine(uint32 line);                                   // Clear a line of the currently executing CPU
 
 #endif // __V6809_H__