1
0
Fork 0
EttinOS/src/LOADF.INC

305 lines
4.9 KiB
Plaintext

;Load a file named in SI as a string ending in a null to the offset BX and set AL to 0x0 if the load was succesful and 0x1 if there was an error.
loadf:
;Store the initial registers in the stack
push ax
push bx
push cx
push dx
push si
push di
;Store the offset
mov word [.pointer], bx
;Set DI at .file and initialise it with spaces
mov di, .file
mov cx, 0xb
mov al, 0x20
rep stosb
sub di, 0xb
;Convert .file into FAT formatting
;Initialise the length counter for the main part of the name
mov bl, 0x8
;Convert the main part of the file name
.nameloop:
;Load a character
lodsb
;Check for a period
cmp al, 0x2e
je .initext
;Check for everything else and convert to upper case
call .checkconv
jmp .nameloop
;Convert the extension
.initext:
;Set DI and initialise the length counter for the extension
mov bl, 0x3
mov di, .file+0x8
.extloop:
;Load a character
lodsb
;Check for a period
push ax
cmp al, 0x2e
je .error
pop ax
;Check for everything else and convert to upper case
call .checkconv
jmp .extloop
;Set the carry flag and print an error message if the file name is invalid
.error:
pop ax
stc
mov si, .errormsg
mov ah, 0x2
int 0x21
jmp .done
;Find and load the file
.load:
pop ax
;Load the root
;Set the source
mov ah, 0x0
mov al, [.fats]
mul word [.sectorsperfat]
add ax, [.bootsectors]
push ax
call .calcsource
;Set the destination
mov si, buffer
mov bx, si
;Set the size
push dx
mov ax, [.rootentries]
mov dx, 0x20
mul dx
mov dx, 0x0
div word [.sectorsize]
pop dx
push ax
;Load
mov ah, 0x2
int 0x13
;Search the root for the file entry
;Set DI to the root
mov di, buffer
;Initialise the search loop
mov cx, word [.rootentries]
mov ax, 0x0
.search:
;Store CX in the stack
push cx
;Check for the file entry
mov si, .file
mov cx, 0xb
rep cmpsb
je .loadentry
;Set DI to the next entry
add ax, 0x20
mov di, buffer
add di, ax
;Load CX from the stack
pop cx
loop .search
;Set the carry flag and print an error message if the file is not found
stc
mov si, .errormsg
mov ah, 0x2
int 0x21
jmp .clearstack
;Load the file entry
.loadentry:
;Load CX from the stack
pop cx
;Store the first cluster
mov ax, word [es:di+0xf]
mov word [.cluster], ax
;Set the source
mov ax, 0x1
call .calcsource
;Set the destination
mov di, buffer
mov bx, di
;Set the size
mov ax, [.sectorsperfat]
;Load
mov ah, 0x2
int 0x13
;Load the file
;Load a cluster
.loadcluster:
;Set the source
pop cx
pop bx
mov ax, word [.cluster]
sub ax, 0x2
mul byte [.clustersize]
add ax, bx
add ax, cx
push bx
push cx
call .calcsource
;Set the destination
mov bx, word [.pointer]
;Set the size
;mov al, 0x1
mov al, [.clustersize]
;Load
mov ah, 0x2
int 0x13
;Calculate the next cluster
mov ax, [.cluster]
mov dx, 0x0
mov bx, 0x3
mul bx
mov bx, 0x2
div bx
mov si, buffer
add si, ax
mov ax, word [ds:si]
or dx, dx
jz .even
shr ax, 1
shr ax, 1
shr ax, 1
shr ax, 1
jmp .contcalc
.even:
and ax, 0xfff
.contcalc:
mov word [.cluster], ax
cmp ax, 0xff8
jge .clearcarry
mov ax, [.sectorsize]
mul word [.clustersize]
add word [.pointer], ax
jmp .loadcluster
;Clear the carry flag if the load was succesful
.clearcarry:
clc
;Clear the stack
.clearstack:
pop cx
pop bx
.done:
;Load the initial registers from the stack
pop di
pop si
pop dx
pop cx
pop bx
pop ax
;Set AL to 0x1 if there was an error and to 0x0 otherwise and return
jc .setal
mov al, 0x0
iret
.setal:
mov al, 0x1
iret
;Data
.file times 0xb db 0x20
.errormsg db "File not found", 0x0
.cluster dw 0x0
.pointer dw 0x0
;These are temporary until i write something to load them from the disk itself
.bootdrive db 0x0
.sectorsize dw 0x200 ;bytes
.clustersize db 0x2 ;sectors
.bootsectors dw 0x1
.fats db 0x2
.rootentries dw 0x70
.sectorsperfat dw 0x2
.sectorspertrack dw 0x9
.sides dw 0x2
;Check the file name and convert to upper case
.checkconv:
;Check for the string end
cmp al, 0x0
je .load
;Check for the length limit
cmp bl, 0x0
je .error
;Check for invalid characters
cmp al, 0x22
je .error
cmp al, 0x2a
jl .contcheck1
cmp al, 0x2c
jg .contcheck1
jmp .error
.contcheck1:
cmp al, 0x2f
je .error
cmp al, 0x3a
jl .contcheck2
cmp al, 0x3f
jg .contcheck2
jmp .error
.contcheck2:
cmp al, 0x5b
jl .contcheck3
cmp al, 0x5d
jg .contcheck3
jmp .error
.contcheck3:
cmp al, 0x7c
je .error
;Check for lower case
cmp al, 0x61
jl .storech
cmp al, 0x7a
jg .storech
;Convert lower to upper case
sub al, 0x20
.storech:
;Store the character
stosb
;Increase the counter
dec bl
ret
;Calculate the source arguments for loading data from the disk
.calcsource:
push ax
push bx
mov bx, ax
mov dx, 0x0
div word [.sectorspertrack]
add dl, 0x1
mov cl, dl
mov ax, bx
mov dx, 0x0
div word [.sectorspertrack]
mov dx, 0x0
div word [.sides]
mov dh, dl
mov ch, al
pop bx
pop ax
mov dl, byte [.bootdrive]
ret