From 452bb368446b4984765ed217214826568c79bbfc Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Sun, 30 Mar 2014 13:07:30 -0500 Subject: [PATCH] Added disk selection functionality, fixed power cycle bug. --- src/apple2.cpp | 11 ++-- src/applevideo.cpp | 7 +++ src/floppy.cpp | 6 +-- src/floppy.h | 2 +- src/gui/diskselector.cpp | 109 +++++++++++++++++++++++++++++++++++---- src/gui/diskselector.h | 4 +- src/gui/gui.cpp | 34 +++++++++--- src/mmu.cpp | 28 ++++++++++ src/mmu.h | 1 + 9 files changed, 178 insertions(+), 24 deletions(-) diff --git a/src/apple2.cpp b/src/apple2.cpp index c74f86a..9afc35f 100644 --- a/src/apple2.cpp +++ b/src/apple2.cpp @@ -283,7 +283,6 @@ static bool LoadApple2State(const char * filename) static void ResetApple2State(void) { - mainCPU.cpuFlags |= V65C02_ASSERT_LINE_RESET; keyDown = false; openAppleDown = false; closedAppleDown = false; @@ -297,9 +296,14 @@ static void ResetApple2State(void) ioudis = true; dhires = false; lcState = 0x02; - SwitchLC(); // Make sure MMU is in sane state +// SwitchLC(); // Make sure MMU is in sane state +//NOPE, does nothing SetupAddressMap(); + ResetMMUPointers(); + + // Without this, you can wedge the system :-/ memset(ram, 0, 0x10000); - memset(ram2, 0, 0x10000); +// memset(ram2, 0, 0x10000); + mainCPU.cpuFlags |= V65C02_ASSERT_LINE_RESET; } @@ -324,6 +328,7 @@ int main(int /*argc*/, char * /*argv*/[]) // Set up MMU SetupAddressMap(); + ResetMMUPointers(); // Set up V65C02 execution context memset(&mainCPU, 0, sizeof(V65C02REGS)); diff --git a/src/applevideo.cpp b/src/applevideo.cpp index db3b15d..e7672cf 100644 --- a/src/applevideo.cpp +++ b/src/applevideo.cpp @@ -724,6 +724,7 @@ fb fb fb -> 15 [1111] -> 15 WHITE static void RenderHiRes(uint16_t toLine/*= 192*/) { +//printf("RenderHiRes to line %u\n", toLine); // NOTE: Not endian safe. !!! FIX !!! [DONE] #if 0 uint32_t pixelOn = (screenType == ST_WHITE_MONO ? 0xFFFFFFFF : 0xFF61FF61); @@ -752,6 +753,12 @@ static void RenderHiRes(uint16_t toLine/*= 192*/) pixels = previous3bits | (pixels << 14) | pixels2; +//testing (this shows on the screen, so it's OK) +//if (x == 0) +//{ +// pixels = 0x7FFFFFFF; +//} + // 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 diff --git a/src/floppy.cpp b/src/floppy.cpp index 4dc4cba..ca78135 100644 --- a/src/floppy.cpp +++ b/src/floppy.cpp @@ -46,7 +46,7 @@ FloppyDrive::FloppyDrive(): motorOn(0), activeDrive(0), ioMode(IO_MODE_READ), ph { disk[0] = disk[1] = NULL; diskSize[0] = diskSize[1] = 0; - diskType[0] = diskType[1] = DT_UNKNOWN; + diskType[0] = diskType[1] = DFT_UNKNOWN; imageDirty[0] = imageDirty[1] = false; writeProtected[0] = writeProtected[1] = false; imageName[0][0] = imageName[1][0] = 0; // Zero out filenames @@ -224,7 +224,7 @@ SpawnMessage("Drive 0: %s...", imageName[0]); void FloppyDrive::DetectImageType(const char * filename, uint8_t driveNum) { - diskType[driveNum] = DT_UNKNOWN; + diskType[driveNum] = DFT_UNKNOWN; if (diskSize[driveNum] == 232960) { @@ -551,7 +551,7 @@ void FloppyDrive::EjectImage(uint8_t driveNum/*= 0*/) disk[driveNum] = NULL; diskSize[driveNum] = 0; - diskType[driveNum] = DT_UNKNOWN; + diskType[driveNum] = DFT_UNKNOWN; imageDirty[driveNum] = false; writeProtected[driveNum] = false; imageName[driveNum][0] = 0; // Zero out filenames diff --git a/src/floppy.h b/src/floppy.h index 969ca0c..6adb039 100644 --- a/src/floppy.h +++ b/src/floppy.h @@ -14,7 +14,7 @@ #endif #include -enum { DT_UNKNOWN, DT_DOS33, DT_DOS33_HDR, DT_PRODOS, DT_NYBBLE }; +enum { DFT_UNKNOWN, DT_DOS33, DT_DOS33_HDR, DT_PRODOS, DT_NYBBLE }; enum { DLS_OFF, DLS_READ, DLS_WRITE }; class FloppyDrive diff --git a/src/gui/diskselector.cpp b/src/gui/diskselector.cpp index 69db0e7..bcc0c23 100644 --- a/src/gui/diskselector.cpp +++ b/src/gui/diskselector.cpp @@ -20,11 +20,25 @@ #include #include #include +#include "apple2.h" #include "font10pt.h" #include "log.h" #include "settings.h" #include "video.h" + +enum { DSS_SHOWING, DSS_HIDING, DSS_SHOWN, DSS_HIDDEN }; + +#define DS_WIDTH 400 +#define DS_HEIGHT 300 + +bool entered = false; +int driveNumber; +int diskSelectorState = DSS_HIDDEN; +int diskSelected = -1; +int lastDiskSelected = -1; + + // // Case insensitve string comparison voodoo // @@ -61,7 +75,7 @@ typedef std::basic_string ci_string; static SDL_Texture * window = NULL; static SDL_Texture * charStamp = NULL; -static uint32_t windowPixels[400 * 300]; +static uint32_t windowPixels[DS_WIDTH * DS_HEIGHT]; static uint32_t stamp[FONT_WIDTH * FONT_HEIGHT]; bool DiskSelector::showWindow = false; std::vector imageList; @@ -70,7 +84,7 @@ std::vector imageList; void DiskSelector::Init(SDL_Renderer * renderer) { window = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ABGR8888, - SDL_TEXTUREACCESS_TARGET, 400, 300); + SDL_TEXTUREACCESS_TARGET, DS_WIDTH, DS_HEIGHT); charStamp = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, FONT_WIDTH, FONT_HEIGHT); @@ -86,7 +100,7 @@ void DiskSelector::Init(SDL_Renderer * renderer) if (SDL_SetTextureBlendMode(charStamp, SDL_BLENDMODE_BLEND) == -1) WriteLog("GUI (DiskSelector): Could not set blend mode for charStamp.\n"); - for(uint32_t i=0; i<400*300; i++) + for(uint32_t i=0; i= imageList[count].length()) break; - DrawCharacter(renderer, currentX + i, currentY, imageList[count][i]); + bool invert = (diskSelected == (int)count ? true : false); + DrawCharacter(renderer, currentX + i, currentY, imageList[count][i], invert); } count++; @@ -184,7 +199,8 @@ void DiskSelector::DrawFilenames(SDL_Renderer * renderer) } -void DiskSelector::DrawCharacter(SDL_Renderer * renderer, int x, int y, uint8_t c) +void DiskSelector::DrawCharacter(SDL_Renderer * renderer, int x, int y, uint8_t c, + bool invert/*=false*/) { #if 0 // uint32_t pixel = 0xFF7F0000; @@ -201,47 +217,120 @@ void DiskSelector::DrawCharacter(SDL_Renderer * renderer, int x, int y, uint8_t SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00); #else - uint32_t pixel = 0xFFFFA020; + uint32_t inv = (invert ? 0x000000FF : 0x00000000); + uint32_t pixel = 0xFFFFC000; // RRGGBBAA uint8_t * ptr = (uint8_t *)&font10pt[(c - 0x20) * FONT_WIDTH * FONT_HEIGHT]; SDL_Rect dst; dst.x = x * FONT_WIDTH, dst.y = y * FONT_HEIGHT, dst.w = FONT_WIDTH, dst.h = FONT_HEIGHT; for(int i=0; i= DS_XPOS) && (x <= (DS_XPOS + DS_WIDTH)) + && (y >= DS_YPOS) && (y <= (DS_YPOS + DS_HEIGHT)))) + entered = true; + + if (entered && ((x < DS_XPOS) || (x > (DS_XPOS + DS_WIDTH)) + || (y < DS_YPOS) || (y > (DS_YPOS + DS_HEIGHT)))) + { + showWindow = false; + return; + } + +// prevDiskSelected = diskSelected; + int xChar = (x - DS_XPOS) / FONT_WIDTH; + int yChar = (y - DS_YPOS) / FONT_HEIGHT; +// int currentX = (count / 27) * 22; +// int currentY = (count % 27); + diskSelected = ((xChar / 22) * 27) + yChar; + + if ((yChar >= 27) || (diskSelected >= (int)imageList.size())) + diskSelected = -1; + + if (diskSelected != lastDiskSelected) + { + HandleSelection(sdlRenderer); + lastDiskSelected = diskSelected; + } +} + + +void DiskSelector::HandleSelection(SDL_Renderer * renderer) +{ +// if (diskSelected == prevDiskSelected) +// return; + + SDL_UpdateTexture(window, NULL, windowPixels, 128 * sizeof(Uint32)); + DrawFilenames(renderer); } void DiskSelector::Render(SDL_Renderer * renderer) { - if (!(window || showWindow)) + if (!(window && showWindow)) return; +// HandleSelection(renderer); + SDL_Rect dst; - dst.x = (VIRTUAL_SCREEN_WIDTH - 400) / 2, dst.y = (VIRTUAL_SCREEN_HEIGHT - 300) / 2, dst.w = 400, dst.h = 300; +// dst.x = (VIRTUAL_SCREEN_WIDTH - DS_WIDTH) / 2, dst.y = (VIRTUAL_SCREEN_HEIGHT - DS_HEIGHT) / 2, dst.w = DS_WIDTH, dst.h = DS_HEIGHT; + dst.x = DS_XPOS, dst.y = DS_YPOS, dst.w = DS_WIDTH, dst.h = DS_HEIGHT; SDL_RenderCopy(renderer, window, NULL, &dst); } diff --git a/src/gui/diskselector.h b/src/gui/diskselector.h index 8299715..c784e21 100644 --- a/src/gui/diskselector.h +++ b/src/gui/diskselector.h @@ -15,10 +15,12 @@ class DiskSelector static void FindDisks(const char *); static bool HasLegalExtension(const char *); static void DrawFilenames(SDL_Renderer *); - static void DrawCharacter(SDL_Renderer *, int, int, uint8_t); + static void DrawCharacter(SDL_Renderer *, int, int, uint8_t, bool inv=false); + static void ShowWindow(int); static void MouseDown(int32_t, int32_t, uint32_t); static void MouseUp(int32_t, int32_t, uint32_t); static void MouseMove(int32_t, int32_t, uint32_t); + static void HandleSelection(SDL_Renderer *); static void Render(SDL_Renderer *); public: diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index af9a5d5..b61eab3 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -187,7 +187,7 @@ void GUI::Init(SDL_Renderer * renderer) } DiskSelector::Init(renderer); - DiskSelector::showWindow = true; +// DiskSelector::showWindow = true; WriteLog("GUI: Successfully initialized.\n"); } @@ -209,11 +209,11 @@ SDL_Texture * GUI::CreateTexture(SDL_Renderer * renderer, const void * source) void GUI::MouseDown(int32_t x, int32_t y, uint32_t buttons) { + DiskSelector::MouseDown(x, y, buttons); + if (sidebarState != SBS_SHOWN) return; -// char [2][2] = {}; - switch (iconSelected) { // Power @@ -230,7 +230,16 @@ void GUI::MouseDown(int32_t x, int32_t y, uint32_t buttons) SpawnMessage("*** DISK #1 ***"); if (disk1EjectHovered && !floppyDrive.IsEmpty(0)) - SpawnMessage("*** EJECT DISK #1 ***"); + { + floppyDrive.EjectImage(0); + SpawnMessage("*** DISK #1 EJECTED ***"); + } + + if (!disk1EjectHovered) + { + // Load the disk selector + DiskSelector::ShowWindow(0); + } break; // Disk #2 @@ -238,12 +247,22 @@ void GUI::MouseDown(int32_t x, int32_t y, uint32_t buttons) SpawnMessage("*** DISK #2 ***"); if (disk2EjectHovered && !floppyDrive.IsEmpty(1)) - SpawnMessage("*** EJECT DISK #2 ***"); + { + floppyDrive.EjectImage(1); + SpawnMessage("*** DISK #2 EJECTED ***"); + } + + if (!disk2EjectHovered) + { + // Load the disk selector + DiskSelector::ShowWindow(1); + } break; // Swap disks case 3: - SpawnMessage("*** SWAP DISKS ***"); + floppyDrive.SwapImages(); + SpawnMessage("*** DISKS SWAPPED ***"); break; // Save state case 4: @@ -263,11 +282,14 @@ void GUI::MouseDown(int32_t x, int32_t y, uint32_t buttons) void GUI::MouseUp(int32_t x, int32_t y, uint32_t buttons) { + DiskSelector::MouseUp(x, y, buttons); } void GUI::MouseMove(int32_t x, int32_t y, uint32_t buttons) { + DiskSelector::MouseMove(x, y, buttons); + if (sidebarState != SBS_SHOWN) { iconSelected = -1; diff --git a/src/mmu.cpp b/src/mmu.cpp index 1b2ccdc..7070fda 100644 --- a/src/mmu.cpp +++ b/src/mmu.cpp @@ -276,6 +276,34 @@ void SetupAddressMap(void) } +// +// Reset the MMU state after a power down event +// +void ResetMMUPointers(void) +{ + if (store80Mode) + { + mainMemoryTextR = (displayPage2 ? &ram2[0x0400] : &ram[0x0400]); + mainMemoryTextW = (displayPage2 ? &ram2[0x0400] : &ram[0x0400]); + } + else + { + mainMemoryTextR = (ramwrt ? &ram2[0x0400] : &ram[0x0400]); + mainMemoryTextW = (ramwrt ? &ram2[0x0400] : &ram[0x0400]); + } + + mainMemoryR = (ramrd ? &ram2[0x0200] : &ram[0x0200]); + mainMemoryHGRR = (ramrd ? &ram2[0x2000] : &ram[0x2000]); + mainMemoryW = (ramwrt ? &ram2[0x0200] : &ram[0x0200]); + mainMemoryHGRW = (ramwrt ? &ram2[0x2000] : &ram[0x2000]); + + slot6Memory = (slotCXROM ? &diskROM[0] : &rom[0xC600]); + slot3Memory = (slotC3ROM ? &rom[0] : &rom[0xC300]); + pageZeroMemory = (altzp ? &ram2[0x0000] : &ram[0x0000]); + SwitchLC(); +} + + // // Built-in functions // diff --git a/src/mmu.h b/src/mmu.h index f5a5b72..aed258b 100644 --- a/src/mmu.h +++ b/src/mmu.h @@ -4,6 +4,7 @@ #include void SetupAddressMap(void); +void ResetMMUPointers(void); uint8_t AppleReadMem(uint16_t); void AppleWriteMem(uint16_t, uint8_t); void SwitchLC(void); -- 2.37.2