265 lines
4.4 KiB
NASM
265 lines
4.4 KiB
NASM
cpu 8086
|
|
org 0x3000
|
|
|
|
;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:
|
|
;Get the BIOS equipment list
|
|
int 0x11
|
|
;Get the number of floppy drives
|
|
times 0x6 shr ax, 0x1
|
|
and ax, 0x3
|
|
inc ax
|
|
;Set the loop and drive letter counters and the drive letter and number
|
|
mov cx, ax
|
|
mov di, driveletters
|
|
mov al, [si]
|
|
mov dl, 0x0
|
|
;Check which drive to change to
|
|
checkdrive:
|
|
cmp al, [di]
|
|
je contchdrive
|
|
inc di
|
|
cmp al, [di]
|
|
je contchdrive
|
|
inc di
|
|
inc dl
|
|
loop checkdrive
|
|
;Print an error message
|
|
jmp driverror
|
|
;Change the drive
|
|
contchdrive:
|
|
mov [drive], dl
|
|
|
|
;Load the disk description table
|
|
;Set the source
|
|
loadvalues:
|
|
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 the disk description table
|
|
mov ah, 0x2
|
|
int 0x13
|
|
jc diskerror
|
|
|
|
;Store the disk values used for the rest of the call
|
|
mov ax, [buffer + 0xb]
|
|
mov [sectorsize], ax
|
|
mov ax, [buffer + 0xe]
|
|
mov [reservedsectors], ax
|
|
mov al, [buffer + 0x10]
|
|
mov [fats], al
|
|
mov ax, [buffer + 0x11]
|
|
mov [rootentries], ax
|
|
mov ax, [buffer + 0x16]
|
|
mov [sectorsperfat], ax
|
|
mov ax, [buffer + 0x18]
|
|
mov [sectorspertrack], ax
|
|
mov ax, [buffer + 0x1a]
|
|
mov [heads], ax
|
|
|
|
;Calculate and store variables not found in the BPB
|
|
;Start of the root
|
|
mov ah, 0x0
|
|
mov al, [fats]
|
|
mul word [sectorsperfat]
|
|
add ax, [reservedsectors]
|
|
mov [rootstart], ax
|
|
;Size of the root in sectors
|
|
mov ax, [rootentries]
|
|
mov dx, 0x20
|
|
mul dx
|
|
mov dx, 0x0
|
|
div word [sectorsize]
|
|
mov [rootsectors], ax
|
|
|
|
;Load the root
|
|
;Set the source
|
|
mov ax, [rootstart]
|
|
;Set the destination
|
|
mov si, buffer
|
|
mov bx, si
|
|
;Set the size
|
|
mov cx, [rootsectors]
|
|
;Store the source and the loop counter in the stack
|
|
loadrootsector:
|
|
push ax
|
|
push cx
|
|
;Set the source
|
|
call calcsource
|
|
;Set the size
|
|
mov al, 0x1
|
|
;Load a sector
|
|
mov ah, 0x2
|
|
int 0x13
|
|
;Load the loop counter and the source from the stack
|
|
pop cx
|
|
pop ax
|
|
;Set the next sector
|
|
add ax, 0x1
|
|
add bx, word [sectorsize]
|
|
loop loadrootsector
|
|
|
|
;List
|
|
;Set SI to the root
|
|
mov si, buffer
|
|
;Initialise the loop
|
|
mov cx, word [rootentries]
|
|
mov ax, 0x0
|
|
mov bl, 0x17
|
|
;Store CX in the stack
|
|
loop:
|
|
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
|
|
;Set SI to the next entry
|
|
skip:
|
|
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
|
|
cmp al, 0x1b
|
|
je done
|
|
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
|
|
reservedsectors dw 0x0
|
|
fats db 0x0
|
|
rootentries dw 0x0
|
|
sectorsperfat dw 0x0
|
|
sectorspertrack dw 0x0
|
|
heads dw 0x0
|
|
rootstart dw 0x0
|
|
rootsectors dw 0x0
|
|
driveletters db "AaBbCcDd"
|
|
driverrormsg db "Drive not found", 0x0
|
|
diskerrormsg db "Unable to read disk", 0x0
|
|
|
|
;***
|
|
|
|
;Calculate the source arguments for loading data from the disk
|
|
calcsource:
|
|
|
|
;Store AX and BX in the stack
|
|
push ax
|
|
push bx
|
|
|
|
;Calculate the cylinder, head, and sector
|
|
;Store the logical sector in BX
|
|
mov bx, ax
|
|
;Calculate the sector
|
|
mov dx, 0x0
|
|
div word [sectorspertrack]
|
|
add dl, 0x1
|
|
mov cl, dl
|
|
;Load the logical sector from BX
|
|
mov ax, bx
|
|
;Calculate the head and cylinder
|
|
mov dx, 0x0
|
|
div word [sectorspertrack]
|
|
mov dx, 0x0
|
|
div word [heads]
|
|
mov dh, dl ;Head
|
|
mov ch, al ;Cylinder
|
|
|
|
;Load the drive number
|
|
mov dl, byte [drive]
|
|
|
|
;Load BX and AX from the stack
|
|
pop bx
|
|
pop ax
|
|
|
|
;Return
|
|
ret
|
|
|
|
;***
|
|
|
|
;Buffer
|
|
buffer:
|