PROCEDURE ,020000 ;+ ; Copyright (C) 1976 ; Digital Equipment Corporation, Maynard, Mass. ; ; This software is furnished under a license for use only on a ; single computer system and may be copied only with the inclu- ; sion of the above copyright notice. This software, or any ; other copies thereof, may not be provided or otherwise made ; available to any other person except for use on such system ; and to one who agrees to these license terms. Title to and ; ownership of the software shall at all times remain in DEC. ; ; The information in this software is subject to change without ; notice and should not be construed as a commitment by Digital ; Equipment Corporation. ; ; DEC assumes no responsibility for the use or reliability of its ; software on equipment which is not supplied by DEC. ; ; Abstract: This module contains various RUNOFF buffer management ; routines. These modules were broken out of the ; RUNOFF mainline so as to provide ease of maintenance. ; ; System: This module was implemented under IAS V3.0, but ; should work on any system supporting RSX-11M. ; Modified to work under RSTS. ; ; Written: 01-Jun-72, -1.0.0-, L. Wade ; ; Modified: 12-Jan-80, -2.0.0-, Henry R. Tumblin ; Produced Duke supported version ; ; Verified: 12-Jan-80, -2.0.0-, Henry R. Tumblin ; ; Modified: 17-July-80, -2.0.1-, Jon Berntsen ; Modified: 27-July-80, -2.0.2-, Jon Berntsen ; Worked on subscripts, superscripts and underlining ; Modified: 1-Sept-80, J. Krupp Middlebury College ; Modified: 30-Dec-80, -2.0.3-, Jon Berntsen ; Added Middlebury Modifications ;- .SBTTL Runoff Definitions ; Global definitions .GLOBL BS ; Backspace character .GLOBL CAS ; Lower to upper conversion factor .GLOBL CPOS ; Current position on line .GLOBL DIASW ; Super/Subscript switch .GLOBL ESC ; ESCAPE character .GLOBL FIN ; Get character from input file .GLOBL FOOTP1 ; Footnote buffer header .GLOBL FOTF ; Footnote active flag .GLOBL FOUT ; Output character to output file .GLOBL F.1 ; Current state flags word .GLOBL GCINP ; Saved string buffer .GLOBL GCSCH ; Saved character buffer .GLOBL LF ; Line feed .GLOBL LIBUF ; Line input buffer .GLOBL LINNSC ; Pointer to last non-spacing char. .GLOBL LOBUF ; Line output buffer .GLOBL LPUS ; Line printer underscore character .GLOBL LWCAS ; Set case mode to lower case .GLOBL METCAP ; Upper case indicator .GLOBL METNHY ; No hyphenation indicator .GLOBL METQSP ; Quoted space indicator .GLOBL METQUO ; Quote next character indicator .GLOBL METSBC ; Subscript character indicator .GLOBL METSHD ; Lower case indicator .GLOBL METSHU ; Upper case indicator .GLOBL METSPC ; Superscript indicator .GLOBL METUNL ; Underline indicator .GLOBL NHLF ; Negative half line feed .GLOBL NSPCH ; Pointer to last non-spacing char. .GLOBL PHLF ; Positive half line feed .GLOBL QTS ; Quoted space(internal rep) .GLOBL SBCHS ; Superscript(internal rep) .GLOBL SDBUF ; Secondary input buffer .GLOBL SPC ; Space or blank character .GLOBL SPCHS ; Subscript(internal rep) .GLOBL S1 ; Temporary string pointer .GLOBL TAB ; Tab character .GLOBL TFOUT ; TOC output character .GLOBL ULCHS ; Underline(internal rep) .GLOBL ULMCH ; Underline saved char. buffer .GLOBL ULPOS ; Next avail. slot in UL buffer .GLOBL UPCAS ; Set mode to upper case .GLOBL UPCSW ; Upper case switch mask .GLOBL WCAS ; Word capitalize conversion value .GLOBL $CFLSW ; Flag capitalize switch .GLOBL $GCISW ; Input from reread buffer switch .GLOBL $HFLSW ; Flags hyphenate switch .GLOBL $SDISW ; Input from secondary input buffer .GLOBL $ULLSW ; Under line lock switch .GLOBL $ULMSW ; Underline mode, Backspace .SBTTL Runoff definitions(continued) ; Globals defined in this module .GLOBL CCIN ; Read character from input file .GLOBL CCINUC ; Read character from input file ; and translate to upper case. ; or from footnote buffer .GLOBL CCOUT ; Output character to output file ; after some tests .GLOBL CCSPC ; Output space to output file .GLOBL GCI ; Get character from buffer .GLOBL GCIN ; Get input character from buffers .GLOBL INIBUF ; Initialize buffer header .GLOBL NSPAC ; Output spaces to output file .GLOBL PSTRAZ ; Output ASCIZ string to output file .GLOBL PSTRPA ; Output a buffer to the output file .GLOBL TNSPAC ; Output spaces to TOC file .GLOBL WCI ; Write character in buffer .GLOBL WCIFTN ; Write character in footnote buffer .GLOBL WLNIN1 ; Write character in line buffer .SBTTL GCIN -- GET INPUT CHARACTER FROM SOURCE FILE CODE BUFMAN ; GCIN ; GCIN will read a character from one of the following buffers: ; ; 1) The saved line buffer(GCINP), ; 2) The saved character buffer (GCSCH), ; 3) The input file buffer(HFIN), GCIN:: .ENABL LSB ; Check to see if read is to be done from saved ; line buffer. ; If so, read the character and return to caller. TSTEQB $GCISW,GCIN3 ; not rereading from buffer? MOV #GCINP,R4 ; Point to saved char. buffer CALL GCI ; Get character from it .WORD 10$ ; If none, then clear re-read flag RETURN ; ; End of saved line buffer reached, clear flag so input ; will come from elsewhere. 10$: CLRB $GCISW ; clear reread flag ; Check to see if the character is coming from the saved ; character buffer. ; The saved character buffer is a 1 byte buffer. It is ; non-zero if it contains a character and null if not. GCIN3: TSTNEB GCSCH,GCIN5 ; saved character? ; Check to see if the character is coming from the ; saved underline character buffer. If so, place it in ; R1 and clear the buffer. ; ULMCH is similar to GCSCH. MOVB ULMCH,R1 ; saved underline character? BEQ GCIN5 ; if eq no CLRB ULMCH ; clear saved underline character CMPEQ R1,#SPCHS,90$ ; superscript request? CMPEQ R1,#SBCHS,90$ ; subscript request? BR 100$ ; ; Get character from file. CCIN knows about GCSCH, so it ; will fill in R1 appropriately. GCIN5: CALL CCIN ; no. get character from file. ; Perform the appropriate case conversions for the ; character input. GCIN6: BITB #CHALC,CHATBL(R1) ; Is the character lower case? BEQ 30$ ; No, upper case or non-alphabetic. ; Check to see if the /UC switch has been specified. If so, ; then force all lower case to upper case. BIT #UPCSW,$INSW ; Force upper case ? BEQ 20$ ; EQ - no SUB #40,R1 ; make upper case BR GCINR ; Convert case of character as necessary 20$: SUB WCAS,R1 ; convert case if necessary BR GCINR ; ; Check for upper case character and convert case as necessary. 30$: BITB #CHAUC!CHALC,CHATBL(R1) ; Is the character alphabetic? BEQ 40$ ; EQ - no TSTNE WCAS,GCINR ; converting to upper case for this word? ADD CAS,R1 ; convert to lower case if necessary BR GCINR ; 40$: TSTEQ $CFLSW,70$ ; flags capitalize not enabled? CMPEQ R1,METQSP,50$ ; quoted space? BITB #CHASP,CHATBL(R1) ; Is it a "normal" spacing char ; (blank or tab)? BNE 50$ ; NE - yes CMPNE R1,#LF,60$ ; not line feed? 50$: CLR WCAS ; clear word case conversion 60$: CMPNE R1,METCAP,70$ ; not word capitalize? MOV #40,WCAS ; set word capitalize conversion value BR GCIN3 ; 70$: CMPEQ R1,METQUO,CWR1 ; quoting a character? CMPEQ R1,METSHU,SHFUP ; upshift character? CMPEQ R1,METSHD,SHFDN1 ; downshift character? CMPEQ R1,METUNL,ULCH ; underline request? CMPEQ R1,METSPC,SPCH ; superscript request ? CMPEQ R1,METSBC,SBCH ; subscript request ? CMPEQ R1,METILR,REMARK ; In-line comment ? CMPNE R1,METBSP,74$ ; Is this a backspace character ? .IF DF R$$OCK BITEQ #DIASW,$INSW,100$ ; Don't allow backspace to go to printer .ENDC ;R$$OCK MOVB #BS,R1 ; Change to a real backspace if so BR 78$ 74$: CMPNE R1,#BS,78$ ; Backspace in input file ? MOVB #'?,R1 ; Output a ? if so 78$: .IF DF H$$PHN TSTEQ $HFLSW,80$ ; flags hyphenate not enabled? CMPEQ METNHY,R1,FLHYP ; flags hyphenate? .IFTF 80$: CMPNE R1,METQSP,GCINR ; not quoted space? MOV #QTS,R1 ; set quoted space .SBTTL GCINR -- Get character from re-read buffer GCINR: TSTEQ $ULLSW,100$ ; underline shift-lock not on? TSTNE $ULLS1,110$ ; check for after a sub or superscript CMPEQ #QTS,R1,100$ ; quoted space? CMP #SPC,R1 ; printing character? BGE 100$ ; if ge no CMPEQB #BS,LCH,100$ ; Don't underline again 85$: MOVB R1,ULMCH ; save underlined character ULCH: MOV #ULCHS,R1 ; set to underline character 90$: INC NSPCH ; count nonspacing characters 100$: RETURN ; 110$: CLR $ULLS1 ; clear flag RETURN SPCH: MOV #SPCHS,R1 ; set to superscript character BR 120$ ; SBCH: MOV #SBCHS,R1 ; set to subscript character 120$: TSTEQ $ULLSW,90$ ; If no underline exit normally MOV SP,$ULLS1 ; set switch BR 85$ ; .DSABL LSB SHFDN1: JMP SHFDN ; SHFDN was to far from the branch .IFT .SBTTL FLHYP -- FLAG HYPHENATE CHARACTER ; flag hyphenate character FLHYP: CALL GCIN ; get next character with translate BITB #CHAUC!CHALC,CHATBL(R1) ; Alphabetic character? BEQ GCINR ; If EQ no BISB #200,R1 ; disable hyphenation on this word BR GCINR ; .ENDC .SBTTL SPECIAL CASES OF INPUT CHARACTER CWR1: CALL CCIN ; read character no translation BR GCINR ; and return it. maybe underlined ; more special cases of get-character routine .ENABL LSB SHFUP: CALL CCIN ; read a character CMPEQ R1,METUNL,ULMON ; lock on underline? CMPEQ R1,METSPC,SPMON ; superscript lock on ? CMPEQ R1,METSBC,SBMON ; subscript lock on ? CMPEQ R1,METILR,REMARK ; In-line remarks ? CMPNE R1,METSHU,20$ ; not double upshift? CALL UPCAS ; set upper case 10$: JMP GCIN3 ; and go read another character ; Process in-line comments ; ; This change allows in line comments of the form: ; ; text ^!comment ; or text ^!comment ! ; REMARK: CALL CCIN ; Gobble character CMPEQ R1,METILR,10$ ; End of comment ? CMPNE R1,#CR,REMARK ; At end of line yet ? RETURN ; If so, then return 20$: BITB #CHAUC!CHALC,CHATBL(R1) ; Alphabetic character? BEQ GCIN6A ; If EQ - no BITB #CHALC,CHATBL(R1) ; Lower case alphabetic? BEQ GCINR ; If EQ - no BIC #40,R1 ; Make into an upper case letter. BR GCINR ; And leave. SHFDN: CALL CCIN ; get another character CMPEQ R1,METUNL,ULMOF ; unlock underline? CMPEQ R1,METSPC,SPMOF ; superscript lock off ? CMPEQ R1,METSBC,SBMOF ; subscript lock off ? CMPNE R1,METSHD,60$ ; not second downshift? CALL LWCAS ; set lower case BR 10$ ; 60$: BITB #CHAUC!CHALC,CHATBL(R1) ; Is it alphabetic? BEQ GCIN6A ; If EQ - no BITB #CHAUC,CHATBL(R1) ; Is it upper case? BEQ GCINR ; No, just leave. BIS #40,R1 ; Yes, make it lower case. BR GCINR ; And leave. GCIN6A: JMP GCIN6 ; ULMON: MOV SP,$ULLSW ; underline locked on BR 10$ ULMOF: CLR $ULLSW ; underline locked off BR 10$ ; SBMOF: SPMON: MOV #SPCHSL,R1 ; Put superscript lock on character in buffer CALL WLNIN1 ; INC LINNSC ; BR 10$ SPMOF: SBMON: MOV #SBCHSL,R1 ; Put subscript lock on character in buffer CALL WLNIN1 ; INC LINNSC ; BR 10$ .DSABL LSB .SBTTL NSPAC -- OUTPUT SPACES TO OUTPUT FILE .ENABL LSB ; ; routine to output spaces to file ; ; R2 has count of spaces to output NSPAC:: DEC R2 ; any more spaces to output? BLT 10$ ; if lt no CALL CCSPC ; output a space BR NSPAC ; 10$: RETURN ; And return. .SBTTL TNSPAC -- OUTPUT SPACES TO TOC FILE TNSPAC::DEC R2 ; any more spaces to output ? BLT 10$ ; if lt, no MOVB #40,R1 ; set to output a space CALL TFOUT ; output a space BR TNSPAC ; .SBTTL PSTRPA -- OUTPUT A STRING TO THE OUTPUT FILE ; ; routines to output a string to the output file ; ; R4 - Pointer to buffer descriptor ; S1 - Pointer to next character to output PSTRPA:: MOV BF.ADR(R4),S1 ; Point to the string CLRB @BF.PTR(R4) ; Make it an ASCIZ string 15$: MOVB @S1,R1 ; Get a character BEQ 17$ ; EQ - then all thru CALL CCOUT ; Output the character to the file INC S1 ; Point to next character BR 15$ ; And loop till thru 17$: MOV BF.ADR(R4),BF.PTR(R4) ; Reset buffer CLR BF.LEN(R4) ; And the length word RETURN ; Return to caller .SBTTL PSTRAZ -- OUTPUT AN ASCIZ STRING TO THE OUTPUT FILE PSTRAZ::MOVB @S1,R1 ; get a character BEQ 20$ ; if eq end of string CALL CCOUT ; output to file INC S1 ; point to next character BR PSTRAZ ; loop for whole string 20$: RETURN ; Return to caller .DSABL LSB .SBTTL CCOUT -- OUTPUT CHARACTER TO OUTPUT FILE ; ; subroutine to output character to file, after some tests ; .ENABL LSB CCOUT:: CMPNEB R1,#BS,4$ ; a backspace INCB ULBKSP ; show another backspace found DEC CPOS ; backup carriage position BR 105$ ; and output it 4$: TSTEQB ULBKSP,8$ ; a bksp to cancel ? DECB ULBKSP ; yes BR 100$ ; output without further fuss 8$: .IF DF R$$STS ; This code needed because of RSTS CMPNEB R1,#33,9$ ; ouputs all ctrl chars as ^, BISB #200,,R1 ; e.g., ctrl/A becomes ^A and becomes 9$: ; a $. Only checked here. Cannot .ENDC ;R$$STS ; output all ctrl chars with parity, since ; for certain terminal/lp modes, these cause ; weird and special things to happen. ; note, lf,cr,ff are not affected by this. ; this code must be here, since hyphenation ; code plays with these bits CMPNE R1,#ULCHS,10$ ; not underline character? TSTEQB $ULMSW,110$ ; by line? MOV #LPUS,R1 ; convert to output underline CALL FOUT ; yes, send underline MOV #BS,R1 ; and follow with backspace JMP FOUT ; Output backspace do not count character 10$: CMPNE R1,#QTS,20$ ; not quoted space? .SBTTL OUTPUT SPACE TO OUTPUT FILE CCSPC:: MOV #SPC,R1 ; make real space BR 100$ 20$: CMPEQ R1,#SBCHSL,40$ ; Check for subscript lock on character CMPNE R1,#SPCHS,60$ ; not superscript ?? BITEQ #DIASW,$INSW,30$ ; not diablo, then skip MOV #ESC,R1 ; set up to CALL FOUT ; output an MOV #NHLF,R1 ; esc-d .IF DF R$$OCK CALL FOUT MOV #ESC,R1 CALL FOUT MOV #LF,R1 CALL FOUT MOV #LF,R1 .ENDC ;R$$OCK CALL FOUT ; to the diablo 30$: MOV #LOBUF,R4 ; Point to output line buffer CALL GCI ; Get character from line buffer .WORD 40$ ; None left ; CALL FOUT ; Output to file ; INC CPOS ; Bump up position on line CALL CCOUT ; Output to file 40$: BITEQ #DIASW,$INSW,120$ ; if not diablo, skip MOV #ESC,R1 CALL FOUT MOV #PHLF,R1 ; CALL FOUT ;50$: RETURN JMP FOUT 60$: CMPEQ R1,#SPCHSL,80$ ; Check for superscript character CMPNE R1,#SBCHS,100$ ; not subscript?? BITEQ #DIASW,$INSW,70$ ; if not diablo, then skip MOV #ESC,R1 CALL FOUT MOV #PHLF,R1 CALL FOUT 70$: MOV #LOBUF,R4 ; Point to outut line buffer CALL GCI ; Get character from there .WORD 80$ ; None left ; CALL FOUT ; Output to file ; INC CPOS ; Bump up current position on line CALL CCOUT ; Output to file 80$: BITEQ #DIASW,$INSW,120$ ; if not diablo, then skip MOV #ESC,R1 CALL FOUT MOV #NHLF,R1 .IF DF R$$OCK CALL FOUT MOV #ESC,R1 CALL FOUT MOV #LF,R1 CALL FOUT MOV #LF,R1 .ENDC ;R$$OCK ; CALL FOUT ;90$: RETURN ; JMP FOUT 100$: INC CPOS ; count position of carriage 105$: JMP FOUT ; output character 110$: MOVB CPOS,@ULPOS ; into underline buffer INC ULPOS ; step buffer pointer (should check it) 120$: RETURN ; .DSABL LSB .SBTTL CCIN - READ INPUT FROM OTHER SOURCE ; routine to read input from file or footnote as appropriate CCIN:: MOVB GCSCH,R1 ; any character saved from earlier pass? BNE 30$ ; NE - Process saved character TSTEQB $SDISW,20$ ; input not from secondary buffer? MOV #SDBUF,R4 ; Point to secondary buffer CALL GCI ; get character from buffer .WORD 10$ ; NONE, Get some from input file RETURN ; 10$: CLRB $SDISW ; clear input from secondary buffer 20$: BITNE #FOTF,F.1,40$ ; characters coming from footnote? CALL FIN ; no. read from file RETURN ; 30$: CLRB GCSCH ; clear saved character RETURN ; 40$: MOV #FOOTP1,R4 ; get character from footnote string CALL GCI ; get the character .WORD 50$ ; none left, -- fatal error!!! RETURN ; 50$: FATAL HALTM ; give the halt message and restart ; CCINUC:: CALL CCIN ; Input the character. BITB #CHALC,CHATBL(R1) ; Is it a lower case letter? BEQ 10$ ; No - just return. BICB #40,R1 ; Yes - make it upper case. 10$: RETURN ; And return to the caller. .SBTTL GCI - GET CHAR. AND INC. PNTRS ; ; GCI -- Get character from input buffer pointed to by R4 ; ; If there are no characters left in the buffer, then ; return is taken to the address specified in the word ; immediately following the call. Else return is to one ; word beyond call. ; ; Example: ; ; MOV #BUFHDR,R4 ; Point to input buffer ; CALL GCI ; Get a character ; .WORD ERR ; Nothing there, error ; TST ... ; etc... ; GCI:: TST BF.LEN(R4) ; Anything there ? BLE 20$ ; LE - then nothing there CLR R1 ; Initialize for character insert BISB @BF.PTR(R4),R1 ; Insert character, no sign extend INC BF.PTR(R4) ; Point to next character in buffer DEC BF.LEN(R4) ; One less from length ADD #2,(SP) ; Return success 10$: RETURN ; 20$: MOV @(SP),(SP) ; set skip return CLR BF.LEN(R4) ; Reset length BR 10$ ; And return ; ; WCIFTN -- Write character into footnote buffer ; WCIFTN::MOV #FOOTP1,R4 ; point to footnote descriptor BR WCI ; ; ; WLNIN1 -- Write character into line buffer ; WLNIN1::MOV #LIBUF,R4 ; standard arg ; ; WCI -- Write character into buffer specified by R4 ; WCI:: CMP BF.PTR(R4),BF.END(R4) ; At end of buffer ? BHIS 10$ ; HIS - Then FATAL error CMPB #SPC,R1 ; If not printing, don't enable BGE 5$ ; change bars for the line BITEQ #CBBIT,$CBON,5$ ; Set on if change bars are on BIS #CBLIN,$CBON 5$: MOVB R1,@BF.PTR(R4) ; Store byte in buffer INC BF.PTR(R4) ; Point to next available word INC BF.LEN(R4) ; Keep count of chars. CLC ; Say it worked RETURN ; 10$: SEC ; Indicate error RETURN ; .sbttl INIBUF -- Initialize buffer header ;+ ; This module will initialize a buffer header prior to use. ; ; On entry, R4 points to the buffer header to be initialized. ; all registers are preserved. ;- INIBUF:: MOV BF.ADR(R4),BF.PTR(R4) ; Initialize pointer CLR BF.LEN(R4) ; Initialize length RETURN ; Return to caller .END