mirror of https://github.com/wwarthen/RomWBW.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1011 lines
26 KiB
1011 lines
26 KiB
;
|
|
;=============================================================================
|
|
; SCSI DISK DRIVER FOR 5380
|
|
;=============================================================================
|
|
;
|
|
; DISK DEVICE DRIVER FOR THE 5380 SCSI CHIP.
|
|
; DERIVED FROM CODE PROVIDED BY JAY COTTON.
|
|
;
|
|
; TODO:
|
|
; - IMPLEMENT BUS SCANNING FOR DEVICES AT STARTUP
|
|
; - USE TEST UNIT READY TO WAIT FOR SPINUP?
|
|
;
|
|
; NOTES:
|
|
;
|
|
SCSIBASE .EQU $40
|
|
;
|
|
; SCSI DEVICE STATUS CODES
|
|
;
|
|
SCSI_STOK .EQU 0
|
|
SCSI_STNOMEDIA .EQU -1
|
|
SCSI_STIOERR .EQU -2
|
|
SCSI_STTO .EQU -3
|
|
SCSI_STNOTRDY .EQU -4
|
|
;
|
|
; NCR 5380 I/O REGISTERS
|
|
;
|
|
SCSI_SR_CSD .EQU SCSIBASE ; CURRENT SCSI DATA
|
|
SCSI_SR_ICR .EQU SCSIBASE + $01 ; INITIATOR COMMAND
|
|
SCSI_SR_MR .EQU SCSIBASE + $02 ; MODE
|
|
SCSI_SR_TCR .EQU SCSIBASE + $03 ; TARGET COMMAND
|
|
SCSI_SR_CSBS .EQU SCSIBASE + $04 ; CURRENT SCSI BUS STAT
|
|
SCSI_SR_BSR .EQU SCSIBASE + $05 ; BUS STATUS
|
|
SCSI_SR_IDR .EQU SCSIBASE + $06 ; INITIATOR DMA RECV
|
|
SCSI_SR_RPI .EQU SCSIBASE + $07 ; RESET PARITY/IRQ
|
|
;
|
|
; NCR 5380 OUTPUT ONLY REGISTERS
|
|
;
|
|
SCSI_SR_ODR .EQU SCSIBASE ; OUTPUT DATA
|
|
SCSI_SR_SER .EQU SCSIBASE + $04 ; SELECT ENABLE
|
|
SCSI_SR_SDS .EQU SCSIBASE + $05 ; START DMA SEND
|
|
SCSI_SR_SDTR .EQU SCSIBASE + $06 ; START TARGET DMA RECV
|
|
SCSI_SR_SDIR .EQU SCSIBASE + $07 ; START INITIATOR DMA RECV
|
|
;
|
|
; SCSI CURRENT BUS STATUS BIT MASKS
|
|
;
|
|
SCSI_SM_RST .EQU $80 ; RESET
|
|
SCSI_SM_BSY .EQU $40 ; BUSY
|
|
SCSI_SM_REQ .EQU $20 ; REQUEST
|
|
SCSI_SM_MSG .EQU $10 ; MESSAGE
|
|
SCSI_SM_CD .EQU $08 ; CMD/DATA
|
|
SCSI_SM_IO .EQU $04 ; IN/OUT
|
|
SCSI_SM_SEL .EQU $02 ; SELECT
|
|
SCSI_SM_DBP .EQU $01 ; PARITY BIT
|
|
;
|
|
SCSI_SM_PHM .EQU $08 ; PHASE MATCH BIT
|
|
;
|
|
; SDCI DEVICE CONFIGURATION
|
|
;
|
|
; PER DEVICE DATA OFFSETS IN CFG BLOCK
|
|
;
|
|
SCSI_DEV .EQU 0 ; OFFSET OF DEVICE NUMBER (BYTE)
|
|
SCSI_IOBASE .EQU 1 ; IO BASE ADDRESS (BYTE)
|
|
SCSI_TGT .EQU 2 ; TARGET DEVICE ID
|
|
SCSI_TID .EQU 3 ; TARGET DEVICE BIT PATTERN
|
|
SCSI_LUN .EQU 4 ; TARGET LUN
|
|
SCSI_STAT .EQU 5 ; LAST STATUS (BYTE)
|
|
SCSI_MEDCAP .EQU 6 ; MEDIA CAPACITY (DWORD)
|
|
SCSI_LBA .EQU 10 ; OFFSET OF LBA (DWORD)
|
|
;
|
|
SCSI_CFGSIZ .EQU 14 ; SIZE OF CFG TBL ENTRIES
|
|
;
|
|
;--------------------------------------------------------------------------------------------------
|
|
; HBIOS MODULE HEADER
|
|
;--------------------------------------------------------------------------------------------------
|
|
;
|
|
ORG_SCSI .EQU $
|
|
;
|
|
.DW SIZ_SCSI ; MODULE SIZE
|
|
.DW SCSI_INITPHASE ; ADR OF INIT PHASE HANDLER
|
|
;
|
|
SCSI_INITPHASE:
|
|
; INIT PHASE HANDLER, A=PHASE
|
|
;CP HB_PHASE_PREINIT ; PREINIT PHASE?
|
|
;JP Z,SCSI_PREINIT ; DO PREINIT
|
|
CP HB_PHASE_INIT ; INIT PHASE?
|
|
JP Z,SCSI_INIT ; DO INIT
|
|
RET ; DONE
|
|
;
|
|
SCSI_CFGTBL:
|
|
;
|
|
#IF (SCSICNT >= 1)
|
|
;
|
|
SCSI0_CFG:
|
|
.DB $FE ; DRIVER DEVICE NUMBER (FILLED DYNAMICALLY)
|
|
.DB SCSIBASE ; IO BASE ADDRESS
|
|
.DB SCSI0_TGT ; TARGT DEVICE ID
|
|
.DB 1 << SCSI0_TGT ; TARGET DEVICE BIT PATTERN
|
|
.DB SCSI0_LUN ; SCSI TARGET LUN
|
|
.DB SCSI_STNOTRDY ; DEVICE STATUS
|
|
.DW $0000,$0010 ; DEVICE CAPACITY (BLOCKS)
|
|
.DW 0,0 ; CURRENT LBA
|
|
;
|
|
DEVECHO "SCSI: IO="
|
|
DEVECHO SCSIBASE
|
|
DEVECHO ", TGT="
|
|
DEVECHO SCSI0_TGT
|
|
DEVECHO ", LUN="
|
|
DEVECHO SCSI0_LUN
|
|
DEVECHO "\n"
|
|
#ENDIF
|
|
;
|
|
#IF (SCSICNT >= 2)
|
|
.DB $FE ; DRIVER DEVICE NUMBER (FILLED DYNAMICALLY)
|
|
.DB SCSIBASE ; IO BASE ADDRESS
|
|
.DB SCSI1_TGT ; TARGT DEVICE ID
|
|
.DB 1 << SCSI1_TGT ; TARGET DEVICE BIT PATTERN
|
|
.DB SCSI1_LUN ; SCSI TARGET LUN
|
|
.DB SCSI_STNOTRDY ; DEVICE STATUS
|
|
.DW $0000,$0010 ; DEVICE CAPACITY (BLOCKS)
|
|
.DW 0,0 ; CURRENT LBA
|
|
;
|
|
DEVECHO "SCSI: IO="
|
|
DEVECHO SCSIBASE
|
|
DEVECHO ", TGT="
|
|
DEVECHO SCSI1_TGT
|
|
DEVECHO ", LUN="
|
|
DEVECHO SCSI1_LUN
|
|
DEVECHO "\n"
|
|
#ENDIF
|
|
;
|
|
#IF (SCSICNT >= 3)
|
|
.DB $FE ; DRIVER DEVICE NUMBER (FILLED DYNAMICALLY)
|
|
.DB SCSIBASE ; IO BASE ADDRESS
|
|
.DB SCSI2_TGT ; TARGT DEVICE ID
|
|
.DB 1 << SCSI2_TGT ; TARGET DEVICE BIT PATTERN
|
|
.DB SCSI2_LUN ; SCSI TARGET LUN
|
|
.DB SCSI_STNOTRDY ; DEVICE STATUS
|
|
.DW $0000,$0010 ; DEVICE CAPACITY (BLOCKS)
|
|
.DW 0,0 ; CURRENT LBA
|
|
;
|
|
DEVECHO "SCSI: IO="
|
|
DEVECHO SCSIBASE
|
|
DEVECHO ", TGT="
|
|
DEVECHO SCSI2_TGT
|
|
DEVECHO ", LUN="
|
|
DEVECHO SCSI2_LUN
|
|
DEVECHO "\n"
|
|
#ENDIF
|
|
;
|
|
#IF (SCSICNT >= 4)
|
|
.DB $FE ; DRIVER DEVICE NUMBER (FILLED DYNAMICALLY)
|
|
.DB SCSIBASE ; IO BASE ADDRESS
|
|
.DB SCSI3_TGT ; TARGT DEVICE ID
|
|
.DB 1 << SCSI3_TGT ; TARGET DEVICE BIT PATTERN
|
|
.DB SCSI3_LUN ; SCSI TARGET LUN
|
|
.DB SCSI_STNOTRDY ; DEVICE STATUS
|
|
.DW $0000,$0010 ; DEVICE CAPACITY (BLOCKS)
|
|
.DW 0,0 ; CURRENT LBA
|
|
;
|
|
DEVECHO "SCSI: IO="
|
|
DEVECHO SCSIBASE
|
|
DEVECHO ", TGT="
|
|
DEVECHO SCSI3_TGT
|
|
DEVECHO ", LUN="
|
|
DEVECHO SCSI3_LUN
|
|
DEVECHO "\n"
|
|
#ENDIF
|
|
;
|
|
#IF ($ - SCSI_CFGTBL) != (SCSICNT * SCSI_CFGSIZ)
|
|
.ECHO "*** INVALID SCSI CONFIG TABLE ***\n"
|
|
#ENDIF
|
|
;
|
|
.DB $FF ; END OF TABLE MARKER
|
|
;
|
|
;=============================================================================
|
|
; INITIALIZATION ENTRY POINT
|
|
;=============================================================================
|
|
;
|
|
SCSI_INIT:
|
|
CALL NEWLINE ; FORMATTING
|
|
PRTS("SCSI:$") ; TAG
|
|
;
|
|
PRTS(" IO=0x$") ; LABEL FOR IO ADDRESS
|
|
LD A,SCSIBASE ; GET IO BASE ADDRES
|
|
CALL PRTHEXBYTE ; DISPLAY IT
|
|
;
|
|
CALL SCSI_DETECT ; DETECT THE SCSI INTERFACE
|
|
JR Z,SCSI_INIT1 ; IF FOUND CONTINUE
|
|
PRTS(" NOT PRESENT$") ; SHOW NOT PRESENT
|
|
XOR A ; SUCCESS
|
|
RET ; AND BAIL OUT
|
|
;
|
|
SCSI_INIT1:
|
|
XOR A ; ZERO ACCUM
|
|
LD (SCSI_DEVNUM),A ; INIT DEV UNIT NUM FOR DYNAMIC ASSIGNMENT
|
|
LD IY,SCSI_CFGTBL ; POINT TO START OF CONFIG TABLE
|
|
;
|
|
SCSI_INIT2:
|
|
LD A,(IY) ; LOAD FIRST BYTE TO CHECK FOR END
|
|
CP $FF ; CHECK FOR END OF TABLE VALUE
|
|
RET Z ; RETURN IF DONE
|
|
;
|
|
CALL SCSI_INIT3 ; REGISTER & INIT DEVICE
|
|
;
|
|
LD DE,SCSI_CFGSIZ ; SIZE OF CFG TABLE ENTRY
|
|
ADD IY,DE ; BUMP POINTER
|
|
JP SCSI_INIT2 ; AND LOOP
|
|
;
|
|
SCSI_INIT3:
|
|
; UPDATE DRIVER RELATIVE UNIT NUMBER IN CONFIG TABLE
|
|
LD A,(SCSI_DEVNUM) ; GET NEXT UNIT NUM TO ASSIGN
|
|
LD (IY+SCSI_DEV),A ; UPDATE IT
|
|
INC A ; BUMP TO NEXT UNIT NUM TO ASSIGN
|
|
LD (SCSI_DEVNUM),A ; SAVE IT
|
|
;
|
|
; ADD UNIT TO GLOBAL DISK UNIT TABLE
|
|
LD BC,SCSI_FNTBL ; BC := FUNC TABLE ADR
|
|
PUSH IY ; CFG ENTRY POINTER
|
|
POP DE ; COPY TO DE
|
|
CALL DIO_ADDENT ; ADD ENTRY TO GLOBAL DISK DEV TABLE
|
|
;
|
|
CALL SCSI_PRTPREFIX ; TAG FOR ACTIVE DEVICE
|
|
;
|
|
PRTS(" TGT=$") ; LABEL FOR TARGET DEVICE
|
|
LD A,(IY+SCSI_TGT) ; GET TARGET DEVICE
|
|
CALL PRTDEC8 ; DISPLAY IT
|
|
;
|
|
PRTS(" LUN=$") ; LUN LABEL
|
|
LD A,(IY+SCSI_LUN) ; LOAD LUN
|
|
CALL PRTDEC8 ; DISPLAY IT
|
|
;
|
|
CALL SCSI_INITDEV ; INITIALIZE DEVICE
|
|
#IF (SCSITRACE < 2)
|
|
JP NZ,SCSI_PRTSTATSTR ; IF ERROR, EXIT VIA PRINT
|
|
#ELSE
|
|
RET NZ
|
|
#ENDIF
|
|
;
|
|
; PRINT STORAGE CAPACITY (BLOCK COUNT)
|
|
PRTS(" BLOCKS=0x$") ; PRINT FIELD LABEL
|
|
LD A,SCSI_MEDCAP ; OFFSET TO CAPACITY FIELD
|
|
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
|
|
CALL LD32 ; GET THE CAPACITY VALUE
|
|
CALL PRTHEX32 ; PRINT HEX VALUE
|
|
;
|
|
; PRINT STORAGE SIZE IN MB
|
|
PRTS(" SIZE=$") ; PRINT FIELD LABEL
|
|
LD B,11 ; 11 BIT SHIFT TO CONVERT BLOCKS --> MB
|
|
CALL SRL32 ; RIGHT SHIFT
|
|
CALL PRTDEC32 ; PRINT DWORD IN DECIMAL
|
|
PRTS("MB$") ; PRINT SUFFIX
|
|
;
|
|
; PRINT INQUIRY DATA (STILL IN HB_WRKBUF FROM INITDEV)
|
|
CALL PC_SPACE ; FORMATTING
|
|
CALL PC_LBKT ; FORMATTING
|
|
LD HL,HB_WRKBUF+8 ; START OF ASCII DATA
|
|
LD B,28 ; VENDOR, PRODUCT, AND REVISTION FIELDS
|
|
SCSI_INIT4:
|
|
LD A,(HL) ; LOAD NEXT CHAR
|
|
CALL COUT ; PRINT IT
|
|
INC HL ; BUMP BUFFER POINTER
|
|
DJNZ SCSI_INIT4 ; LOOP AS NEEDED
|
|
CALL PC_RBKT ; FORMATTING
|
|
;
|
|
SCSI_INIT5:
|
|
XOR A ; SUCCESS
|
|
RET
|
|
;
|
|
;=============================================================================
|
|
; DRIVER FUNCTION TABLE
|
|
;=============================================================================
|
|
;
|
|
SCSI_FNTBL:
|
|
.DW SCSI_STATUS
|
|
.DW SCSI_RESET
|
|
.DW SCSI_SEEK
|
|
.DW SCSI_READ
|
|
.DW SCSI_WRITE
|
|
.DW SCSI_VERIFY
|
|
.DW SCSI_FORMAT
|
|
.DW SCSI_DEVICE
|
|
.DW SCSI_MEDIA
|
|
.DW SCSI_DEFMED
|
|
.DW SCSI_CAP
|
|
.DW SCSI_GEOM
|
|
#IF (($ - SCSI_FNTBL) != (DIO_FNCNT * 2))
|
|
.ECHO "*** INVALID SCSI FUNCTION TABLE ***\n"
|
|
#ENDIF
|
|
;
|
|
SCSI_VERIFY:
|
|
SCSI_FORMAT:
|
|
SCSI_DEFMED:
|
|
SYSCHKERR(ERR_NOTIMPL) ; NOT IMPLEMENTED
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
SCSI_READ:
|
|
CALL HB_DSKREAD ; HOOK HBIOS DISK READ SUPERVISOR
|
|
LD E,SCSI_CMD_READ ; SETUP READ COMMAND
|
|
JP SCSI_IO ; DO THE IO
|
|
;
|
|
;
|
|
;
|
|
SCSI_WRITE:
|
|
CALL HB_DSKWRITE ; HOOK HBIOS DISK WRITE SUPERVISOR
|
|
LD E,SCSI_CMD_WRITE ; SETUP WRITE COMMAND
|
|
JP SCSI_IO ; DO THE IO
|
|
;
|
|
;
|
|
;
|
|
SCSI_STATUS:
|
|
LD A,(IY+SCSI_STAT) ; GET STATUS OF SELECTED DEVICE
|
|
OR A ; SET FLAGS
|
|
RET ; AND RETURN
|
|
;
|
|
;
|
|
;
|
|
SCSI_RESET:
|
|
CALL SCSI_INITDEV ; REINITIALIZE UNIT
|
|
OR A ; SET RESULT FLAGS
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
SCSI_DEVICE:
|
|
LD D,DIODEV_SCSI ; D := DEVICE TYPE
|
|
LD E,(IY+SCSI_DEV) ; E := PHYSICAL DEVICE NUMBER
|
|
LD C,%00110000 ; C := GENERIC HARD DISK ATTRIBUTES
|
|
LD H,0 ; H := MODE
|
|
LD L,(SCSI_IOBASE) ; L := BASE I/O ADDRESS
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
SCSI_MEDIA:
|
|
LD A,E ; GET FLAGS
|
|
OR A ; SET FLAGS
|
|
JR Z,SCSI_MEDIA1 ; JUST REPORT CURRENT STATUS AND MEDIA
|
|
CALL SCSI_INITDEV ; REINITIALIZE DEVICE
|
|
;
|
|
SCSI_MEDIA1:
|
|
LD A,(IY+SCSI_STAT) ; GET STATUS
|
|
OR A ; SET FLAGS
|
|
LD D,0 ; NO MEDIA CHANGE DETECTED
|
|
LD E,MID_HD ; ASSUME WE ARE OK
|
|
RET Z ; RETURN IF GOOD INIT
|
|
LD E,MID_NONE ; SIGNAL NO MEDIA
|
|
LD A,ERR_NOMEDIA ; NO MEDIA ERROR
|
|
OR A ; SET FLAGS
|
|
RET ; AND RETURN
|
|
;
|
|
;
|
|
;
|
|
SCSI_SEEK:
|
|
BIT 7,D ; CHECK FOR LBA FLAG
|
|
CALL Z,HB_CHS2LBA ; CLEAR MEANS CHS, CONVERT TO LBA
|
|
RES 7,D ; CLEAR FLAG REGARDLESS (DOES NO HARM IF ALREADY LBA)
|
|
LD (IY+SCSI_LBA+0),L ; SAVE NEW LBA
|
|
LD (IY+SCSI_LBA+1),H ; ...
|
|
LD (IY+SCSI_LBA+2),E ; ...
|
|
LD (IY+SCSI_LBA+3),D ; ...
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET ; AND RETURN
|
|
;
|
|
;
|
|
;
|
|
SCSI_CAP:
|
|
LD A,(IY+SCSI_STAT) ; GET STATUS
|
|
PUSH AF ; SAVE IT
|
|
LD A,SCSI_MEDCAP ; OFFSET TO CAPACITY FIELD
|
|
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
|
|
CALL LD32 ; GET THE CURRENT CAPACITY INTO DE:HL
|
|
LD BC,512 ; 512 BYTES PER BLOCK
|
|
POP AF ; RECOVER STATUS
|
|
OR A ; SET FLAGS
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
SCSI_GEOM:
|
|
; FOR LBA, WE SIMULATE CHS ACCESS USING 16 HEADS AND 16 SECTORS
|
|
; RETURN HS:CC -> DE:HL, SET HIGH BIT OF D TO INDICATE LBA CAPABLE
|
|
CALL SCSI_CAP ; GET TOTAL BLOCKS IN DE:HL, BLOCK SIZE TO BC
|
|
LD L,H ; DIVIDE BY 256 FOR # TRACKS
|
|
LD H,E ; ... HIGH BYTE DISCARDED, RESULT IN HL
|
|
LD D,16 | $80 ; HEADS / CYL = 16, SET LBA CAPABILITY BIT
|
|
LD E,16 ; SECTORS / TRACK = 16
|
|
RET ; DONE, A STILL HAS SCSI_CAP STATUS
|
|
;
|
|
;=============================================================================
|
|
; FUNCTION SUPPORT ROUTINES
|
|
;=============================================================================
|
|
;
|
|
; ON RETURN, ZF SET INDICATES HARDWARE FOUND
|
|
;
|
|
SCSI_DETECT:
|
|
LD C,SCSIBASE+3
|
|
LD A,$05
|
|
OUT (C),A
|
|
NOP
|
|
IN A,(C)
|
|
CP $05
|
|
RET NZ
|
|
LD A,$0A
|
|
OUT (C),A
|
|
NOP
|
|
IN A,(C)
|
|
CP $0A
|
|
RET
|
|
;
|
|
; INITIALIZE DEVICE
|
|
;
|
|
SCSI_INITDEV:
|
|
; INQUIRY COMMAND TO DETERMINE IF DEVICE EXISTS
|
|
LD HL,HB_WRKBUF ; BUFFER FOR INQUIRY DATA
|
|
CALL SCSI_INQUIRY ; RUN THE COMMAND
|
|
JP NZ,SCSI_NOMEDIA ; CONVERT FAILURE TO NO MEDIA
|
|
;
|
|
; GET DEVICE CAPACITY
|
|
CALL SCSI_CAPACITY
|
|
RET NZ
|
|
;
|
|
XOR A
|
|
LD (IY+SCSI_STAT),A
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
SCSI_IO:
|
|
;
|
|
#IF (ESPSDTRACE == 1)
|
|
PUSH HL
|
|
LD HL,SCSI_PRTERR ; SET UP ESPSD_PRTERR
|
|
EX (SP),HL ; ... TO FILTER ALL EXITS
|
|
#ENDIF
|
|
;
|
|
LD (SCSI_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS
|
|
PUSH DE ; SAVE COMMAND BYTE
|
|
PUSH HL ; SAVE BUFFER ADDRESS
|
|
CALL SCSI_CHKERR ; CHECK FOR ERR STATUS AND RESET IF SO
|
|
POP HL ; RESTORE BUFFER ADDRESS
|
|
POP DE ; RESTORE COMMAND BYTE
|
|
RET NZ ; BAIL OUT ON ERROR
|
|
;
|
|
; SETUP SCSI COMMAND
|
|
LD A,E
|
|
LD (SCSI_S_CDB),A ; SET SCSI COMMAND
|
|
; SETUP DISK BUFFER POINTERS
|
|
LD (SCSI_BUF_OUT),HL ; INPUT BUFFER
|
|
LD (SCSI_BUF_IN),HL ; OUTPUT BUFFER
|
|
; SETUP CDB
|
|
LD HL,SCSI_S_CDB ; SET HL TO R/W CBD
|
|
LD (SCSI_CUR_CDB),HL ; SAVE IN IOT
|
|
; SETUP LUN/LBA
|
|
LD A,(IY+SCSI_LUN) ; PUT LUN IN ACCUM
|
|
RRCA ; MOVE TO TOP 3 BITS
|
|
RRCA ; ...
|
|
RRCA ; ...
|
|
LD B,A ; SAVE IN B
|
|
LD A,(IY+SCSI_LBA+2) ; GET MSB OF LBA
|
|
AND %00011111 ; CLEAR LUN BITS
|
|
OR B ; MERGE WITH LUN
|
|
LD (SCSI_CUR_LUN),A ; PUT IN CDB
|
|
LD A,(IY+SCSI_LBA+1) ; LBA MID
|
|
LD (SCSI_CUR_LBN),A ; PUT IN CDB
|
|
LD A,(IY+SCSI_LBA+0) ; LBA MID
|
|
LD (SCSI_CUR_LBN+1),A ; PUT IN CDB
|
|
; DO THE SCSI TRANSACTION
|
|
CALL SCSI_GO ; DO THE SCSI TRANSACTION
|
|
JR NZ,SCSI_IO1 ; IF ERROR, SKIP INCREMENT
|
|
; INCREMENT LBA
|
|
LD A,SCSI_LBA ; LBA OFFSET
|
|
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
|
|
CALL INC32HL ; INCREMENT THE VALUE
|
|
; INCREMENT DMA
|
|
LD HL,SCSI_DSKBUF+1 ; POINT TO MSB OF BUFFER ADR
|
|
INC (HL) ; BUMP DMA BY
|
|
INC (HL) ; ... 512 BYTES
|
|
XOR A ; SIGNAL SUCCESS
|
|
SCSI_IO1:
|
|
LD HL,(SCSI_DSKBUF) ; CURRENT DMA TO HL
|
|
OR A ; SET FLAGS
|
|
RET Z ; DONE IF NO ERROR
|
|
LD A,ERR_IO ; SIGNAL IO ERROR
|
|
OR A ; SET FLAGS
|
|
RET ; AND DONE
|
|
;
|
|
; CHECK CURRENT DEVICE FOR ERROR STATUS AND ATTEMPT TO RECOVER
|
|
; VIA RESET IF DEVICE IS IN ERROR.
|
|
;
|
|
SCSI_CHKERR:
|
|
LD A,(IY+SCSI_STAT) ; GET STATUS
|
|
OR A ; SET FLAGS
|
|
CALL NZ,SCSI_RESET ; IF ERROR STATUS, RESET BUS
|
|
RET
|
|
;
|
|
; ISSUE SCSI INQUIRY COMMAND
|
|
; ON INPUT, HL POINTS TO OUTPUT DATA BUFFER
|
|
;
|
|
SCSI_INQUIRY:
|
|
; SETUP BUFFER POINTERS
|
|
LD (SCSI_BUF_OUT),HL ; INPUT BUFFER
|
|
LD (SCSI_BUF_IN),HL ; OUTPUT BUFFER
|
|
; SETUP INQUIRY CDB
|
|
LD HL,SCSI_S_INQ ; SET HL TO INQ CBD
|
|
LD (SCSI_CUR_CDB),HL ; SAVE IN IOT
|
|
; SETUP LUN
|
|
LD A,(IY+SCSI_LUN) ; PUT LUN IN ACCUM
|
|
RRCA ; MOVE TO TOP 3 BITS
|
|
RRCA ; ...
|
|
RRCA ; ...
|
|
LD (SCSI_INQ_LUN),A ; PUT IN INQ CDB
|
|
; DO THE SCSI TRANSACTION
|
|
JP SCSI_GO ; DO THE SCSI TRANSACTION
|
|
;
|
|
; ISSUE SCSI CAPACITY COMMAND AND CAPTURE
|
|
; RESULTS AS DEVICE CAPACITY
|
|
;
|
|
SCSI_CAPACITY:
|
|
; SETUP BUFFER POINTERS
|
|
LD HL,SCSI_CAP_BUF
|
|
LD (SCSI_BUF_OUT),HL ; INPUT BUFFER
|
|
LD (SCSI_BUF_IN),HL ; OUTPUT BUFFER
|
|
; SETUP READ CAPACITY CDB
|
|
LD HL,SCSI_S_CAP ; SET HL TO CAP CBD
|
|
LD (SCSI_CUR_CDB),HL ; SAVE IN IOT
|
|
; SETUP LUN
|
|
LD A,(IY+SCSI_LUN) ; PUT LUN IN ACCUM
|
|
RRCA ; MOVE TO TOP 3 BITS
|
|
RRCA ; ...
|
|
RRCA ; ...
|
|
LD (SCSI_CAP_LUN),A ; PUT IN INQ CDB
|
|
; DO THE SCSI TRANSACTION
|
|
CALL SCSI_GO ; DO THE SCSI TRANSACTION
|
|
RET NZ ; ABORT ON ERROR
|
|
;
|
|
; RETURNED LBA IS BIG ENDIAN. CONVERT TO A STANDARD 32-BIT
|
|
; INTEGER IN DE:HL
|
|
LD HL,SCSI_CAP_BUF ; HL POINTS TO START OF BUF
|
|
LD D,(HL) ; MSB
|
|
INC HL ; NEXT BYTE
|
|
LD E,(HL)
|
|
PUSH DE ; SAVE HIGH WORD
|
|
INC HL
|
|
LD D,(HL)
|
|
INC HL
|
|
LD E,(HL) ; LSB
|
|
POP HL ; RECOVER HIGH WORD
|
|
EX DE,HL ; AND SWAP
|
|
;
|
|
; RETURNED CAPACITY IS THE *LAST* LBA. WE WANT THE NUMBER OF
|
|
; BLOCKS AVAILABLE, SO WE NEED TO INCREMENT THE RETURNED VALUE.
|
|
CALL INC32
|
|
;
|
|
; COPY CAPACITY TO DEVICE CONFIG DATA FIELD
|
|
PUSH HL ; SAVE HL
|
|
LD A,SCSI_MEDCAP ; OFFSET OF MEDIA CAPACITY FIELD
|
|
CALL LDHLIYA ; HL POINTS TO MEDIA CAPACITY FIELD
|
|
PUSH HL ; MOVE HL
|
|
POP BC ; ... TO BC
|
|
POP HL ; RECOVER HL
|
|
CALL ST32 ; SAVE CAP TO CFG BLOCK
|
|
;
|
|
XOR A
|
|
RET ; DONE
|
|
;
|
|
;=============================================================================
|
|
; COMMAND PROCESSING
|
|
;=============================================================================
|
|
;
|
|
; WRAPPER FOR HBIOS INVOCATION
|
|
;
|
|
SCSI_GO:
|
|
PUSH IX ; PRESERVE IX
|
|
LD IX,SCSI_S_IOT ; POINT TO IO TABLE
|
|
LD A,(IY+SCSI_TID) ; GET TARGET ID
|
|
LD (IX),A ; PUT IN IOT
|
|
CALL SCSI_GO1 ; RUN THE TRANSACTION
|
|
POP IX ; RESTORE IX
|
|
AND %00111110 ; IGNORE RESERVED BITS OF STATUS
|
|
JP NZ,SCSI_IOERR ; HANDLE ERROR
|
|
RET ; DONE
|
|
;
|
|
;-------------------------------------------------------------------------------
|
|
; DO SCSI TRANSACTION
|
|
;-------------------------------------------------------------------------------
|
|
;
|
|
SCSI_GO1:
|
|
LD A,$FF ; PRESET ERROR STATUS
|
|
LD L,(IX+4) ; POINT TO STATUS ADDRESS
|
|
LD H,(IX+5) ; POINT TO STATUS ADDRESS
|
|
LD (HL),A ; SET ERROR
|
|
;
|
|
XOR A ;
|
|
OUT (SCSI_SR_MR),A ; RESET CONTROL REG
|
|
OUT (SCSI_SR_TCR),A ; CLEAR COMMAND REG.
|
|
OUT (SCSI_SR_ICR),A ;
|
|
LD A,(IX) ; GET TID
|
|
BIT 7,A ; TURN ON MY ID
|
|
OUT (SCSI_SR_ODR),A ; SET TARGET ID
|
|
LD A,$01 ; DRIVE BUS
|
|
OUT (SCSI_SR_ICR),A ;
|
|
LD A,$05 ; SET SEL AND DRIVE BUS
|
|
OUT (SCSI_SR_ICR),A ;
|
|
;
|
|
; WAIT FOR SCSI BUSY
|
|
LD BC,0 ; INIT TIMEOUT
|
|
S_SWT:
|
|
IN A,(SCSI_SR_CSBS) ; GET BUS STATUS
|
|
AND SCSI_SM_BSY ; MASK TO BUSY BIT
|
|
JR NZ,S_BSYA ; JMP IF BUSY ACTIVE
|
|
NOP ; KILL A LITTLE TIME
|
|
NOP
|
|
NOP
|
|
NOP
|
|
DEC BC ; DEC TIMEOUT
|
|
LD A,B ; TEST TIMEOUT=0
|
|
OR C
|
|
JR NZ,S_SWT ; JMP IF NO TIMEOUT
|
|
XOR A ; CLEAR A
|
|
OUT (SCSI_SR_ICR),A ; CLEAR SEL AND DATA
|
|
JR S_EXIT ; ERROR EXIT
|
|
;
|
|
;BUSY IS ACTIVE
|
|
S_BSYA:
|
|
XOR A ; CLEAR A
|
|
OUT (SCSI_SR_ICR),A ; CLEAR SEL AND DATA
|
|
;
|
|
;-------------------------------------------------------------------------------
|
|
;
|
|
; TARGET IS SELECTED SO TEST BSY AND REQ
|
|
; THEN DECODE REQUESTED PHASE
|
|
;
|
|
;-------------------------------------------------------------------------------
|
|
PHASE:
|
|
XOR A
|
|
OUT (SCSI_SR_ICR),A ; RESET INITIATOR
|
|
;
|
|
S_WTREQ:
|
|
IN A,(SCSI_SR_CSBS) ; GET BUS STATUS
|
|
LD B,A ; SAVE COPY
|
|
AND SCSI_SM_BSY ; MASK TO BUSY BIT
|
|
JR NZ,S_WTRQ1 ; STILL BUSY SO CONT.
|
|
;
|
|
;-------------------------------------------------------------------------------
|
|
; BUSY LOST SO EXIT
|
|
;-------------------------------------------------------------------------------
|
|
S_EXIT:
|
|
LD L,(IX+4) ; GET STATUS POINTER
|
|
LD H,(IX+5) ; GET STATUS POINTER
|
|
LD A,(HL)
|
|
RET ; BUSY LOST? WERE DONE
|
|
;
|
|
S_WTRQ1:
|
|
LD A,B ; RECOVER STATUS
|
|
AND SCSI_SM_REQ ; REQUEST ACTIVE?
|
|
JR Z,S_WTREQ ; LOOP TILL REQUEST
|
|
|
|
;-------------------------------------------------------------------------------
|
|
; REQUEST IS ACTIVE SO SET 5380 TO REQUESTED PHASE
|
|
;-------------------------------------------------------------------------------
|
|
LD A,B ; RECOVER BUS STATUS
|
|
RR A ; SHIFT STATUS TO PHASE BITS
|
|
RR A
|
|
AND $07 ; MASK TO PHASE BITS
|
|
OUT (SCSI_SR_TCR),A ; SET PHASE
|
|
;
|
|
; JUMP TO PHASE HANDLER
|
|
;
|
|
LD A,B ; RECOVER BUS STATUS
|
|
RR A
|
|
AND $0E ; MASK TO PHASE BITS
|
|
LD E,A ;
|
|
LD D,0
|
|
LD HL,PHTABL ; POINT TO TABLE
|
|
ADD HL,DE ; OFFSET INTO TABLE
|
|
LD E,(HL) ; GET EXECUTION ADDRESS
|
|
INC HL
|
|
LD D,(HL)
|
|
PUSH DE
|
|
RET ; EXECUTE PHASE
|
|
;
|
|
;-------------------------------------------------------------------------------
|
|
; PHASE TABLE
|
|
;-------------------------------------------------------------------------------
|
|
;
|
|
PHTABL:
|
|
.WORD PHASE0 ; DATA OUT
|
|
.WORD PHASE1 ; DATA IN
|
|
.WORD PHASE2 ; CMD OUT
|
|
.WORD PHASE3 ; STATUS IN
|
|
.WORD S_EXIT ; UNUSED
|
|
.WORD S_EXIT ; UNUSED
|
|
.WORD PHASE6 ; MESSAGE OUT
|
|
.WORD PHASE7 ; MESSAGE IN
|
|
;
|
|
;-------------------------------------------------------------------------------
|
|
;PHASE HANDLERS
|
|
;-------------------------------------------------------------------------------
|
|
;
|
|
; DATA OUT
|
|
PHASE0:
|
|
LD L,(IX+6) ; GET POINTER
|
|
LD H,(IX+7)
|
|
JP S_WRIT ; WRITE BYTES
|
|
;
|
|
; DATA IN
|
|
PHASE1:
|
|
LD L,(IX+8) ; GET POINTER
|
|
LD H,(IX+9)
|
|
JP S_READ ; READ BYTES
|
|
;
|
|
; CMD OUT
|
|
PHASE2:
|
|
LD L,(IX+2)
|
|
LD H,(IX+3)
|
|
JP S_WRIT
|
|
;
|
|
; STATUS IN
|
|
PHASE3:
|
|
LD L,(IX+4)
|
|
LD H,(IX+5)
|
|
JP S_READ
|
|
;
|
|
; MSG OUT
|
|
PHASE6:
|
|
LD L,(IX+10)
|
|
LD H,(IX+11)
|
|
JP S_WRIT
|
|
;
|
|
; MSG IN
|
|
PHASE7:
|
|
LD L,(IX+12)
|
|
LD H,(IX+13)
|
|
JP S_READ
|
|
;
|
|
;-------------------------------------------------------------------------------
|
|
; SCSI WRITE ROUTINE (SEND BYTES TO TARGET)
|
|
; BUS PHASE ALREADY SET. RETURN ON PHASE MISMATCH
|
|
;-------------------------------------------------------------------------------
|
|
S_WRIT:
|
|
LD A,1 ; DRIVE SCSI DATA BUS
|
|
OUT (SCSI_SR_ICR),A
|
|
;
|
|
; WAIT FOR REQ WHILE CHECKING BUSY
|
|
;
|
|
S_WWREQ:
|
|
IN A,(SCSI_SR_CSBS) ; GET CURRENT BUS STAT
|
|
LD B,A ; SAVE IT
|
|
AND SCSI_SM_REQ ; REQUEST ACTIVE?
|
|
JR NZ,S_WNXT ;
|
|
;
|
|
LD A,B ; RECOVER CURRENT BUS STAT
|
|
AND SCSI_SM_BSY ; STILL BUSY?
|
|
JP NZ,S_WWREQ ; LOOP IF STILL BUSY
|
|
JP PHASE ;
|
|
;
|
|
; REQUEST ACTIVE SO CHECK PHASE
|
|
;
|
|
S_WNXT:
|
|
IN A,(SCSI_SR_BSR) ; GET STATUS
|
|
AND SCSI_SM_PHM ; MASK TO PHASE MATCH
|
|
JP Z,PHASE ; JMP IF PHASE MISMATCH
|
|
;
|
|
; REQUEST ACTIVE AND PHASE MATCH SO SEND DATA
|
|
;
|
|
LD A,(HL) ; GET BYTE
|
|
OUT (SCSI_SR_ODR),A ; SEND DATA
|
|
LD A,$11 ; ACK + DRIVE BUS
|
|
OUT (SCSI_SR_ICR),A ; SET ACK,DRIVE SCSI BUS
|
|
INC HL ; ADVANCE BUF POINTER
|
|
;
|
|
; WAIT FOR REQUEST TO DROP
|
|
;
|
|
S_WNREQ:
|
|
IN A,(SCSI_SR_CSBS) ; GET CURRENT STATUS
|
|
AND SCSI_SM_REQ
|
|
JR NZ,S_WNREQ ; LOOP TILL REQ DROPS
|
|
;
|
|
LD A,$1 ; DROP ACK,ASSERT DATA
|
|
OUT (SCSI_SR_ICR),A ; DROP ACK
|
|
JP S_WWREQ ; LOOP FOR NEXT BYTE/PHASE
|
|
;-------------------------------------------------------------------------------
|
|
; SCSI READ ROUTINE (GET BYTES FROM TARGET)
|
|
; BUS PHASE ALREADY SET. RETURN ON PHASE MISMATCH
|
|
;-------------------------------------------------------------------------------
|
|
;
|
|
S_READ:
|
|
;
|
|
; WAIT FOR REQ WHILE CHECKING BUSY
|
|
;
|
|
S_RWREQ:
|
|
IN A,(SCSI_SR_CSBS) ; GET CURRENT BUS STAT
|
|
LD B,A ; SAVE IT
|
|
AND SCSI_SM_REQ ; REQUEST ACTIVE?
|
|
JR NZ,S_RNXT ;
|
|
;
|
|
LD A,B ; RECOVER CURRENT BUS STAT
|
|
AND SCSI_SM_BSY ; STILL BUSY?
|
|
JP NZ,S_RWREQ ; LOOP IF STIL BUSY
|
|
JP PHASE ;
|
|
;
|
|
; REQUEST ACTIVE SO CHECK PHASE
|
|
;
|
|
S_RNXT:
|
|
IN A,(SCSI_SR_BSR) ; GET STATUS
|
|
AND SCSI_SM_PHM ; MASK TO PHASE MATCH
|
|
JP Z,PHASE ; JMP IF PHASE MISMATCH
|
|
;
|
|
; REQUEST ACTIVE AND PHASE MATCH SO GET DATA
|
|
;
|
|
IN A, (SCSI_SR_CSD) ; GET DATA
|
|
LD (HL),A ; SAVE DATA
|
|
LD A,$10
|
|
OUT (SCSI_SR_ICR),A ; SET ACK
|
|
INC HL ; ADVANCE BUF POINTER
|
|
;
|
|
;WAIT FOR REQUEST TO DROP
|
|
;
|
|
S_RNREQ:
|
|
IN A,(SCSI_SR_CSBS) ; GET CURRENT STATUS
|
|
AND SCSI_SM_REQ
|
|
JR NZ,S_RNREQ ; LOOP TILL REQ DROPS
|
|
XOR A
|
|
OUT (SCSI_SR_ICR),A ; DROP ACK
|
|
JP S_READ ; LOOP FOR NEXT BYTE/PHASE
|
|
;
|
|
;=============================================================================
|
|
; HARDWARE INTERFACE ROUTINES
|
|
;=============================================================================
|
|
;
|
|
;=============================================================================
|
|
; ERROR HANDLING AND DIAGNOSTICS
|
|
;=============================================================================
|
|
;
|
|
; ERROR HANDLERS
|
|
;
|
|
SCSI_NOMEDIA:
|
|
LD A,SCSI_STNOMEDIA
|
|
JR SCSI_ERR
|
|
;
|
|
SCSI_IOERR:
|
|
LD A,SCSI_STIOERR
|
|
JR SCSI_ERR
|
|
;
|
|
SCSI_TO:
|
|
LD A,SCSI_STTO
|
|
JR SCSI_ERR
|
|
;
|
|
SCSI_NOTRDY:
|
|
LD A,SCSI_STNOTRDY
|
|
JR SCSI_ERR
|
|
;
|
|
SCSI_ERR:
|
|
LD (IY+SCSI_STAT),A ; SAVE NEW STATUS
|
|
;
|
|
#IF (SCSITRACE >= 2)
|
|
CALL SCSI_PRTSTAT
|
|
#ENDIF
|
|
OR A ; SET FLAGS
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
SCSI_PRTERR:
|
|
RET Z ; DONE IF NO ERRORS
|
|
; FALL THRU TO SCSI_PRTSTAT
|
|
;
|
|
; PRINT FULL DEVICE STATUS LINE
|
|
;
|
|
SCSI_PRTSTAT:
|
|
PUSH AF
|
|
PUSH DE
|
|
PUSH HL
|
|
LD A,(IY+SCSI_STAT)
|
|
CALL SCSI_PRTPREFIX ; PRINT UNIT PREFIX
|
|
JR SCSI_PRTSTAT3
|
|
SCSI_PRTSTAT2:
|
|
CALL NEWLINE
|
|
PRTS("SCSI:$") ; NO UNIT NUM IN PREFIX FOR INVALID UNIT
|
|
SCSI_PRTSTAT3:
|
|
CALL SCSI_PRTSTATSTR
|
|
POP HL
|
|
POP DE
|
|
POP AF
|
|
RET
|
|
;
|
|
; PRINT STATUS STRING
|
|
;
|
|
SCSI_PRTSTATSTR:
|
|
PUSH AF
|
|
PUSH DE
|
|
LD A,(IY+SCSI_STAT)
|
|
OR A
|
|
LD DE,SCSI_STR_STOK
|
|
JR Z,SCSI_PRTSTATSTR1
|
|
INC A
|
|
LD DE,SCSI_STR_STNOMEDIA
|
|
JR Z,SCSI_PRTSTATSTR1
|
|
INC A
|
|
LD DE,SCSI_STR_STIOERR
|
|
JR Z,SCSI_PRTSTATSTR1
|
|
INC A
|
|
LD DE,SCSI_STR_STTO
|
|
JR Z,SCSI_PRTSTATSTR1
|
|
INC A
|
|
LD DE,SCSI_STR_STNOTRDY
|
|
JR Z,SCSI_PRTSTATSTR1
|
|
LD DE,SCSI_STR_STUNK
|
|
SCSI_PRTSTATSTR1:
|
|
CALL PC_SPACE ; FORMATTING
|
|
CALL WRITESTR
|
|
POP DE
|
|
POP AF
|
|
RET
|
|
;
|
|
; PRINT DIAGNONSTIC PREFIX
|
|
;
|
|
SCSI_PRTPREFIX:
|
|
PUSH AF
|
|
CALL NEWLINE
|
|
PRTS("SCSI$")
|
|
LD A,(IY+SCSI_DEV) ; GET CURRENT DEVICE NUM
|
|
CP $FE ; NOT YET ASSIGNED?
|
|
JR Z,SCSI_PRTPREFIX1 ; SKIP DEV NUM IF SO
|
|
CALL PRTDECB
|
|
SCSI_PRTPREFIX1:
|
|
CALL PC_COLON
|
|
POP AF
|
|
RET
|
|
;
|
|
;=============================================================================
|
|
; STRING DATA
|
|
;=============================================================================
|
|
;
|
|
SCSI_STR_STOK .TEXT "OK$"
|
|
SCSI_STR_STNOMEDIA .TEXT "NO MEDIA$"
|
|
SCSI_STR_STIOERR .TEXT "IO ERROR$"
|
|
SCSI_STR_STTO .TEXT "TIMEOUT$"
|
|
SCSI_STR_STNOTRDY .TEXT "NOT READY$"
|
|
SCSI_STR_STUNK .TEXT "UNKNOWN ERROR$"
|
|
;
|
|
;=============================================================================
|
|
; DATA STORAGE
|
|
;=============================================================================
|
|
;
|
|
SCSI_DEVNUM .DB 0 ; TEMP DEVICE NUM USED DURING INIT
|
|
SCSI_DSKBUF .DW 0 ; ACTIVE DISK BUFFER
|
|
;
|
|
;----------------------------------------------------------------
|
|
;SCSI COMMAND DESCRIPTOR FOR READ/WRITE
|
|
;
|
|
SCSI_S_CDB:
|
|
.DB SCSI_CMD_READ ; COMMAND
|
|
SCSI_CUR_LUN .DB 0 << 5 ; LUN/LBA HI
|
|
SCSI_CUR_LBN .DB 0 ; LBA MID
|
|
.DB 0 ; LBA LOW
|
|
.DB 1 ; COUNT
|
|
.DB 0 ; CONTROL
|
|
;
|
|
;----------------------------------------------------------------
|
|
;SCSI COMMAND DESCRIPTOR FOR INQUIRY
|
|
;
|
|
SCSI_S_INQ:
|
|
.DB SCSI_CMD_INQ ; COMMAND
|
|
SCSI_INQ_LUN .DB 0 << 5 ; LUN (TOP 3 BITS)
|
|
.DB 0 ; PAGE CODE (UNUSED)
|
|
.DB 0 ; RESERVED
|
|
.DB $FF ; ALLOCATION LENGTH
|
|
.DB 0 ; CONTROL
|
|
;
|
|
;----------------------------------------------------------------
|
|
;SCSI COMMAND DESCRIPTOR FOR READ CAPACITY
|
|
;
|
|
SCSI_S_CAP:
|
|
.DB SCSI_CMD_RDCAP ; COMMAND
|
|
SCSI_CAP_LUN .DB 0 << 5 ; LUN (TOP 3 BITS)
|
|
.FILL 4,0 ; LBA (UNUSED)
|
|
.FILL 3,0 ; RESERVED
|
|
.DB 0 ; CONTROL
|
|
;
|
|
;----------------------------------------------------------------
|
|
;SCSI I/O ADDRESS TABLE FOR READ/WRITE
|
|
;DONT MESS WITH THIS EITHER
|
|
SCSI_S_IOT:
|
|
SCSI_CUR_TID .DB 0 ; TARGET (FILLED DYNAMICALLY)
|
|
.DB 0 ; UNUSED
|
|
SCSI_CUR_CDB .DW SCSI_S_CDB ; CDB POINTER
|
|
.DW SCSI_S_STAT ; STATUS POINTER
|
|
SCSI_BUF_OUT .DW HB_WRKBUF ; DATA OUT POINTER
|
|
SCSI_BUF_IN .DW HB_WRKBUF ; DATA IN POINTER
|
|
.DW SCSI_S_MSG ; MSG OUT POINTER
|
|
.DW SCSI_S_MSG ; MSG IN POINTER
|
|
;
|
|
SCSI_S_STAT .DW 0 ; SCSI ENDING STATUS
|
|
SCSI_S_MSG .DW 0 ; SCSI MESSAGE
|
|
;
|
|
SCSI_CAP_BUF .FILL 8,0 ; SCSI CAPACITY DATA BUFFER
|
|
;
|
|
;--------------------------------------------------------------------------------------------------
|
|
; HBIOS MODULE TRAILER
|
|
;--------------------------------------------------------------------------------------------------
|
|
;
|
|
END_SCSI .EQU $
|
|
SIZ_SCSI .EQU END_SCSI - ORG_SCSI
|
|
;
|
|
MEMECHO "SCSI occupies "
|
|
MEMECHO SIZ_SCSI
|
|
MEMECHO " bytes.\n"
|
|
|