]> Shamusworld >> Repos - thunder/commitdiff
Fixed IRQ/DAA problems. Emulator is now in a stable state. Woo hoo!
authorShamus Hammons <jlhamm@acm.org>
Thu, 13 Aug 2009 00:10:24 +0000 (00:10 +0000)
committerShamus Hammons <jlhamm@acm.org>
Thu, 13 Aug 2009 00:10:24 +0000 (00:10 +0000)
src/thunder.cpp
src/v6809.cpp

index 5fdd7a88fd114daf1cee260c3d98a5da61b43d49..17ea566f26774da6ad315789ed1df2f5584a855e 100755 (executable)
@@ -310,6 +310,7 @@ uint8 RdMem(uint16 addr)
 //
 void WrMem(uint16 addr, uint8 b)
 {
+       extern bool disasm;
        extern bool charbase;                                                           // Needed for screen. Extern it in it??
   //extern uint16 sr, ur, xr, yr;            // Needed for tracelog
   //extern uint16 pcr;
@@ -362,6 +363,10 @@ void WrMem(uint16 addr, uint8 b)
 //             cpu1.cpuFlags |= V6809_ASSERT_LINE_IRQ;//wil wok???
                // IRQ Ack (may also be frame go...
 //             cpu1.cpuFlags &= ~V6809_ASSERT_LINE_IRQ;
+#if 1
+       if (disasm)
+               WriteLog("WriteMem: CPU #1 Acknowledging IRQ...\n", b);
+#endif
                ClearLineOfCurrentV6809(V6809_ASSERT_LINE_IRQ);
        }
 }
@@ -401,6 +406,7 @@ uint8 RdMemB(uint16 addr)
 //
 void WrMemB(uint16 addr, uint8 b)
 {
+       extern bool disasm;
        extern bool charbase;
   //extern uint16 sr, ur, xr, yr;            // Needed for tracelog
   //extern uint16 pcr;
@@ -452,6 +458,10 @@ void WrMemB(uint16 addr, uint8 b)
        {
                // IRQ Ack (may also be frame go...)
 //             cpu2.cpuFlags &= ~V6809_ASSERT_LINE_IRQ;
+#if 1
+       if (disasm)
+               WriteLog("WriteMem: CPU #2 Acknowledging IRQ...\n", b);
+#endif
                ClearLineOfCurrentV6809(V6809_ASSERT_LINE_IRQ);
        }
 }
@@ -1494,7 +1504,7 @@ WriteLog("About to enter main loop...\n");
                                }
                                if (keys[SDLK_d])                               // (D) start disassembly
                                        disasm = true;
-#if 1
+#if 0
        if (keys[SDLK_k])
                gram1[0x5606] = 0x00;
        if (keys[SDLK_l])
@@ -1510,22 +1520,9 @@ WriteLog("About to enter main loop...\n");
 #endif
 
 
-//                             if (enable_cpu)
-                               if (true)
+                               if (enable_cpu)
+//                             if (true)
                                {
-#if 0
-//                                     if (irqGoA)
-                                               cpu1.cpuFlags |= V6809_ASSERT_LINE_IRQ;
-
-                                       Execute6809(&cpu1, 25000);
-                                       cpu1.clock -= 25000;                            // Remove 25K ticks from clock (in case it overflowed)
-
-//                                     if (irqGoB)
-                                               cpu2.cpuFlags |= V6809_ASSERT_LINE_IRQ;
-
-                                       Execute6809(&cpu2, 25000);
-                                       cpu2.clock -= 25000;                            // Remove 25K ticks from clock (in case it overflowed)//*/
-#else
                                        // We can do this here because we're not executing the cores yet.
                                        cpu1.cpuFlags |= V6809_ASSERT_LINE_IRQ;
                                        cpu2.cpuFlags |= V6809_ASSERT_LINE_IRQ;
@@ -1533,15 +1530,19 @@ WriteLog("About to enter main loop...\n");
 // 1.538 MHz = 25633.333... cycles per frame (1/60 s)
 // 25600 cycles/frame
 // Setting interleave to 25 and below causes the V6809 core to hang...
+// 32 gets to the title screen before hanging...
 // 40 works, until it doesn't... :-P
+// 640 * 40
+// 800 * 32
+// Interesting, putting IRQs at 30 Hz makes it run at the correct speed. Still hangs in the demo, though.
                                        for(uint32 i=0; i<640; i++)
+//                                     for(uint32 i=0; i<1280; i++)
                                        {
                                                // Gay, but what are ya gonna do?
                                                // There's better ways, such as keeping track of when slave writes to master, etc...
                                                Execute6809(&cpu1, 40);
                                                Execute6809(&cpu2, 40);
                                        }
-#endif
                                } // END: enable_cpu
 
 //        if (refresh_++ == 1)                // 30 Hz...
@@ -1553,11 +1554,13 @@ WriteLog("About to enter main loop...\n");
 //          refresh_ = (refresh2 ? 1 : 0);    // 60/30 Hz...
 //        }
 
+#if 1
 //temp, for testing...
 BlitChar(screen, chr_rom, gram1);
-
+#endif
                                // Speed throttling happens here...
                                while (SDL_GetTicks() - oldTicks < 16)  // Actually, it's 16.66... Need to account for that somehow
+//                             while (SDL_GetTicks() - oldTicks < 32)  // Actually, it's 16.66... Need to account for that somehow
                                        SDL_Delay(1);                           // Release our timeslice...
 
                                oldTicks = SDL_GetTicks();
index c8e081a7a72ff419acbb7aa328fef2a09370756e..487493762f5a947db704d4a2eb9337beaffc5145 100755 (executable)
@@ -637,18 +637,47 @@ static void Op17(void)                                                    // LBSR
 
 static void Op19(void)  // DAA
 {
-  if ((regs.cc&0x20) || ((regs.a&0x0F) > 0x09))    // H set or lo nyb too big?
-  {
-    regs.a += 0x06;  regs.cc |= 0x20;              // Then adjust & set half carry
-  }
-  if ((regs.cc&0x01) || (regs.a > 0x9F))           // C set or hi nyb too big?
-  {
-    regs.a += 0x60;  regs.cc |= 0x01;              // Then adjust & set carry
-  }
-  regs.cc &= 0xF1;                             // CL NZV
-  if (regs.a == 0)  regs.cc |= 0x04;               // Adjust Zero flag
-  if (regs.a&0x80)  regs.cc |= 0x08;               // Adjust Negative flag
-  regs.clock += 2;
+#if 0
+       uint8 result = regs.a;
+
+       if ((regs.cc&0x20) || ((regs.a&0x0F) > 0x09))    // H set or lo nyb too big?
+       {
+//             regs.a += 0x06;
+               result += 0x06;
+               regs.cc |= 0x20;              // Then adjust & set half carry
+       }
+
+       if ((regs.cc&0x01) || (regs.a > 0x9F))           // C set or hi nyb too big?
+       {
+//             regs.a += 0x60;
+               result += 0x60;
+               regs.cc |= 0x01;              // Then adjust & set carry
+       }
+
+       regs.a = result;
+
+       regs.cc &= 0xF1;                             // CL NZV
+       if (regs.a == 0)  regs.cc |= 0x04;               // Adjust Zero flag
+       if (regs.a&0x80)  regs.cc |= 0x08;               // Adjust Negative flag
+#else
+       uint16 result = (uint16)regs.a;
+
+       if ((regs.a & 0x0F) > 0x09 || (regs.cc & FLAG_H))
+               result += 0x06;
+
+       if ((regs.a & 0xF0) > 0x90 || (regs.cc & FLAG_C) || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
+               result += 0x60;
+
+       regs.a = (uint8)result;
+//     SET_ZN(result);
+//     CLR_V;                                                                          // Not sure this is correct...
+       regs.cc &= 0xF1;                             // CL NZV
+       if (regs.a == 0)  regs.cc |= 0x04;               // Adjust Zero flag
+       if (regs.a&0x80)  regs.cc |= 0x08;               // Adjust Negative flag
+//     flagC |= (result & 0x100) >> 8;                         // Overwrite carry if it was 0, otherwise, ignore
+       regs.cc |= (result & 0x100) > 8;
+#endif
+       regs.clock += 2;
 }
 
 static void Op1A(void)                                                                 // ORCC #
@@ -3126,7 +3155,9 @@ btPtr = (btPtr + 1) & 0xFF;//*/
 
                // Handle any pending interrupts
 
-               uint32 flags = context->cpuFlags;
+// Hmm, this is bad and only works when flags are changed OUTSIDE of the running context...
+//             uint32 flags = context->cpuFlags;
+               uint32 flags = regs.cpuFlags;
 
                if (flags & V6809_ASSERT_LINE_RESET)                    // *** RESET handler ***
                {
@@ -3268,5 +3299,46 @@ void SetLineOfCurrentV6809(uint32 line)
 // Clear a line of the currently executing CPU
 void ClearLineOfCurrentV6809(uint32 line)
 {
+#ifdef __DEBUG__
+if (disasm)
+       WriteLog("V6809: Clearing line %s...", (line == V6809_ASSERT_LINE_IRQ ? "IRQ" : "OTHER"));
+#endif
        regs.cpuFlags &= ~line;
 }
+
+/*
+Small problem: IRQ is not getting cleared!
+
+
+820E: 9A 01          ORA   $01
+V6809: IRQ line asserted!
+        CC=EF-I-Z-- A=00 B=00 DP=56 X=533C Y=53C0 S=57EE U=8215 PC=8210
+8210: A6 C6          LDA   (A),U
+V6809: IRQ line asserted!
+        CC=EF-I---- A=01 B=00 DP=56 X=533C Y=53C0 S=57EE U=8215 PC=8212
+
+*** CONTEXT SWITCH ***
+
+818E: B7 80 00       STA   $8000
+V6809: IRQ line asserted!
+        CC=EF-I---- A=02 B=00 DP=16 X=81AD Y=6224 S=03F2 U=89D7 PC=8191
+8191: B7 88 00       STA   $8800
+WriteMem: CPU #2 Acknowledging IRQ...
+V6809: Clearing line IRQ...
+V6809: IRQ line asserted!
+        CC=EF-I---- A=02 B=00 DP=16 X=81AD Y=6224 S=03F2 U=89D7 PC=8194
+8194: 3B             RTI
+V6809: IRQ line asserted!
+       IRQ taken...
+        CC=EF-I-Z-- A=03 B=00 DP=16 X=1308 Y=6224 S=03F2 U=B0DC PC=8173
+
+*** CONTEXT SWITCH ***
+
+8212: 97 1E          STA   $1E
+V6809: IRQ line asserted!
+        CC=EF-I---- A=01 B=00 DP=56 X=533C Y=53C0 S=57EE U=8215 PC=8214
+8214: 39             RTS
+V6809: IRQ line asserted!
+
+
+*/
\ No newline at end of file