mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-26 16:49:18 +00:00
632 lines
22 KiB
Plaintext
632 lines
22 KiB
Plaintext
|
;__________________________________________________________________________________________________
|
||
|
;
|
||
|
; File: BootUtils.a
|
||
|
;
|
||
|
; Contains: Network booting utilities
|
||
|
;
|
||
|
; Written by: Patrick Dyson
|
||
|
;
|
||
|
; Copyright © 1989-1993 by Apple Computer, Inc. All rights reserved.
|
||
|
;
|
||
|
; Change History (most recent first):
|
||
|
;
|
||
|
; <SM3> 6/14/93 kc Roll in Ludwig.
|
||
|
; <LW2> 4/8/93 fau Fixed a bug with the opening of the .ATBoot driver. It was
|
||
|
; using an _Open which uses the res-id for the refnum. This came
|
||
|
; out to -50, which was a driver that was already there. I moved
|
||
|
; some code from Startinit.a that installs a driver at the lowest
|
||
|
; refnum available after 47 and changed the .ATBoot open to use it.
|
||
|
; <SM2> 11/5/92 SWC Changed INCLUDEs to a LOAD of StandardEqu.d.
|
||
|
; <7> 3/20/90 PWD Fix to DoATBootOpen to push #'DRVR' instead of 'DRVR'.
|
||
|
; <6> 3/9/90 PWD Merge from xo splitoff - changes to drive queue element size,
|
||
|
; system heap growth routine.
|
||
|
; <5> 2/20/90 PWD Fixed coincident zones grow zone proc by reiniting the app heap
|
||
|
; if I grow the system heap. Also added icons for startup sequence
|
||
|
; and a pc-relative open for the netboot driver.
|
||
|
; <4> 2/1/90 PWD Fixed coincident zones grow zone proc by reiniting the app heap
|
||
|
; if I grow the system heap.
|
||
|
; <4> 01/30/90 PWD Changed grow zone proc to not clobber ApplZone and HeapEnd.
|
||
|
; <3> 12/28/89 SWC Fixed header and set tabs to 4.
|
||
|
; <2> 12/19/89 PWD Adding to bbs.
|
||
|
; <1.1> 12/12/89 PWD Added support for self-authenticating images
|
||
|
; <1.0> 10/30/89 PWD Adding to EASE
|
||
|
;__________________________________________________________________________________________________
|
||
|
|
||
|
PRINT OFF
|
||
|
LOAD 'StandardEqu.d'
|
||
|
INCLUDE 'Slots.a' ; Slot equates
|
||
|
INCLUDE 'ROMequ.a' ; Slot ROM declarations
|
||
|
INCLUDE 'NetBootEQU.a' ; netBoot defs
|
||
|
PRINT ON
|
||
|
|
||
|
|
||
|
;__________________________________________________________________
|
||
|
;
|
||
|
; TestPRam - C procedure to call our pram routines
|
||
|
;
|
||
|
; On Entry: 8(SP) is 0 for write, 1 for read
|
||
|
; 4(SP) points to a buffer to use
|
||
|
;
|
||
|
; On Exit: read pram in buffer
|
||
|
;
|
||
|
;__________________________________________________________________
|
||
|
TestPRam PROC EXPORT
|
||
|
MOVE.L 4(SP), A0 ; buffer to read/write
|
||
|
MOVE.L 8(SP), D0 ; get selector
|
||
|
BEQ.S @write
|
||
|
BSR.S ReadPRAM
|
||
|
BRA.S @Exit
|
||
|
|
||
|
@write BSR.S WritePRAM
|
||
|
|
||
|
@Exit RTS
|
||
|
;__________________________________________________________________
|
||
|
;
|
||
|
; ReadPRAM - read from our PRAM
|
||
|
;
|
||
|
; On Entry: A0 points to a read buffer
|
||
|
; On Exit: the z bit is set if there was an error
|
||
|
; A0 points to the buffer read:
|
||
|
; password
|
||
|
; user name
|
||
|
; server name
|
||
|
;
|
||
|
; Trashes D0,D1,A0,A1
|
||
|
;__________________________________________________________________
|
||
|
pRamEntries EQU 5 ; size of table
|
||
|
pRamTable
|
||
|
DC.L $00040004 ; first four password bytes
|
||
|
DC.L $000300AB ; next three byte
|
||
|
DC.L $000100BC ; last password byte
|
||
|
DC.L $00200020 ; User name (32 bytes)
|
||
|
DC.L $0020008B ; Server name (31 bytes)
|
||
|
|
||
|
ReadPRAM CLR.L D0 ; assume error
|
||
|
BTST #14,HWCfgFlags ; New clock chip?
|
||
|
BEQ.S @10 ; Assume bridge if not
|
||
|
LEA pRamTable, A1 ; start of table
|
||
|
MOVEQ.L #pRamEntries-1, D1 ; entries (-1)
|
||
|
@1 MOVE.L (A1)+,D0 ; first count
|
||
|
MOVE.L D0,D2
|
||
|
; A0 has buffer area
|
||
|
_ReadXPRam ; trashes D0
|
||
|
SWAP D2 ; get count in low byte
|
||
|
ADDA D2,A0 ; bump buffer
|
||
|
DBRA D1,@1 ; go get more
|
||
|
|
||
|
@10 RTS
|
||
|
|
||
|
;__________________________________________________________________
|
||
|
;
|
||
|
; WritePRAM - write to our PRAM
|
||
|
;
|
||
|
; On Entry: A0 points to the buffer to write:
|
||
|
; password
|
||
|
; user name
|
||
|
; server name
|
||
|
; On Exit: the z bit is set if there was an error
|
||
|
;__________________________________________________________________
|
||
|
|
||
|
WritePRAM CLR.L D0 ; assume error
|
||
|
BTST #14,HWCfgFlags ; New clock chip?
|
||
|
BEQ.S @10 ; Assume bridge if not
|
||
|
LEA pRamTable, A1 ; start of table
|
||
|
MOVEQ.L #pRamEntries-1, D1 ; entries (-1)
|
||
|
@1 MOVE.L (A1)+,D0 ; first count
|
||
|
MOVE.L D0,D2
|
||
|
; A0 has buffer area
|
||
|
_WriteXPRam
|
||
|
SWAP D2 ; get count in low byte
|
||
|
ADDA D2,A0 ; bump buffer
|
||
|
DBRA D1,@1 ; go get more
|
||
|
|
||
|
@10 RTS
|
||
|
ENDP
|
||
|
AddMyDrive PROC EXPORT
|
||
|
;---------------------------------------------------------------------------
|
||
|
;FUNCTION AddMyDrive(drvSize: LONGINT; drvrRef: INTEGER; drvStorage: Ptr): INTEGER;
|
||
|
;---------------------------------------------------------------------------
|
||
|
;Add a drive to the drive queue. Returns the new drive number, or a negative
|
||
|
;error code (from trying to allocate the memory for the queue element).
|
||
|
;---------------------------------------------------------------------------
|
||
|
DQESize EQU 18+8 ;size of a drive queue element + private storage
|
||
|
;We use a constant here because the number in SysEqu.a doesn't take into
|
||
|
;account the flags LONGINT before the element, or the size word at the end.
|
||
|
;---------------------------------------------------------------------------
|
||
|
StackFrame RECORD {link},DECR
|
||
|
result DS.W 1 ;function result
|
||
|
params EQU *
|
||
|
drvSize DS.L 1 ;drive size parameter
|
||
|
drvrRef DS.W 1 ;drive refNum parameter
|
||
|
drvNStorage DS.L 1 ; private storage on the end of the drive Q element
|
||
|
paramSize EQU params-*
|
||
|
return DS.L 1 ;return address
|
||
|
link DS.L 1 ;saved value of A6 from LINK
|
||
|
block DS.B ioQElSize ;parameter block for call to MountVol
|
||
|
linkSize EQU *
|
||
|
ENDR
|
||
|
;---------------------------------------------------------------------------
|
||
|
WITH StackFrame ;use the offsets declared above
|
||
|
|
||
|
LINK A6,#linkSize ;create stack frame
|
||
|
|
||
|
;search existing drive queue for an unused number
|
||
|
|
||
|
LEA DrvQHdr,A0 ;get the drive queue header
|
||
|
MOVEQ #4,D0 ;start with drive number 4
|
||
|
CheckDrvNum
|
||
|
MOVE.L qHead(A0),A1 ;start with first drive
|
||
|
CheckDrv
|
||
|
CMP.W dqDrive(A1),D0 ;does this drive already have our number?
|
||
|
BEQ.S NextDrvNum ;yep, bump the number and try again.
|
||
|
CMP.L qTail(A0),A1 ;no, are we at the end of the queue?
|
||
|
BEQ.S GotDrvNum ;if yes, our number's unique! Go use it.
|
||
|
MOVE.L qLink(A1),A1 ;point to next queue element
|
||
|
BRA.S CheckDrv ;go check it.
|
||
|
|
||
|
NextDrvNum
|
||
|
;this drive number is taken, pick another
|
||
|
|
||
|
ADDQ.W #1,D0 ;bump to next possible drive number
|
||
|
BRA.S CheckDrvNum ;try the new number
|
||
|
|
||
|
GotDrvNum
|
||
|
;we got a good number (in D0.W), set it aside
|
||
|
|
||
|
MOVE.W D0,result(A6) ;return it to the user
|
||
|
|
||
|
;get room for the new DQE
|
||
|
|
||
|
MOVEQ #DQESize,D0 ;size of drive queue element, adjusted
|
||
|
_NewPtr ,SYS ;get memory for it
|
||
|
BEQ.S GotDQE ;no error...continue
|
||
|
MOVE.W D0,result(A6) ;couldn't get the memory! return error
|
||
|
BRA.S FinishUp ;and exit
|
||
|
|
||
|
GotDQE
|
||
|
;fill out the DQE
|
||
|
|
||
|
MOVE.L #$80000,(A0)+ ;flags: non-ejectable; bump past flags
|
||
|
|
||
|
MOVE.W #1,qType(A0) ;qType of 1 means we do use dQDrvSz2
|
||
|
MOVE.W #dFSID,dQFSID(A0) ;"external file system"
|
||
|
MOVE.W drvSize(A6),dQDrvSz2(A0) ;high word of number of blocks
|
||
|
MOVE.W drvSize+2(A6),dQDrvSz(A0) ;low word of number of blocks
|
||
|
MOVE.L drvNStorage(A6), drvStorage(A0); private storage
|
||
|
|
||
|
;call AddDrive
|
||
|
|
||
|
MOVE.W result(A6),D0 ;get the drive number back
|
||
|
SWAP D0 ;put it in the high word
|
||
|
MOVE.W drvrRef(A6),D0 ;move the driver refNum in the low word
|
||
|
_AddDrive ;add this drive to the drive queue
|
||
|
|
||
|
FinishUp
|
||
|
UNLK A6 ;get rid of stack frame
|
||
|
MOVE.L (SP)+,A0 ;get return address
|
||
|
ADD #paramSize,SP ;get rid of parameters
|
||
|
JMP (A0) ;back to caller
|
||
|
;---------------------------------------------------------------------------
|
||
|
ENDPROC
|
||
|
|
||
|
;
|
||
|
; RmvDriver - glue for this undocumented trap
|
||
|
;
|
||
|
|
||
|
KillDriver PROC EXPORT
|
||
|
MOVE.L 4(SP), D0 ; pop parameter
|
||
|
_DrvrRemove
|
||
|
; function result in D0
|
||
|
RTS ; C functs clean up after themselves
|
||
|
ENDP
|
||
|
|
||
|
;---------------------------------------------------------------------------
|
||
|
;
|
||
|
; pdbzero - our own copy of the famous "zero this many bytes routine"
|
||
|
;
|
||
|
;
|
||
|
;
|
||
|
;---------------------------------------------------------------------------
|
||
|
CASE OBJ ; make this be case as specified
|
||
|
pdbzero PROC EXPORT
|
||
|
move.l 4(sp),a0 ; pointer to block to zero
|
||
|
move.l 8(sp),d0 ; count of bytes to zero
|
||
|
ble.s @theend ; punt if done already
|
||
|
sub.l #1,d0 ; for dbra
|
||
|
move.l #0,d1 ; something to clear with
|
||
|
@11
|
||
|
move.b d1,(a0)+ ; clear that byte...
|
||
|
dbra d0,@11 ; until done.
|
||
|
@theend
|
||
|
rts
|
||
|
ENDP
|
||
|
|
||
|
;__________________________________________________________________
|
||
|
;
|
||
|
; myExtFSFilter
|
||
|
;
|
||
|
; This routine handles the _MountVol call to BootDrive after the boot
|
||
|
; blocks have been read (handled by .netBoot). It is installed just before
|
||
|
; the netboot read completes and de-installs itself when done.
|
||
|
;
|
||
|
; We install our grow zone proc before making the control call in case
|
||
|
; it wants memory.
|
||
|
;
|
||
|
; Entry: A0 -> the mountvol param block
|
||
|
;
|
||
|
; Exit: D0 any error
|
||
|
;
|
||
|
; We trash D0, all other registers preserved.
|
||
|
;
|
||
|
CASE OBJ ; save case for C linker
|
||
|
WDCBsPtr EQU $372 ; Working Directory queue header
|
||
|
myExtFSFilter PROC EXPORT ; imported by netBoot.c
|
||
|
IMPORT myGrowZone
|
||
|
MOVEM.L A0-A4/D1-D2, -(SP) ; savem
|
||
|
CMP.B #$0F,ioTrap+1(A0) ; is this a MountVol call?
|
||
|
BNE @NotOurs
|
||
|
|
||
|
MOVE.W IODrvNum(A0), D0 ; pick up drive
|
||
|
CMP.W #4, D0 ; is this for us?
|
||
|
BNE @NotOurs
|
||
|
;
|
||
|
; go find the drive queue entry
|
||
|
;
|
||
|
LEA DrvQHdr,A2 ; get the drive queue header
|
||
|
MOVE.L qHead(A2),A1 ; start with first drive
|
||
|
@CheckDrv
|
||
|
CMP.W dqDrive(A1),D0 ; our drive?
|
||
|
BEQ.S @GotDrvNum ; yep, cruise
|
||
|
CMP.L qTail(A2),A1 ; no, are we at the end of the queue?
|
||
|
BEQ @Error ; yes, we're hosed
|
||
|
MOVE.L qLink(A1),A1 ; point to next queue element
|
||
|
BRA.S @CheckDrv ; go check it.
|
||
|
|
||
|
@GotDrvNum ; in A1
|
||
|
CMP.W #dFSID, dQFSID(A1) ; ours?
|
||
|
BNE @Error
|
||
|
|
||
|
MOVE.L drvStorage(A1), D0 ; pick up driver globals (on end of entry)
|
||
|
MOVE.L A1, A4 ; save drive entry pointer
|
||
|
BEQ @Error
|
||
|
|
||
|
MOVE.L D0, A2 ; get globals pointer
|
||
|
|
||
|
MOVE.L SysZone, A0 ; pick up system heap pointer
|
||
|
move.l a0,TheZone ; make sure that we keep our default zone...
|
||
|
MOVE.L gzProc(A0), -(SP) ; save old grow zone
|
||
|
LEA myGrowZone, A1 ; pick up my grow zone proc
|
||
|
MOVE.L A1, gzProc(A0) ; tell the memory manager
|
||
|
SUB #ioQElSize,SP ; make a queue element
|
||
|
MOVE.L SP,A0 ; A0 -> queue element
|
||
|
MOVE #mountSysVol,csCode(A0) ; set control code
|
||
|
MOVE dProtoRefNum(A2),ioRefNum(A0) ; set driver refNum
|
||
|
_Control
|
||
|
BEQ.S @Good ; branch if no error
|
||
|
ADD #ioQElSize, SP ; restore stack
|
||
|
MOVE.L SysZone, A0 ; pick up system heap pointer
|
||
|
MOVE.L (SP)+,gzProc(A0) ; restore old grow zone
|
||
|
BRA @ControlError ; punt if error
|
||
|
|
||
|
@Good MOVE.L returnVCB(A0), A1 ; pick up VCB pointer
|
||
|
MOVE.L A1, DefVCBPtr ; set as default volume
|
||
|
MOVE.L WDCBsPtr, A3
|
||
|
MOVE.L A1, WDVCBPtr+2(A3) ;
|
||
|
MOVEQ #2, D0 ; FSRtDirID
|
||
|
MOVE.L D0, WDDirID+2(A3) ;
|
||
|
CLR.L WDCatHint+2(A3)
|
||
|
CLR.L WDProcID+2(A3)
|
||
|
|
||
|
MOVE.L returnDrvQ(A0), A1 ; pick up drive queue pointer
|
||
|
|
||
|
MOVE dQFSID(A1), dQFSID(A4) ; set drive queue entry fsid
|
||
|
MOVE dQRefNum(A1), dQRefNum(A4) ; set driver refnum to handle calls
|
||
|
MOVE.B -3(A1), -3(A4) ; set flags
|
||
|
|
||
|
SUBQ #4, A1 ; point to buffer start
|
||
|
MOVE.L A1, A0 ; set up for _Dispos
|
||
|
_DisposPtr ; nuke it
|
||
|
|
||
|
CLR.L drvStorage(A4) ; wipe out reference to our storage
|
||
|
|
||
|
MOVE.L doldToExtFS(A2), ToExtFS ; restore ToExtFS (unhook ourselves)
|
||
|
|
||
|
ADD #ioQElSize, SP ; restore stack
|
||
|
MOVE.L SysZone, A0 ; pick up system heap pointer
|
||
|
MOVE.L (SP)+,gzProc(A0) ; restore old grow zone
|
||
|
MOVEQ #0, D0 ; set no error
|
||
|
BRA.S @Leave ; outta' here
|
||
|
@Error
|
||
|
MOVEQ #-1, D0
|
||
|
|
||
|
@ControlError
|
||
|
@Leave
|
||
|
@NotOurs
|
||
|
MOVEM.L (SP)+, A0-A4/D1-D2 ; restorem
|
||
|
RTS
|
||
|
ENDP
|
||
|
|
||
|
;__________________________________________________________________
|
||
|
;
|
||
|
; myGrowZone
|
||
|
;
|
||
|
; This proc is installed before making calls to the boot protocol driver
|
||
|
; or the downloaded code. The memory world is simple: The app and system
|
||
|
; heap are coincident; The app heap about 16k after the end of the system.
|
||
|
;
|
||
|
; The app heap is assumed to be clobberable - our algorithm is to extend the
|
||
|
; system heap by the requested amount + pad (currently 16k). We limit the size
|
||
|
; of the system growth to 1/2 machine memory and by the bottom of the stack.
|
||
|
;
|
||
|
; This is a pascal procedure & thus cleans up its own stack.
|
||
|
;
|
||
|
; Entry: 4(SP).L Requested memory size
|
||
|
; 8(SP).L Space for function return value
|
||
|
;
|
||
|
; Exit: (SP).L Size of block we freed
|
||
|
SysHeapEndBuf EQU 8*1024 ; amount of space between SysHeap end & SP <A286>
|
||
|
myGrowZone PROC EXPORT
|
||
|
MOVE.L 4(SP), D0 ; pick up block size
|
||
|
MOVE.L A2, -(SP) ; save a register
|
||
|
MOVE.L SysZone,A1 ; Point to System Heap. <C102>
|
||
|
MOVE.L bkLim(A1),A0 ; Point to end of System Heap.
|
||
|
MOVE.L A0, A2 ; save the old end of the heap
|
||
|
ADD.L #16*1024, D0 ; add slop
|
||
|
LEA 0(A0,D0.L), A0 ; point to "new" end
|
||
|
MOVE.L D0, D1 ; save off how much we are going for
|
||
|
|
||
|
MOVE.L BufPtr,A1 ; Upper bound is BufPtr <C587>
|
||
|
SUB.L #SysHeapEndBuf,A1 ; …minus a tad. <A286>
|
||
|
CMP.L A1,A0 ; Is proposed end <= limit? <A286>
|
||
|
BLS.S @WithinLimit ; Branch if so.
|
||
|
MOVE.L A1, D1 ; pick up new end
|
||
|
SUB.L A2, D1 ; subtract off the bottom; size = (top-bottom)
|
||
|
MOVE.L A1,A0 ; If not, use upper limit instead. <A286>
|
||
|
@WithinLimit ; <A286>
|
||
|
|
||
|
_SetAppBase ; Set up the start of the application heap. <C102>
|
||
|
; _InitApplZone ; and do all the fun initialization <C793>
|
||
|
|
||
|
MOVE.L SysZone, A1 ; get the system zone
|
||
|
MOVE.L A1,TheZone ; We still want the System Heap to be the default. <C102>
|
||
|
MOVE.L A1,ApplZone ; pd< Put back in for XO >revert to coincident zones <C587>
|
||
|
MOVE.L bkLim(A1),HeapEnd ; pd< Put Back in for XO >end of dynamic sys/appl zone <C587>
|
||
|
|
||
|
MOVE.L (SP)+, A2 ; restore a register
|
||
|
MOVE.L (SP)+, A0 ; pop return address
|
||
|
|
||
|
MOVE.L (SP)+, D0 ; pop the passed size
|
||
|
MOVE.L D1, (SP) ; return how much we are giving
|
||
|
JMP (A0) ; and go back from whence we came
|
||
|
ENDP
|
||
|
|
||
|
|
||
|
|
||
|
myGetA5 PROC EXPORT
|
||
|
MOVE.L A5, D0
|
||
|
RTS
|
||
|
ENDP
|
||
|
|
||
|
mySetA5 PROC EXPORT
|
||
|
MOVE.L 4(SP), A5
|
||
|
RTS
|
||
|
ENDP
|
||
|
|
||
|
CASE OBJ ; c case for the linker
|
||
|
DoATBootOpen PROC EXPORT
|
||
|
move.l 4(SP), a0 ; pick up passed param block
|
||
|
clr.l -(sp) ; function result room
|
||
|
move.l #'DRVR', -(sp) ; push the type
|
||
|
move.l HParamBlockRec.ioNamePtr(a0), -(sp) ; push the name of the driver
|
||
|
_GetNamedResource ; go for it
|
||
|
clr d0 ; assume error (0 is error)
|
||
|
tst.l (sp)+ ; pop result
|
||
|
beq.s @openErr
|
||
|
move.l 4(sp), a0 ; get pb back
|
||
|
move.l HParamBlockRec.ioNamePtr(a0), A1
|
||
|
MOVE.W #60,D2 ; and resource ID <SM84>
|
||
|
BSR InstallDriver ; go install the driver
|
||
|
swap d0 ; get refnum in lower word.
|
||
|
Andi.l #$FFFF,D0 ; clear the top word and return the refnum
|
||
|
|
||
|
@openErr rts
|
||
|
|
||
|
;________________________________________________________________________________________
|
||
|
;
|
||
|
; Routine: InstallDriver
|
||
|
;
|
||
|
; Inputs: A1 - pointer to driver name string (pascal)
|
||
|
; D2 - driver's resource ID
|
||
|
;
|
||
|
; Outputs: none
|
||
|
;
|
||
|
; Trashes: D0-D2, A0-A2
|
||
|
;
|
||
|
; Function: gets a driver from the ROM, and installs and opens it in the first available
|
||
|
; slot after entry 48
|
||
|
;________________________________________________________________________________________
|
||
|
|
||
|
InstallDriver
|
||
|
move.l a1,a2 ; move name ptr to a2 for safe keeping
|
||
|
bsr.s GetDetachDRVR ; get and detach resource (d1,d1/a1)
|
||
|
beq.s @exit ; exit if no handle
|
||
|
|
||
|
bsr.s FirstEntryFree ; get ref num of first free entry (/d0,d1)
|
||
|
_DrvrInstall ; create dce (d0/d0)
|
||
|
tst.l d0 ; test for error
|
||
|
bne.s @releaseDrvr ; ... exit if error
|
||
|
|
||
|
move.l UTableBase,a0 ; point to utable array
|
||
|
move.l (a0,d1),a0 ; get handle to dce in a3
|
||
|
move.l (a0),a0 ; get pointer to dce
|
||
|
move.l a1,dCtlDriver(a0) ; load driver
|
||
|
|
||
|
move.l (a1),a1 ; get pointer to driver
|
||
|
move.w drvrFlags(a1),dCtlFlags(a0) ; copy data to dce
|
||
|
move.w drvrDelay(a1),dCtlDelay(a0)
|
||
|
move.w drvrEMask(a1),dCtlEMask(a0)
|
||
|
move.w drvrMenu(a1),dCtlMenu(a0)
|
||
|
|
||
|
bset.b #dNeedLock,dCtlFlags+1(a0) ; set the handle bit
|
||
|
|
||
|
@openDrvr move.l a2,a1 ; load pointer to driver name
|
||
|
bra.s OpenDRVR ; open the driver (a1/)
|
||
|
@releaseDrvr
|
||
|
move.l a1,a0 ; move handle to a0
|
||
|
_DisposHandle ; release the memory
|
||
|
@exit rts
|
||
|
|
||
|
|
||
|
;________________________________________________________________________________________
|
||
|
;
|
||
|
; Routine: GetDetachDrvr, GetDetachRes
|
||
|
;
|
||
|
; Inputs: D1 - resource type (GetDetachRes)
|
||
|
; D2 - driver's resource ID
|
||
|
;
|
||
|
; Outputs: A1 - handle to resource
|
||
|
; CCR - BEQ if successful, BNE if failure
|
||
|
;
|
||
|
; Trashes: D0-D2, A0-A2
|
||
|
;
|
||
|
; Function: gets a driver from the ROM and detaches it
|
||
|
;________________________________________________________________________________________
|
||
|
|
||
|
GetDetachDRVR
|
||
|
MOVE.L #'DRVR',D1
|
||
|
GetDetachRes
|
||
|
MOVE.W #MapTrue,ROMMapInsert ; make sure we can get it from ROM
|
||
|
SUBQ.L #4, SP ; For return address
|
||
|
MOVE.L D1, -(SP) ; Resource type
|
||
|
MOVE.W D2, -(SP) ; Resource ID
|
||
|
_GetResource
|
||
|
MOVE.L (SP), A1 ; Get resource handle to return
|
||
|
BNE.S @NoDetach ; If not found, don't try to detach it
|
||
|
_DetachResource
|
||
|
MOVE.L A1,D0 ; Set result code
|
||
|
RTS
|
||
|
@NoDetach
|
||
|
ADDA.L #4,SP ; recover stack
|
||
|
MOVEQ #0,D0 ; set error
|
||
|
RTS ; return
|
||
|
|
||
|
|
||
|
;________________________________________________________________________________________
|
||
|
;
|
||
|
; Routine: FirstEntryFree
|
||
|
;
|
||
|
; Inputs: none
|
||
|
;
|
||
|
; Outputs: D0 - driver refNum
|
||
|
;
|
||
|
; Trashes: none
|
||
|
;
|
||
|
; Function: finds the first free entry in the unit table
|
||
|
;________________________________________________________________________________________
|
||
|
|
||
|
StartEntry equ (48-1) ; this avoids AppleTalk area
|
||
|
|
||
|
FirstEntryFree
|
||
|
move.l a0,-(SP) ; save a0
|
||
|
|
||
|
@findEntry move.l UTableBase,a0 ; point to utable array
|
||
|
move.l #(StartEntry*4),d0 ; start at entry (48-1)
|
||
|
|
||
|
@testEntry addq.l #4,d0 ; increment to next entry
|
||
|
tst.l 0(a0,d0) ; test entry
|
||
|
bne.s @testEntry ; if != 0, next entry
|
||
|
|
||
|
@calcRefnum move.l d0,d1
|
||
|
lsr.l #2,d0 ; divide by 4 to get entry number
|
||
|
addq.l #1,d0 ; add 1 (refnum is -(entry number + 1)
|
||
|
neg.l d0 ; negate to get reference number
|
||
|
|
||
|
move.l (SP)+,a0 ; restore a0
|
||
|
rts
|
||
|
|
||
|
|
||
|
;________________________________________________________________________________________
|
||
|
;
|
||
|
; Routine: OpenDRVR
|
||
|
;
|
||
|
; Inputs: A1 - pointer to driver name string (pascal)
|
||
|
;
|
||
|
; Outputs: D0 - driver refNum in high word, Open result in low word
|
||
|
; CCR - BEQ if successful, BNE if failure
|
||
|
;
|
||
|
; Trashes: A0
|
||
|
;
|
||
|
; Function: opens a driver
|
||
|
;________________________________________________________________________________________
|
||
|
|
||
|
OpenDRVR LEA -ioQElSize(SP),SP ; Allocate IO stack frame
|
||
|
MOVE.L SP,A0 ; set a0 to point to the pb
|
||
|
MOVE.L A1,ioVNPtr(A0) ; load pointer to name
|
||
|
MOVE.B #fsCurPerm,ioPermssn(A0) ; set permission (not used)
|
||
|
_Open
|
||
|
|
||
|
MOVE.W ioRefNum(A0),D0 ; return ioRefNum (D0.W:HI)
|
||
|
SWAP D0 ; move ioRefNum HI
|
||
|
MOVE.W ioResult(A0),D0 ; return result (D0.W:LO)
|
||
|
LEA ioQElSize(SP),SP ; Release stack frame
|
||
|
RTS ; Sucess returned in status
|
||
|
|
||
|
|
||
|
ENDP
|
||
|
|
||
|
|
||
|
myGetIcn PROC EXPORT
|
||
|
move.l 4(sp), d0 ; pick up index
|
||
|
lsl #7, d0 ; multiply by 128
|
||
|
lea myIcons, a0 ; pick up icon base
|
||
|
add.l a0,d0 ; point to icon.
|
||
|
rts
|
||
|
myIcons
|
||
|
; resource 'ICN#' (1, "Outline Mac") {
|
||
|
|
||
|
dc.b $0F, $FF, $FF, $E0, $18, $00, $00, $30, $10, $00, $00, $10, $11, $FF, $FF, $10
|
||
|
dc.b $12, $00, $00, $90, $12, $00, $00, $90, $12, $00, $00, $90, $12, $00, $00, $90
|
||
|
dc.b $12, $00, $00, $90, $12, $00, $00, $90, $12, $00, $00, $90, $12, $00, $00, $90
|
||
|
dc.b $12, $00, $00, $90, $12, $00, $00, $90, $12, $00, $00, $90, $12, $00, $00, $90
|
||
|
dc.b $12, $00, $00, $90, $11, $FF, $FF, $10, $10, $00, $00, $10, $10, $00, $00, $10
|
||
|
dc.b $10, $00, $00, $10, $10, $00, $00, $10, $13, $00, $3F, $10, $10, $00, $00, $10
|
||
|
dc.b $10, $00, $00, $10, $10, $00, $00, $10, $10, $00, $00, $10, $1F, $FF, $FF, $F0
|
||
|
dc.b $08, $00, $00, $20, $08, $00, $00, $20, $08, $00, $00, $20, $0F, $FF, $FF, $E0
|
||
|
|
||
|
; resource 'ICN#' (2, "Mac with eyes") {
|
||
|
|
||
|
dc.b $0F, $FF, $FF, $E0, $18, $00, $00, $30, $10, $00, $00, $10, $11, $FF, $FF, $10
|
||
|
dc.b $12, $00, $00, $90, $12, $00, $00, $90, $12, $00, $00, $90, $12, $10, $10, $90
|
||
|
dc.b $12, $10, $10, $90, $12, $00, $00, $90, $12, $00, $00, $90, $12, $00, $00, $90
|
||
|
dc.b $12, $00, $00, $90, $12, $00, $00, $90, $12, $00, $00, $90, $12, $00, $00, $90
|
||
|
dc.b $12, $00, $00, $90, $11, $FF, $FF, $10, $10, $00, $00, $10, $10, $00, $00, $10
|
||
|
dc.b $10, $00, $00, $10, $10, $00, $00, $10, $13, $00, $3F, $10, $10, $00, $00, $10
|
||
|
dc.b $10, $00, $00, $10, $10, $00, $00, $10, $10, $00, $00, $10, $1F, $FF, $FF, $F0
|
||
|
dc.b $08, $00, $00, $20, $08, $00, $00, $20, $08, $00, $00, $20, $0F, $FF, $FF, $E0
|
||
|
|
||
|
;resource 'ICN#' (3, "mac with eyes&nose") {
|
||
|
|
||
|
dc.b $0F, $FF, $FF, $E0, $18, $00, $00, $30, $10, $00, $00, $10, $11, $FF, $FF, $10
|
||
|
dc.b $12, $00, $00, $90, $12, $00, $00, $90, $12, $00, $00, $90, $12, $11, $10, $90
|
||
|
dc.b $12, $11, $10, $90, $12, $01, $00, $90, $12, $01, $00, $90, $12, $03, $00, $90
|
||
|
dc.b $12, $00, $00, $90, $12, $00, $00, $90, $12, $00, $00, $90, $12, $00, $00, $90
|
||
|
dc.b $12, $00, $00, $90, $11, $FF, $FF, $10, $10, $00, $00, $10, $10, $00, $00, $10
|
||
|
dc.b $10, $00, $00, $10, $10, $00, $00, $10, $13, $00, $3F, $10, $10, $00, $00, $10
|
||
|
dc.b $10, $00, $00, $10, $10, $00, $00, $10, $10, $00, $00, $10, $1F, $FF, $FF, $F0
|
||
|
dc.b $08, $00, $00, $20, $08, $00, $00, $20, $08, $00, $00, $20, $0F, $FF, $FF, $E0
|
||
|
ENDP
|
||
|
|
||
|
myGetMask PROC EXPORT
|
||
|
|
||
|
dc.b $0F, $FF, $FF, $E0, $1F, $FF, $FF, $F0, $1F, $FF, $FF, $F0, $1F, $FF, $FF, $F0
|
||
|
dc.b $1F, $FF, $FF, $F0, $1F, $FF, $FF, $F0, $1F, $FF, $FF, $F0, $1F, $FF, $FF, $F0
|
||
|
dc.b $1F, $FF, $FF, $F0, $1F, $FF, $FF, $F0, $1F, $FF, $FF, $F0, $1F, $FF, $FF, $F0
|
||
|
dc.b $1F, $FF, $FF, $F0, $1F, $FF, $FF, $F0, $1F, $FF, $FF, $F0, $1F, $FF, $FF, $F0
|
||
|
dc.b $1F, $FF, $FF, $F0, $1F, $FF, $FF, $F0, $1F, $FF, $FF, $F0, $1F, $FF, $FF, $F0
|
||
|
dc.b $1F, $FF, $FF, $F0, $1F, $FF, $FF, $F0, $1F, $FF, $FF, $F0, $1F, $FF, $FF, $F0
|
||
|
dc.b $1F, $FF, $FF, $F0, $1F, $FF, $FF, $F0, $1F, $FF, $FF, $F0, $1F, $FF, $FF, $F0
|
||
|
dc.b $0F, $FF, $FF, $E0, $0F, $FF, $FF, $E0, $0F, $FF, $FF, $E0, $0F, $FF, $FF, $E0
|
||
|
ENDP
|
||
|
|
||
|
END
|