TITLE DPYPAK -- VIDEO DISPLAY PACKAGE SUBTTL C.D. OTOOLE/CDO 16-APR-80 ;*** COPYRIGHT (C) 1977, 1978, 1979, 1980, ; DIGITAL EQUIPMENT CORP., MARLBORO, MASS. *** SALL ;CLEAN UP LISTING SYN IFE,IF ;DEFINE NEW PSEUDO OP FOR PRETTY CONDITIONALS IFNDEF TOPS, ;BUILD TOPS10 DPYPAK ;DEFINE SOME AC'S FIRST CHAR==0 ;CHARACTER HOLDER ( NEED NOT BE SAVED ) SCR==CHAR+1 ;A SCRATCH REG ( NEED NOT BE SAVED ) TYP==6 ;TYPE OF TERMINAL FOR CONTROL INDEX CUR==7 ;CURRENT POSITION ON SCREEN NEW==10 ;NEW DISPLAY ARRAY OLD==11 ;OLD DISPLAY ARRAY NL==12 ;LINE CURRENTLY EXAMINING NC==13 ;COLUMN " " POSL==14 ;LINE OF CURSOR POSC==15 ;COLUMN " " ARGS==16 ;DPSS ARGUMENT POINTER P==17 ;A PUSH-DOWN LIST IF TOPS-10,< ;TERMINAL SUPPORT DESIRED (TYPES FROM TRMOP. .TOTRM) %VT05== %VT06== %VT50== %VT52== %VT100== TTYBYT==7 ;7 BIT BYTES TTYCPW==5 ;5 CHARACTERS PER WORD TTYFIL==177 ;CHARACTER USED FOR FILLER ;TRMOP. FUNCTIONS .TOSET==1000 ;ADDON TO SET RATHER THAN READ .TONFC==1010 ;NO FREE CRLF .TOPSZ==1023 ;PAGE SIZE .TOTSP==1031 ;TRANSMIT SPEED .TOTRM==1041 ;TERMINAL TYPE > ;END IF TOPS-10 IF TOPS-20,< ;TERMINAL SUPPORT DESIRED (TYPES FROM GTTYP) %VT05==12 %VT50==13 %VT52==17 %VT100==20 TTYBYT==8 ;8 BIT BYTES TTYCPW==4 ;4 CHARACTERS PER WORD TTYFIL==200 ;CHARACTER USED FOR FILL .MORSP==27 ;MTOPR - RETURN BAUD RATES .PRIOU==101 ;PRIMARY OUTPUT JFN ;JSYS DEFINITIONS OPDEF JSYS [104000,,0] OPDEF GTJFN [JSYS 20] OPDEF OPENF [JSYS 21] OPDEF SOUT [JSYS 53] OPDEF PSOUT [JSYS 76] OPDEF MTOPR [JSYS 77] OPDEF DISMS [JSYS 167] OPDEF HALTF [JSYS 170] OPDEF GTTYP [JSYS 303] OPDEF SFPOS [JSYS 526] > ;END IF TOPS-20 ;ENTRY POINTS IN DPYPAK ; DPYINI INITIALIZE A SCREEN FOR A TERMINAL TYPE ; DPYCLR FORCE A REFRESH CYCLE NEXT TIME THROUGH "DPYOUT" ; DPYREF FORCE A REFRESH NOW ; DPYZAP CLEAR SCREEN NOW (ERASE) ; DPYWAT WAIT FOR READER TO SEE THE SCREEN ; DPYLSH SHIFT LEFT JUSTIFIED CHARACTER TO RIGHT JUSTIFIED ; DPYROL SCROLL THE SCREEN ( SEE "RACE" ) ; DPYSIZ RETURN MAX COLUMN AND MAX LINE NUMBERS ; DPYCHR PUT A SINGLE CHARACTER ON THE SCREEN ; DPYCRM SAME AS DPYCHR BUT REMEMBERS WHERE CURSOR WAS LEFT ; DPYOUT MAKE A SCREEN CHANGE ; DPYREM SAME AS DPYOUT BUT REMEMBERS WHERE CURSOR WAS LEFT ; DPYSEC OUTPUT A SCREEN SECTION ; DPYRSC SAVE AS DPYSEC BUT REMEMBERS WHERE CURSOR WAS LEFT ; DPYCSC CLEAR A SCREEN SECTION ; DPYSAV RETURN THE CURRENT SCREEN CONTENTS ; DPYRST RESTORE SCREEN ( OUTPUT FROM DPYSAV ) ; DPYCRM, DPYREM, AND DPYRSC ARE USED WHEN ONLY A SMALL NUMBER OF THINGS ; CHANGE AND SAVES LOTS OF CURSOR MOVEMENTS ( SEE "PONG" ). ; HOWEVER, CALLER GUARANTEES THAT HE DIDN'T MOVE IT BETWEEN ; CALLS. ( LIKE SET NO ECHO ON TERMINAL ) ;TERMINAL SPECIFICS ;ARGUMENTS ARE: ; NAME name of the terminal ; LINES number of lines on the screen ; COLUMNS number of columns ; HOME encoded character for cursor home ; ERSEOL " " " " erase-to-end-of-line ; ERSEOS " " " " erase-to-end-of-screen ; DIRADR " " " " enter direct addressing mode ; TRANSL instruction to execute to convert line/column to commands ; CURUP encoded character for cursor up ; CURLEFT " " " " left ; REVLF " " " " reverse line feed (scroll backwards) ; CURDOWN " " " " down ; FOR CONTROL SEQUENCES, CHARACTER IS ENCODED AS FOLLOWS ; CHAR < 0 ;EXTRA SPECIAL HANDLING FOR THIS SEQUENCE ;CURRENTLY ONLY USED FOR CURSOR ADDRESSING: ;IF POSITIVE, TERMINAL WANTS LINE# THEN COLUMN# ;IF NEGATIVE, TERMINAL WANTS COLUMN# THEN LINE# ; 0 ;TERMINAL CAN'T DO THIS FUNCTION ; 0 < CHAR < 177 ;ONLY NEED CHARACTER ; 1000 < CHAR < 1777 ;CHARACTER THEN FILLERS ; 2000 < CHAR < 2777 ;FILLERS THEN CHARACTER ; 3000 < CHAR < 3777 ;ESCAPE CHARACTER ; 4000 < CHAR < 4777 ;ESCAPE, "[", CHARACTER (VT100) DEFINE DPYTYP,< TRMNAL (VT05,^D20,^D72,1035,1036,1037,16,,1032,10,0,1012) TRMNAL (VT06,^D25,^D72,1035,1036,1037,0,0,2032,2010,0,12) TRMNAL (VT50,^D12,^D80,3110,3113,3112,0,0,3101,10,0,12) TRMNAL (VT52,^D24,^D80,3110,3113,3112,3131,,3101,10,3111,12) TRMNAL (VT100,^D24,^D80,4110,4113,4112,4000,0,4101,10,3115,12) TRMNAL (DM,^D24,^D80,2,27,0,-14,,32,10,0,12) TRMNAL (TEC,^D24,^D80,151,143,163,-154,,170,167,0,150) TRMNAL (IMLAC,^D40,^D80,3,20,13,-1,,4,10,0,12) > ;END OF DEFINED TERMINAL TYPES DOFILL==0 ;ASSUME NO TERMINALS NEED FILLERS DEFINE CONTRL(CHAR),< ..B35==0 ..T0==CHAR IFL ..T0,<..B35==1 ..T0==-..T0> ..T1==..T0&177 ..T2==..T0-..T1 IFE ..T2,<..ANS==> IFE ..T2-1000,> IFE ..T2-2000,> IFE ..T2-3000,<..ANS==> IFE ..T2-4000,<..ANS==> EXP <..ANS!..B35> > ;END OF CONTRL DEFINE TRMNAL(A,B,C,D,E,F,G,INS,H,I,J,K), >> TYPNAM: DPYTYP MAXTYP==.-TYPNAM DEFINE TRMNAL(A,B,C,D,E,F,G,INS,H,I,J,K),> TYPTAB: DPYTYP DEFINE TRMNAL(A,B,C,D,E,F,G,INS,H,I,J,K),, EXP B>> NLMAX==0 ;PRIME COUNTER FOR MAXIMUM LINES NLINES: DPYTYP DEFINE TRMNAL(A,B,C,D,E,F,G,INS,H,I,J,K),> NCMAX==^D80 ;CAN'T REALLY CHANGE THIS WITHOUT BREAKING LOTS OF OLD PROGRAMS WDPLIN== NCOLS: DPYTYP DEFINE TRMNAL(A,B,C,D,E,F,G,INS,H,I,J,K),> HOMEUP: DPYTYP DEFINE TRMNAL(A,B,C,D,E,F,G,INS,H,I,J,K),> ERAEOL: DPYTYP DEFINE TRMNAL(A,B,C,D,E,F,G,INS,H,I,J,K),> ERAEOS: DPYTYP DEFINE TRMNAL(A,B,C,D,E,F,G,INS,H,I,J,K),> REVDIR==0 ;ASSUME NO TERMINALS WANT X,Y REVERSED DIRADR: DPYTYP DEFINE TRMNAL(A,B,C,D,E,F,G,INS,H,I,J,K),> COMPXY: DPYTYP DEFINE TRMNAL(A,B,C,D,E,F,G,INS,H,I,J,K),> CURUP: DPYTYP DEFINE TRMNAL(A,B,C,D,E,F,G,INS,H,I,J,K),> CLEFT: DPYTYP DEFINE TRMNAL(A,B,C,D,E,F,G,INS,H,I,J,K),> REVLF: DPYTYP DEFINE TRMNAL(A,B,C,D,E,F,G,INS,H,I,J,K),> LINEFD: DPYTYP ;ENTRY TO INITIALIZE A DISPLAY.. ; ; CALL DPYINI(BYTE-SIZE,TERMINAL-TYPE) ; ;TERMINAL-TYPE IS ASCII NAME OF A SUPPORTED TERMINAL (VT05,VT06) ; IF DPYPAK CAN FIGURE OUT WHAT KIND OF TERMINAL (TOPS20 OR 7.01) ; IT WILL OVER RIDE CALLERS ARGUMENT AND RETURN TYPE (SEE BELOW) ;BYTE-SIZE IS 7 FOR ENCODE'ED ARRAYS ( "DIMENSION ARRAY(16,25)" ) ; IS 36 FOR RIGHT JUSTIFIED CHARACTERS ( "DIMENSION ARRAY(80,25)" ) ; IS <0 FOR LEFT JUSTIFIED CHARACTERS ( "DIMENSION ARRAY(80,25)" ) ; BUT READ WITH A1 FORMAT ( AVOID DPYLSH ) ;CALLER MUST ACCOUNT FOR ALL 80 POSSIBLE COLUMNS (EVEN IF ONLY 72 FOR TERMINAL) ; ALTHOUGH THAT'S NOT TRUE FOR LINES. E.G. FOR A VT05 SPECIFIC PROGRAM ; USE "DIMENSION ARRAY(80,20)" OR "DIMENSION ARRAY(16,20)" ;DPYINI CAN ALSO BE CALLED AS A FUNCTION RATHER THAN A SUBROUTINE ; ; FOO = DPYINI ( SAME-ARGUMENTS-AS-OTHER-CALL ) ; ;FOO GETS THE TERMINAL ACTUALLY USED (ASCII) OR -1 IF IT WAS INVALID DPYINI:: MOVE CHAR,@0(ARGS) ;GET BYTE SIZE ( 7 OR 36 ) JUMPLE CHAR,[MOVEI CHAR,^D36 ;NEGATIVE IS LEFT JUSTIFIED ARRAY SETOM LJUST ;REMEMBER THAT JRST .+1] ;RESUME IN LINE CODE DPB CHAR,[POINT 6,NEWPTR,11] ;INSERT INTO ARRAY BYTE POINTER PUSHJ P,DPYCLR ;CLEAR THE INTERNAL BUFFER PUSHJ P,GETTYP ;TRY TO FIGURE OUT TERMINAL TYPE MOVE CHAR,@1(ARGS) ;GET TERMINAL TYPE SKIPE SCR ;DO I KNOW IT FROM GETTYP MOVE CHAR,SCR ;YES, OVERRIDE CALLER MOVSI SCR,-MAXTYP ;FORM AOBJN FOR KNOWN TYPES CAME CHAR,TYPNAM(SCR);FOUND IT AOBJN SCR,.-1 ;NO, TRY AGAIN JUMPGE SCR,[SETOB CHAR,VIDEOT ;DIDN'T FIND ONE, RETURN -1, ZAP TYPE POPJ P,] ;AND RETURN HRRZM SCR,VIDEOT ;REMEMBER VIDEO TERMINAL TYPE JRST SETINI ;SET INITIAL TERMINAL CHARACTERISTICS ;ENTRY TO RETURN SCREEN SIZES ; ; CALL DPYSIZ(MAX-COLUMN,MAX-LINE) ; ;SIMPLY RETURNS THOSE VALUES DPYSIZ:: JSP CHAR,SAVREG ;REALLY FOR EVER INITIALIZED CHECK MOVE CHAR,NCOLS(TYP) ;MAXIMUM COLUMN NUMBER FOR THIS TYPE MOVEM CHAR,@0(ARGS) ;STORE FOR USER MOVE CHAR,NLINES(TYP) ;MAXIMUM LINE NUMBER MOVEM CHAR,@1(ARGS) ;SO CALLER CAN FIND END OF SCREEN FOR DPYCHR JSP CHAR,RESREG ;RESTORE REGS POPJ P, ;ALL DONE ;ENTRY TO ALLOW CALLER TO FORCE A REFRESH OF THE ENTIRE SCREEN.. ; ; CALL DPYCLR DPYCLR:: SETZM SCREEN ;CLEAR CURRENT SCREEN DPYCL1: MOVE CHAR,[SCREEN,,SCREEN+1] ;THE ENTIRE SCREEN BLT CHAR,ENDSCR ;TO THE END OF THE SCREEN POPJ P, ;RETURN, WE'LL CLEAR ON NEXT SWEEP ;ENTRY TO ALLOW WATCHER TO READ THE SCREEN.. ; ; CALL DPYWAT(NUMBER-OF-SECONDS) ; IF NUMBER-OF-SECONDS .GT. 60 THEN ITS NUMBER-OF-MILLISECONDS ; ;SIMPLY SLEEPS FOR THAT MANY SECONDS DPYW.1: SKIPA SCR,[^D500] ;1.5 SECONDS DPYWAT:: MOVE SCR,@0(ARGS) ;GET TIMER CAIG SCR,^D60 ;SECONDS OR MILLISECONDS IMULI SCR,^D1000 ;CONVERT SECONDS TO MILLISECONDS IF TOPS-10,< HIBER SCR, ;WAIT THE SPECIFIED AMOUNT JFCL ;IGNORE FAILURE > ;END OF IF TOPS-10 IF TOPS-20, ;WAIT THE SPECIFIED AMOUNT POPJ P, ;THEN RETURN ;ENTRY TO FORCE CLEAR OF ENTIRE SCREEN ( REAL CLEAR, NOT REFRESH ).. ; ; CALL DPYZAP DPYZAP:: MOVE CHAR,[ASCII/ /] ;LOAD BLANKS MOVEM CHAR,SCREEN ;STORE THE BLANKS PUSHJ P,DPYCL1 ;NOW BLT ENTIRE ARRAY JSP CHAR,SAVREG ;SAVE CALLERS REGISTERS PUSHJ P,HOME ;SEND HOME SEQUENCE SKIPE ERAEOS(TYP) ;CAN THE TERMINAL ERASE TO END OF SCREEN JRST [MOVEI CHAR,ERAEOS(TYP) ;YES, GET ERASE SEQUENCE PUSHJ P,PUTCTL ;OUTPUT IT JRST FORGET] ;FORCE OUT, FORGET TRACKS, RETURN MOVEI NC,1 ;WANT TO GET TO COLUMN 1 MOVEI NL,1 ;ON LINE 1 PUSHJ P,ERSLIN ;ERASE LINE N, INCREMENT TO NEXT CAMG NL,NLINES(TYP) ;OFF THE END OF THE SCREEN JRST .-2 ;NO, CLEAR ANOTHER LINE JRST FORGET ;FORCE OUT, FORGET TRACKS, RETURN ;ENTRY TO CONVERT LEFT-JUSTIFIED CHARACTER TO RIGHT-JUSTIFIED BINARY ; ; BIN = DPYLSH(THING-READ-WITH-A1-FORMAT) DPYLSH:: MOVE CHAR,@0(ARGS) ;GET CHARACTER ( ASCII /X / ) LSH CHAR,-^D29 ;MOVE TO LOW 7 BITS POPJ P, ;RETURN WITH IT IN AC 0 ;ENTRY TO SCROLL THE SCREEN SO MANY LINES.. ; ; CALL DPYROL(NUMBER-OF-LINES-TO-ROLL) ; ;MOVES SCREEN FOR NEW OUTPUT ACCORDING TO SIGN OF NUMBER-OF-LINES-TO-ROLL ; IF POSITIVE, BRING IN "N" BLANK LINES ON THE BOTTOM OF THE SCREEN ; IF NEGATIVE, BRING IN "ABS(N)" BLANK LINES FROM THE TOP ; IF ZERO, WHY DID YOU CALL THIS ROUTINE DPYROL:: JSP CHAR,SAVREG ;SAVE CALLERS SKIPN NEW,@0(ARGS) ;ANY LINES TO ROLL JRST FORGET ;NO, RETURN PUSHJ P,GOHOME ;GOTO HOME POSITION (MAYBE) JUMPL NEW,ROL.03 ;GO IF ROLLING BACKWARDS MOVE NL,NLINES(TYP) ;FIND LAST LINE OF THIS SCREEN IMULI NL,WDPLIN ;FIRST WORD NOT INVOLVED IN THE MOVE MOVE OLD,NEW ;NUMBER OF LINES TO ROLL IMULI OLD,WDPLIN ;COMPUTE NEW TOP OF SCREEN ADDI OLD,SCREEN ;... HRL CHAR,OLD ;SOURCE = NEW HOME POSITION HRRI CHAR,SCREEN ;DESTINATION = HOME IN INTERNAL SCREEN MOVNS OLD ;COMPUTE LAST COLUMNS TO APPEAR ON NEW SCREEN ADDI OLD,SCREEN-1(NL) ;... JUMPLE OLD,[JSP CHAR,RESREG ;ROLLING ENOUGH TO ACTUALLY CLEAR SCREEN JRST DPYZAP] ;SO ZAP IT INSTEAD BLT CHAR,SCREEN(OLD) ;MOVE THE NEW SCREEN TO HOME POSITION MOVE CHAR,[ASCII/ /] ;LOAD SOME BLANKS MOVEM CHAR,SCREEN+1(OLD) ;CLEAR LINES ROLLED UP HRLI CHAR,SCREEN+1(OLD) ;SET UP FOR BLT HRRI CHAR,SCREEN+2(OLD) ;... BLT CHAR,SCREEN-1(NL) ;CLEAR IT ALL MOVE NL,NLINES(TYP) ;WHERE TO START ROLLING FROM PUSH P,LINEFD(TYP) ;CONTROL SEQUENCE TO USE ;COMMON RETURN POINT FOR FORWARD OR BACKWARD SCROLL ROL.01: MOVEI NC,1 ;WANT COLUMN 1 PUSHJ P,CURMOV ;GET TO CORRECT POSITION ROL.02: MOVEI CHAR,0(P) ;SAVED CONTROL SEQUENCE PUSHJ P,PUTCTL ;OUTPUT THAT SOJG NEW,ROL.02 ;CONTINUE FOR ALL LINES POP P,(P) ;CLEAN STACK JRST FORGET ;FORGET TRACKS, RETURN ;HERE IF ROLLING BACKWARDS ROL.03: MOVE OLD,NEW ;GET - NUMBER OF LINES TO ROLL IMULI OLD,WDPLIN ;COMPUTE NEW LOWER RIGHT CORNER ADDI OLD,ENDSCR ;... CAIGE OLD,SCREEN ;HOW FAR ARE WE BACKING UP JRST [JSP CHAR,RESREG ;ENOUGH TO ACTUALLY CLEAR THE SCREEN JRST DPYZAP] ;SO ZAP THE SCREEN INSTEAD MOVEI NL,ENDSCR ;LOWER RIGHT IN INCORE SCREEN ROL.04: CAIGE NL,SCREEN ;OFF THE TOP OF THE SCREEN YET JRST ROL.05 ;YES, DONE MOVING THE INCORE SCREEN CAIL OLD,SCREEN ;STILL USING REAL DATA SKIPA SCR,0(OLD) ;YES, GET SCREEN CONTENTS MOVE SCR,[ASCII/ /] ;NO, BRING BLANKS IN ON THE TOP LINES MOVEM SCR,0(NL) ;RIPPLE DATA DOWN SOS OLD ;STEP DOWN TO NEXT LOCATION SOJA NL,ROL.04 ;GET THE ENTIRE SCREEN ROL.05: SKIPN SCR,REVLF(TYP) ;CAN TERMINAL REVERSE SCROLL JRST [JSP CHAR,RESREG ;NO, RESTORE CALLERS REGISTERS JRST DPYREF] ;AND REFRESH FROM INTERNAL SCREEN PUSH P,SCR ;SAVE CONTROL SEQUENCE FOR REVERSE LF MOVMS NEW ;NUMBER OF LINES TO ROLL MOVEI NL,1 ;STARTING AT HOME POSITION JRST ROL.01 ;SCROLL, RETURN ;ENTRY TO PLACE A SINGLE RIGHT JUSTIFIED CHARACTER ON THE SCREEN ; ; CALL DPYCHR(RIGHT-JUSTIFIED-CHAR,COLUMN-DESIRED,LINE-DESIRED) ; ;LEAVES CURSOR TO THE RIGHT ( 1 COLUMN ) OF THE POSITION SPECIFIED ; UNLESS CHARACTER.LT.0 ( IN 36 BITS ) THEN CURSOR IS AT THE POSITION ;DPYCRM REMEMBERS THAT FACT FOR LATER USE DPYCRM:: SETOM REMEMB ;MARK REMEMBERING DPYCHR:: JSP CHAR,SAVREG ;SAVE CALLERS REGISTERS SKIPLE NC,@1(ARGS) ;GET COLUMN DESIRED, RANGE CHECK IT CAMLE NC,NCOLS(TYP) ;... JRST FORGET ;INVALID, RETURN SKIPLE NL,@2(ARGS) ;DO THE SAME FOR NEW LINE CAMLE NL,NLINES(TYP) ;... JRST FORGET ;THAT'S INVALID PUSHJ P,GOHOME ;MOVE TO HOME POSITION (MAYBE) PUSHJ P,CURMOV ;MOVE TO NEW POSITION PUSHJ P,SETCUR ;COMPUTE BYTE POINTER TO SCREEN MOVE CHAR,@0(ARGS) ;GET DISPLAY CHARACTER JUMPL CHAR,CHRRET ;QUIT NOW IF JUST POSITION WITH NO DATA CAIGE CHAR," " ;A CONTROL CHARACTER MOVEI CHAR," " ;YES, CONVERT TO A BLANK IDPB CHAR,CUR ;STORE INTO CURRENT SCREEN PUSHJ P,DPYPUT ;TYPE IT OUT AOS POSC ;ACCOUNT FOR TYPEOUT CHRRET: SKIPN REMEMB ;WANT TO REMEMBER WE LEFT IT HERE JRST FORGET ;NO, FORGET TRACKS JRST FRCRET ;YES, JUST RETURN ;ENTRY TO CLEAR A SELECTED SECTION OF THE SCREEN ; ; CALL DPYCSC(1ST-COL,1ST-LINE,END-COL,END-LINE) ; ;FAKES OUT A CALL TO DPYSEC DPYCSC:: SETOM CLRING ;MARK CLEARING THE SECTION SOS ARGS ;ARGS ARE IN SAME ORDER AS DPYSEC BUT PUSHJ P,DPYSEC ; OFF BY ONE SETZM CLRING ;MAKE OTHER ENTRIES WORK AGAIN AOJA ARGS,CPOPJ ;JUST FOR GRINS, PUT ARGS BACK AGAIN ;ENTRIES TO SAVE/RESTORE A SCREEN.. ; ; CALL DPYSAV(HOLDING-ARRAY) ; CALL DPYRST(THAT-SAME-ARRAY) ; ;THESE ENTRIES ARE USEFUL WHEN CALLER REALLY WANTS TO "PUSH" A SCREEN, FLASH ; SOME OTHER OUTPUT, AND THEN "POP" THE OLD ONE. ESPECIALLY USEFUL WHEN ; CURRENT SCREEN HAS BEEN FILLED WITH DATA THAT IS NOT EASILY RE-CONSTRUCTED ; ( USED "DPYSEC" TO DO LINE AT A TIME OUTPUT OF "ENCODE"D DATA ) ; ; CALLERS ARRAY MUST BE LARGE ENOUGH TO CONTAIN THE SCREEN FOR THE ; TERMINAL TYPE THAT IS CURRENTLY BEING USED. 400 (DECIMAL) WORDS IS ; SAFE FOR DEC TERMINALS AND MOST OTHERS BUT SOME HAVE MORE THAT 25 LINES ; AND REQUIRE MORE SPACE. CAVEAT: THE ARRAY IS NOT CHECKED AS TO LENGTH. DPYSAV:: JSP CHAR,SAVREG ;SAVE REGS, GET TYPE HRLI CHAR,SCREEN ;SOURCE = CURRENT SCREEN HRRI CHAR,@0(ARGS) ;DESTINATION = USERS ARRAY MOVE SCR,NLINES(TYP) ;NUMBER OF LINES ON THE SCREEN IMULI SCR,WDPLIN ;NUMBER OF WORDS NEEDED ADDI SCR,@0(ARGS) ;PLUS ARRAY START BLT CHAR,-1(SCR) ;MOVE TO CALLERS BUFFER JSP CHAR,RESREG ;PUT THE REGS BACK POPJ P, ;RETURN NOW DPYRST:: PUSH P,NEWPTR ;SAVE CURRENT BYTE POINTER INFO PUSH P,LJUST ;AND JUSTIFICATION FLAG MOVSI CHAR,(POINT 7,0) ;GET NEW BYTE POINTER MOVEM CHAR,NEWPTR ;FAKE OUT DPYOUT SETZM LJUST ;... PUSHJ P,DPYOUT ;FLASH THE SCREEN BACK POP P,LJUST ;RESTORE ORIGINAL PARAMETERS POP P,NEWPTR ;... POPJ P, ;ENTRY TO FORCE A REFRESH OF THE SCREEN RIGHT NOW USING THE CURRENT ; SCREEN CONTENTS. BETTER THAN CALLING "DPYCLR" THEN "DPYOUT" OF SCREEN ; OR "DPYSAV", "DPYCLR", "DPYRST". ; ; CALL DPYREF DPYREF:: SETOM REFING ;MARK REFRESHING PUSH P,ARGS ;SAVE CALLERS MOVEI ARGS,[Z SCREEN] ;ARGUMENT IS OLD SCREEN PUSHJ P,DPYRST ;PRETEND THIS IS A RESTORE POP P,ARGS ;RESTORE CALLERS SETZM REFING ;CLEAR FLAG POPJ P, ;RETURN ;ENTRY TO DISPLAY A SCREEN SECTION.. ; ; CALL DPYSEC(NEW-SECTION-ARRAY,1ST-COL,1ST-LINE,END-COL,END-LINE) ; ;THIS ENTRY IS USED TO PARTITION A SCREEN INTO MANY RECTANGULAR SECTIONS. ; THE BOX DEFINED BY THE LAST 4 ARGUMENTS WILL BE THE ONLY SECTION OF THE ; SCREEN AFFECTED. SEE THE SIZE DEFINITIONS IN "DPYINI" AND NOTE THE ; FOLLOWING RESTRICTION. THE NUMBER OF COLUMNS THAT MUST BE ALLOCATED IN ; THE SECTION ARRAY MUST ACCOUNT FOR FULL WORD ALIGNMENT OF THE NEXT ; LINE TO BE DISPLAYED EVEN THOUGH THE DISPLAY WILL STOP AT THE MARGIN ; DEFINED BY "END-COL". AN EXAMPLE: ; ; CALL DPYINI(7,TTTYPE) ;USE ASCII DATA ; CALL DPYSEC(ARRAY,6,2,13,5) ;DISPLAY 8-COL BY 4-LINE AREA ; ; THE ARRAY DIMENSION MUST BE (2,4) . NOTICE 2 FULL WORDS ARE 10 CHARS ; BUT ONLY 8 WILL BE DISPLAYED. ;ENTER AT DPYRSC TO LEAVE CURSOR AT LAST POSITION AND REMEMBER THAT DPYRSC:: SETOM REMEMB ;MARK REMEMBERING DPYSEC:: JSP CHAR,SAVREG ;SAVE CALLERS SETZM BOUNDS ;DPYOUT MUST RESET ITS BOUNDRIES SKIPLE NC,@1(ARGS) ;GET 1ST-COLUMN CAMLE NC,NCOLS(TYP) ;RANGE CHECK IT JRST FORGET ;BAD ARGUMENT MOVEM NC,NCPRIM ;SAVE STARTING COLUMN NUMBER SKIPLE NL,@2(ARGS) ;GET 1ST-LINE CAMLE NL,NLINES(TYP) ;RANGE CHECK THIS TOO JRST FORGET ;ANOTHER BAD ARGUMENT MOVEM NL,NLPRIM ;SAVE STARTING LINE NUMBER MOVE CUR,@3(ARGS) ;GET END COLUMN MOVE OLD,@4(ARGS) ;AND END LINE CAML CUR,NC ;END .LT. BEGINNING CAILE CUR,NCMAX ;BEYOND LEGAL VAULE JRST FORGET ;STRANGE REQUEST CAMLE OLD,NLINES(TYP) ;DON'T DISPLAY OFF THE BOTTOM MOVE OLD,NLINES(TYP) ;SET LOWER MARGIN MOVEM OLD,NLEND ;STORE LOWER BOUND MOVE OLD,NCOLS(TYP) ;GET RIGHT MARGIN FOR THIS TERMINAL CAMGE CUR,OLD ;END COLUMN INVISIBLE MOVE OLD,CUR ;NO, USE IT MOVEM OLD,NCEND ;STORE RIGHT MARGIN LDB SCR,[POINT 6,NEWPTR,11] ;FETCH SIZE FROM DPYINI MOVEI NEW,^D36 ;COMPUTE BYTES PER WORD IDIVI NEW,(SCR) ;FOR WORD ALIGNMENT OF LINES MOVE CHAR,CUR ;COPY FOR LATER DIVIDES SUB CHAR,NC ;COMPUTE NUMBER OF COLUMNS REQUESTED ADDI CHAR,(NEW) ;ROUND UP IDIVI CHAR,(NEW) ;NUMBER OF FULL WORDS NEEDED IMULI CHAR,(NEW) ;BACK TO NUMBER OF CHARACTERS SOS CHAR ;NOW COMPUTE END COLUMN ADD CHAR,NCPRIM ;AS START+NUMBER OF COLUMNS-1 MOVEM CHAR,ENDUSR ;... JRST DPYO.1 ;ENTER DPYOUT FOR THE REST ;ENTRY TO DISPLAY A CHANGING SCREEN.. ; ; CALL DPYOUT(NEW-SCREEN-ARRAY) ; ;SEE SIZE DEFINITIONS FOR "DPYINI" ;ENTER AT DPYREM TO LEAVE CURSOR AT LAST POSITION AND REMEMBER THAT DPYREM:: SETOM REMEMB ;MARK REMEMBERING DPYOUT:: JSP CHAR,SAVREG ;SAVE CALLERS REGISTERS SKIPE BOUNDS ;BOUNDRIES SET UP JRST DPYO.1 ;YES, NO NEED TO DO IT TWICE MOVEI CHAR,1 ;GET A 1 MOVEM CHAR,NLPRIM ;AS 1ST LINE OF SWEEP MOVEM CHAR,NCPRIM ;AS 1ST COLUMN MOVE CHAR,NLINES(TYP);GET LOWER BOUND MOVEM CHAR,NLEND ;MARK END MOVE CHAR,NCOLS(TYP) ;GET RIGHT BOUNDARY MOVEM CHAR,NCEND ;MARK IT MOVEI CHAR,NCMAX ;HIGHEST COLUMN REPRESENTED BY USERS ARRAY MOVEM CHAR,ENDUSR ;FOR KEEPING BYTE POINTERS STRAIGHT SETOM BOUNDS ;FLAG BOUNDS ARE SET NOW DPYO.1: HLL NEW,NEWPTR ;INSERT SIZE AND POSITION FOR BYTE POINTER SKIPE CLRING ;CLEARING THE SPECIFIED SECTION TDZA NEW,NEW ;YES, GENERATE A NULL BYTE POINTER HRRI NEW,@0(ARGS) ;POINT TO NEW SCREEN PUSHJ P,GOHOME ;MAYBE SET TO HOME POSITION ;START OUTER ( PER LINE ) LOOP MOVE NL,NLPRIM ;GET 1ST LINE OF SWEEP MOVEI NC,1 ;SET COLUMN TO 1 FOR FIXOLD PUSHJ P,FIXOLD ;SET "OLD" CORRECTLY M1: SKIPE WHERA ;IS AN ERASE TO END OF LINE POSSIBLE PUSHJ P,CLRLIN ;YES, TRY TO CLEAR IT NOW CAMLE NL,NLEND ;OFF THE BOTTOM OF THE SCREEN JRST REMRET ;YES, ALL DONE WITH THE SWEEP ;START INNER ( PER COLUMN ) LOOP M1.1: MOVE NC,NCPRIM ;GET 1ST COLUMN OF SWEEP CAIE NC,1 ;STARTING AT THE LEFT MARGIN PUSHJ P,FIXOLD ;NO, BYTE POINTER MUST BE RE-COMPUTED M2: CAILE NC,NCMAX ;OFF THE RIGHT HAND SIDE AOJA NL,M1 ;YES, GO TO NEXT LINE CAMG NC,ENDUSR ;OFF THE EDGE OF THE USERS ARRAY ILDB CHAR,NEW ;NO, GET NEW CHARACTER SKIPE LJUST ;LEFT JUSTIFIED A1 FORMAT LSH CHAR,-^D29 ;YES, MOVE IT OVER ANDI CHAR,177 ;DOWN TO ASCII ILDB SCR,OLD ;AND CURRENT SCREEN ENTRY SKIPE REFING ;DOING SCREEN REFRESH SETZ SCR, ;YES, OLD SCREEN CONTENTS = NULL CAMLE NC,NCEND ;OFF THE END OF THE DISPLAY MOVE CHAR,SCR ;YES, DISPLAY SELF TO KEEP POINTERS STRAIGHT CAIGE CHAR," " ;DISPLAYING A CONTROL CHARACTER MOVEI CHAR," " ;YES, TURN THEM INTO BLANKS CAIE CHAR," " ;SHOWING A BLANK JRST M2.1 ;NO, LOOK SOME MORE SKIPN WHERA ;ALREADY FIND FIRST BLANK MOVEM NC,WHERA ;REMEMBER FIRST BLANK CAIN SCR," " ;WAS COLUMN ALREADY BLANKED AOJA NC,M2 ;YES, TRY NEXT COLUMN DPB CHAR,OLD ;STORE INTO CURRENT SCREEN NOW SKIPN WHCHR ;THIS THE FIRST CHANGE TO A BLANK MOVEM NC,WHCHR ;REMEMBER FIRST CHANGE MOVEM NC,WHLST ;REMEMBER LAST CHANGE TO A BLANK TOO AOJA NC,M2 ;AND GO LOOK AT THE NEXT M2.1: SETZM WHERA ;CAN'T ERASE NOW SKIPN WHCHR ;DID A CHANGE TO A BLANK OCCUR JRST M2.2 ;NO, WE DON'T OWE IT ANY CHANGES PUSH P,NC ;SAVE CURRENT COLUMN MOVE NC,WHCHR ;GET WHERE THE FIRST CHANGE OCCURED PUSHJ P,CURMOV ;POSITION CURSOR THERE AOS NC,WHLST ;FIND BEYOND LAST CHANGE TO A BLANK SETOM FRCRTY ;FORCE RE-TYPE OF LINE PUSHJ P,CURMOV ;GET THERE BY RE-TYPING SETZM WHCHR ;AND NOW, NO CHANGES POP P,NC ;RESTORE CURRENT SKIPE REFING ;DOING A REFRESH CYCLE TDZA SCR,SCR ;YES, OLD SCREEN = A NULL LDB SCR,OLD ;GET OLD SCREEN CONTENTS BACK AFTER MOVING M2.2: CAMN CHAR,SCR ;DISPLAYING THE SAME CHARACTER AOJA NC,M2 ;YES, FORGET OUTPUT PUSHJ P,CURMOV ;MOVE FROM "POSL,POSC" TO "NL,NC" DPB CHAR,OLD ;STORE INTO CURRENT SCREEN NOW PUSHJ P,DPYPUT ;OUTPUT IT MOVE CUR,OLD ;REMEMBER WHERE WE ARE NOW AOS POSC ;AND ADJUST CURSOR POSITION AOJA NC,M2 ;AND GET NEXT COLUMN REMRET: SKIPN REMEMB ;WANT TO REMEMBER POSITION FORGET: SETO POSL, ;AND FORGET POSITION INFO FRCRET: SETZM REMEMB ;CLEAR REMEMBER FLAG JSP CHAR,RESREG ;RESTORE CALLERS REGISTERS SKIPN LINPTR ;AVOID OUTSTR IF NO CHANGES THIS SWEEP POPJ P, ;RETURN, NO OUTPUT TO DO FRCOUT: SETZM LINPTR ;CLEAR CURRENT LINE IN CORE IF TOPS-10, ;OUTPUT THE LINE BUFFER IF TOPS-20,< PUSH P,SCR ;SAVE CALLERS PUSH P,SCR+1 ;... PUSH P,SCR+2 ;... PUSH P,SCR+3 ;... MOVE SCR,TTYJFN ;IMAGE MODE OUTPUT JFN MOVE SCR+1,[POINT TTYBYT,LINBUF] SETZB SCR+2,SCR+3 ;STOP ON A NULL SOUT ;OUTPUT IT MOVE SCR+1,[1,,1] ;HACK FOR NOW, SET POS TO 1,,1 SFPOS ;EVENTUALLY I'LL SET TO WHERE CURSOR IS POP P,SCR+3 ;RESTORE CALLERS POP P,SCR+2 ;... POP P,SCR+1 ;... POP P,SCR ;... > ;END IF IF TOPS-20 CPOPJ: POPJ P, ;AND RETURN ;SUBROUTINE TO MOVE THE CURSOR ; ; POSL = LINE WHERE CURSOR IS ; POSC = COLUMN " " " ; ; NL = LINE WHERE WE WANT TO BE ; NC = COLUMN " " " " " CURMOV: PUSH P,CHAR ;SAVE CALLERS CHARACTER SKIPE FRCRTY ;FORCED TO RE-TYPE IN RIGHT MOVEMENT JRST [SETZM FRCRTY ;YES, CLEAR INDICATOR JRST MOV.3] ;AND MOVE IT ( ALREADY ON THE SAME LINE ) MOV.0: CAMN POSL,NL ;AT THE CORRECT LINE JRST MOV.1 ;YES, END OF VERTICAL POSITIONING SKIPE DIRADR(TYP) ;CAN TERMINAL DIRECT ADDRESS JRST MOVDIR ;YES, DO IT NOW SINCE NOT ON RIGHT LINE CAML POSL,NL ;MOVING UP JRST MOV.01 ;YES, DO THAT MOVEI CHAR,LINEFD(TYP);LINE FEED PUSHJ P,PUTCTL ;OUTPUT THE DOWN SEQUENCE TLO CUR,77 ;BYTE POINTER IS INVALID NOW AOJA POSL,MOV.0 ;ADJUST AND GET THE NEXT COLUMN MOV.01: MOVE SCR,POSL ;GET CURRENT POSITION SUB SCR,NL ;DIFFERENCE = NUMBER OF UP MOVES CAILE SCR,-1(NL) ;IS HOME POSITION CLOSER JRST [PUSHJ P,HOME ;GET TO THE HOME POSITION JRST MOV.0] ;NOW GOING THE OTHER WAY MOVEI CHAR,CURUP(TYP) ;GET UP SEQUENCE PUSHJ P,PUTCTL ;OUTPUT THAT TLO CUR,77 ;BYTE POINTER IS INVALID NOW SOJA POSL,MOV.0 ;CONTINUE MOVING MOV.1: CAMN POSC,NC ;AT THE CORRECT COLUMN JRST MOVEND ;YES, WE ARE THERE CAIN NC,1 ;WANT BACK AT THE LEFT MARGIN JRST MOV.2 ;YES, GO DO THAT NOW MOVE SCR,POSC ;GET CURRENT SUB SCR,NC ;HOW MANY AWAY FROM TARGET MOVMS SCR ;IGNORE SIGN PROBLEMS SKIPE DIRADR(TYP) ;CAN TERMINAL DIRECT CURSOR ADDRESS CAIG SCR,4 ;YES, BUT IS MOVEMENT SLIGHT SKIPA ;DO IT THE HARD WAY JRST MOVDIR ;GO DIRECT MOVE CAMGE NC,POSC ;WANT LEFT OF CURRENT CAMG SCR,NC ;AND CLOSER TO THE LEFT MARGIN JRST MOV.3 ;NO, CANNOT USE CARRIAGE RETURN MOV.2: MOVEI CHAR,15 ;A CARRIAGE RETURN PUSHJ P,DPYPUT ;OUTPUT IT TLO CUR,77 ;MARK UNKNOWN POSITION MOVEI POSC,1 ;NOW AT COLUMN 1 MOV.3: CAMLE POSC,NCOLS(TYP) ;BUMPED AGAINST THE RIGHT MARGIN JRST [MOVE POSC,NCOLS(TYP) ;YES, THEN WE ARE THERE TLO CUR,77 ;BYTE POINTER IS INVALID NOW JRST .+1] ;RESUME IN-LINE CODE MOVE SCR,POSC ;GET CURRENT COLUMN MOV.4: CAMG SCR,NC ;HIT SPOT YET JRST MOV.5 ;YES, NOW LOOK THE OTHER WAY MOVEI CHAR,CLEFT(TYP) ;GET CURSOR LEFT SEQUENCE PUSHJ P,PUTCTL ;OUTPUT THE STRING TLO CUR,77 ;MARK UNKNOWN POSITION MOVE POSC,NC ;IN CASE THIS IS THE LAST ITERATION SOJA SCR,MOV.4 ;DRIVE THIS LOOP BACKWARDS MOV.5: CAMN POSC,NC ;AT THE CORRECT SPOT JRST MOVEND ;YES, WE ARE FINALLY THERE TLNE CUR,77 ;BYTE POINTER CORRECT PUSHJ P,SETCUR ;NO, GO FIX IT ILDB CHAR,CUR ;GET WHAT IS ALREADY THERE PUSHJ P,DPYPUT ;OUTPUT IT AOJA POSC,MOV.5 ;AND CONTINUE MOVING RIGHT BY RE-TYPING MOVDIR: MOVEI CHAR,DIRADR(TYP);POINT TO ADDRESSING SEQUENCE PUSHJ P,PUTCTL ;OUTPUT START SEQUENCE IFDEF %VT100,< CAIN TYP,.VT100 ;VT100 TAKES ASCII CHARACTER POSITIONS JRST VT100M ;SO GO OUTPUT THEM > MOVEI CHAR,-1(NL) ;GET LINE NUMBER ( 0 TO NLINES-1 ) IFN REVDIR,< ;IF SOME TERMINAL WANTS COLUMN THEN LINE MOVE POSC,DIRADR(TYP);GET ADDRESSING SEQUENCE (BIT 35 IS FLAG) TRNE POSC,1 ;TERMINAL TAKE COLUMN FIRST MOVEI CHAR,-1(NC) ;YES, COLUMN INSTEAD > XCT COMPXY(TYP) ;COMPUTE CHARACTER FOR TERMINAL PUSHJ P,DPYPUT ;OUTPUT IT IFDEF %VT05,< ;IF SUPPORTING VT05'S CAIN TYP,.VT05 ;VT05 NEEDS SPECIAL HANDLING PUSHJ P,VT05FL ;OUTPUT NULLS FOR FILLER > MOVEI CHAR,-1(NC) ;GET COLUMN NUMBER ( 0 TO NCOLS-1 ) IFN REVDIR,< ;DOES SOMEBODY TAKE LINE SECOND TRNE POSC,1 ;TERMINAL WANT LINE LAST MOVEI CHAR,-1(NL) ;YES, GET LINE INSTEAD > XCT COMPXY(TYP) ;COMPUTE CHARACTER FOR TERMINAL MOVXIT: PUSHJ P,DPYPUT ;OUTPUT THAT MOVE POSC,NC ;RESET CURRENT POINTS MOVE POSL,NL ;... TLO CUR,77 ;BYTE POINTER IS NOW INVALID MOVEND: POP P,CHAR ;RESTORE CALLERS AFTER MOVING POPJ P, ;AND RETURN ;SUBROUTINE TO TRY AN ERASE TO END OF LINE CLRLIN: SOS NL ;ALWAYS CALLED FOR PREVIOUS LINE SETZ SCR, ;CLEAR A REG EXCH SCR,WHCHR ;ANYTHING GET TURNED INTO A BLANK JUMPE SCR,CLRL.2 ;NO, THEN NO NEED FOR ERASE MOVE NC,WHERA ;COLUMN WHERE FIRST BLANK APPEARED CAML NC,POSC ;FIRST BLANK RIGHT OF CURSOR JRST CLRL.1 ;YES, CLEAR FROM THERE CAML SCR,POSC ;FIRST CHANGE RIGHT OF CURSOR JRST [MOVE NC,POSC ;YES, JUST NEED TO MOVE DOWN JRST CLRL.1] ;GO CLEAR MOVE CHAR,POSC ;FIND CLOSEST POINT SUB CHAR,NC ;SAME AS MOV.1 CAMLE CHAR,NC ;WOULD BE CLOSER THAN BACKSPACE MOVE CHAR,NC ;YES, REMEMBER THAT MOVEM CHAR,WHERA ;STORE IN A TEMP FOR NOW MOVE CHAR,POSC ;WHERE DID FIRST CHANGE TO A BLANK OCCUR SUB CHAR,SCR ;AND WHERE WE ARE NOW MOVMS CHAR ;WANT .ABS. OF THAT CAMG CHAR,WHERA ;WHICH IS CLOSER TO CURRENT POINT MOVE NC,SCR ;FIRST BLANK CLRL.1: CAMLE NC,NCOLS(TYP) ;OFF THE RIGHT HAND SIDE ANYWAY JRST CLRL.2 ;YES, WON'T SEE IT ERSLIN: PUSHJ P,CURMOV ;MOVE THE CURSOR TO THE SPOT FOR ERASE MOVEI CHAR,ERAEOL(TYP);ERASE SEQUENCE PUSHJ P,PUTCTL ;OUTPUT CONTROL SEQUENCE CLRL.2: SETZM WHERA ;MARK CLEAR DONE AOJA NL,CPOPJ ;RESTORE THIS LINE AND RETURN ;SUBROUTINE TO BUILD BYTE POINTER TO REFLECT "POSL,POSC" SETCUR: MOVEI CHAR,-1(POSL) ;CURRENT LINE ON SCREEN IMULI CHAR,NCMAX ;COMPUTE DOUBLE SUBSCRIPT ADDI CHAR,-1(POSC) ;INCLUDE COLUMN IDIVI CHAR,5 ;NOW FIND CORRECT WORD AND BYTE MOVEI CUR,SCREEN ;BASE OF THE SCREEN ADD CUR,CHAR ;MOVE ENOUGH WORDS HLL CUR,CURPTR(SCR) ;AND INSERT POSITION INFORMATION POPJ P, ;RETURN FOR "ILDB/IDPB" ;SUBROUTINE TO SET "OLD" TO REFLECT "NL,NC" FIXOLD: MOVEI CHAR,-1(NL) ;SAME CODE AS SETCUR IMULI CHAR,NCMAX ; BUT CAN'T USE THAT SUBROUTINE ADDI CHAR,-1(NC) ; CAUSE I HAVE TO SAVE POSL,POSC IDIVI CHAR,5 ; AND IT WORKS OUT TO THE SAME NUMBER MOVEI OLD,SCREEN ; OF INSTRUCTIONS, SO..... ADD OLD,CHAR ;... HLL OLD,CURPTR(SCR) ;AT LEAST I CAN USE THE SAME TABLE POPJ P, ;SUBROUTINE TO OUTPUT CONTROL SEQUENCES TO TERMINALS ;SUBROUTINE TO PLACE CURSOR AT THE HOME POSITION ( MAYBE ) GOHOME: TLO CUR,77 ;BYTE POINTER IS INVALID JUMPG POSL,CPOPJ ;RETURN IF REMEMBERED POINT SKIPN DIRADR(TYP) ;CAN TERMINAL DIRECT ADDRESS JRST HOME ;NO, DO IT THE HARD WAY MOVEI POSL,^D32768 ;FOR DIRECT MOVEMENT IN CURMOV POPJ P, ;RETURN HOME: MOVEI POSL,1 ;CURSOR IS AT LINE 1 MOVEI POSC,1 ;COLUMN 1 MOVEI CHAR,HOMEUP(TYP);GOTO TOP OF SCREEN PUTCTL: HRLI CHAR,(POINT 7,0);INSERT BYTE INFO MOVEM CHAR,PUTPTR ;SAVE POINTER PUTC.1: ILDB CHAR,PUTPTR ;GET CHARACTER IN SEQUENCE JUMPE CHAR,CPOPJ ;STOP AT A NULL IFN DOFILL,< ;IF SOME TERMINAL NEEDS FILLERS CAIN CHAR,177 ;REQUEST FOR FILLERS JRST PUTC.2 ;DO THEM > PUSHJ P,DPYPUT ;OUTPUT THE CHARACTER JRST PUTC.1 ;RESUME LOOP IFN DOFILL,< PUTC.2: MOVE CHAR,FILLRS ;GET -NUMBER OF FILLERS,,0 JUMPE CHAR,PUTC.1 ;NONE AT THIS SPEED HRRI CHAR,TTYFIL ;GET FILLER CHARACTER PUSHJ P,DPYPUT ;OUTPUT IT AOBJN CHAR,.-2 ;DO AS MANY AS NEEDED JRST PUTC.1 ;AND RESUME FROM THE CONTROL STRING > ;SUBROUTINE TO STUFF "CHAR" INTO INTERMEDIATE BUFFER FOR DISPLAY DPYPUT: SKIPE LINPTR ;ANY CURRENT LINE JRST DPYP.1 ;YES, GO INCLUDE CHARACTER PUSH P,CHAR ;NO, SAVE CURRENT MOVE CHAR,[POINT TTYBYT,LINBUF] ;GET BUFFER POINTER MOVEM CHAR,LINPTR ;INITIALIZE POINTER MOVEI CHAR,^D199 ;CHARACTERS IN THE BUFFER MOVEM CHAR,LINCNT ;AS THE LINE COUNTER SETZM LINBUF ;CLEAR THE INCORE BUFFER NOW MOVE CHAR,[LINBUF,,LINBUF+1] BLT CHAR,LBUFND POP P,CHAR ;RESTORE CHARACTER DPYP.1: SOSL LINCNT ;ROOM IN THE BUFFER JRST [IDPB CHAR,LINPTR ;YES, ADD THE CHARACTER POPJ P,] ;AND RETURN PUSHJ P,FRCOUT ;NO, FORCE OUT THE BUFFER JRST DPYPUT ;AND START AGAIN ;HERE TO HANDLE SPECIAL VT05 FILLERS FOR CURSOR ADDRESSING ;VT05 NEEDS FILLERS BETWEEN LINE NUMBER AND COLUMN NUMBER IFDEF %VT05,< VT05FL: IF TOPS-10,< MOVE CHAR,FILLRS ;DO IT THE HARD WAY HERE CAUSE I REALLY NEED NULLS JUMPE CHAR,CPOPJ ;NOT NEEDED AT THIS SPEED PUSHJ P,FRCOUT ;FORCE OUT THE CURRENT BUFFER SETZ SCR, ;GET A NULL IONEOU SCR ;IMAGE OUTPUT A NULL AOBJN CHAR,.-1 ;OUTPUT AS MANY AS NEEDED POPJ P, ;THEN RETURN > ;END IF TOPS-10 IF TOPS-20,< MOVEI CHAR,[BYTE (7)177] ;ASK FOR FILLERS (WILL BE IMAGE NULLS LATER) JRST PUTCTL ;OUTPUT FILLERS > ;END IF TOPS-20 > ;END IFDEF ;VT100 TAKES ASCII LINE AND COLUMN SEQUENCE, OUTPUT IT HERE IFDEF %VT100,< VT100M: PUSH P,CHAR+1 ;SAVE AC FROM DIVIDES MOVEI CHAR,(NL) ;GET LINE PUSHJ P,VT100D ;OUTPUT LINE NUMBER MOVEI CHAR,";" ;SEPARATE WITH SEMICOLON PUSHJ P,DPYPUT ;STUFF THAT IN MOVEI CHAR,(NC) ;NOW COLUMN NUMBER PUSHJ P,VT100D ;INCLUDE THAT POP P,CHAR+1 ;RESTORE AC MOVEI CHAR,"H" ;END OF SEQUENCE JRST MOVXIT ;SEND IT AND CLEAN UP VT100D: IDIVI CHAR,^D10 ;CONVERT TO DECIMAL LINE/COLUMN NUMBERS HRLM CHAR+1,(P) ;STANDARD STUFF HERE SKIPE CHAR ;DONE YET PUSHJ P,VT100D ;NO, RECURSE A LITTLE HLRZ CHAR,(P) ;GET DIGIT ADDI CHAR,"0" ;TO ASCII JRST DPYPUT ;INCLUDE IN BUFFER, GET ANOTHER (MAYBE) > ;SAVE AND RESTORE SEQUENCES SAVREG: PUSH P,CUR ;SAVE CALLERS REGS PUSH P,NEW ;... PUSH P,OLD ;... PUSH P,NL ;... PUSH P,NC ;... EXCH POSL,CURL ;SAVE OLD, GET NEW EXCH POSC,CURC ;... EXCH TYP,VIDEOT ;... JUMPL TYP,INIERR ;ERROR IF NEVER DEFINED TERMINAL TYPE JRST @CHAR ;RETURN TO CODE RESREG: EXCH POSL,CURL ;SAVE COMPUTED, RESTORE OLD EXCH POSC,CURC ;... EXCH TYP,VIDEOT ;... POP P,NC ;RESTORE CALLERS REGISTERS POP P,NL ;... POP P,OLD ;... POP P,NEW ;... POP P,CUR ;... JRST @CHAR ;RETURN TO CODE ;TABLE OF BYTE POINTERS FOR "SETCUR" AND "FIXOLD" CURPTR: 440700,,0 ;FOR CHARACTER 1 350700,,0 ; " " 2 260700,,0 ; " " 3 170700,,0 ; " " 4 100700,,0 ; " " 5 IF TOPS-10,< NOCRLF: .TOSET+.TONFC ;SET NO FREE CRLF UDX: EXP 0,1 ;UDX FILLED IN, SET TO 1 = NOCRLF GTTYP: .TOTRM ;GET TERMINAL TYPE UDX1: EXP 0,0 ;UDX FILLED IN, DUMMY NOPAGE: EXP .TOSET+.TOPSZ ;SET PAGE SIZE 0 UDX2: EXP 0,0 ;UDX FILLED IN, PAGE 0 IFN DOFILL,< GETSPD: .TOTSP ;GET TERMINAL OUTPUT SPEED UDX3: EXP 0,0 ;UDX FILLED IN, DUMMY > TRMERR: OUTSTR [ASCIZ/?CANNOT SET TTY NO CRLF IN "DPYINI"/] JRST ERRXIT IONERR: OUTSTR [ASCIZ/?CANNOT FIND TERMINAL INDEX IN "DPYINI"/] JRST ERRXIT INIERR: OUTSTR [ASCIZ/?DPYPAK NEVER INITIALIZED/] ERRXIT: EXIT 1, ;REMOVE AND RETURN ERROR = -1 WHEN JRST .-1 ;DPYINI RETURNS TERMINAL HANDLES > ;END OF IF TOPS-10 IF TOPS-20,< NOTTY: SKIPA SCR,[-1,,[ASCIZ\?DPYPAK COULDN'T GTJFN/OPENF THE TTY\]] INIERR: HRROI SCR,[ASCIZ/?DPYPAK NEVER INITIALIZED/] PSOUT ;OUTPUT THE ERROR HALTF ;REMOVE AND RETURN ERROR = -1 WHEN JRST .-1 ;DPYINI RETURNS TERMINAL HANDLES > ;END OF IF TOPS-20 ;SUBROUTINE TO SET JOBS TTY THE WAY DPYPAK WANTS THEM ;RETURNS SCR = THE TERMINAL TYPE IF THIS MONITOR KNOWS IT GETTYP: IF TOPS-10,< MOVSI CHAR,'TTY' ;GET CALLERS TTY NUMBER IONDX. CHAR, ;ASK THE MONITOR JRST IONERR ;CAN'T FIND OUT MOVEM CHAR,UDX ;STUFF INTO ARG BLOCK MOVEM CHAR,UDX1 ;STUFF AGAIN MOVEM CHAR,UDX2 ;STUFF AGAIN IFN DOFILL, ;STUFF AGAIN MOVE CHAR,[3,,GTTYP] ;GET ARGUMENT POINTERS TRMOP. CHAR, ;ASK FOR SET TERMINAL TYPE SETZ CHAR, ;NONE, SET UNKNOWN TYPE > ;END OF IF TOPS-10 IF TOPS-20,< PUSH P,SCR+1 ;KEEP SAFE FROM JSYS'ES MOVEI SCR,.PRIOU ;FOR CURRENT TERMINAL GTTYP ;GET TERMINAL TYPE MOVE CHAR,SCR+1 ;WANT IT IN CHAR POP P,SCR+1 ;RESTORE AC'S > ;END OF IF TOPS-20 MOVSI SCR,-MAXTYP ;NUMBER OF KNOWN TYPES CAME CHAR,TYPTAB(SCR) ;FOUND IT AOBJN SCR,.-1 ;NO, KEEP LOOKING SKIPL SCR ;DID WE FIND ONE TDZA SCR,SCR ;NO, CLEAR TERMINAL TYPE MOVE SCR,TYPNAM(SCR) ;YES, GET ITS REAL NAME POPJ P, ;RETURN TO DPYINI SETINI: IF TOPS-10,< PUSH P,CHAR ;SAVE CALLERS MOVE CHAR,[3,,NOCRLF] ;GET ARGUMENT POINTERS TRMOP. CHAR, ;SET TTY NO CRLF ( MONITOR COUNTS CHARS ) JRST TRMERR ;CAN'T DO THAT ?? MOVE CHAR,[3,,NOPAGE] ;CLEAR PAGE COUNTER TRMOP. CHAR, ;TRY IT JFCL ;USER WILL JUST HAVE TO TYPE ^Q IFN DOFILL,< ;ONLY IF SOME TERMINALS NEED FILLERS MOVE SCR,[3,,GETSPD] ;GET OUTPUT SPEED TRMOP. SCR, ;GET ENCODED SPEED SETZ SCR, ;OH WELL SKIPG SCR ;DID I GET ONE TDZA CHAR,CHAR ;NO, CLEAR SPEED MOVE CHAR,[EXP ^D50,^D75,^D110,^D134,^D150,^D200,^D300,^D600 EXP ^D1200,^D1800,^D2400,^D4800,^D9600,^D9600,^D9600]-1(SCR) MOVEM CHAR,BAUD ;STORE INTERESTING NUMBER IDIVI CHAR,^D600 ;RECOMMENDED CONVERSION MOVNS CHAR ;GET - NUMBER NEEDED HRLZM CHAR,FILLRS ;REMEMBER NUMBER OF FILLERS NEEDED POP P,CHAR ;RESTORE POPJ P, ;RETURN > ;END IFN DOFILL > ;END IF TOPS-10 IF TOPS-20,< PUSH P,SCR+1 ;KEEP SAFE FROM JSYS'ES MOVSI SCR,1 ;SHORT GTJFN HRROI SCR+1,[ASCIZ/TTY:/] GTJFN ;GET HANDLE FOR THE TERMINAL JRST NOTTY ;CAN'T GET THE TTY? HRRZM SCR,TTYJFN ;SAVE JFN ACQUIRED MOVE SCR+1,[100000,,100000] ;8 BIT MODE, WRITE OPENF ;OPEN THE TTY JRST NOTTY ;WHAT? IFN DOFILL,< ;ONLY IF SOME TERMINALS NEED FILLERS PUSH P,SCR+2 ;KEEP SAFE FROM JSYS'ES MOVEI SCR,.PRIOU ;FOR CURRENT TERMINAL MOVEI SCR+1,.MORSP ;FUNCTION RETURN BAUD RATES MTOPR ;GET THEM SKIPGE SCR+2 ;RATE KNOWN SKIPA SCR,[^D2400] ;NO, SAY 2400 (PROBABLY A PTY) HRRI SCR,(SCR+2) ;YES, GET OUTPUT SPEED HRRZM SCR,BAUD ;STORE INTERESTING NUMBER IDIVI SCR,^D600 ;RECOMMENDED CONVERSION MOVNS SCR ;GET - NUMBER NEEDED HRLZM SCR,FILLRS ;REMEMBER NUMBER OF FILLERS NEEDED POP P,SCR+2 ;RESTORE AC'S > ;END IFN DOFILL POP P,SCR+1 ;RESTORE AC'S POPJ P, ;RETURN > ;END IF TOPS-20 ;SCRATCH STORAGE IF TOPS-20,< TTYJFN: .PRIOU ;JFN FOR TTY: (STARTS AS TTY, FILLED IN BY OPEN) > BAUD: 0 ;BAUD RATE FOR TERMINAL FILLRS: 0 ;NUMBER OF FILLERS NEEDED IF REQUESTED REFING: 0 ;FLAG FOR REFRESHING A SCREEN CLRING: 0 ;FLAG FOR CLEARING A SECTION REMEMB: 0 ;FLAG FOR REMEMBERING WHERA: 0 ;COLUMN OF FIRST BLANK ON A LINE WHLST: 0 ;COLUMN OF LAST CHANGE TO A BLANK ON A LINE WHCHR: 0 ;COLUMN OF FIRST CHANGE TO A BLANK PUTPTR: 0 ;BYTE POINTER DURING PUTCTL FRCRTY: 0 ;-1 IF FORCED TO RE-TYPE DURING RIGHT MOVEMENT LINPTR: 0 ;POINTER FOR INCORE LINE LINCNT: 0 ;AMOUNT OF ROOM LEFT IN BUFFER LINBUF: BLOCK <^D200/TTYCPW> ;ROOM FOR 199 CHARACTERS + 1 NULL LBUFND==.-1 ;END OF THE LINE BUFFER ;SCREEN SPECIFIC INFORMATION BOUNDS: 0 ;NEED TO SET BOUNDRIES NLPRIM: 0 ;1ST LINE OF SCREEN SWEEP NCPRIM: 0 ;1ST COLUMN NLEND: 0 ;LAST LINE OF SCREEN SWEEP NCEND: 0 ;LAST COLUMN ENDUSR: 0 ;LAST COLUMN (ROUNDED) OF USERS ARRAY LJUST: 0 ;-1 FOR LEFT JUSTIFIED ( A1 ) FORMAT CURL: -1 ;WHERE WE LEFT THE CURSOR CURC: 0 ; " " " " " VIDEOT:: -1 ;VIDEO TERMINAL TYPE NEWPTR: POINT 0,0 ;SIZE FILLED IN DURING "DPYINI" SCREEN: BLOCK ;ROOM FOR A SCREEN ENDSCR==.-1 ;LAST LOC OF THE SCREEN END ;END OF DPYPAK