From: Shamus Hammons Date: Mon, 23 Sep 2013 16:05:10 +0000 (-0500) Subject: Fixed misc. bugs preventing certain games from working, added pause mode. X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c0001155bc0909da61f6c849c0be9b16e9b7f4b6;p=apple2 Fixed misc. bugs preventing certain games from working, added pause mode. 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. --- diff --git a/apple2.cfg b/apple2.cfg index 3aa30c3..07c414c 100755 --- a/apple2.cfg +++ b/apple2.cfg @@ -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 diff --git a/src/apple2.cpp b/src/apple2.cpp index 12eb8c9..1eeb7e8 100755 --- a/src/apple2.cpp +++ b/src/apple2.cpp @@ -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 } diff --git a/src/applevideo.cpp b/src/applevideo.cpp index 9dc8d89..807253b 100755 --- a/src/applevideo.cpp +++ b/src/applevideo.cpp @@ -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; } } } diff --git a/src/dis65c02.cpp b/src/dis65c02.cpp index 4a7eac6..d275f38 100755 --- a/src/dis65c02.cpp +++ b/src/dis65c02.cpp @@ -6,13 +6,11 @@ // #include "dis65c02.h" - #include -#include +#include #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 -int Decode65C02(uint16_t pc); +int Decode65C02(char * outbuf, uint16_t pc); #endif // __DIS65C02_H__ + diff --git a/src/sound.cpp b/src/sound.cpp index 22a027d..4cab23e 100755 --- a/src/sound.cpp +++ b/src/sound.cpp @@ -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 // diff --git a/src/sound.h b/src/sound.h index af06af4..49dca4b 100755 --- a/src/sound.h +++ b/src/sound.h @@ -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); diff --git a/src/v65c02.cpp b/src/v65c02.cpp index 6f383a3..0ddf251 100755 --- a/src/v65c02.cpp +++ b/src/v65c02.cpp @@ -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(®s, 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, ®s, sizeof(V65C02REGS)); } diff --git a/src/v65c02.h b/src/v65c02.h index 145e659..2a189c8 100755 --- a/src/v65c02.h +++ b/src/v65c02.h @@ -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)