;******************************************************* ; ; SCSI Driver 'Write' filter. ; ; Written by Matt Gulick. Started June 14,1988 ; ; Copyright Apple Computer, Inc. 1988,89 ; ;******************************************************* ;******************************************************* ; ; 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 = scanner THEN ; ; Device is not writable. ; lda #drvr_bad_req sec rts ENDIF ;------------------------------------------------------------------------------- IF scsi_dtype = apple_cd\ OR scsi_dtype = changer THEN ; ; Device is not writable. ; lda #drvr_wrt_prot sec rts ENDIF ;------------------------------------------------------------------------------- IF scsi_dtype <> apple_cd\ AND scsi_dtype <> changer\ AND scsi_dtype <> scanner 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 bcc @deferred ;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. @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 $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 * ;* $80 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 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> jsr |main_drvr bcc @completed ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ IF scsi_dtype = mcd_40 THEN 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 #$0027 ;This cover $27 Write Protected beq @write_protect 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! @write_protect ldy #dib.dvcchar lda [dib_ptr],y and #write_allow--\ $ffff sta [dib_ptr],y lda #drvr_wrt_prot sec rts @not_ready lda #drvr_off_line sec rts ENDIF ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 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 @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_$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 ;------------------------------------------------------------------------------- ENDP EJECT END