]> Shamusworld >> Repos - apple2/commitdiff
Fixed misc. bugs preventing certain games from working, added pause mode.
authorShamus Hammons <jlhamm@acm.org>
Mon, 23 Sep 2013 16:05:10 +0000 (11:05 -0500)
committerShamus Hammons <jlhamm@acm.org>
Mon, 23 Sep 2013 16:05:10 +0000 (11:05 -0500)
There was one bug that went undetected in the v65C02 core (in STX ZP,Y)
and another in the 80STORE handling (80STORE doesn't affect reading).
Also added a pause mode (bound to the Pause key), for those times when
you need to walk away from the emulation for a bit.

apple2.cfg
src/apple2.cpp
src/applevideo.cpp
src/dis65c02.cpp
src/dis65c02.h
src/sound.cpp
src/sound.h
src/v65c02.cpp
src/v65c02.h

index 3aa30c37fd8a1b383aecd199b8b85d2b35f89014..07c414caee0093f7b15e03d2d3d7919a988f1d24 100755 (executable)
@@ -25,12 +25,12 @@ autoSaveState = 1
 # Yes
 #floppyImage1 = ./disks/bt2_boot.dsk
 # Yes (but segfaults in the timer routine in the title screen--NB: Not anymore...)
-#floppyImage1 = ./disks/bt3_boot_fixed.dsk
-#floppyImage2 = ./disks/bt3_character_fixed.dsk
+floppyImage1 = ./disks/bt3_boot_fixed.dsk
+floppyImage2 = ./disks/bt3_character_fixed.dsk
 # Yes
 #floppyImage1 = ./disks/Sabotage.dsk
 # ??? (//c or //e w/128K required) (dumps to monitor) 
-floppyImage1 = ./disks/airheart.dsk
+#floppyImage1 = ./disks/airheart.dsk
 # Yes
 #floppyImage1 = ./disks/drol.dsk
 # Yes
index 12eb8c92181d9263bebb61435e5d0e13778bad51..1eeb7e88c3ed95378516e43052e57d1f2f129b11 100755 (executable)
@@ -98,6 +98,7 @@ static bool writeRAM = false;
 
 static bool running = true;                                            // Machine running state flag...
 static uint32_t startTicks;
+static bool pauseMode = false;
 
 static GUI * gui = NULL;
 
@@ -372,6 +373,8 @@ WriteLog("80STORE (read)\n");
 #ifdef SOFT_SWITCH_DEBUGGING
 WriteLog("VBL (read)\n");
 #endif
+// NB: The doco suggests that this signal goes LOW when in the VBI.
+// Which means that we need to control this by counting lines somewhere.
                return (vbl ? 0x80 : 0x00);
        }
        else if (addr == 0xC01A)
@@ -782,6 +785,8 @@ if (showpath)
        }
        else
        {
+// 80STORE only works for WRITING, not READING!
+#if 0
                // Check for 80STORE mode (STORE80 takes precedence over RAMRD/WRT)...
                if ((((addr >= 0x0400) && (addr <= 0x07FF)) || ((addr >= 0x2000) && (addr <= 0x3FFF))) && store80Mode)
                {
@@ -792,6 +797,7 @@ if (showpath)
 
                        return b;
                }
+#endif
 
                // Finally, check for auxillary/altzp write switches
                if (addr < 0x0200)
@@ -1304,6 +1310,12 @@ if (addr >= 0xD000 && addr <= 0xD00F)
        if (addr < 0x0200)
 //     if (addr < 0x0200 || addr >= 0xD000)
        {
+#if 0
+if (addr == 0x38)
+       WriteLog("Write $38: $%02X\n", b);
+else if (addr == 0x39)
+       WriteLog("Write $39: $%02X\n", b);
+#endif
                if (altzp)
                        ram2[addr] = b;
                else
@@ -1363,7 +1375,6 @@ int main(int /*argc*/, char * /*argv*/[])
        srand(time(NULL));                                                                      // Initialize RNG
 
        // Zero out memory
-//Need to bankify this stuff for the IIe emulation...
        memset(ram, 0, 0x10000);
        memset(rom, 0, 0x10000);
        memset(ram2, 0, 0x10000);
@@ -1671,6 +1682,22 @@ static void FrameCallback(void)
                        if (event.key.keysym.sym == SDLK_q && (event.key.keysym.mod & KMOD_ALT))
                                running = false;
 
+                       if (event.key.keysym.sym == SDLK_PAUSE)
+                       {
+                               pauseMode = !pauseMode;
+
+                               if (pauseMode)
+                               {
+                                       SoundPause();
+                                       SpawnMessage("*** PAUSED ***");
+                               }
+                               else
+                               {
+                                       SoundResume();
+                                       SpawnMessage("*** RESUME ***");
+                               }
+                       }
+
                        // Paddle buttons 0 & 1
                        if (event.key.keysym.sym == SDLK_INSERT)
                                openAppleDown = true;
@@ -1801,7 +1828,8 @@ if (counter == 60)
 //let's wait, then signal...
 //works longer, but then still falls behind...
 #ifdef THREADED_65C02
-       SDL_CondSignal(cpuCond);//OK, let the CPU go another frame...
+       if (!pauseMode)
+               SDL_CondSignal(cpuCond);//OK, let the CPU go another frame...
 #endif
 }
 
index 9dc8d89fefa55ffff2e644913a2593bac73ac368..807253b1d267644d8a98dd0921f69a56dc95d918 100755 (executable)
@@ -416,7 +416,8 @@ static void DrawString2(uint32_t x, uint32_t y, uint32_t color)
                                        uint32_t bBlue  = (eBlue  * invTrans + nBlue  * trans) / 255;
 
 //THIS IS NOT ENDIAN SAFE
-                                       *(scrBuffer + address + xx + (yy * VIRTUAL_SCREEN_WIDTH)) = 0xFF000000 | (bBlue << 16) | (bGreen << 8) | bRed;
+//NB: Setting the alpha channel here does nothing.
+                                       *(scrBuffer + address + xx + (yy * VIRTUAL_SCREEN_WIDTH)) = 0x7F000000 | (bBlue << 16) | (bGreen << 8) | bRed;
                                }
                        }
                }
index 4a7eac6e209df0bf584eba258180010319cdce40..d275f385679d890aa8be3aa2eac764adf0d6101a 100755 (executable)
@@ -6,13 +6,11 @@
 //
 
 #include "dis65c02.h"
-
 #include <stdio.h>
-#include <string>
+#include <string.h>
 #include "v65c02.h"
 #include "log.h"
 
-using namespace std;
 
 // External shit
 
@@ -36,86 +34,83 @@ static uint8_t op_mat[256] = {
        1,  6,  0,  0,  2,  2,  2,  2,  14, 1,  14, 0,  8,  8,  8,  13,
        13, 7,  5,  0,  0,  3,  3,  2,  14, 10, 14, 0,  0,  9,  9,  13,
        1,  6,  0,  0,  2,  2,  2,  2,  14, 1,  14, 0,  8,  8,  8,  13,
-       13, 7,  5,  0,  0,  3,  3,  2,  14, 10, 14, 0,  0,  9,  9,  13  };
-
-static uint8_t mnemonics[256][6] = {
-       "BRK  ","ORA  ","???  ","???  ","TSB  ","ORA  ","ASL  ","RMB0 ",
-       "PHP  ","ORA  ","ASL  ","???  ","TSB  ","ORA  ","ASL  ","BBR0 ",
-       "BPL  ","ORA  ","ORA  ","???  ","TRB  ","ORA  ","ASL  ","RMB1 ",
-       "CLC  ","ORA  ","INC  ","???  ","TRB  ","ORA  ","ASL  ","BBR1 ",
-       "JSR  ","AND  ","???  ","???  ","BIT  ","AND  ","ROL  ","RMB2 ",
-       "PLP  ","AND  ","ROL  ","???  ","BIT  ","AND  ","ROL  ","BBR2 ",
-       "BMI  ","AND  ","AND  ","???  ","BIT  ","AND  ","ROL  ","RMB3 ",
-       "SEC  ","AND  ","DEC  ","???  ","BIT  ","AND  ","ROL  ","BBR3 ",
-       "RTI  ","EOR  ","???  ","???  ","???  ","EOR  ","LSR  ","RMB4 ",
-       "PHA  ","EOR  ","LSR  ","???  ","JMP  ","EOR  ","LSR  ","BBR4 ",
-       "BVC  ","EOR  ","EOR  ","???  ","???  ","EOR  ","LSR  ","RMB5 ",
-       "CLI  ","EOR  ","PHY  ","???  ","???  ","EOR  ","LSR  ","BBR5 ",
-       "RTS  ","ADC  ","???  ","???  ","STZ  ","ADC  ","ROR  ","RMB6 ",
-       "PLA  ","ADC  ","ROR  ","???  ","JMP  ","ADC  ","ROR  ","BBR6 ",
-       "BVS  ","ADC  ","ADC  ","???  ","STZ  ","ADC  ","ROR  ","RMB7 ",
-       "SEI  ","ADC  ","PLY  ","???  ","JMP  ","ADC  ","ROR  ","BBR7 ",
-       "BRA  ","STA  ","???  ","???  ","STY  ","STA  ","STX  ","SMB0 ",
-       "DEY  ","BIT  ","TXA  ","???  ","STY  ","STA  ","STX  ","BBS0 ",
-       "BCC  ","STA  ","STA  ","???  ","STY  ","STA  ","STX  ","SMB1 ",
-       "TYA  ","STA  ","TXS  ","???  ","STZ  ","STA  ","STZ  ","BBS1 ",
-       "LDY  ","LDA  ","LDX  ","???  ","LDY  ","LDA  ","LDX  ","SMB2 ",
-       "TAY  ","LDA  ","TAX  ","???  ","LDY  ","LDA  ","LDX  ","BBS2 ",
-       "BCS  ","LDA  ","LDA  ","???  ","LDY  ","LDA  ","LDX  ","SMB3 ",
-       "CLV  ","LDA  ","TSX  ","???  ","LDY  ","LDA  ","LDX  ","BBS3 ",
-       "CPY  ","CMP  ","???  ","???  ","CPY  ","CMP  ","DEC  ","SMB4 ",
-       "INY  ","CMP  ","DEX  ","???  ","CPY  ","CMP  ","DEC  ","BBS4 ",
-       "BNE  ","CMP  ","CMP  ","???  ","???  ","CMP  ","DEC  ","SMB5 ",
-       "CLD  ","CMP  ","PHX  ","???  ","???  ","CMP  ","DEC  ","BBS5 ",
-       "CPX  ","SBC  ","???  ","???  ","CPX  ","SBC  ","INC  ","SMB6 ",
-       "INX  ","SBC  ","NOP  ","???  ","CPX  ","SBC  ","INC  ","BBS6 ",
-       "BEQ  ","SBC  ","SBC  ","???  ","???  ","SBC  ","INC  ","SMB7 ",
-       "SED  ","SBC  ","PLX  ","???  ","???  ","SBC  ","INC  ","BBS7 " };
+       13, 7,  5,  0,  0,  3,  3,  2,  14, 10, 14, 0,  0,  9,  9,  13
+};
+
+static uint8_t mnemonics[256][5] = {
+       "BRK ","ORA ","??? ","??? ","TSB ","ORA ","ASL ","RMB0",
+       "PHP ","ORA ","ASL ","??? ","TSB ","ORA ","ASL ","BBR0",
+       "BPL ","ORA ","ORA ","??? ","TRB ","ORA ","ASL ","RMB1",
+       "CLC ","ORA ","INC ","??? ","TRB ","ORA ","ASL ","BBR1",
+       "JSR ","AND ","??? ","??? ","BIT ","AND ","ROL ","RMB2",
+       "PLP ","AND ","ROL ","??? ","BIT ","AND ","ROL ","BBR2",
+       "BMI ","AND ","AND ","??? ","BIT ","AND ","ROL ","RMB3",
+       "SEC ","AND ","DEC ","??? ","BIT ","AND ","ROL ","BBR3",
+       "RTI ","EOR ","??? ","??? ","??? ","EOR ","LSR ","RMB4",
+       "PHA ","EOR ","LSR ","??? ","JMP ","EOR ","LSR ","BBR4",
+       "BVC ","EOR ","EOR ","??? ","??? ","EOR ","LSR ","RMB5",
+       "CLI ","EOR ","PHY ","??? ","??? ","EOR ","LSR ","BBR5",
+       "RTS ","ADC ","??? ","??? ","STZ ","ADC ","ROR ","RMB6",
+       "PLA ","ADC ","ROR ","??? ","JMP ","ADC ","ROR ","BBR6",
+       "BVS ","ADC ","ADC ","??? ","STZ ","ADC ","ROR ","RMB7",
+       "SEI ","ADC ","PLY ","??? ","JMP ","ADC ","ROR ","BBR7",
+       "BRA ","STA ","??? ","??? ","STY ","STA ","STX ","SMB0",
+       "DEY ","BIT ","TXA ","??? ","STY ","STA ","STX ","BBS0",
+       "BCC ","STA ","STA ","??? ","STY ","STA ","STX ","SMB1",
+       "TYA ","STA ","TXS ","??? ","STZ ","STA ","STZ ","BBS1",
+       "LDY ","LDA ","LDX ","??? ","LDY ","LDA ","LDX ","SMB2",
+       "TAY ","LDA ","TAX ","??? ","LDY ","LDA ","LDX ","BBS2",
+       "BCS ","LDA ","LDA ","??? ","LDY ","LDA ","LDX ","SMB3",
+       "CLV ","LDA ","TSX ","??? ","LDY ","LDA ","LDX ","BBS3",
+       "CPY ","CMP ","??? ","??? ","CPY ","CMP ","DEC ","SMB4",
+       "INY ","CMP ","DEX ","??? ","CPY ","CMP ","DEC ","BBS4",
+       "BNE ","CMP ","CMP ","??? ","??? ","CMP ","DEC ","SMB5",
+       "CLD ","CMP ","PHX ","??? ","??? ","CMP ","DEC ","BBS5",
+       "CPX ","SBC ","??? ","??? ","CPX ","SBC ","INC ","SMB6",
+       "INX ","SBC ","NOP ","??? ","CPX ","SBC ","INC ","BBS6",
+       "BEQ ","SBC ","SBC ","??? ","??? ","SBC ","INC ","SMB7",
+       "SED ","SBC ","PLX ","??? ","??? ","SBC ","INC ","BBS7"
+};
+
 
 //
 // Display bytes in mem in hex
 //
-static void DisplayBytes(uint16_t src, uint32_t dst)
+static void DisplayBytes(char * outbuf, uint16_t src, uint32_t dst)
 {
-       WriteLog("%04X: ", src);
-       uint8_t cnt = 0;                                                                                // Init counter...
+       char buf[32];
+//     WriteLog("%04X: ", src);
+       sprintf(outbuf, "%04X: ", src);
+       uint8_t cnt = 0;
 
+       // That should fix the $FFFF bug...
        if (src > dst)
-               dst += 0x10000;                                                                 // That should fix the FFFF bug...
+               dst += 0x10000;
 
        for(uint32_t i=src; i<dst; i++)
        {
-               WriteLog("%02X ", mainCPU.RdMem(i));
-               cnt++;                                                                                  // Bump counter...
+//             WriteLog("%02X ", mainCPU.RdMem(i));
+               sprintf(buf, "%02X ", mainCPU.RdMem(i));
+               strcat(outbuf, buf);
+               cnt++;
        }
 
-       for(int i=cnt; i<5; i++)                                                        // Pad the leftover spaces...
-               WriteLog("   ");
+       // Pad the leftover spaces...
+       for(int i=cnt; i<3; i++)
+//             WriteLog("   ");
+       {
+               sprintf(buf, "   ");
+               strcat(outbuf, buf);
+       }
 }
 
+
 //
 // Decode a 65C02 instruction
 //
-int Decode65C02(uint16_t pc)
+int Decode65C02(char * outbuf, uint16_t pc)
 {
-/*
- 0) illegal
- 1) imm = #$00
- 2) zp = $00
- 3) zpx = $00,X
- 4) zpy = $00,Y
- 5) izp = ($00)
- 6) izx = ($00,X)
- 7) izy = ($00),Y
- 8) abs = $0000
- 9) abx = $0000,X
-10) aby = $0000,Y
-11) ind = ($0000)
-12) iax = ($0000,X)
-13) rel = $0000 (PC-relative)
-14) inherent
-*/
-       char outbuf[80];
+       char buf[32], buf2[32];
 
        uint16_t addr = pc;
        uint8_t opcode = mainCPU.RdMem(addr++);                         // Get the opcode
@@ -123,56 +118,57 @@ int Decode65C02(uint16_t pc)
        switch (op_mat[opcode])                                                         // Decode the addressing mode...
        {
        case 0:                                                                                         // Illegal
-               sprintf(outbuf, "???");
+               sprintf(buf, "???");
                break;
        case 1:                                                                                         // Immediate
-               sprintf(outbuf, "%s #$%02X", mnemonics[opcode], mainCPU.RdMem(addr++));
+               sprintf(buf, "%s #$%02X", mnemonics[opcode], mainCPU.RdMem(addr++));
                break;
        case 2:                                                                                         // Zero page
-               sprintf(outbuf, "%s $%02X", mnemonics[opcode], mainCPU.RdMem(addr++));
+               sprintf(buf, "%s $%02X", mnemonics[opcode], mainCPU.RdMem(addr++));
                break;
        case 3:                                                                                         // Zero page, X
-               sprintf(outbuf, "%s $%02X,X", mnemonics[opcode], mainCPU.RdMem(addr++));
+               sprintf(buf, "%s $%02X,X", mnemonics[opcode], mainCPU.RdMem(addr++));
                break;
        case 4:                                                                                         // Zero page, Y
-               sprintf(outbuf, "%s $%02X,Y", mnemonics[opcode], mainCPU.RdMem(addr++));
+               sprintf(buf, "%s $%02X,Y", mnemonics[opcode], mainCPU.RdMem(addr++));
                break;
        case 5:                                                                                         // Zero page indirect
-               sprintf(outbuf, "%s ($%02X)", mnemonics[opcode], mainCPU.RdMem(addr++));
+               sprintf(buf, "%s ($%02X)", mnemonics[opcode], mainCPU.RdMem(addr++));
                break;
        case 6:                                                                                         // Zero page, X indirect
-               sprintf(outbuf, "%s ($%02X,X)", mnemonics[opcode], mainCPU.RdMem(addr++));
+               sprintf(buf, "%s ($%02X,X)", mnemonics[opcode], mainCPU.RdMem(addr++));
                break;
        case 7:                                                                                         // Zero page, Y indirect
-               sprintf(outbuf, "%s ($%02X),Y", mnemonics[opcode], mainCPU.RdMem(addr++));
+               sprintf(buf, "%s ($%02X),Y", mnemonics[opcode], mainCPU.RdMem(addr++));
                break;
        case 8:                                                                                         // Absolute
-               sprintf(outbuf, "%s $%04X", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));
+               sprintf(buf, "%s $%04X", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));
                break;
        case 9:                                                                                         // Absolute, X
-               sprintf(outbuf, "%s $%04X,X", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));
+               sprintf(buf, "%s $%04X,X", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));
                break;
        case 10:                                                                                        // Absolute, Y
-               sprintf(outbuf, "%s $%04X,Y", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));
+               sprintf(buf, "%s $%04X,Y", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));
                break;
        case 11:                                                                                        // Indirect
-               sprintf(outbuf, "%s ($%04X)", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));
+               sprintf(buf, "%s ($%04X)", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));
                break;
        case 12:                                                                                        // Indirect, X
-               sprintf(outbuf, "%s ($%04X,X)", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));
+               sprintf(buf, "%s ($%04X,X)", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));
                break;
        case 13:                                                                                        // Relative
-//             sprintf(outbuf, "%s $%04X", mnemonics[opcode], ++addr + (int16_t)(int8_t)mainCPU.RdMem(addr));
-               sprintf(outbuf, "%s $%04X", mnemonics[opcode], addr + (int16_t)((int8_t)mainCPU.RdMem(addr)) + 1);
+               sprintf(buf, "%s $%04X", mnemonics[opcode], addr + (int16_t)((int8_t)mainCPU.RdMem(addr)) + 1);
                addr++;
                break;
        case 14:                                                                                        // Inherent
-               sprintf(outbuf, "%s ", mnemonics[opcode]);
+               sprintf(buf, "%s ", mnemonics[opcode]);
                break;
        }
 
-       DisplayBytes(pc, addr);                                                         // Show bytes
-       WriteLog("%-16s", outbuf);                                                      // Display opcode & addressing, etc.
+       DisplayBytes(buf2, pc, addr);                                           // Show bytes
+//     WriteLog("%-16s", outbuf);                                                      // Display opcode & addressing, etc.
+       sprintf(outbuf, "%s %-14s", buf2, buf);                         // Display opcode & addressing, etc.
 
        return addr - pc;
 }
+
index 08e1ad1ac6e140e9095710b833518c3b88642291..ab6ba2d691f1be82572a26d5b3e8c28264a5cd73 100755 (executable)
@@ -10,6 +10,7 @@
 
 #include <stdint.h>
 
-int Decode65C02(uint16_t pc);
+int Decode65C02(char * outbuf, uint16_t pc);
 
 #endif // __DIS65C02_H__
+
index 22a027d2cc46c8834fb2184f4316155d619c0c05..4cab23ec0aad0ec7a353e97869cf6ed53d1e5179 100755 (executable)
@@ -147,6 +147,20 @@ void SoundDone(void)
 }
 
 
+void SoundPause(void)
+{
+       if (soundInitialized)
+               SDL_PauseAudioDevice(device, 1);
+}
+
+
+void SoundResume(void)
+{
+       if (soundInitialized)
+               SDL_PauseAudioDevice(device, 0);
+}
+
+
 //
 // Sound card callback handler
 //
index af06af421117d7de64c621533e4cc3021a99a11c..49dca4bf7ee5f40483ad994dcde16a7bb6a15947 100755 (executable)
@@ -17,6 +17,8 @@
 
 void SoundInit(void);
 void SoundDone(void);
+void SoundPause(void);
+void SoundResume(void);
 void ToggleSpeaker(uint64_t elapsedCycles);
 void WriteSampleToBuffer(void);
 //void AddToSoundTimeBase(uint64_t cycles);
index 6f383a3a5fdc1bc81571e711ca605bb89913257a..0ddf25143011ef8bc8158b1ac13180bb105c9c1f 100755 (executable)
@@ -1142,7 +1142,6 @@ static void Op90(void)                                                    // BCC
 
        if (!(regs.cc & FLAG_C))
                HANDLE_BRANCH_TAKEN(m)
-//             regs.pc += m;
 }
 
 static void OpB0(void)                                                 // BCS
@@ -1151,7 +1150,6 @@ static void OpB0(void)                                                    // BCS
 
        if (regs.cc & FLAG_C)
                HANDLE_BRANCH_TAKEN(m)
-//             regs.pc += m;
 }
 
 static void OpF0(void)                                                 // BEQ
@@ -1160,7 +1158,6 @@ static void OpF0(void)                                                    // BEQ
 
        if (regs.cc & FLAG_Z)
                HANDLE_BRANCH_TAKEN(m)
-//             regs.pc += m;
 }
 
 /*
@@ -2606,7 +2603,9 @@ static void Op86(void)
 
 static void Op96(void)
 {
-       regs.WrMem(EA_ZP_X, regs.x);
+// BUG!!! [FIXED]
+//WAS: regs.WrMem(EA_ZP_X, regs.x);
+       regs.WrMem(EA_ZP_Y, regs.x);
 }
 
 static void Op8E(void)
@@ -2855,10 +2854,16 @@ On //e, $FCAA is the delay routine. (seems to not have changed from ][+)
 //Note: could enforce regs.clock to zero on starting the CPU with an Init() function...
 //bleh.
 //static uint32_t limit = 0;
-
-// This should be in the regs struct, in case we have multiple CPUs...
-#warning "!!! Move overflow into regs struct !!!"
-static uint64_t overflow = 0;
+// Or, we could just say that initializing the CPU struct is the responsibility
+// of the caller. :-)
+
+#define DO_BACKTRACE
+#ifdef DO_BACKTRACE
+#define BACKTRACE_SIZE 16384
+uint32_t btQueuePtr = 0;
+V65C02REGS btQueue[BACKTRACE_SIZE];
+uint8_t btQueueInst[BACKTRACE_SIZE][4];
+#endif
 //
 // Function to execute 65C02 for "cycles" cycles
 //
@@ -2867,24 +2872,7 @@ void Execute65C02(V65C02REGS * context, uint32_t cycles)
        myMemcpy(&regs, context, sizeof(V65C02REGS));
 
        // Execute here...
-// NOTE: There *must* be some way of doing this without requiring the caller to subtract out
-//       the previous run's cycles. !!! FIX !!!
-// Could try:
-//     while (regs.clock < regs.clock + cycles) <-- won't work
-/*
-       // This isn't as accurate as subtracting out cycles from regs.clock...
-       // Unless limit is a static variable, adding cycles to it each time through...
-       uint32_t limit = regs.clock + cycles;
-       while (regs.clock < limit)
-*/
-// but have wraparound to deal with. :-/
-/*
-Let's see...
-
-       if (regs.clock + cycles > 0xFFFFFFFF)
-               wraparound = true;
-*/
-       uint64_t endCycles = regs.clock + (uint64_t)cycles - overflow;
+       uint64_t endCycles = regs.clock + (uint64_t)cycles - regs.overflow;
 
        while (regs.clock < endCycles)
        {
@@ -2904,6 +2892,10 @@ if (regs.pc == 0x444E)
        dumpDis = false;
 }//*/
 #endif
+/*if (regs.pc == 0xBF4C)
+{
+       dumpDis = true;
+}//*/
 
 #if 0
 /*if (regs.pc == 0x0801)
@@ -2991,8 +2983,12 @@ if (regs.pc == 0x2000)
 #endif
 
 #ifdef __DEBUG__
+static char disbuf[80];
 if (dumpDis)
-       Decode65C02(regs.pc);
+{
+       Decode65C02(disbuf, regs.pc);
+       WriteLog("%s", disbuf);
+}
 #endif
                uint8_t opcode = regs.RdMem(regs.pc++);
 
@@ -3089,7 +3085,7 @@ WriteLog("\n*** IRQ ***\n\n");
        // subtract it out from a subsequent run. It's guaranteed to be positive,
        // because the condition that exits the main loop above is written such
        // that regs.clock has to be larger than endCycles to exit from it.
-       overflow = regs.clock - endCycles;
+       regs.overflow = regs.clock - endCycles;
 
        myMemcpy(context, &regs, sizeof(V65C02REGS));
 }
index 145e659a39319ecb403992ebe2819eb1b1ea3195..2a189c82c3a11e4176e738df1a064b5e5922ed64 100755 (executable)
@@ -42,6 +42,7 @@ struct V65C02REGS
        uint8_t (* RdMem)(uint16_t);            // Address of BYTE read routine
        void (* WrMem)(uint16_t, uint8_t);      // Address of BYTE write routine
        uint16_t cpuFlags;                              // v65C02 IRQ/RESET flags
+       uint64_t overflow;                              // # of cycles we went over last time through
 };
 
 // Global variables (exported)