;*******************************************************
; MEMORY MAPPED VIDEO DRIVER
;*******************************************************
;
; By Bill Bolton
; Software Tools
; P.O. Box 80
; Newport Beach
; NSW, 2106
; AUSTRALIA
;
;****** DATE OF THIS VERSION 15th February, 1980 *******
;
; Version 1.12
;
MPAGE EQU 0CC00H ;VDM-1 MEMORY ADDR.
SCREEN EQU 0400H ;VDM-1 MEMORY SIZE = 1K
FINIS EQU 004FH ;END OF CP/M SCRATCH RAM
LB EQU 0FFH ;MASK LOW 8 ADDR BITS
SPACE EQU 20H ;ASCII SPACE
DELETE EQU 7FH ;ASCII DEL
FLAG EQU 0FFH ;FLAG SET
OFFSET EQU SPACE ;OFFSET TO GET ABOVE
;CONTROL CODES
HORIZ EQU 64 ;NO. OF CHARACTERS/LINE
VERT EQU 16 ;NO. OF LINES/PAGE
;
ORG 0F000H
;
;
;*******JUMPS MUST REMAIN HERE IN THE SAME ORDER*******
;
;
ENTRY:
JMP VIDEO ;PROCESS A CHARACTER
JMP INITIAL ;INITIALISE RAM
;
;
DB 'VIDEODRV '
DB 'VERSION 1.12 '
DB 'COPYRIGHT (C) '
DB '1977/80 BILL BOLTON '
;
;
VIDEO:
CALL LIFTCUR ;GET CURSOR LOCATION
LDA ESCFLAG ;ESC SEQUENCE IN,
CPI 0 ;PROGRESS ?
JNZ ESCAPE ;YES, GO TO IT
MOV A,C ;GET CHAR INTO A
ANI 07FH ;MASK OUT BIT 7 TO MAKE ASCII
CPI DELETE ;IS IT A DELETE ?
JZ EXIT ;YES, IGNORE IT
CPI OFFSET ;ASCII PRINTING CHAR ?
JP PRINT ;YES, PUT ONTO SCREEN
;NO, MUST BE CONTROL CHARACTER
;
;CONTROL CHARACTER TABLE PROCESSING ROUTINE
;
PUSH H ;SAVE CURRENT SCREEN LOC.
LXI H,VDUTBLE ;GET START OF TABLE
ADD L ;ADD LOW ADDR BYTE TO A
MOV L,A ;PUT RESULT BACK INTO L
MOV L,M ;GET VALUE IN MEMORY,
XTHL ;POINTED TO BY HL INTO L,
RET ;PUT ONTO STACK AND JUMP,
;TO IT, ALSO RESTORE
;CURSOR ADDR TO HL
;
VDUTBLE:
DB EXIT AND LB ;^@
DB EXIT AND LB ;^A
DB EXIT AND LB ;^B
DB EXIT AND LB ;^C
DB EXIT AND LB ;^D
DB EXIT AND LB ;^E
DB EXIT AND LB ;^F
DB PRINT AND LB ;^G BELL
DB BACKSP AND LB ;^H CURSOR LEFT
DB EXIT AND LB ;^I
DB LINEF AND LB ;^J LINE FEED
DB CURSUP AND LB ;^K CURSOR UP
DB EOL AND LB ;^L CURSOR RIGHT
DB CRET AND LB ;^M CARRIAGE RETURN
DB EXIT AND LB ;^N
DB EXIT AND LB ;^O
DB EXIT AND LB ;^P
DB EXIT AND LB ;^Q
DB EXIT AND LB ;^R
DB EXIT AND LB ;^S
DB EXIT AND LB ;^T
DB EXIT AND LB ;^U
DB EXIT AND LB ;^V
DB EXIT AND LB ;^W
DB EXIT AND LB ;^X
DB EXIT AND LB ;^Y
DB FORM AND LB ;^Z CLEAR SCREEN
DB ESCF AND LB ;^[ ESCAPE
DB EXIT AND LB ;^\
DB EXIT AND LB ;^]
DB HOME AND LB ;^^ HOME CURSOR
DB CRLF AND LB ;^- NEW LINE
;
;PRINT THE CHARACTER ON THE SCREEN
;
PRINT:
MOV C,A ;PUT ASCII CHAR BACK
LDA VFL ;GET REV VIDEO FLAG
XRA C ;XOR WITH CHARACTER
MOV M,A ;PUT RESULT ONTO SCREEN
;
;E0L CHECKS THE CURSOR POSITION FOR END OF LINE
;
EOL:
LDA CURPOS ;GET CURSOR POSITION
INR A ;CURSOR=CURSOR+1
CPI HORIZ ;MAX LINE LENGTH ?
JC TABRET ;NO,STORE NEW CURPOS
CRLF:
XRA A ;RESET A TO LINE START
STA CURPOS ;SAVE CURSOR POSITION
;
;MOVE DOWN ONE LINE
;
LINEF:
LDA LINENO ;GET CURRENT LINE NO.
CPI VERT-1 ;AT THE BOTTOM ?
JNZ NOSCRL ;NO, DONT SCROLL UP
;
;SCROLL UP ONE LINE
;
SCROLL:
LXI H,MPAGE+HORIZ ;YES, HL= LINE N+1
LXI D,MPAGE ;DE= LINE N
LXI B,(VERT*(HORIZ/2))-(HORIZ/2) ;CHAR COUNT
SCRL:
MOV A,M ;GET CHAR FROM LINE N+1
STAX D ;PUT IT INTO LINE N
INX D ;BUMP D TO NEXT CHAR POS
INX H ;BUMP H DITTO
MOV A,M ;GET IT
STAX D ;STORE A
INX H ;BUMP H
INX D ;BUMP D
DCX B ;DECR CHAR COUNT EVERY 2 MOVES
MOV A,B ;GET HI BYTE OF COUNT
ORA C ;IS COUNT = 0 ?
JNZ SCRL ;NOT FINISHED, DO IT AGAIN
LDA LINENO ;YES, GET CURRENT LINE NO.
;
;ERASE BOTTOM LINE (DE POINTS TO START OF LINE)
;
EBOTL:
XCHG ;START OF LINE INTO HL
MVI B,HORIZ ;SET UP CHAR COUNT
CALL ELOP ;DO THE ERASE
DCR A ;SET UP TO ENTER NOSCRL
NOSCRL:
INR A ;LINE = LINE + 1
STA LINENO ;SAVE LINE NO.
JMP EXIT
;
ELOP:
MVI M,SPACE ;SPACE TO OVERWRITE
INX H ;BUMP H TO NEXT CHAR
DCR B ;B=0 IS END OF LINE
JNZ ELOP ;NO, DO IT AGAIN
RET
;
;BACKSPACE
;
BACKSP:
LDA CURPOS ;GET CURRENT CURSOR
DCR A ;CURSOR=CURSOR-1
JP TABRET ;STORE NEW CURPOS
JMP CRET ;GONE BACK PAST START
;OF LINE SO RESET
;
;CLEAR THE SCREEN AND HOME CURSOR
;
FORM:
CALL CLEAR
HOME:
XRA A ;RESET A TO 0
STA LINENO ;LINENO.=0
STA VFL ;VFL=0
;
;CARRIAGE RETURN
;
CRET:
XRA A ;RESET CURSOR TO LINE START
TABRET:
STA CURPOS
;
;RETURN TO THE CALLING ROUTINE
;
EXIT:
CALL LIFTCUR ;CURSOR BACK ON SCREEN
RET ;BACK TO CALLING ROUTINE
;
;MOVE CURSOR UP
;
CURSUP:
LDA LINENO ;LINE NUMBER = N
ANA A ;AT TOP (N=0) ?
JZ EXIT ;YES, DO NOTHING
DCR A ;LINENO=LINENO-1
STA LINENO ;SAVE LINE NUMBER
JMP EXIT
;
;CLEAR THE SCREEN
;
CLEAR:
LXI H,MPAGE ;GET SCREEN START ADDR.
WRSPC:
MVI M,SPACE ;PUT SPACE ONTO SCREEN
INX H ;NEXT SCREEN LOCATION
MOV A,H ;GET SCREEN POS. IN A
CPI (MPAGE+SCREEN)/256 ;END OF SCREEN ?
JNZ WRSPC ;NO, WIPE NEXT SCREEN POS.
RET
;
;SET ESCAPE FLAG
;
ESCF:
MVI A,FLAG ;GET FLAG INTO A
STA ESCFLAG ;STORE ESC SEQUENCE FLAG
JMP EXIT
;
;CALCULATE MEMORY ADDRESS FROM CURSOR POSITION
;
LIFTCUR:
LXI H,MPAGE-HORIZ ;SCREEN START - 1 LINE
LXI D,HORIZ ;CHARACTERS/LINE
LDA LINENO ;GET CURRENT LINE NUMBER
INR A ;SET UP TO ENTER CLOP
CLOP:
DAD D ;HL=CHAR PER LINE * NUMBER
;OF LINES
DCR A ;LINENO.= LINENO.-1
JNZ CLOP ;LINENO.= 0 ?
CFIN:
MOV D,A ;YES, RESET D TO 0
LDA CURPOS ;GET CURSOR POSITION
MOV E,A ;PUT IT INTO E
DAD D ;ADD CHAR POS IN CURRENT
;LINE TO TOTAL IN HL
;
;REVERSE THE VIDEO
;
MOV A,M ;GET SCREEN POS CONTENTS
XRI 80H ;COMPLEMENT BIT 8
MOV M,A ;PUT IT BACK ONTO SCREEN
RET
;
;
;SET UP ALL THE INITIAL ENTRY PARAMETERS ON
;POWERING UP. INTENDED TO BE CALLED FROM THE
;OPERATING SYSTEM
;
;
INITIAL:
MVI A,0 ;INITIALISE VDM HARDWARE
OUT 0C8H ;VDM-1 PORT
LXI H,SCRATCH ;SCRATCHPAD RAM AREA
ILOOP:
MVI M,00 ;CLEAR ONE LOCATION
INX H ;NEXT LOCATION
MOV A,L ;GET LOW ADDRES BYTE
CPI FINIS ;AT THE END YET?
JNZ ILOOP ;NO, CLEAR NEXT BYTE
JMP FORM ;CLEAR THE SCREEN AND
;SET UP THE CURSOR
;
;TEST FOR WHICH CHARACTER IN ESC SEQUENCE
;
ESCAPE:
LDA ESCFLAG ;FLAG DOUBLES AS COUNT
CPI 0FFH ;1st CHARACTER ?
JZ ESCAPE1 ;YES
CPI 0FEH ;2nd CHARACTER ?
JZ ESCAPE2 ;YES
CPI 0FDH ;3rd CHARACTER ?
JZ ESCAPE3 ;YES
JMP ESCEND ;NO MATCH SO END SEQ
;
;PROCESS FIRST CHARACTER OF ESCAPE SEQUENCE
;
ESCAPE1:
MOV A,C ;GET CHAR INTO A
CPI '=' ;IS IT '=' ?
JZ POSIT ;YES, SET POSFLAG
CPI '*' ;IS IT '*' ?
JZ FORM ;YES, CLEAR SCREEN
CPI 'G' ;IS IT 'G' ?
JZ ATTRIB ;YES, VIDEO ATTRIB
CPI 'T' ;IS IT 'T'
JZ ERASE ;YES, ERASE TO END OF LINE
JMP ESCEND ;NO MATCH SO END SEQ
;
;SET FLAG TO INDICATE POSITIONING SEQUENCE
;
POSIT:
MVI A,FLAG ;SET UP POSITION FLAG
STA POSFLAG ;STORE IT
DECR:
LDA ESCFLAG ;GET ESC SEQ CHAR COUNT
DCR A ;COUNT = COUNT-1
STA ESCFLAG ;STORE IT
JMP EXIT
;
;SET FLAG TO INDICATE VIDEO ATTRIBUTE SEQUENCE
;
ATTRIB:
MVI A,FLAG ;SET UP ATTRIBUTE FLAG
STA ATTFLAG ;STORE IT
JMP DECR ;DECREMENT ESCFLAG
;
ERASE:
MOV A,L ;GET LOW BYTE OF SCREEN
ORI HORIZ-1 ;SET A TO END OF LINE-1
INR A ;BUMP A TO EOL
SUB L ;SUBTRACT CURSOR LOCATION
;FROM END OF LINE COUNT
;TO GET NUMBER OF CHARS
;TO ERASE
MOV B,A ;PUT INTO B FOR ELOP
CALL ELOP ;DO THE ERASE
JMP ESCEND ;EXIT
;
;PROCESS 2nd CHARACTER OF ESCAPE SEQUENCE
;
ESCAPE2:
LDA POSFLAG ;GET POSITION FLAG
CPI FLAG ;IS IT SET ?
JZ NEWLINE ;YES, SET NEW LINE
LDA ATTFLAG ;GET ATTRIBUTE FLAG
CPI FLAG ;IS IT SET ?
JZ ATTRIB2 ;YES, PROCESS IT
JMP ESCEND
;
;SET CURSOR TO NEW LINE POSITION
;
NEWLINE:
MOV A,C ;GET CHAR INTO A
SUI OFFSET ;REMOVE OFFSET
CPI VERT ;LARGER THAN NO. LINES ?
JM CONT1 ;NO
MVI A,VERT-1 ;GET MAX. LINE NUMBER
CONT1:
STA LINENO ;STORE NEW LINE NO.
JMP DECR ;DECREMENT ESC COUNT
;
;SET VIDEO ATTRIBUTE
;
ATTRIB2:
MOV A,C ;GET CHAR INTO A
CPI '0' ;IS IT ATTRIBUTE OFF?
JZ NORMAL ;YES, RESET VIDEO FLAG
CPI '4' ;IS IT REV VIDEO ON?
JZ REVERSE ;YES, REVERSE VIDEO FLAG
CPI '6' ;IS IT BLINK/REV VIDEO ON?
JZ REVERSE ;CANT BLINK BUT CAN REVERSE
JMP ESCEND
;
;VIDEO FLAG ROUTINES
;
NORMAL:
XRA A ;RESET VIDEO FLAG
JMP VFLSTOR ;SAVE IT
;
REVERSE:
MVI A,80H ;SET VIDEO FLAG
VFLSTOR:
STA VFL ;SAVE IT
JMP ESCEND
;
;PROCESS THIRD CHARACTER OF ESCAPE SEQUENCE
;
ESCAPE3:
LDA POSFLAG ;GET POSITION FLAG
CPI FLAG ;IS IT SET ?
JZ NEWCHAR ;YES, SET NEW CHAR POS
JMP ESCEND
;
;SET NEW CURSOR CHARACTER POSITION
;
NEWCHAR:
MOV A,C ;GET CHAR INTO A
SUI OFFSET ;REMOVE OFFSET
CPI HORIZ ;LARGER THAN LINE LENGTH ?
JM CONT2 ;NO
MVI A,HORIZ-1 ;GET MAX. CHAR COUNT
CONT2:
STA CURPOS ;SAVE NEW CHAR POS
JMP ESCEND
;
;EXIT FROM ESCAPE SEQUENCE
;
ESCEND:
XRA A ;RESET A TO 0
STA ESCFLAG ;RESET FLAGS
STA POSFLAG
STA ATTFLAG
JMP EXIT
;
;CURSOR STORAGE LOCATIONS
;
ORG 0040H ;Or some other RAM scratch area
;
SCRATCH:DS 6 ;THIS AREA MUST BE RAM
CURPOS: EQU SCRATCH ;POSITION ON LINE
LINENO: EQU SCRATCH+1 ;LINE ON SCREEN
VFL: EQU SCRATCH+2 ;REVERSE VIDEO FLAG
ESCFLAG:EQU SCRATCH+3 ;ESCAPE SEQUENCE FLAG
POSFLAG:EQU SCRATCH+4 ;CURSOR POSITIONING FLAG
ATTFLAG:EQU SCRATCH+5 ;VIDEO ATTRIBUTE FLAG
;
END ENTRY