1
0
Fork 0
EttinOS/src/READSTR.INC

205 lines
2.9 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
;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
;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, 0x4f
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, 0x4f
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, 0x4f
int 0x10
ret