diff --git a/bin/driver.bin b/bin/driver.bin index b5551d7..fa5ccab 100755 Binary files a/bin/driver.bin and b/bin/driver.bin differ diff --git a/bin/rom.bin b/bin/rom.bin index cbc5ab7..f4124ec 100755 Binary files a/bin/rom.bin and b/bin/rom.bin differ diff --git a/rdisk.c b/rdisk.c index 36b50f3..5affd63 100644 --- a/rdisk.c +++ b/rdisk.c @@ -39,7 +39,7 @@ const long RDiskIcon[65] = { 0b10001111001111000001111001111001, 0b11000000000000000000000000000001, 0b01010101010101011101010101010101, - 0b01111111111111111111111111111111, + 0b01111111111111110111111111111111, 0b00000000000000000000000000000000, 0b00000000000000000000000000000000, // Mask @@ -78,28 +78,19 @@ const long RDiskIcon[65] = { 0 }; -// Switch to 24-bit mode and copy. Call this with -// PC==0x408XXXXX, not PC==0x008XXXXX -void RDiskCopy24(char *sourcePtr, char *destPtr, unsigned long byteCount) { +// Switch to 24-bit mode and copy +void RDiskCopy24(Ptr sourcePtr, Ptr destPtr, unsigned long byteCount) { char mode = true32b; SwapMMUMode(&mode); BlockMove(sourcePtr, destPtr, byteCount); SwapMMUMode(&mode); } -typedef struct RDiskStorage_s { - DrvSts2 drvsts; - unsigned long init_done; - char *ramdisk; - Ptr ramdisk_alloc; - char ramdisk_valid; -} RDiskStorage_t; - #pragma parameter __D0 RDiskOpen(__A0, __A1) OSErr RDiskOpen(IOParamPtr p, DCtlPtr d) { DrvQElPtr dq; - DrvSts2 *status; int drvNum; + Ptr copy24; RDiskStorage_t *c; // Do nothing if already opened @@ -114,6 +105,11 @@ OSErr RDiskOpen(IOParamPtr p, DCtlPtr d) { // Allocate storage struct d->dCtlStorage = NewHandleSysClear(sizeof(RDiskStorage_t)); if (!d->dCtlStorage) { return openErr; } + + // Allocate copy function buffer and copy RDiskCopy24 to it + copy24 = NewPtrSys(64); + if (!copy24) { DisposeHandle(d->dCtlStorage); return openErr; } + BlockMove(&RDiskCopy24, copy24, 64); // Lock our storage struct and get master pointer HLock(d->dCtlStorage); @@ -122,17 +118,15 @@ OSErr RDiskOpen(IOParamPtr p, DCtlPtr d) { // Initialize storage struct fields c->init_done = 0; c->ramdisk = NULL; - c->ramdisk_alloc = NULL; - c->ramdisk_valid = 0; + c->copy24 = (RDiskCopy_t)copy24; // Set drive status - status = &c->drvsts; - status->writeProt = 0xF0; - status->diskInPlace = 0x08; - status->dQDrive = drvNum; - status->dQRefNum = d->dCtlRefNum; - status->driveSize = (RDiskSize / 512) & 0xFFFF; - status->driveS1 = ((RDiskSize / 512) & 0xFFFF0000) >> 16; + c->status.writeProt = -1; + c->status.diskInPlace = 0x08; + c->status.dQDrive = drvNum; + c->status.dQRefNum = d->dCtlRefNum; + c->status.driveSize = RDiskSize / 512; + c->status.driveS1 = (RDiskSize / 512) >> 16; // Set driver flags? /* d->dCtlFlags |= dReadEnableMask | dWritEnableMask | @@ -140,7 +134,7 @@ OSErr RDiskOpen(IOParamPtr p, DCtlPtr d) { dNeedLockMask; // 0x4F */ // Add drive to drive queue and return - RDiskAddDrive(status->dQRefNum, drvNum, (DrvQElPtr)&status->qLink); + RDiskAddDrive(c->status.dQRefNum, drvNum, (DrvQElPtr)&c->status.qLink); return noErr; } @@ -151,61 +145,64 @@ OSErr RDiskInit(IOParamPtr p, DCtlPtr d, RDiskStorage_t *c) { c->init_done = 1; // Read PRAM - RDiskReadXPRAM(1, 4, &startup); - RDiskReadXPRAM(1, 5, &ram); + /*RDiskReadXPRAM(1, 4, &startup); + RDiskReadXPRAM(1, 5, &ram);*/ // Either enable ROM disk or remove ourselves from the drive queue - if (startup || RDiskIsRPressed()) { // If ROM disk boot set in PRAM or R pressed,*/ + if (/*startup || */RDiskIsRPressed()) { // If ROM disk boot set in PRAM or R pressed,*/ // Set ROM disk attributes - c->drvsts.writeProt = -1; // Set write protected - // Clear disk fields (even though we used NewHandleSysClear) - c->ramdisk = NULL; - c->ramdisk_alloc = NULL; - c->ramdisk_valid = 0; + c->status.writeProt = -1; // Set write protected // If RAM disk set in PRAM or A pressed, enable RAM disk - if (ram || RDiskIsAPressed()) { - unsigned long minBufPtr, newBufPtr; - // Clearing write protect marks RAM disk enabled - c->drvsts.writeProt = 0; - // Compute if there is enough high memory - minBufPtr = ((unsigned long)*MemTop / 2) + 1024; - newBufPtr = (unsigned long)*BufPtr - RDiskSize; - // If in 32-bit mode and there is enough high memory, set ramdisk pointer now - if (*MMU32bit & newBufPtr > minBufPtr && (unsigned long)*BufPtr > newBufPtr) { - // Allocate RAM disk buffer by lowering BufPtr - *BufPtr = (Ptr)newBufPtr; - // Set RAM disk buffer pointer. Defer copying until accRun - // Don't set ramdisk_alloc because there is nothing to free. - c->ramdisk = *BufPtr; + if (/*ram || */RDiskIsAPressed()) { + // Try to allocate RAM disk buffer + if (*MMU32bit) { // 32-bit mode + unsigned long minBufPtr, newBufPtr; + // Compute if there is enough high memory + minBufPtr = ((unsigned long)*MemTop / 2) + 1024; + newBufPtr = (unsigned long)*BufPtr - RDiskSize; + if (newBufPtr > minBufPtr && (unsigned long)*BufPtr > newBufPtr) { + // Allocate RAM disk buffer by lowering BufPtrå + *BufPtr = (Ptr)newBufPtr; + // Set RAM disk buffer pointer. + c->ramdisk = *BufPtr; + // Copy ROM disk image to RAM disk + BlockMove(RDiskBuf, c->ramdisk, RDiskSize); + // Clearing write protect marks RAM disk enabled + c->status.writeProt = 0; + } else { + // Not enough memory so stay write-only + c->status.writeProt = -1; + } + } else { // 24-bit mode + // Put RAM disk just past 8MB + c->ramdisk = (char*)(8 * 1024 * 1024); // Copy ROM disk image to RAM disk - BlockMove(RDiskBuf, c->ramdisk, RDiskSize); - c->ramdisk_valid = 1; - } else { - // Enable accRun to allocate and copy later - d->dCtlFlags |= dNeedTimeMask; - d->dCtlDelay = 0x10; + ((RDiskCopy_t)StripAddress(c->copy24))( + RDiskBuf, StripAddress(c->ramdisk), RDiskSize); + // Clearing write protect marks RAM disk enabled + c->status.writeProt = 0; + //FIXME: what if we don't have enough RAM? + // Will this wrap around and overwrite low memory? + // That's not the worst, since the system would just crash, + // but it would be better to switch to read-only status } } return noErr; } else { // Otherwise if R not held down and ROM boot not set in PRAM, + QHdrPtr head = GetDrvQHdr(); + DrvQElPtr dq = (DrvQElPtr)head->qHead; // Remove our driver from the drive queue - DrvQElPtr dq; - QHdrPtr QHead = DrvQHdr; - - // Loop through entire drive queue, searching for our device or stopping at the end. - dq = (DrvQElPtr)QHead->qHead; - while ((dq != (DrvQElPtr)(QHead->qTail)) && + // Loop through entire drive queue, searching for our device + while ((dq != (DrvQElPtr)(head->qTail)) && (dq->dQRefNum != d->dCtlRefNum)) { dq = (DrvQElPtr)(dq->qLink); } // If we found our driver, remove it from the queue if (dq->dQRefNum == d->dCtlRefNum) { - Dequeue((QElemPtr)dq, QHead); - if (c->ramdisk_alloc) { DisposePtr(c->ramdisk_alloc); } + Dequeue((QElemPtr)dq, head); DisposeHandle(d->dCtlStorage); } d->dCtlStorage = NULL; - // Return disk offline error return offLinErr; } @@ -217,7 +214,6 @@ OSErr RDiskPrime(IOParamPtr p, DCtlPtr d) { char cmd; char *disk; long offset; - RDiskCopy_t copy24 = &RDiskCopy24; // Return disk offline error if dCtlStorage null if (!d->dCtlStorage) { return offLinErr; } @@ -231,7 +227,7 @@ OSErr RDiskPrime(IOParamPtr p, DCtlPtr d) { } // Get pointer to RAM or ROM disk buffer - disk = c->ramdisk && c->ramdisk_valid ? c->ramdisk : RDiskBuf; + disk = c->ramdisk ? c->ramdisk : RDiskBuf; // Add offset to buffer pointer according to positioning mode switch (p->ioPosMode & 0x000F) { case fsAtMark: offset = d->dCtlPosition; break; @@ -250,14 +246,14 @@ OSErr RDiskPrime(IOParamPtr p, DCtlPtr d) { if (cmd == aRdCmd) { // Read // Return immediately if verify operation requested //FIXME: follow either old (verify) or new (read uncached) convention - /*if (p->ioPosMode & rdVerifyMask) { + if (p->ioPosMode & rdVerifyMask) { return noErr; - }*/ + } // Read from disk into buffer. if (*MMU32bit) { BlockMove(disk, p->ioBuffer, p->ioReqCount); } - else { // 24-bit addressing - char *buffer = (char*)Translate24To32(StripAddress(p->ioBuffer)); - copy24(disk, buffer, p->ioReqCount); + else { + ((RDiskCopy_t)StripAddress(c->copy24))( + disk, StripAddress(p->ioBuffer), p->ioReqCount); } // Update count p->ioActCount = p->ioReqCount; @@ -266,12 +262,12 @@ OSErr RDiskPrime(IOParamPtr p, DCtlPtr d) { return noErr; } else if (cmd == aWrCmd) { // Write // Fail if write protected or RAM disk buffer not set up - if (c->drvsts.writeProt || !c->ramdisk || !c->ramdisk_valid) { return wPrErr; } + if (c->status.writeProt || !c->ramdisk) { return wPrErr; } // Write from buffer into disk. - if (*MMU32bit) { BlockMove((char*)p->ioBuffer, disk, p->ioReqCount); } - else { // 24-bit addressing - char *buffer = (char*)Translate24To32(StripAddress(p->ioBuffer)); - copy24(buffer, disk, p->ioReqCount); + if (*MMU32bit) { BlockMove(p->ioBuffer, disk, p->ioReqCount); } + else { + ((RDiskCopy_t)StripAddress(c->copy24))( + StripAddress(p->ioBuffer), disk, p->ioReqCount); } // Update count and position/offset p->ioActCount = p->ioReqCount; @@ -282,47 +278,6 @@ OSErr RDiskPrime(IOParamPtr p, DCtlPtr d) { //FIXME: Should we fail if cmd isn't read or write? } -OSErr RDiskAccRun(CntrlParamPtr p, DCtlPtr d, RDiskStorage_t *c) { - // Disable accRun - d->dCtlDelay = 0; - d->dCtlFlags &= ~dNeedTimeMask; - RDiskBreak(); - - // Set RAM disk buffer if our disk is writable and no RAM buffer set - if (!c->drvsts.writeProt && !c->ramdisk) { - if (*MMU32bit) { // If in 32-bit mode, (implies System 7) - // Allocate RAM disk buffer on system heap (System 7 can resize system heap) - c->ramdisk_alloc = NewPtrSys(RDiskSize); - if (c->ramdisk_alloc) { // If allocation successful, - // Set RAM disk buffer pointer - c->ramdisk = c->ramdisk_alloc; - } - } else { // Otherwise in 24-bit mode, - // Put buffer just beyond the 8 MB of RAM which is usable in 24-bit mode - c->ramdisk = (char*)(8 * 1024 * 1024); - //FIXME: what if we don't have enough RAM? - // Will this wrap around and overwrite low memory? - // That's not the worst, since the system would just crash, - // but it would be better to switch to read-only status - } - // Clear ramdisk_valid just in case, since ROM disk not yet copied to RAM disk - c->ramdisk_valid = 0; - } - - if (!c->ramdisk) { // If RAM disk buffer couldn't be allocated, - // Mark write protected if we couldn't allocate RAM buffer? - c->drvsts.writeProt = -1; - } else if (c->ramdisk && !c->ramdisk_valid) { // Else if buffer exists but is not valid, - RDiskCopy_t copy24 = RDiskCopy24; - // Copy ROM disk to RAM disk buffer if not yet copied - if (*MMU32bit) { BlockMove(RDiskBuf, c->ramdisk, RDiskSize); } - else { copy24(RDiskBuf, c->ramdisk, RDiskSize); } - c->ramdisk_valid = 1; - } - - return noErr; // Always return success -} - #pragma parameter __D0 RDiskControl(__A0, __A1) OSErr RDiskControl(CntrlParamPtr p, DCtlPtr d) { RDiskStorage_t *c; @@ -361,7 +316,7 @@ OSErr RDiskClose(IOParamPtr p, DCtlPtr d) { // If dCtlStorage not null, dispose of it and its contents if (!d->dCtlStorage) { return noErr; } RDiskStorage_t *c = *(RDiskStorage_t**)d->dCtlStorage; - if (c->ramdisk_alloc) { DisposePtr(c->ramdisk_alloc); } + if (c->copy24) { DisposePtr((Ptr)c->copy24); } HUnlock(d->dCtlStorage); DisposeHandle(d->dCtlStorage); d->dCtlStorage = NULL; diff --git a/rdisk.h b/rdisk.h index aa43b96..213e4e6 100644 --- a/rdisk.h +++ b/rdisk.h @@ -7,9 +7,8 @@ #define MemTop ((Ptr*)0x108) #define MMU32bit ((char*)0xCB2) #define JIODone ((char*)0x8FC) -#define DrvQHdr ((QHdrPtr)0x308) -#pragma parameter __D0 RDReadXPRAM(__D0, __D1, __A0) +#pragma parameter __D0 RDiskReadXPRAM(__D0, __D1, __A0) OSErr RDiskReadXPRAM(short numBytes, short whichByte, void *dest) = {0x4840, 0x3001, 0xA051}; // Other definition of RDiskAddDrive with register calling convention @@ -34,6 +33,13 @@ inline char RDiskIsAPressed() { return *((char*)0x174) & 0x01; } void RDiskBreak() = { 0xA9FF }; -typedef void (*RDiskCopy_t)(char *, char *, unsigned long); +typedef void (*RDiskCopy_t)(Ptr, Ptr, unsigned long); + +typedef struct RDiskStorage_s { + DrvSts2 status; + unsigned long init_done; + char *ramdisk; + RDiskCopy_t copy24; +} RDiskStorage_t; #endif