#include #include #include #pragma parameter __D0 VMMap( __A0, __A1 ) OSErr VMMap( UInt32 log, UInt32 phys ) TWOWORDINLINE( 0x7007, 0xfe0a ); #pragma parameter __D0 VMUnmap( __A0, __A1 ) OSErr VMUnmap( UInt32 log, UInt32 key ) TWOWORDINLINE( 0x7008, 0xfe0a ); UInt8 gWindowStor[ 0x1fff ]; UInt32 gWindowPage; struct { UInt8 flags[4]; DrvQEl dqe; } gMyDQE; UInt32 gActualSize = 0x08000000 >> 9; typedef struct PhysRun { UInt32 startPage; UInt32 numBytes; } PhysRun; PhysRun gRuns[] = { { 0x0c000000 >> 12, 0x08000000 } }; int gNumRuns = 1; extern OSErr __Startup__(); extern void DriverHeader(); extern void main(void); extern void CallBootResource( Handle ); extern OSErr DriverOpen(); extern OSErr DriverClose(); extern OSErr DriverPrime( IOParamPtr:__a0, DCtlPtr:__a1 ); extern OSErr DriverStatus( CntrlParamPtr:__a0, DCtlPtr:__a1 ); extern OSErr DriverControl( CntrlParamPtr:__a0, DCtlPtr:__a1 ); extern void NumToHex( UInt32, UInt8 * ); void PrintTrap( UInt16 trap ); void UltimatePatch(); asm OSErr __Startup__() { subq #4, sp // gimme that return ptr back! pea (a3) _DetachResource // no return value move.l a4, -(sp) jsr SetCurrentA4 // boot block calling conventions are pretty freestyle jsr main move.l (sp)+, a4 move.l (sp), a0 move.w (a0)+, -(sp) jsr PrintTrap addq #2, sp move.w (a0)+, -(sp) jsr PrintTrap addq #2, sp move.w (a0)+, -(sp) jsr PrintTrap addq #2, sp move.w (a0)+, -(sp) jsr PrintTrap addq #2, sp move.w (a0)+, -(sp) jsr PrintTrap addq #2, sp move.w (a0)+, -(sp) jsr PrintTrap addq #2, sp // move.w #dsSystemFileErr, d0; move.w #resNotFound, d0; rts } ExitCodeResource(); } asm void DriverHeader() { dc.w dNeedLockMask | dStatEnableMask | dCtlEnableMask | dReadEnableMask | dWritEnableMask dc.w 0 // delay dc.w 0 // evt mask dc.w 0 // menu dc.w 0x1a dc.w 0x1e dc.w 0x28 dc.w 0x32 dc.w 0x3c dc.b "\p.RAMB0" @open: jmp DriverOpen @prime: movem.l a0/a1, -(sp) jsr DriverPrime bra.s @finish @control: movem.l a0/a1, -(sp) jsr DriverControl bra.s @finish @status: movem.l a0/a1, -(sp) jsr DriverStatus bra.s @finish @close: jmp DriverClose @finish: movem.l (sp)+, a0/a1 move.w 6 (a0), d1 // PB.ioTrap btst # noQueueBit, d1 bne.s @rtn move.l 0x8fc, -(sp) // jIODone @rtn: move.w d0, 0x10 (a0) // PB.ioResult rts } extern OSErr DriverOpen() { return noErr; } void PrintTrap( UInt16 trap ) { UInt8 trapstr[8]; EnterCodeResource(); NumToHex( trap, trapstr ); ISDebugText( trapstr+4, 4 ); ExitCodeResource(); } asm void UltimatePatch() { movem.l a0/a1/d0/d1, -(sp) move.l 0x12 (sp), a0 move.w (a0), -(sp) jsr PrintTrap addq #2, sp movem.l (sp)+, a0/a1/d0/d1 jmp 0x80000000 } asm long SetCurrentA4() { lea __Startup__,a0 adda.l #305419896,a0 move.l a0,d0 exg d0,a4 rts } extern OSErr DriverPrime( IOParamPtr pb:__a0, DCtlPtr dce:__a1 ) { OSErr err = noErr; UInt32 ioPage, ioPen; int bcnt; EnterCodeResource(); ISDebugStr( ( pb->ioTrap & 0xff ) == aRdCmd? "\pI" : "\pO" ); pb->ioActCount = 0; VMUnmap( gWindowPage, 1 ); while ( pb->ioActCount < pb->ioReqCount ) { UInt32 maxTrans, actTrans; Ptr disk, buff; for ( bcnt = 0, ioPen = dce->dCtlPosition + pb->ioActCount; bcnt < gNumRuns && gRuns[bcnt].numBytes <= ioPen; bcnt++ ) { ioPen -= gRuns[bcnt].numBytes; } if ( bcnt == gNumRuns ) { err = ioErr; break; } VMMap( gWindowPage, gRuns[bcnt].startPage + ( ioPen >> 12 ) ); maxTrans = 0x1000 - ( ioPen & 0xfff ); actTrans = pb->ioReqCount - pb->ioActCount; actTrans = (maxTransioBuffer + pb->ioActCount; if ( pb->ioTrap & 0xff == aRdCmd ) { BlockMoveData( disk, buff, actTrans ); } else { BlockMoveData( buff, disk, actTrans ); } VMUnmap( gWindowPage, 1 ); pb->ioActCount += actTrans; } ISDebugStr( "\pDone" ); ExitCodeResource(); return err; } extern OSErr DriverControl( CntrlParamPtr pb:__a0, DCtlPtr dce:__a1 ) { EnterCodeResource(); ISDebugStr( "\pC" ); ExitCodeResource(); return controlErr; } extern OSErr DriverStatus( CntrlParamPtr pb:__a0, DCtlPtr dce:__a1 ) { EnterCodeResource(); ISDebugStr( "\pS" ); ExitCodeResource(); return statusErr; } extern OSErr DriverClose void main( void ) { OSErr err = noErr; VCBPtr bootV; SInt16 bootD; CntrlParam pb; SInt16 myRN; UInt32 dlong; EnterCodeResource(); InitInterruptSafeDebug(); * ( (UInt32 *) ( (UInt32) UltimatePatch + 0x16 ) ) = * (UInt32 *) 0x28; //* ( (UInt32 *) 0x28 ) = (UInt32) &UltimatePatch; ISDebugStr( "\pRAMB03" ); Delay( 200, &dlong ); gWindowPage = ( (UInt32) &gWindowStor + 0xfff ) >> 12; HoldMemory( (Ptr) ( gWindowPage << 12 ), 0x1000 ); VMUnmap( gWindowPage, 1 ); ISDebugStr( "\pphysical fenestration" ); { // close the system file & knock the resource manager silly //CloseResFile( LMGetSysMap() ); /*LMSetTopMapHndl( NULL ); LMSetCurMap( 1 );*/ LMSetSysMapHndl( NULL ); LMSetSysMap( 1 ); } { // unmount the boot vol ISDebugStr( "\pSys closed" ); pb.ioCompletion = NULL; bootV = (VCBPtr) GetVCBQHdr()->qHead; bootD = bootV->vcbDrvNum; pb.ioVRefNum = bootV->vcbVRefNum; pb.ioNamePtr = NULL; //err = PBUnmountVol( (ParmBlkPtr) &pb ); } if ( err == noErr ) { // install our drvr ISDebugStr( "\pVol unmounted" ); err = TradInstallDriverFromPtr( (DRVRHeaderPtr) &DriverHeader, 48, 127, &myRN ); } if ( err == noErr ) { err = OpenDriver( "\p.RAMB0", &myRN ); } if ( err == noErr ) { // find the boot drive & link in after it DrvQElPtr dqe; SInt16 highDrive = 0; for ( dqe = (DrvQElPtr) GetDrvQHdr()->qHead; dqe->dQDrive != bootD; dqe = (DrvQElPtr) dqe->qLink ) { if ( dqe->dQDrive > highDrive ) highDrive = dqe->dQDrive; } gMyDQE.dqe.qLink = dqe->qLink; dqe->qLink = (QElemPtr) &gMyDQE.dqe; for ( dqe = (DrvQElPtr) gMyDQE.dqe.qLink; dqe; dqe = (DrvQElPtr) dqe->qLink ) { if ( dqe->dQDrive > highDrive ) highDrive = dqe->dQDrive; } gMyDQE.flags[0] = 0; // unlocked gMyDQE.flags[1] = 8; // nonejectable gMyDQE.flags[2] = 0; // reserved gMyDQE.flags[3] = 0; // n/a gMyDQE.dqe.dQDrive = highDrive + 1; gMyDQE.dqe.dQRefNum = myRN; gMyDQE.dqe.dQFSID = 0; gMyDQE.dqe.dQDrvSz = (UInt16) gActualSize; gMyDQE.dqe.dQDrvSz2 = (UInt32) gActualSize >> 16; PrintTrap( myRN ); } if ( err == noErr ) { HVolumeParam vpb; DrvQElPtr dqe; vpb.ioVRefNum = gMyDQE.dqe.dQDrive; vpb.ioVolIndex = 0; vpb.ioNamePtr = NULL; vpb.ioCompletion = 0; err = PBMountVol( (ParmBlkPtr) &vpb ); if ( err == noErr ) { ISDebugStr( "\pmounted RAM disk" ); err = PBHGetVInfoSync( (HParmBlkPtr) &vpb ); } for ( dqe = (DrvQElPtr) GetDrvQHdr()->qHead; dqe && ( err || vpb.ioVFndrInfo[0] == 0 ); dqe = (DrvQElPtr) dqe->qLink ) { err = PBUnmountVol( (ParmBlkPtr) &vpb ); vpb.ioVRefNum = dqe->dQDrive; err = PBMountVol( (ParmBlkPtr) &vpb ); if ( vpb.ioVRefNum == bootD ) err = dsBadStartupDisk; // no recursion! vpb.ioVolIndex = 0; if ( err == noErr ) { ISDebugStr( "\pmounted something else" ); err = PBHGetVInfoSync( (HParmBlkPtr) &vpb ); } } if ( dqe == NULL ) err = dsBadStartupDisk; /* pb.ioVRefNum = 15; //gMyDQE.dqe.dQDrive; err = PBMountVol( (ParmBlkPtr) &pb ); } if ( err == noErr ) { HVolumeParam vpb; vpb.ioVRefNum = pb.ioVRefNum; vpb.ioVolIndex = 0; vpb.ioNamePtr = 0; vpb.ioCompletion = 0; err = PBHGetVInfoSync( (HParmBlkPtr) &vpb );*/ if ( err == noErr ) { LMSetBootDrive( vpb.ioVDrvInfo ); ( (WDPBPtr) &vpb )->ioWDDirID = vpb.ioVFndrInfo[0]; ( (WDPBPtr) &vpb )->ioWDProcID = 'ERIK'; // Erik... that's me ;v) err = PBOpenWDSync( (WDPBPtr) &vpb ); } if ( err == noErr ) { ISDebugStr( "\pFound a System Folder" ); err = PBSetVolSync( (ParmBlkPtr) &vpb ); } } if ( err == noErr ) { ISDebugStr( "\pSet the sys folder" ); Delay( 60, &dlong ); /*if ( InitResources() < 0 ) { err = dsSystemFileErr; ISDebugStr( "\pNo InitResources() for U" ); }*/ LMSetSysMap( OpenResFile( LMGetSysResName() ) ); Delay( 60, &dlong ); if ( LMGetSysMap() == 0 ) err = fnfErr; } if ( err == noErr ) { Handle boot2; OSType type; SInt16 id, rx = 1; UInt8 check[8]; LMSetSysMapHndl( LMGetTopMapHndl() ); do { boot2 = GetIndResource( 'boot', rx ); err = ResError(); GetResInfo( boot2, &id, &type, check ); PrintTrap( id ); PrintTrap( rx ); NumToHex( * (UInt32 *) *boot2, check ); ISDebugText( check, 8 ); rx++; } while( err == noErr && * (UInt32 *) *boot2 != 0x204ba025 ); Delay( 300, &dlong ); ISDebugStr( "\pCalling boot" ); if ( err == noErr ) { * ( (UInt32 *) 0x28 ) = (UInt32) &UltimatePatch; CallBootResource( boot2 ); } } { UInt8 errstr[8]; NumToHex( err, errstr ); ISDebugText( errstr, 8 ); ISDebugStr("\preturning"); Delay( 600, &dlong ); } ExitCodeResource(); } asm void CallBootResource( Handle boot2 ) { movea.l 4 (sp), a3 movea.l (a3), a0 jmp (a0) } void NumToHex( UInt32 num, UInt8 *hex ) { int ncnt; for ( ncnt = 0; ncnt < 8; ncnt++ ) { int nibble = ( num >> (28-ncnt*4) ) & 0x0f; nibble += (nibble>9)?('a'-10):'0'; hex[ncnt] = nibble; } } /*if ( err == noErr ) { pb.ioVRefNum = gMyDQE.dqe.dQDrive; err = PBMountVol( (ParmBlkPtr) &pb ); } if ( err == noErr ) { ISDebugStr( "\pMounted" ); SetVol( NULL, pb.ioVRefNum );*/ /*void main(void) { Ptr windowStor, window; UInt32 lcnt; SetCurrentA4(); InitInterruptSafeDebug(); ISDebugStr( "\pHello" ); Delay(60, &lcnt); window = (Ptr) ( ( (UInt32) &gWindowStor + 0xfff ) & ~0xfff ); HoldMemory( window, 0x1000 ); VMUnmap( ( (UInt32) window ) >> 12, 1 ); VMMap( ( (UInt32) window ) >> 12, 0 ); for ( lcnt = 0; lcnt < 4; lcnt++ ) { UInt8 hstr[9]; *hstr = 8; NumToHex( ( (UInt32 *) window )[lcnt], hstr + 1 ); ISDebugStr( hstr ); } VMUnmap( ( (UInt32) window ) >> 12, 1 ); UnholdMemory( window, 0x1000 ); //Debugger(); Delay(600, &lcnt); }*/() { return noErr; }