Reorganise and comment the code and rewrite readstr.
This commit is contained in:
parent
ed9ec938ae
commit
adefdf3e4c
5
make.sh
5
make.sh
|
@ -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
|
||||
|
|
26
src/boot.asm
26
src/boot.asm
|
@ -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
|
||||
|
|
|
@ -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"
|
193
src/calls.inc
193
src/calls.inc
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,11 @@
|
|||
;Prints a hello world.
|
||||
|
||||
hello:
|
||||
|
||||
mov si, .hello
|
||||
call println
|
||||
|
||||
ret
|
||||
|
||||
.hello:
|
||||
db "Hello world!", 0x0
|
|
@ -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
|
|
@ -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
|
108
src/os.asm
108
src/os.asm
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue