.TITLE VUESCR : VUE'S 'WATCH' FOR VT-100AA ;RBD-VUE .IDENT /V100.1/ ;FIRST RELEASE 8-JUN-79 ;RBD-VUE ; THIS IS A MODIFIED VERSION OF THE 'SCREEN' MODULE FOR TECO'S I/O UNDER ; RSX-11M. ACTUALLY, THIS MODULE WILL ALSO WORK WITH RT-11'S TECO, AS IT ; DOESN'T HAVE ANY SYSTEM DEPENDENT STUFF IN IT. ; ; THE MODIFICATIONS MADE TO 'SCREEN' ARE PART OF THOSE MADE TO TECO AND IT'S ; I/O TO TURN IT INTO 'VUE', THE NEW CRT EDITOR FOR RSX-11M AT GOULD. THE ; REASON FOR ALL OF THIS IS THAT 'VTEC' + VT52.TEC MACRO HAS BASIC INPUT ; PROBLEMS WHICH CAUSE IT TO MISS CHARACTERS SENT FROM THE TERMINAL, ; PARTICULARLY KEYPAD ESCAPE SEQUENCES. THIS MADE VTEC 'MICKEY MOUSE'. ; ; VUE ALLOWS DISPLAY OF 18 LINES OF THE BUFFER, UPDATED AS NECESSARY BY ; THIS MODULE. AT THE BOTTOM, A COMMAND INPUT/ERROR OUTPUT FIELD IS PROVIDED ; WHERE NORMAL TECO COMMANDS MAY BE ENTERED. ; ; THERE WERE SEVERAL PLACES IN THE ORIGINAL 'SCREEN' PROGRAM WHERE HARD VALUES ; FOR THE SCREEN WIDTH AND #LINES WERE USED, THESE WERE REPLACED WITH ; SYMBOLIC REFERENCES TO H.SIZE AND V.SIZE. THE STANDARD CURSOR POSITION WAS ; CHANGED TO LINE 12(10). THE V.SIZE PARAMETER WAS CHANGED TO 18(10). ; ; ****** NOTE ****** ; THIS ASSEMBLY WILL PRODUCE AN ERROR IF THE SCREEN WIDTH IS SET TO OTHER ; THAN 80. AND IT IS ASSEMBLED FOR A NON-HARDWARE MUL (NON-EIS) MACHINE ; (I$$MUL NOT DEFINED). THIS IS BECAUSE IT MUST USE IT'S HARD-WIRED MUL ; BY 40 OR 80 ROUTINE, AND SO MUST HAVE H.SIZE = 80. IF YOU MUST ASSEMBLE ; FOR A NHD MACHINE AND HAVE H.SIZE NOT = 80., YOU'LL HAVE TO MAKE A NEW ; MUL ROUTINE APPROPRIATE TO YOUR SPECIAL SCREEN WIDTH, AND CHANGE THE ; "MULT" MACRO ACCORDINGLY. ; ; THE MEANING OF THE PARAMETER PASSED TO THIS ROUTINE IN R0 (EITHER THE OLD ; VALUE OF NWATCH OR THE NUMERIC PARAMETER OF THE ^W) HAS BEEN CHANGED. ; NOW, A NEGATIVE VALUE WILL CAUSE SCREEN UPDATES ON ALL SUBSEQUENT CALLS, ; BUT NONE ON THE CALL WHICH PASSED THE NEG VALUE. A ZERO VALUE WILL CAUSE ; THE ENTIRE SCREEN TO BE FORGOTTEN, AND NO UPDATES ON SUBSEQUENT CALLS. ; IF A POSITIVE VALUE IS PASSED IN R0, THE SCREEN WILL BE FORGOTTEN, BUT ; WE PLACE A -1 INTO NWATCH, SO WE'LL UPDATE FROM THE NEXT CALL ON. (IN THIS ; CASE, THE NEXT CALL WILL FORCE A COMPLETE REWRITE OF THE SCREEN). ; ; IF THE VALUE OF NWATCH IS NEGATIVE WHEN THIS GUY IS CALLED, HE'LL UPDATE ; THE SCREEN THROUGH THE 18'TH LINE, THEN CLEAR OUT LINES 19 THRU 24, THEN ; MOVE THE CURSOR DOWN TO THE 20'TH LINE, THEN RETURN TO TECO TO LET HIM ; PROMPT THE USER FOR INPUT. ; ; (CONT.) ; SINCE VUE WILL DO OUTPUT AFTER EACH SCREEN REFRESH, AND IT WILL CAUSE ; THE FLAG 'OUTDNE' IN THE I/O MODULES TO BE SET, I REMOVED THE CODE THAT ; CLEARS THE 'INITFL', FORGETTING THE SCREEN, IF OUTDNE IS NON-ZERO. IT ; IS UP VUE TO FIGURE OUT IF THE SCREEN HAS INADVERTENTLY BEEN SCROLLED, ; DESTROYING ITS CORRESPONDENCE WITH THIS GUY'S MAP, AND CALL WATCH WITH ; A ZERO IN R0. ; ; ALSO, SINCE THE CURSOR IS MOVED OUT OF THE WINDOW WHEN REFRESH IS DONE, ; WE HAVE TO MOVE THE CURSOR BACK TO WHERE IT WAS WHEN WE ENTER THIS ROUTINE. ; ; FINALLY NOTE THAT WE ARE NOW USING ANSI ESCAPE SEQUENCES SO WE CAN ; INDICATE THE POINTER LOCATION BY BLINKING THE CHARACTER IMMEDIATELY ; TO THE RIGHT OF THE POINTER. TOO BAD WE COULDN'T DO THIS WITH VT52 ; ESCAPE SEQUENCES!! ; .ENABL LC ; ; The modifications to this TECO/RSX-11M I/O module were ; made by: ; ; Bob Denny ; Gould, Inc. NavCom Systems Division ; 4323 N. Arden Drive. ; El Monte, Ca. 91731 ; (213) 442-0123 Ext. 587 ; ; If you have any questions about the mods, or find (and maybe fix) ; a problem, feel free to contact me. ; ;------------------------------------------------------------------------- .SBTTL ASSEMBLY PARAMETERS I$$SOB=1 ;ASSEMBLE FOR HARDWARE 'SOB' INSTRUCTION I$$MUL=2 ;ASSEMBLE FOR HARDWARE 'MUL' INSTRUCTION .SBTTL CHARACTER DEFINITIONS TAB = 011 ;ASCII HORIZONTAL TAB LF = 012 ;ASCII LINE FEED CR = 015 ;ASCII CARRIAGE RETURN ESC = 033 ;ASCII ESCAPE (ALSO CALLED ALTMODE) SPACE = 040 ;ASCII SPACE DEL = 177 ;ASCII DELETE (ALSO CALLED RUBOUT) .SBTTL DEFAULT AND SET UP THE ASSEMBLY PARAMETERS H.SIZE = 80. ;HORIZONTAL WIDTH V.SIZE = 18. ;VERTICAL SIZE NOW 18 LINES ;VUE .IF NDF I$$SOB .MACRO SOB REG,DST DEC REG BNE DST .ENDM SOB .SBTTL ASSEMBLED WITHOUT HARDWARE 'SOB' INSTRUCTION .IFF .SBTTL ASSEMBLED WITH HARDWARE 'SOB' INSTRUCTION .ENDC .IF NDF I$$MUL .IF NE H.SIZE-80. ;VUE .ERROR ;CANNOT ASSEMBLE SPECIAL H.SIZE FOR NHD MACHINES!!!!! ;VUE .ERROR ;SEE THE COMMENTS FOR YOUR SOLUTION ;VUE .ENDC ;VUE .MACRO MULT AMT JSR PC,MUL'AMT .ENDM MULT .SBTTL ASSEMBLED WITHOUT HARDWARE 'MUL' INSTRUCTION .IFF .MACRO MULT AMT MUL #AMT'.,R1 .ENDM MULT .SBTTL ASSEMBLED WITH HARDWARE 'MUL' INSTRUCTION .ENDC .SBTTL SCOPE "WATCH" ROUTINE .CSECT SCREEN SCREEN:: .WORD SCRWSZ ;THE READ/WRITE DATA REGION'S SIZE .IIF NE .-SCREEN-2, .ERROR ;ENTRY POINT IS INCORRECTLY LOCATED WATCH:: BIT #512.,ETYPE(R5) ;IS THE SCOPE AVAILABLE? BEQ RET01 ;NOPE, QUICKLY EXIT ;----------------------V U E----------------------- TST R0 ;WADDOWEDO??? BGT FORGET ;FORGET SCREEN, BUT LEAVE NWATCH ALONE! BMI REFRSH ;MIGHT REFRESH NOW! ; GOT A 0^W, FORGET SCREEN AND STOP REFRESHING CLR NWATCH(R5) ;CLEAR NWATCH SO WE'LL STOP REFRESHING ;FALL THRU ... ; GOT A ^W WITH POSITIVE ARG, JUST FORGET SCREEN, LEAVE NWATCH ALONE FORGET: MOV NWATCH(R5),R0 ;KEEP OLD NWATCH PRIOR TO THIS CALL CLR INITFL+RWSIZE(R5) ; FORGET SCREEN RET01: RTS PC ;THAT'S ALL REFRSH: TST NWATCH(R5) ;IS NWATCH ALREADY NEG ? BMI GO ;IF SO, DONT MESS AROUND ... REFRESH SCREEN MOV #-1,R0 ;IF NOT, SET UP TO DO IT NEXT TIME MOV R0,NWATCH(R5) CLR EVFLAG(R5) ;SHUT OFF ANY VERIFY TYPEOUT! CLR ESFLAG(R5) ;SAME WITH SEARCH VERIFICATION! RTS PC GO: MOV NWATCH(R5),R0 ;TECO GETS A COPY OF NWATCH BACK IN R0 JSR R4,SAVREG ;SAVE ALL REGISTERS MOV #CCASEQ,R3 ;IMMEDIATELY CLEAR THE COMMAND FIELD JSR PC,DOTYPE MOV #-1,PRELIN+RWSIZE(R5) ;FORCE SETCUR TO ACTUALLY MOVE CURSOR MOV CURLIN+RWSIZE(R5),BUSTRT+RWSIZE(R5) ;SET CURSOR POS. MOV CURCHR+RWSIZE(R5),R2 JSR PC,SETCUR CLR R0 ;'DOIT' NEEDS R0 = 0 ;FALL THRU... ;----------------------V U E---------------------- .GLOBL ETYPE, RWSIZE, NWATCH, SAVREG, OUTDNE DOIT: MOV ETYPE(R5),-(SP) ;SAVE ENTERING EDIT FLAG VALUE BIS #1,ETYPE(R5) ; AND, THEN, ENSURE IMAGE MODE OUTPUT JSR R4,SETJSR ;SET UP FOR .WORD FTRANS ; COUNTING LINES MOV P(R5),-(SP) ;SAVE CURRENT POINTER ;CLR R0 ;SET THE ARGUMENT JSR PC,.VVV.V ;DO 0L (START OF CURSOR LINE) MOV R1,R4 ;SET START OF THE CURSOR LINE MOV ZZ(R5),R1 ;GET TOTAL SIZE OF TEXT BUFFER SUB R4,R1 ; AND FIND SIZE TO END OF BUFFER JSR PC,DOTEXT ;NOW COUNT LINES IN THAT TEXT MOV #V.SIZE,R0 ;SET SCREEN SIZE ;VUE STDCUR = <2*V.SIZE>/3 ;STD CURSOR LOC. 2/3 DOWN WINDOW ;VUE MOV #STDCUR,-(SP) ;VUE SUB BUSTRT+RWSIZE(R5),R0 CMP R0,(SP) BLOS 30$ MOV R0,(SP) 30$: MOV #CHCKBL+RWSIZE,R2 ;GET POINTER TO CHECKING BUFFER ADD R5,R2 ; ABSOLUTELY MOV R2,-(SP) ;SAVE START OF THE BUFFER CLR (R2) ;INDICATE NO FUDGE MOVEMENT INITIALLY 40$: TST INITFL+RWSIZE(R5) ;DO WE KNOW WHAT'S ON THE SCREEN? BPL 50$ ;BRANCH IF NOT INC (R2) ;SET THE FLAG WORD 50$: JSR R4,SETJSR ;SET UP FOR .WORD FTRANS ; COUNTING LINES .GLOBL ETYPE, P, .VVV.V, ZZ, NWATCH, RWSIZE, OUTDNE LINES: MOV #FCHAR,OUTCHR+RWSIZE(R5) ;RESET OUTPUT ROUTINE MOV P(R5),LINPTR+RWSIZE(R5) ;SAVE OLD LINE INDEX BEQ TRYMOV ;AT TOP OF PAGE, QUIT FOR NOW MOV #-1,R0 ;GET TO START OF PREVIOUS TEXT LINE JSR PC,.VVV.V ;USING TECO'S MOVER MOV R1,R4 ;NEW 'P' IS RETURNED IN R1, MAKE COPY SUB LINPTR+RWSIZE(R5),R1 ;MAKE R1 CONTAIN NEG R1 ; ONLY CHARS IN -1L CMP R1,#15. ;15. OR MORE CHARACTERS HERE? BLO 20$ ;NOPE, DON'T PUT INTO CHECKING BUFFER TST BUSTRT+RWSIZE(R5) ;IS THIS THE FIRST TIME THROUGH?? BEQ 20$ ;YES, FIRST TIME, DON'T BUFFER THE LINE MOV (SP),R2 ;GET CHECKING BUFFER POINTER TSTB (R2) ;IS IT ALREADY FILLED? BLE 20$ ;YEP, DON'T REUSE IT THEN NEG (R2)+ ;ELSE MARK AS USED NOW MOV R2,BUINDX+RWSIZE(R5) ; AND SET STARTING FILL IN POINTER MOV #CCHAR,OUTCHR+RWSIZE(R5) ; AND CHANGE THE OUTPUT ROUTINE MOV #H.SIZE/2,R0 ;SET SIZE OF BUFFER IN WORDS ;VUE 10$: MOV (PC)+,(R2)+ ;BLANK THE .BYTE SPACE,SPACE SOB R0,10$ ; WHOLE BUFFER 20$: MOV BUSTRT+RWSIZE(R5),SVSTRT+RWSIZE(R5) ;SAVE STARTING VALUE JSR PC,DOTEXT ;FORMAT A LINE MOV BUSTRT+RWSIZE(R5),R0 ;GET FINISHING LINE NUMBER TST CHCKBL+RWSIZE(R5) ;DOES CHECKING BUFFER LINE NEED SETTING? BPL 30$ ;NOPE MOVB R0,CHCKBL+1+RWSIZE(R5) ;YEP, SO SAVE LINE NUMBER 30$: CMP R0,2(SP) ;WOULD WE BE AT TOP? BLO LINES ;BRANCH IF NOT MOV SVSTRT+RWSIZE(R5),BUSTRT+RWSIZE(R5) ;RESTORE CORRECT VALUE .GLOBL RWSIZE TRYMOV: MOV (SP)+,R2 ;GET CHECKING BUFFER POINTER TSTB (R2)+ ;DID WE FILL IT? BGE OUTPUT ;NOPE MOVB (R2)+,R0 ;SAVE THE "BUSTRT" VALUE MOV BUSTRT+RWSIZE(R5),R1 ;GET ENDING "BUSTRT" VALUE SUB R0,R1 ;CALCULATE THE BUFFERED LINE NUMBER MULT 80 ;FIND OFFSET OF THE BUFFERED LINE MOV R1,(SP) ; AND SAVE IT MOV #MOVTBL-2,R4 ;GET THE MOVEMENT TABLE 10$: TST (R4)+ ;SKIP OVER THE UNUSED MOVE AMOUNT CMP R4,#MOVTBE ;ARE MORE MOVES POSSIBLE? BHIS OUTPUT ;NO, PUNT ON IT MOV (SP),R1 ;YES, GET THE BUFFERED LINE'S OFFSET ADD (R4)+,R1 ;BUILD OFFSET POINTER FOR THIS TRY CMP R1,#MAPND-MAPST ;IS THIS OFFSET OUT OF THE SCREEN? BHIS 10$ ;TOO FAR OUT, GO TRY ANOTHER MOVE ADD #MAPST+RWSIZE,R1 ;INDEX TO SCREEN MAP ADD R5,R1 ; ABSOLUTELY MOV R2,R3 ;SET POINTER TO CHECK BUFFER MOV #H.SIZE/2,R0 ; AND LOAD A COUNTER ;VUE 20$: CMP (R3)+,(R1)+ ;MATCH?? BNE 10$ ;NO SOB R0,20$ ;YES, LOOP MOV (R4)+,R1 ;TOTAL MATCH!! GET THE MOVMENT AMOUNT CLR R2 ;SET CURSOR TO COLUMN 0 MOV #23.,BUSTRT+RWSIZE(R5) ;ASSUME WE ARE GOING UP MOV #LFSEQ,R3 ;SEQUENCE TO RAISE SCREEN MOV R1,R4 ;SAVE THAT MOVE COUNT BEQ OUTPUT ;NO MOVEMENT, SO QUIT BPL 30$ ;ASSUMPTION RIGHT MOV #REVSEQ,R3 ;SEQUENCE TO LOWER SCREEN CLR BUSTRT+RWSIZE(R5) ;FIX TO LOWER SCREEN NEG R4 ;MAKE COUNT POSITIVE 30$: JSR PC,DOSEQ ;POSITION THE SCREEN SOB R4,30$ ; THE CORRECT NUMBER OF TIMES .GLOBL RWSIZE MOV #MAPST+RWSIZE,R2 ;SET POINTER TO START OF MAP ADD R5,R2 ; ABSOLUTE MOV R2,R0 ;BUILD POINTER ADD #MAPND-MAPST,R0 ; TO END OF MAP MULT 80 ;CALC OFFSET TO START MOVE FROM BMI 60$ ;BRANCH IF TO MOVE INTERNAL MAP DOWN ADD R2,R1 ;ADD IN MAP BASE 40$: MOV (R1)+,(R2)+ ;MOVE THE DATA CMP R1,R0 ;DID WE MOVE LAST DATA BYTE? BLO 40$ ;BRANCH IF NOT 50$: MOV (PC)+,(R2)+ ;FILL REMAINDER WITH BLANKS .BYTE SPACE,SPACE CMP R2,R0 ;ARE WE AT END OF TABLE? BLO 50$ ;BRANCH IF NOT BR OUTPUT ;ELSE DONE SHIFTING 60$: ADD R0,R1 ;POINT TO END OF DATA TO BE MOVED 70$: MOV -(R1),-(R0) ;MOVE THE DATA CMP R1,R2 ;ARE WE AT THE TOP? BHI 70$ ;BRANCH IF NOT 80$: MOV (PC)+,-(R0) ;BLANK FILL REMAINDER .BYTE SPACE,SPACE CMP R0,R2 ;ARE WE AT TOP? BHI 80$ ;BRANCH IF NOT .GLOBL RWSIZE OUTPUT: TST (SP)+ ;JUNK THE STACK ITEM JSR R4,SETJSR ;SET UP FOR .WORD RTRANS ; THE REAL OUTPUT MOV LINPTR+RWSIZE(R5),R4 ;GET STARTING POINT OF TEXT MOV ZZ(R5),R1 ;GET END OF TEXT SUB R4,R1 ; AND FIND AMOUNT OF TEXT TO DO MOV #MAPST+RWSIZE,BUINDX+RWSIZE(R5) ;INIT THE INDEX INTO THE MAP ADD R5,BUINDX+RWSIZE(R5) ; ABSOLUTE TST INITFL+RWSIZE(R5) ;DO WE KNOW THE STATE OF THE SCREEN? BMI 10$ ;BRANCH IF YES CLR R2 ;CLEAR THE COLUMN NUMBER CLR MAPST+RWSIZE(R5) ;CLOBBER THE LAST COPY OF THE MAP MOV #-1,PRELIN+RWSIZE(R5) ;CLOBBER LAST KNOWN CURSOR JSR PC,CLREND ;CLEAR THE SCREEN 10$: MOV (SP),P(R5) ;FINALLY REFIX POINTER ADD TXSTOR(R5),(SP) ;COMPUTE CURSOR POINTER MOV (SP),UNDERC+RWSIZE(R5) ;SAVE POSITION OF UNDER SCORE MOV #V.SIZE-1,CURLIN+RWSIZE(R5) ;PRESET CURSOR AT END OF MOV #H.SIZE-1,CURCHR+RWSIZE(R5) ; SCREEN JSR PC,DOTEXT ;NOW REALLY UPDATE THE SCREEN MOV CURLIN+RWSIZE(R5),BUSTRT+RWSIZE(R5) ;SET THE LINE FOR CURSOR MOV CURCHR+RWSIZE(R5),R2 ;SET THE COLUMN JSR PC,BLINK ;BLINK POINTER CHARACTER ;VUE TST (SP)+ ;POP OFF CURSOR LOCATION ;VUE MOV #CCASEQ,R3 ;CLEAR SCROLL DOWN JUNK AND LEAVE CURSOR;VUE JSR PC,DOTYPE ;...IN THE COMMAND FIELD ;VUE MOV #LINSEQ,R3 ;PLACE THE DIVIDER LINE THERE ;VUE JSR PC,DOTYPE ;VUE JSR PC,TYPEFC ;AND FORCE OUT THE BUFFER ;VUE MOV #-1,INITFL+RWSIZE(R5) ;NOW WE KNOW WHAT'S ON THE SCREEN CLRB OUTDNE ;ALSO CLEAR TERMINAL OUTPUT FLAG ROR (SP)+ ;DO WE NEED TO CLEAR IMAGE OUTPUT? BCS 30$ ;NOPE, IT WAS SET ON ENTRY BIC #1,ETYPE(R5) ;YEP, SO CLEAR IT ALREADY 30$: RTS PC ;FINALLY WE CAN EXIT .GLOBL RWSIZE, ZZ, P, TXSTOR, TYPEFC, OUTDNE, ETYPE .ENABL LSB DOTEXT: ADD TXSTOR(R5),R4 ;MAKE POINTER ABSOLUTE MOV R1,-(SP) ;SAVE THE CHARACTER COUNT BR 70$ ;INITIALIZE COLUMN COUNTER AND POINTER 10$: CMPB (R4),#CR ;AVOID SEQUENCE IF OVERFLOW ON BEQ 60$ ;BRANCH IF MOV #200,R0 ;ELSE SET THE OVERFLOW "CHARACTER" BIT #400,ETYPE(R5) ;ALLOWING LINE OVERFLOWS? BEQ 20$ ;YEP, SO DO IT INC R4 ;NOPE, EAT THE CHARACTER CMP R2,#H.SIZE-1 ;WHERE ARE WE?? BHIS 40$ ;REALLY AT THE END, PUNT ON IT JSR PC,@OUTCHR+RWSIZE(R5) ;PUT OVERFLOW "CHARACTER" THERE BR 40$ ;THEN CONTINUE 20$: INC (SP) ;REMEMBER TO GET THE CHARACTER AGAIN MOV R2,RTMOST+RWSIZE(R5) ;SET HIGHEST COLUMN NUMBER CLR R2 ;SIMULATE CARRIAGE RETURN JSR PC,NEWLIN ;FIX SCREEN BHIS 140$ ;BRANCH IF AT BOTTOM OF SCREEN JSR PC,@OUTCHR+RWSIZE(R5) ;OUTPUT OVERFLOW "CHARACTER" MOV #SPACE,R0 ;FOLLOW IT WITH A 30$: JSR PC,@OUTCHR+RWSIZE(R5) ;OUTPUT CHARACTER 40$: CMP R4,UNDERC+RWSIZE(R5) ;IS THIS WHERE THE CURSOR BELONGS? BNE 50$ ;BRANCH IF NOT MOV R1,CURABS+RWSIZE(R5) ;SAVE ABSOLUTE POSITION IN MAP MOV BUSTRT+RWSIZE(R5),CURLIN+RWSIZE(R5) ;SAVE THE LINE NUMBER MOV R2,CURCHR+RWSIZE(R5) ;SAVE THE COLUMN NUMBER CMP R2,#H.SIZE ;IS THE COLUMN NUMBER ILLEGAL? BLO 50$ ;NOPE MOV #H.SIZE-1,CURCHR+RWSIZE(R5) ;YEP, SO FIX IT ALREADY 50$: DEC (SP) ;KNOCK DOWN CHARACTER COUNT BMI 130$ ;BRANCH IF NO MORE FOR END OF SCREEN CMP R2,#H.SIZE-2 ;ABOUT TO OVERFLOW? BHIS 10$ ;BRANCH IF TRUE 60$: MOVB (R4)+,R0 ;GET A BYTE OF TEXT CMP R0,#DEL ;IS IT ? BEQ 110$ ;BRANCH IF YES CMP R0,#SPACE ;IS IT SPECIAL? BHIS 30$ ;BRANCH IF NOT CMP R0,#TAB ;IS IT A ? BEQ 100$ ;BRANCH IF IT IS BLO 110$ ;BRANCH IF MUST BE REGULAR CONTROL CHAR CMP R0,#CR ;IS CHAR A ? BNE 80$ ;BRANCH IF IT IS, RESET COLUMN COUNTER CMP R2,RTMOST+RWSIZE(R5) ;SAVE RIGHT MOST COLUMN ON LINE BLOS 70$ ;BRANCH IF NOT AT IT MOV R2,RTMOST+RWSIZE(R5) ;SAVE IT FOR CLEARING REMAINDER 70$: CLR R2 ;RESET COLUMN COUNTER MOV BUINDX+RWSIZE(R5),R1 ;SET POINTER INTO MAP BR 40$ ; AND CONTINUE .GLOBL TXSTOR, ETYPE, RWSIZE 80$: BHI 110$ ;BRANCH IF > , MAY BE ? SUB #LF,R0 ;R0=0 FOR , R0=1 FOR , R0=2 FOR ASL R0 ;R0=0 FOR , R0=2 FOR , R0=4 FOR 90$: JSR PC,NEWLIN ;HANDLE A NEW SCOPE LINE BHIS 140$ ;BRANCH IF AT BOTTOM OF SCREEN DEC R0 ;KEEP COUNT FOR 'S AND 'S BMI 40$ ;BRANCH IF DONE WITH CHAR BR 90$ ;ELSE CONTINUE 100$: MOV #SPACE,R0 ;OUT SPACES TO TAB STOP JSR PC,@OUTCHR+RWSIZE(R5) ;OUTPUT THE CHARACTER BIT R2,#7 ;AT A TAB STOP? BEQ 40$ ;BRANCH IF SO CMP R2,#H.SIZE-2 ;ELSE ABOUT TO OVERFLOW LINE? BLO 100$ ;NOPE, LOOP BR 40$ ;YES, QUIT 110$: MOV #'$,-(SP) ;GUESS AT CMP R0,#ESC ;GOOD GUESS?? BEQ 120$ ;YES, GOES AS "$" ADD #100,R0 ;NO, PUT CHARACTER INTO RANGE BIC #^C<177>,R0 ; AND MASK IT FOR SAFETY MOV R0,(SP) ;SAVE CHARACTER MOV #'^,R0 ;PRINT ARROW JSR PC,@OUTCHR+RWSIZE(R5) ;OUTPUT THE CHAR 120$: MOV (SP)+,R0 ;GET THE CHAR BACK BR 30$ ; AND CONTINUE 130$: SUB TXSTOR(R5),R4 ;MAKE TEXT POINTER RELATIVE AGAIN CMP R4,ZZ(R5) ;AT END OF BUFFER NOW? BNE 140$ ;NOPE CMP R2,#H.SIZE ;YEP, ANY ROOM LEFT ON THIS LINE? BHIS 140$ ;SORRY, NO ROOM LEFT MOV #201,R0 ;ROOM, SET END OF BUFFER "CHARACTER" JSR PC,@OUTCHR+RWSIZE(R5) ; AND OUTPUT IT 140$: TST (SP)+ ;JUNK THE CHARACTER COUNTER CLREND: MOV #EEOSEQ,R3 ;SET EOS SEQUENCE FOR BLANKING MOV #MAPND+RWSIZE,R0 ;POINT TO END OF SCREEN MAP ADD R5,R0 ; ABSOLUTELY JMP @OUTBLN+RWSIZE(R5) ;CALL BLANKER FOR REST OF SCREEN .GLOBL RWSIZE, TXSTOR, ZZ .DSABL LSB NEWLIN: MOV R0,-(SP) ;SAVE FOR LATER MOV R2,-(SP) ;ALSO SAVE COLUMN POSITIN MOV BUINDX+RWSIZE(R5),R0 ;CALCULATE END OF ADD #H.SIZE,R0 ; LINE POINTER ;VUE MOV #CLNSEQ,R3 ;SET SEQ TO CLEAR ONLY THIS LINE JSR PC,@OUTBLN+RWSIZE(R5) ;ERASE THE REMAINDER OF LINE IF ANYTHING CLR RTMOST+RWSIZE(R5) ;CLEAR IT FOR NEW LINE MOV R0,BUINDX+RWSIZE(R5) ;UPDATE TO NEW LINE ON SCREEN FACE INC BUSTRT+RWSIZE(R5) ;FLAG A NEW LINE DONE MOV R0,R1 ;SET NEW MAP POINTER TST (SP) ;GET THE COLUMN POSITION BEQ 20$ ;BRANCH IF AT COLUMN 0, NORMAL CASE CMP BUSTRT+RWSIZE(R5),#V.SIZE ;ALREADY OFF THE SCREEN? BHIS 20$ ;YES, FORGET IT CLR R2 ;NO, START FROM COLUMN 0 MOV #SPACE,R0 ; AND USE SPACES FOR BLANKING 10$: JSR PC,@OUTCHR+RWSIZE(R5) ;OUTPUT ONE BLANK CMP R2,(SP) ;UP TO THE CURSOR POSITION YET? BLO 10$ ;NOPE, CONTINUE 20$: MOV (SP)+,R2 ;RESET COLUMN POSITION MOV (SP)+,R0 ;GET BACK FLAG FOR TYPE OF CHAR CMP BUSTRT+RWSIZE(R5),#V.SIZE ;'BHIS' BRANCHES IF AT BOTTOM RTS PC ;RETURN SETJSR: MOV #OUTCHR+RWSIZE,R3 ;GET ADDRESS OF FIRST VECTOR ADD R5,R3 ; ABSOLUTELY MOV (R4)+,R2 ;GET POINTER TO THE TABLE 10$: MOV (R2)+,(R3)+ ;PUT IN A NEW ADDRESS BNE 10$ ;LOOP THROUGH LIST CLR (R3)+ ;CLEAR "BUSTRT" ALSO RTS R4 ;THEN EXIT .IF NDF I$$MUL MUL80: ASL R1 ;*80. IS *40.*2 MUL40: MOV R1,-(SP) ;SAVE *1 ASL R1 ;NOW *2 ASL R1 ;NOW *4 ADD (SP)+,R1 ;NOW *5 ASL R1 ;NOW *10. ASL R1 ;NOW *20. ASL R1 ;NOW *40. RTS PC ;SO EXIT .ENDC .GLOBL RWSIZE VTBLNK: MOV R1,-(SP) ;SAVE MOV R2,-(SP) ; WORK MOV R4,-(SP) ; REGS MOV R0,-(SP) ;ADDRESS TO STOP AT CMP R2,RTMOST+RWSIZE(R5) ;CHECK FOR RIGHTMOST USED COLUMN BHIS 10$ ;R2 IS RIGHT MOV RTMOST+RWSIZE(R5),R2 ;FIX R2 10$: MOV BUINDX+RWSIZE(R5),R1 ;GET ADDRESS OF CURRENT LINE ADD R2,R1 ;POINT TO WHERE WE ARE IN BUFFER MOV #-1,R4 ;SET FLAG TO CLEAR EOS IF NEEDED 20$: CMP R1,(SP) ;ARE WE AT END YET? BHIS 60$ ;BRANCH IF YES BIT R1,#1 ;ON WORD BOUNDARY? BEQ 40$ ;BRANCH IF YES CMPB #SPACE,(R1)+ ;IS THIS A BLANK ALREADY? BEQ 20$ ;BRANCH IF YES MOVB #SPACE,-1(R1) ;SET IT TO A BLANK INC R4 ;DO WE HAVE TO CLEAR END OF SCREEN? BNE 20$ ;BRANCH IF ALREADY DONE 30$: JSR PC,DOSEQ ;CLEAR LINE OR SCREEN BR 20$ ;CONTINUE THE CLEAR LOOP 40$: CMP (PC)+,(R1)+ ;ARE THESE BLANKS ALREADY? .BYTE SPACE,SPACE BEQ 50$ ;YES MOV #SPACE*400+SPACE,-2(R1) ;SET LAST TWO TO BLANKS INC R4 ;DO WE HAVE TO CLEAR TO EOS? BEQ 30$ ;BRANCH IF WE NEED TO 50$: CMP R1,(SP) ;ARE WE AT END YET? BLO 40$ ;NOT YET 60$: MOV (SP)+,R0 ;RESTORE THE LIMIT MOV (SP)+,R4 ;RESTORE MOV (SP)+,R2 ; WORK MOV (SP)+,R1 ; REGS RTS PC ;EXIT .GLOBL RWSIZE VTCHAR: CMPB R0,(R1)+ ;ARE CHARACTERS THE SAME?? BEQ FCHAR ;BRANCH IF YES, DON'T SEND IT! JSR PC,SETCUR ;POSITION THE CURSOR MOVB R0,-1(R1) ;SAVE THE CHARACTER BPL 10$ ;NOT SPECIAL ASLB R0 ;SPECIAL, MAKE INTO AN INDEX MOV SEQS(R0),R3 ; AND GET THE SEQUENCE POINTER JSR PC,DOTYPE ; AND OUTPUT IT BR 20$ ;THEN CONTINUE 10$: JSR PC,TYPEBF ;NOW SEND CHARACTER 20$: INC PRECOL+RWSIZE(R5) ;INDICATE CURSOR MOVED 1 TO THE RIGHT FCHAR: INC R2 ;ADVANCE COLUMN NUMBER RTS PC ; THEN EXIT .ENABL LSB CCHAR: INC R2 ;ADVANCE COLUMN NUMBER MOVB R0,(R1)+ ;SAVE THE CHARACTER BGT 10$ ;NORMAL, CONTINUE NEG CHCKBL+RWSIZE(R5) ;SPECIAL, SAY THIS LINE NOT FILLED FBLNK: MOV #FCHAR,OUTCHR+RWSIZE(R5) ;RESET THE OUTPUT ROUTINE 10$: RTS PC ;THEN RETURN .DSABL LSB .GLOBL TYPEBF, RWSIZE ;---------------------------------V U E------------------------------------ BLINK: MOV #PTRSQ1,R3 ;POSITION CURSOR AND SEND THE FIRST JSR PC,DOSEQ ;>PART OF THE BLINK SEQUENCE MOVB @2(SP),R0 ;GET CHAR TO BLINK CMP P(R5),ZZ(R5) ;END OF BUFFER ? BLO 1$ ;IF NOT SKIP OVER... CLR R0 ;MAKE THE CHAR A NULL 1$: CMP R0,#40 ;CONTROL CHAR ? BGE 2$ ;IF NOT, JUST SEND IT MOVB SPLCHR(R0),R0 ;IF SO, GET THE SUBSTITUTE BPL 2$ ;IF NO GRAPHIC (^), SEND IT AS IS BIC #177600,R0 ;STRIP THE FLAG BIT MOV #GRAFON,R3 ;TURN ON GRAPHIC MODE JSR PC,DOTYPE JSR PC,TYPEBF ;SEND THE GRAPHIC MOV #GRFOFF,R3 ;SHUT OFF GRAPHIC MODE JSR PC,DOTYPE BR 3$ ;FINISH UP 2$: JSR PC,TYPEBF ;SENT IT RIGHT OUT 3$: MOV #PTRSQ2,R3 ;FINISH UP BLINK SEQUENCE JSR PC,DOTYPE CLRB @CURABS+RWSIZE(R5) ; FORGET THAT LOCATION IN MAP RTS PC SPLCHR: .ASCII <340>/^^^^^^^^/ .BYTE 342,345,351,343,344 .ASCII /^^^^^^^^^^^^^$^^^^/ GRAFON: .BYTE ESC,'(,'0,200 GRFOFF: .BYTE ESC,'(,'B,200 .EVEN .ENABL LSB SETCUR: MOV R0,-(SP) ;SAVE R0 MOV BUSTRT+RWSIZE(R5),R0 ;GET LINE NUMBER CMP R0,PRELIN+RWSIZE(R5) ;IS THIS THE RIGHT LINE? BNE 10$ ;BRANCH IF NOT, MUST SET CURSOR MOV #24.,R0 ;SET TO NOT VERTICALLY POSITION CURSOR ;VUE ;USE 24. EVEN THO V.SIZE MAY VARY. ;VUE ;THIS IS TO HELP STOP VT52 FROM FLICKER CMP R2,PRECOL+RWSIZE(R5) ;ARE WE AT RIGHT CURSOR POSITION? BEQ 30$ ;BRANCH IF YES, DON'T MOVE IT 10$: MOV BUSTRT+RWSIZE(R5),PRELIN+RWSIZE(R5) ;SAVE CURSOR POS ON SCREEN MOV R2,PRECOL+RWSIZE(R5) ; BOTH LINE AND COLUMN MOV R3,-(SP) ;SAVE R3 OVER SEQUENCES MOV #DIRSEQ,R3 ;POINT TO DIRECT CURSOR ADDRESS CODE JSR PC,DOTYPE ; AND OUTPUT IT ADD #40,R0 ;ADJUST LINE NUMBER JSR PC,TYPEBF ; AND OUTPUT IT MOV R2,R0 ;NOW SET COLUMN NUMBER ADD #40,R0 ;ADJUST COLUMN NUMBER JSR PC,TYPEBF ; AND OUTPUT IT 20$: MOV (SP)+,R3 ;RESTORE R3 30$: MOV (SP)+,R0 ;RESTORE R0 RTS PC ; AND EXIT DOSEQ: JSR PC,SETCUR ;SET UP THE CURSOR DOTYPE: MOV R0,-(SP) ;SAVE R0 MOV R3,-(SP) ; AND R3 40$: MOVB (R3)+,R0 ;GET A CHARACTER ASLB R0 ;IS IT THE ENDING 200? BEQ 20$ ;YES ASR R0 ;NO, RESTORE CHARACTER JSR PC,TYPEBF ;ELSE BUFFER IT BR 40$ ; AND CONTINUE .DSABL LSB .GLOBL RWSIZE, TYPEBF RTRANS: .WORD VTCHAR, VTBLNK, 0 FTRANS: .WORD FCHAR, FBLNK, 0 MOVTBL: .WORD 000000*H.SIZE, 000000 ;VUE $$$$$$ = 1 .REPT V.SIZE/2 .WORD +$$$$$$*H.SIZE, +$$$$$$ ;VUE .WORD -$$$$$$*H.SIZE, -$$$$$$ ;VUE $$$$$$ = $$$$$$+1 .ENDR MOVTBE: SEQS: .WORD OVRSEQ,EOBSEQ EOBSEQ: .BYTE ESC,'F,'@+40,ESC,'G,200 OVRSEQ: .BYTE ESC,'F,'H+40,ESC,'G,200 CLNSEQ: .BYTE ESC,'K,200 DIRSEQ: .BYTE ESC,'Y,200 EEOSEQ: .BYTE ESC,'J,200 LFSEQ: .BYTE LF,200 REVSEQ: .BYTE ESC,'I,200 CCASEQ: .BYTE ESC,'Y,37+19.,37+1,ESC,'J,200 ;VUE PTRSQ1: .ASCII //[1;5;7/<155><200> ;VUE PTRSQ2: .BYTE ESC,'[,'0,'M+40,ESC,'[,'?,'2,'L+40,200 ;VUE .ENABL LC ;SHOULDA DONE THIS A LONG TIME AGO !! LINSEQ: .ASCII /Fqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq/ .ASCII /qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq/ .BYTE ESC,'G,CR,LF,200 .EVEN ; THE LAYOUT OF THE READ/WRITE REGION .ASECT . = 0 OUTCHR: .BLKW ;OUTPUT A CHARACTER OUTBLN: .BLKW ;END OF LINE OR BUFFER CLEANER RTMOST: .BLKW ;INITED TO ZERO AS END OF LIST BUSTRT: .BLKW ;LINE COUNTER, INITED TO ZERO LINPTR: .BLKW ;CHAR COUNTER (P) OF LINE STARTS SVSTRT: .BLKW ;SAVED LINE COUNTER INITFL: .BLKW ;>=0 IMPLIES UNKNOWN SCREEN STATE BUINDX: .BLKW ;CONTAINS LINE INDEX INTO SCREEN MAP CURLIN: .BLKW ;CONTAINS LINE NUMBER OF CURSOR CURCHR: .BLKW ;CONTAINS COLUMN NUMBER OF CURSOR CURABS: .BLKW ;CONTAINS ABSOLUTE MAP POSITION OF CURSOR UNDERC: .BLKW ;CHARACTER POS OF UNDER SCORE PRELIN: .BLKW ;LAST SET LINE TO SCREEN PRECOL: .BLKW ;LAST SET COLUMN TO SCREEN CHCKBL: .BLKW ;FLAG WORD .BLKB H.SIZE ;ROOM FOR CHARS ;VUE MAPST: .BLKB H.SIZE*V.SIZE ;LAST KNOWN SCREEN ;VUE MAPND: ;END OF SCREEN MAP SCRWSZ: ;SIZE OF READ/WRITE REGION .END