diff --git a/Makefile b/Makefile index 21e2978..ceba2cd 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ SOURCES = main.aii volume.aii get_file_info.aii \ open.aii get_dir_entry.aii close.aii \ - id_disk.aii stubs.aii tables.aii device.aii params.aii + id_disk.aii stubs.aii tables.aii device.aii params.aii data.aii OBJECTS=$(SOURCES:.aii=.o) diff --git a/data.aii b/data.aii new file mode 100644 index 0000000..6b05f5b --- /dev/null +++ b/data.aii @@ -0,0 +1,13 @@ + + case on + + include 'records.equ' + +data record + + export target +target ds GSString32 + + endr + + end \ No newline at end of file diff --git a/get_dir_entry.aii b/get_dir_entry.aii index 0f870b6..2ae2339 100644 --- a/get_dir_entry.aii +++ b/get_dir_entry.aii @@ -1,3 +1,10 @@ + ; + ; This file contains the implementation of get_dir_entry. + ; It also contains other functions for finding an entry within + ; a directory. + ; + + case on include 'gsos.equ' include 'minix.equ' @@ -10,6 +17,10 @@ include 'records.equ' include 'p.equ' + + + + ; ; dirent_entry 0 is a special case. ; (assuming base = 1, displacement = 1) @@ -26,7 +37,10 @@ ; dirent_entry = 2, dirent_zone = ..., dirent_offset = ... ; -gde_dp record dp.__end + ; don't think this needs to be dp... move to a normal record. + + +data record ; size of the directory, divided by dirent_size. @@ -39,15 +53,8 @@ dirent_zone ds.w 1 dirent_offset ds.w 1 dirent_entry ds.w 1 - IF *>=$d4 THEN - AERROR 'dp -- too large.' - ENDIF - endr - - -data record - dirent ds v1L_dirent + endr @@ -82,11 +89,13 @@ dirent ds v1L_dirent entry do_name_buffer_1 entry do_entry_num + entry sparse_dirent_block + get_dir_entry procname export with fst_parms with dp - with gde_dp + with data ;~DebugSetTrace #1 @@ -217,7 +226,7 @@ get_dir_entry_dcb_1 init proc - with fst_parms,dp,gde_dp + with fst_parms,dp,data lda device sta dev_parms.dev_num @@ -305,7 +314,7 @@ minix base_displace proc with fst_parms, dp - with gde_dp + with data ; offset is $04 for class 0, $06 for class 1 lda #$04 @@ -368,7 +377,7 @@ count_entries proc ; count the number of entries. with fst_parms - with dp, gde_dp + with dp, data ; read each block and count the entries. ; only handles direct blocks. so there. @@ -378,27 +387,26 @@ count_entries proc stz dirent_entry ldx #0 zone_loop + stx dirent_zone lda disk_inode.zone,x - beq next ; directory should not be sparse! + bne @ok ; directory should not be sparse! + ; sparse! + jsr sparse_dirent_block + bcs done + bra next - phx ; save +@ok jsr read_data_block - plx ; and restore bcs exit -; phx -; phy -; pha ; ~DebugHexDump dirent_entry, we can re-use that info. lda displacement @@ -642,7 +650,7 @@ no endp find_next_dirent proc - with gde_dp, dp + with data, dp lda dirent_entry beq @first @@ -653,6 +661,10 @@ find_next_dirent proc bmi eod @ok + ; make sure dir not empty (should never happen...) + lda size + beq eod + ldx dirent_zone loop @@ -674,8 +686,10 @@ loop jsr find_dirent_block - bcs exit - bvc found_it + bcc next + ; a = 0 if it was found! + cmp #1 + rts next inx @@ -684,27 +698,11 @@ next cpx #v1.NR_DZONES*2 bcs exit - - ; also check size - lda size - beq eod - bmi eod - bra loop sparse - ; should never happen... - ; skip over 1 block. - ; size -= dirents per block -- 32 for linux, 64 for minix - lda dirent_size ; 16 or 32. 32 -> 32, 16 -> 64. - cmp #32 - beq @ok - lda #64 -@ok - eor #$ffff - sec ; + 1 - adc size - sta size + jsr sparse_dirent_block + bcs eod bra next @@ -723,12 +721,12 @@ eod ; ; returns: - ; carry set on error. - ; overflow clear if found + ; carry set on error or if found. + ; a = 0 if found, or error. ; ; inputs y = dirent offset find_dirent_block proc - with dp, gde_dp + with dp, data ldy dirent_offset loop @@ -753,7 +751,6 @@ next lda #0 clc - sep #p.v rts eod @@ -797,12 +794,183 @@ found_it sta [my_fcr],y lda #0 - clc - clv + sec ; found! rts endp +strcmp proc + ; clobbers ptr + + ; check if the name is even possible... + + with dp + + import target:GSString32 + + ldx target.length + beq no + + ; dirent size is DIRSIZE + 2. -1 + ; to compare >= DIRSIZE+1 + lda data.dirent_size + dec a + cmp target.length + bcs no + + iny ; skip inode + iny + tya + clc + adc io_buffer + sta ptr + adc io_buffer+2 + sta ptr+2 + + ldx target.length + beq no + ldy #0 + short m + + ; y = offset + ; x = length of target string. +loop + lda [ptr],y + beq eos + cmp target.text,y + bne no8 + iny + dex + bne loop + long m +yes + clc + rts + +eos + long m + ; end of string. if x = 1, it's a match! + dex + beq yes + + +no8 + long m +no + sec + rts + + endp + +sparse_dirent_block proc + ; (not 32-bit safe) + + ; decrease size by the appropriate amount + ; for a sparse block. + ; (should probably never happen!) + + ; sets c if size <= 0 + + with data + + lda dirent_size + cmp #32 ; linux? 32 dirents per block + beq @ok + lda #64 ; minix? 64 dirents per block +@ok + eor #$ffff + sec + adc size + sta size + bmi eod + beq eod + clc + rts +eod + sec + rts + + endp + +find_entry_by_name proc export + + ; scan the directory and search by name... + + with dp + with data + + jsr init + lda size + beq fnf + bmi fnf + + ldx #0 +block_loop + ; x = dirent_zone + stx dirent_zone + lda disk_inode,x + beq sparse + + jsr read_data_block + bcc @ok + rts + +@ok + ldy #0 + +dirent_loop + ; y = dirent offset + sty dirent_offset + + lda [io_buffer],y + beq next_dirent + sta inode ; optomistic... + + jsr strcmp + bcs next_dirent + + ; found it! + lda #0 + clc + rts + +next_dirent + + dec size + beq fnf + + lda dirent_offset + clc + adc dirent_size + tay + cmp #1024 + bcs next_zone + bra dirent_loop + + +next_zone + ldx dirent_zone + inx + inx + cpx #v1.NR_DZONES*2 + bcc block_loop + ; all out of zones -> not found! + + +fnf + stz inode + lda #file_not_found + sec + rts + +sparse + ; sparse block. jump to the next zone, decrement size appropriately. + jsr sparse_dirent_block + bcs fnf + bra next_zone + + endp + end \ No newline at end of file diff --git a/get_file_info.aii b/get_file_info.aii index 0c39bb1..88ce5e9 100644 --- a/get_file_info.aii +++ b/get_file_info.aii @@ -1,4 +1,5 @@ + case on include 'gsos.equ' include 'minix.equ' @@ -199,12 +200,21 @@ ok endp + ; + ; sets inode, parent_inode, disk_inode, + ; if file not present but path is otherwise, ok (eg, create), + ; parent inode and disk_inode will be valid for the parent directory. + ; + ; uses path1, dev1, span1. + ; + path_to_inode proc export with dp,fst_parms path equ path1_ptr dev_num equ dev1_num +span equ span1 stz inode lda #1 @@ -232,6 +242,11 @@ bps rts check_path + + lda span + cmp #v1L.DIRSIZE+1 + bcs bps + ; but is it relative? lda [path] @@ -245,6 +260,10 @@ check_path lda dev_num bne bps jsr id_disk + ; + ; now find the actual file... + ; + ; rts absolute @@ -261,4 +280,111 @@ absolute endp + +find_file proc + + with dp + import find_entry_by_name + +path equ fst_parms.path1_ptr +dev_num equ fst_parms.dev1_num +span equ fst_parms.span1 + + import target:GSString32 + + stz more + stz path_offset + + ; we always need to load inode 1 + lda #1 + sta inode + jsr load_inode + _rts.cs + + +dir_loop + + lda inode + sta parent_inode + + ; get a path component. + + ldx #0 + ldy #path_offset + +path_loop + lda [path],y + beq eop + cmp #':' + beq eop + sta target.text,x + inx + bra path_loop +eop + sta more + long m + stx target.length + sty path_offset + and #$00ff + ; a = ':' or 0 ... worry about which later! + + ; target is valid, inode is valid, is target in inode? + + jsr find_entry_by_name + bcc @ok + ; may be file_not_found, may be path_not_found. + ldx more + beq @exit + lda #path_not_found +@exit + sec + rts + +@ok + ; inode, has been updated. + jsr load_inode + _rts.cs + + lda more + beq done + + ; more to go... + + ; this is a directory, right? + lda disk_inode.mode + and #S_IFMT + cmp #S_IFDIR + beq dir + lda #path_not_found + sec + rts + +dir + + ; skip the ':' + short m + ldy path_offset +loop + lda [path],y + beq @ok + cmp #':' + bne @ok + iny + bra loop +@ok + long m + sty path_offset + bra dir_loop + + +done + clc + rts + + +path_offset ds.w 1 +more ds.w 1 + + endp + end diff --git a/main.aii b/main.aii index 621fe5e..1e01109 100644 --- a/main.aii +++ b/main.aii @@ -1,4 +1,5 @@ + case on include 'gsos.equ' include 'minix.equ' diff --git a/records.equ b/records.equ index 6889078..9782c21 100644 --- a/records.equ +++ b/records.equ @@ -19,6 +19,25 @@ __sizeof equ __end - __begin mend +GSString255 begin_struct +length DS.W 1 ; Word - Number of Chars in text field +text DS.B 255 ; char[255] - + end_struct + +GSString32 begin_struct +length DS.W 1 ; Word - Number of characters in text field +text DS.B 32 ; char[32] - + end_struct + +ResultBuf255 begin_struct +bufSize DS.W 1 +bufString DS GSString255 + end_struct + +ResultBuf32 begin_struct +bufSize DS.W 1 +bufString DS GSString32 + end_struct TimeRec begin_struct second DS.B 1 diff --git a/stubs.aii b/stubs.aii index f7d224c..e4c566e 100644 --- a/stubs.aii +++ b/stubs.aii @@ -1,3 +1,6 @@ + + case on + include 'gsos.equ' stubs proc