]> Shamusworld >> Repos - apple2/commitdiff
Added disk selection functionality, fixed power cycle bug.
authorShamus Hammons <jlhamm@acm.org>
Sun, 30 Mar 2014 18:07:30 +0000 (13:07 -0500)
committerShamus Hammons <jlhamm@acm.org>
Sun, 30 Mar 2014 18:07:30 +0000 (13:07 -0500)
src/apple2.cpp
src/applevideo.cpp
src/floppy.cpp
src/floppy.h
src/gui/diskselector.cpp
src/gui/diskselector.h
src/gui/gui.cpp
src/mmu.cpp
src/mmu.h

index c74f86a894e63df5794f7b864ec68bb7e7ea5749..9afc35ff980a86eaa591a801461482ccc008fa00 100644 (file)
@@ -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));
index db3b15dced1c727f77602564ef120de1f06272b1..e7672cff7c2291bc44801354d0e421c8cc676514 100644 (file)
@@ -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
index 4dc4cbae284a62db6803f54dbb8c71195793f719..ca78135c37a04f2943dcdbf2934f7fbf5ca0da5a 100644 (file)
@@ -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
index 969ca0c8dfc2eb00e0ff447b599b9365c84ccd81..6adb039c6022328f75396307c2df6dff7b6b8847 100644 (file)
@@ -14,7 +14,7 @@
 #endif
 #include <stdint.h>
 
-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
index 69db0e7f178904ca747d3fe636809bd0e9aaeaf3..bcc0c239b9609608539326ae9528c0ab7f38cffd 100644 (file)
 #include <algorithm>
 #include <string>
 #include <vector>
+#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<char, ci_char_traits> 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<ci_string> imageList;
@@ -70,7 +84,7 @@ std::vector<ci_string> 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<DS_WIDTH*DS_HEIGHT; i++)
                windowPixels[i] = 0xEF00FF00;
 
        SDL_UpdateTexture(window, NULL, windowPixels, 128 * sizeof(Uint32));
@@ -150,7 +164,7 @@ void DiskSelector::DrawFilenames(SDL_Renderer * renderer)
        // 3 columns of 18 chars apiece (with 7X12 font), 24 rows
        // 3 columns of 21 chars apiece (with 6X11 font), 27 rows
 
-       int count = 0;
+       unsigned int count = 0;
 
        while (count < imageList.size())
        {
@@ -168,7 +182,8 @@ void DiskSelector::DrawFilenames(SDL_Renderer * renderer)
                        if (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<FONT_WIDTH*FONT_HEIGHT; i++)
-               stamp[i] = pixel | ptr[i];
+               stamp[i] = (pixel | ptr[i]) ^ inv;
 
        SDL_UpdateTexture(charStamp, NULL, stamp, FONT_WIDTH * sizeof(Uint32));
        SDL_RenderCopy(renderer, charStamp, NULL, &dst);
 #endif
 }
 
+
 /*
 void DiskSelector::()
 {
 }
 */
 
+
+void DiskSelector::ShowWindow(int drive)
+{
+       entered = false;
+       showWindow = true;
+       driveNumber = drive;
+}
+
+
 void DiskSelector::MouseDown(int32_t x, int32_t y, uint32_t buttons)
 {
+       if (!showWindow)
+               return;
+
+       if (!entered)
+               return;
+
+       if (diskSelected != -1)
+       {
+               char buffer[2048];
+               sprintf(buffer, "%s/%s", settings.disksPath, &imageList[diskSelected][0]);
+//             floppyDrive.LoadImage(&imageList[diskSelected][0], driveNumber);
+               floppyDrive.LoadImage(buffer, driveNumber);
+       }
+
+       showWindow = false;
 }
 
 
 void DiskSelector::MouseUp(int32_t x, int32_t y, uint32_t buttons)
 {
+       if (!showWindow)
+               return;
+
 }
 
 
+#define DS_XPOS        ((VIRTUAL_SCREEN_WIDTH - DS_WIDTH) / 2)
+#define DS_YPOS        ((VIRTUAL_SCREEN_HEIGHT - DS_HEIGHT) / 2)
 void DiskSelector::MouseMove(int32_t x, int32_t y, uint32_t buttons)
 {
+       if (!showWindow)
+               return;
+
+       if (!entered && ((x >= 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);
 }
index 829971566360b46243501afae6e11c3f124146dc..c784e218b25c0c22b4841395600dbf3292ab84b6 100644 (file)
@@ -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:
index af9a5d5939f51ea6ac4db7db4daf1d2b4c4f4c3a..b61eab3c797e376b7fe9a09d5ea25313696a8e64 100644 (file)
@@ -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;
index 1b2ccdc2e1b3e38c7794a3ae7521b21530c8f7cf..7070fda34b93347f6bc539b3c8cf1147a5c6397d 100644 (file)
@@ -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
 //
index f5a5b7232c17b08fdbee70083ec3c7f6bb0f3f3e..aed258b6da91774d46a5cbcbaacb5c88f230faaf 100644 (file)
--- a/src/mmu.h
+++ b/src/mmu.h
@@ -4,6 +4,7 @@
 #include <stdint.h>
 
 void SetupAddressMap(void);
+void ResetMMUPointers(void);
 uint8_t AppleReadMem(uint16_t);
 void AppleWriteMem(uint16_t, uint8_t);
 void SwitchLC(void);