mirror of
https://github.com/antoinevignau/source.git
synced 2025-01-06 01:31:57 +00:00
d29484938c
What we wrote to make audio hearable on a SCSI-2 CD-ROM drive ;-)
1 line
24 KiB
Plaintext
1 line
24 KiB
Plaintext
|
|
;*******************************************************
|
|
;
|
|
; SCSI Driver Set Configuration Parms code.
|
|
;
|
|
; Written by Matt Gulick. Started June 22,1990
|
|
;
|
|
; Copyright Apple Computer, Inc. 1990
|
|
;
|
|
;*******************************************************
|
|
|
|
;*******************************************************
|
|
;
|
|
; This file contains the Set Configuration Parms as
|
|
; defined in the ERS.
|
|
;
|
|
;*******************************************************
|
|
|
|
;*******************************************************
|
|
;
|
|
; Revision History:
|
|
;
|
|
;*******************************************************
|
|
|
|
; June 22, 1988 File started.
|
|
|
|
EJECT
|
|
IMPORT ddm_data
|
|
|
|
;*******************************************************
|
|
;
|
|
; 's_config_parms'
|
|
;
|
|
; This routine is used to set information about the
|
|
; volume or disk in question. If this call is issued
|
|
; to set 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.
|
|
;
|
|
;*******************************************************
|
|
|
|
scp
|
|
;
|
|
; 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. Send 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_hardofl
|
|
bne @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 sta |bitmap
|
|
and #vconf_resv2++\
|
|
vconf_resv3++\ ;Check Bits that are not supported
|
|
vconf_resv4++\ ;at this time.
|
|
vconf_resv5++\
|
|
vconf_resv6
|
|
bne @exit_parm ;If unsupported bit set then error out.
|
|
;
|
|
; Check for Remount Bit
|
|
;
|
|
lda |bitmap
|
|
and #vconf_remount
|
|
beq @next_0
|
|
jsr remount_vol
|
|
;
|
|
; Check Status Bits Flag. If set, then we
|
|
; use the low byte of this word to set the
|
|
; status bits in the Partition Map and in
|
|
; the DIB Status.
|
|
;
|
|
@next_0 lda |bitmap
|
|
and #vconf_set_stat
|
|
beq @next_1
|
|
jsr set_stat_bits
|
|
|
|
@next_1 bcs @rts
|
|
lda #$0004
|
|
sta <trans_cnt
|
|
lda #null
|
|
sta <trans_cnt+2
|
|
clc
|
|
@rts rts
|
|
;
|
|
; Routines used by the above code to
|
|
; perform the requested task.
|
|
;
|
|
remount_vol
|
|
;
|
|
; Mark this DIB as Switched and Hard
|
|
; Offline.
|
|
;
|
|
ldy #dib.dvcflag
|
|
lda [dib_ptr],y
|
|
ora #dvc_online++\
|
|
dvc_switch
|
|
and #dvc_hardofl--\
|
|
$ffff
|
|
sta [dib_ptr],y
|
|
;
|
|
; Generate a Disk Switched Event
|
|
;
|
|
jsr set_disk_sw
|
|
;
|
|
; Clean Exit.
|
|
;
|
|
rts
|
|
|
|
set_stat_bits
|
|
;
|
|
; Set the Status Bits in the Partition
|
|
; Map entry to mach those supplied by
|
|
; this call.
|
|
;
|
|
; 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
|
|
bne @over
|
|
;
|
|
; Not from a partition.
|
|
;
|
|
lda #drvr_bad_parm
|
|
sec
|
|
rts
|
|
;
|
|
; Not from a partition.
|
|
;
|
|
@not_online lda #drvr_off_line
|
|
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
|
|
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 the Status Byte
|
|
;
|
|
lda |bitmap
|
|
and #$00ff
|
|
sta @temp
|
|
lda |pm.PartStatus+2\
|
|
+internal_buff
|
|
xba
|
|
and #$ff00
|
|
ora @temp
|
|
xba
|
|
sta |pm.PartStatus+2\
|
|
+internal_buff
|
|
;
|
|
; Issue the Write PM Block Call.
|
|
;
|
|
jsr |write_pm_blk
|
|
bcc @all_done ;There was no error.
|
|
;
|
|
; Error exit point.
|
|
;
|
|
@bad_exit jsr set_our_dp
|
|
lda #drvr_io
|
|
sec
|
|
rts
|
|
;
|
|
; Clean Exit
|
|
;
|
|
@all_done jsr set_our_dp
|
|
|
|
lda @temp ;Update the DIB.
|
|
and #vconf_wr_enable++\
|
|
vconf_rd_enable
|
|
asl a
|
|
sta @temp
|
|
ldy #dib.dvcchar
|
|
lda [dib_ptr],y
|
|
and #write_allow++\
|
|
read_allow--\
|
|
$ffff
|
|
ora @temp
|
|
sta [dib_ptr],y
|
|
;
|
|
; Generate a Disk Switched Event
|
|
;
|
|
jsr set_disk_sw
|
|
|
|
lda #no_error
|
|
clc
|
|
rts
|
|
;
|
|
; Data Area.
|
|
;
|
|
@temp dc.w null
|
|
|
|
;
|
|
; Set Config Disk Calls are handled
|
|
; here.
|
|
;
|
|
; Init Transfer Count to Null. Then
|
|
; check to be sure that this is a Set
|
|
; Config ParmList and not a Get 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
|
|
beq @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.
|
|
;%01xxx00000000000
|
|
asl temp ;%1xxx000000000000
|
|
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 set_ddm
|
|
bcs @disk_done
|
|
;
|
|
; Check Set Volume Info Bit
|
|
;
|
|
@chk_vol jsr |chk_count
|
|
bcs @disk_done
|
|
asl temp
|
|
bcc @chk_drvr
|
|
jsr set_vol
|
|
bcs @disk_done
|
|
;
|
|
; Check Set Driver Bit
|
|
;
|
|
@chk_drvr jsr |chk_count
|
|
bcs @disk_done
|
|
asl temp
|
|
bcc @disk_done
|
|
jsr set_drvr
|
|
;
|
|
; All done. Return the transfer
|
|
; length and any error codes that
|
|
; were encountered
|
|
;
|
|
@disk_done pha
|
|
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
|
|
|
|
pla
|
|
cmp #$0001
|
|
rts
|
|
;
|
|
; Subroutines for this code.
|
|
;
|
|
; Check to see if the count contains
|
|
; another entry.
|
|
;
|
|
EXPORT chk_count
|
|
chk_count sec
|
|
lda |count
|
|
sbc #config_pl.vol_info\
|
|
-config_pl.ddm_info
|
|
sta |count
|
|
clc
|
|
bpl @chk_done
|
|
sec
|
|
@chk_done rts
|
|
;
|
|
; The first Routine is used to Write
|
|
; the DDM from the callers buffer.
|
|
;
|
|
set_ddm
|
|
;
|
|
; Tell the Main Driver where
|
|
; our command structure resides.
|
|
;
|
|
lda #@write_ddm
|
|
sta <scsi_mdrvr
|
|
lda #^@write_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
|
|
;
|
|
; Is what we are writing a Driver
|
|
; Descriptor Map?
|
|
;
|
|
lda [ddm_buff]
|
|
cmp #DDM_sig
|
|
bne @bad_exit1 ;Bad Data.
|
|
;
|
|
; 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 #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_cont
|
|
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 #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 WRITE BLOCK Command
|
|
;
|
|
@write_ddm dc.b $0A
|
|
dc.b null
|
|
dc.w null
|
|
dcb.b 10,null
|
|
;
|
|
; Other Data Storage areas.
|
|
;
|
|
EXPORT bitmap
|
|
bitmap dc.w null
|
|
EXPORT length
|
|
length dc.l null ;Total length of all data sent
|
|
EXPORT rqst
|
|
rqst dc.l null ;Total length of all data requested
|
|
EXPORT gc_buff_ptr
|
|
gc_buff_ptr dc.l null ;Their buffer pointer
|
|
EXPORT count
|
|
count dc.w null ;Parmlist count. Will be adjusted as we go.
|
|
EXPORT temp
|
|
temp dc.w null
|
|
EXPORT error
|
|
error dc.w null
|
|
EXPORT ddm_index
|
|
ddm_index dc.w null ;Index Into the DDM for the rqsted DRVR
|
|
;
|
|
; This Routine is used to set the
|
|
; Volume Info from the callers buffer.
|
|
;
|
|
set_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
|
|
|
|
lda #$0001 ;Start looking here.
|
|
ldx #internal_buff
|
|
ldy #^internal_buff
|
|
jsr find_drvr_part
|
|
bcs @rts
|
|
;
|
|
; Set the Partition Map Block Number
|
|
; that we need to Write.
|
|
;
|
|
sta @write_vol_num
|
|
;
|
|
; Tell the Main Driver where
|
|
; our command structure resides.
|
|
;
|
|
lda #@write_vol
|
|
sta <scsi_mdrvr
|
|
lda #^@write_vol
|
|
sta <scsi_mdrvr+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
|
|
stx <buff_ptr
|
|
stx <config_buff
|
|
;
|
|
; Is what we are writing a Driver
|
|
; Descriptor Map?
|
|
;
|
|
lda [config_buff]
|
|
cmp #Part_sig
|
|
bne @bad_exit1 ;Bad Data Read.
|
|
;
|
|
; 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 rts
|
|
|
|
@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_cont
|
|
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 #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 WRITE BLOCK Command
|
|
;
|
|
@write_vol dc.b $0A
|
|
dc.b null
|
|
@write_vol_num dc.w null
|
|
dcb.b 10,null
|
|
;
|
|
; This Routine is used to set the
|
|
; Driver Data into the callers buffer.
|
|
;
|
|
set_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 #$000A ;OR in the command number
|
|
sta @write_drvr
|
|
|
|
iny
|
|
iny
|
|
lda [ddm_buff],y
|
|
sta @block_num
|
|
;
|
|
; 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.
|
|
;
|
|
sec
|
|
stz <rqst_cnt+2
|
|
lda [config_tcnt]
|
|
sbc #$0004
|
|
sta <rqst_cnt
|
|
;
|
|
; Tell the Main Driver where
|
|
; our command structure resides.
|
|
;
|
|
lda #@write_drvr
|
|
sta <scsi_mdrvr
|
|
lda #^@write_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
|
|
; WRITE BLOCK Command.
|
|
;
|
|
lda #scsit_cont
|
|
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 I/O Commands.
|
|
;
|
|
@temp dc.w null
|
|
;
|
|
; Command to Write the Driver Data
|
|
;
|
|
@write_drvr dc.b $0A
|
|
dc.b null
|
|
@block_num dc.w null
|
|
dcb.b 10,null
|
|
;
|
|
; Because all three sub-calls require a
|
|
; DDM for information we must make sure
|
|
; that this is available. If they are
|
|
; not setting the DDM we will load ity
|
|
; from the disk. If they are we will
|
|
; use theirs as it is the most current.
|
|
;
|
|
; Check low byte of the Bitmap for which
|
|
; Driver they want and use it to set the
|
|
; ddm_index.
|
|
;
|
|
EXPORT pre_load_ddm
|
|
pre_load_ddm
|
|
ldy #config_pl.bitmap
|
|
lda [buff_ptr],y
|
|
and #$200F ;Max of 15 Drivers in the DDM
|
|
dec a ;Dec so we can use for index
|
|
asl a ;*2
|
|
asl a ;*4
|
|
asl a ;*8
|
|
php
|
|
clc
|
|
adc #$0012 ;Account for the $12 bytes of header
|
|
sta ddm_index
|
|
;
|
|
; If Carry is set, then the DDM is in
|
|
; users memory and we do not need to
|
|
; read it from the disk.
|
|
;
|
|
plp
|
|
bcs @ddm_loaded
|
|
;
|
|
; We need to load the DDM into the
|
|
; internal buffer.
|
|
;
|
|
; Tell the Main Driver where
|
|
; our command structure resides.
|
|
;
|
|
lda #@read_ddm
|
|
sta <scsi_mdrvr
|
|
lda #^@read_ddm
|
|
sta <scsi_mdrvr+2
|
|
;
|
|
; Set our buffer
|
|
;
|
|
lda #ddm_data
|
|
sta <buff_ptr
|
|
sta <ddm_buff
|
|
lda #^ddm_data
|
|
sta <buff_ptr+2
|
|
sta <ddm_buff+2
|
|
;
|
|
; And our Block Size value
|
|
;
|
|
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
|
|
|
|
@ddm_loaded clc
|
|
rts
|
|
;
|
|
; Use this code to exit when no data is
|
|
; being sent.
|
|
;
|
|
@exit_parm lda #drvr_bad_parm
|
|
sec
|
|
rts
|
|
;
|
|
; Error exit point.
|
|
;
|
|
@bad_exit1 jsr set_our_dp
|
|
lda #drvr_io
|
|
sec
|
|
rts
|
|
;
|
|
; Command to Read the DDM if we
|
|
; need it.
|
|
;
|
|
@read_ddm dc.b $08
|
|
dc.b null
|
|
dc.w null
|
|
dcb.b 10,null
|
|
;
|
|
; This routine will search for the
|
|
; Partition Map entry that has the same
|
|
; data block location as that for the
|
|
; referenced entry in the DDM.
|
|
;
|
|
; Acc = Block to start with
|
|
; Y reg = High word of the Buffer to use
|
|
; X reg = Low word of the Buffer to use
|
|
;
|
|
EXPORT find_drvr_part
|
|
find_drvr_part
|
|
xba
|
|
sta @block_num
|
|
stx <buff_ptr
|
|
sty <buff_ptr+2
|
|
|
|
;
|
|
; And our length.
|
|
;
|
|
stz <rqst_cnt+2
|
|
lda #block_size
|
|
sta <rqst_cnt
|
|
;
|
|
; Tell the Main Driver where
|
|
; our command structure resides.
|
|
;
|
|
lda #@read_part
|
|
sta <scsi_mdrvr
|
|
lda #^@read_part
|
|
sta <scsi_mdrvr+2
|
|
;
|
|
; Set internal command flag
|
|
;
|
|
@loop 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
|
|
;
|
|
; Is this the block that we want?
|
|
;
|
|
ldy #pm.PyPartStart
|
|
lda [buff_ptr],y
|
|
cmp |pdata_block
|
|
bne @next
|
|
ldy #pm.PyPartStart+2
|
|
lda [buff_ptr],y
|
|
cmp |pdata_block+2
|
|
bne @next
|
|
;
|
|
; Replace the Buffer Pointer.
|
|
;
|
|
lda gc_buff_ptr
|
|
sta <buff_ptr
|
|
|
|
lda gc_buff_ptr+2
|
|
sta <buff_ptr+2
|
|
;
|
|
; It's a match. Pass it on in the Acc.
|
|
;
|
|
lda @block_num
|
|
;
|
|
; Check for Call Errors
|
|
;
|
|
plp
|
|
clc
|
|
rts
|
|
;
|
|
; Not a match. Do the next one only if
|
|
; still in the range of the partition map.
|
|
;
|
|
@next plp
|
|
lda @block_num
|
|
xba
|
|
inc a
|
|
xba
|
|
sta @block_num
|
|
ldy #pm.MapBlkCnt+2
|
|
cmp [buff_ptr],y
|
|
bne @loop
|
|
;
|
|
; Not found. Do Cleanup and exit
|
|
; with an error.
|
|
;
|
|
; Replace the Buffer Pointer.
|
|
;
|
|
lda gc_buff_ptr
|
|
sta <buff_ptr
|
|
|
|
lda gc_buff_ptr+2
|
|
sta <buff_ptr+2
|
|
|
|
sec
|
|
lda #drvr_bad_blk
|
|
rts
|
|
;
|
|
; Command to Read the DDM if we
|
|
; need it.
|
|
;
|
|
@read_part dc.b $08
|
|
dc.b null
|
|
@block_num dc.w null
|
|
dcb.b 10,null
|
|
|
|
EXPORT pdata_block
|
|
pdata_block dc.l null
|
|
|
|
EJECT
|