EttinOS/src/LOADF.INC

407 lines
6.8 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;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 current drive and offset
mov word [.pointer], bx
mov dl, byte [drive]
mov byte [.drive], dl
;Change the drive if needed
;Check for a drive specification
cmp byte [si + 0x1], ":"
jne .start
;Check which drive to change to
cmp byte [si], "a"
je .cha
cmp byte [si], "A"
je .cha
cmp byte [si], "b"
je .chb
cmp byte [si], "B"
je .chb
cmp byte [si], "c"
je .chc
cmp byte [si], "C"
je .chc
cmp byte [si], "d"
je .chd
cmp byte [si], "D"
je .chd
;Set the carry flag and print an error message
stc
mov si, .driverrormsg
mov ah, 0x2
int 0x21
jmp .done
;Change
.cha:
mov dl, 0x0
mov byte [.drive], dl
jmp .drivechanged
.chb:
mov dl, 0x1
mov byte [.drive], dl
jmp .drivechanged
.chc:
mov dl, 0x2
mov byte [.drive], dl
jmp .drivechanged
.chd:
mov dl, 0x3
mov byte [.drive], dl
.drivechanged:
add si, 0x2
.start:
;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 file 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
.error:
pop ax
stc
mov si, .filerrormsg
mov ah, 0x2
int 0x21
jmp .done
;Find and load the file
.load:
pop ax
;Load the disk description table
;Set the source
mov dl, [.drive]
mov ch, 0x0
mov dh, 0x0
mov cl, 0x1
;Set the destination
mov si, buffer
mov bx, si
;Set the size
mov al, 0x1
;Load
mov ah, 0x2
int 0x13
;Set the carry flag and print an error message
jnc .storevalues
mov si, .diskerrormsg
mov ah, 0x2
int 0x21
jmp .done
;Store the disk values used for the rest of the call
.storevalues:
mov ax, word [buffer + 0xb]
mov word [.sectorsize], ax
mov al, byte [buffer + 0xd]
mov byte [.clustersize], al
mov ax, word [buffer + 0xe]
mov word [.bootsectors], ax
mov al, byte [buffer + 0x10]
mov byte [.fats], al
mov ax, word [buffer + 0x11]
mov word [.rootentries], ax
mov ax, word [buffer + 0x16]
mov word [.sectorsperfat], ax
mov ax, word [buffer + 0x18]
mov word [.sectorspertrack], ax
mov ax, word [buffer + 0x1a]
mov word [.sides], 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, .filerrormsg
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
;Set the destination
mov bx, word [.pointer]
;Load a sector
mov ch, 0x0
mov cl, byte [.clustersize]
.loadsector:
push cx
call .calcsource
;Set the size
push ax
mov al, 0x1
;Load
mov ah, 0x2
int 0x13
pop ax
;Set the next sector
add ax, 0x1
add bx, word [.sectorsize]
pop cx
loop .loadsector
;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
.drive db 0x0
.sectorsize dw 0x0 ;bytes
.clustersize db 0x0 ;sectors
.bootsectors dw 0x0
.fats db 0x0
.rootentries dw 0x0
.sectorsperfat dw 0x0
.sectorspertrack dw 0x0
.sides dw 0x0
.file times 0xb db 0x20
.cluster dw 0x0
.pointer dw 0x0
.driverrormsg db "Drive not found", 0x0
.diskerrormsg db "Disk not found", 0x0
.filerrormsg db "File not found", 0x0
;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
;Decrease 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 [.drive]
ret