fat16 working
This commit is contained in:
366
OperatingSystem/monitor_v2/include/fat16_cmd.s
Normal file
366
OperatingSystem/monitor_v2/include/fat16_cmd.s
Normal file
@@ -0,0 +1,366 @@
|
||||
;-------------------------------------
|
||||
; 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 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 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
|
||||
ld hl,[var_input+6]
|
||||
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
|
||||
Reference in New Issue
Block a user