sys7.1-doc-wip/OS/SCSIMgr/SCSIMgrInit.a
2019-07-27 22:37:48 +08:00

833 lines
36 KiB
Plaintext

;----------------------------------------------------------------------------------------------
; File: SCSIMgrInit.a
;
; Written by: Jerry Katzung
;
; Copyright: © 1989-1993 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <SM27> 11/22/93 pdw Removed useless old ISR initialization, added stack
; manipulations around call to SCSIReset.
; <SM26> 11/10/93 chp Avoid initializing for SCSI96_BIOS as the default case.
; <SM25> 10/14/93 pdw Fixed up forPDMProto stuff. Take out EVT1 PDM support. Moved
; initialization of SCSIDrvrs and SCSIPoll to StartSearch.
; <SM24> 7/20/93 pdw Cleaned up (a little - it still needs a lot more). Added
; ShouldWeDoAsyncSCSI routine which allows HWInit to figure out
; whether it should do anything or not. Also used to decide
; whether to call InitItt. Moved SCSIReset to pt after InitItt.
; <SM23> 7/17/93 pdw Put idiotic CASE stuff around call to DoWeHaveAMIC3B.
; <SM22> 7/17/93 pdw Moved ck4AMIC3B routine to SCSIMgr4pt3:HALc96Init.a.
; <SM21> 7/8/93 pdw Moved code to check for AMIC3(B) into a routine of its own so
; that I can use it elsewhere.
; <SM20> 6/29/93 pdw Added check for AMIC3 to see if we can run on bus>50MHz
; machines.
; <SM19> 6/8/93 SAM Turning Async SCSI off for Evt1 PDMs.
; <SM18> 5/26/93 DCB Turning on Async SCSI for Quadras and Wombats.
; <SM17> 5/5/93 PW Adding check for 50MHz bus on PDM around call to InitItt until
; the VIAs get more stable.
; <SM16> 4/23/93 SAM Disabled Itt on PDM evt2 for now.
; <SM15> 3/29/93 PW Freeing up two PRAM bits that are wasted in the CPU's SCSI ID
; and internal drive's SCSI ID.
; <SM14> 2/17/93 CSS Fix check for whether to use SCSIBIOS to include PDM test. We
; need a better test here. i.e. SCSIBIOSExists or something based
; on the SCSIBIOS feature not on machine memory controls or other
; unrelated information.
; <SM13> 2/12/93 PW Removing COUSIN_ITT checks (instead just using hasAsyncSCSI).
; <SM12> 2/10/93 CSS Fix bug introduced in last checkin which made all SCSI80 machine
; break.
; <SM11> 2/5/93 CSS Added the Horror changes from SCSIMiscPatch.a.
; Comments from SCSIMiscPatch.a in Horror follow:
; <H10> 9/25/92 BG Re-did H5-H9 so that they are Politically Correct WRT the
; overpatched way of life (so that older addresses stay consistent
; with previous ROMs).
; <H9> 9/18/92 jab Changed BIOS/Quadra tests to rely on the existence of Orwell.
; <H8> 9/14/92 jab BSR offset trouble.
; <H7> 9/14/92 jab Fixed bug that did not allow Quadra SCSI Manager to be
; initialized correctly.
; <H6> 9/6/92 jab Added patch for BIOS c96 based SCSI HW initialization.
; <H5> 6/10/92 BG (actually JAB) Overpatch for correctly setting up DREQ access.
; <H4> 03/23/92 jmp Overpatched the InitSCSIMgrPatch2 routine so that this file
; lines up with the TERROR/Zydeco ROM map.
; <H3> 2/10/92 SWC jab/Added support for multiple c80 SCSI buses on DB Lite.
; <H2> 12/21/91 jmp (BG,Z14) (for JBlair) Added fix for busy status from drive while
; spinning up .
; <SM10> 2/4/93 PW Added check for PDM as one of the machines to have async SCSI
; enabled on.
; <SM9> 2/1/93 PW Preparing for enabling Cousin Itt on PDM.
; <SM8> 12/4/92 fau Changed use of Boxflags for Cyclone machines to use PSCExists
; flag.
; <SM7> 11/30/92 PW Added hasAsyncSCSI check around CousinItt initialization. This
; is to use hasAsyncSCSI as the feature flag and COUSIN_ITT as a
; temporary debugging build flag.
; <SM6> 11/9/92 fau Added a check for a Tempest where there was one for a Cyclone.
; <SM5> 7/28/92 PW Disabled loading of Cousin Itt on Quadras. Don't worry - it'll
; get in there eventually.
; <SM4> 7/28/92 PW Added support for SCSIMgr4pt3.
; <SM3> 6/2/92 kc Roll in Pandora changes. Comments follow: Fix bug in JumpTable
; init code.
; <P2> 1/17/92 PDW Jumps to InitMgr_SCSI96, InitHW_SCSI96 changed to
; InitMgr_SCSI_PSC and InitHW_SCSI_PSC.
; <13> 5/1/92 JSM Get rid of conditionals: delete code not forROM, this file is
; only used in ROM builds, so also delete forROM conditionals.
; This file now has no conditionals.
; <12> 12/27/91 RB I've got the EXPORT blues...forgot to export a label.
; <11> 12/27/91 RB Added the Terror changes from SCSIMiscPatch.a
; <10> 12/26/91 RB SleepQueue definitions are now in SleepQRec record, updated
; usage of sleep queue fields.
; <9> 11/16/91 DTY The old style equates got nixed from InternalOnlyEqu.a. Update
; places that used those equates to use PMgrRec to get the ROM
; build working again.
; <8> 9/16/91 JSM Cleanup header.
; <7> 9/21/90 BG Removed various 040-related kludges.
; <6> 9/14/90 MSH Add to list of conditionals that include disk spin down support.
; <5> 6/22/90 CCH Put code in to set SCSI IRQ line to VIA2 CB2 for Eclipse.
; <4> 5/16/90 MSH Added hasPowerControls to hcmac conditional.
; <3> 1/18/90 JWK Needed for Zone5 - Initialize variable watchdog timer timeout.
; <2> 1/11/90 CCH Added include of “HardwarePrivateEqu.a”.
; <1.7> 12/10/89 jwk NEEDED FOR F19 - Installs DMA routines for blind transfers.
; <1.6> 11/2/89 MSH SlpQInstall now available, setupsleeptask modified to use it.
; <1.5> 9/11/89 jwk NEEDED FOR F19 - Streamlined code, added Bus Device Reset
; support
; <1.4> 7/15/89 jwk NEEDED FOR AURORA - Added code review changes, F19 routines
; <1.3> 6/29/89 jwk NEEDED FOR AURORA - Fixed Tape Drive and Slow Write timing bugs
; <1.2> 6/26/89 GMR Restore a0 to point to globals after _NewPtr call in
; InitScsiMgr.
; <1.1> 6/15/89 GGD Removed VIA2 vPCR initialization when for ROM, since InitVIAs at
; StartInit time initializes it correctly. Moved the code to the
; correct place also, since it was setting values for CB2 even
; when the SCSI interrupt is on CA2.
; <1.0> 6/13/89 jwk Reorganizing SCSI sources to be Universal-ROM friendly
;
;----------------------------------------------------------------------------------------------
;
; Old comments are saved for historical purposes in the SCSIMgrOld.a file. <v1.4>
;
;----------------------------------------------------------------------------------------------
BLANKS ON
STRING ASIS
PRINT OFF
LOAD 'StandardEqu.d'
INCLUDE 'HardwarePrivateEqu.a'
INCLUDE 'UniversalEqu.a' ; <11> rb
INCLUDE 'GestaltEqu.a'
INCLUDE 'SCSI.a'
INCLUDE 'SCSIPriv.a'
INCLUDE 'SCSIEqu96.a' ; SCSI96 private equ's <11> rb
PRINT ON
SCSIInit PROC EXPORT
EXPORT InitSCSIMgr, InitSCSIHW ; called by StartInit
IMPORT DoRequestIO, DoKillIO, DoBusInfo, AltBusCall
IMPORT SCSIMgr, DataDMA ;<v1.4>
IMPORT DoSCSIReset, DoSCSIGet, DoSCSISelect, DoSCSICmd, DoSCSIComplete
IMPORT DoSCSIStat, DoSCSISelAtn, DoSCSIMsgIn, DoSCSIMsgOut
IMPORT NewSCSIRead, NewSCSIWrite, Unimplemented, NewSCSIRBlind, NewSCSIWBlind ;<v1.4>
IMPORT DataIO, Command, StatusPhase, ResetBus, MsgOut, MsgIn
IMPORT SlowRead, SlowWrite, FastRead, FastWrite
IMPORT SlowComp, FastComp
IMPORT FastReadOSS, FastWriteOSS ;<v1.4>
IMPORT VFastReadOSS, VFastRead, VFastWriteOSS, VFastWrite
IMPORT PFastReadOSS, PFastRead, PFastWriteOSS, PFastWrite
IMPORT msgCmdComplete, msgSaveDataPtr, msgRestorePtrs, msgDisconnect
IMPORT msgIdentifyIn, msgInvalidIn, msgMsgRejIn, msgLCCF
IMPORT msgIdentifyOut, msgMsgRejOut, msgInvalidOut, msgKillio, msgNoOp
IMPORT msgBusDevRst ;<v1.5>
IMPORT Preflight, EnDequeue
IMPORT Message, ClearIRQ, DisEnable, SCSIDT, LogError ;<v1.4>
IMPORT Find, Setup, ClearBus, BusErrHandler
IMPORT Arb, Sel, Delay22, ClearState, Transfer, SetTimer
IMPORT TimeTask, SCSIIntHnd, NewSCSITrap
IMPORT SCSISetFlags ; <v1.3>
IMPORT SleepTask, DoSpinDown, StartItUp
IMPORT InitHW_SCSI_PSC
IMPORT InitHW_SCSI96_BIOS, InitMgr_SCSI96_BIOS ; <SM11> CSS
IMPORT InitHW_SCSI96,InitMgr_SCSI96 ; <SM11> CSS
WITH scsiPB,scsiPrivPB, scsiGlobalRecord, dcInstr, machSpecRecord, ROMHeader ;<v1.4>
WITH DecoderInfo,PmgrRec,SleepQRec,pmCommandRec ; <11> rb
;-------------------------------------------------------------
;
; Initialization code for the SCSI Manager (called by StartInit).
;
InitSCSIMgr
movem.l intrRegs,-(sp) ; save all registers, for convenience
moveq.l #0,zeroReg ; initialize "zeroReg"
;=== Set up the new improved SCSI manager globals <v1.3>
move.l #GlobalSize,d0 ; size of globals to allocate
_NewPtr ,SYS,CLEAR ; put it in the system heap
bne @InitSCSIDone ; failed, just exit (bad news...)
move.l a0,SCSIGlobals ; save low-mem ptr to globals
@setupA4
movea.l a0,a4 ; use normal SCSI Mgr register conventions
;--- Allocate additional space if there's a power manager for "machine specific structure"
TestFor hwCbPwrMgr ; is there a power manager in this machine? <11> rb
beq.s @nopmgr ; no power manager
move.l #machSpecSize,d0 ; size of additional globals to allocate
_NewPtr ,SYS,CLEAR ; put it in the system heap
bne @InitSCSIDone ; failed, just exit (bad news...) <11> rb
move.l a0,G_Reserved2(a4) ; save pointer to machine-specific structure
movea.l a4,a0 ; restore ptr to beginning of globals again <1.2>
@nopmgr
;--- Set up hardware config flags for this machine <v1.3>
jsr SCSISetFlags ; get the flags in d0
move.l d0,G_Reserved0(a4) ; save in globals
;--- Hardware initialization right here in the middle of software init
; turn off test mode for chip if we have a SCSI DMA part <v1.3>
btst.b #sSCSIDMAExists,G_Reserved0+3(a4) ; see if we really have the DMA chip<2.8>
beq.s @DMAdone ; if not, skip it <2.8>
movea.l SCSIBase,a3 ; get the chip base <2.9>
move.l #iINTREN,sDCTRL(a3) ; turn off SCSI Test Mode and enable intrs <C914><v1.4>
@DMAdone ; <2.8>
;………………………………………………………………………………………………………………………………………………………………………………………………………………………
;
;=== Now set up the jump table (for SCSIDispatch selectors)
;
moveq.l #numSelectors-1,d1 ; loop count <v1.6>
lea.l SCSIMgr,a1 ; get start of SCSI Mgr code
move.l a1,d0 ; remember base address
lea OffsetTbl,a1 ; address of offset table
movea.l a4,a0 ; point to base of old SCSI Mgr jump table <v1.3>
@MakeJmpTbl
move.w (a1)+,d2 ; get the next offset
ext.l d2 ; make it a long <SM3>
add.l d0,d2 ; compute the address
move.l d2,(a0)+ ; install it in the jump table
dbra d1,@MakeJmpTbl ; loop for all vectors
;--- set the SCSI chip base addresses <v1.3>
lea.l base5380(a4),a0 ; point to hardware portion of globals <v1.5>
@SCSIBase move.l SCSIBase,(a0)+ ; addr of SCSI chip
move.l SCSIDMA,(a0)+ ; pseudo-DMA base of SCSI chip
move.l SCSIHsk,(a0)+ ; hardware-handshaking base of SCSI chip
@wrOff
move.w #wrOffs,(a0)+ ; write offset to SCSI chip <v1.7>
moveq.l #-1,d0 ; "infinite" value for timeout <v1.5>
move.l d0,timeout(a4) ; set timeout to infinity <v1.5>
;………………………………………………………………………………………………………………………………………………………………………………………………………………………
;
;——— Do PRAM stuff : Bytes 2 & 3 are allocated for SCSI stuff
;
; ——— Byte 2 ———
; bit - def: meaning
; 7 - 0 : If set, disable the SCSIReset on machine reset
; 6 - 1 : unused
; 5 - 0 : unused
; 4 - 0 : unused (on PDM debug, affects Read DMA reads)
; 3 - 1 : validity bit (both must be 1 for bytes 2&3 to be valid, else init them)
; 2 - 1 : \
; 1 - 1 : — Host ID (i.e. SCSI ID of this Macintosh)
; 0 - 1 : /
;
; ——— Byte 3 ———
; 7 - 0 : unused
; 6 - 1 : unused
; 5 - 0 : unused
; 4 - 0 : unused (on PDM debug, affects Read DMA writes)
; 3 - 1 : validity bit (see above)
; 2 - 0 : \
; 1 - 0 : — "Internal Drive" ID (i.e. zero generally because nobody changes this)
; 0 - 0 : /
;
subq.l #2,sp ; make space for PRAM SCSI id <v1.4>
move.l sp,a0 ; address of PRAM return buffer
move.l #$00020002,d0 ; read 2 bytes of PRAM at offset 2 <C613>
_ReadXPRam ; get the SCSI id
move.w (sp),d0 ; check high bits for validity <A324>
and.w #$0808,d0 ; look at upper bit in lower nibble <SM15> pdw
cmp.w #$0808,d0 ; equal to magic pattern? <C613>
beq.s @GotID ; yes, so use those SCSI IDs <A324>
;--- if invalid, reinitialize values to defaults
@SetID
move.w #(($48+7)<<8) + ($48+0),(sp) ; defaults: CPU=7,hd=0 <C613>
move.l sp,a0 ; address of new PRAM value
move.l #$00020002,d0 ; write 2 bytes of PRAM to offset 2 <C613>
_WriteXPRam ; save the IDs in parameter RAM <C613>
@GotID
move.w (sp)+, D3 ; hold PRAM in D3 for later check of RESET bit
move.w D3,D0
lsr.w #8,d0 ; get CPU SCSI ID for shift count
and.w #$7,d0 ; mask all but the ID bit
moveq.l #1,d1 ; 1 << SCSI id
lsl.b d0,d1 ; form the SCSI id mask
move.b d1,G_ID(a4) ; initialize the ID mask
move.b d1,SCSIDrvrs ; clear all SCSI driver flags but our own
;………………………………………………………………………………………………………………………………………………………………………………………………………………………
;--- Jerry's stuff's starting
btst.b #sSCSIDMAExists,G_Reserved0+3(a4) ; do we have SCSI DMA ?
beq.s @noDCTRL ; if not, we don't need this constant
andi.l #LUNMask,d0 ; make sure CPU's SCSI ID is only thing in d0
moveq.l #bDMABERR+1,d1 ; bit position of CPU ID in sDCTRL register
lsl.l d1,d0 ; shift the CPU SCSI ID up
ori.l #(iARBIDEN)|\ ; enable auto-arbitration
iINTREN,d0 ; set up for auto-arbitration
move.l d0,G_Reserved2(a4) ; save "machine-specific" value
move.l #sc250msTicks,G_Reserved1(a4) ; constant for 250ms 4-byte timeout <3>
@noDCTRL
move.w #250,G_Async(a4) ; old SCSI Mgr Select timeout of 250 ms
; (G_State, G_Reserved0-2 (pageFault), G_ExtPtr = 0)
; (discLUN, discID, state1 = 0)
@setIntfLvl
move.b #mgrVersion,state2(a4) ; save the version number
@setBusTO
move.l #4,busTO(a4) ; assume 4 us byte-to-byte hhsk timeout (default)
btst.b #sSCSIDMAExists,G_Reserved0+3(a4) ; do we have a SCSI DMA chip ?
beq.s @initPhaseTable ; if not, skip
move.l #$19999999,busTO(a4) ; 7.2 minute byte-to-byte timeout <v1.5>
@initPhaseTable
moveq.l #numExtVec-1,d1 ; lots of jump table entries to process
lea.l SCSIMgr,a1 ; point to start of SCSI Mgr code
move.l a1,d0 ; keep base of it
lea OffsetTbl2,a1 ; address of offset table
lea.l phaseTable(a4),a0 ; point at the phase handler jump table
@MakeJmpTbl2
move.w (a1)+,d2 ; get the next offset
ext.l d2 ; make it a long <SM3>
beq.s @zero ; if it is zero, place a zero in the globals
add.l d0,d2 ; compute the address
move.l d2,(a0)+ ; install it in the jump table
bra.s @loop ; continue looping
@zero
move.l zeroReg,(a0)+ ; zero the vector (unique error vector ???) <v1.4>
@loop
dbra d1,@MakeJmpTbl2 ; loop for all vectors
@setupMsgInTbl
@setupMsgOutTbl
moveq.l #(numMsgVct/2)-1,d1 ; # of message routing vectors ("2*numMsgVct/4" longs)
lea.l msgTbl,a1 ; address of message routing table
lea.l msgInTbl(a4),a0 ; point at the message routing table in RAM
@makeMsgTbl
move.l (a1)+,(a0)+ ; copy the routing information
dbra.w d1,@makeMsgTbl ; do for all entries
@setupDeferredTask
lea.l dTask(a4),a1 ; point to Deferred Task Mgr task record
move.w #dtQType,qType(a1) ; set qType <v1.5>
lea.l SCSIDT,a0 ; address of deferred task
move.l a0,dtAddr(a1) ; set dtAddr <v1.5>
@setupTimer
lea.l timer(a4),a0 ; point to Time Mgr task record
lea.l TimeTask,a1 ; point to timer interrupt handler
move.l a1,tmAddr(a0) ; point to interrupt handler
_InsTime ; install the task record in Time Mgr queue <v1.7>
@setupReqSense
;
; This sets up the data-chaining commands for the automatic Request Sense feature.
;
move.w #$0300,RSCmd(a4) ; Request Sense command byte <v1.5>
lea.l RSDC(a4),a1 ; point to Req Sense data-chaining instr
moveq.l #1,d0
move.l d0,dcCount(a1) ; move one byte
move.l d0,dcOffset(a1) ; bump address by one
adda.w #dcSize,a1 ; point to next data-chaining instr
moveq.l #dcLoop,d0 ; "dcLoop" instruction (-1)
move.l d0,dcAddr(a1) ; set the opcode
move.l d0,dcOffset(a1) ; -1 happens to be the loop offset, also
@setupDummyPB
lea.l dummy(a4),a1 ; point to the dummy parameter block <v1.8>
st.b scsiReqID(a1) ; mark as a dummy parameter block (only once) <v1.8>
lea.l dummyPriv(a4),a0 ; point to private storage for dummy PB <v1.5>
move.l a0,scsiPrivate(a1) ; attach private storage to dummy PB <v1.5>
@setupDummyPrivate
@setupFaultPrivate
; nothing to do
@setupPrivates
lea.l firstPriv(a4),a1 ; point to first private storage record <v1.7>
move.l a1,firstPrivate(a4) ; save ptr to head of queue
move.l a1,nextPrivate(a4) ; it's also the first available record
move.l a1,d0 ; put addr of record in d0
moveq.l #scsiPrivPBSize,d1 ; size of each record
add.l d1,d0 ; addr of next record
move.l d0,(a1) ; save pointer to next record
move.l d0,a1 ; point to next record
add.l d1,d0 ; addr of next record
move.l d0,(a1) ; save pointer to next record
move.l d0,a1 ; point to next record
add.l d1,d0 ; addr of next record
move.l d0,(a1) ; save pointer to next record
;--- Jerry's stuff's over
;………………………………………………………………………………………………………………………………………………………………………………………………………………………
;——— Do the 53c96 Software Initializations
TestFor GrandCentralExists ; do we have Grand Central ?
bne.s @xit
TestFor SCSI96_1Exists ; do we have a SCSI96_1 chip ?
beq.s @xit ; no c96, so exit
TestFor PSCExists ; are we running with a PSC ?
beq.s @noPSC ; no, do the c96 stuff.
IMPORT InitMgr_SCSI_PSC ; <P2>
bsr.l InitMgr_SCSI_PSC ; initialize SCSIMgr for 5396 (with PSC)<P2>
bra @xit
; The Quadra 700/9x0 machines are the only ones that will ever use <SM11> CSS
; combination of Orwell + DAFB_Turbo_SCSI ASICs. Identify whether <SM11> CSS
; we're on a Quadra by the memory controller, which is readily <SM11> CSS
; testable via the TestFor MACRO. <SM11> CSS
@noPSC
TestFor HMCDecoder ;
bne.s @96_Init ; IF PDM SCSI <SM14> CSS
TestFor OrwellExists ; <SM11> CSS
beq.s @BIOS_Init ; ELSE IF Quadra_Based_SCSI THEN <SM11> CSS
@96_Init bsr.l InitMgr_SCSI96 ; InitMgr_SCSI96() <SM11> CSS
bra.s @xit ; ELSE <SM11> CSS
@BIOS_Init
bsr.l InitMgr_SCSI96_BIOS ; InitMgr_SCSI96_BIOS() <SM11> CSS
@xit ;
;………………………………………………………………………………………………………………………………………………………………………………………………………………………
;——— POWER MANAGER stuff in the SCSI Manager
; Install a sleep queue element
TestFor hwCbPwrMgr ; is there a power manager in this machine?
beq.s @nopmgr2 ; no power manager
@setupDoSpinDown
lea.l DoSpinDown,a1 ; ptr to the spin-down timer task
move.l PmgrBase,a0 ; point to the Power Mgr globals
move.l a1,HDvector(a0) ; store the routine address
@setupSleepTask
movea.l G_Reserved2(a4),a0 ; point a0 at the Sleep queue element
lea.l SleepTask,a1 ; ptr to the Sleep task
move.l a1,SleepqProc(a0) ; store the routine address
move.w #SlpQType,SleepqType(a0) ; set up the type
clr.w SleepqFlags(a0) ; clear out the flags
_SlpQInstall ; enqueue the element
@nopmgr2
;………………………………………………………………………………………………………………………………………………………………………………………………………………………
;——— Install the new dual bus DB Lite SCSI manager if we have a valid external c80 address <H3>
@InstallSCSIDB ; <SM11> CSS
TestFor MSCChipBit ; <SM11> CSS
beq.s @noExtc80 ; don't initialize if not on a DB Lite <SM11> CSS
IMPORT InitMgr_SCSIDB ; <SM11> CSS
bsr.l InitMgr_SCSIDB ; initialize SCSIMgr for DB Lite external c80 <SM11> CSS
@noExtc80
;………………………………………………………………………………………………………………………………………………………………………………………………………………………
;——— If this ROM (build time) hasAsyncSCSI and (runtime) we Should have it, run InitItt
IF hasAsyncSCSI THEN
bsr.s ShouldWeDoAsyncSCSI
beq.s @skipAsync ; no -> don't run async
CASE ON
IMPORT InitItt
movem.l D0-D2/A1, -(sp)
lea InitItt, A0
jsr (A0) ; This will only initialize Itt on 53c96 machines.
movem.l (sp)+, D0-D2/A1 ; It has no effect on other machines.
CASE OFF
@skipAsync
ENDIF
;………………………………………………………………………………………………………………………………………………………………………………………………………………………
@resetBus
btst #15,D3 ; (pram 2,bit7) skip the reset? <C644>
bne.s @skip ; skip if set <C644>
subq.l #2, sp
_SCSIReset ; taken from StartInit.a <A300/30Oct86>
addq.l #2, sp
@skip
;………………………………………………………………………………………………………………………………………………………………………………………………………………………
@InitSCSIDone
movem.l (sp)+,intrRegs ; restore registers
rts
; NAME 'InitSCSIMgr'
;________________________________________________________________________________
;================================================================================
ShouldWeDoAsyncSCSI
TestFor SCSI96_1Exists ; Do we have at least 1 c96 ?
beq.s @DontDoAsyncSCSI ; -> Nope, we can't do it then
IF forPDMProto THEN
TestFor HMCDecoder ; are we PDM ?
beq.s @DoAsyncSCSI ; -> Nope, Try to initialize Itt
;
; Even if we're not an EVT1, we need to check how fast the bus clock is because of AMIC1,2 problem with the VIAs
; If BusClockRate < 50MHz then DoAsync else
; (if >= 50MHz) then check for AMIC3 (because we should be able to work with it)
;
movem.l ([ProcessorInfoPtr],\
ProcessorInfo.BusClockRateHz),D1 ; Get the I/O bus clock rate <SM17>
cmp.l #50000000, D1 ; 50MHz bus?
blo.s @DoAsyncSCSI ; -> we're lower, its ok to do itt. <SM17>
CASE ON
IMPORT DoWeHaveAMIC3B
bsr.w DoWeHaveAMIC3B
CASE OFF
beq.s @DontDoAsyncSCSI ; no -> don't run async
; yes: it's OK to run at 50MHz with an AMIC3B
ENDIF
@DoAsyncSCSI
moveq.l #1, D0
rts
@DontDoAsyncSCSI
clr.l D0
rts
; NAME 'ShouldWeDoAsyncSCSI'
;_______________________________________________________________________
;*********** Old SCSI Manager Dispatch Tables *******************
OffsetTbl
DC.W DoSCSIReset-SCSIMgr ; 0: SCSIReset
DC.W DoSCSIGet-SCSIMgr ; 1: SCSIGet
DC.W DoSCSISelect-SCSIMgr ; 2: SCSISelect
DC.W DoSCSICmd-SCSIMgr ; 3: SCSICmd
DC.W DoSCSIComplete-SCSIMgr ; 4: SCSIComplete
DC.W NewSCSIRead-SCSIMgr ; 5: SCSIRead
DC.W NewSCSIWrite-SCSIMgr ; 6: SCSIWrite
DC.W Unimplemented-SCSIMgr ; 7: Was SCSIInstall <v1.4>
DC.W NewSCSIRBlind-SCSIMgr ; 8: SCSIRBlind
DC.W NewSCSIWBlind-SCSIMgr ; 9: SCSIWBlind
DC.W DoSCSIStat-SCSIMgr ; 10: SCSIStat
DC.W DoSCSISelAtn-SCSIMgr ; 11: SCSISelAtn <A370/07Nov86>
DC.W DoSCSIMsgIn-SCSIMgr ; 12: SCSIMsgIn
DC.W DoSCSIMsgOut-SCSIMgr ; 13: SCSIMsgOut
;*********** Jerry's Tables *******************
OffsetTbl2
@patchPhaseTable
DC.W DataIO-SCSIMgr ; 00: Data (Out) phase handler
DC.W DataIO-SCSIMgr ; 01: Data (In) phase handler
DC.W Command-SCSIMgr ; 02: Command phase handler
DC.W StatusPhase-SCSIMgr ; 03: Status phase handler
DC.W ResetBus-SCSIMgr ; 04: Illegal phase handler
DC.W ResetBus-SCSIMgr ; 05: Illegal phase handler
DC.W MsgOut-SCSIMgr ; 06: Message Out phase handler
DC.W MsgIn-SCSIMgr ; 07: Message In phase handler
@patchTransferTable
DC.W SlowRead-SCSIMgr ; 08: Slow read routine
DC.W SlowWrite-SCSIMgr ; 09: Slow write routine
DC.W VFastRead-SCSIMgr ; 10: Fast read routine
DC.W VFastWrite-SCSIMgr ; 11: Fast write routine
DC.W 0 ; 12: Unused (illegal)
DC.W 0 ; 13: Unused (illegal)
DC.W PFastRead-SCSIMgr ; 14: Physical fast read routine
DC.W PFastWrite-SCSIMgr ; 15: Physical fast write routine
DC.W SlowRead-SCSIMgr ; 16: Slow read routine
DC.W SlowWrite-SCSIMgr ; 17: Slow write routine
DC.W FastRead-SCSIMgr ; 18: Old SCSI Mgr (hhsk) fast read routine
DC.W FastWrite-SCSIMgr ; 19: Old SCSI Mgr (hhsk) fast write routine
DC.W SlowComp-SCSIMgr ; 20: Slow compare routine
DC.W 0 ; 21: Unused
DC.W FastComp-SCSIMgr ; 22: Fast compare routine
DC.W 0 ; 23: Unused
@patchMsgTable
; Message In handlers
DC.W msgInvalidIn-SCSIMgr ; 24: bad incoming message -- start a Message Reject
DC.W msgIdentifyIn-SCSIMgr ; 25: incoming Identify message
DC.W msgCmdComplete-SCSIMgr ; 26: incoming Command Complete message
DC.W 0 ; 27: no Extended Message
DC.W msgSaveDataPtr-SCSIMgr ; 28: msgSaveDataPtr
DC.W msgRestorePtrs-SCSIMgr ; 29: msgRestorePtrs
DC.W msgDisconnect-SCSIMgr ; 30: msgDisconnect
DC.W msgMsgRejIn-SCSIMgr ; 31: incoming Message Reject
DC.W msgLCCF-SCSIMgr ; 32: Linked Command Complete with (or w/o) Flag
DC.W 0 ; 33: Unused10
DC.W 0 ; 34: Unused11
DC.W 0 ; 35: Unused12
DC.W 0 ; 36: Unused13
DC.W 0 ; 37: Unused14
DC.W 0 ; 38: Unused15
DC.W 0 ; 39: Unused16
; Message Out handlers
DC.W msgIdentifyOut-SCSIMgr ; 40: outgoing Identify message
DC.W msgMsgRejOut-SCSIMgr ; 41: outgoing Message Reject message
DC.W msgInvalidOut-SCSIMgr ; 42: bad Message Out state machine handler
DC.W msgKillio-SCSIMgr ; 43: Kill I/O sequence
DC.W msgNoOp-SCSIMgr ; 44: outgoing No Operation message
DC.W msgBusDevRst-SCSIMgr ; 45: outgoing Bus Device Reset message <v1.5>
DC.W 0 ; 46: Unused23
DC.W 0 ; 47: Unused24
DC.W 0 ; 48: Unused25
DC.W 0 ; 49: Unused26
DC.W 0 ; 50: Unused27
DC.W 0 ; 51: Unused28
DC.W 0 ; 52: Unused29
DC.W 0 ; 53: Unused30
DC.W 0 ; 54: Unused31
DC.W 0 ; 55: Unused32
@patchUtilityTable
DC.W SCSIIntHnd-SCSIMgr ; 56: interrupt handler
DC.W Message-SCSIMgr ; 57: send a msg to SCSIDT
DC.W ClearIRQ-SCSIMgr ; 58: clear SCSI interrupts
DC.W DisEnable-SCSIMgr ; 59: enable/disable interrupts
DC.W LogError-SCSIMgr ; 60: log errors in the PB <v1.4>
DC.W SCSIDT-SCSIMgr ; 61: SCSI Mgr deferred task
DC.W Find-SCSIMgr ; 62: find a PB to process
DC.W Setup-SCSIMgr ; 63: setup a PB
DC.W Preflight-SCSIMgr ; 64: preflight a PB
DC.W EnDequeue-SCSIMgr ; 65: enqueue/dequeue routine
DC.W Arb-SCSIMgr ; 66: Arb
DC.W Sel-SCSIMgr ; 67: Sel
DC.W Delay22-SCSIMgr ; 68: Delay22
DC.W ClearState-SCSIMgr ; 69: ClearState
DC.W Transfer-SCSIMgr ; 70: Transfer
DC.W SetTimer-SCSIMgr ; 71: SetTimer
DC.W ResetBus-SCSIMgr ; 72: ResetBus
DC.W ClearBus-SCSIMgr ; 73: ClearBus
DC.W BusErrHandler-SCSIMgr ; 74: Bus error handler
DC.W DataDMA-SCSIMgr ; 75: DMA-related data-chaining interpreter <v1.4>
DC.W 0 ; 76: Unused8
DC.W 0 ; 77: Unused9
DC.W 0 ; 78: Unused10
DC.W 0 ; 79: Unused11
DC.W 0 ; 80: Unused50
DC.W 0 ; 81: Unused51
DC.W 0 ; 82: Unused52
DC.W 0 ; 83: Unused53
DC.W 0 ; 84: Unused54
DC.W 0 ; 85: Unused55
DC.W 0 ; 86: Unused56
DC.W 0 ; 87: Unused57
@NewSCSIDispTbl
DC.W DoRequestIO-SCSIMgr ; 88: SCSIRequestIO
DC.W DoKillIO-SCSIMgr ; 89: SCSIKillIO
DC.W DoBusInfo-SCSIMgr ; 90: SCSIBusInfo
DC.W 0 ; 91: Unused63
DC.W 0 ; 92: Unused64
DC.W 0 ; 93: Unused65
DC.W 0 ; 94: Unused66
DC.W AltBusCall-SCSIMgr ; 95: Call to alternate SCSI bus
msgTbl
;
; Message In messages
;
DC.B jvCmdComplete-msgTable ; Command Complete sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvSaveDataPtr-msgTable ; Save Data Pointer sequence
DC.B jvRestorePtrs-msgTable ; Restore Pointers sequence
DC.B jvDisconnect-msgTable ; Disconnect sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvMsgRejIn-msgTable ; Message Reject in sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
DC.B jvInvalidIn-msgTable ; Message Reject out sequence
;
; Message Out scenarios
;
DC.B jvIdentifyOut-msgTable ; normal Identify sequence
DC.B jvMsgRejOut-msgTable ; Message Reject sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvKillIO-msgTable ; Kill I/O sequence
DC.B jvNoOp-msgTable ; No Operation sequence
DC.B jvBusDevRstOut-msgTable ; Bus Device Reset state machine state sequence <v1.5>
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
DC.B jvInvalidOut-msgTable ; Invalid state machine state sequence
; <11> rb, from here on we have new code from Terror
;————————————————————————————————————————————————————————————————————————————
;
; InitSCSIHW - Initialize whatever SCSCI controller this system has.
; Existing Mac SCSI systems are either 80-base or 96-based
;
; -> no inputs
; <- no outputs
; trashes D0, D1
;
; Called: from StartInit.a
InitSCSIHW
IMPORT InitHW_SCSI96
movem.l a3/a4,-(sp) ; <T9>
IF hasAsyncSCSI THEN
bsr.s ShouldWeDoAsyncSCSI
bne.s @Exit ; yes -> skip this bogus HW init
ENDIF
movea.l SCSIBase, a3 ; setup SCSI base addrs
TestFor SCSI96_1Exists ; use macro to check if we have
bne.s @FirstSCSI96 ; 1st SCSI96. Bra. if so
bsr.s InitHW_SCSI80 ; Init SCSI 5380 hw
bra @Exit ; <SM12> CSS
@FirstSCSI96
move.l #SCSI0_DAFB, a4 ; setup SCSI DAFB addrs <T9>
bsr.s @InitSCSIMulti ; Init first SCSI bus
@SecondSCSI96
TestFor SCSI96_2Exists ; use macro to check if we have
beq.s @Exit ; 2nd SCSI96. Bra. if not
movea.l SCSI2Base, a3 ; setup SCSI base addrs
move.l #SCSI1_DAFB, a4 ; setup SCSI DAFB addrs <T9>
bsr.s @InitSCSIMulti ; Init Second SCSI bus
@Exit movem.l (sp)+,a3/a4 ; <T9>
rts
;……………………………………………………
@InitSCSIMulti
TestFor PSCExists ; are we running with a PSC ?
beq.s @noPSC ; no psc, do the 96
bsr.l InitHW_SCSI_PSC ; Init SCSI 5396 hw <P2>
bra.s @rts
; The Quadra 700/9x0 machines are the only ones that will ever use <SM11> CSS
; combination of Orwell + DAFB_Turbo_SCSI ASICs. Identify whether <SM11> CSS
; we're on a Quadra by the memory controller, which is readily <SM11> CSS
; testable via the TestFor MACRO. <SM11> CSS
@noPSC
TestFor HMCDecoder ;
bne.s @96_Init ; IF PDM SCSI <SM14> CSS
TestFor OrwellExists ; <SM11> CSS
beq.s @BIOS_Init ; ELSE IF Quadra_Based_SCSI THEN <SM11> CSS
@96_Init bsr.l InitHW_SCSI96 ; InitHW_SCSI96() <SM11> CSS
bra.s @rts ; ELSE <SM11> CSS
@BIOS_Init
bsr.l InitHW_SCSI96_BIOS ; InitHW_SCSI96_BIOS() <SM11> CSS
@rts rts
;……………………………………………………
;————————————————————————————————————————————————————————————————————————————
;
; Old InitSCSI: Reset 5380 registers to a known state.
; From StartInit.a, InitSCSI Proc. Should be in SCSIMgrHW.a (c80-based)
;
;
; a3 -> SCSI base address
;
; Destroys A0, D0
; Called by Hardware init sequence
InitHW_SCSI80
CLR.B sICR+wrOffs(a3) ; Clear Initiator Command Register.
CLR.B sMR+wrOffs(a3) ; Clear Mode Register.
CLR.B sTCR+wrOffs(a3) ; Clear Target Command Register.
CLR.B sSER+wrOffs(a3) ; Clear Select Enable Register.
RTS
ENDWITH
ENDP
END