TITLE 'MYVIO.ASM VERSION OF 27 MAY 84 RHP' ;************************************************************** ;VIO TERMINAL FIRMWARE REQUIRES REFRESH MEMORY TO BE AT ;F000 AND FIRMWARE ITSELF AT F800 ;************************************************************** REFRESH EQU 0F000H ;REFRESH MEMORY ON VIO SYSRAM EQU REFRESH+780H ;SYSTEM RAM VIOFM EQU 0F800H ;FIRMWARE BEGINNING CTRPORT EQU REFRESH+7FFH ;HARDWARE CONTROL WORD ORG SYSRAM CURLIN DB 0 ;CURRENT LINE # 0-23 CURCOL DB 0 ;CURRENT COL # 0-79 INVIDIO DB 0 ;INVERSE VIDIO MODE(BY CHAR) VDIMDE DB 0 ;MODE 0=GRAPHICS, NOT 0= TEXT INSRT DB 0 ;INSERTING CHARS MODE ESCCNT DB 0 ;ESCAPE CHAR COUNT ESCCDE DB 0 ;ESCAPE CODE LAST USED USERCTR DW 0 ;USER CTR TBLE PTR, NON ZERO USERESC DW 0 ;USER ESCAPE TBLE PTR,NON ZERO USERCMD DW 0 ;USER MONITOR COMMAND TABLE RAMPTR DW 0 ;RAM SPACE PTR WITH DIRECT I/O CURPTR DW 0 ;CURSOR ADDRESS PRTMD DB 0 ;PROTECTED MODE 0=NO CCUR DB 0 ;CHAR UNDER CURSOR(FOR GRAPHICS MODE) CCHAR DB 0 ;CURRENT CHARACTER TO DISPLAY CTRLC DB 0 ;CONTROL WORD AS FOLLOWS ; 7 SCROLL MODE 0=SCROLL,1=WRAP ; 6 UNUSED ; 5 UP/LOW 0=UP,1=UP+LOW ; 4 1=INVERSE VIDIO SCREEN ; 3 00=BLANK,01=LOW128+INV,10=HIGH128+INV ; 2 11=256 CHAR GRAPHICS ; 1 #LINES 0=24,1=12 ; 0 #CHARS 0=80,1=40 TAB DS 10 ;80 BITS FOR TAB CONTROL CLINE DW 0 ;CHARS/LINE LPAGE DB 0 ;LINES/PAGE-1 NCHARS DW 0 ;#CHARS ON DISPLAY PRUPRF DB 0 ;TRANSITION PROTECT FLAG USERF DB 0 ;ENTRY POINT FLAG 0=INIT48,1=CHAR48,2=USER LASTC DW 0 ;LAST CHAR ON SCREEN PTR+1 ;************************************************************** ; USER ;ENTRY POINTS ;************************************************************** ORG VIOFM JMP INIT ;INITIALIZATION POINT JMP CHAROUT ;DISPLAY CHARACTER IN A JMP MONT ;MONITOR ENTRY POINT JMP VIOTEST ;DEMO TEST JMP CONST ;GET CONSOLE STATUS JMP CHIN1 ;GET CONSOLE DATA JMP PRSTAT ;GET PRINTER STATUS JMP PRINTA ;PRINT CHARACTER IN A JMP PRINTC ;PRINT CHARACTER IN C JMP CHAROUC ;DISPLAY CHARACTER IN C ;************************************************************** VIOTEST LXI SP,SYSRAM+7EH CALL INIT ŠVIOTES1 CALL CHIN JMP VIOTES1 ;DEMO TESTER INIT PUSH H PUSH D PUSH B PUSH PSW LXI H,CURLIN ;START OF ZEROED AREA MVI B,CLINE-CURLIN AND 0FFH XRA A INIT1 MOV M,A ;ZERO AREA INX H DCR B JNZ INIT1 LXI H,REFRESH ;BEGIN CURSOR POS SHLD CURPTR LXI H,1920 ;DEFAULT CHARS/SCREEN SHLD NCHARS CALL BLNKS ;CLEAR SCREEN AND HOME MVI A,8H ;DEFAULT 80X24 SCREEN TEXT MODE LXI D,BMP1 ;SET UP RETURN ADDR PUSH D ;SUBROUTINE TO SET HARDWARE CONTROL PORT SETCMD STA CTRLC STA CTRPORT ;HARDWARE CONTROL PORT CMA ANI 3 RRC ;FINDING NCHARS ON SCREEN LXI H,40 ;COLS/LINE JNC SETCM1 ;ENOUGH DAD H ;COLS/LINE=80 SETCM1 SHLD CLINE LXI H,LPAGE ;PT AT LINES/PAGE MVI M,11 RAR JNC SETCM2 MVI M,23 SETCM2 LXI H,480 ;COUNT FOR 12 X 40 SCREEN JNC SETCM3 DAD H SETCM3 ORA A ;SET FLAGS JZ SETCM4 DAD H SETCM4 SHLD NCHARS LXI D,REFRESH DAD D SHLD LASTC ;LAST CHAR ON SCREEN PTR+1 LDA CTRLC ;CONTOL CODE ANI 0CH ;MODE BITS ONLY XRI 0CH STA VDIMDE ;0=GRAPHICS ;CHECK CURSOR WITHIN POSSIBLE NEW BOUNDS ESCRET XRA A STA ESCCNT ;COUNT=0 RET ;TO LAST ADDR ON STACK, BMP1 Š ;************************************************************** ;CRLF DO CARRIAGE RETURN/LINE FEED ;************************************************************** CRLF MVI C,0DH CALL CHAROUT MVI C,0AH ;************************************************************** ; THIS IS THE NORMAL ENTRY POINT FOR COMMUNICATING WITH THE ; VIDIO MONITOR AS YOU WOULD A CRT. ;************************************************************** CHAROUC MOV A,C CHAROUT PUSH H PUSH D PUSH B PUSH PSW STA CCHAR LHLD CURPTR ;CURSOR POSITION LDA CCUR ;CHAR UNDER CURSOR MOV M,A ;REMOVE CURSOR LXI H,CCHAR ;PT AT CURRENT CHAR MOV A,M ;GET CHAR CPI 1BH ;ESCAPE CHAR? JZ ESCAPE LDA ESCCNT ;ARE WE IN ESCAPE SEQ ALREADY? ORA A JNZ ESCAPE ;YES MOV A,M ;CURRENT CHAR CPI 7FH ;DELETE CHAR (RUBOUT)? JZ NOUSER1 ;YES LDA VDIMDE ;GRAPHICS MODE? ORA A JZ CHAR1 ;YES MOV A,M CPI 0FFH ;DUMMY PAD FROM USER? JZ BMP1 ;YES ANI 7FH ;STRIP PARITY BIT MOV M,A SBI 20H ;CONTROL CODE? JM CONTROL ;YES LDA CTRLC ;CONTROL WORD MOV B,A ;TMP SAVE ANI 0CH ;MODE ONLY CPI 08H ;LOW HALF OF CHAR GEN ROM? JNZ CHAR1 ;NO,UPPER HALF MOV A,B ;CONTROL WORD ANI 20H ;UP/LOW CASE JNZ CHAR1 ;LOWER OK AS IS MOV A,M ;CURRENT CHAR SBI 61H ;LOWER CASE A JM CHAR1 ;NOT ALPHA SBI 7BH-61H JP CHAR1 ;NOT ALPHA ADI 7BH-20H ;RESTORE AND CONVERT TO UPPER CASE MOV M,A CHAR1 CALL INSCHR ;INSERT CCHAR AT CURSOR POS CALL BMPCUR BMP10 CALL CALPOS ;CURSOR POS BMP1 CALL INSCURS ;INSERT CURSOR POP PSW POP B POP D POP H Š RET ;TO EXTERNAL WORLD BMPCUR EQU $ CALL BMPC ;BUMP CURSOR CHAR POSITION CZ BMPCUR1 ;DO LINE FEED LDA PRTMD ;PROTECT MODE? XCHG ;H,L=CURRENT CURSOR PTR ANA M ;IS IT PROTECTED? JM BMPCUR ;YES,SKIP PROTECTED FIELD RET ;GO INSERT CURSOR LFEED LXI H,CURLIN BMPCUR1 INR M LDA LPAGE ;MAX LINES/PAGE CMP M ;EXCEED MAX? RP DCR M ;LEAVE AT LAST LINE ;************************************************************** ;SCROLL UP OR WRAP AROUND AS SET BY CTRLC ;************************************************************** SCROLL LDA CTRLC ;KIND OF SCROLL? ANI 8CH ;LEAVE SCROLL AND MODE BITS JM SCROLL3 ;WRAP AROUND CPI 0CH ;GRAPHICS MODE JNZ SCROLL1 ;NO, ALLOW SCROLL SCROLL3 XRA A MOV M,A ;HOME CURSOR FOR WRAP AROUND INX H MOV M,A RET SCROLL1 LHLD CLINE ;COLS/LINE PUSH H ;SAVE COLS/LINE XCHG LHLD NCHARS ;# CHARS PER PAGE MOV A,L SUB E MOV C,A MOV B,H XCHG LXI D,REFRESH DAD D ;HL=SOURCE,DE=DEST. CALL MVCUP SCROLL2 JMP DLINE1 ;ERASE CURRENT LINE AND RETURN ;************************************************************** ;PROCESS CONTROL CODES ;************************************************************** CONTROL XCHG ;D,E=CCHR PTR LHLD USERCTR ;USER TABLE IF ANY MOV A,H ORA A LDAX D ;CCHAR IN A JZ NOUSER ;NO TABLE USER DEFINED CALL LOOKUP JNZ FNDCTRL ;FOUND TABLE ENTRY NOUSER LDA CCHAR NOUSER1 LXI H,CTRTBL CALL LOOKUP Š JZ BMP1 ;NOT FOUND FNDCTRL LXI D,BMP10 ;RETURN ADDRESS PUSH D ;ON STACK LXI D,CURCOL PCHL ;************************************************************** ;PROCESS ESCAPE SEQUENCES ;************************************************************** ESCAPE LXI D,BMP10 ;RETURN ADDR PUSH D XCHG LXI H,ESCCNT MOV A,M ;ESCCAPE COUNT INR M ;ESCCNT=ESCCNT+1 ORA A RZ DCR A INX H ;POINT TO ESCAPE CODE LDAX D ;GET CCHAR JNZ ESCAP1 ;ESCCNT>1 MOV M,A ;SAVE ESCAPE CODE ESCAP1 LHLD USERESC ;USER ESCAPE TABLE PTR MOV A,H ORA A LDAX D ;ESCCODE JZ NUESC ;NO USER DEFINED TABLE CALL LOOKUP ;LOOKUP IN USERS TABLE JNZ FNDESC ;FOUND ESCAPE SEQ IN USER NUESC LDA ESCCDE ;TRY AGAIN IN VIO TABLE ANI 0DFH ;REMOVE LOWER CASE BIT LXI H,ESCTBL CALL LOOKUP JZ ESCRET ;NOT FOUND FNDESC LDA CTRLC LXI D,SETCMD PCHL ;************************************************************** ;CURSOR CONTROL ;************************************************************** UPLINE DCX D ;D,E=CURLIN PTR BCKLNE LDAX D ;D,E=CURLIN OR CURCOL ORA A ;SET FLAGS RZ DCR A ;BACK UP 1 BCKL1 STAX D RET CRET XRA A STA INSRT ;REMOVE INSERT MODE JMP BCKL1 ;************************************************************** ;TOGGLE PROTECTED MODE FLAG ;************************************************************** PRTECT LXI H,PRTMD ;PT AT FLAG Š JMP INSMDE+3 ;GO TOGGLE IT ;************************************************************** ;TOGGLE INSERT MODE FLAG ;************************************************************** INSMDE LXI H,INSRT INSMD1 MOV A,M CMA MOV M,A RET ;************************************************************** ;BLANK SCREEN AND HOME ;************************************************************** BLNKS LHLD NCHARS ;#CHARS ON SCREEN XCHG LXI H,REFRESH BLNKS1 LDA PRTMD ;IN PROTECTED MODE? ANI 80H ANA M ;PROTECTED? JM BLNKS2 ;IS PROTECTED, DO NOT BLANK MVI M,' ' BLNKS2 INX H DCX D MOV A,D ORA E ;DONE YET? JNZ BLNKS1 ;NO HOME LXI H,0 SHLD CURLIN RET ;************************************************************** ;BLANK FROM CURSOR TO END OF UNPROTECTED FIELD ;************************************************************** BLANKL CALL CHARLN ;CALC # CHARS TO END OF FIELD BLANKL3 LDA PRTMD ;PROTECTED MODE? ORA A JZ BLANKL1 ;NOT PROTECTED,SKIP CHECK MOV A,M ;GET CHAR ORA A JM BLANKL2 ;IS PROTECTED,DO NOT BLANK BLANKL1 MVI A,' ' MOV M,A ;INSERT BLANK BLANKL2 INX H ;NEXT CHAR DCR C ;COUNT JNZ BLANKL3 RET ;************************************************************** ;TURN ON PROTECTED FIELD/TURN OFF PROT FIELD ;************************************************************** PROTC LXI H,INVIDIO ;PT AT INVERTED VIDIO FLAG JMP INSMD1 ;************************************************************** ;DELETE CHAR AND SHIFT PROTECTED FIELD LEFT ONE PLACE ;************************************************************** DELETE CALL CHARLN LHLD CURPTR ;CURSOR POSITION MOV D,H Š MOV E,L INX H CALL MVCUP ;SHIFT LINE LEFT ONE PLACE MVI A,' ' DCX D ;BACK UP ONE STAX D ;INSERT FINAL BLANK RET ;************************************************************** ;CALC # CHARS FROM CURSOR TO END OF UNPROT FIELD INCLUSIVE ; RETURN H,L=CURSOR PTR ;************************************************************** CHARLN LDA PRTMD ;PROTECT MODE FLAG ANI 80H MOV D,A ;SAVE PROTECT MODE BIT LHLD CURPTR ;CURSOR POSITION PUSH H LDA CURCOL MOV E,A ;E=CURRENT COLUMN LXI B,0 ;# CHARS TO END CHARLN1 LDA CLINE ;COLS/LINE SUB E INR E INX H INR C ;COUNT INCREASED DCR A ;DNE YET WITH LINE JZ CHARLN2 ;END OF LINE RETURN MOV A,M ;H,L=END +1 ANA D ;PROTECTED? JP CHARLN1 ;NO, KEEP GOING CHARLN2 POP H ;CURSOR POSITION RET ;************************************************************** ;TABLE LOOK UP ROUTINE. SEARCHES FIRST BYTE OF THREE BYTE TABLE OF ;RECORDS FOR A MATCH OR ZERO. ZERO INDICATES END OF TABLE WITH NO ;MATCH, RETURNED IN A REG.H,L LOADED WITH SECOND TWO BYTES OF TABLE ;IF MATCH FOUND. ;************************************************************** LOOKUP MOV B,A ;SAVE LOOKU1 MOV A,M ;GET FIRST BYTE OF RECORD LXI D,CURLIN ORA A RZ ;DONE,NO MATCH CMP B ;SAME AS REQUESTED? JNZ TBLUP1 ;NO INX H MOV E,M INX H MOV D,M XCHG ORA A ;SET FLAGS RET TBLUP1 INX H INX H INX H ;BUMP TO NEXT RECORD Š JMP LOOKU1 ;************************************************************** ;DELETE CURRENT LINE AND RETURN CURSOR ;************************************************************** DLINE CALL NMCHM ;SET UP FOR MOVE PUSH H ;SAVE COLS/LINE DAD D ;H,L=SOURCE BEGIN CALL MVCUP DLINE1 POP B ;COLS/LINE XCHG JMP EN1 ;ERASE LINE ;************************************************************** ;ENTER NEW LINE AT CURSOR LINE,PUSH BOTTOM DOWN ;************************************************************** ENLINE CALL NMCHM ;SET UP FOR MOVE PUSH H ;SAVE COLS/LINE DAD D ;H,L=SOURCE BEGIN DAD B ;H,L=END OF DEST+1 XCHG DAD B ;H,L=END OF SOURCE+1 DCX H DCX D CALL MVCDN ;MOVE DOWN 1 LINE POP B INX H EN1 MVI M,' ' INX H DCR C JNZ EN1 RET NMCHM XRA A STAX D ;COL=0 CALL CHARSN ;#CHARS TO END OF SCREEN XCHG ;D,E=DEST. LHLD CLINE ;COLS/LINE MOV A,L ;COLS/LINE NMCHM1 DCX B DCR A JNZ NMCHM1 ;DECREASE COUNT BY ONE LINES WORTH RET ;************************************************************** ;CALC # CHARS TO END OF SCREEN FROM CURSOR ;************************************************************** CHARSN CALL CALPOS PUSH H ;SAVE XCHG ;D,E=CURSOR POS LHLD LASTC ;LAST CHAR POSITION+1 MOV A,D CMA MOV D,A MOV A,E CMA MOV E,A INX D ;COMPLIMENT D,E Š DAD D ;H,L=# CHARS TO END-1 PUSH H POP B ;B,C=#CHARS TO END POP H ;CURRENT POSITION CURSOR RET ;************************************************************** ;ESCAPE CODE PROCESSING ;************************************************************** HIGH128 ANI 0F3H ORI 4H XCHG ;H,L=SETCMD ADDR PCHL ;GRAPHIC MODE 256 CHAR ROM,NO INVERSE VIDIO GRAPHIC ORI 0CH XCHG ;H,L=SETCMD ADDR PCHL ;LOWER HALF OF ROM+REVERSE VIDIO LOW128 ANI 0F3H ORI 8H XCHG ;H,L=SETCMD ADDR PCHL ;SCROLL TOGGLE SCRL XRI 80H XCHG ;H,L=SETCMD ADDR PCHL ;UPPER LOWER CASE TOGGLE UPLOW XRI 20H XCHG ;H,L=SETCMD ADDR PCHL ;INVERSE VIDIO TOGGLE VIDIO XRI 10H XCHG ;H,L=SETCMD ADDR PCHL ;# LINES PER PAGE SWITCH LINES XRI 02H XCHG ;H,L=SETCMD ADDR PCHL ;#COLS/LINE TOGGLE COLS XRI 01H XCHG ;H,L=SETCMD ADDR PCHL ;************************************************************** ;INSERT CURSOR CHAR AT PROPER POSITION ;************************************************************** INSCURS LHLD CURPTR MOV A,M STA CCUR ;SAVE CHAR UNDER CURSOR FOR GRAPHICS MODE ORI 80H ;BIT 7 FOR INVERSE VIDIO MOV M,A ;STORE BACK LDA VDIMDE ORA A RNZ ;NO GRAPHICS MVI M,7FH ;BLOCK FOR GRAPHICS MODE RET Š ;************************************************************** ;CLEAR TABS ;************************************************************** CLRTBS LXI H,TAB ;TABS BITS MVI B,10 ;#BYTES FOR TABS XRA A CLRT1 MOV M,A INX H DCR B JNZ CLRT1 JMP ESCRET ;PUT IN CURSOR ;************************************************************** ;SET OR CLEAR TAB TOGGLE BIT ;************************************************************** SETTAB CALL FNDTB XRI 80H ;INVERT TAB BIT SETD2 RRC DCR B JNZ SETD2 STAX D ;STORE TAB BYTE JMP ESCRET ;DO CURSOR ;FIND TAB BIT, LEAVE IN A REG BIT 7 FNDTB LDA CURCOL ;COL # MOV H,A INR H LXI D,TAB ;WORD PTR FNDTB1 MVI C,8 ;BIT COUNTER FNDTB3 DCR H JZ FNDTDN ;FOUND IT DCR C ;BIT COUNTER JNZ FNDTB3 INX D ;PT AT NEXT BYTE JMP FNDTB1 FNDTDN LDAX D ;GET TAB BYTE BITS MOV B,C ;SAVE COUNT OF BITS FNDTB2 RLC DCR C JNZ FNDTB2 ;ROTATE UNTIL FOUND RET ;************************************************************** ;TAB TO BEGINNING OF NEXT UNPROTECTED FIELD OR TAB OR HOME IF NONE ;************************************************************** TABB XRA A STA PRUPRF ;PROTECT/UNPROTECT TRANSITION FLAG TAB3 CALL BMPC ;BUMP CURSOR POSITION JNZ TAB1 ;NO LINE FEED NECESSARY INR M ;BUMP LINE # CMP M ;EXCEED LPAGE? JM SCROLL3 ;YES,HOME AND RETURN TAB1 LDA PRTMD ;PROTECT MODE FLAG XCHG ;H,L PTS AT CHAR ANA M ;PROTECTED? MOV A,M ;GET CHAR Š LXI D,PRUPRF ;TRANSITION FLAG JP TAB2 ;NO PROTECTED FIELD STAX D ;SET TRANSITION FLAG JMP TAB3 TAB2 LDAX D ;GET TRANSITION FLAG ORA A RM ;UNPROT FIELD WITH TRANSITION CALL FNDTB ;FIND TAB POSITION BIT ORA A ;SET FLAGS RM ;TAB IS SET JMP TAB3 ;************************************************************** ;CALCULATE CURSOR POSITION FROM CURLIN AND CURCOL ;************************************************************** CALPOS LHLD CLINE ;CHARS/LINE-1 XCHG LHLD CURLIN ;L=CURLIN,H=CURCOL MOV C,H MOV B,L LXI H,REFRESH ;BOTTOM OF REFRESH MEMORY INR B CALPOS1 DCR B ;DONE YET JZ CALPOS2 ;YES DAD D ;ADD ANOTHER LINE OF CHARS JMP CALPOS1 CALPOS2 DAD B ;ADD CURRENT COL SHLD CURPTR ;SAVE RET ;************************************************************** ;BMPC BUMP CURSOR 1 PLACE. ON RETURN ; D,E=CURSOR POSITION ; H,L=CURCOL PTR OR CURLIN PTR DEPENDING ON Z FLAG ; Z FLAG=0 IF NO LINE FEED NEEDED,1 IF LINE FEED NEEDED ; CURLIN AND CURCOL AND CURPTR ARE UPDATED AS IF LINE FEED ; A REG =LPAGE IF LINE FEED NEEDED ;************************************************************** BMPC LHLD CURPTR INX H SHLD CURPTR ;UPDATE ABS CURSOR ADDRESS XCHG ;D,E=PTR LXI H,CURCOL INR M ;BUMP COLUMN LDA CLINE ;MAX COLS/LINE SUB M ;ZERO IF EXCEED LINE RNZ ;OK AS IS MOV M,A ;COL=0 DCX H LDA LPAGE ;MAX LINES/PAGE RET ;************************************************************** ;ADDRESSABLE CURSOR FUNCTION ;************************************************************** ADDCURS LXI H,ESCCNT ;PT AT ESCAPE COUNT LXI D,CURLIN ;PT AT CURRENT LINE COUNT LDA CCHAR Š SUI 20H ;REMOVE OFFSET FOR COUNT MOV B,A MOV A,M ;GET COUNT SUI 3 RM ;NO VALID NUMBS YET JNZ XADD ;X AXIS VALUE ;Y-AXIS VALUE LDA LPAGE XADD3 STAX D ;MAX LINE # CMP B RM MOV A,B STAX D RET XADD MVI M,0 ;ESCCNT=0 LDA CLINE ;MAX COL/LINE INX D DCR A JMP XADD3 ;************************************************************** ;INSERT CHAR AT CURSOR POSITION.EITHER WRITES OVER PREVIOS ;CHAR OR PUSHES ENTIRE FIELD OVER ONE CHAR BEFORE INSERTING. ;************************************************************** INSCHR LHLD CURPTR ;CURSOR ADDRESS PUSH H ;SAVE LDA INSRT ;INSERT FLAG ORA A JZ INSC3 ;OVERWRITE CALL CHARLN DCX B ;3CHARS-1 TO END DAD B ;H,L PTS AT LAST CHAR ON LINE MOV D,H MOV E,L DCX D ;D,E PTS AT SOURCE XCHG ;H,L=SOURCE,D,E=DEST CALL MVCDN ;MOVE CHARS RIGHT INSC3 POP H ;CURSOR POSITION LDA INVIDIO ANI 80H MOV B,A ;INVERT BIT LDA CCHAR ORA B ;MERGE WITH INVERT BIT INSC4 MOV M,A RET ;************************************************************** ;SHIFT CHARS RIGHT FROM D,E TO H,L, B,C CHARS FROM RIGHT ;************************************************************** MVCDN MOV A,C ORA B RZ ;DONE MOV A,M STAX D DCX H DCX D Š DCX B JMP MVCDN ; CONTROL FUNCTION JUMP TABLE CTRTBL EQU $ DB 0DH ;CARRIAGE RETURN DW CRET DB 0AH ;LINE FEED DW LFEED DB 04H ;DELETE LINE (CTRL D) DW DLINE DB 05H ;INSERT LINE (CTRL E) DW ENLINE DB 08H ;BACK CURSOR (CTRL H) DW BCKLNE DB 09H ;TAB (CTRL I) DW TABB DB 0BH ;UP CURSOR (CTRL K) DW UPLINE DB 0CH ;FORWARD CURSOR (CTRL L) DW BMPCUR DB 10H ;PROTECTED MODE TOGGLE (CTRL P) DW PRTECT DB 14H ;INSERT MODE (CTRL T) DW INSMDE DB 15H ;CLEAR TO EOL (CTRL U) DW BLANKL DB 16H ;PROTECTED FIELDS (CTRL V) DW PROTC DB 1AH ;SCREEN ERASE (CTRL Z) DW BLNKS DB 1EH ;HOME CURSOR (CTRL ^) DW HOME DB 7FH ;DELETE CHAR (RUBOUT) DW DELETE DB 0 ;TERMINATOR ; ESCAPE FUNCTION JUMP TABLE ESCTBL EQU $ DB 1DH ;CURSOR CONTROL ('=' LESS BIT 5 LOWER CASE) DW ADDCURS DB 09H ;CLEAR TABS DW CLRTBS DB 'C' ;COLS/LINE DW COLS DB 'E' ;EXTENDED MODE UPPER 128 DW HIGH128 DB 'G' ;GRAPHIC SET DW GRAPHIC DB 'I' ;SET TAB DW SETTAB DB 'L' ;LINES/PAGE DW LINES DB 'S' ;SCROLL TOGGLE DW SCRL DB 'T' ;LOWER 128 BYTES OF ROM DW LOW128 DB 'U' ;UPPER/LOWER CASE DW UPLOW DB 'V' ;INVERSE VIDIO TOGGLE Š DW VIDIO DB 0 ;TERMINATOR ;************************************************************** ;8080 MONITOR PROGRAM USING THE VIO FIRMWARE ;************************************************************** MONT LXI SP,REFRESH+7FFH ;TOP OF MEMORY CALL INIT ;INIT VIO LXI H,SIGNON CALL MSGNC ;SIGNON MSG PRMPT CALL CRLF MVI A,'?' CALL CHAROUT CALL CHIN ;GET COMMAND MOV B,A ;SAVE IT LXI D,PRMPT PUSH D ;RETURN ADDRESS LHLD USERCMD ;USER COMMAND TABLE MOV A,H ORA A ;SET FLAGS MOV A,B ;RETRIEVE CODE JZ NUCMD ;NO USER COMMAND TABLE CALL LOOKUP ;LOOKUP IN USER TABLE JNZ FNDCMD ;FOUND COMMAND NUCMD MOV A,B ;GET COMMAND AGAIN LXI H,CMDTBL ;COMAND TABLE PTR CALL LOOKUP RZ ;NO ENTRY,PROMPT AGIN MVI B,1 ;FOR PROT/UNPROT FNDCMD PCHL ;GO TO ROUTINE SIGNON DB 'R H PETERS VIO',0 DB 'MONITOR 4/84' ;************************************************************** ;JUMP TO MEMORY "JAAAA" ;CALL MEMORY WITH RETURN TO MONITOR ;************************************************************** JUMP POP D ;REMOVE RETURN ADDRESS CALL1 CALL IHEX ;GET JUMP ADDRESS Š PCHL ;DO IT ;************************************************************** ;ENTER BYTE INTO MEMORY AND MODIFY IF DESIRED ;************************************************************** ENTR CALL IHEX ;START ADDR ENTR1 CALL CRLF CALL OHEXHL ;DISPLAY ADDRESS MOV A,M ;GET BYTE IN MEMORY MOV E,A ;PRESET FOR IHEX CALL OHEXB ;DISPLAY BYTE XCHG ;D,E=ADDRESS,L=DEFAULT CHAR CALL IHEX2 ;GET MODIFIER OR DEFAULT XCHG ;H,L=ADDR,E=BYTE MOV M,E DCX H CPI 0AH ;DONE? RZ ;YES CPI '-' ;BACKWARD JZ ENTR1 ;YES INX H INX H ;DEFAULT FORWARD JMP ENTR1 ;************************************************************** ;DISPLAY MEMORY "D,START,END CR" ;************************************************************** DISP CALL SIZE ;H,L=START,B,C=SIZE DISP4 LDA CTRLC ;#LINES/COLS RRC ;#LINES BIT IN CARRY RRC MVI D,12 JC DISP2 MVI D,24 DISP2 CALL CRLF IN 3 ANI 2 ;ANY INPUT RNZ ;YES,INTERRRUPT MVI E,8 LDA CTRLC RRC JC DISP3 MVI E,16 DISP3 CALL OHEXHL ;OUTPUT ASCII H,L REG DISP1 MOV A,M ;GET DATA BYTE CALL OHEXB ;OUTPUT WITH TRAIL BLANK INX H DCX B MOV A,B ORA C RZ ;DONE DCR E JNZ DISP1 ;KEEP WITH CURRENT LINE DCR D ;FILLED PAGE YET? JNZ DISP2 CALL CHIN ;WAIT FOR PAGE PROMT JMP DISP4 Š ;************************************************************** ;ALLOW ESCAPE SEQUENCES TO CONTROL ;************************************************************** ESCAP CALL CHIN ;READ ESCAPE SEQUENCE CODE RET ;************************************************************** ;OUTPUT HEX WITH TRAILING BYTE ;************************************************************** OHEXB CALL OHEX MVI A,' ' CALL CHAROUT RET ;************************************************************** ;OUTPUT 16 BIT ASCII HEX FROM H,L ;************************************************************** OHEXHL MOV A,H CALL OHEX MOV A,L CALL OHEXB RET ;************************************************************** ;INTEL LOADER LOADS INTEL FORMAT TAPES FROM ;TELETYPE (PORT 2,3) ;************************************************************** INTEL CALL CHIN ;READ WITHOUT ECHO SBI ':' ;RCORD MARKER? JNZ INTEL ;NO MOV D,A ;ZERO CHECKSUM CALL IBYTE ;INPUT 2 HEX CHARS ORA A ;SET FLAGS RZ ;COUNT =0 MEANS END MOV D,A ;BYTE COUNT CALL IBYTE MOV H,A CALL IBYTE MOV L,A CALL IBYTE ;DUMMY RECORD TYPE IGNORED DATA CALL IBYTE Š MOV M,A INX H DCR D JNZ DATA CALL IBYTE ;READ AND ADD CHECKSUM JZ INTEL ;OK AS IS MVI A,'C' CALL CHAROUT ;ERROR MESSAGE RET ;************************************************************** ;READ 2 ASCII HEX BYTES AND CONVERT TO BINARY ;************************************************************** IBYTE CALL CHIN ;READ CHAR CALL ASBI ;CONVERT TO BINARY JC ERR2 ADD A ADD A ADD A ADD A MOV E,A ;SAVE CALL CHIN CALL ASBI JC ERR2 ;INVALID ASCII HEX CHAR ADD E MOV E,A ;SAVE CHAR ADD D ;ADD TO CHECKSUM MOV D,A RET ;************************************************************** ;SIZE INPUTS START,END ADDR AND CONVERTS TO START ; AND SIZE IN H,L AND B,C ;************************************************************** SIZE CALL PARM2 ;H,L=START D,E=END PUSH A MOV A,E SUB L ;LOW BYTE SIZE MOV C,A MOV A,D SBB H ;HIGH BYTE SIZE MOV B,A INX B ;ADD 1 POP A RET ;************************************************************** ;MEMORY MOVE "M SOURCE BEG,SOURCE END,DEST BEG" ;************************************************************** MOVE CALL PARM4 ;START,END,DEST MOVE1 CALL MVCUP ;DO MOVE RET ;************************************************************** ;FILL MEMORY WITH CHAR ;************************************************************** FILL CALL PARM4 ;START,END,FILL CHAR IN L MOV A,E ;FILL CHAR MOV M,A ;STORE IN FIRST LOCATION Š DCX B MOV D,H MOV E,L ;DEST ADDR INX D ;=START ADDR+1 JMP MOVE1 ;************************************************************** ;MEMORY TEST ROUTINE ;************************************************************** MEMTEST CALL SIZE ;H,L=START,B,C=SIZE DCX B ;B,C=SIZE-1 OR 0 MEM2 XRA A MOV D,M ;SAVE CELL MEM1 MOV M,A CMP M JNZ MEMERR ;NOT GOOD DCR A ;NEXT PATTERN JNZ MEM1 MOV M,D ;RESTORE MEMORY IN 3 ANI 2 ;BAIL OUT? RNZ ;YES INX H DCX B MOV A,B ORA C JNZ MEM2 RET MEMERR INX H ;ADJUST FOR PRNMEM MOV E,A ;SAVE CALL PNTMEM ;PRINT ADDR,CONTENTS MOV A,E ;RESTORE JMP SRCPNT1 ;PRINT SOULD BE ;************************************************************** ;DO DIRECT INPUT/OUTPUT FROM SPECIFIED PORT ;************************************************************** INPORT DCR B ;B=0=INPUT,B=1=OUTPUT OUTPORT CALL PARM2 ;INPUT PORT,VALUE IN H,L AND D,E MOV A,B ;FLAG RLC RLC RLC XRI 08H ;INVERT BIT 3 ORI 0D3H ;FORM I/O INST MOV D,L LHLD RAMPTR ;GET AVAIL RAM PTR MOV M,A CMP M RNZ ;INVALID RAM PUSH H INX H MOV M,D ;PORT # INX H MVI M,0C9H ;RETURN LXI H,IORET XTHL ;PUT RETURN ADDRESS,GET START ADDR Š MOV A,B ORA A ;SET FLAG FOR IN OR OUT MOV A,E ;OUTPUT BYTE PCHL IORET RNZ ;DONE IF OUTPUT INST CALL OHEXB ;PRINT VALUE IF INPUT RET ;************************************************************** ;SET FREE RAM PTR FOR DIRECT IO INSTS ;************************************************************** RAMFND CALL IHEX ;GET RAM ADDR SHLD RAMPTR ;SAVE IN VIO RAM RET ;************************************************************** ;COMPARE MEMORY BLOCKS AND PRINT DIFFERENCES ;************************************************************** CMPBLK CALL PARM4 ;START,SIZE,DEST IN HL BC,DE CMPBLK1 LDAX D ;DEST BYTE CMP M ;SAME AS SOURCE BYTE? INX H INX D JZ CMPB1 ;YES, NO PRINT CALL PNTMEM ;PRINT ADDR,SOURCE DEST XCHG CALL PNTME1 ;NO CRLF XCHG CMPB1 DCX B MOV A,B ORA C RZ ;YES,RETURN IN 3 ANI 2 RNZ ;BAIL OUT JMP CMPBLK1 ;************************************************************** ;SEARCH MEMORY FOR MASKED 16 BIT VALUE ;S,FROM,TO,16BIT VALUE,16 BIT MASK ;************************************************************** SEARCH CALL PARM4 ;START,SIZE,VALUE IN H,L B,C D,E PUSH H ;SAVE LXI H,-1 ;DEFAULT MASK ALL CPI 0AH ;USER SPECIFIED MASK? CNZ IHEX ;YES,READ IT INTO H,L XTHL ;MASK ON STACK,START IN H,L SEARCH1 MOV A,M ;LOW BYTE XTHL ;H,L=MASK VALUE ANA H ;MASK HIGH BYTE CMP D ;IS IT CORRECT VALUE? XTHL ;RESTORE START PTR INX H ;BUMP PTR JNZ CMP16 ;NO MATCH MOV A,M ;LOW BYTE XTHL ;GET MASK IN H,L ANA L CMP E Š XTHL ;H,L=START,STACK=MASK CZ SRCPNT ;PRINT MATCH IF FOUND CMP16 DCX B MOV A,B ORA C JNZ SEARCH1 POP B ;REMOVE MASK VALUE RET ;************************************************************** ;PARM4 INPUTS START,END,VALUE AND ;CONVERTS TO START,SIZE,VALUE IN H,L B,C AND D,E ;RESPECTIVELY ;************************************************************** PARM4 CALL SIZE JMP PARM3 ;************************************************************** ;MVCUP MOVE B,C CHARS FROM H,L TO D,E FROM BOTTOM ;************************************************************** MVCUP MOV A,B ORA C RZ MOV A,M STAX D ;MOVE IT DCX B INX H INX D JMP MVCUP ;KEEP GOING ERR2 MVI A,'T' ;TYPE CODE ERROR JZ RDRCRDS ;NO ERROR CALL CHAROUT JMP PRMPT ;BAIL OUT ;************************************************************** ;CHARACTER INPUT ROUTINES Š;************************************************************** CHIN CALL CHIN1 CPI 03 ;CRTL C? JZ MONT ;YES,RESET AND PROMPT CALL CHAROUT CPI 0DH CZ CRLF ;ADD LINE FEED RET CHIN1 CALL CONST ORA A JZ CHIN1 IN 2 ;READ PORT 2 ANI 7FH ;MASK PARITY RET PRSTAT IN 3 ;READ STATUS PORT ANI 8 ;CHECK THE READY BIT JMP STAT1 CONST IN 3 ;READ STATUS PORT ANI 2 ;CHECK FOR KEYPRESS STAT1 MVI A,0FFH ;GET READY FOR KEYPRESS RNZ CMA ;NO KEYPRESS RET PRINTA MOV C,A PRINTC CALL PRSTAT ORA A JZ PRINTC MOV A,C OUT 1 RET ;************************************************************** ;PARM2 READ 2 PARAMETERS 16 BITS EACH INTO H,L AND D,E ;************************************************************** PARM2 CALL IHEX MOV D,H MOV E,L CPI 0AH ;TERMINATED? RZ ;YES,USE SAME VALUE CPI ',' JZ PARM3 CPI ' ' RNZ ;INVALID PARM3 XCHG CALL IHEX ;GET SECOND PARM XCHG RET ;************************************************************** ;INPUT CHARS ASSUMED HEX AND CONVERT TO BINARY ;TERMINATES ON FIRST NO HEX CHAR WHICH IS LEFT ;IN A REG. H,L RETURNS WITH VALUE ;************************************************************** IHEX LXI H,0 IHEX2 CALL CHIN ;READ CHAR PUSH A CALL ASBI ;CONVERT TO BIBARY JNC IHEX1 POP A RET IHEX1 DAD H DAD H DAD H DAD H ;ADD NEW DIGIT Š ADD L MOV L,A POP A JMP IHEX2 ;************************************************************** ;CONVERT ASCII HEX CHAR IN A-REG TO BINARY IN A REG ;RETURN WITH CARRY SET IF INVALID CHAR,RESET OTHERWISE ;************************************************************** ASBI SUI 30H ;REMOVE ASCII BIAS RC ;INVALID <0 CPI 10 JC ASBI1 ;VALID 0-9 SUI 17 RC ;INVALID ADI 10 CPI 16 ;SET CARRY IF <0FH ASBI1 CMC RET ;************************************************************** ;PRINT H,L AND 16 BIT MEMORY AT H,L ;************************************************************** SRCPNT CALL PNTMEM MOV A,M ;BYTE 2 SRCPNT1 CALL OHEX RET PNTMEM CALL CRLF PNTME1 DCX H ;BACK UP 1 CALL OHEXHL MOV A,M CALL OHEXB INX H RET ;************************************************************** ;OUTPUT HEX CHARS TO VIDIO FROM A REG ;************************************************************** OHEX PUSH PSW ;SAVE CHAR RRC RRC RRC RRC CALL BIAS ;BINARY TO ASCII AND OUT POP PSW CALL BIAS RET ;************************************************************** ;CONVERT BINARY TO ASCII ;************************************************************** BIAS ANI 0FH ;MASK NIBBLE ADI 90H DAA ACI 40H DAA CALL CHAROUT RET Š ;************************************************************** ;OUTPUT MESSAGE PTED TO BY H,L AND TERMINATED ;BY ONE BYTE OF BINARY ZEROS ;************************************************************** MSG CALL CRLF MSGNC MOV A,M ORA A RZ CALL CHAROUT INX H JMP MSGNC CMDTBL EQU $ DB 1BH ;ESCAPE CODE DW ESCAP DB 'C' ;CALL MEMORY WITH RETURN DW CALL1 DB 'D' ;DISPLAY MEMORY DW DISP DB 'E' ;ENTER INTO MEMORY DW ENTR DB 'F' ;FILL MEMORY DW FILL DB 'H' ;INTEL HEX LOADS DW INTEL DB 'I' ;INPUT FROM SPECIFIED PORT DW INPORT DB 'J' ;JUMP TO ADDRESS DW JUMP DB 'M' ;MOVE MEMORY BLOCK DW MOVE DB 'O' ;OUTPUT TO SPECIFIED PORT DW OUTPORT DB 'R' ;FREE RAM LOCATION DW RAMFND DB 'S' ;16 BIT MASKED SEARCH DW SEARCH DB 'T' ;TEST MEMORY DW MEMTEST DB 'V' ;COMPARE MEMORY BLOCKS DW CMPBLK DB 0 END