.TITLE GCIN .IDENT /V01/ .PSECT $TEMP,RW,D,OVR,GBL TBUFF: .BLKB 12. .PSECT GCTABL,RW,D ; ; INPUT CHARACTER PARSING TABLES ; TO ADD MORE FLAGS THESE TABLES MUST BE CHANGED ; THE FLAG DEFINITIONS COORESPOND TO THE FLAG SWITCHES ; GC.UC==0 GC.LC==2 GC.AFL==4 ; THESE REFLECT THE ORDER OF THE FLAG WORD SWITCHES GC.CFL==6 GC.UFL==10 GC.LFL==12 GC.SFL==14 GC.QFL==16 GC.OFL==20 GC.IFL==22 GC.HFL==24 GC.EFL==26 GC.SUB==30 ; substitute flag GC.BRK==32 ; break flag GC.NFL=34 ; COMMAND FLAG GC.CR==36 ; CARRIAGE RETURN GC.TAB==40 ; tab input char GC.LF==42 ; lin feed input GC.DIG==44 ; digit (0-9) GC.SPC==46 ; space GC.MSC==50 ; MISCELLANEOUS CHARS GO.UNL==-2 ; underline 1 char GO.BUL==-4 ; begin underlining GO.SUL==-6 ; begin underlining spaces GO.EUL==-10 ; end underlining GO.ESC==-12 ; begin escape sequence GO.QTS==-14 ; quoted space output GO.BS==-16 ; backspace output GC.ILL=-20 ; illegal character ; ; 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,GC.ILL,GC.ILL,GC.ILL,GC.ILL ; DC1-SYN .BYTE GC.ILL,GC.ILL,GC.ILL,GC.ILL ; ETB-SUB .BYTE GO.ESC,GO.UNL,GO.BUL,GO.SUL,GO.EUL ; 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.ES1==1 ; FIRST CHAR IN ESCAPE SEQ CH.ES2==2 ; SECOND CHAR IN ESCAPE SEQ CH.FLC==4 ; CHAR MAY BE FLAG CHAR CH.FLG==10 ; CHAR IS CURRENTLY FLAG CHAR CH.PER==20 ; CHAR IS PUNCTUATION CH.VOW==40 ; character is a vowel CHTABL:: .BLKB 33. ; NUL-SPC .BYTE CH.FLC!CH.PER,CH.FLC,CH.FLC,CH.FLC,CH.FLC,CH.FLC ; !-& .BYTE CH.FLC,CH.FLC,CH.FLC,CH.FLC,CH.FLC,CH.FLC ; ' - , .BYTE CH.FLC,CH.FLC!CH.PER,CH.FLC ; - . / .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 ; ? @ .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,CH.FLC,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 0 ; DEL .PSECT $CODE,I,RO,LCL,CON ; ; THE JUMP TABLE TO PARSE CHARS ; ; NOTE: HOOK FOR AUTOINDEXING EXISTS BUT NO AUTO INDEX ROUTINE YET .WORD HLTER,FOUT,CCSPC,GOESC,GOEUL,GOSUL,GOBUL,GOUNL GCJMP: .WORD GCDN,GCUP .WORD GCACC,GCCAP,GCUNL,SHFDN,SHFUP,GCQTS,GCOVR,GCINR,GCHYP .WORD GCESC,GCSUB,GCBRK,GCINR .WORD GCCR,GCTAB,GCLF,GCINR,GCSPC,GCINR ; ; GET INPUT CHARACTER FROM SOURCE FILE AND INTERPRET IT ; GCIN:: CALL CCIN ; GET CHARACTER FROM FILE. GCIN1: MOVB GCTABL(R1),R0 ; GET CHARACTER TYPE DSPTCH: JMP @GCJMP(R0) ; DISPATCH ACCORDING TO TABLE ; ; HERE ARE SPECIAL CHARACTER CASES ; ; UPPER CASE GCDN: TSTB CASE ; CONVERSION NECESSARY BGE GCINR ; NO GCDN1: ADD #40,R1 ; CONVERT CASE IF NECESSARY BR GCINR ; ; LOWER CASE LETTERS GCUP: TSTB CASE ; CONVERSION NECESSARY BLE GCINR ; NO GCUP1: SUB #40,R1 ; CONVERT TO UPPER CASE BIC #1002,CASE ; Reset temporary upper case conversion BR GCINR ; ; CAPITALIZE FLAG GCCAP: MOVB #1,CASE ; SET WORD CAPITALIZE CONVERSION VALUE BR GCIN ; ; ACCEPT FLAG GCACC: CALL CCIN ; READ CHARACTER NO TRANSLATION BR GCINR ; AND RETURN IT. MAYBE UNDERLINED ; UNDERLINE FLAG GCUNL: BITB #277,$UNLSW ; CHECK UNDERLINING SWITCH BNE GCIN ; IT IS DISABLED MOV #ULCHS,R1 ; SET TO UNDERLINE CHARACTER BR GCINO ; ; OVERSTRIKE FLAG GCOVR: BISB #100,$HYPSW ; TEMPORARILY DISABLE HYPHENATION TSTEQB $OVRSW,10$ ; OVERSTRIKE ENABLED? INC OVRCT ; YES, COUNT ABORTED CHARS. BR GCIN ; MORE INPUT 10$: MOV #BS,R1 ; MAKE IT BACK SPACE INC LINBK ; ADD TO LINE LEFT DEC SPCH ; SUBTRACT FROM SPACING CHARS BR GCINO ; ; HYPHENATE FLAG GCHYP: CMPEQ LCH,#SPC,20$ ; LAST CHAR SPACE? CALL CCIN ; GET NEXT CHAR MOVB GCTABL(R1),R0 ; GET TYPE CMP R0,#GC.LC ; IS IT UPPER OR LOWER CASE BGT DSPTCH ; NO BIS #200,R1 ; SET FOR HYPHENATION BISB #1,$AUHYP ; Set temporary no auto hyphenation BR DSPTCH ; AND DISPATCH IT 20$: BISB #100,$HYPSW ; SET NO HYPHENATION BR GCIN ; GET NEXT CHAR ; QUOTED SPACE FLAG GCQTS: MOV #NXS,R1 ; SET NON EXPANDABLE SPACE MOVB ULOCK,CASE ; RESET CASE BR GCINR ; AND SAVE IT GCINR: TSTEQ OVRCT,10$ ; NO BACKSPACE ABORTS DEC OVRCT ; DECREMENT ABORTS BR GCIN ; NEXT CHAR 10$: INC SPCH ; INCREMENT SPACING CHARS MOVB R1,LCH ; SAVE LAST CHARACTER CALL PBYT ; OUTPUT CHAR DEC LINBK ; END OF LINE? BEQ 20$ ; YES BR GCIN ; NO 20$: MOV BF.FUL(R3),LNINS ; LAST CHAR IN LINE TSTEQ BRCNT,GCLF ; NO breaks this line? TSTNEB $GCEND,GCLF ; Immediate end requested? BR GCIN GCLF: RETURN GCINO: CALL PBYT ; OUTPUT CHAR BR GCIN ; CONTINUE PARSING INPUT ; ;ROUTINE TO READ INPUT FROM FILE AND REMOVE BAD INPUT ; R1= CHARACTER READ ; CCIN:: MOVB SUBSTK,R1 ; substitution? BEQ 10$ ; no MOV BUFADD(R1),R1 ; input buffer header CALL GBYT1 ; get input TSTNE R1,20$ ; is it ok? DECB SUBSTK ; pop stack DECB SUBSTK ; pop stack BR CCIN ; try again 10$: CALL FIN ; NO. READ FROM FILE BIC #^C<177>,R1 ; CLEAR EXCESS BITS TSTB GCTABL(R1) ; LEGAL CHARACTER? BLT CCIN ; NO GET ANOTHER 20$: RETURN ; ; routine to parse suubstitution ; GCSUB: MOV R4,-(SP) MOV R3,-(SP) ; save MOVB SUBSTK,R3 ; substitution stack pointer CMPB R3,SUBSTK+1 ; max stack reached? BLO 40$ ; no CALL $ERMSG ; give error too many nestings .WORD ERSBST BR 20$ 10$: CALL $ERMSG ; undefined substitution .WORD ERSBNF 20$: CALL ILCM1 ; tell the user where 30$: MOV (SP)+,R3 ; restore MOV (SP)+,R4 JMP GCIN ; try again 40$: MOV BUFADD(R3),R3 ; get buffer header for input MOV #TBUFF,R2 ; temporary buffer MOV BF.FUL(R3),-(SP) ; save current location MOV #10.,R4 ; max number of char/label 50$: CALL GBYT ; get input CMP R1,#SPC ; non printable? BLE 60$ ; yes, done MOVB R1,(R2)+ ; Save char SOB R4,50$ ; no, continue 60$: CLRB (R2)+ ; Chock end of string MOV (SP)+,R1 ; current location CALL FNDBF ; go back to it MOVB SUBSTK,R3 ; current stack MOV BUFADD+2(R3),R3 ; next stack header CALL BEGBF ; set to beginning of buffer 70$: CALL GBYT ; get byte count BCS 10$ ; end, no escape found MOV R1,R4 ; save BIC #^C<377>,R4 ; clear extra bits MOV #TBUFF,R2 ; temporary buffer 80$: CALL GBYT ; search for key word TSTEQ R1,90$ ; end of search? DEC R4 ; decrement char count CMPEQB R1,(R2)+,80$ ; match? MOV BF.FUL(R3),R1 ; current index ADD R4,R1 ; add on offset CALL FNDBF ; go to new location BR 70$ ; search again 90$: MOV R2,R1 ; end of string SUB #TBUFF,R1 ; find string length MOVB SUBSTK,R3 ; current input ADD #2,R3 ; next entry TSTNEB $SUBSW,100$ ; substitution suppressed? MOVB R3,SUBSTK ; into stack 100$: MOV BUFADD-2(R3),R3 ; input buffer header ADD BF.FUL(R3),R1 ; add word size to current index CALL FNDBF ; skip over $ and key word BR 30$ ; done, continue with normal sequence ; ; EXPAND TABS TO MULTIPLE QUOTED SPACES ; GCTAB: TSTNEB $TABSW,GCSPC ; NO TABS ALLOWED? MOVB ULOCK,CASE ; RESTORE CASE MOV SPCH,R2 ; NUMBER OF SPACING CHARS ADD LMARG,R2 ; ADD ON LEFT MARGIN ADD INDCT,R2 ; PLUS INDENTATION CALL TABB ; FIND WHERE NEXT TAB STOP IS TSTEQ OVRCT,10$ ; NO BACKSPACE ABORTIONS? MOV R2,R1 ; DUPLICATE SPACING SUB OVRCT,R2 ; SPACING COUNT AFTER ABORTS BGT 5$ ; STILL SOME SPACES LEFT! SUB R1,OVRCT ; DECREASE ABORTS JMP GCIN 5$: CLR OVRCT ; NO ABORTS 10$: CMP R2,LINBK ; WOULD THAT MANY EQUAL OR EXCEED LINE SIZE? BGE GCSPC ; YES. TREAT AS SPACE, NOT TAB SUB R2,LINBK ; AND DECREMENT LINBK COUNT BY THAT AMOUNT ADD R2,SPCH ; AND INCREMENT SPACINT CHARS MOV #NXS,R1 ; PUT N NON EXPANDABLE SPACES IN BUFFER MOVB R1,LCH ; LAST CHAR 20$: CALL PBYT ; .. DEC R2 ; .. BGT 20$ JMP GCIN ; GET NEXT CHAR ; ;HERE ON SPACE IN INPUT FILE .. OR ;TAB WHICH COULDN'T BE SATISFIED SO IS MADE A SPACE ; HERE WE ABORT MULTIPLE SPACES AND INSERT SPACES AFTER PUNTUATION ; GCSPC:: MOVB ULOCK,CASE ; RESTORE CASE TST LINBK ; BREAK FOR LINE? BGE 3$ ; NO RETURN ; YES BREAK 3$: BICB #100,$HYPSW ; HYPHENATION ON? BICB #1,$AUHYP ; Allow auto hyphenation BITEQ #FILLF,F.1,30$ ; NO FILLING INPUT BEYOND BREAKS? MOVB LCH,R1 ; GET PREVIOUS CHARACTER WHAT WAS IT? BNE 10$ ; NOT START OF LINE 5$: JMP GCIN ; START OF LINE IGNORE IT 10$: CMPEQ R1,#SPC,5$ ; SPACE? CMPEQ R1,#NXS,5$ ; NON-EXPANDABLE SPACE? TSTEQ $PERSW,30$ ; ONE SPACE AFTER PUNCTUATION? BITEQB #CH.PER,CHTABL(R1),30$ ; NOT PUNCTUATION? CMP LINBK,#1 ; YES. ANY MORE ROOM LEFT? BLE 30$ ; No, keep space 20$: CALL 50$ ; CALL PBYT ; .. INC SPCH ; INCREMENT NUMBER OF SPACING CHARS DEC LINBK ; AND COUNT FOLLOWING CHARACTER MOV #NXS,R1 ; NON-EXPANDABLE SPACE BR 40$ ; 30$: CALL 50$ ; 40$: JMP GCINR ; RETURN CHAR. 50$: CALL LSINSV ; save input addresses MOV BF.FUL(R3),LSTSP ; POSITION IN BUFFER MOV CASE,CASSAV ; SAVE CURRENT CASE MOV SPCH,LSPCH ; SAVE SPACE COUNT MOV LCH,LSCH ; SAVE CHAR BEFORE SPACE MOV SPCNT,SPCNSV ; Save old space count INC SPCNT ; COUNT THIS SPACE INC BRCNT ; count breaks MOV #SPC,R1 ; SPACE CHARACTER (EXPANDABLE) RETURN ; ; ; break flag here ; GCCR: CMPNE LCH,#SPC,GCBR1 ; Last char not space? JMP GCIN ; No GCBRK: BISB #100,$HYPSW ; set temporary no hyphenation GCBR1: TST LINBK ; Past end of line BGE 10$ ; Not yet RETURN 10$: CALL LSINSV ; save input addresses MOV BF.FUL(R3),LSTSP ; POSITION IN BUFFER MOV CASE,CASSAV ; SAVE CURRENT CASE MOV SPCH,LSPCH ; SAVE SPACE COUNT MOV LCH,LSCH ; SAVE CHAR BEFORE SPACE MOV SPCNT,SPCNSV ; Save old space count INC BRCNT ; count breaks this line JMP GCIN ; next char ; ; HERE WE HANDLE SEPARATE ESCAPE SEQUENCES ; GCESC: CALL CCIN ; GET NEXT CHAR MOVB $EFLSW,R0 ; MATCH CHAR CALL ESCSEQ ; ESCAPE SEQUENCE? BCC 10$ ; YES JMP GCIN1 ; NO 10$: JMP GCIN ; NEXT CHAR ; ; SUBROUTINE TO FIND ESCAPE SEQUENCE FROM TABLE ; ESCSEQ: TSTNEB $EFLSW+1,15$ ; ESCAPE FLAG DISABLED? MOV R3,-(SP) ; save MOV #ESCBF,R3 ; escape buffer MOV R1,-(SP) ; SAVE CHAR MOVB R0,1(SP) ; AND OTHER TEST CHAR CALL BEGBF ; Start at beginning 10$: CALL GBYT ; get beginning of sequence BCC 20$ ; not end of table? MOVB (SP)+,R1 ; GET CHAR BACK MOV (SP)+,R3 ; restore 15$: SEC ; NO SEQ FOUND RETURN 20$: MOV R1,R2 ; number of bytes in sequence DEC R2 ; DECREMENT COUNTER CALL GBYT ; get next bytes CMPEQB 1(SP),R1,30$ ; MATCH WITH CHAR? 25$: MOV R2,R1 ; number of bytes to skip ADD BF.FUL(R3),R1 ; add on current index CALL FNDBF ; skip them BR 10$ 30$: DEC R2 CALL GBYT ; get next bytes CMPNEB (SP),R1,25$ ; SECOND CHAR NOT MATCH? TST (SP)+ ; UNSTACK MOV (SP)+,R3 ; restore output buffer TSTNEB $ESCSW,50$ ; ESCAPE SEQUENCES DISABLED? BISB #100,$HYPSW ; DISABLE HYPHENATION THIS WORD MOV #ESC,R1 ; FIRST CHAR TO INSERT CALL PBYT ; OUTPUT IT MOV R2,R1 ; escape count CALL PBYT ; OUTPUT IT 40$: MOV #ESCBF,R1 ; escape buffer CALL GBYT1 ; get next bytes CALL PBYT ; OUTPUT CHAR SOB R2,40$ ; CONTINUE TILL DONE 50$: CLC ; SUCCESS RETURN ; ; ; ROUTINE TO FIND NEXT TABSTOP FOR OUTLIN ROUTINE. ; INPUT R2= CURRENT POSITION ; OUTPUT R2= DISTANCE TO NEXT STOP ; TABB: CLR R0 ; START AT FIRST TABSTOP BR 20$ ; PRE-ENDCHECK, IN CASE NONE. 10$: MOVB TABTAB-1(R0),R1 ; GET CURRENT TAB STOP CMP R2,R1 ; THIS STOP BEYOND CURRENT POS? BLO 40$ ; YES. GET DIFFERENCE 20$: CMP R0,NTABS ; LOOKED AT ALL TAB STOPS? BHIS 30$ INC R0 ; ADVANCE TO NEXT ENTRY BR 10$ 30$: MOV RMARG,R1 ; YES. ASSUME A TABSTOP AT RIGHT END 40$: SUB R2,R1 ; GET DISTANCE TO TABSTOP MOV R1,R2 ; ANSWER IN A RETURN ; ; ; UPPER CASE FLAG ; .ENABL LSB SHFUP: CALL CCIN ; READ A CHARACTER CMPNE R1,$UFLSW,10$ ; LOCK ON UNDERLINE? BICB #100,$UNLSW ; UNDERLINING POSSIBLY ON TSTNEB $UNLSW,30$ ; NOT ON? MOV #ULBEG,R1 ; START IT TSTEQ $UNLSP,5$ ; underline no spaces? MOV #ULSBG,R1 ; underline spaces 5$: JMP GCINO 10$: CMPNE R1,$CFLSW,20$ ; NOT LOCK UPPER CASE? MOV #401,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,R0 ; MATCH CHAR CALL ESCSEQ ; SEARCH FOR ESCAPE SEQUENCE BCC 30$ ; FOUND ONE! MOVB GCTABL(R1),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 @GCJMP(R0) ; DISPATCH IT 60$: JMP GCINR ; ; LOWER CASE FLAG DETECTED ; SHFDN: CALL CCIN ; GET ANOTHER CHARACTER CMPNE R1,$UFLSW,70$ ; UNLOCK UNDERLINE? BISB #100,$UNLSW ; UNDERLINING OFF MOV #ULEND,R1 ; UNDERLINE OFF CHAR JMP GCINO ; 70$: CMPNE R1,$LFLSW,80$ ; NOT LOWERCASE LOCK? CALL LWCAS ; SET LOWER CASE SHIFT BR 30$ ; 80$: MOVB $LFLSW,R0 ; MATCH CHAR CALL ESCSEQ ; HANDLE ESCAPE SEQUENCES BCC 30$ ; FOUND ESC SEQ MOVB GCTABL(R1),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 #401,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,2(SP) ;SAVE CURRENT CASE MOV #401,CASE ; UPPER CASE ONLY ; *** CALL @(SP)+ ;CALL THE CALLER BACK MOV (SP)+,CASE ;RESTORE PREVIOUS CASE ; *** SHXIT: RETURN ; ; ; ROUTINES TO OUTPUT A STRING TO THE OUTPUT FILE ; R3=BUFFER ADDRESS FOR STRING ; PSTRPA::CALL BEGBF ; SET TO TOP OF BUFFER 80$: CALL GBYT ; GET NEXT BYTE BCS SHXIT ; IF EQ END OF STRING CALL CCOUT ; OUTPUT TO FILE BR 80$ ; LOOP FOR WHOLE STRING ; ; PUT STRING TERMINATED BY ZERO BYTE TO OUTPUT ; S1= STRING ADDRESS ; PSTRAZ::MOVB @S1,R1 ; GET BYTE BEQ SHXIT ; END OF BUFFER CALL CCOUT INC S1 BR PSTRAZ ; CONTINUE ; ; PUT STRING ENDED BY ZERO BYTE TO BUFFER ; R0= STRING ADDRESS ; PSTRZB:: MOVB (R0)+,R1 ; GET FIRST CHAR BEQ SHXIT ; DONE MOV R0,-(SP) CALL PBYT ; PUT IT INC BF.SPC(R3) ; Count chars MOV (SP)+,R0 INC R2 ; COUNTS CHARS. BR PSTRZB ; CONTINUE .DSABL LSB ; ; ROUTINE TO DO FINAL OUTPUT ; CCOUT:: TSTEQ ESCCNT,20$ ; IS ESCAPE NOT IN PROGRESS BLT 10$ ; IS THIS COUNT? DEC ESCCNT ; DECREMENT COUNT JMP FOUT ; NO INTERPRETATION 10$: MOV R1,ESCCNT ; SAVE COUNT RETURN 20$: BIC #^C<177>,R1 ; CLEAR OUT HYPHENATION BITS MOVB GCTABL(R1),R0 ; GET CHAR TYPE BGE CCPRN ; PRINTABLE JMP @GCJMP(R0) ; EXECUTE FUNCTION GOESC: DEC ESCCNT ; YES RETURN GOBUL: MOVB #-1,$ULOSW ; SET UNDERLINE ON RETURN GOSUL: MOVB #1,$ULOSW ; set to underline spaces RETURN GOEUL: CLRB $ULOSW ; SET NO UNDERLINE RETURN CCSPC:: MOV #SPC,R1 ; GET SPACE CCPRN: CMP R1,#SPC ; PRINTABLE CHAR? BLT 70$ ; NO TSTEQB $ULOSW,60$ ; NO UNDERLINING CALL GOUNL ; YES, DO IT 60$: INC CPOS ; INCREMENT POSITION COUNTER 70$: CALL FOUT ; OUTPUT CHAR CMPNE R1,#BS,75$ ; BACKSPACE? DEC CPOS ; DECREMENT POSTION 75$: RETURN GOUNL: MOV R1,-(SP) ; SAVE CHAR TSTB $ULOSW ; underline spaces? BGT 80$ ; yes CMPEQ R1,#SPC,100$ ; SPACE? 80$: TSTEQB $ULMSW,90$ ; UNDERLINE BY LINE? MOV #LPUS,R1 ; GET UNDERLINE CALL FOUT ; OUTPUT IT MOV #BS,R1 ; GET BACKSPACE CALL FOUT ; OUTPUT IT BR 100$ 90$: MOV CPOS,R0 ; POSITION CMP R0,#ULNSZ ; TOO BIG? BHI 100$ ; 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 100$: MOV (SP)+,R1 ; GET SAVED CHAR RETURN .END