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
23 KiB
Plaintext
1 line
23 KiB
Plaintext
|
||
;*******************************************************
|
||
;
|
||
; SCSI Driver 'Read' filter.
|
||
;
|
||
; Written by Matt Gulick. Started June 13,1988
|
||
;
|
||
; Copyright Apple Computer, Inc. 1988,89
|
||
;
|
||
;*******************************************************
|
||
|
||
;*******************************************************
|
||
;
|
||
; This file contains the 'Read' filter as defined in
|
||
; the ERS.
|
||
;
|
||
;*******************************************************
|
||
|
||
;*******************************************************
|
||
;
|
||
; Revision History:
|
||
;
|
||
;*******************************************************
|
||
|
||
; June 13, 1988 File started.
|
||
; June 20, 1988 Registers in and out are
|
||
|
||
STRING PASCAL
|
||
BLANKS OFF
|
||
PAGESIZE 70
|
||
PRINT NOGEN
|
||
PRINT NOMDIR
|
||
MACHINE M65816
|
||
|
||
IMPORT unit_state
|
||
IMPORT main_drvr
|
||
IMPORT call_type
|
||
IMPORT r_get_cache
|
||
IMPORT r_all_in_cache
|
||
IMPORT divend
|
||
IMPORT divsor
|
||
IMPORT result
|
||
IMPORT max_blk_cnt
|
||
IMPORT m_blk_size
|
||
IMPORT m_blk_cnt
|
||
IMPORT calc_bytes
|
||
IMPORT m_rslt
|
||
IMPORT gsos_dpage
|
||
IMPORT divide
|
||
IMPORT check_532_rw
|
||
IMPORT chk_play_mode
|
||
IMPORT auto_sense_data
|
||
IMPORT sense_data
|
||
IMPORT open_flag
|
||
IMPORT get_data_status
|
||
IMPORT internal_buff
|
||
IMPORT scratch0
|
||
IMPORT internal
|
||
|
||
PRINT OFF
|
||
|
||
INCLUDE 'scsihd.equates'
|
||
INCLUDE 'M16.MEMORY'
|
||
INCLUDE 'M16.UTIL'
|
||
PRINT ON
|
||
|
||
EJECT
|
||
|
||
IF block_dvc = true\
|
||
AND character_dvc = false THEN
|
||
|
||
;*******************************************************
|
||
;
|
||
; Main Entry point to the 'Read' filter. This
|
||
; "Filter" takes the information given by the caller
|
||
; on direct page and builds the equivilent to a Read
|
||
; Extended Status Call. In order of appearence:
|
||
;
|
||
; Verify that Device # $0000
|
||
; Call Number = $0002
|
||
; 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 + Offset
|
||
; This is for partitions.
|
||
;
|
||
; After calling the Main driver and if no errors were
|
||
; encountered, then the Transfer count will be
|
||
; updated.
|
||
;
|
||
; Inputs: None.
|
||
;
|
||
; Outputs: Acc = 0
|
||
; Carry = 0
|
||
; Y register = Unspecified
|
||
; X register = Unspecified
|
||
; P register = 0=M=X=e
|
||
; Direct Page = Ours
|
||
; Data Bank = Ours
|
||
;
|
||
; Errors: See Spec.
|
||
;
|
||
;*******************************************************
|
||
|
||
ENDIF
|
||
|
||
IF character_dvc = true\
|
||
AND block_dvc = false THEN
|
||
|
||
;*******************************************************
|
||
;
|
||
; Main Entry point to the 'Read' filter. This
|
||
; "Filter" takes the information given by the caller
|
||
; on direct page and builds the equivilent to a Read
|
||
; Extended Status Call. In order of appearence:
|
||
;
|
||
; Verify that Device # $0000
|
||
; Call Number = $0002
|
||
; Block Size = $0000
|
||
; Device Opened = True
|
||
;
|
||
; We now Build the SCSI Main Driver Command and send
|
||
; it.
|
||
;
|
||
; After calling the Main driver and if no errors were
|
||
; encountered, then the Transfer count will be
|
||
; updated.
|
||
;
|
||
; Inputs: None.
|
||
;
|
||
; Outputs: Acc = 0
|
||
; Carry = 0
|
||
; Y register = Unspecified
|
||
; X register = Unspecified
|
||
; P register = 0=M=X=e
|
||
; Direct Page = Ours
|
||
; Data Bank = Ours
|
||
;
|
||
; Errors: See Spec.
|
||
;
|
||
;*******************************************************
|
||
|
||
ENDIF
|
||
|
||
EXPORT Read
|
||
Read PROC
|
||
|
||
;-------------------------------------------------------------------------------
|
||
|
||
IF block_dvc = true\
|
||
AND character_dvc = false THEN
|
||
|
||
stz @cache
|
||
;
|
||
; 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
|
||
bcs @rts_out
|
||
;
|
||
; Is the device online?
|
||
;
|
||
@online ldy #dib.dvcflag
|
||
|
||
lda [dib_ptr],y
|
||
and #dvc_hardofl
|
||
bne @off_line ;Yes.
|
||
|
||
lda [dib_ptr],y
|
||
and #dvc_online
|
||
bne @read ;Yes.
|
||
;
|
||
; Device is currently offline.
|
||
;
|
||
@off_line lda #drvr_off_line
|
||
sec
|
||
@rts_out rts
|
||
|
||
;
|
||
; Preserve entry values. This will
|
||
; help restore the environment when
|
||
; we exit. To much is going on for
|
||
; speeds sake to rely on these
|
||
; locations.
|
||
;
|
||
@read lda <rqst_cnt
|
||
sta @orig_rqst
|
||
lda <rqst_cnt+2
|
||
sta @orig_rqst+2
|
||
;
|
||
; Preserve Buffer pointer in case we
|
||
; need to bump it.
|
||
;
|
||
lda <buff_ptr
|
||
sta @orig_buff
|
||
lda <buff_ptr+2
|
||
sta @orig_buff+2
|
||
;
|
||
; Preserve starting Block Number in case
|
||
; we need to bump it.
|
||
;
|
||
lda <block_num
|
||
sta @orig_strt_blk
|
||
lda <block_num+2
|
||
sta @orig_strt_blk+2
|
||
|
||
;-------------------------------------------------------------------------------
|
||
|
||
IF scsi_dtype = apple_cd\
|
||
OR scsi_dtype = changer THEN
|
||
;
|
||
; If the device is a CD_ROM device
|
||
; then check to see if it is in audio
|
||
; play mode. If not clear the play
|
||
; flag, otherwise set the audio play
|
||
; flag. This is used to prevent reads
|
||
; while the audio tracks are playing.
|
||
;
|
||
; Is the device in Play Mode?
|
||
;
|
||
jsr chk_play_mode
|
||
|
||
ldy #dib.dvcflag
|
||
bcs @no_play_mode
|
||
|
||
lda #play_mode
|
||
ora [dib_ptr],y
|
||
bra @store_play
|
||
|
||
@no_play_mode lda #play_mode--\
|
||
$ffff
|
||
and [dib_ptr],y
|
||
|
||
@store_play sta [dib_ptr],y
|
||
|
||
bcs @read_2 ;No.
|
||
;
|
||
; Device is Busy in PLAY MODE..
|
||
;
|
||
lda #drvr_busy
|
||
sec
|
||
rts
|
||
|
||
@read_2
|
||
ENDIF
|
||
|
||
;-------------------------------------------------------------------------------
|
||
|
||
;
|
||
; Let's check the request count. If
|
||
; this is $00000000, then exit clean
|
||
; with no data transfered.
|
||
;
|
||
lda <rqst_cnt
|
||
and #$01ff ;Cheap Check for multiple of 512
|
||
bne @bad_rqst_cnt
|
||
lda <rqst_cnt
|
||
ora <rqst_cnt+2
|
||
bne @chk_max
|
||
jmp @out_of_here
|
||
;
|
||
; Block Number is beyond the range for this disk.
|
||
;
|
||
@out_of_range lda #drvr_bad_blk
|
||
sec
|
||
rts
|
||
;
|
||
; Requested Byte Count not a multiple of 512
|
||
;
|
||
@bad_rqst_cnt lda #drvr_bad_cnt
|
||
sec
|
||
rts
|
||
;
|
||
; Check to see if more is being
|
||
; requested then we can give him.
|
||
;
|
||
@chk_max lda <rqst_cnt
|
||
sta |divend
|
||
lda <rqst_cnt+2
|
||
sta |divend+2
|
||
|
||
lda #block_size
|
||
sta |divsor
|
||
|
||
sec
|
||
ldy #dib.blkcnt
|
||
lda [dib_ptr],y
|
||
sbc <block_num
|
||
sta |max_blk_cnt
|
||
tax
|
||
|
||
ldy #dib.blkcnt+2
|
||
lda [dib_ptr],y
|
||
sbc <block_num+2
|
||
sta |max_blk_cnt+2
|
||
|
||
bcc @out_of_range
|
||
ora |max_blk_cnt
|
||
beq @out_of_range
|
||
|
||
jsr divide
|
||
bcc @dont_fix_cnt
|
||
|
||
lda #block_size
|
||
sta |m_blk_size
|
||
|
||
lda |max_blk_cnt
|
||
sta |m_blk_cnt
|
||
|
||
lda |max_blk_cnt+2
|
||
sta |m_blk_cnt+2
|
||
|
||
jsr calc_bytes
|
||
|
||
lda |m_rslt
|
||
sta <rqst_cnt
|
||
sta @orig_rqst
|
||
lda |m_rslt+2
|
||
sta <rqst_cnt+2
|
||
sta @orig_rqst+2
|
||
|
||
@dont_fix_cnt
|
||
|
||
;-------------------------------------------------------------------------------
|
||
|
||
IF scsi_dtype = direct_acc THEN
|
||
|
||
;
|
||
; 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_now rts
|
||
;
|
||
; Check for 532 byte block size
|
||
;
|
||
@chk_532 tax
|
||
|
||
lda <blk_size
|
||
cmp #block_size
|
||
bne @bad_parm
|
||
|
||
cpx #$0214
|
||
beq @no_cache
|
||
bra @bad_parm
|
||
|
||
ELSE
|
||
|
||
;-------------------------------------------------------------------------------
|
||
|
||
;
|
||
; Verify Block Size.
|
||
;
|
||
@cnt_non_zero ldy #dib.blksize
|
||
lda [dib_ptr],y ;Block Size
|
||
cmp <blk_size
|
||
bne @bad_parm
|
||
|
||
ldy #dib.blksize+2
|
||
lda [dib_ptr],y
|
||
beq @blk_size_ok
|
||
|
||
@bad_parm lda #drvr_bad_parm
|
||
sec
|
||
@rts_now rts
|
||
|
||
ENDIF
|
||
|
||
;-------------------------------------------------------------------------------
|
||
|
||
@blk_size_ok
|
||
|
||
;-------------------------------------------------------------------------------
|
||
|
||
IF cache_blks = true THEN
|
||
;
|
||
; Skip Cache if FST Number >$8000
|
||
; Otherwise check to see if they are
|
||
; all in the cache. If not we will
|
||
; need to issue a read call. If they
|
||
; are all there we will skip the read
|
||
; and go to the post processing
|
||
; section.
|
||
;
|
||
bit <fst_num ;Force Device Access?
|
||
bmi @no_cache ;Yes.
|
||
|
||
dec @cache
|
||
|
||
jsr r_all_in_cache ;Are they all there?
|
||
bcc @all_there ;Yes.
|
||
|
||
ENDIF
|
||
|
||
;-------------------------------------------------------------------------------
|
||
|
||
@no_cache
|
||
;
|
||
; Build the (Read Data) Status
|
||
; Command $8028, and just in case
|
||
; it is not accepted, we will also
|
||
; build $8008.
|
||
;
|
||
lda <block_num ; Sent to me Low >> High.
|
||
xba ; I Send it out High >> Low.
|
||
sta |c_block_num_l+2
|
||
sta |c_block_num_s
|
||
lda <block_num+2
|
||
xba
|
||
sta |c_block_num_l
|
||
;
|
||
; Set Main Driver Pointer to
|
||
; our data for the command.
|
||
;
|
||
lda #cmd_$8028
|
||
sta <scsi_mdrvr
|
||
lda #^cmd_$8028
|
||
sta <scsi_mdrvr+2
|
||
;
|
||
; Call Main Driver
|
||
;
|
||
lda #scsit_stat
|
||
sta |call_type
|
||
|
||
;-------------------------------------------------------------------------------
|
||
|
||
IF scsi_dtype = direct_acc THEN
|
||
;
|
||
; Issue the call.
|
||
;
|
||
jsr check_532_rw
|
||
bcc @all_there ;Everything went ok.
|
||
cmp #drvr_bad_code ;Was it a Bad Command?
|
||
beq @munge ;Yes. Do the Munging
|
||
brl @crapped_out2 ;No. Then get out of here.
|
||
|
||
@all_there jmp @completed
|
||
;
|
||
; At this point the extended call was not
|
||
; excepted. We must now issue the normal
|
||
; version of this command. First, we must
|
||
; check to see if the request is within the
|
||
; one byte block count range. If not, we
|
||
; will need to special process this request.
|
||
;
|
||
; Setup Divide routine while preserving the
|
||
; origonal count for later.
|
||
;
|
||
@munge lda @orig_rqst
|
||
sta @rem_rqst
|
||
sta |divend
|
||
lda @orig_rqst+2
|
||
sta @rem_rqst+2
|
||
sta |divend+2
|
||
|
||
lda <blk_size
|
||
sta |divsor
|
||
|
||
jsr divide
|
||
bcs @rts_0
|
||
;
|
||
; Get result in block count. If > $80,
|
||
; then we need to break it into multiple
|
||
; calls. If not, then send it as is.
|
||
;
|
||
lda |result+1
|
||
bne @gr8er_80
|
||
lda |result
|
||
dec a
|
||
cmp #$0080
|
||
blt @issue_call
|
||
;
|
||
; Set the max count for a single byte block
|
||
; count (Block size * $80).
|
||
;
|
||
@gr8er_80 lda <blk_size+1
|
||
and #$00ff
|
||
lsr a
|
||
sta <rqst_cnt+2
|
||
lda <blk_size-1
|
||
and #$ff00
|
||
ror a
|
||
sta <rqst_cnt
|
||
;
|
||
; Set Main Driver Pointer to
|
||
; our data for the command.
|
||
;
|
||
@issue_call lda #cmd_$8008
|
||
sta <scsi_mdrvr
|
||
lda #^cmd_$8008
|
||
sta <scsi_mdrvr+2
|
||
;
|
||
; Call Main Driver
|
||
;
|
||
lda #scsit_stat
|
||
sta |call_type
|
||
;
|
||
; Issue the call.
|
||
;
|
||
jsr check_532_rw
|
||
bcc @did_munge
|
||
sta @error_loc
|
||
lda auto_sense_data+\
|
||
rqst_sens.sense_key
|
||
and #$00ff ;Checking for $03
|
||
cmp #$0003 ;This covers $03
|
||
bne @craped_out
|
||
;
|
||
; Some kind of I/O Error.
|
||
;
|
||
@io_error lda #drvr_io
|
||
sec
|
||
rts
|
||
|
||
@craped_out lda @error_loc
|
||
@crapped_out2 and #$7FFF
|
||
cmp #$7E00
|
||
bge @io_error
|
||
sec
|
||
@rts_0 rts
|
||
|
||
@error_loc dc.w null
|
||
;
|
||
; Check for special processing.
|
||
;
|
||
@did_munge ;
|
||
; Get Transfer Result and bump values
|
||
; for the next call.
|
||
;
|
||
clc
|
||
ldy #dib.trx_rqst
|
||
lda [dib_ptr],y
|
||
sta @trans_cnt
|
||
adc <buff_ptr
|
||
sta <buff_ptr
|
||
ldy #dib.trx_rqst+2
|
||
lda [dib_ptr],y
|
||
sta @trans_cnt+2
|
||
adc <buff_ptr+2
|
||
sta <buff_ptr+2
|
||
;
|
||
; Get remaining bytes to be transfered.
|
||
;
|
||
sec
|
||
lda @rem_rqst
|
||
sbc @trans_cnt
|
||
sta @rem_rqst
|
||
lda @rem_rqst+2
|
||
sbc @trans_cnt+2
|
||
sta @rem_rqst+2
|
||
ora @rem_rqst
|
||
beq @done
|
||
|
||
clc ;Cause = values to result in Negative
|
||
lda @rem_rqst
|
||
sbc <rqst_cnt
|
||
lda @rem_rqst+2
|
||
sbc <rqst_cnt+2
|
||
bpl @over
|
||
|
||
lda @rem_rqst
|
||
sta <rqst_cnt
|
||
lda @rem_rqst+2
|
||
sta <rqst_cnt+2
|
||
|
||
;
|
||
;*****************************************
|
||
;* Bump Block number. Pay close *
|
||
;* attention to what this comment says. *
|
||
;* If you don't and you change the code *
|
||
;* then your on your own. This word is *
|
||
;* in MSB >> LSB order. We need to add *
|
||
;* $100 to it. This is done by a simple *
|
||
;* increment. *
|
||
;*****************************************
|
||
;
|
||
@over lda |c_block_num_s
|
||
clc
|
||
xba
|
||
adc #$0080
|
||
xba
|
||
sta |c_block_num_s
|
||
|
||
brl @issue_call
|
||
;
|
||
; Restore the environment.
|
||
;
|
||
@done lda @orig_rqst
|
||
sta <rqst_cnt
|
||
lda @orig_rqst+2
|
||
sta <rqst_cnt+2
|
||
|
||
lda @orig_buff
|
||
sta <buff_ptr
|
||
lda @orig_buff+2
|
||
sta <buff_ptr+2
|
||
|
||
|
||
ENDIF
|
||
|
||
;-------------------------------------------------------------------------------
|
||
|
||
IF scsi_dtype = apple_cd\
|
||
OR scsi_dtype = changer THEN
|
||
|
||
@redo_CDread jsr |main_drvr
|
||
bcc @all_there
|
||
cmp #$fe11
|
||
beq @redo_CDread
|
||
|
||
lda auto_sense_data+\ ;Is it an audio disk?
|
||
rqst_sens.addnl_sens_code
|
||
and #$00ff ;Checking for $84, $64, or $63
|
||
cmp #$0063 ;This cover $63
|
||
beq @audio_disk
|
||
cmp #$0064 ;This cover $64
|
||
beq @audio_disk
|
||
cmp #$0084 ;This cover $84
|
||
beq @audio_disk
|
||
|
||
lda #drvr_io
|
||
sec
|
||
rts ;There was an error!
|
||
|
||
@audio_disk lda #drvr_no_dev
|
||
sec
|
||
rts
|
||
@all_there
|
||
|
||
ENDIF
|
||
|
||
;-------------------------------------------------------------------------------
|
||
|
||
IF scsi_dtype = mcd_40 THEN
|
||
|
||
jsr |main_drvr
|
||
bcc @all_there
|
||
|
||
lda auto_sense_data+\
|
||
rqst_sens.addnl_sens_code
|
||
and #$00ff ;Checking for $04, $A7, $A8, or $B0
|
||
cmp #$0004 ;This cover $04
|
||
beq @not_ready
|
||
cmp #$00A7 ;This cover $A7
|
||
beq @not_ready
|
||
cmp #$00A8 ;This cover $A8
|
||
beq @not_ready
|
||
cmp #$00B0 ;This cover $B0
|
||
beq @not_ready
|
||
|
||
lda #drvr_io
|
||
sec
|
||
rts ;There was an error!
|
||
|
||
@not_ready lda #drvr_off_line
|
||
sec
|
||
rts
|
||
|
||
@all_there
|
||
|
||
ENDIF
|
||
|
||
;-------------------------------------------------------------------------------
|
||
|
||
@completed
|
||
|
||
;-------------------------------------------------------------------------------
|
||
|
||
IF cache_blks = true THEN
|
||
;
|
||
; Check force device access Flag. If
|
||
; set, then exit out.
|
||
;
|
||
bit @cache ;Forced Device Access?
|
||
bpl @out_of_here ;Yes.
|
||
|
||
;
|
||
; Check for CACHING.
|
||
;
|
||
clc ;Flag to force cache if needed.
|
||
lda <cache_prio ;Force Cache?
|
||
bne @do_cache ;Yes.
|
||
sec ;Update only.
|
||
@do_cache jsr r_get_cache
|
||
|
||
ENDIF
|
||
|
||
;-------------------------------------------------------------------------------
|
||
|
||
@out_of_here
|
||
;
|
||
; Restore the environment and
|
||
; update Transfer Count.
|
||
;
|
||
ldx |gsos_dpage
|
||
lda >rqst_cnt,x
|
||
sta <rqst_cnt
|
||
lda >rqst_cnt+2,x
|
||
sta <rqst_cnt+2
|
||
|
||
lda @orig_rqst
|
||
sta <trans_cnt
|
||
lda @orig_rqst+2
|
||
sta <trans_cnt+2
|
||
|
||
lda @orig_buff
|
||
sta <buff_ptr
|
||
lda @orig_buff+2
|
||
sta <buff_ptr+2
|
||
|
||
lda @orig_strt_blk
|
||
sta <block_num
|
||
lda @orig_strt_blk+2
|
||
sta <block_num+2
|
||
;
|
||
; Exit No Error.
|
||
;
|
||
lda #$0000
|
||
clc
|
||
@rts rts
|
||
|
||
;
|
||
; Variables and storage for short call.
|
||
;
|
||
@cache dc.w null ;Cache flag
|
||
|
||
@orig_buff dc.l null ;Origonal Buffer Pointer
|
||
@orig_rqst dc.l null ;Origonal Request Count
|
||
@orig_strt_blk dc.l null ;Origonal Starting Block Number
|
||
@rem_rqst dc.l null ;Number of bytes remaining
|
||
@trans_cnt dc.l null ;number of bytes transfered by device
|
||
;this time
|
||
;
|
||
; Command Data for this call.
|
||
;
|
||
cmd_$8028 dc.b $28
|
||
dc.b $00
|
||
c_block_num_l dc.l $00000000
|
||
c_block_cnt_l dcb.b 3,$00
|
||
dcb.b 7,$00
|
||
;
|
||
; Command Data for this call.
|
||
;
|
||
cmd_$8008 dc.b $08
|
||
dc.b $00
|
||
c_block_num_s dc.w $0000
|
||
c_block_cnt_s dc.b $00
|
||
dcb.b 7,$00
|
||
|
||
ENDIF
|
||
|
||
;-------------------------------------------------------------------------------
|
||
|
||
IF character_dvc = true\
|
||
AND block_dvc = false THEN
|
||
|
||
;
|
||
; Check to see if the Device is Opened.
|
||
;
|
||
lda |open_flag
|
||
beq @not_open
|
||
;
|
||
; Is the device online?
|
||
;
|
||
@open
|
||
ldy #dib.dvcflag
|
||
|
||
lda [dib_ptr],y
|
||
and #dvc_hardofl
|
||
bne @off_line ;Yes.
|
||
|
||
lda [dib_ptr],y
|
||
and #dvc_online
|
||
bne @read ;Yes.
|
||
;
|
||
; Device is currently offline.
|
||
;
|
||
@off_line lda #drvr_off_line
|
||
sec
|
||
@rts_out rts
|
||
;
|
||
; Device is not Opened.
|
||
;
|
||
@not_open lda #drvr_not_open
|
||
sec
|
||
rts
|
||
|
||
@read
|
||
|
||
;-------------------------------------------------------------------------------
|
||
|
||
IF scsi_dtype = scanner THEN
|
||
|
||
;
|
||
; Save Requested amount for later.
|
||
;
|
||
lda <rqst_cnt
|
||
sta @t_rqst_cnt ;Total Request Count (LOW)
|
||
sta @r_rqst_cnt ;Remaining Request Count (LOW)
|
||
lda <rqst_cnt+2
|
||
sta @t_rqst_cnt+2 ;Total Request Count (HIGH)
|
||
sta @r_rqst_cnt+2 ;Remaining Request Count (HIGH)
|
||
|
||
lda <buff_ptr
|
||
sta @orig_buffer
|
||
lda <buff_ptr+2
|
||
sta @orig_buffer+2
|
||
|
||
;
|
||
; Clear out Total Data Transfered Area.
|
||
;
|
||
stz @t_transfered
|
||
stz @t_transfered+2
|
||
;
|
||
; Check to see if there is data to be had.
|
||
;
|
||
@wait_loop jsr |get_data_status
|
||
bcs @io_error
|
||
lda |gds.data_avail\
|
||
+sense_data
|
||
ora |gds.data_avail\
|
||
+sense_data\
|
||
+1
|
||
beq @wait_loop
|
||
bra @have_data
|
||
;
|
||
; Return an I/O Error.
|
||
;
|
||
@io_error lda #drvr_io
|
||
sec
|
||
rts
|
||
;
|
||
; We have Data. We need to check to see
|
||
; if this is enough to give the user what
|
||
; he requested.
|
||
;
|
||
@have_data stz @enough_data
|
||
|
||
lda |gds.data_avail\ ;Data is in High -> Low format.
|
||
+sense_data\
|
||
+1
|
||
xba
|
||
sta |scratch0
|
||
|
||
lda |gds.data_avail\
|
||
+sense_data\
|
||
-1
|
||
xba
|
||
and #$00ff
|
||
sta |scratch0+2
|
||
|
||
sec
|
||
lda @r_rqst_cnt
|
||
sbc |scratch0
|
||
sta @stuff
|
||
|
||
lda @r_rqst_cnt+2
|
||
sbc |scratch0+2
|
||
;
|
||
; Was the request count < than what is
|
||
; available in the scanner? If so then
|
||
; we will return request count bytes only.
|
||
;
|
||
; Were They equal?
|
||
;
|
||
blt @do_rqst_cnt ;Yes.
|
||
ora @stuff
|
||
beq @do_rqst_cnt ;Yes.
|
||
;
|
||
; Well, it would apear that the request
|
||
; count is > then what is available. We
|
||
; will go ahead and get what is there
|
||
; and then we will check the wait flag.
|
||
; If we are in wait state, then we will
|
||
; loop around until we are able to get
|
||
; what the user has requested. If we are
|
||
; not in wait state, then we will exit
|
||
; after the read.
|
||
;
|
||
ldx |scratch0
|
||
ldy |scratch0+2
|
||
|
||
sec
|
||
lda @r_rqst_cnt
|
||
sbc |scratch0
|
||
sta @r_rqst_cnt
|
||
lda @r_rqst_cnt+2
|
||
sbc |scratch0+2
|
||
sta @r_rqst_cnt+2
|
||
|
||
dec @enough_data
|
||
bra @do_read
|
||
|
||
@do_rqst_cnt ldx @r_rqst_cnt
|
||
ldy @r_rqst_cnt+2
|
||
stz @r_rqst_cnt
|
||
stz @r_rqst_cnt+2
|
||
;
|
||
; Set our Request Count for this call.
|
||
;
|
||
@do_read stx <rqst_cnt
|
||
sty <rqst_cnt+2
|
||
;
|
||
; Set Main Driver Pointer to our data for the
|
||
; command.
|
||
;
|
||
lda #cmd_$8028
|
||
sta <scsi_mdrvr
|
||
lda #^cmd_$8028
|
||
sta <scsi_mdrvr+2
|
||
;
|
||
; It's a Status Call.
|
||
;
|
||
lda #scsit_stat
|
||
sta |call_type
|
||
;
|
||
; Set Internal Command Flag
|
||
;
|
||
dec |internal
|
||
;
|
||
; Issue the call.
|
||
;
|
||
jsr |main_drvr
|
||
;
|
||
; Save transfer count.
|
||
;
|
||
clc
|
||
ldy #dib.trx_len
|
||
lda [dib_ptr],y
|
||
adc @t_transfered
|
||
sta @t_transfered
|
||
ldy #dib.trx_len+2
|
||
lda [dib_ptr],y
|
||
adc @t_transfered+2
|
||
sta @t_transfered+2
|
||
;
|
||
; Was there enough data?
|
||
;
|
||
lda @enough_data
|
||
beq @no_wait ;Yes.
|
||
;
|
||
; Are we in WAIT Mode?
|
||
;
|
||
ldy #dib.dvcflag
|
||
lda [dib_ptr],y
|
||
and #wait_mode
|
||
beq @no_wait ;No.
|
||
;
|
||
; Bump Buffer Pointer
|
||
;
|
||
clc
|
||
ldy #dib.trx_len
|
||
lda [dib_ptr],y
|
||
adc <buff_ptr
|
||
sta <buff_ptr
|
||
ldy #dib.trx_len+2
|
||
lda [dib_ptr],y
|
||
adc <buff_ptr+2
|
||
sta <buff_ptr+2
|
||
|
||
jmp @wait_loop ;Yes.
|
||
;
|
||
; Update transfer count.
|
||
;
|
||
@no_wait lda @orig_buffer
|
||
sta <buff_ptr
|
||
lda @orig_buffer+2
|
||
sta <buff_ptr+2
|
||
|
||
lda @t_transfered
|
||
sta <trans_cnt
|
||
lda @t_transfered+2
|
||
sta <trans_cnt+2
|
||
;
|
||
; Clean Exit.
|
||
;
|
||
lda #$0000
|
||
clc
|
||
rts
|
||
|
||
;
|
||
; Data Area.
|
||
;
|
||
@orig_buffer dc.l null ;Origonal Buffer Pointer
|
||
@t_rqst_cnt dc.l null ;TOTAL REQUEST COUNT
|
||
@r_rqst_cnt dc.l null ;REMAINING REQUEST COUNT
|
||
@t_transfered dc.l null ;AMOUNT ACTUALLY TRANSFERED
|
||
@enough_data dc.w null ;Is there enough data flag.
|
||
@stuff dc.w null ;Temporary Storage
|
||
;
|
||
; Command Description.
|
||
;
|
||
cmd_$8028 dc.b $28
|
||
rel_adr dc.b null ;Relative Address Bit is bit 0
|
||
t_data_type dc.b null ;Transfer Data Type
|
||
dc.b null ;Reserved
|
||
t_id dc.w null ;Transfer ID
|
||
t_length dcb.b 3,null ;Transfer Length
|
||
control dc.b null ;Control Byte
|
||
|
||
ENDIF
|
||
|
||
;-------------------------------------------------------------------------------
|
||
|
||
ENDIF
|
||
|
||
;-------------------------------------------------------------------------------
|
||
|
||
|
||
ENDP
|
||
|
||
EJECT
|
||
|
||
END
|