EttinOS/src/SYSTEM.ASM

276 lines
4.2 KiB
NASM
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.

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
;Store the boot drive number and set the drive letter
mov [drive], dl
call setdriveletter
;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
;Print the drive letter
mov si, driveletter
mov ah, 0x0
int 0x21
;Print a prompt
mov si, prompt
mov ah, 0x0
int 0x21
;Read
mov di, input
mov al, 0x4c
mov ah, 0x3
int 0x21
;Check for an empty command
cmp byte [input], 0x0
jz shell
;Check for a drive change command
;Set SI at input
mov si, input
;Ignore leading spaces
call ignoreleading
;Check
cmp byte [si + 0x1], ":"
jne extract
cmp byte [si + 0x2], 0x0
je changedrive
cmp byte [si + 0x2], 0x20
je changedrive
;Extract the specification of the program file
extract:
;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, 0xe
mov al, 0x20
rep stosb
sub di, 0xe
;Initialise the length counter
mov bl, 0xa
specloop:
;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 cmderror2
;Store the character
stosb
;Decrease the counter
dec bl
jmp specloop
;Add extension to the name
addext:
push si
mov si, extension
mov cx, 0x5
rep movsb
;Load and execute the program
;Load
mov bx, 0x3000
mov si, program
mov ah, 0x0
int 0x22
;Check for errors
cmp al, 0x1
je cmderror
;Pass the drive and command tail to the program
mov dl, [drive]
pop si
call ignoreleading
;Execute
jmp 0x3000
;Print a command error message and return to the shell
cmderror:
mov bh, 0x0
mov ah, 0x3
int 0x10
dec dh
mov ah, 0x2
int 0x10
cmderror2:
mov si, cmderrormsg
mov ah, 0x2
int 0x21
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
welcomemsg db 0xd, 0xa, "Welcome to EttinOS!", 0xd, 0xa, 0x0
drive db 0x0
driveletter db "?:", 0x0
prompt db "> ", 0x0
input times 0x4c db 0x0
program times 0xf db 0x0
extension db ".BIN", 0x0
cmderrormsg db "Program not found", 0x0
driverrormsg db "Drive not found", 0x0
;Set the drive letter
setdriveletter:
;Check the drive number
cmp dl, 0x0
je .seta
cmp dl, 0x1
je .setb
cmp dl, 0x2
je .setc
cmp dl, 0x3
je .setd
ret
;Set
.seta:
mov byte [driveletter], "A"
ret
.setb:
mov byte [driveletter], "B"
ret
.setc:
mov byte [driveletter], "C"
ret
.setd:
mov byte [driveletter], "D"
ret
;Ignore leading spaces in the command and its tail
ignoreleading:
lodsb
cmp al, 0x20
je ignoreleading
dec si
ret
;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
;Data
.crlf db 0xd, 0xa, 0x0
;File system buffer
buffer: