mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-25 09:30:50 +00:00
1631 lines
62 KiB
Plaintext
1631 lines
62 KiB
Plaintext
|
;_______________________________________________________________________________________
|
|||
|
;
|
|||
|
; File: SlotMgrInit.a
|
|||
|
;
|
|||
|
; Contains: This file contains all the slot manager initialization routines. The routines
|
|||
|
; in this file are used for the ROM version, the 32bit QuickDraw INIT version,
|
|||
|
; and the system patch version(for Mac II's, IIx's, IIcx's, and Mac SE/30's).
|
|||
|
; When this code is used in RAM, it is cut back after executing.
|
|||
|
;
|
|||
|
; Written by: David Wong, September 17, 1989
|
|||
|
;
|
|||
|
; Copyright: © 1989-1993 by Apple Computer, Inc., all rights reserved.
|
|||
|
;
|
|||
|
; Change History (most recent first):
|
|||
|
;
|
|||
|
; <SM15> 9/12/93 pdw Removed a push,SwapMMU,pop sequence.
|
|||
|
; <SM14> 9/1/93 SKH Fixed a bug where only LastSDMSelts were being allocated in the dispatch
|
|||
|
; table.
|
|||
|
; <SM13> 8/4/93 GMR RC: Added code to enable slave block transfers for BART machines
|
|||
|
; (PDM,CF).
|
|||
|
; <SM12> 6/14/93 kc Roll in Ludwig.
|
|||
|
; <LW2> 3/24/93 mal Added EnableBlockXfer after PrimaryInit for each slot.
|
|||
|
; EnableBlockXfer sets bits in a MUNI register if slot has block
|
|||
|
; xfer sRsrcs indicating it supports block xfers.
|
|||
|
; <SM11> 11/17/92 kc Add "IF NOT LC930 THEN" around patchPrimaryInit to facilitate
|
|||
|
; dead code stripping for the LC930 build.
|
|||
|
; <SM10> 10/14/92 CSS Change some branch short instructions to branches.
|
|||
|
; <SM9> 09-24-92 jmp Added a pRAM-based mechanism for skipping BootBug altogether if
|
|||
|
; it is installed.
|
|||
|
; <SM8> 08-27-92 jmp Added support for Brigent, Inc.’s BootBug card.
|
|||
|
; <SM7> 6/30/92 kc Roll in Horror, comments follow:
|
|||
|
; • From SlotMgr.a
|
|||
|
; <H5> djw Add new selector for DoSecondaryInit.
|
|||
|
; • From SlotMgrPatch.a
|
|||
|
; <H11> djw Added DoSecondaryInit routine.
|
|||
|
; <SM6> 5/16/92 kc Roll in Horror changes. Comments follow:
|
|||
|
; Note: This is going to take some work for the system build but
|
|||
|
; it is likely to change so we might want to hold off awhile.
|
|||
|
; • From SlotMgr.a
|
|||
|
; <H3> 3/18/92 djw Add new calls to support docking code - AddCard, RemoveCard,
|
|||
|
; CheckSlot, and GetSRTEntry.
|
|||
|
; <H2> 3/5/92 djw Replaced InitSlotMgr, InitsRsrcTable, InitPRAMRecs, and
|
|||
|
; Primary_Init entries in the table with new routines.
|
|||
|
; • From SlotMgrPatch.a
|
|||
|
; <H5> 02/05/92 jmp Unfortunately, I put some tables in the middle of this file
|
|||
|
; that, in Cyclone, will get bigger. So, I moved them from the
|
|||
|
; middle of the file into the pad space. Also, I generalized the
|
|||
|
; routine that decides whether a DeclROM’s PrimaryInit/Driver
|
|||
|
; should be patched by not stopping once I found the version I was
|
|||
|
; looking for (e.g., in case we need to patch out versions 1, 2,
|
|||
|
; and 3 of the 8•24 card).
|
|||
|
; <H2> 10/22/91 SAM/jmp Discontinued patching out the JMFB PrimaryInit & Driver on the
|
|||
|
; Bungee (1.1) version of the 4•8/8•24 Card ROM. From Zydeco-TERROR ROM.
|
|||
|
; <T6> 2/25/91 jmp Added code to check version number of the driver before doing
|
|||
|
; PrimaryInit and GetDriver patches.
|
|||
|
; <T3> 11/19/90 jmp Added in patches for PrimaryInit and GetDriver.
|
|||
|
; • From SlotInfo.a
|
|||
|
; <H5> 3/18/92 djw Add stub entry points for new docking support routines -
|
|||
|
; StubAddCard and StubRemoveCard
|
|||
|
; <H4> 3/6/92 SWC We thank Dave for <H3> (getting it working in under 25 tries…),
|
|||
|
; and move the Docking Manager initialization to StartSDeclMgr
|
|||
|
; just before running the primary inits so that we can decided
|
|||
|
; whether or not to install the built-in LCD driver when DBLite
|
|||
|
; (etc.) is inside a docking station and thus the LCD screen is
|
|||
|
; not useable.
|
|||
|
; <H3> 3/5/92 djw Rewrote slot manager initialization code (major routines from
|
|||
|
; beginning of file to SecondaryInit) to facilitate new code for
|
|||
|
; DBLite docking station. The major change was to modify the
|
|||
|
; routines to execute their functions for a single slot instead of
|
|||
|
; for every slot.
|
|||
|
; <H2> 10/29/91 jmp Added a patch to the VerifySlot routine for supporting super
|
|||
|
; sRsrc directories in Slot $0.
|
|||
|
; <SM5> 5/5/92 JSM Roll-in changes from Reality:
|
|||
|
; <17> 5/4/92 JSM The checks for isUniversal in this file should just be forROM.
|
|||
|
; (Dean really didn’t have to do all that work in <14>).
|
|||
|
; <SM4> 2/21/92 RB delete rude code which snuck in late at night while no one was
|
|||
|
; looking…
|
|||
|
; <SM3> 2/12/92 RM Change BRA.S to BRA.L.
|
|||
|
; <SM2> 2/11/92 RB Fixed InitPRamRecs. It was not working right on the Quadras due
|
|||
|
; to a confusing situation caused when using forROM, and NOT
|
|||
|
; forROM in diferent places of the same routine. I hate
|
|||
|
; them...conditionals.
|
|||
|
; <15> 1/7/92 RB Rolled in Terror changes.
|
|||
|
; <14> 8/30/91 DTY Define isUniversal here since it’s no longer defined in
|
|||
|
; BBSStartup.
|
|||
|
; <13> 6/12/91 LN removed #include 'HardwareEqu.a'
|
|||
|
; <12> 12/10/90 BBM (dba) Eliminate cutback code now that this is a linked patch.
|
|||
|
; <11> 8/17/90 DTY Dean screws up the ROM build again. Have the ROM build use the
|
|||
|
; SeparateFile code. Merge the two jump tables into one, and use a
|
|||
|
; macro to decide which format to use.
|
|||
|
; <10> 8/17/90 DTY Made second copy of SDMJumpTable which uses dcImportResident for
|
|||
|
; system patch case. (Darin said I could check it in.)
|
|||
|
; <9> 7/30/90 BG Removed CPU = 040 conditional in preparation for moving from
|
|||
|
; Mac040 to Mac32 build.
|
|||
|
; <8> 6/29/90 djw Fix bug in InitPRAMRecs where there is only a slot zero if
|
|||
|
; "hasRBV" is set. Rewrote primaryInit to execute slot zero's
|
|||
|
; before any other slots. Moved SecondaryInit code here, so it
|
|||
|
; would be cut back. Added call to ReconfigVideo into
|
|||
|
; SecondaryInit for patch version. Added code into SecondaryInit
|
|||
|
; to cutback itself when done (for 7.0 patch).
|
|||
|
; <7> 4/5/90 djw Fix bug introduced in non-universal version of code in routine
|
|||
|
; alloc_sInfo
|
|||
|
; <6> 4/2/90 djw Modify Alloc_sInfo to scan only enabled slots using universal
|
|||
|
; tables.
|
|||
|
; <5> 3/15/90 djw Moved code in InitJmpTbl to slotmgrpatch.a which was only used
|
|||
|
; for the patch version. Fixed InitPramRecs bug where I was
|
|||
|
; writting a bad board id when init-ing the pram rec.
|
|||
|
; <4> 1/21/90 BG Added code to modify the JmpTbl entry for the SlotMgr Bus Error
|
|||
|
; Exception Handler to be the 040 bus error exception handler if
|
|||
|
; we are running on an 040.
|
|||
|
; <3> 1/17/90 djw Modified init code so same source could be used in RAM and ROM.
|
|||
|
; Modify InitJmpTbl to install slot mgr A-trap if in RAM. Add code
|
|||
|
; back to initjmptbl to install slot mgr trap if a patch. Moved
|
|||
|
; SecondaryInit and GetBoard to SlotMgr.a - added them to jump
|
|||
|
; table.
|
|||
|
; <2> 1/11/90 CCH Added include of “HardwarePrivateEqu.a”.
|
|||
|
; <1.1> 10/10/89 djw removed code in initjmptbl which installed the slot mgr trap if
|
|||
|
; a patch.
|
|||
|
; <1.0> 9/18/89 djw New file combining all slotmgr initialization code for sharing
|
|||
|
; with system 7.0 patch.
|
|||
|
;
|
|||
|
;_______________________________________________________________________________________
|
|||
|
|
|||
|
Machine MC68020
|
|||
|
String Asis
|
|||
|
Print Off
|
|||
|
LOAD 'StandardEqu.d'
|
|||
|
Include 'HardwarePrivateEqu.a'
|
|||
|
Include 'RomEqu.a'
|
|||
|
Include 'UniversalEqu.a'
|
|||
|
Include 'SlotMgrEqu.a'
|
|||
|
Include 'ComVideoEqu.a' ; <15> rb
|
|||
|
Print On
|
|||
|
|
|||
|
|
|||
|
IMPORT ReadSlotByte
|
|||
|
IMPORT ReadSlotWord
|
|||
|
IMPORT ReadSlotLong
|
|||
|
IMPORT GetcString
|
|||
|
IMPORT GetSlotBlock
|
|||
|
IMPORT FindSlotStruct
|
|||
|
IMPORT ReadSlotStruct
|
|||
|
IMPORT SlotVersion
|
|||
|
IMPORT InsertSRT
|
|||
|
IMPORT SetsRsrcState
|
|||
|
|
|||
|
IMPORT ReadSlotInfo
|
|||
|
IMPORT ReadSlotPRAM
|
|||
|
IMPORT PutSlotPRAM
|
|||
|
IMPORT ReadFHeader
|
|||
|
IMPORT NextsRsrc
|
|||
|
IMPORT NextTypesRsrc
|
|||
|
IMPORT SlotRsrcInfo
|
|||
|
IMPORT SlotDisposPtr
|
|||
|
IMPORT CkCardStat
|
|||
|
IMPORT ReadSlotDrvrName
|
|||
|
IMPORT FindDevBase
|
|||
|
IMPORT GetsRsrc
|
|||
|
IMPORT GetTypesRsrc
|
|||
|
IMPORT FindSRTRec
|
|||
|
|
|||
|
IMPORT CardChanged
|
|||
|
IMPORT SlotExec
|
|||
|
IMPORT OffsetData
|
|||
|
IMPORT ReadPBSize
|
|||
|
IMPORT CalcStep
|
|||
|
IMPORT SearchSRT
|
|||
|
IMPORT UpdateSRT
|
|||
|
IMPORT CalcsPointer
|
|||
|
IMPORT GetSlotDrvr
|
|||
|
IMPORT PtrToSlot
|
|||
|
IMPORT FindsInfoRecPtr
|
|||
|
IMPORT DeleteSRTRec
|
|||
|
IMPORT InitSlotPRAM
|
|||
|
IMPORT FindsRsrcPtr
|
|||
|
IMPORT GetsRsrcPtr
|
|||
|
|
|||
|
IMPORT pNewSRTEntry
|
|||
|
IMPORT pInitEntry
|
|||
|
IMPORT pSrToSpBlock
|
|||
|
IMPORT pRead4Bytes
|
|||
|
IMPORT pBusException
|
|||
|
IMPORT pInstallBus
|
|||
|
IMPORT pRestoreBus
|
|||
|
IMPORT pAllocSRTBlk
|
|||
|
|
|||
|
IMPORT GetSRTEntry ; <h3> djw
|
|||
|
|
|||
|
IMPORT SlotEmpty ; <djw>
|
|||
|
IMPORT pGetBoard ; <3>
|
|||
|
|
|||
|
IMPORT SlotManager ; <3>
|
|||
|
IMPORT p040BusException ; <4>
|
|||
|
|
|||
|
EXPORT InitsInfo,InitPrimary,InitsPram,InitsRsrc,InitsInfo
|
|||
|
EXPORT Secondary_Init,StubCheckSlot,StubAddCard,StubRemoveCard,SDMJmpTable
|
|||
|
EXPORT DoSecondaryInit
|
|||
|
|
|||
|
If (&TYPE('SeparateFile') = 'UNDEFINED') Then ; equ indicating whether we are <3>
|
|||
|
SeparateFile Equ 0 ; ... building for 32bit QD INIT
|
|||
|
Endif ; ... or as a system patch
|
|||
|
|
|||
|
If (&TYPE('forAUX') = 'UNDEFINED') Then ; equ indicating whether we are <8>
|
|||
|
forAUX Equ 0 ; ... building for an A/UX patch
|
|||
|
Endif
|
|||
|
|
|||
|
if not(forAUX) then
|
|||
|
Include 'LinkedPatchMacros.a'
|
|||
|
endif
|
|||
|
|
|||
|
Macro
|
|||
|
DispatchVector &ROMAddress
|
|||
|
if SeparateFile or forAUX or forROM then
|
|||
|
dc.w &ROMAddress-*
|
|||
|
else
|
|||
|
dcImportResident &ROMAddress
|
|||
|
endif
|
|||
|
EndM
|
|||
|
|
|||
|
;_______________________________________________________________________________________ <1.6>
|
|||
|
; InitJmpTbl - initialize the slot manager's secondary dispatch table
|
|||
|
;
|
|||
|
; Build the slot manager's jump table in RAM, from the ROM table.
|
|||
|
;
|
|||
|
; Input : none
|
|||
|
;
|
|||
|
; Output :
|
|||
|
;
|
|||
|
|
|||
|
InitJmpTbl Proc Export
|
|||
|
|
|||
|
IF SeparateFile or forAUX or forROM then
|
|||
|
|
|||
|
movem.l a0-a2,-(sp)
|
|||
|
|
|||
|
; SKH, was only allocating lastsdmselt's
|
|||
|
|
|||
|
move.l #(LastSDMSelt + 1)*4,D0 ; alloc new jmp tbl <SM14>
|
|||
|
_NewPtr ,SYS,CLEAR
|
|||
|
move.l a0,SDMJmpTblPtr ; put in low mem
|
|||
|
|
|||
|
; Convert ROM table offsets to address vectors for RAM jump table
|
|||
|
|
|||
|
; SKH, was only copying the first LastSDMSelt-1 elements
|
|||
|
|
|||
|
moveq #LastSDMSelt,d0 ; d0 = number entries in jump tbl <SM14>
|
|||
|
lea SDMJmpTable,A1 ; A1 = addr of ROM jump tbl
|
|||
|
|
|||
|
@Loop
|
|||
|
movea.l a1,a2 ; a2 = current base to calc addr from
|
|||
|
adda.w (a1)+,a2 ; a2 = add offset to base
|
|||
|
move.l a2,(a0)+ ; move vector to RAM jump tbl
|
|||
|
dbra d0,@Loop
|
|||
|
|
|||
|
cmpi.b #cpu68040,CpuFlag ; are we running on an 040? <4>
|
|||
|
bne.s @notAn040 ; NO ... we're done <4>
|
|||
|
lea p040BusException,a0 ; YES ... retrieve address of 040 handler <4>
|
|||
|
move.l a0,([SDMJmpTblPtr],BusException*4) ; replace bus error handler with 040 version <4>
|
|||
|
@notAn040 ; <4>
|
|||
|
movem.l (sp)+,a0-a2
|
|||
|
moveq #0,d0
|
|||
|
rts
|
|||
|
|
|||
|
ELSE ; Not SeparateFile or forAUX or forROM then
|
|||
|
|
|||
|
movem.l a0-a2,-(sp)
|
|||
|
|
|||
|
leaResident SDMJmpTable,a0 ; Load up the jump table
|
|||
|
move.l a0,SDMJmpTblPtr ; Stash it in lowmem
|
|||
|
|
|||
|
movem.l (sp)+,a0-a2
|
|||
|
moveq #0,d0
|
|||
|
rts
|
|||
|
|
|||
|
ENDIF ; SeparateFile or forAUX or forROM then
|
|||
|
|
|||
|
|
|||
|
|
|||
|
;_______________________________________________________________________________________ <1.6>
|
|||
|
; ROM Jump table
|
|||
|
;
|
|||
|
|
|||
|
SDMJmpTable Proc
|
|||
|
|
|||
|
DispatchVector ReadSlotByte ;$00
|
|||
|
DispatchVector ReadSlotWord ;$01
|
|||
|
DispatchVector ReadSlotLong ;$02
|
|||
|
DispatchVector GetcString ;$03
|
|||
|
DispatchVector SlotEmpty ;$04
|
|||
|
DispatchVector GetSlotBlock ;$05
|
|||
|
DispatchVector FindSlotStruct ;$06
|
|||
|
DispatchVector ReadSlotStruct ;$07
|
|||
|
DispatchVector SlotVersion ;$08 <1.2>
|
|||
|
DispatchVector SetsRsrcState ;$09 <1.2>
|
|||
|
DispatchVector InsertSRT ;$0A <1.2>
|
|||
|
DispatchVector GetsRsrc ;$0B <1.2>
|
|||
|
DispatchVector GetTypesRsrc ;$0C <1.2>
|
|||
|
DispatchVector SlotEmpty ;$0D
|
|||
|
DispatchVector SlotEmpty ;$0E
|
|||
|
DispatchVector DoSecondaryInit ;$0F <H5>
|
|||
|
|
|||
|
|
|||
|
; Specialized
|
|||
|
DispatchVector ReadSlotInfo ;$10
|
|||
|
DispatchVector ReadSlotPRAM ;$11
|
|||
|
DispatchVector PutSlotPRAM ;$12
|
|||
|
DispatchVector ReadFHeader ;$13
|
|||
|
DispatchVector NextsRsrc ;$14
|
|||
|
DispatchVector NextTypesRsrc ;$15
|
|||
|
DispatchVector SlotRsrcInfo ;$16
|
|||
|
DispatchVector SlotDisposPtr ;$17
|
|||
|
DispatchVector CkCardStat ;$18
|
|||
|
DispatchVector ReadSlotDrvrName ;$19
|
|||
|
DispatchVector FindSRTRec ;$1A <1.2>
|
|||
|
DispatchVector FindDevBase ;$1B
|
|||
|
DispatchVector FindDevBase ;$1C map findbigdevbase to finddevbase <1.6>
|
|||
|
DispatchVector GetsRsrcPtr ;$1D <1.3>
|
|||
|
DispatchVector StubAddCard ;$1E <h3> djw
|
|||
|
DispatchVector StubRemoveCard ;$1F <h3> djw
|
|||
|
|
|||
|
|
|||
|
; Advanced (SDM private routines).
|
|||
|
DispatchVector InitsInfo ;$20 <h2> djw
|
|||
|
DispatchVector InitPrimary ;$21 <h2> djw
|
|||
|
DispatchVector CardChanged ;$22
|
|||
|
DispatchVector SlotExec ;$23
|
|||
|
DispatchVector OffsetData ;$24
|
|||
|
DispatchVector InitsPram ;$25 <h2> djw
|
|||
|
DispatchVector ReadPBSize ;$26
|
|||
|
DispatchVector StubCheckSlot ;$27 <h3> djw
|
|||
|
DispatchVector CalcStep ;$28
|
|||
|
DispatchVector InitsRsrc ;$29 <h2> djw
|
|||
|
DispatchVector SearchSRT ;$2A
|
|||
|
DispatchVector UpdateSRT ;$2B
|
|||
|
DispatchVector CalcsPointer ;$2C
|
|||
|
DispatchVector GetSlotDrvr ;$2D
|
|||
|
DispatchVector PtrToSlot ;$2E
|
|||
|
DispatchVector FindsInfoRecPtr ;$2F
|
|||
|
DispatchVector FindsRsrcPtr ;$30
|
|||
|
DispatchVector DeleteSRTRec ;$31
|
|||
|
DispatchVector Secondary_Init ;$32 <3>
|
|||
|
DispatchVector InitSlotPRAM ;$33 <v1.5>
|
|||
|
|
|||
|
; New private routines - vectored to (not through the trap dispatcher)
|
|||
|
|
|||
|
DispatchVector pNewSRTEntry ;$34
|
|||
|
DispatchVector pInitEntry ;$35
|
|||
|
DispatchVector pSrToSpBlock ;$36
|
|||
|
DispatchVector pRead4Bytes ;$37
|
|||
|
DispatchVector pGetBoard ;$38 <3>
|
|||
|
DispatchVector pBusException ;$39
|
|||
|
DispatchVector pInstallBus ;$3A
|
|||
|
DispatchVector pRestoreBus ;$3B
|
|||
|
DispatchVector pAllocSRTBlk ;$3C
|
|||
|
DispatchVector GetSRTEntry ;$3D <h3> djw
|
|||
|
|
|||
|
;=======================================================================================
|
|||
|
; Re-wrote the following old routines:
|
|||
|
; StartSDeclMgr
|
|||
|
; InitSlotMgr
|
|||
|
; InitsRsrcTable
|
|||
|
; InitPRAMRecs
|
|||
|
; Primary_Init
|
|||
|
;
|
|||
|
; ...into these new routines:
|
|||
|
; StartSDeclMgr
|
|||
|
; AllocSlot
|
|||
|
; InitsInfo
|
|||
|
; InitsRsrc
|
|||
|
; InitsPram
|
|||
|
; InitPrimary
|
|||
|
;
|
|||
|
; The major rewrite of the slot manager initialization code was to go from each routine
|
|||
|
; executing a single function for all slot, to routines which would only execute the
|
|||
|
; function for a given slot. This change was to facilitate slot manager changes for
|
|||
|
; DBLite to accomodate their docking module. The end resulting data structures are
|
|||
|
; not changed from the previous slot manager version.
|
|||
|
;=======================================================================================
|
|||
|
|
|||
|
;_______________________________________________________________________________________ <h3> djw
|
|||
|
; StartSDeclMgr - start the slot manager
|
|||
|
;
|
|||
|
; Initialize the slot manager. Create the sInfo and the slot resource table. Load
|
|||
|
; and init any slot PRAM records, and load and execute any primary init records.
|
|||
|
; This routine is called from startinit.a
|
|||
|
;
|
|||
|
; Input : none
|
|||
|
; Output : d0 = status
|
|||
|
;
|
|||
|
|
|||
|
Proc
|
|||
|
Export StartSDeclMgr
|
|||
|
Import InitJmpTbl, InitDocking
|
|||
|
with spBlock,sInfoRecord,FHeaderRec,slotGlobals,seBlock
|
|||
|
|
|||
|
StartSDeclMgr
|
|||
|
sub.w #spBlockSize,sp ; allocate spBlock
|
|||
|
movea.l sp,a0 ; setup a0 = ptr to spBlock
|
|||
|
|
|||
|
jsr InitJmpTbl ; create the slot manager's dispatch table
|
|||
|
bne @Done
|
|||
|
|
|||
|
bsr AllocSlot ; allocate all the slot manager data structures
|
|||
|
bne @Done
|
|||
|
|
|||
|
; For all the slots, determine its status, verify its format record, log its
|
|||
|
; sResources, initialize the PRAM for the slot.
|
|||
|
|
|||
|
moveq.l #sLastSlot,d1 ; d1 = slot loop counter from last slot
|
|||
|
@Loop
|
|||
|
move.b d1,spSlot(a0) ; set slot number
|
|||
|
bsr InitsInfo ; initialize the sInfo table
|
|||
|
bsr InitsRsrc ; initialize the slot resource table (SRT)
|
|||
|
bsr InitsPram ; initial a slot's PRAM
|
|||
|
dbra d1,@Loop
|
|||
|
|
|||
|
; Initialize the Docking Manager so built-in video and docking cards can use its facilities
|
|||
|
|
|||
|
BSR.L InitDocking ; initialize the Docking Manager <H4>
|
|||
|
|
|||
|
; Set up the warm/cold start flag for later. <SM8>
|
|||
|
|
|||
|
Moveq.l #0,D2 ; D2 = flag for cold start.
|
|||
|
Cmpi.l #WmStConst,WarmStart ; Check low mem for warm start value.
|
|||
|
Bne.s @Continue ; Cold start.
|
|||
|
Bset.l #fWarmStart,D2 ; Warm start.
|
|||
|
|
|||
|
@Continue
|
|||
|
|
|||
|
; Determine if there’s a BootBug card installed or not. If one is installed,
|
|||
|
; execute it first. Otherwise, just run the normal sequence.
|
|||
|
|
|||
|
Clr.b -(Sp) ; Initialize our “savedSlot” space.
|
|||
|
|
|||
|
Clr.b spSlot(A0) ; Start with Slot $0.
|
|||
|
Clr.b spID(A0) ; Begin search with ID 0.
|
|||
|
Clr.b spExtDev(A0) ; No external device(s).
|
|||
|
Clr.b spTBMask(A0) ; No mask in search.
|
|||
|
Move.w #CatProto,spCategory(A0) ; Look for: Proto,
|
|||
|
Move.w #TypDebugger,spCType(A0) ; Debugger,
|
|||
|
Move.w #DrSwMacsBug,spDrvrSW(A0) ; MacsBug,
|
|||
|
Move.w #DrHwBootBug,spDrvrHW(A0) ; BootBug.
|
|||
|
Clr.l spParamData(A0) ; Clear the flags field.
|
|||
|
Ori.b #(1<<fNext),spParamData+3(A0) ; Search for the 1st one.
|
|||
|
_GetTypeSRsrc ; If we don’t find a BootBug card
|
|||
|
Bne.s @DoZeroFirst ; then just run the normal sequence.
|
|||
|
Move.b spSlot(A0),(Sp) ; Remember which slot has BootBug in it.
|
|||
|
|
|||
|
Move.l A0,-(Sp) ; Save SpBlockPtr. <H15>
|
|||
|
Subq #4,Sp ; Make a pRAM buffer on the stack.
|
|||
|
Move.l Sp,A0 ; Point to it.
|
|||
|
Move.l #$000400FC,D0 ; Set up to read 4 bytes starting at $FC.
|
|||
|
_ReadXPRAM ; Read ’em.
|
|||
|
Move.l (Sp)+,D0 ; Get the result, release buffer.
|
|||
|
Move.l (Sp)+,A0 ; Restore SpBlockPtr.
|
|||
|
Cmpi.l #'Skip',D0 ; If the BootBug skip signature is set,
|
|||
|
Beq.s @DoZeroFirst ; then skip it.
|
|||
|
|
|||
|
; Now, go execute all the PrimaryInits as usual, except run the BootBug PrimaryInit
|
|||
|
; first.
|
|||
|
|
|||
|
Move.b D2,spFlags(A0) ; Set flag for warm or cold start.
|
|||
|
Bsr InitPrimary ; Execute the PrimaryInit.
|
|||
|
|
|||
|
@DoZeroFirst
|
|||
|
Clr.b spSlot(A0) ; Set slot 0.
|
|||
|
Move.b D2,spFlags(A0) ; Set flag for warm or cold start.
|
|||
|
Bsr InitPrimary ; Execute the PrimaryInit.
|
|||
|
|
|||
|
Moveq.l #sLastSlot,D1 ; D1 = slot loop counter from last slot.
|
|||
|
@Loop1
|
|||
|
Move.b D1,spSlot(A0) ; Set the Slot number.
|
|||
|
Cmp.b (Sp),D1 ; If this is the BootBug slot,
|
|||
|
Beq.s @Skip ; then skip it this time.
|
|||
|
|
|||
|
Move.b D2,spFlags(A0) ; Set flag for warm or cold start.
|
|||
|
Bsr InitPrimary ; Execute the PrimaryInit.
|
|||
|
|
|||
|
Bsr EnableBlockXfer ; Enable block xfer, if this slot is capable <LW2>
|
|||
|
|
|||
|
@Skip Subq.b #1,D1
|
|||
|
Bne.s @Loop1 ; Continue for all slots.
|
|||
|
|
|||
|
Tst.b (Sp)+ ; Free up “savedSlot” space.
|
|||
|
@Done
|
|||
|
Add.w #spBlockSize,Sp ; Free SpBlock.
|
|||
|
Moveq.l #noErr,D0 ; Return noErr.
|
|||
|
Rts ; <SM8>
|
|||
|
|
|||
|
|
|||
|
;_______________________________________________________________________________________ <h3> djw
|
|||
|
; AllocSlot - allocate slot manager data structures
|
|||
|
;
|
|||
|
; Allocate the slot manager globals, the sInfo table, the sInfoRecords for disabled
|
|||
|
; and reserved slots, and the first block of sRsrcRecords for the SRT.
|
|||
|
;
|
|||
|
; Input : a0 = ptr to spBlock
|
|||
|
; Output : d0 = status ccr reflects status
|
|||
|
;
|
|||
|
|
|||
|
AllocSlot
|
|||
|
@regs reg a0-a1
|
|||
|
movem.l @regs,-(sp) ; save registers
|
|||
|
|
|||
|
; Allocate the necessary memory as one contiguous block
|
|||
|
|
|||
|
move.l #(slotGlobalSize \ ; size of globals
|
|||
|
+(4*TotalSlots) \ ; size of sInfor vector table
|
|||
|
+(3*sInfoNewSize) \ ; size of 3 sInfoRecords (disabled,reserved,empty)
|
|||
|
),d0 ; d0 = number of bytes to alloc
|
|||
|
_NewPtr ,sys,clear ; alloc block
|
|||
|
bne.s @Done ; some error - done
|
|||
|
|
|||
|
adda.w #slotGlobalSize,a0 ; globals are at a negative offset from sInfo tbl
|
|||
|
move.l a0,sInfoPtr ; set ptr to sInfo table
|
|||
|
|
|||
|
; There are three special sInfoRecords which we are setting up. These records are shared by
|
|||
|
; all slots which have a disabled, reserved, or empty status. The records are shared because
|
|||
|
; the sInfoTable is mainly empty and there is no sense wasting an sInfoRecord. The two
|
|||
|
; records are at the end of the sInfoTable: first the disabled, followed by the reserved,
|
|||
|
; followed by the empty.
|
|||
|
|
|||
|
lea 4*TotalSlots(a0),a0 ; inc a0 past sInfoTable to disable sInfoRecord
|
|||
|
move.w #smDisabledSlot, \
|
|||
|
siInitStatusA(a0) ; set slot status to disabled
|
|||
|
lea sInfoNewSize(a0),a0 ; inc a0 to reserved sInfoRecord
|
|||
|
move.w #smReservedSlot, \
|
|||
|
siInitStatusA(a0) ; set slot status to reserved
|
|||
|
lea sInfoNewSize(a0),a0 ; inc a0 to empty sInfoRecord
|
|||
|
move.w #smEmptySlot, \
|
|||
|
siInitStatusA(a0) ; set slot status to reserved
|
|||
|
|
|||
|
; Allocate the first SRT block.
|
|||
|
|
|||
|
slotjsr AllocSRTBlk ; return a1 = ptr to blk
|
|||
|
move.l a1,sRsrcTblPtr ; save ptr in low mem
|
|||
|
move.l a1,([sInfoPtr],lastSRTPtr) ; set ptr to last entry in SRT
|
|||
|
|
|||
|
@Done
|
|||
|
tst.w d0 ; return err in ccr
|
|||
|
movem.l (sp)+,@regs
|
|||
|
rts
|
|||
|
|
|||
|
|
|||
|
;_______________________________________________________________________________________ <h3> djw
|
|||
|
; InitsInfo - init a slot's sinfoRecord
|
|||
|
;
|
|||
|
; Check the NuBus info in the universal tables to see if the given slot is enabled.
|
|||
|
; If so, then scan the slot to determine whether it is occupied or empty. If occupied,
|
|||
|
; then verify the declaration ROM.
|
|||
|
;
|
|||
|
; Input : a0 = ptr to spBlock
|
|||
|
; Output : none
|
|||
|
;
|
|||
|
; spBlock : -> spSlot slot number
|
|||
|
Export InitsInfo
|
|||
|
InitsInfo
|
|||
|
@regs reg d1/a0-a3
|
|||
|
movem.l @regs,-(sp)
|
|||
|
|
|||
|
moveq.l #0,d1
|
|||
|
move.b spSlot(a0),d1 ; d1 = slot number in question
|
|||
|
movea.l sInfoPtr,a1 ; a1 = ptr to beginning of sInfoTable
|
|||
|
|
|||
|
; Check if the slot is enabled in the universal tables. The two currently defined
|
|||
|
; states are enabled (no bit set), disabled (do no scan), and reserved (hack for VM
|
|||
|
; to disable VM from looking into slot's address space. Previously, VM ignored
|
|||
|
; the disabled error).
|
|||
|
|
|||
|
movea.l a1,a3
|
|||
|
lea 4*TotalSlots(a3),a3 ; a3 = ptr to disabled sInfoRecord
|
|||
|
move.l a3,(a1,d1.w*4) ; set slot pointing to disabled record
|
|||
|
|
|||
|
with NuBusInfo
|
|||
|
movea.l UnivInfoPtr,a2
|
|||
|
adda.l ProductInfo.NuBusInfoPtr(a2),a2 ; a2 = ptr to universal slot info tbl
|
|||
|
btst.b #slotDisabled,(a2,d1.w) ; test if slot is disabled
|
|||
|
bne @Done
|
|||
|
lea sInfoNewSize(a3),a3 ; a3 = ptr to reserved record
|
|||
|
move.l a3,(a1,d1.w*4) ; set slot pointing to reserved record
|
|||
|
btst.b #slotReserved,(a2,d1.w) ; test if the slot is reserved
|
|||
|
bne @Done ; <SM10> CSS
|
|||
|
endwith
|
|||
|
|
|||
|
; The slot is enabled for use. Initially, set the slot to point to the empty sInfoRecord.
|
|||
|
|
|||
|
lea sInfoNewSize(a3),a3 ; a3 = ptr to empty record
|
|||
|
move.l a3,(a1,d1.w*4) ; set slot pointing to empty record
|
|||
|
|
|||
|
; If this is slot zero, then special case the declaration ROM address
|
|||
|
|
|||
|
tst.b d1 ; slot 0 ?
|
|||
|
bne.s @doRead ; not slot 0
|
|||
|
movea.l RomBase,a3 ; get base of rom
|
|||
|
adda.l ROMHeader.RomSize(a3),a3 ; a3 = addr of end of ROM
|
|||
|
suba.l #1,a3 ; adjust to last byte in ROM
|
|||
|
bra.s @Verify ; verify slot 0
|
|||
|
|
|||
|
; Do a nubus read to see if the slot is occupied. If it is, then when we
|
|||
|
; read, we will not get a bus error.
|
|||
|
|
|||
|
@doRead
|
|||
|
moveq.l #-1,d0
|
|||
|
bfins d1,d0{4,4} ; inset slot number to get $fsffffff
|
|||
|
movea.l d0,a3 ; a3 = minor space nubus addr for slot
|
|||
|
lea @Empty,a2 ; a2 = addr to go if bus error occurs
|
|||
|
slotjsr InstallBus ; replace bus excptn, 32 bit mode
|
|||
|
move.b (a3),d0 ; NUBUS READ - read byte from minor space
|
|||
|
slotjsr RestoreBus ; restore mmu state and bus exception vector
|
|||
|
bra.s @Verify ; slot is occupied - verify config rom
|
|||
|
@Empty
|
|||
|
slotjsr RestoreBus ; restore mmu state and bus exception vector
|
|||
|
bra.s @Done
|
|||
|
|
|||
|
|
|||
|
; The slot is not empty. Allocate an sInfoRecord for it and verify the card.
|
|||
|
; a0 = ptr to spBlock, a1 = ptr to sInfoTable, a3 = ptr to top of config rom
|
|||
|
|
|||
|
@Verify
|
|||
|
movea.l a0,a2 ; save ptr to spBlock
|
|||
|
move.l #sInfoNewSize,d0 ; size of sInfoRecord
|
|||
|
_NewPtr ,sys,clear
|
|||
|
bne.s @Done ; err - leave pointing to empty record
|
|||
|
move.l a0,(a1,d1.w*4) ; set ptr in sInfo vector table
|
|||
|
movea.l a0,a1 ; a1 = ptr to sInfoRecord for this slot
|
|||
|
movea.l a2,a0 ; restore a0 = ptr to spBlock
|
|||
|
|
|||
|
move.w #retryCnt,siTOConst(a1) ; set default bus error retry cnt (not used)
|
|||
|
move.b d1,siSlot(a1) ; set slot number
|
|||
|
move.l a3,siROMAddr(a1) ; set ROM address
|
|||
|
|
|||
|
bsr.s VerifySlot ; verify the config rom format
|
|||
|
|
|||
|
@Done
|
|||
|
movem.l (sp)+,@regs
|
|||
|
rts
|
|||
|
|
|||
|
|
|||
|
;_______________________________________________________________________________________
|
|||
|
; VerifySlot - verify a slot's declaration ROM
|
|||
|
;
|
|||
|
; Verify a slot's declaration ROM. Fill in the information from the ROM format
|
|||
|
; block to the sInfo record for that card. This routine is called in 32 bit mode.
|
|||
|
;
|
|||
|
; <***Problem - at every error return, should we try the next byte lane, or do as we
|
|||
|
; do now, and just give up. Could be a case where the byte lane is
|
|||
|
; bad, but we read a valid test pattern***>
|
|||
|
;
|
|||
|
; Input : reg A0 = ptr to spBlock
|
|||
|
; A1 = ptr to sInfo record for card
|
|||
|
; Output : reg D0 = status, 0=ok CCR reflects status
|
|||
|
;
|
|||
|
; spBlock : -> spSlot slot number
|
|||
|
;
|
|||
|
Export VerifySlot
|
|||
|
With FHeaderRec
|
|||
|
|
|||
|
VerifySlot
|
|||
|
MOVEM.L D1/A2,-(SP)
|
|||
|
suba.w #fhBlockSize,sp ; alloc space for format block
|
|||
|
MOVE.L SP,A2 ; A2 = ptr to blk for format record
|
|||
|
|
|||
|
; Get the byte lane from the declaration ROM. Read in the format block and check the
|
|||
|
; test pattern. If it does not match, then the byte lane must be bad, so loop and try
|
|||
|
; another one.
|
|||
|
|
|||
|
MOVE.L A2,spResult(A0) ; pass A2 = addr to put format header
|
|||
|
moveq #3,d1 ; start with byte lane 3 <2.0>
|
|||
|
|
|||
|
@Loop BSR GetByteLane ; get a valid byte lane - return byte lane value in D1
|
|||
|
BNE VerifySlotDone ; error - no valid byte lane
|
|||
|
_sReadFHeader ; read the format header from the declaration ROM
|
|||
|
BNE.S @EndLoop ; some error - try another byte lane <1.7>
|
|||
|
|
|||
|
; Verify the ByteLanes value (by checking the Test pattern) - reg A2 = ptr to format header image
|
|||
|
|
|||
|
CMP.L #TestPattern,fhTstPat(A2)
|
|||
|
bne.s @EndLoop ; bad signature - try another byte lane <1.7>
|
|||
|
|
|||
|
; Found a valid test pattern. Now check the rest of the format block fields
|
|||
|
; and the ROM checksum.
|
|||
|
|
|||
|
BSR VerifyFormat ; chk the format blk - reg A2 = ptr to format blk image
|
|||
|
bne.s @EndLoop ; error
|
|||
|
|
|||
|
BSR VerifyCRC ; verify the ROM checksum
|
|||
|
beq.s @GoodRom ; good rom - get ptr to the sRsrc directory
|
|||
|
|
|||
|
@EndLoop sub.l #1,siROMAddr(a1) ; decrement ROM ptr to next byte lane <1.7>
|
|||
|
DBRA D1,@Loop
|
|||
|
move.w #smBLFieldBad,d0 ; error - could not find a valid byte lane
|
|||
|
BRA VerifySlotDone
|
|||
|
|
|||
|
; Get the pointer to the sResource directory from the declaration ROM and store
|
|||
|
; it in the sInfo record for future use. The directory is at an offset from the
|
|||
|
; directory offset field in the format header.
|
|||
|
EndWith ; FHeaderRec
|
|||
|
With XFHeaderRec
|
|||
|
@GoodRom
|
|||
|
VerifySlotPatch
|
|||
|
|
|||
|
Tst.b spSlot(A0) ; If we’re not looking at slot 0, then
|
|||
|
Bne @StdHeader ; just assume a standard header.
|
|||
|
|
|||
|
Move.l siROMAddr(A1),spsPointer(A0) ; Set ptr to top of ROM.
|
|||
|
Move.l #-(fhXBlockSize)+1,spOffsetData(A0) ; Set offset to beginning of extended header.
|
|||
|
Move.b siCPUByteLanes(A1),spByteLanes(A0) ; Set byte lanes field.
|
|||
|
_sCalcsPointer ; Get pointer to extended header.
|
|||
|
Bne @StdHeader ; If failed, just try standard header.
|
|||
|
|
|||
|
@SaveRegs Reg A3-A4 ; Define some work register.
|
|||
|
Movem.l @SaveRegs,-(Sp) ; Save them.
|
|||
|
Suba.l #XFHdrExtraSize,Sp ; Allocate space for extended part of FHeaderRec.
|
|||
|
Move.l Sp,A3 ; Point to it.
|
|||
|
Suba.l #seBlockSize,Sp ; Allocate space for sExec block.
|
|||
|
Move.l Sp,A4 ; Point to it.
|
|||
|
|
|||
|
Move.l A3,spResult(A0) ; Point to buffer for extra part of format block.
|
|||
|
Move.l #XFHdrExtraSize,spSize(A0) ; Number of bytes to copy.
|
|||
|
_sReadStruct ; Read extended part of header.
|
|||
|
Bne.s @FallBack ; If failed, just try the standard header.
|
|||
|
|
|||
|
Cmpi.l #TestPattern,fhXSTstPat(A3) ; If the (extended) test pattern doesn’t exist,
|
|||
|
Bne.s @FallBack ; just try the standard header.
|
|||
|
|
|||
|
Move.b fhFormat(A2),D0 ; Get the format ID of the header.
|
|||
|
Cmp.b fhXSuperInit(A3),D0 ; If not using an appropriately ID’d SuperInit,
|
|||
|
Bne.s @FallBack ; just try the standard header.
|
|||
|
|
|||
|
Move.b spSlot(A0),seSlot(A4) ; Copy the slot number.
|
|||
|
Move.b fhXSuperInit(A3),sesRsrcId(A4) ; Copy the sRsrc/format ID of the SuperInit.
|
|||
|
Move.b fhXSuperInit(A3),spID(A0) ; Make sure sExec calls the right SuperInit.
|
|||
|
Move.l A4,spsExecPBlk(A0) ; Point to the sExec param block.
|
|||
|
_SExec ; Call SuperInit.
|
|||
|
Bne.s @FallBack ; If failed, just try the standard header.
|
|||
|
|
|||
|
Tst.b seStatus(A4) ; If upper byte of seStatus is non-zero (a failure),
|
|||
|
Bne.s @FallBack ; just try the standard header.
|
|||
|
|
|||
|
Move.l siROMAddr(A1),spsPointer(A0) ; Point back to the top of ROM.
|
|||
|
Move.l fhXSDirOffset(A3),spOffsetData(A0) ; Load super directory offset.
|
|||
|
Clr.b spOffsetData(A0) ; Strip psuedo-spID byte.
|
|||
|
Add.l #XOffsetToDir,spOffsetData(A0) ; Negative offset.
|
|||
|
Move.b siCPUByteLanes(A1),spByteLanes(A0) ; Set byte-lanes field.
|
|||
|
_sCalcsPointer ; Get ptr to start of super sRsrc directory.
|
|||
|
Bne.s @FallBack ; If failed, just try standard header.
|
|||
|
|
|||
|
Move.b seStatus+1(A4),spID(A0) ; Get the id of the super sRsrc directory.
|
|||
|
_sFindStruct ; Look for it.
|
|||
|
Bne.s @FallBack ; If failed, try standard header.
|
|||
|
|
|||
|
Move.l spsPointer(A0),siDirPtr(A1) ; Set ptr to sRsrc dir in sInfo record.
|
|||
|
Adda.l #XFHdrExtraSize+seBlockSize,Sp ; Restore stack.
|
|||
|
Movem.l (Sp)+,@SaveRegs ; Restore work registers.
|
|||
|
Bra.s VerifySlotDone
|
|||
|
|
|||
|
@FallBack Adda.l #XFHdrExtraSize+seBlockSize,Sp ; Restore stack.
|
|||
|
Movem.l (Sp)+,@SaveRegs ; Restore work registers.
|
|||
|
|
|||
|
@StdHeader MOVE.L siROMAddr(A1),spsPointer(A0) ; set ptr to slot declaration ROM
|
|||
|
MOVE.L fhDirOffset(A2),spOffsetData(A0) ; get dir offset from format blk image
|
|||
|
add.l #OffsetToDir,spOffsetData(a0) ; negative offset to directory field <2.0>
|
|||
|
_sCalcsPointer ; calc ptr to directory
|
|||
|
BNE.S VerifySlotDone
|
|||
|
MOVE.L spsPointer(A0),siDirPtr(A1) ; set ptr to sRsrc dir in sInfo record
|
|||
|
|
|||
|
VerifySlotDone
|
|||
|
|
|||
|
adda.w #fhBlockSize,sp ; de-alloc space on stack
|
|||
|
MOVE D0,siInitStatusA(A1) ; set current status
|
|||
|
MOVEM.L (SP)+,D1/A2
|
|||
|
RTS ; done - VerifySlot
|
|||
|
EndWith
|
|||
|
|
|||
|
;_______________________________________________________________________________________
|
|||
|
; GetByteLane - get the byte lane field
|
|||
|
;
|
|||
|
; Read and verify the byte lane field in the format header block of a declaration ROM.
|
|||
|
; Start looking from the byte lane given. The byte lane value determines the address
|
|||
|
; in the ROM to look ($FsFFFFFF - $FsFFFFFC). This routine handles the case where reading
|
|||
|
; an unsupported bytelane field from the ROM causes a bus exception, and where it does
|
|||
|
; not.
|
|||
|
;
|
|||
|
; The byte lane field in the declaration ROM is a two nibble field. The high nibble
|
|||
|
; is the complement of the low nibble. The low nibble indicates the byte lanes
|
|||
|
; supported (0-$F).
|
|||
|
;
|
|||
|
; Input : reg D1 = byte lane to start from (0-3)
|
|||
|
; A0 = ptr to spBlock (free to use - but not used in this routine)
|
|||
|
; A1 = ptr to sInfo record for card
|
|||
|
; Output : reg D0 = status, 0=ok CCR reflects status
|
|||
|
; D1 = new byte lane value
|
|||
|
;
|
|||
|
|
|||
|
GetByteLane
|
|||
|
movem.l d2/a0/a2,-(sp) ; <2.0>
|
|||
|
MOVE.L siROMAddr(A1),A0 ; A0 = ptr to ROM
|
|||
|
|
|||
|
; Loop until a valid byte lane value is found
|
|||
|
|
|||
|
slotjsr InstallBus ; switch to 32bit mode and new bus exception <2.0>
|
|||
|
lea @EndLoop,a2 ; addr to go if bus error occurs <2.0>
|
|||
|
|
|||
|
@Loop
|
|||
|
MOVE.B (A0),D0 ; NUBUS READ - read bytelane field from ROM
|
|||
|
moveq #$0f,d2 ; <2.0>
|
|||
|
and.b d0,d2 ; mask d2=byte lane value <2.0>
|
|||
|
beq.s @EndLoop ; byte lane value cannot be zero <2.0>
|
|||
|
not.b d0 ; complement high nibble <2.0>
|
|||
|
asr.w #4,d0 ; get high nib which should be complement of low <2.0>
|
|||
|
CMP.B D0,D2 ; same?
|
|||
|
BNE.S @EndLoop ; error - not the same, try again
|
|||
|
BTST.L D1,D0 ; is this the byte lane we think we have?
|
|||
|
BNE.S @Good ; good - found a valid byte lane
|
|||
|
@EndLoop suba.w #1,a0 ; decrement a0 = ROM ptr to next byte lane
|
|||
|
DBRA D1,@Loop ; dec byte lane cntr and continue
|
|||
|
move.w #smBLFieldBad,d0 ; error - no valid byte lane field
|
|||
|
BRA.S @Done
|
|||
|
|
|||
|
@Good move.b d0,siCPUByteLanes(a1) ; good - save byte lane value from ROM <2.0>
|
|||
|
move.l a0,siROMAddr(a1) ; ptr to top of ROM with correct bytelane start <2.0>
|
|||
|
MOVE.L A0,D0 ; get last byte of address
|
|||
|
move.b d0,siTopOfROM(a1) ; $FsFFFFF<x> where <x> is top of rom - this field for compatibility <2.0>
|
|||
|
moveq #noErr,d0 ; set good return
|
|||
|
|
|||
|
@Done slotjsr RestoreBus ; switch back mmu mode and bus exception
|
|||
|
movem.l (sp)+,d2/a0/a2
|
|||
|
RTS ; done - GetByteLane
|
|||
|
|
|||
|
;_______________________________________________________________________________________
|
|||
|
; VerifyFormat - verify format block
|
|||
|
;
|
|||
|
; Given a pointer to a format header block image, verify that all the required fields
|
|||
|
; have reasonable values. The format block is in RAM pointed to by reg A2
|
|||
|
;
|
|||
|
; Input : reg A0 = ptr to spBlock (free to use)
|
|||
|
; A1 = ptr to sInfo record for card
|
|||
|
; A2 = ptr to format block image
|
|||
|
; Output : reg D0 = status, 0=ok CCR reflects status
|
|||
|
;
|
|||
|
|
|||
|
VerifyFormat
|
|||
|
|
|||
|
; Check ROM format
|
|||
|
|
|||
|
CMP.B #AppleFormat,fhFormat(A2) ; check for an Apple format type
|
|||
|
bne.s @Error ; not apple format - log as error
|
|||
|
|
|||
|
; Check revision level
|
|||
|
|
|||
|
CMP.B #ROMRevRange,fhROMRev(A2) ; the rev number must be less than 9<***why?***>
|
|||
|
bhi.s @Error ; revision number out of range
|
|||
|
|
|||
|
; Check fhReserved for zero.
|
|||
|
|
|||
|
TST.B fhReserved(A2) ; reserved field must be zero
|
|||
|
bne.s @Error ; not zero - error
|
|||
|
|
|||
|
; Check sResource Directory Offset (Offset must not be nil, although the reserved
|
|||
|
; field must be nil).
|
|||
|
|
|||
|
MOVE.L fhDirOffset(A2),D0 ; get D0 = directory offset value
|
|||
|
beq.s @Error ; zero offset <2.0>
|
|||
|
rol.l #8,d0 ; d0 = xxxx xxxx xxxx <id> <2.0>
|
|||
|
ext.w d0 ; sign extend the <id> <2.0>
|
|||
|
beq.s @Done ; ok - id field is zero
|
|||
|
|
|||
|
@Error move.w #smFormatErr,D0 ; some format header error
|
|||
|
@Done RTS ; done - VerifyFormat
|
|||
|
|
|||
|
|
|||
|
;_______________________________________________________________________________________ <2.0>
|
|||
|
; VerifyCRC - verify declaration ROM CRC
|
|||
|
;
|
|||
|
; Verify that a slot's declaration ROM's CRC matches the value in the format block.
|
|||
|
; The CRC calculations are really a modified checksum. If the length field in the
|
|||
|
; format header block is zero, then the checksum is not calculated.
|
|||
|
;
|
|||
|
; The algorithm used is :
|
|||
|
; start pointer at bottom of ROM
|
|||
|
; load sum = 0
|
|||
|
; @1 rotate sum left by one bit
|
|||
|
; if pointer is pointing to CRC field in format header, goto @2
|
|||
|
; get a byte
|
|||
|
; add byte to sum
|
|||
|
; @2 increment pointer to next data byte
|
|||
|
; goto @1 until done
|
|||
|
;
|
|||
|
; Input : reg A0 = ptr to spBlock (pre-initialized for this slot)
|
|||
|
; A1 = ptr to sInfo record for card
|
|||
|
; A2 = ptr to format block image
|
|||
|
; Output : reg D0 = status, 0=ok CCR reflects status
|
|||
|
;
|
|||
|
|
|||
|
VerifyCRC
|
|||
|
|
|||
|
movem.l d1-d4/a2-a4,-(sp)
|
|||
|
|
|||
|
; Calculate pointer to the bottom of the declaration data (taking into account
|
|||
|
; the bytelane supported)
|
|||
|
|
|||
|
MOVEA.L A2,A4 ; A4 = ptr to format blk
|
|||
|
move.l fhLength(a4),d2 ; d2 = length of declaration ROM data
|
|||
|
beq.s @Done ; zero length - ignore checksum calculation
|
|||
|
moveq #1,d1
|
|||
|
sub.l d2,d1 ; d1 = negative offset to bottom of rom
|
|||
|
|
|||
|
MOVE.L siROMAddr(A1),spsPointer(A0) ; ptr to top of ROM
|
|||
|
MOVE.L D1,spOffsetData(A0) ; D1 = negative offset to bottom
|
|||
|
_sCalcsPointer ; calc pointer to bottom
|
|||
|
BNE.S @Done
|
|||
|
MOVE.L spsPointer(A0),A3 ; set A3 = ptr to bottom of declaration ROM
|
|||
|
|
|||
|
; Setup for calculating CRC. Since we are stepping through the ROM one byte at a
|
|||
|
; time, we are calculating the step register (indicating which byte lanes are valid).
|
|||
|
; The pointer increment is done by macro which uses the step register.
|
|||
|
|
|||
|
BSET.B #fConsecBytes,spFlags(A0) ; calc for consecutive bytes.
|
|||
|
_sCalcStep ; calculate the step value.
|
|||
|
BNE.S @Done
|
|||
|
MOVE.L spResult(A0),D4 ; D4 = the quad step value
|
|||
|
|
|||
|
MOVEQ #0,D1 ; init D1 = crc sum
|
|||
|
MOVEQ #0,D3 ; temp reg - bits 8-15 must be zero for sNextStep
|
|||
|
|
|||
|
; Loop and calculate CRC - treat the CRC field in the format header as zero (4 bytes)
|
|||
|
; reg A3 = ptr to bottom of declaration ROM
|
|||
|
; reg D1 = crc sum, D2 = length of ROM, D3 = temp, D4 = step register
|
|||
|
|
|||
|
slotjsr InstallBus ; switch to 32bit mode and new bus exception
|
|||
|
move.w #smCRCFail,d0 ; prepare for a bad CRC error return
|
|||
|
lea @Restore,a2 ; set addr to jmp if bus error
|
|||
|
|
|||
|
@Loop
|
|||
|
ROL.L #1,D1 ; Rotate-left the crc value.
|
|||
|
cmp.l #fhCRC+4,d2 ; are we at crc field yet?
|
|||
|
bhi.s @Continue ; not yet - read byte from card's rom
|
|||
|
cmp.l #fhCRC,d2 ; are we in the crc field ?
|
|||
|
bhi.s @EndLoop ; yes - inc pass this byte
|
|||
|
@Continue
|
|||
|
MOVE.B (A3),D3 ; NUBUS READ - read D3 = the next byte
|
|||
|
add.l d3,d1 ; update the CRC value.
|
|||
|
@EndLoop
|
|||
|
sNextStep D4,D3,A3 ; point to the next byte in ROM.
|
|||
|
SUBQ.L #1,D2 ; dec 'bytes left' cntr
|
|||
|
bne.s @Loop ; continue looping
|
|||
|
|
|||
|
; Done computing the CRC value. Compare with the value stored in the format header
|
|||
|
|
|||
|
CMP.L fhCRC(A4),D1 ; cmp computed CRC with format ROM's CRC
|
|||
|
BNE.S @Restore ; error - no match
|
|||
|
moveq #noErr,d0 ; CRC matches - set good return
|
|||
|
|
|||
|
@Restore slotjsr RestoreBus ; switch back mmu mode and bus exception
|
|||
|
|
|||
|
@Done movem.l (sp)+,d1-d4/a2-a4
|
|||
|
RTS ; end - VerifyCRC
|
|||
|
|
|||
|
|
|||
|
;_______________________________________________________________________________________ <h3> djw
|
|||
|
; InitsRsrc - initialize the slot resource table
|
|||
|
;
|
|||
|
; Loop through the given slot's sRsrc directory and add all the sRsrcs to the
|
|||
|
; SRT. The SRT is actually made up of fixed sized blocks linked together. A
|
|||
|
; slot or id of $FF indicates the last entry in the block. An SRT block consist
|
|||
|
; of the block, and a link block at the end indicating the end of the block and
|
|||
|
; linking to the next block.
|
|||
|
;
|
|||
|
; Input : a0 = ptr to spBlock
|
|||
|
; Output : none
|
|||
|
;
|
|||
|
; spBlock : -> spSlot slot number
|
|||
|
|
|||
|
Export InitsRsrc
|
|||
|
with srrBlock,srtLink
|
|||
|
|
|||
|
InitsRsrc
|
|||
|
@regs reg d1-d3/a1-a2
|
|||
|
movem.l @regs,-(sp)
|
|||
|
|
|||
|
; Check the slot's status
|
|||
|
|
|||
|
_sFindsInfoRecPtr ; get ptr to sInfoRecord
|
|||
|
bne.s @Done ; slot not valid - done
|
|||
|
movea.l spResult(a0),a2 ; a2 = ptr to sInfoRecord
|
|||
|
tst.w siInitStatusA(a2) ; is the slot status ok?
|
|||
|
bmi.s @Done ; bad slot - done
|
|||
|
|
|||
|
; Calculate the step value for this slot so we can step through the sRsrc dir
|
|||
|
|
|||
|
move.l siDirPtr(a2),spsPointer(a0) ; set ptr field to get step value for
|
|||
|
move.b siCPUByteLanes(a2),spByteLanes(a0) ; set byte lanes field
|
|||
|
bset.b #fConsecBytes,spFlags(a0) ; set flag for step value for bytes
|
|||
|
_sCalcStep
|
|||
|
bne.s @Done
|
|||
|
|
|||
|
; Loop through the sResource directory. Check that the sResource id's are in
|
|||
|
; acsending order. The last entry must have id = $FF.
|
|||
|
; d1 = last id read, d2 = ptr to current dir entry, d3 = temp
|
|||
|
|
|||
|
move.l spResult(a0),spParamData(a0) ; set step value for reading bytes
|
|||
|
move.l siDirPtr(a2),d2 ; set d2 = ptr to current dir entry
|
|||
|
moveq.l #0,d1 ; zero last id read
|
|||
|
|
|||
|
@Loop move.l d2,spsPointer(a0) ; set spsPointer to addr of id to read in dir
|
|||
|
slotjsr Read4Bytes ; read <id><offset> - inc spsPointer to next long
|
|||
|
bne.s @Done ; an error - stop adding SRT entries
|
|||
|
move.l spsPointer(a0),d3 ; get d3 = ptr to next id to read
|
|||
|
move.l d2,spsPointer(a0) ; restore ptr to current dir entry
|
|||
|
move.l d3,d2 ; setup d2 = ptr to next entry in sRsrc dir
|
|||
|
|
|||
|
; Check for acsending order in sResource directory id's
|
|||
|
|
|||
|
move.b spResult(a0),d3 ; get high byte to get <id> field
|
|||
|
cmp.b #$ff,d3 ; end of list ?
|
|||
|
beq.s @Done ; done - a good return
|
|||
|
cmp.b d1,d3 ; is new id greater than last id ?
|
|||
|
bls.s @Done ; id's out of order
|
|||
|
move.b d3,d1 ; set reg d1 = last id read
|
|||
|
|
|||
|
; Given the sRsrc id, insert a new entry into the SRT
|
|||
|
|
|||
|
move.b d3,spId(a0) ; set sRsrc id to insert
|
|||
|
clr.l spsPointer(a0) ; clear fields used by _InsertSRTRec
|
|||
|
clr.w spIOReserved(a0)
|
|||
|
clr.w spRefNum(a0)
|
|||
|
clr.b spExtDev(a0)
|
|||
|
clr.b spHwDev(a0)
|
|||
|
clr.l spParamData(a0) ; make sure to insert sRsrc as enabled
|
|||
|
_InsertSRTRec ; insert <slot><id> sRsrc into SRT
|
|||
|
beq.s @Loop ; continue inserting sRsrc's
|
|||
|
|
|||
|
@Done
|
|||
|
movem.l (sp)+,@regs
|
|||
|
rts
|
|||
|
|
|||
|
endwith
|
|||
|
|
|||
|
|
|||
|
|
|||
|
;_______________________________________________________________________________________ <h3> djw
|
|||
|
; InitsPRAM - initialize slot PRAM
|
|||
|
;
|
|||
|
; Each slot is assigned 8 bytes of PRAM: <board id><6 user bytes>. On boot,
|
|||
|
; the <board id> is compared against the card in the slot. If they are
|
|||
|
; different, then the PRAM is initialized. If the card has a PRAM initialization
|
|||
|
; record in its declaration ROM, then the user bytes along with the new <board id>
|
|||
|
; are written into PRAM. If there is no PRAM init record, or if the slot is bad,
|
|||
|
; then the PRAM is zeroed.
|
|||
|
;
|
|||
|
; Input : a0 = ptr to spBlock
|
|||
|
; Output : none
|
|||
|
;
|
|||
|
; spBlock : -> spSlot slot number
|
|||
|
|
|||
|
Export InitsPRAM
|
|||
|
InitsPRAM
|
|||
|
@regs reg d1-d3/a1-a2
|
|||
|
movem.l @regs,-(sp)
|
|||
|
suba.w #SizesPRAMRec,sp ; alloc slot PRAM buffer
|
|||
|
movea.l sp,a1 ; a1 = ptr to PRAM buffer
|
|||
|
clr.l (a1) ; zero pram buffer (8 bytes)
|
|||
|
clr.l 4(a1)
|
|||
|
|
|||
|
; Get the state of this slot. If the slot is disabled or reserved, then DO NOT ZERO
|
|||
|
; PRAM. If the pram has already been initialized, then do not initialize again.
|
|||
|
|
|||
|
_sFindsInfoRecPtr ; get ptr to sInfoRecord
|
|||
|
bne @Done ; slot invalid - done
|
|||
|
movea.l spResult(a0),a2 ; a2 = ptr to sInfoRecord
|
|||
|
|
|||
|
cmpi.b #statePRAMInit,siState(a2) ; has PRAM already been initialized ?
|
|||
|
bge @Done ; already initialized - done
|
|||
|
tst.w siInitStatusA(a2) ; is the slot status ok?
|
|||
|
beq.s @readPRAM ; slot ok - read board id from pram
|
|||
|
cmp.w #smDisabledSlot,siInitStatusA(a2) ; is slot disabled?
|
|||
|
beq.s @Done ; don't touch disabled slot's pram
|
|||
|
cmp.w #smReservedSlot,siInitStatusA(a2) ; is slot reserved?
|
|||
|
beq.s @Done ; reserved is the same as disabled
|
|||
|
bra.s @writePRAM ; slot status is bad - zero pram
|
|||
|
|
|||
|
; Read PRAM to get the current board id.
|
|||
|
|
|||
|
@readPRAM
|
|||
|
move.l a1,spResult(a0) ; pass ptr to read PRAM bytes into
|
|||
|
_sReadPRAMRec ; return (a1).w = board id
|
|||
|
move.w (a1),d3 ; d3 = board id from PRAM
|
|||
|
clr.l (a1) ; zero pram buffer (8 bytes)
|
|||
|
clr.l 4(a1)
|
|||
|
|
|||
|
; Read the board id from the board sRsrc in the config ROM. Compare the card board id
|
|||
|
; with the pram board id. If they do not match, then the card in the slot has changed
|
|||
|
; so we should either zero or initialize the pram for the new card. Slot zero is a
|
|||
|
; special case for board sResources. The universal ROM supports multiple board sResource
|
|||
|
; records in the declaration ROM so we can represent different CPU's. Therefore, for
|
|||
|
; slot zero, loop through all the board sResource records found, trying to match the
|
|||
|
; pram board id.
|
|||
|
|
|||
|
moveq.l #0,d1 ; sRsrc id to start looking at (incase of slot 0)
|
|||
|
|
|||
|
@Loop
|
|||
|
move.b d1,spId(a0) ; pass sRsrc id to routine to begin looking from
|
|||
|
slotjsr GetBoard ; return board sRsrc and sInfo rec ptrs
|
|||
|
bne.s @writePRAM ; no board sRsrc - write zero PRAM
|
|||
|
|
|||
|
; Board sResource is found - read the board id
|
|||
|
|
|||
|
move.b spId(a0),d1 ; save spId incase we need to loop (for slot 0)
|
|||
|
move.b #Boardid,spId(A0) ; read board id field from board sRsrc
|
|||
|
_sReadWord
|
|||
|
beq.s @doMatch ; compare with pram board id
|
|||
|
move.w #smNoBoardId,siInitStatusA(A2) ; no board id - fatal error
|
|||
|
bra.s @writePRAM ; slot is bad - zero PRAM
|
|||
|
|
|||
|
; Compare the card's board id with the pram board id. d3 = pram board id
|
|||
|
|
|||
|
@doMatch
|
|||
|
move.w spResult+2(a0),d2 ; d2 = card board id
|
|||
|
cmp.w d3,d2 ; compare board id's
|
|||
|
beq.s @Done ; board id's match - do not initialize
|
|||
|
|
|||
|
; Board id's are different - if this is slot zero, then look for another board sResource
|
|||
|
|
|||
|
tst.b spSlot(a0) ; slot zero ?
|
|||
|
beq.s @Loop ; yes - look for another board sResource
|
|||
|
|
|||
|
; Look for a pram init record on the card's config ROM. If found, use the values to
|
|||
|
; initialize pram.
|
|||
|
|
|||
|
move.b #PRAMInitData,spId(a0) ; look for PRAM init in board sRsrc
|
|||
|
_sReadPBSize ; spsPointer = ptr to board sRsrc list
|
|||
|
bne.s @notFound ; not found - write new board id, zero the rest
|
|||
|
subq.l #4,spSize(a0) ; sub 4 bytes for size field
|
|||
|
move.l a1,spResult(a0) ; pass ptr to PRAM buffer
|
|||
|
_sReadStruct ; read the PRAM init rec into (a1)
|
|||
|
bne.s @notFound ; failed - just write board id
|
|||
|
bset.b #fCardIsChanged,siStatusFlags(a2) ; indicate card has changed in sInfo record
|
|||
|
|
|||
|
@notFound
|
|||
|
move.w d2,(a1) ; set new board id in buffer
|
|||
|
|
|||
|
@writePRAM
|
|||
|
move.l a1,spsPointer(a0) ; ptr to pram data
|
|||
|
_InitSlotPRAM ; initialize board id and user PRAM
|
|||
|
|
|||
|
@Done
|
|||
|
adda.w #SizesPRAMRec,sp ; free pram data buffer
|
|||
|
movem.l (sp)+,@regs
|
|||
|
rts
|
|||
|
|
|||
|
|
|||
|
;_______________________________________________________________________________________ <h3> djw
|
|||
|
; InitPrimary - execute primaryInit
|
|||
|
;
|
|||
|
; Execute primary init code for a slot having a primaryInit record in it's board
|
|||
|
; sResource. Primary inits are passed parameters in an seBlock.Primary inits are
|
|||
|
; executed before patches with interrupts disabled. <in 24bit mode-removed>
|
|||
|
;
|
|||
|
; Input : a0 = ptr to spBlock
|
|||
|
; Output : none
|
|||
|
;
|
|||
|
; spBlock : -> spSlot slot number
|
|||
|
; -> spFlags fWarmStart - if set then a warm start (may be used by primary
|
|||
|
; init code)
|
|||
|
; seBlock : seSlot -> spSlot
|
|||
|
; sesRsrcId -> BoardId
|
|||
|
; seFlags -> spFlags
|
|||
|
;
|
|||
|
Export InitPrimary
|
|||
|
|
|||
|
InitPrimary
|
|||
|
@regs reg d1-d3/a1-a3
|
|||
|
movem.l @regs,-(sp)
|
|||
|
suba.w #seBlockSize,sp
|
|||
|
movea.l sp,a2 ; a2 = ptr to sExec param blk
|
|||
|
move.l a2,spsExecPBlk(a0) ; set ptr in spblock to sExec blk
|
|||
|
move.b #BoardId,sesRsrcId(a2) ; indicates exec code is from board sResource
|
|||
|
|
|||
|
bsr.s doPrimaryInit ; execute the primary init
|
|||
|
|
|||
|
adda.w #seBlockSize,sp
|
|||
|
movem.l (sp)+,@regs
|
|||
|
rts
|
|||
|
|
|||
|
|
|||
|
;_______________________________________________________________________________________ <8>
|
|||
|
; doPrimaryInit - find and execute primaryInit records
|
|||
|
;
|
|||
|
; Called by Primary_Init. For a single slot, find the board sResource and if there
|
|||
|
; is a primary init record, execute it.
|
|||
|
;
|
|||
|
; Input : reg A0 = ptr to spBlock
|
|||
|
; A2 = ptr to sExecBlk
|
|||
|
; Output : none
|
|||
|
;
|
|||
|
; Torches A1/A3.
|
|||
|
;
|
|||
|
; spBlock : -> spSlot slot number
|
|||
|
;
|
|||
|
doPrimaryInit
|
|||
|
|
|||
|
clr.b spId(a0) ; start looking with id = 0
|
|||
|
slotjsr GetBoard ; return board sRsrc and sInfo rec ptrs
|
|||
|
bne @Done ; bad slot - done
|
|||
|
movea.l spsPointer(a0),a3 ; save ptr to board srsrc
|
|||
|
movea.l spResult(a0),a1 ; get a1 = ptr to sInfo record
|
|||
|
tst.w siInitStatusA(a1) ; test card status
|
|||
|
bmi.s @Done ; bad slot - skip it
|
|||
|
cmpi.b #statePInit,siState(a1) ; have we already executed primary inits ?
|
|||
|
bhs.s @Done ; yes - don't execute a second time
|
|||
|
|
|||
|
; Check if the board sResource has a primary init record
|
|||
|
|
|||
|
move.b #PrimaryInit,spId(a0) ; id to search for
|
|||
|
_sFindStruct
|
|||
|
bne.s @Done ; no primary init record - done
|
|||
|
|
|||
|
IF NOT LC930 THEN
|
|||
|
|
|||
|
; Identify Apple Cards whose PrimaryInit code is faulty, and execute fixed
|
|||
|
; versions from the CPU ROM.
|
|||
|
Bsr.s PatchPrimaryInit ; If PatchPrimaryInit returns a
|
|||
|
Tst.b D0 ; result >= 0, don’t execute
|
|||
|
Bpl.s @cleanup ; normal PrimaryInit.
|
|||
|
|
|||
|
ENDIF
|
|||
|
|
|||
|
; Load the code and execute the primary init record.
|
|||
|
;
|
|||
|
Move.l A3,spsPointer(A0) ; Restore ptr to board sRsrc.
|
|||
|
Move.b spSlot(A0),seSlot(A2) ; Set slot in sExec blk.
|
|||
|
Move.b spFlags(A0),seFlags(A2) ; Xfer warmstart flag (if present).
|
|||
|
_sExec ; Execute the code.
|
|||
|
|
|||
|
; Update the sInfo record status field - vendor status returned in sExec blk.
|
|||
|
;
|
|||
|
@cleanup Move.b #statePInit,siState(A1) ; Update state variable
|
|||
|
Move.w seStatus(A2),siInitStatusV(A1) ; Update vendor status
|
|||
|
Bpl.s @done ; Good primary init status - done
|
|||
|
Move.w #smInitStatVErr,siInitStatusA(A1) ; Some fatal vendor status returned
|
|||
|
|
|||
|
@done Rts
|
|||
|
|
|||
|
;____________________________________________________________________________
|
|||
|
;
|
|||
|
; PatchPrimaryInit and support (called from doPrimaryInit).
|
|||
|
;
|
|||
|
; Entry: A0 -- points to spBlock.
|
|||
|
; A1 -- points to sInfoRecord.
|
|||
|
; A2 -- (after restore from BigJump) points to sExec param blk.
|
|||
|
; A3 -- points to board sResource.
|
|||
|
;
|
|||
|
; D1 -- contains spSlot (we use spBlock.spSlot here, though).
|
|||
|
;
|
|||
|
; Exit: A0-A3 -- preserved.
|
|||
|
; D1 -- preserved.
|
|||
|
;
|
|||
|
; Purpose: The purpose of SlotPrimaryInitPatch is to identify Apple
|
|||
|
; Cards whose PrimaryInit code is faulty, and execute fixed
|
|||
|
; versions from the CPU ROM.
|
|||
|
;
|
|||
|
; SlotPrimaryInitPatch is executed from the (non-exported)
|
|||
|
; routine doPrimayInit in SlotInfo.a.
|
|||
|
;____________________________________________________________________________
|
|||
|
|
|||
|
IF NOT LC930 THEN
|
|||
|
|
|||
|
With seBlock,spBlock
|
|||
|
Import GetDevIndex,JsrTbl
|
|||
|
|
|||
|
PatchPrimaryInit
|
|||
|
|
|||
|
@saveRegs Reg A0-A3/D1/D3 ; Define some work and scratch registers,
|
|||
|
Movem.l @saveRegs,-(Sp) ; and save them on the stack.
|
|||
|
|
|||
|
Move.l A0,A3 ; Save the spBlockPtr for later.
|
|||
|
|
|||
|
Bsr GetDevIndex ; Get the device/card index into D0.
|
|||
|
Move.l D0,D3 ; If the device index is negative, then
|
|||
|
Bmi.s @done ; PrimaryInit doesn’t need patching.
|
|||
|
|
|||
|
Lea JsrTbl,A1 ; Point to base of JsrTbl.
|
|||
|
Lsl.l #2,D3 ; Adjust index.
|
|||
|
|
|||
|
Move.l A1,A0 ; Copy base address.
|
|||
|
Add.l D3,A0 ; Point to proper entry.
|
|||
|
Add.l (A0),A1 ; Load A1 with effective address of PrimaryInit.
|
|||
|
|
|||
|
Move.l A3,A0 ; Restore spBlockPtr.
|
|||
|
Move.b spSlot(A0),seSlot(A2) ; Set the right slot number.
|
|||
|
Move.b spFlags(A0),seFlags(A2) ; Set the flags.
|
|||
|
Move.l A2,A0 ; Set A0 to sExecBlkPtr for fake sExec call.
|
|||
|
Jsr (A1) ; Execute the PrimaryInit.
|
|||
|
|
|||
|
Move.l D3,D0 ; Return result code.
|
|||
|
|
|||
|
@done Movem.l (Sp)+,@saveRegs
|
|||
|
Rts
|
|||
|
|
|||
|
Endwith
|
|||
|
|
|||
|
ENDIF
|
|||
|
|
|||
|
;_______________________________________________________________________________________ <h5> djw
|
|||
|
; StubCheckSlot - check if a slot status has changed
|
|||
|
;
|
|||
|
; This is a little stub routine for the real CheckSlot routine in the slot manager
|
|||
|
; overpatch file. We need this stub because the slot manager jump table in ROM only
|
|||
|
; has 16 bit offset and the overpatch file is out of range. We therefore vector to
|
|||
|
; this stub routine which then jumps to the overpatch file.
|
|||
|
;
|
|||
|
; Input : none
|
|||
|
; Output : none
|
|||
|
;
|
|||
|
export StubCheckSlot
|
|||
|
import CheckSlot
|
|||
|
|
|||
|
StubCheckSlot
|
|||
|
bra.l CheckSlot ; go to the real routine
|
|||
|
|
|||
|
|
|||
|
;_______________________________________________________________________________________ <h5> djw
|
|||
|
; StubAddCard - add a card to slot manager
|
|||
|
;
|
|||
|
; This is a little stub routine for the real StubAddCard routine in the slot manager
|
|||
|
; overpatch file. We need this stub because the slot manager jump table in ROM only
|
|||
|
; has 16 bit offset and the overpatch file is out of range. We therefore vector to
|
|||
|
; this stub routine which then jumps to the overpatch file.
|
|||
|
;
|
|||
|
; Input : none
|
|||
|
; Output : none
|
|||
|
;
|
|||
|
export StubAddCard
|
|||
|
import AddCard
|
|||
|
|
|||
|
StubAddCard
|
|||
|
bra.l AddCard ; go to the real routine
|
|||
|
|
|||
|
|
|||
|
;_______________________________________________________________________________________ <h5> djw
|
|||
|
; StubRemoveCard - remove a card from the slot manager
|
|||
|
;
|
|||
|
; This is a little stub routine for the real CheckSlots routine in the slot manager
|
|||
|
; overpatch file. We need this stub because the slot manager jump table in ROM only
|
|||
|
; has 16 bit offset and the overpatch file is out of range. We therefore vector to
|
|||
|
; this stub routine which then jumps to the overpatch file.
|
|||
|
;
|
|||
|
; Input : none
|
|||
|
; Output : none
|
|||
|
;
|
|||
|
export StubRemoveCard
|
|||
|
import RemoveCard
|
|||
|
|
|||
|
StubRemoveCard
|
|||
|
bra.l RemoveCard ; go to the real routine
|
|||
|
|
|||
|
;_______________________________________________________________________________________ start <LW2>
|
|||
|
; EnableBlockXfer - find then enable cards capable of support block xfers as a Slave
|
|||
|
;
|
|||
|
; Input : a0 = ptr to spBlock
|
|||
|
; Output : none
|
|||
|
;
|
|||
|
; spBlock : -> spSlot slot number
|
|||
|
; -> spFlags fWarmStart - if set then a warm start (may be used by primary
|
|||
|
EnableBlockXfer
|
|||
|
Testfor BARTExists ; are we on a ColdFusion or PDM
|
|||
|
bne.s @goodMach
|
|||
|
Testfor MUNIExists ; do we have MUNI Nubus Controller?
|
|||
|
Beq @exit ; no, leave
|
|||
|
|
|||
|
@goodMach MoveM.l A0/D0-D2, -(SP)
|
|||
|
Clr.b spID(A0) ; Begin search with ID 0.
|
|||
|
Clr.b spExtDev(A0) ; No external device(s).
|
|||
|
Clr.b spHwDev(A0) ; No hardware device(s).
|
|||
|
Clr.b spTBMask(A0) ; No mask in search.
|
|||
|
Move.w #catBoard,spCategory(A0) ; Look for: Board sRsrc
|
|||
|
Clr.w spCType(A0)
|
|||
|
Clr.w spDrvrSW(A0)
|
|||
|
Clr.w spDrvrHW(A0)
|
|||
|
Move.l #(1<<foneslot), spParamData(A0) ; look only in this slot
|
|||
|
_GetTypeSRsrc ; get slots board sRsrc
|
|||
|
Bne.s @done
|
|||
|
Move.b #sBlockTransferInfo, spID(A0)
|
|||
|
_sReadLong ; does slot support block xfers?
|
|||
|
Bne.s @done ; no, leave
|
|||
|
Move.l spResult(A0), D0 ; get sBlockTransferInfo long
|
|||
|
BTst #fIsSlave, D0 ; handles blk xfer as slave?
|
|||
|
Beq.s @done ; no, leave
|
|||
|
|
|||
|
Testfor BARTExists ; are we on a ColdFusion or PDM
|
|||
|
beq.s @muni ; no, must be MUNI
|
|||
|
BTst #fSlvXferSz2, D0 ; handles blk xfer size of 2?
|
|||
|
Bne.s @enable ; yes, go
|
|||
|
BTst #fSlvXferSz8, D0 ; handles blk xfer size of 8?
|
|||
|
Bne.s @enable ; yes, go
|
|||
|
bra.s @done ; no, exit
|
|||
|
|
|||
|
@muni BTst #fSlvXferSz4, D0 ; handles blk xfer size of 4?
|
|||
|
Beq.s @done ; no, leave
|
|||
|
|
|||
|
@enable MoveQ #0, D0
|
|||
|
Move.b spSlot(A0), D0
|
|||
|
BSet #8, D0 ; make high word indicate enable blk xfer
|
|||
|
Move.l D0, A0
|
|||
|
_SlotBlockXferCtl
|
|||
|
|
|||
|
@done MoveM.l (SP)+, A0/D0-D2
|
|||
|
@exit Rts
|
|||
|
;end <LW2>
|
|||
|
|
|||
|
;_______________________________________________________________________________________
|
|||
|
; Secondary_Init - secondary initialization
|
|||
|
;
|
|||
|
; Secondary init records are the same as primary init records, except they are run
|
|||
|
; after patches are loaded, with interrupts enabled. If the slot's siInitStatusA field
|
|||
|
; value is zero or positive, the secondary init is executed. If there is a fatal
|
|||
|
; primary init status error smIntStatVErr, but the vendor status error (field
|
|||
|
; siInitStatusV) is in the range svTempDisable (-32768) to svDisabled (-32640), then
|
|||
|
; the secondary init will still be run. The secondary init status will replace the
|
|||
|
; primary init status. Normally the vendor error is not Apple's concern, but a special
|
|||
|
; error is needed to temporarily disable a card, and have the secondary init re-enable it.
|
|||
|
;
|
|||
|
; A special flag "fTempDisabled" has been added to the sInfo record to help the slot
|
|||
|
; manager patch version. A temporarily disabled card will have it's siInitStatusA field
|
|||
|
; cleared in the patch, so that the slot manager will look at it. It will have the
|
|||
|
; "fTempDisabled" flag set to indicate this state. In this routine, if there is no
|
|||
|
; secondary init record, and the "fTempDisabled" flag is set, then an error will be
|
|||
|
; placed back in siInitStatusA. Card's should only be in this "temporarily enabled"
|
|||
|
; state, within the bounds of the slot manager's execution.
|
|||
|
;
|
|||
|
; Input : reg A0 = ptr to spBlock
|
|||
|
; Output : reg D0 = status, 0=ok CCR reflects status
|
|||
|
; A0 = ptr to spBlock
|
|||
|
;
|
|||
|
; spBlock : -> spFlags fWarmStart - if set then a warm start (may be used by primary
|
|||
|
; init code)
|
|||
|
;
|
|||
|
; seBlock : seSlot <- spSlot
|
|||
|
; sesRsrcId <- #BoardId
|
|||
|
; seFlags <- spFlags
|
|||
|
;
|
|||
|
|
|||
|
Proc
|
|||
|
Export Secondary_Init, SecondaryEnd
|
|||
|
WITH spBlock,sInfoRecord,seBlock
|
|||
|
|
|||
|
Secondary_Init
|
|||
|
movem.l d1-d2/a1-a3,-(sp)
|
|||
|
suba.w #seBlockSize,sp
|
|||
|
movea.l sp,a2 ; a2 = ptr to sExec param blk
|
|||
|
move.l a2,spsExecPBlk(a0) ; set ptr in spblock to sExec blk
|
|||
|
move.b #BoardId,sesRsrcId(a2) ; indicates exec code is from board sResource
|
|||
|
|
|||
|
; Loop through all slots and get their board sResources. See if there is a secondary init
|
|||
|
; record associated with it.
|
|||
|
|
|||
|
moveq #sLastSlot,d1 ; start with slot $E <2.0>
|
|||
|
@Loop
|
|||
|
move.b d1,spSlot(a0)
|
|||
|
bsr.s DoSecondaryInit ; execute slot secondaryInit code <h7> djw
|
|||
|
|
|||
|
@EndLoop dbra d1,@Loop ; dec slot count <2.0>
|
|||
|
cmpi.b #sLastSlot,d1 ; done ?
|
|||
|
bls.s @Loop ; not done yet - continue
|
|||
|
|
|||
|
If SeparateFile or Not forROM then ; code for 32bitQD INIT and RAM patch <8>
|
|||
|
|
|||
|
; Re-define the default video device in-case a temporarily disabled card was brought
|
|||
|
; back to life by secondary inits.
|
|||
|
|
|||
|
move.w sr,-(sp) ; save current interrupt level
|
|||
|
ori.w #hiIntMask,sr ; disable all interrupts again
|
|||
|
bsr ReConfigVideo
|
|||
|
move.w (sp)+,sr ; restore interrupts
|
|||
|
endif ; <8>
|
|||
|
|
|||
|
adda.w #seBlockSize,sp
|
|||
|
movem.l (sp)+,d1-d2/a1-a3
|
|||
|
rts
|
|||
|
|
|||
|
;_______________________________________________________________________________________ <h11> djw
|
|||
|
; DoSecondaryInit - find and execute secondaryInit records
|
|||
|
;
|
|||
|
; Called by Secondary_Init. For a single slot, find the board sResource and if there
|
|||
|
; is a secondary init record, execute it.
|
|||
|
;
|
|||
|
; Input : reg a0 = ptr to spBlock
|
|||
|
; a2 = ptr to sExecBlk
|
|||
|
; Output : none
|
|||
|
;
|
|||
|
; trashes d0/d2-a1/a3.
|
|||
|
;
|
|||
|
; spBlock : -> spSlot slot number
|
|||
|
;
|
|||
|
Export DoSecondaryInit
|
|||
|
|
|||
|
DoSecondaryInit
|
|||
|
@regs reg d0-d2/a1/a3
|
|||
|
movem.l @regs,-(sp)
|
|||
|
|
|||
|
clr.b spId(a0) ; start looking with id = 0 <4>
|
|||
|
slotjsr GetBoard ; get the sInfo and board sRsrc ptrs <4>
|
|||
|
bne.s @Done ; bad slot
|
|||
|
movea.l spsPointer(a0),a3 ; save ptr to board srsrc
|
|||
|
movea.l spResult(a0),a1 ; get a1 = ptr to sInfo record
|
|||
|
|
|||
|
; Check the status of this slot. If "temporarily disabled", then enable the slot
|
|||
|
|
|||
|
cmpi.b #stateSInit,siState(a1) ; have we already executed secondary init ?
|
|||
|
bhs.s @Done ; yes - skip this slot
|
|||
|
move.w siInitStatusA(a1),d0 ; get card status
|
|||
|
bpl.s @Continue ; status ok
|
|||
|
cmpi.w #smInitStatVErr,d0 ; is card temporarily disabled ?
|
|||
|
bne.s @Done ; no - card is really bad
|
|||
|
cmpi.w #svDisabled,siInitStatusV(a1) ; vendor temporarily disabled code ?
|
|||
|
bgt.s @Done ; no - a fatal vendor code
|
|||
|
|
|||
|
clr.w siInitStatusA(a1) ; temp disabled - clr err so FindStruct will work
|
|||
|
bset.b #fTempEnabled,siStatusFlags(a1) ; make sure temp enabled bit is set
|
|||
|
|
|||
|
; Check if the board sResource has a secondary init record
|
|||
|
|
|||
|
@Continue move.w d0,d2 ; save status value for siInitStatusA field
|
|||
|
move.b #SecondaryInit,spId(a0) ; id to search for
|
|||
|
_sFindStruct
|
|||
|
beq.s @Execute ; secondary init record found
|
|||
|
move.w d2,siInitStatusA(a1) ; no secondary init - restore status error
|
|||
|
bclr.b #fTempEnabled,siStatusFlags(a1) ; test and clear temp enabled bit
|
|||
|
beq.s @Done ; was not set
|
|||
|
move.w #smInitStatVErr,siInitStatusA(a1) ; was "temp enabled" - restore error
|
|||
|
bra.s @Done ; continue to next slot
|
|||
|
|
|||
|
; Load the code and execute the secondary init record
|
|||
|
|
|||
|
@Execute move.l a3,spsPointer(a0) ; restore ptr to board srsrc
|
|||
|
move.b spSlot(a0),seSlot(a2) ; set slot in sExec blk
|
|||
|
move.b spFlags(a0),seFlags(a2) ; xfer warmstart flag (if present)
|
|||
|
_sExec ; execute the code
|
|||
|
|
|||
|
; Update the sInfo record status field - vendor status returned in sExec blk
|
|||
|
|
|||
|
bclr.b #fTempEnabled,siStatusFlags(a1) ; clear temp enabled bit
|
|||
|
move.b #stateSInit,siState(a1) ; update state variable
|
|||
|
move.w seStatus(a2),siInitStatusV(a1) ; update vendor status
|
|||
|
bpl.s @Done ; good secondary init status - continue
|
|||
|
move.w #smInitStatVErr,siInitStatusA(a1) ; some fatal vendor status returned
|
|||
|
|
|||
|
@Done
|
|||
|
movem.l (sp)+,@regs
|
|||
|
rts
|
|||
|
endwith
|
|||
|
|
|||
|
If SeparateFile or Not forROM then ; <8>
|
|||
|
|
|||
|
;_______________________________________________________________________________________
|
|||
|
; ReConfigVideo - select new default video screen
|
|||
|
;
|
|||
|
; This routine select a new default video device if the old default was the dummy
|
|||
|
; screen. The new default may be a video card which was temporarily disabled, but
|
|||
|
; has been re-enabled by a SecondayInit. It deletes the dummy screen from the gDevice
|
|||
|
; list and jumps back into ROM to the routine which selects the default video device.
|
|||
|
;
|
|||
|
; Input: none
|
|||
|
; Output: none
|
|||
|
;
|
|||
|
|
|||
|
ReConfigVideo
|
|||
|
|
|||
|
ROMFROVideo Equ $00000b58 ; hard offset only applies to Mac II rev A roms <4>
|
|||
|
|
|||
|
; This code deletes the dummy screen in the gDevice list (if present), and searches
|
|||
|
; for the default video device all over again (normally done earlier in the start
|
|||
|
; code), just in case a video card was temporarily disabled, and re-enabled by the
|
|||
|
; secondary init.
|
|||
|
|
|||
|
|
|||
|
; Determine if the main gDevice is the dummy screen. If so, then delete it from the
|
|||
|
; gDevice list and look for the default video again (incase the default video card
|
|||
|
; was temporarily disabled and is now enabled).
|
|||
|
|
|||
|
_HideCursor
|
|||
|
MOVE.L MainDevice,A1 ; A1 = handle to gDevice from low mem
|
|||
|
MOVE.L (A1),A0 ; A0 = ptr to gDevice
|
|||
|
TST gdRefNum(A0) ; is ref number zero?
|
|||
|
BNE.S @Fixup ; no - not dummy screen
|
|||
|
CMP #32,GDRect+right(A0) ; make sure size of rect is 32x32
|
|||
|
BNE.S @Fixup ; not dummy screen
|
|||
|
CMP #32,GDRect+bottom(A0)
|
|||
|
BNE.S @Fixup ; not dummy screen
|
|||
|
MOVE.L A1,-(SP) ; push handle of dummy screen gDevice
|
|||
|
_DisposGDevice ; get rid of the dummy screen gDevice
|
|||
|
CLR.L DeviceList
|
|||
|
suba.w #ioQElSize,sp
|
|||
|
movea.l sp,a0 ; allocate an iopb into a0 for frovideo
|
|||
|
st.b QDExist ; indicate QD environment is invalid so pallette <4>
|
|||
|
jsr ([rombase],ROMFROVideo) ; select new default video - slimy jump to hard <4>
|
|||
|
adda.w #ioQElSize,sp
|
|||
|
_AllocCursor ; fixup cursor to new gdevice
|
|||
|
_ShowCursor
|
|||
|
|
|||
|
; Set the lowmem 'scrnbase' to the proper base address. This should be done in
|
|||
|
; 'RdVidParam', but on 1.0 roms, it does not know about 32bit base addresses.
|
|||
|
;
|
|||
|
; <1.1/DAF> The original version of this code moved dCtlDevBase into ScrnBase which isn't
|
|||
|
; correct (it's missing two critical offsets). At this point, ScrnBase is the base address
|
|||
|
; of the boot screen's frame buffer (by the first app launch, it will be the main screen's
|
|||
|
; frame buffer base). If the machine has 1.0 or 1.1 ROMs (old Slot Manager) then the
|
|||
|
; video card's SecondaryInit was responsible for updating the base address in the card's
|
|||
|
; gdPixMap. So the fix is to always copy the boot screen gDevice's base address into
|
|||
|
; ScrnBase. No other gDevices exist yet so we don't need to look for it. The refnum
|
|||
|
; test prevents problems if the dummy screen is still in effect.
|
|||
|
|
|||
|
@Fixup MOVE.L MainDevice,A0 ; A0 = handle to gDevice from low mem
|
|||
|
MOVE.L (A0),A0 ; A0 = ptr to gDevice
|
|||
|
MOVE.W gdRefNum(A0),D1 ; is ref number zero?
|
|||
|
BEQ.S @Done ; no ref num - no video devices
|
|||
|
MOVE.L gdPMap(A0),A0 ; get handle to device pixmap <1.1>
|
|||
|
MOVE.L (A0),A0 ; get pointer <1.1>
|
|||
|
MOVE.L pmBaseAddr(A0),ScrnBase ; put it in lo-mem <1.1>
|
|||
|
|
|||
|
@Done MOVEQ #0,D0 ; only good returns
|
|||
|
RTS ; done
|
|||
|
|
|||
|
endif ; <8>
|
|||
|
|
|||
|
SecondaryEnd
|
|||
|
|
|||
|
|
|||
|
End
|
|||
|
|