368 lines
9.3 KiB
ArmAsm
368 lines
9.3 KiB
ArmAsm
;-------------------------------------
|
|
; Print current fat directory of MEM_FAT_CURRDIR
|
|
;-------------------------------------
|
|
fat_print_directory:
|
|
ld hl,MEM_FAT_CURRDIR
|
|
ld de,MEM_IDE_POINTER
|
|
ldi
|
|
ldi
|
|
ldi
|
|
ldi
|
|
|
|
LD DE,(MEM_FAT_SECTORS)
|
|
LD (MEM_FAT_COUNT1),DE
|
|
LD HL,MEM_IDE_POINTER ;read first sector
|
|
LD B,1
|
|
ld a,1
|
|
LD DE, MEM_IDE_BUFFER ;where to store data?
|
|
call read_lba_sector
|
|
|
|
call PRINTINLINE
|
|
db 10,13," Filename Cluster Size",10,13,0
|
|
|
|
LD HL, MEM_IDE_BUFFER ;set buffer start
|
|
LD C,16 ;set entries counter
|
|
|
|
_fat_print_directory_loop: ;loop over each entry (32byte)
|
|
LD A,(HL) ; check first byte
|
|
PUSH HL ;backup start of entry
|
|
POP IX
|
|
PUSH HL
|
|
;ignore unwanted entries
|
|
CP 0x41 ;skip invisible
|
|
JP Z, _fat_print_directory_loop_next
|
|
CP 0xE5 ;skip deleted
|
|
JP Z, _fat_print_directory_loop_next
|
|
CP 0x00 ;reached end
|
|
JP Z, _fat_print_directory_loop_break
|
|
|
|
;check file attribute
|
|
ld a,(IX+0x0B)
|
|
cp 0x10 ;if subdirectors
|
|
jp z, _fat_print_directory_dir ;print dir
|
|
;else print file
|
|
_fat_print_directory_loop_file
|
|
;print filename
|
|
ld a,' '
|
|
call print_char
|
|
ld a,' '
|
|
call print_char
|
|
LD B,8
|
|
call print_str_fixed
|
|
ld A,'.'
|
|
call print_char
|
|
LD B,3
|
|
call print_str_fixed
|
|
|
|
call PRINTINLINE
|
|
db " 0x",0
|
|
;first cluster number
|
|
ld a,(ix+0x1B)
|
|
call print_a_hex
|
|
ld a,(ix+0x1A)
|
|
call print_a_hex
|
|
call PRINTINLINE
|
|
db " 0x",0
|
|
ld a,(ix+0x1F)
|
|
call print_a_hex
|
|
ld a,(ix+0x1E)
|
|
call print_a_hex
|
|
ld a,(ix+0x1D)
|
|
call print_a_hex
|
|
ld a,(ix+0x1C)
|
|
call print_a_hex
|
|
call print_newLine
|
|
jr _fat_print_directory_loop_next
|
|
_fat_print_directory_dir
|
|
ld a,'D'
|
|
call print_char
|
|
ld a,' '
|
|
call print_char
|
|
LD B,8
|
|
call print_str_fixed
|
|
call PRINTINLINE
|
|
db " 0x",0
|
|
;first cluster number
|
|
ld a,(ix+0x1B)
|
|
call print_a_hex
|
|
ld a,(ix+0x1A)
|
|
call print_a_hex
|
|
call print_newLine
|
|
jr _fat_print_directory_loop_next
|
|
|
|
_fat_print_directory_loop_next: ; read next entry
|
|
DEC C ;next sector after 32 entries
|
|
JR Z,_fat_print_directory_loop_next_sector
|
|
POP HL ;restore start
|
|
LD DE, 32 ;length of entry
|
|
ADD HL,DE ;increment
|
|
JP _fat_print_directory_loop
|
|
|
|
_fat_print_directory_loop_next_sector: ; end fo sector. read next sector from disk
|
|
POP HL ;clear stack from old hl
|
|
LD H,0
|
|
LD L,1
|
|
call _fat_math_sector_add_16 ;increment sector
|
|
|
|
LD DE,(MEM_FAT_COUNT1) ; decrement sector count (max FAT length)
|
|
DEC DE
|
|
LD (MEM_FAT_COUNT1),DE
|
|
LD A,D
|
|
OR E
|
|
RET Z ; if DE is 0, mmax is reached. End here
|
|
|
|
LD HL,MEM_IDE_POINTER ;read next sector
|
|
LD B,1
|
|
ld a,1
|
|
LD DE, MEM_IDE_BUFFER ;where to store data?
|
|
call read_lba_sector
|
|
|
|
LD HL, MEM_IDE_BUFFER ;set buffer start
|
|
LD C,16 ;set entries counter
|
|
JP _fat_print_directory_loop
|
|
|
|
_fat_print_directory_loop_break
|
|
POP HL
|
|
ret
|
|
|
|
;-------------------------------------
|
|
; Changes current fat directory of MEM_FAT_CURRDIR
|
|
; input is relativ path
|
|
; DE points to path
|
|
;-------------------------------------
|
|
fat_cd_single:
|
|
push de
|
|
; check if user wants to go back (input = '..')
|
|
ld a,(de)
|
|
cp '.'
|
|
jr nz, _fat_cd_navigate; if not, skip
|
|
inc de ;check next
|
|
ld a,(de)
|
|
cp '.'
|
|
jr nz, _fat_cd_navigate; if not, skip
|
|
ld a,(var_dir+79) ;last byte contains depth
|
|
or a; Test if 0
|
|
jp z, _fat_cd_navigate_error ;cannot go back any more (already at root)
|
|
; check if .. exists in directory
|
|
ld a,'.' ;prepare filename buffer
|
|
ld hl,[MEM_FAT_TMPFNAME]
|
|
ld (hl),a
|
|
inc hl
|
|
ld (hl),a
|
|
inc hl
|
|
ld a,0x20 ;clear char 3-11
|
|
ld b,11
|
|
_fat_cd_navigate_goback_fl:
|
|
ld (hl),a
|
|
inc hl
|
|
djnz _fat_cd_navigate_goback_fl ;fill loop end
|
|
call fat_openfile_noprepare ;load file table (only 1st sector needed)
|
|
or a ;check for error
|
|
jp nz, _fat_cd_navigate_error ;entry not found exception
|
|
|
|
|
|
; find end of path
|
|
ld hl,[var_dir+3] ;current position
|
|
ld bc,76
|
|
ld a,0x00 ;termination char
|
|
cpir ;find end
|
|
jp po,_fat_cd_navigate_inerror ;in case of error, abort
|
|
;hl is now at end of string
|
|
ld bc,76
|
|
ld a,'\' ;seperation char
|
|
cpdr ;serach backwards for "/"
|
|
jp po,_fat_cd_navigate_inerror ;in case of error, abort
|
|
;hl is now at end of string
|
|
inc hl
|
|
xor a
|
|
ld (hl),a ;set termination char
|
|
inc hl
|
|
ld (hl),a ;set termination char
|
|
ld a,(var_dir+79)
|
|
dec a
|
|
ld (var_dir+79),a ;decrement dir depth counter
|
|
|
|
pop de
|
|
|
|
ld hl,[var_dir+2]
|
|
ld a,'\'
|
|
ld (hl),a ;set first /
|
|
|
|
ld hl,MEM_FAT_OF0_DATSEC ;setup directory pointer
|
|
ld de,MEM_FAT_CURRDIR
|
|
ldi
|
|
ldi
|
|
ldi
|
|
ldi
|
|
|
|
ret
|
|
|
|
_fat_cd_navigate
|
|
pop de ;get pointer to directory namme
|
|
push de ;and re-store it for next use
|
|
call fat_openfile ;find 'file' in current directory
|
|
_fat_cd_navigate_findsec
|
|
or a
|
|
jp nz, _fat_cd_navigate_error ;entry not found
|
|
ld a, (MEM_FAT_OF0_ATTRIBUTE)
|
|
cp 0x10
|
|
jp nz, _fat_cd_navigate_errfile
|
|
ld a,(var_dir+79)
|
|
inc a
|
|
ld (var_dir+79),a ;increment dir depth counter
|
|
ld hl,[var_dir+2] ;load start of path string
|
|
ld a,0 ;load termination char
|
|
ld bc,76 ;max length of string
|
|
cpir ;find end of path string
|
|
dec hl
|
|
jp po,_fat_cd_navigate_inerror ;in case of error, abort
|
|
;HL now has last element, BC has remaining max length
|
|
ld a,(var_dir+79) ;last byte contains depth
|
|
cp 1 ;if first path, skip /
|
|
jr z, _fat_cd_navigate_findsec_skipslash
|
|
ld a,'\'
|
|
ld (hl),a
|
|
inc hl
|
|
_fat_cd_navigate_findsec_skipslash
|
|
pop de ;get argument from stack
|
|
ex de,hl
|
|
push de ;store start to stack
|
|
;HL now has start of input string, DE has end of current path
|
|
ld bc,09 ;maximum length of directory name +1
|
|
_fat_cd_navigate_l2: ;copy new subdirectory
|
|
ldi ;copy
|
|
jp po,_fat_cd_navigate_inerrorS ;in case of error, abort
|
|
ld a,(hl) ;check next char
|
|
cp '\' ;end at '\'
|
|
jr z, _fat_cd_navigate_end ;else next byte
|
|
or a ;or and at 0x00
|
|
jr z, _fat_cd_navigate_end ;else next byte
|
|
jr _fat_cd_navigate_l2
|
|
_fat_cd_navigate_end:
|
|
xor a
|
|
ld (de),a ;set last byte to 0x00 (termination)
|
|
ld hl,MEM_FAT_OF0_DATSEC
|
|
;setup directory pointer
|
|
ld de,MEM_FAT_CURRDIR
|
|
ldi
|
|
ldi
|
|
ldi
|
|
ldi
|
|
pop de ;stack cleanup
|
|
ret
|
|
|
|
_fat_cd_navigate_error:
|
|
ld hl,[_fat_cd_navigate_error_str]
|
|
call print_str
|
|
pop de
|
|
ret
|
|
|
|
_fat_cd_navigate_inerrorS: ;with path reset
|
|
pop de ;restore former path
|
|
dec de ;change pointer to remove previous '\' as well
|
|
xor a ;clear a to 0x00
|
|
ld (de),a ;set last byte to 0x00 (termination)
|
|
jr _fat_cd_navigate_inerrore
|
|
_fat_cd_navigate_inerror: ;without path reset
|
|
pop de
|
|
_fat_cd_navigate_inerrore:
|
|
ld hl,[_fat_cd_navigate_inputerr_str]
|
|
call print_str
|
|
ret
|
|
_fat_cd_navigate_errfile:
|
|
pop de
|
|
ld hl,[_fat_cd_navigate_errfile_str]
|
|
call print_str
|
|
ret
|
|
|
|
_fat_cd_navigate_error_str:
|
|
db 10,13,"No such directory!",10,13,0
|
|
_fat_cd_navigate_inputerr_str:
|
|
db 10,13,"Invalid input!",10,13,0
|
|
_fat_cd_navigate_errfile_str:
|
|
db 10,13,"Cannot cd to file!",10,13,0
|
|
|
|
fat_exec:
|
|
push de
|
|
;DE has pointer to arguments
|
|
call fat_openfile
|
|
or a
|
|
jp nz, _fat_exec_notfound ;if not found, abort
|
|
;call fat_print_dbg
|
|
;load header
|
|
ld de, MEM_IDE_BUFFER
|
|
call fat_readfilesec
|
|
|
|
|
|
;ld hl, MEM_IDE_BUFFER ;print sector
|
|
;ld b,0x20
|
|
;call dump_pretty
|
|
|
|
ld a,(MEM_IDE_BUFFER)
|
|
cp 0xC3
|
|
jp nz, _fat_exec_notexec
|
|
|
|
call PRINTINLINE
|
|
db 10,13,"Loading ",0
|
|
pop hl ;get and re-store pointer ot filename from and to stack
|
|
push hl
|
|
call print_str
|
|
call PRINTINLINE
|
|
db " to 0x",0
|
|
;get start address
|
|
ld bc,(MEM_IDE_BUFFER + 10)
|
|
ld a,b
|
|
call print_a_hex
|
|
ld a,c
|
|
call print_a_hex
|
|
call PRINTINLINE
|
|
db " ... ",0
|
|
;bc has start addr
|
|
ld (MEM_FAT_EXEC_CURR),bc
|
|
ld (MEM_FAT_EXEC_START),bc
|
|
|
|
;get amount of sectors to load
|
|
ld hl,(MEM_IDE_BUFFER + 14)
|
|
ld l,h
|
|
srl l
|
|
ld h,0 ;divide by 512
|
|
inc hl ;increment because first sector is always loaded
|
|
; hl contains sector count
|
|
ld (MEM_FAT_EXEC_COUNT), hl
|
|
|
|
pop de ; restore filename
|
|
call fat_openfile ;reset file information
|
|
;start reading
|
|
_fat_exec_readloop1:
|
|
ld de,(MEM_FAT_EXEC_CURR)
|
|
call fat_readfilesec
|
|
ld hl,(MEM_FAT_EXEC_CURR)
|
|
ld de,512
|
|
add hl,de
|
|
ld (MEM_FAT_EXEC_CURR),hl
|
|
|
|
ld hl,(MEM_FAT_EXEC_COUNT)
|
|
dec hl
|
|
ld (MEM_FAT_EXEC_COUNT),hl
|
|
ld a,h
|
|
or l
|
|
jr z, _fat_exec_read_done
|
|
jr _fat_exec_readloop1
|
|
_fat_exec_read_done:
|
|
call PRINTINLINE
|
|
db "Load complete!",10,13,0
|
|
ld hl,(MEM_FAT_EXEC_START)
|
|
jp (hl)
|
|
|
|
|
|
_fat_exec_notfound:
|
|
pop de
|
|
call PRINTINLINE
|
|
db 10,13,"File not found!",10,13,0
|
|
ret
|
|
|
|
_fat_exec_notexec:
|
|
pop de
|
|
call PRINTINLINE
|
|
db 10,13,"File is not an executable!",10,13,0
|
|
ret |