minix.fst/read.aii

809 lines
9.4 KiB
Plaintext

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 [<my_fcr],y
and #read_access
bne @access_ok
lda #invalid_access
sec
rtl
@access_ok
stz transferCount
stz transferCount+2
ldy #fcr.mark
lda [my_fcr],y
sta mark
iny
iny
lda [my_fcr],y
sta mark+2
lda call_class
beq class0
class1
lda [param_blk_ptr] ; pcount
dec a
asl a ; x 2
asl a ; x 4
tax
dispatch read_dcb_1
lda tool_error
beq class_over
sec
rtl
class0
ldx #read_dcb_0_size-4
dispatch read_dcb_0
bra class_over
read_dcb_1
with IORecGS
dc.w refNum, do_ignore
dc.w dataBuffer, do_data_buffer
dc.w requestCount, do_request_count
dc.w transferCount, do_ignore
dc.w cachePriority, do_cache_priority
endwith
read_dcb_0
with FileIORec
dc.w fileRefNum, do_ignore
dc.w dataBuffer, do_data_buffer
dc.w requestCount, do_request_count
dc.w transferCount, do_ignore
endwith
read_dcb_0_size equ *-read_dcb_0
class_over
; end of file?
lda mark+2
cmp disk_inode.size+2
bcc noteof
lda mark
cmp disk_inode.size
bne noteof
eof
lda #end_of_file
sec
rtl
noteof
; if requestCount is 0, just quit now!
lda requestCount
ora requestCount+2
bne @rc
lda #0
clc
rtl
@rc
; transferCount can't go past the eof mark...
tc
; mtc -- max transferCount
sec
lda disk_inode.size
sbc mark
sta mtc
lda disk_inode.size+2
sbc mark+2
sta mtc+2
; if negative, we have a problem...
bmi eof
; if 0, end of file...
ora mtc
beq eof
lda requestCount+2
cmp mtc+2
bcc @ok
beq @lw
bra @toobig
@lw ; low word
lda requestCount
cmp mtc
beq @ok
bcc @ok
@toobig
lda mtc
sta requestCount
lda mtc+2
sta requestCount+2
@ok
jsr init_block
bcs exit
; we are ok to read!
; check for new line mode...
jsr build_nl_table
bcs normal_read
jsr slow_read
bcc done
rtl
normal_read
; currently limited to 7 zones, anyhow!
; first block may have extra work since it may be offset into a block.
; (should store block in the fcr)
lda mark
and #1024-1
beq aligned
jsr read_partial_block
bcs exit
aligned
; while transferCount >= 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