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