2021 lines
47 KiB
NASM
2021 lines
47 KiB
NASM
;**************************************************************************
|
|
;**************************************************************************
|
|
;
|
|
; WDOS-BIOS - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1988
|
|
; Programm: term.asm
|
|
;
|
|
; Bearbeiter : P. Hoge
|
|
; Datum : 8.3.90
|
|
; Version : 1.1
|
|
;
|
|
;**************************************************************************
|
|
;
|
|
; Wyse-Terminal (WY-99GT)
|
|
;
|
|
;**************************************************************************
|
|
;**************************************************************************
|
|
|
|
|
|
.EXTERNAL DDS ;NEAR
|
|
.EXTERNAL START ;NEAR
|
|
.EXTERNAL BYTE BIOS_BREAK
|
|
.EXTERNAL WORD RESET_FLAG
|
|
.EXTERNAL BYTE KB_FLAG
|
|
.EXTERNAL BYTE KB_FLAG_1
|
|
.EXTERNAL BYTE KB_FLAG_2
|
|
.EXTERNAL BYTE ALT_INPUT
|
|
.EXTERNAL WORD BUFFER_START
|
|
.EXTERNAL WORD BUFFER_END
|
|
.EXTERNAL WORD BUFFER_HEAD
|
|
.EXTERNAL WORD BUFFER_TAIL
|
|
.EXTERNAL WORD CURSOR_POSN
|
|
.EXTERNAL WORD CURSOR_MODE
|
|
.EXTERNAL BYTE CRT_MODE
|
|
.EXTERNAL WORD CRT_COLS
|
|
.EXTERNAL WORD CRT_LEN
|
|
.external word ADDR_6845
|
|
.external byte reset
|
|
.external byte intin
|
|
.external byte intout
|
|
.external byte ttyin
|
|
.external byte ttyout
|
|
.external byte lpout
|
|
.external byte ttybuf
|
|
.external byte lpbuf
|
|
|
|
.PUBLIC PUTA
|
|
.PUBLIC KBOARD
|
|
.PUBLIC KBINT
|
|
.PUBLIC VIDEO
|
|
.PUBLIC PRINTER
|
|
.PUBLIC RS232
|
|
|
|
;---- INT 16 ------------------------------------------------------------------
|
|
;KEYBOARD I/O
|
|
; THESE ROUTINES PROVIDE KEYBOARD SUPPORT
|
|
;INPUT
|
|
; (AH)=0 READ THE NEXT ASCII CHARACTER STRUCK FROM THE KEYBOARD
|
|
; RETURN THE RESULT IN (AL), SCAN CODE IN (AH)
|
|
; (AH)=1 SET THE Z FLAG TO INDICATE IF AN ASCII CHARACTER IS AVAILABLE
|
|
; (ZF)=1 -- NO CODE AVAILABLE
|
|
; (ZF)=0 -- CODE IS AVAILABLE
|
|
; IF ZF = 0, THE NEXT CHARACTER IN THE BUFFER TO BE READ IS
|
|
; IN AX, AND THE ENTRY REMAINS IN THE BUFFER
|
|
; (AH)=2 RETURN THE CURRENT SHIFT STATUS IN AL REGISTER
|
|
; THE BIT SETTINGS FOR THIS CODE ARE INDICATED IN THE
|
|
; THE EQUATES FOR KB_FLAG
|
|
; (AH)=5 Extended Write CX to Input-Buffer
|
|
; (AH)=10 Extended ah=0 function
|
|
; (AH)=11 Extended ah=1 function
|
|
; (AH)=12 Extended ah=2 function
|
|
;OUTPUT
|
|
; AS NOTED ABOVE, ONLY AX AND FLAGS CHANGED
|
|
; ALL REGISTERS RETAINED
|
|
;------------------------------------------------------------------------------
|
|
KBCNT: defb 0
|
|
|
|
KBOARD ;PROC FAR ;>>> ENTRY POINT FOR ORG 0E82EH
|
|
sti ;INTERRUPTS BACK ON
|
|
push ds ;SAVE CURRENT DS
|
|
push bx ;SAVE BX TEMPORARILY
|
|
call DDS ;ESTABLISH POINTER TO DATA REGION
|
|
cmp ah,5
|
|
jz K3 ;Write to keybord buffer
|
|
cmp ah,10h
|
|
jz K0 ;Extended keybord read
|
|
cmp ah,11h
|
|
jz K1 ;Get keystroke status
|
|
cmp ah,12h
|
|
jz K2e ;Get extended shift status
|
|
or ah,ah ;AH=0
|
|
jz K0 ;ASCII_READ
|
|
dec ah ;AH=1
|
|
jz K1 ;ASCII_STATUS
|
|
dec ah ;AH=2
|
|
jz K2 ;SHIFT_STATUS
|
|
pop bx
|
|
pop ds
|
|
iret ;INVALID COMMAND
|
|
|
|
;------ SHIFT STATUS
|
|
|
|
K2e: mov ah,KB_FLAG_2 ;extended shift status
|
|
K2: mov al,KB_FLAG ;GET THE SHIFT STATUS FLAGS
|
|
pop bx
|
|
pop ds
|
|
iret
|
|
|
|
;----- write cx to keyboard buffer (extended function)
|
|
|
|
K3: push si
|
|
mov bx,BUFFER_TAIL ;GET THE END POINTER TO THE BUFFER
|
|
mov si,bx ;SAVE THE VALUE
|
|
call K4 ;ADVANCE THE TAIL
|
|
cmp bx,BUFFER_HEAD ;HAS THE BUFFER WRAPPED AROUND
|
|
je K3a ;Buffer full
|
|
mov [si],cx ;STORE THE VALUE
|
|
mov BUFFER_TAIL,bx ;MOVE THE POINTER UP
|
|
K3a: pop si
|
|
pop bx
|
|
pop ds
|
|
iret
|
|
|
|
;------ READ THE KEY TO FIGURE OUT WHAT TO DO
|
|
|
|
K0: push cx
|
|
mov cx,ax
|
|
K0A: ;read loop
|
|
sti
|
|
call SCREEN_OUT ;"Bildwiederholspeicher" ausgeben
|
|
|
|
; MOV BX,BUFFER_HEAD ;GET POINTER TO HEAD OF BUFFER
|
|
; CMP BX,BUFFER_TAIL ;TEST END OF BUFFER
|
|
; JNE K0B ;IF ANYTHING IN BUFFER DONT DO INTERRUPT
|
|
; MOV AX,09002H ;MOVE IN WAIT CODE & TYPE
|
|
; INT 15H ;PERFORM OTHER FUNCTION
|
|
|
|
K0B: CLI ;INTERRUPTS BACK OFF
|
|
MOV BX,BUFFER_HEAD ;GET POINTER TO HEAD OF BUFFER
|
|
CMP BX,BUFFER_TAIL ;TEST END OF BUFFER
|
|
JZ K0A ;LOOP UNTIL SOMETHING IN BUFFER
|
|
|
|
MOV AX,[BX] ;GET SCAN CODE AND ASCII CODE
|
|
call KTRANS
|
|
jz K0A ;discard Output
|
|
CALL K4 ;MOVE POINTER TO NEXT POSITION
|
|
K0C: MOV BUFFER_HEAD,BX ;STORE VALUE IN VARIABLE
|
|
pop cx
|
|
POP BX
|
|
POP DS
|
|
IRET
|
|
|
|
;------ ASCII STATUS
|
|
|
|
K1: push cx
|
|
mov cx,ax
|
|
mov bl,cs:TTYFLG1 ;war TTY_WRITE ?
|
|
or bl,bl
|
|
jnz K1a
|
|
mov bl,cs:KBCNT
|
|
inc cs:KBCNT
|
|
cmp bl,10
|
|
jnz K1b
|
|
K1a: call SCREEN_OUT
|
|
mov cs:KBCNT,0
|
|
|
|
K1b: CLI ;INTERRUPTS OFF
|
|
K1c: MOV BX,BUFFER_HEAD ;GET HEAD POINTER
|
|
CMP BX,BUFFER_TAIL ;IF EQUAL (Z=1) THEN NOTHING THERE
|
|
MOV AX,[BX]
|
|
jz K1d
|
|
call KTRANS
|
|
jnz K1d
|
|
call K4 ;kein gueltiges Zeichen
|
|
mov BUFFER_HEAD,bx
|
|
jmp short K1c
|
|
|
|
K1d: pop cx
|
|
POP BX
|
|
POP DS
|
|
STI
|
|
RET FAR 2
|
|
|
|
;Translate Code
|
|
|
|
KTRANS: cmp ch,3 ;extended Read ?
|
|
jc KT1 ,no
|
|
cmp al,0f0h ;xxf0 -> xx00
|
|
jnz KT0
|
|
xor al,al
|
|
KT0: cmp ax,-1
|
|
ret
|
|
|
|
;Extended Code in Normalcode umwandeln
|
|
|
|
KT1: or ah,ah ;wenn ah = 0, kein translate
|
|
jz KT0
|
|
cmp ah,0e0h
|
|
jnz KT4
|
|
cmp al,2fh ;wenn e02f -> 352f
|
|
jnz KT2
|
|
mov ax,352fh
|
|
jmp short KT0
|
|
KT2: cmp al,0dh ;wenn e00d -> 1c0d
|
|
jnz KT3
|
|
mov ax,1c0dh
|
|
jmp short KT0
|
|
KT3: cmp al,0ah ;wenn e00a -> 1c0a
|
|
jnz KT4
|
|
mov ax,1c0ah
|
|
jmp short KT0
|
|
KT4: cmp ah,85H ;wenn ah > 84 discard output
|
|
jnc KT5
|
|
cmp al,0f0h ;wenn al = f0 discard output
|
|
jz KT5
|
|
cmp al,0e0h ;wenn al = e0 -> al = 0
|
|
jnz KT0
|
|
xor al,al
|
|
jmp short KT0
|
|
|
|
KT5: mov ax,-1 ;discard Output
|
|
jmp short KT0
|
|
|
|
;------ INCREMENT A BUFFER POINTER
|
|
|
|
K4 ;PROC NEAR
|
|
INC BX ;MOVE TO NEXT WORD IN LIST
|
|
INC BX
|
|
CMP BX,BUFFER_END ;AT END OF BUFFER?
|
|
JNE K4A ;NO, CONTINUE
|
|
MOV BX,BUFFER_START ;YES, RESET TO BUFFER BEGINNING
|
|
K4A: RET
|
|
|
|
|
|
;---- Tastaturcode
|
|
;---- Normal-UK (lower case)
|
|
|
|
TNGER: defw ffffh, 011bh, 0231h, 0332h, 0433h, 0534h, 0635h, 0736h
|
|
defw 0837h, 0938h, 0a39h, 0b30h, 0c2dh, 0d3dh, 0e08h, 0f09h
|
|
defw 1071h, 1177h, 1265h, 1372h, 1474h, 1579h, 1675h, 1769h
|
|
defw 186fh, 1970h, 1a5bh, 1b5dh, 1c0dh, ffffh, 1e61h, 1f73h
|
|
defw 2064h, 2166h, 2267h, 2368h, 246ah, 256bh, 266ch, 273bh
|
|
defw 2827h, 2960h, ffffh, 2b23h, 2c7ah, 2d78h, 2e63h, 2f76h
|
|
defw 3062h, 316eh, 326dh, 332ch, 342eh, 352fh, ffffh, 372ah
|
|
defw ffffh, 3920h, ffffh, 3b00h, 3c00h, 3d00h, 3e00h, 3f00h
|
|
defw 4000h, 4100h, 4200h, 4300h, 4400h, ffffh, ffffh, 47e0h
|
|
defw 48e0h, 49e0h, 4a2dh, 4be0h, 4cf0h, 4de0h, 4e2bh, 4fe0h
|
|
defw 50e0h, 51e0h, 52e0h, 53e0h, ffffh, ffffh, 565ch, 8500h
|
|
defw 8600h
|
|
defw 1177h, 1372h
|
|
defw e02fh, e00dh
|
|
|
|
;---- Shift-UK
|
|
|
|
TSGER: defw ffffh, 011bh, 0221h, 0322h, 049ch, 0524h, 0625h, 075eh
|
|
defw 0826h, 092ah, 0a28h, 0b29h, 0c5fh, 0d2bh, 0e08h, 0f00h
|
|
defw 1051h, 1157h, 1245h, 1352h, 1454h, 1559h, 1655h, 1749h
|
|
defw 184fh, 1950h, 1a7bh, 1b7dh, 1c0dh, ffffh, 1e41h, 1f53h
|
|
defw 2044h, 2146h, 2247h, 2348h, 244ah, 254bh, 264ch, 273ah
|
|
defw 2840h, 297eh, ffffh, 2b7eh, 2c5ah, 2d58h, 2e43h, 2f56h
|
|
defw 3042h, 314eh, 324dh, 333ch, 343eh, 353fh, ffffh, 372ah
|
|
defw ffffh, 3920h, ffffh, 5400h, 5500h, 5600h, 5700h, 5800h
|
|
defw 5900h, 5a00h, 5b00h, 5c00h, 5d00h, ffffh, ffffh, 4737h
|
|
defw 4838h, 4939h, 4a2dh, 4b34h, 4c35h, 4d36h, 4e2bh, 4f31h
|
|
defw 5032h, 5133h, 5230h, 532eh, ffffh, ffffh, 567ch, 8700h
|
|
defw 8800h
|
|
defw 1157h, 1352h
|
|
defw e02fh, e00dh
|
|
|
|
;---- Normal-ASCII (lower case)
|
|
|
|
TNASC: defw ffffh, 011bh, 0231h, 0332h, 0433h, 0534h, 0635h, 0736h
|
|
defw 0837h, 0938h, 0a39h, 0b30h, 0c2dh, 0d3dh, 0e08h, 0f09h
|
|
defw 1071h, 1177h, 1265h, 1372h, 1474h, 1579h, 1675h, 1769h
|
|
defw 186fh, 1970h, 1a5bh, 1b5dh, 1c0dh, ffffh, 1e61h, 1f73h
|
|
defw 2064h, 2166h, 2267h, 2368h, 246ah, 256bh, 266ch, 273bh
|
|
defw 2827h, 2960h, ffffh, 2b5ch, 2c7ah, 2d78h, 2e63h, 2f76h
|
|
defw 3062h, 316eh, 326dh, 332ch, 342eh, 352fh, ffffh, 372ah
|
|
defw ffffh, 3920h, ffffh, 3b00h, 3c00h, 3d00h, 3e00h, 3f00h
|
|
defw 4000h, 4100h, 4200h, 4300h, 4400h, ffffh, ffffh, 47e0h
|
|
defw 48e0h, 49e0h, 4a2dh, 4be0h, 4cf0h, 4de0h, 4e2bh, 4fe0h
|
|
defw 50e0h, 51e0h, 52e0h, 53e0h, ffffh, ffffh, ffffh, 8500h
|
|
defw 8600h
|
|
defw 1177h, 1372h
|
|
defw e02fh, e00dh
|
|
|
|
;---- Shift-ASCII
|
|
|
|
TSASC: defw ffffh, 011bh, 0221h, 0340h, 0423h, 0524h, 0625h, 075eh
|
|
defw 0826h, 092ah, 0a28h, 0b29h, 0c5fh, 0d2bh, 0e08h, 0f00h
|
|
defw 1051h, 1157h, 1245h, 1352h, 1454h, 1559h, 1655h, 1749h
|
|
defw 184fh, 1950h, 1a7bh, 1b7dh, 1c0dh, ffffh, 1e41h, 1f53h
|
|
defw 2044h, 2146h, 2247h, 2348h, 244ah, 254bh, 264ch, 273ah
|
|
defw 2822h, 297eh, ffffh, 2b7ch, 2c5ah, 2d58h, 2e43h, 2f56h
|
|
defw 3042h, 314eh, 324dh, 333ch, 343eh, 353fh, ffffh, 372ah
|
|
defw ffffh, 3920h, ffffh, 5400h, 5500h, 5600h, 5700h, 5800h
|
|
defw 5900h, 5a00h, 5b00h, 5c00h, 5d00h, ffffh, ffffh, 4737h
|
|
defw 4838h, 4939h, 4a2dh, 4b34h, 4c35h, 4d36h, 4e2bh, 4f31h
|
|
defw 5032h, 5133h, 5230h, 532eh, ffffh, ffffh, ffffh, 8700h
|
|
defw 8800h
|
|
defw 1157h, 1352h
|
|
defw e02fh, e00dh
|
|
|
|
;---- Control-ASCII
|
|
|
|
TCASC: defw ffffh, 011bh, ffffh, 0300h, ffffh, ffffh, ffffh, 071eh
|
|
defw 081bh, 091bh, 0a1dh, 0b1dh, 0c1ch, 0d00h, 0e7fh, 94f0h
|
|
defw 1011h, 1117h, 1205h, 1312h, 1414h, 151ah, 1615h, 1709h
|
|
defw 180fh, 1910h, 1a1bh, 1b1dh, 1c0ah, ffffh, 1e01h, 1f13h
|
|
defw 2004h, 2106h, 2207h, 2308h, 240ah, 250bh, 260ch, ffffh
|
|
defw ffffh, 291eh, ffffh, ffffh, 2c19h, 2d18h, 2e03h, 2f16h
|
|
defw 3002h, 310eh, 320dh, ffffh, ffffh, 351fh, ffffh, 9600h
|
|
defw ffffh, 3920h, ffffh, 5e00h, 5f00h, 6000h, 6100h, 6200h
|
|
defw 6300h, 6400h, 6500h, 6600h, 6700h, ffffh, ffffh, 77e0h
|
|
defw 8de0h, 84e0h, 8e00h, 73e0h, 8f00h, 74e0h, 9000h, 75e0h
|
|
defw 91e0h, 76e0h, 92e0h, 93e0h, ffffh, ffffh, ffffh, 8900h
|
|
defw 8a00h
|
|
defw 1117h, 1312h
|
|
defw 9500h, e00ah
|
|
|
|
;---- left Alt-ASCII
|
|
|
|
TAASC: defw 4ef0h, 01f0h, 7800h, 7900h, 7a00h, 7b00h, 7c00h, 7d00h
|
|
defw 7e00h, 7f00h, 8000h, 8100h, 0cf0h, 0df0h, 0ef0h, a500h
|
|
defw 1000h, 1100h, 1200h, 1300h, 1400h, 1500h, 1600h, 1700h
|
|
defw 1800h, 1900h, 1af0h, 1bf0h, 1cf0h, ffffh, 1e00h, 1f00h
|
|
defw 2000h, 2100h, 2200h, 2300h, 2400h, 2500h, 2600h, 27f0h
|
|
defw 28f0h, 29f0h, ffffh, 2bf0h, 2c00h, 2d00h, 2e00h, 2f00h
|
|
defw 3000h, 3100h, 3200h, 33f0h, 34f0h, 35f0h, ffffh, 37f0h
|
|
defw ffffh, 3920h, ffffh, 6800h, 6900h, 6a00h, 6b00h, 6c00h
|
|
defw 6d00h, 6e00h, 6f00h, 7000h, 7100h, ffffh, ffffh, 9700h
|
|
defw 9800h, 9900h, 4af0h, 9b00h, ffffh, 9d00h, 4ef0h, 9f00h
|
|
defw a000h, a100h, a200h, a300h, ffffh, ffffh, 56f0h, 8b00h
|
|
defw 8c00h
|
|
defw 1100h, 1300h
|
|
defw a400h, a600h
|
|
|
|
;---- right Alt-ASCII
|
|
|
|
TARASC: defw 4e2bh, 011bh, ffffh, 03fdh, 04fch, ffffh, ffffh, ffffh
|
|
defw 087bh, 095bh, 0a5dh, 0b7dh, 0c5ch, ffffh, ffffh, ffffh
|
|
defw 1040h, ffffh, ffffh, ffffh, ffffh, ffffh, ffffh, ffffh
|
|
defw ffffh, ffffh, ffffh, 1b7eh, 1c0dh, ffffh, ffffh, ffffh
|
|
defw ffffh, ffffh, ffffh, ffffh, ffffh, ffffh, ffffh, ffffh
|
|
defw ffffh, ffffh, ffffh, ffffh, ffffh, ffffh, ffffh, ffffh
|
|
defw ffffh, ffffh, 32e6h, ffffh, ffffh, ffffh, ffffh, 372ah
|
|
defw ffffh, 3920h, ffffh, 3b00h, 3c00h, 3d00h, 3e00h, 3f00h
|
|
defw 4000h, 4100h, 4200h, 4300h, 4400h, ffffh, ffffh, 4737h
|
|
defw 4838h, 4939h, 4a2dh, 4b34h, 4c35h, 4d36h, 4e3dh, 4f31h
|
|
defw 5032h, 5133h, 5230h, 532eh, ffffh, ffffh, 567ch, 8500h
|
|
defw 8600h
|
|
defw ffffh, ffffh
|
|
defw e02fh, e00dh
|
|
|
|
|
|
;------ KEYBOARD INTERRUPT ROUTINE
|
|
|
|
KBLAST: defb 0
|
|
|
|
KBINT ;PROC FAR
|
|
sti
|
|
db 60h ;pusha
|
|
push ds
|
|
push es
|
|
push cs
|
|
pop es
|
|
cld ;vorwaerts
|
|
call DDS
|
|
mov cs:intin,0 ;naechsten Int freigeben
|
|
mov al,cs:ttyin+2
|
|
mov ah,al
|
|
mov dl,cs:KBLAST
|
|
and dl,0feh
|
|
mov cs:KBLAST,al
|
|
|
|
;------ TEST FOR OVERRUN SCAN CODE FROM KEYBOARD
|
|
|
|
cmp al,0ffh ;IS THIS AN OVERRUN CHAR
|
|
jnz TESTE0
|
|
jmp BELL ;Bell
|
|
|
|
;------- Test for e0 1c and e0 35
|
|
|
|
TESTE0: and al,7fh
|
|
cmp dl,0e0h
|
|
jnz SYSKEY
|
|
cmp al,35h
|
|
jnz TEST1
|
|
mov al,5bh
|
|
jmp BREAK_CODE
|
|
TEST1: cmp al,1ch
|
|
jnz SYSKEY
|
|
mov al,5ch
|
|
jmp BREAK_CODE
|
|
|
|
|
|
;------- TEST FOR SYSTEM KEY
|
|
|
|
SYSKEY: cmp al,54h ;IS IT THE SYSTEM KEY
|
|
jnz SHIFTKEY
|
|
|
|
mov cs:ttyin+1,0 ;Tastatur Int enable
|
|
test ah,80h ;CHECK IF THIS A BREAK CODE
|
|
jnz SYS_BREAK ;DONT TOUCH SYSTEM INDICATOR IF TRUE
|
|
|
|
test KB_FLAG_1,04h ;SEE IF IN SYSTEM KEY HELD DOWN
|
|
jnz KEND0 ;IF YES, DONT PROCESS SYSTEM INDICATOR
|
|
|
|
or KB_FLAG_1,04h ;INDICATE SYSTEM KEY DEPRESSED
|
|
or KB_FLAG_2,80h
|
|
mov ax,8500h ;FUNCTION VALUE FOR MAKE OF SYSTEM KEY
|
|
int 15h ;USER INTERRUPT
|
|
jmp short KEND0 ;END PROCESSING
|
|
|
|
SYS_BREAK:
|
|
and KB_FLAG_1,0fdh ;TURN OFF SHIFT KEY HELD DOWN
|
|
and KB_FLAG_2,7fh
|
|
mov cs:ttyin+1,0 ;Tastatur Int enable
|
|
mov ax,08501H ;FUNCTION VALUE FOR BREAK OF SYSTEM KEY
|
|
int 15h ;USER INTERRUPT
|
|
KEND0: jmp KEND1 ;IGNORE SYSTEM KEY
|
|
|
|
;------ TEST FOR SHIFT KEYS
|
|
|
|
SHIFTKEY:
|
|
sub bx,bx
|
|
cmp al,2ah ;left shift
|
|
jnz RSHIFT
|
|
mov bl,02h
|
|
jmp short SET_SHIFT
|
|
|
|
RSHIFT: cmp al,36h ;right shift
|
|
jnz CSHIFT
|
|
mov bl,01h
|
|
jmp short SET_SHIFT
|
|
|
|
CSHIFT: cmp al,1dh ;control
|
|
jnz ASHIFT
|
|
mov bl,04h
|
|
cmp dl,0e0h
|
|
jz RCSHIFT
|
|
mov bh,01h ;left control
|
|
jmp short SET_SHIFT
|
|
|
|
RCSHIFT:
|
|
mov bh,04h ;right control
|
|
jmp short SET_SHIFT
|
|
|
|
ASHIFT: cmp al,38h ;alt
|
|
jnz SHIFT_TOGGLE
|
|
mov bl,08h
|
|
cmp dl,0e0h
|
|
jz RASHIFT
|
|
mov bh,02h ;left alt
|
|
jmp short SET_SHIFT
|
|
|
|
RASHIFT:
|
|
mov bh,08h ;right alt
|
|
|
|
SET_SHIFT:
|
|
test ah,80h ;break code ?
|
|
jnz RES_SHIFT
|
|
|
|
or KB_FLAG,bl ;set shift
|
|
or KB_FLAG_2,bh
|
|
KEND3: jmp KEND
|
|
|
|
RES_SHIFT:
|
|
not bx
|
|
and KB_FLAG,bl ;res shift
|
|
and KB_FLAG_2,bh
|
|
|
|
cmp al,38h ;IS THIS ALTERNATE SHIFT RELEASE
|
|
jne KEND3
|
|
|
|
;------ ALTERNATE SHIFT KEY RELEASED, GET THE VALUE INTO BUFFER
|
|
|
|
mov al,ALT_INPUT
|
|
sub ah,ah ;SCAN CODE OF 0
|
|
mov ALT_INPUT,ah ;ZERO OUT THE FIELD
|
|
or al,al ;WAS THE INPUT=0
|
|
jz KEND3 ;INTERRUPT_RETURN
|
|
jmp BFILL ;IT WASNT, SO PUT IN BUFFER
|
|
|
|
;------ TOGGLED SHIFT KEY, TEST FOR IST MAKE OR NOT
|
|
|
|
SHIFT_TOGGLE:
|
|
test KB_FLAG,04h ;CHECK CTL SHIFT STATE
|
|
jnz BREAK_CODE ;JUMP IF CTL STATE
|
|
|
|
cmp al,52h ;CHECK FOR INSERT KEY
|
|
jnz CAPS_LOCK ;JUMP IF NOT INSERT KEY
|
|
|
|
test KB_FLAG,08h ;CHECK FOR ALTERNATE SHIFT
|
|
jnz BREAK_CODE ;JUMP IF ALTERNATE SHIFT
|
|
|
|
test KB_FLAG,20h ;CHECK FOR NUM STATE
|
|
jnz INS1 ;JUMP IF NUM LOCK IS ON
|
|
test KB_FLAG,03h ;LEFT OR RIGHT SHIFT ?
|
|
jnz BREAK_CODE ;no NUM_LOCK
|
|
jmp short INS2
|
|
|
|
INS1: ;MIGHT BE NUMERIC
|
|
test KB_FLAG,03h ;LEFT OR RIGHT SHIFT ?
|
|
jz BREAK_CODE ;JUMP NUMERIC, NOT INSERT
|
|
|
|
INS2: ;Insert is tru
|
|
mov bx,0080h
|
|
jmp short SET_TOGGLE
|
|
|
|
CAPS_LOCK:
|
|
cmp al,3ah
|
|
jnz NUM_LOCK
|
|
mov bx,4040h
|
|
jmp short SET_TOGGLE
|
|
|
|
NUM_LOCK:
|
|
cmp al,45h
|
|
jnz SCROLL_LOCK
|
|
mov bx,2020h
|
|
jmp short SET_TOGGLE
|
|
|
|
SCROLL_LOCK:
|
|
cmp al,46h
|
|
jnz BREAK_CODE
|
|
mov bx,1010h
|
|
|
|
SET_TOGGLE:
|
|
test ah,80h
|
|
jnz RES_TOGGLE
|
|
|
|
test bl,KB_FLAG_1 ;IS KEY ALREADY DEPRESSED
|
|
jnz KEND ;JUMP IF KEY ALREADY DEPRESSED
|
|
or KB_FLAG_1,bl ;INDICATE THAT THE KEY IS DEPRESSED
|
|
or KB_FLAG_2,bh
|
|
xor KB_FLAG,bl ;TOGGLE THE SHIFT STATE
|
|
cmp al,52h ;TEST FOR IST MAKE OF INSERT KEY
|
|
jne KEND ;JUMP IF NOT INSERT KEY
|
|
jmp short BREAK_CODE
|
|
|
|
RES_TOGGLE:
|
|
not bx ;INVERT MASK
|
|
and KB_FLAG_1,bl ;INDICATE NO LONGEST DEPRESSED
|
|
and KB_FLAG_2,bh
|
|
jmp short KEND
|
|
|
|
|
|
;------ No shift found, test for break code
|
|
|
|
BREAK_CODE:
|
|
cmp ah,80h ;TEST FOR BREAK KEY
|
|
jae KEND ;NOTHING FOR BREAK CHARS FROM HERE ON
|
|
|
|
;------ TEST FOR HOLD STATE
|
|
|
|
test KB_FLAG_1,08h ;ARE WE IN HOLD STATE
|
|
jz ALTSHIFT ;BRANCH AROUND TEST IF NOT
|
|
cmp al,45h ;NUM_KEY
|
|
je KEND ;CANT END HOLD ON NUM LOCK
|
|
and KB_FLAG_1,0f7h ;TURN OFF THE HOLD STATE BIT
|
|
|
|
KEND: cli ;INTERRUPT-RETURN
|
|
mov cs:ttyin+1,0 ;Tastatur Int enable
|
|
KEND1:
|
|
pop es ;RESTORE REGISTERS
|
|
pop ds
|
|
db 61h ;popa
|
|
iret
|
|
|
|
;------ ALT-INPUT-TABLE
|
|
|
|
K30: DB 82,79,80,81,75,76,77
|
|
DB 71,72,73 ;10 NUMBERS ON KEYPAD
|
|
|
|
;------ NOT IN HOLD STATE
|
|
|
|
ALTSHIFT:
|
|
test KB_FLAG,08h ;ARE WE IN ALTERNATE SHIFT
|
|
jz CTLSHIFT ;JUMP IF NOT ALTERNATE
|
|
|
|
test KB_FLAG_1,01h ;German ?
|
|
jnz ALTS0 ;no
|
|
test KB_FLAG_2,08h ;right alt ?
|
|
jz ALTS0
|
|
TRANS3: mov bx,offset TARASC ;right ALT-Code Table
|
|
jmp TRANS
|
|
|
|
;------ TEST FOR RESET KEY SEQUENCE (CTL ALT DEL)
|
|
|
|
ALTS0: test KB_FLAG,04h ;ARE WE IN CONTROL SHIFT ALSO
|
|
jz NUM
|
|
cmp al,53h ;SHIFT STATE IS THERE, TEST KEY
|
|
jne NO_RESET
|
|
|
|
;------ CTL-ALT-DEL HAS BEEN FOUND, DO I/O CLEANUP
|
|
|
|
cli
|
|
mov cs:ttyin+1,0 ;Tastatur Int enable
|
|
mov RESET_FLAG,1234h ;SET FLAG FOR RESET FUNCTION
|
|
jmp START ;JUMP TO POWER ON DIAGNOSTICS
|
|
|
|
;------ CTL-ALT-F1 ASCII
|
|
|
|
NO_RESET:
|
|
cmp al,3bh
|
|
jnz GERMAN
|
|
or KB_FLAG_1,01h
|
|
jmp KEND
|
|
|
|
;------ CTL-ALT-F2 German
|
|
|
|
GERMAN: cmp al,3ch
|
|
jnz ALT1
|
|
and KB_FLAG_1,0feh
|
|
jmp KEND
|
|
|
|
;------ Rest von CTL-ALT wie ALT1 behandeln
|
|
|
|
ALT1: test KB_FLAG_1,01h ;German ?
|
|
jz TRANS3 ;yes
|
|
|
|
;------ IN ALTERNATE SHIFT
|
|
;------ LOOK FOR KEY PAD ENTRY
|
|
|
|
NUM: cmp dl,0e0h
|
|
jz ALTS1
|
|
mov di,offset K30 ;ALT-INPUT-TABLE
|
|
mov cx,10 ;LOOK FOR ENTRY USING KEYPAD
|
|
repne scasb ;LOOK FOR MATCH
|
|
jne ALTS1 ;NO_ALT-KEYPAD
|
|
|
|
sub di,offset K30+1 ;DI NOW HAS ENTRY VALUE
|
|
mov al,ALT_INPUT ;GET THE CURRENT BYTE
|
|
mov ah,10 ;MULTIPLY BY 10
|
|
mul ah
|
|
add ax,di ;ADD IN THE LATEST ENTRY
|
|
mov ALT_INPUT,al ;STORE IT AWAY
|
|
jmp KEND ;THROW AWAY THAT KEYSTROKE
|
|
|
|
;------ LOOK FOR ALT CODE
|
|
|
|
ALTS1: mov ALT_INPUT,0 ;ZERO ANY PREVIOUS ENTRY INTO INPUT
|
|
mov bx,offset TAASC ;left ALT-Code Table
|
|
ALTS2: jmp TRANS
|
|
|
|
;------ NOT IN ALTERNATE SHIFT
|
|
|
|
CTLSHIFT:
|
|
test KB_FLAG,04h ;ARE WE IN CONTROL SHIFT
|
|
jz NO_CTL ;NOT-CTL-SHIFT
|
|
|
|
;------ CONTROL SHIFT, TEST SPECIAL CHARACTERS
|
|
;------ TEST FOR BREAK (CTL SCROLL) AND PAUSE KEYS
|
|
|
|
cmp al,46h ;TEST FOR BREAK
|
|
jne NO_BREAK
|
|
mov bx,BUFFER_START ;RESET BUFFER TO EMPTY
|
|
mov BUFFER_HEAD,bx
|
|
mov BUFFER_TAIL,bx
|
|
mov BIOS_BREAK,80h ;TURN ON BIOS_BREAK BIT
|
|
int 1bh ;BREAK INTERRUPT VECTOR
|
|
sub ax,ax ;PUT OUT DUMMY CHARACTER
|
|
jmp BFILL ;BUFFER_FILL
|
|
|
|
NO_BREAK:
|
|
cmp al,45h ;LOOK FOR PAUSE KEY
|
|
jne NO_PAUSE
|
|
|
|
or KB_FLAG_1,08h ;TURN ON THE HOLD FLAG
|
|
mov cs:ttyin+1,0 ;Tastatur Int enable
|
|
|
|
;------ PAUSE INTERVAL
|
|
|
|
PAUSE: test KB_FLAG_1,08h
|
|
jnz PAUSE ;LOOP UNTIL FLAG TURNED OFF
|
|
jmp KEND1 ;INTERRUPT_RETURN_NO_EOI
|
|
|
|
;------ TEST SPECIAL CASE KEY E0 55
|
|
|
|
NO_PAUSE:
|
|
cmp al,37h
|
|
jne NO_PRINT ;NOT-KEY-55
|
|
cmp dl,0e0h
|
|
jne NO_PRINT
|
|
mov ax,114*256 ;START/STOP PRINTING SWITCH
|
|
jmp BFILL ;BUFFER FILL
|
|
|
|
;------ SET UP TO TRANSLATE CONTROL SHIFT
|
|
|
|
NO_PRINT:
|
|
mov bx,offset TCASC
|
|
jmp TRANS
|
|
|
|
|
|
;------ NOT IN CONTROL SHIFT
|
|
|
|
NO_CTL: cmp dl,0e0h
|
|
jnz NO_E0
|
|
|
|
;------ HANDLE SPECIAL CASES
|
|
|
|
cmp al,37h ;PRINT SCREEN KEY
|
|
jne NO_SHIFT
|
|
|
|
;------ ISSUE INTERRUPT TO INDICATE PRINT SCREEN FUNCTION
|
|
|
|
mov cs:ttyin+1,0 ;Tastatur Int enable
|
|
int 5h ;ISSUE PRINT SCREEN INTERRUPT
|
|
jmp KEND1 ;GO BACK WITHOUT EOI OCCURRING
|
|
|
|
|
|
NO_E0: mov bx,offset TSGER ;German upper case table
|
|
test KB_FLAG_1,01h
|
|
jz KPAD
|
|
mov bx,offset TSASC ;ASCII upper case table
|
|
KPAD: cmp al,47h ;TEST FOR KEYPAD REGION
|
|
jc NO_KPAD
|
|
|
|
;------ KEYPAD KEYS, MUST TEST NUM LOCK FOR DETERMINATION
|
|
|
|
cmp al,54h
|
|
jnc NO_KPAD
|
|
test KB_FLAG,20h ;ARE WE IN NUM LOCK
|
|
jnz NUM_STATE ;TEST FOR SURE
|
|
NO_KPAD:
|
|
test KB_FLAG,03h ;LEFT_SHIFT+RIGHT_SHIFT
|
|
jnz TRANS ;IF SHIFTED, REALLY NUM STATE
|
|
jmp short NO_SHIFT ;BASE CASE FOR KEYPAD
|
|
|
|
;------ MIGHT BE NUM LOCK, TEST SHIFT STATUS
|
|
|
|
NUM_STATE: ;ALMOST-NUM-STATE
|
|
test KB_FLAG,03h ;LEFT_SHIFT+RIGHT_SHIFT
|
|
jz TRANS
|
|
|
|
;------ LOWER CASE
|
|
|
|
NO_SHIFT:
|
|
mov bx,offset TNGER ;German lower case table
|
|
test KB_FLAG_1,01h
|
|
jz TRANS
|
|
mov bx,offset TNASC ;ASCII lower case table
|
|
|
|
;------ TRANSLATE THE CHARACTER
|
|
|
|
TRANS: add al,al
|
|
sub ah,ah
|
|
add ax,bx
|
|
mov bx,ax
|
|
mov ax,cs:[bx]
|
|
cmp ax,-1
|
|
jz KEND2
|
|
cmp al,0e0h ;Extended Code ?
|
|
jnz BFILL
|
|
cmp dl,0e0h ;last byte e0 ?
|
|
jz BFILL
|
|
sub al,al ;no al = 0
|
|
|
|
;------ PUT CHARACTER INTO BUFFER
|
|
;------ HANDLE THE CAPS LOCK PROBLEM
|
|
|
|
BFILL: test KB_FLAG,40h ;ARE WE IN CAPS LOCK STATE ?
|
|
jz NO_CAPS ;SKIP IF NOT
|
|
|
|
;------ IN CAPS LOCK STATE
|
|
|
|
test KB_FLAG,03h ;LEFT_SHIFT+RIGHT_SHIFT
|
|
jz LOUP ;IF NOT SHIFT, CONVERT LOWER TO UPPER
|
|
|
|
;------ CONVERT ANY UPPER CASE TO LOWER CASE
|
|
|
|
cmp al,'A' ;FIND OUT IF ALPHABETIC
|
|
jc NO_CAPS ;NOT_CAPS_STATE
|
|
cmp al,'Z'
|
|
ja UML1
|
|
add al,20h ;CONVERT TO LOWER CASE
|
|
jmp short NO_CAPS
|
|
|
|
;KEND2: jmp KEND
|
|
|
|
;---- Behandlung der Umlaute
|
|
|
|
UML1: cmp al,8eh ;Ae
|
|
jnz UML2
|
|
mov al,84h ;ae
|
|
jmp short NO_CAPS
|
|
|
|
UML2: cmp al,99h ;Oe
|
|
jnz UML3
|
|
mov al,94h ;oe
|
|
jmp short NO_CAPS
|
|
|
|
UML3: cmp al,9Ah ;Ue
|
|
jnz NO_CAPS
|
|
mov al,81h
|
|
jmp short NO_CAPS
|
|
|
|
;------ CONVERT ANY LOWER CASE TO UPPER CASE
|
|
|
|
LOUP: cmp al,'a' ;FIND OUT IF ALPHABETIC
|
|
jc NO_CAPS
|
|
cmp al,'z'
|
|
ja UML4
|
|
sub al,20h ;CONVERT TO UPPER CASE
|
|
jmp short NO_CAPS
|
|
|
|
;---- Behandlung der Umlaute
|
|
|
|
UML4: cmp al,84h ;ae
|
|
jnz UML5
|
|
mov al,8eh ;Ae
|
|
jmp short NO_CAPS
|
|
|
|
UML5: cmp al,94h ;oe
|
|
jnz UML6
|
|
mov al,99h ;Oe
|
|
jmp short NO_CAPS
|
|
|
|
UML6: cmp al,81h ;ue
|
|
jnz NO_CAPS
|
|
mov al,9ah ;Ue
|
|
|
|
NO_CAPS:
|
|
mov bx,BUFFER_TAIL ;GET THE END POINTER TO THE BUFFER
|
|
mov si,bx ;SAVE THE VALUE
|
|
call K4 ;ADVANCE THE TAIL
|
|
cmp bx,BUFFER_HEAD ;HAS THE BUFFER WRAPPED AROUND
|
|
je BELL ;BUFFER_FULL_BEEP
|
|
mov [si],ax ;STORE THE VALUE
|
|
mov BUFFER_TAIL,bx ;MOVE THE POINTER UP
|
|
mov ax,9102h ;MOVE IN POST CODE & TYPE
|
|
int 15h ;PERFORM OTHER FUNCTION
|
|
KEND2: jmp KEND ;INTERRUPT_RETURN
|
|
|
|
;------ BUFFER IS FULL, SOUND THE BEEPER
|
|
|
|
BELL: mov al,07h ;Bell
|
|
call PUTA
|
|
jmp KEND
|
|
|
|
|
|
;--- INT 10 --------------------------------------------------------------
|
|
;VIDEO_IO
|
|
; THESE ROUTINES PROVIDE THE CRT INTERFACE
|
|
; THE FOLLOWING FUNCTIONS ARE PROVIDED:
|
|
; (AH)=0 SET MODE - nur Mode 7 moeglich
|
|
; (AH)=1 SET CURSOR TYPE - nicht moeglich
|
|
; (AH)=2 SET CURSOR POSITION
|
|
; (AH)=3 READ CURSOR POSITION
|
|
; (AH)=4 READ LIGHT PEN POSITION - nicht moeglich
|
|
; (AH)=5 SELECT ACTIVE DISPLAY PAGE - nur Page 0
|
|
; (AH)=6 SCROLL ACTIVE PAGE UP
|
|
; (AH)=7 SCROLL ACTIVE PAGE DOWN
|
|
;CHARAKTER HANDLING ROUTINES
|
|
; (AH)=8 READ ATTRIBUTE/CHARAKTER AT CURRENT CURSOR POSITION
|
|
; (AH)=9 WRITE ATTRIBUTE/CHARAKTER AT CURRENT CURSOR POSITION
|
|
; (AH)=10 WRITE CHARACTER ONLY AT CURRENT CURSOR POSITION
|
|
;GRAPHICS INTERFACE
|
|
; (AH)=11 SET COLOR PALETTE - nicht moeglich
|
|
; (AH)=12 WRITE DOT - nicht moeglich
|
|
; (AH)=13 READ DOT - nicht moeglich
|
|
;ASCII TELETYPE ROUTINE FOR OUTPUT
|
|
; (AH)=14 WRITE TELETYPE TO ACTIVE PAGE
|
|
; (AH)=15 CURRENT VIDEO STATE
|
|
; (AH)=16 RESERVED
|
|
; (AH)=17 RESERVED
|
|
; (AH)=18 RESERVED
|
|
; (AH)=19 WRITE STRING
|
|
; (AL) = 0
|
|
; BL - ATTRIBUTE
|
|
; STRING IS [CHAR,CHAR, ... ,CHAR]
|
|
; CURSOR NOT MOVED
|
|
; (AL) = 1
|
|
; BL - ATTRIBUTE
|
|
; STRING IS [CHAR,CHAR, ... ,CHAR]
|
|
; CURSOR IS MOVED
|
|
; (AL) = 2
|
|
; STRING IS [CHAR,ATTR,CHAR,ATTR, ... ,CHAR,ATTR]
|
|
; CURSOR IS NOT MOVED
|
|
; (AL) = 3
|
|
; STRING IS [CHAR,ATTR,CHAR,ATTR, ... ,CHAR,ATTR]
|
|
; CURSOR IS MOVED
|
|
; NOTE: CARRIAGE RETURN, LINE FEED, BACKSPACE, AND BELL ARE
|
|
; TREATED AS COMMANDS RATHER THEN PRINTABLE CHARACTERS.
|
|
;
|
|
; SS,SP,ES,DS,DX,CX,BX,SI,DI,BP PRESERVED DURING CALL
|
|
; ALL OTHERS DESTROYED.
|
|
;-------------------------------------------------------------------------
|
|
|
|
.PUBLIC SET_MODE
|
|
.PUBLIC SET_CTYPE
|
|
.PUBLIC SET_CPOS
|
|
.PUBLIC READ_CURSOR
|
|
.PUBLIC READ_LPEN
|
|
.PUBLIC ACT_DISP_PAGE
|
|
.PUBLIC SCROLL_UP
|
|
.PUBLIC SCROLL_DOWN
|
|
.PUBLIC READ_AC_CURRENT
|
|
.PUBLIC WRITE_AC_CURRENT
|
|
.PUBLIC WRITE_C_CURRENT
|
|
.PUBLIC SET_COLOR
|
|
.PUBLIC WRITE_DOT
|
|
.PUBLIC READ_DOT
|
|
.PUBLIC WRITE_TTY
|
|
.PUBLIC VIDEO_STATE
|
|
|
|
V1 DW SET_MODE
|
|
DW SET_CTYPE
|
|
DW SET_CPOS
|
|
DW READ_CURSOR
|
|
DW READ_LPEN
|
|
DW ACT_DISP_PAGE
|
|
DW SCROLL_UP
|
|
DW SCROLL_DOWN
|
|
DW READ_AC_CURRENT
|
|
DW WRITE_AC_CURRENT
|
|
DW WRITE_C_CURRENT
|
|
DW SET_COLOR
|
|
DW WRITE_DOT
|
|
DW READ_DOT
|
|
DW WRITE_TTY
|
|
DW VIDEO_STATE
|
|
DW VIDEO_RETURN ;Reserved
|
|
DW VIDEO_RETURN ;Reserved
|
|
DW VIDEO_RETURN ;Reserved
|
|
DW WRITE_STRING ;CASE 19h, Write string
|
|
V1L EQU $-V1
|
|
|
|
VIDEO ;PROC NEAR ;ENTRY POINT FOR ORG 0F065H
|
|
STI ;INTERRUPTS BACK ON
|
|
CLD ;SET DIRECTION FORWARD
|
|
PUSH ES
|
|
PUSH DS ;SAVE SEGMENT REGISTERS
|
|
PUSH DX
|
|
PUSH CX
|
|
PUSH BX
|
|
PUSH SI
|
|
PUSH DI
|
|
PUSH BP
|
|
PUSH AX ;SAVE AX VALUE
|
|
cmp ah,14 ;WRITE TTY ?
|
|
jz V0
|
|
mov byte ptr cs:TTYFLG,0
|
|
V0: MOV AL,AH ;GET INTO LOW BYTE
|
|
XOR AH,AH ;ZERO TO HIGH BYTE
|
|
SAL AX,1 ;*2 FOR TABLE LOOKUP
|
|
MOV SI,AX ;PUT INTO SI FOR BRANCH
|
|
CMP AX,V1L ;TEST FOR WITHIN RANGE
|
|
JB V2 ;BRANCH AROUND BRANCH
|
|
POP AX ;THROW AWAY THE PARAMETER
|
|
JMP short VIDEO_RETURN
|
|
|
|
V2: CALL DDS
|
|
MOV AX,0B000H ;SEGMENT FOR BW CARD
|
|
MOV ES,AX ;SET UP TO POINT AT VIDEO RAM AREAS
|
|
POP AX ;RECOVER VALUE
|
|
CMP AH,13H ;TEST FOR WRITE STRING OP
|
|
JNE V3
|
|
PUSH BP ;IF IT'S WRITE STRING THEN GET THE
|
|
MOV BP,SP ;STRINGS SEGMENT,SINCE IT GET CLOBBERED
|
|
MOV ES,[BP]+10H ;MOV ES,[BP].ES_POS ????
|
|
POP BP
|
|
|
|
V3: JMP CS:[SI]+V1
|
|
|
|
;---------------------------------------------------------------
|
|
;LIGHT PEN Implementation nicht moeglich
|
|
;ACT_DISP_PAGE
|
|
;SET_COLOR
|
|
;READ DOT -- WRITE DOT
|
|
;---------------------------------------------------------------
|
|
READ_LPEN: ;AH = 0 = nicht verfuegbar
|
|
mov ah,0 ;nicht verfuegbar
|
|
jmp short VIDEO_RETURN
|
|
READ_DOT: ;AL = DOT VALUE
|
|
sub al,al
|
|
ACT_DISP_PAGE:
|
|
SET_COLOR:
|
|
WRITE_DOT:
|
|
|
|
;------ NORMAL RETURN FROM ALL VIDEO RETURNS
|
|
VIDEO_RETURN:
|
|
POP BP
|
|
POP DI
|
|
POP SI
|
|
POP BX
|
|
POP CX
|
|
POP DX
|
|
POP DS
|
|
POP ES
|
|
IRET
|
|
|
|
;-----------------------------------------------------
|
|
;SET_MODE
|
|
;Mode setzen und Bildschirm loeschen
|
|
;-----------------------------------------------------
|
|
CURSOR_TTY:
|
|
defw -1
|
|
|
|
SET_MODE ;PROC NEAR
|
|
mov CRT_MODE,7
|
|
mov CRT_COLS,80
|
|
mov CRT_LEN,2*25*80
|
|
mov ADDR_6845,03b4h
|
|
mov bh,07h ;Attribut
|
|
call CLR_TTY ;Bildschirm loeschen
|
|
mov CURSOR_POSN,0 ;Cursor Home setzen
|
|
mov word ptr cs:CURSOR_TTY,-1 ;Cursor synchronisieren
|
|
mov bx,ax
|
|
call CURSOR_OUT
|
|
mov ax,bx
|
|
jmp short VIDEO_RETURN
|
|
|
|
CLR_TTY:
|
|
;------ ADM 31 Escape-Folge Bildschirm loeschen
|
|
mov bx,ax
|
|
mov al,1bh ;Video-Attribute ruecksetzen
|
|
call PUTA
|
|
mov al,'G'
|
|
call PUTA
|
|
mov al,'0'
|
|
call PUTA
|
|
mov al,1bh ;Loeschen
|
|
call PUTA
|
|
mov al,';'
|
|
call PUTA
|
|
|
|
;------ beide Bildschirmpuffer mit Space fuellen
|
|
|
|
xor di,di ;SET UP POINTER
|
|
mov cx,800h+25*80 ;NUMBER OF WORDS
|
|
mov al,20h ;FILL CHAR
|
|
mov ah,bh ;Attribut
|
|
mov ah,07h
|
|
rep stosw ;FILL THE REGEN BUFFER WITH BLANKS
|
|
mov ax,bx
|
|
ret
|
|
|
|
;---------------------------------------------------------
|
|
;SET_CTYPE
|
|
;---------------------------------------------------------
|
|
SET_CTYPE ;PROC NEAR ;**** nicht moeglich
|
|
mov CURSOR_MODE,cx
|
|
jmp short VIDEO_RETURN
|
|
|
|
;---------------------------------------------------------------
|
|
;SET_CPOS
|
|
; THIS ROUTINE SETS THE CURRENT CURSOR POSITION TO THE
|
|
; NEW X-Y VALUES PASSED
|
|
;INPUT
|
|
; DX - ROW, COLUMN OF NEW CURSOR
|
|
;OUTPUT
|
|
; CURSOR IS SET
|
|
;---------------------------------------------------------------
|
|
SET_CPOS ;PROC NEAR ;nur 1 Page moeglich
|
|
mov CURSOR_POSN,dx
|
|
jmp short VIDEO_RETURN
|
|
|
|
;---------------------------------------------------------------
|
|
;READ_CURSOR
|
|
; THIS ROUTINE READS THE CURRENT CURSOR VALUE
|
|
;OUTPUT
|
|
; DX - ROW, COLUMN OF THE CURRENT CURSOR POSITION
|
|
; CX - CURRENT CURSOR MODE
|
|
;---------------------------------------------------------------
|
|
READ_CURSOR ;PROC NEAR ;nur 1 Page
|
|
mov dx,CURSOR_POSN
|
|
mov cx,CURSOR_MODE
|
|
POP BP
|
|
POP DI
|
|
POP SI
|
|
POP BX
|
|
POP AX ;DISCARD SAVED CX AND DX
|
|
POP AX
|
|
POP DS
|
|
POP ES
|
|
IRET
|
|
|
|
;---------------------------------------------------------------
|
|
;VIDEO_STATE
|
|
; RETURNS THE CURRENT VIDEO STATE IN AX
|
|
; AH = NUMBER OF COLUMNS ON THE SCREEN
|
|
; AL = CURRENT VIDEO MODE
|
|
; BH = CURRENT ACTIVE PAGE
|
|
;---------------------------------------------------------------
|
|
VIDEO_STATE ;PROC NEAR
|
|
mov ah,80 ;GET NUMBER OF COLUMNS
|
|
mov al,7 ;CURRENT MODE
|
|
mov bh,0 ;GET CURRENT ACTIVE PAGE
|
|
POP BP
|
|
POP DI
|
|
POP SI
|
|
POP CX ;DISCARD SAVED BX
|
|
POP CX
|
|
POP DX
|
|
POP DS
|
|
POP ES
|
|
IRET
|
|
|
|
;---------------------------------------------------------------
|
|
;SCROLL_UP
|
|
; THIS ROUTINE MOVES A BLOCK OF CHARACTERS UP
|
|
; ON THE SCREEN
|
|
;INPUT
|
|
; (AL) = NUMBER OF ROWS TO SCROLL
|
|
; (CX) = ROW/COLUMN OF UPPER LEFT CORNER
|
|
; (DX) = ROW/COLUMN OF LOWER RIGHT CORNER
|
|
; (BH) = ATTRIBUTE TO BE USED ON BLANKED LINE
|
|
; (DS) = DATA SEGMENT
|
|
; (ES) = REGEN BUFFER SEGMENT
|
|
;OUTPUT
|
|
; NONE -- THE REGEN BUFFER IS MODIFIED
|
|
;---------------------------------------------------------------
|
|
SCROLL_UP ;PROC NEAR
|
|
call TEST_LINE_COUNT
|
|
jnz SUP2 ;nicht ganzen BS
|
|
or bl,bl
|
|
jnz SUP0
|
|
call CLR_TTY ;BS loeschen
|
|
jmp VIDEO_RETURN
|
|
|
|
SUP0: push ax ;Rollen durch LF realisieren
|
|
SUP1: mov ax,0e0ah ;Write TTY: LF ausgeben
|
|
int 10h
|
|
dec bl
|
|
jnz SUP1
|
|
pop ax
|
|
jmp VIDEO_RETURN
|
|
|
|
SUP2: PUSH BX ;SAVE FILL ATTRIBUTE IN BH
|
|
MOV AX,CX ;UPPER LEFT POSITION
|
|
CALL SCROLL_POSITION ;DO SETUP FOR SCROLL
|
|
JZ SUP6 ;BLANK_FIELD
|
|
ADD SI,AX ;FROM ADDRESS
|
|
MOV AH,DH ;# ROWS IN BLOCK
|
|
SUB AH,BL ;# ROWS TO BE MOVED
|
|
SUP3: ;ROW_LOOP
|
|
CALL MRAW ;MOVE ONE ROW
|
|
ADD SI,BP
|
|
ADD DI,BP ;POINT TO NEXT LINE IN BLOCK
|
|
DEC AH ;COUNT OF LINES TO MOVE
|
|
JNZ SUP3 ;ROW_LOOP
|
|
SUP4: ;CLEAR_ENTRY
|
|
POP AX ;RECOVER ATTRIBUTE IN AH
|
|
MOV AL,' ' ;FILL WITH BLANKS
|
|
SUP5: ;CLEAR_LOOP
|
|
CALL CRAW ;CLEAR THE ROW
|
|
ADD DI,BP ;POINT TO NEXT LINE
|
|
DEC BL ;COUNTER OF LINES TO SCROLL
|
|
JNZ SUP5 ;CLEAR_LOOP
|
|
jmp VIDEO_RETURN
|
|
SUP6: ;BLANK_FIELD
|
|
MOV BL,DH ;GET ROW COUNT
|
|
jmp short SUP4
|
|
|
|
;---------------------------------------------------------------
|
|
;SCROLL_DOWN
|
|
; THIS ROUTINE MOVES THE CHARACTERS WITHIN A DEFINED
|
|
; BLOCK DOWN ON THE SCREEN, FILLING THE TOP LINES
|
|
; WITH A DEFINED CHARACTER
|
|
;INPUT
|
|
; (AL) = NUMBER OF LINES TO SCROLL
|
|
; (CX) = UPPER LEFT CORNER OF REGION
|
|
; (DX) = LOWER RIGHT CORNER OF REGION
|
|
; (BH) = FILL CHARACTER
|
|
; (DS) = DATA SEGMENT
|
|
; (ES) = REGEN SEGMENT
|
|
;OUTPUT
|
|
; NONE -- SCREEN IS SCROLLED
|
|
;----------------------------------------------------------------
|
|
SCROLL_DOWN ;PROC NEAR
|
|
call TEST_LINE_COUNT
|
|
jnz SD0 ;nicht ganzen BS
|
|
or bl,bl ;BS loeschen ?
|
|
jnz SD0
|
|
call CLR_TTY
|
|
jmp VIDEO_RETURN
|
|
|
|
SD0: STD ;DIRECTION FOR SCROLL DOWN
|
|
PUSH BX ;SAVE ATTRIBUTE IN BH
|
|
MOV AX,DX ;LOWEN RIGHT CORNER
|
|
CALL SCROLL_POSITION ;GET REGEN LOCATION
|
|
JZ SD4
|
|
SUB SI,AX ;SI IS FROM ADDRESS
|
|
MOV AH,DH ;GET TOTAL # HOWS
|
|
SUB AH,BL ;COUNT TO MOVE IN SCROLL
|
|
SD1:
|
|
CALL MRAW ;MOVE ONE ROW
|
|
SUB SI,BP
|
|
SUB DI,BP
|
|
DEC AH
|
|
JNZ SD1
|
|
SD2:
|
|
POP AX ;RECOVER ATTRIBUTE IN AH
|
|
MOV AL,' '
|
|
SD3:
|
|
CALL CRAW ;CLEAR ONE ROW
|
|
SUB DI,BP ;GO TO NEXT ROW
|
|
DEC BL
|
|
JNZ SD3
|
|
JMP VIDEO_RETURN ;SCROLL_END
|
|
SD4:
|
|
MOV BL,DH
|
|
jmp short SD2
|
|
|
|
;------ TEST IF AMOUNT OF LINES TO BE SCROLLED = AMOUNT OF LINES IN WINDOW
|
|
;------ IF TRUE THEN WE ADJUST AL, IF FALSE WE RETURN...
|
|
|
|
TEST_LINE_COUNT ;PROC NEAR
|
|
MOV BL,AL ;SAVE LINE COUNT IN BL
|
|
OR AL,AL ;TEST IF AL IS ALREADY ZERO
|
|
JZ BL_SET ;IF IT IS THEN RETURN...
|
|
PUSH AX ;SAVE AX
|
|
MOV AL,DH ;SUBTRACT LOWER ROW FROM UPPER ROW
|
|
SUB AL,CH
|
|
INC AL ;ADJUST DIFERENCE BY 1
|
|
CMP AL,BL ;TEST IF LCOUNT = AMOUNT OF ROWS IN WIND
|
|
POP AX ;RESTORE AX
|
|
JNE BL_SET ;IF NOT THEN WE'RE ALL SET
|
|
SUB BL,BL ;OTHERWISE SET BL TO ZERO
|
|
BL_SET:
|
|
|
|
;Test ob Bildschirmbereich ueberschritten und auf Loeschen ganzer BS
|
|
|
|
cmp dx,184fh
|
|
jc TL1
|
|
mov dx,184fh
|
|
TL1: or cx,cx ;ganzer Bildschirm ?
|
|
jnz TL2
|
|
cmp dx,184fh
|
|
TL2: ret
|
|
|
|
;------ HANDLE COMMON SCROLL SET UP HERE
|
|
|
|
SCROLL_POSITION ;PROC NEAR
|
|
CALL POSITION ;CONVERT TO REGEN POINTER
|
|
MOV DI,AX ;TO ADDRESS FOR SCROLL
|
|
MOV SI,AX ;FROM ADDRESS FOR SCROLL
|
|
SUB DX,CX ;DX = #ROWS, #COLS IN BLOCK
|
|
INC DH
|
|
INC DL ;INCREMENT FOR 0 ORIGIN
|
|
XOR CH,CH ;SET HIGH BYTE OF COUNT TO ZERO
|
|
MOV BP,2*80 ;GET NUMBER OF COLUMNS IN DISPLAY
|
|
;TIMES 2 FOR ATTRIBUTE BYTE
|
|
MOV AL,BL ;GET LINE COUNT
|
|
mov bh,2*80 ;*2 for Attribute Byte
|
|
MUL bh ;DETERMINE OFFSET TO FROM ADDRESS
|
|
PUSH ES ;ESTABLISH ADDRESSING TO REGEN BUFFER
|
|
POP DS ;FOR BOTH POINTERS
|
|
CMP BL,0 ;0 SCROLL MEANS BLANK FIELD
|
|
RET ;RETURN WITH FLAGS SET
|
|
|
|
;------ MOVE_ROW
|
|
|
|
MRAW ;PROC NEAR
|
|
MOV CL,DL ;GET # OF COLS TO MOVE
|
|
PUSH SI
|
|
PUSH DI ;SAVE START ADDRESS
|
|
REP MOVSW ;MOVE THAT LINE OK SCREEN
|
|
POP DI
|
|
POP SI ;RECOVER ADDRESSES
|
|
RET
|
|
|
|
;------ CLEAR_ROW
|
|
CRAW ;PROC NEAR
|
|
MOV CL,DL ;GET # COLUMNS TO CLEAR
|
|
PUSH DI
|
|
REP STOSW ;STORE THE FILL CHARACTER
|
|
POP DI
|
|
RET
|
|
|
|
;---------------------------------------------------------------
|
|
;READ_AC_CURRENT
|
|
; THIS ROUTINE READS THE ATTRIBUTE AND CHARACTER AT THE CURRENT
|
|
; CURSOR POSITION AND RETURNS THEN TO THE CALLER
|
|
;INPUT
|
|
; (DS) = DATA SEGMENT
|
|
; (ES) = REGEN SEGMENT
|
|
;OUTPUT
|
|
; (AL) = CHAR READ
|
|
; (AH) = ATTRIBUTE READ
|
|
;----------------------------------------------------------------
|
|
READ_AC_CURRENT ;PROC NEAR
|
|
MOV AX,CURSOR_POSN ;GET ROW/COLUMN
|
|
CALL POSITION ;DETERMINE LOCATION IN REGEN
|
|
MOV SI,AX ;ESTABLISH ADDRESSING IN SI
|
|
PUSH ES
|
|
POP DS ;GET SEGMENT FOR QUICK ACCESS
|
|
LODSW ;GET THE CHAR/ATTR
|
|
JMP VIDEO_RETURN
|
|
|
|
;---------------------------------------------------------------
|
|
;WRITE_AC_CURRENT
|
|
; THIS ROUTINE WRITES THE ATTRIBUTE AND CHARAKTER AT
|
|
; THE CURRENT CURSOR POSITION
|
|
;INPUT
|
|
; (CX) = COUNT OF CHARACTERS TO WRITE
|
|
; (AL) = CHAR TO WRITE
|
|
; (BL) = ATTRIBUTE OF CHAR TO WRITE
|
|
; (DS) = DATA SEGMENT
|
|
; (ES) = REGEN SEGMENT
|
|
;OUTPUT
|
|
; NONE
|
|
;----------------------------------------------------------------
|
|
WRITE_AC_CURRENT ;PROC NEAR
|
|
MOV AH,BL ;GET ATTRIBUTE TO AH
|
|
PUSH AX ;SAVE ON STACK
|
|
MOV AX,CURSOR_POSN ;GET ROW/COLUMN
|
|
CALL POSITION ;DETERMINE LOCATION IN REGEN
|
|
MOV DI,AX ;ADDRESS TO DI REGISTER
|
|
POP AX ;CHARACTER
|
|
WAC: ;WRITE_LOOP
|
|
STOSW ;PUT THE CHAR/ATTR
|
|
LOOP WAC ;AS MANY TIMES AS REQUESTED
|
|
JMP VIDEO_RETURN
|
|
|
|
;---------------------------------------------------------------
|
|
;WRITE_C_CURRENT
|
|
; THIS ROUTINE WRITES THE CHARACTER AT
|
|
; THE CURRENT CURSOR POSITION, ATTRIBUTE UNCHANGED
|
|
;INPUT
|
|
; (CX) = COUNT OF CHARACTERS TO WRITE
|
|
; (AL) = CHAR TO WRITE
|
|
; (DS) = DATA SEGMENT
|
|
; (ES) = REGEN SEGMENT
|
|
;OUTPUT
|
|
; NONE
|
|
;---------------------------------------------------------------
|
|
WRITE_C_CURRENT ;PROC NEAR
|
|
PUSH AX ;SAVE ON STACK
|
|
MOV AX,CURSOR_POSN ;GET ROW/COLUMN
|
|
CALL POSITION ;DETERMINE LOCATION IN REGEN
|
|
MOV DI,AX ;ADDRESS TO DI
|
|
POP AX ;AL HAS CHAR TO WRITE
|
|
WCC: ;WRITE_LOOP
|
|
STOSB ;PUT THE CHAR
|
|
INC DI ;BUMP POINTER PAST ATTRIBUTE
|
|
LOOP WCC ;AS MANY TIMES AS REQUESTED
|
|
JMP VIDEO_RETURN
|
|
;WRITE_AC_CURRENT
|
|
|
|
;---------------------------------------------------------------
|
|
;WRITE_TTY
|
|
; THIS INTERFACE PROVIDES A TELETYPE LIKE INTERFACE.
|
|
; THE INPUT CHARACTER IS WRITTEN TO THE CURRENT
|
|
; CURSOR POSITION, AND THE CURSOR IS MOVED TO THE NEXT POSITION.
|
|
; IF THE CURSOR LEAVES THE LAST COLUMN OF THE FIELD, THE COLUMN
|
|
; IS SET TO ZERO, AND THE ROW VALUE IS INCREMENTED. IF THE ROW
|
|
; VALUE LEAVES THE FIELD. THE CURSOR IS PLACED ON THE LAST ROW,
|
|
; FIRST COLUMN, AND THE ENTIRE SCREEN IS SCROLLED UP ONE LINE.
|
|
; WHEN THE SCRENN IS SCROLLED UP, THE ATTRIBUTE FOR FILLING THE
|
|
; NEWLY BLANKED LINE IS READ FROM THE CURSOR POSITION ON THE PREVIOS
|
|
; LINE BEFORE THE SCROLL.
|
|
;ENTRY --
|
|
; (AL) = CHARACTER TO BE WRITTEN
|
|
; NOTE THAT BACK SPACE, CR, BELL AND LINE FEED ARE HANDLED
|
|
; AS COMMANDS RATHER THAN AS DISPLAYABLE GRAPHICS
|
|
;EXIT --
|
|
; ALL REGISTERS SAVED
|
|
;---------------------------------------------------------------
|
|
TTYFLG defb 0
|
|
TTYFLG1 defb 0
|
|
|
|
WRITE_TTY ;PROC NEAR
|
|
mov bx,ax
|
|
call CURSOR_OUT
|
|
mov ax,bx
|
|
mov dl,cs:TTYFLG
|
|
or dl,dl
|
|
jnz WT1
|
|
mov cs:TTYFLG1,1 ;BS muss ausgegeben werden
|
|
WT1: mov cs:TTYFLG,1 ;letzter VIDEO-Request: WRITE_TTY
|
|
mov dx,CURSOR_POSN ;READ CURSOR POSITION
|
|
|
|
call PUTA
|
|
cmp al,08h
|
|
jnz WT2
|
|
|
|
mov al,20h ;Backspace behandeln
|
|
call PUTA
|
|
mov al,08h
|
|
call PUTA
|
|
jmp short U5
|
|
|
|
;------ DX NOW HAS THE CURRENT CURSOR POSITION
|
|
|
|
WT2: CMP AL,0DH ;IS IT CARRIAGE RETURN
|
|
JE U6 ;CAR_RET
|
|
CMP AL,0AH ;IS IT A LINE FEED
|
|
JE U7 ;LINE_FEED
|
|
CMP AL,07H ;IS IT A BELL
|
|
JE U4 ;Return
|
|
|
|
;------ WRITE THE CHAR TO THE SCREEN
|
|
|
|
mov ax,dx
|
|
call POSITION
|
|
mov di,ax
|
|
mov al,bl
|
|
mov ah,07h
|
|
stosb
|
|
mov es:[di]+0fffh,al ;in 2.Abbild eintragen
|
|
|
|
;------ POSITION THE CURSOR FOR NEXT CHAR
|
|
|
|
INC DL
|
|
CMP DL,80 ;TEST FOR COLUMN OVERFLOW
|
|
JNZ U3 ;SET_CURSOR
|
|
MOV DL,0 ;COLUMN FOR CURSOR
|
|
CMP DH,24
|
|
JNZ U2 ;SET_CURSOR_INC
|
|
|
|
;------ SCROLL REQUIRED
|
|
|
|
U1: push ds
|
|
push es
|
|
pop ds
|
|
mov cx,24*80 ;Anzahl der Zeichen
|
|
sub di,di ;Zieladresse
|
|
mov si,2*80 ;Startadresse
|
|
rep movsw ;1 Zeile nach oben rollen
|
|
mov cx,80 ;letzte Zeile loeschen
|
|
mov ax,0720h
|
|
rep stosw
|
|
|
|
mov cx,24*80 ;2. Abbild rollen
|
|
mov di,1000h ;Zieladresse
|
|
mov si,1000h+2*80 ;Startadresse
|
|
rep movsw ;1 Zeile nach oben rollen
|
|
mov cx,80 ;letzte Zeile loeschen
|
|
mov ax,0720h
|
|
rep stosw
|
|
pop ds
|
|
jmp short U3
|
|
|
|
U2: inc dh ;SET-CURSOR-INC NEXT ROW
|
|
U3: mov CURSOR_POSN,dx ;SET-CURSOR
|
|
mov cs:CURSOR_TTY,dx
|
|
|
|
U4: mov ax,bx ;RESTORE THE CHARACTER
|
|
jmp VIDEO_RETURN
|
|
|
|
;------ BACK SPACE FOUND
|
|
U5: CMP DL,0 ;ALREADY AT END OF LINE
|
|
JE U3 ;SET_CURSOR
|
|
DEC DL ;NO -- JUST MOVE IT BACK
|
|
JMP short U3 ;SET_CURSOR
|
|
|
|
;------ CARRIAGE RETURN FOUND
|
|
U6: MOV DL,0 ;MOVE TO FIRST COLUMN
|
|
JMP short U3 ;SET_CURSOR
|
|
|
|
;------ LINE FEED FOUND
|
|
U7: CMP DH,24 ;BOTTOM OF SCREEN
|
|
JNE U2 ;YES, SCROLL THE SCREEN
|
|
JMP short U1 ;NO, JUST SET THE CURSOR
|
|
|
|
;---------------------------------------------------------------
|
|
;WRITE STRING
|
|
; This routine writes a string of characters to the crt.
|
|
;INPUT
|
|
; (AL) = WRITE STRING COMMAND 0 - 3
|
|
; (CX) = COUNT OF CHARACTERS TO WRITE. IF CX == 0 THEN RETURN
|
|
; (DX) = CURSOR POSITION
|
|
; (BL) = ATTRIBUTE OF CHAR TO WRITE IF AL == 0 | AL == 1
|
|
; (ES) = STRING SEGMENT
|
|
; (BP) = STRING OFFSET
|
|
;OUTPUT
|
|
; N/A
|
|
;----------------------------------------------------------------
|
|
WRITE_STRING ;PROC NEAR
|
|
CMP AL,04 ;TEST FOR INVALID WRITE STRING OPTION
|
|
JB W0 ;IF OPTION INVALID THEN RETURN
|
|
JMP DONE
|
|
W0: OR CX,CX ;TEST FOR ZERO LENGTH STRING
|
|
JNZ W1
|
|
JMP short DONE ;IF ZERO LENGTH STRING THEN RETURN
|
|
W1: MOV SI,CURSOR_POSN
|
|
PUSH SI ;SAVE CURRENT CURSOR POSITION
|
|
mov CURSOR_POSN,dx ;SET NEW CURSOR POSITION
|
|
|
|
WRITE_CHAR:
|
|
PUSH CX
|
|
PUSH BX
|
|
PUSH AX
|
|
PUSH ES
|
|
XCHG AH,AL ;PUT THE WRITE STRING OPTION INTO AH
|
|
MOV AL,ES:[BP] ;GET CHARACTER FROM INPUT STRING
|
|
INC BP ;BUMP POINTER TO CHARACTER
|
|
|
|
;------ TEST FOR SPECIAL CHARACTER'S
|
|
|
|
CMP AL,8 ;IS IT A BACKSPACE
|
|
JE DO_TTY ;BACK_SPACE
|
|
CMP AL,0DH ;IS IT CARRIAGE RETURN
|
|
JE DO_TTY ;CAR_RET
|
|
CMP AL,0AH ;IS IT A LINE FEED
|
|
JE DO_TTY ;LINE_FEED
|
|
CMP AL,07H ;IS IT A BELL
|
|
JNE GET_ATTRIBUTE ;IF NOT THEN DO WRITE CHARACTER
|
|
DO_TTY:
|
|
MOV AH,14 ;WRITE TTY CHARACTER TO THE CRT
|
|
INT 10H
|
|
MOV DX,CURSOR_POSN ;GET CURRENT CURSOR POSITION
|
|
POP ES
|
|
POP AX ;RESTORE REGISTERS
|
|
POP BX
|
|
POP CX
|
|
JMP short ROWS_SET
|
|
|
|
GET_ATTRIBUTE:
|
|
MOV CX,1 ;SET CHARACTER WRITE AMOUNT TO ONE
|
|
CMP AH,2 ;IS THE ATTRIBUTE IN THE STRING
|
|
JB GOT_IT ;IF NOT THEN JUMP
|
|
MOV BL,ES:[BP] ;ELSE GET IT
|
|
INC BP ;BUMP STRING POINTER
|
|
|
|
GOT_IT: MOV AH,09 ;WRITE CHARACTER TO THE CRT
|
|
INT 10H
|
|
POP ES
|
|
POP AX ;RESTORE REGISTERS
|
|
POP BX
|
|
POP CX
|
|
INC DL ;INCREMENT COLUMN COUNTER
|
|
CMP DL,80 ;IF COLS ARE WITHIN RANGE FOR THIS MODE
|
|
JB COLUMNS_SET ;THEN GOTO COLS SET
|
|
INC DH ;BUMP ROW COUNTER BY ONE
|
|
SUB DL,DL ;SET COLUMN COUNTER TO ZERO
|
|
CMP DH,25 ;IF ROWS ARE < 25 THEN
|
|
JB ROWS_SET ;GOTO ROWS_SET
|
|
;SAVE WRITE STRING PARAMETER REGS
|
|
PUSH ES ;SAVE REG'S THAT GET CLOBBERED
|
|
PUSH AX
|
|
MOV AX,0E0AH ;DO SCROLL ONE LINE
|
|
INT 10H ;RESET ROW COUNTER TO 24
|
|
DEC DH
|
|
POP AX ;RESTORE REG'S
|
|
POP ES
|
|
|
|
ROWS_SET:
|
|
COLUMNS_SET:
|
|
mov CURSOR_POSN,dx
|
|
LOOP WRITE_CHAR ;DO IT ONCE MORE UNTIL CX = ZERO
|
|
POP DX ;RESTORE OLD CURSOR COORDINATES
|
|
CMP AL,1 ;IF CURSOR WAS TO BE MOVED THEN
|
|
JE DONE ;WE'RE DONE
|
|
CMP AL,3
|
|
JE DONE
|
|
mov CURSOR_POSN,dx ;ELSE RESTORE OLD CURSOR POSITION
|
|
DONE:
|
|
JMP VIDEO_RETURN ;RETURN TO CALLER
|
|
|
|
;---------------------------------------------------------------
|
|
;POSITION
|
|
; THIS SERVICE ROUTINE CALCULATES THE REGEN BUFFER ADDRESS
|
|
; OF A CHARACTER IN THE ALPHA MODE
|
|
;INPUT
|
|
; AX = ROW, COLUMN POSITION
|
|
;OUTPUT
|
|
; AX = OFFSET OF CHAR POSITION IN REGEN BUFFER
|
|
;---------------------------------------------------------------
|
|
POSITION ;PROC NEAR
|
|
PUSH BX ;SAVE REGISTER
|
|
MOV BX,AX
|
|
MOV AL,AH ;ROWS TO AL
|
|
mov bh,80
|
|
MUL bh ;DETERMINE BYTES TO ROW
|
|
XOR BH,BH
|
|
ADD AX,BX ;ADD IN COLUMN VALUE
|
|
SAL AX,1 ;*2 FOR ATTRIBUTE BYTES
|
|
POP BX
|
|
RET
|
|
|
|
;---------------------------------------------------------------
|
|
;Bildwiederholspeicher vergleichen und Differenzen ausgeben
|
|
;---------------------------------------------------------------
|
|
CURSON: defb 1 ;sichtbar
|
|
|
|
CURSOR_OUT: ;CURSOR-Stand vergleichen und Cursor setzen
|
|
mov dx,CURSOR_POSN
|
|
cmp dx,1850h
|
|
jnc COFF
|
|
mov ax,CURSOR_MODE
|
|
test ah,20h ;Cursor unterdruecken ?
|
|
jnz COUT1 ;ja
|
|
|
|
call COUT2
|
|
mov al,cs:CURSON
|
|
or al,al ;Cursor einschalten
|
|
jnz COUT0 ;Cursor ist eingeschaltet
|
|
mov cs:CURSON,1
|
|
mov al,1bh
|
|
call PUTA
|
|
mov al,'.'
|
|
call PUTA
|
|
mov al,'1'
|
|
jmp PUTA
|
|
|
|
COUT:
|
|
COUT1: call COFF
|
|
COUT2: cmp dx,cs:CURSOR_TTY
|
|
jz COUT0 ;Cursor steht auf Bildschirm richtig
|
|
|
|
COUT3: mov cs:CURSOR_TTY,dx
|
|
mov al,1bh ;ADM 31 ESC-Folge
|
|
call PUTA
|
|
mov al,'='
|
|
call PUTA
|
|
mov al,dh
|
|
add al,20h
|
|
call PUTA
|
|
mov al,dl
|
|
add al,20h
|
|
jmp PUTA
|
|
COUT0: ret
|
|
|
|
COFF: mov al,cs:CURSON ;Cursor ausschalten
|
|
or al,al
|
|
jz COUT0 ;Cursor ist ausgeschaltet
|
|
mov cs:CURSON,0
|
|
mov al,1bh
|
|
call PUTA
|
|
mov al,'.'
|
|
call PUTA
|
|
mov al,'0'
|
|
jmp PUTA
|
|
|
|
|
|
SCREEN_OUT:
|
|
push ax
|
|
mov al,cs:reset ;restart von WDOS ?
|
|
or al,al
|
|
jnz SO0
|
|
mov ax,cs:TTYFLG ;Bildwiederholspeicher Vergleich erforderlich ?
|
|
or ah,ah ;TTYFLG1
|
|
jnz SO0
|
|
or al,al
|
|
jz SO0
|
|
pop ax
|
|
ret
|
|
|
|
SO0: mov cs:TTYFLG1,0
|
|
pop ax
|
|
db 60h ;pusha
|
|
push ds
|
|
push es
|
|
cld
|
|
mov ax,0b000h
|
|
mov ds,ax
|
|
mov ax,0b100h
|
|
mov es,ax
|
|
xor dx,dx ;Zeile 0
|
|
xor bx,bx
|
|
|
|
mov al,cs:reset ;restart ?
|
|
or al,al
|
|
jz SO1
|
|
xor ax,ax ;zweiten Bildwiederholspeicher loeschen
|
|
mov cs:reset,al
|
|
mov di,ax
|
|
mov cx,800h
|
|
rep stosw
|
|
|
|
SO1: mov si,bx
|
|
mov di,bx
|
|
mov cx,80 ;80 Zeichen pro Zeile
|
|
repe cmpsw ;1 Zeile vergleichen
|
|
jz SO2 ;Zeile ist gleich: keine Ausgaben
|
|
push bx
|
|
call SO3
|
|
mov cs:CURSOR_TTY,dx
|
|
pop bx
|
|
|
|
SO2: add bx,2*80 ;naechste Zeile
|
|
inc dh
|
|
cmp dh,25 ;alle Zeilen verglichen ?
|
|
jc SO1
|
|
|
|
pop es
|
|
pop ds
|
|
call CURSOR_OUT
|
|
db 61h ;popa
|
|
ret
|
|
|
|
SO3: dec si
|
|
dec si
|
|
inc cx
|
|
push si
|
|
mov si,bx
|
|
add si,2*79 ;Adresse Ende der Zeile
|
|
mov bx,cx
|
|
mov dl,80 ;Nummer der 1. ungleichen Spalte berechnen
|
|
sub dl,cl
|
|
call COUT ;Cursor positionieren
|
|
|
|
mov di,si ;Zeile von hinten vergleichen
|
|
std
|
|
repe cmpsw
|
|
cld
|
|
inc cl ;in cl Anzahl der ungleichen Zeichen
|
|
mov ch,bl ;in ch Anzahl der Zeichen ab si bis Zeilenende
|
|
pop si ;Adr erstes ungleiches Zeichen
|
|
mov di,si
|
|
|
|
sub bp,bp ;Video-Attribute + Zeichen ruecksetzen
|
|
mov bx,bp
|
|
|
|
SO4: lodsw ;Zeichen aus 1. Bildwiederholspeicher nach ax
|
|
|
|
cmp ah,bh ;neues + vorheriges Zeichen Attribute gleich ?
|
|
jnz SO11
|
|
|
|
;altes Zeichen aus 2. Bildwiederholspeicher
|
|
cmp ah,es:[di]+1 ;Attribute gleich ?
|
|
jnz SO11 ;nein
|
|
|
|
stosw
|
|
call SOUT
|
|
inc dl ;Spalten-Zaehler inc
|
|
dec ch
|
|
dec cl
|
|
jnz SO4
|
|
jmp short ZOUTR ;restliche Zeichen ausgeben
|
|
|
|
SO10: lodsw ;volle Anzahl Zeichen ausgeben
|
|
SO11: stosw
|
|
call SOUT
|
|
inc dl
|
|
dec ch
|
|
jnz SO10
|
|
jmp short ZOUTR ;restliche Zeichen ausgeben
|
|
|
|
;Zeichen ausgeben
|
|
|
|
SOUT: or bp,bp ;nur Attribute ausgeben ?
|
|
jnz SOUT4 ;nein
|
|
|
|
SOUT1: cmp ah,bh ;Attribute gleich ?
|
|
mov bx,ax
|
|
jz SOUT2 ;ja
|
|
call SATTR
|
|
SOUT2: inc bp
|
|
SOUT0: ret
|
|
|
|
SOUT4: cmp ax,bx ;neues = letztes Zeichen ?
|
|
jz SOUT2 ;ja
|
|
call ZOUT ;bisherige Zeichen ausgeben
|
|
jmp short SOUT1 ;neues Attribut testen
|
|
|
|
ZOUTR: or bp,bp ;restliche Zeichen ausgeben
|
|
jz ZOUT0 ;keine Zeichen vorhanden
|
|
or bl,bl ;Blank-Zeichen ueber Clear to End
|
|
jz CLREND
|
|
cmp bl,20h
|
|
jz CLREND
|
|
|
|
ZOUT: push ax
|
|
mov ax,bx
|
|
cmp bl,20h
|
|
jnc ZOUT2
|
|
mov al,3eh
|
|
cmp bl,10h
|
|
jz ZOUT2
|
|
mov al,3ch
|
|
cmp bl,11h
|
|
jz ZOUT2
|
|
|
|
mov al,0
|
|
call PUTA
|
|
|
|
ZOUT1: mov al,20h
|
|
|
|
ZOUT2: call PUTA ;Zeichen einzeln ausgeben
|
|
dec bp
|
|
jnz ZOUT2
|
|
pop ax
|
|
ZOUT0: ret
|
|
|
|
|
|
;Zeile von Cursor bis Ende loeschen
|
|
|
|
CLREND: mov al,1bh ;Zeile loeschen
|
|
call PUTA
|
|
mov al,'T'
|
|
jmp short PUTA
|
|
|
|
;Video-Attribut ausgeben
|
|
|
|
SATTR: mov al,1bh
|
|
call PUTA
|
|
mov al,'G'
|
|
call PUTA
|
|
mov al,'p' ;normal
|
|
test ah,08h ;intensiv ?
|
|
jz SATTR1
|
|
mov al,'0' ;intensiv
|
|
SATTR1: test ah,80h ;blinkend ?
|
|
jz SATTR2
|
|
add al,2 ;ja
|
|
SATTR2: and ah,77h
|
|
cmp ah,01h ;unterstrichen ?
|
|
jnz SATTR3
|
|
add al,8 ;ja
|
|
jmp short PUTA
|
|
|
|
SATTR3: cmp ah,70h ;invers ?
|
|
jnz SATTR4
|
|
add al,4 ;ja
|
|
jmp short PUTA
|
|
|
|
SATTR4: cmp ah,0
|
|
jnz PUTA
|
|
inc al
|
|
|
|
;---------------------------------------------------------------
|
|
;PUTA
|
|
;---------------------------------------------------------------
|
|
PUTA: push ax
|
|
push bx
|
|
push di
|
|
mov di,offset ttybuf
|
|
PU1: mov bx, word ptr cs:ttyout+2
|
|
xchg bh,bl
|
|
cmp bx,800h
|
|
jnc PU1 ;warten, da Puffer voll
|
|
PU2: sti
|
|
nop
|
|
cli
|
|
mov ah,cs:ttyout+0 ;outstop
|
|
or ah,ah
|
|
jnz PU2
|
|
mov bx, word ptr cs:ttyout+2
|
|
xchg bh,bl
|
|
mov cs:[bx+di],al
|
|
inc bx
|
|
xchg bh,bl
|
|
mov word ptr cs:ttyout+2,bx ;noutb
|
|
cmp bx,0100h
|
|
jnz PU4
|
|
PU3: sti ;beim 1.Zeichen INT geben
|
|
nop
|
|
cli
|
|
mov ah,cs:intout ;kann INT gegeben werden ?
|
|
or ah,ah
|
|
jnz PU3
|
|
mov cs:intout,1 ;tty
|
|
out 0,al ;INT geben
|
|
PU4: sti
|
|
pop di
|
|
pop bx
|
|
pop ax
|
|
ret
|
|
|
|
|
|
;--- INT 17 --------------------------------------------------------------
|
|
;PRINTER_IO
|
|
; THIS ROUTINE PROVIDES COMMUNICATION WITH THE PRINTER
|
|
;INPUT
|
|
; (AH)=0 PRINT THE CHARACTER IN (AL)
|
|
; ON RETURN, (AH) BITS SET AS ON NORMAL STATUS CALL
|
|
; (AH)=1 INITIALIZE THE PRINTER PORT
|
|
; RETURNS WITH (AH) SET WITH PRINTER STATUS
|
|
; (AH)=2 READ THE PRINTER STATUS INTO (AH)
|
|
;
|
|
; (DX) = PRINTER TO BE USED (0,1,2) - nur ein Printer moeglich
|
|
;
|
|
;REGISTERS AH IS MODIFIED
|
|
; ALL OTHERS UNCHANGED
|
|
;-------------------------------------------------------------------------
|
|
PRINTER ;PROC FAR ;ENTRY POINT FOR ORG 0EFD2H
|
|
STI ;INTERRUPTS BACK ON
|
|
OR AH,AH ;TEST FOR (AH)=0
|
|
JZ P0 ;PRINT_AL
|
|
DEC AH ;TEST FOR (AH)=1
|
|
JZ P1 ;INIT_PRT - nicht implementiert
|
|
DEC AH ;TEST FOR (AH)=2
|
|
JZ P1 ;PRINTER STATUS
|
|
JMP SHORT P3
|
|
|
|
;------ PRINT THE CHARACTER IN (AL)
|
|
|
|
P0: push bx
|
|
push di
|
|
mov di,offset lpbuf
|
|
P0A: mov bx, word ptr cs:lpout+2
|
|
xchg bh,bl
|
|
cmp bx,100h
|
|
jnc P0A ;warten Uebergabepuffer voll
|
|
P0B: sti
|
|
nop
|
|
cli
|
|
mov ah,cs:lpout+0 ;outstop
|
|
or ah,ah
|
|
jnz P0A
|
|
mov bx, word ptr cs:lpout+2
|
|
xchg bh,bl
|
|
mov cs:[bx+di],al
|
|
inc bx ;noutb
|
|
xchg bh,bl
|
|
mov word ptr cs:lpout+2,bx
|
|
cmp bx,0100h
|
|
jnz P0D
|
|
P0C: sti ;beim 1.Zeichen INT geben
|
|
nop
|
|
cli
|
|
mov ah,cs:intout ;kann INT gegeben werden ?
|
|
or ah,ah
|
|
jnz P0C
|
|
mov cs:intout,2 ;lp
|
|
out 0,al ;INT geben
|
|
P0D: sti
|
|
pop di
|
|
pop bx
|
|
|
|
;------ PRINTER STATUS
|
|
|
|
P1: push bx
|
|
mov bx, word ptr cs:lpout+2
|
|
xchg bh,bl
|
|
cmp bx,100h ;Puffer voll ?
|
|
jnc P2
|
|
mov bh,cs:lpout+0 ;outstop
|
|
or bh,bh
|
|
jnz P2
|
|
mov ah,0d0h ;bereit fuer naechstes Zeichen
|
|
pop bx
|
|
iret
|
|
P2: mov ah,50h ;nicht bereit fuer naechstes Zeichen
|
|
pop bx
|
|
P3: iret
|
|
|
|
|
|
;------- INT_14 -----------------------------------------------------
|
|
;RS232_IO
|
|
; THIS ROUTINE PROVIDES BYTE STREAM I/O TO THE COMMUNICATIONS
|
|
; PORT ACCORDING TO THE PARAMETERS:
|
|
; (AH)=0 INITIALIZE THE COMMUNICATIONS PORT
|
|
; (AL) HAS PARMS FOR INITIALIZATION
|
|
;
|
|
; 7 6 5 4 3 2 1 0
|
|
; ----- BAUD RATE -- -PARITY-- STOPBIT --WORD LENGTH--
|
|
;
|
|
; 000 - 110 XO - NONE 0 - 1 10 - 7 BITS
|
|
; 001 - 150 01 - ODD 1 - 2 11 - 8 BITS
|
|
; 010 - 300 11 - EVEN
|
|
; 011 - 600
|
|
; 100 - 1200
|
|
; 101 - 2400
|
|
; 110 - 4800
|
|
; 111 - 9600
|
|
; ON RETURN, CONDITIONS SET AS IN CALL TO COMMO STATUS (AH=3)
|
|
; (AH)=1 SEND THE CHARACTER IN (AL) OVER THE COMMO LINE
|
|
; (AL) REGISTER IS PRESERVED.
|
|
; ON EXIT, BIT 7 OF AH IS SET IF THE ROUTINE HAS UNABLE TO
|
|
; TO TRNASMIT THE BYTE OF DATA OVER THE LINE.
|
|
; IF BIT 7 OF AH IS NOT SET, THE
|
|
; REMAINDER OF AH IS SET AS IN A STATUS REQUEST,
|
|
; REFLECTING THE CURRENT STATUS OF THE LINE.
|
|
; (AH)=2 RECEIVE A CHARACTER IN (AL) FROM COMMO LINE BEFORE
|
|
; RETURNIND TO CALLER
|
|
; ON EXIT, AH HAS THE CURRENT LINE STATUS, AS SET BY THE
|
|
; THE STATUS ROUTINE, EXCEPT THAT THE ONLY BITS
|
|
; LEFT ON ARE THE ERROR BITS (7,4,3,2,1)
|
|
; IF AH HAS BIT 7 ON (TIME OUT) THE REMAINING
|
|
; BITS ARE NOT PREDICTABLE.
|
|
; THUS, AH IS NON ZERO ONLY WHEN AH ERROR OCCURRED.
|
|
; (AH)=3 RETURN THE COMMO PORT STATUS IN (AX)
|
|
; AH CONTAINS THE LINE CONTROL STATUS
|
|
; BIT 7 = TIME OUT
|
|
; BIT 6 = TRANS HOLDING REGISTER EMPTY
|
|
; BIT 5 = TRAN HOLDING REGISTER EMPTY
|
|
; BIT 4 = BREAK DETECT
|
|
; BIT 3 = FRANING ERROR
|
|
; BIT 2 = PARITY ERROR
|
|
; BIT 1 = OVERRUN ERROR
|
|
; BIT 0 = DATA READY
|
|
; AL CONTAINS THE MODEM STATUS
|
|
; BIT 7 = RECEVED LINE SIGNAL DETECT
|
|
; BIT 6 = RING INDICATOR
|
|
; BIT 5 = DATA SET READY
|
|
; BIT 4 = CLEAR TO SEND
|
|
; BIT 3 = DELTA RECEIVE LINE SIGNAL DETECT
|
|
; BIT 2 = TRAILING EDCE RING DETECTOR
|
|
; BIT 1 = DELTA DATA SET READY
|
|
; BIT 0 = DELTA CLEAR TO SEND
|
|
;
|
|
; (DX) = PARAMETER INDICATING WHICH RS232 CARD (0,1 ALLOWED)
|
|
;
|
|
;OUTPUT
|
|
; AX MODIFIED ACCORDING TO PARMS OF CALL
|
|
; ALL OTHERS UNCHANCED:
|
|
;----------------------------------------------------------------------
|
|
RS232 ;PROC FAR
|
|
|
|
;------ VECTOR TO APPROPRIATE ROUTINE
|
|
|
|
STI ;INTERRUPTS BACK ON
|
|
OR AH,AH ;TEST FOR (AH)=0
|
|
JZ RS0 ;COMMUN INIT
|
|
DEC AH ;TEST FOR (AH)=1
|
|
JZ RS1 ;SEND AL
|
|
DEC AH ;TEST FOR (AH)=2
|
|
JZ RS2 ;RECEIVE INTO AL
|
|
DEC AH ;TEST FOR (AH)=3
|
|
JZ RS3 ;COMMUNICATION STATUS
|
|
JMP SHORT RS4
|
|
|
|
;------ INITIALIZE THE COMMUNICATIONS PORT
|
|
RS0:
|
|
|
|
;------ RECEIVE CHARACTER FROM COMMO LINE
|
|
RS2:
|
|
|
|
;------ COMMO PORT STATUS ROUTINE
|
|
RS3: MOV AL,0
|
|
|
|
;------ SEND CHARACTER IN (AL) OVER COMMO LINE
|
|
RS1: MOV AH,80H ;INDICATE TIME OUT
|
|
RS4: IRET
|
|
|
|
END
|