EttinOS/src/LIST.ASM

247 lines
3.8 KiB
NASM

CPU 8086
ORG 0x3000
;List the files on a drive
;Store the drive number
mov [drive], dl
;Check for an empty tail
cmp byte [si], 0x0
je loadvalues
;Change the drive if needed
;Check for a drive specification
cmp byte [si + 0x1], ":"
jne driverror
cmp byte [si + 0x2], 0x0
je changedrive
cmp byte [si + 0x2], 0x20
je changedrive
;Print an error message
jmp driverror
changedrive:
;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
;Print an error message
jmp driverror
;Change
cha:
mov dl, 0x0
mov byte [drive], dl
jmp loadvalues
chb:
mov dl, 0x1
mov byte [drive], dl
jmp loadvalues
chc:
mov dl, 0x2
mov byte [drive], dl
jmp loadvalues
chd:
mov dl, 0x3
mov byte [drive], dl
;Load the disk description table
loadvalues:
;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
jc diskerror
;Store the disk values used for the rest of the call
mov ax, word [buffer + 0xb]
mov word [sectorsize], ax
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
;Set the destination
mov si, buffer
mov bx, si
;Set the size
mov ax, [rootentries]
mov dx, 0x20
mul dx
mov dx, 0x0
div word [sectorsize]
mov cx, ax
pop ax
push ax
push cx
loadroot:
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 loadroot
;List
;Set SI to the root
mov si, buffer
;Initialise the loop
mov cx, word [rootentries]
mov ax, 0x0
mov bl, 0x17
loop:
;Store CX in the stack
push cx
;Check for an empty entry
cmp byte [si], 0xe5
je skip
;Check for the end of entries
cmp byte [si], 0x0
je done
;store AX in the stack
push ax
;Print the main part of the name
mov cx, 0x8
push ax
printname:
mov al, [si]
mov ah, 0xe
int 0x10
inc si
loop printname
;Print a space
mov al, 0x20
mov ah, 0xe
int 0x10
;Print the extension
mov cx, 0x3
printext:
mov al, [si]
mov ah, 0xe
int 0x10
inc si
loop printext
;Print a newline
mov al, 0xd
mov ah, 0xe
int 0x10
mov al, 0xa
mov ah, 0xe
int 0x10
;Load AX from the stack
pop ax
;Check paging
cmp bl, 0x0
jz page
dec bl
skip:
;Set SI to the next entry
add ax, 0x20
mov si, buffer
add si, ax
;Load CX from the stack
pop cx
loop loop
page:
push ax
mov ah, 0x0
int 0x16
pop ax
mov bl, 0x17
jmp skip
done:
int 0x20
driverror:
mov si, driverrormsg
mov ah, 0x2
int 0x21
jmp done
diskerror:
mov si, diskerrormsg
mov ah, 0x2
int 0x21
jmp done
;Data
drive db 0x0
sectorsize dw 0x0 ;bytes
bootsectors dw 0x0
fats db 0x0
rootentries dw 0x0
sectorsperfat dw 0x0
sectorspertrack dw 0x0
sides dw 0x0
driverrormsg db "Drive not found", 0x0
diskerrormsg db "Unable to read disk", 0x0
;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
;Buffer
buffer: