mirror of
https://github.com/antoinevignau/source.git
synced 2025-01-01 15:30:02 +00:00
d29484938c
What we wrote to make audio hearable on a SCSI-2 CD-ROM drive ;-)
1 line
46 KiB
Plaintext
1 line
46 KiB
Plaintext
|
|
;*******************************************************
|
|
;
|
|
; SCSI Driver 'Status' filter.
|
|
;
|
|
; Written by Matt Gulick. Started August 12,1988
|
|
;
|
|
; Copyright Apple Computer, Inc. 1988-93
|
|
; All Rights Reserved
|
|
;
|
|
;*******************************************************
|
|
|
|
;*******************************************************
|
|
;
|
|
; This file contains the 'Status' filter as defined
|
|
; in the ERS.
|
|
;
|
|
;*******************************************************
|
|
|
|
;*******************************************************
|
|
;
|
|
; Revision History:
|
|
;
|
|
;*******************************************************
|
|
;
|
|
; Aug 12, 1988 File started.
|
|
; April 17, 1989 Made changes to accomadate the
|
|
; Scanner Driver.
|
|
;
|
|
; *** System 6.0.1 ***
|
|
;
|
|
; 16-Feb-93 Jim Murphy added DStatus $4000
|
|
; to return SCSI ID (search for
|
|
; JCM).
|
|
;
|
|
;*******************************************************
|
|
|
|
STRING PASCAL
|
|
BLANKS OFF
|
|
PAGESIZE 70
|
|
PRINT NOGEN
|
|
PRINT NOMDIR
|
|
MACHINE M65816
|
|
|
|
IMPORT bitmap
|
|
IMPORT rpm_blk_num
|
|
IMPORT stat_cont
|
|
IMPORT rebuild
|
|
IMPORT read_pm_blk
|
|
|
|
IMPORT call_type
|
|
IMPORT main_drvr
|
|
IMPORT internal
|
|
IMPORT f_partition
|
|
IMPORT test_unit_rdy
|
|
IMPORT rqst_sense
|
|
IMPORT mode_sense
|
|
IMPORT read_capacity
|
|
IMPORT t_dvc_blocks
|
|
IMPORT set_512_mode
|
|
IMPORT open_flag
|
|
IMPORT set_our_dp
|
|
IMPORT disk_switch
|
|
IMPORT set_disk_sw
|
|
IMPORT rebld_dibs
|
|
IMPORT unit_state
|
|
IMPORT trash_it
|
|
IMPORT uses_dc
|
|
IMPORT dib_data_struct
|
|
IMPORT lst_rslt_ec ;Status
|
|
IMPORT lst_rslt_id ;Status
|
|
IMPORT lst_rslt_stat ;Status
|
|
IMPORT lst_rslt_skey ;Status
|
|
IMPORT lst_rslt_info ;Status
|
|
IMPORT lst_rslt_rqlen ;Status
|
|
IMPORT lst_rslt_scode ;Status
|
|
IMPORT sense_data
|
|
IMPORT auto_sense_data
|
|
IMPORT internal_buff
|
|
IMPORT display_cnt
|
|
IMPORT current_fmt
|
|
IMPORT opt1_blk_cnt
|
|
IMPORT opt1_blk_siz
|
|
IMPORT opt1_med_siz
|
|
IMPORT opt2_blk_cnt
|
|
IMPORT opt2_blk_siz
|
|
IMPORT opt2_med_siz
|
|
IMPORT opt3_blk_cnt
|
|
IMPORT opt3_blk_siz
|
|
IMPORT opt3_med_siz
|
|
IMPORT format_options
|
|
IMPORT check_532_rw
|
|
|
|
ENTRY dvc_status
|
|
ENTRY g_config_parms
|
|
ENTRY wait_status
|
|
ENTRY fmt_options
|
|
ENTRY read_p_map
|
|
ENTRY g_last_rslt
|
|
ENTRY get_target_priority
|
|
|
|
PRINT OFF
|
|
|
|
INCLUDE 'scsihd.equates'
|
|
INCLUDE 'M16.MEMORY'
|
|
INCLUDE 'M16.UTIL'
|
|
PRINT ON
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = direct_acc THEN
|
|
|
|
ENTRY gdp
|
|
ENTRY gvp
|
|
|
|
ENDIF
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
EJECT
|
|
|
|
;*******************************************************
|
|
;
|
|
; Main Entry point to the 'Status' filter. This
|
|
; "Filter" is called when a Status Command comes in.
|
|
; See the headers of the seperate sections for the
|
|
; details of the commands.
|
|
;
|
|
; Inputs: [dib_ptr] = Last DIB built (LONG)
|
|
; Acc = Unspecified
|
|
; Carry = Unspecified
|
|
; Y register = Unspecified
|
|
; X register = Unspecified
|
|
; P register = 0=M=X=e
|
|
; Direct Page = Ours
|
|
; Data Bank = Ours
|
|
;
|
|
; Outputs: Acc = DRVR_BUSY
|
|
; Carry = 1
|
|
; unless we have no more dibs then
|
|
; Acc = 0
|
|
; Carry = 0
|
|
;
|
|
; Y register = Unspecified
|
|
; X register = Unspecified
|
|
; P register = 0=M=X=e
|
|
; Direct Page = GS/OS Direct Page
|
|
; Data Bank = Ours
|
|
;
|
|
; Errors: See Spec.
|
|
;
|
|
;*******************************************************
|
|
|
|
EXPORT status
|
|
status PROC
|
|
;
|
|
; Check to see if this is a Get Last Result
|
|
; call. If so, then don't worry yet about
|
|
; getting the Unit State.
|
|
;
|
|
lda <cont_code
|
|
cmp #$0005
|
|
beq @status
|
|
|
|
*** Added - 16-Feb-93 JCM
|
|
|
|
cmp #$4000 ;how about GetSCSITargetPriority?
|
|
beq @status
|
|
|
|
*** End - 16-Feb-93 JCM
|
|
;
|
|
; Is the device Removable?
|
|
;
|
|
ldy #dib.dvcchar
|
|
|
|
lda [dib_ptr],y
|
|
and #removable
|
|
beq @online ;No.
|
|
;
|
|
; This device is removable. Now we
|
|
; need to check to see if the unit
|
|
; has gone offline, (then we need to
|
|
; report that to the OS) or if the
|
|
; unit has come back online (Rebuild
|
|
; the DIBs).
|
|
;
|
|
jsr unit_state
|
|
bcc @online
|
|
;
|
|
; Check to see if this is a Device Status.
|
|
; If so, then don't worry yet about returning
|
|
; the Error State.
|
|
;
|
|
tay
|
|
lda <cont_code
|
|
beq @status
|
|
cmp #$0004
|
|
blt @status
|
|
bpl @tya_out
|
|
cmp #$8040
|
|
blt @status
|
|
; bmi @status
|
|
@tya_out tya ;The Carry Bit is still set.
|
|
rts
|
|
;
|
|
; Check to see if this is a Device Specific
|
|
; Status call. If so, then don't worry
|
|
; about it being Offline
|
|
;
|
|
@online lda <cont_code
|
|
beq @status
|
|
bmi @status
|
|
;
|
|
; Is the device online?
|
|
;
|
|
ldy #dib.dvcflag
|
|
|
|
lda [dib_ptr],y
|
|
and #dvc_online
|
|
bne @status ;Yes.
|
|
;
|
|
; Device is currently offline.
|
|
;
|
|
lda #drvr_off_line
|
|
sec
|
|
@rts_out rts
|
|
;
|
|
; Zero out the Data Chaining Flag
|
|
;
|
|
@status stz |uses_dc
|
|
;
|
|
; Clear transfer count.
|
|
;
|
|
lda #null
|
|
ldy #dib.trx_len
|
|
sta [dib_ptr],y
|
|
ldy #dib.trx_len+2
|
|
sta [dib_ptr],y
|
|
;
|
|
; Entry to the Status Call Filter.
|
|
; This filter acts as a mini driver.
|
|
; It examines the Status Code sent
|
|
; and calls the appropriate routines.
|
|
; If the Command is $8000 or greater,
|
|
; then it will be routed to the device
|
|
; specific section.
|
|
;
|
|
lda <stat_code
|
|
bmi @do_dvc_spec ;Device Specific Code.
|
|
;
|
|
; Check the range of the command.
|
|
;
|
|
|
|
*** Added - 16-Feb-93 JCM - This implements a new Apple-defined subcode for returning
|
|
*** the SCSI target priority (aka SCSI ID).
|
|
|
|
cmp #$4000 ;is it GetSCSITargetPriority?
|
|
bne @checkStandards
|
|
|
|
brl get_target_priority
|
|
|
|
@checkStandards
|
|
|
|
*** End - 16-Feb-93 JCM
|
|
|
|
cmp #max_s_cmd+1
|
|
bge @error
|
|
;
|
|
; Convert to an index
|
|
;
|
|
asl a
|
|
tax
|
|
jsr (@ncmd_tbl,x)
|
|
rts
|
|
;
|
|
; Bad Command Error.
|
|
;
|
|
@error lda #drvr_bad_req
|
|
sec
|
|
rts
|
|
;
|
|
; Normal Command Table.
|
|
;
|
|
@ncmd_tbl dc.w dvc_status ;Coded
|
|
dc.w g_config_parms ;Coded
|
|
dc.w wait_status ;Coded
|
|
dc.w fmt_options ;Coded
|
|
dc.w read_p_map ;Coded
|
|
dc.w g_last_rslt ;Coded
|
|
;
|
|
; Device Specific Code handling
|
|
; starts here.
|
|
;
|
|
@do_dvc_spec
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = direct_acc THEN
|
|
|
|
cmp #$F000
|
|
blt @do_scsi_cmd
|
|
and #$00ff
|
|
cmp #max_config_cmd+1
|
|
bge @error
|
|
;
|
|
; Convert to an index
|
|
;
|
|
asl a
|
|
tax
|
|
jsr (@c_cmd_tbl,x)
|
|
rts
|
|
;
|
|
; Config Command Table.
|
|
;
|
|
@c_cmd_tbl dc.w gdp ;Coded (Get Disk Parms)
|
|
dc.w gvp ;Coded (Get Volume Parms)
|
|
|
|
@do_scsi_cmd
|
|
|
|
ENDIF
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
;
|
|
; Check version of data structure
|
|
;
|
|
stz @chk_zero ;Precondition the flag to no check
|
|
lda [buff_ptr]
|
|
beq @version_0
|
|
cmp #$0001
|
|
bne @error
|
|
;
|
|
; Version 1. Preserve the data pointer
|
|
; currently used in the DIB and replace
|
|
; it with a pointer to the USER supplied
|
|
; Data Chaining instructions.
|
|
;
|
|
clc
|
|
ldy #dib.trx_ptr
|
|
lda [dib_ptr],y
|
|
sta |dib_data_struct
|
|
|
|
lda <buff_ptr
|
|
adc #ds.DCcode ;Offset to first D.C. Data
|
|
sta [dib_ptr],y
|
|
|
|
ldy #dib.trx_ptr+2
|
|
lda [dib_ptr],y
|
|
sta |dib_data_struct+2
|
|
|
|
lda <buff_ptr+2
|
|
adc #^ds.DCcode
|
|
sta [dib_ptr],y
|
|
;
|
|
; Set flag to indicate that D.C. Commands
|
|
; were used and that we need to restore
|
|
; the pointer in the DIB to the normal
|
|
; data descriptor. Also set the flag to
|
|
; indicate that we need to check the first
|
|
; buffer pointer for Zero.
|
|
;
|
|
dec |uses_dc
|
|
dec @chk_zero
|
|
;
|
|
; Do the rest normally and check the above
|
|
; flag later.
|
|
;
|
|
@version_0 clc
|
|
lda <buff_ptr
|
|
adc #$0002
|
|
sta <scsi_mdrvr
|
|
|
|
lda <buff_ptr+2
|
|
adc #null
|
|
sta <scsi_mdrvr+2
|
|
;
|
|
; Check the buffer pointer for Null.
|
|
;
|
|
ldy #$000C
|
|
lda [scsi_mdrvr],y
|
|
sta <buff_ptr
|
|
ldy #$000C+2
|
|
lda [scsi_mdrvr],y
|
|
sta <buff_ptr+2
|
|
;
|
|
; Check First Buffer for $00000000
|
|
;
|
|
ora <buff_ptr
|
|
bne @DH_Branch
|
|
lda @chk_zero
|
|
bne @error
|
|
;
|
|
; Call Main Driver
|
|
;
|
|
@DH_Branch lda #scsit_stat
|
|
sta |call_type
|
|
jsr |main_drvr
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = apple_cd\
|
|
OR scsi_dtype = changer THEN
|
|
|
|
bcc @no_cd_error
|
|
lda auto_sense_data+\ ;Was it an $82, $84, or $85 Error?
|
|
rqst_sens.addnl_sens_code
|
|
and #$00ff
|
|
cmp #$0082 ;Checking for $82 (End of User Area)
|
|
beq @eua
|
|
cmp #$0084 ;Checking for $84 (Illegal Mode)
|
|
beq @im
|
|
cmp #$0085 ;Checking for $85 (Bad Audio Address)
|
|
beq @baa
|
|
cmp #$00B0 ;Checking for $B0 (No Media)
|
|
beq @no_media
|
|
;
|
|
; None of those. Return I/O Error.
|
|
;
|
|
lda #$0027
|
|
sec
|
|
bra @exit
|
|
;
|
|
; End of User Area.
|
|
; Carry is set by CMP being equal
|
|
;
|
|
@eua lda #$00F0
|
|
bra @exit
|
|
;
|
|
; Illegal Mode.
|
|
; Carry is set by CMP being equal
|
|
;
|
|
@im lda #$00F1
|
|
bra @exit
|
|
;
|
|
; Bad Audio Address.
|
|
; Carry is set by CMP being equal
|
|
;
|
|
@baa lda #$00F2
|
|
bra @exit
|
|
;
|
|
; Bad Audio Address.
|
|
; Carry is set by CMP being equal
|
|
;
|
|
@no_media lda #$002f
|
|
bra @exit
|
|
|
|
|
|
ELSE
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
bcs @exit
|
|
|
|
ENDIF
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = apple_cd\
|
|
OR scsi_dtype = changer THEN
|
|
|
|
@no_cd_error
|
|
|
|
ENDIF
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
;
|
|
; Save transfer count.
|
|
;
|
|
ldy #dib.trx_len
|
|
lda [dib_ptr],y
|
|
sta @call_trns_cnt
|
|
ldy #dib.trx_len+2
|
|
lda [dib_ptr],y
|
|
sta @call_trns_cnt+2
|
|
;
|
|
; Check to see if we need to handle
|
|
; a Disk Switched Event. If not,
|
|
; then exit.
|
|
;
|
|
lda |disk_switch
|
|
bpl @exit
|
|
;
|
|
; Don't Trash the Volumes.
|
|
;
|
|
jsr rebld_dibs ;Issues a DISK_SW for each rebuilt DIB.
|
|
;
|
|
; Restore Direct Page Values.
|
|
;
|
|
@exit pha
|
|
php
|
|
;
|
|
; Check the D.C. Flag
|
|
;
|
|
lda |uses_dc
|
|
beq @set_our_zp
|
|
|
|
ldy #dib.trx_ptr
|
|
lda |dib_data_struct
|
|
sta [dib_ptr],y
|
|
|
|
ldy #dib.trx_ptr+2
|
|
lda |dib_data_struct+2
|
|
sta [dib_ptr],y
|
|
|
|
stz |uses_dc ;Reset Flag
|
|
|
|
@set_our_zp jsr set_our_dp
|
|
;
|
|
; Set transfer count.
|
|
;
|
|
lda @call_trns_cnt
|
|
sta <trans_cnt
|
|
lda @call_trns_cnt+2
|
|
sta <trans_cnt+2
|
|
;
|
|
; Exit.
|
|
;
|
|
plp
|
|
pla
|
|
rts
|
|
;
|
|
; Data Area.
|
|
;
|
|
@call_trns_cnt dc.l null ;Transfer count before we stepped on it.
|
|
@chk_zero dc.w null ;Check first DCMove Flag.
|
|
|
|
ENDP
|
|
|
|
EJECT
|
|
|
|
;*******************************************************
|
|
;
|
|
;
|
|
;
|
|
; Called via 'JSR'
|
|
;
|
|
; Inputs: [dib_ptr] = Target DIB l (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.
|
|
;
|
|
;*******************************************************
|
|
|
|
EXPORT dvc_status
|
|
dvc_status PROC
|
|
;
|
|
; Get Device Status Call
|
|
;
|
|
lda <rqst_cnt+2
|
|
bne @do_max
|
|
lda <rqst_cnt
|
|
cmp #$0007
|
|
blt @no_odds
|
|
@do_max lda #$0006
|
|
@no_odds lsr a ;0 --> Bit 15, Bit 0 --> Carry
|
|
bcs @bad_rqst_cnt ;No odd byte transfers
|
|
asl a ;Carry <-- Bit 15, Bit 0 <-- 0
|
|
sta <trans_cnt
|
|
stz <trans_cnt+2
|
|
bne @at_least_2
|
|
jmp @clc
|
|
;
|
|
; Bad Request Count.
|
|
;
|
|
@bad_rqst_cnt lda #drvr_bad_cnt
|
|
rts
|
|
;
|
|
; Init Status to $0000
|
|
;
|
|
@at_least_2 stz @dvc_stat
|
|
;
|
|
; Is the Device Linked?
|
|
;
|
|
ldy #dib.dvcchar
|
|
|
|
lda [dib_ptr],y
|
|
and #linked_dvc
|
|
beq @no_link ;No.
|
|
|
|
lda #bit_14 ;Yes. Set the bit
|
|
tsb @dvc_stat
|
|
;
|
|
; Is the device busy with a pending call?
|
|
;
|
|
@no_link ldy #dib.dvcflag
|
|
|
|
lda [dib_ptr],y
|
|
and #int_busy
|
|
beq @not_busy ;No.
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF character_dvc = true THEN
|
|
|
|
;
|
|
; If the device is a character device,
|
|
; and it's busy, then also set the Buffer
|
|
; Not Empty Flag.
|
|
;
|
|
lda #bit_13\
|
|
++bit_5 ;Yes. Set the bits
|
|
tsb @dvc_stat
|
|
|
|
ENDIF
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF block_dvc = true THEN
|
|
|
|
lda #bit_13 ;Yes. Set the bit
|
|
tsb @dvc_stat
|
|
|
|
ENDIF
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
;
|
|
; Is the Device Online?
|
|
;
|
|
@not_busy ldy #dib.dvcflag
|
|
|
|
lda [dib_ptr],y
|
|
and #dvc_online
|
|
beq @not_online2 ;No. Skip Switch flag.
|
|
|
|
lda [dib_ptr],y ;Also Check Hard Offline
|
|
and #dvc_hardofl ;Is it hard offline?
|
|
bne @not_online ;Yes. Do switch flag
|
|
|
|
lda #bit_4 ;Online, Set the bit
|
|
tsb @dvc_stat
|
|
|
|
lda [dib_ptr],y ;Also Check switch flag
|
|
and #dvc_switch ;Is it Switched?
|
|
pha
|
|
|
|
lda [dib_ptr],y ;Clear Switch Flag.
|
|
and #dvc_switch--\
|
|
$ffff
|
|
sta [dib_ptr],y
|
|
|
|
pla
|
|
bne @not_online1 ;Yes. Do switch flag
|
|
|
|
bra @online ;Skip the following mess.
|
|
|
|
@not_online
|
|
;
|
|
; If the device's Online Flag is set
|
|
; and it's Hard Offline Flag is also
|
|
; set, then we will treat this as a
|
|
; disk switch.
|
|
;
|
|
lda [dib_ptr],y
|
|
and #dvc_online++\
|
|
dvc_switch--\
|
|
$ffff
|
|
sta [dib_ptr],y
|
|
|
|
@not_online1 lda #bit_0
|
|
tsb @dvc_stat
|
|
|
|
@not_online2
|
|
|
|
@online
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF block_dvc = true THEN
|
|
|
|
;
|
|
; If the device is a block device, is
|
|
; the Device Write Protected?
|
|
;
|
|
ldy #dib.dvcchar
|
|
|
|
lda [dib_ptr],y
|
|
and #write_allow
|
|
bne @writeable ;No.
|
|
|
|
lda #bit_2 ;Yes. Set the bit
|
|
tsb @dvc_stat
|
|
|
|
ENDIF
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
@writeable
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF block_dvc = true THEN
|
|
|
|
;
|
|
; If the device is a block device, has
|
|
; the Device been switched?
|
|
;
|
|
jsr rqst_sense
|
|
bcc @no_error
|
|
jmp @switch ;Yes!
|
|
;
|
|
; The following lines of code commented
|
|
; by a '****' were added because of an
|
|
; SCSI Device that returned no error when
|
|
; there was no media on line. This was
|
|
; not the correct thing for the device to
|
|
; do. Shame on him. What we needed to do
|
|
; to correct this was to get the offline
|
|
; flag, then check to see if the device
|
|
; returned an error. If an error is
|
|
; returned, then we process it normally.
|
|
; If no error was returned and the device
|
|
; is still ofline, then we treat it as a
|
|
; device not ready error. The offline will
|
|
; be cleared when the device returns an 06
|
|
; in the sense key.
|
|
;
|
|
@no_error ldy #dib.dvcflag
|
|
lda [dib_ptr],y ;****
|
|
and #dvc_hardofl ;****
|
|
tax ;****
|
|
;****
|
|
lda |sense_data+\
|
|
rqst_sens.sense_key
|
|
bne @chk_sense_key ;****
|
|
txa ;****
|
|
beq @too_far
|
|
jmp @opened ;****
|
|
@too_far jmp @its_back ;****
|
|
|
|
@chk_sense_key and #$00ff
|
|
cmp #$0002
|
|
bne @chk_for_6
|
|
jmp @chk_switch
|
|
|
|
|
|
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
|
|
IF scsi_dtype<>apple_cd\
|
|
AND scsi_dtype<>changer THEN
|
|
|
|
@chk_for_6 cmp #$0006
|
|
beq @inserted
|
|
|
|
ELSE
|
|
|
|
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
|
|
@chk_for_6 cmp #$0006
|
|
bne @not_a_6
|
|
|
|
lda sense_data+\ ;Was it a RESET?
|
|
rqst_sens.addnl_sens_code
|
|
and #$00ff
|
|
cmp #$00b0 ;Checking for $B0 (NO MEDIA)
|
|
beq @fixit
|
|
and #$00fe ;Checking for $28 (INSERTION)
|
|
cmp #$0028 ;or $29 (RESET)
|
|
beq @inserted ;Yes it was.
|
|
@fixit jmp @chk_switch
|
|
;
|
|
; If the device is a CD_ROM device
|
|
; then check to see if the SENSE KEY
|
|
; = 5. If so, then treat it as no
|
|
; error.
|
|
;
|
|
@not_a_6 cmp #$0005
|
|
bne @its_bs
|
|
jmp @its_back
|
|
@its_bs
|
|
ENDIF
|
|
|
|
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
|
|
stz <trans_cnt
|
|
ora #$ff00
|
|
sec
|
|
rts
|
|
;
|
|
; Rebuild the DIBs.
|
|
;
|
|
@inserted
|
|
;
|
|
; Is this device linked? If it is,
|
|
; then we need to mark them all as
|
|
; being online.
|
|
;
|
|
; Start at the headptr if non-zero.
|
|
;
|
|
ldy #dib.headptr
|
|
lda [dib_ptr],y
|
|
tax
|
|
ldy #dib.headptr+2
|
|
lda [dib_ptr],y
|
|
bne @set_pointer0 ;Should not be bank 0
|
|
;
|
|
; Current pointer is the first.
|
|
;
|
|
lda <dib_ptr+2
|
|
ldx <dib_ptr
|
|
;
|
|
; Set temp Zero Page Pointer
|
|
;
|
|
@set_pointer0 stx <scsi_zp0
|
|
sta <scsi_zp0+2
|
|
;
|
|
; Set the Flags.
|
|
;
|
|
ldy #dib.dvcflag
|
|
lda [scsi_zp0],y
|
|
and #dvc_hardofl--\
|
|
$ffff
|
|
ora #dvc_switch++\
|
|
dvc_online++\
|
|
dvc_hard_sw
|
|
sta [scsi_zp0],y
|
|
;
|
|
; If there is a forward device
|
|
; pointer than get it.
|
|
;
|
|
ldy #dib.fdvcptr
|
|
lda [scsi_zp0],y
|
|
tax
|
|
ldy #dib.fdvcptr+2
|
|
lda [scsi_zp0],y
|
|
bne @set_pointer0
|
|
|
|
@turdy jsr test_unit_rdy ;Is it ready yet?
|
|
bcc @they_r_built ;Yes.
|
|
lda auto_sense_data+\ ;Is there media in the drive?
|
|
rqst_sens.addnl_sens_code
|
|
and #$00ff
|
|
cmp #$00b0 ;Checking for $B0 (NO MEDIA)
|
|
bne @turdy ;No.
|
|
; bcs @turdy ;*************************
|
|
|
|
@they_r_built
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype <> mcd_40 THEN
|
|
|
|
jsr set_512_mode
|
|
|
|
ENDIF ;scsi_dtype <> mcd_40
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
;
|
|
; Issue the READ CAPACITY Command.
|
|
;
|
|
jsr read_capacity
|
|
bcs @no_capacity ;Was there an error?
|
|
;
|
|
; Get the Block Count (Stored
|
|
; High >> Low. Must be switched
|
|
; to Low >> High). This is the last
|
|
; readable block number. Add 1 to
|
|
; it for comparison reasons.
|
|
;
|
|
lda |block.count\
|
|
+internal_buff\
|
|
+2
|
|
xba
|
|
adc #$0001 ;Carry is Clear as a result
|
|
sta |t_dvc_blocks ;of the 'READ CAPACITY' Call
|
|
lda |block.count\
|
|
+internal_buff
|
|
xba
|
|
adc #null
|
|
sta |t_dvc_blocks+2
|
|
|
|
@no_capacity jsr rebld_dibs ;Rebuild DIBs and Issue a DISK_SW
|
|
php ;for each
|
|
;
|
|
; Restore the origonal Direct Page
|
|
; values.
|
|
;
|
|
jsr set_our_dp
|
|
plp
|
|
bcc @set_switch
|
|
jsr test_unit_rdy
|
|
bcc @set_switch
|
|
;
|
|
; For some reason, we cannot talk to the
|
|
; device. It must be offline.
|
|
;
|
|
@chk_switch ldy #dib.dvcflag
|
|
lda [dib_ptr],y
|
|
tax
|
|
|
|
and #dvc_hardofl
|
|
bne @opened
|
|
|
|
txa
|
|
and #dvc_online--\
|
|
$ffff
|
|
ora #dvc_hardofl
|
|
sta [dib_ptr],y
|
|
|
|
lda #bit_4 ;Clear the Online bit
|
|
trb @dvc_stat
|
|
|
|
lda #bit_0 ;Set the Switch bit
|
|
tsb @dvc_stat
|
|
|
|
bra @opened
|
|
;
|
|
; Set Online Bit. If dvc_hard_sw is
|
|
; set, then clear it and return the
|
|
; disk switch bit.
|
|
;
|
|
@its_back lda [dib_ptr],y
|
|
pha
|
|
and #dvc_hard_sw
|
|
tax
|
|
pla
|
|
and #dvc_hard_sw--\
|
|
$ffff
|
|
sta [dib_ptr],y
|
|
txa
|
|
bne @set_switch
|
|
bra @opened ;Back in business
|
|
|
|
@switch ;
|
|
; Is this device linked? If it is,
|
|
; then we need to mark them all as
|
|
; being offline.
|
|
;
|
|
; Start at the headptr if non-zero.
|
|
;
|
|
ldy #dib.headptr
|
|
lda [dib_ptr],y
|
|
tax
|
|
ldy #dib.headptr+2
|
|
lda [dib_ptr],y
|
|
bne @set_pointer2 ;Should not be bank 0
|
|
;
|
|
; Current pointer is the first.
|
|
;
|
|
lda <dib_ptr+2
|
|
ldx <dib_ptr
|
|
;
|
|
; Set temp Zero Page Pointer
|
|
;
|
|
@set_pointer2 stx <scsi_zp0
|
|
sta <scsi_zp0+2
|
|
;
|
|
; Set the Flags.
|
|
;
|
|
ldy #dib.dvcflag
|
|
lda [scsi_zp0],y
|
|
ora #dvc_switch++\
|
|
dvc_online++\
|
|
dvc_hard_sw
|
|
and #dvc_online--\
|
|
$ffff
|
|
sta [scsi_zp0],y
|
|
;
|
|
; If there is a forward device
|
|
; pointer than get it.
|
|
;
|
|
ldy #dib.fdvcptr
|
|
lda [scsi_zp0],y
|
|
tax
|
|
ldy #dib.fdvcptr+2
|
|
lda [scsi_zp0],y
|
|
bne @set_pointer2
|
|
|
|
;
|
|
; Set the Switched Bit in Status
|
|
;
|
|
@set_switch lda #bit_0 ;Yes. Set the bit
|
|
tsb @dvc_stat
|
|
;
|
|
; No forward pointer. Continue on.
|
|
;
|
|
ENDIF
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
@opened
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF character_dvc = true THEN
|
|
;
|
|
; If the device is a character device,
|
|
; has the Device been opened?
|
|
;
|
|
lda |open_flag
|
|
beq @not_open ;No.
|
|
|
|
lda #bit_0 ;Yes. Set the bit
|
|
tsb @dvc_stat
|
|
|
|
@not_open
|
|
|
|
ENDIF
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
;
|
|
; If it is switched, then call disk switch.
|
|
;
|
|
lda @dvc_stat
|
|
and #bit_0+bit_4 ;If Online Bit is set then
|
|
cmp #bit_0 ;don't call disk switch
|
|
bne @no_call
|
|
jsr set_disk_sw
|
|
;
|
|
; Return the combined flags.
|
|
;
|
|
@no_call lda <rqst_cnt+2
|
|
bne @its_big
|
|
lda <rqst_cnt
|
|
beq @clc
|
|
cmp #$0007
|
|
blt @no_odds_1
|
|
@its_big lda #$0006
|
|
@no_odds_1 and #$fffe ;No odd byte transfers
|
|
sta <trans_cnt
|
|
stz <trans_cnt+2
|
|
|
|
tax
|
|
lda @dvc_stat
|
|
sta [buff_ptr]
|
|
;
|
|
; Return the Block Count.
|
|
;
|
|
dex
|
|
dex
|
|
beq @clc
|
|
|
|
ldy #dib.blkcnt
|
|
lda [dib_ptr],y
|
|
ldy #$0002
|
|
sta [buff_ptr],y
|
|
|
|
dex
|
|
dex
|
|
beq @clc
|
|
|
|
ldy #dib.blkcnt+2
|
|
lda [dib_ptr],y
|
|
ldy #$0004
|
|
sta [buff_ptr],y
|
|
;
|
|
; Exit real nice like.
|
|
;
|
|
@clc clc
|
|
rts
|
|
;
|
|
; Data for this call.
|
|
;
|
|
@dvc_stat dc.w null
|
|
|
|
ENDP
|
|
|
|
EJECT
|
|
|
|
;*******************************************************
|
|
;
|
|
; 'g_config_parms'
|
|
;
|
|
; Called via 'JSR'
|
|
;
|
|
; Inputs: [dib_ptr] = Target DIB l (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.
|
|
;
|
|
;*******************************************************
|
|
|
|
EXPORT g_config_parms
|
|
g_config_parms PROC
|
|
;
|
|
; Get Config Parms Call
|
|
;
|
|
lda #null
|
|
sta <trans_cnt
|
|
sta <trans_cnt+2
|
|
clc
|
|
rts
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = direct_acc THEN
|
|
|
|
INCLUDE 'SCSI Get Vol/Disk'
|
|
|
|
ENDIF
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
ENDP
|
|
|
|
EJECT
|
|
|
|
;*******************************************************
|
|
;
|
|
; Get the current Wait/No Wait status of this device.
|
|
; If it is a block device then no error will occur and
|
|
; a $0000 (Wait Mode) will be returned.
|
|
;
|
|
; Called via 'JSR'
|
|
;
|
|
; Inputs: [dib_ptr] = Target DIB l (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
|
|
;
|
|
; [buff_ptr] = Current Mode
|
|
; Y register = Unspecified
|
|
; X register = Unspecified
|
|
; P register = 0=M=X=e
|
|
; Direct Page = Ours
|
|
; Data Bank = Ours
|
|
;
|
|
; Errors: See Spec.
|
|
;
|
|
;*******************************************************
|
|
|
|
EXPORT wait_status
|
|
wait_status PROC
|
|
;
|
|
; Check the parameters list.
|
|
; Should contain a WORD
|
|
;
|
|
lda <rqst_cnt
|
|
cmp #$0002
|
|
bne @bad_parm
|
|
sta <trans_cnt
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF block_dvc = true THEN
|
|
;
|
|
; If a Block Device then return Wait Mode.
|
|
;
|
|
lda #null
|
|
|
|
ENDIF
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF character_dvc = true THEN
|
|
;
|
|
; Check the Current Mode
|
|
;
|
|
ldy #dib.dvcflag
|
|
lda [dib_ptr],y
|
|
and #wait_mode
|
|
bne @wait
|
|
;
|
|
; Return No Wait Mode.
|
|
;
|
|
lda #bit_15
|
|
bra @exit
|
|
;
|
|
; Return Wait Mode.
|
|
;
|
|
@wait lda #null
|
|
|
|
ENDIF
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
;
|
|
; Save it and exit.
|
|
;
|
|
@exit sta [buff_ptr]
|
|
lda #null ;Clear the Acc.
|
|
clc
|
|
rts
|
|
;
|
|
; Bad Parm Error
|
|
;
|
|
@bad_parm lda #drvr_bad_parm
|
|
sec
|
|
rts
|
|
|
|
ENDP
|
|
|
|
EJECT
|
|
|
|
;*******************************************************
|
|
;
|
|
; Get Format Options Call
|
|
;
|
|
; Called via 'JSR'
|
|
;
|
|
; Inputs: [dib_ptr] = Target DIB l (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.
|
|
;
|
|
;*******************************************************
|
|
|
|
EXPORT fmt_options
|
|
fmt_options PROC
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF block_dvc = true\
|
|
AND character_dvc = false THEN
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = apple_cd\
|
|
OR scsi_dtype = changer THEN
|
|
;
|
|
; If the device is a CD_ROM, then there
|
|
; are no format options.
|
|
stz <trans_cnt
|
|
stz <trans_cnt+2
|
|
lda #bad_dev_number
|
|
sec
|
|
rts
|
|
|
|
ENDIF ;scsi_dtype = apple_cd or changer
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = mcd_40 THEN
|
|
;
|
|
; If the device is a Tape, then there
|
|
; are no format options.
|
|
stz <trans_cnt
|
|
stz <trans_cnt+2
|
|
lda #null
|
|
clc
|
|
rts
|
|
|
|
ENDIF ;scsi_dtype = mcd_40
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = direct_acc THEN
|
|
;
|
|
; Get Format Options Call
|
|
;
|
|
; It's a block device. But is
|
|
; it partitioned? If it has a
|
|
; zero start block then there is
|
|
; no partition.
|
|
;
|
|
ldy #dib.start_blk
|
|
lda [dib_ptr],y
|
|
ldy #dib.start_blk+2
|
|
ora [dib_ptr],y
|
|
beq @no_link
|
|
;
|
|
; Well, it is a partition. But is it
|
|
; the only partition. By this, I mean,
|
|
; is it a disk with a partition map
|
|
; containing only two entries, one for
|
|
; the partition map and the other for
|
|
; a single volume?
|
|
;
|
|
; Is it linked? Let's see.
|
|
;
|
|
ldy #dib.dvcchar
|
|
lda [dib_ptr],y
|
|
and #linked_dvc
|
|
bne @linked ;Linked.
|
|
;
|
|
; Now check if this is the first or
|
|
; second entry in the Partition Map.
|
|
;
|
|
ldy #dib.part_blk
|
|
lda [dib_ptr],y
|
|
xba
|
|
cmp #$0003
|
|
blt @no_link ;Only one partition.
|
|
|
|
@linked stz <trans_cnt
|
|
stz <trans_cnt+2
|
|
lda #null
|
|
clc
|
|
rts
|
|
;
|
|
; Set display count to 3
|
|
;
|
|
@no_link lda #$0003
|
|
sta |display_cnt-2
|
|
sta |display_cnt
|
|
;
|
|
; Issue MODE SENSE Call
|
|
;
|
|
jsr mode_sense
|
|
;
|
|
; Check to see if the device supports
|
|
; the page discriptors.
|
|
;
|
|
lda |mode.blk_disc\
|
|
+internal_buff
|
|
and #$00ff
|
|
beq @do_from_dib
|
|
;
|
|
; Not all device return the block count
|
|
; in this call. Shame on them. If the
|
|
; block count is missing, then get it
|
|
; from the DIB. This data is 3 bytes
|
|
; MSB >> LSB formatted.
|
|
;
|
|
lda |mode.blocks\ ;High Byte
|
|
+internal_buff\
|
|
-1
|
|
and #$ff00
|
|
ora |mode.blocks\ ;.OR.ed with the Low Word
|
|
+internal_buff\
|
|
+1
|
|
beq @do_from_dib
|
|
;
|
|
; MODE SENSE is legal. Use it.
|
|
;
|
|
; Set Block Count in format
|
|
; option list.
|
|
;
|
|
lda |mode.blocks\
|
|
+internal_buff\
|
|
+1
|
|
xba
|
|
sta |opt1_blk_cnt
|
|
sta |opt2_blk_cnt
|
|
|
|
lda |mode.blocks\
|
|
+internal_buff\
|
|
-1
|
|
xba
|
|
sta |opt1_blk_cnt+2
|
|
sta |opt2_blk_cnt+2
|
|
;
|
|
; Set Block Size in format
|
|
; option list.
|
|
;
|
|
lda |mode.blk_size\
|
|
+internal_buff\
|
|
+1
|
|
xba
|
|
cmp #$0214 ;is it = 532?
|
|
bne @not_532 ;No.
|
|
lda #$0200 ;Yes.
|
|
@not_532 sta |opt1_blk_siz
|
|
sta |opt2_blk_siz
|
|
bra @set_med_size
|
|
;
|
|
; Set Block Count in format
|
|
; option list from DIB.
|
|
;
|
|
@do_from_dib ldy #dib.blkcnt
|
|
lda [dib_ptr],y
|
|
sta |opt1_blk_cnt
|
|
sta |opt2_blk_cnt
|
|
|
|
ldy #dib.blkcnt+2
|
|
lda [dib_ptr],y
|
|
sta |opt1_blk_cnt+2
|
|
sta |opt2_blk_cnt+2
|
|
;
|
|
; Set Block Size in format
|
|
; option list.
|
|
;
|
|
ldy #dib.blksize
|
|
lda [dib_ptr],y
|
|
sta |opt1_blk_siz
|
|
sta |opt2_blk_siz
|
|
;
|
|
; Set Media Size in format
|
|
; option list.
|
|
;
|
|
@set_med_size lda |opt1_blk_cnt+3
|
|
and #$00ff
|
|
sta @t_blocks
|
|
lda |opt1_blk_cnt+1
|
|
lsr @t_blocks
|
|
lsr a
|
|
lsr @t_blocks
|
|
lsr a
|
|
lsr @t_blocks
|
|
lsr a
|
|
adc #$0000
|
|
sta |opt1_med_siz
|
|
sta |opt2_med_siz
|
|
;
|
|
; Get Read Capacity
|
|
;
|
|
jsr read_capacity
|
|
;
|
|
; Set Block Size in format
|
|
; option list.
|
|
;
|
|
lda |block.size\
|
|
+internal_buff\
|
|
+2
|
|
xba
|
|
sta |opt3_blk_siz
|
|
cmp #$0200
|
|
bne @over
|
|
;
|
|
; Set display count to 2
|
|
;
|
|
lda #$0002
|
|
sta |display_cnt-2
|
|
sta |display_cnt
|
|
;
|
|
; Set Block Count in format
|
|
; option list.
|
|
;
|
|
@over lda |block.count\
|
|
+internal_buff\
|
|
+2
|
|
xba
|
|
sta |opt3_blk_cnt
|
|
|
|
lda |block.count\
|
|
+internal_buff
|
|
xba
|
|
sta |opt3_blk_cnt+2
|
|
;
|
|
; Set Media Size in format
|
|
; option list.
|
|
;
|
|
lda |block.count\
|
|
+internal_buff\
|
|
-1
|
|
xba
|
|
sta @t_blocks
|
|
lda |block.count\
|
|
+internal_buff\
|
|
+1
|
|
xba
|
|
lsr @t_blocks
|
|
lsr a
|
|
lsr @t_blocks
|
|
lsr a
|
|
lsr @t_blocks
|
|
lsr a
|
|
adc #$0000
|
|
sta |opt3_med_siz
|
|
;
|
|
; Restore Direct Page
|
|
;
|
|
jsr set_our_dp
|
|
;
|
|
; Check Count range
|
|
;
|
|
lda <rqst_cnt+2
|
|
bne @do_max
|
|
lda <rqst_cnt
|
|
cmp #opt3_med_siz-\
|
|
format_options+\
|
|
2
|
|
blt @this_many
|
|
@do_max lda #opt3_med_siz-\
|
|
format_options+\
|
|
2
|
|
;
|
|
; Send this many bytes of the list.
|
|
;
|
|
@this_many sta <trans_cnt
|
|
stz <trans_cnt+2
|
|
tay
|
|
dey
|
|
bmi @exit
|
|
short
|
|
@loop lda format_options,y
|
|
sta [buff_ptr],y
|
|
dey
|
|
bpl @loop
|
|
longmx
|
|
;
|
|
; Exit.
|
|
;
|
|
@exit lda #null
|
|
clc
|
|
rts
|
|
;
|
|
; Data Area
|
|
;
|
|
@t_blocks dc.w null
|
|
|
|
ENDIF ;scsi_dtype = direct_acc
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
ENDIF ;block_dvc = true
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF block_dvc = false\
|
|
AND character_dvc = true THEN
|
|
;
|
|
; If the device is a Character Device,
|
|
; then there are no Format Options to
|
|
; return.
|
|
;
|
|
stz <trans_cnt
|
|
stz <trans_cnt+2
|
|
lda #null
|
|
clc
|
|
rts
|
|
|
|
ENDIF ;character_dvc = true
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
ENDP
|
|
|
|
EJECT
|
|
|
|
;*******************************************************
|
|
;
|
|
; Most be the first device in a link!!!!
|
|
;
|
|
; Entry point to the 'Read PMap' call. This call
|
|
; takes the information given by the caller on direct
|
|
; page and builds the equivilent to a Read Status Call
|
|
; to read request count bytes starting at physical
|
|
; block number 1. This is done by setting the high
|
|
; bit of the partition call flag 'f_partition'.
|
|
;
|
|
; Block Size = dib.blksize
|
|
;
|
|
; We now Build the SCSI Main Driver Command and send
|
|
; it.
|
|
;
|
|
; The following will be validated by the Main Driver
|
|
; when it builds the command.
|
|
;
|
|
; Request Count = Block Size * i
|
|
; Block Number = Blk Num (No Offset)
|
|
; This is for partitions.
|
|
;
|
|
; After calling the Main driver and if no errors were
|
|
; encountered, then the Transfer count will be
|
|
; updated.
|
|
;
|
|
; Called via 'JSR'
|
|
;
|
|
; Inputs: [dib_ptr] = Target DIB l (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.
|
|
;
|
|
;*******************************************************
|
|
|
|
EXPORT read_p_map
|
|
read_p_map PROC
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF block_dvc = true\
|
|
AND character_dvc = false THEN
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = apple_cd\
|
|
OR scsi_dtype = changer THEN
|
|
;
|
|
; Exit No Error.
|
|
;
|
|
lda #drvr_bad_code
|
|
sec
|
|
rts
|
|
|
|
ENDIF ;scsi_dtype = apple_cd or changer
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = mcd_40 THEN
|
|
;
|
|
; Exit No Error.
|
|
;
|
|
lda #drvr_bad_code
|
|
sec
|
|
rts
|
|
|
|
ENDIF ;scsi_dtype = mcd_40
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = direct_acc THEN
|
|
|
|
stz @do_532
|
|
;
|
|
; Set the Block size on Direct Page.
|
|
; It is not placed there for this call,
|
|
; and we should not rely on it being
|
|
; left behind by the last call.
|
|
;
|
|
lda #block_size
|
|
sta <blk_size
|
|
;
|
|
; Check if first DIB in link if any.
|
|
; If it is zero, then we are already
|
|
; there. If not then error out.
|
|
;
|
|
ldy #dib.headptr+2
|
|
lda [dib_ptr],y
|
|
ldy #dib.headptr
|
|
ora [dib_ptr],y
|
|
bne @bad_dev_num
|
|
;
|
|
; Let's check the request count. If
|
|
; this is $00000000, then exit clean
|
|
; with no data transfered.
|
|
;
|
|
lda <rqst_cnt
|
|
ora <rqst_cnt+2
|
|
bne @cnt_non_zero
|
|
jmp @out_of_here
|
|
;
|
|
; Verify Block Size.
|
|
;
|
|
@cnt_non_zero ldy #dib.blksize
|
|
lda [dib_ptr],y ;Block Size
|
|
cmp <blk_size
|
|
bne @chk_532
|
|
|
|
ldy #dib.blksize+2
|
|
lda [dib_ptr],y
|
|
beq @blk_size_ok
|
|
|
|
@bad_parm lda #drvr_bad_parm
|
|
sec
|
|
rts
|
|
;
|
|
; Check for 532 byte block size
|
|
;
|
|
@chk_532 tax
|
|
|
|
lda <blk_size
|
|
cmp #block_size
|
|
bne @bad_parm
|
|
|
|
cpx #$0214
|
|
bne @bad_parm
|
|
dec @do_532
|
|
|
|
@blk_size_ok
|
|
;
|
|
; Build the (Read Data)
|
|
; Status Command $8008
|
|
;
|
|
lda #$0001 ; Sent to me Low >> High.
|
|
xba ; I Send it out High >> Low.
|
|
sta |c_block_num
|
|
;
|
|
; Set Main Driver Pointer to
|
|
; our data for the command.
|
|
;
|
|
lda #cmd_$8008
|
|
sta <scsi_mdrvr
|
|
lda #^cmd_$8008
|
|
sta <scsi_mdrvr+2
|
|
;
|
|
; Set the Partition call flag
|
|
;
|
|
dec |f_partition
|
|
;
|
|
; Call Main Driver
|
|
;
|
|
lda #scsit_stat
|
|
sta |call_type
|
|
;
|
|
; Issue the call.
|
|
;
|
|
jsr check_532_rw
|
|
bcs @rts
|
|
;
|
|
; Update Transfer Count.
|
|
;
|
|
@out_of_here lda <rqst_cnt
|
|
sta <trans_cnt
|
|
lda <rqst_cnt+2
|
|
sta <trans_cnt+2
|
|
;
|
|
; Exit No Error.
|
|
;
|
|
lda #$0000
|
|
clc
|
|
rts
|
|
|
|
|
|
@bad_dev_num lda #bad_dev_number
|
|
sec
|
|
@rts rts
|
|
;
|
|
; Variables and storage for short call.
|
|
;
|
|
@do_532 dc.w null ;532 byte block flag
|
|
;
|
|
; Command Data for this call.
|
|
;
|
|
cmd_$8008 dc.b $08
|
|
dc.b $00
|
|
c_block_num dc.w $0000
|
|
c_block_cnt dc.b $00
|
|
dcb.b 7,$00
|
|
|
|
ENDIF ;scsi_dtype = direct_acc
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
ENDIF ;block_dvc = true
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF block_dvc = false\
|
|
AND character_dvc = true THEN
|
|
;
|
|
; If the device is a Character Device,
|
|
; then there are no Partitions to
|
|
; read.
|
|
;
|
|
stz <trans_cnt
|
|
stz <trans_cnt+2
|
|
lda #null
|
|
clc
|
|
rts
|
|
|
|
ENDIF ;character_dvc = true
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
ENDP
|
|
|
|
EJECT
|
|
|
|
;*******************************************************
|
|
;
|
|
; 'g_last_rslt'
|
|
;
|
|
; This call returns the Error code result of the last
|
|
; call. This used to inquire about the result of a
|
|
; call that may have been executed asyncronously. If
|
|
; the device is busy with a pending call when this call
|
|
; is issued, a DEVICE_BUSY Error will be returned.
|
|
;
|
|
; Called via 'JSR'
|
|
;
|
|
; Inputs: [dib_ptr] = Target DIB l (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
|
|
;
|
|
; Users Buffer =
|
|
; |----------------------------------------|
|
|
; WORD +- GS/OS Error Code -+
|
|
; |----------------------------------------|
|
|
; WORD +- Device ID Number -+
|
|
; |----------------------------------------|
|
|
; WORD +- SCSI Status Code -+
|
|
; |----------------------------------------|
|
|
; WORD +- SCSI REQUEST SENSE sense key -+
|
|
; |----------------------------------------|
|
|
; LONG +- MSB -+
|
|
; +- Information Bytes -+
|
|
; +- LSB -+
|
|
; |----------------------------------------|
|
|
; WORD +- REQUEST SENSE data length -+
|
|
; |----------------------------------------|
|
|
; WORD +- Reserved -+
|
|
; |----------------------------------------|
|
|
;
|
|
; Errors: Device Busy. Only if the target device
|
|
; currently has a call pending.
|
|
;
|
|
;*******************************************************
|
|
|
|
EXPORT g_last_rslt
|
|
g_last_rslt PROC
|
|
;
|
|
; Is this the same device?
|
|
;
|
|
lda <dev_num
|
|
cmp |lst_rslt_id
|
|
bne @bad_dvc_num
|
|
;
|
|
; Check if the device has a call
|
|
; pending.
|
|
;
|
|
ldy #dib.dvcflag
|
|
lda [dib_ptr],y
|
|
and #int_busy
|
|
bne @device_busy
|
|
;
|
|
; Update Transfer Count.
|
|
;
|
|
lda <rqst_cnt+2
|
|
bne @rslt_all
|
|
lda <rqst_cnt
|
|
and #$fffe ;No odd byte transfers
|
|
beq @exit
|
|
cmp #lst_rslt_scode+2-\
|
|
lst_rslt_ec
|
|
blt @set_rslt
|
|
|
|
@rslt_all lda #lst_rslt_scode+2-\
|
|
lst_rslt_ec
|
|
@set_rslt sta <trans_cnt
|
|
tay
|
|
lda #null
|
|
sta <trans_cnt+2
|
|
;
|
|
; Move the Data.
|
|
;
|
|
dey
|
|
dey
|
|
|
|
@loop lda |lst_rslt_ec,y
|
|
sta [buff_ptr],y
|
|
dey
|
|
dey
|
|
bpl @loop
|
|
;
|
|
; Exit No Error.
|
|
;
|
|
@exit lda #$0000
|
|
clc
|
|
rts
|
|
;
|
|
; Errors.
|
|
;
|
|
@device_busy lda #drvr_busy
|
|
sec
|
|
@rts rts
|
|
|
|
@bad_dvc_num lda #bad_dev_number
|
|
sec
|
|
rts
|
|
|
|
ENDP
|
|
|
|
*** Added - 16-Feb-93 JCM
|
|
|
|
;*******************************************************
|
|
;
|
|
; 'get_target_priority'
|
|
;
|
|
; This is skanky, this is skanky, this is skanky. Did
|
|
; I mention that this is skanky? - jm3
|
|
;
|
|
; This call returns the SCSI target priority (known to
|
|
; most as the SCSI ID) for a given device. We walk the
|
|
; SCSI Manager's internal tables to figure this out,
|
|
; since we never need to know the ID otherwise.
|
|
; This was added solely for Jim Murphy's convience in
|
|
; adding a bit of new information to Finder's Get Info
|
|
; window ("Where" card). I've always wanted an easier
|
|
; method of getting SCSI ID's, and the Macintosh shows
|
|
; it in it's device Icon Info, so why shouldn't we? Now
|
|
; we will (at least when this code is done :-).
|
|
;
|
|
; Called via 'JSR'
|
|
;
|
|
; Inputs: [dib_ptr] = Target DIB l (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
|
|
;
|
|
; User's Buffer =
|
|
; |----------------------------------------|
|
|
; WORD +- SCSI Target Priority -+
|
|
; |----------------------------------------|
|
|
;
|
|
; Errors: ACC = drvr_bad_cnt if user did not request
|
|
; 2 bytes as the request count
|
|
;
|
|
;*******************************************************
|
|
|
|
EXPORT get_target_priority
|
|
get_target_priority PROC
|
|
|
|
lda <rqst_cnt+2
|
|
bne @bad_rqst_cnt
|
|
|
|
lda <rqst_cnt
|
|
dec a
|
|
dec a
|
|
beq @doCall
|
|
|
|
@bad_rqst_cnt lda #drvr_bad_cnt
|
|
|
|
sec
|
|
|
|
rts
|
|
|
|
; Force the SCSI Manager to update its internal variables so we can be assured that
|
|
; <active_sdr points to the SCSI Device Record associated with this dib and, correspondingly,
|
|
; this device.
|
|
|
|
@doCall jsr test_unit_rdy ;basically a dummy call, we don't care about errors
|
|
|
|
; By taking advantage of the fact that our Direct Page is $100 bytes before the SCSI Manager's,
|
|
; (it gave it to us), we can quickly get lots of cool things from it.
|
|
|
|
tdc ;our DP is active
|
|
clc
|
|
adc #$100
|
|
sta <scsi_zp0 ;we now have the SCSI Manager's direct page. Whooee! :-)
|
|
stz <scsi_zp0+2
|
|
|
|
; Now we will also rely on the fact that the SCSI Manager's direct page is set up
|
|
; at $4C on like this:
|
|
|
|
active_sdr equ $4C ;pointer to currently active SDR
|
|
|
|
ldy #active_sdr
|
|
lda [<scsi_zp0],y
|
|
tax
|
|
iny
|
|
iny
|
|
lda [<scsi_zp0],y
|
|
sta <scsi_zp0+2
|
|
stx <scsi_zp0
|
|
|
|
; Finally we have a pointer to the SDR for the target SCSI device. At offset $14 in the
|
|
; record we have the magic word - the target priority value. A single bit that's set
|
|
; within the low order byte indicates the priority.
|
|
|
|
sdr_targ_priot equ $14 ;Target device priority
|
|
|
|
ldy #sdr_targ_priot ;offset to the SCSI target priority
|
|
lda [<scsi_zp0],y
|
|
beq @ouch ;if no bits are set, we're screwed, so exit now
|
|
|
|
ldx #-1
|
|
|
|
@getTheID inx
|
|
lsr a
|
|
bcc @getTheID
|
|
|
|
txa
|
|
@ouch sta [buff_ptr] ;stuff this value in the caller's buffer
|
|
|
|
lda #2 ;we transferred 2 bytes
|
|
sta <trans_cnt
|
|
stz <trans_cnt+2
|
|
|
|
dec a ;no errors possible
|
|
dec a ; (was 2 - now 0 - save's a byte)
|
|
clc
|
|
|
|
rts
|
|
|
|
ENDP
|
|
|
|
*** End - 16-Feb-93 JCM
|
|
|
|
EJECT
|
|
|
|
END
|