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 }; + 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" +}; -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 " }; // // 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; +// Or, we could just say that initializing the CPU struct is the responsibility +// of the caller. :-) -// This should be in the regs struct, in case we have multiple CPUs... -#warning "!!! Move overflow into regs struct !!!" -static uint64_t overflow = 0; +#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)