;Reads a string of at most al characters to di until a return. readstr: ;Store the initial registers in the stack pusha ;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 ;Initialise the cursor pointer mov bl, 0x1 .loop: ;Read a keypress mov ah, 0x0 int 0x16 ;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 .char: ;Store the character stosb ;Print the character mov ah, 0xe int 0x10 ;Move the cursor pointer inc bl jmp .loop .erase: ;Replace the cursor position with a space mov al, 0x20 jmp .char .space: call .nextchar inc di inc bl jmp .loop .backspace: ;Check for the input beginning cmp bl, 0x1 je .loop call .prevchar dec di dec bl jmp .loop .return: ;Go to the end of the input pop ax mov bh, 0x0 sub ax, bx push di add di, ax .findtrailing: ;Check for a trailing space cmp byte [di], 0x20 je .deltrailing jmp .end .deltrailing: ;Delete a trailing space mov al, 0x0 stosb sub di, 0x2 jmp .findtrailing .end: ;Move the cursor to the end of the input string pop di .findend: cmp byte [di], 0x0 jne .notend jmp .done .notend: call .nextchar inc di inc bl jmp .findend .done: ;Load the initial registers from the stack popa ret .nextchar: ;Get the cursor position mov ah, 0x3 int 0x10 ;Move 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 ret .nextln: mov ah, 0x2 inc dh mov dl, 0x1 int 0x10 ret .prevchar: ;Get the cursor position mov ah, 0x3 int 0x10 ;Move 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 ret .prevln: mov ah, 0x2 dec dh mov dl, [cpl] int 0x10 ret