diff --git a/src/calls.inc b/src/calls.inc new file mode 100644 index 0000000..14d4c9e --- /dev/null +++ b/src/calls.inc @@ -0,0 +1,193 @@ +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 diff --git a/src/os.asm b/src/os.asm index 0688e9d..c42cf16 100644 --- a/src/os.asm +++ b/src/os.asm @@ -1,4 +1,8 @@ -;Main +jmp start + +%include "calls.inc" + +start: mov ax, 0x1000 mov ds, ax @@ -8,250 +12,48 @@ int 0x10 mov byte [cpl], ah mov si, welcome -call print +call printstr loop: mov si, prompt -call print -call read -cmp byte [input], 0 +call printstr +call readstr +cmp byte [readstr.out], 0 je loop - -execute: +exec: .help: -mov si, input -mov di, command.help -call compare +mov si, readstr.out +mov di, cmd.help +call cmpstr jnc .hello call help jmp loop .hello: -mov si, input -mov di, command.hello -call compare +mov si, readstr.out +mov di, cmd.hello +call cmpstr jnc .echo call hello jmp loop .echo: -mov si, input -mov di, command.echo -call compare +mov si, readstr.out +mov di, cmd.echo +call cmpstr jnc .keycode call echo jmp loop .keycode: -mov si, input -mov di, command.keycode -call compare -jnc .unknown +mov si, readstr.out +mov di, cmd.keycode +call cmpstr +jnc .error call keycode jmp loop -.unknown: -mov si, command.unknown -call print +.error: +mov si, cmd.error +call printstr 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 @@ -261,7 +63,7 @@ db 0xd, 0xa, "Welcome to EttinOS!", 0xd, 0xa, 0xd, 0xa, 0 prompt: db "> ", 0 -command: +cmd: .help: db "help", 0 .hello: @@ -270,13 +72,8 @@ db "hello", 0 db "echo", 0 .keycode: db "keycode", 0 -.unknown: +.error: db "Unknown command", 0xd, 0xa, 0 newline: db 0xd, 0xa, 0 - -input: -times 0x80 db 0 -.end: -db 0