minix.fst/get_file_info.aii
2015-08-12 11:25:40 -04:00

483 lines
5.8 KiB
Plaintext

include 'gsos.equ'
include 'minix.equ'
include 'fst.equ'
include 'fst.macros'
include 'M16.Debug'
include 'records.equ'
entry path_to_inode
import id_disk
import device_read
get_file_info procname export
with fst_parms
with dev_parms
with dp
jsr path_to_inode
bcc @inode
rtl
@inode
; we have an inode. and my_vcr is valid.
; we need to actually _load_ the inode.
; todo -- check if inode # is valid?
; todo -- check if bit set in imap?
;~DebugSetTrace #1
;pla ; prev value
ldy #vcr.first_inode_block
lda [my_vcr],y
asl a ; x 2
sta dev_blk_num
; 32 inodes per block.
; however, I'd rather read half-block chunks, with means
; 16 inodes per half-block.
lda inode
dec a ; inode 1 is offset 0.
lsr a ; / 2
lsr a ; / 4
lsr a ; / 8
lsr a ; / 16
;lsr a ; / 32
clc
adc dev_blk_num
sta dev_blk_num
lda #512
sta dev_req_cnt
lda device
sta dev_num
jsr device_read
bcc ok
rtl
ok
; find the inode...
lda inode
dec a ; inode 1 is offset 0.
and #$0f
; multiply by 32
asl a ; x 2
asl a ; x 4
asl a ; x 8
asl a ; x 16
asl a ; x 32
clc
adc io_buffer
sta ptr
lda #0
adc io_buffer+2
sta ptr+2
; copy to dp
ldy #v1_inode.sizeof-2
ldx #v1_inode.sizeof-2
@loop
lda [ptr],y
sta disk_inode,x
dey
dey
dex
dex
bpl @loop
;pha ; space
;~DebugSetTrace #0
;pla ; prev value
lda <call_class
beq class0
class1
lda [param_blk_ptr] ; pcount
dec a
asl a ; x 2
asl a ; x 4
tax
dispatch file_info_dcb_1
lda tool_error
cmp #0
rtl
class0
ldx #file_info_dcb_0_size-4
dispatch file_info_dcb_0
lda tool_error
cmp #0
rtl
import do_ignore
import do_access
import do_create_date_time, do_mod_date_time
import do_create_date_time_0, do_mod_date_time_0
import do_option_list
import do_file_type, do_aux_type, do_storage_type
import do_eof, do_blocks, do_r_eof, do_r_blocks
file_info_dcb_0
dc.w $00, do_ignore ; pathname
dc.w $04, do_access
dc.w $06, do_file_type
dc.w $08, do_aux_type
dc.w $0c, do_storage_type
dc.w $0e, do_create_date_time_0
dc.w $12, do_mod_date_time_0
dc.w $16, do_blocks
file_info_dcb_0_size equ *-file_info_dcb_0
file_info_dcb_1
;dc.w $00, do_ignore ; pCount
dc.w $02, do_ignore ; pathname
dc.w $06, do_access
dc.w $08, do_file_type
dc.w $0a, do_aux_type
dc.w $0e, do_storage_type
dc.w $10, do_create_date_time
dc.w $18, do_mod_date_time
dc.w $20, do_option_list
dc.w $24, do_eof
dc.w $28, do_blocks
dc.w $2c, do_r_eof
dc.w $30, do_r_blocks
endp
do_access proc
with dp,fst_parms
lda disk_inode.mode
lda #$c3 ; ehh
sta [param_blk_ptr],y
rts
endp
do_storage_type proc
with dp,fst_parms
lda disk_inode.mode
; check for directory. GS/OS doesn't have concepts for other types (yet).
and #S_IFMT
cmp #S_IFDIR
beq dir
lda #1
bra store
dir
lda #$0d
store
sta [param_blk_ptr],y
rts
endp
do_file_type proc
with dp,fst_parms
lda disk_inode.mode
and #S_IFMT
cmp #S_IFDIR
beq dir
cmp #S_IFREG
beq reg
unknown
lda #$00
bra store
dir
lda #$0f
bra store
reg
lda #$06 ; binary
bra store
store
sta [param_blk_ptr],y
rts
endp
do_aux_type proc
with dp,fst_parms
lda #0
sta [param_blk_ptr],y
rts
endp
do_eof proc
with dp,fst_parms
lda disk_inode.size
sta [param_blk_ptr],y
iny
iny
lda disk_inode.size+2
sta [param_blk_ptr],y
rts
endp
do_blocks proc
with dp,fst_parms
with v1
; not sure if minix supports sparse blocks. could just estimate
; based on file size.
phx ; save
phy ; save
; 7 direct blocks, 1 indirect block, 1 double indirect block.
ldx #0
ldy #0 ; count
@loop
lda disk_inode.zone,x
beq @next
iny
@next
inx
inx
cpx #NR_DZONES*2
bcc @loop
; y is number of direct blocks.
; check for indirect block...
lda disk_inode.zone + NR_DZONES * 2
beq dib
;
; count up indirect blocks...
;
iny
dib
; check for double indirect block
lda disk_inode.zone + (NR_DZONES + 1) * 2
beq store
;
; count up double indirect blocks....
;
iny
store
tya
ply
sta [param_blk_ptr],y
iny
iny
lda #0
sta [param_blk_ptr],y
plx ; restore
rts
endp
do_r_eof proc
with dp,fst_parms
entry do_r_blocks
do_r_blocks
lda #0
sta [param_blk_ptr],y
iny
iny
sta [param_blk_ptr],y
rts
endp
do_option_list proc
with dp,fst_parms
; if the option list is present, store my fst id.
lda [param_blk_ptr],y
sta ptr
iny
iny
lda [param_blk_ptr],y
sta ptr+2
ora ptr
beq exit
; check if the option list ptr is large enough.
lda [ptr]
cmp #4
bcc pre
; store the size of the option list.
ldy #2
lda #2
sta [ptr],y
lda [ptr]
cmp #6
bcc bts
bra ok
; less than 4 is a parm range error.
; less than the necessary option list size is a buf_too_small error. (but store the space required)
pre
lda #parm_range_err
sta tool_error
bra exit
bts
lda #buff_too_small
sta tool_error
bra exit
ok
ldy #4
lda #fst_id
sta [ptr],y
exit
rts
endp
do_create_date_time_0 proc
with fst_parms
; todo ...
entry do_mod_date_time_0
do_mod_date_time_0
lda #0
sta [param_blk_ptr],y
iny
iny
sta [param_blk_ptr],y
rts
endp
do_create_date_time proc
with fst_parms
; todo ...
entry do_mod_date_time
do_mod_date_time
lda #0
sta [param_blk_ptr],y
iny
iny
sta [param_blk_ptr],y
iny
iny
sta [param_blk_ptr],y
iny
iny
sta [param_blk_ptr],y
rts
endp
path_to_inode proc
with dp,fst_parms
path equ path1_ptr
dev_num equ dev1_num
stz inode
lda #1
sta parent_inode
lda path_flag
and #$4000
bne check_path
no_path
; device only (eg, .dev1 )
;
lda #1
sta inode
lda dev_num
beq bps
sta device
jmp id_disk
; returns
bps
lda #bad_path_syntax
sec
rts
check_path
; but is it relative?
lda [path]
and #$00ff
cmp #':'
beq absolute
lda #1
sta inode
lda dev_num
bne bps
jsr id_disk
rts
absolute
;
; worst case ...
; 1. extract the volume name.
; 2. call find_vcr to find it by name
; 3. if that fails, scan all devices.
lda #1
sta inode
clc
rts
endp
end