]> Shamusworld >> Repos - stargem2/commitdiff
Some more fixes to the V6809 core to prevent clock destruction, fixes to
authorShamus Hammons <jlhamm@acm.org>
Sat, 18 Jul 2009 03:50:32 +0000 (03:50 +0000)
committerShamus Hammons <jlhamm@acm.org>
Sat, 18 Jul 2009 03:50:32 +0000 (03:50 +0000)
make it so that fix doesn't screw up the demo mode.

Makefile
src/sdlemu_config.cpp
src/stargem2.cpp
src/v6808.cpp
src/v6809.cpp
src/v6809.h
stargem2.cfg

index c8e488649902f37c4784557988ce74bdc4ecc68c..52955a6dc055da7eee3252ed6c87146c95e4dbca 100755 (executable)
--- 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)
index 75d764430dd98880da08d3fd0725178fad24dfb5..5b063ea8a59bcf70fac68a3b22ec89e265b6e1cf 100755 (executable)
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+
 #include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
 #include <string>
 #include <list>
 #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<token_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<token_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<token_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;
index 9ee92439be4807c372777dee64f32405a92cef8c..32248fcdd8d6bc854fe611d5f02c778a1c00e88a 100755 (executable)
@@ -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...
index b7691cf4122bcbca0f2b4c30a1648faa1de79051..96ff8144c23a3ae0dbd827a0cf6b9667d61e90dc 100755 (executable)
@@ -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)...
                        }
index 45e072d1363bff8b92d294049695534eb699b148..197cdea906a88ae1b653aecc253499be4220e8ae 100755 (executable)
@@ -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(&regs, 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, &regs, sizeof(V6809REGS));
 }
 
 //
 // Get the clock of the currently executing CPU
 //
-uint32 GetCurrentV6809Clock(void)
+uint64 GetCurrentV6809Clock(void)
 {
        return regs.clock;
 }
index d371f06f380c8675136d35f02f5d32bd2f1dcf63..4655ef5809dfe3d3172302551661a99413cd7f0a 100755 (executable)
@@ -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
index 76daeb416b530abe3774fe9d32f8d9aaf9ef04f5..9b04a0dc901641777ae300d98c406732d4fa83b9 100755 (executable)
@@ -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