.TITLE SCREEN VT52 SCREEN FORMAT/CONTROL .NLIST MEB,BEX ;+ ; ; SCREEN IS A SET OF FORTRAN CALLABLE ROUTINES TO ENABLE THE ; PROGRAM CONTROL OF THE VT52. ; ; CALLING SEQUENCE: CALL SCREEN(FCN,P1,P2,ERCODE) ; ; WHERE: ; FCN = SCREEN CONTROL CODE ; P1 = PARAMETER 1 ; P2 = PARAMETER 2 ; ERCODE = SCREEN ROUTINES ERROR RETURN CODES ; ( DSW C BIT SET ON ERROR RETURN) ; ; 1 = SUCCESS ; 0 = RSX DSW ERROR CODE MAY BE FOUND IN P2 ; -1 = ILLEGAL NUMBER OF ARGUEMENTS IN CALL ; -2 = ILLEGAL CONTROL CODE ; -3 = ILLEGAL P1 VALUE ; -4 = ILLEGAL P2 VALUE ; -5 = REQUESTED CURSOR WOULD BE OFF SCREEN ; -6 = ILLEGAL LUN ; -7 = ILLEGAL EVENT FLAG ; ; NOTE: ALL CALLS TO SCREEN MUST CONTAIN 4 PARAMETERS, ALTHOUGH 1 OR ; MORE OF THESE PARAMETERS MAY NOT BE USED IN A PARTICULAR ; FUNCTION. ; ;- .PAGE .SBTTL DATA AREA .MCALL QIO$S,QIOW$S,SMACIT SMACIT ; EQUATED SYMBOLS ; LST$$=1 ; EXPAND LISTINGS IF DEFINED ; ZERO = 37 ; VT52 LINE AND COLLUMN ORIGIN ESC CODE ORIGIN = 1 ; X AND Y ORIGIN LSTCOL = 80. ; LAST COLLUMN (X) MIDCOL = 40. ; MIDDLE COLLUMN LSTROW = 24. ; LAST ROW (Y) ; TABLE: ; TAB POSITION LIST .WORD 0 ; TAB 0 .WORD 9. ; 1 .WORD 17. ; 2 .WORD 25. ; 3 .WORD 33. ; 4 .WORD 41. ; 5 .WORD 49. ; 6 .WORD 57. ; 7 .WORD 65. ; 8. .WORD 73. ; 9. ; PRMLST: ; HOLDS INTERNAL VALUES .WORD 0 ; ATTACHED FLAG .WORD 0 ; LUN .WORD 0 ; EFN .WORD 0 ; XPOS .WORD 0 ; YPOS ; BUFFER: .BLKB 80. ; OUTPUT BUFFER BUFMAX =.-BUFFER ; SIZE OF BUFFER BUFPTR: .WORD 0 ; POINTS INTO BUFFER BUFCNT: .WORD 0. ; BUFFER IN USE COUNTER TEMP: .WORD 0. ; TEMP STORAGE ; HOMEC: .BYTE 33,'H ; HOME SEQ CLEFT: .BYTE 33,'D ; BACKSPACE CRIGHT: .BYTE 33,'C ; CURSOR RIGHT CDOWN: .BYTE 33,'B ; CURSOR DOWN REVLF: .BYTE 33,'I ; REVERSE LF CUP: .BYTE 33,'A ; CURSOR UP ADC: .BYTE 33,'Y ; ADDRESS CURSOR ERL: .BYTE 33,'K ; ERASE TO END OF LINE ERS: .BYTE 33,'J ; ERASE TO END OF SCREEN .PAGE .SBTTL SCREEN ENTRY POINT .GLOBL SCREEN ;+ ; ** - SUBROUTINE SCREEN ENTRY POINT ; ; PURPOSE: CHECK FOR LEGAL PARAMETERS AND DISPATCH TO CORRECT ROUTINE. ;- SCREEN: ; ENTRY POINT CALL $SAVALL ; SAVE R0-R5 ; CHECK TO SEE IF CORRECT NUMBER OF PARAMETERS BEGIN CHECK IF (R5) EQ #4 LEAVE CHECK ; IF 4, THEN OK IF (R5) EQ #0 ; IF NOT 4, ANY? RETURN ELSE LET @2(R5) := #-1 ; CAN ONLY SET CODE IN FCN PARM RETURN END END CHECK LET R4 := #PRMLST ; GET INTERNAL PARAMETER LIST TST (R5)+ ; GET R5 PAST ARGS WORD IF (R4) EQ #0 AND @(R5) NE #0 ;IF NOT ATTACHED, FCN MUST BE ATTACH LET @6(R5) := #-2 ; SET ILLEGAL FUNCTION CODE RETURN END LET R0 := @(R5) L.SHIFT 1 ; MULTIPLY FCN BY 2 IF R0 HI #MAXFCN ; BE SURE WE DON'T JUMP INTO NOWHERE LET @6(R5) := #-2 ; GET ERROR CODE JUMPTO ERROR ; AND QUIT END LET @6(R5) := #1 ; INITIALLY SET SUCCESS CODE JMP @DISPAT(R0) ; JUMP TO CORRECT ROUTINE .PAGE .SBTTL DISPATCH TABLE DISPAT: ; ; ADDRESS CODE OFFSET FUNCTION .WORD ATTDET ;0 0 ATTATCH/DETTACH .WORD HOME ;1 2 CURSOR HOME .WORD BOL ;2 4 CURSOR BEGINNING OF LINE .WORD MOL ;3 6 " MIDDLE OF LINE .WORD EOL ;4 8. " END OF LINE .WORD SR ;5 10. CURSOR SPACE RIGHT .WORD SL ;6 12. CURSOR SPACE LEFT .WORD TAB ;7 14. HORIZONTAL TAB .WORD UPC ;8. 16. CURSOR UP .WORD DNC ;9. 18. CURSOR DOWN (LF) .WORD BOLL ;10. 20. CURSOR BOTTOM LEFT .WORD BLS ;11. 22. BLANK SCREEN .WORD CEOL ;12. 24. CLEAR TO END OF LINE .WORD CEOS ;13. 26. CLEAR TO END OF SCREEN .WORD FND ;14. 28. FIND X,Y CURSOR POSITION .WORD DIRECT ;15. 30. SET CURSOR X,Y .WORD PSTRNG ;16. 32. WRITE STRING MAXFCN = .-DISPAT ; MAXIMUM OFFSET INTO TABLE .PAGE .SBTTL MAIN ROUTINES ;+ ; * - ATTDET: ATTACH/DETACH SCREEN ; ; FCN 0 ; P1 = LOGICAL UNIT NUMBER (LUN) ; P2 = EVENT FLAG ;- ATTDET: LET R1 := @2(R5) ; GET LUN IF R1 LE #0 LET @6(R5) := #-6 ; SET ERROR CODE JUMPTO ERROR END IF (R4) EQ #-1 ; IF ATTACHED LET (R4) := #0 ; CLEAR ATTACHED FLAG QIO$S #IO.DET,R1 ; DETACH TERMINAL RETURN ; AND GO AWAY ELSE ; IF NOT ATTACHED LET 2(R4) := R1 ; SAVE LUN LET 4(R4) := @4(R5) ; SAVE EVENT FLAG LET (R4) := #-1 ; SET ATT/DET FLAG TO ATTACHED QIO$S #IO.ATT,R1 ; ATTACH TERMINAL LET 6(R4) := #-1 ; SET XPOS TO UNKNOWN LET 8.(R4) := #-1 ; SET YPOS TO UNKNOWN LET BUFPTR := #BUFFER ; INIT BUFFER POINTER LET BUFCNT := #0 ; CLEAR COUNTER RETURN ; AND GO AWAY END ;+ ; * - HOME: CURSOR HOME ; ; FCN = 0 ; P1 = 0 CURSOR HOME, NO BLANK ; = 1 CURSOR HOME, SCREEN CLEARED ; P2 ...UNUSED ; ERCODE: ; +1 = SUCCESS ; -3 = ILLEGAL P1 VALUE ;- HOME: IF @2(R5) GT #1 OR @2(R5) LT #0 ; SWITCH CAN ONLY BE 0 OR 1 LET 6(R5) := #-3 ; SET ERROR CODE JUMPTO ERROR ; END IF 2(R5) EQ #1 ; IF WANT ERASURE ;JAN22RLM CALL BLS ; CALL BLANK SCREEN ROUTINE ELSE $CALL STUFF <#HOMEC> ; STORE IT CALL OUTPUT ; SEND STRING END RETURN ; GO AWAY ;+ ; * - BOL: CURSOR TO BEGINNING OF LINE ; ; FCN = 2 ; P1 ...UNUSED ; P2 ...UNUSED ;- BOL: LET @2(R5) := #ORIGIN ; WANT XPOS OF ORIGIN LET @4(R5) := 8.(R4) ; WANT OLD YPOS CALL DIRECT ; PLACE CURSOR RETURN ; DONE ;+ ; * - MOL: CURSOR TO MIDDLE OF LINE (COLLUMN 40.) ; ; FCN = 3 ; P1 = 0 DO NOT ERASE ; 1 ERASE ; P2 ...UNUSED ; ERCODE = +1,-3 ; ; NOTE: IF ERASURE SET, SCREEN IS BLANKED FROM CURSOR POSITION TO ; COLLUMN 40. ;- MOL: IF @2(R5) LT #0 OR @2(R5) GT #1 ; CHECK SWITCH RANGE LET @6(R5) := #-3 ; SET ERROR CODE JUMPTO ERROR ; AND DO IT END IF @2(R5) EQ #1 ; IF WANT ERASURE LET R3 := #MIDCOL - 6(R4) ; GET NUMBER OF SPACES NEEDED IF R3 LT #0 ; NEED TO BACKSPACE? NEG R3 ; NEGATE CALL HALF ; PUT CURSOR AT C 40. $CALL SPACES ; SPACE OUT CHARACTERS CALL HALF ; BACK TO MIDDLE AGAIN ELSE $CALL SPACES ; IF GOING RIGHT, THEN JUST SPACE END ; IF NO ERASURE, THEN THE JOB IS EASY - JUST ADDRESS CURSOR ELSE CALL HALF END CALL OUTPUT ; SEND STRING RETURN ; AND DONE ;+ ; * - EOL: CURSOR TO END OF CURRENT LINE ; ; FCN = 4 ; P1 = 0 NO ERASURE ; 1 ERASE ; ; AT END OF CALL, CURSOR AT END OF CURRENT LINE. ;- EOL: IF @2(R5) GT #1 OR @2(R5) LT #0 ; CHECK SWITCH VALUE LET @6(R5) := #-3 ; SET ERROR CODE JUMPTO ERROR ; AND GET OUT END IF @2(R5) EQ #1 ; IF WANT ERASURE $CALL STUFF <#ERL> ; STORE STRING END LET @2(R5) := #LSTCOL ; SEND CURSOR TO END OF LINE LET @4(R5) := 8.(R4) ; USE SAME YPOS CALL DIRECT ; DO IT RETURN ; AND GO AWAY ;+ ; * - SR: CURSOR SPACE RIGHT ; ; FCN = 5 ; P1 = 0 NO ERASURE ; 1 ERASE CHAR AT CURRENT XPOS ; P2 = NUMBER OF SPACING DESIRED ;- SR: IF @2(R5) GT #1 OR @2(R5) LT #0 ; CHECK SWITCH VALUE LET @6(R5) := #-3 ; GET ERROR CODE JUMPTO ERROR ; AND QUIT END IF @4(R5) GT #LSTCOL-1 OR @4(R5) LT #0 ; CHECK LEGAL RANGE LET @6(R5) := #-4 ; GET ERROR CODE JUMPTO ERROR ; AND QUIT END LET R0 := 6(R4) + @4(R5) ; SEE IF WOULD GO OFF SCREEN IF R0 GT #LSTCOL LET @6(R5) := #-5 JUMPTO ERROR ; IF SO THEN QUIT END IF @2(R5) EQ #0 ; IF DON'T WANT ERASURE $CALL RL <#CRIGHT> ; AND DO IT ELSE $CALL SPACES <@4(R5)> ; SPACE AND DELETE END CALL OUTPUT ; SEND STRING RETURN ; AND GO AWAY ;+ ; * - SL: CURSOR SPACE LEFT ; ; FCN = 6 ; P1 = 0 NO ERASE ; 1 ERASE ; P2 = NUMBER OF SPACES ;- SL: IF @2(R5) GT #1 OR @2(R5) LT #0 ; CHECK SWITCH VALUE LET @6(R5) := #-3 ; GET ERROR CODE JUMPTO ERROR ; AND QUIT END IF @4(R5) GT #LSTCOL-1 OR @4(R5) LT #0 ; CHECK RANGE LET @6(R5) := #-4 ; GET ERROR CODE JUMPTO ERROR ; AND QUIT END LET R0 := 6(R4) - @4(R5) ; SEE IF WOULD GO OFF SCREEN IF R0 LT #ORIGIN LET @6(R5) := #-5 ; IF SO THEN GET ERROR CODE JUMPTO ERROR ; AND QUIT END IF @2(R5) EQ #1 ; IF WANT ERASURE $CALL RL <#CLEFT> ; MOV CURSOR TO LEFT @4(R5) SPACES $CALL SPACES <@4(R5)> ; SPACE BACK END $CALL RL <#CLEFT> ; IN ANY CASE, SPACE LEFT CALL OUTPUT ; AND SEND STRING RETURN ; AND GO AWAY. ;+ ; * -TAB: CURSOR TO NEXT TAB POS ; ; FCN = 7 ; P1 = NUMBER OF TAB POSITIONS ; P2 UNUSED ;- TAB: IF @2(R5) GT #9. OR @2(R5) LT #0 ; CHECK RANGE LET @6(R5) := #-3 ; GET ERROR CODE JUMPTO ERROR ; AND QUIT END IF 6(R4) LE #8. ; SEE IF WITHIN 1ST TAB POSITION LET R0 := #0 ; SET TABS POINTER TO 1ST TAB ELSE LET R0 := 6(R4) ; GET CURRENT XPOS LET R0 := R0 R.SHIFT 2 ; DIV BY 4. IF R0 GT #18. ; 18. IS MAX POINTER VALUE LET @6(R5) := #-5. ; SET ERROR CODE FOR OFF SCREEN JUMPTO ERROR ; AND QUIT END END ; NOW GET CORRECT COLLUMN NUMBER IN R0 $CALL TABPOS ; TABPOS WILL TAB AND UPDATE XPOS CALL OUTPUT ; SEND STRING RETURN ; DONE ;+ ; * - UPC: UP CURSOR (- VERTICAL TAB) ; ; FCN = 8. ; P1 = 0 NO ERASE ; 1 ERASE ; P2 = NUMBER OF TIMES ;- UPC: IF @2(R5) GT #1 OR @2(R5) LT #0 ; CHECK VALUE LET @6(R5) := #-3 ; GET ERROR CODE JUMPTO ERROR ; AND QUIT END IF @4(R5) GT #LSTROW-1 OR @4(R5) LT #0 ; CHECK VALUE LET @6(R5) := #-4 ; GET ERROR CODE JUMPTO ERROR ; AND QUIT END IF @4(R5) GT 8.(R4) ; CAN'T BACKUP OFF SCREEN! LET @6(R5) := #-5 ; GET ERROR CODE JUMPTO ERROR ; AND QUIT END $CALL UPDN <#CUP> ; STORE IT CALL OUTPUT ; SEND STRING RETURN ; AND DONE ;+ ; * - DNC: DOWN CURSOR ; ; FCN = 9. ; P1 = 0 NO ERASE ; 1 ERASE ; P2 = NUMBER OF TIMES ;- DNC: IF @2(R5) GT #1 OR @2(R5) LT #0 ; CHECK VALUE LET @6(R5) := #-3 ; GET ERROR CODE JUMPTO ERROR ; AND QUIT END IF @4(R5) GT #LSTROW-1 OR @4(R5) LT #0 ; CHECK RANGE LET @6(R5) := #-4 ; GET ERROR CODE JUMPTO ERROR ; AND QUIT END LET R0 := @4(R5) + 8.(R4) ; SEE IF WOULD GO OFF SCREEN IF R0 GT #LSTROW ; MUST NOT GO OFF SCREEN LET @6(R5) := #-5 ; GET ERROR CODE JUMPTO ERROR ; AND QUIT END $CALL UPDN <#CDOWN> ; STORE N DOWN CURSORS CALL OUTPUT ; OUTPUT STRING RETURN ; AND GO AWAY ;+ ; * - BOLL: SEND CURSOR TO BOTTOM LEFT (XPOS=1, YPOS=24.) ; ; FCN = 10. ; P1 UNUSED ; P2 UNUSED ;- BOLL: LET @2(R5) := #ORIGIN ; SET XPOS TO ORIGIN LET @4(R5) := #LSTROW ; SET YPOS TO LAST ROW CALL DIRECT ; ADDRESS CURSOR RETURN ; AND DONE ;+ ; * - BLS: BLANK SCREEN (HOME-CLEAR SCREEN) ; ; FCN 11. ; P1 UNUSED ; P2 UNUSED ;- BLS: $CALL STUFF <#HOMEC> ; STORE IT $CALL STUFF <#ERS> ; STORE IT CALL OUTPUT ; SEND STRING LET 6(R4) := #ORIGIN ; SET XPOS TO ORIGIN LET 8.(R4) := #ORIGIN ; SET YPOS TO ORIGIN RETURN ; DONE ;+ ; * - CEOL: CLEAR SCREEN TO END OF LINE ; ; FCN = 12. ; P1 UNUSED ; P2 UNUSED ; NOTE: CURSOR DOES NOT MOVE ;- CEOL: $CALL STUFF <#ERL> ; STORE IT CALL OUTPUT ; SEND STRING RETURN ; DONE ;+ ; * - CEOS CLEAR TO END OF SCREEN ; ; P1 UNUSED ; P2 UNUSED ; NOTE: CURSOR DOES NOT MOVE ;- CEOS: $CALL STUFF <#ERS> ; STORE IT CALL OUTPUT ; SEND STRING RETURN ; DONE ;+ ; * - FND FIND XPOS,YPOS ; ; P1 = VARIABLE THAT WILL HOLD XPOS ON RETURN ; P2 = VARIABLE THAT WILL HOLD YPOS ON RETURN ;- FND: LET @2(R5) := 6(R4) ; GET XPOS LET @4(R5) := 8.(R4) ; GET YPOS RETURN ; DONE ;+ ; * - DIRECT: DIRECT ADDRESS CURSOR ; ; P1 = NEW XPOS (COLLUMN) ; P2 = NEW YPOS (ROW) ;- DIRECT: IF @2(R5) LT #ORIGIN OR @2(R5) GT #LSTCOL ; CHECK VALUE LET @6(R5) := #-3 ; GET ERROR CODE JUMPTO ERROR ; AND QUIT END IF @4(R5) LT #ORIGIN OR @4(R5) GT #LSTROW ; CHECK VALUE LET @6(R5) := #-4 ; GET ERROR CODE JUMPTO ERROR ; AND QUIT END $CALL STUFF <#ADC> ; STORE IT LET R0 := @4(R5) ; GET LINE (YPOS) LET 8.(R4) := R0 ; TRACK YPOS LET R0 := R0 + #ZERO ; POS IS RECEIVED POS + VT52 0 LET TEMP :B= R0 ; STORE IN LOWER BYTE LET R0 := @2(R5) ; GET ADDRESS OF COLLUMN (XPOS) LET 6(R4) := R0 ; TRACK XPOS LET R0 := R0 + #ZERO ; GET REAL XPOS LET TEMP+1 :B= R0 ; STORE IN UPPER BYTE $CALL STUFF <#TEMP> ; STORE IT CALL OUTPUT ; OUTPUT IT RETURN ; AND DONE ;+ ; * - PSTRNG: PUT STRING TO CRT AND UPDATE X AND Y POS ; ; FCN = 16. ; P1 = ADDRESS OF STRING LITERAL OR ARRAY ; P2 = DUMMY TO HOLD STRING SIZE (NCHARS) ON RETURN ; NOTE: AT END OF CALL CURSOR POINTS TO SPACE FOLLOWING ; LAST CHARACTER IN STRING. ; ALSO, FOR FORTRAN CALLS STRING MUST BE A LOGICAL*1 OR BYTE ARRAY ;- PSTRNG: LET R1 := 2(R5) ; GET STRING ADDRESS LET @4(R5) := #0 ; CLEAR COUNTER BEGIN CNTLP REPEAT ; UNTIL HAVE COUNT OR ERROR IFB (R1)+ EQ #0 LEAVE LOOP ; IF FOUND EOS (0) ;JAN22RM LET @4(R5) := @4(R5) + #1 ; INCREMENT COUNTER ;**-1 IF @4(R5) GT #LSTCOL ; SEE IF STRING TOO BIG LET @6(R5) := #-3 ; GET ERROR CODE IF STRING TOO BIG JUMPTO ERROR ; AND QUIT END END CNTLP ; NOW HAVE STRING SIZE LET R1 := @4(R5) + 6(R4) ; CALCULATE WHERE CURSOR WOULD B;JAN22RLM IF R1 GT #LSTCOL ; CAN'T LET CURSOR GO OFF SCREEN LET @6(R5) := #-5 ; IF SO, GET ERROR CODE JUMPTO ERROR ; AND QUIT END LET 6(R4) := R1 ; OTHERWISE, UPDATE XPOS $CALL WRITE <@4(R5),2(R5)> ; WRITE THE STRING ;JAN22RLM RETURN ; AND DONE .PAGE .SBTTL UTILITIES ;+ ; STUFF ; INPUTS: ; R0 = ADDRESS OF 2 BYTES TO STORE IN BUFFER (CAN BE ODD). ;- STUFF: LET R1 := BUFPTR ; GET LOCATION IN BUFFER TO STORE LET (R1)+ :B= (R0)+ ; STORE A BYTE LET (R1)+ :B= (R0) ; GET THE 2ND BYTE LET BUFCNT := BUFCNT + #2 ; COUNT THE CHARACTERS IF BUFCNT GE #BUFMAX ; IF AT END OF BUFFER CALL OUTPUT ; FORCE OUTPUT ELSE LET BUFPTR := R1 ; RESTORE POINTER END RETURN ; AND DONE ;+ ; OUTPUT ; INPUTS: ; NONE ;- OUTPUT: LET R4 := #PRMLST ; BE SURE R4 POINTS TO PARAMETERS LET R0 := BUFCNT ; GET SIZE LET R1 := #BUFFER ; GET ADDRESS OF STRING LET BUFPTR := R1 ; RESET POINTER LET BUFCNT := #0 ; RESET COUNTER ; WRITE: QIOW$S #IO.WLB,2(R4),4(R4),,,, ; WRITE STRING CLC ; KEEP C CLEARED RETURN ; AND DONE ;+ ; SPACES ; INPUTS: ; R0 = NUMBER OF SPACES SPACES: LET 6(R4) := 6(R4) + R0 ; UPDATE XPOS $CALL LOOP ; INSERT SPACES INTO BUFFER CALL OUTPUT ; PRINT STRING RETURN ; DONE ;+ ; HALF ; INPUTS: NONE ;- HALF: LET @2(R5) := #MIDCOL ; SET XPOS TO MIDDLE LET @4(R5) := 8.(R4) ; USE SAME YPOS CALL DIRECT ; DO IT RETURN ; DONE ;+ ; TABPOS ; INPUTS: ; R0 = NEW COLLUMN NUMBER ; R1 = NUMBER OF TABS TO DO ;- TABPOS: LET 6(R4) := R0 ; UPDATE XPOS $CALL LOOP ; PUT TABS IN BUFFER RETURN ; DONE ;+ ; RL MOVE CURSOR RIGHT OR LEFT ; INPUTS: ; R0 = RIGHT OR LEFT ESCAPE SEQUENCE ADDRESS ;- RL: LET R3 := R0 ; GET SEQUENCE IF R3 EQ #CRIGHT LET 6(R4) := 6(R4) + @4(R5) ; ADD TO TRACK XPOS ELSE LET 6(R4) := 6(R4) - @4(R5) ; ELSE SUBTRACT TO TRACK XPOS END FOR R2 := #0 TO @4(R5) ; SEND C RIGHT @4(R5) SPACES NO DELETE $CALL STUFF ; ONE SPACE RIGHT OR LEFT END ; END OF LOOP RETURN ; DONE ;+ ; UPDN MOVE CURSOR UP OR DOWN N TIMES ; INPUTS: ; R0 = ESCAPE SEQUENCE FOR UP OR DOWN ;- UPDN: LET R3 := R0 ; GET ESCAPE SEQUENCE IF R3 EQ #UPC LET 8.(R4) := 8.(R4) - @4(R5) ; SUBTRACT TO TRACK YPOS ELSE LET 8.(R4) := 8.(R4) + @4(R5) ; ELSE ADD TO TRACK YPOS END FOR R2 := #0 TO @4(R5) ; SET UP LOOP IF @2(R5) EQ #1 ; IF WANT ERASURE $CALL DELCHR ; DELETE CHAR END $CALL STUFF ; STORE ESCAPE SEQUENCE END ; END LOOP RETURN ; AND DONE ;+ ; DELCHR BS-SPACE ; INPUTS: NONE ;- DELCHR: $CALL STUFF <#CLEFT> ; DO A BACKSPACE LET 6(R4) := 6(R4) - #1 ; TRACK XPOS $CALL SPACES <#1> ; ONE SPACE RETURN ; ;+ ; LOOP INSERT CHARACTERS INTO BUFFER. ;INPUTS: ; R0 = NUMBER OF CHARACTERS ; R1 = BYTE TO INSERT ;- LOOP: LET R4 := R1 ; SAVE THE BYTE LET R1 := BUFPTR ; GET BUFFER ADDRESS LET R3 := R0 ; GET COUNT FOR R2 := #0 TO R3 ; DO R3 TIMES IF BUFCNT GE #BUFMAX ; DON'T OVERDO IT! CALL OUTPUT ; IF SO, THEN EMPTY BUFFER NOW LET R1 := BUFPTR ; GET BUFFER AGAIN END LET (R1)+ :B= R4 ; STORE A BYTE LET BUFCNT := BUFCNT + #1 ; INCREMENT COUNTER END ; END LOOP RETURN ; AND DONE ;+ ; ERROR EXIT ;- ERROR: ; JUST EXIT WITH C SET SEC RETURN .END