;******************************************************* ; ; SCSI Driver 'Write' filter. ; ; Written by Matt Gulick. Started June 14,1988 ; ; Copyright Apple Computer, Inc. 1988-90 ; ;******************************************************* ;******************************************************* ; ; This file contains the 'Write' filter as defined in ; the ERS. ; ;******************************************************* ;******************************************************* ; ; Revision History: ; ;******************************************************* ; June 14, 1988 File started. ; June 21, 1988 Modified to mach the results of ; the Code Review and added ; register comments. STRING PASCAL BLANKS OFF PAGESIZE 70 PRINT NOGEN PRINT NOMDIR MACHINE M65816 IMPORT unit_state IMPORT test_unit_rdy IMPORT auto_sense_data IMPORT main_drvr IMPORT call_type IMPORT w_update_cache IMPORT divend IMPORT divsor IMPORT result IMPORT max_blk_cnt IMPORT divide IMPORT check_532_rw PRINT OFF INCLUDE 'scsihd.equates' INCLUDE 'M16.MEMORY' INCLUDE 'M16.UTIL' PRINT ON EJECT ;******************************************************* ; ; Main Entry point to the 'Write' filter. This ; "Filter" takes the information given by the caller ; on direct page and builds the equivilent to a Write ; Extended Control Call. In order of appearence: ; ; Verify that Device # ­ $0000 ; Call Number = $0003 ; 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 = GS/OS Direct Page ; Data Bank = Ours ; ; Errors: See Spec. ; ;******************************************************* EXPORT Write Write PROC ;------------------------------------------------------------------------------- IF scsi_dtype = apple_cd THEN ; ; Device is not writable. ; lda #drvr_wrt_prot sec rts ENDIF ;------------------------------------------------------------------------------- IF scsi_dtype <> apple_cd THEN stz @cache ; ; Is the device Removable? ; ldy #dib.dvcchar lda [dib_ptr],y and #removable beq @write ;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? ; ldy #dib.dvcflag lda [dib_ptr],y and #dvc_hardofl bne @off_line ;Yes. lda [dib_ptr],y and #dvc_online bne @write ;Yes. ; ; Device is currently offline. ; @off_line lda #drvr_off_line sec @rts_out rts ; ; Let's check the request count. If ; this is $00000000, then exit clean ; with no data transfered. ; @write lda >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> IF scsi_dtype = direct_acc THEN ; ; Verify Block Size. ; @cnt_non_zero ldy #dib.blksize lda [dib_ptr],y ;Block Size cmp >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; ; Verify Block Size. ; @cnt_non_zero ldy #dib.blksize lda [dib_ptr],y ;Block Size cmp >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @blk_size_ok ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> IF cache_blks = true THEN ; ; Regardless of the Cache Priority, ; we need to see if it is in the cache. ; ; Set flag to cache the block only if ; it is already there. ; dec @cache lda >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @no_cache ; ; Build the (Write Data) Status ; Command $802A, and just in case ; it is not accepted, we will also ; build $800A. ; lda > High. xba ; I Send it out High >> Low. sta |c_block_num_l+2 sta |c_block_num_s lda >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> IF scsi_dtype = direct_acc THEN ; ; Issue the call. ; jsr check_532_rw bcs @munge @deferred 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 a ; single byte count, then we need to ; break it into multiple calls. If ; not, then send it as is. ; lda |result sta @blk_rqst lda |result+1 sta @blk_rqst+1 beq @issue_call ; ; Set the max count for a single byte block ; count (Block size * $100). ; lda > LSB order. We need to add * ;* $100 to it. This is done by a simple * ;* increment. * ;***************************************** ; @over inc |c_block_num_s bra @issue_call ; ; Restore the environment. ; @done lda @orig_rqst sta >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> jsr |main_drvr bcc @completed lda #drvr_io rts ;There was an error! @deferred ENDIF ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; ; Update Transfer Count. ; @completed lda >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> IF cache_blks = true THEN ; ; Check if cache bypassed. ; bit @cache bpl @out_of_here ;Yes. clc lda >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; ; Exit No Error. ; @out_of_here lda #$0000 clc @rts rts ; ; Variables and storage for short call. ; @cache dc.w null ;Cache flag @do_532 dc.w null ;532 byte block flag @orig_buff dc.l null ;Origonal Buffer Pointer @orig_rqst dc.l null ;Origonal Request Count @blk_rqst dc.l null ;Number of Blocks requested ; ; Command Data for this call. ; cmd_$800A dc.b $0A dc.b $00 c_block_num_s dc.w $0000 c_block_cnt_s dc.b $00 dcb.b 7,$00 ; ; Command Data for this call. ; cmd_$802A dc.b $2A dc.b $00 c_block_num_l dc.l $00000000 c_block_cnt_l dcb.b 3,$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 @write ;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 @write ;------------------------------------------------------------------------------- IF scsi_dtype = character_dvc THEN ; ; Save Requested amount for later. ; lda