From: Shamus Hammons Date: Wed, 4 Feb 2009 14:19:00 +0000 (+0000) Subject: Added infrastructure to handle write protecting floppy disks X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a3edd967566ede2c3d58d459b115acc94b13b329;p=apple2 Added infrastructure to handle write protecting floppy disks --- diff --git a/apple2.cfg b/apple2.cfg index 2762779..bd3016b 100755 --- a/apple2.cfg +++ b/apple2.cfg @@ -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 diff --git a/src/floppy.cpp b/src/floppy.cpp index 56ea414..d403714 100755 --- a/src/floppy.cpp +++ b/src/floppy.cpp @@ -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]; diff --git a/src/floppy.h b/src/floppy.h index 7fe310f..f92a99b 100755 --- a/src/floppy.h +++ b/src/floppy.h @@ -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; diff --git a/src/gui/button.cpp b/src/gui/button.cpp index be7caaa..4a77a13 100755 --- a/src/gui/button.cpp +++ b/src/gui/button.cpp @@ -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()); +} diff --git a/src/gui/button.h b/src/gui/button.h index 0f73b7b..bd0cc7c 100755 --- a/src/gui/button.h +++ b/src/gui/button.h @@ -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; diff --git a/src/gui/diskwindow.cpp b/src/gui/diskwindow.cpp index 5029372..25e7537 100644 --- a/src/gui/diskwindow.cpp +++ b/src/gui/diskwindow.cpp @@ -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(); diff --git a/src/gui/diskwindow.h b/src/gui/diskwindow.h index 9d4541a..8ef6272 100644 --- a/src/gui/diskwindow.h +++ b/src/gui/diskwindow.h @@ -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__