diff --git a/source/readln.inc b/source/readln.inc index 23d9063..d45d1e4 100644 --- a/source/readln.inc +++ b/source/readln.inc @@ -2,181 +2,10 @@ readln: -;Store the input length in the stack -mov ah, 0 -push ax +;Read the string +call readstr -;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 - -;Initialise the last input line pointer -mov ah, 0x3 -int 0x10 -mov byte [.lastln], dh - -.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 -call .checkln -jmp .loop - -.erase: -;Replace the cursor position with a space -mov al, 0x20 -jmp .char - -.space: -call .nextchar -jmp .loop - -.backspace: -;Check for the input beginning -cmp bl, 0x1 -je .loop -call .prevchar -jmp .loop - -.return: - -;Go to the end of the input -mov bh, 0x0 -sub di, bx -pop ax -add di, ax - -.findtrailing: -;Check for a trailing space -cmp byte [di], 0x20 -je .deltrailing -jmp .done - -.deltrailing: -;Delete a trailing space -mov al, 0x0 -stosb -sub di, 0x2 -jmp .findtrailing - -.done: -;Move the cursor to the last line of input -mov ah, 0x2 -mov dh, [.lastln] -int 0x10 ;Print a newline call newline ret - -.lastln: -db 0x0 - -.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 -inc di -inc bl -ret - -.nextln: -mov ah, 0x2 -inc dh -mov dl, 0x1 -int 0x10 -inc di -inc bl -;Go to the last input line check -call .checkln -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 -dec di -dec bl -ret - -.prevln: -mov ah, 0x2 -dec dh -mov dl, [cpl] -int 0x10 -dec di -dec bl -ret - -.checkln: -;Get the cursor position -mov ah, 0x3 -int 0x10 -;Check if the current line is the last one of the input -cmp dh, [.lastln] -jg .markln -ret - -.markln: -;Mark the current line as the last one of the input -mov byte [.lastln], dh -ret diff --git a/source/readstr.inc b/source/readstr.inc new file mode 100644 index 0000000..e9119ae --- /dev/null +++ b/source/readstr.inc @@ -0,0 +1,160 @@ +;Reads a string of at most al characters to di until a return. + +readstr: + +;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: +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 diff --git a/source/system.asm b/source/system.asm index f4792f9..3c3e49c 100644 --- a/source/system.asm +++ b/source/system.asm @@ -4,6 +4,7 @@ jmp start ;Calls %include "printstr.inc" %include "println.inc" +%include "readstr.inc" %include "readln.inc" %include "newline.inc" %include "cmpstr.inc"