Reorganise and comment the code and rewrite readstr.

This commit is contained in:
CrazyEttin 2021-05-30 19:12:19 +03:00
parent ed9ec938ae
commit adefdf3e4c
14 changed files with 453 additions and 239 deletions

View File

@ -1,5 +1,10 @@
#!/bin/bash
if [ ! -d "build" ];
then
mkdir build
fi
cd src/
nasm boot.asm -f bin -o ../build/boot.bin
nasm os.asm -f bin -o ../build/os.bin

0
src/EttinOS.img Normal file
View File

View File

@ -1,23 +1,31 @@
[ORG 0x7c00]
mov ax, 0
mov ds, ax
jmp 0:start
start:
;Initialise ds
mov ax, 0x0
mov ds, ax
;Set the source
mov dh, 0x0
mov ch, 0x0
mov cl, 0x2
;Set the destination
mov ax, 0x1000
mov es, ax
mov bx, 0
;Set the size
mov al, 0x20
mov dh, 0
mov ch, 0
mov cl, 0x2
;Load
mov ah, 0x2
int 0x13
;Boot
jmp 0x1000:0
;Padding
times 0x1fe-($-$$) db 0
db 0x55
db 0xaa
;Boot signature
dw 0xaa55

32
src/byte2hexstr.inc Normal file
View File

@ -0,0 +1,32 @@
;Converts a byte in ah to a hex string at di.
byte2hexstr:
;Set a key for the hex digits
mov si, .key
;Set a counter for the two characters of the hex string
mov cx, 0x2
.loop:
;Read the byte
rol ax, 0x4
mov bx, ax
;Convert the byte to a hex digit
and bx, 0xf
mov bl, [si + bx]
;Store the hex digit
mov [di], bl
;Repeat
inc di
dec cx
jnz .loop
ret
.key:
db "0123456789abcdef"

View File

@ -1,193 +0,0 @@
printstr:
lodsb
cmp al, 0
je .done
mov ah, 0xe
int 0x10
jmp printstr
.done:
ret
readstr:
mov di, readstr.out
mov cx, 0x80
mov al, 0
rep stosb
mov bl, 0
mov ah, 0x3
int 0x10
mov byte [.lastln], dh
mov di, readstr.out
.loop:
mov ah, 0
int 0x16
cmp al, 0
je .loop
cmp al, 0xd
je .return
cmp al, 0x8
je .backspace
cmp bl, 0x80
je .loop
cmp al, 0x9
je .erase
cmp al, 0x20
je .space
.char:
mov byte [di], 0
mov ah, 0xe
int 0x10
stosb
inc bl
jmp .checkln
.erase:
mov al, 0x20
jmp .char
.space:
cmp byte [di], 0
je .char
mov al, byte [di]
mov ah, 0xe
int 0x10
inc di
inc bl
.checkln:
mov ah, 0x3
int 0x10
cmp dh, [.lastln]
jle .loop
mov byte [.lastln], dh
jmp .loop
.backspace:
cmp bl, 0
je .loop
mov ah, 0x3
int 0x10
cmp dl, 1
je .prevln
mov ah, 0xe
int 0x10
dec di
dec bl
jmp .loop
.prevln:
mov ah, 0x2
dec dh
mov dl, [cpl]
int 0x10
dec di
dec bl
jmp .loop
.return:
mov di, readstr.end
.findtrailing:
dec di
cmp byte [di], 0
je .findtrailing
cmp byte [di], 0x20
je .deltrailing
jmp .done
.deltrailing:
mov al, 0
stosb
dec di
jmp .findtrailing
.done:
mov ah, 0x2
mov dh, [.lastln]
int 0x10
mov si, newline
call printstr
ret
.lastln:
db 0
.out:
times 0x80 db 0
.end:
db 0
cmpstr:
mov al, [si]
mov bl, [di]
cmp al, bl
jne .neq
cmp al, 0
je .eq
inc si
inc di
jmp cmpstr
.neq:
clc
ret
.eq:
stc
ret
byte2hexstr:
mov di, .out
mov si, .key
mov cx, 0x2
.loop:
rol ax, 0x4
mov bx, ax
and bx, 0xf
mov bl, [si + bx]
mov [di], bl
inc di
dec cx
jnz .loop
ret
.key:
db "0123456789abcdef"
.out:
times 3 db 0
help:
mov si, .out
call printstr
ret
.out:
db "Input:", 0xd, 0xa, "* Typing a character overwrites the cursor location.", 0xd, 0xa, "* The tab key erases the cursor location.", 0xd, 0xa, "* The space and backspace keys move the cursor.", 0xd, 0xa, "Commands:", 0xd, 0xa, "* help: you are reading it.", 0xd, 0xa, "* hello: a hello world program.", 0xd, 0xa, "* echo: echoes its input.", 0xd, 0xa, "* keycode: echoes the BIOS code of a key.", 0xd, 0xa, 0
hello:
mov si, .out
call printstr
ret
.out:
db "Hello world!", 0xd, 0xa, 0
echo:
call readstr
cmp byte [readstr.out], 0
je .done
mov si, readstr.out
call printstr
mov si, newline
call printstr
.done:
ret
keycode:
mov ah, 0
int 0x16
mov byte [.scan], ah
mov byte [.ascii], al
mov si, .prefix
call printstr
mov ah, [.scan]
call byte2hexstr
mov si, byte2hexstr.out
call printstr
mov ah, [.ascii]
call byte2hexstr
mov si, byte2hexstr.out
call printstr
mov si, newline
call printstr
ret
.prefix:
db "0x", 0
.scan:
db 0
.ascii:
db 0

32
src/cmpstr.inc Normal file
View File

@ -0,0 +1,32 @@
;Compares strings from si and di and sets the carry flag if they are equal and clears it if not.
cmpstr:
;Load 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
inc si
inc di
jmp cmpstr
.neq:
;Clear the carry flag
clc
ret
.eq:
;Set the carry flag
stc
ret

19
src/echo.inc Normal file
View File

@ -0,0 +1,19 @@
;Reads a string to the buffer and prints it.
echo:
;Read a string
mov di, buffer
mov al, 0xff
call readstr
;Check for an empty string
cmp byte [buffer], 0x0
je .done
;Print the string
mov si, buffer
call println
.done:
ret

11
src/hello.inc Normal file
View File

@ -0,0 +1,11 @@
;Prints a hello world.
hello:
mov si, .hello
call println
ret
.hello:
db "Hello world!", 0x0

11
src/help.inc Normal file
View File

@ -0,0 +1,11 @@
;Prints help.
help:
mov si, .help
call println
ret
.help:
db "Input:", 0xd, 0xa, "* Typing a character overwrites the cursor location.", 0xd, 0xa, "* The erase (=tab) key erases the cursor location.", 0xd, 0xa, "* The space and backspace keys move the cursor.", 0xd, 0xa, "Commands:", 0xd, 0xa, "* echo: echoes its input.", 0xd, 0xa, "* hello: a hello world program.", 0xd, 0xa, "* help: you are reading it.", 0xd, 0xa, "* keycode: echoes the BIOS code of a key.", 0x0

44
src/keycode.inc Normal file
View File

@ -0,0 +1,44 @@
;Reads a keypress and prints its keycode.
keycode:
;Read a keypress
mov ah, 0x0
int 0x16
;Store the keycode
mov [.scan], ah
mov [.ascii], al
;Print the prefix
mov si, .prefix
call printstr
;Convert the scancode to a hex string
mov ah, [.scan]
mov di, .keycode
call byte2hexstr
;Convert the ascii value to a hex string
mov ah, [.ascii]
mov di, .keycode
add di, 0x2
call byte2hexstr
;Print the keycode
mov si, .keycode
call println
ret
.prefix:
db "0x", 0x0
.scan:
db 0x0
.ascii:
db 0x0
.keycode:
times 0x5 db 0x0

View File

@ -1,79 +1,113 @@
jmp start
%include "calls.inc"
;Calls
%include "printstr.inc"
%include "println.inc"
%include "readstr.inc" ;Under construction
%include "cmpstr.inc"
%include "byte2hexstr.inc"
;Commands
%include "echo.inc"
%include "hello.inc"
%include "help.inc"
%include "keycode.inc"
start:
;Initialise ds
mov ax, 0x1000
mov ds, ax
;Get the terminal width
mov ah, 0xf
int 0x10
mov byte [cpl], ah
mov [cpl], ah
;Print a welcome message
mov si, welcome
call printstr
call println
loop:
;Print a prompt
mov si, prompt
call printstr
;Read a command
mov di, buffer
mov al, 0xff
call readstr
cmp byte [readstr.out], 0
je loop
exec:
.help:
mov si, readstr.out
mov di, cmd.help
call cmpstr
jnc .hello
call help
jmp loop
.hello:
mov si, readstr.out
mov di, cmd.hello
call cmpstr
jnc .echo
call hello
jmp loop
;No command
cmp byte [buffer], 0x0
je loop
.echo:
mov si, readstr.out
;Check for the command
mov si, buffer
mov di, cmd.echo
call cmpstr
jnc .keycode
jnc .hello
;Execute the command
call echo
jmp loop
.hello:
;Check for the command
mov si, buffer
mov di, cmd.hello
call cmpstr
jnc .help
;Execute the command
call hello
jmp loop
.help:
;Check for the command
mov si, buffer
mov di, cmd.help
call cmpstr
jnc .keycode
;Execute the command
call help
jmp loop
.keycode:
mov si, readstr.out
;Check for the command
mov si, buffer
mov di, cmd.keycode
call cmpstr
jnc .error
;Execute the command
call keycode
jmp loop
.error:
mov si, cmd.error
call printstr
mov si, error
call println
jmp loop
cpl:
db 0
db 0x0
welcome:
db 0xd, 0xa, "Welcome to EttinOS!", 0xd, 0xa, 0xd, 0xa, 0
db 0xd, 0xa, "Welcome to EttinOS!", 0xd, 0xa, 0x0
prompt:
db "> ", 0
db "> ", 0x0
cmd:
.help:
db "help", 0
.hello:
db "hello", 0
.echo:
db "echo", 0
db "echo", 0x0
.hello:
db "hello", 0x0
.help:
db "help", 0x0
.keycode:
db "keycode", 0
.error:
db "Unknown command", 0xd, 0xa, 0
db "keycode", 0x0
newline:
db 0xd, 0xa, 0
error:
db "Unknown command", 0x0
;buffer:
;times 0x100 db 0
buffer:
times 0x100 db 0

14
src/println.inc Normal file
View File

@ -0,0 +1,14 @@
;Prints a line from si until a null.
println:
;Print a string
call printstr
;Print a newline
mov si, .newline
call printstr
ret
.newline:
db 0xd, 0xa, 0x0

20
src/printstr.inc Normal file
View File

@ -0,0 +1,20 @@
;Prints a string from si until a null.
printstr:
;Load a character
lodsb
;Check for the string end
cmp al, 0x0
je .done
;Print the character
mov ah, 0xe
int 0x10
;Repeat
jmp printstr
.done:
ret

177
src/readstr.inc Normal file
View File

@ -0,0 +1,177 @@
;Reads a string of at most al characters to di.
readstr:
;Store the length
mov [.length], al
;Initialise the destination with spaces
mov cx, [.length]
mov al, 0x20
rep stosb
sub di, [.length]
;Initialise the cursor pointer
mov bl, 0x0
;Initialise the last input line pointer
mov ah, 0x3
int 0x10
mov byte [.lastln], dh
.loop:
;Read a keypress
mov ah, 0x0
int 0x16
;Check for null
cmp al, 0x0
je .loop
;Check for return
cmp al, 0xd
je .return
;Check for backspace
cmp al, 0x8
je .backspace
;Check for input end
cmp bl, [.length]
je .loop
;Check for space
cmp al, 0x20
je .space
;Check for erase
cmp al, 0x9
je .erase
;Check for non-printing characters
cmp al, 0x1f
jle .loop
cmp al, 0x7f
je .loop
.char:
;Store the character
stosb
;Print the character
mov ah, 0xe
int 0x10
;Move the cursor pointer
inc bl
.checkln:
;Get the cursor position
mov ah, 0x3
int 0x10
;Check if the current line is the last one of the input
cmp dh, [.lastln]
jle .loop
;If it is mark it as so
mov byte [.lastln], dh
jmp .loop
.erase:
;Replace the cursor position with a space
mov al, 0x20
jmp .char
.space:
;Get the cursor position
mov ah, 0x3
int 0x10
;More from the end of a line to the beginning of the next one
cmp dl, [cpl]
je .nextln
;Move forward within a line
inc dl
mov ah, 0x2
int 0x10
inc di
inc bl
jmp .loop
.nextln:
mov ah, 0x2
inc dh
mov dl, 0x1
int 0x10
inc di
inc bl
;Go to the last input line check
jmp .checkln
.backspace:
;Check for the input beginning
cmp bl, 0x0
je .loop
;Get the cursor position
mov ah, 0x3
int 0x10
;More from the beginning of a line to the end of the previous one
cmp dl, 0x1
je .prevln
;Move backward within a line
dec dl
mov ah, 0x2
int 0x10
dec di
dec bl
jmp .loop
.prevln:
mov ah, 0x2
dec dh
mov dl, [cpl]
int 0x10
dec di
dec bl
jmp .loop
.return:
;Go to the end of the input
mov bh, 0
sub di, bx
add di, [.length]
.findtrailing:
;Check for a trailing space
dec di
cmp byte [di], 0x20
je .deltrailing
jmp .done
.deltrailing:
;Delete a trailing space
mov al, 0x0
stosb
dec di
jmp .findtrailing
.done:
;Move the cursor to the last line of input
mov ah, 0x2
mov dh, [.lastln]
int 0x10
;Print a newline
mov si, .newline
call printstr
ret
.length:
db 0x0
.cursor:
db 0x0
.lastln:
db 0x0
.newline:
db 0xd, 0xa, 0x0