283 lines
3.3 KiB
NASM
283 lines
3.3 KiB
NASM
;Main
|
|
|
|
mov ax, 0x1000
|
|
mov ds, ax
|
|
|
|
mov ah, 0xf
|
|
int 0x10
|
|
mov byte [cpl], ah
|
|
|
|
mov si, welcome
|
|
call print
|
|
|
|
loop:
|
|
mov si, prompt
|
|
call print
|
|
call read
|
|
cmp byte [input], 0
|
|
je loop
|
|
|
|
execute:
|
|
.help:
|
|
mov si, input
|
|
mov di, command.help
|
|
call compare
|
|
jnc .hello
|
|
call help
|
|
jmp loop
|
|
.hello:
|
|
mov si, input
|
|
mov di, command.hello
|
|
call compare
|
|
jnc .echo
|
|
call hello
|
|
jmp loop
|
|
.echo:
|
|
mov si, input
|
|
mov di, command.echo
|
|
call compare
|
|
jnc .keycode
|
|
call echo
|
|
jmp loop
|
|
.keycode:
|
|
mov si, input
|
|
mov di, command.keycode
|
|
call compare
|
|
jnc .unknown
|
|
call keycode
|
|
jmp loop
|
|
.unknown:
|
|
mov si, command.unknown
|
|
call print
|
|
jmp loop
|
|
|
|
;Calls
|
|
|
|
print:
|
|
lodsb
|
|
cmp al, 0
|
|
je .done
|
|
mov ah, 0xe
|
|
int 0x10
|
|
jmp print
|
|
.done:
|
|
ret
|
|
|
|
clear:
|
|
mov di, input
|
|
mov cx, 0x80
|
|
mov al, 0
|
|
rep stosb
|
|
ret
|
|
|
|
read:
|
|
call clear
|
|
mov bl, 0
|
|
mov ah, 0x3
|
|
int 0x10
|
|
mov byte [.lastline], dh
|
|
mov di, input
|
|
.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
|
|
.character:
|
|
mov byte [di], 0
|
|
mov ah, 0xe
|
|
int 0x10
|
|
stosb
|
|
inc bl
|
|
jmp .linecheck
|
|
.erase:
|
|
mov al, 0x20
|
|
jmp .character
|
|
.space:
|
|
cmp byte [di], 0
|
|
je .character
|
|
mov al, byte [di]
|
|
mov ah, 0xe
|
|
int 0x10
|
|
inc di
|
|
inc bl
|
|
.linecheck:
|
|
mov ah, 0x3
|
|
int 0x10
|
|
cmp dh, [.lastline]
|
|
jle .loop
|
|
mov byte [.lastline], dh
|
|
jmp .loop
|
|
.backspace:
|
|
cmp bl, 0
|
|
je .loop
|
|
mov ah, 0x3
|
|
int 0x10
|
|
cmp dl, 1
|
|
je .prevline
|
|
mov ah, 0xe
|
|
int 0x10
|
|
dec di
|
|
dec bl
|
|
jmp .loop
|
|
.prevline:
|
|
mov ah, 0x2
|
|
dec dh
|
|
mov dl, [cpl]
|
|
int 0x10
|
|
dec di
|
|
dec bl
|
|
jmp .loop
|
|
.return:
|
|
mov di, input.end
|
|
.findtrailingspace:
|
|
dec di
|
|
cmp byte [di], 0
|
|
je .findtrailingspace
|
|
cmp byte [di], 0x20
|
|
je .erasetrailingspace
|
|
jmp .done
|
|
.erasetrailingspace:
|
|
mov al, 0
|
|
stosb
|
|
dec di
|
|
jmp .findtrailingspace
|
|
.done:
|
|
mov ah, 0x2
|
|
mov dh, [.lastline]
|
|
int 0x10
|
|
mov si, newline
|
|
call print
|
|
ret
|
|
.lastline:
|
|
db 0
|
|
|
|
compare:
|
|
mov al, [si]
|
|
mov bl, [di]
|
|
cmp al, bl
|
|
jne .nequal
|
|
cmp al, 0
|
|
je .equal
|
|
inc si
|
|
inc di
|
|
jmp compare
|
|
.nequal:
|
|
clc
|
|
ret
|
|
.equal:
|
|
stc
|
|
ret
|
|
|
|
byte2hex:
|
|
call clear
|
|
mov di, input
|
|
mov si, .hex
|
|
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
|
|
.hex:
|
|
db "0123456789abcdef"
|
|
|
|
help:
|
|
mov si, .input
|
|
call print
|
|
mov si, .commands
|
|
call print
|
|
ret
|
|
.input:
|
|
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, 0
|
|
.commands:
|
|
db "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, .msg
|
|
call print
|
|
ret
|
|
.msg:
|
|
db "Hello world!", 0xd, 0xa, 0
|
|
|
|
echo:
|
|
call read
|
|
cmp byte [input], 0
|
|
je .done
|
|
mov si, input
|
|
call print
|
|
mov si, newline
|
|
call print
|
|
.done:
|
|
ret
|
|
|
|
keycode:
|
|
mov ah, 0
|
|
int 0x16
|
|
mov byte [.scan], ah
|
|
mov byte [.ascii], al
|
|
mov si, .prefix
|
|
call print
|
|
mov ah, [.scan]
|
|
call byte2hex
|
|
mov si, input
|
|
call print
|
|
mov ah, [.ascii]
|
|
call byte2hex
|
|
mov si, input
|
|
call print
|
|
mov si, newline
|
|
call print
|
|
ret
|
|
.prefix:
|
|
db "0x", 0
|
|
.scan:
|
|
db 0
|
|
.ascii:
|
|
db 0
|
|
|
|
;Data
|
|
|
|
cpl:
|
|
db 0
|
|
|
|
welcome:
|
|
db 0xd, 0xa, "Welcome to EttinOS!", 0xd, 0xa, 0xd, 0xa, 0
|
|
|
|
prompt:
|
|
db "> ", 0
|
|
|
|
command:
|
|
.help:
|
|
db "help", 0
|
|
.hello:
|
|
db "hello", 0
|
|
.echo:
|
|
db "echo", 0
|
|
.keycode:
|
|
db "keycode", 0
|
|
.unknown:
|
|
db "Unknown command", 0xd, 0xa, 0
|
|
|
|
newline:
|
|
db 0xd, 0xa, 0
|
|
|
|
input:
|
|
times 0x80 db 0
|
|
.end:
|
|
db 0
|