.TITLE PUTSTR .IDENT /020283/ ; ; File: [22,310]PUTSTR.MAC Last edit: 17-JUL-1989 10:59:08 ; ; History: ; ; j.m.b. 020282 ; j.m.b. 022182 fix buffer overrun problem. Max instring now 80. bytes. ; this is checked, and clamped to 80. ; Add erase to EOL function. ; j.m.b. 022582 Allow zero length input string. ; J.M.B. 040382 Remove explicit P2UDAT PSECT deifinition. ; J.M.B. 020283 Sign extend byte error codes. ; ; NOTE: This version does NOT use the TTDRV cursor positioning features! ; NOTE: 040382 this only works reliably if 1)terminal buffer set to ; >=110. and 2) terminal set to NOWRAP. ; ; 17-Jul-89. Philip Hannay. Some clean up. Changed QIO flag to ; 24 (reserved for P3UTIL), and P2UDAT to Data PSECT. ; .REM | PROCEDURE PUTSTR(Lin,Col:Integer;Attributes:CRT_Attribute_set; Base:Address; Count:Integer; Save:Boolean; VAR IOSB:Integer);external; {*USER* Pascal-2 procedure to display Count characters beginning at Base on a CRT at line Lin, column Col, with display attributes Attributes. If Save is true, the cursor and CRT context are preserved across the field write. If false, the context is established by the PUTSTR parameters, and the cursor remains following the last character written. Maximum input string length is 80. bytes. Minimum input string length is 0. bytes. If Count=0, the cursor positioning, attribute setting, and save characteristics will be set up, but of course no text from Base^ will be output. If lin is negative, the entire screen will be erased prior to writing the field, which will appear at abs(lin). Column must be 00-132. lin must be 00-24. (or -24 for auto erase). If col is negative, an erase to end-of-line sequence will be generated following the string output (but before a possible cursor restore). Abs(col) will be used to position the cursor. If lin is zero, col is ignored, and no cursor positioning is done. Note that save may still be used, and will preserve CRT attrubutes across the QIO, leaving the cursor at the first byte of the string. The I/O is done on LUN 5, and efn 24, which is reserved for P3UTIL routines, is used. } | ; ; Assemble with PASMAC.MAC as prefix file. ; .MCALL QIOW$,DIR$ .ENABL LC ; ; Most of the needed DPB offsets are system-defined. Notably absent ; are QIO parameter block offsets. So here they are... ; ; QIOPL=12. ;SAME AS SYSTEM SYMBOL Q.IOPL QIOBUF=QIOPL ;BUFFER ADDX QIOSIZ=QIOPL+2 ;BUFFER SIZE QIOTMO=QIOPL+4 ;TIME-OUT VALUE (SEC) QIOVFC=QIOPL+4 ;FORMS CHAR (ON SEND) QIOTBL=QIOPL+6 ;SPECIAL-TERMINATOR TABLE ADDX QIOPRB=QIOPL+6 ;PROMPT ADDX QIOPRL=QIOPL+8. ;PROMPT SIZE QIOPVF=QIOPL+10 ;PROMPT VFC ; ; .PSECT P2UDAT,D IOSB: .BLKW 2 BUFF: .BLKB 120. ;OUTPUT BUFFER FOR QIO ; ESC=^O33 ;ESCAPE CHARACTER SCUR: .BYTE ESC,'7 ;CURSOR SAVE SEQUENCE RCUR: .BYTE ESC,'8 ;CURSOR RESTORE SEQUENCE .EVEN QIODPB: QIOW$ IO.WLB,5,24.,,IOSB,, ; ;DEFINE THE RUN-TIME ADDRESS OF BUFFER LENGTH AND VFC QIO PARAMETERS ;COLU= ;LINE= BLEN= .PSECT PROC PUTSTR PARAM LIN, INTEGER PARAM COL, INTEGER PARAM ATTS, SCALAR ; ITS REALLY A SET, KIDDIES! PARAM BASE, POINTER PARAM COUNT, INTEGER PARAM SAV, BOOLEAN PARAM ISB, ADDRESS SAVE BEGIN MOV #BUFF,R0 ;R0->OUTPUT BUFFER ; ;CHECK FOR CURSOR SAVE/RESTORE REQUEST ; SAVT: TSTB SAV(SP) ;SAVE/RESTORE SEQUENCE? BEQ 1$ ;BR IF NOT MOVB SCUR,(R0)+ ;SAVE CURSOR SEQUENCE TO BUFFER MOVB SCUR+1,(R0)+ 1$: ; ;CHECK FOR ERASE SCREEN REQUEST, AND CURSOR POSITION REQUEST ; MOV LIN(SP),R1 ;LINE PARAMETER BEQ ATCK ;BR IF NO CURSOR POSITIONING REQD BGT CURP ;NO ERASE REQUEST NEG R1 ;ERASE REQUESTED, RESTORE LINE PARAM TO >0 MOVB #ESC,(R0)+ ;STUFF ERASE SEQUENCE TO BUFFER MOVB #'[, (R0)+ MOVB #'2,(R0)+ MOVB #'J,(R0)+ CURP: MOVB #ESC,(R0)+ ;SET UP CURSOR POSITION SEQUENCE MOVB #'[,(R0)+ CLR R2 ;SET UP TO CONVERT LINE TO ASCII ;R1=LINE IN BINARY >0 CALL $CBDMG ;CONVERT TO 1-5 ASCII. (WE DON'T CHECK RANGE!) MOVB #';,(R0)+ ;CONTINUE CURSOR SEQUENCT MOV COL(SP),R1 ;R1=COLUMN PARAMETER BPL 1$ ; MAKE IT ABSOLUTE NEG R1 1$: CLR R2 ;SET UP TO CONVERT IT TO ASCII CALL $CBDMG ;CONVERT TO ASCII IN OUTPUT BUFF MOVB #'H,(R0)+ ;COMPLETE CURSOR POSITION SEQUENCE ;CHECK FOR ATTRIBUTES... ATCK: MOVB ATTS(SP),R1 ;R1=BIT SET OF CRT ATTRIBUTES BIT #^O37,R1 ;NULL ATTRIBUTES? BEQ NOATT ;BR IF NONE ; ;NOW SET UP THE ATTRIBUTE SEQUENCE ; MOVB #ESC,(R0)+ MOVB #'[,(R0)+ ; ;CHECK EACH ATTRIBUTE, AND STUFF IT'S CHARACTER ; BIT #1,R1 ;STANDARD? BEQ 2$ ;BR IF NOT MOVB #0,(R0)+ MOVB #';, (R0)+ 2$: BIT #2,R1 ;BOLD? BEQ 3$ ;BR IF NOT MOVB #'1,(R0)+ MOVB #';,(R0)+ 3$: BIT #4,R1 ;UNDERLINE? BEQ 4$ ;BR IF NOT MOVB #'4,(R0)+ MOVB #';,(R0)+ 4$: BIT #^O10,R1 ;BLINK? BEQ 5$ ;BR IF NOT MOVB #'5,(R0)+ MOVB #';,(R0)+ 5$: BIT #^O20,R1 ;REVERSE? BEQ 6$ ;BR IF NOT MOVB #'7,(R0)+ MOVB #';,(R0)+ 6$: MOVB #'m,-1(R0) ;OVERWRITE LAST ";" WITH LOWER "M" NOATT: MOV BASE(SP),R1 ;R1->INPUT BUFFER MOV COUNT(SP),R2 ;R2=STRING LENGTH BEQ 6$ ;SKIP COPY IF ZERO LENGTH SPECIFIED CMP #80.,R2 ;CHECK MAX STRING LENGTH BHIS 2$ ; BR IF LENGTH OK MOV #80., R2 ; ONLY USE FIRST 80 OF HIS LONG BUFFER 2$: MOVB (R1)+,(R0)+ ;COPY STRING TO OUTPUT BUFFER SOB R2,2$ 6$: TST COL(SP) ;CHECK FOR ERASE TO EOL BPL 1$ ;BR IF NO EREOL MOVB #ESC,(R0)+ ;GENERATE EREOL COMMAND IN-LINE MOVB #'[, (R0)+ MOVB #'K, (R0)+ 1$: TSTB SAV(SP) ;SAVE/RESTORE SEQUENCE? BEQ 3$ ;BR IF NOT MOVB RCUR,(R0)+ ;RESTORE SEQUENCE TO BUFFER MOVB RCUR+1,(R0)+ ;BYTE AT A TIME SINCE COUNT MIGHT BE ODD 3$: SUB #BUFF,R0 ;R0=LENGTH OF OUTPUT BUFFER MOV R0,BLEN DIR$ #QIODPB ;DO IT BCC 4$ ;BRANCH IF NO DIRECTIVE ERROR MOV $DSW,@ISB(SP) ;RETURN $DSW AS ERROR BR 5$ 4$: TSTB IOSB ; ERROR? ;JMB001 BPL 16$ ; BR - NOPE ;JMB001 MOVB #-1, IOSB+1 ; SIGN EXTEND ERROR CODE ;JMB001 16$: MOV IOSB,@ISB(SP) ;RETURN IO STATUS ;JMB001 5$: ;**-1 ENDPR .END