P8000/WEGA/contrib/wdos/src/termp8.asm

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