.TITLE VTLFMT - Format and Write Record .IDENT /1.1/ .ENABL LC ;+ ; ; Free software BY ; Project Software & Development, Inc. ; ; This software is furnished for free and may be used and copied as ; desired. This software or any other copies thereof may be provided or ; otherwise made available to any other person. No title to and ; ownership of the software is hereby transferred or allowed. ; ; The information in this software is subject to change without notice ; and should not be construed as a commitment by PROJECT SOFTWARE ; AND DEVELOPMENT, INC. ; ; PROJECT SOFTWARE assumes no responsibility for the use or reliability ; of this software on any equipment whatsoever. ; ; Project Software & Development, Inc. ; 14 Story St. ; Cambridge, Ma. 02138 ; 617-661-1444 ; ; ; Title: VTLFMT.MAC ; Author: Robin Miller ; Date: June 30, 1983 ; ; Description: ; ; These routines are used to format special characters and then write ; the buffer to the terminal. ; ; Modification History: ; ; June 13, 1984 by Robin Miller. Edit (01), Version 1.1 ; Added routines CHKGRA, DOGRA, and MOVEF to check/format/copy ; characters which can be displayed in graphics. ; ;- .ENABL AMA .NLIST BEX .MCALL QIOW$S ; DEBUG = 0 ; Define for DDT debugging. .IFDF DEBUG .GLOBL ADJTAB, CKNUMB, DOFMT,DOSEE, DOSPEC, DOTAB, DOWRT .GLOBL INDENT, NBCONT .ENDC ; DEBUG ; Macro to move a single character to buffer in R0. .MACRO MOVCHR CHAR .NCHR $$$,^/CHAR/ .IF EQ $$$-1 MOVB #''CHAR,(R0)+ .IFF MOVB #CHAR,(R0)+ .ENDC .ENDM ; Equates for special graphics. G.DIA = 140 ; (') Diamond. G.CHK = 141 ; (a) Check board. G.HT = 142 ; (b) Horizontal tab. G.FF = 143 ; (c) Form feed. G.CR = 144 ; (d) Carriage return. G.LF = 145 ; (e) Line feed. G.DEG = 146 ; (f) Degree symbol. G.PLMI = 147 ; (g) Plus/minus. G.NL = 150 ; (h) New line. G.VT = 151 ; (i) Vertical tab. G.DOT = 176 ; (~) Centered dot. US = 31. ; Unit seperator. NUMSIZ = 8. ; Record number field size. ; Table of characters to be printed in graphics. GRATBL: .BYTE HT,FF,CR,LF,VT,0 ; Graphics character table. .SBTTL WRTBUF - Format and write the record. ;+ ; ; WRTBUF - Format and write the record. ; ; Implicit inputs: ; IENTRY = The file entry address. ; ; Outputs: ; All registers are preserved. ; ;- WRTBUF::CALL $SAVAL ; Save all registers. MOV IENTRY,R5 ; Copy the file entry address. ; Check for continuation of previous record. MOV O.BADR(R5),R1 ; Copy the record buffer address. BEQ 5$ ; If EQ, there is none. CLR O.BADR(R5) ; Show no continuation record now. MOV O.BCNT(R5),R2 ; Else, copy the byte count. BIS #S.CONT,(R5) ; Show this is a continuation. BR 7$ ; And continue ... 5$: MOV O.FDB(R5),R0 ; Copy the FDB address. MOV F.NRBD+2(R0),R1 ; Copy the record buffer address. MOV F.NRBD(R0),R2 ; and the record byte count. 7$: MOV #FMTBUF,R0 ; Set the output buffer address. MOV TABSIZ,O.TCNT(R5) ; Setup the maximum tab count. ; ; When backing up a partial page, we display the number of lines ; we were told to backup and then skip the remaining records until ; the current page is full. ; BIT #B.BACK,STATUS ; Are we backing up partial page ? BEQ 10$ ; If EQ, no (continue ...) DEC BCKCNT ; Yes, adjust the backup count. BPL 10$ ; If PL, more to go. INC O.LCNT(R5) ; Else, just adjust the line count. RETURN ; And return ... 10$: CLR O.CCNT(R5) ; Initialize the character count. CALL CKNUMB ; Check and format record number. CALL INDENT ; Indent the margin (if any). ; Fall through to format the data. .SBTTL DOFMT - Format characters for output. ;+ ; ; DOFMT - Format charaters for output. ; ; Inputs: ; R0 = The output buffer address. ; R1 = The record buffer address. ; R2 = The record byte count. ; R5 = The file entry address. ; ;- DOFMT: TST R2 ; Any record byte count left ? BGT 10$ ; If GT, yes (continue ...) JMP 70$ ; No, write the format buffer. 10$: CALL CKSRCH ; Check for a search string. MOVB (R1)+,R3 ; Copy the next character. BIC #^C177,R3 ; Clear any garbage bits. ; Check for special characters to format. BIT #S.SEE!S.BIN,(R5) ; See-all or binary mode ? BNE 15$ ; If NE, yes (display all). CMPB R3,#LF ; Is this a line feed ? BEQ 30$ ; If EQ, yes (end of line). CMPB R3,#FF ; Is this a form feed ? BEQ 35$ ; If EQ, yes. 15$: CMPB R3,#DEL ; Is this a DELETE character ? BEQ 20$ ; If EQ, yes (special format). CMPB R3,#SPACE ; Is this a control character ? BGE 40$ ; If GE, no (normal character). 20$: CALL DOSPEC ; Yes, do special formatting. BR 50$ ; And continue ... ; Special code for embedded line feed. 30$: CALL DOWRT ; Write the format buffer. DEC R2 ; Adjust the record byte count. BEQ 100$ ; If EQ, we're all done. CMP O.LCNT(R5),O.LMAX(R5) ; Exceeding the line count ? BGE 32$ ; If GE, yes. BIS #S.CONT,(R5) ; Show this is a continuation. CALL CKNUMB ; Format the continuation record. BR DOFMT ; And do the next character. ; The screen is full, now save the record context. 32$: MOV R1,O.BADR(R5) ; Save the record buffer address MOV R2,O.BCNT(R5) ; and the record byte count. BR 100$ ; All done for now ... ; ; The passing of form feeds to the terminal was added for terminals ; with the hardcopy option. The formfeed is displayed as a line ; feed by the VT100, thus some work needs done here to adjust the ; line count, etc. ; 35$: BIT #B.FF,SWMASK ; Pass formfeeds to terminal ? BEQ 50$ ; If EQ, no (ignore form feed). ; Copy the normal character and adjust the counts. 40$: MOVB R3,(R0)+ ; Copy the normal character. INC O.CCNT(R5) ; Adjust the character count. CALL ADJTAB ; Now adjust the tab count. ; Prepare to process the next character. 50$: DEC R2 ; Adjust the record byte count. BLE 70$ ; If LE, we're all done. CMP O.CCNT(R5),O.LWID(R5) ; Have we filled up the line ? BGE 70$ ; If GE, yes. CMP R0,#FMTBUF+RECSIZ-50. ; Exceeding the output buffer ? BLOS 60$ ; If LOS, no. CALL VTYPE ; Display the format buffer. 60$: JMP DOFMT ; Else, format the next character. ; *** The check for WRAP should go here. ** 70$: CALL DOWRT ; Write this display line. CLR O.BADR(R5) ; Show no continuation record. 100$: RETURN .SBTTL DOWRT - Write the formatted buffer. ;+ ; ; DOWRT - Write the formatted buffer. ; ; Inputs: ; R0 = The output buffer address. ; R1 = The record buffer address. ; R2 = The record byte count. ; R5 = The file entry address. ; ; Outputs: ; R0 = Reset to the starting buffer address. ; O.CCNT(R5) = The character count is cleared. ; O.LCNT(R5) = The line count is adjusted. ; O.TCNT(R5) = The tab count is reset to maximum. ; ; All other registers are preserved. ; ;- DOWRT: JSR R5,.SAVR1 ; Save R1 - R5. MOV R0,R3 ; Copy the output buffer address. SUB #FMTBUF,R3 ; Now, calculate the byte count. BNE 20$ ; If NE, we got one. CLRB (R0)+ ; Else, prepare for null record. ; Turn off the video attributes if they are still on. 20$: BIT #S.SEL,(R5) ; Is a select range active ? BNE 25$ ; If NE, yes (turn off attributes). BIT #B.ATTR,STATUS ; Are video attributes still on ? BEQ 30$ ; If EQ, no (continue ...) 25$: CALL ATTOFF ; Yes, turn them off. BIC #B.ATTR,STATUS ; Show the attributes are off. 30$: BIT #S.SEE,(R5) ; Are we in see-all mode ? BEQ 70$ ; If EQ, no (output the buffer). CALL SGRAPH ; Turn on special graphics set. TST R2 ; Is there any record count left ? BLE 40$ ; If LE, no (show end of the line). MOVCHR ; Show more on line with diamond. BR 50$ ; Use common code ... 40$: MOVCHR ; Show end of line with NL. 50$: CALL USSET ; Return to ASCII character set. ; Adjust the line count and add carriage control. 70$: INC O.LCNT(R5) ; Adjust the line count. CMP O.LCNT(R5),O.LMAX(R5) ; Are we at the last line ? BGE 80$ ; If GE, yes (no spacing). CALL CPYBLA ; Add carriage return/line feed. ; Finally output the formatted buffer. 80$: CALL VTYPE ; Display the format buffer. CLR O.CCNT(R5) ; Reinitialize character count. MOV TABSIZ,O.TCNT(R5) ; Reset the maximum tab count. RETURN .SBTTL CHKGRA - Check for graphics character. ;+ ; ; CHKGRA - Check for graphics character. ; ; This routine determines whether the specified character is displayed ; in special graphics. This routine is needed by the input routine when ; deleting control characters from the screen. In special graphics, the ; character is displayed in a single character position. All other ; characters are displayed in two character positions as ^char. ; ; Inputs: ; R3 = Address of character to check. ; ; Outputs: ; C bit clear/set = graphics/no graphics. ; ; All registers are preserved. ; ;- CHKGRA::JSR R2,$SAVVR ; Save R0 - R2. MOV #GRATBL,R0 ; Set graphics table address. 10$: MOVB (R0)+,R1 ; Copy the next character. BEQ 90$ ; If EQ, end of the table. CMPB R1,(R3) ; Displayed in graphics ? BNE 10$ ; If NE, no. BR 100$ ; Use common return ... 90$: SEC ; Show not displayed in graphics. 100$: RETURN .SBTTL CKNUMB - Check for record number display. ;+ ; ; CKNUMB - Check for display of the record number. ; ; This routine formats and displays the record number at the beginning of ; each line if NUMBERing is enabled. It also puts the screen in reverse ; video if a SELECT range is active for the write command. ; ; Inputs: ; R0 = The output buffer address. ; R5 = The file entry address. ; ; Outputs: ; R0 = The updated buffer address. ; O.CCNT(R5) = The updated character count. ; ; All other registers are preserved. ; ;- CKNUMB: JSR R5,.SAVR1 ; Save R1 - R5. BIT #S.NUMB,(R5) ; Display the record number ? BEQ 100$ ; If EQ, no. BIT #S.SEL,(R5) ; Is a select range active ? BEQ 10$ ; If NE, no (turn on reverse). BIT #B.AVO,SWMASK ; Do we have advanced video ? BEQ 15$ ; If EQ, no (no attributes then). CALL BOLD ; Else, BOLD/REVERSE the number. 10$: CALL REVERSE ; Turn on reverse video attribute. 15$: MOV #NUMSIZ,R2 ; Set the record number field size. BIT #S.CONT,(R5) ; Are we doing a continuation ? BNE 20$ ; If NE, yes (no record number). MOV R0,R3 ; Copy the buffer address. MOV R5,R1 ; Copy the file entry address. ADD #O.CREC,R1 ; Point to the current record. CALL CVTDTD ; Convert record number to ASCII. MOV R0,R1 ; Copy the updated buffer address. SUB R3,R1 ; Calculate the byte count. SUB R1,R2 ; Calculate the space count. BEQ 30$ ; If EQ, no space count. 20$: MOVCHR ; Fill remaining with space. SOB R2,20$ ; Loop until done. 30$: MOV #NUMSIZ,O.CCNT(R5) ; Set the starting character count. CALL ATTOFF ; Turn off the video attributes. 100$: BIC #S.CONT,(R5) ; Show we're done with continuation. BIT #S.SEL,(R5) ; Is the select range active ? BEQ 110$ ; If EQ, no. CALL REVERSE ; Yes, put select range in reverse. 110$: RETURN .SBTTL CKSRCH - Check for a search string. ;+ ; ; CKSRCH - Check current record for search string record. ; ; This routine is used to display a search string in BOLD/REVERSE ; video if one is active. ; ; Inputs: ; R0 = The output buffer address. ; R1 = The record buffer address. ; R2 = The record byte count. ; R5 = The file entry address. ; ; Outputs: ; R0 = The updated output buffer address. ; ; All other registers are preserved. ; ;- CKSRCH: JSR R5,$SAVRG ; Save R3 - R5. BIT #S.SRCH,(R5) ; Is a search string active ? BEQ 100$ ; If EQ, no. CMP O.FREC(R5),O.CREC(R5) ; Possibly this record number ? BNE 100$ ; If NE, no. CMP O.FREC+2(R5),O.CREC+2(R5) ; Really this record number ? BNE 100$ ; If NE, no. ; We're at the right record, now check the byte position. CMP R1,O.FBEG(R5) ; Beginning of search string ? BLO 100$ ; If LO, no (before string). CMP R1,O.FEND(R5) ; Within range of search string ? BHIS 20$ ; If HIS, at end or out of range. ; Put the search string in BOLD/REVERSE video attributes. BIT #B.ATTR,STATUS ; Are the attributes already on ? BNE 100$ ; If NE, yes (don't do it again). CALL BOLD ; Turn on the BOLD CALL REVERSE ; and REVERSE attributes. BIS #B.ATTR,STATUS ; Show attributes are enabled. BR 100$ ; And use common return ... ; At the end of the search string, turn off the attributes. 20$: BIT #B.ATTR,STATUS ; Are the attributes already off ? BEQ 100$ ; If EQ, yes (don't do it again). CALL ATTOFF ; Turn off all video attributes. BIC #B.ATTR,STATUS ; Show attributes are removed. BIT #S.SEL,(R5) ; Is a select range active ? BEQ 100$ ; If EQ, no. CALL REVERSE ; Yes, turn reverse video on. 100$: RETURN .SBTTL DOSPEC - Do special formatting. ;+ ; ; DOSPEC - Do special formatting. ; ; This routine is used to format special characters. Special characters ; are all the control characters and the delete character. ; ; Inputs: ; R0 = The output buffer address. ; R1 = The record buffer address. ; R2 = The record byte count. ; R3 = The character to format. ; R5 = The file entry address. ; ; Outputs: ; R0 = The updated output buffer address. ; O.CCNT(R5) = The updated character count. ; O.TCNT(R5) = The adjusted tab count. ; ; All other registers are preserved. ; ;- DOSPEC: JSR R5,.SAVR1 ; Save R1 - R5. CMPB R3,#HT ; Is this a horizontal tab ? BNE 10$ ; If NE, no. JMP DOTAB ; Yes, do the tab formatting. ; In see-all mode, use special graphics for display. 10$: BIT #S.SEE,(R5) ; Are we in see-all mode ? BEQ 20$ ; If EQ, no. JMP DOSEE ; Yes, do see-all formatting. ; Allow carriage return for overprinting. 20$: BIT #S.BIN,(R5) ; Displaying a binary file ? BNE 70$ ; If NE, yes (convert to a space). CMPB R3,#CR ; Is this a carriage return ? BNE 30$ ; If NE, no. CLR O.CCNT(R5) ; Yes, clear the line count. MOV TABSIZ,O.TCNT(R5) ; Set tab count to the maximum. BR 90$ ; Use common code ... ; Allow backspace for overprinting. 30$: CMPB R3,#BS ; Is this a backspace ? BNE 40$ ; If NE, no. TST O.CCNT(R5) ; Is there any character count ? BEQ 100$ ; If EQ, no (ignore backspace). DEC O.CCNT(R5) ; Yes, adjust the character count. BR 90$ ; Use common code ... ; Allow bells and escapes but don't adjust the character count. 40$: CMPB R3,#ESC ; Is this an escape ? BEQ 90$ ; If EQ, yes. CMPB R3,#BELL ; Is this a bell ? BNE 70$ ; If NE, no. BIT #B.BELL,SWMASK ; Is ringing of the bell enabled ? BNE 90$ ; If NE, yes. ; Display a space for the control character. 70$: MOV #SPACE,R3 ; Use space for non-printable. 80$: CALL ADJTAB ; Adjust the tab count. INC O.CCNT(R5) ; Adjust the character count. 90$: MOVB R3,(R0)+ ; Copy character to output buffer. 100$: RETURN .SBTTL DOSEE - Do see-all formatting. ;+ ; ; DOSEE - Do see-all formatting. ; ; This routine formats control characters to match those used by TECO. ; ; Inputs: ; R0 = The output buffer address. ; R3 = The character to format. ; R5 = The file entry address. ; ; Outputs: ; R0 = The updated output buffer address. ; O.CCNT(R5) = The updated character count. ; O.TCNT(R5) = The adjusted tab count. ; ; All other registers are preserved. ; ;- DOSEE: JSR R5,.SAVR1 ; Save R1 - R5. CALL DOGRA ; Do special graphics characters.(01) BCC 100$ ; If CC, character displayed. (01) ; Convert control to either "^char" or "+/-char". BIT #S.TECO,(R5) ; Display TECO see-all mode ? BEQ 10$ ; If EQ, no (skip graphics). CALL SGRAPH ; Turn on the special graphics. (01) MOVCHR ; Copy graphics for plus/minus. CALL USSET ; Return to ASCII character set.(01) BR 20$ ; And continue ... 10$: CMPB R3,#ESC ; Is this an escape character ? BNE 15$ ; If NE, no. MOVCHR <$> ; Yes, display as dollar sign. BR 100$ ; And continue ... 15$: MOVB #'^,(R0)+ ; No, print as "^char". ; Do special check for the delete character. 20$: CMPB R3,#DEL ; Is this a delete character ? BNE 30$ ; If NE, no. MOVCHR ; Display delete as question mark. BR 50$ ; And continue ... ; ; If this is a US (31.) character, turn off special graphics, ; because the underscore in graphics prints a space. ; 30$: ;(01) CMPB R3,#US ; Is this the unit separator ? ;(01) BNE 40$ ; If NE, no. ;(01) CALL USSET ; Return to ASCII character set. ; Convert control character to printable ASCII. 40$: ADD #64.,R3 ; Make control printable ASCII. MOVB R3,(R0)+ ; And copy to the output buffer. ; Adjust counts for 2 characters. 50$: CALL ADJTAB ; Adjust the tab count. INC O.CCNT(R5) ; Adjust the character count. 100$: CALL ADJTAB ; Adjust the tab count. INC O.CCNT(R5) ; Adjust the character count. RETURN .SBTTL DOCHAR - Copy/format a character. ;+ ; ; DOCHAR - Copy/format a character. ; ; This routine is called to copy and format a single character converting ; control characters to printable ASCII as necessary. ; ; Inputs: ; R0 = The output buffer address. ; R3 = The character to format. ; ; Outputs: ; R0 = The updated output buffer address. ; ; All other registers are preserved. ; ;- DOCHAR::JSR R5,$SAVRG ; Save R3 - R5. CMPB R3,#SPACE ; Is this a control character ? BGE 10$ ; If GE, no (normal character). CALL DOGRA ; Do special graphics characters. BCC 100$ ; If CC, character displayed. MOVB #'^,(R0)+ ; Display control as ^char. ADD #64.,R3 ; Make control printable ASCII. 10$: MOVB R3,(R0)+ ; And copy to the output buffer. 100$: RETURN .SBTTL DOGRA - Display character in graphics. ;+ ; ; DOGRA - Display a character in graphics. ; ; This routine checks for and displays characters which can be displayed ; using a VT100 special graphics charater. ; ; Inputs: ; R0 = The output buffer address. ; R3 = The character to check. ; ; Outputs: ; C bit clear/set = graphics/no graphics. ; ; R0 = The updated output buffer address. ; All other registers are preserved. ; ;- DOGRA:: JSR R5,.SAVR1 ; Save R1 - R5. ; Special graphics for HT, LF, VT, FF, and CR. MOVB #G.HT,R1 ; Set graphic for horizontal tab. CMPB R3,#HT ; Is it a horizontal tab ? BEQ 10$ ; If EQ, yes. MOVB #G.LF,R1 ; Set graphic for line feed. CMPB R3,#LF ; Is it a line feed ? BEQ 10$ ; If EQ, yes. MOVB #G.VT,R1 ; Set graphic for vertical tab. CMPB R3,#VT ; Is it a vertical tab ? BEQ 10$ ; If EQ, yes. MOVB #G.FF,R1 ; Set graphic for form feed. CMPB R3,#FF ; Is it a form feed ? BEQ 10$ ; If EQ, yes. MOVB #G.CR,R1 ; Set graphic for carriage return. CMPB R3,#CR ; Is it a carriage return ? BNE 90$ ; If NE, no. 10$: CALL SGRAPH ; Turn on the special graphics. MOVB R1,(R0)+ ; Copy the graphics character. CALL USSET ; Return to ASCII character set. CLC ; Show displayed in graphics. BR 100$ ; And use common return ... 90$: SEC ; Show not a graphics character. 100$: RETURN .SBTTL DOTAB - Do special formatting of tab. ;+ ; ; DOTAB - Do special formatting of tab. ; ; Inputs: ; R0 = The output buffer address. ; R5 = The file entry address: ; O.TCNT = The current tab count. ; ; Outputs: ; R0 = The updated output buffer address. ; O.CCNT(R5) = The updated character count. ; O.TCNT(R5) = The tab count is reset to maximum. ; ; All other registers are preserved. ; ;- DOTAB: JSR R5,.SAVR1 ; Save R1 - R5. MOV O.TCNT(R5),R1 ; Copy the tab count. ADD R1,O.CCNT(R5) ; Adjust the character count. ; In see-all mode, display the special graphics tab character. BIT #S.SEE,(R5) ; Are we in see-all mode ? BEQ 50$ ; If EQ, no. CALL SGRAPH ; Turn on special graphics. MOVCHR ; Now display the HT character. DEC R1 ; Adjust the count for HT. BEQ 20$ ; If EQ, no fill characters. ; Use the centered dot to show where the tab ends. 10$: MOVCHR ; Fill with the centered dot. SOB R1,10$ ; Loop until done. 20$: CALL USSET ; Return to ASCII character set. BR 100$ ; And use common return ... ; When not in see-all mode, convert tabs to spaces. 50$: MOVB #SPACE,(R0)+ ; Fill buffer with spaces. SOB R1,50$ ; Loop until done. 100$: MOV TABSIZ,O.TCNT(R5) ; Now reset to maximum tab count. RETURN .SBTTL INDENT - Indent the margin. ;+ ; ; INDENT - Indent the margin (if any). ; ; This routine is used to adjust the record buffer address and byte count ; based on the margin indent and the tab size. When indenting a partial ; tab, the appropriate number of spaces are added to align the output. ; ; Inputs: ; R0 = The output buffer address. ; R1 = The record buffer address. ; R2 = The record byte count. ; R5 = The file entry address. ; ; Outputs: ; R0, R1, and R2 are updated appropriatly. ; O.CCNT(R5) = Adjusted if spaces were added. ; ; All other registers are preserved. ; ;- INDENT: JSR R5,$SAVRG ; Save R3 - R5. MOV O.MARG(R5),R3 ; Copy the margin indent. BEQ 100$ ; If EQ, there is none. 10$: CMPB (R1)+,#HT ; Is this a horizontal tab ? BNE 20$ ; If NE, no. SUB O.TCNT(R5),R3 ; Yes, adjust the margin. BMI 60$ ; If MI, indent is exceeded. BEQ 80$ ; If EQ, margin indent complete. MOV TABSIZ,O.TCNT(R5) ; Else, reset the tab count. BR 30$ ; And continue ... 20$: CALL ADJTAB ; Adjust the tab count. DEC R3 ; Adjust the margin indent. BEQ 90$ ; If EQ, margin indent complete. 30$: SOB R2,10$ ; Else, adjust the record count. BR 100$ ; If EQ, record count exhausted. ; For partial tab indent, we must insert some spaces. 60$: NEG R3 ; Make positive space count. ADD R3,O.CCNT(R5) ; Adjust the character count. BIT #S.SEE,(R5) ; Are we in see-all mode ? BNE 75$ ; If NE, yes. 70$: MOVB #SPACE,(R0)+ ; Fill output buffer with space. SOB R3,70$ ; And loop until done. BR 80$ ; And continue ... ; Use the centered dot to show where the tab ends in see-all mode. 75$: CALL SGRAPH ; Turn on special graphics. 72$: MOVCHR ; Fill with the centered dot. SOB R3,72$ ; Loop until done. CALL USSET ; Return to ASCII character set. 80$: MOV TABSIZ,O.TCNT(R5) ; Reset the maximum tab count. 90$: DEC R2 ; Adjust the record byte count. 100$: RETURN .SBTTL ADJTAB - Adjust the tab count. ;+ ; ; ADJTAB - Adjust the tab count. ; ; Inputs: ; R5 = The file entry address. ; ; Outputs: ; O.TCNT(R5) = The adjusted tab count. ; ; All registers are preserved. ; ;- ADJTAB: DEC O.TCNT(R5) ; Adjust the tab count. BGT 10$ ; If GT, more count to go. MOV TABSIZ,O.TCNT(R5) ; Else, reset the tab count. 10$: RETURN .SBTTL MOVEF - Move characters with format. ;+ ; ; MOVEF - Move characters with format. ; ; This routine copies characters converting control characters to ; printable ASCII or special graphics as necessary. ; ; Inputs: ; R0 = The output buffer address. ; R1 = The input string to copy (terminated by null). ; ; Outputs: ; R0 = The updated output buffer address. ; ; All other registers are preserved. ; ;- MOVEF:: JSR R5,.SAVR1 ; Save R1 - R5. 10$: MOVB (R1)+,R3 ; Copy the next character. BEQ 100$ ; If EQ, end of string. CALL DOCHAR ; Copy/format this character. BR 10$ ; Go get the next character. 100$: RETURN .END