;******************************************************* ; 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