mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2025-01-06 14:30:37 +00:00
4325cdcc78
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
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
|
|
|