; ============================================================================
;
; MicroDOS - Console device
;
; ============================================================================
; ----------------------------------------------------------------------------
; Correct character from keyboard
; ----------------------------------------------------------------------------
; INPUT: AX = character from keyboard
; OUTPUT: AX = character from keyboard
; NZ (sets ZF)
; ----------------------------------------------------------------------------
; ------------- Substitute Ctrl+PrintScreen key with Ctrl+P
CorrChar: cmp ax,CTRL_PRINTSCR; is it Ctrl+Print Screen?
jne CorrChar2 ; it is not Ctrl+Print Screen
or al,PRINT ; substitute it with Ctrl+P
CorrChar2: ret
; ----------------------------------------------------------------------------
; Console test character
; ----------------------------------------------------------------------------
; OUTPUT: AL = character (0=scan code follows)
; ZY = no character (NZ = a character is ready)
; ----------------------------------------------------------------------------
; NOTES: use CALL FAR
; ----------------------------------------------------------------------------
; ------------- Push registers
TestChar: push dx ; push DX
xchg ax,dx ; DH <- push AH
; ------------- Read old character from buffer
TestChar2: mov al,[cs:OldChar] ; AL <- old character
or al,al ; is it valid character?
jnz TestChar8 ; it is valid character
; ------------- Read character from keyboard
mov ah,1 ; AH <- 1 function code
int 16h ; test character from keyboard
jz TestChar8 ; no character
; ------------- Skip Ctrl+Break code
or ax,ax ; is it Ctrl+Break?
jnz TestChar6 ; it is not Ctrl+Break
mov ah,0 ; AH <- 0 function code
int 16h ; read character from keyboard
jmp short TestChar2 ; next key
; ------------- Correct character from keyboard (and clear ZF)
TestChar6: call CorrChar ; correct character from keyboard
; ------------- Pop registers
TestChar8: mov ah,dh ; AH <- pop AH
pop dx ; pop DX
retf
; ----------------------------------------------------------------------------
; Console read character
; ----------------------------------------------------------------------------
; OUTPUT: AL = character (0=scan code follows)
; ZY = scan code follows (AL = 0)
; ----------------------------------------------------------------------------
; NOTES: use CALL FAR
; ----------------------------------------------------------------------------
; ------------- Push registers
GetChar: push dx ; push DX
xchg ax,dx ; DH <- push AH
; ------------- Read old character from buffer
GetChar2: mov al,0 ; AL <- new invalid old character
xchg al,[cs:OldChar] ; AL <- old character
or al,al ; is it valid character?
jnz GetChar8 ; it is valid character
; ------------- Read character from keyboard
mov ah,0 ; AH <- 0 function code
int 16h ; read character from keyboard
; ------------- Skip Ctrl+Break code
or ax,ax ; is it Ctrl+Break?
jz GetChar2 ; it is Ctrl+Break
; ------------- Correct character from keyboard
call CorrChar ; correct character from keyboard
; ------------- Store scan code
or al,al ; is it special key?
jnz GetChar8 ; it is not special key
mov [cs:OldChar],ah ; store scan code
; ------------- Pop registers
GetChar8: mov ah,dh ; AH <- pop AH
pop dx ; pop DX
retf
; ----------------------------------------------------------------------------
; Display character
; ----------------------------------------------------------------------------
; INPUT: AL = character to display
; ----------------------------------------------------------------------------
; NOTES: use CALL FAR
; ----------------------------------------------------------------------------
; ------------- Push registers
DispChar: push ax ; push AX
push bx ; push BX
; ------------- Display character
mov ah,0eh ; AH <- 0Eh function code
mov bx,7 ; BL <- color of text, BH <- page 0
call Int10 ; call Int 10h
; ------------- Pop registers
pop bx ; pop BX
pop ax ; pop AX
retf
; ----------------------------------------------------------------------------
; Display ASCIIZ text
; ----------------------------------------------------------------------------
; INPUT: CS:DX = text to display (zero terminated)
; ----------------------------------------------------------------------------
; ------------- Push registers
DispText: push ax ; push AX
push si ; push SI
; ------------- Prepare registers
mov si,dx ; SI <- text to display
; ------------- Display one character
DispText2: cld ; direction up
cs lodsb ; load character to display
cmp al,0 ; is it end of text?
je DispText3 ; it is end of text
push cs ; simulate call far
call JVTDispChar ; display character
jmp short DispText2 ; display next character
; ------------- Pop registers
DispText3: pop si ; pop SI
pop ax ; pop AX
ret
; ----------------------------------------------------------------------------
; Call Int 10h interrupt with saving registers
; ----------------------------------------------------------------------------
; NOTES: Some BIOSes destroy some registers, so we call it with saving them.
; ----------------------------------------------------------------------------
; ------------- Push registers
Int10: pushf ; push flags
push si ; push SI
push di ; push DI
push bp ; push BP
push ds ; push DS
push es ; push ES
; ------------- Call INT 10h
int 10h ; call INT 10h
; ------------- Pop registers
pop es ; pop ES
pop ds ; pop DS
pop bp ; pop BP
pop di ; pop DI
pop si ; pop SI
popf ; pop flags
ret
; ----------------------------------------------------------------------------
; Interrupt 1Bh handler (program break)
; ----------------------------------------------------------------------------
MyInt1B: mov byte [cs:OldChar],BREAK ; break character
iret
; ----------------------------------------------------------------------------
; Data
; ----------------------------------------------------------------------------
OldChar: db 0 ; old character from console (0=none)
|