.TITLE SCREEN "WATCH" FOR TECO-11 .IDENT /M34C/ ; ; Screen handling subroutine for video TECO. ; This version is a modification of the screen handler ; for V28 TECO. Modifications include V34 retrofit, ; table driven device characteristics, and :W support. ; 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 = 24. ;VERTICAL SIZE .IF NDF I$$MUL .MACRO MUL SRC,REG .IF DIF , MOV SRC,R0 .ENDC .IF DIF , MOV REG,R1 .IFTF CALL $MUL .IFT MOV R1,REG .ENDC .ENDM .ENDC .SBTTL Dispatch table for special functions .PSECT PURE,D,RO,CON WOPTAB: .WORD TERMTP ; Terminal typer .WORD SCWDTH ; Screen width .WORD SCHITE ; Screen Height .WORD SEEALL ; SEEALL mode .WORD MARKME ; Set mark routine .WORD HOLDMD ; Hold mode routine .WORD ULHCPS ; Screen placement stuff .WORD INSCHR ; Gather line of text stuff WOPTL = .-WOPTAB .PSECT CODE,I,RO,CON ; ; All the special functions which are as yet unsupported here. ; SCWDTH: SCHITE: SEEALL: MARKME: HOLDMD: ULHCPS: MOV #-1,R0 ; Claim bad command RTS PC .SBTTL SCOPE "WATCH" ROUTINE WATCH:: TST NFLG(R5) ; Is this a special window call? BPL 5$ ; If NE, no. go do display stuff ASL R0 ; Make arg into word offset CMP R0,#WOPTL ; Test against maximum argument BGE 7$ ; If too big, go complain JMP @WOPTAB(R0) ; Else go do whatever ; 7$: .IF DF D$$BUG BPT ; Deliberate trap if debugging .ENDC MOV #-1,R0 ; If bad arg, return -1 RTS PC ; Go back to caller ; 5$: TST $DIR ;CHECK FOR SCREEN OVERLAY BEQ 10$ ;IF NO SCREEN, FORGET IT MOV R0,BUSTRT ;SAVE THE CALLING ARGUMENT BEQ 10$ ;IF ARG=0, IGNORE IT BPL 15$ ;IF ARG >0, SET CURSOR LINE TST $CLN ;CHECK IF WE CAN NICELY CLEAN BNE 20$ ;IF NE, WE CAN CMP R0,#-10. ;ELSE CHECK SOME REASONABLE LIMIT BGT 20$ ;IF GT, TOO MESSY SO FORGET CLR INITFL ;ARG >=0, FORGET THE ENTIRE SCREEN 10$: RTS PC ;EXIT 15$: MOV R0,NWATCH(R5) ;SET CURSOR LINE RTS PC ;DONE FOR NOW 20$: MOV NWATCH(R5),R0 ;RESTORE ARGUMENT TO OLD ARGUMENT JSR R4,SAVREG ;SAVE ALL REGISTERS MOV BUSTRT,R0 ;GET CALLING ARGUMENT BACK AGAIN COM R0 ;MAKE COUNT OF CHANGED LINES POSITIVE BEQ DOIT ;BRANCH IF NO SPECIAL SCREEN MODS MOV #24.,R1 ;PUT MAXIMUM LEGAL COUNT INTO ODD REG CMP R0,R1 ;IS ARGUMENT OVER MAXIMUM? BHI 30$ ;YES, USE MAXIMUM MOV R0,R1 ;NO, USE ARGUMENT 30$: MUL #40.,R1 ;MULTIPLY LINE COUNT BY 40. TO GET WORDS MOV #MAPST,R0 ; Get a pointer to the map 40$: CLR (R0)+ ;CLEAR WHAT WE THINK IT LOOKS LIKE SOB R1,40$ ; FOR THAT MANY LINES MOV #-1,PRELIN ;CLOBBER LAST KNOWN CURSOR CLR OUTDNE(R5) ;RESET THE OUTPUT OCCURRED FLAG RTS PC ; AND EXIT 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 Y$SIZE,R0 ;SET THE SCREEN'S SIZE MOV NWATCH(R5),-(SP) ;GET THE STANDARD CURSOR LINE NUMBER BEQ 10$ ;ZERO, MAKE IT VALID CMP R0,(SP) ;MIGHT BE VALID, CHECK UPPER LIMIT BGE 20$ ;IT IS VALID, USE IT 10$: MOV #16.,(SP) ;USE A DEFAULT STANDARD IF INVALID 20$: SUB BUSTRT,R0 ;CALC LINE NUMBER OF CURSOR LINE CMP R0,(SP) ;SHOULD WE USE THE CALCULATED VALUE? BLOS 30$ ;NOPE, USE STANDARD MOV R0,(SP) ;YEP, USE CALCULATED 30$: MOV #CHCKBL,R2 ;GET POINTER TO CHECKING BUFFER MOV R2,-(SP) ;SAVE START OF THE BUFFER CLR (R2) ;INDICATE NO FUDGE MOVEMENT INITIALLY TST OUTDNE(R5) ;HAS ANY TERMINAL OUTPUT BEEN DONE? BEQ 40$ ;NOPE CLR INITFL ;YEP, INDICATE SCREEN UNKNOWN 40$: TST INITFL ;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 LINES: MOV #FCHAR,OUTCHR ;RESET OUTPUT ROUTINE MOV P(R5),LINPTR ;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,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 ;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 ; AND SET STARTING FILL IN POINTER MOV #CCHAR,OUTCHR ; AND CHANGE THE OUTPUT ROUTINE MOV #40.,R0 ;SET SIZE OF BUFFER IN WORDS 10$: MOV (PC)+,(R2)+ ;BLANK THE .BYTE SPACE,SPACE SOB R0,10$ ; WHOLE BUFFER 20$: MOV BUSTRT,SVSTRT ;SAVE STARTING VALUE JSR PC,DOTEXT ;FORMAT A LINE MOV BUSTRT,R0 ;GET FINISHING LINE NUMBER TST CHCKBL ;DOES CHECKING BUFFER LINE NEED SETTING? BPL 30$ ;NOPE MOVB R0,CHCKBL+1 ;YEP, SO SAVE LINE NUMBER 30$: CMP R0,2(SP) ;WOULD WE BE AT TOP? BLO LINES ;BRANCH IF NOT MOV SVSTRT,BUSTRT ;RESTORE CORRECT VALUE 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,R1 ;GET ENDING "BUSTRT" VALUE SUB R0,R1 ;CALCULATE THE BUFFERED LINE NUMBER MUL #80.,R1 ;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,R1 ;INDEX TO SCREEN MAP MOV R2,R3 ;SET POINTER TO CHECK BUFFER MOV #40.,R0 ; AND LOAD A COUNTER 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 Y$SIZE,BUSTRT ;ASSUME WE ARE GOING UP DEC BUSTRT ; Row 1 is Row # 0 MOV $LFSEQ,R3 ;SEQUENCE TO RAISE SCREEN MOV R1,R4 ;SAVE THAT MOVE COUNT BEQ OUTPUT ;NO MOVEMENT, SO QUIT BPL 30$ ;ASSUMPTION RIGHT CLR BUSTRT ;FIX TO LOWER SCREEN MOV $REV,R3 ;GET REVERSE SEQUENCE BEQ OUTPUT ;IF NO SEQUENCE, JUST REWRITE SCREEN NEG R4 ;MAKE COUNT POSITIVE 30$: JSR PC,DOSEQ ;POSITION THE SCREEN SOB R4,30$ ; THE CORRECT NUMBER OF TIMES MOV #MAPST,R2 ;SET POINTER TO START OF MAP MOV R2,R3 ;BUILD POINTER ADD #MAPND-MAPST,R3 ; TO END OF MAP MUL #80.,R1 ;CALC OFFSET TO START MOVE FROM .IF NDF I$$MUL TST R1 ; Set flags in case software MUL .ENDC 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,R3 ;DID WE MOVE LAST DATA BYTE? BLO 40$ ;BRANCH IF NOT 50$: MOV (PC)+,(R2)+ ;FILL REMAINDER WITH BLANKS .BYTE SPACE,SPACE CMP R2,R3 ;ARE WE AT END OF TABLE? BLO 50$ ;BRANCH IF NOT BR OUTPUT ;ELSE DONE SHIFTING 60$: ADD R3,R1 ;POINT TO END OF DATA TO BE MOVED 70$: MOV -(R1),-(R3) ;MOVE THE DATA CMP R1,R2 ;ARE WE AT THE TOP? BHI 70$ ;BRANCH IF NOT 80$: MOV (PC)+,-(R3) ;BLANK FILL REMAINDER .BYTE SPACE,SPACE CMP R3,R2 ;ARE WE AT TOP? BHI 80$ ;BRANCH IF NOT OUTPUT: TST (SP)+ ;JUNK THE STACK ITEM JSR R4,SETJSR ;SET UP FOR .WORD RTRANS ; THE REAL OUTPUT MOV LINPTR,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,BUINDX ;INIT THE INDEX INTO THE MAP TST INITFL ;DO WE KNOW THE STATE OF THE SCREEN? BMI 10$ ;BRANCH IF YES CLR R2 ;CLEAR THE COLUMN NUMBER MOV #-1,PRELIN ;CLOBBER LAST KNOWN CURSOR MOV $ZAP,R3 ;GET SEQUENCE TO ZAP SCREEN JSR PC,DOTYPE ;OUTPUT THE SEQUENCE MOV BUINDX,R0 ;PICK UP BUFFER START MOV #/2,R3 ;GET LENGTH OF MAP 5$: MOV (PC)+,(R0)+ ;CLEAR OUT O COUPLE .BYTE SPACE,SPACE SOB R3,5$ ;LOOP OVER MAP 10$: MOV (SP),P(R5) ;FINALLY REFIX POINTER ADD TXSTOR(R5),(SP) ;COMPUTE CURSOR POINTER MOV (SP),UNDERC ;SAVE POSITION OF UNDER SCORE MOV Y$SIZE,CURLIN ;PRESET CURSOR AT END OF MOV X$SIZE,CURCHR ; SCREEN DEC CURLIN ; Offset 0 for line DEC CURCHR ; Offset 0 for column JSR PC,DOTEXT ;NOW REALLY UPDATE THE SCREEN MOV CURLIN,BUSTRT ;SET THE LINE FOR CURSOR MOV CURCHR,R2 ;SET THE COLUMN JSR PC,SETCUR ;MOVE THE CURSOR MOV (SP)+,R0 ;GET ABS CURSOR LOCATION TST P(R5) ;IS CURSOR AT START OF TEXT? BEQ 20$ ;YES, CANNOT BE AFTER ANYTHING... CMPB -(R0),#CR ;IMMEDIATELY AFTER A ? BNE 20$ ;NOPE MOV $CUR,R3 ;YEP, SET FANCY SEQUENCE JSR PC,DOTYPE ; AND OUTPUT IT CLRB @CURABS ; BUT FORGET THAT LOCATION IN THE MAP 20$: JSR PC,TYPEBC ;FORCE OUT ANY PARTIAL BUFFER MOV #-1,INITFL ;NOW WE KNOW WHAT'S ON THE SCREEN CLR OUTDNE(R5) ;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 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 ;PUT OVERFLOW "CHARACTER" THERE BR 40$ ;THEN CONTINUE 20$: INC (SP) ;REMEMBER TO GET THE CHARACTER AGAIN MOV R2,RTMOST ;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 ;OUTPUT OVERFLOW "CHARACTER" MOV #SPACE,R0 ;FOLLOW IT WITH A 30$: JSR PC,@OUTCHR ;OUTPUT CHARACTER 40$: CMP R4,UNDERC ;IS THIS WHERE THE CURSOR BELONGS? BNE 50$ ;BRANCH IF NOT MOV R1,CURABS ;SAVE ABSOLUTE POSITION IN MAP MOV BUSTRT,CURLIN ;SAVE THE LINE NUMBER MOV R2,CURCHR ;SAVE THE COLUMN NUMBER CMP R2,X$SIZE ; Is the column number illegal? BLO 50$ ; If LO, no. MOV X$SIZE,CURCHR ; Else fix it DEC CURCHR ; Offset 0 for column 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 BIC #^C<177>,R0 ;Mask off high (special) bit 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 ;SAVE RIGHT MOST COLUMN ON LINE BLOS 70$ ;BRANCH IF NOT AT IT MOV R2,RTMOST ;SAVE IT FOR CLEARING REMAINDER 70$: CLR R2 ;RESET COLUMN COUNTER MOV BUINDX,R1 ;SET POINTER INTO MAP BR 40$ ; AND CONTINUE 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 ;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 ;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,X$SIZE ;YEP, ANY ROOM LEFT ON THIS LINE? BGE 140$ ;SORRY, NO ROOM LEFT MOV #201,R0 ;ROOM, SET END OF BUFFER "CHARACTER" JSR PC,@OUTCHR ; AND OUTPUT IT 140$: TST (SP)+ ;JUNK THE CHARACTER COUNTER MOV $EEO,R3 ;SET EOS SEQUENCE FOR BLANKING MOV #MAPND,R0 ;POINT TO END OF SCREEN MAP JMP @OUTBLN ;CALL BLANKER FOR REST OF SCREEN NEWLIN: MOV R0,-(SP) ;SAVE FOR LATER MOV R2,-(SP) ;ALSO SAVE COLUMN POSITIN MOV BUINDX,R0 ;CALCULATE END OF ADD #80.,R0 ; LINE POINTER MOV $CLN,R3 ;SET SEQ TO CLEAR ONLY THIS LINE JSR PC,@OUTBLN ;ERASE THE REMAINDER OF LINE IF ANYTHING CLR RTMOST ;CLEAR IT FOR NEW LINE MOV R0,BUINDX ;UPDATE TO NEW LINE ON SCREEN FACE INC BUSTRT ;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,Y$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 ;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,Y$SIZE ;'BHIS' BRANCHES IF AT BOTTOM RTS PC ;RETURN SETJSR: MOV #OUTCHR,R3 ;GET ADDRESS OF FIRST VECTOR 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 VTBLNK: MOV R1,-(SP) ;SAVE MOV R2,-(SP) ; WORK MOV R4,-(SP) ; REGS MOV R0,-(SP) ;ADDRESS TO STOP AT CMP R2,RTMOST ;CHECK FOR RIGHTMOST USED COLUMN BHIS 10$ ;R2 IS RIGHT MOV RTMOST,R2 ;FIX R2 10$: MOV BUINDX,R1 ;GET ADDRESS OF CURRENT LINE ADD R2,R1 ;POINT TO WHERE WE ARE IN BUFFER TST R3 ;CHECK IF SEQUENCE EXISTS BEQ 70$ ;GO CLEAR WITH SPACES IF NOT MOV #-1,R4 ;SET FLAG TO CLEAR EOS IF NEEDED 20$: CMP R1,(SP) ;ARE WE AT END YET? BGE 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 70$: CMP R1,(SP) ;ARE WE AT END YET? BHIS 60$ ;IF HIS, YES. SO STOP CMP R2,#H.SIZE-1 ;RUNNING OFF LINE? BGT 80$ ;IF GT, YES. GO FIX LINE MOV #SPACE,R0 ;ELSE GET A SPACE JSR PC,@OUTCHR ;SPIT IT OUT BR 70$ ;GO FOR MORE 80$: INC BUSTRT ;ANOTHER LINE, ANOTHER PENNY CLR R2 ;START LINE IN COLUMN 0 BR 70$ ;TRY THIS ONE AGAIN 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 CLRB (R1) ;FORGET WE KNEW IT ASLB R0 ;SPECIAL, MAKE INTO AN INDEX MOV SEQS(R0),R3 ; AND GET THE SEQUENCE POINTER MOV (R3),R3 ;NOW POINT TO THE SEQUENCE JSR PC,DOTYPE ; AND OUTPUT IT BR 20$ ;THEN CONTINUE 10$: JSR PC,TYPEBF ;NOW SEND CHARACTER 20$: INC PRECOL ;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 ;SPECIAL, SAY THIS LINE NOT FILLED FBLNK: MOV #FCHAR,OUTCHR ;RESET THE OUTPUT ROUTINE 10$: RTS PC ;THEN RETURN .DSABL LSB .ENABL LSB SETCUR: MOV R0,-(SP) ;SAVE R0 MOV R1,-(SP) ;SAVE VOLATILE REGISTERS MOV R2,-(SP) MOV R3,-(SP) MOV BUSTRT,R0 ;GET LINE NUMBER CMP R0,PRELIN ;IS THIS THE RIGHT LINE? BNE 10$ ;BRANCH IF NOT, MUST SET CURSOR CMP R2,PRECOL ;ARE WE AT RIGHT CURSOR POSITION? BEQ 30$ ;BRANCH IF YES, DON'T MOVE IT .IF DF I$$MUL ; ; Here we move the cursor along the same line it is currently ; on. This version uses the cheapest move possible, either by ; direct cursor addressing, or by incremental moves. ; MOV R2,R1 ;HOLD NEW COLUMN POSITION SUB PRECOL,R1 ;FORM LENGTH TO MOVE BMI 5$ ;IF MOVING BACKWARDS... TST $CRT ; Can we do an incremental move? BEQ 10$ ; If EQ, no. MOVB @$CRT,R3 ;PICK UP INCREMENTAL LENGTH MUL R1,R3 ;MAKE COST OF INCREMENTAL MOVE CMPB @$DIR,R3 ;COMPARE COSTS BLOS 10$ ;IF LE, DIRECT IS CHEAPER MOV $CRT,R3 ;PICK UP STRING 15$: JSR PC,DOTYPE ;OUTPUT THE STRING INC PRECOL ;COUNT THIS MOVE SOB R1,15$ ;REPEAT TIL DONE BR 30$ ;LEAVE WHEN DONE 5$: TST $CLT ; Can we do an incremental move? BEQ 10$ ; If EQ, no. NEG R1 ;MOVING BACKWARDS MOVB @$CLT,R3 ;GET INCREMENTAL LENGTH MUL R1,R3 ;COST OF INCREMENTAL MOVE CMPB @$DIR,R3 ;COMPARE COSTS BLOS 10$ ;IF LE, DIRECT IS CHEAPER MOV $CLT,R3 ;PICK UP LEFT STRING 17$: JSR PC,DOTYPE ;OUTPUT IT DEC PRECOL ;COUNT THIS MOVE SOB R1,17$ ;REPEAT TIL DONE BR 30$ ;AND LEAVE .ENDC ; ; At this point we have determined that a direct cursor move ; must be done. The address is moved into the addressing ; string and output. ; 10$: MOV BUSTRT,PRELIN ;SAVE CURSOR POS ON SCREEN MOV R2,PRECOL ; BOTH LINE AND COLUMN MOV $DEC,R1 ; Get the addressing type. BIC #1,R1 ; Clear the decimal/binary flag. BEQ 11$ ; If EQ, internal mapping. ; ; Here we have determined that something strange must be done ; to accomodate direct cursor addressing for this CRT. Go call ; the external routine to do it. ; ; The arguments for the call are as follows: ; ; R2 -- Desired X position on screen ; BUSTRT -- Desired Y position on screen ; ; R0-3 are scratch and may be destroyed by the cursor routine. ; Routine DOTYPE is available to do the output. ; CALL (R1) ; Else do it externally. BR 30$ ; And merge ahead to exit. 11$: TST $DEC ;DECIMAL ADDRESSING? BEQ 20$ ;IF EQ, OLD FASHIONED BINARY MOV R2,R1 ;GET X POSITION ADD $XBIAS,R1 ;BIAS IT FOR SCREEN MOV X$POS,R0 ;PLACE TO CONVERT INTO MOV #15012,R2 ;3 DIGITS, NO ZERO SUPPRESS CALL $CBTA ;CONVERT IT MOV BUSTRT,R1 ;PICK UP LINE NUMBER ADD $YBIAS,R1 ;BIAS IT FOR SCREEN MOV Y$POS,R0 ;POINT TO STRING LOC MOV #15012,R2 ;3 DIGITS, NO ZERO SUPPRESS CALL $CBTA ;CONVERT IT BR 25$ 20$: ADD $YBIAS,R0 ;ADD INSCREEN ADDRESS BIAS MOVB R0,@Y$POS ;STICK IN THE Y ADDRESS MOV R2,R0 ;GET X ADDRESS ADD $XBIAS,R0 ;ADD IN SCREEN BIAS MOVB R0,@X$POS ;PUT ADDRESS INTO SEQUENCE 25$: MOV $DIR,R3 ;POINT TO STRING JSR PC,DOTYPE ;OUTPUT CURSOR SEQUENCE 30$: MOV (SP)+,R3 ;RESTORE R3 MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 ;RESTORE R0 RTS PC ; AND EXIT DOSEQ: JSR PC,SETCUR ;SET UP THE CURSOR ; ; DOTYPE may be called by an external CRT addressing routine. ; ; Arguments are: ; ; R3 -- pointer to string ; DOTYPE::MOV R0,-(SP) ;SAVE R0 MOV R1,-(SP) ;SAVE R1 MOV R3,-(SP) ;SAVE R3 CLR R1 ;R1 WILL BE A WORD BISB (R3)+,R1 ;GET COUNTER 40$: MOVB (R3)+,R0 ;GET A CHARACTER JSR PC,TYPEBF ;PUT IT OUT SOB R1,40$ ;DO UNTIL DONE MOV (SP)+,R3 MOV (SP)+,R1 ;RETRIEVE R MOV (SP)+,R0 ;RETRIEVE R0 RTS PC ;GO AWAY .DSABL LSB RTRANS: .WORD VTCHAR, VTBLNK, 0 FTRANS: .WORD FCHAR, FBLNK, 0 MOVTBL: .WORD 000000*80., 000000 $$$$$$ = 1 .REPT V.SIZE/2 .WORD +$$$$$$*80., +$$$$$$ .WORD -$$$$$$*80., -$$$$$$ $$$$$$ = $$$$$$+1 .ENDR MOVTBE: SEQS: .WORD $OVR,$EOB .EVEN .END