diff --git a/Makefile b/Makefile index e7ad809..fedc7c9 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,7 @@ obj/entry_rel.sym: obj obj/entry.o obj/rdisk.o: rdisk.c obj - $(CC) -c -O1 $< -o $@ + $(CC) -c -Os $< -o $@ obj/rdisk.s: obj obj/rdisk.o $(OBJDUMP) -d obj/rdisk.o > $@ diff --git a/RDisk1M5-6.dsk b/RDisk1M5-6.dsk index a5655d6..0a1e62b 100644 Binary files a/RDisk1M5-6.dsk and b/RDisk1M5-6.dsk differ diff --git a/baserom.bin b/baserom.bin index 29aaac9..12c1e51 100755 Binary files a/baserom.bin and b/baserom.bin differ diff --git a/bin/driver.bin b/bin/driver.bin index db6de75..ee4e7a6 100755 Binary files a/bin/driver.bin and b/bin/driver.bin differ diff --git a/bin/rom.bin b/bin/rom.bin index ed4754b..cbba136 100755 Binary files a/bin/rom.bin and b/bin/rom.bin differ diff --git a/entry.s b/entry.s index c513a8f..a64a11b 100644 --- a/entry.s +++ b/entry.s @@ -56,11 +56,5 @@ ImmedRTS: rts Queued: - tst.w %D0 - ble.b MyIODone - clr.w %D0 - rts - -MyIODone: move.l JIODone, -(%SP) rts diff --git a/rdisk.c b/rdisk.c index b2c69c8..3f2f3e0 100644 --- a/rdisk.c +++ b/rdisk.c @@ -8,7 +8,90 @@ #include "rdisk.h" -const char RDiskIcon[285] = { +#ifdef RDISK_COMPRESS_ICON +#include +const char const RDiskIconCompressed[92] = { + -1 * (80 - 1), 0b00000000, /* + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, */ + -1 * (4 - 1), 0b11111111, /* + 0b11111111, 0b11111111, 0b11111111, 0b11111111, */ + (40 - 1), + 0b11111111, 0b11111111, 0b11111111, 0b11111111, + 0b10000000, 0b00000000, 0b00000000, 0b00000001, + 0b10001111, 0b00011110, 0b00111100, 0b01111001, + 0b10001001, 0b00010010, 0b00100100, 0b01001001, + 0b10001001, 0b00010010, 0b00100100, 0b01001001, + 0b10001001, 0b00010010, 0b00100100, 0b01001001, + 0b10001111, 0b00011110, 0b00111100, 0b01111001, + 0b11000000, 0b00000000, 0b00000000, 0b00000001, + 0b01010101, 0b01010101, 0b11010101, 0b01010101, + 0b01111111, 0b11111111, 0b01111111, 0b11111111, + -1 * (8 - 1), 0b00000000, /* + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, */ + + -1 * (80 - 1), 0b00000000, /* + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, */ + -1 * (32 - 1), 0b11111111, /* + 0b11111111, 0b11111111, 0b11111111, 0b11111111, + 0b11111111, 0b11111111, 0b11111111, 0b11111111, + 0b11111111, 0b11111111, 0b11111111, 0b11111111, + 0b11111111, 0b11111111, 0b11111111, 0b11111111, + 0b11111111, 0b11111111, 0b11111111, 0b11111111, + 0b11111111, 0b11111111, 0b11111111, 0b11111111, + 0b11111111, 0b11111111, 0b11111111, 0b11111111, + 0b11111111, 0b11111111, 0b11111111, 0b11111111, */ + (8 - 1), + 0b01111111, 0b11111111, 0b11111111, 0b11111111, + 0b01111111, 0b11111111, 0b11111111, 0b11111111, + -1 * (8 - 1), 0b00000000, /* + 0b00000000, 0b00000000, 0b00000000, 0b00000000, + 0b00000000, 0b00000000, 0b00000000, 0b00000000, */ + (29 - 1), + 27, 'G', 'a', 'r', 'r', 'e', 't', 't', '\'', 's', ' ', + 'W', 'o', 'r', 'k', 's', 'h', 'o', 'p', ' ', + 'R', 'O', 'M', ' ', 'D', 'i', 's', 'k', 0 +}; +#else +const char const RDiskIcon[285] = { // Icon 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, @@ -79,35 +162,38 @@ const char RDiskIcon[285] = { 'W', 'o', 'r', 'k', 's', 'h', 'o', 'p', ' ', 'R', 'O', 'M', ' ', 'D', 'i', 's', 'k', 0 }; +#endif -static void RDiskDecodeSettings(RDiskStorage_t *c, char *enable, char* boot, char* mount, char* ram) { - char rKey, aKey, legacy_startup, legacy_ram; - // Read PRAM and keys - RDiskReadXPRAM(1, 4, &legacy_startup); - RDiskReadXPRAM(1, 5, &legacy_ram); - rKey = RDiskIsRPressed(); - aKey = RDiskIsAPressed(); +static void RDiskDecodeSettings(RDiskStorage_t *c, Ptr unmount, Ptr mount, Ptr ram) { // Decode settings if (c->postBoot) { - *enable = 1; - *boot = 1; // Boot set so first access works + *unmount = 0; *mount = 1; *ram = 0; - } else if (rKey) { // R boots from ROM disk - *enable = 1; - *boot = 1; + } else if (RDiskIsRPressed()) { // R boots from ROM disk + *unmount = 0; *mount = 0; - *ram = aKey; // A enables RAM disk - } else if (legacy_startup) { - *enable = 1; - *boot = (legacy_startup & 0xFD) && (legacy_startup != 0xFD); - *mount = !*boot && legacy_startup & 0x02; - *ram = legacy_ram; + *ram = RDiskIsAPressed(); // A enables RAM disk } else { - *enable = 0; - *boot = 0; - *mount = 0; - *ram = 0; + // Read PRAM + char legacy_startup, legacy_ram; + RDiskReadXPRAM(1, 4, &legacy_startup); + RDiskReadXPRAM(1, 5, &legacy_ram); + if (legacy_startup == 1) { + *unmount = 0; + *mount = 0; + *ram = legacy_ram; + } else if (legacy_startup == 2 || legacy_startup == 3 || + legacy_startup == 4 || legacy_startup == 5 || + legacy_startup == 6 || legacy_startup == 7) { + *unmount = 1; + *mount = 1; + *ram = legacy_ram & 1; + } else { + *unmount = 1; + *mount = 0; + *ram = 0; + } } } @@ -119,91 +205,72 @@ void RDiskCopy24(Ptr sourcePtr, Ptr destPtr, unsigned long byteCount) { SwapMMUMode(&mode); } +// Figure out the first available drive number >= 5 +static int RDiskFindDrvNum() { + DrvQElPtr dq; + int drvNum = 5; + for (dq = (DrvQElPtr)(GetDrvQHdr())->qHead; dq; dq = (DrvQElPtr)dq->qLink) { + if (dq->dQDrive >= drvNum) { drvNum = dq->dQDrive + 1; } + } + return drvNum; +} + #pragma parameter __D0 RDiskOpen(__A0, __A1) OSErr RDiskOpen(IOParamPtr p, DCtlPtr d) { - DrvQElPtr dq; int drvNum; - Ptr copy24; RDiskStorage_t *c; + char legacy_startup, legacy_ram; // Do nothing if already opened if (d->dCtlStorage) { return noErr; } - // Figure out first available drive number - drvNum = 1; - for (dq = (DrvQElPtr)(GetDrvQHdr())->qHead; dq; dq = (DrvQElPtr)dq->qLink) { - if (dq->dQDrive >= drvNum) { drvNum = dq->dQDrive + 1; } - } - // 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); c = *(RDiskStorage_t**)d->dCtlStorage; - // Initialize storage struct fields - //c->initialized = 0; - //c->removed = 0; - //c->postBoot = 0; - //c->ramdisk = NULL; - c->copy24 = (RDiskCopy_t)copy24; + // Find first available drive number + drvNum = RDiskFindDrvNum(); // Set drive status - c->status.writeProt = -1; - c->status.diskInPlace = 8; // 8 means nonejectable disk + c->status.track = 0; + c->status.writeProt = -1; // nonzero is write protected + c->status.diskInPlace = 8; // 8 is nonejectable disk + c->status.installed = 1; // drive installed + c->status.sides = 0; // drive installed + c->status.qType = 1; c->status.dQDrive = drvNum; + c->status.dQFSID = 0; c->status.dQRefNum = d->dCtlRefNum; c->status.driveSize = RDiskSize / 512; c->status.driveS1 = (RDiskSize / 512) >> 16; - // Set driver flags - /*d->dCtlFlags |= dReadEnableMask | dWritEnableMask | - dCtlEnableMask | dStatEnableMask | - dNeedLockMask;*/ // 0x4F + #ifdef RDISK_COMPRESS_ICON + // Decompress icon + char *src = &RDiskIconCompressed[0]; + char *dst = &c->icon[0]; + UnpackBits(&src, &dst, 285); + #endif // Add drive to drive queue and return RDiskAddDrive(c->status.dQRefNum, drvNum, (DrvQElPtr)&c->status.qLink); return noErr; } -static OSErr RDiskInit(IOParamPtr p, DCtlPtr d, RDiskStorage_t *c) { - char rdiskEN, mountEN, bootEN, ramEN; +static void RDiskInit(IOParamPtr p, DCtlPtr d, RDiskStorage_t *c) { + char unmountEN, mountEN, ramEN; // Mark init done c->initialized = 1; // Decode settings - RDiskDecodeSettings(c, &rdiskEN, &bootEN, &mountEN, &ramEN); + RDiskDecodeSettings(c, &unmountEN, &mountEN, &ramEN); - // If ROM disk not enabled, remove drive from drive queue - if (!rdiskEN) { - QHdrPtr head = GetDrvQHdr(); - DrvQElPtr dq = (DrvQElPtr)head->qHead; - // Remove our drive from the system drive queue - // Loop through entire drive queue, searching for our deive - while ((dq != (DrvQElPtr)(head->qTail)) && - (dq->dQRefNum != d->dCtlRefNum)) { - dq = (DrvQElPtr)(dq->qLink); - } - // If we found our drive, remove it from the queue - if (dq->dQRefNum == d->dCtlRefNum) { - Dequeue((QElemPtr)dq, head); - } - // Mark drive removed and offline - c->removed = 1; - c->status.diskInPlace = 0; // 0 means no disk in drive - return offLinErr; - } - - // If RAM disk enabled, try to allocate RAM disk buffer - if (ramEN) { + // If RAM disk enabled, try to allocate RAM disk buffer if not already + if (ramEN & !c->ramdisk) { if (*MMU32bit) { // 32-bit mode unsigned long minBufPtr, newBufPtr; // Compute if there is enough high memory @@ -220,11 +287,12 @@ static OSErr RDiskInit(IOParamPtr p, DCtlPtr d, RDiskStorage_t *c) { c->status.writeProt = 0; } } else { // 24-bit mode + // Get address of copy24 routine + RDiskCopy_t copy24 = (RDiskCopy_t)RDiskCopy24; // Put RAM disk just past 8MB - c->ramdisk = (char*)(8 * 1024 * 1024); + c->ramdisk = (Ptr)(8 * 1024 * 1024); // Copy ROM disk image to RAM disk - ((RDiskCopy_t)StripAddress(c->copy24))( - RDiskBuf, StripAddress(c->ramdisk), RDiskSize); + copy24(RDiskBuf, c->ramdisk, RDiskSize); // Clearing write protect marks RAM disk enabled c->status.writeProt = 0; //FIXME: what if we don't have enough RAM? @@ -234,133 +302,125 @@ static OSErr RDiskInit(IOParamPtr p, DCtlPtr d, RDiskStorage_t *c) { } } - // If boot disabled... - if (!bootEN) { - // Set drive offline - c->status.diskInPlace = 0; // 0 means no disk in drive - // Enable accRun to post disk inserted event if mount enabled - if (mountEN) { - d->dCtlDelay = 150; - d->dCtlFlags |= dNeedTimeMask; - } - return offLinErr; + // Unmount if not booting from ROM disk + if (unmountEN) { + c->status.diskInPlace = 0; // 0 == no disk in drive } - return noErr; + // If mount enabled, enable accRun to post disk inserted event later + if (mountEN) { + d->dCtlFlags |= dNeedTimeMask; // Enable accRun + d->dCtlDelay = 150; // Set accRun delay (150 ticks is 2.5 sec.) + } } #pragma parameter __D0 RDiskPrime(__A0, __A1) OSErr RDiskPrime(IOParamPtr p, DCtlPtr d) { RDiskStorage_t *c; char cmd; - char *disk; - long offset; + Ptr disk; // Return disk offline error if dCtlStorage null - if (!d->dCtlStorage) { return offLinErr; } + if (!d->dCtlStorage) { return notOpenErr; } // Dereference dCtlStorage to get pointer to our context c = *(RDiskStorage_t**)d->dCtlStorage; + + // Initialize if this is the first prime call + if (!c->initialized) { RDiskInit(p, d, c); } + // Return disk offline error if virtual disk not inserted if (!c->status.diskInPlace) { return offLinErr; } - // Initialize if this is the first prime call - if (!c->initialized) { - OSErr ret = RDiskInit(p, d, c); - if (ret != noErr) { return ret; } - } - // Get pointer to RAM or ROM disk buffer - 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; - case fsFromStart: offset = p->ioPosOffset; break; - case fsFromMark: offset = d->dCtlPosition + p->ioPosOffset; break; - default: break; - } - disk += offset; - // Bounds checking disabled - if (offset >= RDiskSize || p->ioReqCount >= RDiskSize || - offset + p->ioReqCount >= RDiskSize) { return posErr; } + disk = (c->ramdisk ? c->ramdisk : RDiskBuf) + d->dCtlPosition; + // Bounds checking + if (d->dCtlPosition >= RDiskSize || p->ioReqCount >= RDiskSize || + d->dCtlPosition + p->ioReqCount >= RDiskSize) { return paramErr; } // Service read or write request cmd = p->ioTrap & 0x00FF; if (cmd == aRdCmd) { // Read - // Return immediately if verify operation requested - //FIXME: follow either old (verify) or new (read uncached) convention - if (p->ioPosMode & rdVerifyMask) { - return noErr; - } // Read from disk into buffer. if (*MMU32bit) { BlockMove(disk, p->ioBuffer, p->ioReqCount); } else { - ((RDiskCopy_t)StripAddress(c->copy24))( - disk, StripAddress(p->ioBuffer), p->ioReqCount); + // Get address of copy24 routine and then copy + RDiskCopy_t copy24 = (RDiskCopy_t)RDiskCopy24; + copy24(disk, StripAddress(p->ioBuffer), p->ioReqCount); } - // Update count - p->ioActCount = p->ioReqCount; - d->dCtlPosition = offset + p->ioReqCount; - p->ioPosOffset = d->dCtlPosition; - return noErr; } else if (cmd == aWrCmd) { // Write // Fail if write protected or RAM disk buffer not set up if (c->status.writeProt || !c->ramdisk) { return wPrErr; } // Write from buffer into disk. if (*MMU32bit) { BlockMove(p->ioBuffer, disk, p->ioReqCount); } else { - ((RDiskCopy_t)StripAddress(c->copy24))( - StripAddress(p->ioBuffer), disk, p->ioReqCount); + // Get address of copy24 routine and then copy + RDiskCopy_t copy24 = (RDiskCopy_t)RDiskCopy24; + copy24(StripAddress(p->ioBuffer), disk, p->ioReqCount); } - // Update count and position/offset - p->ioActCount = p->ioReqCount; - d->dCtlPosition = offset + p->ioReqCount; - p->ioPosOffset = d->dCtlPosition; - return noErr; - } else { return noErr; } - //FIXME: Should we fail if cmd isn't read or write? + } else { return noErr; } //FIXME: Fail if cmd isn't read or write? + + // Update count and position/offset, then return + d->dCtlPosition += p->ioReqCount; + p->ioActCount = p->ioReqCount; + return noErr; } #pragma parameter __D0 RDiskControl(__A0, __A1) OSErr RDiskControl(CntrlParamPtr p, DCtlPtr d) { RDiskStorage_t *c; // Fail if dCtlStorage null - if (!d->dCtlStorage) { return controlErr; } + if (!d->dCtlStorage) { return notOpenErr; } // Dereference dCtlStorage to get pointer to our context c = *(RDiskStorage_t**)d->dCtlStorage; // Handle control request based on csCode switch (p->csCode) { - case 6: // Format - if (!c->status.diskInPlace || c->status.writeProt || !c->ramdisk) { + case kFormat: + if (!c->status.diskInPlace || c->status.writeProt || !c->ramdisk) { return controlErr; - } else { - char zero[64]; - for (int i = 0; i < sizeof(zero); i++) { zero[i] = 0; } - for (int i = 0; i < RDiskSize / 64; i++) { - if (*MMU32bit) { BlockMove(zero, c->ramdisk, sizeof(zero)); } - else { - ((RDiskCopy_t)StripAddress(c->copy24))( - StripAddress(zero), c->ramdisk, sizeof(zero)); - } + } + long zero[16]; + zero[0] = 0; + for (int i = 0; i < 256; i++) { + if (*MMU32bit) { BlockMove(zero, c->ramdisk, sizeof(zero)); } + else { + // Get address of copy24 routine and then copy + RDiskCopy_t copy24 = (RDiskCopy_t)RDiskCopy24; + copy24((Ptr)zero, c->ramdisk, sizeof(zero)); } } return noErr; - case 5: // Verify (after format) - if (!c->status.diskInPlace || c->status.writeProt || !c->ramdisk) { - return controlErr; - } else { return noErr; } + case kVerify: + if (!c->status.diskInPlace) { return controlErr; } + return noErr; + case killCode: + return noErr; + case kEject: + // "Reinsert" disk if ejected illegally + if (c->installed) { PostEvent(diskEvt, c->status.dQDrive); } + return controlErr; // Eject not allowed so return error case accRun: - // Disable accRun - d->dCtlFlags &= ~dNeedTimeMask; - // If drive present in drive queue, set drive online - if (!c->removed) { - c->status.diskInPlace = 8; // 8 means nonejectable disk - PostEvent(diskEvt, c->status.dQDrive); - } + d->dCtlFlags &= ~dNeedTimeMask; // Disable accRun + c->status.diskInPlace = 8; // 8 is nonejectable disk + PostEvent(diskEvt, c->status.dQDrive); // Post disk inserted event return noErr; - case 21: case 22: // Get icon - *(Ptr*)&p->csParam = (Ptr)&RDiskIcon; + case kDriveIcon: case kMediaIcon: // Get icon + #ifdef RDISK_COMPRESS_ICON + *(Ptr*)p->csParam = (Ptr)c->icon; + #else + *(Ptr*)p->csParam = (Ptr)RDiskIcon; + #endif return noErr; - case 128: + case kDriveInfo: + // high word (bytes 2 & 3) clear + // byte 1 = primary + fixed media + internal + // byte 0 = drive type (0x10 is RAM disk) / (0x11 is ROM disk) + if (c->status.writeProt) { *(long*)p->csParam = 0x00000410; } + else { *(long*)p->csParam = 0x00000411; } + return noErr; + case 24: // Return SCSI partition size + *(long*)p->csParam = RDiskSize / 512; + return noErr; + case 2351: // Enable post-boot mode c->postBoot = 1; return noErr; default: return controlErr; @@ -371,17 +431,14 @@ OSErr RDiskControl(CntrlParamPtr p, DCtlPtr d) { OSErr RDiskStatus(CntrlParamPtr p, DCtlPtr d) { RDiskStorage_t *c; // Fail if dCtlStorage null - if (!d->dCtlStorage) { return statusErr; } + if (!d->dCtlStorage) { return notOpenErr; } // Dereference dCtlStorage to get pointer to our context c = *(RDiskStorage_t**)d->dCtlStorage; // Handle status request based on csCode switch (p->csCode) { - case drvStsCode: + case kDriveStatus: BlockMove(*d->dCtlStorage, &p->csParam, sizeof(DrvSts2)); return noErr; - case 128: // Get size - *((long*)p->csParam) = RDiskSize; - return noErr; default: return statusErr; } } @@ -391,7 +448,6 @@ 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->copy24) { DisposePtr((Ptr)c->copy24); } HUnlock(d->dCtlStorage); DisposeHandle(d->dCtlStorage); d->dCtlStorage = NULL; diff --git a/rdisk.h b/rdisk.h index b0b7929..ffae652 100644 --- a/rdisk.h +++ b/rdisk.h @@ -35,31 +35,19 @@ void RDiskBreak() = { 0xA9FF }; typedef void (*RDiskCopy_t)(Ptr, Ptr, unsigned long); +//#define RDISK_COMPRESS_ICON typedef struct RDiskStorage_s { DrvSts2 status; char initialized; - char removed; - char postBoot; - char *ramdisk; - RDiskCopy_t copy24; -} RDiskStorage_t; - -/* - - -typedef void (*RDiskCopy_t)(Ptr, Ptr, unsigned long); -typedef void (*RDiskFormat_t)(Ptr); - -typedef struct RDiskStorage_s { - DrvSts2 status; - char initialized; - char removed; + char installed; char postBoot; Ptr ramdisk; - char copy24[64] __attribute__ ((aligned (4))) ; - char format24[64] __attribute__ ((aligned (4))) ; + #ifdef RDISK_COMPRESS_ICON + char icon[285]; + #endif } RDiskStorage_t; -*/ +#define PackBits_Repeat(count) ((-1) * (count - 1)) +#define PackBits_Literal(count) (count - 1) #endif