;======================================================================
;Very powerful OS Input Function By MBR_TSR
;Call AmazeInput() with DS:SI as String to Edit
;Call Input() to Edit a New String
;Use Arrows, Insert, Delete, Home, End, BackSpace
;This is Nice, can be called from an Interrupt.
;Multi-Line Support added on May 28, 2013
;======================================================================
Org 0x0100
push cs
pop ds
mov si, Help
call Show
mov si, Prompt
call Show
mov si, MyBuffer
call AmazeInput
mov ah, 0x4c
int 0x21
;======================================================================
;AmazeInput Edit String in DS:SI Returns DS:SI
AmazeInput:
mov byte [cs:Amaze], 1
jmp Input
Amaze db 0
Input:
push ax
push bx
push cx
push dx
push di
push si
push bp
push ds
push es
pushf
mov word [cs:BufferAddr], si
cmp byte [cs:Amaze], 1
je Amazing
mov si, word [cs:BufferAddr]
mov byte [DS:SI], 0
mov byte [cs:TotalLength], 0
mov byte [cs:CurrentPos], 0
jmp AllRight
Amazing:
mov si, word [cs:BufferAddr]
call StrLen
mov byte [cs:TotalLength], cl
mov byte [cs:CurrentPos], 0
call GetPos
mov si, word [cs:BufferAddr]
call Show
call SetPos
AllRight:
mov byte [cs:Amaze], 0
push cs
pop es
call GetPos
mov word [cs:StartPos], DX
mov si, word [cs:BufferAddr]
;--------------------------------------------------------------
StartInput:
mov byte [cs:SkipStore], 0
mov cl, byte [cs:CurrentPos]
call FindPos
call GetKey
cmp ah, 0x1C ;CR
;cmp ah, 0x44 ;F10
jne NotExit
ExitNow:
mov bh, 0
mov bl, byte [cs:TotalLength]
mov byte [ds:si+bx], 0
mov si, Msg1
call Show
mov si, word [cs:BufferAddr]
call Show
popf
pop es
pop ds
pop bp
pop si
pop di
pop dx
pop cx
pop bx
pop ax
ret
;mov ah, 0x4C
;int 0x21
NotExit:
cmp ah, 0x01 ;ESC
jne NotClear
cmp byte [cs:TotalLength], 0
je NotClear0
call EraseText
NotClear0:
mov byte [cs:SkipStore], 1
NotClear:
call CheckArrows
call CheckDelete
call CheckInsert
call DetectHomeEnd
cmp byte [cs:SkipStore], 1
je Skip
call ShowKey
call StoreAL
Skip:
jmp StartInput
;--------------------------------------------------------------
;input stuff
GetKey:
mov ah, 0
int 0x16
ret
ShowKey:
mov ah, 0x0E
int 0x10
ret
StoreAL:
push si
mov si, word [cs:BufferAddr]
mov bh, 0
mov bl, byte [cs:CurrentPos]
mov byte [ds:si+bx], al
inc byte [cs:CurrentPos] ;debug!
mov bl, byte [cs:TotalLength]
mov byte [ds:si+bx+1], 0
mov cl, byte [cs:CurrentPos]
cmp cl, byte [cs:TotalLength]
jle DontIncMids
inc byte [cs:TotalLength]
DontIncMids:
pop si
ret
CheckArrows:
push ax
cmp ah, 0x4B
jne NotLeft
call GetPos
mov cx, word [cs:StartPos]
cmp cx, dx
je TooFarLeft
dec byte [cs:CurrentPos]
call DecCol
TooFarLeft:
mov byte [cs:SkipStore], 1
jmp DoneArrowCheck
NotLeft:
cmp ah, 0x4D
jne NotRight
mov ch, byte [cs:CurrentPos]
mov cl, byte [cs:TotalLength]
cmp ch, cl
jge Avoidoid
call IncCol
inc byte [cs:CurrentPos]
Avoidoid:
mov byte [cs:SkipStore], 1
jmp DoneArrowCheck
NotRight:
DoneArrowCheck:
pop ax
ret
DetectHomeEnd:
push ax
cmp ah, 0x47
jne NotHome
mov byte [cs:CurrentPos], 0
mov dx, word [cs:StartPos]
call SetPos
mov byte [cs:SkipStore], 1
NotHome:
cmp ah, 0x4F
jne NotEnd
mov cl, byte [cs:TotalLength]
mov byte [cs:CurrentPos], cl
call FindPos
mov byte [cs:SkipStore], 1
NotEnd:
pop ax
ret
FindPos:
push ax
push cx
push dx
mov ch, 0
mov dx, word [cs:StartPos]
call SetPos
add dl, cl
call SetPos
pop dx
pop cx
pop ax
ret
DecCol:
push ax
push dx
call GetPos
cmp dl, 0
jne SetNow
mov cx, word [cs:StartPos]
cmp dh, ch
je QuitSet
dec dh
call Gcols2
mov dl, cl
call SetPos
jmp QuitSet
SetNow:
dec dl
call SetPos
QuitSet:
pop dx
pop ax
ret
IncCol:
push dx
push cx
push ax
call GetPos
inc dl
call SetPos
pop ax
pop cx
pop dx
ret
CheckInsert:
push ax
cmp ah, 0x52
jne NotInsert
cmp byte [cs:TotalLength], 0
je NotInsert2
call ClearBuff
mov si, word [cs:BufferAddr]
mov di, AnotherBuffer
mov ch, 0
mov cl, byte [cs:CurrentPos]
cmp cl, 0
je SkipBug
PutBlank:
lodsb
stosb
loop PutBlank
SkipBug:
mov al, ' '
stosb
mov ch, 0
mov cl, byte [cs:TotalLength]
sub cl, byte [cs:CurrentPos]
FinishCopy:
lodsb
stosb
loop FinishCopy
inc byte [cs:TotalLength]
mov ch, 0
mov cl, byte [cs:TotalLength]
push ds
push es
push ds
push cs
pop ds
pop es
mov si, AnotherBuffer
mov di, word [cs:BufferAddr]
Replace:
lodsb
stosb
loop Replace
pop es
pop ds
call EraseShow
call ShowAndSet
NotInsert2:
mov byte [cs:SkipStore], 1
NotInsert:
pop ax
ret
CheckDelete:
push ax
cmp ah, 0x0E
je BackSpace
cmp ah, 0x53
jne NotDelete
BackSpace:
cmp byte [cs:TotalLength], 0
je SkipPos0
mov ch, byte [cs:CurrentPos]
mov cl, byte [cs:TotalLength]
cmp ch, cl
jge SkipPos0
mov si, word [cs:BufferAddr]
mov di, word [cs:BufferAddr]
mov bh, 0
mov bl, byte [cs:CurrentPos]
inc si
mov ch, 0
mov cl, byte [cs:TotalLength]
DeleteLoop:
mov al, byte [ds:si+bx]
mov byte [ds:di+bx], al
inc bx
cmp bl, byte [cs:TotalLength]
je DoneLoop
loop DeleteLoop
DoneLoop:
call EraseShow
call ShowAndSet
dec byte [cs:TotalLength]
SkipPos0:
mov byte [cs:SkipStore], 1
NotDelete:
pop ax
ret
;GetPos Get ROW and COL into DX
;SetPos Set ROW and COL to DX
SetPos:
push ax
push bx
mov ah, 0x02
mov bh, 0
int 0x10
pop bx
pop ax
ret
GetPos:
push ax
push bx
mov ah, 0x03
mov bh, 0
int 0x10
pop bx
pop ax
ret
EraseShow:
push ax
mov DX, word [cs:StartPos]
call SetPos
mov ch, 0
mov cl, byte [cs:TotalLength]
ClearLine:
mov al, ' '
call ShowKey
loop ClearLine
mov DX, word [cs:StartPos]
call SetPos
pop ax
ret
ShowAndSet:
push ax
push di
push si
push es
push ds
pop es
mov di, word [cs:BufferAddr]
mov ch, 0
mov cl, byte [cs:TotalLength]
add di, cx
mov al, 0
stosb
pop es
mov dx, word [cs:StartPos]
call SetPos
mov si, word [cs:BufferAddr]
call Show
mov cl, byte [cs:CurrentPos]
call FindPos
pop si
pop di
pop ax
ret
ShowBug:
push ax
mov ah, 0x0e
mov al, 1
int 0x10
pop ax
ret
ClearBuff:
push ax
push es
push ds
pop es
mov di, word [cs:BufferAddr]
mov ch, 0
mov cl, byte [cs:TotalLength]
add di, cx
sub cl, byte [cs:CurrentPos]
mov al, 0
LoopClear:
stosb
loop LoopClear
pop es
pop ax
ret
Gcols2:
push ax
push bx
push es
mov ax, 0x40
mov es, ax
mov bx, 0x4a
mov cx, word [es:bx]
sub cl, 2
pop es
pop bx
pop ax
ret
EraseText:
push ax
push es
push ds
pop es
mov byte [cs:CurrentPos], 0
mov di, word [cs:BufferAddr]
mov ch, 0
mov cl, byte [cs:TotalLength]
mov al, 0
LoopErase:
stosb
loop LoopErase
pop es
call EraseShow
mov byte [cs:TotalLength], 0
pop ax
ret
StrLen:
push SI
mov cx, 0
GetLen:
cmp byte [ds:si], 0
je OverLen
cmp cx, 0xffff
je OverLen
inc CX
inc SI
jmp GetLen
OverLen:
pop SI
ret
Show:
push ax
push bx
push si
Show1:
lodsb
cmp al, 0
je Okay
mov ah, 0x0E
mov bh, 0x00
mov bl, 0x07
int 0x10
jmp Show1
Okay:
pop si
pop bx
pop ax
ret
SkipStore db 0
StartPos dw 0
CurrentPos db 0
TotalLength db 0
BufferAddr dw 0
AnotherBuffer rb 300
Msg1 db 13,10,13,10,"Your String Is: ",0
Help db 13,10,"Input Routine Example"
db 13,10,"Use Arrows, Insert, Delete, Home, End, BackSpace",0
Prompt db 13,10,"What?",0
MyBuffer db "Edit This Text!",0
;===========================================