From d0de183d57fcc78fe9fa111af63572cd16161129 Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Thu, 9 Jul 2009 01:37:07 +0000 Subject: [PATCH] Added miscellaneous warnings, minor documentation --- src/apple2.cpp | 11 +- src/sound.cpp | 22 +- src/v65c02.cpp | 636 ++++++++++++++++++++++++++++++++++++++++++++++++- src/video.cpp | 8 + 4 files changed, 658 insertions(+), 19 deletions(-) diff --git a/src/apple2.cpp b/src/apple2.cpp index fa25cb4..e76ea89 100755 --- a/src/apple2.cpp +++ b/src/apple2.cpp @@ -59,7 +59,7 @@ #define THREADED_65C02 #define CPU_THREAD_OVERFLOW_COMPENSATION //#define DEBUG_LC -#define CPU_CLOCK_CHECKING +//#define CPU_CLOCK_CHECKING #define THREAD_DEBUGGING // Global variables @@ -1000,6 +1000,7 @@ memcpy(ram + 0xD000, ram + 0xC000, 0x1000); //(Fix so that this is not a requirement!) //Fixed, but mainCPU.clock is destroyed in the bargain. Oh well. // mainCPU.clock -= USEC_TO_M6502_CYCLES(timeToNextEvent); + #ifdef CPU_CLOCK_CHECKING #ifndef THREADED_65C02 totalCPU += USEC_TO_M6502_CYCLES(timeToNextEvent); @@ -1218,9 +1219,6 @@ if (counter == 60) counter = 0; } #endif -#ifdef THREADED_65C02 - SDL_CondSignal(cpuCond);//OK, let the CPU go another frame... -#endif //Instead of this, we should yield remaining time to other processes... !!! FIX !!! //lessee... //nope. @@ -1228,6 +1226,11 @@ if (counter == 60) //SDL_Delay(10); while (SDL_GetTicks() - startTicks < 16); // Wait for next frame... startTicks = SDL_GetTicks(); +//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... +#endif } static void BlinkTimer(void) diff --git a/src/sound.cpp b/src/sound.cpp index 202eaae..f9f259b 100755 --- a/src/sound.cpp +++ b/src/sound.cpp @@ -31,19 +31,27 @@ //#define DEBUG //#define WRITE_OUT_WAVE -#define SAMPLE_RATE (44100.0) -//#define SAMPLE_RATE (48000.0) +// This is odd--seems to be working properly now! Maybe a bug in the SDL sound code? +// Actually, it still doesn't sound right... Sounds too slow now. :-/ +// But then again, it's difficult to tell. Sometimes it slows waaaaaay down, but generally +// seems to be OK other than that +// Also, it could be that the discrepancy in pitch is due to the V65C02 and it's lack of +// cycle accuracy... + +//#define SAMPLE_RATE (44100.0) +#define SAMPLE_RATE (48000.0) #define SAMPLES_PER_FRAME (SAMPLE_RATE / 60.0) // This works for AppleWin but not here... ??? WHY ??? // ~ 21 -// #define CYCLES_PER_SAMPLE (1024000.0 / SAMPLE_RATE) +#define CYCLES_PER_SAMPLE (1024000.0 / SAMPLE_RATE) // ~ 17 (lower pitched than above...!) // Makes sense, as this is the divisor for # of cycles passed //#define CYCLES_PER_SAMPLE (800000.0 / SAMPLE_RATE) // This seems about right, compared to AppleWin--but AW runs @ 1.024 MHz // 23 (1.024) vs. 20 (0.900) -#define CYCLES_PER_SAMPLE (900000.0 / SAMPLE_RATE) +//#define CYCLES_PER_SAMPLE (900000.0 / SAMPLE_RATE) //nope, too high #define CYCLES_PER_SAMPLE (960000.0 / SAMPLE_RATE) +//#define CYCLES_PER_SAMPLE 21 //#define SOUND_BUFFER_SIZE (8192) #define SOUND_BUFFER_SIZE (32768) @@ -52,7 +60,7 @@ // Local variables -static SDL_AudioSpec desired; +static SDL_AudioSpec desired, obtained; static bool soundInitialized = false; static bool speakerState = false; static int16 soundBuffer[SOUND_BUFFER_SIZE]; @@ -92,7 +100,9 @@ return; desired.samples = 1024; // Let's try a 1K buffer (can always go lower) desired.callback = SDLSoundCallback; - if (SDL_OpenAudio(&desired, NULL) < 0) // NULL means SDL guarantees what we want +// if (SDL_OpenAudio(&desired, NULL) < 0) // NULL means SDL guarantees what we want +//When doing it this way, we need to check to see if we got what we asked for... + if (SDL_OpenAudio(&desired, &obtained) < 0) { WriteLog("Sound: Failed to initialize SDL sound.\n"); return; diff --git a/src/v65c02.cpp b/src/v65c02.cpp index 6f2c969..b103187 100755 --- a/src/v65c02.cpp +++ b/src/v65c02.cpp @@ -95,6 +95,7 @@ static V65C02REGS regs; //(ABS, ABS X/Y, ZP) crosses a page boundary, or extra cycle for BCD add/subtract... #warning "Cycle counts are not accurate--!!! FIX !!!" static uint8 CPUCycles[256] = { +#if 0 7, 6, 1, 1, 5, 3, 5, 1, 3, 2, 2, 1, 6, 4, 6, 1, 2, 5, 5, 1, 5, 4, 6, 1, 2, 4, 2, 1, 6, 4, 6, 1, 6, 6, 1, 1, 3, 3, 5, 1, 4, 2, 2, 1, 4, 4, 6, 1, @@ -111,6 +112,603 @@ static uint8 CPUCycles[256] = { 2, 5, 5, 1, 1, 4, 6, 1, 2, 4, 3, 1, 1, 4, 6, 1, 2, 6, 1, 1, 3, 3, 5, 1, 2, 2, 2, 1, 4, 4, 6, 1, 2, 5, 5, 1, 1, 4, 6, 1, 2, 4, 4, 1, 1, 4, 6, 1 }; +#else + 7, 6, 2, 2, 5, 3, 5, 2, 3, 2, 2, 2, 6, 4, 6, 2, + 2, 5, 5, 2, 5, 4, 6, 2, 2, 4, 2, 2, 6, 4, 6, 2, + 6, 6, 2, 2, 3, 3, 5, 2, 4, 2, 2, 2, 4, 2, 6, 2, + 2, 5, 5, 2, 4, 4, 6, 2, 2, 4, 2, 2, 4, 4, 6, 2, + 6, 6, 2, 2, 3, 3, 5, 2, 3, 2, 2, 2, 3, 4, 6, 2, + 2, 5, 5, 2, 4, 4, 6, 2, 2, 4, 3, 2, 8, 4, 6, 2, + 6, 6, 2, 2, 3, 3, 5, 2, 4, 2, 2, 2, 6, 4, 6, 2, + 2, 5, 5, 2, 4, 4, 6, 2, 2, 4, 4, 2, 6, 4, 6, 2, + 2, 6, 2, 2, 3, 3, 3, 2, 2, 2, 2, 2, 4, 4, 4, 2, + 2, 6, 5, 2, 4, 4, 4, 2, 2, 5, 2, 2, 4, 5, 5, 2, + 2, 6, 2, 2, 3, 3, 3, 2, 2, 2, 2, 2, 4, 4, 4, 2, + 2, 5, 5, 2, 4, 4, 4, 2, 2, 4, 2, 2, 4, 4, 4, 2, + 2, 6, 2, 2, 3, 3, 5, 2, 2, 2, 2, 2, 4, 4, 5, 2, + 2, 5, 5, 2, 4, 4, 6, 2, 2, 4, 3, 2, 4, 4, 6, 2, + 2, 6, 2, 2, 3, 3, 5, 2, 2, 2, 2, 2, 4, 4, 6, 2, + 2, 5, 5, 2, 4, 4, 6, 2, 2, 4, 4, 2, 4, 4, 6, 2 }; +#endif + +static uint8 _6502Cycles[256] = { + 7, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 4, 4, 6, 6, + 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 6, 7, + 6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 4, 2, 6, 6, + 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 6, 7, + 6, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 3, 4, 6, 6, + 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 6, 7, + 6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 6, 4, 6, 6, + 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 6, 7, + 2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, + 2, 6, 2, 6, 4, 4, 4, 4, 2, 5, 2, 5, 5, 5, 5, 5, + 2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, + 2, 5, 2, 5, 4, 4, 4, 4, 2, 4, 2, 4, 4, 4, 4, 4, + 2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 5, 6, + 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 6, 7, + 2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6, + 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 6, 7 }; + +static uint8 _65C02Cycles[256] = { + 7, 6, 2, 2, 5, 3, 5, 2, 3, 2, 2, 2, 6, 4, 6, 2, + 2, 5, 5, 2, 5, 4, 6, 2, 2, 4, 2, 2, 6, 4, 6, 2, + 6, 6, 2, 2, 3, 3, 5, 2, 4, 2, 2, 2, 4, 2, 6, 2, + 2, 5, 5, 2, 4, 4, 6, 2, 2, 4, 2, 2, 4, 4, 6, 2, + 6, 6, 2, 2, 3, 3, 5, 2, 3, 2, 2, 2, 3, 4, 6, 2, + 2, 5, 5, 2, 4, 4, 6, 2, 2, 4, 3, 2, 8, 4, 6, 2, + 6, 6, 2, 2, 3, 3, 5, 2, 4, 2, 2, 2, 6, 4, 6, 2, + 2, 5, 5, 2, 4, 4, 6, 2, 2, 4, 4, 2, 6, 4, 6, 2, + 2, 6, 2, 2, 3, 3, 3, 2, 2, 2, 2, 2, 4, 4, 4, 2, + 2, 6, 5, 2, 4, 4, 4, 2, 2, 5, 2, 2, 4, 5, 5, 2, + 2, 6, 2, 2, 3, 3, 3, 2, 2, 2, 2, 2, 4, 4, 4, 2, + 2, 5, 5, 2, 4, 4, 4, 2, 2, 4, 2, 2, 4, 4, 4, 2, + 2, 6, 2, 2, 3, 3, 5, 2, 2, 2, 2, 2, 4, 4, 5, 2, + 2, 5, 5, 2, 4, 4, 6, 2, 2, 4, 3, 2, 4, 4, 6, 2, + 2, 6, 2, 2, 3, 3, 5, 2, 2, 2, 2, 2, 4, 4, 6, 2, + 2, 5, 5, 2, 4, 4, 6, 2, 2, 4, 4, 2, 4, 4, 6, 2 }; + +#if 0 +// ExtraCycles: +// +1 if branch taken +// +1 if page boundary crossed +#define BRANCH_TAKEN { \ + base = regs.pc; \ + regs.pc += addr; \ + if ((base ^ regs.pc) & 0xFF00) \ + uExtraCycles=2; \ + else \ + uExtraCycles=1; \ + } + +{ + oldpc = regs.pc; + regs.pc += v; + if ((oldc ^ regs.pc) & 0xFF00) + regs.clock++; + regs.clock++; +} +#endif + +/* +6502 cycles (includes illegal opcodes): + + case 0x00: BRK CYC(7) break; + case 0x01: INDX ORA CYC(6) break; + case 0x02: INV HLT CYC(2) break; + case 0x03: INV INDX ASO CYC(8) break; + case 0x04: INV ZPG NOP CYC(3) break; + case 0x05: ZPG ORA CYC(3) break; + case 0x06: ZPG ASL_NMOS CYC(5) break; + case 0x07: INV ZPG ASO CYC(5) break; + case 0x08: PHP CYC(3) break; + case 0x09: IMM ORA CYC(2) break; + case 0x0A: ASLA CYC(2) break; + case 0x0B: INV IMM ANC CYC(2) break; + case 0x0C: INV ABSX NOP CYC(4) break; + case 0x0D: ABS ORA CYC(4) break; + case 0x0E: ABS ASL_NMOS CYC(6) break; + case 0x0F: INV ABS ASO CYC(6) break; + case 0x10: REL BPL CYC(2) break; + case 0x11: INDY ORA CYC(5) break; + case 0x12: INV HLT CYC(2) break; + case 0x13: INV INDY ASO CYC(8) break; + case 0x14: INV ZPGX NOP CYC(4) break; + case 0x15: ZPGX ORA CYC(4) break; + case 0x16: ZPGX ASL_NMOS CYC(6) break; + case 0x17: INV ZPGX ASO CYC(6) break; + case 0x18: CLC CYC(2) break; + case 0x19: ABSY ORA CYC(4) break; + case 0x1A: INV NOP CYC(2) break; + case 0x1B: INV ABSY ASO CYC(7) break; + case 0x1C: INV ABSX NOP CYC(4) break; + case 0x1D: ABSX ORA CYC(4) break; + case 0x1E: ABSX ASL_NMOS CYC(6) break; + case 0x1F: INV ABSX ASO CYC(7) break; + case 0x20: ABS JSR CYC(6) break; + case 0x21: INDX AND CYC(6) break; + case 0x22: INV HLT CYC(2) break; + case 0x23: INV INDX RLA CYC(8) break; + case 0x24: ZPG BIT CYC(3) break; + case 0x25: ZPG AND CYC(3) break; + case 0x26: ZPG ROL_NMOS CYC(5) break; + case 0x27: INV ZPG RLA CYC(5) break; + case 0x28: PLP CYC(4) break; + case 0x29: IMM AND CYC(2) break; + case 0x2A: ROLA CYC(2) break; + case 0x2B: INV IMM ANC CYC(2) break; + case 0x2C: ABS BIT CYC(4) break; + case 0x2D: ABS AND CYC(2) break; + case 0x2E: ABS ROL_NMOS CYC(6) break; + case 0x2F: INV ABS RLA CYC(6) break; + case 0x30: REL BMI CYC(2) break; + case 0x31: INDY AND CYC(5) break; + case 0x32: INV HLT CYC(2) break; + case 0x33: INV INDY RLA CYC(8) break; + case 0x34: INV ZPGX NOP CYC(4) break; + case 0x35: ZPGX AND CYC(4) break; + case 0x36: ZPGX ROL_NMOS CYC(6) break; + case 0x37: INV ZPGX RLA CYC(6) break; + case 0x38: SEC CYC(2) break; + case 0x39: ABSY AND CYC(4) break; + case 0x3A: INV NOP CYC(2) break; + case 0x3B: INV ABSY RLA CYC(7) break; + case 0x3C: INV ABSX NOP CYC(4) break; + case 0x3D: ABSX AND CYC(4) break; + case 0x3E: ABSX ROL_NMOS CYC(6) break; + case 0x3F: INV ABSX RLA CYC(7) break; + case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break; + case 0x41: INDX EOR CYC(6) break; + case 0x42: INV HLT CYC(2) break; + case 0x43: INV INDX LSE CYC(8) break; + case 0x44: INV ZPG NOP CYC(3) break; + case 0x45: ZPG EOR CYC(3) break; + case 0x46: ZPG LSR_NMOS CYC(5) break; + case 0x47: INV ZPG LSE CYC(5) break; + case 0x48: PHA CYC(3) break; + case 0x49: IMM EOR CYC(2) break; + case 0x4A: LSRA CYC(2) break; + case 0x4B: INV IMM ALR CYC(2) break; + case 0x4C: ABS JMP CYC(3) break; + case 0x4D: ABS EOR CYC(4) break; + case 0x4E: ABS LSR_NMOS CYC(6) break; + case 0x4F: INV ABS LSE CYC(6) break; + case 0x50: REL BVC CYC(2) break; + case 0x51: INDY EOR CYC(5) break; + case 0x52: INV HLT CYC(2) break; + case 0x53: INV INDY LSE CYC(8) break; + case 0x54: INV ZPGX NOP CYC(4) break; + case 0x55: ZPGX EOR CYC(4) break; + case 0x56: ZPGX LSR_NMOS CYC(6) break; + case 0x57: INV ZPGX LSE CYC(6) break; + case 0x58: CLI CYC(2) break; + case 0x59: ABSY EOR CYC(4) break; + case 0x5A: INV NOP CYC(2) break; + case 0x5B: INV ABSY LSE CYC(7) break; + case 0x5C: INV ABSX NOP CYC(4) break; + case 0x5D: ABSX EOR CYC(4) break; + case 0x5E: ABSX LSR_NMOS CYC(6) break; + case 0x5F: INV ABSX LSE CYC(7) break; + case 0x60: RTS CYC(6) break; + case 0x61: INDX ADC_NMOS CYC(6) break; + case 0x62: INV HLT CYC(2) break; + case 0x63: INV INDX RRA CYC(8) break; + case 0x64: INV ZPG NOP CYC(3) break; + case 0x65: ZPG ADC_NMOS CYC(3) break; + case 0x66: ZPG ROR_NMOS CYC(5) break; + case 0x67: INV ZPG RRA CYC(5) break; + case 0x68: PLA CYC(4) break; + case 0x69: IMM ADC_NMOS CYC(2) break; + case 0x6A: RORA CYC(2) break; + case 0x6B: INV IMM ARR CYC(2) break; + case 0x6C: IABSNMOS JMP CYC(6) break; + case 0x6D: ABS ADC_NMOS CYC(4) break; + case 0x6E: ABS ROR_NMOS CYC(6) break; + case 0x6F: INV ABS RRA CYC(6) break; + case 0x70: REL BVS CYC(2) break; + case 0x71: INDY ADC_NMOS CYC(5) break; + case 0x72: INV HLT CYC(2) break; + case 0x73: INV INDY RRA CYC(8) break; + case 0x74: INV ZPGX NOP CYC(4) break; + case 0x75: ZPGX ADC_NMOS CYC(4) break; + case 0x76: ZPGX ROR_NMOS CYC(6) break; + case 0x77: INV ZPGX RRA CYC(6) break; + case 0x78: SEI CYC(2) break; + case 0x79: ABSY ADC_NMOS CYC(4) break; + case 0x7A: INV NOP CYC(2) break; + case 0x7B: INV ABSY RRA CYC(7) break; + case 0x7C: INV ABSX NOP CYC(4) break; + case 0x7D: ABSX ADC_NMOS CYC(4) break; + case 0x7E: ABSX ROR_NMOS CYC(6) break; + case 0x7F: INV ABSX RRA CYC(7) break; + case 0x80: INV IMM NOP CYC(2) break; + case 0x81: INDX STA CYC(6) break; + case 0x82: INV IMM NOP CYC(2) break; + case 0x83: INV INDX AXS CYC(6) break; + case 0x84: ZPG STY CYC(3) break; + case 0x85: ZPG STA CYC(3) break; + case 0x86: ZPG STX CYC(3) break; + case 0x87: INV ZPG AXS CYC(3) break; + case 0x88: DEY CYC(2) break; + case 0x89: INV IMM NOP CYC(2) break; + case 0x8A: TXA CYC(2) break; + case 0x8B: INV IMM XAA CYC(2) break; + case 0x8C: ABS STY CYC(4) break; + case 0x8D: ABS STA CYC(4) break; + case 0x8E: ABS STX CYC(4) break; + case 0x8F: INV ABS AXS CYC(4) break; + case 0x90: REL BCC CYC(2) break; + case 0x91: INDY STA CYC(6) break; + case 0x92: INV HLT CYC(2) break; + case 0x93: INV INDY AXA CYC(6) break; + case 0x94: ZPGX STY CYC(4) break; + case 0x95: ZPGX STA CYC(4) break; + case 0x96: ZPGY STX CYC(4) break; + case 0x97: INV ZPGY AXS CYC(4) break; + case 0x98: TYA CYC(2) break; + case 0x99: ABSY STA CYC(5) break; + case 0x9A: TXS CYC(2) break; + case 0x9B: INV ABSY TAS CYC(5) break; + case 0x9C: INV ABSX SAY CYC(5) break; + case 0x9D: ABSX STA CYC(5) break; + case 0x9E: INV ABSY XAS CYC(5) break; + case 0x9F: INV ABSY AXA CYC(5) break; + case 0xA0: IMM LDY CYC(2) break; + case 0xA1: INDX LDA CYC(6) break; + case 0xA2: IMM LDX CYC(2) break; + case 0xA3: INV INDX LAX CYC(6) break; + case 0xA4: ZPG LDY CYC(3) break; + case 0xA5: ZPG LDA CYC(3) break; + case 0xA6: ZPG LDX CYC(3) break; + case 0xA7: INV ZPG LAX CYC(3) break; + case 0xA8: TAY CYC(2) break; + case 0xA9: IMM LDA CYC(2) break; + case 0xAA: TAX CYC(2) break; + case 0xAB: INV IMM OAL CYC(2) break; + case 0xAC: ABS LDY CYC(4) break; + case 0xAD: ABS LDA CYC(4) break; + case 0xAE: ABS LDX CYC(4) break; + case 0xAF: INV ABS LAX CYC(4) break; + case 0xB0: REL BCS CYC(2) break; + case 0xB1: INDY LDA CYC(5) break; + case 0xB2: INV HLT CYC(2) break; + case 0xB3: INV INDY LAX CYC(5) break; + case 0xB4: ZPGX LDY CYC(4) break; + case 0xB5: ZPGX LDA CYC(4) break; + case 0xB6: ZPGY LDX CYC(4) break; + case 0xB7: INV ZPGY LAX CYC(4) break; + case 0xB8: CLV CYC(2) break; + case 0xB9: ABSY LDA CYC(4) break; + case 0xBA: TSX CYC(2) break; + case 0xBB: INV ABSY LAS CYC(4) break; + case 0xBC: ABSX LDY CYC(4) break; + case 0xBD: ABSX LDA CYC(4) break; + case 0xBE: ABSY LDX CYC(4) break; + case 0xBF: INV ABSY LAX CYC(4) break; + case 0xC0: IMM CPY CYC(2) break; + case 0xC1: INDX CMP CYC(6) break; + case 0xC2: INV IMM NOP CYC(2) break; + case 0xC3: INV INDX DCM CYC(8) break; + case 0xC4: ZPG CPY CYC(3) break; + case 0xC5: ZPG CMP CYC(3) break; + case 0xC6: ZPG DEC_NMOS CYC(5) break; + case 0xC7: INV ZPG DCM CYC(5) break; + case 0xC8: INY CYC(2) break; + case 0xC9: IMM CMP CYC(2) break; + case 0xCA: DEX CYC(2) break; + case 0xCB: INV IMM SAX CYC(2) break; + case 0xCC: ABS CPY CYC(4) break; + case 0xCD: ABS CMP CYC(4) break; + case 0xCE: ABS DEC_NMOS CYC(5) break; + case 0xCF: INV ABS DCM CYC(6) break; + case 0xD0: REL BNE CYC(2) break; + case 0xD1: INDY CMP CYC(5) break; + case 0xD2: INV HLT CYC(2) break; + case 0xD3: INV INDY DCM CYC(8) break; + case 0xD4: INV ZPGX NOP CYC(4) break; + case 0xD5: ZPGX CMP CYC(4) break; + case 0xD6: ZPGX DEC_NMOS CYC(6) break; + case 0xD7: INV ZPGX DCM CYC(6) break; + case 0xD8: CLD CYC(2) break; + case 0xD9: ABSY CMP CYC(4) break; + case 0xDA: INV NOP CYC(2) break; + case 0xDB: INV ABSY DCM CYC(7) break; + case 0xDC: INV ABSX NOP CYC(4) break; + case 0xDD: ABSX CMP CYC(4) break; + case 0xDE: ABSX DEC_NMOS CYC(6) break; + case 0xDF: INV ABSX DCM CYC(7) break; + case 0xE0: IMM CPX CYC(2) break; + case 0xE1: INDX SBC_NMOS CYC(6) break; + case 0xE2: INV IMM NOP CYC(2) break; + case 0xE3: INV INDX INS CYC(8) break; + case 0xE4: ZPG CPX CYC(3) break; + case 0xE5: ZPG SBC_NMOS CYC(3) break; + case 0xE6: ZPG INC_NMOS CYC(5) break; + case 0xE7: INV ZPG INS CYC(5) break; + case 0xE8: INX CYC(2) break; + case 0xE9: IMM SBC_NMOS CYC(2) break; + case 0xEA: NOP CYC(2) break; + case 0xEB: INV IMM SBC_NMOS CYC(2) break; + case 0xEC: ABS CPX CYC(4) break; + case 0xED: ABS SBC_NMOS CYC(4) break; + case 0xEE: ABS INC_NMOS CYC(6) break; + case 0xEF: INV ABS INS CYC(6) break; + case 0xF0: REL BEQ CYC(2) break; + case 0xF1: INDY SBC_NMOS CYC(5) break; + case 0xF2: INV HLT CYC(2) break; + case 0xF3: INV INDY INS CYC(8) break; + case 0xF4: INV ZPGX NOP CYC(4) break; + case 0xF5: ZPGX SBC_NMOS CYC(4) break; + case 0xF6: ZPGX INC_NMOS CYC(6) break; + case 0xF7: INV ZPGX INS CYC(6) break; + case 0xF8: SED CYC(2) break; + case 0xF9: ABSY SBC_NMOS CYC(4) break; + case 0xFA: INV NOP CYC(2) break; + case 0xFB: INV ABSY INS CYC(7) break; + case 0xFC: INV ABSX NOP CYC(4) break; + case 0xFD: ABSX SBC_NMOS CYC(4) break; + case 0xFE: ABSX INC_NMOS CYC(6) break; + case 0xFF: INV ABSX INS CYC(7) break; + + +65C02 opcodes: (all illegal are NOP, but have cycle counts) + + case 0x00: BRK CYC(7) break; + case 0x01: INDX ORA CYC(6) break; + case 0x02: INV IMM NOP CYC(2) break; + case 0x03: INV NOP CYC(2) break; + case 0x04: ZPG TSB CYC(5) break; + case 0x05: ZPG ORA CYC(3) break; + case 0x06: ZPG ASL_CMOS CYC(5) break; + case 0x07: INV NOP CYC(2) break; + case 0x08: PHP CYC(3) break; + case 0x09: IMM ORA CYC(2) break; + case 0x0A: ASLA CYC(2) break; + case 0x0B: INV NOP CYC(2) break; + case 0x0C: ABS TSB CYC(6) break; + case 0x0D: ABS ORA CYC(4) break; + case 0x0E: ABS ASL_CMOS CYC(6) break; + case 0x0F: INV NOP CYC(2) break; + case 0x10: REL BPL CYC(2) break; + case 0x11: INDY ORA CYC(5) break; + case 0x12: IZPG ORA CYC(5) break; + case 0x13: INV NOP CYC(2) break; + case 0x14: ZPG TRB CYC(5) break; + case 0x15: ZPGX ORA CYC(4) break; + case 0x16: ZPGX ASL_CMOS CYC(6) break; + case 0x17: INV NOP CYC(2) break; + case 0x18: CLC CYC(2) break; + case 0x19: ABSY ORA CYC(4) break; + case 0x1A: INA CYC(2) break; + case 0x1B: INV NOP CYC(2) break; + case 0x1C: ABS TRB CYC(6) break; + case 0x1D: ABSX ORA CYC(4) break; + case 0x1E: ABSX ASL_CMOS CYC(6) break; + case 0x1F: INV NOP CYC(2) break; + case 0x20: ABS JSR CYC(6) break; + case 0x21: INDX AND CYC(6) break; + case 0x22: INV IMM NOP CYC(2) break; + case 0x23: INV NOP CYC(2) break; + case 0x24: ZPG BIT CYC(3) break; + case 0x25: ZPG AND CYC(3) break; + case 0x26: ZPG ROL_CMOS CYC(5) break; + case 0x27: INV NOP CYC(2) break; + case 0x28: PLP CYC(4) break; + case 0x29: IMM AND CYC(2) break; + case 0x2A: ROLA CYC(2) break; + case 0x2B: INV NOP CYC(2) break; + case 0x2C: ABS BIT CYC(4) break; + case 0x2D: ABS AND CYC(2) break; + case 0x2E: ABS ROL_CMOS CYC(6) break; + case 0x2F: INV NOP CYC(2) break; + case 0x30: REL BMI CYC(2) break; + case 0x31: INDY AND CYC(5) break; + case 0x32: IZPG AND CYC(5) break; + case 0x33: INV NOP CYC(2) break; + case 0x34: ZPGX BIT CYC(4) break; + case 0x35: ZPGX AND CYC(4) break; + case 0x36: ZPGX ROL_CMOS CYC(6) break; + case 0x37: INV NOP CYC(2) break; + case 0x38: SEC CYC(2) break; + case 0x39: ABSY AND CYC(4) break; + case 0x3A: DEA CYC(2) break; + case 0x3B: INV NOP CYC(2) break; + case 0x3C: ABSX BIT CYC(4) break; + case 0x3D: ABSX AND CYC(4) break; + case 0x3E: ABSX ROL_CMOS CYC(6) break; + case 0x3F: INV NOP CYC(2) break; + case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break; + case 0x41: INDX EOR CYC(6) break; + case 0x42: INV IMM NOP CYC(2) break; + case 0x43: INV NOP CYC(2) break; + case 0x44: INV ZPG NOP CYC(3) break; + case 0x45: ZPG EOR CYC(3) break; + case 0x46: ZPG LSR_CMOS CYC(5) break; + case 0x47: INV NOP CYC(2) break; + case 0x48: PHA CYC(3) break; + case 0x49: IMM EOR CYC(2) break; + case 0x4A: LSRA CYC(2) break; + case 0x4B: INV NOP CYC(2) break; + case 0x4C: ABS JMP CYC(3) break; + case 0x4D: ABS EOR CYC(4) break; + case 0x4E: ABS LSR_CMOS CYC(6) break; + case 0x4F: INV NOP CYC(2) break; + case 0x50: REL BVC CYC(2) break; + case 0x51: INDY EOR CYC(5) break; + case 0x52: IZPG EOR CYC(5) break; + case 0x53: INV NOP CYC(2) break; + case 0x54: INV ZPGX NOP CYC(4) break; + case 0x55: ZPGX EOR CYC(4) break; + case 0x56: ZPGX LSR_CMOS CYC(6) break; + case 0x57: INV NOP CYC(2) break; + case 0x58: CLI CYC(2) break; + case 0x59: ABSY EOR CYC(4) break; + case 0x5A: PHY CYC(3) break; + case 0x5B: INV NOP CYC(2) break; + case 0x5C: INV ABSX NOP CYC(8) break; + case 0x5D: ABSX EOR CYC(4) break; + case 0x5E: ABSX LSR_CMOS CYC(6) break; + case 0x5F: INV NOP CYC(2) break; + case 0x60: RTS CYC(6) break; + case 0x61: INDX ADC_CMOS CYC(6) break; + case 0x62: INV IMM NOP CYC(2) break; + case 0x63: INV NOP CYC(2) break; + case 0x64: ZPG STZ CYC(3) break; + case 0x65: ZPG ADC_CMOS CYC(3) break; + case 0x66: ZPG ROR_CMOS CYC(5) break; + case 0x67: INV NOP CYC(2) break; + case 0x68: PLA CYC(4) break; + case 0x69: IMM ADC_CMOS CYC(2) break; + case 0x6A: RORA CYC(2) break; + case 0x6B: INV NOP CYC(2) break; + case 0x6C: IABSCMOS JMP CYC(6) break; + case 0x6D: ABS ADC_CMOS CYC(4) break; + case 0x6E: ABS ROR_CMOS CYC(6) break; + case 0x6F: INV NOP CYC(2) break; + case 0x70: REL BVS CYC(2) break; + case 0x71: INDY ADC_CMOS CYC(5) break; + case 0x72: IZPG ADC_CMOS CYC(5) break; + case 0x73: INV NOP CYC(2) break; + case 0x74: ZPGX STZ CYC(4) break; + case 0x75: ZPGX ADC_CMOS CYC(4) break; + case 0x76: ZPGX ROR_CMOS CYC(6) break; + case 0x77: INV NOP CYC(2) break; + case 0x78: SEI CYC(2) break; + case 0x79: ABSY ADC_CMOS CYC(4) break; + case 0x7A: PLY CYC(4) break; + case 0x7B: INV NOP CYC(2) break; + case 0x7C: IABSX JMP CYC(6) break; + case 0x7D: ABSX ADC_CMOS CYC(4) break; + case 0x7E: ABSX ROR_CMOS CYC(6) break; + case 0x7F: INV NOP CYC(2) break; + case 0x80: REL BRA CYC(2) break; + case 0x81: INDX STA CYC(6) break; + case 0x82: INV IMM NOP CYC(2) break; + case 0x83: INV NOP CYC(2) break; + case 0x84: ZPG STY CYC(3) break; + case 0x85: ZPG STA CYC(3) break; + case 0x86: ZPG STX CYC(3) break; + case 0x87: INV NOP CYC(2) break; + case 0x88: DEY CYC(2) break; + case 0x89: IMM BITI CYC(2) break; + case 0x8A: TXA CYC(2) break; + case 0x8B: INV NOP CYC(2) break; + case 0x8C: ABS STY CYC(4) break; + case 0x8D: ABS STA CYC(4) break; + case 0x8E: ABS STX CYC(4) break; + case 0x8F: INV NOP CYC(2) break; + case 0x90: REL BCC CYC(2) break; + case 0x91: INDY STA CYC(6) break; + case 0x92: IZPG STA CYC(5) break; + case 0x93: INV NOP CYC(2) break; + case 0x94: ZPGX STY CYC(4) break; + case 0x95: ZPGX STA CYC(4) break; + case 0x96: ZPGY STX CYC(4) break; + case 0x97: INV NOP CYC(2) break; + case 0x98: TYA CYC(2) break; + case 0x99: ABSY STA CYC(5) break; + case 0x9A: TXS CYC(2) break; + case 0x9B: INV NOP CYC(2) break; + case 0x9C: ABS STZ CYC(4) break; + case 0x9D: ABSX STA CYC(5) break; + case 0x9E: ABSX STZ CYC(5) break; + case 0x9F: INV NOP CYC(2) break; + case 0xA0: IMM LDY CYC(2) break; + case 0xA1: INDX LDA CYC(6) break; + case 0xA2: IMM LDX CYC(2) break; + case 0xA3: INV NOP CYC(2) break; + case 0xA4: ZPG LDY CYC(3) break; + case 0xA5: ZPG LDA CYC(3) break; + case 0xA6: ZPG LDX CYC(3) break; + case 0xA7: INV NOP CYC(2) break; + case 0xA8: TAY CYC(2) break; + case 0xA9: IMM LDA CYC(2) break; + case 0xAA: TAX CYC(2) break; + case 0xAB: INV NOP CYC(2) break; + case 0xAC: ABS LDY CYC(4) break; + case 0xAD: ABS LDA CYC(4) break; + case 0xAE: ABS LDX CYC(4) break; + case 0xAF: INV NOP CYC(2) break; + case 0xB0: REL BCS CYC(2) break; + case 0xB1: INDY LDA CYC(5) break; + case 0xB2: IZPG LDA CYC(5) break; + case 0xB3: INV NOP CYC(2) break; + case 0xB4: ZPGX LDY CYC(4) break; + case 0xB5: ZPGX LDA CYC(4) break; + case 0xB6: ZPGY LDX CYC(4) break; + case 0xB7: INV NOP CYC(2) break; + case 0xB8: CLV CYC(2) break; + case 0xB9: ABSY LDA CYC(4) break; + case 0xBA: TSX CYC(2) break; + case 0xBB: INV NOP CYC(2) break; + case 0xBC: ABSX LDY CYC(4) break; + case 0xBD: ABSX LDA CYC(4) break; + case 0xBE: ABSY LDX CYC(4) break; + case 0xBF: INV NOP CYC(2) break; + case 0xC0: IMM CPY CYC(2) break; + case 0xC1: INDX CMP CYC(6) break; + case 0xC2: INV IMM NOP CYC(2) break; + case 0xC3: INV NOP CYC(2) break; + case 0xC4: ZPG CPY CYC(3) break; + case 0xC5: ZPG CMP CYC(3) break; + case 0xC6: ZPG DEC_CMOS CYC(5) break; + case 0xC7: INV NOP CYC(2) break; + case 0xC8: INY CYC(2) break; + case 0xC9: IMM CMP CYC(2) break; + case 0xCA: DEX CYC(2) break; + case 0xCB: INV NOP CYC(2) break; + case 0xCC: ABS CPY CYC(4) break; + case 0xCD: ABS CMP CYC(4) break; + case 0xCE: ABS DEC_CMOS CYC(5) break; + case 0xCF: INV NOP CYC(2) break; + case 0xD0: REL BNE CYC(2) break; + case 0xD1: INDY CMP CYC(5) break; + case 0xD2: IZPG CMP CYC(5) break; + case 0xD3: INV NOP CYC(2) break; + case 0xD4: INV ZPGX NOP CYC(4) break; + case 0xD5: ZPGX CMP CYC(4) break; + case 0xD6: ZPGX DEC_CMOS CYC(6) break; + case 0xD7: INV NOP CYC(2) break; + case 0xD8: CLD CYC(2) break; + case 0xD9: ABSY CMP CYC(4) break; + case 0xDA: PHX CYC(3) break; + case 0xDB: INV NOP CYC(2) break; + case 0xDC: INV ABSX NOP CYC(4) break; + case 0xDD: ABSX CMP CYC(4) break; + case 0xDE: ABSX DEC_CMOS CYC(6) break; + case 0xDF: INV NOP CYC(2) break; + case 0xE0: IMM CPX CYC(2) break; + case 0xE1: INDX SBC_CMOS CYC(6) break; + case 0xE2: INV IMM NOP CYC(2) break; + case 0xE3: INV NOP CYC(2) break; + case 0xE4: ZPG CPX CYC(3) break; + case 0xE5: ZPG SBC_CMOS CYC(3) break; + case 0xE6: ZPG INC_CMOS CYC(5) break; + case 0xE7: INV NOP CYC(2) break; + case 0xE8: INX CYC(2) break; + case 0xE9: IMM SBC_CMOS CYC(2) break; + case 0xEA: NOP CYC(2) break; + case 0xEB: INV NOP CYC(2) break; + case 0xEC: ABS CPX CYC(4) break; + case 0xED: ABS SBC_CMOS CYC(4) break; + case 0xEE: ABS INC_CMOS CYC(6) break; + case 0xEF: INV NOP CYC(2) break; + case 0xF0: REL BEQ CYC(2) break; + case 0xF1: INDY SBC_CMOS CYC(5) break; + case 0xF2: IZPG SBC_CMOS CYC(5) break; + case 0xF3: INV NOP CYC(2) break; + case 0xF4: INV ZPGX NOP CYC(4) break; + case 0xF5: ZPGX SBC_CMOS CYC(4) break; + case 0xF6: ZPGX INC_CMOS CYC(6) break; + case 0xF7: INV NOP CYC(2) break; + case 0xF8: SED CYC(2) break; + case 0xF9: ABSY SBC_CMOS CYC(4) break; + case 0xFA: PLX CYC(4) break; + case 0xFB: INV NOP CYC(2) break; + case 0xFC: INV ABSX NOP CYC(4) break; + case 0xFD: ABSX SBC_CMOS CYC(4) break; + case 0xFE: ABSX INC_CMOS CYC(6) break; + case 0xFF: INV NOP CYC(2) break; +*/ // Private function prototypes @@ -525,6 +1123,17 @@ BCS Relative BCS Oper B0 2 2 BEQ Relative BEQ Oper F0 2 2 */ +// Branch taken adds a cycle, crossing page adds one more + +#define HANDLE_BRANCH_TAKEN(m) \ +{ \ + uint16 oldpc = regs.pc; \ + regs.pc += m; \ + regs.clock++; \ + if ((oldpc ^ regs.pc) & 0xFF00) \ + regs.clock++; \ +} + // Branch opcodes static void Op90(void) // BCC @@ -532,7 +1141,8 @@ static void Op90(void) // BCC int16 m = (int16)(int8)READ_IMM; if (!(regs.cc & FLAG_C)) - regs.pc += m; + HANDLE_BRANCH_TAKEN(m) +// regs.pc += m; } static void OpB0(void) // BCS @@ -540,7 +1150,8 @@ static void OpB0(void) // BCS int16 m = (int16)(int8)READ_IMM; if (regs.cc & FLAG_C) - regs.pc += m; + HANDLE_BRANCH_TAKEN(m) +// regs.pc += m; } static void OpF0(void) // BEQ @@ -548,7 +1159,8 @@ static void OpF0(void) // BEQ int16 m = (int16)(int8)READ_IMM; if (regs.cc & FLAG_Z) - regs.pc += m; + HANDLE_BRANCH_TAKEN(m) +// regs.pc += m; } /* @@ -616,7 +1228,8 @@ static void Op30(void) // BMI int16 m = (int16)(int8)READ_IMM; if (regs.cc & FLAG_N) - regs.pc += m; + HANDLE_BRANCH_TAKEN(m) +// regs.pc += m; } static void OpD0(void) // BNE @@ -624,7 +1237,8 @@ static void OpD0(void) // BNE int16 m = (int16)(int8)READ_IMM; if (!(regs.cc & FLAG_Z)) - regs.pc += m; + HANDLE_BRANCH_TAKEN(m) +// regs.pc += m; } static void Op10(void) // BPL @@ -632,13 +1246,15 @@ static void Op10(void) // BPL int16 m = (int16)(int8)READ_IMM; if (!(regs.cc & FLAG_N)) - regs.pc += m; + HANDLE_BRANCH_TAKEN(m) +// regs.pc += m; } static void Op80(void) // BRA { int16 m = (int16)(int8)READ_IMM; - regs.pc += m; + HANDLE_BRANCH_TAKEN(m) +// regs.pc += m; } /* @@ -669,7 +1285,8 @@ static void Op50(void) // BVC int16 m = (int16)(int8)READ_IMM; if (!(regs.cc & FLAG_V)) - regs.pc += m; + HANDLE_BRANCH_TAKEN(m) +// regs.pc += m; } static void Op70(void) // BVS @@ -677,7 +1294,8 @@ static void Op70(void) // BVS int16 m = (int16)(int8)READ_IMM; if (regs.cc & FLAG_V) - regs.pc += m; + HANDLE_BRANCH_TAKEN(m) +// regs.pc += m; } /* diff --git a/src/video.cpp b/src/video.cpp index 170b238..5f8ff84 100755 --- a/src/video.cpp +++ b/src/video.cpp @@ -190,13 +190,21 @@ WriteLog("\n");//*/ // void VideoDone(void) { + WriteLog("Video: Shutting down OpenGL...\n"); if (settings.useOpenGL) sdlemu_close_opengl(); + WriteLog("Video: Shutting down joystick....\n"); SDL_JoystickClose(joystick); + WriteLog("Video: Freeing 'surface'...\n"); SDL_FreeSurface(surface); +#warning "The problem is here: Doing either of the SDL_Quitxxx functions causes a double free. !!! FIX !!!" +#warning "Some googling suggests that it may be the thread component causing the trouble." + WriteLog("Video: Shutting down SDL subsystems...\n"); SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO | SDL_INIT_TIMER); + WriteLog("Video: Shutting down SDL...\n"); SDL_Quit(); + WriteLog("Video: Done.\n"); } // -- 2.37.2