From ebcadf2555c4086606f3a0b6c23cbec80d9ac1fd Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Wed, 18 Sep 2013 19:03:09 -0500 Subject: [PATCH] Fixes to make emulator //e compatible; display can do double hires now. --- ROMs/apple2.rom | Bin ROMs/apple2c.rom | Bin ROMs/apple2e-enhanced.rom | Bin 0 -> 16384 bytes ROMs/apple2e.rom | Bin 16384 -> 16384 bytes apple2.cfg | 9 +- src/apple2.cpp | 520 ++++++++++++++++++++++++++++++++++++-- src/apple2.h | 2 + src/applevideo.cpp | 183 ++++++++++++-- src/applevideo.h | 1 + src/firmware.h | 19 ++ src/sound.cpp | 2 +- src/v65c02.cpp | 47 ++++ 12 files changed, 735 insertions(+), 48 deletions(-) mode change 100755 => 100644 ROMs/apple2.rom mode change 100755 => 100644 ROMs/apple2c.rom create mode 100644 ROMs/apple2e-enhanced.rom mode change 100755 => 100644 ROMs/apple2e.rom diff --git a/ROMs/apple2.rom b/ROMs/apple2.rom old mode 100755 new mode 100644 diff --git a/ROMs/apple2c.rom b/ROMs/apple2c.rom old mode 100755 new mode 100644 diff --git a/ROMs/apple2e-enhanced.rom b/ROMs/apple2e-enhanced.rom new file mode 100644 index 0000000000000000000000000000000000000000..65bb648567f66b37874b1a417f564b296280c5f7 GIT binary patch literal 16384 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 I|Nid(1v1KeNdN!< literal 0 HcmV?d00001 diff --git a/ROMs/apple2e.rom b/ROMs/apple2e.rom old mode 100755 new mode 100644 index 65bb648567f66b37874b1a417f564b296280c5f7..916b318b7c053030cdeb24749be99cb57ef77f15 GIT binary patch delta 4746 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 delta 4709 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 AQvd(} diff --git a/apple2.cfg b/apple2.cfg index f672918..3aa30c3 100755 --- a/apple2.cfg +++ b/apple2.cfg @@ -4,7 +4,7 @@ # Apple ROM paths -BIOSROM = ./ROMs/apple2.rom +BIOSROM = ./ROMs/apple2e-enhanced.rom diskROM = ./ROMs/disk.rom ROMs = ./ROMs @@ -29,8 +29,8 @@ autoSaveState = 1 #floppyImage2 = ./disks/bt3_character_fixed.dsk # Yes #floppyImage1 = ./disks/Sabotage.dsk -# ??? (//c or //e w/128K required) -#floppyImage1 = ./disks/airheart.dsk +# ??? (//c or //e w/128K required) (dumps to monitor) +floppyImage1 = ./disks/airheart.dsk # Yes #floppyImage1 = ./disks/drol.dsk # Yes @@ -51,6 +51,7 @@ autoSaveState = 1 #floppyImage2 = ./disks/MoebiusIIB.dsk # Yes #floppyImage1 = ./disks/wind_walker_1.dsk +#floppyImage2 = ./disks/wind_walker_2.dsk # Yes #floppyImage1 = ./disks/dino_eggs.dsk # ??? 1, yes; 2, no @@ -74,7 +75,7 @@ autoSaveState = 1 # Yes #floppyImage1 = ./disks/lode_runner.dsk # Yes -floppyImage1 = ./disks/championship_lode_runner.dsk +#floppyImage1 = ./disks/championship_lode_runner.dsk # OpenGL filtering type: 1 - blurry, 0 - sharp diff --git a/src/apple2.cpp b/src/apple2.cpp index 8b6a36f..572d758 100755 --- a/src/apple2.cpp +++ b/src/apple2.cpp @@ -58,17 +58,18 @@ #define THREADED_65C02 #define CPU_THREAD_OVERFLOW_COMPENSATION -//#define DEBUG_LC +#define DEBUG_LC //#define CPU_CLOCK_CHECKING -#define THREAD_DEBUGGING +//#define THREAD_DEBUGGING +#define SOFT_SWITCH_DEBUGGING // Global variables uint8_t ram[0x10000], rom[0x10000]; // RAM & ROM spaces -uint8_t ram2[0x10000]; +uint8_t ram2[0x10000]; // Auxillary RAM uint8_t diskRom[0x100]; // Disk ROM space V65C02REGS mainCPU; // v65C02 execution context -uint8_t appleType = APPLE_TYPE_II; +uint8_t appleType = APPLE_TYPE_IIE; FloppyDrive floppyDrive; // Local variables @@ -77,6 +78,15 @@ static uint8_t lastKeyPressed = 0; static bool keyDown = false; static bool openAppleDown = false; static bool closedAppleDown = false; +static bool store80Mode = false; +static bool vbl = false; +static bool slotCXROM = false; +static bool slotC3ROM = false; +static bool ramrd = false; +static bool ramwrt = false; +static bool altzp = false; +static bool ioudis = true; +bool dhires = false; //static FloppyDrive floppyDrive; @@ -114,6 +124,8 @@ static bool cpuFinished = false; static bool cpuSleep = false; +// NB: Apple //e Manual sez 6502 is running @ 1,022,727 Hz + // Let's try a thread... /* Here's how it works: Execute 1 frame's worth, then sleep. @@ -188,7 +200,7 @@ WriteLog("CPU: Execute65C02(&mainCPU, cycles);\n"); } #endif -WriteLog("CPUThread: Supposedly end of frame...\n"); +//WriteLog("CPUThread: Supposedly end of frame...\n"); #ifdef THREAD_DEBUGGING WriteLog("CPU: SDL_mutexP(cpuMutex);\n"); @@ -288,7 +300,8 @@ if (addr >= 0xC080 && addr <= 0xC08F) { return lastKeyPressed | (keyDown ? 0x80 : 0x00); } - else if ((addr & 0xFFF0) == 0xC010) // Read $C010-$C01F +// else if ((addr & 0xFFF8) == 0xC010) // Read $C010-$C01F + else if (addr == 0xC010) { //This is bogus: keyDown is set to false, so return val NEVER is set... //Fixed... @@ -297,6 +310,112 @@ if (addr >= 0xC080 && addr <= 0xC08F) keyDown = false; return retVal; } + // These are //e locations + else if (addr == 0xC011) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("RDBANK2 (read)\n"); +#endif + return (visibleBank == LC_BANK_2 ? 0x80 : 0x00); + } + else if (addr == 0xC012) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("RDLCRAM (read)\n"); +#endif + return (readRAM ? 0x80 : 0x00); + } + else if (addr == 0xC013) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("RAMRD (read)\n"); +#endif + return (ramrd ? 0x80 : 0x00); + } + else if (addr == 0xC014) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("RAMWRT (read)\n"); +#endif + return (ramwrt ? 0x80 : 0x00); + } + else if (addr == 0xC015) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("SLOTCXROM (read)\n"); +#endif + return (slotCXROM ? 0x80 : 0x00); + } + else if (addr == 0xC016) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("ALTZP (read)\n"); +#endif + return (altzp ? 0x80 : 0x00); + } + else if (addr == 0xC017) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("SLOTC3ROM (read)\n"); +#endif + return (slotC3ROM ? 0x80 : 0x00); + } + else if (addr == 0xC018) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("80STORE (read)\n"); +#endif + return (store80Mode ? 0x80 : 0x00); + } + else if (addr == 0xC019) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("VBL (read)\n"); +#endif + return (vbl ? 0x80 : 0x00); + } + else if (addr == 0xC01A) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("TEXT (read)\n"); +#endif + return (textMode ? 0x80 : 0x00); + } + else if (addr == 0xC01B) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("MIXED (read)\n"); +#endif + return (mixedMode ? 0x80 : 0x00); + } + else if (addr == 0xC01C) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("PAGE2 (read)\n"); +#endif + return (displayPage2 ? 0x80 : 0x00); + } + else if (addr == 0xC01D) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("HIRES (read)\n"); +#endif + return (hiRes ? 0x80 : 0x00); + } + else if (addr == 0xC01E) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("ALTCHARSET (read)\n"); +#endif + return (alternateCharset ? 0x80 : 0x00); + } + else if (addr == 0xC01F) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("80COL (read)\n"); +#endif + return (col80Mode ? 0x80 : 0x00); + } else if ((addr & 0xFFF0) == 0xC030) // Read $C030-$C03F { /* @@ -322,36 +441,76 @@ deltaT to zero. In the sound IRQ, if deltaT > buffer size, then subtract buffer } else if (addr == 0xC050) // Read $C050 { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("TEXT off (read)\n"); +#endif textMode = false; } else if (addr == 0xC051) // Read $C051 { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("TEXT on (read)\n"); +#endif textMode = true; } else if (addr == 0xC052) // Read $C052 { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("MIXED off (read)\n"); +#endif mixedMode = false; } else if (addr == 0xC053) // Read $C053 { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("MIXED on (read)\n"); +#endif mixedMode = true; } else if (addr == 0xC054) // Read $C054 { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("PAGE2 off (read)\n"); +#endif displayPage2 = false; } else if (addr == 0xC055) // Read $C055 { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("PAGE2 on (read)\n"); +#endif displayPage2 = true; } else if (addr == 0xC056) // Read $C056 { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("HIRES off (read)\n"); +#endif hiRes = false; } else if (addr == 0xC057) // Read $C057 { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("HIRES on (read)\n"); +#endif hiRes = true; } + else if (addr == 0xC05E) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("DHIRES on (read)\n"); +#endif + if (ioudis) + dhires = true; + } + else if (addr == 0xC05F) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("DHIRES off (read)\n"); +#endif + if (ioudis) + dhires = false; + } else if (addr == 0xC061) // Read $C061 { // Open Apple key (or push button 0) @@ -362,6 +521,40 @@ deltaT to zero. In the sound IRQ, if deltaT > buffer size, then subtract buffer // Open Apple key (or push button 0) return (closedAppleDown ? 0x80 : 0x00); } + // The way the paddles work is that a strobe is written (or read) to $C070, + // then software counts down the time that it takes for the paddle outputs + // to have bit 7 return to 0. If there are no paddles connected, bit 7 + // stays at 1. + else if (addr == 0xC064) // Paddles 0-3 + { + return 0xFF; + } + else if (addr == 0xC065) + { + return 0xFF; + } + else if (addr == 0xC066) + { + return 0xFF; + } + else if (addr == 0xC067) + { + return 0xFF; + } + else if (addr == 0xC07E) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("IOUDIS (read)\n"); +#endif + return (ioudis ? 0x80 : 0x00); + } + else if (addr == 0xC07F) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("DHIRES (read)\n"); +#endif + return (dhires ? 0x80 : 0x00); + } //Note that this is a kludge: The $D000-$DFFF 4K space is shared (since $C000-$CFFF is //memory mapped) between TWO banks, and that that $E000-$FFFF RAM space is a single bank. @@ -520,62 +713,107 @@ if (addr >= 0xD000 && addr <= 0xD00F) showpath = true; #endif //This sux... - if (addr >= 0xC100 && addr <= 0xCFFF) // The $C000-$CFFF block is *never* RAM -#ifdef LC_DEBUGGING + if (addr >= 0xC100 && addr <= 0xC7FF) // The $C000-$CFFF block is *never* RAM { -#endif - b = rom[addr]; +// Looks like the ][e ref manual got this one wrong: slotCXROM set should mean +// use internal ROM, NOT slot ROM. :-/ +// (fixed now, by setting the switch correctly in the write mem section :-P) + if (!slotCXROM) +// if (slotCXROM) + b = rom[addr]; + else + { + if (addr >= 0xC100 && addr <= 0xC1FF) + b = parallelROM[addr & 0xFF]; + else if (addr >= 0xC600 && addr <= 0xC6FF) + b = diskROM[addr & 0xFF]; + else if (addr >= 0xC300 && addr <= 0xC3FF && !slotC3ROM) + b = rom[addr]; + else + b = 0xFF; +// b = rom[addr]; + } #ifdef LC_DEBUGGING if (showpath) WriteLog("b is from $C100-$CFFF block...\n"); - } #endif + } + else if (addr >= 0xC800 && addr <= 0xCFFF) // 2K peripheral or OS ROM + { + b = rom[addr]; + } else if (addr >= 0xD000) { if (readRAM) { if (addr <= 0xDFFF && visibleBank == LC_BANK_1) #ifdef LC_DEBUGGING - { + { #endif b = ram[addr - 0x1000]; +// b = (ramrd ? ram2[addr - 0x1000] : ram[addr - 0x1000]); #ifdef LC_DEBUGGING if (showpath) WriteLog("b is from LC bank #1 (ram[addr - 0x1000])...\n"); - } + } #endif else #ifdef LC_DEBUGGING - { + { #endif b = ram[addr]; +// b = (ramrd ? ram2[addr] : ram[addr]); #ifdef LC_DEBUGGING if (showpath) WriteLog("b is from LC bank #2 (ram[addr])...\n"); - } + } #endif } else #ifdef LC_DEBUGGING - { + { #endif b = rom[addr]; #ifdef LC_DEBUGGING if (showpath) WriteLog("b is from LC ROM (rom[addr])...\n"); - } + } #endif } else -#ifdef LC_DEBUGGING { +#if 1 + // Check for 80STORE mode (STORE80 takes precedence over RAMRD/WRT)... + if ((((addr >= 0x0400) && (addr <= 0x07FF)) || ((addr >= 0x2000) && (addr <= 0x3FFF))) && store80Mode) + { + if (displayPage2) + b = ram2[addr]; + else + b = ram[addr]; + + return b; + } + + // Finally, check for auxillary/altzp write switches #endif - b = ram[addr]; + if (addr < 0x0200) + b = (altzp ? ram2[addr] : ram[addr]); + else + b = (ramrd ? ram2[addr] : ram[addr]); +// if (ramrd) +// b = ram2[addr]; +// else +// { +// if (altzp) +// b = ram2[addr]; +// else +// b = ram[addr]; +// } #ifdef LC_DEBUGGING if (showpath) WriteLog("b is from ram[addr]...\n"); - } #endif + } #ifdef LC_DEBUGGING if (addr >= 0xD000 && addr <= 0xD00F) @@ -687,12 +925,117 @@ SET80VID = $C00D ;enable 80-column display mode (WR-only) CLRALTCH = $C00E ;use main char set- norm LC, Flash UC (WR-only) SETALTCH = $C00F ;use alt char set- norm inverse, LC; no Flash (WR-only) */ - if (addr == 0xC00E) + if (addr == 0xC000) { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("80STORE off (write)\n"); +#endif + store80Mode = false; + } + else if (addr == 0xC001) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("80STORE on (write)\n"); +#endif + store80Mode = true; + } + else if (addr == 0xC002) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("RAMRD off (write)\n"); +#endif + ramrd = false; + } + else if (addr == 0xC003) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("RAMRD on (write)\n"); +#endif + ramrd = true; + } + else if (addr == 0xC004) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("RAMWRT off (write)\n"); +#endif + ramwrt = false; + } + else if (addr == 0xC005) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("RAMWRT on (write)\n"); +#endif + ramwrt = true; + } + else if (addr == 0xC006) + { + // This is the only soft switch that breaks the usual convention. +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("SLOTCXROM on (write)\n"); +#endif + slotCXROM = true; + } + else if (addr == 0xC007) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("SLOTCXROM off (write)\n"); +#endif + slotCXROM = false; + } + else if (addr == 0xC008) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("ALTZP off (write)\n"); +#endif + altzp = false; + } + else if (addr == 0xC009) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("ALTZP on (write)\n"); +#endif + altzp = true; + } + else if (addr == 0xC00A) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("SLOTC3ROM off (write)\n"); +#endif + slotC3ROM = false; + } + else if (addr == 0xC00B) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("SLOTC3ROM on (write)\n"); +#endif + slotC3ROM = true; + } + else if (addr == 0xC00C) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("80COL off (write)\n"); +#endif + col80Mode = false; + } + else if (addr == 0xC00D) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("80COL on (write)\n"); +#endif + col80Mode = true; + } + else if (addr == 0xC00E) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("ALTCHARSET off (write)\n"); +#endif alternateCharset = false; } else if (addr == 0xC00F) { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("ALTCHARSET on (write)\n"); +#endif alternateCharset = true; } else if ((addr & 0xFFF0) == 0xC010) // Keyboard strobe @@ -704,36 +1047,95 @@ SETALTCH = $C00F ;use alt char set- norm inverse, LC; no Flash (WR-only) } else if (addr == 0xC050) { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("TEXT off (write)\n"); +#endif textMode = false; } else if (addr == 0xC051) { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("TEXT on (write)\n"); +#endif textMode = true; } else if (addr == 0xC052) { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("MIXED off (write)\n"); +#endif mixedMode = false; } else if (addr == 0xC053) { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("MIXED on (write)\n"); +#endif mixedMode = true; } else if (addr == 0xC054) { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("PAGE2 off (write)\n"); +#endif displayPage2 = false; } else if (addr == 0xC055) { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("PAGE2 on (write)\n"); +#endif displayPage2 = true; } else if (addr == 0xC056) { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("HIRES off (write)\n"); +#endif hiRes = false; } else if (addr == 0xC057) { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("HIRES on (write)\n"); +#endif hiRes = true; } + else if (addr == 0xC05E) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("DHIRES on (write)\n"); +#endif + if (ioudis) + dhires = true; + +//static int goDumpDis = 0; +//goDumpDis++; +//if (goDumpDis == 2) +// dumpDis = true; + } + else if (addr == 0xC05F) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("DHIRES off (write)\n"); +#endif + if (ioudis) + dhires = false; + } + else if (addr == 0xC07E) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("IOUDIS on (write)\n"); +#endif + ioudis = true; + } + else if (addr == 0xC07F) + { +#ifdef SOFT_SWITCH_DEBUGGING +WriteLog("IOUDIS off (write)\n"); +#endif + ioudis = false; + } else if ((addr & 0xFFFB) == 0xC080) { #ifdef DEBUG_LC @@ -861,16 +1263,70 @@ if (addr >= 0xD000 && addr <= 0xD00F) { if (writeRAM) { +#if 1 if (addr <= 0xDFFF && visibleBank == LC_BANK_1) ram[addr - 0x1000] = b; else ram[addr] = b; +#else + if (addr <= 0xDFFF && visibleBank == LC_BANK_1) + { + if (ramwrt) + ram2[addr - 0x1000] = b; + else + ram[addr - 0x1000] = b; + } + else + { + if (ramwrt) + ram2[addr] = b; + else + ram[addr] = b; + } +#endif } return; } - ram[addr] = b; + // Check for 80STORE mode (STORE80 takes precedence over RAMRD/WRT)... + if ((((addr >= 0x0400) && (addr <= 0x07FF)) || ((addr >= 0x2000) && (addr <= 0x3FFF))) && store80Mode) + { + if (displayPage2) + ram2[addr] = b; + else + ram[addr] = b; + + return; + } + + // Finally, check for auxillary/altzp write switches +#if 0 + if (ramwrt) + ram2[addr] = b; + else + { + if (altzp) + ram2[addr] = b; + else + ram[addr] = b; + } +#else + if (addr < 0x0200) + { + if (altzp) + ram2[addr] = b; + else + ram[addr] = b; + } + else + { + if (ramwrt) + ram2[addr] = b; + else + ram[addr] = b; + } +#endif } @@ -928,7 +1384,9 @@ int main(int /*argc*/, char * /*argv*/[]) mainCPU.WrMem = WrMem; mainCPU.cpuFlags |= V65C02_ASSERT_LINE_RESET; - if (!LoadImg(settings.BIOSPath, rom + 0xD000, 0x3000)) +// alternateCharset = true; +// if (!LoadImg(settings.BIOSPath, rom + 0xD000, 0x3000)) + if (!LoadImg(settings.BIOSPath, rom + 0xC000, 0x4000)) { WriteLog("Could not open file '%s'!\n", settings.BIOSPath); return -1; @@ -948,7 +1406,7 @@ int main(int /*argc*/, char * /*argv*/[]) //Kill the DOS ROM in slot 6 for now... //not - memcpy(rom + 0xC600, diskROM, 0x100); +// memcpy(rom + 0xC600, diskROM, 0x100); // memcpy(rom + 0xC700, diskROM, 0x100); // Slot 7??? WriteLog("About to initialize video...\n"); @@ -1156,7 +1614,7 @@ Z $DA $9A $DA $9A ESC $9B $9B $9B $9B No xlation */ -static uint64_t lastCPUCycles = 0; +//static uint64_t lastCPUCycles = 0; static uint32_t frameCount = 0; static void FrameCallback(void) { @@ -1179,8 +1637,8 @@ static void FrameCallback(void) //kludge: should have a caps lock thingy here... //or all uppercase for ][+... - if (lastKeyPressed >= 'a' && lastKeyPressed <='z') - lastKeyPressed &= 0xDF; // Convert to upper case... +// if (lastKeyPressed >= 'a' && lastKeyPressed <='z') +// lastKeyPressed &= 0xDF; // Convert to upper case... break; case SDL_KEYDOWN: @@ -1197,10 +1655,16 @@ static void FrameCallback(void) lastKeyPressed = 0x15, keyDown = true; else if (event.key.keysym.sym == SDLK_LEFT) lastKeyPressed = 0x08, keyDown = true; + else if (event.key.keysym.sym == SDLK_UP) + lastKeyPressed = 0x0B, keyDown = true; + else if (event.key.keysym.sym == SDLK_DOWN) + lastKeyPressed = 0x0A, keyDown = true; else if (event.key.keysym.sym == SDLK_RETURN) lastKeyPressed = 0x0D, keyDown = true; else if (event.key.keysym.sym == SDLK_ESCAPE) lastKeyPressed = 0x1B, keyDown = true; + else if (event.key.keysym.sym == SDLK_BACKSPACE) + lastKeyPressed = 0x7F, keyDown = true; // Fix CTRL+key combo... if (event.key.keysym.mod & KMOD_CTRL) @@ -1337,7 +1801,7 @@ if (counter == 60) SDL_Delay(1); // Wait for next frame... startTicks = SDL_GetTicks(); -#if 1 +#if 0 uint64_t cpuCycles = GetCurrentV65C02Clock(); uint32_t cyclesBurned = (uint32_t)(cpuCycles - lastCPUCycles); WriteLog("FrameCallback: used %i cycles\n", cyclesBurned); diff --git a/src/apple2.h b/src/apple2.h index 958bb0b..7696c5a 100755 --- a/src/apple2.h +++ b/src/apple2.h @@ -10,5 +10,7 @@ enum { APPLE_TYPE_II, APPLE_TYPE_IIE, APPLE_TYPE_IIC }; // Global variables (exported) extern uint8_t ram[0x10000], rom[0x10000]; // RAM & ROM pointers +extern uint8_t ram2[0x10000]; // Auxillary RAM extern uint8_t appleType; extern FloppyDrive floppyDrive; +extern bool dhires; diff --git a/src/applevideo.cpp b/src/applevideo.cpp index 919776f..d3060bf 100755 --- a/src/applevideo.cpp +++ b/src/applevideo.cpp @@ -62,12 +62,13 @@ // Global variables -bool flash; -bool textMode; -bool mixedMode; -bool displayPage2; -bool hiRes; -bool alternateCharset; +bool flash = false; +bool textMode = true; +bool mixedMode = false; +bool displayPage2 = false; +bool hiRes = false; +bool alternateCharset = false; +bool col80Mode = false; //void SpawnMessage(const char * text, ...); // Local variables @@ -228,6 +229,7 @@ uint16_t appleHiresToMono[0x200] = { //static uint8_t blurTable[0x800][8]; // Color TV blur table static uint8_t blurTable[0x80][8]; // Color TV blur table +static uint8_t mirrorTable[0x100]; static uint32_t * palette = (uint32_t *)altColors; enum { ST_FIRST_ENTRY = 0, ST_COLOR_TV = 0, ST_WHITE_MONO, ST_GREEN_MONO, ST_LAST_ENTRY }; static uint8_t screenType = ST_COLOR_TV; @@ -235,9 +237,12 @@ static uint8_t screenType = ST_COLOR_TV; // Local functions static void Render40ColumnTextLine(uint8_t line); +static void Render80ColumnTextLine(uint8_t line); static void Render40ColumnText(void); +static void Render80ColumnText(void); static void RenderLoRes(uint16_t toLine = 24); static void RenderHiRes(uint16_t toLine = 192); +static void RenderDHiRes(uint16_t toLine = 192); void SetupBlurTable(void) @@ -294,6 +299,18 @@ void SetupBlurTable(void) } } #endif + + for(int i=0; i<256; i++) + { + mirrorTable[i] = ((i & 0x01) << 7) + | ((i & 0x02) << 5) + | ((i & 0x04) << 3) + | ((i & 0x08) << 1) + | ((i & 0x10) >> 1) + | ((i & 0x20) >> 3) + | ((i & 0x40) >> 5) + | ((i & 0x80) >> 7); + } } @@ -425,10 +442,9 @@ static void Render40ColumnTextLine(uint8_t line) { uint32_t pixel = 0xFF000000; - if (!alternateCharset) + if (alternateCharset) { if (textChar[((chr & 0x3F) * 56) + cx + (cy * 7)]) -// pixel = 0xFFFFFFFF; pixel = pixelOn; if (chr < 0x80) @@ -440,12 +456,9 @@ static void Render40ColumnTextLine(uint8_t line) else { if (textChar2e[(chr * 56) + cx + (cy * 7)]) -// pixel = 0xFFFFFFFF; pixel = pixelOn; } -// scrBuffer[(x * 7 * 2) + (line * VIRTUAL_SCREEN_WIDTH * 8) + (cx * 2) + 0 + (cy * VIRTUAL_SCREEN_WIDTH)] = pixel; -// scrBuffer[(x * 7 * 2) + (line * VIRTUAL_SCREEN_WIDTH * 8) + (cx * 2) + 1 + (cy * VIRTUAL_SCREEN_WIDTH)] = pixel; scrBuffer[(x * 7 * 2) + (line * VIRTUAL_SCREEN_WIDTH * 8 * 2) + (cx * 2) + 0 + (cy * VIRTUAL_SCREEN_WIDTH * 2)] = pixel; scrBuffer[(x * 7 * 2) + (line * VIRTUAL_SCREEN_WIDTH * 8 * 2) + (cx * 2) + 1 + (cy * VIRTUAL_SCREEN_WIDTH * 2)] = pixel; @@ -454,8 +467,8 @@ static void Render40ColumnTextLine(uint8_t line) pixel = 0xFF000000; { - scrBuffer[(x * 7 * 2) + (line * VIRTUAL_SCREEN_WIDTH * 8 * 2) + (cx * 2) + 0 + (((cy * 2) + 1) * VIRTUAL_SCREEN_WIDTH)] = pixel; - scrBuffer[(x * 7 * 2) + (line * VIRTUAL_SCREEN_WIDTH * 8 * 2) + (cx * 2) + 1 + (((cy * 2) + 1) * VIRTUAL_SCREEN_WIDTH)] = pixel; + scrBuffer[(x * 7 * 2) + (line * VIRTUAL_SCREEN_WIDTH * 8 * 2) + (cx * 2) + 0 + (((cy * 2) + 1) * VIRTUAL_SCREEN_WIDTH)] = pixel; + scrBuffer[(x * 7 * 2) + (line * VIRTUAL_SCREEN_WIDTH * 8 * 2) + (cx * 2) + 1 + (((cy * 2) + 1) * VIRTUAL_SCREEN_WIDTH)] = pixel; } } } @@ -463,6 +476,65 @@ static void Render40ColumnTextLine(uint8_t line) } +static void Render80ColumnTextLine(uint8_t line) +{ + uint32_t pixelOn = (screenType == ST_GREEN_MONO ? 0xFF61FF61 : 0xFFFFFFFF); + + for(int x=0; x<80; x++) + { +#if 0 +// This is wrong; it should grab from the alt bank if Page2 is set, not main RAM @ $0 + uint8_t chr = ram[lineAddrLoRes[line] + (displayPage2 ? 0x0400 : 0x0000) + x]; + + if (x > 39) + chr = ram2[lineAddrLoRes[line] + (displayPage2 ? 0x0400 : 0x0000) + x - 40]; +#else + uint8_t chr; + + if (x & 0x01) + chr = ram[lineAddrLoRes[line] + (x >> 1)]; + else + chr = ram2[lineAddrLoRes[line] + (x >> 1)]; +#endif + + // Render character at (x, y) + + for(int cy=0; cy<8; cy++) + { + for(int cx=0; cx<7; cx++) + { + uint32_t pixel = 0xFF000000; + + if (alternateCharset) + { + if (textChar[((chr & 0x3F) * 56) + cx + (cy * 7)]) + pixel = pixelOn; + + if (chr < 0x80) + pixel = pixel ^ (screenType == ST_GREEN_MONO ? 0x0061FF61 : 0x00FFFFFF); + + if ((chr & 0xC0) == 0x40 && flash) + pixel = 0xFF000000; + } + else + { + if (textChar2e[(chr * 56) + cx + (cy * 7)]) + pixel = pixelOn; + } + + scrBuffer[(x * 7) + (line * VIRTUAL_SCREEN_WIDTH * 8 * 2) + cx + (cy * 2 * VIRTUAL_SCREEN_WIDTH)] = pixel; + + // QnD method to get blank alternate lines in text mode + if (screenType == ST_GREEN_MONO) + pixel = 0xFF000000; + + scrBuffer[(x * 7) + (line * VIRTUAL_SCREEN_WIDTH * 8 * 2) + cx + (((cy * 2) + 1) * VIRTUAL_SCREEN_WIDTH)] = pixel; + } + } + } +} + + static void Render40ColumnText(void) { for(uint8_t line=0; line<24; line++) @@ -470,6 +542,13 @@ static void Render40ColumnText(void) } +static void Render80ColumnText(void) +{ + for(uint8_t line=0; line<24; line++) + Render80ColumnTextLine(line); +} + + static void RenderLoRes(uint16_t toLine/*= 24*/) { // NOTE: The green mono rendering doesn't skip every other line... !!! FIX !!! @@ -716,6 +795,75 @@ static void RenderHiRes(uint16_t toLine/*= 192*/) } +static void RenderDHiRes(uint16_t toLine/*= 192*/) +{ +// NOTE: Not endian safe. !!! FIX !!! [DONE] +#if 0 + uint32_t pixelOn = (screenType == ST_WHITE_MONO ? 0xFFFFFFFF : 0xFF61FF61); +#else +// Now it is. Now roll this fix into all the other places... !!! FIX !!! +// The colors are set in the 8-bit array as R G B A + uint8_t monoColors[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0x61, 0xFF, 0x61, 0xFF }; + uint32_t * colorPtr = (uint32_t *)monoColors; + uint32_t pixelOn = (screenType == ST_WHITE_MONO ? colorPtr[0] : colorPtr[1]); +#endif + + for(uint16_t y=0; y> 1); + + // We now have 28 pixels (expanded from 14) in word: mask is $0F FF FF FF + // 0ppp 1111 1111 1111 1111 1111 1111 1111 + // 31 27 23 19 15 11 7 3 0 + + if (screenType == ST_COLOR_TV) + { + for(uint8_t i=0; i<7; i++) + { + uint8_t bitPat = (pixels & 0x7F000000) >> 24; + pixels <<= 4; + + for(uint8_t j=0; j<4; j++) + { + uint8_t color = blurTable[bitPat][j]; + scrBuffer[(x * 14) + (i * 4) + j + (((y * 2) + 0) * VIRTUAL_SCREEN_WIDTH)] = palette[color]; + scrBuffer[(x * 14) + (i * 4) + j + (((y * 2) + 1) * VIRTUAL_SCREEN_WIDTH)] = palette[color]; + } + } + + previous3bits = pixels & 0x70000000; + } + else + { + for(int j=0; j<28; j++) + { + scrBuffer[(x * 14) + j + (((y * 2) + 0) * VIRTUAL_SCREEN_WIDTH)] = (pixels & 0x08000000 ? pixelOn : 0xFF000000); + + if (screenType == ST_GREEN_MONO) + pixels &= 0x07FFFFFF; + + scrBuffer[(x * 14) + j + (((y * 2) + 1) * VIRTUAL_SCREEN_WIDTH)] = (pixels & 0x08000000 ? pixelOn : 0xFF000000); + pixels <<= 1; + } + } + } + } +} + + void RenderVideoFrame(void) { //temp... @@ -726,7 +874,10 @@ return;//*/ if (textMode) { // There's prolly more to it than this (like 80 column text), but this'll have to do for now... - Render40ColumnText(); + if (!col80Mode) + Render40ColumnText(); + else + Render80ColumnText(); } else { @@ -751,7 +902,9 @@ return;//*/ } else { - if (hiRes) + if (dhires) + RenderDHiRes(); + else if (hiRes) RenderHiRes(); else RenderLoRes(); diff --git a/src/applevideo.h b/src/applevideo.h index fcb2cac..e0707ac 100755 --- a/src/applevideo.h +++ b/src/applevideo.h @@ -13,6 +13,7 @@ extern bool mixedMode; extern bool displayPage2; extern bool hiRes; extern bool alternateCharset; +extern bool col80Mode; // Functions (exported) diff --git a/src/firmware.h b/src/firmware.h index d27fcc8..63cc197 100755 --- a/src/firmware.h +++ b/src/firmware.h @@ -40,6 +40,25 @@ char hdROM[0x100] = { // Loads at $C700 (slot 7) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x7F, 0xD7, 0x46 }; +char parallelROM[0x100] = { + 0x18, 0xB0, 0x38, 0x48, 0x8A, 0x48, 0x98, 0x48, 0x08, 0x78, 0x20, 0x58, 0xFF, 0xBA, 0x68, 0x68, + 0x68, 0x68, 0xA8, 0xCA, 0x9A, 0x68, 0x28, 0xAA, 0x90, 0x38, 0xBD, 0xB8, 0x05, 0x10, 0x19, 0x98, + 0x29, 0x7F, 0x49, 0x30, 0xC9, 0x0A, 0x90, 0x3B, 0xC9, 0x78, 0xB0, 0x29, 0x49, 0x3D, 0xF0, 0x21, + 0x98, 0x29, 0x9F, 0x9D, 0x38, 0x06, 0x90, 0x7E, 0xBD, 0xB8, 0x06, 0x30, 0x14, 0xA5, 0x24, 0xDD, + 0x38, 0x07, 0xB0, 0x0D, 0xC9, 0x11, 0xB0, 0x09, 0x09, 0xF0, 0x3D, 0x38, 0x07, 0x65, 0x24, 0x85, + 0x24, 0x4A, 0x38, 0xB0, 0x6D, 0x18, 0x6A, 0x3D, 0xB8, 0x06, 0x90, 0x02, 0x49, 0x81, 0x9D, 0xB8, + 0x06, 0xD0, 0x53, 0xA0, 0x0A, 0x7D, 0x38, 0x05, 0x88, 0xD0, 0xFA, 0x9D, 0xB8, 0x04, 0x9D, 0x38, + 0x05, 0x38, 0xB0, 0x43, 0xC5, 0x24, 0x90, 0x3A, 0x68, 0xA8, 0x68, 0xAA, 0x68, 0x4C, 0xF0, 0xFD, + 0x90, 0xFE, 0xB0, 0xFE, 0x99, 0x80, 0xC0, 0x90, 0x37, 0x49, 0x07, 0xA8, 0x49, 0x0A, 0x0A, 0xD0, + 0x06, 0xB8, 0x85, 0x24, 0x9D, 0x38, 0x07, 0xBD, 0xB8, 0x06, 0x4A, 0x70, 0x02, 0xB0, 0x23, 0x0A, + 0x0A, 0xA9, 0x27, 0xB0, 0xCF, 0xBD, 0x38, 0x07, 0xFD, 0xB8, 0x04, 0xC9, 0xF8, 0x90, 0x03, 0x69, + 0x27, 0xAC, 0xA9, 0x00, 0x85, 0x24, 0x18, 0x7E, 0xB8, 0x05, 0x68, 0xA8, 0x68, 0xAA, 0x68, 0x60, + 0x90, 0x27, 0xB0, 0x00, 0x10, 0x11, 0xA9, 0x89, 0x9D, 0x38, 0x06, 0x9D, 0xB8, 0x06, 0xA9, 0x28, + 0x9D, 0xB8, 0x04, 0xA9, 0x02, 0x85, 0x36, 0x98, 0x5D, 0x38, 0x06, 0x0A, 0xF0, 0x90, 0x5E, 0xB8, + 0x05, 0x98, 0x48, 0x8A, 0x0A, 0x0A, 0x0A, 0x0A, 0xA8, 0xBD, 0x38, 0x07, 0xC5, 0x24, 0x68, 0xB0, + 0x05, 0x48, 0x29, 0x80, 0x09, 0x20, 0x2C, 0x58, 0xFF, 0xF0, 0x03, 0xFE, 0x38, 0x07, 0x70, 0x84 +}; + // Various firmware from the IIe ROM file... //Not sure what the heck this is... diff --git a/src/sound.cpp b/src/sound.cpp index 0d794c9..22a027d 100755 --- a/src/sound.cpp +++ b/src/sound.cpp @@ -162,7 +162,7 @@ static void SDLSoundCallback(void * /*userdata*/, Uint8 * buffer8, int length8) // Let's try using a mutex for shared resource consumption... //Actually, I think Lock/UnlockAudio() does this already... -WriteLog("SDLSoundCallback: soundBufferPos = %i\n", soundBufferPos); +//WriteLog("SDLSoundCallback: soundBufferPos = %i\n", soundBufferPos); SDL_mutexP(mutex2); // Recast this as a 16-bit type... diff --git a/src/v65c02.cpp b/src/v65c02.cpp index 7f86895..e10006c 100755 --- a/src/v65c02.cpp +++ b/src/v65c02.cpp @@ -2844,8 +2844,14 @@ FBEF: 60 602 RTS2B RTS //int instCount[256]; #ifdef __DEBUG__ bool dumpDis = false; +//bool dumpDis = true; #endif +/* +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; @@ -2899,6 +2905,47 @@ if (regs.pc == 0x444E) }//*/ #endif +#if 0 +/*if (regs.pc == 0x0801) +{ + WriteLog("\n*** DISK BOOT subroutine...\n\n"); + dumpDis = true; +}//*/ +if (regs.pc == 0xE000) +{ +#if 0 + WriteLog("\n*** Dump of $E000 routine ***\n\n"); + + for(uint32_t addr=0xE000; addr<0xF000;) + { + addr += Decode65C02(addr); + WriteLog("\n"); + } +#endif + WriteLog("\n*** DISK part II subroutine...\n\n"); + dumpDis = true; +}//*/ +if (regs.pc == 0xD000) +{ + WriteLog("\n*** CUSTOM DISK READ subroutine...\n\n"); + dumpDis = false; +}//*/ +if (regs.pc == 0xD1BE) +{ +// WriteLog("\n*** DISK part II subroutine...\n\n"); + dumpDis = true; +}//*/ +if (regs.pc == 0xD200) +{ + WriteLog("\n*** CUSTOM SCREEN subroutine...\n\n"); + dumpDis = false; +}//*/ +if (regs.pc == 0xD269) +{ +// WriteLog("\n*** DISK part II subroutine...\n\n"); + dumpDis = true; +}//*/ +#endif #ifdef __DEBUGMON__ //WAIT is commented out here because it's called by BELL1... if (regs.pc == 0xFCA8)