string asis include 'gsos.equ' include 'minix.equ' include 'records.equ' include 'fst.equ' include 'fst.macros' include 'M16.Debug' include 'p.equ' import do_ignore import init_fcr import init_vcr import read_data_block entry memcpy entry do_transfer_count entry do_data_buffer entry do_request_count entry init_block entry next_block entry slow_read entry read_direct_block entry read_partial_block entry getchar entry build_nl_table import disk_inode:v1_inode my_dp record dp.__end dataBuffer ds.l 1 requestCount ds.l 1 transferCount ds.l 1 mark ds.l 1 mtc ds.l 1 count ds.w 1 ; count from partial block read block ds.w 1 ; current block for reading. zone ds.l 1 nl_mask ds.w 1 IF *>=$d4 THEN AERROR 'dp -- too large.' ENDIF endr data record nl_table ds.b 256 endr ; ; read logic... ; if (mark & 1024-1) read partial block ; while (transferCount >= 1024) direct read into dataBuffer ; if (transferCount & 1024 - 1) read partial block do_transfer_count procname with fst_parms, my_dp lda transferCount sta [param_blk_ptr],y iny iny lda transferCount+2 sta [param_blk_ptr],y rts endp do_data_buffer procname with fst_parms, my_dp lda [param_blk_ptr],y sta dataBuffer iny iny lda [param_blk_ptr],y sta dataBuffer+2 rts endp do_request_count procname with fst_parms, my_dp lda [param_blk_ptr],y sta requestCount iny iny lda [param_blk_ptr],y sta requestCount+2 rts endp do_cache_priority procname with fst_parms, my_dp, dp lda [param_blk_ptr],y ; 0 or 1 only. cmp #2 bcs pre sta dev_parms.dev_cache_pr rts pre lda #parm_range_err sta tool_error rts endp entry set_zone init_block procname with my_dp lda mark+1 sta zone lda mark+3 and #$00ff sta zone+2 lsr zone+2 ror zone lsr zone+2 ror zone ldx zone bra set_zone endp ; updates block, zone, etc. ; find the block to read. next_block procname with my_dp, dp, v1 ldx zone inx inx stx zone entry set_zone set_zone cpx #NR_DZONES*2 bcc direct indirect double_indirect ; todo ... lda #damaged_bitmap sec rts direct lda disk_inode.zone,x sta block clc rts endp read procname export with dp, my_dp, fst_parms ; jsr init_vcr jsr init_fcr ; zero-out transferCount, even if there's an error ; later ldy call_class lda tc_table,y tay lda #0 sta [param_blk_ptr],y iny iny sta [param_blk_ptr],y ;brk $ea ;~DebugSetTrace #1 ; can only read from regular files or links. lda disk_inode.mode and #S_IFMT cmp #S_IFREG beq @ok cmp #S_IFLNK beq @ok lda #bad_store_type sec rtl @ok ; offset is 2 for class 0, 4 for class 1! ; check for read-access ldy #fcr.access lda [= 1024 { read_direct_block } lda requestCount+2 bne @read lda requestCount beq done cmp #1024 bcc tail @read jsr read_direct_block bcs exit bra aligned tail ; read a partial tail block. ; set up block... jsr read_partial_block bcs exit done ; read complete! ; todo -- update fcr, transferCount ldy #fcr.mark lda mark sta [my_fcr],y iny iny lda mark+2 sta [my_fcr],y ; eventually, data_zone, data_block. ldx call_class lda tc_table,x tay lda transferCount sta [param_blk_ptr],y iny iny lda transferCount+2 sta [param_blk_ptr],y ;~DebugSetTrace #0 lda tool_error cmp #1 rtl exit rtl tc_table dc.w FileIORec.transferCount, IORecGS.transferCount endp update_counts procname with my_dp ; mark += count lda count clc adc mark sta mark lda #0 adc mark+2 sta mark+2 ;dataBuffer += count lda count clc adc dataBuffer sta dataBuffer lda #0 adc dataBuffer+2 sta dataBuffer+2 ; transferCount += count lda count clc adc transferCount sta transferCount lda #0 adc transferCount+2 sta transferCount+2 ; ; requestCount -= count lda requestCount sec sbc count sta requestCount lda requestCount+2 sbc #0 sta requestCount+2 ; a = requestCount+2 ora requestCount beq done jmp next_block done clc rts endp ; todo -- should read block into fcr, update fcr. read_partial_block procname ; read a block into io_buffer, then copy the parts we want into dataBuffer. ; a = block number. with my_dp, dp ; count = 1024 - (mark & 0x1023) lda mark and #1024-1 rsb #1024 sta count lda requestCount+2 bne @ok lda requestCount cmp count bcs @ok ; requestCount is less than count... sta count @ok ; assume block, etc are set up. lda io_buffer sta dev_parms.dev_buff lda io_buffer+2 sta dev_parms.dev_buff+2 lda block jsr read_data_block bcs exit ; set ptr to the offset... lda mark and #1024-1 clc adc io_buffer sta ptr lda #0 adc io_buffer+2 sta ptr+2 lda count jsr memcpy jmp update_counts exit rts endp read_direct_block procname with dp, my_dp ; set up for direct read! lda dataBuffer sta dev_parms.dev_buff lda dataBuffer+2 sta dev_parms.dev_buff+2 lda block jsr read_data_block bcs exit lda #1024 sta count jmp update_counts exit rts endp memcpy procname ; copy from ptr to dataBuffer ; a = count ;pha ; save ; all registers are clobbered. with dp, my_dp lsr a ; / 2 beq last_byte tax ldy #0 loop lda [ptr],y sta [dataBuffer],y iny iny dex bne loop last_byte ;pla ; carry still set... bcc done short m lda [ptr],y sta [dataBuffer],y long m done rts endp macro fix_count lda requestCount+2 bne @fini lda requestCount cmp count bcs @fini sta count @fini endm ; ; builds a new-line table, if necessary. ; returns: ; c = 0 if new_line mode enabled. ; c = 1 if new_line mode disabled. build_nl_table procname with dp, my_dp with data ldy #fcr.mask lda [my_fcr],y sta nl_mask bne @yes sec rts @yes lda #0 ldx #256-2 zloop sta nl_table,x dex dex bpl zloop ; newline list is a virtual pointer. ldy #fcr.newline lda [my_fcr],y tax iny iny lda [my_fcr],y tay jsl deref stx ptr sty ptr+2 ldy #fcr.newline_length lda [my_fcr],y tay dey ldx #0 short m nloop lda [ptr],y ;and nl_mask tax lda #$ff sta nl_table,x dey bpl nloop long m clc rts endp slow_read procname with dp, my_dp ; new-line processing is in effect. ; read a block, then copy each character at a time. ; first block may not be aligned. ;jsr build_nl_table lda mark and #1024-1 beq aligned lda block jsr read_data_block _rts.cs ; set up ptr. lda mark and #1024-1 clc adc io_buffer sta ptr lda #0 adc io_buffer+2 sta ptr+2 ; count = (1024 - mark) & 1023 lda #1024 sec sbc mark and #1024-1 sta count ; count = min(requestCount,count) fix_count jsr getchar bcs exit bvs done lda requestCount ora requestCount+2 beq done aligned lda io_buffer sta ptr lda io_buffer+2 sta ptr+2 @loop ; read aligned blocks. lda block jsr read_data_block bcs exit lda #1024 sta count fix_count jsr getchar bcs exit bvs done lda requestCount ora requestCount+2 bne @loop done lda #0 clc exit rts endp ; copies up to count characters from ptr to dataBuffer ; returns v = 1 if eol found, ; returns v = 0 if eol not found. ; (c set from next_block) ; updates mark, transferCount, dataBuffer, requestCount, etc. ; getchar procname with dp, my_dp with data ldy #0 short m bloop lda [ptr],y sta [dataBuffer],y iny and nl_mask ; bit nl_mask+1 ; high bit set if 1-char nl ; bpl @table ; cmp nl_char ; beq @eol ;@table tax lda nl_table,x bne @eol @next cpy count bcc bloop long m sty count jsr update_counts clv rts @eol ; end-of-line! long m sty count jsr update_counts sep #p.v rts endp end