From 7c0ff1ece391810183f1d37923a66bf30de480ee Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Thu, 13 Aug 2009 00:10:24 +0000 Subject: [PATCH] Fixed IRQ/DAA problems. Emulator is now in a stable state. Woo hoo! --- src/thunder.cpp | 39 +++++++++++--------- src/v6809.cpp | 98 ++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 106 insertions(+), 31 deletions(-) diff --git a/src/thunder.cpp b/src/thunder.cpp index 5fdd7a8..17ea566 100755 --- a/src/thunder.cpp +++ b/src/thunder.cpp @@ -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(); diff --git a/src/v6809.cpp b/src/v6809.cpp index c8e081a..4874937 100755 --- a/src/v6809.cpp +++ b/src/v6809.cpp @@ -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 -- 2.37.2