mirror of
https://github.com/elliotnunn/sys7.1-doc-wip.git
synced 2024-12-12 20:29:12 +00:00
1178 lines
42 KiB
Plaintext
1178 lines
42 KiB
Plaintext
;
|
||
; Hacks to match MacOS (most recent first):
|
||
;
|
||
; <Sys7.1> 8/3/92 Elliot make this change
|
||
; 9/2/94 SuperMario ROM source dump (header preserved below)
|
||
;
|
||
|
||
;_______________________________________________________________________________________
|
||
;
|
||
; 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):
|
||
;
|
||
; <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>).
|
||
; <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'
|
||
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 SlotEmpty ; <djw>
|
||
IMPORT pGetBoard ; <3>
|
||
|
||
IMPORT SlotManager ; <3>
|
||
IMPORT p040BusException ; <4>
|
||
|
||
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 SlotEmpty ;$0F
|
||
|
||
|
||
; 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 SlotEmpty ;$1E
|
||
DispatchVector SlotEmpty ;$1F
|
||
|
||
|
||
; Advanced (SDM private routines).
|
||
DispatchVector SlotEmpty ;$20
|
||
DispatchVector SlotEmpty ;$21
|
||
DispatchVector CardChanged ;$22
|
||
DispatchVector SlotExec ;$23
|
||
DispatchVector OffsetData ;$24
|
||
DispatchVector SlotEmpty ;$25
|
||
DispatchVector ReadPBSize ;$26
|
||
DispatchVector SlotEmpty ;$27
|
||
DispatchVector CalcStep ;$28
|
||
DispatchVector SlotEmpty ;$29
|
||
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
|
||
|
||
;_______________________________________________________________________________________
|
||
; 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
|
||
;
|
||
|
||
InitSlotMgr Proc Export
|
||
with spBlock,sInfoRecord,FHeaderRec,slotGlobals,seBlock
|
||
|
||
movem.l d1/a1/a2,-(sp)
|
||
|
||
bsr Subroutine
|
||
|
||
; 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
|
||
_sFindsInfoRecPtr ; get ptr to sInfoRecord
|
||
movea.l spResult(a0),a1 ; a1 = ptr to sInfoRecord
|
||
tst.w siInitStatusA(a1) ; is the slot status ok?
|
||
bmi.s @SlotDone ; bad slot - done
|
||
|
||
bsr VerifySlot ; verify the config rom format
|
||
|
||
@SlotDone dbra d1,@Loop
|
||
|
||
movem.l (sp)+,d1/a1/a2
|
||
rts
|
||
|
||
Subroutine
|
||
@regs reg d1-d2/a0-a3
|
||
movem.l @regs,-(sp) ; save registers
|
||
|
||
; Enumerate all the slots
|
||
; d0 = number of slots found
|
||
; sp points to array of index/-1 words
|
||
|
||
move.l sp,SInfoPtr ; create a fake SlotMgr global block for InstallBus
|
||
sub.w #slotGlobalSize,sp
|
||
|
||
move.l #minorLast,a1 ; explore the standard slot space ($Fn......)
|
||
move.l #TotalSlots-1,d1
|
||
move.l #0,d0
|
||
|
||
lea @BusError,a2 ; switch to 32-bit mode, and jump to a2 on bus error
|
||
slotjsr InstallBus
|
||
|
||
@NextSlot
|
||
sub.l #2,sp
|
||
move.b (a1),d2
|
||
add.w #1,d0
|
||
move.w d0,(sp)
|
||
bra.s @NoBusError
|
||
@BusError
|
||
move.w #-1,(sp)
|
||
@NoBusError
|
||
sub.l #minorStep,a1
|
||
sub.w #1,d1
|
||
bne.s @NextSlot
|
||
|
||
slotjsr RestoreBus ; undo InstallBus
|
||
|
||
; Allocate the necessary memory as one contiguous block
|
||
|
||
mulu.w #sInfoNewSize,d0 ; size of N sInfoRecords
|
||
add.l #(slotGlobalSize \ ; size of globals
|
||
+(4*TotalSlots)+48 \ ; size of sInfor vector table ?????
|
||
),d0
|
||
_NewPtr ,sys,clear ; alloc block
|
||
|
||
adda.w #slotGlobalSize,a0 ; globals are at a negative offset from sInfo tbl
|
||
move.l a0,sInfoPtr ; set ptr to sInfo table
|
||
move.l a0,a1
|
||
|
||
; 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 #smEmptySlot, \
|
||
siInitStatusA(a0) ; set slot status to disabled
|
||
lea sInfoNewSize(a0),a0 ; inc a0 to reserved sInfoRecord
|
||
|
||
move.l #$40000,d0
|
||
sub.l #1,d0
|
||
add.l RomBase,d0
|
||
move.l d0,siROMAddr(a0)
|
||
move.w #1,siTOConst(a0)
|
||
|
||
move.l a0,(a1) ; ?????
|
||
|
||
move.w #1,d0
|
||
@Loop
|
||
movea.l a0,a2 ; save ptr to spBlock
|
||
move.w (sp)+,d1 ; pop word from
|
||
muls.w #sInfoNewSize,d1 ; size of sInfoRecord
|
||
add.l d1,a2
|
||
move.l a2,(a1,d0.w*4) ; set ptr in sInfo vector table
|
||
|
||
move.w #retryCnt,siTOConst(a2) ; set default bus error retry cnt (not used)
|
||
move.b d0,siSlot(a2) ; set slot number
|
||
|
||
not.l siROMAddr(a2) ; set ROM address ???
|
||
bfins d0,siROMAddr(a2){4,4} ; inset slot number to get $fsffffff
|
||
|
||
add.w #1,d0
|
||
cmp.w #sLastSlot,d0
|
||
ble.s @Loop
|
||
|
||
add.w #slotGlobalSize,sp ; pop fake globals
|
||
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.S GetByteLane ; get a valid byte lane - return byte lane value in D1
|
||
BNE.S 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.S VerifySlotDone
|
||
|
||
@GoodRom 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
|
||
|
||
|
||
;_______________________________________________________________________________________
|
||
; InitsRsrcTable - 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
|
||
|
||
InitsRsrcTable Proc Export
|
||
with spBlock,sInfoRecord,FHeaderRec,slotGlobals,seBlock,srrBlock,srtLink
|
||
|
||
@regs reg a1-a2
|
||
movem.l @regs,-(sp)
|
||
|
||
slotjsr AllocSRTBlk
|
||
|
||
move.l a1,SRsrcTblPtr
|
||
|
||
clr.b spSlot(a0) ; clear fields used by _InsertSRTRec
|
||
clr.w spIOReserved(a0)
|
||
clr.w spRefNum(a0)
|
||
clr.b spExtDev(a0)
|
||
clr.b spHwDev(a0)
|
||
|
||
; Check the slot's status
|
||
@NextSlot
|
||
_sFindsInfoRecPtr ; get ptr to sInfoRecord
|
||
movea.l spResult(a0),a2 ; a2 = ptr to sInfoRecord
|
||
tst.w siInitStatusA(a2) ; is the slot status ok?
|
||
bmi.s @BadSlot ; bad slot - done
|
||
bsr @InitTheResourceTable
|
||
@BadSlot
|
||
add.b #1,spSlot(a0)
|
||
cmp.b #sLastSlot,spSlot(a0)
|
||
ble.s @NextSlot
|
||
|
||
movem.l (sp)+,@regs
|
||
rts
|
||
|
||
@InitTheResourceTable
|
||
movem.l d3-d5/a3,-(sp)
|
||
; 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 @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),d4 ; set d4 = ptr to current dir entry
|
||
moveq.l #0,d3 ; zero last id read
|
||
|
||
@Loop move.l d4,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),d5 ; get d5 = ptr to next id to read
|
||
move.l d4,spsPointer(a0) ; restore ptr to current dir entry
|
||
move.l d5,d4 ; setup d4 = ptr to next entry in sRsrc dir
|
||
|
||
; Check for acsending order in sResource directory id's
|
||
|
||
move.b spResult(a0),d5 ; get high byte to get <id> field
|
||
cmp.b #$ff,d5 ; end of list ?
|
||
beq.s @Done ; done - a good return
|
||
cmp.b d3,d5 ; is new id greater than last id ?
|
||
bls.s @Done ; id's out of order
|
||
move.b d5,d3 ; set reg d3 = last id read
|
||
|
||
; Given the sRsrc id, insert a new entry into the SRT
|
||
|
||
move.b d3,spId(a0) ; set sRsrc id to insert
|
||
|
||
move.l spResult(a0),d5
|
||
and.l #$FFFFFF,d5
|
||
move.l d5,spOffsetData(a0)
|
||
|
||
_SCalcSPointer
|
||
bne.s @Done
|
||
|
||
cmp.w #-1,(a1)
|
||
bne.s @no
|
||
move.l a1,a3
|
||
|
||
slotjsr AllocSRTBlk
|
||
move.l a1,2(a3)
|
||
|
||
@no
|
||
clr.l $18(a0)
|
||
slotjsr InitEntry
|
||
bne.s @Done
|
||
add.w #1,([sInfoPtr],srtCnt)
|
||
move.l a1,([sInfoPtr],lastSRTPtr)
|
||
add.l #$18,a1
|
||
bra @Loop
|
||
@Done
|
||
movem.l (sp)+,d3-d5/a3
|
||
rts
|
||
|
||
|
||
|
||
;_______________________________________________________________________________________
|
||
; InitPramRecs - 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
|
||
|
||
InitPramRecs Proc Export
|
||
with spBlock,sInfoRecord,FHeaderRec,slotGlobals,seBlock,srrBlock,srtLink
|
||
|
||
@regs reg d1-d4/a1-a2
|
||
movem.l @regs,-(sp)
|
||
suba.w #SizesPRAMRec,sp ; alloc slot PRAM buffer
|
||
movea.l sp,a1 ; a1 = ptr to PRAM buffer
|
||
moveq #sLastSlot,d1
|
||
|
||
@NextSlot
|
||
|
||
; Read PRAM to get the current board id.
|
||
|
||
move.b d1,spSlot(a0)
|
||
clr.w (a1) ; zero board ID in pram buffer
|
||
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,d4 ; sRsrc id to start looking at (incase of slot 0)
|
||
|
||
@Loop
|
||
move.b d4,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
|
||
|
||
movea.l spResult(a0),a2 ; a2 = ptr to sInfoRecord
|
||
tst.w siInitStatusA(a2) ; is the slot status ok?
|
||
bmi.s @writePRAM ; slot status is bad - zero pram
|
||
cmpi.b #statePRAMInit,siState(a2) ; has PRAM already been initialized ?
|
||
bge.s @Done ; already initialized - done
|
||
|
||
; Board sResource is found - read the board id
|
||
|
||
move.b spId(a0),d4 ; 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 d1 ; 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
|
||
dbra d1,@NextSlot
|
||
moveq #0,d0
|
||
|
||
adda.w #SizesPRAMRec,sp ; free pram data buffer
|
||
movem.l (sp)+,@regs
|
||
rts
|
||
|
||
|
||
;_______________________________________________________________________________________
|
||
; Primary_Init - 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 Primary_Init
|
||
|
||
Primary_Init
|
||
@regs reg d1/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
|
||
|
||
moveq #0,d0 ; MMU to 32-bit mode
|
||
_SwapMMUMode
|
||
move.b d0,-(sp)
|
||
|
||
move.b #0,spSlot(a0)
|
||
bsr.s doPrimaryInit ; execute the primary init
|
||
|
||
moveq #sLastSlot,d1
|
||
@Loop
|
||
move.b d1,spSlot(a0)
|
||
bsr.s doPrimaryInit ; execute the primary init
|
||
subq #1,d1
|
||
bnz.s @Loop
|
||
|
||
move.b (sp)+,d0 ; restore MMU
|
||
_SwapMMUMode
|
||
|
||
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
|
||
|
||
; Load the code and execute the primary init record.
|
||
;
|
||
Move.l A3,spsPointer(A0) ; Restore ptr to board sRsrc.
|
||
Move.b D1,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
|
||
|
||
|
||
;_______________________________________________________________________________________
|
||
; 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)
|
||
|
||
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 d1,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
|
||
|
||
|
||
@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
|
||
|
||
;_______________________________________________________________________________________
|
||
; 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
|
||
|
||
SecondaryEnd
|
||
|
||
|
||
End
|
||
|