EttinOS/src/READSTR.INC

210 lines
2.9 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;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 [.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
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
call .prevchar
dec di
dec bl
jmp .loop
;Finish reading the string
.return:
;Check for 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
cmp byte [di], 0x20
je .deltrailing
jmp .end
.deltrailing:
;Remove
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 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 the cursor 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 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 the cursor to the end of the previous line
.prevln:
mov ah, 0x2
dec dh
mov dl, [.lastcolumn]
int 0x10
ret