antoine-source/scsi2/SCSI.Drivers/SCSI Get Config

1 line
15 KiB
Plaintext

;*******************************************************
;
; SCSI Driver Get Configuration Parms code.
;
; Written by Matt Gulick. Started June 22,1990
;
; Copyright Apple Computer, Inc. 1990
;
;*******************************************************
;*******************************************************
;
; This file contains the Get Configuration Parms as
; defined in the ERS.
;
;*******************************************************
;*******************************************************
;
; Revision History:
;
;*******************************************************
; June 22, 1988 File started.
IMPORT chk_count
IMPORT bitmap
IMPORT length
IMPORT rqst
IMPORT gc_buff_ptr
IMPORT count
IMPORT temp
IMPORT error
IMPORT ddm_index
IMPORT pre_load_ddm
IMPORT pdata_block
IMPORT find_drvr_part
EJECT
;*******************************************************
;
; 'g_config_parms'
;
; This routine is used to get information about the
; volume or disk in question. If this call is issued
; to get disk info, then the DIB Pointer must point to
; the head DIB if this is a linked device. Volume
; calls should have the DIB Pointer set to the volume
; for which the information is being requested.
;
; The structure of the parameter list is defined in the
; SCSI Driver ERS. The parameters are going to depend
; greatly on the type of device that this driver is
; written for. That means that the info for the Scanner
; will not be the same in any form as that for a Hard
; Disk, or a Tape drive. These calls will be particular
; for the device type supported.
;
; Called via 'JSR'
;
; Inputs: [dib_ptr] = Target DIB (LONG)
; [buff_ptr] = Data Buffer Pointer (LONG)
; Acc = Unspecified
; Carry = Unspecified
; Y register = Unspecified
; X register = Unspecified
; P register = 0=M=X=e
; Direct Page = Ours
; Data Bank = Ours
;
; Returns via 'RTS'
;
; Outputs: Acc = 0
; Carry = 0
; or
; Acc = Error
; Carry = 1
;
; Y register = Unspecified
; X register = Unspecified
; P register = 0=M=X=e
; Direct Page = Ours
; Data Bank = Ours
;
; Errors: See Spec.
;
;*******************************************************
gcp
;
; Check the Request Count. Volume calls
; need at least 4 bytes. Disk calls need
; more and that will be verified there.
;
lda <rqst_cnt+2
bne @rqst_cnt_ok
lda <rqst_cnt
cmp #$0004
blt @bad_cnt
;
; Do a mini check of the parameter list
; to see if it is correct.
;
@rqst_cnt_ok lda [buff_ptr] ;Is the Request Count = 0?
beq @exit_none ;Yes. Get Zero
cmp #$0002 ;Is the count bigger than the min
blt @exit_parm ;Overhead Structure? No? Parm Error.
;
; Check to see if this Volume is Online.
;
ldy #dib.dvcflag
lda [dib_ptr],y
and #dvc_online
beq @not_online
;
; Validate that this DIB is from
; a Partition Map Entry.
;
ldy #dib.start_blk
lda [dib_ptr],y
ldy #dib.start_blk+2
ora [dib_ptr],y
beq @exit_parm
;
; Check Bitmap.
;
ldy #config_pl.bitmap
lda [buff_ptr],y
bmi @do_volume
brl do_disk
;
; Not from a partition.
;
@not_online lda #drvr_off_line
bra @exit_none
;
; Error exit point.
;
@bad_exit jsr set_our_dp
lda #drvr_io
bra @exit_none
;
; Error exit point.
;
@bad_cnt lda #drvr_bad_cnt
bra @exit_none
;
; Use this code to exit when no data is
; being returned.
;
@exit_parm lda #drvr_bad_parm
@exit_none stz <trans_cnt
stz <trans_cnt+2
cmp #$0001
rts
;
; Do the Volume Parms Here.
; Acc = Bitmap on entry.
;
@do_volume cmp #$8000 ;All other bits must be zero or
bne @exit_parm ;we have a parm error.
sta |bitmap
;
; Get block that contains this
; DIB's Partition Map Entry.
;
ldy #dib.part_blk
lda [dib_ptr],y
sta |rpm_blk_num
;
; Tell the code that we have already
; set the Block Number and that this
; is not a startup call.
;
dec |stat_cont ;This is from a Status or Control Call
dec |rebuild ;And not from a startup Call
;
; Issue the Read PM Block Call.
;
jsr |read_pm_blk
bcs @bad_exit ;There was an error.
jsr set_our_dp
;
; Is what we read a Partition Map?
;
lda |pm.Sig\
+internal_buff
cmp #Part_sig
bne @bad_exit ;Bad Data Read.
;
; GTet the Status Byte
;
ldy #config_pl.bitmap
lda |pm.PartStatus+2\
+internal_buff
xba
and #$00ff
ora |bitmap
sta [buff_ptr],y
;
; Clean Exit
;
lda #$0004
sta <trans_cnt
lda #no_error
sta <trans_cnt+2
clc
rts
;
; Get Config Disk Calls are handled
; here.
;
; Init Transfer Count to Null. Then
; check to be sure that this is a get
; Config ParmList and not a Set Config
; List.
;
do_disk stz length
stz length+2
;
; Get the Request Count.We will set this
; aside and subtract from that as data
; is transfered. This way we will not
; over run their buffers.
;
ldy <rqst_cnt
sty rqst
ldy <rqst_cnt+2
sty rqst+2
sta temp
and #$4000
bne @exit_parm
;
; Check Count. Must have a count that
; is at least big enough to cover the
; count and bitmap fields plus the first
; DDM_Info field. If not then there is
; an error.
;
ldy #config_pl.count
sec
lda [buff_ptr],y
sbc #config_pl.vol_info\
-config_pl.count
sta count
blt @exit_parm
;
; Put the first flag bit in Bit 15.
;%00xxx00000000000
asl temp ;%0xxx000000000000
asl temp ;%xxx0000000000000
;
; Preserve the Users Buffer Pointer.
;
lda <buff_ptr
sta gc_buff_ptr
lda <buff_ptr+2
sta gc_buff_ptr+2
;
; Pre_load the DDM if needed.
;
jsr pre_load_ddm
bcc @ddm_loaded
rts
;
; Use this code to exit when no data is
; being returned.
;
@exit_parm lda #drvr_bad_parm
sec
rts
;
; Check Set DDM Bit
;
@ddm_loaded asl temp
bcc @chk_vol
jsr get_ddm
bcs @disk_done
;
; Check Get Volume Info Bit
;
@chk_vol jsr |chk_count
bcs @disk_done
asl temp
bcc @chk_drvr
jsr get_vol
bcs @disk_done
;
; Check Get Driver Bit
;
@chk_drvr jsr |chk_count
bcs @disk_done
asl temp
bcc @disk_done
jsr get_drvr
;
; All done. Return the transfer
; length and any error codes that
; were encountered
;
@disk_done sta error
lda length
sta <trans_cnt
lda length+2
sta <trans_cnt+2
;
; Replace the Buffer Pointer.
;
lda gc_buff_ptr
sta <buff_ptr
lda gc_buff_ptr+2
sta <buff_ptr+2
lda error
cmp #$0001
rts
;
; Subroutines for this code.
;
; The first Routine is used to Read
; the DDM into the callers buffer.
;
get_ddm
;
; Tell the Main Driver where
; our command structure resides.
;
lda #@read_ddm
sta <scsi_mdrvr
lda #^@read_ddm
sta <scsi_mdrvr+2
;
; Set the user's buffer
;
ldy #config_pl.ddm_info
clc
lda [buff_ptr],y
sta <config_tcnt
adc #$0004
tax
ldy #config_pl.ddm_info+2
lda [buff_ptr],y
sta <config_tcnt+2
adc #$0000
sta <buff_ptr+2
sta <ddm_buff+2 ;Incase we need it for the Driver Code
stx <buff_ptr
stx <ddm_buff ;Incase we need it for the Driver Code
;
; And our length from the DIB's
; Block Size value
;
lda [config_tcnt]
cmp #block_size+4
beq @over_0
@over_0 lda #block_size
sta <rqst_cnt
lda #^block_size
sta <rqst_cnt+2
;
; Set internal command flag
;
dec |internal
;
; Set the Partition call flag
;
dec |f_partition
;
; Set the Call Type and Issue the
; READ BLOCK Command.
;
lda #scsit_stat
sta |call_type
;
; Issue the call.
;
jsr check_532_rw
php
;
; Replace the Buffer Pointer.
;
lda gc_buff_ptr
sta <buff_ptr
lda gc_buff_ptr+2
sta <buff_ptr+2
;
; Check for Call Errors
;
plp
bcs @bad_exit1
;
; Is what we read a Driver
; Descriptor Map?
;
lda [ddm_buff]
cmp #DDM_sig
bne @bad_exit1 ;Bad Data Read.
;
; Add in the Length
;
clc
lda #block_size
ldy #$0002
sta [config_tcnt],y
adc length
sta length
lda length+2
adc #^block_size
sta length+2
;
; Clean Exit.
;
lda #$0000
clc
rts
;
; Error exit point.
;
@bad_exit1 jsr set_our_dp
lda #drvr_io
sec
rts
;
; Data for the READ BLOCK Command
;
@read_ddm dc.b $08
dc.b null
dc.w null
dcb.b 10,null
;
; This Routine is used to get the
; Volume Info into the callers buffer.
;
get_vol
;
; Find the Partition Map Entry that matches
; the data blocks used in the DDM.
;
ldy ddm_index
lda [ddm_buff],y
sta |pdata_block
iny
iny
lda [ddm_buff],y
sta |pdata_block+2
;
; Set the user's buffer
;
ldy #config_pl.vol_info
clc
lda [buff_ptr],y
sta <config_tcnt
adc #$0004
tax
ldy #config_pl.vol_info+2
lda [buff_ptr],y
sta <config_tcnt+2
adc #$0000
sta <buff_ptr+2
sta <config_buff+2
tay
stx <buff_ptr
stx <config_buff
;
; And our length from the DIB's
; Block Size value
;
lda [config_tcnt]
cmp #block_size+4
beq @over_0
;
; Use this code to exit when no data is
; being sent.
;
@exit_parm1 lda #drvr_bad_parm
sec
rts
@over_0 lda #$0001 ;Start looking here.
jsr find_drvr_part
php
;
; Replace the Buffer Pointer.
;
lda gc_buff_ptr
sta <buff_ptr
lda gc_buff_ptr+2
sta <buff_ptr+2
;
; Check for Call Errors
;
plp
bcs @bad_exit1
;
; Is what we read a Driver
; Descriptor Map?
;
lda [config_buff]
cmp #Part_sig
bne @bad_exit1 ;Bad Data Read.
;
; Add in the Length
;
clc
lda #block_size
ldy #$0002
sta [config_tcnt],y
adc length
sta length
lda length+2
adc #^block_size
sta length+2
;
; Clean Exit.
;
lda #$0000
clc
@rts rts
;
; Error exit point.
;
@bad_exit1 jsr set_our_dp
lda #drvr_io
sec
rts
;
; Data for the READ BLOCK Command
;
@read_vol dc.b $08
dc.b null
@read_vol_num dc.w null
dcb.b 10,null
;
; This Routine is used to get the
; Driver Data into the callers buffer.
;
get_drvr
;
; At this point the DDM is in Memory
; and the Zero Page Pointer 'DDM_BUFF'
; points to it.
;
ldy ddm_index
lda [ddm_buff],y
and #%0001111100000000 ;Allow Byte 1, bits 0-4 to pass
ora #$0008 ;OR in the command number
sta @read_drvr
iny
iny
lda [ddm_buff],y
sta @block_num
iny
iny
lda [ddm_buff],y
xba
asl a ;Cheap Multiply by $200
stz <rqst_cnt
stz <rqst_cnt+2
sta <rqst_cnt+1
;
; Set the user's buffer
;
ldy #config_pl.driver_info
clc
lda [buff_ptr],y
sta <config_tcnt
adc #$0004
tax
ldy #config_pl.driver_info+2
lda [buff_ptr],y
sta <config_tcnt+2
adc #$0000
sta <buff_ptr+2
sta <config_buff+2
stx <buff_ptr
stx <config_buff
;
; And our length from the DIB's
; Block Size value
;
lda <rqst_cnt+2
bne @too_big
lda [config_tcnt]
cmp <rqst_cnt
bge @length_ok
@too_big sec
stz <rqst_cnt+2
lda [config_tcnt]
sbc #$0004
sta <rqst_cnt
;
; Tell the Main Driver where
; our command structure resides.
;
@length_ok lda #@read_drvr
sta <scsi_mdrvr
lda #^@read_drvr
sta <scsi_mdrvr+2
;
; Set internal command flag
;
dec |internal
;
; Set the Partition call flag
;
dec |f_partition
;
; Set the Call Type and Issue the
; READ BLOCK Command.
;
lda #scsit_stat
sta |call_type
;
; Issue the call.
;
jsr check_532_rw
php
;
; Replace the Buffer Pointer.
;
lda gc_buff_ptr
sta <buff_ptr
lda gc_buff_ptr+2
sta <buff_ptr+2
;
; Check for Call Errors
;
plp
bcs @bad_exit1
;
; Add in the Length
;
clc
lda <rqst_cnt
ldy #$0002
sta [config_tcnt],y
adc length
sta length
lda length+2
adc <rqst_cnt+2
sta length+2
;
; Clean Exit.
;
lda #$0000
rts
;
; Error exit point.
;
@bad_exit1 jsr set_our_dp
lda #drvr_io
sec
rts
;
; Data for the READ BLOCK Command
;
@temp dc.w null
;
; Command to Read the Driver Data
;
@read_drvr dc.b $08
dc.b null
@block_num dc.w null
dcb.b 10,null
EJECT