Rewrite everything to be more elegant, prevent changing to non-existent drives, add the option to quit print and list while paging and modify the readme accordingly, and add info on the EttinOS-extra repository to the readme.
This commit is contained in:
parent
a20d846f60
commit
8baa294947
19
README.MD
19
README.MD
|
@ -3,7 +3,9 @@ EttinOS
|
||||||
|
|
||||||
EttinOS is a minimalist 16-bit DOS-like hobbyist operating system for
|
EttinOS is a minimalist 16-bit DOS-like hobbyist operating system for
|
||||||
the IBM Personal Computer and compatible machines. Its git repository
|
the IBM Personal Computer and compatible machines. Its git repository
|
||||||
can be found at https://ahti.space/git/crazyettin/EttinOS.
|
can be found at https://ahti.space/git/crazyettin/EttinOS and that of
|
||||||
|
EttinOS-extra, a collection of programs for the system, at
|
||||||
|
https://ahti.space/git/crazyettin/EttinOS-extra.
|
||||||
|
|
||||||
System requirements
|
System requirements
|
||||||
-------------------
|
-------------------
|
||||||
|
@ -38,11 +40,12 @@ overwrites the cursor location and the erase (=tab) key erases it. The
|
||||||
space and backspace keys move the cursor.
|
space and backspace keys move the cursor.
|
||||||
|
|
||||||
EttinOS assigns the drives letters from A to D and uses the FAT12 file
|
EttinOS assigns the drives letters from A to D and uses the FAT12 file
|
||||||
system. The extended BIOS parameter block, file attributes, and the file
|
system. The hidden and total sectors entries of the BIOS parameter
|
||||||
access date are not supported and are ignored if present: as a result
|
block, the entire extended BIOS parameter block, file attributes, and
|
||||||
disk labels and subdirectories are not supported. Drive letters and file
|
the file access date are not supported and are ignored if present: as a
|
||||||
names are case-insensitive and the latter follow the 8.3 format. Text
|
result disk labels and subdirectories are not supported. Drive letters
|
||||||
files use CRLF line endings.
|
and file names are case-insensitive and the latter follow the 8.3
|
||||||
|
format. Text files use CRLF line endings.
|
||||||
|
|
||||||
Drives and files are specified as ([A-D]:) and ([A-D]:)FILENAME.EXT
|
Drives and files are specified as ([A-D]:) and ([A-D]:)FILENAME.EXT
|
||||||
respectively. Specifying the current drive, indicated in the prompt, is
|
respectively. Specifying the current drive, indicated in the prompt, is
|
||||||
|
@ -61,8 +64,8 @@ Commands included in EttinOS:
|
||||||
* PRINT: Print a text file. Syntax: PRINT FILE
|
* PRINT: Print a text file. Syntax: PRINT FILE
|
||||||
|
|
||||||
Both LIST and PRINT page their output if all of it does not fit on the
|
Both LIST and PRINT page their output if all of it does not fit on the
|
||||||
screen at the same time. Press any key to continue printing after each
|
screen at the same time. Press any key other than escape to continue
|
||||||
screen.
|
printing after each screen or escape to quit the program.
|
||||||
|
|
||||||
Programming
|
Programming
|
||||||
-----------
|
-----------
|
||||||
|
|
208
src/BOOT.ASM
208
src/BOOT.ASM
|
@ -1,122 +1,135 @@
|
||||||
CPU 8086
|
cpu 8086
|
||||||
ORG 0x7c00
|
org 0x7c00
|
||||||
|
|
||||||
|
;Jump to the code
|
||||||
jmp start
|
jmp start
|
||||||
|
|
||||||
|
;Padding
|
||||||
nop
|
nop
|
||||||
|
|
||||||
;Disk description tables
|
;OEM label
|
||||||
|
db "ETTINOS "
|
||||||
|
|
||||||
%ifdef F1440
|
%ifdef F1440
|
||||||
;1.44 MB 3.5" floppy disk (enable with the argument -d F1440)
|
|
||||||
oemlabel db "ETTINOS "
|
;1.44 MB 3.5" floppy disk BPB (enable with the argument -d F1440)
|
||||||
sectorsize dw 0x200 ;bytes
|
sectorsize dw 0x200 ;bytes
|
||||||
clustersize db 0x1 ;sectors
|
clustersize db 0x1 ;sectors
|
||||||
bootsectors dw 0x1
|
reservedsectors dw 0x1
|
||||||
fats db 0x2
|
fats db 0x2
|
||||||
rootentries dw 0xe0
|
rootentries dw 0xe0
|
||||||
logicalsectors dw 0xb40
|
logicalsectors dw 0xb40
|
||||||
mediadescriptor db 0xf0
|
mediadescriptor db 0xf0
|
||||||
sectorsperfat dw 0x9
|
sectorsperfat dw 0x9
|
||||||
sectorspertrack dw 0x12
|
sectorspertrack dw 0x12
|
||||||
sides dw 0x2
|
heads dw 0x2
|
||||||
hiddensectors dd 0x0
|
|
||||||
largesectors dd 0x0
|
|
||||||
|
|
||||||
%else
|
%else
|
||||||
;360 KiB 5.25" floppy disk (default)
|
|
||||||
oemlabel db "ETTINOS "
|
;360 KiB 5.25" floppy disk BPB (default)
|
||||||
sectorsize dw 0x200 ;bytes
|
sectorsize dw 0x200 ;bytes
|
||||||
clustersize db 0x2 ;sectors
|
clustersize db 0x2 ;sectors
|
||||||
bootsectors dw 0x1
|
reservedsectors dw 0x1
|
||||||
fats db 0x2
|
fats db 0x2
|
||||||
rootentries dw 0x70
|
rootentries dw 0x70
|
||||||
logicalsectors dw 0x2d0
|
logicalsectors dw 0x2d0
|
||||||
mediadescriptor db 0xfd
|
mediadescriptor db 0xfd
|
||||||
sectorsperfat dw 0x2
|
sectorsperfat dw 0x2
|
||||||
sectorspertrack dw 0x9
|
sectorspertrack dw 0x9
|
||||||
sides dw 0x2
|
heads dw 0x2
|
||||||
hiddensectors dd 0x0
|
|
||||||
largesectors dd 0x0
|
|
||||||
|
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
start:
|
|
||||||
|
|
||||||
;Setup
|
;Setup
|
||||||
;Set up the data, stack, and extra segments
|
;Set the segments
|
||||||
|
start:
|
||||||
mov ax, 0x0
|
mov ax, 0x0
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov ss, ax
|
mov ss, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
;Set up the stack
|
;Set the stack
|
||||||
cli
|
cli
|
||||||
mov sp, 0x0
|
mov sp, 0x0
|
||||||
sti
|
sti
|
||||||
;Store the boot drive number
|
;Store the boot drive number
|
||||||
mov [drive], dl
|
mov [drive], dl
|
||||||
|
|
||||||
;Load the root
|
;Calculate and store variables not found in the BPB
|
||||||
;Set the source
|
;Start of the root
|
||||||
mov ah, 0x0
|
mov ah, 0x0
|
||||||
mov al, [fats]
|
mov al, [fats]
|
||||||
mul word [sectorsperfat]
|
mul word [sectorsperfat]
|
||||||
add ax, [bootsectors]
|
add ax, [reservedsectors]
|
||||||
push ax
|
mov [rootstart], ax
|
||||||
;Set the destination
|
;Size of the root in sectors
|
||||||
mov si, buffer
|
|
||||||
mov bx, si
|
|
||||||
;Set the size
|
|
||||||
mov ax, [rootentries]
|
mov ax, [rootentries]
|
||||||
mov dx, 0x20
|
mov dx, 0x20
|
||||||
mul dx
|
mul dx
|
||||||
mov dx, 0x0
|
mov dx, 0x0
|
||||||
div word [sectorsize]
|
div word [sectorsize]
|
||||||
mov cx, ax
|
mov [rootsectors], ax
|
||||||
pop ax
|
;Start of data
|
||||||
|
add ax, [rootstart]
|
||||||
|
mov [datastart], 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 ax
|
||||||
push cx
|
push cx
|
||||||
loadroot:
|
;Set the source
|
||||||
push cx
|
|
||||||
call calcsource
|
call calcsource
|
||||||
;Set the size
|
;Set the size
|
||||||
push ax
|
|
||||||
mov al, 0x1
|
mov al, 0x1
|
||||||
;Load
|
;Load a sector
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x13
|
int 0x13
|
||||||
|
;Load the loop counter and the source from the stack
|
||||||
|
pop cx
|
||||||
pop ax
|
pop ax
|
||||||
;Set the next sector
|
;Set the next sector
|
||||||
add ax, 0x1
|
add ax, 0x1
|
||||||
add bx, word [sectorsize]
|
add bx, word [sectorsize]
|
||||||
pop cx
|
;Load the next sector
|
||||||
loop loadroot
|
loop loadrootsector
|
||||||
|
|
||||||
;Search the root for the system entry
|
;Search the root for the system entry
|
||||||
;Set DI to the root
|
;Set DI to the root
|
||||||
mov di, buffer
|
mov di, buffer
|
||||||
;Initialise the search loop
|
;Set the number of root entries
|
||||||
mov cx, word [rootentries]
|
mov cx, word [rootentries]
|
||||||
|
;Set the entry pointer
|
||||||
mov ax, 0x0
|
mov ax, 0x0
|
||||||
|
;Store the loop counter in the stack
|
||||||
search:
|
search:
|
||||||
;Store CX in the stack
|
|
||||||
push cx
|
push cx
|
||||||
;Check for the system entry
|
;Check for the system entry
|
||||||
mov si, sysfile
|
mov si, file
|
||||||
mov cx, 0xb
|
mov cx, 0xb
|
||||||
rep cmpsb
|
rep cmpsb
|
||||||
je loadentry
|
je loadfat
|
||||||
;Set DI to the next entry
|
;Set DI at the next entry
|
||||||
add ax, 0x20
|
add ax, 0x20
|
||||||
mov di, buffer
|
mov di, buffer
|
||||||
add di, ax
|
add di, ax
|
||||||
;Load CX from the stack
|
;Load the loop counter from the stack
|
||||||
pop cx
|
pop cx
|
||||||
|
;Search the next entry
|
||||||
loop search
|
loop search
|
||||||
|
|
||||||
;Print an error message if the system is not found
|
;Print an error message and hang if the system is not found
|
||||||
mov si, errormsg
|
;Set SI at the file error message
|
||||||
printerror:
|
mov si, filerrormsg
|
||||||
;Load a character
|
;Load a character
|
||||||
|
printstr:
|
||||||
lodsb
|
lodsb
|
||||||
;Check for the string end
|
;Check for the string end
|
||||||
cmp al, 0x0
|
cmp al, 0x0
|
||||||
|
@ -124,62 +137,61 @@ je $
|
||||||
;Print the character
|
;Print the character
|
||||||
mov ah, 0xe
|
mov ah, 0xe
|
||||||
int 0x10
|
int 0x10
|
||||||
;Repeat
|
;Print the next character
|
||||||
jmp printerror
|
jmp printstr
|
||||||
|
|
||||||
;Load the system entry
|
;Load the FAT
|
||||||
loadentry:
|
|
||||||
;Load CX from the stack
|
;Load CX from the stack
|
||||||
|
loadfat:
|
||||||
pop cx
|
pop cx
|
||||||
;Store the first cluster
|
;Store the address of the first cluster
|
||||||
mov ax, word [es:di+0xf]
|
mov ax, [di + 0xf]
|
||||||
mov word [cluster], ax
|
mov [cluster], ax
|
||||||
;Set the source
|
;Set the source
|
||||||
mov ax, 0x1
|
mov ax, [reservedsectors]
|
||||||
call calcsource
|
call calcsource
|
||||||
;Set the destination
|
;Set the destination
|
||||||
mov di, buffer
|
mov bx, buffer
|
||||||
mov bx, di
|
|
||||||
;Set the size
|
;Set the size
|
||||||
mov ax, [sectorsperfat]
|
mov ax, [sectorsperfat]
|
||||||
;Load
|
;Load the FAT
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x13
|
int 0x13
|
||||||
|
|
||||||
;Load a cluster
|
;Load a cluster
|
||||||
loadcluster:
|
loadcluster:
|
||||||
;Set the source
|
;Set the source
|
||||||
pop cx
|
|
||||||
pop bx
|
|
||||||
mov ax, word [cluster]
|
mov ax, word [cluster]
|
||||||
sub ax, 0x2
|
sub ax, 0x2
|
||||||
mul byte [clustersize]
|
mul byte [clustersize]
|
||||||
add ax, bx
|
add ax, [datastart]
|
||||||
add ax, cx
|
|
||||||
push bx
|
|
||||||
push cx
|
|
||||||
;Set the destination
|
;Set the destination
|
||||||
mov bx, word [pointer]
|
mov bx, word [pointer]
|
||||||
;Load a sector
|
;Set the size
|
||||||
mov ch, 0x0
|
mov ch, 0x0
|
||||||
mov cl, byte [clustersize]
|
mov cl, byte [clustersize]
|
||||||
loadsector:
|
;Store the loop counter in the stack
|
||||||
|
loadclustersector:
|
||||||
push cx
|
push cx
|
||||||
|
;Set the source
|
||||||
call calcsource
|
call calcsource
|
||||||
;Set the size
|
;Set the size
|
||||||
push ax
|
push ax
|
||||||
mov al, 0x1
|
mov al, 0x1
|
||||||
;Load
|
;Load a sector
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x13
|
int 0x13
|
||||||
pop ax
|
pop ax
|
||||||
;Set the next sector
|
;Set the next sector
|
||||||
add ax, 0x1
|
add ax, 0x1
|
||||||
add bx, word [sectorsize]
|
add bx, [sectorsize]
|
||||||
|
;Load the loop counter from the stack
|
||||||
pop cx
|
pop cx
|
||||||
loop loadsector
|
;Load the next sector
|
||||||
|
loop loadclustersector
|
||||||
|
|
||||||
;Calculate the next cluster
|
;Calculate the next cluster
|
||||||
|
;Check if the cluster is even or odd
|
||||||
mov ax, [cluster]
|
mov ax, [cluster]
|
||||||
mov dx, 0x0
|
mov dx, 0x0
|
||||||
mov bx, 0x3
|
mov bx, 0x3
|
||||||
|
@ -188,67 +200,87 @@ mov bx, 0x2
|
||||||
div bx
|
div bx
|
||||||
mov si, buffer
|
mov si, buffer
|
||||||
add si, ax
|
add si, ax
|
||||||
mov ax, word [ds:si]
|
mov ax, word [si]
|
||||||
or dx, dx
|
or dx, dx
|
||||||
jz even
|
jz even
|
||||||
odd:
|
;If the cluster is odd shift out the first four bits
|
||||||
shr ax, 1
|
times 0x4 shr ax, 0x1
|
||||||
shr ax, 1
|
|
||||||
shr ax, 1
|
|
||||||
shr ax, 1
|
|
||||||
jmp contcalc
|
jmp contcalc
|
||||||
|
;If the cluster is even mask out the final four bits
|
||||||
even:
|
even:
|
||||||
and ax, 0xfff
|
and ax, 0xfff
|
||||||
contcalc:
|
contcalc:
|
||||||
mov word [cluster], ax
|
;Check for the file end
|
||||||
cmp ax, 0xff8
|
cmp ax, 0xff8
|
||||||
jge boot
|
jge boot
|
||||||
|
;Store the address of the next cluster
|
||||||
|
mov word [cluster], ax
|
||||||
|
;Set the destination of the next cluster
|
||||||
mov ax, [sectorsize]
|
mov ax, [sectorsize]
|
||||||
mul word [clustersize]
|
mul word [clustersize]
|
||||||
add word [pointer], ax
|
add word [pointer], ax
|
||||||
|
;Load the next cluster
|
||||||
jmp loadcluster
|
jmp loadcluster
|
||||||
|
|
||||||
;Clear the stack and boot the system
|
;Boot the system
|
||||||
|
;Pass the boot drive number to the system
|
||||||
boot:
|
boot:
|
||||||
;Clear
|
|
||||||
pop cx
|
|
||||||
pop bx
|
|
||||||
;Pass the drive number to the system
|
|
||||||
mov dl, byte [drive]
|
mov dl, byte [drive]
|
||||||
;Boot
|
;Boot the system
|
||||||
jmp 0x0:0x500
|
jmp 0x0:0x500
|
||||||
|
|
||||||
;Data
|
;Data
|
||||||
drive db 0x0
|
drive db 0x0
|
||||||
sysfile db "SYSTEM BIN"
|
rootstart dw 0x0
|
||||||
errormsg db "System not found", 0xd, 0xa, 0x0
|
rootsectors dw 0x0
|
||||||
cluster dw 0x0
|
datastart dw 0x0
|
||||||
pointer dw 0x500
|
file db "SYSTEM BIN"
|
||||||
|
filerrormsg db "System not found", 0xd, 0xa, 0x0
|
||||||
|
cluster dw 0x0
|
||||||
|
pointer dw 0x500
|
||||||
|
|
||||||
|
;***
|
||||||
|
|
||||||
;Calculate the source arguments for loading data from the disk
|
;Calculate the source arguments for loading data from the disk
|
||||||
calcsource:
|
calcsource:
|
||||||
|
|
||||||
|
;Store AX and BX in the stack
|
||||||
push ax
|
push ax
|
||||||
push bx
|
push bx
|
||||||
|
|
||||||
|
;Calculate the cylinder, head, and sector
|
||||||
|
;Store the logical sector in BX
|
||||||
mov bx, ax
|
mov bx, ax
|
||||||
|
;Calculate the sector
|
||||||
mov dx, 0x0
|
mov dx, 0x0
|
||||||
div word [sectorspertrack]
|
div word [sectorspertrack]
|
||||||
add dl, 0x1
|
add dl, 0x1
|
||||||
mov cl, dl
|
mov cl, dl
|
||||||
|
;Load the logical sector from BX
|
||||||
mov ax, bx
|
mov ax, bx
|
||||||
|
;Calculate the head and cylinder
|
||||||
mov dx, 0x0
|
mov dx, 0x0
|
||||||
div word [sectorspertrack]
|
div word [sectorspertrack]
|
||||||
mov dx, 0x0
|
mov dx, 0x0
|
||||||
div word [sides]
|
div word [heads]
|
||||||
mov dh, dl
|
mov dh, dl ;Head
|
||||||
mov ch, al
|
mov ch, al ;Cylinder
|
||||||
|
|
||||||
|
;Load the boot drive number
|
||||||
|
mov dl, byte [drive]
|
||||||
|
|
||||||
|
;Load BX and AX from the stack
|
||||||
pop bx
|
pop bx
|
||||||
pop ax
|
pop ax
|
||||||
mov dl, byte [drive]
|
|
||||||
|
;Return
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;Pad the binary to a full sector and make the disk bootable
|
;***
|
||||||
|
|
||||||
;Padding
|
;Padding
|
||||||
times 0x1fe-($-$$) db 0x0
|
times 0x1fe-($-$$) db 0x0
|
||||||
|
|
||||||
;Boot signature
|
;Boot signature
|
||||||
dw 0xaa55
|
dw 0xaa55
|
||||||
|
|
||||||
|
|
10
src/ECHO.ASM
10
src/ECHO.ASM
|
@ -1,12 +1,14 @@
|
||||||
CPU 8086
|
cpu 8086
|
||||||
ORG 0x3000
|
org 0x3000
|
||||||
|
|
||||||
;Echo the tail
|
|
||||||
;Check for an empty tail
|
;Check for an empty tail
|
||||||
cmp byte [si], 0x0
|
cmp byte [si], 0x0
|
||||||
je done
|
je done
|
||||||
;Echo
|
|
||||||
|
;Print the message
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x21
|
int 0x21
|
||||||
|
|
||||||
|
;Return to the system
|
||||||
done:
|
done:
|
||||||
int 0x20
|
int 0x20
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
CPU 8086
|
cpu 8086
|
||||||
ORG 0x3000
|
org 0x3000
|
||||||
|
|
||||||
;Print a hello world.
|
;Print a hello world.
|
||||||
mov si, hello
|
mov si, hello
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x21
|
int 0x21
|
||||||
|
|
||||||
|
;Return to the system
|
||||||
int 0x20
|
int 0x20
|
||||||
|
|
||||||
;Data
|
;Data
|
||||||
|
|
170
src/LIST.ASM
170
src/LIST.ASM
|
@ -1,7 +1,5 @@
|
||||||
CPU 8086
|
cpu 8086
|
||||||
ORG 0x3000
|
org 0x3000
|
||||||
|
|
||||||
;List the files on a drive
|
|
||||||
|
|
||||||
;Store the drive number
|
;Store the drive number
|
||||||
mov [drive], dl
|
mov [drive], dl
|
||||||
|
@ -21,45 +19,36 @@ je changedrive
|
||||||
;Print an error message
|
;Print an error message
|
||||||
jmp driverror
|
jmp driverror
|
||||||
changedrive:
|
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
|
;Check which drive to change to
|
||||||
cmp byte [si], "a"
|
checkdrive:
|
||||||
je cha
|
cmp al, [di]
|
||||||
cmp byte [si], "A"
|
je contchdrive
|
||||||
je cha
|
inc di
|
||||||
cmp byte [si], "b"
|
cmp al, [di]
|
||||||
je chb
|
je contchdrive
|
||||||
cmp byte [si], "B"
|
inc di
|
||||||
je chb
|
inc dl
|
||||||
cmp byte [si], "c"
|
loop checkdrive
|
||||||
je chc
|
|
||||||
cmp byte [si], "C"
|
|
||||||
je chc
|
|
||||||
cmp byte [si], "d"
|
|
||||||
je chd
|
|
||||||
cmp byte [si], "D"
|
|
||||||
je chd
|
|
||||||
;Print an error message
|
;Print an error message
|
||||||
jmp driverror
|
jmp driverror
|
||||||
;Change
|
;Change the drive
|
||||||
cha:
|
contchdrive:
|
||||||
mov dl, 0x0
|
mov [drive], dl
|
||||||
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
|
;Load the disk description table
|
||||||
loadvalues:
|
|
||||||
;Set the source
|
;Set the source
|
||||||
|
loadvalues:
|
||||||
mov dl, [drive]
|
mov dl, [drive]
|
||||||
mov ch, 0x0
|
mov ch, 0x0
|
||||||
mov dh, 0x0
|
mov dh, 0x0
|
||||||
|
@ -69,62 +58,68 @@ mov si, buffer
|
||||||
mov bx, si
|
mov bx, si
|
||||||
;Set the size
|
;Set the size
|
||||||
mov al, 0x1
|
mov al, 0x1
|
||||||
;Load
|
;Load the disk description table
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x13
|
int 0x13
|
||||||
jc diskerror
|
jc diskerror
|
||||||
|
|
||||||
;Store the disk values used for the rest of the call
|
;Store the disk values used for the rest of the call
|
||||||
mov ax, word [buffer + 0xb]
|
mov ax, [buffer + 0xb]
|
||||||
mov word [sectorsize], ax
|
mov [sectorsize], ax
|
||||||
mov ax, word [buffer + 0xe]
|
mov ax, [buffer + 0xe]
|
||||||
mov word [bootsectors], ax
|
mov [reservedsectors], ax
|
||||||
mov al, byte [buffer + 0x10]
|
mov al, [buffer + 0x10]
|
||||||
mov byte [fats], al
|
mov [fats], al
|
||||||
mov ax, word [buffer + 0x11]
|
mov ax, [buffer + 0x11]
|
||||||
mov word [rootentries], ax
|
mov [rootentries], ax
|
||||||
mov ax, word [buffer + 0x16]
|
mov ax, [buffer + 0x16]
|
||||||
mov word [sectorsperfat], ax
|
mov [sectorsperfat], ax
|
||||||
mov ax, word [buffer + 0x18]
|
mov ax, [buffer + 0x18]
|
||||||
mov word [sectorspertrack], ax
|
mov [sectorspertrack], ax
|
||||||
mov ax, word [buffer + 0x1a]
|
mov ax, [buffer + 0x1a]
|
||||||
mov word [sides], ax
|
mov [heads], ax
|
||||||
|
|
||||||
;Load the root
|
;Calculate and store variables not found in the BPB
|
||||||
;Set the source
|
;Start of the root
|
||||||
mov ah, 0x0
|
mov ah, 0x0
|
||||||
mov al, [fats]
|
mov al, [fats]
|
||||||
mul word [sectorsperfat]
|
mul word [sectorsperfat]
|
||||||
add ax, [bootsectors]
|
add ax, [reservedsectors]
|
||||||
push ax
|
mov [rootstart], ax
|
||||||
;Set the destination
|
;Size of the root in sectors
|
||||||
mov si, buffer
|
|
||||||
mov bx, si
|
|
||||||
;Set the size
|
|
||||||
mov ax, [rootentries]
|
mov ax, [rootentries]
|
||||||
mov dx, 0x20
|
mov dx, 0x20
|
||||||
mul dx
|
mul dx
|
||||||
mov dx, 0x0
|
mov dx, 0x0
|
||||||
div word [sectorsize]
|
div word [sectorsize]
|
||||||
mov cx, ax
|
mov [rootsectors], ax
|
||||||
pop 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 ax
|
||||||
push cx
|
push cx
|
||||||
loadroot:
|
;Set the source
|
||||||
push cx
|
|
||||||
call calcsource
|
call calcsource
|
||||||
;Set the size
|
;Set the size
|
||||||
push ax
|
|
||||||
mov al, 0x1
|
mov al, 0x1
|
||||||
;Load
|
;Load a sector
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x13
|
int 0x13
|
||||||
|
;Load the loop counter and the source from the stack
|
||||||
|
pop cx
|
||||||
pop ax
|
pop ax
|
||||||
;Set the next sector
|
;Set the next sector
|
||||||
add ax, 0x1
|
add ax, 0x1
|
||||||
add bx, word [sectorsize]
|
add bx, word [sectorsize]
|
||||||
pop cx
|
loop loadrootsector
|
||||||
loop loadroot
|
|
||||||
|
|
||||||
;List
|
;List
|
||||||
;Set SI to the root
|
;Set SI to the root
|
||||||
|
@ -133,8 +128,8 @@ mov si, buffer
|
||||||
mov cx, word [rootentries]
|
mov cx, word [rootentries]
|
||||||
mov ax, 0x0
|
mov ax, 0x0
|
||||||
mov bl, 0x17
|
mov bl, 0x17
|
||||||
loop:
|
|
||||||
;Store CX in the stack
|
;Store CX in the stack
|
||||||
|
loop:
|
||||||
push cx
|
push cx
|
||||||
;Check for an empty entry
|
;Check for an empty entry
|
||||||
cmp byte [si], 0xe5
|
cmp byte [si], 0xe5
|
||||||
|
@ -178,8 +173,8 @@ pop ax
|
||||||
cmp bl, 0x0
|
cmp bl, 0x0
|
||||||
jz page
|
jz page
|
||||||
dec bl
|
dec bl
|
||||||
skip:
|
|
||||||
;Set SI to the next entry
|
;Set SI to the next entry
|
||||||
|
skip:
|
||||||
add ax, 0x20
|
add ax, 0x20
|
||||||
mov si, buffer
|
mov si, buffer
|
||||||
add si, ax
|
add si, ax
|
||||||
|
@ -190,6 +185,8 @@ page:
|
||||||
push ax
|
push ax
|
||||||
mov ah, 0x0
|
mov ah, 0x0
|
||||||
int 0x16
|
int 0x16
|
||||||
|
cmp al, 0x1b
|
||||||
|
je done
|
||||||
pop ax
|
pop ax
|
||||||
mov bl, 0x17
|
mov bl, 0x17
|
||||||
jmp skip
|
jmp skip
|
||||||
|
@ -212,35 +209,56 @@ jmp done
|
||||||
;Data
|
;Data
|
||||||
drive db 0x0
|
drive db 0x0
|
||||||
sectorsize dw 0x0 ;bytes
|
sectorsize dw 0x0 ;bytes
|
||||||
bootsectors dw 0x0
|
reservedsectors dw 0x0
|
||||||
fats db 0x0
|
fats db 0x0
|
||||||
rootentries dw 0x0
|
rootentries dw 0x0
|
||||||
sectorsperfat dw 0x0
|
sectorsperfat dw 0x0
|
||||||
sectorspertrack dw 0x0
|
sectorspertrack dw 0x0
|
||||||
sides dw 0x0
|
heads dw 0x0
|
||||||
|
rootstart dw 0x0
|
||||||
|
rootsectors dw 0x0
|
||||||
|
driveletters db "AaBbCcDd"
|
||||||
driverrormsg db "Drive not found", 0x0
|
driverrormsg db "Drive not found", 0x0
|
||||||
diskerrormsg db "Unable to read disk", 0x0
|
diskerrormsg db "Unable to read disk", 0x0
|
||||||
|
|
||||||
|
;***
|
||||||
|
|
||||||
;Calculate the source arguments for loading data from the disk
|
;Calculate the source arguments for loading data from the disk
|
||||||
calcsource:
|
calcsource:
|
||||||
|
|
||||||
|
;Store AX and BX in the stack
|
||||||
push ax
|
push ax
|
||||||
push bx
|
push bx
|
||||||
|
|
||||||
|
;Calculate the cylinder, head, and sector
|
||||||
|
;Store the logical sector in BX
|
||||||
mov bx, ax
|
mov bx, ax
|
||||||
|
;Calculate the sector
|
||||||
mov dx, 0x0
|
mov dx, 0x0
|
||||||
div word [sectorspertrack]
|
div word [sectorspertrack]
|
||||||
add dl, 0x1
|
add dl, 0x1
|
||||||
mov cl, dl
|
mov cl, dl
|
||||||
|
;Load the logical sector from BX
|
||||||
mov ax, bx
|
mov ax, bx
|
||||||
|
;Calculate the head and cylinder
|
||||||
mov dx, 0x0
|
mov dx, 0x0
|
||||||
div word [sectorspertrack]
|
div word [sectorspertrack]
|
||||||
mov dx, 0x0
|
mov dx, 0x0
|
||||||
div word [sides]
|
div word [heads]
|
||||||
mov dh, dl
|
mov dh, dl ;Head
|
||||||
mov ch, al
|
mov ch, al ;Cylinder
|
||||||
|
|
||||||
|
;Load the drive number
|
||||||
|
mov dl, byte [drive]
|
||||||
|
|
||||||
|
;Load BX and AX from the stack
|
||||||
pop bx
|
pop bx
|
||||||
pop ax
|
pop ax
|
||||||
mov dl, byte [drive]
|
|
||||||
|
;Return
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
;***
|
||||||
|
|
||||||
;Buffer
|
;Buffer
|
||||||
buffer:
|
buffer:
|
||||||
|
|
270
src/LOADF.INC
270
src/LOADF.INC
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
loadf:
|
loadf:
|
||||||
|
|
||||||
;Store the initial registers in the stack
|
;Store BX, DX, SI, and DI in the stack
|
||||||
push bx
|
push bx
|
||||||
push dx
|
push dx
|
||||||
push si
|
push si
|
||||||
|
@ -22,24 +22,28 @@ mov byte [.drive], dl
|
||||||
;Change the drive if needed
|
;Change the drive if needed
|
||||||
;Check for a drive specification
|
;Check for a drive specification
|
||||||
cmp byte [si + 0x1], ":"
|
cmp byte [si + 0x1], ":"
|
||||||
jne .start
|
jne .convert
|
||||||
|
;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
|
;Check which drive to change to
|
||||||
cmp byte [si], "a"
|
.checkdrive:
|
||||||
je .cha
|
cmp al, [di]
|
||||||
cmp byte [si], "A"
|
je .contchdrive
|
||||||
je .cha
|
inc di
|
||||||
cmp byte [si], "b"
|
cmp al, [di]
|
||||||
je .chb
|
je .contchdrive
|
||||||
cmp byte [si], "B"
|
inc di
|
||||||
je .chb
|
inc dl
|
||||||
cmp byte [si], "c"
|
loop .checkdrive
|
||||||
je .chc
|
|
||||||
cmp byte [si], "C"
|
|
||||||
je .chc
|
|
||||||
cmp byte [si], "d"
|
|
||||||
je .chd
|
|
||||||
cmp byte [si], "D"
|
|
||||||
je .chd
|
|
||||||
;Set AL to 0x1, CX to 0x0, and print an error message
|
;Set AL to 0x1, CX to 0x0, and print an error message
|
||||||
mov si, .driverrormsg
|
mov si, .driverrormsg
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
|
@ -47,57 +51,41 @@ int 0x21
|
||||||
mov al, 0x1
|
mov al, 0x1
|
||||||
mov cx, 0x0
|
mov cx, 0x0
|
||||||
jmp .done
|
jmp .done
|
||||||
;Change
|
;Change the drive
|
||||||
.cha:
|
.contchdrive:
|
||||||
mov dl, 0x0
|
mov [.drive], dl
|
||||||
mov byte [.drive], dl
|
;Move to the file name
|
||||||
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
|
add si, 0x2
|
||||||
|
|
||||||
.start:
|
|
||||||
|
|
||||||
;Set DI at .file and initialise it with spaces
|
;Set DI at .file and initialise it with spaces
|
||||||
|
.convert:
|
||||||
mov di, .file
|
mov di, .file
|
||||||
mov cx, 0xb
|
mov cx, 0xb
|
||||||
mov al, 0x20
|
mov al, 0x20
|
||||||
rep stosb
|
rep stosb
|
||||||
sub di, 0xb
|
sub di, 0xb
|
||||||
|
|
||||||
;Convert .file into FAT formatting
|
;Convert the main part of the file name into FAT format
|
||||||
|
;Set the length counter
|
||||||
;Initialise the length counter for the main part of the file name
|
|
||||||
mov bl, 0x8
|
mov bl, 0x8
|
||||||
|
|
||||||
;Convert the main part of the file name
|
|
||||||
.nameloop:
|
|
||||||
;Load a character
|
;Load a character
|
||||||
|
.nameloop:
|
||||||
lodsb
|
lodsb
|
||||||
;Check for a period
|
;Check for a period
|
||||||
cmp al, 0x2e
|
cmp al, 0x2e
|
||||||
je .initext
|
je .initext
|
||||||
;Check for everything else and convert to upper case
|
;Check for everything else and convert to upper case
|
||||||
call .checkconv
|
call .checkconv
|
||||||
|
;Load the next character
|
||||||
jmp .nameloop
|
jmp .nameloop
|
||||||
|
|
||||||
;Convert the extension
|
;Convert the extension into FAT format
|
||||||
|
;Set DI and the length counter for the extension
|
||||||
.initext:
|
.initext:
|
||||||
;Set DI and initialise the length counter for the extension
|
|
||||||
mov bl, 0x3
|
mov bl, 0x3
|
||||||
mov di, .file+0x8
|
mov di, .file+0x8
|
||||||
.extloop:
|
|
||||||
;Load a character
|
;Load a character
|
||||||
|
.extloop:
|
||||||
lodsb
|
lodsb
|
||||||
;Check for a period
|
;Check for a period
|
||||||
push ax
|
push ax
|
||||||
|
@ -106,6 +94,7 @@ je .error
|
||||||
pop ax
|
pop ax
|
||||||
;Check for everything else and convert to upper case
|
;Check for everything else and convert to upper case
|
||||||
call .checkconv
|
call .checkconv
|
||||||
|
;Load the next character
|
||||||
jmp .extloop
|
jmp .extloop
|
||||||
;Set AL to 0x4, CX to 0x0, and print an error message
|
;Set AL to 0x4, CX to 0x0, and print an error message
|
||||||
.error:
|
.error:
|
||||||
|
@ -118,7 +107,6 @@ mov cx, 0x0
|
||||||
jmp .done
|
jmp .done
|
||||||
|
|
||||||
;Find and load the file
|
;Find and load the file
|
||||||
|
|
||||||
.load:
|
.load:
|
||||||
pop ax
|
pop ax
|
||||||
|
|
||||||
|
@ -133,7 +121,7 @@ mov si, buffer
|
||||||
mov bx, si
|
mov bx, si
|
||||||
;Set the size
|
;Set the size
|
||||||
mov al, 0x1
|
mov al, 0x1
|
||||||
;Load
|
;Load the disk description table
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x13
|
int 0x13
|
||||||
jnc .storevalues
|
jnc .storevalues
|
||||||
|
@ -147,79 +135,91 @@ jmp .done
|
||||||
|
|
||||||
;Store the disk values used for the rest of the call
|
;Store the disk values used for the rest of the call
|
||||||
.storevalues:
|
.storevalues:
|
||||||
mov ax, word [buffer + 0xb]
|
mov ax, [buffer + 0xb]
|
||||||
mov word [.sectorsize], ax
|
mov [.sectorsize], ax
|
||||||
mov al, byte [buffer + 0xd]
|
mov al, [buffer + 0xd]
|
||||||
mov byte [.clustersize], al
|
mov [.clustersize], al
|
||||||
mov ax, word [buffer + 0xe]
|
mov ax, [buffer + 0xe]
|
||||||
mov word [.bootsectors], ax
|
mov [.reservedsectors], ax
|
||||||
mov al, byte [buffer + 0x10]
|
mov al, [buffer + 0x10]
|
||||||
mov byte [.fats], al
|
mov [.fats], al
|
||||||
mov ax, word [buffer + 0x11]
|
mov ax, [buffer + 0x11]
|
||||||
mov word [.rootentries], ax
|
mov [.rootentries], ax
|
||||||
mov ax, word [buffer + 0x16]
|
mov ax, [buffer + 0x16]
|
||||||
mov word [.sectorsperfat], ax
|
mov [.sectorsperfat], ax
|
||||||
mov ax, word [buffer + 0x18]
|
mov ax, [buffer + 0x18]
|
||||||
mov word [.sectorspertrack], ax
|
mov [.sectorspertrack], ax
|
||||||
mov ax, word [buffer + 0x1a]
|
mov ax, [buffer + 0x1a]
|
||||||
mov word [.sides], ax
|
mov [.heads], ax
|
||||||
|
|
||||||
;Load the root
|
;Calculate and store variables not found in the BPB
|
||||||
;Set the source
|
;Start of the root
|
||||||
mov ah, 0x0
|
mov ah, 0x0
|
||||||
mov al, [.fats]
|
mov al, [.fats]
|
||||||
mul word [.sectorsperfat]
|
mul word [.sectorsperfat]
|
||||||
add ax, [.bootsectors]
|
add ax, [.reservedsectors]
|
||||||
push ax
|
mov [.rootstart], ax
|
||||||
;Set the destination
|
;Size of the root in sectors
|
||||||
mov si, buffer
|
|
||||||
mov bx, si
|
|
||||||
;Set the size
|
|
||||||
mov ax, [.rootentries]
|
mov ax, [.rootentries]
|
||||||
mov dx, 0x20
|
mov dx, 0x20
|
||||||
mul dx
|
mul dx
|
||||||
mov dx, 0x0
|
mov dx, 0x0
|
||||||
div word [.sectorsize]
|
div word [.sectorsize]
|
||||||
mov cx, ax
|
mov [.rootsectors], ax
|
||||||
pop ax
|
;Start of data
|
||||||
|
add ax, [.rootstart]
|
||||||
|
mov [.datastart], 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 ax
|
||||||
push cx
|
push cx
|
||||||
.loadroot:
|
;Set the source
|
||||||
push cx
|
|
||||||
call .calcsource
|
call .calcsource
|
||||||
;Set the size
|
;Set the size
|
||||||
push ax
|
|
||||||
mov al, 0x1
|
mov al, 0x1
|
||||||
;Load
|
;Load a sector
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x13
|
int 0x13
|
||||||
|
;Load the loop counter and the source from the stack
|
||||||
|
pop cx
|
||||||
pop ax
|
pop ax
|
||||||
;Set the next sector
|
;Set the next sector
|
||||||
add ax, 0x1
|
add ax, 0x1
|
||||||
add bx, word [.sectorsize]
|
add bx, word [.sectorsize]
|
||||||
pop cx
|
;Load the next sector
|
||||||
loop .loadroot
|
loop .loadrootsector
|
||||||
|
|
||||||
;Search the root for the file entry
|
;Search the root for the file entry
|
||||||
;Set DI to the root
|
;Set DI to the root
|
||||||
mov di, buffer
|
mov di, buffer
|
||||||
;Initialise the search loop
|
;Set the number of root entries
|
||||||
mov cx, word [.rootentries]
|
mov cx, word [.rootentries]
|
||||||
|
;Set the entry pointer
|
||||||
mov ax, 0x0
|
mov ax, 0x0
|
||||||
|
;Store the loop counter in the stack
|
||||||
.search:
|
.search:
|
||||||
;Store CX in the stack
|
|
||||||
push cx
|
push cx
|
||||||
;Check for the file entry
|
;Check for the file entry
|
||||||
mov si, .file
|
mov si, .file
|
||||||
mov cx, 0xb
|
mov cx, 0xb
|
||||||
rep cmpsb
|
rep cmpsb
|
||||||
je .checksize
|
je .checksize
|
||||||
;Set DI to the next entry
|
;Set DI at the next entry
|
||||||
add ax, 0x20
|
add ax, 0x20
|
||||||
mov di, buffer
|
mov di, buffer
|
||||||
add di, ax
|
add di, ax
|
||||||
;Load CX from the stack
|
;Load the loop counter from the stack
|
||||||
pop cx
|
pop cx
|
||||||
|
;Search the next entry
|
||||||
loop .search
|
loop .search
|
||||||
;Set AL to 0x4, CX to 0x0, and print an error message
|
;Set AL to 0x4, CX to 0x0, and print an error message
|
||||||
mov si, .filerrormsg
|
mov si, .filerrormsg
|
||||||
|
@ -227,11 +227,11 @@ mov ah, 0x2
|
||||||
int 0x21
|
int 0x21
|
||||||
mov al, 0x4
|
mov al, 0x4
|
||||||
mov cx, 0x0
|
mov cx, 0x0
|
||||||
jmp .clearstack
|
jmp .done
|
||||||
|
|
||||||
;Check and store the file size
|
;Check and store the file size
|
||||||
.checksize:
|
|
||||||
;Load CX from the stack
|
;Load CX from the stack
|
||||||
|
.checksize:
|
||||||
pop cx
|
pop cx
|
||||||
;Check for files larger than 64 KiB
|
;Check for files larger than 64 KiB
|
||||||
cmp word [di + 0x13], 0x0
|
cmp word [di + 0x13], 0x0
|
||||||
|
@ -259,61 +259,58 @@ mov ah, 0x2
|
||||||
int 0x21
|
int 0x21
|
||||||
mov al, 0x8
|
mov al, 0x8
|
||||||
mov cx, 0x0
|
mov cx, 0x0
|
||||||
jmp .clearstack
|
jmp .done
|
||||||
|
|
||||||
;Load the FAT
|
;Load the FAT
|
||||||
.loadfat:
|
.loadfat:
|
||||||
;Store the first cluster of the file
|
;Store the address of the first cluster
|
||||||
mov ax, word [di + 0xf]
|
mov ax, [di + 0xf]
|
||||||
mov word [.cluster], ax
|
mov [.cluster], ax
|
||||||
;Set the source
|
;Set the source
|
||||||
mov ax, 0x1
|
mov ax, [.reservedsectors]
|
||||||
call .calcsource
|
call .calcsource
|
||||||
;Set the destination
|
;Set the destination
|
||||||
mov di, buffer
|
mov bx, buffer
|
||||||
mov bx, di
|
|
||||||
;Set the size
|
;Set the size
|
||||||
mov ax, [.sectorsperfat]
|
mov ax, [.sectorsperfat]
|
||||||
;Load
|
;Load the FAT
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x13
|
int 0x13
|
||||||
|
|
||||||
;Load the file
|
|
||||||
|
|
||||||
;Load a cluster
|
;Load a cluster
|
||||||
.loadcluster:
|
.loadcluster:
|
||||||
;Set the source
|
;Set the source
|
||||||
pop cx
|
|
||||||
pop bx
|
|
||||||
mov ax, word [.cluster]
|
mov ax, word [.cluster]
|
||||||
sub ax, 0x2
|
sub ax, 0x2
|
||||||
mul byte [.clustersize]
|
mul byte [.clustersize]
|
||||||
add ax, bx
|
add ax, [.datastart]
|
||||||
add ax, cx
|
|
||||||
push bx
|
|
||||||
push cx
|
|
||||||
;Set the destination
|
;Set the destination
|
||||||
mov bx, word [.pointer]
|
mov bx, word [.pointer]
|
||||||
;Load a sector
|
;Set the size
|
||||||
mov ch, 0x0
|
mov ch, 0x0
|
||||||
mov cl, byte [.clustersize]
|
mov cl, byte [.clustersize]
|
||||||
|
;Store the loop counter in the stack
|
||||||
.loadsector:
|
.loadsector:
|
||||||
push cx
|
push cx
|
||||||
|
;Set the source
|
||||||
call .calcsource
|
call .calcsource
|
||||||
;Set the size
|
;Set the size
|
||||||
push ax
|
push ax
|
||||||
mov al, 0x1
|
mov al, 0x1
|
||||||
;Load
|
;Load a sector
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x13
|
int 0x13
|
||||||
pop ax
|
pop ax
|
||||||
;Set the next sector
|
;Set the next sector
|
||||||
add ax, 0x1
|
add ax, 0x1
|
||||||
add bx, word [.sectorsize]
|
add bx, word [.sectorsize]
|
||||||
|
;Load the loop counter from the stack
|
||||||
pop cx
|
pop cx
|
||||||
|
;Load the next sector
|
||||||
loop .loadsector
|
loop .loadsector
|
||||||
|
|
||||||
;Calculate the next cluster
|
;Calculate the next cluster
|
||||||
|
;Check if the cluster is even or odd
|
||||||
mov ax, [.cluster]
|
mov ax, [.cluster]
|
||||||
mov dx, 0x0
|
mov dx, 0x0
|
||||||
mov bx, 0x3
|
mov bx, 0x3
|
||||||
|
@ -322,23 +319,26 @@ mov bx, 0x2
|
||||||
div bx
|
div bx
|
||||||
mov si, buffer
|
mov si, buffer
|
||||||
add si, ax
|
add si, ax
|
||||||
mov ax, word [ds:si]
|
mov ax, word [si]
|
||||||
or dx, dx
|
or dx, dx
|
||||||
jz .even
|
jz .even
|
||||||
shr ax, 1
|
;If the cluster is odd shift out the first four bits
|
||||||
shr ax, 1
|
times 0x4 shr ax, 0x1
|
||||||
shr ax, 1
|
|
||||||
shr ax, 1
|
|
||||||
jmp .contcalc
|
jmp .contcalc
|
||||||
|
;If the cluster is even mask out the final four bits
|
||||||
.even:
|
.even:
|
||||||
and ax, 0xfff
|
and ax, 0xfff
|
||||||
.contcalc:
|
.contcalc:
|
||||||
mov word [.cluster], ax
|
;Check for the file end
|
||||||
cmp ax, 0xff8
|
cmp ax, 0xff8
|
||||||
jge .success
|
jge .success
|
||||||
|
;Store the address of the next cluster
|
||||||
|
mov word [.cluster], ax
|
||||||
|
;Set the destination of the next cluster
|
||||||
mov ax, [.sectorsize]
|
mov ax, [.sectorsize]
|
||||||
mul word [.clustersize]
|
mul word [.clustersize]
|
||||||
add word [.pointer], ax
|
add word [.pointer], ax
|
||||||
|
;Load the next cluster
|
||||||
jmp .loadcluster
|
jmp .loadcluster
|
||||||
|
|
||||||
;Set AL to 0x0 and load the file size to CX if the load was succesful
|
;Set AL to 0x0 and load the file size to CX if the load was succesful
|
||||||
|
@ -347,13 +347,9 @@ mov al, 0x0
|
||||||
mov cx, [.size]
|
mov cx, [.size]
|
||||||
|
|
||||||
;Clear the stack
|
;Clear the stack
|
||||||
.clearstack:
|
|
||||||
pop bx
|
|
||||||
pop bx
|
|
||||||
|
|
||||||
.done:
|
.done:
|
||||||
|
|
||||||
;Load the initial registers from the stack
|
;Load DI, SI, DX, and BX from the stack
|
||||||
pop di
|
pop di
|
||||||
pop si
|
pop si
|
||||||
pop dx
|
pop dx
|
||||||
|
@ -362,18 +358,22 @@ pop bx
|
||||||
;Set AH to its initial value
|
;Set AH to its initial value
|
||||||
mov ah, 0x0
|
mov ah, 0x0
|
||||||
|
|
||||||
|
;Return
|
||||||
iret
|
iret
|
||||||
|
|
||||||
;Data
|
;Data
|
||||||
.drive db 0x0
|
.drive db 0x0
|
||||||
.sectorsize dw 0x0 ;bytes
|
.sectorsize dw 0x0 ;bytes
|
||||||
.clustersize db 0x0 ;sectors
|
.clustersize db 0x0 ;sectors
|
||||||
.bootsectors dw 0x0
|
.reservedsectors dw 0x0
|
||||||
.fats db 0x0
|
.fats db 0x0
|
||||||
.rootentries dw 0x0
|
.rootentries dw 0x0
|
||||||
.sectorsperfat dw 0x0
|
.sectorsperfat dw 0x0
|
||||||
.sectorspertrack dw 0x0
|
.sectorspertrack dw 0x0
|
||||||
.sides dw 0x0
|
.heads dw 0x0
|
||||||
|
.rootstart dw 0x0
|
||||||
|
.rootsectors dw 0x0
|
||||||
|
.datastart dw 0x0
|
||||||
.file times 0xb db 0x20
|
.file times 0xb db 0x20
|
||||||
.size dw 0x0
|
.size dw 0x0
|
||||||
.cluster dw 0x0
|
.cluster dw 0x0
|
||||||
|
@ -383,8 +383,12 @@ iret
|
||||||
.filerrormsg db "File or command not found", 0x0
|
.filerrormsg db "File or command not found", 0x0
|
||||||
.sizerrormsg db "Not enough memory", 0x0
|
.sizerrormsg db "Not enough memory", 0x0
|
||||||
|
|
||||||
|
;***
|
||||||
|
|
||||||
;Check the file name and convert to upper case
|
;Check the file name and convert to upper case
|
||||||
.checkconv:
|
.checkconv:
|
||||||
|
|
||||||
|
;Check for the string end, length limit, and invalid characters
|
||||||
;Check for the string end
|
;Check for the string end
|
||||||
cmp al, 0x0
|
cmp al, 0x0
|
||||||
je .load
|
je .load
|
||||||
|
@ -416,6 +420,8 @@ jmp .error
|
||||||
.contcheck3:
|
.contcheck3:
|
||||||
cmp al, 0x7c
|
cmp al, 0x7c
|
||||||
je .error
|
je .error
|
||||||
|
|
||||||
|
;Check for lower case and convert it to upper case
|
||||||
;Check for lower case
|
;Check for lower case
|
||||||
cmp al, 0x61
|
cmp al, 0x61
|
||||||
jl .storech
|
jl .storech
|
||||||
|
@ -423,30 +429,50 @@ cmp al, 0x7a
|
||||||
jg .storech
|
jg .storech
|
||||||
;Convert lower to upper case
|
;Convert lower to upper case
|
||||||
sub al, 0x20
|
sub al, 0x20
|
||||||
.storech:
|
|
||||||
;Store the character
|
;Store the character
|
||||||
|
.storech:
|
||||||
stosb
|
stosb
|
||||||
|
|
||||||
;Decrease the counter
|
;Decrease the counter
|
||||||
dec bl
|
dec bl
|
||||||
|
|
||||||
|
;Return
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
;***
|
||||||
|
|
||||||
;Calculate the source arguments for loading data from the disk
|
;Calculate the source arguments for loading data from the disk
|
||||||
.calcsource:
|
.calcsource:
|
||||||
|
|
||||||
|
;Store AX and BX in the stack
|
||||||
push ax
|
push ax
|
||||||
push bx
|
push bx
|
||||||
|
|
||||||
|
;Calculate the cylinder, head, and sector
|
||||||
|
;Store the logical sector in BX
|
||||||
mov bx, ax
|
mov bx, ax
|
||||||
|
;Calculate the sector
|
||||||
mov dx, 0x0
|
mov dx, 0x0
|
||||||
div word [.sectorspertrack]
|
div word [.sectorspertrack]
|
||||||
add dl, 0x1
|
add dl, 0x1
|
||||||
mov cl, dl
|
mov cl, dl
|
||||||
|
;Load the logical sector from BX
|
||||||
mov ax, bx
|
mov ax, bx
|
||||||
|
;Calculate the head and cylinder
|
||||||
mov dx, 0x0
|
mov dx, 0x0
|
||||||
div word [.sectorspertrack]
|
div word [.sectorspertrack]
|
||||||
mov dx, 0x0
|
mov dx, 0x0
|
||||||
div word [.sides]
|
div word [.heads]
|
||||||
mov dh, dl
|
mov dh, dl ;Head
|
||||||
mov ch, al
|
mov ch, al ;Cylinder
|
||||||
|
|
||||||
|
;Load the drive number
|
||||||
|
mov dl, byte [.drive]
|
||||||
|
|
||||||
|
;Load BX and AX from the stack
|
||||||
pop bx
|
pop bx
|
||||||
pop ax
|
pop ax
|
||||||
mov dl, byte [.drive]
|
|
||||||
|
;Return
|
||||||
ret
|
ret
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
CPU 8086
|
cpu 8086
|
||||||
ORG 0x3000
|
org 0x3000
|
||||||
|
|
||||||
;Load a file and print it
|
;Load a file and print it
|
||||||
|
|
||||||
|
@ -11,17 +11,16 @@ sti
|
||||||
;Check for an empty tail
|
;Check for an empty tail
|
||||||
;Check
|
;Check
|
||||||
cmp byte [si], 0x0
|
cmp byte [si], 0x0
|
||||||
jne start
|
jne extract
|
||||||
;Print an error message and abort if the tail is empty
|
;Print an error message and abort if the tail is empty
|
||||||
mov si, errormsg
|
mov si, errormsg
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x21
|
int 0x21
|
||||||
je done
|
je done
|
||||||
|
|
||||||
start:
|
|
||||||
|
|
||||||
;Find the end of the filename and add a null if needed
|
;Find the end of the filename and add a null if needed
|
||||||
;Set DI at the tail
|
;Set DI at the tail
|
||||||
|
extract:
|
||||||
mov di, si
|
mov di, si
|
||||||
findend:
|
findend:
|
||||||
;Check for the string end
|
;Check for the string end
|
||||||
|
@ -32,13 +31,14 @@ cmp byte [di], 0x20
|
||||||
je addnull
|
je addnull
|
||||||
inc di
|
inc di
|
||||||
jmp findend
|
jmp findend
|
||||||
|
;Add a null
|
||||||
addnull:
|
addnull:
|
||||||
mov al, 0x0
|
mov al, 0x0
|
||||||
stosb
|
stosb
|
||||||
|
|
||||||
;Load the file
|
;Load the file
|
||||||
load:
|
|
||||||
;Load
|
;Load
|
||||||
|
load:
|
||||||
mov bx, stack + 0x100
|
mov bx, stack + 0x100
|
||||||
mov ah, 0x0
|
mov ah, 0x0
|
||||||
int 0x22
|
int 0x22
|
||||||
|
@ -52,8 +52,8 @@ mov bh, 0x0
|
||||||
mov bl, 0x18
|
mov bl, 0x18
|
||||||
mov dl, 0x50
|
mov dl, 0x50
|
||||||
mov si, stack + 0x100
|
mov si, stack + 0x100
|
||||||
print:
|
|
||||||
;Decrease the character counter
|
;Decrease the character counter
|
||||||
|
print:
|
||||||
dec dl
|
dec dl
|
||||||
;Load the current character
|
;Load the current character
|
||||||
lodsb
|
lodsb
|
||||||
|
@ -66,8 +66,8 @@ je linecount
|
||||||
;Check for a soft line end
|
;Check for a soft line end
|
||||||
cmp dl, 0x0
|
cmp dl, 0x0
|
||||||
je linecount
|
je linecount
|
||||||
contprint:
|
|
||||||
;Check paging
|
;Check paging
|
||||||
|
contprint:
|
||||||
cmp bl, 0x0
|
cmp bl, 0x0
|
||||||
jz page
|
jz page
|
||||||
;Repeat for the next character
|
;Repeat for the next character
|
||||||
|
@ -83,15 +83,19 @@ page:
|
||||||
push ax
|
push ax
|
||||||
mov ah, 0x0
|
mov ah, 0x0
|
||||||
int 0x16
|
int 0x16
|
||||||
|
cmp al, 0x1b
|
||||||
|
je done
|
||||||
pop ax
|
pop ax
|
||||||
mov bl, 0x18
|
mov bl, 0x18
|
||||||
mov dl, 0x50
|
mov dl, 0x50
|
||||||
loop print
|
loop print
|
||||||
|
|
||||||
|
;Return to the system
|
||||||
done:
|
done:
|
||||||
int 0x20
|
int 0x20
|
||||||
|
|
||||||
;Data
|
;Data
|
||||||
errormsg db "File not found", 0x0
|
errormsg db "File not found", 0x0
|
||||||
|
|
||||||
|
;Stack
|
||||||
stack:
|
stack:
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
;Print a string ending in a null from SI followed by a CRLF.
|
;Print a string ending in a null from SI followed by a CRLF.
|
||||||
|
|
||||||
println:
|
println:
|
||||||
|
|
||||||
;Print the string
|
;Print the string
|
||||||
|
@ -9,4 +8,5 @@ int 0x21
|
||||||
;Print a CRLF
|
;Print a CRLF
|
||||||
call printcrlf
|
call printcrlf
|
||||||
|
|
||||||
|
;Return
|
||||||
iret
|
iret
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
;Print a string ending in a null from SI.
|
;Print a string ending in a null from SI.
|
||||||
|
|
||||||
printstr:
|
printstr:
|
||||||
|
|
||||||
;Store the initial registers in the stack
|
;Store AX and SI in the stack
|
||||||
push ax
|
push ax
|
||||||
push si
|
push si
|
||||||
|
|
||||||
;Print the string
|
;Print the string
|
||||||
.loop:
|
|
||||||
;Load the current character
|
;Load the current character
|
||||||
|
.loop:
|
||||||
lodsb
|
lodsb
|
||||||
;Check for the string end
|
;Check for the string end
|
||||||
cmp al, 0x0
|
cmp al, 0x0
|
||||||
|
@ -16,13 +15,13 @@ je .done
|
||||||
;Print the character
|
;Print the character
|
||||||
mov ah, 0xe
|
mov ah, 0xe
|
||||||
int 0x10
|
int 0x10
|
||||||
;Repeat for the next character
|
;Print the next character
|
||||||
jmp .loop
|
jmp .loop
|
||||||
|
|
||||||
.done:
|
|
||||||
|
|
||||||
;Load the initial registers from the stack
|
;Load the initial registers from the stack
|
||||||
|
.done:
|
||||||
pop si
|
pop si
|
||||||
pop ax
|
pop ax
|
||||||
|
|
||||||
|
;Return
|
||||||
iret
|
iret
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
;Read a string ending in a null of at most AL characters to DI until a
|
;Read a string ending in a null of at most AL characters to DI until a
|
||||||
;return and print a CRLF.
|
;return and print a CRLF.
|
||||||
|
|
||||||
readln:
|
readln:
|
||||||
|
|
||||||
;Read the string
|
;Read the string
|
||||||
|
@ -10,4 +9,5 @@ int 0x21
|
||||||
;Print a CRLF
|
;Print a CRLF
|
||||||
call printcrlf
|
call printcrlf
|
||||||
|
|
||||||
|
;Return
|
||||||
iret
|
iret
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
;Read a string ending in a null of at most AL characters to DI until a
|
;Read a string ending in a null of at most AL characters to DI until a
|
||||||
;return.
|
;return.
|
||||||
|
|
||||||
readstr:
|
readstr:
|
||||||
|
|
||||||
;Store the initial registers in the stack
|
;Store AX, BX, CX, DX, and DI in the stack
|
||||||
push ax
|
push ax
|
||||||
push bx
|
push bx
|
||||||
push cx
|
push cx
|
||||||
|
@ -26,12 +25,11 @@ mov ah, 0xf
|
||||||
int 0x10
|
int 0x10
|
||||||
dec ah
|
dec ah
|
||||||
mov [.lastcolumn], ah
|
mov [.lastcolumn], ah
|
||||||
;Initialise the cursor pointer in BL and clear BH
|
;Set the cursor pointer in BL and clear BH
|
||||||
mov bx, 0x1
|
mov bx, 0x1
|
||||||
|
|
||||||
.loop:
|
|
||||||
|
|
||||||
;Read a keypress
|
;Read a keypress
|
||||||
|
.loop:
|
||||||
mov ah, 0x0
|
mov ah, 0x0
|
||||||
int 0x16
|
int 0x16
|
||||||
|
|
||||||
|
@ -87,29 +85,27 @@ jmp .loop
|
||||||
;Check for the input beginning
|
;Check for the input beginning
|
||||||
cmp bl, 0x1
|
cmp bl, 0x1
|
||||||
je .loop
|
je .loop
|
||||||
;Move
|
;Move the cursor
|
||||||
call .prevchar
|
call .prevchar
|
||||||
dec di
|
dec di
|
||||||
dec bl
|
dec bl
|
||||||
jmp .loop
|
jmp .loop
|
||||||
|
|
||||||
;Finish reading the string
|
|
||||||
.return:
|
|
||||||
|
|
||||||
;Check for and remove trailing spaces
|
;Check for and remove trailing spaces
|
||||||
;Go to the end of the input
|
;Go to the end of the input
|
||||||
|
.return:
|
||||||
pop ax
|
pop ax
|
||||||
mov bh, 0x0
|
mov bh, 0x0
|
||||||
sub ax, bx
|
sub ax, bx
|
||||||
push di
|
push di
|
||||||
add di, ax
|
add di, ax
|
||||||
|
;Check for trailing spaces
|
||||||
.findtrailing:
|
.findtrailing:
|
||||||
;Check
|
|
||||||
cmp byte [di], 0x20
|
cmp byte [di], 0x20
|
||||||
je .deltrailing
|
je .deltrailing
|
||||||
jmp .end
|
jmp .end
|
||||||
|
;Remove trailing spaces
|
||||||
.deltrailing:
|
.deltrailing:
|
||||||
;Remove
|
|
||||||
mov al, 0x0
|
mov al, 0x0
|
||||||
stosb
|
stosb
|
||||||
sub di, 0x2
|
sub di, 0x2
|
||||||
|
@ -128,49 +124,57 @@ inc di
|
||||||
inc bl
|
inc bl
|
||||||
jmp .findend
|
jmp .findend
|
||||||
|
|
||||||
|
;Load DI, DX, CX, BX, and AX from the stack
|
||||||
.done:
|
.done:
|
||||||
|
|
||||||
;Load the initial registers from the stack
|
|
||||||
pop di
|
pop di
|
||||||
pop dx
|
pop dx
|
||||||
pop cx
|
pop cx
|
||||||
pop bx
|
pop bx
|
||||||
pop ax
|
pop ax
|
||||||
|
|
||||||
|
;Return
|
||||||
iret
|
iret
|
||||||
|
|
||||||
;Data
|
;Data
|
||||||
.lastcolumn db 0x0
|
.lastcolumn db 0x0
|
||||||
|
|
||||||
;Move the cursor forward within a line
|
;***
|
||||||
|
|
||||||
|
;Move the cursor forward
|
||||||
.nextchar:
|
.nextchar:
|
||||||
|
|
||||||
;Get the cursor position
|
;Get the cursor position
|
||||||
mov ah, 0x3
|
mov ah, 0x3
|
||||||
int 0x10
|
int 0x10
|
||||||
|
|
||||||
;Check for the end of the line
|
;Check for the end of the line
|
||||||
cmp dl, [.lastcolumn]
|
cmp dl, [.lastcolumn]
|
||||||
je .nextln
|
je .nextln
|
||||||
;Move
|
|
||||||
|
;Move the cursor forward within a line
|
||||||
inc dl
|
inc dl
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x10
|
int 0x10
|
||||||
|
|
||||||
|
;Return
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;Move the cursor to the beginning of the next line
|
;Move the cursor to the beginning of the next line
|
||||||
.nextln:
|
|
||||||
;Check if the current line is the last on screen
|
;Check if the current line is the last on screen
|
||||||
|
.nextln:
|
||||||
cmp dh, 0x18
|
cmp dh, 0x18
|
||||||
je .scroll
|
je .scroll
|
||||||
;Move
|
;Move the cursor
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
inc dh
|
inc dh
|
||||||
mov dl, 0x0
|
mov dl, 0x0
|
||||||
int 0x10
|
int 0x10
|
||||||
|
|
||||||
|
;Return
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;Scroll the screen up by one line
|
;Scroll the screen up by one line
|
||||||
.scroll:
|
.scroll:
|
||||||
;Scroll
|
|
||||||
mov ah, 0x6
|
mov ah, 0x6
|
||||||
mov al, 0x1
|
mov al, 0x1
|
||||||
mov bh, 0x7
|
mov bh, 0x7
|
||||||
|
@ -179,25 +183,35 @@ mov cl, 0x0
|
||||||
mov dh, 0x18
|
mov dh, 0x18
|
||||||
mov dl, [.lastcolumn]
|
mov dl, [.lastcolumn]
|
||||||
int 0x10
|
int 0x10
|
||||||
|
|
||||||
;Move to the beginning of the new line
|
;Move to the beginning of the new line
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
mov bh, 0x0
|
mov bh, 0x0
|
||||||
mov dl, 0x0
|
mov dl, 0x0
|
||||||
int 0x10
|
int 0x10
|
||||||
|
|
||||||
|
;Return
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;Move the cursor backward within a line
|
;***
|
||||||
|
|
||||||
|
;Move the cursor backward
|
||||||
.prevchar:
|
.prevchar:
|
||||||
|
|
||||||
;Get the cursor position
|
;Get the cursor position
|
||||||
mov ah, 0x3
|
mov ah, 0x3
|
||||||
int 0x10
|
int 0x10
|
||||||
|
|
||||||
;Check for the beginning of the line
|
;Check for the beginning of the line
|
||||||
cmp dl, 0x0
|
cmp dl, 0x0
|
||||||
je .prevln
|
je .prevln
|
||||||
;Move
|
|
||||||
|
;Move the cursor backward within a line
|
||||||
dec dl
|
dec dl
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x10
|
int 0x10
|
||||||
|
|
||||||
|
;Return
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;Move the cursor to the end of the previous line
|
;Move the cursor to the end of the previous line
|
||||||
|
@ -206,4 +220,6 @@ mov ah, 0x2
|
||||||
dec dh
|
dec dh
|
||||||
mov dl, [.lastcolumn]
|
mov dl, [.lastcolumn]
|
||||||
int 0x10
|
int 0x10
|
||||||
|
|
||||||
|
;Return
|
||||||
ret
|
ret
|
||||||
|
|
166
src/SYSTEM.ASM
166
src/SYSTEM.ASM
|
@ -1,6 +1,7 @@
|
||||||
CPU 8086
|
cpu 8086
|
||||||
ORG 0x500
|
org 0x500
|
||||||
|
|
||||||
|
;Jump to the code
|
||||||
jmp start
|
jmp start
|
||||||
|
|
||||||
;Interrupt handler
|
;Interrupt handler
|
||||||
|
@ -25,17 +26,16 @@ je loadf
|
||||||
;To do: savef
|
;To do: savef
|
||||||
iret
|
iret
|
||||||
|
|
||||||
;System calls
|
;System call includes
|
||||||
%include "PRINTSTR.INC"
|
%include "PRINTSTR.INC"
|
||||||
%include "READSTR.INC"
|
%include "READSTR.INC"
|
||||||
%include "PRINTLN.INC"
|
%include "PRINTLN.INC"
|
||||||
%include "READLN.INC"
|
%include "READLN.INC"
|
||||||
%include "LOADF.INC"
|
%include "LOADF.INC"
|
||||||
|
|
||||||
start:
|
|
||||||
|
|
||||||
;Set up the interrupt vectors
|
;Set up the interrupt vectors
|
||||||
;Interrupt 0x20 offset
|
;Interrupt 0x20 offset
|
||||||
|
start:
|
||||||
mov ax, int0x20
|
mov ax, int0x20
|
||||||
mov [0x80], ax
|
mov [0x80], ax
|
||||||
;Interrupt 0x21 offset
|
;Interrupt 0x21 offset
|
||||||
|
@ -110,10 +110,10 @@ mov cx, 0xe
|
||||||
mov al, 0x20
|
mov al, 0x20
|
||||||
rep stosb
|
rep stosb
|
||||||
sub di, 0xe
|
sub di, 0xe
|
||||||
;Initialise the length counter
|
;Set the length counter
|
||||||
mov bl, 0xa
|
mov bl, 0xa
|
||||||
specloop:
|
|
||||||
;Load a character
|
;Load a character
|
||||||
|
specloop:
|
||||||
lodsb
|
lodsb
|
||||||
;Check for the string end
|
;Check for the string end
|
||||||
cmp al, 0x0
|
cmp al, 0x0
|
||||||
|
@ -128,16 +128,18 @@ je cmderror
|
||||||
stosb
|
stosb
|
||||||
;Decrease the counter
|
;Decrease the counter
|
||||||
dec bl
|
dec bl
|
||||||
|
;Extract the next character
|
||||||
jmp specloop
|
jmp specloop
|
||||||
;Add extension to the name
|
;Store the start of the command tail in the stack
|
||||||
addext:
|
addext:
|
||||||
push si
|
push si
|
||||||
|
;Add extension to the specification
|
||||||
mov si, extension
|
mov si, extension
|
||||||
mov cx, 0x5
|
mov cx, 0x5
|
||||||
rep movsb
|
rep movsb
|
||||||
|
|
||||||
;Load and execute the program
|
;Load and execute the program
|
||||||
;Load
|
;Load the program
|
||||||
mov bx, 0x3000
|
mov bx, 0x3000
|
||||||
mov si, program
|
mov si, program
|
||||||
mov ah, 0x0
|
mov ah, 0x0
|
||||||
|
@ -149,9 +151,43 @@ jne shell
|
||||||
mov dl, [drive]
|
mov dl, [drive]
|
||||||
pop si
|
pop si
|
||||||
call ignoreleading
|
call ignoreleading
|
||||||
;Execute
|
;Execute the program
|
||||||
jmp 0x3000
|
jmp 0x3000
|
||||||
|
|
||||||
|
;Change the drive
|
||||||
|
;Get the BIOS equipment list
|
||||||
|
changedrive:
|
||||||
|
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 a drive error message and return to the shell
|
||||||
|
mov si, driverrormsg
|
||||||
|
mov ah, 0x2
|
||||||
|
int 0x21
|
||||||
|
jmp shell
|
||||||
|
;Change the drive
|
||||||
|
contchdrive:
|
||||||
|
mov [drive], dl
|
||||||
|
call setdriveletter
|
||||||
|
jmp shell
|
||||||
|
|
||||||
;Print a command error message and return to the shell
|
;Print a command error message and return to the shell
|
||||||
cmderror:
|
cmderror:
|
||||||
mov si, cmderrormsg
|
mov si, cmderrormsg
|
||||||
|
@ -159,56 +195,11 @@ mov ah, 0x2
|
||||||
int 0x21
|
int 0x21
|
||||||
jmp shell
|
jmp shell
|
||||||
|
|
||||||
;Change the drive
|
|
||||||
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 a drive error message and return to the shell
|
|
||||||
mov si, driverrormsg
|
|
||||||
mov ah, 0x2
|
|
||||||
int 0x21
|
|
||||||
jmp shell
|
|
||||||
;Change
|
|
||||||
cha:
|
|
||||||
mov dl, 0x0
|
|
||||||
mov [drive], dl
|
|
||||||
call setdriveletter
|
|
||||||
jmp shell
|
|
||||||
chb:
|
|
||||||
mov dl, 0x1
|
|
||||||
mov [drive], dl
|
|
||||||
call setdriveletter
|
|
||||||
jmp shell
|
|
||||||
chc:
|
|
||||||
mov dl, 0x2
|
|
||||||
mov [drive], dl
|
|
||||||
call setdriveletter
|
|
||||||
jmp shell
|
|
||||||
chd:
|
|
||||||
mov dl, 0x3
|
|
||||||
mov [drive], dl
|
|
||||||
call setdriveletter
|
|
||||||
jmp shell
|
|
||||||
|
|
||||||
;Data
|
;Data
|
||||||
welcomemsg db 0xd, 0xa, "Welcome to EttinOS!", 0xd, 0xa, 0x0
|
welcomemsg db 0xd, 0xa, "Welcome to EttinOS!", 0xd, 0xa, 0x0
|
||||||
drive db 0x0
|
drive db 0x0
|
||||||
driveletter db "?:", 0x0
|
driveletter db "?:", 0x0
|
||||||
|
driveletters db "AaBbCcDd"
|
||||||
prompt db "> ", 0x0
|
prompt db "> ", 0x0
|
||||||
input times 0x4c db 0x0
|
input times 0x4c db 0x0
|
||||||
program times 0xf db 0x0
|
program times 0xf db 0x0
|
||||||
|
@ -216,53 +207,70 @@ extension db ".BIN", 0x0
|
||||||
cmderrormsg db "File or command not found", 0x0
|
cmderrormsg db "File or command not found", 0x0
|
||||||
driverrormsg db "Drive not found", 0x0
|
driverrormsg db "Drive not found", 0x0
|
||||||
|
|
||||||
|
;***
|
||||||
|
|
||||||
;Set the drive letter
|
;Set the drive letter
|
||||||
setdriveletter:
|
setdriveletter:
|
||||||
|
|
||||||
|
;Set the drive number and letter counters
|
||||||
|
mov dh, 0x0
|
||||||
|
mov si, driveletters
|
||||||
|
|
||||||
;Check the drive number
|
;Check the drive number
|
||||||
cmp dl, 0x0
|
.checkdrive:
|
||||||
je .seta
|
cmp dl, dh
|
||||||
cmp dl, 0x1
|
je .set
|
||||||
je .setb
|
add si, 0x2
|
||||||
cmp dl, 0x2
|
inc dh
|
||||||
je .setc
|
jmp .checkdrive
|
||||||
cmp dl, 0x3
|
|
||||||
je .setd
|
;Set the drive letter
|
||||||
ret
|
.set:
|
||||||
;Set
|
mov al, [si]
|
||||||
.seta:
|
mov byte [driveletter], al
|
||||||
mov byte [driveletter], "A"
|
|
||||||
ret
|
;Return
|
||||||
.setb:
|
|
||||||
mov byte [driveletter], "B"
|
|
||||||
ret
|
|
||||||
.setc:
|
|
||||||
mov byte [driveletter], "C"
|
|
||||||
ret
|
|
||||||
.setd:
|
|
||||||
mov byte [driveletter], "D"
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
;***
|
||||||
|
|
||||||
;Ignore leading spaces in the command and its tail
|
;Ignore leading spaces in the command and its tail
|
||||||
ignoreleading:
|
ignoreleading:
|
||||||
|
|
||||||
|
;Check for a space
|
||||||
lodsb
|
lodsb
|
||||||
cmp al, 0x20
|
cmp al, 0x20
|
||||||
je ignoreleading
|
je ignoreleading
|
||||||
|
|
||||||
|
;Set SI to the first non-space character
|
||||||
dec si
|
dec si
|
||||||
|
|
||||||
|
;Return
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
;***
|
||||||
|
|
||||||
;Print a CRLF
|
;Print a CRLF
|
||||||
printcrlf:
|
printcrlf:
|
||||||
;Store the initial registers in the stack
|
|
||||||
|
;Store SI in the stack
|
||||||
push si
|
push si
|
||||||
|
|
||||||
;Print the CRLF
|
;Print the CRLF
|
||||||
mov si, .crlf
|
mov si, .crlf
|
||||||
mov ah, 0x0
|
mov ah, 0x0
|
||||||
int 0x21
|
int 0x21
|
||||||
;Load the initial registers from the stack
|
|
||||||
|
;Load SI from the stack
|
||||||
pop si
|
pop si
|
||||||
|
|
||||||
|
;Return
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;Data
|
;Data
|
||||||
.crlf db 0xd, 0xa, 0x0
|
.crlf db 0xd, 0xa, 0x0
|
||||||
|
|
||||||
|
;***
|
||||||
|
|
||||||
;File system buffer
|
;File system buffer
|
||||||
buffer:
|
buffer:
|
||||||
|
|
Loading…
Reference in New Issue