]> Shamusworld >> Repos - apple2/commitdiff
Added infrastructure to handle write protecting floppy disks
authorShamus Hammons <jlhamm@acm.org>
Wed, 4 Feb 2009 14:19:00 +0000 (14:19 +0000)
committerShamus Hammons <jlhamm@acm.org>
Wed, 4 Feb 2009 14:19:00 +0000 (14:19 +0000)
apple2.cfg
src/floppy.cpp
src/floppy.h
src/gui/button.cpp
src/gui/button.h
src/gui/diskwindow.cpp
src/gui/diskwindow.h

index 2762779184c32fde7eb64cdbc494e0e291e8dde1..bd3016bf1133a96cb6e13655903e192a5cd921ad 100755 (executable)
@@ -25,8 +25,8 @@ 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)
@@ -47,8 +47,8 @@ floppyImage2 = ./disks/bt3_character_fixed.dsk
 # Yes, but crashes on the attract mode (does the same in AppleWin)
 # Also, has keyboard troubles... no, write problems
 #floppyImage1 = ./disks/moebiusiia.dsk
-#floppyImage1 = ./disks/MoebiusIIA.dsk
-#floppyImage2 = ./disks/MoebiusIIB.dsk
+floppyImage1 = ./disks/MoebiusIIA.dsk
+floppyImage2 = ./disks/MoebiusIIB.dsk
 # Yes, but segfaults on title screen
 #floppyImage1 = ./disks/wind_walker_1.dsk
 # Yes
index 56ea4147333a8aab7ff607bc1f62b96617067766..d4037140d5e652b6474af8a585c0e9889da2934e 100755 (executable)
@@ -47,6 +47,7 @@ FloppyDrive::FloppyDrive(): motorOn(0), activeDrive(0), ioMode(IO_MODE_READ), ph
        diskSize[0] = diskSize[1] = 0;
        diskType[0] = diskType[1] = DT_UNKNOWN;
        imageDirty[0] = imageDirty[1] = false;
+       writeProtected[0] = writeProtected[1] = false;
        imageName[0][0] = imageName[1][0] = 0;                  // Zero out filenames
 }
 
@@ -170,6 +171,7 @@ void FloppyDrive::CreateBlankImage(uint8 driveNum/*= 0*/)
        memset(nybblizedImage[driveNum], 0x00, 232960); // Set it to 0 instead of $FF for proper formatting...
        diskType[driveNum] = DT_DOS33;
        strcpy(imageName[driveNum], "newblank.dsk");
+       writeProtected[driveNum] = false;
 SpawnMessage("New blank image inserted in drive %u...", driveNum);
 }
 
@@ -201,6 +203,10 @@ void FloppyDrive::SwapImages(void)
        uint8 imageDirtyTmp = imageDirty[0];
        imageDirty[0] = imageDirty[1];
        imageDirty[1] = imageDirtyTmp;
+
+       uint8 writeProtectedTmp = writeProtected[0];
+       writeProtected[0] = writeProtected[1];
+       writeProtected[1] = writeProtectedTmp;
 SpawnMessage("Drive 0: %s...", imageName[0]);
 }
 
@@ -515,17 +521,45 @@ void FloppyDrive::EjectImage(uint8 driveNum/*= 0*/)
        diskSize[driveNum] = 0;
        diskType[driveNum] = DT_UNKNOWN;
        imageDirty[driveNum] = false;
+       writeProtected[driveNum] = false;
        imageName[driveNum][0] = 0;                     // Zero out filenames
        memset(nybblizedImage[driveNum], 0xFF, 232960); // Doesn't matter if 00s or FFs...
-
 }
 
 bool FloppyDrive::DriveIsEmpty(uint8 driveNum/*= 0*/)
 {
+       if (driveNum > 1)
+       {
+               WriteLog("FLOPPY: Attempted DriveIsEmtpy() for drive #%u!\n", driveNum);
+               return true;
+       }
+
        // This is kinda gay, but it works
        return (imageName[driveNum][0] == 0 ? true : false);
 }
 
+bool FloppyDrive::DiskIsWriteProtected(uint8 driveNum/*= 0*/)
+{
+       if (driveNum > 1)
+       {
+               WriteLog("FLOPPY: Attempted DiskIsWriteProtected() for drive #%u!\n", driveNum);
+               return true;
+       }
+
+       return writeProtected[driveNum];
+}
+
+void FloppyDrive::SetWriteProtect(bool state, uint8 driveNum/*= 0*/)
+{
+       if (driveNum > 1)
+       {
+               WriteLog("FLOPPY: Attempted set write protect for drive #%u!\n", driveNum);
+               return;
+       }
+
+       writeProtected[driveNum] = state;
+}
+
 
 // Memory mapped I/O functions
 
@@ -597,8 +631,13 @@ Which we now do. :-)
 */
        if (ioMode == IO_MODE_WRITE && (latchValue & 0x80))
        {
-               nybblizedImage[activeDrive][(track * 6656) + currentPos] = latchValue;
-               imageDirty[activeDrive] = true;
+               // Does it behave like this?
+#warning "Write protection kludged in--investigate real behavior!"
+               if (!writeProtected[activeDrive])
+               {
+                       nybblizedImage[activeDrive][(track * 6656) + currentPos] = latchValue;
+                       imageDirty[activeDrive] = true;
+               }
        }
 
        uint8 diskByte = nybblizedImage[activeDrive][(track * 6656) + currentPos];
index 7fe310f2a4951bc5d01f34990d8a37907bb8c701..f92a99b9b3b6e3ef66789443ef9dcc8da62045b7 100755 (executable)
@@ -30,6 +30,8 @@ class FloppyDrive
                const char * GetImageName(uint8 driveNum = 0);
                void EjectImage(uint8 driveNum = 0);
                bool DriveIsEmpty(uint8 driveNum = 0);
+               bool DiskIsWriteProtected(uint8 driveNum = 0);
+               void SetWriteProtect(bool, uint8 driveNum = 0);
 
                // I/O functions ($C0Ex accesses)
 
@@ -53,6 +55,7 @@ class FloppyDrive
                uint32 diskSize[2];
                uint8 diskType[2];
                bool imageDirty[2];
+               bool writeProtected[2];
                uint8 motorOn;
                uint8 activeDrive;
                uint8 ioMode;
index be7caaad04b342841eec2cc5085c85ee436c7fb9..4a77a13f6e82aff37ffaf0520a464b31cf157c0c 100755 (executable)
@@ -255,3 +255,15 @@ void Button::CheckStateAndRedrawIfNeeded(void)
        if (activated != activatedSave || clicked != clickedSave || inside != insideSave)
                Draw();
 }
+
+void Button::SetText(std::string s)
+{
+       // Need to create backgrounds before we do this stuff...
+       SDL_FillRect(buttonUp, NULL, bgColor);
+       SDL_FillRect(buttonDown, NULL, fgColor);
+       SDL_FillRect(buttonHover, NULL, bgColorHL);
+
+       DrawStringTrans(buttonUp, GetFontWidth(), 0, fgColor, s.c_str());
+       DrawStringTrans(buttonDown, GetFontWidth(), 0, fgColor, s.c_str());
+       DrawStringTrans(buttonHover, GetFontWidth(), 0, fgColorHL, s.c_str());
+}
index 0f73b7bad6d6c4942b7436eb4d43085c2f73b4d9..bd0cc7c75838b0a65fd332fa33796fd7b7fadb77 100755 (executable)
@@ -31,6 +31,7 @@ class Button: public Element
                bool ButtonClicked(void);
                void SaveStateVariables(void);
                void CheckStateAndRedrawIfNeeded(void);
+               void SetText(std::string s);
 
        protected:
                bool activated, clicked, inside;
index 5029372a91705edb49562f12a4dea96fb51a6e78..25e7537e16f59176c1797b443081539c3e2725b4 100644 (file)
@@ -75,12 +75,25 @@ DiskWindow::DiskWindow(FloppyDrive * fdp, uint32 x/*= 0*/, uint32 y/*= 0*/): Win
 
        newDisk1 = new Button(4, 132, "NewDisk1", this);
        newDisk2 = new Button(4, 152, "NewDisk2", this);
-       swap = new Button(4, 176, "Swap Disks", this);
+       writeProtect1 = new Button(4, 176, "WriteProt1", this);
+       writeProtect2 = new Button(4, 196, "WriteProt2", this);
+       swap = new Button(4, 220, "Swap Disks", this);
+//Weird... It's showing an initial state of write-protected even though
+//the constructor of FloppyDrive sets it to false!
+#warning "Write protection state is wrong. !!! FIX !!!"
+       writeProtect1->SetText((floppyDrive->DiskIsWriteProtected(0) ? "write" : "no write"));
+       writeProtect2->SetText((floppyDrive->DiskIsWriteProtected(1) ? "write" : "no write"));
 
        AddElement(newDisk1);
        AddElement(newDisk2);
+       AddElement(writeProtect1);
+       AddElement(writeProtect2);
        AddElement(swap);
 
+       // In spite of this, it's still blanking out the background...
+       // Actually, come to think of it, it's got a stale backbuffer when
+       // the GUI comes in again... !!! FIX !!!
+#warning !!! FIX !!!
        SetBackgroundDraw(false);
 //     CreateBackstore();
        Draw(); // Can we do this in the constructor??? Mebbe.
@@ -206,6 +219,17 @@ void DiskWindow::Notify(Element * e)
                {
                        // Put up a warning and give user a chance to exit this potentially
                        // disastrous action
+// Now, how to do this? Notify() isn't asynchronous...
+// And until we return from here, there is no GUI main loop to show any dialogs!
+/*
+what you could do is like this way:
+
+-- have a callback function for after the intermediate window gets dismissed
+-- have a separate GUI thread
+-- have a 2nd GUI object and run that loop to completion
+
+
+*/
                }
 
                floppyDrive->SaveImage(0);
@@ -234,6 +258,25 @@ void DiskWindow::Notify(Element * e)
                name2->SetText(floppyDrive->GetImageName(1));
                Draw();
        }
+       else if (e == writeProtect1)
+       {
+               floppyDrive->SetWriteProtect((floppyDrive->DiskIsWriteProtected(0) ? false : true), 0);
+//                     floppyDrive->SetWriteProtect(false, 0);
+//             else
+//                     floppyDrive->SetWriteProtect(true, 0);
+
+               // Housekeeping
+               writeProtect1->SetText((floppyDrive->DiskIsWriteProtected(0) ? "write" : "no write"));
+               Draw();
+       }
+       else if (e == writeProtect2)
+       {
+               floppyDrive->SetWriteProtect((floppyDrive->DiskIsWriteProtected(1) ? false : true), 1);
+
+               // Housekeeping
+               writeProtect2->SetText((floppyDrive->DiskIsWriteProtected(1) ? "write" : "no write"));
+               Draw();
+       }
        else if (e == swap)
        {
                floppyDrive->SwapImages();
index 9d4541aedf159fafecca7beacdc2bd11ff076fde..8ef6272bb820474244b3cd9097b0d1ffc93438f1 100644 (file)
@@ -35,7 +35,8 @@ class DiskWindow: public Window
 //             uint16 cbWidth, cbHeight;
 //             SDL_Surface * cbUp, * cbDown, * cbHover;
                Text * name1, * name2;
-               Button * load1, * load2, * eject1, * eject2, * newDisk1, * newDisk2, * swap;
+               Button * load1, * load2, * eject1, * eject2,
+                       * newDisk1, * newDisk2, * swap, * writeProtect1, * writeProtect2;
 };
 
 #endif // __DISKWINDOW_H__