// --- ---------- ------------------------------------------------------------
// JLH 06/15/2006 Added changelog ;-)
// JLH 06/15/2006 Switched over to timeslice execution code
+// JLH 07/15/2009 Solved problem with DEMO mode (IRQ handling)
//
#include "SDL.h"
#include "dis6809.h"
#include "dis6808.h"
-#define __DEBUG__
-
-#define LOG_PIA1_IO
+//#define __DEBUG__
+//#define LOG_PIA1_IO
using namespace std;
static bool running = true; // Machine running state flag...
static uint32 startTicks;
static uint8 * keys; // SDL raw keyboard matrix
+static uint64 clockFrameStart; // V6809 clock at the start of the frame
// Local timer callback functions
// A wee kludge (though I doubt it reads from anywhere other than $CB00)...
if ((addr & 0xFF00) == 0xCB00)
+#if 0
b = gram[0xCB00] & 0xFC; // Only bits 2-7 are connected...
+#else
+ {
+//Interesting, this code ALSO fucks up the demo...
+//Except when the correct code is called in the scanline callback function...
+ uint32 elapsedCycles = (uint32)(GetCurrentV6809Clock() - clockFrameStart);
+ uint32 scanline = (uint32)(((double)elapsedCycles * M6809_CYCLE_IN_USEC) / 65.10416666666667);
+//Changes here don't seem to do much...
+// uint32 scanline = (uint32)(((double)elapsedCycles * M6809_CYCLE_IN_USEC) / 70.0);
+ b = (uint8)scanline & 0xFC; // Only bits 2-7 are connected...
+ }
+#endif
// More kludge...
if ((addr == 0xC80C) && (gram[0xC80D] & 0x04)) // Read PORTA and DDR is set to Output
+ {
ClearLine(V6809_ASSERT_LINE_IRQ); // Then clear the IRQ
+//OK, this ALSO fucks up the execution of the demo...
+// mainCPU.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Then clear the IRQ
+ }
if ((addr == 0xC80E) && (gram[0xC80F] & 0x04)) // Read PORTB and DDR is set to Output
+ {
ClearLine(V6809_ASSERT_LINE_IRQ); // Then clear the IRQ
+//OK, this ALSO fucks up the execution of the demo...
+// mainCPU.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Then clear the IRQ
+ }
//temp...
/*extern uint16 pcr;
gram[addr] = b;
- if (addr > 0x0006 && addr < 0x97F7) // 304 pixels 152-128=24-16=8
+ if (addr >= 0x0006 && addr < 0x97F7) // 304 pixels 152-128=24-16=8
{
// NOTE: Screen was 304 x 256, but we truncate the vertical dimension here...
uint16 sx = (addr >> 7) & 0x01FE, sy = addr & 0x00FF;
if (sy > 5 && sy < 246)
{
uint32 saddr = 8 + sx + ((sy - 6) * 320); // Calc screen address
-//Hmm. This approach won't work with palette color cycling...
-#if 0
- scrBuffer[saddr + 0] = b >> 4;
- scrBuffer[saddr + 1] = b & 0x0F;
-#else
scrBuffer[saddr + 0] = palette[color[b >> 4]];
scrBuffer[saddr + 1] = palette[color[b & 0x0F]];
-#endif
}
}
else if (addr >= 0xC000 && addr <= 0xC00F)
-//Let's see if we can fix the color cycling here... [DONE]
-#if 0
- color[addr - 0xC000] = b; // color[] from VIDEO.CPP (not any more!)
-#else
{
// A better strategy here would probably be to set a flag when the color register changes,
// then change it before doing the render.
// ALSO: This approach doesn't take the color to the edges of the screen
-#warning "This should only touch memory right before a render. !!! FIX !!!"
+//#warning "This should only touch memory right before a render. !!! FIX !!!"
+//Now it does. :-)
color[addr - 0xC000] = b;
#if 0
- for(uint32 addr=0x0007; addr<0x97F7; addr++)
+ for(uint32 addr=0x0006; addr<0x97F7; addr++)
{
uint16 sx = (addr >> 7) & 0x01FE, sy = addr & 0x00FF;
paletteDirty = true;
#endif
}
-#endif
else if (addr == 0xC80E)
{
sram[0x0402] = b; // Connect PIAs in 6809 & 6808
// A total guess, but let's try it...
//It probably depends on how the PIA is configured, so this is most likely wrong.
+// It is wrong: IRQs are cleared on PIA PORTx reads!
// if (addr == 0x0401)
// soundCPU.cpuFlags &= ~V6808_ASSERT_LINE_IRQ;
}
ignoredResult = fread(&soundCPU, 1, sizeof(V6808REGS), fp);
fclose(fp);
- for(int i=0x0006; i<0x97F8; i++) // Set up backbuffer... ;-)
- WrMem6809(i, gram[i]);
+// for(int i=0x0006; i<0x97F8; i++) // Set up backbuffer... ;-)
+// WrMem6809(i, gram[i]);
+
+ paletteDirty = true; // Set up backbuffer...
mainCPU.RdMem = RdMem6809; // Make sure our function pointers are
mainCPU.WrMem = WrMem6809; // pointing to the right places!
soundCPU.RdMem = RdMem6808;
soundCPU.WrMem = WrMem6808;
+ mainCPU.clock = 0; // Zero out our clocks...
+ soundCPU.clock = 0;
return true;
}
{
InitLog("stargem2.log");
WriteLog("StarGem2 - A portable Stargate emulator by James L. Hammons\n");
+ WriteLog("(C) 2009 Underground Software\n\n");
LoadSettings();
#endif
// Zero out memory
-// for(long i=0; i<0x10000; i++)
-// gram[i] = grom[i] = sram[i] = srom[i] = 0;
memset(gram, 0, 0x10000);
memset(grom, 0, 0x10000);
memset(sram, 0, 0x10000);
if (i > 8)
baseAddress += 0x4000;
-#if 0
-WriteLog("Loading ROM image '%s' at $%04X...\n", ROMs[i], baseAddress);
-#endif
-// if (!LoadImg(ROMs[i], grom + (i * 0x1000), 0x1000))
if (!LoadImg(ROMs[i], grom + baseAddress, 0x1000))
{
WriteLog("Could not open file '%s'!\n", ROMs[i]);
WriteLog("About to intialize audio...\n");
SoundInit();
-// uint8 * keys = SDL_GetKeyState(NULL);
keys = SDL_GetKeyState(NULL);
-
-// running = true; // Set running status...
srom[0xF800] = 0x37; // Fix checksum so ST works...
-
-#if 0
-
-//kludge...
-//This didn't work--it still acted like the old way (interrupt @ VC = 0)
-//gram[0xCB00] = 64*3;
-
- WriteLog("Entering main loop...\n");
- while (running)
- {
- SDL_PumpEvents(); // Force key events into the buffer.
- gram[0xC804] = gram[0xC806] = gram[0xC80C] = 0; // Reset PIA ports...
-
- if (keys[SDLK_ESCAPE])
- running = false; // ESC to exit...
-
- if (keys[SDLK_SEMICOLON])
- gram[0xC804] |= 0x01; // Fire (;)
- if (keys[SDLK_l])
- gram[0xC804] |= 0x02; // Thrust (L)
- if (keys[SDLK_SPACE])
- gram[0xC804] |= 0x04; // Smart Bomb (space)
- if (keys[SDLK_BACKSPACE])
- gram[0xC804] |= 0x08; // Hyperspace (BkSp)
- if (keys[SDLK_2])
- gram[0xC804] |= 0x10; // Two Player Start (2)
- if (keys[SDLK_1])
- gram[0xC804] |= 0x20; // One Player Start (1)
- if (keys[SDLK_RETURN])
- gram[0xC804] |= 0x40; // Reverse (Enter)
- if (keys[SDLK_f])
- gram[0xC804] |= 0x80; // Down (F)
-
- if (keys[SDLK_r])
- gram[0xC806] |= 0x01; // Up (R)
- if (keys[SDLK_a])
- gram[0xC806] |= 0x02; // Inviso (A)
-
- if (keys[SDLK_F1])
- gram[0xC80C] |= 0x01; // Auto up (F1)
- if (keys[SDLK_F2])
- gram[0xC80C] |= 0x02; // Advance (F2)
- if (keys[SDLK_5])
- gram[0xC80C] |= 0x04; // Right Coin (5)
- if (keys[SDLK_F3])
- gram[0xC80C] |= 0x08; // High Score Reset (F3)
- if (keys[SDLK_3])
- gram[0xC80C] |= 0x10; // Left Coin (3)
- if (keys[SDLK_4])
- gram[0xC80C] |= 0x20; // Center Coin (4)
- if (keys[SDLK_F4])
- gram[0xC80C] |= 0x40; // Slam Switch (F4)
-
- if (keys[SDLK_F5]) // Sound CPU self-test (F5)
- soundCPU.cpuFlags |= V6808_ASSERT_LINE_NMI;
- if (keys[SDLK_F6]) // Reset the 6808 (F6)
- soundCPU.cpuFlags |= V6808_ASSERT_LINE_RESET;
-
-/*
-$CB00 is scanline counter, bits 2-7 (1 frame/240 =69.44... usec)
-
-Some places of interest to look at:
-
-RdMem: Reading address C80E [=0C, PC=15C3] <- Inside interrupt (read, then discarded)...
-RdMem: Reading address CB00 [=43, PC=15C6] <- interrupt
-RdMem: Reading address C80C [=00, PC=0758] <- input (?)
-RdMem: Reading address C80C [=00, PC=07B9] <- input (?)
-RdMem: Reading address C806 [=00, PC=078C] <- input
-RdMem: Reading address C804 [=00, PC=2679] <- input
-*/
- uint32 startTicks = SDL_GetTicks();
-// long video_clk = 0;
-// gram[0xCB00] = 0;
-
-/*
-//This is where the interrupt mask is restored in CC... Hmm...
-//This enables interrupts *after* the previous interrupt has occurred... Hmm.
-//Could $C80F (rom_pia_ctrlb) be the IRQ inhibit? Yes, it is!
-
- // the IRQ signal comes into CB1, and is set to VA11
- pia_1_cb1_w(0, scanline & 0x20);
-...
- // the COUNT240 signal comes into CA1, and is set to the logical AND of VA10-VA13
- pia_1_ca1_w(0, 0);
-...
- // the COUNT240 signal comes into CA1, and is set to the logical AND of VA10-VA13
- pia_1_ca1_w(0, 1);
-*/
-
-//WriteLog("--> Start of frame...\n");
- for(int i=0; i<3; i++)
- {
-//Not sure, but this *might* fix IRQ problem...
-//Checking the PIA IRQ mask for an IRQ seems to work OK. Now if only the timing elsewhere was right...
- if (gram[0xC80F] & 0x01)
- mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;//*/
-
- Execute6809(&mainCPU, 4000);
- mainCPU.clock -= 4000; // Remove 4K ticks from clock (in case it overflowed)
-//Not sure, but this *might* fix IRQ problem...
-//Checking the PIA IRQ mask for an IRQ seems to work OK. Now if only the timing elsewhere was right...
-/* if (gram[0xC80F] & 0x01)
- mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;//*/
-
- gram[0xCB00] += 64; // Update video counter...
- }
-
-//Hmm.
-/*if (gram[0xC80E] & 0x01)
- mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;//*/
-//48 lines... (+ 16)
-//gram[0xCB00] = 0;
- Execute6809(&mainCPU, 3000);
- mainCPU.clock -= 3000; // Remove 3K ticks from clock (in case it overflowed)
-//Not sure, but this *might* fix IRQ problem...
-//if (gram[0xC80F] & 0x01)
-//This isn't the right port on the PIA, but it does seem to make it through the demo now...
-//Lesse if this works... Seems to!
- if (gram[0xC80D] & 0x01) // Do COUNT240 IRQ (if enabled!)
- mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;
-
-/*if (gram[0xC80F] & 0x01)
- mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;
-gram[0xCB00] = 0; //*/
-
- gram[0xCB00] += 48; // Update video counter...
-
- Execute6809(&mainCPU, 1000);
- mainCPU.clock -= 1000; // Remove 1K ticks from clock (in case it overflowed)
-//Eh?
-//Ok, this is the interrupt it's looking for, but still...
-//if (gram[0xC80F] & 0x01)
-// mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;
-
- gram[0xCB00] += 16; // Update video counter...
-
-// RenderScreenBuffer();
- RenderScreenBuffer2(); // 1 frame = 16667 cycles
-// WriteLog("Main: Rendered back buffer. [6809 PC=%04X]\n", pcr);
-
- Execute6809(&mainCPU, 667); // Do QnD VBLANK
-
- // 1/60 sec = ? ms (16.6 ms)
- while (SDL_GetTicks() - startTicks < 16); // Wait for next frame...
-
-//kludge, temp...
-//Very interesting! It's the palette rotation that's slowing it down!
-//Fixed now, but this allows the color rotation while the wrong timing is in effect...
-/*for(int i=0; i<16; i++)
- WrMem(0xC000 + i, gram[0x9C26 + i]);//*/
- }
-
-/*uint16 pc = 0x15BA;
-for(int i=0; i<200; i++)
-//while (pc < 0x9000)
- pc += Decode6809(pc);//*/
-
-#else
-
running = true; // Set running status...
InitializeEventList(); // Clear the event list before we use it...
SetCallbackTime(FrameCallback, 16666.66666667); // Set frame to fire at 1/60 s interval
-// SetCallbackTime(BlinkTimer, 250000); // Set up blinking at 1/4 s intervals
// SetCallbackTime(ScanlineCallback, 520.83333334); // Set scanline callback at 1/32 of frame
SetCallbackTime(ScanlineCallback, 520.83333334/2.0); // Set scanline callback at 1/64 of frame
-// SetCallbackTime(ScanlineCallback, 520.83333334*32.00); // Set scanline callback at 1/32 of frame
+ clockFrameStart = mainCPU.clock;
startTicks = SDL_GetTicks();
WriteLog("Entering main loop...\n");
Execute6809(&mainCPU, USEC_TO_M6809_CYCLES(timeToNextEvent));
//We MUST remove a frame's worth of time in order for the CPU to function... !!! FIX !!!
//(Fix so that this is not a requirement!)
- mainCPU.clock -= USEC_TO_M6809_CYCLES(timeToNextEvent);
+//Very odd... Execution seems to fuck up when using a 64-bit clock...
+//(i.e., when this is commented out!)
+// mainCPU.clock -= USEC_TO_M6809_CYCLES(timeToNextEvent);
HandleNextEvent();
}
pc += Decode6809(pc);
WriteLog("\n");
}//*/
-#endif
-
#endif
SoundDone();
if (keys[SDLK_F6]) // Reset the 6808 (F6)
soundCPU.cpuFlags |= V6808_ASSERT_LINE_RESET;
-#if 0
-//Grr...
-for(int i=0; i<16; i++)
- WrMem6809(0xC000 + i, gram[0x9C26 + i]);//*/
-#endif
-
if (paletteDirty)
{
- for(uint32 addr=0x0007; addr<0x97F7; addr++)
+ for(uint32 addr=0x0006; addr<0x97F7; addr++)
{
uint16 sx = (addr >> 7) & 0x01FE, sy = addr & 0x00FF;
RenderScreenBuffer(); // 1 frame = 1/60 sec ~ 16667 cycles
SetCallbackTime(FrameCallback, 16666.66666667);
+ clockFrameStart = mainCPU.clock;
-//Hmm. Yield some time?
-//This works, but doesn't seem to yield much CPU--maybe 10%
-//SDL_Delay(2);
-//The following works much better--yields as much as 50%
// Wait for next frame...
while (SDL_GetTicks() - startTicks < 16)
SDL_Delay(1);
static void ScanlineCallback(void)
{
-// CA1 of PIA 1 maps to $C80C-F... <-- Count240 is in PIA1...
-// What about COUNT240???
-// COUNT240 asserts between scanlines 240-256, and clears everywhere else. so !!! FIX !!!
#if 0
- // NOTE that this is writing to CA1!!!
- pia_1_ca1_w(0, 0); // COUNT240 off
- pia_1_ca1_w(0, 1); // COUNT240 on
- pia_1_cb1_w(0, scanline & 0x20); // Signal into CB1
- // NOTE: The reads to $CB00 are at a granularity of 4, not 8
- { 0xcb00, 0xcb00, williams_video_counter_r },
-READ_HANDLER( williams_video_counter_r )
-{
- return cpu_getscanline() & 0xFC;
-}
-#endif
-// mainCPU.cpuFlags &= ~V6809_ASSERT_LINE_IRQ;
-
-//wil wok? Yes, but still screws up on the demo...
-/* if (gram[0xCB00] & 0x20)
- if (gram[0xC80F] & 0x01)
- mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;//*/
-
if ((gram[0xCB00] & 0x20) && (gram[0xC80F] & 0x01))
mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;//*/
+#else
+ mainCPU.cpuFlags &= ~V6809_ASSERT_LINE_IRQ;
-/* if ((gram[0xCB00] >= 0xF0) && (gram[0xCB00] & 0x20) && (gram[0xC80F] & 0x01))
+ if ((RdMem6809(0xCB00) & 0x20) && (gram[0xC80F] & 0x01))
mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;//*/
+#endif
-// Hmm. No. But this *should* do it... Why doesn't it???
/*
The problem is that this is already asserted above, by virtue of the fact that
240 = $F0 = bit 5 is set! So this does nothing! So obviously, the above IRQ assertion
is wrong--just need to figure out how the write of $20 and $00 affects the PBCTRL in the PIA.
It looks like Stargate never asserts the COUNT240 IRQ, and could be because of the above...
-*/
- if ((gram[0xCB00] >= 240) && (gram[0xC80D] & 0x09)) // Do COUNT240 IRQ (if enabled!)
- mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;
-//Is $C80E COUNT240? Hmm... Doesn't seem to be. Bleh.
-/* if (gram[0xCB00] >= 240)
- gram[0xC80E] = 0xFF;
- else
- gram[0xC80E] = 0x00;//*/
-// gram[0xC80E] = (gram[0xCB00] >= 240 ? 0xFF : 0x00);
+Apparently, COUNT240 is unimportant, at least as far as STARGATE is concerned...
+*/
+// if ((gram[0xCB00] >= 240) && (gram[0xC80D] & 0x09)) // Do COUNT240 IRQ (if enabled!)
+// mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;
// This should set everything between $CB00-CBFF...
// gram[0xCB00] += 8; // Update video counter...
// 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;
}