865 lines
21 KiB
NASM
865 lines
21 KiB
NASM
;**************************************************************************
|
|
;**************************************************************************
|
|
;
|
|
; WDOS-BIOS - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1988
|
|
;
|
|
; Programm: termp8.asm
|
|
;
|
|
; Bearbeiter : P. Hoge
|
|
; Datum : 24.1.89
|
|
; Version : 1.1
|
|
;
|
|
;**************************************************************************
|
|
;
|
|
; normales P8000-Terminal (ADM31) ohne Bildwiederholspeicher
|
|
;
|
|
;**************************************************************************
|
|
;**************************************************************************
|
|
|
|
|
|
.EXTERNAL DDS ;NEAR
|
|
.EXTERNAL BYTE KB_FLAG
|
|
.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 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
|
|
;OUTPUT
|
|
; AS NOTED ABOVE, ONLY AX AND FLAGS CHANGED
|
|
; ALL REGISTERS RETAINED
|
|
;------------------------------------------------------------------------------
|
|
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
|
|
call CURSOR_OUT
|
|
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 ;RECOVER REGISTER
|
|
POP DS
|
|
IRET ;INVALID COMMAND
|
|
|
|
;------ READ THE KEY TO FIGURE OUT WHAT TO DO
|
|
|
|
K0:
|
|
; 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
|
|
|
|
K0A: ;ASCII READ
|
|
STI ;INTERRUPTS BACK ON DURING LOOP
|
|
NOP ;ALLOW AN INTERRUPT TO OCCUR
|
|
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 K3 ;MOVE POINTER TO NEXT POSITION
|
|
MOV BUFFER_HEAD,BX ;STORE VALUE IN VARIABLE
|
|
POP BX ;RECOVER REGISTER
|
|
POP DS ;RECOVER SEGMENT/
|
|
IRET ;RETURN TO CALLER
|
|
|
|
;------ ASCII STATUS
|
|
|
|
K1: CLI ;INTERRUPTS OFF
|
|
MOV BX,BUFFER_HEAD ;GET HEAD POINTER
|
|
CMP BX,BUFFER_TAIL ;IF EQUAL (Z=1) THEN NOTHING THERE
|
|
MOV AX,[BX]
|
|
POP BX ;RECOVER REGISTER
|
|
POP DS ;RECOVER SEGMENT
|
|
STI ;INTERRUPTS BACK ON
|
|
RET FAR 2 ;THROW AWAY FLAGS
|
|
|
|
;------ SHIFT STATUS
|
|
|
|
K2: MOV AL,KB_FLAG ;GET THE SHIFT STATUS FLAGS
|
|
POP BX ;RECOVER REGISTER
|
|
POP DS ;RECOVER REGISTERS
|
|
IRET ;RETURN TO CALLER
|
|
|
|
;------ INCREMENT A BUFFER POINTER
|
|
|
|
K3 ;PROC NEAR
|
|
INC BX ;MOVE TO NEXT WORD IN LIST
|
|
INC BX
|
|
CMP BX,BUFFER_END ;AT END OF BUFFER?
|
|
JNE K3A ;NO, CONTINUE
|
|
MOV BX,BUFFER_START ;YES, RESET TO BUFFER BEGINNING
|
|
K3A: RET
|
|
|
|
;------ KEYBOARD INTERRUPT ROUTINE
|
|
|
|
KBINT ;PROC FAR
|
|
STI
|
|
PUSH AX
|
|
PUSH BX
|
|
PUSH SI
|
|
PUSH DS
|
|
CALL DDS ;SET UP ADDRESSING
|
|
mov cs:intin,0 ;naechsten Int freigeben
|
|
mov al,cs:ttyin+2
|
|
and al,7fh
|
|
xor ah,ah
|
|
|
|
;------ PUT CHARACTER INTO BUFFER
|
|
|
|
MOV BX,BUFFER_TAIL ;GET THE END POINTER TO THE BUFFER
|
|
MOV SI,BX ;SAVE THE VALUE
|
|
CALL K3 ;ADVANCE THE TAIL
|
|
CMP BX,BUFFER_HEAD ;HAS THE BUFFER WRAPPED AROUND
|
|
JE K4B ;BUFFER_FULL_BEEP
|
|
MOV [SI],AX ;STORE THE VALUE
|
|
MOV BUFFER_TAIL,BX ;MOVE THE POINTER UP
|
|
|
|
K4A: POP DS
|
|
POP SI
|
|
POP BX
|
|
POP AX
|
|
mov cs:ttyin+1,0
|
|
IRET ;RETURN, INTERRUPTS BACK ON WITH FLAG CHANGE
|
|
|
|
K4B: mov al,07h ;BUFFER FULL BEEP
|
|
call PUTA
|
|
JMP SHORT K4A
|
|
|
|
|
|
;--- 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 - nur Loeschen (al = 0)
|
|
; (AH)=7 SCROLL ACTIVE PAGE DOWN - nur Loeschen (al = 0)
|
|
;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
|
|
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
|
|
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
|
|
call CLR_TTY ;Bildschirm loeschen
|
|
mov CURSOR_POSN,0 ;Cursor Home setzen
|
|
jmp short VIDEO_RETURN
|
|
|
|
CLR_TTY:
|
|
;------ ADM 31 Escape-Folge Bildschirm loeschen
|
|
push ax
|
|
mov al,1bh
|
|
call PUTA
|
|
mov al,'*'
|
|
call PUTA
|
|
|
|
mov ax,-1
|
|
mov cs:CURSOR_TTY,ax ;Cursor synchronisieren
|
|
call CURSOR_OUT
|
|
pop ax
|
|
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 / SCROLL_DOWN
|
|
; realisiert nur Bildschirmloeschen
|
|
;INPUT
|
|
; (AL) = 0 = Loeschen Bildschirm
|
|
;---------------------------------------------------------------
|
|
SCROLL_UP ;PROC NEAR
|
|
SCROLL_DOWN ;PROC NEAR
|
|
or al,al ;Loeschen
|
|
jnz SUP0
|
|
call CLR_TTY
|
|
jmp VIDEO_RETURN
|
|
|
|
SUP0: push ax ;Rollen durch LF realisieren
|
|
mov ax,0e0ah ;Write TTY: LF ausgeben
|
|
int 10h
|
|
pop ax
|
|
dec al
|
|
jnz SUP0
|
|
jmp VIDEO_RETURN
|
|
|
|
;---------------------------------------------------------------
|
|
;READ_AC_CURRENT
|
|
; nicht moeglich, Return mit 0720h
|
|
;OUTPUT
|
|
; (AL) = 20h (Space)
|
|
; (AH) = 07h (Attribut)
|
|
;----------------------------------------------------------------
|
|
READ_AC_CURRENT ;PROC NEAR
|
|
mov ax,0720h
|
|
JMP VIDEO_RETURN
|
|
|
|
;---------------------------------------------------------------
|
|
;WRITE_AC_CURRENT
|
|
; nicht moeglich, Funktion wie WRITE_C_CURRENT
|
|
;---------------------------------------------------------------
|
|
WRITE_AC_CURRENT ;PROC NEAR
|
|
|
|
;---------------------------------------------------------------
|
|
;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
|
|
;OUTPUT
|
|
; NONE
|
|
;---------------------------------------------------------------
|
|
WRITE_C_CURRENT ;PROC NEAR
|
|
call CURSOR_OUT
|
|
WCC0: ;WRITE_LOOP
|
|
inc word ptr cs:CURSOR_TTY
|
|
cmp al,07h ;Diese Zeichen haben hier
|
|
jz WCC1 ;keine Sonderbedeutung
|
|
cmp al,08h
|
|
jz WCC1
|
|
cmp al,0ah
|
|
jz WCC1
|
|
cmp al,0dh
|
|
jnz WCC2
|
|
WCC1: mov al,20h
|
|
WCC2: call PUTA
|
|
LOOP WCC0 ;AS MANY TIMES AS REQUESTED
|
|
JMP VIDEO_RETURN
|
|
;WRITE_AC_CURRENT
|
|
|
|
;---------------------------------------------------------------
|
|
;WRITE_TTY
|
|
; THIS INTERFACE PROVIDES A TELETYPE LIKE INTERFACE.
|
|
;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
|
|
;---------------------------------------------------------------
|
|
WRITE_TTY ;PROC NEAR
|
|
call CURSOR_OUT
|
|
call PUTA
|
|
mov dx,CURSOR_POSN ;READ CURSOR POSITION
|
|
|
|
;------ DX NOW HAS THE CURRENT CURSOR POSITION
|
|
|
|
CMP AL,8 ;IS IT A BACKSPACE
|
|
JE U5 ;BACK_SPACE
|
|
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
|
|
|
|
;------ 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: jmp short U3
|
|
|
|
U2: inc dh ;SET-CURSOR-INC NEXT ROW
|
|
U3: mov CURSOR_POSN,dx ;SET-CURSOR
|
|
mov cs:CURSOR_TTY,dx
|
|
|
|
U4: 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
|
|
|
|
;---------------------------------------------------------------
|
|
; Cursor-Stand vergleichen und Differenzen ausgeben
|
|
;---------------------------------------------------------------
|
|
CURSOR_OUT: ;CURSOR-Stand vergleichen und Cursor setzen
|
|
push ax
|
|
push dx
|
|
mov dx,CURSOR_POSN
|
|
cmp dx,cs:CURSOR_TTY
|
|
jz COUT2 ;Cursor steht auf Bildschirm richtig
|
|
|
|
mov al,1bh ;ADM 31 ESC-Folge
|
|
call PUTA
|
|
mov cs:CURSOR_TTY,dx
|
|
mov al,'='
|
|
call PUTA
|
|
mov al,dh
|
|
cmp al,24 ;Terminal hat nur 24 Zeilen
|
|
jnz COUT1
|
|
dec al ;25 = 24 Zeile, da 24 Zeilen-Terminal
|
|
COUT1: add al,20h
|
|
call PUTA
|
|
mov al,dl
|
|
add al,20h
|
|
call PUTA
|
|
|
|
COUT2: pop dx
|
|
pop ax
|
|
ret
|
|
|
|
;---------------------------------------------------------------
|
|
;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
|
|
cmp al,80h
|
|
jc PU2
|
|
mov al,20h
|
|
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
|
|
xchg bh,bl
|
|
mov word ptr cs:lpout+2,bx ;noutb
|
|
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
|