492 lines
10 KiB
C
Executable File
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;
|
|
} |