;Read a string ending in a null of at most AL characters to DI until a ;return. readstr: ;Store AX, BX, CX, DX, and DI in the stack push ax push bx push cx push dx push di ;Setup ;Store the input length in the stack mov ah, 0 push ax ;Initialise the destination with spaces mov cx, ax mov al, 0x20 rep stosb pop ax push ax sub di, ax ;Store the last column number mov ah, 0xf int 0x10 dec ah mov [.lastcolumn], ah ;Set the cursor pointer in BL and clear BH mov bx, 0x1 ;Read a keypress .loop: mov ah, 0x0 int 0x16 ;Check for special keys and non-printing characters ;Check for return cmp al, 0xd je .return ;Check for backspace cmp al, 0x8 je .backspace ;Check for input end pop dx push dx cmp bl, dl 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 ;Store and print a character .character: ;Store stosb ;Print mov ah, 0xe int 0x10 ;Move the cursor pointer inc bl jmp .loop ;Replace the cursor position with a space .erase: mov al, 0x20 jmp .character ;Move the cursor forward .space: call .nextchar inc di inc bl jmp .loop ;Move the cursor backward .backspace: ;Check for the input beginning cmp bl, 0x1 je .loop ;Move the cursor call .prevchar dec di dec bl jmp .loop ;Check for and remove trailing spaces ;Go to the end of the input .return: pop ax mov bh, 0x0 sub ax, bx push di add di, ax ;Check for trailing spaces .findtrailing: cmp byte [di], 0x20 je .deltrailing jmp .end ;Remove trailing spaces .deltrailing: mov al, 0x0 stosb sub di, 0x2 jmp .findtrailing ;Move the cursor to the end of the input string .end: pop di .findend: cmp byte [di], 0x0 jne .notend jmp .done .notend: call .nextchar inc di inc bl jmp .findend ;Load DI, DX, CX, BX, and AX from the stack .done: pop di pop dx pop cx pop bx pop ax ;Return iret ;Data .lastcolumn db 0x0 ;*** ;Move the cursor forward .nextchar: ;Get the cursor position mov ah, 0x3 int 0x10 ;Check for the end of the line cmp dl, [.lastcolumn] je .nextln ;Move the cursor forward within a line inc dl mov ah, 0x2 int 0x10 ;Return ret ;Move the cursor to the beginning of the next line ;Check if the current line is the last on screen .nextln: cmp dh, 0x18 je .scroll ;Move the cursor mov ah, 0x2 inc dh mov dl, 0x0 int 0x10 ;Return ret ;Scroll the screen up by one line .scroll: mov ah, 0x6 mov al, 0x1 mov bh, 0x7 mov ch, 0x0 mov cl, 0x0 mov dh, 0x18 mov dl, [.lastcolumn] int 0x10 ;Move to the beginning of the new line mov ah, 0x2 mov bh, 0x0 mov dl, 0x0 int 0x10 ;Return ret ;*** ;Move the cursor backward .prevchar: ;Get the cursor position mov ah, 0x3 int 0x10 ;Check for the beginning of the line cmp dl, 0x0 je .prevln ;Move the cursor backward within a line dec dl mov ah, 0x2 int 0x10 ;Return ret ;Move the cursor to the end of the previous line .prevln: mov ah, 0x2 dec dh mov dl, [.lastcolumn] int 0x10 ;Return ret