Google
 

Trailing-Edge - PDP-10 Archives - bb-h138e-bm_tops20_v6_1_distr - 6-1-sources/makvfu.mac
There are 30 other files named makvfu.mac in the archive. Click here to see a list.
;Edit 7 to MAKVFU.MAC by SANTIAGO on Tue 12-Mar-85, for SPR #19424
;		Don't update CHNMSK until entire command
;;		has been processed.
;Edit 6 to MAKVFU.MAC by SANTIAGO on Tue 12-Mar-85, for SPR #18624
;		Install TAKE command.
;Edit 5 to MAKVFU.MAC by SANTIAGO on Mon 11-Mar-85, for SPR #20321
;		Require confirmation on filespec for OUTPUT command
;<5.UTILITIES>MAKVFU.MAC.2, 28-Oct-81 15:23:25, EDIT BY GRANT
;Change major version to 5
; UPD ID= 309, FARK:<4-WORKING-SOURCES.UTILITIES>MAKVFU.MAC.2,   3-Dec-80 13:05:24 by ZIMA
;Edit 4 - add MAKVF7 functionality to MAKVFU
;<4.UTILITIES>MAKVFU.MAC.3,  3-Jan-80 15:26:02, EDIT BY R.ACE
;UPDATE COPYRIGHT DATE
;<4.UTILITIES>MAKVFU.MAC.2, 10-Mar-79 14:12:49, EDIT BY KONEN
;UPDATE COPYRIGHT FOR RELEASE 4
;<4.UTILITIES>MAKVFU.MAC.2, 23-Jan-79 10:42:48, Edit by KONEN
;UPDATE VERSION NUMBER FOR RELEASE 4
TITLE MAKVFU - PROGRAM TO GENERATE BINARY VFU FILES



;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1976,1977,1978,1979,1980 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.

	SEARCH MONSYM,MACSYM
	.REQUIRE SYS:MACREL
	sall
	IFDEF .PSECT,<
	.DIRECT FLBLST>
	IFNDEF .PSECT,<
	.DIRECT .XTABM>

;DEFINITIONS

A==1
B==2
C==3
D==4
PNT==5
W==6
W1==7
W2==10
W3==11
P==17

; VERSION INFORMATION

VMAJOR==5		;MAJOR VERSION
VMINOR==0		;MINOR VERSION
VWHO==0			;WHO LAST EDITED (0=DEC DEVELOPMENT)
VEDIT==^D7		;EDIT NUMBER

VMAKVF== <VWHO>B2+<VMAJOR>B11+<VMINOR>B17+VEDIT

;TXTPTR- MACRO TO SET UP BYTE POINTER TO A STRING

	DEFINE TXTPTR (MSG) <POINT 7,[ASCIZ/MSG/]>
DEFINE	NOISE(TEXT),<		;MACRO TO DO NOISE
	MOVEI B,[FLDDB. (.CMNOI,,TXTPTR<TEXT>)]
	CALL DOCMND
>


DEFINE	CMMND(ARGS),<		;MACRO TO CALL COMND% ROUTINE
	MOVEI B,ARGS
	CALL DOCMND
>


DEFINE	CONFRM,<		;MACRO TO CONFIRM A LINE
	CALL DOCFRM
>

;**;[4] Add 3 lines at INILPP== -1L	JGZ	30-NOV-80
LPI6==354		;[4] LP07 CONTROL BYTE FOR 6 LINES/INCH
LPI8==355		;[4] LP07 CONTROL BYTE FOR 8 LINES/INCH
LPIX==356		;[4] CONTROL BYTE TO LEAVE LPI ALONE (REQUIRED FOR LP14)
INILPP==^D66		;INITIAL DEFAULT LINES/PAGE
NCHPW==5		;NUMBER OF ASCII CHARACTERS PER WORD
BUFSIZ==200		;SIZE OF INPUT TEXT BUFFER
ATMSIZ==200		;SIZE OF ATOM BUFFER
GJFSIZ==.GJRTY+2	;SIZE OF GTJFN BLOCK FOR COMND JSYS
MAXLIN==^D143		;MAXIMUM LINES IN VFU
MAXCHN==^D12		;MAX CHANNEL NUMBER
PDLN==50


PDL:	BLOCK PDLN		;PUSH DOWN LIST
CMDBLK:	BLOCK .CMGJB+5		;COMMAND STATE BLOCK FOR COMND JSYS
ATMBFR:	BLOCK ATMSIZ		;ATOM BUFFER
BUFFER:	BLOCK BUFSIZ		;INPUT TEXT BUFFER
GJFBLK:	BLOCK GJFSIZ		;GTJFN BLOCK FOR COMND JSYS
CHNBUF:	BLOCK ^D12*<MAXLIN/^D36+1> ;ALLOCATE VFU BIT MASK
CHNMSK:	BLOCK 1			;REMEMBER CHANNELS SPECIFIED
CHANEL:	BLOCK 1			;CURRENT CHANNEL
PAGSIZ:	PAGESZ:	BLOCK 1		;PAGE SIZE
TAKJFN:	BLOCK 1			;JFN FOR TAKE FILE, IF ANY
LINPPG:	BLOCK 1			;LINES PER PAGE
VFUBUF:	BLOCK ^D256
MARKW:	BLOCK 1			;REMEMBER IF MARKING WANTED
FORMS:	BLOCK 1			;FORMS BREAK CHANNEL
;**;[4] Add 1 line at FORMS: +1L	JGZ	30-NOV-80
LPI:	BLOCK	1		;[4] CONTROL BYTE FOR 6/8/LEAVE ALONE LPI
ENDZRO==.-1

ENTVEC:	JRST START
	JRST START
	VMAKVF

PROMPT:	ASCIZ /MAKVFU>/

;**;[4] Add LINES-PER-INCH at HLPTXT: +12L	JGZ	30-NOV-80
HLPTXT: ASCIZ /
Commands are:

EXIT		Return to command language
CHANNEL 	Specifies line or lines on which a channel will stop.
		Arguments are: ALL,LINES,EVERY.
FORMS-BREAK	SPecifies the channel or channels which will stop on
		the lines in the forms break margin.
MARK		Directs MAKVFU to set any unspecified channel to stop
		at all lines. This is equivalent to "CHANNEL n ALL"
		for each unspecified channel.
INFORMATION	Produces a brief summary of the VFU so far defined.
LINES-PER-INCH	Specifies a lines per inch setting for the LP07 printer.
		Arguments are: 6-LPI, 8-LPI, LEFT-ALONE.
LENGTH		Specifies the physical length of the page. This value
		is defaulted to 66 at start-up time but may be changed
		with this command.
PAGE-SIZE	Specifies the logical length of the page. This parameter
		defines the number of printable lines per page and
		the difference between it and the physical length
		is the forms break margin.
HELP		Produces this text.
/

;COMMAND TABLES

CMDTAB:	ELEV1-.-1,,ELEV1-.-1
	XWD [ASCIZ /CHANNEL/],.CHNL
	XWD [ASCIZ /EXIT/],.EXIT
	XWD [ASCIZ /FORMS-BREAK/],.FORM
	XWD [ASCIZ /HELP/],.HELP
	XWD [ASCIZ /INFORMATION/],.INFO
	XWD [ASCIZ /LENGTH/],.LENTH
;**;[4] Add one line at CMDTAB: +7L	JGZ	30-NOV-80
	XWD [ASCIZ /LINES-PER-INCH/],.LPI ;[4]
	XWD [ASCIZ /MARK/],.MARK
	XWD [ASCIZ /OUTPUT/],.OUTPT
	XWD [ASCIZ /PAGE-SIZE/],.PAGE
	XWD [ASCIZ /TAKE/],.TAKE
ELEV1:
LEV2:	ELEV2-.-1,,ELEV2-.-1
	XWD [ASCIZ /ALL/],.ALL
	XWD [ASCIZ /BOTTOM-OF-FORM/],.BOTOM
	XWD [ASCIZ /EVERY/],EVERY
	XWD [ASCIZ /LINE/],LINES
	XWD [ASCIZ /TOP-OF-FORM/],.TOP
ELEV2:
;**;[4] Add several lines at ELEV2: +1L	JGZ	30-NOV-80
LPITB:	ELPITB-.-1,,ELPITB-.-1	;[4] TABLE SIZE
	XWD [ASCIZ /6-LPI/],LPI6 ;[4]
	XWD [ASCIZ /8-LPI/],LPI8 ;[4]
	XWD [ASCIZ /LEFT-ALONE/],LPIX ;[4]
ELPITB:				;[4] END OF LPI TABLE

START:	RESET			;CLEAN UP
	SETZM CHNBUF		;SET UP TO CLEAR ALL DATA AREAS
	MOVE A,[CHNBUF,,CHNBUF+1]
	BLT A,ENDZRO		;ZAP ALL VULNERABLE DATA
	MOVEI A,INILPP		;ASSUME 66 LINES PER PAGE
	MOVEM A,LINPPG		;SET IT
;**;[4] Add two lines at START: +6L	JGZ	30-NOV-80
	MOVEI A,LPIX		;[4] DEFAULT LINES/INCH
	MOVEM A,LPI		;[4]  IS TO LEAVE SETTING ALONE
	;..
	;..

; COMMAND PARSER AND DISPATCH

	HRROI A,PROMPT		;GET POINTER TO PROMPT STRING
	MOVEM A,CMDBLK+.CMRTY	;PUT RE-TYPE PROMPT POINTER IN STATE BLOCK
	HRROI A,BUFFER		;GET POINTER TO INPUT TEXT BUFFER
	MOVEM A,CMDBLK+.CMPTR	;SAVE POINTER TO COMMAND STRING
	MOVEM A,CMDBLK+.CMBFP	;SAVE POINTER TO START-OF-BUFFER
	MOVE A,[.PRIIN,,.PRIOU] ;GET PRIMARY INPUT,, OUTPUT JFN'S
	MOVEM A,CMDBLK+.CMIOJ	;SAVE PRIMARY JFN'S
	MOVEI A,PARSE1		;GET RE-PARSE ADDRESS
	MOVEM A,CMDBLK+.CMFLG	;SAVE RE-PARSE ADDRESS
	SETZM CMDBLK+.CMINC	;INITIALIZE # OF CHARACTERS AFTER POINTER
	MOVEI A,BUFSIZ*NCHPW	;GET # OF CHARACTERS IN BUFFER AREA
	MOVEM A,CMDBLK+.CMCNT	;SAVE INITIAL # OF FREE CHARACTER POSITIONS
	HRROI A,ATMBFR		;GET POINTER TO ATOM BUFFER
	MOVEM A,CMDBLK+.CMABP	;SAVE POINTER TO LAST ATOM INPUT
	MOVEI A,ATMSIZ*NCHPW	;GET # OF CHARACTERS IN ATOM BUFFER
	MOVEM A,CMDBLK+.CMABC	;SAVE COUNT OF SPACE LEFT IN ATOM BUFFER
REEN:	MOVE P,[IOWD PDLN,PDL]	;SET UP STACK
	CALL RELTAK		;RELEASE JFNS FOR TAKE FILE
PARSE:
COMMAN:	MOVE P,[IOWD PDLN,PDL]	;SET UP STACK
	MOVEI A,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	CMMND [FLDDB. (.CMINI)]	;INITIALIZE COMMAND SCANNER JSYS

PARSE1:	MOVE A,[GJFBLK,,GJFBLK+1] ;SET UP TO CLEAR GTJFN BLOCK
	SETZM GJFBLK		;CLEAR FIRST WORD OF BLOCK
	BLT A,GJFBLK+GJFSIZ-1	;CLEAR GTJFN BLOCK

	MOVEI A,GJFBLK		;GET ADDRESS OF GTJFN BLOCK
	MOVEM A,CMDBLK+.CMGJB	;STORE POINTER TO GTJFN BLOCK
	MOVEI A,CMDBLK		;GET POINTER TO COMMAND STATE BLOCK
	CMMND [FLDDB. (.CMKEY,,CMDTAB)] ;DO INITIAL PARSE
	TXNN A,CM%NOP		;VALID COMMAND ENTERED ?
	JRST PARSE5		;YES, GO DISPATCH TO PROCESSING ROUTINE
	CALL TSTCOL		;GO SEE IF CRLF NEEDED
	TMSG <? MAKVFU: No such MAKVFU command as ">
	MOVE A,CMDBLK+.CMABP	;GET POINTER TO ATOM BUFFER
	PSOUT			;OUTPUT STRING ENTERED BY USER
	TMSG <"
>				;OUTPUT END-OF-MESSAGE
	JRST PARSE		;GO TRY TO GET A COMMAND AGAIN

PARSE5:	HRRZ A,(B)		;GET DISPATCH ADDRESS
	CALL (A)		;PERFORM REQUESTED FUNCTION
	JRST PARSE		;GO PARSE NEXT COMMAND
;DO SPACING

.LENTH:	STKVAR <SPCING>
	MOVEI A,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	NOISE (OF PHYSICAL PAGE IS) ;PARSE NOISE WORD
	MOVEI A,CMDBLK		;GET COMMAND STATE BLOCK ADDRESS
	CMMND [FLDDB. (.CMNUM,,^D10,,66)] ;GET SPACING IN DECIMAL 
	TXNN A,CM%NOP		;NUMBER PARSED OK ?
	JRST LENTH2		;YES, GO SAVE THE NUMBER AND GET CONFIRMATION
	CALL TSTCOL		;NO, ISSUE CRLF IF NEEDED
	TMSG <? MAKVFU: Invalid decimal number ">
	HRROI A,ATMBFR		;GET POINTER TO TEXT JUST ENTERED
	PSOUT			;OUTPUT TEXT JUST ENTERED
	TMSG <" for length
>				;OUTPUT REMAINDER OF MESSAGE
	RET			;RETURN WITH NO ACTION

; HERE ON GETTING A GOOD VALUE FOR THE LENGTH

LENTH2:	MOVEM B,SPCING		;SAVE SPACING
	MOVEI A,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	CONFRM			;REQUEST COMMAND CONFIRMATION
	TXNE A,CM%NOP		;GOT VALID CONFIRMATION?
	 CALLRET COMER1		;NO, ISSUE MESSAGE AND RETURN

; HERE WITH A GOOD COMMAND - VERIFY THAT A LEGAL SPACING WAS ENTERED

	MOVE A,SPCING		;RESTORE SPACING
	SKIPE A			;GOT A GOOD VALUE?
	CAILE A,MAXLIN		;AND WITHIN PRACTICAL LIMITS?
	JRST SPACER		;NO, GO ISSUE ERROR MESSAGE
	CAMGE A,PAGSIZ		;MUST BE AT LEAST SAME AS LOGICAL SIZE
	JRST SPACER		;NOT
	MOVEM A,LINPPG
	RET			;RETURN TO PARSER

; HERE ON A BAD VALUE FOR SPACING

SPACER:	CALL TSTCOL			;ISSUE CRLF IF NEEDED
	TMSG <? MAKVFU: LENGTH argument out of range
>
	RET			;RETURN TO WHENCE WE CAME ...
;**;[4] Add several lines at SPACER: +5L	JGZ	30-NOV-80
;[4] LINES-PER-INCH COMMAND

.LPI:	STKVAR <LPIHLD>		;[4] TO HOLD SETTING FOR CONFIRMATION
	MOVEI A,CMDBLK		;[4] SETUP TO PARSE REST OF COMMAND
	NOISE (FOR LP07 PRINTER) ;[4] GUIDEWORDS
	MOVEI A,CMDBLK		;[4] NOW PARSE SETTING
	CMMND [FLDDB. (.CMKEY,,LPITB,,<LEFT-ALONE>)] ;[4] PARSE KEYWORD
	TXNN A,CM%NOP		;[4] DID IT PARSE?
	 JRST .LPIOK		;[4] YES, CONTINUE
	CALL TSTCOL		;[4] NO, ISSUE NEW LINE IF NEEDED
	TMSG <? MAKVFU: No such LPI setting> ;[4] GIVE ERROR MESSAGE
	RET			;[4] AND RETURN

.LPIOK:	HRRZ B,0(B)		;[4] GET VALUE ASSOCIATED WITH KEYWORD
	MOVEM B,LPIHLD		;[4] SAVE IT FOR CONFIRMATION
	MOVEI A,CMDBLK		;[4] SETUP CONFIRMATION PARSE
	CONFRM			;[4] CONFIRM THE COMMAND
	TXNE A,CM%NOP		;[4] END OF COMMMAND PARSED OK?
	 CALLRET COMER1		;[4] NO, ISSUE MESSAGE
	MOVE A,LPIHLD		;[4] YES, GET LPI VALUE
	MOVEM A,LPI		;[4] AND SET IT OFFICIALLY
	RET			;[4] THEN RETURN


;MARK COMMAND

.MARK:	MOVEI A,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	NOISE (UNASSIGNED CHANNELS) ;PARSE NOISE
	MOVEI A,CMDBLK		;GET ADDRESS OF COMMANDS STATE BLOCK
	CONFRM			;GET CONFIRMATION FUNCTION
	TXNE A,CM%NOP		;END OF COMMMAND PARSED OK?
	 CALLRET COMER1		;NO, ISSUE MESSAGE
	SETOM MARKW		;REMEMBER TO DO MARKING
	RET			;RETURN TO WHENCE WE CAME ...


; INFO COMMAND

.INFO:	MOVEI A,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	NOISE (ABOUT CURRENT VFU) ;PARSE NOISE
	MOVEI A,CMDBLK		;GET COMMAND STATE BLOCK
	CONFRM			;CONFIRM FUNCTION
	TXNE A,CM%NOP		;END OF COMMMAND PARSED OK?
	 CALLRET COMER1		;NO, ISSUE MESSAGE

; HERE TO OUTPUT INFORMATION

;**;[4] Add several lines at INFO10: +0L	JGZ	30-NOV-80
INFO05:	MOVE A,LPI		;[4] GET LPI SETTING
	CAIN A,LPIX		;[4] STILL AT DEFAULT?
	 JRST INFO10		;[4] YES, DON'T MENTION IT THEN
	TMSG <
LINES-PER-INCH		>	;[4] LEADIN
	MOVE A,LPI		;[4] GET LPI AGAIN
	CAIE A,LPI6		;[4] IS IT 6?
	JRST INFO08		;[4] NO - ASSUME IT MUST BE 8 LPI
	TMSG <6-LPI>		;[4] INFORM
	JRST INFO10		;[4] AND CONTINUE
INFO08:	TMSG <8-LPI>		;[4] INFORM OF 8-LPI

INFO10:	TMSG <
LENGTH			>
	SKIPN B,LINPPG		;HAVE A LENGTH YET?
	MOVEI B,^D66		;NO. GET DEFAULT
	CALL NUMOUT		;AND DISPLAY A NUMBER
	SKIPN B,PAGSIZ		;HAVE A PAGE SIZE YET?
	JRST INFO20		;NO. GO ON
	TMSG <
PAGE SIZE		>
	CALL NUMOUT		;AND OUTPUT IT
INFO20:	SKIPN W2,CHNMSK		;HAVE ANY CHANNELS YET?
	JRST INFO30
	TMSG <
CHANNELS ASSIGNED	>
	CALL NUMS		;OUTPUT NUMBER LIST
INFO30:	SKIPN B,MARKW		;DOING MARKING?
	JRST INFO40		;NO
	TMSG <
MARKING UNASSIGNED CHANNELS>
INFO40:	SKIPN W2,FORMS		;DOING A FORMS CHANNEL?
	RET			;NO. ALL DONE
	TMSG <
FORMS CHANNELS		>
	CALLRET NUMS		;GO OUTPUT THEM

NUMS:	MOVSI W1,-^D12		;DO 12 CHANNELS
	ROT W2,-1		;SKIP 0
INFLOP:	ROT W2,-1		;GET NEXT CHANNEL
	JUMPGE W2,INFLO1	;NOT SET
	MOVEI B,1(W1)		;GET CHANNEL NUMBER
	CALL NUMOUT		;AND DISPLAY IT
	MOVEI A," "
	PBOUT			;MAKE IT LOOK NICE
INFLO1:	AOBJN W1,INFLOP		;DO ALL CHANNELS
	RET			;AND DONE
;FORM COMMAD TO DEFINE FORMS BREAK CHANNEL

.FORM:	STKVAR <FRMNUM>
	MOVEI A,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	NOISE (IS)		;PARSE NOISE WORD
	MOVEI A,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	CMMND [FLDDB. (.CMNUM,,^D10)] ;PARSE DECIMAL NUMERIC ARGUMENT
	TXNE A,CM%NOP		;NUMBER PARSED OK ?
	JRST NOFRM		;NO, GO ISSUE ERROR MESSAGE
	MOVEM B,FRMNUM		;SAVE NUMBER ENTERED
	MOVEI A,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	CONFRM			;GET CONFIRMATION FUNCTION
	TXNE A,CM%NOP		;END OF COMMMAND PARSED OK?
	 CALLRET COMER1		;NO, ISSUE MESSAGE

; HERE WITH A VALID NUMBER

	MOVE A,FRMNUM		;RESTORE NUMBER ENTERED BY USER
	SKIPE A			;IN RANGE?
	CAILE A,^D12		;STILL?
	JRST BADFRM		;INVALID VALUE GIVEN
	MOVEI B,1		;GET A BIT
	LSH B,0(A)		;POSITION IT
	IORM B,FORMS		;REMEMBER THIS CHANNEL
	RET			;RETURN TO WHENCE WE CAME ...

; HERE IF NUMBER NOT PARSED OK

NOFRM:	CALL TSTCOL		;ISSUE NEW LINE IF NEEDED
	TMSG <? MAKVFU: Invalid decimal number entered
>				;OUTPUT MESSAGE
	RET			;RETURN

; HERE IF NUMBER ENTERED IS OUT OF RANGE

BADFRM:	CALL TSTCOL		;ISSUE NEW LINE IF NEEDED
	TMSG <? MAKVFU: Channel out of range
>
	RET			;RETURN TO WHENCE WE CAME ...
;DO PAGE SIZE

.PAGE:	STKVAR <PAGELN>
	MOVEI A,CMDBLK		;GET COMMAND STATE BLOCK ADDRESS
	NOISE (IS)		;PARSE NOISE WORD
	MOVEI A,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	CMMND [FLDDB. (.CMNUM,,^D10)] ;PARSE DECIMAL PAGE SIZE
	TXNN A,CM%NOP		;NUMBER PARSED OK ?
	JRST PAGE05		;YES, GO ON AND SAVE THE PAGE SIZE
	CALL TSTCOL		;NO, ISSUE CRLF IF NEEDED
	TMSG <? MAKVFU: Invalid decimal number entered for page size
>				;OUTPUT MESSAGE
	RET			;RETURN

; HERE WITH A VALID PAGE SIZE - SAVE IT AND PARSE END OF COMMAND

PAGE05:	MOVEM B,PAGELN		;SAVE SIZE ENTERED
	MOVEI A,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	CONFRM			;GET CONFIRMATION FUNCTION
	TXNE A,CM%NOP		;END OF COMMMAND PARSED OK?
	 CALLRET COMER1		;NO, ISSUE MESSAGE
	MOVE A,PAGELN		;RESTORE PAGE SIZE ENTERED
	CAMG A,LINPPG		;REASONABLE SIZE?
	SKIPN A			;A NON-ZERO PAGE SIZE?
	JRST BADSIZ		;NO. DON'T BELIEVE IT
	SKIPN PAGSIZ		;ALREADY HAVE ONE?
	JRST PAGE10		;NO, ALL SET
	PUSH P,A		;SAVE LINE NUMBER
	CALL TSTCOL		;YES, GO ISSUE CRLF IF NEEDED
	TMSG <% MAKVFU: Page size already specified. Superceded
>				;OUTPUT WARNING MESSAGE
	POP P,A			;RECOVER PAGE SIZE
PAGE10:	MOVEM A,PAGSIZ		;REMEMBER IT
	RET			;RETURN TO WHENCE WE CAME ...

; HERE ON A BAD PAGE SIZE SPECIFIED

BADSIZ:	CALL TSTCOL		;ISSUE NEW LINE IF NEEDED
	TMSG <? MAKVFU: Invalid argument for page size. Command ignored
>				;OUTPUT MESSAGE
	RET			;RETURN TO WHENCE WE CAME ...
;READ VFU CHANNEL ASSIGMENT AND SET UP VFU BIT PATTERN

.CHNL:	TRVAR <CHNARG,TMPCHN>
	MOVEI A,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	NOISE (NUMBER)		;PARSE NOISE WORDS
	MOVEI A,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	CMMND [FLDDB. (.CMNUM,,^D10)] ;PARSE DECIMAL CHANNEL NUMBER
	TXNN A,CM%NOP		;NUMBER PARSED OK ?
	JRST CHNL05		;YES, GO ON
	CALL TSTCOL		;NO, ISSUE NEW LINE IF NEEDED
	TMSG <? MAKVFU: Invalid decimal number entered for channel
>				;OUTPUT MESSAGE
	RET			;RETURN TOW WHENCE WE CAME ...

; HERE WITH A GOOD CHANNEL NUMBER

CHNL05:	SKIPLE B		;A VALID CHANNEL NUMBER?
	CAILE B,MAXCHN		;STILL?
	JRST [	CALL TSTCOL	;NO. TELL USER
		TMSG <? MAKVFU: Channel number out of range
>
		RET]		;AND IGNORE REST OF COMMAND
	MOVEM B,CHANEL		;REMEMBER CURRENT CHANNEL
	MOVEI A,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	CMMND [FLDDB. (.CMKEY,,LEV2)] ;PARSE NEXT SUBCOMMAND
	TXNN A,CM%NOP		;PARSED NEXT PART OK ?
	JRST CHNL10		;YES, GO ON
	CALL TSTCOL		;NO, ISSUE NEW LINE IF NEEDED
	TMSG <? MAKVFU: Invalid argument to CHANNEL command, ignored.
>				;OUTPUT MESSAGE
	RET			;RETURN...

; HERE WITH A VALID ARGUMENT

CHNL10:	MOVEM B,CHNARG		;SAVE ARGUMENT ADDRESS

; SET UP CHANNEL MASK AND DISPATCH

	MOVEI B,1
	MOVE A,CHANEL
	LSH B,0(A)		;POSITION A BIT
	MOVEM B,TMPCHN		;KEEP CHANNEL FOR FLAGGING AS SEEN
	MOVE A,CHNARG		;GET CHANNEL ARG ADDRESS
	HRRZ A,(A)		;GET DISPATCH ADDRESS FOR ARGUMENT ENTERED
	CALLRET (A)		;GO PROCESS ARGUMENT AND RETURN
;UTILITY SUBROUTINES

NUMOUT:	MOVEI A,.PRIOU		;PRIMARY OUT
	MOVEI C,12		;IN DECIMAL
	NOUT			;OUTPUT A NUMBER
	 JFCL
	RET			;AND DONE

PBLANK:	ILDB A,PNT		;NEXT ATOM
	CAIE A," "		;A BLANK?
	CAIN A,"	"
	JRST PBLANK		;YES. SKIP IT
	CAIN A,.CHCRT		;A CR?
	JRST PBLANK		;YES
	CAIN A,.CHLFD		;END OF LINE?
	RET			;YES. BAD
	MOVNI A,1		;BACK UP PNT
	IBP A,PNT
	MOVE PNT,A		;DO IT
	AOS (P)
	RET			;GOOD

;SET A BIT IN THE CHNBUF

SETBIT:	PUSH P,A
	IDIVI A,^D36		;GET WORD AND BIT
	MOVE W,CHANEL		;GET CHANNEL
	SOS W			;ADJUST FOR CRUDE COUNTING
	IMULI W,<MAXLIN/^D36+1>	;WORDS PER CHANNEL
	ADDI A,0(W)		;WORD TO SET
	MOVSI C,(1B0)		;GET A BIT
	MOVNI B,0(B)
	ROT C,(B)		;POSITION BIT
	IORM C,CHNBUF(A)	;SET IT
	POP P,A			;RETURN THE ARG
	RET			;AND DONE
;SUBCOMMANDS OF CHANNEL

;FIRST, DO TOP

.TOP:	MOVEI A,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	CONFRM			;PARSE END OF COMMAND
	TXNE A,CM%NOP		;END OF COMMMAND PARSED OK?
	 CALLRET COMER1		;NO, ISSUE MESSAGE
	SKIPN PAGSIZ		;HAVE A PAGE SIZE YET?
	JRST [	CALL TSTCOL	;OUTPUT NEW LINE IF NEEDED
		TMSG <? MAKVFU: Illegal to specify "TOP" unless PAGE SIZE has been specified
>
		RET ]		;RETURN
	MOVE A,TMPCHN		;GET CHANNEL NUMBER
	IORM A,CHNMSK		;AND MARK AS SEEN.
	MOVEI A,0		;CHANNEL TO SET
	CALL SETBIT		;SET BIT FOR TOP
	RET			;RETURN TO WHENCE WE CAME ...

;DO BOTTOM

.BOTOM:	MOVEI A,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	CONFRM			;PARSE END OF COMMAND
	TXNE A,CM%NOP		;END OF COMMMAND PARSED OK?
	 CALLRET COMER1		;NO, ISSUE MESSAGE
	SKIPN PAGSIZ		;HAVE A PAGE SIZE YET?
	JRST [	CALL TSTCOL	;OUTPUT CRLF IF NEEDED
		TMSG <? MAKVFU: Illegal to specify "BOTTOM" unless PAGE SIZE has been specified
>				;OUTPUT MESSAGE
		RET ]		;RETURN
	MOVE A,TMPCHN		;GET CHANNEL NUMBER
	IORM A,CHNMSK		;AND MARK AS SEEN.
	MOVE A,PAGSIZ		;FIRST MARK IS AT THE BOTTOM
	CALLRET SETBIT		;GO SET BIT AND RETURN

;DO ALL LINES

.ALL:	MOVEI A,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	CONFRM			;PARSE END OF COMMAND
	TXNE A,CM%NOP		;END OF COMMMAND PARSED OK?
	 CALLRET COMER1		;NO, ISSUE MESSAGE
	SKIPN PAGSIZ		;HAVE A PAGE SIZE YET
	JRST [	CALL TSTCOL	;OUTPUT NEW LINE IF NEEDED
		TMSG <? MAKVFU: Illegal to specify "ALL" unless PAGE SIZE has been specified
>				;OUTPUT MESSAGE
		RET ]		;RETURN
	MOVEI A,0		;INITIALIZE CHANNEL NUMBER
ALL1:	CALL SETBIT
	AOS A			;NEXT LINE
	CAMGE A,PAGSIZ		;AT THE END?
	 JRST ALL1		;NO
	MOVE A,TMPCHN		;GET CHANNEL NUMBER
	IORM A,CHNMSK		;AND MARK AS SEEN.
	RET			;RETURN TO PARSER
;MORE SUBCOMMANDS.

;SET EVERY LINE

EVERY:	STKVAR <EVYSTP>
	MOVEI A,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	CMMND [FLDDB. (.CMNUM,,^D10)] ;PARSE DECIMAL NUMBER
	TXNN A,CM%NOP		;PARSED NUMBER OK ?
	JRST EVRY10		;YES, GO SAVE THE NUMBER
	CALL TSTCOL		;NO, ISSUE NEW LINE IF NEEDED
	TMSG <? MAKVFU: Invalid number entered for step size
>				;OUTPUT MESSAGE
	RET			;RETURN

; HERE WITH A GOOD STEP SIZE

EVRY10:	MOVEM B,EVYSTP		;SAVE STEP SIZE
	MOVEI A,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	NOISE (LINES)		;PARSE NOISE WORDS
	MOVEI A,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	CONFRM			;PARSE END OF COMMAND
	TXNE A,CM%NOP		;END OF COMMMAND PARSED OK?
	 CALLRET COMER1		;NO, ISSUE MESSAGE
	SKIPG PAGSIZ		;HAVE A PAGE SIZE YET?
	 JRST [	CALL TSTCOL	;ISSUE NEW LINE IF NEEDED
		TMSG <? MAKVFU: Can't specify "EVERY" unless PAGE SIZE has been specified
>				;OUTPUT MESSAGE
		RET ]		;RETURN
	MOVE A,TMPCHN		;GET CHANNEL NUMBER
	IORM A,CHNMSK		;AND MARK AS SEEN.
	SETZ A,			;START HERE
EVERY1:	CALL SETBIT
	ADD A,EVYSTP		;NEXT
	CAMGE A,PAGSIZ		;AT THE END YET?
	JRST EVERY1		;NO
	RET			;RETURN
;DO LINES COMMAND

LINFDB:	FLDDB. (.CMNUM,,^D10,,,<[FLDDB. (.CMCMA,,,,,<[FLDDB. (.CMCFM)]>)]>)


LINES:	MOVEI A,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	NOISE (NUMBERS)		;PARSE NOISE
LINE05:	MOVEI A,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	CMMND LINFDB		;PARSE NEXT FIELD
	TXNN A,CM%NOP		;ANYTHING PARSE OK ?
	JRST LINE10		;YES, GO SEE WHAT WE GOT
	CALL TSTCOL		;NO, ISSUE NEW LINE IF NEEDED
	TMSG <? MAKVFU: Invalid argument
>				;OUTPUT MESSAGE
	RET			;RETURN


; HERE ON A VALID ARGUMENT - SEE WHAT WAS ENTERED

LINE10:	LDB A,[POINT 9,(C),8]	;GET FUNCTION CODE PARSED
	CAIN A,.CMCFM		;GOT END OF COMMAND ?
	JRST [	MOVE A,TMPCHN		;GET CHANNEL NUMBER
		IORM A,CHNMSK		;AND MARK AS SEEN.
		RET ]			;RETURN, ALL DONE
	CAIN A,.CMCMA		;GOT A COMMA ?
	JRST LINE05		;YES, GO GET NEXT FIELD
	CAIN A,.CMNUM		;GET A NUMBER ?
	JRST LINNUM		;YES, GO HANDLE THE LINE NUMBER
	CALL TSTCOL		;ERROR, SEE IF CRLF NEEDED
	TMSG <? MAKVFU: Internal error, command ignored
>				;OUTPUT MESSAGE
	RET			;RETURN
; HERE TO HANDLE A NUMBER

LINNUM:	SOS B			;USE CORRECT ADDRESSING
	SKIPL B			;VALID?
	CAML B,PAGSIZ		;WITHIN RANGE?
	JRST [	CALL TSTCOL		;ISSUE MESSAGE IF NEEDED
		TMSG <? MAKVFU: Line number out of range
>				;OUTPUT MESSAGE
		RET ]		;RETURN
	MOVE A,B		;COPY LINE NUMBER
	CALL SETBIT		;GO SET THE BIT
	JRST LINE05		;AND GET NEXT
SUBTTL	COMMAND ERROR SUBROUTINES

; INVALID END-OF-COMMAND

COMER1:	CALL TSTCOL		;TEST COLUMN POSITION
	TMSG <? MAKVFU: Garbage at end-of-command
>				;OUTPUT ERROR MESSAGE
	JRST REEN		;CLEAR STUFF AND CONTINUE...


; SUBROUTINE TO TEST COLUMN POSITION AND OUTPUT CRLF IF NEEDED

TSTCOL:	movei A,.priou		;get primary output designator
	rfpos			;read file position
	hrrz B,B		;keep just the column position
	JUMPE B,R		;IF AT COLUMN 1 DO NOT OUTPUT CRLF
	tmsg <
>				;no, output a crlf
	RET			;RETURN
; EXIT COMMAND

.EXIT:	MOVEI A,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	NOISE (TO MONITOR)	;PARSE NOISE FIELD
	CONFRM			;PARSE END OF COMMAND
	TXNE A,CM%NOP		;END OF COMMMAND PARSED OK?
	 CALLRET COMER1		;NO, ISSUE MESSAGE
	HALTF			;TO THE EXEC
	JRST START		;IN CASE OF CONTINUE


; HELP COMMAND

.HELP:	MOVEI A,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	CONFRM			;WAIT FOR END-OF-COMMAND
	TXNE A,CM%NOP		;END OF COMMMAND PARSED OK?
	 CALLRET COMER1		;NO, ISSUE MESSAGE
	HRROI A,HLPTXT
	PSOUT
	JRST PARSE		;GO DO NEXT COMMAND
;NOW BUILD VFU

.OUTPT:	STKVAR <VFUJFN>
	MOVEI A,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	NOISE (TO VFU FILE)	;PARSE NOISE WORDS
	MOVEI A,CMDBLK		;GET ADDRESS OF COMMAND STATE BLOCK
	CMMND [FLDDB. (.CMOFI)] ;PARSE OUTPUT FILE SPEC
	TXNN A,CM%NOP		;PARSED OK ?
	JRST OUTPT2		;YES, GO SAVE JFN
	CALL TSTCOL		;NO, ISSUE CRLF IF NEEDED
	TMSG <? MAKVFU: Invalid file specification
>				;OUTPUT MESSAGE
	RET			;RETURN

; HERE WITH A JFN FOR OUTPUT FILE

OUTPT2:	MOVEM B,VFUJFN		;SAVE JFN FOR VFU FILE
	CONFRM			;GET CONFIRMATION FOR COMMAND
	TXNE A,CM%NOP		;END OF COMMMAND PARSED OK?
	 CALLRET COMER1		;NO, ISSUE MESSAGE
OUTPT3:	SKIPN A,FORMS		;HAVE A FORMS BREAK CHANNEL?
	JRST MAKVF1		;NO. GO ON
	JFFO A,.+1		;GET LOG OF CHANNEL NUMBER
	SUBI B,^D35		;NEGATIVE OF CHANNEL
	MOVN B,B		;GET CHANNEL NUMBER
	MOVEM B,CHANEL		;SET IT UP
	MOVEI A,1		;A BIT
	LSH A,0(B)		;POSITION IT
	ANDCAM A,FORMS		;TURN IT OFF
	MOVE A,PAGSIZ		;GET TO BOTTOM
MAKVF2:	CALL SETBIT		;SET THE BIT
	AOS A			;NEXT LINE
	CAMGE A,LINPPG		;ALL DONE?
	JRST MAKVF2		;NO. DO THE LINE THEN
	JRST OUTPT3		;YES. GO DO NEXT THEN
MAKVF1:	SETZ W1,		;LINE NUMBER
	MOVE PNT,[POINT ^D8,VFUBUF] ;WHERE TO BUILD IT
;**;[4] Change one line at MAKVF1: +2L	JGZ	30-NOV-80
	MOVE A,LPI		;[4] START VFU LOAD WITH CONTROL BYTE
	IDPB A,PNT		;STASH IT
CHNLOP:	MOVSI C,-^D12		;DO 12 CHANNELS
	SETZ W2,		;MASK WORD
	CALL BLDVFU		;GO BUILD WORD FOR THIS LINE
	LSHC W2,-6		;SPLIT THE FIELD
	LSH W3,-^D30		;POSITION FIRST BYTE
	IDPB W3,PNT
	IDPB W2,PNT		;PUT IN THE BYTES
	AOS W1			;NEXT LINE
	CAMGE W1,LINPPG		;OVER THE END?
	JRST CHNLOP		;NO. GO DO IT THEN
	MOVEI A,357		;LAST BYTE
	IDPB A,PNT

;NOW SWAP THE BYTES SO DATA CAN BE SENT IN WORD MODE TO THE -11

	HRRZ A,PNT		;GET LAST WORD USED
	SUBI A,VFUBUF-1		;CALCULATE WORDS USED
	LSH A,1			;-11 WORDS USED
	MOVE D,[POINT ^D8,VFUBUF]
	MOVE W3,D		;SET UP BYTE POINTERS
SWPLOP:	ILDB B,D		;GET  NEXT BYTE
	ILDB C,D		;AND THE NEXT
	IDPB C,W3
	IDPB B,W3		;SWAP THE BYTES
	SOJG A,SWPLOP		;DO ALL WORDS
	;..
	;..

; NOW OPEN THE OUTPUT FILE

	MOVE A,VFUJFN		;GET JFN FOR VFU FILE
	MOVE B,[200000,,100000]
	OPENF
	 JRST [	CALL TSTCOL	;ISSUE NEW LINE IF NEEDED
		TMSG <? MAKVFU: Cannot open output file
>				;OUTPUT MESSAGE
		MOVE A,VFUJFN		;GET JFN FOR VFU FILE
		RLJFN		;RELEASE THE JFN
		 JFCL		;IGNORE ERRORS HERE
		RET ]		;RETURN
	MOVEI C,VFUBUF-1
	SUBI C,0(PNT)
	LSH C,1			;TWO BYTES PER
	TLNE PNT,200000		;ODD BYTE IN LAST WORD?
	AOS C			;YES.
	MOVE B,[POINT ^D16,VFUBUF]
	SOUT			;WRITE THE FILE
	CLOSF			;CLOSE IT
	 JRST [	CALL TSTCOL	;ISSUE NEW LINE IF NEEDED
		TMSG <% MAKVFU: Cannot close output file
>				;OUTPUT MESSAGE
		RET ]		;RETURN
	JRST START		;START ALL OVER AGAIN
;WORKER ROUTINE TO BUILD THE BYTE AND STORE IT

BLDVFU:	MOVEI D,<MAXLIN/^D36+1>	;SIZE OF A CHANNEL BUFFER
	MOVEI A,1		;SEE IF CHANNEL ASSIGNED
	LSH A,1(C)		;POSITION BIT
	TDNN A,CHNMSK		;IS IT?
	JRST SETIT1		;NO. GO SEE IF MARKING IS IN FORCE
	IMULI D,0(C)		;GET START WORD FOR THIS CHANNEL
	MOVEI A,0(W1)		;GET PROPER LINE
	IDIVI A,^D36		;LINES PER WORD
	ADDI D,0(A)		;THE WORD
	MOVNI B,0(B)		;ROT COUNT
	MOVSI A,(1B0)		;A BIT
	ROT A,(B)		;POSITION IT
	TDNE A,CHNBUF(D)	;SET?
	JRST SETIT		;YES. DO IT
BLD1:	AOBJN C,BLDVFU		;DO NEXT CHANNEL
	RET			;AND DONE

SETIT1:	SKIPN MARKW		;DOING MARKING?
	JRST BLD1		;NO. SKIP IT THEN
SETIT:	MOVEI A,1		;A BIT
	LSH A,0(C)		;POSITION ACCORDING TO CHANNEL
	IOR W2,A		;SET IT
	JRST BLD1		;AND PROCEED
;TAKE COMMANDS FROM INPUT FILE

.TAKE:	STKVAR <TMPJFN>		;STORE TEMPORARY JFN HERE
	MOVEI A,CMDBLK
	NOISE (COMMANDS FROM FILE) ;PARSE NOISE
	HRROI B,[ASCIZ@CMD@]	;DEFAULT EXTENSION
	MOVEM B,GJFBLK+.GJEXT
	MOVX B,GJ%OLD
	MOVEM B,GJFBLK+.GJGEN
	CMMND [FLDDB. (.CMFIL)]	;GET INPUT FILE
	MOVEM B,TMPJFN
	SETZM GJFBLK+.GJEXT
	CONFRM			;CONFIRM THE LINE
	SKIPE TAKJFN		;ARE WE ALREADY INSIDE A TAKE FILE?
	 JRST [	CALL TSTCOL
		TMSG <% MAKVFU: Cannot nest TAKE files
>
		RET ]
	MOVE A,TMPJFN		;RESTORE JFN
	MOVX B,OF%RD+7B5
	OPENF			;TRY TO OPEN THE FILE
	 JRST [ CALL TSTCOL
		TMSG <? MAKVFU: Cannot open TAKE file
>
		RET ]
	MOVEM A,TAKJFN
	RET

;RELEASE JFN FOR TAKE FILE AND GO BACK TO NORMAL

RELTAK:	SKIPE B,TAKJFN		;GET JFN IF IT EXISTS
	 JRST [	TMSG <   End of > ;IT DOES, LET USER KNOW ALL IS OK
		MOVEI A,.PRIOU	;THIS GOES TO TERMINAL
		SETZ C,		;JUST A NORMAL PRINT, NO FLAGS
		JFNS		;PRINT FILE NAME
		MOVE A,B	;RESTORE JFN FOR CLOSING
		CLOSF		;CLOSE FILE
		 ERJMP .+1	;IGNORE ERROR
		JRST .+1 ]
	SETZM TAKJFN		;FORGET ABOUT IT NOW
	RET
;ROUTINES TO CALL COMND% USED FOR REGULAR INPUT OR TAKE FILE.

DOCFRM:	MOVEI B,[FLDDB. (.CMCFM)] ;SET UP TO CONFIRM INPUT
DOCMND:	HRLZ C,TAKJFN		;GET TAKE FILE JFN (IF ANY)
	SKIPE C			;IS THERE ONE?
	 TROA C,.NULIO		; YES, SET OUTPUT JFN TO NULL
	  MOVE C,[.PRIIN,,.PRIOU] ; NO, USE REGULAR JFN.
	MOVEM C,CMDBLK+.CMIOJ	;PLACE IN COMND BLOCK
	COMND			;PARSE INPUT
	 ERJMP DOCMMF		;FAILED
	RET			;GO BACK TO WHENCE WE CAME...

DOCMMF:	SKIPN TAKJFN		;READING FROM TAKE FILE?
	 CALLRET COMER1		; NO, GIVE ERROR MESSAGE
	MOVX A,.FHSLF
	GETER			;YES, READ LAST ERROR
	ANDI B,-1		;KEEP ONLY ERROR CODE
	CAIE B,IOX4		;END OF TAKE FILE?
	 JRST [	CALL TSTCOL
		TMSG <% MAKVFU: Error reading TAKE file
>				;NO, COMPLAIN
		JRST REEN ]
	JRST REEN

	END <3,,ENTVEC>