.TITLE GCIN .IDENT /V01/ ; ; These are general input/output character interpretation routines ; .vars .BLKB 1 TBUFF: .BLKB SUBMAX+2 .even ADDR: .BLKA 1 ; ; INPUT CHARACTER PARSING TABLES ; TO ADD MORE FLAGS THESE TABLES MUST BE CHANGED ; THE FLAG DEFINITIONS COORESPOND TO THE FLAG SWITCHES ; GC.UC== 0*$WORDL ; Upper case letters GC.LC== 1*$WORDL ; Lower case letters GC.AFL== 2*$WORDL ; Accept flag GC.CFL== 3*$WORDL ; Capitalize flag GC.UFL== 4*$WORDL ; Underline flag GC.LFL== 5*$WORDL ; Lowercase flag GC.SFL== 6*$WORDL ; Uppercase flag GC.QFL== 7*$WORDL ; Quoted space flag GC.OFL== 8.*$WORDL ; Overstrike flag GC.IFL== 9.*$WORDL ; Index flag GC.HFL== 10.*$WORDL ; Hyphenation flag GC.EFL== 11.*$WORDL ; Escape flag GC.SUB== 12.*$WORDL ; substitute flag GC.BRK== 13.*$WORDL ; break flag GC.NFL== 14.*$WORDL ; COMMAND FLAG GC.CR== 15.*$WORDL ; CARRIAGE RETURN GC.TAB== 16.*$WORDL ; tab input char GC.LF== 17.*$WORDL ; lin feed input GC.DIG== 18.*$WORDL ; digit (0-9) GC.SPC== 19.*$WORDL ; space GC.MSC== 20.*$WORDL ; MISCELLANEOUS CHARS GC.SPF== 21.*$WORDL ; Special flag GC.EQ1== 22.*$WORDL ; Equation flags GC.EQ2== 23.*$WORDL ; Equation flags GC.SIX== 24.*$WORDL ; Subindex flag GC.PFL== 25.*$WORDL ; PEriod flag GO.UNL== -1*$WORDL ; underline 1 char GO.ESC== -2*$WORDL ; begin escape sequence GO.QTS== -3*$WORDL ; quoted space output GO.BS== -4*$WORDL ; backspace output GO.TAB= -5*$WORDL ; Tab count byte follows GO.ELP= -6*$WORDL ; Ellipses count follows this GC.ILL= -7*$WORDL ; illegal character GO.REP= -8.*$WORDL ; Repeat characters GO.INX= -9.*$WORDL ; Index entry GO.TOC= -10.*$WORDL ; TOC entry GO.PAG= -11.*$WORDL ; Page number ; ; THE FOLLOWING CORRESPOND TO THE ASCII CHARACTERS ; GCTABL:: .BYTE GC.ILL,GC.ILL,GC.ILL,GC.ILL,GC.ILL,GC.ILL ; NUL-ENQ .BYTE GC.ILL,GC.ILL,GO.BS ; ACK-BS .BYTE GC.TAB,GC.LF,GC.ILL,GC.ILL ; TAB,LF,VT,FF .BYTE GC.CR,GC.ILL,GC.ILL,GC.ILL ; CR,SO,SI,DLE .BYTE GC.ILL,GC.ILL,GO.PAG,GO.TOC,GC.ILL ; DC1-nak .BYTE GO.INX,GO.REP,GO.TAB,GO.ELP,GC.ILL ; SYN-SUB .BYTE GO.ESC,GO.UNL,GC.ILL,GC.ILL,GC.ILL ; ESC-US .BYTE GC.SPC ; SPACE .BYTE GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC ; - & .BYTE GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC ; ' - , .BYTE GC.MSC,GC.MSC,GC.MSC ; - . / .BYTE GC.DIG,GC.DIG,GC.DIG,GC.DIG,GC.DIG ; 0 - 4 .BYTE GC.DIG,GC.DIG,GC.DIG,GC.DIG,GC.DIG ; 5 - 9 .BYTE GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC ; : - @ .BYTE GC.UC,GC.UC,GC.UC,GC.UC,GC.UC,GC.UC ; UPPER CASE .BYTE GC.UC,GC.UC,GC.UC,GC.UC,GC.UC,GC.UC ; UPPER CASE .BYTE GC.UC,GC.UC,GC.UC,GC.UC,GC.UC,GC.UC ; UPPER CASE .BYTE GC.UC,GC.UC,GC.UC,GC.UC,GC.UC,GC.UC,GC.UC,GC.UC ; UPPER CASE .BYTE GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC ; [ - ` .BYTE GC.LC,GC.LC,GC.LC,GC.LC,GC.LC,GC.LC ; LOWER CASE .BYTE GC.LC,GC.LC,GC.LC,GC.LC,GC.LC,GC.LC ; LOWER CASE .BYTE GC.LC,GC.LC,GC.LC,GC.LC,GC.LC,GC.LC ; LOWER CASE .BYTE GC.LC,GC.LC,GC.LC,GC.LC,GC.LC,GC.LC,GC.LC,GC.LC ; LOWER CASE .BYTE GC.MSC,GC.MSC,GC.MSC,GC.MSC ; { - ~ .BYTE GO.QTS ; DEL ; ; CHARACTER DEFINITION TABLE ; CH.BRK== ^o1 ; Char is followed by break CH.BRB== ^o2 ; Char is preceeded by break CH.FLC== ^o4 ; CHAR MAY BE FLAG CHAR CH.FLG== ^o10 ; CHAR IS CURRENTLY FLAG CHAR CH.PER== ^o20 ; CHAR IS PUNCTUATION CH.VOW== ^o40 ; character is a vowel CH.PNC== ^o100 ; char is punctuation (for routine HYPHEN) CH.UNL== ^o200 ; char is not underlinable CHTABL:: .BLKB 9. ; Nul-BS .BYTE CH.FLC ; Tab .BLKB 22. ; LF-US .BYTE CH.PNC!CH.UNL ; "space" .BYTE CH.FLC!CH.PNC!CH.PER ; ! .BYTE CH.FLC!CH.PNC ; " .BYTE CH.FLC ; # .BYTE CH.FLC ; $ .BYTE CH.FLC ; % .BYTE CH.FLC ; & .BYTE CH.FLC ; ' .BYTE CH.FLC!CH.PNC ; ( .BYTE CH.FLC!CH.PNC ; ) .BYTE CH.FLC ; * .BYTE CH.FLC ; + .BYTE CH.FLC!CH.PNC ; , .BYTE CH.FLC ; - .BYTE CH.FLC!CH.PER!CH.PNC ; . .BYTE CH.FLC!CH.PNC ; / .BLKB 10. ; 0 - 9 .BYTE CH.FLC!CH.PER,CH.FLC!CH.PER ; : ; .BYTE CH.FLC,CH.FLC,CH.FLC ; < = > .BYTE CH.FLC!CH.PER,CH.FLC!CH.PNC ; ? @ .BYTE CH.VOW,0,0,0,CH.VOW,0,0,0 ; A-H .BYTE CH.VOW,0,0,0,0,0,CH.VOW,0 ; I-P .BYTE 0,0,0,0,CH.VOW,0,0,0 ; Q-X .BYTE CH.VOW,0 ; Y-Z .BYTE CH.FLC ; [ .BYTE CH.FLC!CH.PNC ; \ .BYTE CH.FLC ; ] .BYTE CH.FLC ; ^ .BYTE CH.FLC ; _ underscore .BYTE CH.FLC ; ` .BYTE CH.VOW,0,0,0,CH.VOW,0,0,0 ; A-H .BYTE CH.VOW,0,0,0,0,0,CH.VOW,0 ; I-P .BYTE 0,0,0,0,CH.VOW,0,0,0 ; Q-X .BYTE CH.VOW,0 ; Y-Z .BYTE CH.FLC,CH.FLC,CH.FLC,CH.FLC ; { - ~ .BYTE CH.PNC ; DEL ; ; Contains character width ; CHWADD::.WORDA 0 CHWTAB::.BLKB 128.*FNTSIZ ; Contains character widths .even .text ILSBST: .ASCIZ /RNO -- Too many nested substitutions/ ILSBND: .ASCIZ /RNO -- Undefined substitution/ ILUNES: .ASCIZ /RNO -- Undefined escape seq./ EQER1: .ASCIZ /RNO -- Missing denominator in equation/ EQER2: .ASCIZ /RNO -- Missing right brace (}) in equation/ EQER3: .ASCIZ /RNO -- Too many nested fractions/ EQER4: .ASCIZ /RNO -- Syntax error in equation/ .even .const ; ; THE JUMP TABLE TO PARSE CHARS ; .code .WORDA HLTER .WORDA GOPAG .WORDA GOTOC .WORDA GOINX .WORDA GOREP .WORDA HLTER .WORDA GOELP .WORDA GOTAB .WORDA GOBS .WORDA GOQTS .WORDA GOESC .WORDA GOUNL GCJMP: .WORDA GCDN .WORDA GCUP .WORDA GCACC .WORDA GCCAP .WORDA GCUNL .WORDA SHFDN .WORDA SHFUP .WORDA GCQTS .WORDA GCOVR .WORDA GCIFL .WORDA GCHYP .WORDA GCESC .WORDA GCSUB .WORDA GCBRK .WORDA GCINR .WORDA GCCR .WORDA GCTAB .WORDA GCLF .WORDA GCINR .WORDA GCSPC .WORDA GCINR .WORDA GCSPF .WORDA GCEQN1 .WORDA GCEQN2 .WORDA GCSIX .WORDA GCPER ; ; GET INPUT CHARACTER FROM SOURCE FILE AND INTERPRET IT ; All registers except for R3 are destroyed ; .code GCIN:: CALL CCIN ; GET CHARACTER FROM FILE. GCIN1: MOVB (R0),R0 ; Get character type GCIN2: ADD #GCJMP,R0 ; Dispatch table JMP @(R0) ; DISPATCH ACCORDING TO TABLE ; ; HERE ARE SPECIAL CHARACTER CASES ; ; UPPER CASE GCDN: TSTB CASE ; CONVERSION NECESSARY BGE NOCONV ; No ? GCDN1: ADD #^o40,R1 ; CONVERT CASE IF NECESSARY JMP GCINR ; ; LOWER CASE LETTERS GCUP: TSTB CASE ; CONVERSION NECESSARY BLE NOCONV GCUP1: SUB #^o40,R1 ; CONVERT TO UPPER CASE NOCONV: JMP GCINR ; ; CAPITALIZE FLAG GCCAP: TSTNEB $CFLSW+1,NOCONV ; Flag temporarily disabled ? MOVB #1,CASE ; SET WORD CAPITALIZE CONVERSION VALUE BR GCIN ; ; UNDERLINE FLAG GCUNL: TSTEQB $UFLSW+1,1$ ; Flag not disabled ? JMP GCINR ; Temporarily disabled 1$: BITEQB #^C,$UNLSW,20$ ; Permanently disabled ? 10$: JMP GCIN ; Permanently disabled ? 20$: TSTNE @EQSTK,10$ ; Equation in progress ? MOV #ULCHS,R1 ; SET TO UNDERLINE CHARACTER MOVB R1,$UNLLN ; Set to mark this line as underlined JMP GCINO ; ; OVERSTRIKE FLAG GCOVR: TSTEQB $OFLSW+1,1$ ; Flag not disabled ? JMP GCINR ; Temporarily disabled 1$: BISB #SW.TDS,$AUHYP ; Temporary disable hyphenation TSTEQB $OVRSW,2$ ; Overstrike enabled JMP GCIN ; Overstrike disabled ? 2$: MOV #BS,R1 ; MAKE IT BACK SPACE MOV PHSP,R0 ; Horizontal spacing BGE 10$ ; Not proportional ? NEG R0 ; Get width 10$: ADD R0,LINBK ; Add to remaining chars SUB R0,SPCH ; Subtract from spacing characters JMP GCINO ; ; HYPHENATE FLAG GCHYP: TSTEQB $HFLSW+1,1$ ; Flag not disabled ? JMP GCINR ; Temporarily disabled 1$: TSTEQB RETSW,2$ ; No return ? JMP GCLF ; Return ? 2$: TSTNE @EQSTK,50$ ; Equation being formatted ? BISB #SW.TDS,$AUHYP ; Set temporary no auto hyphenation MOV PHSP,R0 BGE 10$ ; Not proportional ? NEG R0 ; Get positive width 10$: SUB LINBK,R0 ; Check room on page BLE 15$ ; Room for hyphen ? 12$: JMP GCIN ; No room 15$: CMPEQB LCH,#SPC,12$ ; Last char space ? CMPEQB LCH,#TAB,12$ ; or tab ? CMPEQB LCH,#NXS,12$ ; or non expandable space ? CALL BRKSV INCB HYPSP ; Hyphenation Enabled this word 50$: JMP CONTIN ; QUOTED SPACE FLAG GCQTS: TSTEQB $QFLSW+1,1$ ; Flag not disabled ? JMP GCINR ; Temporarily disabled 1$: TSTEQB RETSW,2$ ; No return JMP GCLF ; Return ? 2$: MOVB ULOCK,CASE ; RESET CASE GCQTS1: MOV #NXS,R1 ; SET NON EXPANDABLE SPACE BISB #SW.TDS,$AUHYP ; Set temporary no auto hyphenation BR GCINR1 ; AND SAVE IT GCINR: BIC #^o1002,CASE ; Reset temporary upper case conversion GCINR1: CALL PUBYT ; OUTPUT CHAR MOV TESMSK,R4 ; Cancel escapes ? BEQ 20$ ; No ? CALL ESCEND ; Cancel them 20$: MOVB LCH,R1 MOV R1,R0 ADD #CHTABL,R0 BITEQB #CH.BRK,(R0),GCINR2 ; No AutoBreak ? CMPEQB R1,#SPC,GCINR2 ; Space ? TSTNEB $AUBRK,GCINR2 ; No auto break ? TSTNE @EQSTK,GCINR2 ; Equation being formatted ? TST LINBK ; Past end of line ? BLT GCINR2 ; Yes ? BISB #SW.TDS,$AUHYP ; set temporary no hyphenation TSTEQB $TABPD,30$ ; No right tabs ? CALL BRKTS ; Set them up BR GCINR2 ; done 30$: CALL BRKSV ; Set up break here GCINR2: TSTEQB $GCEND,80$ ; Immediate end requested? DECB $GCEND ; Decrement hyphenation count BLE GCLF ; Done ? 80$: JMP GCIN ; Continue GCLF: CLRB $GCEND TSTNEB @EQSTK,10$ ; Equation pending ? RETURN 10$: CALL BKSPI ; Backspace over LF CMPEQB #2,@EQSTK,20$ ; Denominator ? ADD #EQ.NX,EQSTK ; Restack CMP EQSTK,#EQSTK ; Check if too small BHI 14$ ; Ok ? CALL HLTER 14$: MOV #EQER1,R0 ; Missing denominator CALL ILCMC JMP GCIN ; And continue 20$: MOV #EQER2,R0 ; Missing right brace CALL ILCMC JMP GCEQN2 ; Attempt to end equation GCINO: CALL PBYT ; OUTPUT CHAR JMP GCIN ; CONTINUE PARSING INPUT ; ACCEPT FLAG GCACC: TSTEQB $AFLSW+1,1$ ; Flag not disabled ? JMP GCINR ; Temporarily disabled 1$: CALL CCIN ; READ CHARACTER NO TRANSLATION CMP R1,#SPC ; Compare with space BGT 10$ ; Printable ? BNE 5$ ; Not space ? JMP GCQTS1 ; Space ? Make it quoted space 5$: JMP GCIN1 ; Less than space ? 10$: BIC #^o1002,CASE ; Reset temporary upper case conversion CALL PUBYT ; OUTPUT CHAR BIS #^o200,LCH ; Set for quoted char MOV TESMSK,R4 ; Cancel escapes ? BEQ 20$ ; No ? CALL ESCEND ; Cancel them 20$: BR GCINR2 ; ; ROUTINE TO READ INPUT FROM FILE AND REMOVE BAD INPUT ; output: R0= Location in GCTABL ; R1= CHARACTER READ ; Carry clear if OK ; R2-R5 are saved ; CCIN:: MOV BUFAD,R1 ; input buffer header CALL GBYT1 ; get input BLOS 20$ ; At end of buffer ? BIC #^C<^o177>,R1 ; CLEAR EXCESS BITS MOV R1,R0 ADD #GCTABL,R0 TSTB (R0) ; LEGAL CHARACTER? BLT CCIN ; NO GET ANOTHER CLC RETURN 20$: BCS 25$ ; Carry set ? CALL BKSPI ; Backup over 0 25$: TSTEQB SUBSTK,30$ ; End of input line ? CALL POPINS ; Go down one entry BR CCIN ; try again 30$: CALL FIN ; NO. READ FROM FILE BCC CCIN ; Successful input ? RETURN ; None to get ; ; Get params from current level of subst only ; output: R0= Location in GCTABL ; R1= CHARACTER READ ; Carry clear if OK ; CCINP:: MOV BUFAD,R1 CALL GBYT1 ; get input BCS 30$ BIC #^C<^o177>,R1 ; CLEAR EXCESS BITS BEQ 20$ ; At end of buffer ? MOV R1,R0 ADD #GCTABL,R0 TSTB (R0) ; LEGAL CHARACTER? BLT CCINP ; NO GET ANOTHER CLC RETURN 20$: CALL BKSPI ; Backup over input char 30$: CLR R1 SEC RETURN ; ; routine to parse substitution - SUBSTITUTE FLAG ; GCSUB: TSTEQB $SBFSW+1,1$ ; Flag not disabled ? JMP GCINR 1$: MOV R3,-(SP) ; save MOV BUFAD,R3 ; get buffer header for input MOV BF.FUL(R3),R1 ; For traceback DEC R1 ; Points to traceback point MOV R1,BF.VSP(R3) ; Save it MOV #TBUFF-1,R2 ; temporary buffer MOVB R1,(R2)+ ; Save flag CLRB (R2) ; Clear in case no more MOV BF.FUL(R3),-(SP) ; save current location MOV #SUBMAX,R4 ; max number of char/label 50$: CALL GBYT ; get input CMP R1,#SPC ; non printable? BLE 60$ ; yes, done MOV R1,R0 ADD #GCTABL,R0 CMPNEB (R0),#GC.LC,55$ ; Not lower case ? CMPEQ R2,#TBUFF,55$ ; Not first char ? SUB #^o40,R1 ; Make it lower case 55$: MOVB R1,(R2)+ ; Save char SOB R4,50$ ; no, continue 60$: CLRB (R2)+ ; Chock end of string MOV BF.FUL(R3),BF.HED(R3) ; End of string MOV #TBUFF,R2 ; Start of buffer CMPNEB (R2),$SBFSW,65$ ; First char not substitute flag ? MOVB #DOLAR,(R2) ; Make first char $ 65$: MOV (SP)+,R1 ; current location CALL FNDBF ; go back to it MOV #TBUFF,R0 ; Starting address CALL FNDSB ; Find substitution BCC 80$ ; Found it ? CALL ILCMC 80$: MOV (SP)+,R3 ; restore JMP GCIN ; ; Find substitutions All registers destroyed ; FNDSB:: MOV R0,ADDR ; Start of string CMPB SUBSTK,SUBSTK+1 ; max stack reached? BLO 40$ ; no MOV #ILSBST,R0 ; Too many nestings error BR 20$ 10$: CALL POPINS ; Back in stack MOV #ILSBND,R0 ; Undefined substitution error 20$: SEC return 40$: CALL PSHINS ; Set up input stack CALL BEGBF ; Start at beginning CALL GWRD ; First index BCS 10$ ; None? 50$: TSTEQ R1,10$ ; None ? CALL FNDBF ; Find next entry CALL GWRD ; get next index BCS 10$ ; end, no escape found MOV R1,R4 ; save MOV ADDR,R2 ; temporary buffer MOV BF.FUL(R3),BF.SPC(R3) ; Save index for traceback 60$: CALL GBYT ; Get next char in key word table BCS 10$ ; None? BITEQ R1,#^o140,90$ ; End of search ? 70$: CMPEQB R1,(R2)+,60$ ; match? TSTB @ADDR ; Check first byte BGT 80$ ; Not command ? DEC R2 ; Go back to last char checked CMPEQB R1,#SPC,60$ ; Space in table ? CMPNEB -1(R2),#SPC,80$ ; Char before last not space ? CMPEQB (R2)+,#SPC,70$ ; Current space ? 80$: MOV R4,R1 ; Next entry index BR 50$ ; search again 90$: MOV BF.FUL(R3),BF.VSP(R3) ; Set traceback CLR BF.HED(R3) ; Set no traceback TSTB @ADDR ; Check for command BGT 92$ ; Not commad MOVB (R2),R0 ; Get terminal char BITNEB #^o100,R0,80$ ; Alpha char ? 92$: BITEQB R1,#7,95$ ; Not a number ? MOV R1,R5 CLR -(SP) ; Chock stack 93$: CALL GWRD ; get the number TSTEQ R1,94$ ; Zero ? MOV R1,-(SP) ; Save number 94$: SOB R5,93$ MOVB #MINUS,$SEPR ; Page separator CALL ENDBF ; Set to end of buffer MOV BF.FUL(r3),R4 ; Save index MOV R4,BF.VSP(R3) ; Set traceback CALL PAGCV ; And convert number MOV BF.FUL(R3),BF.HED(R3) ; Set traceback CALL CBYT ; Chock it MOV R4,R1 ; Beginning of string CALL FNDBF ; Set to scratch location 95$: MOV R2,R1 ; end of string SUB ADDR,R1 ; find string length MOVB SUBSTK,R3 ; Get subst stack ADD #BUFADD-$WORDL,R3 ; Old stack MOV (R3),R3 ; Old stack ADD BF.FUL(r3),R1 ; Add offset to start of string CALL FNDBF ; Set to end of string TSTB @ADDR BLT 110$ ; Command ? TSTEQB $SUBSW,110$ ; substitution not suppressed? 100$: JMP POPINS ; Reset subst 110$: CLC RETURN ; done, continue with normal sequence ; ; TAB character handled here. It is expanded. ; GCTAB: TSTNEB $TBFSW+1,1$ ; Flag disabled ? TSTNE @EQSTK,1$ ; Equation being formatted ? TSTNEB $CENSW,1$ ; Centering enabled ? TSTNEB $RIGSW,1$ ; Right justify enabled TSTEQB $TABSW,2$ ; Tabs allowed ? 1$: JMP GCSPC ; NO! 2$: BISB #SW.TDS,$AUHYP ; No autohyphenation now MOVB ULOCK,CASE ; RESTORE CASE CALL BRKTS ; Test + execute right tabs CLR R2 CALL TABB ; FIND WHERE NEXT TAB STOP IS CMP R2,LINBK ; Compare with remaining dist BLE 20$ ; It is OK ? TST LINBK ; Currently too long ? BLT 10$ ; Yes CALL BKSPI ; Backup over tab to save it CALL BRKSV ; No, put break here 10$: MOVB #TAB,R1 ; Current char RETURN 20$: MOV #TABBF,R1 ; Get status CALL GBYT1 ; BITNE #TB.L,R1,30$ ; Tab only left BITNE #TB.R!TB.C,R1,25$; Tab right or center TSTEQB $TABLF,30$ ; Left justify tabs ? MOV #TB.R,R1 ; Set it to right 25$: MOV PHSP,R2 ; Only 1 space for right justify BGE 26$ ; Positive NEG R2 ; Make it positive 26$: MOVB R1,$TABPD ; Set for right tab MOV SPCH,LSPCH ; Save spacing for tab 30$: CMPNEB LCH,#TAB,35$ ; Was last char not tab ? TSTEQ LTAB,35$ ; No tab pending CALL ADDTAB ; Add r2 to previous tab BR TABXIT ; 35$: SUB R2,LINBK ; Subtrac from remaining space ADD R2,SPCH ; Add to spacing characters TSTEQB BRCNT,36$ ; Beginning of line ? CALL BKSPI ; Backup over tab to save it CALL BRKSV ; Save break before tab CALL CCIN BR 37$ 36$: CALL BRKSV ; Set break after tab 37$: MOVB #TAB,LCH ; LAST CHAR MOVB #TABO,R1 ; Set to output tab MOVB @TABBF+BF.ADD,R4; Ellipses count BIC #^C,R4 ; Clear count BNE 39$ ; Ellipses spec ? TSTEQB $ELIPS,40$ ; No ellipses? 39$: TST PHSP ; Check if proportional BLE 40$ ; Yes ? MOVB #ELIP,R1 ; Yes, set to output ellipses 40$: CALL PBYT ; Into buffer MOV BF.FUL(R3),LTAB ; Address of last tab char MOV R2,R1 ; Number of spaces CALL PBYT ; Into buffer TSTNEB $ELIPS,45$ ; Ellipses ? TSTEQ R4,TABXIT ; No ellipses ? 45$: TST PHSP ; Check if proportional BLE TABXIT ; Yes ? MOV R4,R1 ; Ellipses count CALL PBYT TSTEQ R4,TABXIT ; Done ? 50$: MOV #TABBF,R1 CALL GBYT1 ; Put ellipses into buffer CALL PBYT SOB R4,50$ TABXIT: JMP GCIN ; Next char ; ; End of line action, space if fill disabled ; GCCR: CALL BRKTS ; Test tab + break TSTNEB $BRKSW,10$ ; Break line enabled ? TSTNEB $CENSW,10$ ; Centering enabled ? TSTNEB $RIGSW,10$ ; Right justify enabled BITNE #FILLF,F.1,GCSPC ; Fill enabled ? 10$: TST LINBK ; Past end of line ? BGE TABXIT ; No ? TSTNE @EQSTK,TABXIT ; Equation in progress ? RETURN ; Yes ! ; ; Handle spaces in input stream ; SPCXIT: JMP GCIN GCSPC:: TSTEQB RETSW,1$ ; Not Return ? RETURN 1$: MOVB ULOCK,CASE ; RESTORE CASE TSTEQ @EQSTK,2$ ; Equation being formatted ? JMP 25$ ; Yes 2$: TST LINBK ; Line full ? BGE 10$ ; NO ? RETURN ; Yes, break for full line 10$: BITEQB #CH.BRK,CHTABL+SPC,15$ ; No AutoBreak ? CALL BRKTS ; Test and set up right tabs 15$: BITEQ #FILLF,F.1,30$ ; FILL disabled ? MOVB LCH,R1 ; GET PREVIOUS CHARACTER WHAT WAS IT? BEQ SPCXIT ; Start of new line ? BLT 30$ CMPEQB R1,#SPC,SPCXIT ; Space before space ? CMPEQB R1,#TAB,SPCXIT ; Tab before space ? CMPEQB R1,#NXS,SPCXIT ; Non expandable space before space ? CMPEQB R1,#CPER,17$ ; Is it following period char? TSTEQB $PERSW,30$ ; Automatic punctuation spacing disabled ? MOV R1,R0 ADD #CHTABL,R0 BITEQB #CH.PER,(R0),30$ ; Not Punctuation before space ? 17$: CMP LINBK,#1 ; Space left ? BLE 30$ ; No 20$: CALL 50$ ; Set up for space CALL PUBYT ; Save space TSTEQB $GCEND,25$ ; Immediate end ? DECB $GCEND ; Done ? BNE 25$ ; No ? RETURN 25$: MOV #NXS,R1 ; Next output non expandable space BR 40$ ; 30$: CALL 50$ ; 40$: BICB #SW.TDS,$HYPSW ; Allow hyphenation BICB #SW.TDS,$AUHYP ; Allow auto hyphenation CLRB HYPSP 45$: JMP GCINR1 ; RETURN CHAR. ; ; Section to insert spaces ; 50$: BITEQB #CH.BRK,CHTABL+SPC,55$ ; No AutoBreak ? CALL BRKSV ; Set up for break here 55$: TSTNEB $NOSPC,70$ ; No expandable spaces allowed ? INC SPCNT ; COUNT THIS SPACE MOV #SPC,R1 ; SPACE CHARACTER (EXPANDABLE) 60$: RETURN ; 70$: MOV #NXS,R1 ; Make it non expandable SPCRET: RETURN ; ; Period flag here ; GCPER: TSTNEB $PFLSW+1,10$ ; Period flag disabled ? MOVB #CPER,LCH ; Last is period flag JMP GCIN 10$: JMP GCINR ; Output char ; ; break flag here ; GCBRK: TSTEQB $BRFSW+1,1$ ; Flag not disabled ? JMP GCINR 1$: TSTNEB RETSW,SPCRET ; Return ? TSTNE @EQSTK,CONTIN ; Equation being formatted ? BISB #SW.TDS,$AUHYP ; set temporary no hyphenation TST LINBK ; Past end of line BGE 10$ ; Not yet RETURN 10$: TSTEQB $TABPD,20$ ; No right tabs ? CALL BRKTS ; Set them up BR CONTIN ; done 20$: CALL BRKSV ; Set up break here CONTIN: TSTNEB $CONT,20$ ; Continue disabled ? CALL CCIN ; Get next char CMPNEB R1,#CR,40$ ; Not CR CALL FIN ; Next line CALL LSINSV ; Save input line 20$: JMP GCIN ; And next line 40$: JMP GCIN1 ; next char ; ; Test and set up right tab ; BRKTS: MOVB $TABPD,R0 ; Check pending tabs BNE 2$ ; tab pending? 1$: RETURN 2$: CLRB $TABPD ; No more tabs pending TSTEQ LTAB,1$ ; No tab address ? MOV #-1,R2 ; Initial tab BITEQ #TB.C,R0,5$ ; No centered tabs ? MOV SPCH,R0 ; Get text size SUB LSPCH,R0 ; Minus previous size DEC R0 ; Account for tab ASR R0 ; Divided by 2 SUB R0,R2 ; Subtract from Offset 5$: CALL TABB ; Find next tab stop DEC R2 ADDTAB: CMP R2,LINBK ; Compare with remaining line BGT 10$ ; Too big ? ADD R2,SPCH ; Spacing chars SUB R2,LINBK ; Current length this line MOV LTAB,R1 ; Previous address CALL FNDBF CALL GBYT ADD R1,R2 ; Add on more MOV LTAB,R1 CALL FNDBF MOV R2,R1 CALL PBYT ; Increment old tab CALL ENDBF 10$: RETURN ; ; Set up break (save current character status) ; BRKSV:: CLRB HYPSP CALL LSINSV ; save input addresses INC BRCNT ; count breaks this line MOV PHSP,LPHSP ; Spacing at break MOV CASE,CASSAV ; SAVE CURRENT CASE MOV BF.FUL(R3),LSTSP ; POSITION IN BUFFER MOV ESMSK,LESMSK ; Save current escape mask MOVB $UNLSW,LUNLSW ; And underline status MOVB LCH,LSCH ; SAVE CHAR BEFORE SPACE MOV SPCNT,SPCNSV ; Save old space count MOV SPCH,LSPCH ; Save current spacing char count RETURN ; ; Here we handle Index flag ; GCIFL: TSTEQB $IFLSW+1,10$ ; Autoindex flag on ? JMP GCINR ; No, ouput char 10$: CALL AINDEX ; Do autoindex JMP GCIN ; Continue ; ; SUBINDEX FLAG ; GCSIX: TSTEQB $SIFSW+1,10$ ; Autoindex flag on ? JMP GCINR ; No, ouput char 10$: CMPNEB LCH,#SPC,20$ ; Not last space MOV LSTSP,R1 ; Abort last space CALL RSTBF ; Terminate buffer here 20$: CLR LCH ; Set last to null MOVB #SXCHR,R1 ; Get subindex character JMP GCINO ; Save subindex flag ; ; HERE WE HANDLE SEPARATE ESCAPE SEQUENCES ; GCESC: TSTEQB $EFLSW+1,1$ ; Flag not disabled ? JMP GCINR 1$: MOV R1,R5 ; First character MOV BUFAD,R0 ; Get input buffer MOV BF.FUL(R0),BF.VSP(R0) ; Current index saved DEC BF.VSP(R0) ; For error traceback CALL CCIN ; GET NEXT CHAR GCES1: CALL ESCSEQ ; ESCAPE SEQUENCE? BCC 10$ ; No ? MOV #ILUNES,R0 ; Message undefined escape CALL ILCMC ; Output error message 10$: JMP GCIN ; NEXT CHAR ; ; Special Flag character detected ; GCSPF: TSTEQB $SPFSW+1,1$ ; Flag not disabled ? JMP GCINR 1$: MOV #CIRCUM+^o100000,R5 ; Move in shift up operator+ temp flag CALL ESCSEQ ; Execute sequence BCC 10$ ; Not executed ? MOV #ILUNES,R0 ; Message undefined escape CALL ILCMC ; Output error message 10$: JMP GCIN ; Continue ; ; SUBROUTINE TO FIND ESCAPE SEQUENCE FROM TABLE ; ; R5=0 for begin ; =non zero for end seq ; R4=Escape sequence mask ; R3 is preserved/ all other registers changed ; .enabl LSB ESCBEG:: CLR R5 ; Look for begin sequence BR ESCEN1 ESCEND:: MOV #^o177,R5 ; Look for end sequence ESCEN1: TSTEQ R4,7$ ; No escapes ? TSTNEB $ESCSW,7$ ; Escapes disabled ? MOV R3,-(SP) ; Save current buffer MOV #ESCBF,R3 ; Escape buffer CALL BEGBF ; Start at beginning MOV (SP)+,R3 ; Restore 2$: TSTEQ R4,7$ ; Done ? CALL 11$ ; Do next sequence BCC 2$ ; Ok ? 7$: RETURN 11$: MOV R3,-(SP) ; Save current buffer MOV #ESCBF,R3 ; Escape buffer 12$: CALL GBYT ; Get count BCC 13$ ; Not Done ? MOV (SP)+,R3 ; restore SEC ; NO SEQ FOUND RETURN 13$: MOV BF.FUL(R3),-(SP); And current index MOV R1,R2 ; Character count CALL GBYT ; Skip first char CALL GBYT ; Skip second char CALL GBYT ; Get status MOV R1,-(SP) ; Save status BITNEB #ES.LCK,R1,4$ ; Is this lock status ? 3$: TST (SP)+ ; Pop status MOV R2,R1 ; number of bytes to skip ADD (SP)+,R1 ; New index CALL FNDBF ; skip them BR 12$ ; Try again 4$: CALL GBYT ; Get lock byte BLT 5$ ; Unlock ? TSTNEB R5,3$ ; Lock desired ? BIC #^C<^o17>,R1 ; Clear extra bits MOV #1,R0 ASH R1,R0 BITEQ R0,R4,3$ ; Not requested escape ? BIC R0,R4 ; Clear 1 bit BR 31$ ; Ok! 5$: TSTEQB R5,3$ ; Unlock desired ? BIC #^C<^o17>,R1 ; Clear extra bits MOV #1,R0 ASH R1,R0 BITEQ R0,R4,3$ ; Not requested escape ? BIC R0,R4 ; Clear 1 bit BITNE R0,TESMSK,6$ ; Clearing temporary bit? JMP 31$ 6$: JMP 32$ ; ; R5 = first char ; R1 = second char ; R3,R5 are preserved ; C = set if sequence not found ; ESCSEQ: MOV R3,-(SP) ; save current buffer MOV #ESCBF,R3 ; escape buffer MOV R1,R4 ; SAVE CHAR CALL BEGBF ; Start at beginning 10$: CALL GBYT ; get beginning of sequence BCC 20$ ; not end of table? 17$: MOVB R4,R1 ; GET CHAR BACK MOV (SP)+,R3 ; restore SEC ; NO SEQ FOUND RETURN 20$: MOV BF.FUL(R3),-(SP) ; And save current index MOV R1,R2 ; number of bytes in sequence CALL GBYT ; get next bytes CMPNEB R5,R1,25$ ; MATCH WITH CHAR? CALL GBYT ; get next bytes CMPEQB R4,R1,30$ ; MATCH WITH CHAR? 25$: MOV R2,R1 ; number of bytes to skip ADD (SP)+,R1 ; add on current index CALL FNDBF ; skip them BCS 17$ ; Bad address BR 10$ 30$: TSTEQB $ESCSW,27$ ; ESCAPE SEQUENCES not DISABLED? JMP 55$ ; Disabled 27$: BISB #SW.TDS,$AUHYP ; set temporary no hyphenation CALL GBYT ; Get flag byte MOV R1,-(SP) ; Save bit mask BITEQ #ES.LCK,(SP),31$ ; Not lock/Unlock ? CALL GBYT ; Get lock word BLT 21$ ; Unlock ? BIC #^C<^o17>,R1 ; Clear extra bits MOV #1,R0 ASH R1,R0 BITEQ R0,ESMSK,272$ ; Not locked on ? JMP 54$ ; currently locked on 272$: BIS R0,ESMSK ; Lock it on BITEQ #^o100000,R5,31$ ; Not temporary lock ? BITEQ #ES.CHR,(SP),31$ ; Not Temporary sequence ? BIS R0,TESMSK ; Set temporary mask BR 31$ 21$: BIC #^C<^o17>,R1 ; Clear extra bits MOV #1,R0 ASH R1,R0 BITNE R0,ESMSK,32$ ; Not locked off ? JMP 54$ ; Currently locked off ? 32$: BIC R0,ESMSK ; Lock it off BIC R0,TESMSK ; Clear temporary mask also 31$: BITEQ #ES.VSP,(SP),33$ ; No vertical spacing CALL GBYT ; Get vertical spacing TSTNEB $PAGNG,299$ ; No paging ? SUB R1,LINEC3 ; Decrement lines left ; ADD R1,BF.VSP(R3) ; Add to saved spacing - SPR 015 MOV 2*$WORDL(SP),R0 ; Location of buffer - SPR 015 ADD R1,BF.VSP(R0) ; Add on line spacing - SPR 015 299$: ADD CURVS,R1 ; Add on current VS MOV R1,CURVS ; Save current CMP R1,MINVS ; Compare with min BGT 311$ ; Bigger ? MOV R1,MINVS ; New min 311$: CMP R1,MAXVS ; Compare with max BLT 312$ ; Smaller ? MOV R1,MAXVS ; New max 312$:; ADD R1,BF.VSP(R3) ; Count deferred text line - SPR 015 33$: BITEQ #ES.HSP,(SP),40$ ; No Horizontal spacing CALL GBYT ; Get horizontal spacing BITNE #ES.PSP,(SP),35$ ; Permanent spacing ? MOVB R4,LCH ; Set last char ADD R1,SPCH ; Count spacing chars SUB R1,LINBK ; And remove from available spaces BR 40$ 35$: BICB #^o40,$NOSPC ; Set for expandable spaces ok BICB #^o40,$TABSW ; Enable tabs MOV R1,PHSP ; Set permanent horiz spacing ; BICB #SW.TD2,$AUHYP ; Temporary hyphenation off TSTNEB $VARSP,40$ ; Variable spacing on ? CMPEQ R1,#1,40$ ; Spacing 1 ? ; BISB #SW.TD2,$AUHYP ; set temporary no hyphenation BISB #^o40,$NOSPC ; Set no expandable spaces BISB #^o40,$TABSW ; Set no tabs 40$: TST (SP)+ ; Pop saved flags MOV (SP)+,R1 ; Index for transfer ADD #2,R1 ; Points to status now SUB #2,R2 ; Number of bytest to transfer CALL FNDBF ; Go back to start of sequence MOV (SP)+,R3 ; Output buffer MOV #ESC,R1 ; Mark escape sequence in output buffer CALL PUBYT1 ; OUTPUT IT MOV R2,R1 ; Number of bytes in seq CALL PBYT ; Save it *** Jan 1,1986 50$: MOV #ESCBF,R1 ; escape buffer CALL GBYT1 ; get next bytes CALL PBYT ; OUTPUT CHAR SOB R2,50$ BR 60$ 54$: TST (SP)+ ; Pop stack 55$: TST (SP)+ ; Pop stack MOV (SP)+,R3 ; Restore buffer address 60$: CLC ; SUCCESS RETURN ; .DSABL LSB ; ; ROUTINE TO FIND NEXT TABSTOP FOR OUTLIN ROUTINE. ; INPUT R2= Space to include ; OUTPUT R2= DISTANCE TO NEXT STOP ; R0,R1 are destroyed ; TABB: MOV R3,-(SP) ; Save R3 MOV R2,-(SP) ; And R2 MOV #TABBF,R3 ; Set to search tab buffer CALL BEGBF ; Start at beginning MOV LMARG,R0 ; Left margin ADD INDCT,R0 ; Plus indentation CALL CVHSP ; Get horiz spacing ADD R1,R2 ADD SPCH,R2 ; Number of spacing chars 10$: CALL GWRD ; Get next tab BCC 20$ ; Not End of buffer ? MOV LINBK,R2 ; Set at end of line SUB (SP),R2 ; Plus current amount BGT 40$ ; At least 1 space? MOV #1,R2 ; No make it 1 BR 40$ 20$: MOV R1,R0 CALL CVHSP ; Horizontal spacing CMP R1,R2 ; Compare tab with current position BGT 30$ ; Larger than current ? CALL GBYT ; Get status BIC #^C,R1 ; Chars to skip BEQ 10$ ; None ADD BF.FUL(R3),R1 ; Add on current location CALL FNDBF ; Skip em BCC 10$ ; Is it OK ? CALL HLTER ; FATAL ERROR **** 30$: SUB R2,R1 ; GET DISTANCE TO TABSTOP MOV R1,R2 ; Get into R2 40$: TST (SP)+ ; Pop old R2 MOV (SP)+,R3 ; Restore RETURN ; ; ; UPPER CASE FLAG ; .ENABL LSB SHFUP: TSTEQB $SFLSW+1,1$ ; Flag not disabled ? JMP GCINR 1$: CALL CCIN ; READ A CHARACTER MOV R1,R0 ADD #CHTABL,R0 BITEQB (R0),#CH.FLG,40$ ; Not flag character ? CMPNE R1,$UFLSW,10$ ; LOCK ON UNDERLINE? BICB #SW.TDS,$UNLSW ; UNDERLINING POSSIBLY ON BR 30$ 10$: CMPNE R1,$CFLSW,20$ ; NOT LOCK UPPER CASE? MOV #^o401,CASE ; SET UPPER CASE + LOCK BR 30$ ; READ ONOTHER CHAR 20$: CMPNE R1,$SFLSW,40$ ; NOT UNLOCK ALL? CALL UPCAS ; SET TO UPPER CASE 30$: JMP GCIN ; AND GO READ ANOTHER CHARACTER 40$: MOVB $SFLSW,R5 ; MATCH CHAR CALL ESCSEQ ; SEARCH FOR ESCAPE SEQUENCE BCC 30$ ; FOUND ONE! MOV R1,R0 ADD #GCTABL,R0 MOVB (R0),R0 ; CHAR TYPE? CMPNE R0,#GC.LC,50$ ; NOT LOWER CASE? JMP GCUP1 ; LOWER CASE, SHIFT IT. 50$: CMP R0,#GC.LC ; ALPHABETIC CHAR? BLE 60$ ; YES, DO NOT EXECUTE IT JMP GCIN2 60$: JMP GCINR ; ; LOWER CASE FLAG DETECTED ; SHFDN: TSTEQB $LFLSW+1,2$ ; Flag not disabled ? JMP GCINR 2$: CALL CCIN ; GET ANOTHER CHARACTER MOV R1,R0 ADD #CHTABL,R0 BITEQB (R0),#CH.FLG,80$ ; Not flag character ? CMPNE R1,$UFLSW,70$ ; UNLOCK UNDERLINE? BISB #SW.TDS,$UNLSW ; UNDERLINING OFF BR 30$ ; 70$: CMPNE R1,$LFLSW,80$ ; NOT LOWERCASE LOCK? CALL LWCAS ; SET LOWER CASE SHIFT BR 30$ ; 80$: MOVB $LFLSW,R5 ; MATCH CHAR CALL ESCSEQ ; HANDLE ESCAPE SEQUENCES BCS 82$ ; No escape seq ? BR 30$ ; Found esc seq 82$: MOV R1,R0 ADD #GCTABL,R0 MOVB (R0),R0 ; CHAR TYPE? CMPNE R0,#GC.UC,50$ ; NOT UPPER CASE? BITNE #UPCSW,$SWTCH,60$ ; IS UP SHIFT MANDATED? JMP GCDN1 ; SHIFT TO LOWER CASE .DSABL LSB ; ; CASE SELECTION COMMANDS ; .ENABL LSB LWCAS:: MOV #-1,R1 ; SET FOR CONVERSION TO LOWER CASE BR 10$ ; UPCAS:: CLR R1 ; SET FOR NO CASE CONVERSION 10$: BITEQ #UPCSW,$SWTCH,20$ ; Not Upper case only? MOV #^o401,R1 ; FORCE TO UPPER CASE 20$: MOV R1,CASE ; SET CASE CONVERSION RETURN ; .DSABL LSB ; ; COROUTINE TO SHIFT TO UPPER CASE TEMPORARILY ; SHFUC:: MOV (SP),-(SP) ; COPY RETURN ADDRESS MOV CASE,$wordl(SP) ; SAVE CURRENT CASE MOV #^o401,CASE ; UPPER CASE ONLY CALL @(SP)+ ; CALL THE CALLER BACK MOV (SP)+,CASE ; RESTORE PREVIOUS CASE SHXIT: RETURN ; ; ; PUT STRING ENDED BY ZERO BYTE TO BUFFER ; R0= STRING ADDRESS ; PSTRZB::MOV R2,-(SP) ; Save R2 MOV R0,R2 10$: MOVB (R2)+,R1 ; Get char BEQ 20$ ; If zero done ? CALL PBYT ; PUT IT BR 10$ ; CONTINUE 20$: MOV (SP)+,R2 ; Restore RETURN ; ; ROUTINES TO OUTPUT A STRING TO THE OUTPUT FILE ; R3=BUFFER ADDRESS FOR STRING ; Output terminates at either null or end of input buffer ; Z or C tell user what form of termination occurred. ; ; This one starts at top of buffer PSTRPA::CALL BEGBF ; SET TO TOP OF BUFFER CLR EXSP1 ; No multiple spaces CLR EXSP2 ; No multiple spaces MOVB #-1,EXSP3 ; No multiple spaces CLRB EXSTAT ; No status CLR EXMSP ; No multiple micro spaces ; ; This one starts anywhere in buffer ; R3 is preserved all other registers destroyed ; CCOUT:: CLRB $ULOSW ; No underlining at first CCOUT2: CALL GBYT ; Get 1 byte BHI 1$ ; Not done ? RETURN ; Done on zero or carry set 1$: BGT 10$ ; No extra bits INCB $ULOSW ; Set underline 10$: BIC #^C<^o177>,R1 ; Clear extra bits CMPEQB R1,#SPC,GOSPC ; Is it space ? MOV R1,R0 ADD #GCTABL,R0 MOVB (R0),R0 ; GET CHAR TYPE BGE GOPRN ; PRINTABLE ADD #GCJMP,R0 JMP @(R0) ; DISPATCH ACCORDING TO TABLE ; Handle single underline GOUNL: INCB $ULOSW BR CCOUT2 ; Printable char GOPRN: CALL CCPRN ; Print 1 char BR CCOUT GOSPC: MOV EXMSP,-(SP) ; Micro spaces MOV EXSP1,-(SP) ; YES. HOW MANY MULTIPLE SPACES? DEC EXSP2 ; TO EXTRA BLANKS YET? BGE 70$ ; NO. TSTEQB EXSP3,80$ ; EXTRA SPACES TO RIGHT? BR 90$ ; LEFT. NO MORE EXTRAS, JUST LOOP 70$: TSTEQB EXSP3,90$ ; NO EXTRA SPACES LEFT OR RIGHT? 80$: BITEQB #HD.VAR,EXSTAT,85$ ; No micro spacing ? INC $wordl(SP) ; Micro spacing count BR 90$ 85$: INC (SP) ; Extra space to output 90$: BITEQB #HD.VAR,EXSTAT,110$ ; No micro spacing ? MOV $wordl(SP),R1 ; count DEC R1 BLE 110$ ; micro count too small ? TSTEQB $ULMSW,94$ ; Underline by BS ? MOV CPOS,R0 ; Current position CMP R0,#ULNSZ ; check with max BHI 95$ ; Too big ? BIS #^o200,R1 ; Now is count for underline buffer MOVB R1,UBUFF-1(R0) ; Into buffer MOVB #-1,$UNLRS INC CPOS ; Next position BR 95$ 94$: TSTEQB $ULOSW,95$ ; No underlining ? MOV #1,R2 ; Number of chars to underline CALL CCUNL 95$: MOV $wordl(SP),R1 ; micro spaces DEC R1 CALL VAROUT ; Output variable escap seq 110$: CALL CCSPC ; OUTPUT SPACES DEC (SP) ; Decrement counter BGT 110$ ; Not done ? CMP (SP)+,(SP)+ ; Pop counters JMP CCOUT GOQTS: CALL CCSPC ; Turn quoted space to single space JMP CCOUT ; ; Put variable escape seq into buffer ; INPUT: ; R1 = number of micro spaces ; VAROUT::TST R1 BLE 30$ ; No count ? MOV R2,-(SP) ; Save MOV R4,-(SP) MOV R5,-(SP) MOV R1,R5 ; Total count 1$: MOV #VARESC+1,R2 ; Address of escape sequence buffer MOVB (R2)+,R4 ; Count BLE 20$ ; None ? 10$: MOVB (R2)+,R1 ; Data to output CALL FOUT ; Output it SOB R4,10$ ; Output it SOB R5,1$ 20$: MOV (SP)+,R5 MOV (SP)+,R4 ; Restore MOV (SP)+,R2 30$: RETURN ; ; Output escape sequences ; GOESC: CALL GBYT ; Get count MOV R1,R4 ; Save it DEC R4 ; Decrement count CALL GBYT ; Get flag byte MOV R1,-(SP) ; Save bit mask BITEQB #ES.LCK,(SP),10$ ; Not lock/Unlock ? DEC R4 ; Decrement count CALL GBYT ; Get lock word 10$: BITEQB #ES.VSP,(SP),20$ ; No vertical spacing DEC R4 ; Decrement count CALL GBYT ; Get vertical spacing TSTNEB $PAGNG,20$ ; No paging SUB R1,LINEC1 ; Decrement lines left SUB R1,LINEC2 ; Decrement lines left 20$: BITEQB #ES.HSP,(SP),80$ ; No Horizontal spacing DEC R4 ; Decrement count CALL GBYT ; Get horizontal spacing BLE 80$ ; Too small ? BITNEB #ES.PSP,(SP),40$ ; Permanent spacing ? TSTNEB $ULOSW,30$ ; Underline ? ADD R1,CPOS ; No BR 80$ 30$: MOV R1,R2 ; Number of underlines CALL CCUNL ; Perform underlining BR 80$ 40$: MOV R1,PHSPOU ; Set permanent horiz spacing ; ; Now output escape sequence ; 80$: TST (SP)+ ; Pop status TST R4 ; Check count BLE 100$ ; Done ? 90$: CALL GBYT ; Get escape sequence chars CALL FOUT ; Output char with no interpretation SOB R4,90$ ; More ? 100$: JMP CCOUT ; End of escape seq buffer ? ; ; Handle backspaces ; GOBS: SUB PHSPOU,CPOS ; New position BGT 10$ ; OK ? MOV #1,CPOS ; No, make it 1 10$: CALL FOUT ; Output backspace JMP CCOUT ; ; Handle tabs ; GOTAB: CALL GBYT ; Get next input byte MOV R1,-(SP) ; Save it 10$: DECB (SP) ; Done? BGE 20$ ; Not done yet TST (SP)+ ; Pop stack JMP CCOUT 20$: CALL CCSPC ; Output a space BR 10$ ; Check it ; Handle tabs with ellipses GOELP: CALL GBYT ; Get 1 byte CLR -(SP) ; Clear counter on stack MOVB R1,(SP) ; Save count CALL GBYT ; Get ellipses count MOV #TBUFF,R4 ; Temporary buffer MOV R1,R2 ; Count MOV R1,R5 ; Count BEQ 6$ ; No ellipse spec ? 5$: CALL GBYT ; Get chars MOVB R1,(R4)+ ; Till done SOB R5,5$ ; Get them all BR 7$ 6$: MOVB #SPC,(R4)+ ; set first MOVB #PD,(R4)+ ; second MOV #2,R2 ; And count 7$: CLRB (R4)+ ; chock buffer DEC (SP) ; Output 1 char ? BLE 15$ ; No, done CALL CCSPC ; DIV$ R2,CPOS ; Divide CPOS/R2 result = R0 ADD #TBUFF-1,R1 ; Add on temporary buffer address MOV R1,ADDR 10$: DEC (SP) BGT 20$ ; Spaces to output ? 15$: BLT 16$ ; No output ? CALL CCSPC ; Output 1 space 16$: TST (SP)+ ; Done so pop stack JMP CCOUT 20$: INC ADDR MOVB @ADDR,R1 ; Char to print BNE 30$ ; Char ok ? MOV #TBUFF-1,ADDR ; No, start at beginning BR 20$ 30$: CALL CCPRN ; Output printable char BR 10$ ; ; Handle repeated output ; GOREP: CALL GBYT ; Get repeat count BNE 5$ ; Repeat not zero ? CALL ENDREP ; SKip it JMP CCOUT ; And do more 5$: CLR -(SP) ; Clear count on stack MOVB R1,(SP) ; Save count MOV BF.FUL(R3),-(SP) ; Save input index 10$: CALL CCOUT ; Now output string DEC $wordl(SP) ; Done ? BLE 20$ ; Yes ? MOV (SP),R1 ; Rewind input buffer CALL FNDBF ; Back over string BR 10$ ; Repeat 20$: CMP (SP)+,(SP)+ ; Pop stack JMP CCOUT ; And continue ; ; section to fill in index entries ; GOINX: CALL GWRD ; Get address inside index buffer MOV R1,R4 ; backward link MOV R3,-(SP) ; Save MOV #INXBF,R3 ; Get index buffer address CALL FNDBF ; get next entry BCS 11$ ; None ? CALL GWRD ; get link to next MOV R1,R5 10$: MOV R5,R1 ; next entry BEQ 15$ ; End of line ? CALL FNDBF ; find it BCC 12$ ; OK ? 11$: CALL HLTER 12$: CALL GWRD ; get next foreward link BCS 11$ ; None ? MOV R1,R2 CALL GBYT ; get status byte BCS 11$ ; None ? BITNE #X.ENT,R1,15$ ; No entry ? MOV R5,R4 ; R4 has backward link MOV R2,R5 ; next foreward link BR 10$ 15$: MOV R4,R1 ; Go back to last one CALL FNDBF ; Get the index entry address BCS 11$ ; None ? MOV BF.MAX(R3),R1 ; New entry address CALL PWRD ; Link to end CALL ENDBF ; Now go to end MOV R5,R1 ; Save foreward link CALL PWRD MOV #X.PAG,R1 ; Set for page number TSTNEB $CHPSW,30$ ; no chapter print? BITEQ #NM.MSK,APNDN,20$ ; No appendix? BIS #X.AP,R1 ; Set appendix status BR 30$ ; no chapter if appendix 20$: BITEQ #NM.MSK,CHPTN,30$ ; No chapter? BIS #X.CH,R1 30$: BITEQ #NM.MSK,SUBPGE,40$ ; No subpage? BIS #X.SPG,R1 40$: CALL PBYT ; Save status bits TSTNEB $CHPSW,60$ ; no chapter print? MOV APNDN,R1 BEQ 50$ BIS APNDSP,R1 ; Set display bits BR 55$ 50$: MOV CHPTN,R1 BEQ 60$ BIS CHPDSP,R1 ; Set display bits 55$: CALL PWRD ; put chapter 60$: MOV PAGENO,R1 BNE 65$ ; Not zero ? INC R1 ; Make it 1 65$: BIS PAGDSP,R1 ; Add on display bits CALL PWRD ; put chapter 70$: MOV SUBPGE,R1 ; Subpage number BEQ 80$ BIS SUBDSP,R1 ; Display bits CALL PWRD ; put subpage 80$: MOV (SP)+,R3 ; Restore JMP CCOUT ; ; Routine to output TOC entries ; GOTOC: MOV #TTBUF,R2 ; Get temporary buffer 10$: CALL GBYT ; Get 1 byte MOVB R1,(R2)+ ; Into buffer BNE 10$ MOV #TTBUF+1,R1 ; Address of array SUB R1,R2 ; Size of array DEC R2 ; Final BLE 40$ ; None ?? CALL OUTTOC ; Output the toc line TSTB TTBUF ; Check type of output BLE 40$ ; No number requested ?? MOV R3,-(SP) ; Save R3 MOV #TTBF,R3 ; Get temporary buffer CALL CLRBF ; Clear it MOV #TAB,R1 ; Tab char. CALL PBYT ; into buffer MOV #TOCM1,R0 ; Pre-header CALL PSTRZB ; Ino buffer CALL PUTPAG ; Get page number MOV #TOCM1,R0 ; Post-header CALL PSTRZB MOV BF.FUL(R3),R2 ; Get size MOV (SP)+,R3 ; Restore MOV #TTBUF,R1 ; Start of buffer CALL OUTTOC ; And output it 40$: JMP CCOUT ; ; Set up page number ; GOPAG: MOV R3,-(SP) CALL GWRD ; Get page number index MOV R1,R2 MOV #SUBF0,R3 ; Substitution buffer CALL BEGBF ; Reset to beginning of buffer MOV R2,R1 CALL FNDBF ; Get location BCS 10$ CALL GETPAG ; Get page number 10$: MOV (SP)+,R3 ; Restore JMP CCOUT ; Return ; ; Routine to get page number into buffer in symbolic rep. ; GETPAG::CLR R1 TSTNEB $CHPSW,20$ ; No chapter ? MOV APNDN,R1 ; Get appendix BEQ 10$ BIS APNDSP,R1 ; And format BR 20$ 10$: MOV CHPTN,R1 ; Chapter number BEQ 20$ ; None ? BIS CHPDSP,R1 ; And format 20$: CALL PWRD MOV PAGENO,R1 ; Get page number BNE 25$ ; Not zero ? INC R1 ; Set it to 1 25$: BIS PAGDSP,R1 ; Set format CALL PWRD ; Save current page CLR R1 ; Incase no subpage TSTEQ $SBPSW,30$ ; No subpage ? MOV SUBPGE,R1 ; Get subpage BIS SUBDSP,R1 ; And format 30$: CALL PWRD RETURN ; ; Subroutine to output printable chars ; CCSPC:: MOV #SPC,R1 ; GET SPACE CCPRN: TSTEQB $ULOSW,NOUNL ; No underlining ? MOV PHSPOU,R2 ; Number of underlines CALL CCUNL ; YES, DO IT JMP FOUT ; output character NOUNL: ADD PHSPOU,CPOS ; INCREMENT POSITION COUNTER JMP FOUT ; OUTPUT CHAR ; ; Do underlining ; R2 = Number of positions to underline ; CCUNL: MOV R1,-(SP) ; SAVE CHAR 80$: TSTNEB $ULMSW,90$ ; Underline by line or sim. ? MOV R2,-(SP) ; Save count ADD R2,CPOS ; New position 82$: MOV #LPUS,R1 ; GET UNDERLINE CALL FOUT ; OUTPUT IT SUB PHSPOU,R2 ; Remaining count BGT 82$ ; More to do ? MOV (SP)+,R2 ; Get count again 84$: MOV #BS,R1 ; GET BACKSPACE CALL FOUT ; OUTPUT IT SUB PHSPOU,R2 ; Remaining count BGT 84$ ; More to do ? BR 100$ 90$: MOV CPOS,R0 ; POSITION CMP R0,#ULNSZ ; TOO BIG? BHI 95$ ; YES MOVB $ULCH,UBUFF-1(R0) ; PUT IT INTO BUFFER CMP R0,ULNMAX ; SMALLER DUE TO BS BLOS 100$ ; YES, KEEP MAX MOV R0,ULNMAX ; AND SAVE LAST ADDRESS 95$: INC CPOS SOB R2,90$ ; Do it for each char 100$: MOV (SP)+,R1 ; GET SAVED CHAR RETURN ; ; Routine to get character width ; INPUT: R1=character ; OUTPUT: R0=width ; GETCHW::MOV PHSP,R0 ; Horizontal spacing BGE 10$ ; Not proportional ? NEG R0 MOV R1,-(SP) ADD #CHWTAB,R1 MOV (R1),R1 ; Get width CMPNE R0,CHWTAB+40,5$ ; Not correct table ? MOV R1,R0 BR 7$ ; Save 5$: MUL$ R1,R0 DIV$ CHWTAB+40,R1 ; Divide by space 7$: MOV (SP)+,R1 ; Restore char 10$: RETURN ; ; Output byte underlined ; PUBYT:: MOVB R1,LCH ; SAVE LAST CHARACTER CALL GETCHW ; Get character width ADD R0,SPCH ; Add to spacing char count SUB R0,LINBK ; Subtract from char count remaining BCC PUBYT1 ; Not crossed end of line ? MOV BF.FUL(R3),LNINS; Char count at last character TSTNEB $LINBR,PUBYT1 ; Do not automatically break ? TSTNEB @EQSTK,PUBYT1 ; Equation in progress ? TSTNE BRCNT,PUBYT1 ; Breaks this line? CALL BKSPI ; Backup input MOV #-1,LINBK ; Set false indicator of bad line CALL BRKSV CALL CCIN MOVB LCH,R1 ; Get char again PUBYT1: TSTNEB $UNLSW,10$ ; No underline this char ? TSTNE @EQSTK,10$ ; Equation in progress ? MOV R1,R0 ADD #CHTABL,R0 BITNEB #CH.UNL,(R0),10$ ; Underlining not allowed ? BIS #^o200,R1 ; Mark it as underlined 10$: JMP PBYT ; OUTPUT CHAR ; ; This is an equation writing routine ; It will parse fractions written in the form: ; { . . . }/{. . .} ; and using standard letter quality printer escape sequences ; generate factions. ; ; ; The first left brace generates: ; 1. Shift up ; 2. Multiple spaces = 0 ; ; The numerator right brace ( }/{ ) ; 1. Shift down ; 2. Multiple BS ; 3. Multiple underscore ; 4. Multiple BS ; 5. Shift down ; ; Denominator right brace ; 1. Multiple spaces ? ; 2. Shift up ; ; EQSTK contains the following ; Word 0 = 0 ; . . . . . . . ; 1+N = Index points to beginning of numerator ; 2+N = Shift up count ; 3+N = Vertical space occupied ; 3+N = Current spacing ; 4+N = Type (1 = Numerator, 2 = Denom.) ; . . . . . . . ; EQ.HS=-1*$WORDL ; Offset from type EQ.VSZ=-2*$WORDL ; Offset to vertical size EQ.VSP=-3*$WORDL ; Offset from type for horiz spacing param EQ.AD=-4*$WORDL ; Offset from type for address of output EQ.NX=-5*$WORDL ; Offset to next stack entry ; ; Add word to equation stack ; R0=word to add ; STACK: CMP EQSTK,#EQSEN-$WORDL ; Past end of stack ? BHIS EQERR3 ; Yes ? ADD #$WORDL,EQSTK ; Incrment stack pointer MOV R0,@EQSTK ; Save value RETURN EQERR3: MOV #EQER3,R0 CALL ILCMC ; Output error message JMP GCIN ; ; ; Routine to alter shifts if necessary ; SHIFT: CMP R1,EQ.VSP(R5) ; Extra shift needed BLE 10$ ; No extra needed MOV R1,EQ.VSP(R5) 10$: MOV EQ.VSP(R5),R1 ; New shift count CMP R2,EQ.VSZ(R5) ; Check vertical size BLE 20$ ; Not larger than saved ? MOV R2,EQ.VSZ(R5) ; Save new one 20$: MOV EQ.VSZ(R5),R2 ; New vertical size RETURN ; ; Found left brace { ; ; ; Service equation flags ; GCEQN1: TSTNEB $EQFSW+1,NOEQ ; No equations allowed ? MOVB #LPAREN,R1 ; Just in case no flag TSTNEB $EQUSW,NOEQ ; Equation disabled ? CALL PADIT ; Check for subscripts/superscripts MOV BF.FUL(R3),R0 ; And current buffer pointer CALL STACK ; EQ.AD MOV #1,R2 ADD EQSPC,R2 ; Plust extra MOV R2,R0 ; Save on stack CALL STACK ; EQ.VSP CALL UP ; Shift up CLR R0 ; Vertical size CALL STACK ; EQ.VSZ MOV SPCH,R0 ; Save the current spacing chars CALL STACK ; EQ.HS MOV #1,R0 ; And now the type CALL STACK ; EQ.TYP MOV #NXS,R4 ; Character to store CLR R2 ; Number of times CALL REPEAT JMP GCIN ; Continue NOEQ: JMP GCINR ; No char formation ; ; Found right brace } ; GCEQN2: TSTNEB $EQFSW+1,NOEQ ; No equations allowed ? MOVB #RPAREN,R1 ; In case no equation TSTNEB $EQUSW,NOEQ ; Equation disabled ? CALL PADIT ; Check for subscripts/superscripts MOV EQSTK,R5 ; Get current stack CMPNE (R5),#1,10$ ; End of denominator ? JMP GCEQ3 ; Parse End of numerator 10$: CMPEQ (R5),#2,11$ ; End of denom ? CALL HLTER ; Bad stack 11$: MOV EQ.VSP(R5),R2 ; Shift back up CALL UP MOV SPCH,R2 ; Current spacing SUB EQ.NX+EQ.HS(R5),R2 ; - previous spacing BGT 12$ ; OK ? JMP EQERR4 ; Bad ? 12$: SUB EQ.HS(R5),R2 ; Subtract numerator spacing BNE 15$ ; Not done ? JMP 50$ ; Done ? 15$: BGT 40$ ; Denom bigger ? NEG R2 ADD R2,SPCH ; Adjust spacing char count SUB R2,LINBK MOV R2,-(SP) ; Save ASR R2 ; Divide by 2 BEQ 20$ ; No spaces at end MOV #NXS,R4 ; Add on spaces at end CALL REPEAT 20$: SUB R2,(SP) ; Now spacing at beginning of line MOV (SP)+,R2 ; Get result BNE 25$ ; Ok ? JMP 50$ ; None at beginning 25$: MOV EQ.AD(R5),R1 ; Buffer index for spacing CALL FNDBF CALL SKPREP ; Skip shift down 1. CALL SKPREP ; Skip BS 2. CALL SKPREP ; Skip underline 3. CALL GBYT ; Skip begin of next rep MOV EQ.HS(R5),R1 ; Previous spacing SUB R2,R1 ; New Backspace count CALL PBYT ; Save the space count BR 50$ ; Now handle vertical spacing 40$: MOV R2,-(SP) ; Save count ASR R2 ; Divide by 2 BEQ 45$ ; No count MOV EQ.NX+EQ.AD(R5),R1 ; left brace output index CALL FNDBF CALL SKPREP ; Now have spacing count CALL GBYT ; Skip repeat start MOV R2,R1 ; Actual number of spaces CALL PBYT 45$: MOV EQ.AD(R5),R1 ; Get index CALL FNDBF ; Get location CALL SKPREP ; Skip shift param CALL GBYT ; Skip repeat start MOV EQ.HS(R5),R1 ; Backspace count ADD R2,R1 ; + spaces at beginning CALL PBYT ; And save it CALL SKPREP ; Now have underline repeat CALL GBYT ; Skip repeat start ADD EQ.HS(R5),(SP) ; Total number of char in denom MOV (SP),R1 ; Actual underline size CALL PBYT CALL SKPREP ; Next BS CALL GBYT ; Skip repeat start MOV (SP)+,R1 ; Number to do CALL PBYT 50$: MOV EQ.NX+EQ.AD(R5),R1 ; Adjust the vertical spacing CALL FNDBF ; Get vertical spacing repeat CALL GBYT ; Skip repeat spec. MOV EQ.NX+EQ.VSP(R5),R1 ; Adjusted vertical spacing MOV R1,R2 ; Save CALL PBYT MOV EQ.AD(R5),R1 ; Denominator CALL FNDBF CALL GBYT ; Skip repeat spec. DEC R2 ; MOV R2,R1 ; Back to line vs CALL PBYT MOV #4,R4 ; Skip 4 params 60$: CALL SKPREP SOB R4,60$ CALL GBYT ; Skip repeat start MOV EQ.VSP(R5),R1 INC R1 ; Plus 1 CALL PBYT ; New vertical spacing MOV EQSTK,R0 ; Current stack address MOV EQ.VSZ(R0),R1 ; Denominator ADD EQ.VSP(R0),R1 ; Total denom size ADD #EQ.NX,R0 ; Next entry MOV EQ.VSZ(R0),R2 ; Numerator size ADD EQ.VSP(R0),R2 ; Total numerator size ADD #EQ.NX,R0 ; Next entry MOV R0,EQSTK TSTNE (R0),100$ ; Equation not ended ? TSTEQB $SEQSW,80$ ; No separated equations ? BITNE #FOTF,F.1,80$ ; Footnote in progress ? DEC R1 ; Size -1/2 line already accounted for DEC R2 ; Ditto CMP R1,EQBOT ; Compare with current value BLE 65$ ; Smaller ? MOV R1,EQBOT ; Save size 65$: CMP R2,EQTOP ; Compare with current value BLE 80$ ; Smaller ? MOV R2,EQTOP ; Save top size 80$: TSTEQ BRCNT,90$ ; No breaks this line ? TST LINBK ; Past end of line ? BLT 100$ 90$: CALL ENDBF ; Back at end of buffer ; CALL BRKSV ; Put line break here 100$: CALL ENDBF JMP GCIN ; Continue ; ; Error during text processing ; EQERR5: CALL BKSPI EQERR4: TSTEQ @EQSTK,10$ ; No equation in progress ? ADD #EQ.NX,EQSTK ; Restack kill this entry 10$: MOV #EQER4,R0 CALL ILCMC ; Output error message JMP GCIN ; Next char ; ; End numerator ; GCEQSK: CALL CCIN BCC 1$ ; Not end of input TST (SP)+ ; REturn to user RETURN 1$: CMPEQB R1,#SPC,GCEQSK ; Space ? CMPEQB R1,#TAB,GCEQSK ; Tab ? 10$: RETURN GCEQ3: CALL GCEQSK ; Skip over end of line CMPEQB R1,#SLASH,GCEQ3 ; Slash ? CMPNEB R1,#LBRACE,EQERR5 ; Error in parsing ? not left brace ? MOV BF.FUL(R3),R0 ; And current buffer pointer CALL STACK ; EQ.AD MOV EQ.VSP(R5),R2 ; Previous vertical shift DEC R2 ; - 1 CALL DOWN ; Now execute a shift down MOV #1,R0 ADD EQSPC,R0 ; Vertical shift for stack CALL STACK ; EQ.VSP Save shift on stack CLR R0 ; Vertical size CALL STACK ; EQ.VSZ MOV SPCH,R0 ; Current spacing SUB EQ.HS(R5),R0 ; Horizontal movement MOV R0,R2 ; Save BGT 20$ ; Is it positive ? JMP EQERR4 ; Bad ! 20$: SUB R0,SPCH ADD R0,LINBK ; Set back to old spacing char CALL STACK ; EQ.HS Save it for convenience MOV #2,R0 ; And now the type CALL STACK ; EQ.TYP MOV #BS,R4 ; Repeat backspace CALL REPEAT MOV #UNDSC,R4 ; Repeat underline CALL REPEAT MOV #BS,R4 ; Back space again CALL REPEAT MOV #2,R2 ; Down shift to execute CALL DOWN ; Now shift down JMP GCIN ; ; Pad the equation with 1/2 lines as necessary ; PADIT: MOV EQSTK,R5 ; Get stack location TSTEQ (R5),100$ ; First time thru ? MOV MINVS,R2 ; Subscripts NEG R2 ; Correct sign MOV MAXVS,R1 ; Plus Superscripts INC R1 ; Account for 1/2 line INC R2 ; Ditto 5$: CMPEQ (R5),#1,10$ ; Numerator ? MOV R2,-(SP) MOV R1,R2 ; Reverse order MOV (SP)+,R1 10$: TSTEQ (R5),100$ ; Done ? CALL SHIFT ; Check if spacing is correct CMPEQ (R5),#1,30$ ; Current is numerator ? ADD #EQ.NX,R5 ; Next entry ADD R2,R1 ; Now is shift up MOV EQ.VSZ(R5),R2 ; Get size above numerator ADD EQ.VSP(R5),R2 ; Add shift up ADD #EQ.NX,R5 ; Next entry BR 5$ 30$: ADD #EQ.NX,R5 ; Next entry CMPEQ (R5),#1,40$ ; Another numerator? ADD R2,R1 ; Add size to shift CLR R2 ; Clear shift BR 10$ 40$: ADD R1,R2 ; Add shift to spacing CLR R1 BR 10$ 100$: CLR MAXVS ; Maximum vertical spacing CLR MINVS ; Minimum vertical spacing CLR CURVS ; And clear current RETURN ; ; Enter repeating char into output ; R4=Char to repeat ; R2=Repeat count ; REPEAT: MOV #REPO,R1 ; Set for repeat CALL PBYT MOV R2,R1 ; Repeat count CALL PBYT MOV R4,R1 ; Char to repeat CALL PBYT ; Now output character CALL CBYT RETURN ; ; Put up/down shifts into output ; INPUT: ; R2 = Number of shifts ; OUTPUT: ; R2 Destroyed ; DOWN: MOV #DNTAB,-(SP) ; Table BR UP1 UP: MOV #UPTAB,-(SP) ; Table UP1: MOV #REPO,R1 ; Get repeat char CALL PBYT ; To output MOV R2,R1 ; Number of shifts CALL PBYT ; Into buffer 10$: MOV (SP)+,R2 ; Characters to transfer MOV R4,-(SP) ; Save R4 MOVB (R2),R4 ; Count BLE 20$ ; Zero or negative ? MOV #ESC,R1 ; Set up for escape CALL PBYT INC R4 15$: MOVB (R2)+,R1 ; Characters CALL PBYT ; Tranferred to buffer SOB R4,15$ ; Till done 20$: MOV (SP)+,R4 ; Restore CALL CBYT ; Terminate repeat RETURN ; ; Skip over a repeat function ; SKPREP: CALL GBYT ; Get next char in output buffer BNE 1$ ; Not null ? RETURN ; Done 1$: CMPNEB R1,#REPO,2$ ; Repeat ? CALL GBYT ; Skip count BR ENDREP ; Now end the repeat 2$: CMPNEB R1,#ESC,SKPREP ; Not escape ? CALL ENDESC ; End escape seq BR SKPREP ; ; Subroutine to find end of repeat function ; ENDREP: CALL GBYT ; Get next char in output buffer BNE 1$ ; Not null ? RETURN ; Done 1$: CMPNEB R1,#REPO,2$ ; Repeat ? CALL GBYT ; Skip count BR ENDREP 2$: CMPNEB R1,#ESC,ENDREP ; Not escape ? CALL ENDESC ; End escape seq BR ENDREP ; ; Skip over escape seq ; ENDESC: MOV R2,-(SP) ; Save R2 CALL GBYT ; Begin next param MOV R1,R2 ; Count 3$: CALL GBYT SOB R2,3$ ; Skip escape seq. MOV (SP)+,R2 ; Restore RETURN .END