mirror of
https://github.com/antoinevignau/source.git
synced 2024-11-19 22:31:52 +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 'Control' filter.
|
|
;
|
|
; Written by Matt Gulick. Started August 13,1988
|
|
;
|
|
; Copyright Apple Computer, Inc. 1988,89
|
|
;
|
|
;*******************************************************
|
|
|
|
;*******************************************************
|
|
;
|
|
; This file contains the 'Control' filter as defined
|
|
; in the ERS.
|
|
;
|
|
;*******************************************************
|
|
|
|
;*******************************************************
|
|
;
|
|
; Revision History:
|
|
;
|
|
;*******************************************************
|
|
|
|
; Aug 13, 1988 File started.
|
|
|
|
STRING PASCAL
|
|
BLANKS OFF
|
|
PAGESIZE 70
|
|
PRINT NOGEN
|
|
PRINT NOMDIR
|
|
MACHINE M65816
|
|
|
|
IMPORT rpm_blk_num
|
|
IMPORT wpm_blk_num
|
|
IMPORT stat_cont
|
|
IMPORT rebuild
|
|
IMPORT read_pm_blk
|
|
IMPORT write_pm_blk
|
|
|
|
IMPORT call_type
|
|
IMPORT internal
|
|
IMPORT main_drvr
|
|
IMPORT f_partition
|
|
IMPORT direct_page
|
|
IMPORT gsos_dpage
|
|
IMPORT internal_buff
|
|
IMPORT set_our_dp
|
|
IMPORT chk_lnk_offline
|
|
IMPORT set_disk_sw
|
|
IMPORT leave_switched ; *** MSG 12/12/91 ***
|
|
IMPORT disk_switch
|
|
IMPORT rebld_dibs
|
|
IMPORT unit_state
|
|
IMPORT test_unit_rdy
|
|
IMPORT trash_volume
|
|
IMPORT trash_it
|
|
IMPORT ko_cache
|
|
IMPORT trans_flag
|
|
IMPORT uses_dc
|
|
IMPORT dib_data_struct
|
|
IMPORT display_cnt
|
|
IMPORT current_fmt
|
|
IMPORT opt1_blk_cnt
|
|
IMPORT opt1_blk_siz
|
|
IMPORT opt1_interleave
|
|
IMPORT opt1_med_siz
|
|
IMPORT opt2_blk_cnt
|
|
IMPORT opt2_blk_siz
|
|
IMPORT opt2_interleave
|
|
IMPORT opt2_med_siz
|
|
IMPORT opt3_blk_cnt
|
|
IMPORT opt3_blk_siz
|
|
IMPORT opt3_interleave
|
|
IMPORT opt3_med_siz
|
|
IMPORT format_data
|
|
IMPORT check_532_rw
|
|
IMPORT sense_data
|
|
IMPORT t_dvc_blocks
|
|
IMPORT un_formatted
|
|
|
|
ENTRY reset_dvc
|
|
ENTRY eject
|
|
ENTRY s_config_parms
|
|
ENTRY s_wait_mode
|
|
ENTRY format_opt
|
|
ENTRY assign_part
|
|
ENTRY arm_signal
|
|
ENTRY disarm_sig
|
|
ENTRY set_p_map
|
|
ENTRY format_dvc
|
|
|
|
PRINT OFF
|
|
|
|
INCLUDE 'scsihd.equates'
|
|
INCLUDE 'M16.MEMORY'
|
|
INCLUDE 'M16.UTIL'
|
|
PRINT ON
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = direct_acc THEN
|
|
|
|
ENTRY sdp
|
|
ENTRY svp
|
|
|
|
ENDIF
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
EJECT
|
|
|
|
;*******************************************************
|
|
;
|
|
; Main Entry point to the 'Control' filter. This
|
|
; "Filter" is called when a Control Command comes in.
|
|
; See the headers of the seperate sections for the
|
|
; details of the commands.
|
|
;
|
|
; 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 control
|
|
control PROC
|
|
;
|
|
; Check to see if this is a set Config call.
|
|
; If so, then don't worry yet about ONLINE
|
|
; or REMOVABLE.
|
|
;
|
|
lda <cont_code
|
|
cmp #$0003
|
|
beq @control
|
|
;
|
|
; 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
|
|
beq @online ;**** test Code ****
|
|
bit |un_formatted ;**** test Code ****
|
|
|
|
bpl @sec_out ;**** test Code ****
|
|
; bmi @rts_out
|
|
;
|
|
; 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
|
|
bmi @control
|
|
;
|
|
; Is the device online?
|
|
;
|
|
ldy #dib.dvcflag
|
|
|
|
lda [dib_ptr],y
|
|
and #dvc_online
|
|
bne @control ;Yes.
|
|
;
|
|
; Device is currently offline.
|
|
;
|
|
lda #drvr_off_line
|
|
@sec_out sec
|
|
@rts_out rts
|
|
;
|
|
; Zero out the Data Chaining Flag
|
|
;
|
|
@control 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 Control Call Filter.
|
|
; This filter acts as a mini driver.
|
|
; It examines the Control 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 <cont_code
|
|
bmi @do_dvc_spec ;Device Specific Code.
|
|
;
|
|
; Check the range of the command.
|
|
;
|
|
cmp #max_c_cmd+1
|
|
bge @error
|
|
;
|
|
; Convert to an index
|
|
;
|
|
asl a
|
|
tax
|
|
jsr (@ncmd_tbl,x)
|
|
rts
|
|
;
|
|
; Normal Command Table.
|
|
;
|
|
@ncmd_tbl dc.w reset_dvc ;Coded
|
|
dc.w format_dvc ;Coded
|
|
dc.w eject ;Coded
|
|
dc.w s_config_parms ;Coded Temp
|
|
dc.w s_wait_mode ;Coded
|
|
dc.w format_opt ;Coded
|
|
dc.w assign_part
|
|
dc.w arm_signal ;Coded & Tested
|
|
dc.w disarm_sig ;Coded & Tested
|
|
dc.w set_p_map ;Coded & Tested
|
|
;
|
|
; Bad Command Error.
|
|
;
|
|
@error lda #drvr_bad_req
|
|
sec
|
|
rts
|
|
;
|
|
; 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 sdp ;Coded (Set Disk Parms)
|
|
dc.w svp ;Coded (Set 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
|
|
|
|
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_cont
|
|
sta |call_type
|
|
jsr |main_drvr
|
|
bcs @exit
|
|
;
|
|
; 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 ;= $ffff
|
|
bpl @exit
|
|
;
|
|
; Don't Trash the Volumes.
|
|
;
|
|
jsr set_disk_sw ;DISK_SW for each Linked DIB.
|
|
jsr rebld_dibs ;Rebuild DIBs.
|
|
lda #null
|
|
clc
|
|
;
|
|
; 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
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF cache_blks = true THEN
|
|
|
|
;
|
|
; If it is a Data Call and has a timer
|
|
; that is adjusted by the block count,
|
|
; then this call could cause the cache
|
|
; to be in-validated.
|
|
;
|
|
lda |trans_flag
|
|
and #scsit_data++\ ;Is it a data call
|
|
scsic_tout++\ ;with a block count
|
|
scsit_cont ;Writing data?
|
|
cmp #scsit_data++\
|
|
scsic_tout++\
|
|
scsit_cont
|
|
bne @no_write ;No.
|
|
jsr ko_cache ;Yes. Kill the blocks.
|
|
|
|
ENDIF
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
;
|
|
; Exit.
|
|
;
|
|
@no_write plp
|
|
pla
|
|
rts
|
|
;
|
|
; Data Area.
|
|
;
|
|
@call_trns_cnt dc.l null ;Transfer count befor we steped on it.
|
|
@chk_zero dc.w null ;Check first DCMove Flag.
|
|
|
|
ENDP
|
|
|
|
EJECT
|
|
|
|
;*******************************************************
|
|
;
|
|
; This Control Call is used to reset a particular
|
|
; device to it's default settings. A Device Driver
|
|
; should configure itself based on the contents of the
|
|
; drivers configuration parameter list. This call
|
|
; should reset any media variables that were modified
|
|
; through a Set_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 reset_dvc
|
|
reset_dvc PROC
|
|
;
|
|
; Issue a REeZero Unit Call to the device.
|
|
;
|
|
; Set Main Driver Pointer to
|
|
; our data for the command.
|
|
;
|
|
lda #cmd_$8001
|
|
sta <scsi_mdrvr
|
|
lda #^cmd_$8001
|
|
sta <scsi_mdrvr+2
|
|
;
|
|
; Call Main Driver
|
|
;
|
|
lda #scsit_cont
|
|
sta |call_type
|
|
jsr |main_drvr
|
|
;
|
|
; Update Transfer Count.
|
|
;
|
|
stz <trans_cnt
|
|
stz <trans_cnt+2
|
|
;
|
|
; Exit No Error.
|
|
;
|
|
lda #$0000
|
|
clc
|
|
rts
|
|
;
|
|
; Command Data for this call.
|
|
;
|
|
cmd_$8001 dc.b $01
|
|
dcb.b 11,$00
|
|
|
|
ENDP
|
|
|
|
EJECT
|
|
|
|
;*******************************************************
|
|
;
|
|
; The Format call will ensure that the media is
|
|
; formatted and ready to receive data. If the DIB
|
|
; points to a partition then the Format call will
|
|
; return no error while taking no action (If it is
|
|
; partitioned, then it must have been formatted or the
|
|
; partition map could not have been written. Right?).
|
|
;
|
|
; 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 format_dvc
|
|
format_dvc PROC
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF character_dvc = true THEN
|
|
;
|
|
; It's a character device and
|
|
; the Acc is zero by virtue of
|
|
; the missed branch.
|
|
;
|
|
stz <trans_cnt
|
|
stz <trans_cnt+2
|
|
lda #null
|
|
clc
|
|
rts
|
|
|
|
ENDIF
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = apple_cd\
|
|
OR scsi_dtype = changer THEN
|
|
;
|
|
; If the device is a CD_ROM, then
|
|
; it is write protected.
|
|
;
|
|
stz <trans_cnt
|
|
stz <trans_cnt+2
|
|
lda #drvr_wrt_prot
|
|
sec
|
|
rts
|
|
|
|
ENDIF
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = mcd_40 THEN
|
|
|
|
;
|
|
; Is the device Write Enabled?
|
|
;
|
|
ldy #dib.dvcchar
|
|
lda [dib_ptr],y
|
|
and #write_allow
|
|
beq @write_protect
|
|
;
|
|
; Set Format Parm Pointer.
|
|
;
|
|
lda #@format_p
|
|
sta <scsi_mdrvr
|
|
lda #^@format_p
|
|
sta <scsi_mdrvr+2
|
|
;
|
|
; Set our own buffer pointer
|
|
; for this call.
|
|
;
|
|
lda #format_data
|
|
sta <buff_ptr
|
|
lda #^format_data
|
|
sta <buff_ptr+2
|
|
;
|
|
; Set our own request count
|
|
; for this call.
|
|
;
|
|
stz <rqst_cnt
|
|
stz <rqst_cnt+2
|
|
;
|
|
; It's a Control Call.
|
|
;
|
|
lda #scsit_cont
|
|
sta |call_type
|
|
;
|
|
; Set Internal Command Flag
|
|
;
|
|
dec |internal
|
|
;
|
|
; Issue the Call
|
|
;
|
|
jsr |main_drvr
|
|
|
|
pha
|
|
php
|
|
|
|
@test_loop jsr |test_unit_rdy
|
|
bcc @fmt_done
|
|
cmp #$FE08
|
|
beq @test_loop
|
|
cmp #$FE02
|
|
bne @test_loop
|
|
bra @tape_io_error
|
|
|
|
@fmt_done plp
|
|
pla
|
|
|
|
rts
|
|
;
|
|
; Return an I/O Error
|
|
;
|
|
@tape_io_error plp
|
|
pla
|
|
|
|
lda #drvr_io
|
|
sec
|
|
rts
|
|
;
|
|
; Return a Write Protected Error
|
|
;
|
|
@write_protect lda #drvr_wrt_prot
|
|
sec
|
|
rts
|
|
;
|
|
; FORMAT Command Packet
|
|
;
|
|
@format_p dc.b $04 ;Command Number
|
|
dc.b $00 ;Vendor Unique
|
|
dc.b $00 ;Reserved
|
|
dc.b $00 ;SCSI Interleave (MSB)
|
|
@interleave dc.b interleave ;SCSI Interleave (LSB)
|
|
dcb.b 6,$00 ;Reserved
|
|
|
|
ENDIF
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = direct_acc THEN
|
|
;
|
|
; It's a block device. But is
|
|
; it partitioned? If it has a
|
|
; zero start block then there is
|
|
; no partition.
|
|
;
|
|
stz @error ;Set to No Error.
|
|
ldy #dib.start_blk
|
|
lda [dib_ptr],y
|
|
ldy #dib.start_blk+2
|
|
ora [dib_ptr],y
|
|
beq @over
|
|
;
|
|
; 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?
|
|
;
|
|
; First check if this is the first or
|
|
; second entry in the Partition Map.
|
|
;
|
|
ldy #dib.part_blk
|
|
lda [dib_ptr],y
|
|
xba
|
|
cmp #$0003
|
|
bge @do_part_fmt ;Past the second entry. Do as if multi
|
|
;partition.
|
|
;
|
|
; Is it linked? Let's see.
|
|
;
|
|
ldy #dib.dvcchar
|
|
lda [dib_ptr],y
|
|
and #linked_dvc
|
|
beq @over ;Not linked. Must be only one.
|
|
|
|
@do_part_fmt jsr trash_volume ;Trash this volume only.
|
|
jmp @clean_exit ;Sorry. Not the only volume
|
|
;
|
|
; Well there is no getting around
|
|
; it. We need to issue a format
|
|
; call to this device.
|
|
;
|
|
; Setup from last format options call
|
|
;
|
|
@over lda |current_fmt
|
|
dec a
|
|
asl a
|
|
asl a
|
|
asl a
|
|
asl a
|
|
tax
|
|
|
|
ldy #dib.blksize
|
|
lda |opt1_blk_siz,x
|
|
sta [dib_ptr],y
|
|
xba
|
|
sta @blk_size+2
|
|
|
|
lda |opt1_blk_cnt,x
|
|
sta |t_dvc_blocks
|
|
|
|
lda |opt1_blk_cnt+2,x
|
|
sta |t_dvc_blocks+2
|
|
|
|
stz @blk_size
|
|
shortm
|
|
lda opt1_interleave,x
|
|
sta @interleave
|
|
longm
|
|
;
|
|
; Preserve the Current Direct
|
|
; Page values stored in the
|
|
; buff_ptr and rqst_cnt fields.
|
|
;
|
|
pei <buff_ptr
|
|
pei <buff_ptr+2
|
|
pei <rqst_cnt
|
|
pei <rqst_cnt+2
|
|
;
|
|
; Set Format Parm Pointer.
|
|
;
|
|
lda #@format_p
|
|
sta <scsi_mdrvr
|
|
lda #^@format_p
|
|
sta <scsi_mdrvr+2
|
|
;
|
|
; Set our own buffer pointer
|
|
; for this call.
|
|
;
|
|
lda #format_data
|
|
sta <buff_ptr
|
|
lda #^format_data
|
|
sta <buff_ptr+2
|
|
;
|
|
; Set our own request count
|
|
; for this call.
|
|
;
|
|
stz <rqst_cnt
|
|
stz <rqst_cnt+2
|
|
;
|
|
; It's a Control Call.
|
|
;
|
|
lda #scsit_cont
|
|
sta |call_type
|
|
;
|
|
; Set Internal Command Flag
|
|
;
|
|
dec |internal
|
|
;
|
|
; Issue the Call
|
|
;
|
|
jsr |main_drvr
|
|
bcc @rebuild_dib
|
|
;
|
|
; Save error code
|
|
;
|
|
sta @error
|
|
;
|
|
; Rebuild the DIB.
|
|
;
|
|
@rebuild_dib jsr rebld_dibs
|
|
;
|
|
; Restore the Direct Page Values.
|
|
;
|
|
@return_dp pla
|
|
sta <rqst_cnt+2
|
|
pla
|
|
sta <rqst_cnt
|
|
pla
|
|
sta <buff_ptr+2
|
|
pla
|
|
sta <buff_ptr
|
|
;
|
|
; Restore the Acc result.
|
|
;
|
|
@clean_exit jsr set_disk_sw
|
|
lda @error
|
|
and #$7FFF
|
|
cmp #$7E00
|
|
bge @io_error
|
|
cmp #$0001
|
|
rts
|
|
;
|
|
; Some kind of I/O Error.
|
|
;
|
|
@io_error lda #drvr_io
|
|
rts
|
|
;
|
|
; Data for this call
|
|
;
|
|
@error dc.w null
|
|
;
|
|
; MODE SELECT Command Packet
|
|
;
|
|
@mode_select dc.b $15 ;Command Number
|
|
dc.b $00 ;Vendor Unique
|
|
dc.b $00 ;Reserved
|
|
dc.b $00 ;Reserved
|
|
dc.b $00 ;Resolved by Main Driver
|
|
dcb.b 6,$00 ;Reserved
|
|
;
|
|
; MODE SELECT Data
|
|
;
|
|
@mode_data dc.b $00 ;Command Number
|
|
dc.b $00 ;Reserved
|
|
dc.b $00 ;Reserved
|
|
dc.b $08 ;Length of extension
|
|
dc.b $00 ;Block Count (MSB)
|
|
dc.b $00 ;Block Count
|
|
dc.b $00 ;Block Count
|
|
dc.b $00 ;Block Count (LSB)
|
|
@blk_size dc.b $00 ;Block Size (MSB)
|
|
dc.b $00 ;Block Size
|
|
dc.b $02 ;Block Size
|
|
dc.b $00 ;Block Size (LSB)
|
|
;
|
|
; FORMAT Command Packet
|
|
;
|
|
@format_p dc.b $04 ;Command Number
|
|
dc.b $00 ;Vendor Unique
|
|
dc.b $00 ;Reserved
|
|
dc.b $00 ;SCSI Interleave (MSB)
|
|
@interleave dc.b interleave ;SCSI Interleave (LSB)
|
|
dcb.b 6,$00 ;Reserved
|
|
|
|
ENDIF
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
;
|
|
; Bad Parm Error
|
|
;
|
|
@bad_parm lda #drvr_bad_parm
|
|
sec
|
|
rts
|
|
|
|
ENDP
|
|
|
|
EJECT
|
|
|
|
;*******************************************************
|
|
;
|
|
; The EJECT command is used to cause the target to
|
|
; eject the currently mounted device. This could be a
|
|
; CD Device, Tape Drive or Removable hard disk. The
|
|
; first thing that we will check is to see if the
|
|
; removable bit is set. It not then a DRVR_BAD_CODE
|
|
; error will be returned. Otherwise the call will be
|
|
; sent to the device. Any error, if any at all, will
|
|
; be returned to the caller of this routine.
|
|
;
|
|
; 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 eject
|
|
eject PROC
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF block_dvc = true\
|
|
AND character_dvc = false THEN
|
|
;
|
|
; Verify request count. Should be
|
|
; zero
|
|
;
|
|
clc
|
|
lda <rqst_cnt
|
|
bne @bad_parm
|
|
;
|
|
; Check to see if it's removable. If it
|
|
; is then we will only mark it as offline,
|
|
; no EJECT will be attempted.
|
|
;
|
|
ldy #dib.dvcchar
|
|
lda [dib_ptr],y
|
|
and #removable
|
|
clc
|
|
beq @mark_offline ;Carry Clear says do Switch
|
|
;
|
|
; Is this device linked to other
|
|
; active devices?
|
|
;
|
|
jsr chk_lnk_offline
|
|
bcs @mark_offline ;Yes. Skip Eject and DISK SWITCH Calls
|
|
;
|
|
; Issue the eject call to the device.
|
|
;
|
|
; Set internal command flag
|
|
;
|
|
dec |internal
|
|
;
|
|
; Tell the Main Driver where
|
|
; our command structure resides.
|
|
;
|
|
|
|
;* BD 201811
|
|
;* Eject with the standard #$1B
|
|
;* If it fails, eject with the non-standard $C0
|
|
|
|
lda #@eject
|
|
sta <scsi_mdrvr
|
|
lda #^@eject
|
|
sta <scsi_mdrvr+2
|
|
;
|
|
; Set the Call Type and Issue the
|
|
; EJECT Command.
|
|
;
|
|
lda #scsit_cont
|
|
sta |call_type
|
|
jsr |main_drvr
|
|
; bcs @rts
|
|
|
|
IF scsi_dtype = apple_cd\
|
|
OR scsi_dtype = changer THEN
|
|
|
|
bcc @ejectOK
|
|
|
|
clc
|
|
lda #@ejectC0 ; If we're here, the eject $1B
|
|
sta <scsi_mdrvr ; returned in error
|
|
lda #^@ejectC0 ; so, we try the non-standa
|
|
sta <scsi_mdrvr+2 ; $C0 command
|
|
|
|
lda #scsit_cont
|
|
sta |call_type
|
|
jsr |main_drvr ; and we call the driver again
|
|
;
|
|
ENDIF
|
|
; Issue DISK_SW Call. This is only done
|
|
; when the media is actually EJECTed
|
|
; in response to this call.
|
|
;
|
|
@ejectOK jsr set_disk_sw
|
|
;
|
|
; Mark this DIB as Switched and Hard
|
|
; Offline.
|
|
;
|
|
lda #dvc_hardofl++\
|
|
dvc_switch
|
|
clc ;Do the Switch Call
|
|
bra @mark_offline2
|
|
;
|
|
; Mark this DIB as Switched only.
|
|
;
|
|
@mark_offline lda #dvc_switch
|
|
dec leave_switched
|
|
|
|
@mark_offline2 ldy #dib.dvcflag
|
|
ora [dib_ptr],y
|
|
and #dvc_online--\
|
|
$ffff
|
|
sta [dib_ptr],y
|
|
;
|
|
; Issue DISK_SW Call. This is only done when
|
|
; carry is clear which can only happen when
|
|
; ejecting non-removable media or when the
|
|
; media is actually EJECTed in response to
|
|
; this call.
|
|
;
|
|
bcs @no_switch
|
|
jsr set_disk_sw
|
|
;
|
|
; Clean Exit.
|
|
;
|
|
@no_switch lda #no_error
|
|
clc
|
|
rts
|
|
;
|
|
; Bad request length.
|
|
;
|
|
@bad_parm lda #drvr_bad_parm
|
|
sec
|
|
;
|
|
; Exit.
|
|
;
|
|
@rts rts
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = direct_acc THEN
|
|
|
|
;
|
|
; Command Packet
|
|
;
|
|
@eject dc.b $1B
|
|
dc.b $01 ;IMMED Bit Set
|
|
dcb.b 2,$00 ;Reserved
|
|
dc.b $02 ;Normal Unload. See document.
|
|
dcb.b 7,$00
|
|
|
|
ENDIF ;scsi_dtype = direct_acc
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = apple_cd\
|
|
OR scsi_dtype = changer THEN
|
|
|
|
;
|
|
; Command Packet
|
|
;
|
|
@eject dc.b $1B
|
|
dc.b $00 ;IMMED Bit Set
|
|
dcb.b 2,$00 ;Reserved
|
|
dc.b $02 ;Normal Unload. See document.
|
|
dcb.b 7,$00
|
|
|
|
@ejectC0 dc.b $C0 ; BD 201811 - renamed
|
|
dcb.b 11,$00
|
|
|
|
ENDIF ;scsi_dtype = apple_cd or changer
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = mcd_40 THEN
|
|
|
|
;
|
|
; Command Packet
|
|
;
|
|
@eject dc.b $1B
|
|
dc.b $01 ;IMMED Bit Set
|
|
dcb.b 2,$00 ;Reserved
|
|
dc.b $00 ;Normal Unload. See document.
|
|
dcb.b 7,$00
|
|
|
|
ENDIF ;scsi_dtype = mcd_40
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
ENDIF ;block_dvc = true
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF block_dvc = false\
|
|
AND character_dvc = true THEN
|
|
;
|
|
; If the device is a Character Device,
|
|
; then there is nothing to eject.
|
|
;
|
|
stz <trans_cnt
|
|
stz <trans_cnt+2
|
|
lda #null
|
|
clc
|
|
rts
|
|
|
|
ENDIF ;character_dvc = true
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
ENDP
|
|
|
|
EJECT
|
|
|
|
;*******************************************************
|
|
;
|
|
; This call set the configuration parms for the
|
|
; specified device. The parameters are device
|
|
; specific. The list is preceded by a word length
|
|
; which must be equal to the transmit count. If not
|
|
; then a DRVR_BAD_PARM error is 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
|
|
;
|
|
; Errors: See Spec.
|
|
;
|
|
;*******************************************************
|
|
|
|
EXPORT s_config_parms
|
|
s_config_parms PROC
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF block_dvc = true\
|
|
AND character_dvc = false THEN
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = apple_cd\
|
|
OR scsi_dtype = changer THEN
|
|
;
|
|
; Exit Write Protect Error.
|
|
;
|
|
lda #drvr_wrt_prot
|
|
sec
|
|
rts
|
|
|
|
ENDIF ;scsi_dtype = apple_cd or changer
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = mcd_40 THEN
|
|
;
|
|
; Exit Bad Call Error.
|
|
;
|
|
lda #drvr_bad_code
|
|
sec
|
|
rts
|
|
|
|
ENDIF ;scsi_dtype = mcd_40
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = direct_acc THEN
|
|
|
|
; INCLUDE 'SCSI Set Config'
|
|
|
|
lda #null
|
|
sta <trans_cnt
|
|
sta <trans_cnt+2
|
|
clc
|
|
rts
|
|
|
|
ENDIF ;scsi_dtype = direct_acc
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
ELSE ;block_dvc = False
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
;
|
|
; Lie for now. Say that we did even
|
|
; though we didn't.
|
|
;
|
|
clc
|
|
lda <rqst_cnt ;*************************
|
|
beq @rts ;*************************
|
|
;
|
|
; Bad request length.
|
|
;
|
|
lda #drvr_bad_parm
|
|
sec
|
|
;
|
|
; Exit.
|
|
;
|
|
@rts rts
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
ENDIF ;block_dvc = true
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = direct_acc THEN
|
|
|
|
INCLUDE 'SCSI Set Vol/Disk'
|
|
|
|
ENDIF ;scsi_dtype = direct_acc
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
|
|
ENDP
|
|
|
|
EJECT
|
|
|
|
;*******************************************************
|
|
;
|
|
; This call is used to set the Wait or No Wait state
|
|
; for a character device. If in wait mode the device
|
|
; will wait until request count bytes have been read
|
|
; before returning to the caller. Block devices will
|
|
; return no error for this call.
|
|
;
|
|
; Called via 'JSR'
|
|
;
|
|
; Inputs: [dib_ptr] = Target DIB l (LONG)
|
|
; [buff_ptr] = Wait flag
|
|
; $0000 = Wait Mode
|
|
; $8000 = No Wait Mode
|
|
; 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 s_wait_mode
|
|
s_wait_mode PROC
|
|
;
|
|
; Check the parameters list.
|
|
; Should contain a WORD
|
|
;
|
|
lda <rqst_cnt
|
|
cmp #$0002
|
|
bne @bad_parm
|
|
;
|
|
; Is it a block device?
|
|
;
|
|
ldy #dib.dvcchar
|
|
lda [dib_ptr],y
|
|
and #blk_device
|
|
bne @clean_exit
|
|
;
|
|
; It's a character device. Do we
|
|
; set or clear the wait bit?
|
|
;
|
|
@char_dvc lda [buff_ptr]
|
|
beq @set_wait ;Set the Wait Mode
|
|
cmp #$8000
|
|
bne @bad_parm
|
|
;
|
|
; Clear the Wait mode to No Wait.
|
|
;
|
|
ldy #dib.dvcflag
|
|
lda [dib_ptr],y
|
|
and #wait_mode--\ ;Generate a mask for this bit
|
|
$ffff
|
|
;
|
|
; Save it and exit.
|
|
;
|
|
bra @set_state
|
|
;
|
|
; Set Wait Mode
|
|
;
|
|
@set_wait ldy #dib.dvcflag
|
|
lda [dib_ptr],y
|
|
ora #wait_mode
|
|
;
|
|
; Save New Mode
|
|
;
|
|
@set_state sta [dib_ptr],y
|
|
lda #$0002
|
|
sta <trans_cnt
|
|
stz <trans_cnt+2
|
|
;
|
|
; Clean Exit
|
|
;
|
|
@clean_exit lda #null ;Clear the Acc.
|
|
clc
|
|
rts
|
|
;
|
|
; Bad Parm Error
|
|
;
|
|
@bad_parm lda #drvr_bad_parm
|
|
sec
|
|
rts
|
|
|
|
ENDP
|
|
|
|
EJECT
|
|
|
|
;*******************************************************
|
|
;
|
|
; The set format options call is not supported by this
|
|
; driver. No error is returned unless they send a
|
|
; transfer length > 0000.
|
|
;
|
|
; 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 format_opt
|
|
format_opt 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 #bad_dev_number
|
|
sec
|
|
rts
|
|
|
|
ENDIF ;scsi_dtype = mcd_40
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = direct_acc THEN
|
|
;
|
|
; If we are partitioned, then no data.
|
|
;
|
|
ldy #dib.dvcchar
|
|
|
|
lda [dib_ptr],y
|
|
and #linked_dvc
|
|
beq @no_link ;No.
|
|
stz <trans_cnt
|
|
stz <trans_cnt+2
|
|
lda #null
|
|
clc
|
|
rts
|
|
;
|
|
;
|
|
; Check the count
|
|
;
|
|
@no_link lda <rqst_cnt
|
|
beq @bad_parm
|
|
cmp #$0002
|
|
bne @bad_parm
|
|
sta <trans_cnt
|
|
stz <trans_cnt+2
|
|
;
|
|
; Set default Option.
|
|
;
|
|
lda [buff_ptr]
|
|
sta current_fmt
|
|
;
|
|
; Exit.
|
|
;
|
|
lda #null
|
|
clc
|
|
rts
|
|
;
|
|
; Bad request length.
|
|
;
|
|
@bad_parm lda #drvr_bad_parm
|
|
sec
|
|
rts
|
|
|
|
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.
|
|
;
|
|
lda #drvr_bad_code
|
|
sec
|
|
rts
|
|
|
|
ENDIF ;character_dvc = true
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
ENDP
|
|
|
|
EJECT
|
|
|
|
;*******************************************************
|
|
;
|
|
; Main Entry point to the 'Control' filter. This
|
|
; "Filter" is called when a Control Command comes in.
|
|
; See the headers of the seperate sections for the
|
|
; details of the commands.
|
|
;
|
|
; 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 assign_part
|
|
assign_part PROC
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF block_dvc = true\
|
|
AND character_dvc = false THEN
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = apple_cd\
|
|
OR scsi_dtype = changer THEN
|
|
;
|
|
; Exit Write Protect Error.
|
|
;
|
|
lda #drvr_wrt_prot
|
|
sec
|
|
rts
|
|
|
|
ENDIF ;scsi_dtype = apple_cd or changer
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = mcd_40 THEN
|
|
;
|
|
; Exit Bad Call Error.
|
|
;
|
|
lda #drvr_bad_code
|
|
sec
|
|
rts
|
|
|
|
ENDIF ;scsi_dtype = mcd_40
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = direct_acc THEN
|
|
|
|
;
|
|
; 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
|
|
bne @over
|
|
;
|
|
; Not from a partition.
|
|
;
|
|
lda #bad_dev_number
|
|
sec
|
|
rts
|
|
;
|
|
; Get block that contains this
|
|
; DIB's Partition Map Entry.
|
|
;
|
|
@over ldy #dib.part_blk
|
|
lda [dib_ptr],y
|
|
sta |rpm_blk_num
|
|
sta |wpm_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
|
|
;
|
|
; Restore Direct Page Values.
|
|
;
|
|
pha
|
|
php
|
|
jsr set_our_dp
|
|
plp
|
|
pla
|
|
bcs @bad_exit ;There was an error.
|
|
;
|
|
; Is what we read a Partition Map?
|
|
;
|
|
lda |pm.Sig\
|
|
+internal_buff
|
|
cmp #Part_sig
|
|
bne @bad_exit ;Bad Data Read.
|
|
;
|
|
; Set a pointer to actual text.
|
|
;
|
|
clc
|
|
lda <buff_ptr
|
|
adc #$0002
|
|
sta <scsi_zp4
|
|
lda <buff_ptr+2
|
|
adc #null
|
|
sta <scsi_zp4+2
|
|
;
|
|
; Get length of data
|
|
;
|
|
lda [buff_ptr]
|
|
cmp #$0020+1
|
|
bge @bad_exit
|
|
tay
|
|
tax
|
|
dey ;16 bit mode
|
|
dex
|
|
;
|
|
; Are they the same? If so we can
|
|
; save a block write.
|
|
;
|
|
@cmp_loop lda |pm.PartType\
|
|
+internal_buff,y
|
|
cmp [scsi_zp4],y
|
|
bne @move_new
|
|
dey
|
|
bpl @cmp_loop
|
|
bra @all_done
|
|
;
|
|
; Not the same. Replace old with
|
|
; the new.
|
|
;
|
|
@move_new txa
|
|
tay
|
|
@move_loop lda [scsi_zp4],y
|
|
sta |pm.PartType\
|
|
+internal_buff,y
|
|
dey
|
|
bpl @move_loop
|
|
;
|
|
; Issue the Write PM Block Call.
|
|
;
|
|
jsr |write_pm_blk
|
|
;
|
|
; Restore Direct Page Values.
|
|
;
|
|
pha
|
|
php
|
|
jsr set_our_dp
|
|
plp
|
|
pla
|
|
bcc @all_done ;There was no error.
|
|
;
|
|
; Error exit point.
|
|
;
|
|
@bad_exit lda #drvr_io
|
|
sec
|
|
rts
|
|
;
|
|
; Clean Exit
|
|
;
|
|
@all_done lda #no_error
|
|
clc
|
|
rts
|
|
|
|
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
|
|
; assign.
|
|
;
|
|
stz <trans_cnt
|
|
stz <trans_cnt+2
|
|
lda #null
|
|
clc
|
|
rts
|
|
|
|
ENDIF ;character_dvc = true
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
ENDP
|
|
|
|
EJECT
|
|
|
|
;*******************************************************
|
|
;
|
|
; Entry point for the Arm Signal Drivcer Call. This
|
|
; call is not supported by this driver. An error is
|
|
; returned in all cases.
|
|
;
|
|
; 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 arm_signal
|
|
arm_signal PROC
|
|
|
|
lda #drvr_bad_code
|
|
sec
|
|
rts
|
|
|
|
ENDP
|
|
|
|
EJECT
|
|
|
|
;*******************************************************
|
|
;
|
|
; Entry point for the Disarm Signal Drivcer Call.
|
|
; This call is not supported by this driver. An error
|
|
; is returned in all cases.
|
|
;
|
|
; 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 disarm_sig
|
|
disarm_sig PROC
|
|
|
|
lda #drvr_bad_code
|
|
sec
|
|
rts
|
|
|
|
ENDP
|
|
|
|
EJECT
|
|
|
|
;*******************************************************
|
|
;
|
|
; Most be the first device in a link!!!!
|
|
;
|
|
; Entry point to the 'Set PMap' call. This call
|
|
; takes the information given by the caller on direct
|
|
; page and builds the equivilent to a Write Status
|
|
; Call to write 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 set_p_map
|
|
set_p_map PROC
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF block_dvc = true\
|
|
AND character_dvc = false THEN
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
IF scsi_dtype = apple_cd\
|
|
OR scsi_dtype = changer THEN
|
|
;
|
|
; Exit Write Protect Error.
|
|
;
|
|
lda #drvr_wrt_prot
|
|
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
|
|
|
|
@bad_dev_num lda #bad_dev_number
|
|
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 (Write Data)
|
|
; Control Command $800A
|
|
lda #$0001 ; Sent to me Low >> High.
|
|
xba ; Send it out High >> Low.
|
|
sta |c_block_num
|
|
;
|
|
; Set Main Driver Pointer to
|
|
; our data for the command.
|
|
;
|
|
lda #cmd_$800A
|
|
sta <scsi_mdrvr
|
|
lda #^cmd_$800A
|
|
sta <scsi_mdrvr+2
|
|
;
|
|
; Set the Partition call flag
|
|
;
|
|
dec |f_partition
|
|
;
|
|
; Call Main Driver
|
|
;
|
|
lda #scsit_cont
|
|
sta |call_type
|
|
;
|
|
; Issue the call.
|
|
;
|
|
jsr check_532_rw
|
|
bcs @rts
|
|
;
|
|
; Build the (Write Data) command
|
|
; to write the Driver Descriptor
|
|
; Map.
|
|
;
|
|
@do_ddm lda #$5245 ;Defined by MAC as $4552
|
|
sta |sense_data
|
|
|
|
lda #block_size
|
|
sta <rqst_cnt
|
|
stz <rqst_cnt+2
|
|
xba
|
|
sta |sense_data+2 ;Defined by MAC as $0200
|
|
|
|
ldx #$0040
|
|
@loop stz |sense_data+4,x
|
|
dex
|
|
dex
|
|
bpl @loop
|
|
|
|
stz |c_block_num
|
|
;
|
|
; Set our buffer pointer
|
|
;
|
|
lda #sense_data
|
|
sta <buff_ptr
|
|
lda #^sense_data
|
|
sta <buff_ptr+2
|
|
;
|
|
; Set Main Driver Pointer to
|
|
; our data for the command.
|
|
;
|
|
lda #cmd_$800A
|
|
sta <scsi_mdrvr
|
|
lda #^cmd_$800A
|
|
sta <scsi_mdrvr+2
|
|
;
|
|
; Set the Partition call flag
|
|
;
|
|
dec |f_partition
|
|
;
|
|
; Call Main Driver
|
|
;
|
|
lda #scsit_cont
|
|
sta |call_type
|
|
;
|
|
; Issue the call.
|
|
;
|
|
jsr check_532_rw
|
|
bcs @rts
|
|
;
|
|
; Rebuild the DIBs.
|
|
; Trashing the Volumes.
|
|
;
|
|
dec |trash_it
|
|
;
|
|
jsr rebld_dibs ;Issues a DISK_SW for each rebuilt DIB.
|
|
;
|
|
; Reset The 'TRASH IT' Flag..
|
|
;
|
|
stz |trash_it
|
|
;
|
|
; Restore the origonal Direct Page values.
|
|
;
|
|
jsr set_our_dp
|
|
;
|
|
; 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 rts
|
|
;
|
|
; Variables and storage for short call.
|
|
;
|
|
@do_532 dc.w null ;532 byte block flag
|
|
;
|
|
; Command Data for this call.
|
|
;
|
|
cmd_$800A dc.b $0A
|
|
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
|
|
; write.
|
|
;
|
|
stz <trans_cnt
|
|
stz <trans_cnt+2
|
|
lda #null
|
|
clc
|
|
rts
|
|
|
|
ENDIF ;character_dvc = true
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
ENDP
|
|
|
|
EJECT
|
|
|
|
END
|