From d1485d7c8a16bf3dd7601bbf6016998eb28bf989 Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Sat, 18 Jul 2009 03:50:32 +0000 Subject: [PATCH] Some more fixes to the V6809 core to prevent clock destruction, fixes to make it so that fix doesn't screw up the demo mode. --- Makefile | 26 ++-- src/sdlemu_config.cpp | 14 ++- src/stargem2.cpp | 285 ++++++++---------------------------------- src/v6808.cpp | 1 + src/v6809.cpp | 66 ++++++---- src/v6809.h | 7 +- stargem2.cfg | 4 +- 7 files changed, 117 insertions(+), 286 deletions(-) diff --git a/Makefile b/Makefile index c8e4886..52955a6 100755 --- a/Makefile +++ b/Makefile @@ -71,36 +71,36 @@ OBJS = \ all: checkenv message obj $(TARGET)$(EXESUFFIX) @echo - @echo "*** Looks like it compiled OK... Give it a whirl!" + @echo -e "\033[01;33m***\033[00;32m Looks like it compiled OK... Give it a whirl!\033[00m" # Check the compilation environment, barf if not appropriate checkenv: @echo - @echo -n "*** Checking compilation environment... " + @echo -en "\033[01;33m***\033[00;32m Checking compilation environment... \033[00m" ifeq "" "$(shell which sdl-config)" @echo @echo - @echo "It seems that you don't have the SDL development libraries installed. If you" - @echo "have installed them, make sure that the sdl-config file is somewhere in your" - @echo "path and is executable." + @echo -e "\033[01;33mIt seems that you don't have the SDL development libraries installed. + @echo -e "have installed them, make sure that the sdl-config file is somewhere in your" + @echo -e "path and is executable.\033[00m" @echo #Is there a better way to break out of the makefile? @break else - @echo "OK" + @echo -e "\033[01;37mOK\033[00m" endif message: @echo - @echo "*** Building StarGem 2 for $(MSG)..." + @echo -e "\033[01;33m***\033[00;32m Building StarGem 2 for $(MSG)...\033[00m" @echo clean: - @echo -n "*** Cleaning out the garbage..." + @echo -en "\033[01;33m***\033[00;32m Cleaning out the garbage...\033[00m" @rm -rf obj @rm -f ./$(TARGET)$(EXESUFFIX) - @echo "done!" + @echo -e "\033[01;37mdone!\033[00m" obj: @mkdir obj @@ -109,20 +109,20 @@ obj: ifneq "" "$(ICON)" $(ICON): res/$(TARGET).rc res/$(TARGET).ico - @echo "*** Processing icon..." + @echo -e "\033[01;33m***\033[00;32m Processing icon...\033[00m" @windres -i res/$(TARGET).rc -o $(ICON) --include-dir=./res endif obj/%.o: src/%.c - @echo "*** Compiling $<..." + @echo -e "\033[01;33m***\033[00;32m Compiling $<...\033[00m" @$(CC) $(CFLAGS) $(INCS) -c $< -o $@ obj/%.o: src/%.cpp - @echo "*** Compiling $<..." + @echo -e "\033[01;33m***\033[00;32m Compiling $<...\033[00m" @$(CC) $(CPPFLAGS) $(INCS) -c $< -o $@ $(TARGET)$(EXESUFFIX): $(OBJS) - @echo "*** Linking it all together..." + @echo -e "\033[01;33m***\033[00;32m Linking it all together...\033[00m" @$(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) # strip --strip-all $(TARGET)$(EXESUFFIX) # upx -9 $(TARGET)$(EXESUFFIX) diff --git a/src/sdlemu_config.cpp b/src/sdlemu_config.cpp index 75d7644..5b063ea 100755 --- a/src/sdlemu_config.cpp +++ b/src/sdlemu_config.cpp @@ -16,8 +16,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - + #include +#include +#include #include #include #include "sdlemu_config.h" @@ -76,11 +78,11 @@ int sdlemu_init_config(const char *filename) { FILE *f = fopen(filename, "r"); if(!f) return 0; - + fseek(f, 0, SEEK_END); int len = ftell(f); fseek(f, 0, SEEK_SET); - + char *s = new char[len]; fread(s, 1, len, f); string str(s); @@ -115,7 +117,7 @@ const char *sdlemu_getval_string(const char *key_string, const char *default_str { list::iterator p; for(p = vec.begin(); p != vec.end(); p++) { - + if(strcmp((*p).Token().c_str(), key_string) == 0) return (*p).Value().c_str(); } @@ -126,7 +128,7 @@ int sdlemu_getval_int(const char *key_string, int default_int) { list::iterator p; for(p = vec.begin(); p != vec.end(); p++) { - + if(strcmp((*p).Token().c_str(), key_string) == 0) { const char *ret = (*p).Value().c_str(); if(ret) return atoi(ret); @@ -139,7 +141,7 @@ int sdlemu_getval_bool(const char *key_string, int default_int) { list::iterator p; for(p = vec.begin(); p != vec.end(); p++) { - + if(strcmp((*p).Token().c_str(), key_string) == 0) { const char *ret = (*p).Value().c_str(); if(ret) return atoi(ret)>0; diff --git a/src/stargem2.cpp b/src/stargem2.cpp index 9ee9243..32248fc 100755 --- a/src/stargem2.cpp +++ b/src/stargem2.cpp @@ -10,6 +10,7 @@ // --- ---------- ------------------------------------------------------------ // 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" @@ -31,9 +32,8 @@ #include "dis6809.h" #include "dis6808.h" -#define __DEBUG__ - -#define LOG_PIA1_IO +//#define __DEBUG__ +//#define LOG_PIA1_IO using namespace std; @@ -55,6 +55,7 @@ bool paletteDirty = false; 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 @@ -85,14 +86,34 @@ uint8 RdMem6809(uint16 addr) // 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; @@ -119,7 +140,7 @@ void WrMem6809(uint16 addr, uint8 b) 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; @@ -127,30 +148,21 @@ void WrMem6809(uint16 addr, uint8 b) 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; @@ -167,7 +179,6 @@ void WrMem6809(uint16 addr, uint8 b) paletteDirty = true; #endif } -#endif else if (addr == 0xC80E) { sram[0x0402] = b; // Connect PIAs in 6809 & 6808 @@ -196,6 +207,7 @@ void WrMem6808(uint16 addr, uint8 b) // 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; } @@ -249,13 +261,17 @@ bool LoadMachineState(void) 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; } @@ -286,6 +302,7 @@ int main(int /*argc*/, char * /*argv*/[]) { InitLog("stargem2.log"); WriteLog("StarGem2 - A portable Stargate emulator by James L. Hammons\n"); + WriteLog("(C) 2009 Underground Software\n\n"); LoadSettings(); @@ -303,8 +320,6 @@ int main(int /*argc*/, char * /*argv*/[]) #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); @@ -334,10 +349,6 @@ int main(int /*argc*/, char * /*argv*/[]) 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]); @@ -373,178 +384,15 @@ WriteLog("Loading ROM image '%s' at $%04X...\n", ROMs[i], baseAddress); 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"); @@ -555,7 +403,9 @@ for(int i=0; i<200; i++) 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(); } @@ -579,8 +429,6 @@ while (pc < 0xFFFF) pc += Decode6809(pc); WriteLog("\n"); }//*/ -#endif - #endif SoundDone(); @@ -643,15 +491,9 @@ static void FrameCallback(void) 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; @@ -670,11 +512,8 @@ for(int i=0; i<16; i++) 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); @@ -684,50 +523,26 @@ for(int i=0; i<16; i++) 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... diff --git a/src/v6808.cpp b/src/v6808.cpp index b7691cf..96ff814 100755 --- a/src/v6808.cpp +++ b/src/v6808.cpp @@ -2177,6 +2177,7 @@ logGo = true; regs.pc = RdMemW(0xFFF8); // And do it! regs.clock += 0; // How many??? +#warning "IRQ/NMI lines should not be cleared here... !!! FIX !!!" context->cpuFlags &= ~V6808_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)... regs.cpuFlags &= ~V6808_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)... } diff --git a/src/v6809.cpp b/src/v6809.cpp index 45e072d..197cdea 100755 --- a/src/v6809.cpp +++ b/src/v6809.cpp @@ -17,7 +17,7 @@ // We have a start... ;-) // -#define __DEBUG__ +//#define __DEBUG__ #include "v6809.h" @@ -46,6 +46,7 @@ #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 @@ -218,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 @@ -384,37 +378,30 @@ 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; @@ -465,19 +452,12 @@ uint16 DecodeIDX(uint8 code) } 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; } } } @@ -3069,12 +3049,33 @@ static void myMemcpy(void * dst, void * src, uint32 size) // // 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); @@ -3130,8 +3131,8 @@ if (disasm) WriteLog("\nV6809: NMI line asserted!\n"); 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 *** { @@ -3152,8 +3153,8 @@ if (disasm) WriteLog(" FIRQ taken...\n"); 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 *** @@ -3197,13 +3198,24 @@ if (disasm) WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04 #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; } diff --git a/src/v6809.h b/src/v6809.h index d371f06..4655ef5 100755 --- a/src/v6809.h +++ b/src/v6809.h @@ -44,17 +44,18 @@ struct V6809REGS 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 +// 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 -uint32 GetCurrentV6809Clock(void); // Get the clock of the currently executing CPU +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 diff --git a/stargem2.cfg b/stargem2.cfg index 76daeb4..9b04a0d 100755 --- a/stargem2.cfg +++ b/stargem2.cfg @@ -18,7 +18,7 @@ autoSaveState = 1 # OpenGL options: 1 - use OpenGL rendering, 0 - use old style rendering -useOpenGL = 0 +useOpenGL = 1 # OpenGL filtering type: 1 - blurry, 0 - sharp @@ -46,7 +46,7 @@ frameSkip = 0 useJoystick = 0 -# Joyport option: If joystick is enabled above, set the port (0 - 3) here +# Joyport option: If joystick is enabled above, set the port (0 - 3) here joyport = 0 -- 2.37.2