; ; 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 'records.equ' include 'fst.equ' include 'fst.macros' include 'M16.Debug' include 'p.equ' import disk_inode:v1_inode import disk_super:v1_super ; ; 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_vcr jsr init_fcr ;brk $ea ; 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 procname ; 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) ; ; ; 9/4/2015 -- The first two entries (. and ..) should be skipped. ; ; find_absolute_dirent procname 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 ; set dirent_offset = dirent_size * 2 to skip over . and .. lda dirent_size asl a ; x 2 sta dirent_offset @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 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