2021-06-22 13:05:09 +00:00
|
|
|
CPU 8086
|
|
|
|
ORG 0x500
|
|
|
|
|
|
|
|
jmp start
|
|
|
|
|
|
|
|
;Interrupt handler
|
|
|
|
;Return to the shell
|
|
|
|
int0x20:
|
|
|
|
jmp shell
|
|
|
|
;Input and output
|
|
|
|
int0x21:
|
|
|
|
cmp ah, 0x0
|
|
|
|
je printstr
|
|
|
|
cmp ah, 0x1
|
|
|
|
je readstr
|
|
|
|
cmp ah, 0x2
|
|
|
|
je println
|
|
|
|
cmp ah, 0x3
|
|
|
|
je readln
|
|
|
|
iret
|
|
|
|
;Disk operations
|
|
|
|
int0x22:
|
|
|
|
cmp ah, 0x0
|
|
|
|
je loadf
|
|
|
|
;To do: savef
|
|
|
|
iret
|
|
|
|
|
|
|
|
;System calls
|
|
|
|
%include "PRINTSTR.INC"
|
|
|
|
%include "READSTR.INC"
|
|
|
|
%include "PRINTLN.INC"
|
|
|
|
%include "READLN.INC"
|
|
|
|
%include "LOADF.INC"
|
|
|
|
|
|
|
|
start:
|
|
|
|
|
|
|
|
;Set up the interrupt vectors
|
|
|
|
;Interrupt 0x20 offset
|
|
|
|
mov ax, int0x20
|
|
|
|
mov [0x80], ax
|
|
|
|
;Interrupt 0x21 offset
|
|
|
|
mov ax, int0x21
|
|
|
|
mov [0x84], ax
|
|
|
|
;Interrupt 0x22 offset
|
|
|
|
mov ax, int0x22
|
|
|
|
mov [0x88], ax
|
|
|
|
;Segments
|
|
|
|
mov ax, 0x0
|
|
|
|
mov [0x82], ax
|
|
|
|
mov [0x86], ax
|
|
|
|
mov [0x8a], ax
|
|
|
|
|
2021-06-24 16:31:15 +00:00
|
|
|
;Store the boot drive number and set the drive letter
|
2021-06-24 15:34:41 +00:00
|
|
|
mov [drive], dl
|
2021-06-24 16:31:15 +00:00
|
|
|
call setdriveletter
|
2021-06-24 15:34:41 +00:00
|
|
|
|
2021-06-22 13:05:09 +00:00
|
|
|
;Print a welcome message
|
|
|
|
mov si, welcomemsg
|
|
|
|
mov ah, 0x2
|
|
|
|
int 0x21
|
|
|
|
|
|
|
|
shell:
|
|
|
|
|
|
|
|
;Re-set the stack
|
|
|
|
cli
|
|
|
|
mov sp, 0x0
|
|
|
|
sti
|
|
|
|
|
|
|
|
;Prompt for and read a command
|
2021-06-24 16:31:15 +00:00
|
|
|
;Print the drive letter
|
|
|
|
mov si, driveletter
|
|
|
|
mov ah, 0x0
|
|
|
|
int 0x21
|
2021-06-22 13:05:09 +00:00
|
|
|
;Print a prompt
|
|
|
|
mov si, prompt
|
|
|
|
mov ah, 0x0
|
|
|
|
int 0x21
|
|
|
|
;Read
|
|
|
|
mov di, input
|
2021-06-24 17:30:49 +00:00
|
|
|
mov al, 0x4c
|
2021-06-22 13:05:09 +00:00
|
|
|
mov ah, 0x3
|
|
|
|
int 0x21
|
|
|
|
|
2021-06-24 16:31:15 +00:00
|
|
|
;Check for non-program stuff
|
2021-06-22 13:05:09 +00:00
|
|
|
;Check for an empty command
|
|
|
|
cmp byte [input], 0x0
|
|
|
|
jz shell
|
2021-06-24 16:31:15 +00:00
|
|
|
;Check for a drive change command
|
2021-06-25 11:35:15 +00:00
|
|
|
mov si, input + 0x1
|
|
|
|
mov di, driveletter + 0x1
|
2021-06-24 16:31:15 +00:00
|
|
|
call cmpstr
|
|
|
|
jnc changedrive
|
|
|
|
|
2021-06-25 11:35:15 +00:00
|
|
|
;Extract the program name
|
|
|
|
;Set SI at input and DI at program
|
|
|
|
mov si, input
|
|
|
|
mov di, program
|
|
|
|
;Ignore leading spaces
|
|
|
|
call ignoreleading
|
|
|
|
;Initialise program with spaces
|
|
|
|
mov cx, 0xc
|
|
|
|
mov al, 0x20
|
|
|
|
rep stosb
|
|
|
|
sub di, 0xc
|
|
|
|
;Initialise the length counter
|
|
|
|
mov bl, 0x8
|
|
|
|
extractprog:
|
|
|
|
;Load a character
|
|
|
|
lodsb
|
|
|
|
;Check for the string end
|
|
|
|
cmp al, 0x0
|
|
|
|
je addext
|
|
|
|
;Check for a space
|
|
|
|
cmp al, 0x20
|
|
|
|
je addext
|
|
|
|
;Check for the length limit
|
|
|
|
cmp bl, 0x0
|
|
|
|
je cmderror
|
|
|
|
;Store the character
|
|
|
|
stosb
|
|
|
|
;Decrease the counter
|
|
|
|
dec bl
|
|
|
|
jmp extractprog
|
|
|
|
;Add extension to the name
|
|
|
|
addext:
|
|
|
|
push si
|
|
|
|
mov si, extension
|
|
|
|
mov cx, 0x5
|
2021-06-25 17:24:38 +00:00
|
|
|
rep movsb
|
2021-06-25 11:35:15 +00:00
|
|
|
|
|
|
|
;Load and execute the program
|
2021-06-22 13:05:09 +00:00
|
|
|
;Load
|
|
|
|
mov bx, 0x2000
|
2021-06-25 11:35:15 +00:00
|
|
|
;mov si, input
|
|
|
|
mov si, program
|
2021-06-22 13:05:09 +00:00
|
|
|
mov ah, 0x0
|
|
|
|
int 0x22
|
|
|
|
;Check for errors
|
|
|
|
cmp al, 0x1
|
2021-06-24 16:31:15 +00:00
|
|
|
je cmderror
|
2021-06-25 11:35:15 +00:00
|
|
|
;Pass the command tail to the program
|
|
|
|
pop si
|
|
|
|
call ignoreleading
|
2021-06-22 13:05:09 +00:00
|
|
|
;Execute
|
|
|
|
jmp 0x2000
|
|
|
|
|
2021-06-24 16:31:15 +00:00
|
|
|
;Print a command error message and return to the shell
|
|
|
|
cmderror:
|
|
|
|
mov si, cmderrormsg
|
2021-06-22 13:05:09 +00:00
|
|
|
mov ah, 0x2
|
|
|
|
int 0x21
|
|
|
|
jmp shell
|
|
|
|
|
2021-06-24 16:31:15 +00:00
|
|
|
;Change the drive
|
|
|
|
changedrive:
|
|
|
|
;Check which drive to change to
|
|
|
|
cmp byte [input], "a"
|
|
|
|
je .a
|
|
|
|
cmp byte [input], "A"
|
|
|
|
je .a
|
|
|
|
cmp byte [input], "b"
|
|
|
|
je .b
|
|
|
|
cmp byte [input], "B"
|
|
|
|
je .b
|
|
|
|
cmp byte [input], "c"
|
|
|
|
je .c
|
|
|
|
cmp byte [input], "C"
|
|
|
|
je .c
|
|
|
|
cmp byte [input], "d"
|
|
|
|
je .d
|
|
|
|
cmp byte [input], "D"
|
|
|
|
je .d
|
|
|
|
;Print a drive error message and return to the shell
|
|
|
|
mov si, driverrormsg
|
|
|
|
mov ah, 0x2
|
|
|
|
int 0x21
|
|
|
|
jmp shell
|
|
|
|
;Change
|
|
|
|
.a:
|
|
|
|
mov dl, 0x0
|
|
|
|
mov byte [drive], dl
|
|
|
|
call setdriveletter
|
|
|
|
jmp shell
|
|
|
|
.b:
|
|
|
|
mov dl, 0x1
|
|
|
|
mov byte [drive], dl
|
|
|
|
call setdriveletter
|
|
|
|
jmp shell
|
|
|
|
.c:
|
|
|
|
mov dl, 0x2
|
|
|
|
mov byte [drive], dl
|
|
|
|
call setdriveletter
|
|
|
|
jmp shell
|
|
|
|
.d:
|
|
|
|
mov dl, 0x3
|
|
|
|
mov byte [drive], dl
|
|
|
|
call setdriveletter
|
|
|
|
jmp shell
|
|
|
|
|
2021-06-22 13:05:09 +00:00
|
|
|
;Data
|
2021-06-25 11:35:15 +00:00
|
|
|
welcomemsg db 0xd, 0xa, "Welcome to EttinOS!", 0xd, 0xa, 0x0
|
2021-06-24 16:31:15 +00:00
|
|
|
drive db 0x0
|
|
|
|
driveletter db "?:", 0x0
|
|
|
|
prompt db "> ", 0x0
|
2021-06-24 17:30:49 +00:00
|
|
|
input times 0x4c db 0x0
|
2021-06-25 11:35:15 +00:00
|
|
|
program times 0xd db 0x0
|
|
|
|
extension db ".BIN", 0x0
|
|
|
|
cmderrormsg db "Unknown command", 0x0
|
|
|
|
driverrormsg db "Unknown drive", 0x0
|
2021-06-24 16:31:15 +00:00
|
|
|
crlf db 0xd, 0xa, 0x0
|
|
|
|
|
|
|
|
;Set the drive letter
|
|
|
|
setdriveletter:
|
|
|
|
;Check the drive number
|
|
|
|
cmp dl, 0x0
|
|
|
|
je .a
|
|
|
|
cmp dl, 0x1
|
|
|
|
je .b
|
|
|
|
cmp dl, 0x2
|
|
|
|
je .c
|
|
|
|
cmp dl, 0x3
|
|
|
|
je .d
|
|
|
|
ret
|
|
|
|
;Set
|
|
|
|
.a:
|
|
|
|
mov byte [driveletter], "A"
|
|
|
|
ret
|
|
|
|
.b:
|
|
|
|
mov byte [driveletter], "B"
|
|
|
|
ret
|
|
|
|
.c:
|
|
|
|
mov byte [driveletter], "C"
|
|
|
|
ret
|
|
|
|
.d:
|
|
|
|
mov byte [driveletter], "D"
|
|
|
|
ret
|
|
|
|
|
|
|
|
;Compare two strings ending in a null at SI and DI and clear the carry flag if they are equal and set it if not
|
|
|
|
cmpstr:
|
|
|
|
;Store the initial registers in the stack
|
|
|
|
push ax
|
|
|
|
push bx
|
|
|
|
;Compare the strings
|
|
|
|
.loop:
|
|
|
|
;Load the current characters
|
|
|
|
mov al, [si]
|
|
|
|
mov bl, [di]
|
|
|
|
;Compare the characters
|
|
|
|
cmp al, bl
|
|
|
|
;Check for difference
|
|
|
|
jne .neq
|
|
|
|
;Check for the string end
|
|
|
|
cmp al, 0x0
|
|
|
|
je .eq
|
|
|
|
;Repeat for the next characters
|
|
|
|
inc si
|
|
|
|
inc di
|
|
|
|
jmp .loop
|
|
|
|
;Clear the carry flag
|
|
|
|
.eq:
|
|
|
|
clc
|
|
|
|
jmp .done
|
|
|
|
;Set the carry flag
|
|
|
|
.neq:
|
|
|
|
stc
|
|
|
|
.done:
|
|
|
|
;Load the initial registers from the stack
|
|
|
|
pop bx
|
|
|
|
pop ax
|
|
|
|
ret
|
2021-06-22 13:05:09 +00:00
|
|
|
|
2021-06-25 11:35:15 +00:00
|
|
|
;Ignore leading spaces in the command and its tail
|
|
|
|
ignoreleading:
|
|
|
|
lodsb
|
|
|
|
cmp al, 0x20
|
|
|
|
je ignoreleading
|
|
|
|
dec si
|
|
|
|
ret
|
|
|
|
|
2021-06-22 13:05:09 +00:00
|
|
|
;Print a CRLF
|
|
|
|
printcrlf:
|
|
|
|
;Store the initial registers in the stack
|
|
|
|
push si
|
|
|
|
;Print the CRLF
|
|
|
|
mov si, crlf
|
|
|
|
mov ah, 0x0
|
|
|
|
int 0x21
|
|
|
|
;Load the initial registers from the stack
|
|
|
|
pop si
|
|
|
|
ret
|
|
|
|
|
|
|
|
;File system buffer
|
|
|
|
buffer:
|