;******************************************************* ; ; 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 $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 > High. xba ; I Send it out High >> Low. sta |c_block_num_l+2 sta |c_block_num_s lda $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 > 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,x sta rqst_cnt+2,x sta 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