; ; This file contains the implementation of get_dir_entry. ; It also contains other functions for finding an entry within ; a directory. ; string asis include 'gsos.equ' include 'minix.equ' include 'fst.equ' include 'fst.macros' include 'M16.Debug' include 'records.equ' include 'p.equ' ; ; dirent_entry 0 is a special case. ; (assuming base = 1, displacement = 1) ; first call: ; before ; dirent_entry = 0, dirent_zone = 0, dirent_offset = 0 ; after: ; dirent_entry = 1, dirent_zone = 0, dirent_offset = 0 ; ; subsequent calls: ; before ; dirent_entry = 1, dirent_zone = ..., dirent_offset = ... ; after ; dirent_entry = 2, dirent_zone = ..., dirent_offset = ... ; ; don't think this needs to be dp... move to a normal record. data record ; size of the directory, divided by dirent_size. size ds.l 1 displacement ds.w 1 dirent_size ds.w 1 dirent_zone ds.w 1 dirent_offset ds.w 1 dirent_entry ds.w 1 dirent ds v1L_dirent endr import init_fcr import init_vcr import load_inode import read_data_block import do_ignore import do_eof import do_blocks import do_r_eof import do_r_blocks import do_access import do_file_sys_id import do_option_list import do_create_date_time import do_mod_date_time import do_file_type import do_aux_type entry init entry base_displace entry find_next_dirent entry find_absolute_dirent entry find_dirent_block entry count_entries entry count_dirent_block entry do_flags entry do_name_buffer_0 entry do_name_buffer_1 entry do_entry_num entry sparse_dirent_block get_dir_entry procname export with fst_parms with dp with data ;~DebugSetTrace #1 jsr init_fcr jsr init_vcr ; check for read-access ldy #fcr.access lda [ return total count. ; cmp #0 beq @count jmp find_absolute_dirent @count jmp count_entries forward jmp find_next_dirent ; backward ; backward 0 ? == forward 0 cmp #0 beq forward eor #$ffff sec ; inc / clc adc dirent_entry sta displacement jmp find_absolute_dirent endp count_entries proc ; count the number of entries. with fst_parms with dp, data ; read each block and count the entries. ; only handles direct blocks. so there. ; disk inode has been copied to the dp. stz dirent_entry ldx #0 zone_loop stx dirent_zone lda disk_inode.zone,x bne @ok ; directory should not be sparse! ; sparse! jsr sparse_dirent_block bcs done bra next @ok jsr read_data_block bcs exit ; ~DebugHexDump read entry 0) ; ; find_absolute_dirent proc with data ; if displacement > dirent_entry, we can re-use that info. lda displacement cmp dirent_entry bcc no sec sbc dirent_entry sta displacement bra find_next_dirent no stz dirent_entry stz dirent_zone stz dirent_offset bra find_next_dirent endp find_next_dirent proc with data, dp lda dirent_entry beq @first dec dirent_entry bra @ok @first dec displacement bmi eod @ok ; make sure dir not empty (should never happen...) lda size beq eod ldx dirent_zone loop lda disk_inode.zone,x beq sparse ; should never happen... phx ; save jsr read_data_block plx bcs exit ; phx ; phy ; pha ; ~DebugHexDump = 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