214 lines
3.0 KiB
Plaintext
214 lines
3.0 KiB
Plaintext
;Read a string ending in a null of at most AL characters to DI until a
|
||
;return.
|
||
|
||
readstr:
|
||
|
||
;Store the initial registers 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 byte [.lastcolumn], ah
|
||
;Initialise the cursor pointer in BL and clear BH
|
||
mov bx, 0x1
|
||
|
||
.loop:
|
||
|
||
;Read a keypress
|
||
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 the character
|
||
stosb
|
||
;Print the character
|
||
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
|
||
|
||
;Finish reading the string
|
||
.return:
|
||
|
||
;Find and remove trailing spaces
|
||
;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
|
||
|
||
;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
|
||
|
||
.done:
|
||
|
||
;Load the initial registers from the stack
|
||
pop di
|
||
pop dx
|
||
pop cx
|
||
pop bx
|
||
pop ax
|
||
|
||
iret
|
||
|
||
;Data
|
||
.lastcolumn db 0x0
|
||
|
||
;Move the cursor forward
|
||
|
||
;Move forward within a line
|
||
.nextchar:
|
||
;Get the cursor position
|
||
mov ah, 0x3
|
||
int 0x10
|
||
;Check for the end of the line
|
||
cmp dl, [.lastcolumn]
|
||
je .nextln
|
||
;Move
|
||
inc dl
|
||
mov ah, 0x2
|
||
int 0x10
|
||
ret
|
||
|
||
;Move to the beginning of the next line
|
||
.nextln:
|
||
;Check if the current line is the last on screen
|
||
cmp dh, 0x18
|
||
je .scroll
|
||
;Move
|
||
mov ah, 0x2
|
||
inc dh
|
||
mov dl, 0x0
|
||
int 0x10
|
||
ret
|
||
|
||
;Scroll the screen up by one line
|
||
.scroll:
|
||
;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
|
||
ret
|
||
|
||
;Move the cursor backward
|
||
|
||
;Move backward within a line
|
||
.prevchar:
|
||
;Get the cursor position
|
||
mov ah, 0x3
|
||
int 0x10
|
||
;Check for the beginning of the line
|
||
cmp dl, 0x0
|
||
je .prevln
|
||
;Move
|
||
dec dl
|
||
mov ah, 0x2
|
||
int 0x10
|
||
ret
|
||
|
||
;Move to the end of the previous line
|
||
.prevln:
|
||
mov ah, 0x2
|
||
dec dh
|
||
mov dl, [.lastcolumn]
|
||
int 0x10
|
||
ret
|
||
|