.TITLE RNCMD .IDENT /M3.0/ ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ;* * ;* General permission to copy (but not for profit) is hereby * ;* granted, provided that reference is made to the fact that * ;* reproduction privileges were granted by DECUS. * ;* * ;* The information in this document is subject to change with- * ;* out notice and should not be construed as a commitment by * ;* the contributor(s), DECUS or Digital Equipment Corporation. * ;* * ;* These parties make no warranty as to the suitability of this * ;* material for use by the recipient, nor as to the accuracy or * ;* functioning of the software or related material, and no * ;* responsibility is assumed in connection therewith. * ;* * ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; RUNOFF COMMANDS ; ; AUTHOR: L. WADE 1-JUN-72 ; ; MODIFIED BY ; ; E. POLLACK U. OF W. 19-DEC-73 ; ; D. N. CUTLER 27-JUL-75 ; ; C. H. Spalding, Unimation, Jan. '83 ; ; MODIFICATIONS ; ; chs12 Add EVEN and ODD ; chs16 Use local symbols for constants ; chs19 Add AUTOSUBTITLE ; chs23 Add RIGHT JUSTIFY ; chs24 Fix skip at bottom of page ; chs30 Allow negative argument for SKIP & BLANK ; chs32 Allow PARAGRAPH in footnotes ; chs34 Changes to PARAGRAPH processing ; chs35 Misc. changes to tab processing ; chs37 Fix FIGURE to work as claimed; added queue ; chs39 Add LAYOUT and related switches ; chs40 Expand HEADER ; chs43 Add QUOTE CHARACTER ; chs44 Add "!" comment command and flag ; chs48 Have NUMBER take actual & relative page number ; chs51 Add [NO] FLAGS SUBINDEX ; chs53 Add orphan control to TEST PAGE ; chs54a Footnote processing reworked ; chs54b Add automatic footnote line ; chs55 Fix duplicate output of blank lines in autoparagraph mode ; chs56 Add PAGE NAME ; chs58 Add tests for unreasonable command parameters ; chs60 Make syntax for command arguments common ; chs61 Changes to LITERAL processing ; chs67 Expand error checks of margin parameters ; chs69 Consider line spacing in TEST PAGE ; chs70 Add TEST LINES ; chs71 Add orphan control to PARAGRAPH ; chs76 Have JUSTIFY always turn on FILL ; chs77 Eliminate FIRST TITLE ; chs78 FOOTNOTE and FIGURE moved to BLOCK.MAC ; chs78a Add BLOCK ; chs79 Move infrequent code to SETUP.MAC ("START" overlay) ; chs80 Add text argument to FIGURE ; chs83 Add AUTOCONTENTS ; chs84 Add exit status (rework error handling) ; chs87a Allow TAB STOPS in blocks and footnotes ; ; ALL COMMAND ROUTINES ARE ENTERED WITH: ; ; R4 = Address of number conversion routine (relative or absolute) ; R5 = Address of flag word F.1 ; (NO)AUTOPARAGRAPH, QUOTE CHARACTER ; NOFLAGS, (NO)FLAG CAPITALIZE, (NO)FLAG HYPHENATE, (NO)FLAG SUBINDEX ; AUTOPARAGRAPH commands AUTOP:: MOV SP,$AUTSW ;SET AUTOPARAGRAPH MODE .IIF NZ AUTFIX, CLR AUTFLG ;CLEAR BLANK-LINE FLAG ;chs55a RETURN NAUTO:: CLR $AUTSW ;CLEAR AUTOPARAGRAPH MODE RETURN ; QUOTE CHARACTER command ;chs43+ .IF NZ QTCHAR QTCH:: CALL NXTCHR ;GET NEXT NON-BLANK CHARACTER BCS 10$ ;SKIP IF END OF COMMAND HIT MOVB R1,QTCHR ;SAVE AS NEW QUOTE CHARACTER BR 20$ 10$: MOVB #CWARN,QTCHR ; ELSE USE DEFAULT 20$: RETURN .ENDC ; NZ QTCHAR ;chs43- ; NOFLAGS command DSAFL:: CALL DSCFL ;CLEAR FLAGS CAPITALIZE ;chs .IIF NZ SUBIDX, CALL DSSFL ;CLEAR FLAGS SUBINDEX ;chs51b BR DSHFL ;CLEAR FLAGS HYPHENATE ;chs ; FLAG CAPITALIZE commands .ENABL LSB DSCFL:: CLR $CFLSW ;CLEAR WORD CAPITALIZE ENABLE BR 10$ ; ENCFL:: MOV SP,$CFLSW ;SET WORD CAPITALIZE ENABLE 10$: CLR WCAS ;CLEAR CASE CONVERSION VALUE RETURN .DSABL LSB ; FLAG HYPHENATE commands DSHFL:: CLR $HFLSW ;CLEAR HYPHENATE ENABLE RETURN ENHFL:: MOV SP,$HFLSW ;SET HYPHENATE ENABLE RETURN ; FLAG SUBINDEX commands ;chs51b+ .IF NZ SUBIDX DSSFL:: CLR $SFLSW ;CLEAR SUBINDEX ENABLE RETURN ENSFL:: MOV SP,$SFLSW ;SET SUBINDEX ENABLE RETURN .ENDC ; NZ SUBIDX ;chs51b- ; (NO)HYPHENATION, (NO)PERIOD, INDENT, BREAK, LOWER CASE, UPPER CASE ; HYPHENATION commands HYPHN:: MOV SP,$HPHSW ;SET HYPHENATION ACTIVE RETURN NHYPH:: CLR $HPHSW ;CLEAR HYPHENATION ACTIVE RETURN ; PERIOD spacing commands PERSP:: MOV SP,$PERSW ;ENABLE TWO SPACES AFTER PUNCTUATION RETURN NPERS:: CLR $PERSW ;DISABLE TWO SPACES AFTER PUNCTUATION RETURN ; INDENT command INDENT::CALL (R4) ;READ SIGNED DECIMAL NUMBER MOV PARIND,R3 ;NONE. USE CURRENT VALUE .IF NZ MARCHK ;chs67+ CALL INDCHK ;CHECK FOR VALID VALUE BCC 10$ ;CONTINUE IF OKAY .IFF ;chs67- CMP R3,RMARG ;LEGITIMATE VALUE? BLE 10$ .ENDC ; -NZ MARCHK ;chs67 JMP ILCM ;NO. COMPLAIN 10$: MOV R3,INDCT ;YES. STORE ARGUMENT .IF NZ GENSEP ;chs60+ CALL SKPEND ;SKIP OVER SEPARATOR CALL LINSET ;RESET LINE PARAMETERS MOV #LGO,(SP) ;RESET RETURN ADDRESS .ENDC ; NZ GENSEP ;chs60- ; BREAK command BREAK:: RETURN ; CASE SELECTION commands .ENABL LSB LWCAS:: MOV #40,R1 ;SET FOR LOWER CASE BITEQ #UPCSW,$SWTCH,10$ ;DON'T FORCE ALL UPPER CASE? UPCAS:: CLR R1 ;SET FOR UPPER CASE 10$: MOV R1,CAS ;STORE RETURN .DSABL LSB ; (NO)NUMBER, PAGE ; PAGE NUMBER commands NUMON:: .IIF NZ NUMREL, MOV PAGENO,R3 ;START WITH CURRENT PAGE ;chs48b CALL (R4) ;NUMBER PAGES. ANY PARTICULAR NUMBER? .IF Z NUMFIX ;chs48a MOV PAGENO,R3 ;NO. LEAVE SAME AS BEFORE .IFF ;chs48a+ JMP 20$ ;NO INPUT, SKIP DEC R3 ;COMPENSATE FOR INC ON NEW PAGE BGE 10$ ;REQUESTED NUMBER MUST BE POSITIVE JMP ILCM ; ELSE ERROR 10$: .ENDC ; -Z NUMFIX ;chs48a- MOV R3,PAGENO ;STORE PAGE NUMBER 20$: MOV SP,$NUMSW ;TURN ON FLAG TO CAUSE NUMBERING RETURN NUMOF:: CLR $NUMSW ;TURN OFF NUMBERING. RETURN ; PAGE command CPAGE:: CMP $HDRSW,LINEC ;IN HEADER REGION OF PAGE? BGE 20$ ;IF GE YES 10$: MOV SP,$PGPSW ;SET PAGE PENDING FLAG 20$: RETURN ; EVEN and ODD commands ;chs12+ .IF NZ EVNODD .ENABL LSB EPAGE:: .IIF NZ ALTHDR, BITEQ #ALHSW,$SWTCH,40$ ;ALTERNATING HEADERS ENABLED? CALL 30$ ;GET # LINES TO SKIP & CHECK PAGE # BCS 10$ ;CONTINUE IF PAGE # ODD BR 40$ ; ELSE DO NOTHING OPAGE:: .IIF NZ ALTHDR, BITEQ #ALHSW,$SWTCH,40$ ;ALTERNATING HEADERS ENABLED? CALL 30$ ;GET # LINES TO SKIP & CHECK PAGE # BCS 40$ ;CONTINUE ONLY IF PAGE # EVEN 10$: MOV R3,-(SP) ;SAVE # BLANK LINES CALL PAGEC ;START NEW PAGE MOV (SP)+,R2 ;RESTORE SKIP COUNT BLE 20$ ;ANY TO CALL SKIPN ;OUTPUT BLANK LINES 20$: .IF NZ GENSEP ;chs60+ CALL SKPSEP ;SKIP TO NEXT ARGUMENT BCS 45$ ;SKIP IF NO TEXT TO CENTER .IFF ;chs60- CALL $FRCND ;FORCE TO LOGICAL END OF LINE COUNT CMPEQ #CR,R1,40$ ;ANY TEXT TO CENTER? .ENDC ; -NZ GENSEP ;chs60 MOV RMARG,-(SP) ;YES, CENTER ON RIGHT MARGIN .IF NZ RTJUST ;chs23+ CALL GETTXT ;GET TEXT TO CENTER JMP CENT2 ;AND DO IT .IFF ;chs23- JMP CENT1 ;GET TEXT AND CENTER IT .ENDC ; -NZ RTJUST ;chs23 30$: .IIF NZ FIGFIX, CALL FIGDMP ;PROCESS ALL PENDING FIGURES ;chs37 .IIF NZ BLKCMD, CALL BLKDMP ;PROCESS ALL QUEUED TEXT BLOCKS ;chs78a CALL (R4) ;GET SKIP COUNT FROM COMMAND .IF NZ BLSW CALL 50$ ;DEFAULT TO CHAPTER SPACING .IFF MOV #7,R3 ;DEFAULT TO FIXED CHAPTER SPACING .ENDC ; -NZ BLSW .IF NZ PRMCHK ;chs58+ CMP R3,PNLPG ;SKIP COUNT REASONABLE? BLT 35$ ; YES, CONTINUE JMP ILCM ; NO, DISPLAY ERROR .ENDC ; NZ PRMCKH ;chs58- 35$: MOV PAGENO,-(SP) ;GET PAGE NUMBER ROR (SP)+ ;MOVE LSB TO C BIT RETURN ;RETURN TO MAIN STREAM 40$: CALL GCIN ;DISCARD REST OF COMMAND LINE CMPNEB #CR,R1,40$ ; I.E., TO RETURN .IF NZ GENSEP ;chs60 45$: ;chs60 .ENDC ; -NZ GENSEP ;chs60 .IIF NZ SKPFIX, CLR $PGPSW ;CANCEL ANY PAGE PENDING ;chs24 RETURN ;EXIT COMMAND .IF NZ BLSW 50$: MOV CHPSKP,R3 ;GET DEFAULT CHAPTER SPACING SUB $HDRSW,R3 ;DECREASE BY HEADER LENGTH ;chs40 BGE 60$ CLR R3 ;MINIMUM IS ZERO 60$: RETURN .ENDC ; NZ BLSW .DSABL LSB .ENDC ; NZ EVNODD ;chs12- ; RIGHT MARGIN and LEFT MARGIN ; RIGHT MARGIN command .ENABL LSB SETRM:: MOV RMARG,R3 ;GET CURRENT RIGHT MARGIN CALL (R4) ;GET RELATIVE ARGUMENT MOV PRMRG,R3 ;IF NONE, INITIALIZE .IF NZ MARCHK ;chs67+ MOV LMARG,-(SP) ;ADD LEFT MARGIN ADD INDCT,(SP) ; AND INDENT CMP R3,(SP)+ ;RIGHT MARGIN SHOULD BE BIGGER BLE 10$ .ENDC ; NZ MARCHK ;chs67- CMP R3,LMARG ;MUST BE RIGHT OF LEFT MARGIN BGT 20$ ;IF GT OKAY 10$: JMP ILCM ;ILLEGAL COMMAND 20$: MOV R3,RMARG ;STORE RIGHT MARGIN ;chs79 RETURN ;chs79 ; LEFT MARGIN command SETLM:: MOV LMARG,R3 ;GET CURRENT LEFT MARGIN CALL (R4) ;GET RELATIVE ARGUMENT MOV #ILMRG,R3 ;IF NONE, INITIALIZE TST R3 ;MUST NOT BE NEGATIVE ;chs BLT 10$ ;chs .IF NZ MARCHK ;chs67+ CALL LMCHK ;CHECK FOR VALID VALUE BCS 10$ ;CONTINUE IF OKAY .ENDC ; NZ MARCHK ;chs67- CMP R3,RMARG ;MUST BE LESS THAN RIGHT MARGIN? BGE 10$ ;IF GE NO MOV R3,LMARG ;OK SAVE AS LEFT MARGIN RETURN ; (LSB continued next page) ; PARAGRAPH command ; (LSB continued from previous page) PARAG:: .IIF NZ PARFN, MOV R4,-(SP) ;SAVE IN CASE IN FOOTNOTE ;chs32 CALL (R4) ;OPTIONAL IDENTING ARGUMENT MOV PARIND,R3 ;NO. USE OLD VALUE .IF NZ MARCHK ;chs67+ CALL INDCHK ;CHECK FOR VALID VALUE BCS 10$ ;CONTINUE IF OKAY .IFF ;chs67- CMP R3,RMARG ;REASONABLE VALUE? BGT 10$ ;IF GT NO .ENDC ; -NZ MARCHK ;chs67 MOV R3,INDCT ;SET PARAGRAPH INDENT MOV R3,PARIND ;STORE PARA INDENT VALUE .IIF NZ PARFN, MOV (SP),R4 ;MAKE SURE ITS RIGHT ;chs32 CALL (R4) ;GET PARAGRAPH SPACING MOV PARSP,R3 ;DEFAULT TO NORMAL SPACING CMP R3,#MXSPC ;LEGAL VALUE? ;chs16 BHI 10$ ;IF HI NO MOV R3,PARSP ;SET NEW PARAGRAPH SPACING .IIF NZ PARFN, MOV (SP)+,R4 ;MAKE SURE ITS RIGHT ;chs32 CALL (R4) ;GET TEST PAGE COUNT .IF NZ DEFPTP ;chs34a JMP PARTP ;DEFAULT TO PREVIOUS VALUE ;chs34a .IFF ;chs34a JMP 30$ ;IF NONE NO TEST .ENDC ; -NZ DEFPTP ;chs34a CMP R3,PNLPG ;VALUE WITHIN REASON? BHI 10$ ;IF HI NO MOV R3,PARPT ;SET NEW PARAGRAPH PAGE TEST COUNT PARTP:: .IF NZ PARORD ;chs34b MOV PARSP,R1 ;GET CURRENT PARAGRAPH SPACING ;chs34b CALL LSTTP ;SKIP THE LINES ;chs34b MOV PARPT,R3 ;GET PAGE TEST COUNT ;chs34b .IF NZ XPARTP ;chs71+ MOV #RCNO,R4 ;MAKE SURE CONVERSION POINTER OKAY CMP (SP),#ATOPAR ;DOING AN AUTOPARAGRAPH? BNE TSTPG2 ; NO, GO PROCESS FULL TEST PAGE .ENDC ; -NZ XPARTP ;chs71- .IF NZ XTSTPG ;chs69 BR TESTL ;TEST IF ROOM FOR R3 TEXT LINES ;chs69 .IFF ;chs69 BR TESTP ;TEST IF ROOM ON PAGE ;chs34b .ENDC ; -NZ XTSTPG ;chs69 .IIF Z DEFPTP, 30$: MOV PARSP,R1 ;GET CURRENT PARAGRAPH SPACING ;chs34a .IFF ;chs34b MOV PARPT,R3 ;GET PAGE TEST COUNT .IF NZ XTSTPG ;chs69 CALL TESTL ;TEST IF ROOM FOR R3 TEXT LINES ;chs69 .IFF ;chs69 CALL TESTP ;TEST IF ROOM ON PAGE .ENDC ; -NZ XTSTPG ;chs69 30$: MOV PARSP,R1 ;GET CURRENT PARAGRAPH SPACING .ENDC ; -NZ PARORD ;chs34b LSTTP:: BEQ 40$ ;IF EQ NO SPACING MOV NSPNG,R0 ;GET LINES PER LINE CALL $MUL ;CALCULATE ACTUAL NUMBER OF LINES TO SKIP CMP $HDRSW,LINEC ;ALREADY IN HEADING AREA? BGE 40$ ;IF GE YES MOV R1,R2 ;SET LINE SKIP COUNT CALL SKIPN ;SKIP LINES .IIF NZ AUTFIX, MOV SP,AUTFLG ;SET BLANK-LINE FLAG ;chs55a 40$: RETURN .DSABL LSB ; TEST PAGE and TEST LINES commands .ENABL LSB .IIF NZ TSTLIN, TSTLN:: NOP ;SEPARATE ENTRY POINT--IGNORE SPACING ;chs70 TSTPG:: CALL (R4) ;GET ARGUMENT OF TEST JMP ILCM ;MUST BE ONE CMP R3,PNLPG ;VALUE WITHIN REASON? BHI 10$ ;IF HI NO .IF NZ EXPTP ;chs53+ TSTPG2: MOV R3,-(SP) ;SAVE TEST COUNT CALL (R4) ;GET BLOCK LENGTH JMP 5$ ;IGNORE END TEST IF MISSING MOV R3,-(SP) ;SAVE IT .IIF NZ XTSTPG, CALL LCNT ;CONVERT TO OUTPUT LINES ;chs69 ADD LINEC,R3 ;ADD ON CURRENT LINE POSITION CMP R3,NLPG ;WILL ENTIRE BLOCK FIT ON PAGE? BLE 4$ ; YES, DON'T NEED END TEST CALL (R4) ;GET LENGTH OF END GROUP MOV 2(SP),R3 ;DEFAULT TO LENGTH OF START GROUP SUB (SP)+,R3 ;CALCULATE #LINES BEFORE END NEG R3 CMP R3,(SP) ;BEYOND START GROUP? BLT 10$ ; NO, INVALID COMBINATION .IIF NZ XTSTPG, CALL LCNT ;CONVERT TO OUTPUT LINES ;chs69 ADD LINEC,R3 ;ADD ON CURRENT LINE POSITION CMP R3,NLPG ;WILL IT INCREASE PAGE LENGTH? BGE 6$ ; YES, DON'T CHANGE IT MOV R3,NLPG ;STORE AS NEW MAX. PAGE LENGTH BR 6$ 4$: TST (SP)+ ;THROW AWAY BLOCK LENGTH 5$: CALL NXTCMD ;IGNORE REST OF COMMAND ;chs53a 6$: MOV (SP)+,R3 ;RESTORE START TEST COUNT .ENDC ; NZ EXPTP ;chs53- .IF NZ XTSTPG ;chs69 TESTL:: CALL LCNT ;CONVERT TO OUTPUT LINES ;chs69 .IFTF ;chs69 TESTP:: ADD LINEC,R3 ;ADD ON CURRENT LINE POSITION CMP R3,NLPG ;COMPARE TO LENGTH W/O FOOTNOTES BLE 20$ JMP BPAGE ;TEST SHOWS NEAR END. BREAK PAGE. .IFT ;chs69 LCNT: .IIF NZ TSTLIN, CMPEQ #TSTLN,ACTCMD,8$ ;SKIP IF "TEST LINES" ;chs70 MOV R3,R1 ;NUMBER OF LINES TO CHECK FOR ;chs69+ DEC R1 ;LAST LINE ONLY COUNTS FOR ONE MOV NSPNG,R0 ;GET LINE SPACING CALL $MUL ;CALC. TOTAL LINES AS INC R1 ; (-1) + 1 MOV R1,R3 ;SET RETURN 8$: RETURN .ENDC ; NZ XTSTPG ;chs69- ; SPACING, PAGE NAME, SUBTITLE, FIRST TITLE, TITLE, AUTOSUBTITLE ; SPACING command SSP:: CALL (R4) ;GET ARGUMENT OF SPACING COMMAND 10$: JMP ILCM ;MUST BE ONE CMP R3,#MXSPC ;MUST BE IN RANGE 1 TO MXSPC ;chs16 BHI 10$ TSTEQ R3,10$ ;ILLEGAL VALUE? MOV R3,NSPNG ;OK. STORE AS NORMAL SPACING 20$: RETURN .DSABL LSB ; PAGE NAME command ;chs56+ .ENABL LSB .IF NZ PAGNAM SETPN:: MOV #PGNMP1,R5 ;POINT TO PAGE NAME BUFFER BR 10$ .ENDC ; NZ PAGNAM ;chs56- ; SUBTITLE command SETSTL::MOV #STTLP1,R5 ;SET FOR SUBTITLE BUFFER BR 10$ ; .IF NZ FIRTIT ;chs77 ; FIRST TITLE command FTITL:: CLRB $HDSSW ;ENABLE HEADER ON FIRST PAGE .ENDC ; NZ FIRTIT ;chs77 ; TITLE command SETTL:: MOV #TTLP1,R5 ;SET FOR TITLE BUFFER CALL SHFUC ;SHIFT TO UPPER CASE FOR TITLE 10$: MOV (R5),2(R5) ;INITIALIZE DESCRIPTOR .IF NZ GENSEP ;chs60+ CALL $FRCND ;SKIP TO START OF TEXT BR 20$ ;SAVE TEXT .IFTF ;chs60- SETBF:: .IFT ;chs60+ CALL SKPSEP ;SKIP TO START OF TEXT BCS 30$ ;QUIT IF NONE .IFF ;chs60- CALL $FRCND ;FORCE TO LOGICAL END OF COMMAND .ENDC ; -NZ GENSEP ;chs60 20$: CALL GCIN ;READ A CHARACTER FROM TITLE OR SUBTITLE CMPEQ #CR,R1,30$ ;CARRIAGE RETURN? MOV R5,R4 ;POINT TO BUFFER POINTER CALL WCI ;WRITE CHARACTER IN BUFFER BR 20$ ; 30$: JMP ULBSET ;RESET UNDERLINE BUFFER .DSABL LSB ; AUTOCONTENTS command ;chs83+ .IF NZ ATOTOC .ENABL LSB ATOC:: MOV #DEFATC,-(SP) ;DEFAULT ARGUMENT MOV #ATCLVL,-(SP) ;ADDRESS OF ACTIVE LEVEL BR 10$ .ENDC ; NZ ATOTOC ;chs83- ; AUTOSUBTITLE command ;chs19+ .IF NZ ATOSUB ASUBT:: MOV #DEFAST,-(SP) ;DEFAULT ARGUMENT ;chs83 MOV #ASTLVL,-(SP) ;ADDRESS OF ACTIVE LEVEL MOVB @(SP),R3 ;GET CURRENT MAXIMUM LEVEL .ENDC ; NZ ATOSUB .IF NZ ATOHDR 10$: CALL (R4) ;GET RELATIVE ARGUMENT MOV 2(SP),R3 ;USE DEFAULT IF NO ENTRY ;chs83 ; Negative argument allowed (same as 0 for AS; disables AC) CMP R3,#MAXHL ;VALUE IN RANGE? BLE 20$ ; YES, OKAY ;chs83 JMP ILCM ; NO, COMMAND ERROR 20$: MOVB R3,@(SP)+ ;SAVE NEW VALUE ;chs83+ TST (SP)+ ;THROW AWAY DEFAULT RETURN ;chs19- .DSABL LSB .ENDC ; NZ ATOHDR ;chs83- ; BLANK, SKIP, TAB STOPS ; SKIP and BLANK commands .ENABL LSB SKIPL:: MOV NSPNG,-(SP) ;SKIP COMMAND. N CURRENT LINES BR 10$ LINSKP::MOV #1,-(SP) ;BLANK COMMAND. N REAL LINES 10$: CALL (R4) ;GET OPTIONAL ARGUMENT MOV #1,R3 ;IF NONE, ASSUME 1 MOV (SP)+,R0 ;RETRIEVE NUMBER OF LINE TO SKIP .IF Z SKPNEG ;chs30 .IIF NZ BLKCMD, BITNE #BLKF,(R5),15$ ;SKIP IF PROCESSING BLOCK ;chs78a CMP LINEC,$HDRSW ;AT TOP OF PAGE? BLE 30$ ;IF LE YES 15$: ;chs78a .IFTF ;chs30 MOV R3,R1 CALL $MUL ;MULTIPLY MOV R1,R2 ;CHECK IF ROOM ON PAGE .IFF ;chs30 BLT 40$ ;SKIP DOWN PAGE IF NEGATIVE ;chs30 .IIF NZ BLKCMD, BITNE #BLKF,(R5),15$ ;SKIP IF PROCESSING BLOCK ;chs78a CMP LINEC,$HDRSW ;AT TOP OF PAGE? ;chs30 BLE 30$ ;IF LE YES ;chs30 15$: ;chs78a .ENDC ; Z SKPNEG ;chs30 .IF Z SKPFIX ;chs24 ADD LINEC,R1 ;ADD CURRENT LINE CMP R1,NLPG ;ROOM FOR ANOTHER? BLE 20$ JMP BPAGE ;NO. MAKE A NEW PAGE .ENDC ; Z SKPFIX ;chs24 20$: CALL SKIPN ;YES. SPACE OUT C(R2) LINES 30$: RETURN .IF NZ SKPNEG ;chs30+ 40$: SUB LINEC,R2 ;COMPUTE NUMBER OF LINES TO SKIP ADD NLPG,R2 ; (ALLOWING FOR FOOTNOTE SPACE) BGT 20$ ;SKIP THE LINES IF COUNT OKAY BEQ 30$ ;QUIT IF NOTHING TO DO 50$: JMP ILCM ;TOO FAR DOWN PAGE ALREADY .ENDC ; NZ SKPNEG ;chs30- ; TAB STOPS command SETTAB::CLR R0 ;CLEAR NUMBER OF TABS ;chs35a .IIF NZ BLKTAB, MOV R4,-(SP) ;SAVE ADDRESS OF CONVERSION ROUTINE ;chs87a 60$: MOVB R0,NTABS ;chs35a .IIF NZ BLKTAB, MOV (SP),R4 ;RESTORE ADDR OF CONVERSION ROUTINE ;chs87a .IIF NZ RELTAB, MOVB TABTAB(R0),R3 ;GET CURRENT SETTING ;chs35c CALL (R4) ;GET ANOTHER STOP IF ANY ;chs35a .IF NZ BLKTAB ;chs87a+ TST (SP)+ ;CLEAN STACK .IFF ;chs87a- NOP .ENDC ; -NZ BLKTAB ;chs87a RETURN INC R0 ;COUNT THIS SETTING ;chs35a CMP R0,#TABTL ;TABLE FULL? ;chs35a BGT 50$ ; IF SO, ERROR ;chs35a CMPB R3,TABTAB-2(R0) ;LARGER THAN LAST VALUE? ;chs35b BLE 50$ ; ERROR IF NOT ;chs35b MOVB R3,TABTAB-1(R0) ;STORE THIS TABSTOP BR 60$ ;GO BACK FOR ANOTHER ;chs35a .DSABL LSB ; LITERAL, END LITERAL, (NO)FILL, (NO)JUSTIFY ; LITERAL command LITRL:: MOV (R5),LITSV ;SAVE CURRENT FLAGS WORD BIS #LITFG!SPECF,(R5) ;SET LITERAL FLAG MOV CMADR,LITCM ;SAVE CURRENT EXPECTED COMMAND ADDRESS MOV ELCMD,CMADR ;SET ADDRESS OF EXPECTED COMMAND .IF NZ LITSPC ;chs61a+ MOV NSPNG,LITSP ;SAVE LINE SPACING MOV #1,NSPNG ;SET TO SINGLE SPACING .ENDC ; NZ LITSPC ;chs61a- .IF NZ LITMRG ;chs61b+ MOV RMARG,LITRM ;SAVE RIGHT MARGIN MOV #MAXMRG,RMARG ;SET TO MAXIMUM WIDTH .ENDC ; NZ LITMRG ;chs61b- BR FILOF ;TURN OFF FILL AND JUSTIFY ; END LITERAL command ELTRL:: MOV LITSV,(R5) ;RESTORE PREVIOUS FLAGS WORD MOV LITCM,CMADR ;RESTORE PREVIOUS EXPECTED COMMAND ADDRESS .IIF NZ LITMRG, MOV LITRM,RMARG ;RESTORE NORMAL RIGHT MARGIN ;chs61b .IF NZ LITSPC ;chs61a .IF NZ LITEND ;chs61d+ MOV LITSP,R2 ;RESTORE NORMAL LINE SPACING MOV R2,NSPNG DEC R2 ;NEED TO OUTPUT SPACING LINES? BEQ 10$ ; NO, ALL DONE CALL SKIPN ; YES, DO IT 10$: .IFF ;chs61d- MOV LITSP,NSPNG ;RESTORE NORMAL LINE SPACING ;chs61a .ENDC ; -NZ LITEND ;chs61d .ENDC ; NZ LITSPC ;chs61a RETURN ; FILL and JUSTIFY commands .IF Z JUSFIL ;chs76 JUSTN:: BIS #JUSTF+PJUSTF,(R5) ;TURN ON JUSTIFYING RETURN .IFTF ;chs76 JUSOF:: BIC #PJUSTF+JUSTF,(R5) ;TURN OFF JUSTIFY BITS RETURN .IFF ;chs76 JUSTN:: BIS #PJUSTF,(R5) ;TURN ON JUSTIFYING ... AND FILLING ;chs76 .ENDC ; -Z JUSFIL ;chs76 FILLN:: BIS #FILLF+JUSTF,(R5) ;TURN ON FILLING, COPY PJUSTF TO JUSTF BITNE #PJUSTF,(R5),10$ ;COPY PERMANENT FLAG BIC #JUSTF,(R5) ;TO CURRENT ONE. 10$: RETURN FILOF:: BIC #FILLF+JUSTF,(R5) ;TURN OFF FILLING AND JUSTIFYING RETURN ; CENTER command CENTER:: .IF NZ RTJUST ;chs23 CALL GTARGS ;GET COMMAND ARGUMENTS ;chs23 .IFF ;chs23 MOV RMARG,R3 ;GET RIGHT MARGIN CALL (R4) ;GET RELATIVE ARGUMENT MOV RMARG,R3 ;DEFAULT IS RIGHT MARGIN .IF NZ PRMCHK ;chs58+ CMP R3,#MAXMRG ;IS VALUE REASONABLE? BLE 5$ ; YES, CONTINUE JMP ILCM ; NO, DISPLAY ERROR .ENDC ; NZ PRMCHK ;chs58- 5$: MOV R3,-(SP) ;STORE .IF NZ GENSEP ;chs60 CALL SKPEND ;SKIP TO TEXT ARGUMENT ;chs60 .IFF ;chs60 CALL $FRCND ;FORCE TO LOGICAL END OF COMMAND CMPNE #CR,R1,CENT1 ;NOT END OF LINE? 10$: CALL GCIN ;DISCARD REST OF THIS COMMAND CMPNE R1,#LF,10$ ;NOT LINE FEED? .ENDC ; -NZ GENSEP ;chs60 CENT1: CALL GCIN ;READ LINE TO BE CENTERED CMPEQ R1,#CR,CENT2 ;CARRIAGE RETURN? CALL WLNIN1 ;PUT IN LINE INPUT BUFFER BR CENT1 ;LOOP FOR MORE .ENDC ; -NZ RTJUST ;chs23 CENT2:: MOV (SP)+,R2 ;COMPUTE SPACING BEFORE LINE ;chs80 CMPEQ LNIN1,LNIN2,CENT4 ;NO TEXT TO OUTPUT? ;chs12 ADD LNIN1,R2 ;AS HALF RIGHT MARGIN SUB LNIN2,R2 ;MINUS HALF OF LINE SIZE SUB LMARG,R2 ;MINUS LEFT MARGIN ADD NSPCH,R2 ; INCLUDING UNDERLINES, ET ASR R2 ;TAKE HALF TST R2 ;IS RESULT REASONABLE? ;chs23+ BGE 10$ ; YES, CONTINUE CALL $ERMSG ; NO, WARN USER ;chs84 .WORD CTRERR ;; CALL ONPAG ;INDICATE WHICH PAGE IT WAS ON ;chs84 CLR R2 ;chs23- 10$: ADD LMARG,R2 ;ADD IN LEFT MARGIN .IIF NZ LAYOUT, ADD BASMRG,R2 ;INCLUDING BASE MARGIN ;chs39 CENT3: CALL NSPAC ;OUTPUT SPACES ;chs23 MOV #LNIN1,R4 ;THEN OUTPUT LINE BUFFER TO FILE CALL PSTRPA JMP SKIPS CENT4: RETURN ;chs12 ; RIGHT JUSTIFY command ;chs23+ .IF NZ RTJUST RJUST:: MOV #ENDBCM,(SP) ;SET BREAK STATUS MOV R4,-(SP) ;SAVE ADDR OF CONVERSION ROUTINE MOV INDCT,R2 ;GET CURRENT INDENT CLR INDCT ;USE ONCE ONLY ADD LMARG,R2 .IF NZ LAYOUT ;chs39 CALL NSPACB ;SPACE OVER FROM BASE MARGIN ;chs39 .IFF ;chs39 CALL NSPAC ;SPACE OVER TO START OF TEXT .ENDC ; -NZ LAYOUT ;chs39 MOV #LNIN1,R4 ;OUTPUT CURRENT LINE CALL PSTRPA TSTNEB $ULNSW,10$ ;CONSIDER UNDERLINES IF ACTIVE TSTEQB $ULMSW,10$ ; AND NOT OVERPRINT SUB NSPCH,CPOS ;ADJUST CURRENT POSITION 10$: CLR NSPCH ;RESET NON-SPACING COUNT MOV LNIN1,LNIN2 ;RESET LINE BUFFER MOV (SP)+,R4 ;RETRIEVE ADDR OF CONVERSION ROUTINE CALL GTARGS ;GET COMMAND ARGUMENTS MOV (SP)+,R2 ;GET BACK RIGHT MARGIN CMPEQ LNIN1,LNIN2,CENT4 ;NO TEXT TO OUTPUT? .IIF NZ LAYOUT, ADD BASMRG,R2 ;INCLUDE BASE MARGIN ;chs39 MOV R2,-(SP) ;SAVE IN CASE OF ERROR CLR R3 ;CLEAR ERROR FLAG 20$: ADD LNIN1,R2 ;COMPUTE SPACING BEFORE TEXT = RT MARG SUB LNIN2,R2 ; MINUS LENGTH OF TEXT SUB CPOS,R2 ; MINUS CURRENT POSITION ADD NSPCH,R2 ; PLUS NON-SPACING CHARACTERS BGE 40$ ;CONTINUE IF NO OVERLAP TSTNE R3,30$ ; OR IF SECOND ERROR CALL $ERMSG ;WARN USER ;chs84 .WORD RJUERR CALL ONPAG ;INDICATE WHICH PAGE IT WAS ON MOV NSPCH,-(SP) ;SAVE TEMPORARILY CALL SKIPS ;MOVE ON TO NEXT LINE MOV (SP)+,NSPCH ;RESTORE MOV SP,R3 ;SET ERROR FLAG MOV (SP),R2 ;RESTORE RIGHT MARGIN BR 20$ ;TRY AGAIN 30$: CALL $ERMSG ;WARN USER .WORD RJUERR ; LINE TOO LONG TO JUSTIFY CALL TTC33 ;OUTPUT LINE ;chs84 40$: TST (SP)+ ;POP STACK JMP CENT3 ;OUTPUT SPACES AND TEXT ; Local subroutine to get command-line arguments GTARGS: MOV RMARG,R3 ;GET RIGHT MARGIN CALL (R4) ;GET RELATIVE ARGUMENT MOV RMARG,R3 ;DEFAULT IS RIGHT MARGIN .IF NZ PRMCHK ;chs58+ CMP R3,#MAXMRG ;IS VALUE REASONABLE? BLE 10$ ; YES, CONTINUE JMP ILCM ; NO, DISPLAY ERROR .ENDC ; NZ PRMCHK ;chs58- 10$: MOV (SP),-(SP) ;RETURN VALUE ON STACK MOV R3,2(SP) ; Get text argument .IF NZ GENSEP ;chs60 CALL SKPEND ;SKIP TO TEXT ARGUMENT ;chs60 .IFF ;chs60 CALL $FRCND ;FORCE TO LOGICAL END OF COMMAND CMPNE #CR,R1,GETTXT ;NOT END OF LINE? 10$: CALL GCIN ;DISCARD REST OF THIS COMMAND CMPNE R1,#LF,10$ ;NOT LINE FEED? .ENDC ; -NZ GENSEP ;chs60 GETTXT::CALL GCIN ;READ LINE TO BE CENTERED ;chs80 CMPEQ R1,#CR,10$ ;CARRIAGE RETURN? CALL WLNIN1 ;PUT IN LINE INPUT BUFFER BR GETTXT ;LOOP FOR MORE 10$: RETURN .ENDC ; NZ RTJUST ;chs23- ; MISCELLANEOUS SUBROUTINES ; Coroutine to shift to upper case temporarily SHFUC:: MOV (SP),-(SP) ;COPY RETURN ADDRESS MOV CAS,2(SP) ;SAVE CURRENT CASE CLR CAS ;SET FOR UPPER CASE CALL @(SP)+ ;CALL THE CALLER BACK MOV (SP)+,CAS ;RESTORE PREVIOUS CASE RETURN ; Local subroutines to error check margin parameters ;chs67+ .IF NZ MARCHK .ENABLE LSB LMCHK: MOV INDCT,-(SP) ;SET UP CURRENT INDENT BR 10$ INDCHK: MOV LMARG,-(SP) ;SET UP CURRENT LEFT MARGIN 10$: ADD R3,(SP) ;ADD IN PARAMETER TO CHECK BLT 20$ ;SUM SHOULDN'T BE NEGATIVE CMP RMARG,(SP) ;RIGHT MARGIN SHOULD BE LARGER BGT 30$ 20$: SEC ;SIGNAL ERROR RETURN BR 40$ 30$: CLC ;SIGNAL OKAY RETURN 40$: INC (SP)+ ;POP STACK RETURN .DSABLE LSB .ENDC ; NZ MARCHK ;chs67- ; Subroutine to get next non-blank character ;chs54b+ NXTCHR:: .IF NZ GENSEP ;chs60 CALL SKPWHT ;GET NEXT NON-BLANK CHARACTER ;chs60 .IFF ;chs60 CALL CCIN ;READ NEXT CHARACTER CMPEQ #SPC,R1,NXTCHR ;IGNORE SPACES CMPEQ #TAB,R1,NXTCHR ; AND TABS .ENDC ; -NZ GENSEP ;chs60 CMPEQ #CMA,R1,NXTCHR ;KEEP LOOKING IF COMMA CMPEQ #CR,R1,10$ ;STOP ON CMPEQ #PD,R1,10$ ; OR PERIOD CMPEQ #SEMI,R1,10$ ; OR SEMICOLON .IIF NZ EXCMNT, CMPEQ #EXCL,R1,10$ ; OR EXCLAMATION MARK ;chs44 CLC ;MAKE SURE C BIT CLEAR BR 20$ ;DON'T SAVE BREAK CHARACTER 10$: MOVB R1,GCSCH ;SAVE BREAK CHARACTER SEC ;SIGNAL END OF COMMAND 20$: RETURN ;chs54b- .END