Ephemerboot/Bonus Junk/MegaBoot.c

492 lines
10 KiB
C
Executable File

#include <InterruptSafeDebug.h>
#include <TradDriverLoaderLib.h>
#include <A4Stuff.h>
#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 = (maxTrans<actTrans)? maxTrans : actTrans;
disk = (Ptr) ( gWindowPage << 12 ) + ( ioPen & 0xfff );
buff = pb->ioBuffer + 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;
}