Google
 

Trailing-Edge - PDP-10 Archives - SRI_NIC_PERM_SRC_3_19910112 - mit/exec/execqu.mac
There are 47 other files named execqu.mac in the archive. Click here to see a list.
;[MIT-XX]SRC:<EXEC.TEST>EXECQU.MAC.3, 24-Jul-84 23:13:09, Edit by JTW
;111 PRINT options for SPEECH
;7 REL-4 changes, apparently
;713 add literals label
;   use new configuration switches
;712 DEC release version
; UPD ID= 136, SNARK:<5.EXEC>EXECQU.MAC.19,   3-Feb-82 13:25:19 by GROUT
;TCO 5.1708 - Fix /JOBNAME help message, make comma illegal after comma
; UPD ID= 130, SNARK:<5.EXEC>EXECQU.MAC.18,  13-Jan-82 16:03:52 by KROSENBLUH
;TCO 5.1670 - make /LIMIT work for card-reader, punch and plotter
; UPD ID= 125, SNARK:<5.EXEC>EXECQU.MAC.17,  28-Dec-81 11:17:13 by CHALL
;TCO 5.1644 - UPDATE COPYRIGHT NOTICE
; UPD ID= 62, SNARK:<5.EXEC>EXECQU.MAC.13,   3-Sep-81 18:28:27 by TILLSON
;TCO 5.1489 Let CANCEL request-type ? tell us about "*"
; UPD ID= 28, SNARK:<5.EXEC>EXECQU.MAC.11,  14-Aug-81 18:34:52 by CHALL
;TCO 5.1456 .MODIF- TELL ABOUT "*" AS A LEGAL OPTION TO "MOD MUMBLE"
;TCO 5.1454 CHANGE NAME FROM XDEF TO EXECDE
; UPD ID= 23, SNARK:<5.EXEC>EXECQU.MAC.10,  14-Aug-81 10:47:54 by GROUT
; UPD ID= 2299, SNARK:<5.EXEC>EXECQU.MAC.8,   6-Jul-81 14:47:27 by GROUT
; UPD ID= 2231, SNARK:<5.EXEC>EXECQU.MAC.6,  21-Jun-81 09:37:00 by ACARLSON
; UPD ID= 2212, SNARK:<5.EXEC>EXECQU.MAC.5,  18-Jun-81 11:04:21 by GROUT
;TCO 5.1374 - Make code check extensions in all cases for PRINT default actions
; UPD ID= 2068, SNARK:<5.EXEC>EXECQU.MAC.4,  22-May-81 13:19:24 by GROUT
;TCO 5.1343 - Make IPCF code flush buffers only if necessary
; UPD ID= 2009, SNARK:<5.EXEC>EXECQU.MAC.3,  15-May-81 13:59:25 by ACARLSON
;<ACARLSON>EXECQU.MAC.5, 15-May-81 13:58:14, EDIT BY ACARLSON
;   Add another % to UETYPE instr so _ does not print
; UPD ID= 1956, SNARK:<5.EXEC>EXECQU.MAC.2,   6-May-81 15:06:45 by MURPHY
;DELETE DEADLINE AND CODE FOR IT
;PUT IPCF STUFF FROM SUBRS TO HERE
;SEARCH GALAXY UNV'S
; UPD ID= 955, SNARK:<5.EXEC>EXECQU.MAC.4,  24-Aug-80 21:11:26 by ZIMA
;TCO 5.1137 - fix "SET DEFAULT PLOT<return>" from blowing up.
; UPD ID= 538, SNARK:<5.EXEC>EXECQU.MAC.3,  20-May-80 15:46:37 by MURPHY
;<4.1.EXEC>EXECQU.MAC.4, 15-Apr-80 10:06:47, EDIT BY OSMAN
;Neaten up .CSO references
;<4.1.EXEC>EXECQU.MAC.3, 14-Feb-80 09:36:14, EDIT BY OSMAN
;tco 4.1.1080 - Fix MOD PR CMD/NOHEADER to not cause pushdown overflow
; UPD ID= 95, SNARK:<4.1.EXEC>EXECQU.MAC.2,   5-Dec-79 10:44:27 by OSMAN
;tco 4.1.1045 - Allow all filespec characters in jobnames for CANCEL and
;   friends 
;<EKLUND>EXECQU.MAC.15, 17-Oct-79 11:12:48, EDIT BY EKLUND
;Fix 4.2354 so extraneous FDB blocks do not exist
;Also correct the handling of specs after commas (don't do hrrz B,(B))
;<4.EXEC>EXECQU.MAC.164, 28-Sep-79 08:38:14, EDIT BY OSMAN
;tco 4.2499 - remove spurious "4" at beginning of edit line
;<4.EXEC>EXECQU.MAC.163, 28-Sep-79 08:36:11, EDIT BY OSMAN
;tco 4.2498 - Print double colons under INFO DEF PRINT on node names
;<4.EXEC>EXECQU.MAC.162, 18-Sep-79 12:32:28, EDIT BY TOMCZAK
;TCO# 4.2474 - /LOGNAME: shouldn't pass generation#'s to BATCON (SUBMIT)
;<4.EXEC>EXECQU.MAC.161, 12-Sep-79 11:24:56, EDIT BY OSMAN
;Don't call JFNSTK at PRIFIL; it's already done at CFN2
;<4.EXEC>EXECQU.MAC.158, 13-Aug-79 09:26:48, EDIT BY OSMAN
;tco 4.2389 - Put (ID) guideword after CANCEL request-type.
;<4.EXEC>EXECQU.MAC.156, 27-Jul-79 16:09:59, EDIT BY EKLUND
;tco 4.2354 - Forbid file specific switches after comma in all commands
;<4.EXEC>EXECQU.MAC.155, 26-Jul-79 13:37:13, EDIT BY OSMAN
;tco 4.2348 - Fix INFO DEFAULT SUBMIT (/TIME:30:0 printout)
;<4.EXEC>EXECQU.MAC.154, 13-Jul-79 11:01:02, EDIT BY OSMAN
;tco 4.2325 - Don't allow /MODE on SUBMIT
;tco 4.2293 - Make CANCEL RETRIEVE like all other CANCEL commands
;<4.EXEC>EXECQU.MAC.151,  4-May-79 09:34:52, EDIT BY OSMAN
;ALLOW CANCEL MOUNT * (WHY DID I DISALLOW IT BEFORE???)
;<4.EXEC>EXECQU.MAC.150, 23-Apr-79 09:30:43, EDIT BY R.ACE
;INFORMATION COMMAND - CLEAR .OFLAG BEFORE SETTING ANY FLAGS
;<4.EXEC>EXECQU.MAC.149, 18-Apr-79 13:45:02, EDIT BY HURLEY.CALVIN
; fix canret so that 1st pass in canre1 loop works properly
;<4.EXEC>EXECQU.MAC.148, 10-Apr-79 10:07:34, EDIT BY OSMAN
;FIX "requuest" at GJNM help message
;<4.EXEC>EXECQU.MAC.145, 29-Mar-79 15:13:16, EDIT BY OSMAN
;Don't default jobname on CANCEL to *.  Require it (or request ID)!
;<4.EXEC>EXECQU.MAC.144, 28-Mar-79 10:09:56, EDIT BY EKLUND
;MAKE @PRINT/FILE:ASCII A.DAT    AND
;     @PRINT/PRESERVE B.LST   AND THE LIKE WORK PROPERLY - TCO 4.2224
;<4.EXEC>EXECQU.MAC.142, 23-Mar-79 10:28:24, EDIT BY OSMAN
;FIX INFO DEF PR (FORGOT PRISTG AT ID0)
;<4.EXEC>EXECQU.MAC.141, 13-Mar-79 16:22:01, EDIT BY OSMAN
;PUT /SEQ BACK.  (MERE BUG!)
;<4.EXEC>EXECQU.MAC.140, 13-Mar-79 10:55:12, EDIT BY OSMAN
;FIX "I O" (DO PRISTG AT IPR11)
;<4.EXEC>EXECQU.MAC.139, 12-Mar-79 18:04:08, EDIT BY KONEN
;UPDATE COPYRIGHT FOR RELEASE 4
;<4.EXEC>EXECQU.MAC.138, 12-Mar-79 09:29:46, EDIT BY OSMAN
;fix /FILE
;<4.EXEC>EXECQU.MAC.137,  9-Mar-79 15:39:56, EDIT BY OSMAN
;USE GETBUF INSTEAD OF QSTK
;<4.EXEC>EXECQU.MAC.135,  5-Mar-79 14:14:14, EDIT BY HURLEY.CALVIN
; CAUSE CANRET NOT TO TRY FILES THAT ARE NOT OFFLINE. BEST WE CAN
; DO AT THE MOMENT SINCE ONLY QUASAR KNOWS IF A RETRIEVE IS OUTSTANDING
;<4.EXEC>EXECQU.MAC.134, 21-Feb-79 16:24:32, EDIT BY OSMAN
;REMOVE JOBNAME-DEFAULTING CODE.  LET QUASAR DO IT
;<4.EXEC>EXECQU.MAC.133, 21-Feb-79 13:50:28, EDIT BY HURLEY.CALVIN
; Put in spaces before the "%" in CANCEL RET messages
;<4.EXEC>EXECQU.MAC.132, 13-Feb-79 17:18:12, EDIT BY OSMAN
;ALLOW /GENERIC ON ALL DEVICES
;<4.EXEC>EXECQU.MAC.131,  9-Feb-79 14:01:16, EDIT BY OSMAN
;FIX /PROCESSING-NODE
;<4.EXEC>EXECQU.MAC.124,  8-Feb-79 16:35:07, EDIT BY OSMAN
;ADD INFO DEF PLOT
;<4.EXEC>EXECQU.MAC.119,  7-Feb-79 13:55:49, EDIT BY OSMAN
;ADD PLOT
;<4.EXEC>EXECQU.MAC.118,  2-Feb-79 11:05:14, EDIT BY OSMAN
;FIX /UNIQUE
;<4.EXEC>EXECQU.MAC.117,  1-Feb-79 11:00:45, EDIT BY OSMAN
;FIX /ASSISTANCE (FORGOT TO CALL GETKEY!)
;<4.EXEC>EXECQU.MAC.116,  1-Feb-79 09:56:35, EDIT BY OSMAN
;add /SEQUENCE WHICH GOT MYSTERIOUSLY LOST
;<4.EXEC>EXECQU.MAC.115, 31-Jan-79 15:45:14, EDIT BY OSMAN
;CHANGE /DELETE: TO /DELETE
;<4.EXEC>EXECQU.MAC.114, 29-Jan-79 10:46:30, EDIT BY ACARLSON
;CHANGE .FPFAS (BATCH DEFAULT) TO .FPFSA (STREAM ASCII)
;<4.EXEC>EXECQU.MAC.113, 26-Jan-79 14:16:08, EDIT BY OSMAN
;Use FNODEX to read node names, so that it needn't exist
;<4.EXEC>EXECQU.MAC.112, 25-Jan-79 16:50:14, EDIT BY ACARLSON
;<4.EXEC>EXECQU.MAC.111, 25-Jan-79 16:43:35, EDIT BY ACARLSON
;FIX A 'PRI FOO/GENERIC' BUG AND MAKE BATCH FILES
;     DEFAULT TO ASCII FORMAT
;<4.EXEC>EXECQU.MAC.107, 23-Jan-79 14:41:40, EDIT BY OSMAN
;FIX SET NO DEFAULT WHEN THERE ARE NONE
;<4.EXEC>EXECQU.MAC.106, 23-Jan-79 14:22:43, EDIT BY OSMAN
;ALLOW MANY THINGS TO BE MODIFIED
;<4.EXEC>EXECQU.MAC.105, 23-Jan-79 09:50:09, EDIT BY OSMAN
;/HEADER, /FORMS, /NOTE ALLOWABLE FOR ALL DEVICES (SAYS PTAYLOR)
;<4.EXEC>EXECQU.MAC.94, 19-Jan-79 18:53:47, EDIT BY OSMAN
;RECOGNIZE REQUEST ID'S IN MODIFY AND CANCEL
;<4.EXEC>EXECQU.MAC.93, 19-Jan-79 17:40:31, EDIT BY OSMAN
;<4.EXEC>EXECQU.MAC.92, 19-Jan-79 17:19:37, EDIT BY OSMAN
;implement /processing-node on info batch
;<4.EXEC>EXECQU.MAC.90, 19-Jan-79 15:59:25, EDIT BY OSMAN
;ALLOW /DELETE ON SUBMIT COMMAND
;<4.EXEC>EXECQU.MAC.59, 17-Jan-79 13:52:57, EDIT BY OSMAN
;tco 4.2167 - Keep duplications out of default tables
;<4.EXEC>EXECQU.MAC.56, 17-Jan-79 09:52:06, EDIT BY OSMAN
;/NOTIFY:YES or NO, /GENERIC
;<4.EXEC>EXECQU.MAC.55, 15-Jan-79 17:45:54, EDIT BY HURLEY.CALVIN
; Fix bug in CANRET causing "JSYS ERROR - File still mapped" error
;<4.EXEC>EXECQU.MAC.50, 13-Jan-79 14:50:37, EDIT BY OSMAN
;PUT IN /ACCOUNT
;<4.EXEC>EXECQU.MAC.49, 13-Jan-79 14:27:42, EDIT BY OSMAN
;PUT IN /READER
;<4.EXEC>EXECQU.MAC.48, 13-Jan-79 13:52:42, EDIT BY OSMAN
;CHANGE /WRITE-LOG TO /BATCH-LOG
;<4.EXEC>EXECQU.MAC.47, 12-Jan-79 09:23:35, EDIT BY ACARLSON
;CHANGE SPOOLED CARDS FIELD NAME FROM 'NCRDS' TO 'SCDP'
;<4.EXEC>EXECQU.MAC.46, 11-Jan-79 18:38:38, EDIT BY ACARLSON
;FIX /MODIFY BUG SO THAT /DEST:NODE IS A MAJOR MODIFICATION
;<4.EXEC>EXECQU.MAC.45, 10-Jan-79 21:50:37, EDIT BY HURLEY.CALVIN
; Fixup file handling in CANRET
;<4.EXEC>EXECQU.MAC.44, 10-Jan-79 18:30:56, EDIT BY HURLEY.CALVIN
; Allow QSRMAC to define .OTRET and LIQRET
; Add X%RE and LIQRET to the PRLSTQ routine
;<4.EXEC>EXECQU.MAC.37, 20-Dec-78 14:57:48, EDIT BY HURLEY.CALVIN
; Replace CANRET routine with release 4 QUASAR code
;<4.EXEC>EXECQU.MAC.36, 18-Dec-78 10:58:26, EDIT BY OSMAN
;put it in alphabetical order!
;add /LOGDISPOSITION
;<4.EXEC>EXECQU.MAC.30,  8-Dec-78 11:50:25, EDIT BY OSMAN
;PUT IN /ASSISTANCE:, /WRITE-LOG, /NOTIFY
;TCO 4.2111 - MAKE /TIME: ALLOW MORE THAN 24 HOURS
;<4.EXEC>EXECQU.MAC.28, 30-Oct-78 14:43:04, EDIT BY OSMAN
;FIX CANCEL
;<4.EXEC>EXECQU.MAC.27, 26-Oct-78 16:31:38, EDIT BY OSMAN
;MAKE /ALL SET LS.ALL
;<4-ARC-DEC>EXECQU.MAC.1, 23-Oct-78 16:13:46, EDIT BY CALVIN
; Install commands for archive system
;<4.EXEC>EXECQU.MAC.23, 16-Oct-78 16:25:55, EDIT BY OSMAN
;DON'T ALLOW /SPOOLED-OUTPUT ON NON-APPLICABLE FLAVORS OF CANCEL
;<4.EXEC>EXECQU.MAC.22, 13-Oct-78 11:16:01, EDIT BY OSMAN
;ADD CANCEL MOUNT
;<4.EXEC>EXECQU.MAC.21, 13-Oct-78 10:54:16, EDIT BY OSMAN
;ADD INFO MOUNT-REQUESTS
;<4.EXEC>EXECQU.MAC.11, 25-Sep-78 10:48:00, EDIT BY OSMAN
;REMOVE REFS TO OQCF
;FIX MODIFY /LIMIT
;TCO 4.2015 - PRINT BETTER ERROR ON "PRINT TTY:"
;<4.EXEC>EXECQU.MAC.9, 14-Sep-78 14:34:59, EDIT BY OSMAN
;USE LOAD AND STOR INSTEAD OF QLOAD AND QSTOR
;<4.EXEC>EXECQU.MAC.8, 14-Sep-78 14:12:55, EDIT BY OSMAN
;ONLY SEARCH XDEF, TTITLE DOES REST
;<4.EXEC>EXECQU.MAC.6, 14-Sep-78 11:14:50, EDIT BY OSMAN
;MOVE QUASND, UNMAP, PRITXT OUT OF HERE AND INTO EXECSU
;<4.EXEC>EXECQU.MAC.5, 13-Sep-78 11:27:17, EDIT BY OSMAN
;FIX MODIFY PRINT /UNIT:
;ALLOW * AND % IN JOBNAME ON MODIFY AND CANCEL
;<4.EXEC>NEW.MAC.20, 29-Aug-78 11:42:01, EDIT BY OSMAN
;TCO 1995 - ALLOW LEAVING OUT JOBNAME IN CANCEL AND MODIFY.
;PUT IN /SPOOLED-OUTPUT
;MAKE A MODULE THAT'S ONLY FOR LATEST QUASAR (GET RID OF CONDITIONALS)
;<4.EXEC>EXECQU.MAC.83, 22-Aug-78 11:54:55, EDIT BY OSMAN
;FIX "SET DEFAULT" (LOCAL STORAGE WASN'T BEING INITIALIZED)
;<4.EXEC>EXECQU.MAC.80, 11-Aug-78 13:42:38, EDIT BY OSMAN
;ALLOW /UNIQUE:YES AND /UNIQUE:NO
;FIX /LIMIT
;<4.EXEC>EXECQU.MAC.76,  3-Aug-78 17:21:04, EDIT BY OSMAN
;<4.EXEC>EXECQU.MAC.75,  3-Aug-78 17:09:04, EDIT BY OSMAN
;ADD DEFERRED OUTPUT STUFF
;<4.EXEC>EXECQU.MAC.74,  3-Aug-78 16:26:11, EDIT BY OSMAN
;ADD "S" TO /PAGES
;<4.EXEC>EXECQU.MAC.73,  1-Aug-78 08:47:54, EDIT BY OSMAN
;FIX /RESTARTABLE (ONLY BROKEN IN R4)
;<4.EXEC>EXECQU.MAC.72, 26-Jul-78 15:55:08, EDIT BY OSMAN
;MAKE "SET DEF PRINT /PRESERVE" WORK
;<4.EXEC>EXECQU.MAC.70, 19-Jul-78 15:58:39, EDIT BY OSMAN
;use movem instead of qstor to set up fsize
;<4.EXEC>EXECQU.MAC.68, 11-Jul-78 13:02:35, EDIT BY OSMAN
;MAKE PRIJFN BE LOCAL, QUSR,FSIZE,QPT,QSTK
;<4.EXEC>EXECQU.MAC.66, 29-Jun-78 15:43:16, EDIT BY OSMAN
;make crejob be local
;<4.EXEC>EXECQU.MAC.64, 29-Jun-78 14:26:06, EDIT BY OSMAN
;ADD /PROCESSING-NODE
;<4.EXEC>EXECQU.MAC.63, 23-Jun-78 21:13:54, EDIT BY OSMAN
;REMOVE BAKLOG, REQ1, .CORE (UNREFERENCED SYMBOLS)
;ADD /UNIT:
;<4.EXEC>EXECQU.MAC.49, 16-Jun-78 10:07:39, EDIT BY OSMAN
;MAKE HELP ON /NOTE: NOT HAVE TRAILING "OR" (FIX /REPORT: TOO)
;<4.EXEC>EXECQU.MAC.40, 15-Jun-78 15:45:44, EDIT BY OSMAN
;ADD INFO DEFAULTS SUBMIT, PAPER-TAPE, PUNCH, PRINT, CARDS
;<4.EXEC>EXECQU.MAC.37,  9-Jun-78 18:07:39, EDIT BY OSMAN
;CHANGE CALLS TO FIELD TO FLDSKP
;<4.EXEC>EXECQU.MAC.35,  8-Jun-78 14:32:01, EDIT BY OSMAN
;CHANGE IBINARY TO IMAGE-BINARY
;CHANGE TPUNCH/CPUNCH TO PUNCH PAPER-TAPE/CARDS
;CHANGE /NODE TO /DESTINATION-NODE
;CHANGE /TAPE AND /PUNCH TO /MODE
;<4.EXEC>EXECQU.MAC.30,  2-Jun-78 14:57:37, EDIT BY OSMAN
;MAKE SOME GENERAL CHANGES TO QUASAR PARAMETER BLOCK FORMATS
;ADD /NODE:
;<4.EXEC>EXECQU.MAC.28,  1-Jun-78 13:48:25, EDIT BY OSMAN
;CHANGE CHOICES FOR CANCEL AND MODIFY TO HAVE CPUNCH, TPUNCH
;<4.EXEC>EXECQU.MAC.25, 31-May-78 16:44:06, EDIT BY OSMAN
;ADD SET DEFAULT CPUNCH AND SET DEFAULT TPUNCH
;<4.EXEC>EXECQU.MAC.22, 31-May-78 15:01:45, EDIT BY OSMAN
;IF GTFDB FAILS, USE CJERR INSTEAD OF JERR (GTFDB DOESN'T PUT ERROR CODE IN
;   AC1!) 
;<4.EXEC>EXECQU.MAC.7, 30-May-78 16:52:33, EDIT BY OSMAN
;ADD CPUNCH, TPUNCH
;<4.EXEC>EXECQU.MAC.2, 26-May-78 15:07:50, EDIT BY OSMAN
;TOPS20 'EXECUTIVE' COMMAND LANGUAGE

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

	SEARCH EXECDE
	TTITLE EXECQU
	GLXSCH			;SEARCH GALAXY UNV'S

;THIS FILE CONTAINS CODE TO IMPLEMENT COMMANDS WHICH COMMUNICATE WITH QUASAR,
;   THE QUEUE SYSTEM: PUNCH CARDS, PRINT, SUBMIT, PUNCH PAPER-TAPE, INFORMATION

;CAUTION: DON'T CHANGE THE ORDER OF THE FOLLOWING DEFINITIONS OF X%...
;   THEY ARE LOADED INTO P4 AND A TABLE IS INDEXED BY P4. GET IT?

;MACRO TO DEFINE X%... AND B%...
DEFINE DEFSM (NAME,VALUE)
   <	X%'NAME==VALUE
	B%'NAME==1B<VALUE>>
				;COMMANDS:
	DEFSM CP,0		;PUNCH CARDS
	DEFSM PR,1		;PRINT
	DEFSM SU,2		;SUBMIT
	DEFSM TP,3		;PUNCH PAPER-TAPE
	DEFSM PL,4		;PLOT
	DEFSM MO,5		;MOUNT (USED FOR INFO MOUNT)
	DEFSM RE,6		;RETRIEVE
	DEFSM AR,7		;ARCHIVE (NOT REALLY USED)

	PR%LC==1		;SYMBOL FOR /LOWERCASE
	PR%UC==2		;SYMBOL FOR /UPPERCASE
	PR%ANY==3		;/GENERIC

;MACRO FOR PRINTING SWITCH VALUES.
DEFINE PSWITCH (TEXT)
   <	ETYPE < /TEXT>
	RET>

;MACRO TO ALLOCATE LOCAL STORAGE. NEEDED SO VARIOUS COMMANDS CAN CALL COMMON
;   ROUTINES WHICH REFERENCE THE STORAGE  
	FDBSIZ==.CMDEF		;SIZE OF COMND FDB
	ISIZ==3			;SIZE OF ITEM ON ARG STACK (NUMBER OF WORDS)

DEFINE PRISTG
   <	TRVAR <JNGF,ANYS,SDF,ASYF,<FDBBLK,FDBSIZ>,<SCRLIM,EQLMSZ>,IQPT,QPT,
QIDX,FSIZE,NEWJFN,PRIJFN,SAVEA,PRESF,FILSF,CSF>>

;MACRO TO STORE VALUE IN A FIELD, AND THEN READ IT BACK TO MAKE SURE IT FITS,
;   AND SKIPS IFF SO. THIS MACRO CLOBBERS "D"
DEFINE VERIFY(A,B,C)
   <	STOR A,C,B	;;STORE THE VALUE
	LOAD D,C,B	;;GET WHAT REALLY GOT STORED
	CAME A,D>	;MAKE SURE IT GOT SUCCESSFULLY STORED

;SIMILAR MACRO TO VERIFY LIMITS
DEFINE VERLIM(A,B,C)
   <	STOLIM A,B,C
	GETLIM D,B,C
	CAME A,D>

;   ACS:	Z/	FLAGS:
	INFOF==1B0		;ON IF DOING INFO
	TPRES==1B2		;ON IF /PRESERVE OR /DELETE GIVEN ON CURRENT
				;   SPEC 
	NPRES==1B3		;ON IF /PRESERVE OR /DELETE GIVEN ON NEXT SPEC
	TFILES==1B4		;ON IF /FILE GIVEN ON CURRENT SPEC
	NFILES==1B5		;ON IF /FILE GIVEN ON NEXT SPEC
;		Q1/	FILE PARAMETER BLOCK ADDRESS (LOCAL FILE OR GLOBAL
;			    BLOCK) 
;		P1/	REQUEST HEADER ADDRESS (GLOBAL OR LOCAL IF SUBMIT
;			    COMMAND) 
;		P2/	FILE PARAMETER ADDRESS

;SPECIAL BUFFER DEFINITIONS
	EQ0==BUF1		;HOLDS QUASAR REQUEST BLOCK
	EQGLOB==BUF2		;GLOBAL VALUES FOR REQUEST BLOCK DURING SUBMIT
	GLBBLK==EQGLOB+EQHSIZ	;PRINT COMMAND GLOBAL BLOCK
	FILMAX==FDXSIZ-1	;MAXIMUM NUMBER OF WORDS FILESPEC MAY TAKE UP
				;   ALLOWS FOR MANY ^V'S, AND OBNOXIOUSLY LONG 
				;   NAMES
	LSTBLK==BUF3		;HOLDS VALUES DURING EXPANSION OF WILDCARDS
	LOGNAM==EQHSIZ+FPXSIZ+1+FILMAX+FPXSIZ+1	;OFFSET INTO PAGE TO WHERE LOG
				;   FILE NAME GOES 
	LOGFIL==EQHSIZ+FPXSIZ+1+FILMAX	;OFFSET FOR LOG FILE BLOCK

;INSTRUCTION FOR OBTAINING OBJECT TYPE
GOTYP:	MOVE A,[.OTCDP
		.OTLPT
		.OTBAT
		.OTPTP
		.OTPLT](P4)	;GET REQUEST TYPE

;FDB'S FOR COMND JSYS FOR READING COMMAND LINES
;NOTICE THAT IN GENERAL ONE MAY NOT SPECIFY A FILE SPECIFIC SWITCH AFTER A
;   COMMA (HENCE THE ADDITIONAL TABLES AND WORK), SINCE THERE IS NO EASY WAY TO
;   GET SUCH SWITCHES TO APPLY TO THE FILE SPECS WHICH FOLLOW THE SWITCH. IT IS
;   VERY HARD TO IMPLEMENT THE SEMI-GLOBAL SWITCH CONCEPT, SO TO AVOID
;   CONFUSION, WE SIMPLY FORBID THE PLACEMENT OF A FILE-SPECIFIC SWITCH
;   DIRECTLY AFTER A COMMA.

;COMMA OR FILE SPEC FDB...
CORFIL:	FLDDB. .CMCMA,,,,,FLONLY			;COMMA IS OPTIONAL
FLONLY:	FLDDB. .CMFIL,CM%SDH,,<a file specification>	;FILESPEC

;FDB'S FOR COMND JSYS FOR READING COMMAND LINES

;PRINT...
PRFDB:	FLDDB. .CMCFM,,,,,[				;END OF LINE
	FLDDB. .CMSWI,,$JOBSW,<a job switch,>,,[	;JOB SWITCH
	FLDDB. .CMSWI,,$FILSW,<a file switch,>,,CORFIL	;FILE SWITCH
	]]						;COMMA OR FILE 

;PRINT AFTER A COMMA SEEN...
PRFDBC:	FLDDB. .CMSWI,,$JOBSC,<a job switch,>,,FLONLY	;JOB SWITCH 
							;FILE SPEC AFTER COMMA

;SUBMIT...
SUFDB:	FLDDB. .CMCFM,,,,,[				;END OF LINE
	FLDDB. .CMSWI,,$SUBSW,<a switch,>,,CORFIL	;SWITCH
	]						;COMMA OR FILE

;SUBMIT AFTER COMMA SEEN...
SUFDBC:	FLDDB. .CMSWI,,$SUBSC,<a switch,>,,FLONLY	;ONLY SWITCH
							;FILE SPEC AFTER COMMA

;PUNCH CARDS...
CPFDB:	FLDDB. .CMCFM,,,,,[				;END OF LINE
	FLDDB. .CMSWI,,$CPJOB,<a job switch,>,,[	;JOB SWITCH
	FLDDB. .CMSWI,,$CPFIL,<a file switch,>,,CORFIL	;FILE SWITCH
	]]						;COMMA OR FILE TOO

;PUNCH CARDS AFTER COMMA SEEN...
CPFDBC:	FLDDB. .CMSWI,,$CPJOC,<a job switch,>,,FLONLY	;ONLY JOB SWITCH
							;FILE SPEC AFTER COMMA

;PLOT
PLFDB:	FLDDB. .CMCFM,,,,,[				;END OF LINE
	FLDDB. .CMSWI,,$PLJOB,<a job switch,>,,[	;JOB SWITCH
	FLDDB. .CMSWI,,$PLFIL,<a file switch,>,,CORFIL	;FILE SWITCH
	]]						;COMMA OR FILE TOO

;PLOT AFTER COMMA SEEN...
PLFDBC:	FLDDB. .CMSWI,,$PLJOC,<a job switch,>,,FLONLY	;ONLY JOB SWITCH
							;FILE SPEC AFTER COMMA

;PUNCH PAPER-TAPE...
TPFDB:	FLDDB. .CMCFM,,,,,[				;END OF LINE
	FLDDB. .CMSWI,,$TPJOB,<a job switch,>,,[	;JOB SWITCH
	FLDDB. .CMSWI,,$TPFIL,<a file switch,>,,CORFIL	;FILE SWITCH
	]]						;COMMA OR FILE TOO

;PUNCH PAPER-TAPE AFTER COMMA SEEN...
TPFDBC:	FLDDB. .CMSWI,,$TPJOC,<a job switch,>,,FLONLY	;ONLY JOB SWITCH
							;FILE SPEC AFTER COMMA

;COMND JSYS FDB'S FOR SET DEFAULT COMMANDS FOR QUEUE-CLASS COMMANDS,

;PUNCH CARD DEFAULTS
SDCFDB:	FLDDB. .CMCFM,,,,,[				;END OF LINE
	FLDDB. .CMSWI,,$CPJOB,<a job switch,>,,[	;JOB SWITCH
	FLDDB. .CMSWI,,$CPFIL,<a file switch,>]]	;FILE SWITCH

;PRINT DEFAULTS
SDPFDB:	FLDDB. .CMCFM,,,,,[				;END OF LINE
	FLDDB. .CMSWI,,$JOBSW,<a job switch,>,,[	;JOB SWITCH
	FLDDB. .CMSWI,,$FILSW,<a file switch,>]]	;FILE SWITCH

;SUBMIT DEFAULTS
SDSFDB:	FLDDB. .CMCFM,,,,,[				;END OF LINE
	FLDDB. .CMSWI,,$SUBSW,<a switch,>]		;SWITCH

;PUNCH PAPER-TAPE DEFAULTS
SDTFDB:	FLDDB. .CMCFM,,,,,[				;END OF LINE
	FLDDB. .CMSWI,,$TPJOB,<a job switch,>,,[	;JOB SWITCH
	FLDDB. .CMSWI,,$TPFIL,<a file switch,>]]	;FILE SWITCH

;PLOT DEFAULTS
SDPLFB:	FLDDB. .CMCFM,,,,,[				;END OF LINE
	FLDDB. .CMSWI,,$PLJOB,<a job switch,>,,[	;JOB SWITCH
	FLDDB. .CMSWI,,$PLFIL,<a file switch,>]]	;FILE SWITCH
;PRINT (FILE) /SW/SW FILE /SW/SW/SW FILE FILE,FILE ....
;SUBMIT "	"	"
;   SWITCHES MAY APPEAR ANYWHERE ON THE LINE. THERE ARE TWO TYPES OF SWITCHES,
;   FILE SWITCHES AND JOB SWITCHES. FILE SWITCHES APPEARING BEFORE ANY FILE HAS
;   BEEN ENTERED APPLY TO ALL FILES IN THE COMMAND. THAT IS, THEY ARE GLOBAL
;   FILE SWITCHES. ANY FILE SWITCH ENTERED SUBSEQUENT TO SOME FILESPEC ONLY
;   APPLIES TO THE MOST RECENT FILE SPEC BEFORE IT ON THE LINE. JOB SWITCHES
;   MEAN THE SAME ANYWHERE ON THE LINE. FOR SUBMIT COMMAND, ALL SWITCHES ARE
;   "FILE" SWITCHES. 

.SUBMI::NOISE <batch job>
	MOVX P4,X%SU		;1 FOR SUBMIT, 0 FOR PRINT
	JRST X2

;QUEUE UP FILES FOR PLOTTER

.PLOT::	MOVX P4,X%PL		;SAY THIS IS "PLOT"
	JRST X1			;FINISH LIKE THE REST OF 'EM

;PUNCH CARDS/PAPER-TAPE

.PUNCH::NOISE <onto>
	KEYWD $PDEV
	 0
	 CMERRX <Invalid selection for PUNCH>
	MOVE P4,P3		;GET TYPE OF THING BEING PUNCHED
	JRST X1

;TABLE OF SELECTIONS FOR PUNCH
$PDEV:	TABLE
	T cards,,X%CP
	T paper-tape,,X%TP
	TEND

.PRINT::MOVEI P4,X%PR
X1:	NOISE <files>
X2:	PRISTG			;ALLOCATE LOCAL STORAGE
	SETZM CSF		;NO COMMA SEEN YET
	SETZM PRESF		;NO /PRESERVE OR /DELETE SEEN YET
	SETZM FILSF		;NO /FILE:<ANY> SEEN YET
	SETZM SDF		;NOT SETTING DEFAULTS
	SETZM ASYF		;SAY NOTHING SEEN YET
	TLZ Z,F1		;FILE FLAG, COMES ON IF WE'VE SEEN A FILESPEC
	CALL PRINI		;INITIALIZE BLOCKS
PR1:	DEXTX <CTL>		;DEFAULT EXTENSION FOR BATCH FILES
	CAIE P4,X%SU		;DON'T SET THIS DEFAULT UNLESS "SUBMIT"
	 DEXTX <>		;NO DEFAULT EXTENSION FOR PRINT REQUESTS
	MOVX A,GJ%OLD!GJ%IFG!GJ%FLG ;ALLOW *'S AND RETURN FLAGS,FILE MUST EXIST
	MOVEM A,CJFNBK+.GJGEN	;STORE FLAGS
	MOVE B,[CPFDB
		PRFDB
		SUFDB
		TPFDB
		PLFDB](P4)	;CORRECT FDB FOR PARTICUAR COMMAND
	SKIPE CSF		;JUST SEEN A COMMA?
	MOVE B,[CPFDBC		;YES, TREAT SPECIAL
		PRFDBC
		SUFDBC
		TPFDBC
		PLFDBC](P4)	;CORRECT FDB TO FOLLOW COMMA
	TLNN Z,F1		;HAVE WE SEEN A FILESPEC YET?
	 SKIPE CSF		;AND NOT JUST SEEN A COMMA?
	  ABSKP
	   HRRZ B,(B)		;YES, SO CONFIRMATION INVALID HERE
	CAIE P4,X%SU		;NO SPOOLED-OUTPUT FOR SUBMIT
	 SKIPE ASYF		;ANYTHING SEEN YET?
	  JRST YESSS		;YES, SOMETHING SEEN
	HRLI A,[FLDDB. .CMSWI,CM%SDH,[1,,1
		T spooled-output,,.RSO],</spooled-output>]
	HRRI A,FDBBLK		;PREPARE TO SET UP EXTENDED FDB
	BLT A,.CMHLP+FDBBLK	;SET IT UP
	STOR B,CM%LST,FDBBLK	;STORE REST OF FDB'S AS REST OF CHAIN
	MOVEI B,FDBBLK		;SET UP B AS POINTER TO EXTENDED FDB
YESSS:	CALL FLDSKP		;SEE WHAT THE USER TYPED
	 JRST BADQ		;BAD COMMAND
	SETOM ASYF		;SAY SOMETHING SEEN
	GTFLDT D		;FIND OUT WHAT GOT TYPED
	CAIN D,.CMCMA		;COMMA?
	 JRST  [SETOM CSF	;SAY COMMA SEEN
		JRST PR1]	;AND PROCEED
	CAIN D,.CMCFM		;END OF LINE?
	 JRST PRIEOL		;YES
	CAIN D,.CMFIL		;A FILE?
	 JRST PRIFIL		;YES
	JRST PRIFS		;NONE OF THE ABOVE, MUST BE A SWITCH

BADQ:	XCT    [CMERRX <Invalid PUNCH CARDS command>
		CMERRX <Invalid PRINT command>
		CMERRX <Invalid SUBMIT command>
		CMERRX <Invalid PUNCH PAPER-TAPE command>
		CMERRX <Invalid PLOT command>](P4)

;A FILE SWITCH HAS BEEN TYPED. IF NO FILENAMES HAVE BEEN TYPED, THIS SWITCH
;   SHOULD BE CONSIDERED GLOBAL. OTHERWISE, THIS SWITCH ONLY APPLIES TO THE
;   LAST FILE SEEN. 
PRIFS:	CALL GETKEY		;GET SWITCH INFO
	CAIN P3,.RSO		;RELEASING SPOOLED-OUTPUT?
	 JRST .RSO		;YES, GO DO IT
	CALL (P3)		;NO, EXECUTE THE SWITCH
	JRST PR1		;GO BACK FOR MORE FIELDS

;FILESPEC SEEN.
PRIFIL:	SETZM CSF		;CLEAR THE COMMA SEEN FLAG AFTER FILE SEEN
	MOVE A,B
	TLON Z,F1		;IS THIS THE FIRST FILE?
	 SKIPN D,DPPT		;AND ARE THERE ANY DEFAULTS TO SCAN?
	  JRST NOTFST		;NO, NOT THE FIRST OR NO DEFAULTS
	MOVE D,[IOWD QSLEN,DPSTK-ISIZ+1] ;YES, PROCESS GLOBAL SWITCHES
PRIDEF:	ADJSP D,ISIZ		;STEP TO NEXT POTENTIAL DEFAULT
	CAML D,DPPT		;LAST BLOCK PROCESSED?
	 JRST NOTFST		;YES, GO LOOK AT THE FILE
	HRRZ B,(D)		;GET DISPATCH ADDRESS
	CAIN B,FIL2		;IS THIS A /FILE:<ANY> SWITCH?
	 SETOM FILSF		;YES, RAISE THE FLAG
	CAIN B,DEL2		;IS IT A /PRESERVE OR /DELETE SWITCH?
	 SETOM PRESF		;YES, RAISE THAT FLAG
	JRST PRIDEF		;PROCESS NEXT SWITCH...

NOTFST:	MOVE B,A
	MOVEI A,FIL22		;DON'T REALLY PROCESS IT UNTIL PASS 2
	MOVEM B,NEWJFN		;SAVE JFN
	CALL STOR1
	JRST PR1

FIL22:	MOVEI P1,EQ0		;WAS POINTING AT GLOBAL BLOCK IF SUBMIT COMMAND
	MOVEM B,NEWJFN		;SAVE THE NEW JFN
	SKIPE PRIJFN		;ANY PREVIOUS FILESPEC?
	 CALL FILDO		;FINISH LAST FILE
	MOVE Q1,P2		;FROM NOW ON ALL SWITCHES ARE LOCAL
	MOVE A,NEWJFN
	MOVEM A,PRIJFN		;ESTABLISH NEW JFN AS CURRENT ONE
	CAIN P4,X%SU		;DOING SUBMIT?
	 JRST SUBGLB		;YES, GO MOVE ENTIRE PAGE
	HRLI A,GLBBLK		;GET ADDRESS OF GLOBAL INFO BLOCK
	HRR A,P2		;AND ADDRESS OF NEW FILE PARAMETER BLOCK
	BLT A,FPXSIZ-1(P2)	;MOVE GLOBAL PARAMETERS INTO NEW BLOCK
	CAIE P4,X%PR		;DOING A PRINT?
	 JRST FIL0		;NOPE, SKIP EXTENSION TESTING
	MOVE A,P2		;MOVE IN ADDRESS OF AREA TO CHANGE
	CALL CHKEXT		;CHECK EXTENSION OF FILE
FIL0:	CALL FILBLK		;FILL IN INFO FOR THIS FILE
	 RET			;WAIT FOR SWITCHES BEFORE MORE PROCESSING

SUBGLB:	MOVE A,[EQGLOB,,EQ0]	;MOVE FROM GLOBAL AREA INTO LOCAL AREA
	BLT A,EQ0+777
	JRST FIL0		;REJOIN COMMON CODE

;ROUTINE TO FINISH LAST CURRENT FILESPEC. MUST BE CALLED BEFORE NEW FILSPEC CAN
;   BE PROCESSED, BUT NOT EARLIER, SINCE SWITCHES SYNTACTICALLY FOLLOW
;   FILESPECS. 
FILDO:	CAIN P4,X%SU		;SUBMIT?
	 JRST  [MOVE A,[EQ0,,LSTBLK] ;YES
		BLT A,LSTBLK+777 ;REMEMBER ENTIRE PAGE
		JRST FILDLB]	;GO FILL IN LOG FILE BLOCK
	HRLI A,(P2)
	HRRI A,LSTBLK
	BLT A,LSTBLK+FPXSIZ-1	;REMEMBER FILE PARAMETER'S IN CASE *'S
	SKIPE PRESF		;IS THERE A GLOBAL /PRESERVE OR /DELETE?
	 JRST FILDF0		;YES, SET TPRES
	TXZN Z,NPRES		;CLEAR AND CHECK NPRES
	 TXZA Z,TPRES		;NPRES WAS CLEAR, CLEAR TPRES
FILDF0:	  TXO Z,TPRES		;NPRES OR GLOBAL SW WAS SET, SET TPRES
	SKIPE FILSF		;IS THERE A GLOBAL /FILE?
	 JRST FILDF1		;YES, SET TFILES
	TXZN Z,NFILES		;CLEAR AND CHECK NFILES
	 TXZA Z,TFILES		;NFILES WAS CLEAR, CLEAR TFILES
FILDF1:	  TXO Z,TFILES		;NFILES OR GLOBAL SW WAS SET, SET TFILES
PRF1:	CAIN P4,X%SU		;DOING SUBMIT?
	 JRST FILDLB		;YES, GO FILL IN LOG FILE BLOCK
	LOAD A,FP.FCY,.FPINF(P2) ;GET NUMBER OF COPIES WANTED FOR THIS FILE
	IMUL A,FSIZE		;MULTIPLY BY FILE SIZE TO GET REQUEST SIZE FOR
				;   THIS FILE 
	GETLIM B,.EQLIM(P1),NBLK
	ADD B,A			;ADD IN THIS FILE'S SIZE TO GRAND TOTAL
	VERLIM B,.EQLIM(P1),NBLK ;PUT BACK TOTAL MAKING SURE IT FITS
	 ERROR <Too many file pages being requested at once>
FILNJF:	CALL NEWBLK		;GET NEW PARAMETER BLOCK FOR THE NEXT FILE
	MOVE A,PRIJFN
	GNJFN			;SEE IF ANY MORE FILES ASSOCIATED WITH THIS JFN
	 RET			;ON GNJFN FAILURE, ASSUME NO MORE FILES FOR
				;   THIS JFN 
	TXNN A,GN%EXT		;DID EXTENSION CHANGE?
	 JRST FILFPR		;NO, SKIP DEFAULT EXTENSION CHECKING
	CAIE P4,X%PR		;ARE WE DOING A PRINT?
	 JRST FILFPR		;NOPE, SKIP EXTENSION CHECKING
	JXO Z,TPRES!TFILES,FILFPR ;IF BOTH FLAGS ON, SKIP CHECKING
FILCEX:	MOVE A,P2		;MOVE IN ADDRESS OF AREA TO CHANGE
	CALL CHKEXT		;CHECK EXTENSION OF FILE
	HRLI A,(P2)		;STORE FILE PARAMETERS IN LSTBLK
	HRRI A,LSTBLK
	BLT A,LSTBLK+FPXSIZ-1
FILFPR:	CALL FILBLK		;FILL IN PARAMETERS FOR THIS FILE
	JRST PRF1		;SEE IF MORE FILES ON THIS JFN

;FILL IN LOG FILE DATA
FILDLB:	CALL SUBLOG		;FILL IN LOG FILE DATA
	JRST FILNJF		;GO LOOK AT NEXT FILE (IF ANY)

SUBLOG:	STKVAR <CONDN>		;HOLDS CONNECTED DIRECTORY NUMBER
	CALL NEWBLK		;ALLOCATE FILE BLOCK FOR LOG FILE NAME
	SKIPE LOGNAM(P1)	;LOG FILE NAME ALREADY SPECIFIED?
	 JRST FILBK1		;YES
	GJINF			;GET CONNECTED DIRECTORY NUMBER
	MOVEM B,CONDN		;SAVE IT
	CALL GETFP		;GET POINTER TO WHERE FILENAME GOES
	MOVE B,CONDN		;GET CONNECTED DIRECTORY
	DIRST			;LOG FILE GOES IN THAT DIRECTORY BY DEFAULT
	 ERCAL JERR		;SHOULDN'T FAIL
	HRRZ B,PRIJFN		;USE CONTROL FILE AS SOURCE
	MOVX C,FLD(.JSAOF,JS%NAM)!JS%PAF ;GET NAME
	JFNS			;GET STRING FOR BEGINNING OF NAME
	HRROI B,[ASCIZ/.LOG/]	;STANDARD EXTENSION IS .LOG
	SETZ C,			;PUT NULL AFTER IT
	SOUT			;FINISH MAKING FILESPEC
	JRST FILBK1		;JOIN COMMON CODE TO FINISH FILEBLOCK

;ROUTINE WHICH FILES IN PARAMETERS FOR FILE ASSOCIATED WITH JFN IN PRIJFN
FILBLK:	CALL GETFP		;GET POINTER TO WHERE STRING GOES
	MOVX C,FLD(.JSAOF,JS%DEV)!FLD(.JSAOF,JS%DIR)!FLD(.JSAOF,JS%NAM)!
FLD(.JSAOF,JS%TYP)!FLD(.JSAOF,JS%GEN)!JS%PAF ;WE WANT COMPLETE FILESPEC,
				;   PUNCTUATED 
	HRRZ B,PRIJFN		;GET JFN
	JFNS			;STORE THE NAME
FILBK1:	SUBI A,FPXSIZ+.FDFIL-2(P2);CALCULATE NUMBER OF WORDS USED FOR FILESPEC
	ADDI A,1		;LEAVE ROOM FOR ONE LENGTH WORD
	CAIN P4,X%SU
	 MOVX A,FILMAX+1	;FOR SUBMIT, FILESPEC AREA IS FIXED LENGTH
	STOR A,FD.LEN,FPXSIZ+.FDLEN(P2)	;REMEMBER LENGTH OF FILENAME
	ADDI A,FPXSIZ		;GET TOTAL SIZE FOR THIS FILE
	LOAD B,MS.CNT,.MSTYP(P1) ;GET OLD MESSAGE LENGTH
	ADD B,A			;GET INCREASED LENGTH DUE TO NEW FILE
	STOR B,MS.CNT,.MSTYP(P1) ;STORE NEW LENGTH
	LOAD A,EQ.NUM,.EQSPC(P1) ;GET NUMBER OF FILES IN REQUEST
	ADDI A,1		;COUNT THE NEW FILE
	STOR A,EQ.NUM,.EQSPC(P1) ;STORE NEW FILE COUNT
	CAIN P4,X%SU		;SUBMIT COMMAND?
	 JRST NOFDB		;YES, DON'T GET SIZE OF FILE
	HRRZ A,PRIJFN		;GET THE JFN AGAIN
	MOVE B,[1,,.FBBYV]	;FILE SIZE IN PAGES
	MOVEI C,C		;FILE SIZE IN PAGES
	GTFDB			;READ THE FILE INFO
	 ERCAL [HRRZ A,PRIJFN
		ETYPE <%%Can't get file size for %1s - %?%%_>
		SETZ C,		;USE 0 SIZE
		RET]
	HRRZM C,FSIZE		;STORE PAGE COUNT
NOFDB:	RET

;ROUTINE TO RETURN POINTER TO FILENAME STRINGS IN QUASAR REQUEST BLOCK
;
;   RETURNS:	A/	POINTER 
GETFP:	HRROI A,FPXSIZ+.FDFIL(P2) ;GET ADDRESS OF WHERE NAME IS TO BE STORED
	RET

;ROUTINE TO RETURN POINTER TO A NEW FILE PARAMETER BLOCK
;   IF THIS NEW BLOCK IS TOO CLOSE TO THE END OF A PAGE, THE CURRENT PAGE IS
;   SENT OFF TO QUASAR, AND A NEW ONE STARTED. 
;
;   RETURNS:	P2/	POINTER
NEWBLK:	LOAD A,FD.LEN,FPXSIZ+.FDLEN(P2)	;GET SPACE USED FOR LAST FILESPEC
	ADDI P2,FPXSIZ(A)	;NOT FIRST FILE, LEAVE ROOM FOR PARAMETER AREA
	CAIE P4,X%SU		;SUBMIT?
	 JRST NOTSUB		;YES, ONLY SINGLE FILE CAN BE SENT AT A TIME
	LOAD A,EQ.NUM,.EQSPC(P1) ;GET NUMBER OF FILES SO FAR
	CAIN A,2		;SUBMIT COMMAND.  DO WE HAVE EXACTLY 2 FILES?
	 JRST NEW1		;YES, SO SHIP THE PAIR OFF TO QUASAR
NOTSUB:	MOVEI A,100+FPXSIZ(P2)	;GET WORST CASE LAST ADDRESS OF NEW PARAMETER
				;   BLOCK 
	CAIL A,1000(P1)		;BEYOND END OF REQUEST BLOCK?
NEW1:	 CALL SHPOFF		;YES, SO SEND THIS ONE TO MAKE MORE ROOM
	HRLI A,LSTBLK		;GET ADDRESS OF LAST FILEBLOCK
	CAIN P4,X%SU		;SUBMIT?
	 JRST NEW2		;YES, COPY ENTIRE PAGE
	HRR A,P2
	BLT A,FPXSIZ-1(P2)	;WHEN EXPANDING *'S, USE SAME PARAMETERS FOR
				;   EACH FILE 
	RET

NEW2:	LOAD B,EQ.NUM,.EQSPC(P1) ;GET NUMBER OF FILES SO FAR IN REQUEST
	CAIE B,0		;DID SUBMIT REQUEST JUST GET SENT?
	 RET			;NOT YET, SO DON'T RESET BLOCK YET
	HRRI A,EQ0
	BLT A,EQ0+777
	SETZ A,
	STOR A,EQ.NUM,.EQSPC(P1) ;CLEAR NUMBER OF FILES
	MOVX A,EQHSIZ		;LENGTH OF MESSAGE IS EQHSIZ
	STOR A,MS.CNT,(P1)	;GETS INCREMENTED AS WE ADD FILESPECS TO
				;   REQUEST 
	RET

SHPOFF:	LOAD A,EQ.NUM,.EQSPC(P1) ;GET NUMBER OF FILES IN REQUEST
	JUMPE A,R		;DON'T SEND BLOCK IF NO FILES IN REQUEST
	MOVE A,[EQ0,,IPCFP]	;MOVE REQUEST BLOCK
	BLT A,IPCFP+777		;INTO PAGE FOR IPCF SEND
	CALL QUASND		;SEND TO QUASAR AND PRINT RESPONSE
	MOVEI P2,EQHSIZ(P1)	;RESET FILE PARAMETER POINTER
	SETZ A,
	STOLIM A,.EQLIM(P1),NBLK ;RESET PAGE COUNTER
	STOR A,EQ.NUM,.EQSPC(P1) ;CLEAR NUMBER OF FILES
	MOVX A,EQHSIZ		;LENGTH OF MESSAGE IS EQHSIZ
	STOR A,MS.CNT,(P1)	;GETS INCREMENTED AS WE ADD FILESPECS TO
				;   REQUEST 
	RET

;ROUTINE TO SET DEFAULT SWITCHES FOR FILES WITH CERTAIN EXTENSIONS (.LST, .DAT)
CHKEXT: STKVAR <CNGEAR>
	MOVEM A,CNGEAR		;STORE AREA TO CHANGE
	HRRZ B,PRIJFN		;GET JFN
	MOVX C,FLD(.JSAOF,JS%TYP) ;WE WANT THE EXTENSION
	MOVE A,CSBUFP		;WRITE IT INTO FREE SPACE
	JFNS			;GET EXTENSION
	TXNN Z,TPRES		;IS /PRESERVE IN EFFECT?
	 SKIPE PRESF
	  JRST TRYDAT		;YES, SKIP CHECK (A IS NON-0)
	MOVE A,CSBUFP		;
	HRROI B,[ASCIZ/LST/]	;SEE IF EXTENSION IS "LST"
	STCMP
	MOVE B,CNGEAR		;IF IT IS, STORE "DELETE", ELSE STORE
	CAIE A,0		;"PRESERVE"
	 TDZA C,C
	  MOVX C,1
	STOR C,FP.DEL,.FPINF(B)	;STORE NEW DEFAULT
TRYDAT:	TXNN Z,TFILES		;IS /FILE SWITCH IN EFFECT?
	 SKIPE FILSF
	  RET			;YES, LEAVE
	JUMPE A,LSTSEN		;IF WE SAW "LST", IT'S NOT "DAT"
	MOVE A,CSBUFP		;GET EXTENSION AGAIN
	HRROI B,[ASCIZ/DAT/]	;SEE IF EXTENSION IS "DAT"
	STCMP
	MOVE B,CNGEAR
	JUMPE A,FORSEN		;FILE IS FORTRAN IF "DAT" SEEN
LSTSEN:	TDZA C,C		;FILE IS ASCII IF "LST" SEEN OR "DAT" NOT SEEN
FORSEN:	 MOVX C,.FPFFO		;SPECIFY FORTRAN FILE
	STOR C,FP.FFF,.FPINF(B)	;STORE INFORMATION AWAY
	RET			;GO BACK

;END OF LINE SEEN. SHIP THE BLOCK OFF TO QUASAR, GET MESSAGE BACK, TYPE IT,
;   CLEAN UP, AND RETURN. 
PRIEOL:	TXZ Z,INFOF		;SAY NOT DOING INFO
	CALL GROVEL		;PROCESS ALL THE ARGUMENTS
	CALL FILDO		;FINISH LAST FILESPEC
	CALL SHPOFF		;SHIP OFF THE LAST BLOCK
	CALLRET UNMAP		;CLEAN UP AND RETURN

;THIS ROUTINE GETS EXECUTED AFTER END OF LINE SEEN TO DO THE ACTUAL EXECUTING
;   OF THE QUEUE-CLASS COMMAND. THE REASON WE CAN'T EXECUTE AS WE GO ALONG IS
;   THAT IF THINGS LIKE *.* ARE TYPED, THEY MAY TAKE MORE THAN ONE IPCF MESSAGE
;   TO HANDLE ALL OF THEM, BUT SENDING THE IPCF MESSAGES OFF IMMEDIATELY WOULD
;   CAUSE THE USER'S COMMAND TO START EXECUTING BEFORE HE TYPES CONFIRMATION,
;   SO THAT HE MAY TYPE ^C OR ^U, EXPECTING TO CANCEL THE COMMAND, AND SOME
;   FILES MAY HAVE ALREADY BEEN SUBMITTED!
GROVEL:	STKVAR <CURPTR>		;HOLDS END OF ARG LIST
	MOVE A,QPT		;GET POINTER TO END OF ARG LIST
	MOVEM A,CURPTR		;REMEMBER WHERE IT ENDS
	TLZ Z,F1		;NO FILESPEC SEEN YET
	MOVEI Q1,GLBBLK		;SWITCHES GLOBAL UNTIL FILESPEC SEEN
	CAIN P4,X%SU
	 MOVEI P1,EQGLOB	;FOR SUBMIT, P1 FIRST POINTS TO GLOBAL PAGE
	MOVX A,1		;7 default to /NOTIFY:YES
	STOR A,EQ.NOT,.EQSEQ(P1) ;7
	CALL GRVDEF		;GROVEL THROUGH THE DEFAULTS
	MOVE A,CURPTR
	MOVEM A,QPT		;SET END OF CURRENT ARGS
	MOVE Q2,IQPT		;GET POINTER TO TOP OF LIST
	CALLRET GROVEX		;GROVEL THROUGH REAL ARGS

;ROUTINE TO GROVEL THROUGH THE DEFAULTS
GRVDEF:	MOVE Q2,[IOWD QSLEN,DCSTK
		 IOWD QSLEN,DPSTK
		 IOWD QSLEN,DSSTK
		 IOWD QSLEN,DTSTK
		 IOWD QSLEN,DPLSTK](P4)	;GET CORRECT DEFAULT POINTER
	MOVE A,@[DCPT
		 DPPT
		 DSPT
		 DTPT
		 DPLPT](P4)	;GET POINTER TO END OF LIST
	MOVEM A,QPT		;REMEMBER WHERE END OF DEFAULT LIST IS
	JUMPE A,R		;RETURN IF THERE ARE NO DEFAULTS
				;   ELSE FALL INTO GROVEX

GROVEX:	ADJSP Q2,1-ISIZ		;SO FIRST INCREMENT GETS TO BEGINNING
GRV1:	ADJSP Q2,ISIZ		;POINT TO NEXT ENTRY
	CAML Q2,QPT		;STILL IN THE STACK ?
	 RET			;NOPE-GO AWAY
	DMOVE A,(Q2)		;ADDRESSES IN A, DATA IN B
	MOVE C,2(Q2)		;SECOND WORD OF DATA IN C
	TXNE Z,INFOF		;DOING INFO?
	 MOVSS A		;YES, GET INFO ADDRESS
	HRRZ A,A		;KEEP ONLY ADDRESS PART
	CALL (A)		;PROCESS THE DATA
	JRST GRV1		;TRY AGAIN

;ROUTINE TO STORE PARSED DATA ON ARG STACK
STOR1:	STKVAR <DA,<DDATA,2>,DPTR>
	MOVEM A,DA		;SAVE DISPATCH ADDRESSES
	DMOVEM B,DDATA		;SAVE DATA
	MOVE A,IQPT		;GET POINTER TO TOP OF LIST
	SKIPN SDF		;SETTING DEFAULTS?
	 JRST STOR3		;NO, SO DUPLICATES ALLOWED (LIKE 2 FILESPECS!)
STOR2:	CAMN A,QPT		;SCANNED ENTIRE LIST?
	 JRST STOR3		;YES
	MOVE B,1(A)		;NO, GET DISPATCH ADDRESSES FOR AN ITEM ALREADY
				;   ON THE LIST 
	CAMN B,DA		;IS NEW SWITCH NEW VALUE FOR OLD SWITCH?
	 JRST STOR4		;YES, GO RELEASE OLD SPACE USED AND PUT NEW
				;   ITEM IN 
	ADJSP A,ISIZ		;NO, SCAN REST OF LIST
	JRST STOR2

STOR3:	MOVE D,QPT		;GET POINTER
	PUSH D,DA		;STORE DISPATCH ADDRESSES
	 ERCAL TMA		;TOO MANY ARGUMENTS
	PUSH D,DDATA		;STORE FIRST WORD OF DATA
	 ERCAL TMA
	PUSH D,1+DDATA		;STORE SECOND WORD OF DATA
	 ERCAL TMA
	MOVEM D,QPT		;REMEMBER NEW VALUE OF POINTER
	RET

TMA:	ERROR <Too many filespecs or switches, break into several commands>

STOR4:	MOVEM A,DPTR		;REMEMBER POINTER TO ITEM
	CALL PIOFF		;^C WOULD BE EMBARRASSING BETWEEN RELEASING OLD
				;   SPACE AND STORING NEW ITEM! 
	MOVE A,DPTR		;DON'T ASSUME PIOFF SAVES TEMPS
	MOVE B,2(A)		;GET POSSIBLE POINTER TO FREE SPACE
	HRRZ A,DA		;GET DISPATCH ADDRESS OF OLD ITEM
	CALL QRELFR		;RELEASE ANY FREE SPACE ITEM WAS TYING
	MOVE A,DPTR		;RESTORE POINTER TO ITEM
	DMOVE B,DDATA		;GET NEW DATA
	DMOVEM B,2(A)		;REPLACE OLD DATA WITH IT
	CALLRET PION		;^C IS OK NOW

;ROUTINE CALLED TO REMOVE ALL DEFAULTS FOR A COMMAND
;   IT RELEASES ANY FREE SPACE THAT MAY HAVE BEEN TIED UP REMEMBER THE
;   DEFAULTS. 
;
;   ACCEPTS:	A/	ADDRESS OF STACK BEING CLEARED
;		B/	ADDRESS OF STACK POINTER MARKING END OF STACK
REMDEF:	STKVAR <STKPW,STKP>
	SKIPN @B		;ANY STACK ESTABLISHED YET?
	 RET			;NO, NOTHING TO REMOVE!
	SUBI A,1		;MAKE BONA FIDE STACK POINTER TO START OF LIST
	HRLI A,-QSLEN
	ADJSP A,-ISIZ		;CAUSE FIRST INCREMENT TO GET TO FIRST SLOT
	MOVEM A,STKPW		;REMEMBER OUR WORKING POINTER
	MOVEM B,STKP		;REMEMBER ARGS
	CALL PIOFF		;DON'T ALLOW ^C AFTER SPACE RELEASED BUT BEFORE
				;   STACK RESET! 
REMD1:	MOVE C,STKPW		;GET OUR WORKING POINTER
	ADJSP C,ISIZ		;STEP TO NEXT SLOT TO DO (GUARANTEED NOT TO
				;   PDLOV) 
	MOVEM C,STKPW		;SAVE FOR NEXT TIME THROUGH
	CAMN C,@STKP		;HAVE WE SCANNED ENTIRE LIST YET?
	 JRST REMD2		;YES
	HRRZ A,1(C)		;NO, GET DISPATCH ADDRESS OF ITEM ON STACK
	MOVE B,2(C)		;GET CANDIDATE FOR BYTE POINTER TO SPACE TO BE
				;   REMOVED 
	CALL QRELFR		;CHECK FOR FREE SPACE FOR RETURNING
	JRST REMD1		;LOOP FOR REST OF ITEMS

REMD2:	HRRZ A,STKP		;GET ADDRESS OF STACK POINTER
	SETZM (A)		;CLEAR THE STACK POINTER
	CALLRET PION		;ALLOW ^C AGAIN

;ROUTINE USED TO FREE UP FREE SPACE THAT WAS TIED UP BY SOME DEFAULT THAT IS
;   BEING REMOVED  
;
;   ACCEPTS:	A/	DISPATCH ADDRESS IDENTIFYING ITEM
;		B/	POSSIBLE POINTER TO FREE SPACE
;
QRELFR:	MOVE C,QFLST		;GET TOTAL LENGTH OF LIST
QRF1:	SOJLE C,R		;ITEM NOT IN LIST IF COUNT RUNS OUT
	CAME A,QFLST(C)		;FOUND ITEM IN TABLE?
	 JRST QRF1		;NOT YET
	MOVE A,B		;YES, GET POINTER TO STRING
	CALLRET STREM		;FREE UP SPACE USED BY STRING AND RETURN

;TABLE LISTING DISPATCH ADDRESSES FOR ITEMS THAT TAKE UP PERMANENT FREE SPACE
QFLST:	QFLEN			;FIRST ENTRY IS ENTIRE LENGTH OF TABLE
	LFN2			;ENTRY FOR DEFAULT LOG FILENAME STRING
	ACC2			;ACCOUNT STRING
QFLEN==.-QFLST

;LIST OF SWITCHES FOR PRINT, PUNCH CARDS, PUNCH PAPER-TAPE, SUBMIT
DEFINE SLIST
   <	JOBS <TV account>		;;CHARGE PARTICULAR ACCOUNT FOR THIS
					;;  REQEST 
	JOBS <TV after>			;;PRINT AFTER THIS TIME
	JOBS <TV assistance>,B%SU	;;DECLARE WHETHER JOB NEEDS ASSISTANCE
	JOBS <TV batch-log,,.WLOG>,B%SU	;;SAY HOW TO WRITE LOG
ONEON <DECN,LPTD>,<			;;713
	FILS <TV begin,,.PB>,B%PR>	;;713 BEGIN ON SPECIFIC PAGE
	JOBS <TV begin,,.SBEG>,B%SU	;;BEGIN PROCESSING ON SPECIFIC LINE
ONEON <CDPD,DECN>,<			;;713
	JOBS <TV cards>,B%SU>		;;713 NUMBER OF CARDS JOB IS ALLOWED TO
					;;  PRINT 
	JOBS <TV connected-directory,,.BCON>,B%SU ;;DIRECTORY TO CONNECT BATCH
					;;  JOB TO
	FILS <TV copies>		;;HOW MANY COPIES
	FILS <T delete>,,B%SU		;;DELETE FILE AFTER PRINTING
	JOBS <T delete>,B%SU
	JOBS <TV dependency-count,,.DEPEN>,B%SU	;;SPECIFY DEPENDENCY COUNT
DECN,<	JOBS <TV destination-node,,.NODE>> ;;713 WHICH NODE REQUEST IS DESTINED
					;;  FOR, LOG FILE FOR SUBMIT
ONEON <DECN,PTPD>,<			;;713
	JOBS <TV feet>,B%SU>		;;713 NUMBER OF FEET OF TAPE JOB IS
					;;  ALLOWED TO PUNCH
ONEON <DECN,LPTD>,<			;;713
	FILS <TV file>,B%PR>		;;713 WHICH TYPE OF FILE IT IS
	JOBS <TV forms>,,B%SU		;;KIND OF PAPER TO USE
	JOBS <T generic>,,B%SU		;;ANY UNIT
	FILS <T header>,,B%SU		;;HEADER LINE FLAVOR
	JOBS <TV jobname,,.GOBNA>	;;SPECIFY NON-DEFAULT JOBNAME
ALLON <SP,LPTD>,<
	JOBS <T lgp>,B%PR>		;;111 PRINT ON LGP (SPEECH)
ONEON <DECN,LPTD>,<			;;713
	JOBS <TV limit>,,B%SU>		;;713 NUMBER OF PAGES TO ALLOW TO BE
					;;  PRINTED 
	JOBS <TV logdisposition>,B%SU	;;SPECIFY HOW TO DISPOSE OF LOG FILE
	JOBS <TV logname,,.LFN>,B%SU	;;SPECIFY NON-STANDARD LOG FILE NAME
	JOBS <T lowercase,,.LOWER>,B%PR	;;PRINT FILE ONLY ON PRINTER WITH
					;;  UPPER-LOWER CAPABILITY 
ONEON <DECN,PTPD>,<			;;713
	JOBS <TV meters>,B%TP>		;;713 PUNCH SO MANY METERS OF PAPER
					;;  TAPE 
	FILS <TV mode>,,B%SU		;;SPECIFY FORMAT
	FILS <T noheader>,,B%SU
	JOBS <TV note>,,B%SU		;;PUT NOTE ON OUTPUT
	JOBS <TV notify>		;;GET NOTIFICATION WHEN REQUEST IS
					;;  PROCESSED 
	JOBS <TV output>,B%SU		;;CONTROL WHETHER LOG FILE GETS PRINTED
ONEON <DECN,LPTD>,<			;;713
	JOBS <TV pages>,B%SU>		;;713 SPECIFY PAGE LIMIT
	FILS <T preserve>		;;DON'T DELETE FILE, DEFAULT UNLESS
					;;  .LST 
	JOBS <TV priority>		;;PRIORITY LEVEL OF REQUEST
DECN,<	JOBS <TV processing-node,,.PN>,B%SU> ;;713 NODE WHERE JOB SHOULD BE RUN
	JOBS <T reader>,B%SU		;;SPECIFY THAT CONTROL FILE IS A
					;;  PSEUDO-CARD-DECK 
ONEON <DECN,LPTD>,<			;;713
	FILS <TV report>,B%PR>		;;713 PRINT REPORT WITH COBOL REPORT
					;;  FILE 
	JOBS <TV restartable>,B%SU	;;ALLOW OR DISALLOW JOB TO BE
					;;  RESTARTTED AFTER SYSTEM CRASH 
	JOBS <TV sequence>		;;SEQUENCE NUMBER OF REQUEST
ONEON <DECN,LPTD>,<			;;713 
	FILS <TV spacing>,B%PR>		;;713 SINGLE OR DOUBLE SPACING
	JOBS <TV tag>,B%SU		;;START PROCESSING AT THIS TAG
	JOBS <TV time,,.QUTML>,B%SU	;;SPECIFY EXECUTION TIME LIMIT FOR JOB
ONEON <DECN,PLTD>,<			;;713
	JOBS <TV tplot>,B%SU>		;;713 SPECIFY PLOTTER TIME JOB IS
					;;  ALLOWED 
	JOBS <TV unique>,B%SU		;;SPECIFY UNIQUENESS OF JOB (WHETHER
					;;  CONCURRENCY ALLOWED OR NOT) 
	JOBS <TV unit>,,B%SU		;;SPECIFIC UNIT NUMBER
ONEON <DECN,LPTD>,<			;;713
	JOBS <T uppercase>,B%PR>	;;713 SEND TO UPPERCASE PRINTER
	JOBS <TV user,,.BUSER>		;;SPECIAL OWNER FOR THIS REQUEST
       >			;END OF DEFINE SLIST

;WHEN THE USER TYPES "?" AFTER THE WORD "PRINT", HE WANTS TO SEE TWO DISTINCT
;   LISTS. HOWEVER, NOTE THAT THERES "/FORMS" IN ONE LIST AND "/FILE" IN THE
;   OTHER. HENCE WHEN USER TYPES "/F$", HE SHOULD GET A DING BECAUSE IT'S
;   AMBIGUOUS. ALSO, "/F" SHOULD BE AN ERROR, FOR THE SAME REASON. HOWEVER, THE
;   WAY MONITOR WORKS, "/F" WILL MATCH /FORMS UNIQUELY BECAUSE MONITOR DOESN'T
;   CHECK MORE THAN ONE LIST IF SOMETHING MATCHES. HENCE TO MAKE THINGS WORK
;   DESIRABLY, WE MUST INCLUDE ALL SWITCHES IN BOTH LISTS, AND ARRANGE FOR EACH
;   LIST TO HAVE THE APPROPRIATE ENTRIES MARKED AS "INVISIBLE", SO THAT USER
;   WILL JUST SEE TWO SEPARATE DIFFERENT LISTS AND "/F" WILL ACT AMBIGUOUS. TO
;   DO ALL THIS, THE FOLLOWING HAIR:  

DEFINE BUILDF
   <	%%C==0			;;1 FOR JOB SWITCHES
	BUILD>			;;DO THE WORK

DEFINE BUILDJ
   <	%%C==1			;;0 FOR FILE SWITCHES
	BUILD>			;;DO THE WORK

DEFINE BUILDO
   <	%%C=-1			;;-1 FOR ONLY JOB SWITCHES
	BUILD>

DEFINE BUILD
   <	SLIST>			;BUILD SWITCH TABLE

;IN JOBS AND FILS, THE ARGS ARE:
;   SWITCH	ENTRY FOR TABLE
;   COM		OPTIONAL SET OF BITS, IF GIVEN DECLARE WHICH TABLES THAT SWITCH
;		    GOES IN 
;   NCOM	LIKE COM, BUT TABLES SWITCH SHOULDN'T GO IN

DEFINE JOBS(SWITCH,COM,NCOM)
   <	DOSWX JOBS,,I,COM,NCOM,<SWITCH>>

DEFINE FILS(SWITCH,COM,NCOM)
   <	DOSWX FILS,I,,COM,NCOM,<SWITCH>>

DEFINE DOSWX (TYPE,HACK1,HACK2,COM,NCOM,SWITCH)
   <	IFNB <COM>,<IFN COM&WUTCMD,<TYPE <SWITCH>>>
	IFB <COM>,<IFG %%C,<HACK1'SWITCH>
	    IFE %%C,<HACK2'SWITCH>
	    IFL %%C,<IFIDN <TYPE><JOBS>,<SWITCH>>>
	IFNB <NCOM>,<IFN NCOM&WUTCMD,<RELOC .-1>>>

;TABLE OF FILE SWITCHES FOR PRINT COMMAND
	WUTCMD==B%PR		;SPECIFY PRINT COMMAND
$FILSW:	TABLE
	BUILDF			;BUILD TABLE OF FILE SWITCHES
	TEND

;TABLE OF JOB SWITCHES FOR PRINT COMMAND
$JOBSW:	TABLE
	BUILDJ			;BUILD JOB SWITCH TABLE
	TEND

;TABLE OF JOB SWITCHES AFTER COMMA FOR PRINT COMMAND
$JOBSC:	TABLE
	BUILDO			;BUILD JOB SWITCH TABLE AFTER COMMA
	TEND

;TABLE OF FILE SWITCHES FOR PUNCH CARDS COMMAND
	WUTCMD==B%CP		;SPECIFY PUNCH CARDS COMMAND
$CPFIL:	TABLE
	BUILDF			;BUILD TABLE OF FILE SWITCHES
	TEND

;TABLE OF JOB SWITCHES FOR PUNCH CARDS COMMAND
$CPJOB:	TABLE
	BUILDJ			;BUILD JOB SWITCH TABLE
	TEND

;TABLE OF JOB SWITCHES AFTER COMMA FOR PUNCH CARD COMMAND
$CPJOC:	TABLE
	BUILDO			;BUILD JOB SWITCH TABLE AFTER COMMA
	TEND

;FILE SWITCHES FOR PLOT COMMAND
	WUTCMD==B%PL		;SAY PLOT
$PLFIL:	TABLE
	BUILDF
	TEND

;JOB SWITCHES FOR PLOT
$PLJOB:	TABLE
	BUILDJ
	TEND

;TABLE OF JOB SWITCHES AFTER COMMA FOR PLOT COMMAND
$PLJOC:	TABLE
	BUILDO			;BUILD JOB SWITCH TABLE AFTER COMMA
	TEND

;TABLE OF FILE SWITCHES FOR PUNCH PAPER-TAPE COMMAND
	WUTCMD==B%TP		;SPECIFY PUNCH PAPER-TAPE COMMAND
$TPFIL:	TABLE
	BUILDF			;BUILD TABLE OF FILE SWITCHES
	TEND

;TABLE OF JOB SWITCHES FOR PUNCH PAPER-TAPE COMMAND
$TPJOB:	TABLE
	BUILDJ			;BUILD JOB SWITCH TABLE
	TEND

;TABLE OF JOB SWITCHES AFTER COMMA FOR PUNCH PAPER-TAPE COMMAND
$TPJOC:	TABLE
	BUILDO			;BUILD JOB SWITCH TABLE AFTER COMMA
	TEND

;TABLE OF SUBMIT SWITCHES, ONE TYPE ONLY
	WUTCMD==B%SU		;SPECIFY SUBMIT
$SUBSW:	TABLE
	BUILDJ
	TEND

;TABLE OF JOB SWITCHES AFTER COMMA FOR SUBMIT COMMAND
$SUBSC:	TABLE
	BUILDO			;BUILD JOB SWITCH TABLE AFTER COMMA
	TEND

;BEGIN ON SPECIFIC PAGE OF FILE
.PB:	CALL GPBEG
	MOVE A,[IBEGIN,,PB2]	;DISPATCH ADDRESSES
	CALLRET STOR1

GPBEG:	DECX <Decimal page number of file on which to start listing>
	 CMERRX
	RET

PB2:	MOVEM B,.FPFST(P2)
	RET

;NUMBER OF CARDS JOB IS ALLOWED TO PUNCH
.CARDS:	CALL GCARDS
	VERLIM B,SCRLIM,SCDP	;VERIFY RANGE
	 ERROR <Card limit out of range>
	MOVE A,[ICARDS,,CAR2]	;DISPATCH ADDRESSES
	CALLRET STOR1

GCARDS:	DECX <Decimal number of spooled cards job is allowed to punch>
	 CMERRX
	RET

CAR2:	STOLIM B,.EQLIM(P1),SCDP ;SAVE THE VALUE
	RET

GDEAD:	DTX <Date and time before which request must start being processed>
	 CMERRX <Invalid DEADLINE value>
	RET

;SPECIFY DEPENDENCY COUNT
.DEPEN:	DECX <Decimal DEPENDENCY-COUNT>
	 CMERRX <Invalid DEPENDENCY-COUNT>
	VERLIM B,SCRLIM,DEPN	;VERIFY RANGE
	 ERROR <DEPENDENCY-COUNT out of range>
	MOVE A,[IDEPEN,,DEP2]
	CALLRET STOR1

DEP2:	STOLIM B,.EQLIM(P1),DEPN
	RET

;NUMBER OF FEET OF PAPER TAPE (SPOOLED) JOB IS ALLOWED TO PUNCH
.FEET:	CALL GFEET
	MOVE A,[IFEET,,FE2]
	CALLRET STOR1

GFEET:	DECX <Decimal number of feet of spooled paper tape job is allowed to 
punch>
	 CMERRX <Invalid FEET value>
	VERLIM B,SCRLIM,SPTP
	 ERROR <FEET value out of range>
	RET

FE2:	STOLIM B,.EQLIM(P1),SPTP
	RET

;SPECIFY WHERE TO WRITE THE LOG FILE
.WLOG:	KEYWD $WLOG
	 0			;NO DEFAULT
	 CMERRX <Invalid value for /BATCH-LOG switch>
	MOVE B,P3		;GET VALUE SPECIFIED
	MOVE A,[IWRITE,,WLOG2]
	CALLRET STOR1

$WLOG:	TABLE
	T append,,%BAPND
	T spool,,%BSPOL
	T supersede,,%BSCDE
	TEND

WLOG2:	STOLIM B,.EQLIM(P1),BLOG
	RET

;SPECIFY WHETHER LOG FILE SHOULD BE PRINTED
.OUTPU:	CALL GOUTPU
	MOVE A,[IOUTPU,,OUT2]
	CALLRET STOR1

GOUTPU:	KEYWD $OUTPU
	 0			;NO DEFAULT
	 CMERRX <Invalid value for /OUTPUT switch>
	MOVE B,P3		;GET VALUE FOR SWITCH
	RET

OUT2:	STOLIM B,.EQLIM(P1),OUTP
	RET

$OUTPU:	TABLE
	T always,,%EQOLG
	T errors,,%EQOLE
	T nolog,,%EQONL
	TEND

;SPECIFY HOW MUCH SPOOLED LINEPRINTER OUTPUT JOB MAY WRITE
.PAGES:	CALL GPAGES
	MOVE A,[IPAGES,,PAG2]
	CALLRET STOR1

PAG2:	STOLIM B,.EQLIM(P1),SLPT
	RET

GPAGES:	DECX <Decimal number of spooled lineprinter pages job may write>
	 CMERRX <Invalid PAGE value>
	VERLIM B,SCRLIM,SLPT
	 ERROR <PAGE count out of range>
	RET

;SPECIFY PROTECTION OF REQUEST
.PROTE:	OCTX <Octal protection number for request>
	 CMERRX <Invalid PROTECTION>
	VERIFY B,C,EQ.PRO	;CHECK RANGE
	 ERROR <PROTECTION out of range>
	MOVE A,[IPROTE,,PRO2]
	CALLRET STOR1

PRO2:	STOR B,EQ.PRO,.EQSPC(P1)
	RET

;SPECIFY WHETHER ASSISTANCE IS NEEDED OR NOT
.ASSIS:	KEYWD $YESNO
	 T yes,,1		;DEFAULT IS YES (/ASSIST MEANS ASSISTANCE)
 	 CMERRX <YES or NO required> ;7 SPR #:20-16853 better error msg
	CALL GETKEY		;GET TABLE INFORMATION
	HRRZ B,P3		;GET ANSWER
	MOVE A,[IASSIS,,ASS2]
	CALLRET STOR1

ASS2:	MOVX C,.OPINN
	CAIN B,1		;YES?
	 MOVX C,.OPINY
	STOLIM C,.EQLIM(P1),OINT
	RET

;SPECIFY WHETHER JOB IS RESTARTABLE OR NOT
.RESTA:	CALL GRES		;GET RESTARTABLE VALUE
	MOVE A,[IRESTA,,RES2]
	CALLRET STOR1

RES2:	CALL RESCVT		;CONVERT 0/1 TO INTERNAL FORMAT
	STOLIM B,.EQLIM(P1),REST
	RET

GRES:	KEYWD $YESNO
	 T yes,,1		;DEFAULT IS YES
	 CMERRX <YES or NO required>
	HRRZ B,P3		;RETURN REPONSE IN B
	RET

;ROUTINE TO CHANGE 0=NO AND 1=YES INTO QUASAR INTERNAL
RESCVT:	MOVE B,[%EQRNO
		%EQRYE](B)	;0=%EQRNO, 1=%EQRYE
	RET

$YESNO:	TABLE
	T no,,0
	T yes,,1
	TEND

;TIME LIMIT FOR JOB
.QUTML:	DEFX <60>		;SET UP A DEFAULT FOR RUN TIME
	CALL GTIME		;GET TIME IN SECONDS
	MOVE A,[ITIME,,TIM2]
	CALLRET STOR1

TIM2:	STOLIM B,.EQLIM(P1),TIME
	RET

;ROUTINE TO INPUT TIME IN SECONDS INTO B.
GTIME:	CALL GETAMT		;READ AMOUNT OF TIME
	 CMERRX <Invalid TIME>
	VERLIM B,SCRLIM,TIME	;MAKE SURE IT FITS IN FIELD
	 ERROR <TIME out of range>
	RET

;SPECIFY PLOTTER TIME ALLOWED
.TPLOT:	CALL GTPLOT
	MOVE A,[ITPLOT,,PLO2]
	CALLRET STOR1

PLO2:	STOLIM B,.EQLIM(P1),SPLT
	RET

GTPLOT:	DECX <Decimal number of plotter minutes job is to be allowed>
	 CMERRX <Invalid TPLOT value>
	VERLIM B,SCRLIM,SPLT	;CHECK RANGE
	 ERROR <TPLOT value out of range>
	RET

;SPECIFY UNIQUENESS OF JOB
.UNIQU:	CALL GUNI		;GET UNIQUENESS VALUE
	MOVE A,[IUNIQU,,UNI2]
	CALLRET STOR1

UNI2:	CALL CVTUNI		;GET QUASAR VALUES FOR YES AND NO
	STOLIM B,.EQLIM(P1),UNIQ
	RET

CVTUNI:	MOVX C,%EQUYE		;ASSUME YES
	CAIN B,0		;BUT MAYBE NO
	 MOVX C,%EQUNO
	MOVE B,C		;RETURN QUASAR FORM IN B
	RET

GUNI:	MOVEI B,[FLDDB. .CMKEY,,$UNI]
	CALL FLDSKP
	 CMERRX <Invalid UNIQUEness value>
	CALL GETKEY		;GET KEYWORD DATA
	MOVE B,P3		;GET TYPED VALUE
	RET

$UNI:	TABLE
	IT 0,,0			;7 2ndary usage
	IT 1,,1			;7 2ndary usage
	T no,,0
	T yes,,1
	TEND

;SPECIFY LINE OF CONTROL FILE ON WHICH TO BEGIN EXECUTION
.SBEG:	CALL GSBEG
	MOVE A,[IBEGIN,,SB2]
	CALLRET STOR1

SB2:	MOVEM B,.FPFST(Q1)
	RET

GSBEG:	DECX <Decimal line number of control file on which to start processing>
	 CMERRX <Invalid line number>
	RET

;DISPOSITION OF LOG FILE
.LOGDI:	KEYWD $LDISP		;SEE WHAT DISPOSITION IS
	 0			;NO DEFAULT
	 CMERRX			;BAD INPUT, SAY REASON
	MOVE B,P3		;GET VALUE FOR BIT
	MOVE A,[ILOGDI,,LDIS2]
	CALLRET STOR1

LDIS2:	STOR B,FP.DEL,LOGFIL+.FPINF(P1)	;STORE VALUE
	RET

ILOGDI:	HRROI C,[ASCIZ /keep/]
	CAIE B,0
	 HRROI C,[ASCIZ /delete/]
	PSWITCH <logdisposition:%3M>

$LDISP:	TABLE
	T delete,,1		;DELETE LOG FILE
	T keep,,0		;KEEP LOG FILE
	TEND

;SPECIAL LOG FILE NAME
.LFN:	MOVEI A,[ASCIZ/LOG/]	;DEFAULT EXTENSION FOR LOG FILE
	MOVX B,(GJ%MSG)		;PRINT A MESSAGE FOR RECOGNITION
	CALL SPECFN		;PARSE A FILE NAME
	 CMERRX <Invalid log file name>
	MOVE B,A		;PUT JFN IN AC2
	MOVE A,CSBUFP		;GET POINTER TO SCRATCH SPACE
	MOVX C,FLD(.JSAOF,JS%DEV)!FLD(.JSAOF,JS%DIR)!FLD(.JSAOF,JS%NAM)!
FLD(.JSAOF,JS%TYP)!JS%PAF
	JFNS			;GET STRING FOR FILE NAME
	MOVE A,CSBUFP
	SKIPN SDF		;USE PERMANENT STORAGE FOR SETTING DEFAULT,
				;   TEMP FOR REAL SUBMIT COMMAND 
	 CALL BUFFS		;BUFFER UP THE STRING
	SKIPE SDF
	 CALL XBUFFS
	MOVE B,A		;REMEMBER POINTER TO FILENAME IN B
	MOVE A,[ILOGNA,,LFN2]
	CALLRET STOR1		;JUST STORE JFN ON FIRST PASS

LFN2:	HRROI A,LOGNAM(P1)	;ON SECOND PASS, POINT TO NAME AREA
	SETZ C,			;END ON NULL
	SOUT			;WRITE FILESPEC INTO LOG FILE AREA
	RET

;TAG AT WHICH TO BEGIN PROCESSING BATCH REQUEST
.TAG:	WORDX <TAG in batch file at which to begin processing, six 
characters or less>
	 CMERRX <Invalid TAG>
	CALL GETSXB		;GET SIXBIT OF TAG
	MOVE B,A
	MOVE A,[ITAG,,TAG2]
	CALLRET STOR1

TAG2:	MOVEM B,.FPFST(Q1)
	RET

.COPIE:	CALL GCOPIE
	MOVE A,[ICOPIE,,COP2]
	CALLRET STOR1		;SAVE ARG

GCOPIE:	DECX <Decimal number of copies to print>
	 CMERRX
	VERIFY B,C,FP.FCY	;VERIFY RANGE
	 ERROR <Invalid number of copies requested>
	RET

COP2:	STOR B,FP.FCY,.FPINF(Q1)
	RET

;ROUTINE TO SEARCH A TABLE FOR A VALUE
;
;   ACCEPTS:	A/	TABLE ADDRESS
;		B/	VALUE
;   RETURNS: +1		VALUE NOT FOUND
;	     +2		ADDRESS OF VALUE IN TABLE
TSX:	MOVE D,A		;PUT TABLE BASE ADDRESS IN D
	HLRZ A,(D)		;NUMBER ENTRIES TO SEARCH
TSX0:	SOJL A,R		;ENTRY NOT FOUND IF COUNT RUNS OUT
	HRRZ C,A		;GET RELATIVE ADDRESS OF VALUE
	ADDI C,1(D)		;MAKE ABSOLUTE TABLE ADDRESS
	HRRZ C,(C)		;GET ADDRESS OF VALUE
	CAME B,(C)		;FIND CORRECT ONE YET?
	 JRST TSX0		;NO
	ADDI D,1(A)		;YES, CALCULATE ABSOLUTE ADDRESS
	MOVE A,D		;RETURN ADDRESS IN A
	RETSKP

$PUNCH:	TABLE
	T ascii,,%FPCAS
	T bcd,,%FPCBC
	T binary,,%FPCBI
	T image,,%FPCIM
	TEND

$PLFRM:	TABLE			;MODES FOR PLOTTER
	T ascii,,%FPPAS
	T binary,,%FPPBI
	T image,,%FPPIM
	TEND

$TFORM:	TABLE
	T ascii,,%FPTAS
	T binary,,%FPTBI
	T image,,%FPTIM
	T image-binary,,%FPTIB
	TEND

$PF:	TABLE
	T arrow,,%FPLAR		;PRINT CONTROLS AS UPARROW LETTER
NOSP,<	T ascii,,%FPLAS>	;SEND FILE "AS IS"
SP,<	T raw-ascii,,%FPLAS>	;111 Different name hopefully clearer
	T octal,,%FPLOC		;PRINT IN OCTAL
EE,<	T quality,,%FPLAR >	;7 for EE's Trilog printer
	T suppress,,%FPLSU	;SUPPRESS CONTROL CHARACTERS
EE,<	T unreadable,,%FPLAS >	;7 for EE's Trilog printer
	TEND

;MODE OF OUTPUT
.MODE:	CALL GMODE		;READ DATA
	MOVE A,[IMODE,,MOD2]
	CALLRET STOR1

GMODE:	KEYWD @[$PUNCH
		$PF
		0
		$TFORM
		$PLFRM](P4)	;USE APPROPRIATE TABLE
	 0
	 CMERRX
	MOVE B,P3		;GET ITEM SELECTED
	RET

MOD2:	STOR B,FP.FPF,.FPINF(Q1)
	RET

IMODE:	MOVE A,[$PUNCH
		$PF
		0
		$TFORM
		$PLFRM](P4)	;TABLE TO SEARCH
	CALL TSX		;SEARCH FOR VALUE
	 JRST IPBAD		;VALUE NOT FOUND
	HLRO D,(A)		;YES, GET POINTER TO STRING
IP1:	PSWITCH <mode:%4M>

IPBAD:	HRROI D,[ASCIZ/?/]
	JRST IP1

.FILE:	CALL GFILE
	MOVE B,P3
FFI1:	TLNN Z,F1		;IS THIS A GLOBAL SWITCH?
	 SETOM FILSF		;YES, RAISE A FLAG TO REMEMBER
	MOVE A,[IFILE,,FIL2]
	CALLRET STOR1

GFILE:	KEYWD @[$PUNFL
		$PRIFL
		0
		$TAPFL
		$PLOFL](P4)
	 0			;NO DEFAULT
	 CMERRX			;ERROR IF NONE TYPED
	MOVE B,P3		;GET KEYWORD DATA
	RET

IFILE:	MOVE A,[$PUNFL
		$PRIFL
		0
		$TAPFL
		$PLOFL](P4)
	CALL TSX		;FIND CORRECT TABLE ADDRESS
	 JRST FILBAD		;NOT FOUND
IFI0:	HLRO D,(A)		;MAKE POINTER TO NAME
	PSWITCH <mode:%4M>

FILBAD:	HRROI D,[ASCIZ/?/]
	JRST IFI0

FIL2:	STOR B,FP.FFF,.FPINF(Q1)
	TXO Z,NFILES		;INDICATE EXPLICIT /FILE FOR NEXT SPEC
	RET			;(IRRELEVANT IF GLOBAL SW)

DEFINE SLIST
   <	JOBS <T ascii,,.FPFAS>
ONEON <DECN,LPTD>,<			;;713
	JOBS <T cobol,,.FPFCO>,B%PR>	;;713
	JOBS <T eleven,,.FPF11>
ONEON <DECN,LPTD>,<			;;713
	JOBS <T fortran,,.FPFFO>,B%PR>	;;713
SP,<	JOBS <T image,,.FPFIM>,B%PR>	;;111 8-BIT IMAGE FILES

       >			;end SLIST

$PRIFL:	WUTCMD==B%PR		;DO /FILE: VALUES FOR PRINT COMMAND
	TABLE
	BUILDJ
	TEND

$PLOFL:	WUTCMD==B%PL		;DO PLOT VALUES FOR /FILE:
	TABLE
	BUILDJ
	TEND

;PUNCH CARDS...
$PUNFL:	WUTCMD==B%CP
	TABLE
	BUILDJ
	TEND

;PUCH TAPE
$TAPFL:	WUTCMD==B%TP
	TABLE
	BUILDJ
	TEND

;HEADER TO PRINT HEADER ON FILE OUTPUT
.HEADE:	MOVE A,[IHEADE,,NHEA2]
	SETZ B,
	CALL STOR1		;TURN OFF "NO HEADER" BIT
	RET

;NOTIFICATION WANTED AFTER REQUEST IS DONE
.NOTIF:	KEYWD $YESNO
	 T yes,,1		;MAKE "/NOTIFY" = "/NOTIFY:YES"
	CMERRX <YES or NO required>
	MOVE B,P3		;GET 0 FOR NO, 1 FOR YES
	MOVE A,[INOTIF,,NOTIF2]
	CALLRET STOR1

NOTIF2:	STOR B,EQ.NOT,.EQSEQ(P1)
	RET

;NO HEADER WANTED
.NOHEA:	MOVE A,[IHEADE,,NHEA2]
	MOVX B,1
	CALL STOR1		;TURN OFF "NO HEADER" BIT
	RET

NHEA2:	STOR B,FP.NFH,.FPINF(Q1)
	RET

;REPORT CODE TO SEARCH FOR
.REPOR:	CALL GREPOR
	CALLRET STOR1

REP2:	DMOVEM B,.FPFR1(Q1)	;STORE REPORT CODE
	RET

GREPOR:	MOVEI B,[FLDDB. .CMQST,,,<a report code, up to twelve characters,>,,[
		FLDDB. .CMFLD,CM%SDH]]	;REPORT CODE MAY OR MAY NOT BE IN
				;   QUOTES 
	CALL FLDSKP	;READ IN THE REPORT FIELD
	 CMERRX <Invalid report string>
	MOVE A,[ASCPTR ATMBUF]	;PREPARE TO CHANGE REPORT TO SIXBIT
	MOVE B,[POINT 6,Q2]
	SETZB Q2,Q3
REP1:	CALL CACKLE		;GET CHARACTER FROM REPORT
	 JRST REP3		;NO MORE CHARACTERS
	CAMN B,[POINT 6,Q3,35]
	 ERROR <Report string too long>
	IDPB C,B		;STORE CHARACTER OF REPORT STRING
	JRST REP1		;GO BACK FOR MORE

REP3:	MOVE A,[IREPOR,,REP2]
	DMOVE B,Q2		;GET THE SIXBIT NAME
	RET

;PRESERVE FILE (DON'T DELETE IT AFTER PRINTING)
.PRESE:	TDZA B,B		;SET B=0 AND SKIP

;DELETE FILE AFTER PRINTING
.DELET:	 MOVX B,1		;SET FLAG
	TLNN Z,F1		;IS THIS A GLOBAL SWITCH?
	 SETOM PRESF		;YES, RAISE A FLAG IN CASE EXTENSION IS .LST
	MOVE A,[IDELET,,DEL2]
	CALLRET STOR1

DEL2:	STOR B,FP.DEL,.FPINF(Q1)
	TXO Z,NPRES		;INDICATE EXPLICIT /PRESERVE OR /DELETE FOR
	RET			;   NEXT SPEC (IRRELEVANT IF GLOBAL SW)

;SPACING BETWEEN LINES
.SPACI:	CALL GSPACE
	MOVE A,[ISPACI,,SPA2]
	CALLRET STOR1

GSPACE:	KEYWD $SPACE		;GET SPACING PARAMETER
	 0			;NO DEFAULT
	 CMERRX			;BAD TYPEIN
	MOVE B,P3
	RET

SPA2:	STOR B,FP.FSP,.FPINF(Q1)
	RET

$SPACE:	TABLE
	T double,,2
	T single,,1
	T triple,,3
	TEND

;CHARGE PARTICULAR ACCOUNT
.ACCOU:	CALL GACT		;GET ACCOUNT STRING
	MOVE B,A		;POINTER TO STRING IN B
	MOVE A,[IACCOU,,ACC2]
	CALLRET STOR1

ACC2:	HRROI A,.EQACT(P1)	;POINT AT BLOCK IN IPCF MESSAGE FOR ACCOUNT
				;   STRING 
	SETZ C,			;END ON A 0
	SOUT			;COPY STRING INTO MESSAGE
	RET

IACCOU:	PSWITCH <account:%2M>

;ROUTINE TO READ ACCOUNT. IT RETURNS POINTER IN A.
GACT:	ACCTX <Account to be charged for request>
	 CMERRX			;FAILED
	HRROI A,ATMBUF		;POINT TO THE ACCOUNT STRING
	SKIPN SDF		;USE TEMPORARY STORAGE IF NOT SETTING DEFAULTS
	 CALLRET BUFFS		;BUFFER THE ACCOUNT AND RETURN POINTER IN A
	SKIPE SDF
	 CALLRET XBUFFS		;AND PERMANENT IF SETTING DEFAULT

;PROCESS REQUEST /AFTER: A CERTAIN TIME
.AFTER:	CALL GAFT		;GET AFTER VALUE
	MOVE A,[IAFTER,,AFT2]
	CALLRET STOR1

AFT2:	MOVEM B,.EQAFT(P1)	;STORE SPECIFIED TIME AND DATE
	RET

GAFT:	DTX <Date and/or time after which to process request>
	 CMERRX <Invalid /AFTER value>
	RET

;PAPER TYPE SPECIFICATION
.FORMS:	CALL GFORMS		;GET FORMS WORD INTO B
	VERLIM B,SCRLIM,FORM	;MAKE SURE IT FITS
	 ERROR <Invalid FORMS specification>
	MOVE A,[IFORMS,,FOR2]
	CALLRET STOR1

FOR2:	STOLIM B,.EQLIM(P1),FORM
	RET

GFORMS:	WORDX <Type of paper to use for printing, six characters or less>
	 CMERRX <Invalid paper type>
	MOVE A,[ASCPTR ATMBUF]	;POINTER TO READ ASCII WORD
	MOVE B,[POINT 6,D]	;WE'LL FORM SIXBIT WORD IN D
	SETZ D,			;START WITH CLEAR WORD
FORM1:	CALL CACKLE		;GET CHARACTER
	 JRST FORM2		;DONE
	TLNN B,770000		;MAKE SURE ROOM FOR ANOTHER CHARACTER
	 ERROR <FORMS specification too long>
	IDPB C,B		;STORE THE SIXBIT CHARACTER
	JRST FORM1		;GO DO REST OF CHARACTERS

FORM2:	MOVE B,D		;RETURN VALUE IN "B"
	RET

;SPECIFY THAT CONTROL FILE IS TO BE INTERPRETED AS A CARD DECK
.READE:	MOVE A,[IREADE,,READ2]
	CALLRET STOR1

READ2:	MOVX B,.OTBIN		;SPECIFY SPECIAL QUEUE
	MOVEM B,.EQROB+.ROBTY(P1)
	RET

IREADE:	PSWITCH <reader>

;SPECIFY NON-DEFAULT JOBNAME
.GOBNA:	CALL GJOB		;GET JOBNAME
	MOVE A,[IJOBNA,,JOB2]
	CALLRET STOR1

JOB2:	MOVEM B,.EQJOB(P1)	;STORE IT
	RET

;READ SIXBIT JOBNAME INTO B AND MASK INTO C...
GJOB:	MOVEI B,[FLDBK. .CMFLD,CM%SDH,,<Name of request, six characters or 
less>,,[BRMSK. FILB0.,FILB1.,FILB2.,FILB3.]]
	CALL FLDSKP
	 CMERRX <Invalid JOBNAME>

;ROUTINE TO PROCESS JOBNAME ASSUMING IT'S ALREADY IN ATOM BUFFER...
GJOB1:	CALL GETSXB		;GET SIXBIT VALUE FOR JOBNAME
	MOVE B,A
	CAIN B,0		;NULL NAME?
	 MOVX B,SIXBIT/*/	;YES, SO ASSUME ALL JOBS
	SETO C,			;FIRST ASSUME SPECIFIC NAME GIVEN
	CAMN B,[SIXBIT/*/]	;BUT IF "*" GIVEN,
	 SETZ C,		;THEN ALLOW ANY JOBNAME TO MATCH
	RET

;111 ADDITION
SP,<
;PRINT ON LGP (SPEECH). THIS IS EQ TO /FORMS:LGP!!!

.LGP:	MOVE B,[SIXBIT /LGP/]	;SIXBIT FORMS VALUE
	MOVE A,[ILGP,,LGP2]
	CALLRET STOR1		;GO SET IT UP

LGP2:	STOLIM B,.EQLIM(P1),FORM
	RET

ILGP:	PSWITCH <%2'>
>;END SP
;111 END

;SPECIFY METERS OF PAPER TAPE TO ALLOW IN REQUEST
.METER:	CALL GMET
	MOVE A,[IMETER,,MET2]
	CALLRET STOR1

;LIMIT OF NUMBER OF PAGES TO PRINT
.LIMIT:	CALL GLIM		;GET LIMIT VALUE
	MOVE A,[ILIMIT,,LIM2]
	CALLRET STOR1

MET2:	CALL M2F		;CHANGE METERS TO FEET
LIM2:	STOLIM B,.EQLIM(P1),OLIM
	RET

M2F:	FLTR B,B		;GET FLOATING REPRESENTATIN
	FMP B,[39.37]		;GET NUMBER OF INCHES DESIRED
	FDVRI B,(12.0)		;CHANGE TO FEET
	FIXR B,B		;GET INTEGER
	RET

GMET:	STKVAR <SAVMET>
	DECX <Decimal maximum paper tape length>
	 CMERRX <Invalid /METERS value>
	MOVEM B,SAVMET		;SAVE METERS VALUE
	CALL M2F		;CHANGE METERS TO FEET
	VERLIM B,SCRLIM,OLIM	;MAKE SURE VALUE FITS IN FIELD
	 ERROR <Limit out of range>
	MOVE B,SAVMET		;GET NUMBER OF METERS
	RET

GLIM:	DECX <Decimal number of pages, cards, or feet to limit request to>
	 CMERRX <Invalid /LIMIT value>
	VERLIM B,SCRLIM,OLIM	;CHECK VALUE
	 ERROR <LIMIT out of range>
	RET

;SPECIFY WHAT TYPE OF PRINTER TO USE FOR REQUEST
.UPPER:	SKIPA B,[PR%UC]
.LOWER:	 MOVX B,PR%LC
	ABSKP
.GENER:	 MOVX B,PR%ANY		;GENERIC MEANS ANY
	MOVE A,[ICASE,,LOW2]
	CALLRET STOR1

LOW2:	MOVX C,OBDLLC		;FIRST ASSUME LOWERCASE
	CAIN B,PR%UC		;UPPERCASE?
	 MOVX C,OBDLUC		;YES
	CAIN B,PR%ANY
	 SETZ C,		;GENERIC
	MOVEM C,.EQROB+.ROBAT(P1) ;TURN ON APPROPRIATE BITS, TURN OFF RO.PHY
	RET

;NOTE FOR HEADER PAGE
.NOTE:	CALL GNOTE
	MOVE A,[INOTE,,NOT2]
	CALLRET STOR1

NOT2:	STOLIM B,.EQLIM(P1),NOT1
	STOLIM C,.EQLIM(P1),NOT2
	RET

GNOTE:	MOVEI B,[FLDDB. .CMQST,,,<a note for header page, up to twelve 
characters,>,,[
		FLDDB. .CMFLD,CM%SDH]]	;NOTE MAY OR MAY NOT BE IN QUOTES
	CALL FLDSKP		;READ IN THE NOTE
	 CMERRX <Invalid NOTE>
	MOVE A,[ASCPTR ATMBUF]	;PREPARE TO CHANGE NOTE TO SIXBIT
	MOVE B,[POINT 6,Q2]
	SETZB Q2,Q3		;START WITH CLEAR NOTE
NOTE1:	CALL CACKLE		;GET CHARACTER FROM NOTE
	 JRST NOTE3		;NO MORE CHARACTERS
	CAMN B,[POINT 6,Q3,35]
	 ERROR <NOTE too long>
	IDPB C,B		;STORE CHARACTER OF NOTE
	JRST NOTE1		;GO BACK FOR MORE

NOTE3:	DMOVE B,Q2		;RETURN NOTE IN B AND C
	RET

;SUBROUTINE USED FOR READING CHARACTER. MAKES SURE CHARACTER, IF LETTER, IS
;   UPPERCASE. THEN IT CHANGES IT TO SIXBIT. 
CACKLE:	ILDB C,A		;READ CHARACTER
	JUMPE C,R		;SINGLE RETURN ON NULL CHARACTER
	CAIN C,""		;IS IT THE QUOTING CHARACTER?
	 JRST CAK1		;YES
	CAIGE C,40		;MAKE SURE IT CAN BE CHANGED TO SIXBIT
	 MOVX C,"?"		;USE ? IF NOT
CAK1:	CAIL C,"a"
	 CAILE C,"z"
	  ABSKP			;NOT LOWERCASE LETTER
	   TRZ C,40		;WAS LOWERCASE, MAKE UPPERCASE
	SUBI C,40		;CHANGE TO SIXBIT
	RETSKP			;SKIP RETURN BECAUSE WE READ A CHARACTER

;SPECIAL CONNECTED DIRECTORY FOR BATCH JOB
.BCON:	DIRX <Directory to which batch job is to be connected>
	 CMERRX <Invalid CONNECTED-DIRECTORY for batch job>
	MOVE A,[ICONNE,,BC2]
	CALLRET STOR1

BC2:	HRROI A,.EQCON(P1)
	DIRST			;STORE DIRECTORY NAME
	 ERCAL CJERRE
	RET

;SPECIAL OWNER FOR REQUEST
.BUSER:	USERX <User who is to own this request>
	 CMERRX <Invalid owner of request>
	MOVE A,[IUSER,,BU2]
	CALLRET STOR1

BU2:	HRROI A,.EQOWN(P1)
	DIRST			;STORE OWNER NAME
	 ERCAL CJERRE
	RET

;PRIORITY SPECIFICATION
.PRIOR:	CALL GPRIO
	VERIFY B,C,EQ.PRI
	 ERROR <PRIORITY value out of range>
	MOVE A,[IPRIOR,,PRIO2]
	CALLRET STOR1

PRIO2:	STOR B,EQ.PRI,.EQSEQ(P1)
	RET

GPRIO:	DECX <Decimal priority level>
	 CMERRX <Invalid PRIORITY level>
	VERIFY B,C,EQ.PRI	;CHECK RANGE
	 ERROR <PRIORITY out of range>
	RET

;SEQUENCE NUMBER
.SEQUE:	CALL GSEQ
	VERIFY B,C,EQ.SEQ
	 ERROR <SEQUENCE number out of range>
	MOVE A,[ISEQUE,,SEQ2]
	CALLRET STOR1

SEQ2:	STOR B,EQ.SEQ,.EQSEQ(P1)
	RET

GSEQ:	DECX <Decimal sequence number>
	 CMERRX <Invalid SEQUENCE number>
	VERIFY B,C,EQ.SEQ
	 ERROR <SEQUENCE number out of range>
	RET

;INITIALIZATION ROUTINE. SETS UP INITIAL ADDRESSES FOR REQUEST AND FILE
;   DESCRIPTOR BLOCKS 
PRINI:	SETZM PRIJFN		;MARK THAT THERE'S NO CURRENT JFN YET
	CALL EQINI		;INITIALIZE REQUEST BLOCK
	MOVX A,QSLEN		;ALLOCATE ARG STACK
	CALL GETBUF
	SUBI A,1		;SO FIRST PUSH USES FIRST WORD
	HRLI A,-QSLEN		;CATCH OVERFLOW
	MOVEM A,QPT		;INITIALIZE ARGUMENT STACK
	MOVEM A,IQPT		;REMEMBER INITIAL POINTER
	RET

;ROUTINE TO INITIALIZE REQUEST BLOCK
EQINI:	MOVEI P1,EQGLOB		;GLOBAL REQUEST BLOCK
	MOVEI P2,EQ0+EQHSIZ	;FIRST FILESPEC STARTS RIGHT AFTER FIRST BLOCK
	SETZM (P1)		;CLEAR FIRST WORD OF REQUEST BLOCK
	HRL A,P1
	HRRI A,1(P1)		;MAKE BLT POINTER
	MOVEI B,777(P1)
	BLT A,(B)		;CLEAR OUT FIRST BLOCK
	MOVX A,EQHSIZ		;LENGTH OF MESSAGE IS EQHSIZ
	STOR A,MS.CNT,(P1)
	MOVX A,.QOCRE		;MESSAGE TYPE (REQUEST CREATION)
	STOR A,MS.TYP,(P1)
	MOVX A,EQHSIZ		;SIZE OF REQUEST HEADER
	STOR A,EQ.LOH,.EQLEN(P1)
	MOVX A,%%.QSR		;VERSION NUMBER
	STOR A,EQ.VRS,.EQLEN(P1)
	XCT GOTYP		;GET OBJECT TYPE
	MOVEM A,.EQROB+.ROBTY(P1)
	MOVX A,FPXSIZ		;ALLOCATE LARGEST SIZE FOR FILE-PARAMETER AREA
	STOR A,FP.LEN,GLBBLK+.FPLEN
	STOR A,FP.LEN,GLBBLK+.FPLEN+FPXSIZ+FILMAX+1	;STORE FOR LOG FILE TOO
	CAIN P4,X%SU		;SUBMIT?
	 JRST EQSINI		;YES, DIFFERENT INITIALIZATION
	MOVE A,[EQGLOB,,EQ0]	;NO GLOBAL PAGE FOR PRINT COMMAND
	BLT A,EQ0+777
	MOVX A,1		;DEFAULT NUMBER OF COPIES IS 1
	STOR A,FP.FCY,GLBBLK+.FPINF
	MOVEI P1,EQ0		;NO GLOBAL JOB SWITCH BLOCK FOR PRINT COMMAND
	RET

EQSINI:	MOVX A,.FPFSA		;ASSUME ITS STREAM ASCII FORMAT
	STOR A,FP.FFF,GLBBLK+.FPINF ;SAVE IT
	RET
;INFORMATION (ABOUT) RETRIEVAL-REQUESTS
;INFORMATION (ABOUT) OUTPUT-REQUESTS
;INFORMATION (ABOUT) BATCH-REQUESTS
;INFORMATION (ABOUT) MOUNT-REQUESTS
;
;   ACS:	P1/	POINTER TO LIST REQUEST TO BE SENT TO QUASAR
;		P2/	POINTER TO QUEUE ENTRY RECEIVED FROM QUASAR, AND
;			    POINTER TO BLOCK BEING CREATED 

.IRR::	MOVX P4,X%RE		;RETRIEVAL
	JRST IPR11

.IMR::	MOVX P4,X%MO		;SPECIFY WE WANT TO SEE MOUNTS
	JRST IPR11

.IBR::	MOVX P4,X%SU
	JRST IPR11

.IPR::	MOVX P4,X%PR		;0 FOR OUTPUT REQUESTS, 1 FOR BATCH REQUESTS
IPR11:	PRISTG			;ALLOCATE STORAGE (SUCH AS QIDX)
	CALL IPRINI		;INITIALIZE FOR LISTING REQUESTS
	CALL PRLSTQ		;SET UP REQUEST BLOCK
IPR12:	MOVEI B,[FLDDB. .CMCFM,,,,,[ ;END OF LINE ONE POSSIBILITY
		FLDDB. .CMSWI,,$IPRSW]]	;SWITCH ANOTHER POSSIBILITY
	CAIN P4,X%SU		;USE CORRECT SWITCH TABLE
	 MOVEI B,[FLDDB. .CMCFM,,,,,[
		FLDDB. .CMSWI,,$ISBSW]]
	CALL FLDSKP		;GET SOME INPUT
	 CMERRX
	GTFLDT D		;GET DATA TYPE
	CAIN D,.CMSWI		;SWITCH?
	 JRST ISWI		;YES
	CALL QUASND		;SEND REQUEST OFF TO QUASAR
	MOVEM A,QIDX		;REMEMBER ID
	CALL REQX		;ANYTHING IN THE QUEUE?
	CALLRET DONREQ		;ALL DONE,CLEAN UP

;SWITCHES FOR INFORMATION (ABOUT) BATCH OR OUTPUT REQUESTS
DEFINE SLIST
   <	JOBS <T all>		;LIST ALL SWITCHES
	JOBS <T fast>		;OMIT ALL SWITCHES
	JOBS <TV processing-node,,.LNODE>,B%SU
	JOBS <TV user>
       >

;SWITCHES FOR OUTPUT-REQUESTS
	WUTCMD==B%PR		;SPECIFY NOT SUBMIT
$IPRSW:	TABLE
	BUILDJ
	TEND

;SWITCHES FOR INFO BATCH
	WUTCMD==B%SU		;SPECIFY SUBMIT
$ISBSW:	TABLE
	BUILDJ
	TEND

;SWITCH TYPED
ISWI:	CALL EXSWI		;EXECUTE SWITCH
	JRST IPR12		;GO BACK FOR MORE INPUT

;/FAST CAUSES SWITCHES NOT TO BE LISTED
.FAST:	MOVX A,1		;SAY /FAST
	STOR A,LS.FST,.OFLAG(P1) ;TELL QUASAR
	RET

;/ALL CAUSES ALL SWITCHES TO BE LISTED
.ALL:	MOVX A,1		;SAY /ALL
	STOR A,LS.ALL,.OFLAG(P1)
	RET

;/USER:NAME CAUSES ONLY REQUESTS BY SPECIFIED USER TO BE LISTED
.USER:	HELPX <Name of user whose requests are to be listed>
	TLZ Z,F1		;ALLOW DEFAULTING TO LOGGED-IN USER NAME
	CALL USRNAM		;GET THE USER NAME
	 ERROR <Invalid USER name>
	MOVE A,C		;USER NUMBER IN A
	MOVE B,[2,,.LSUSR]	;SPECIFY USER NAME
	CALLRET STASH		;STASH SPECIFIED USER NAME

;/NODE:NAME CAUSES ONLY ENTRIES FOR SPECIFIED NODE TO BE LISTED
.LNODE:	FNODEX <Name of node whose entries should be listed>
	 CMERRX
	CALL GETSXB		;GET SIXBIT VERSION OF NAME
	MOVE B,[2,,.ORNOD]	;GET LENGTH OF BLOCK AND TYPE
;	CALLRET STASH		;STASH THE BLOCK AND RETURN

;ROUTINE TO STASH A BLOCK FOR GETTING INFORMATION FROM QUASAR
;
;   ACCEPTS:	A/	DATA WORD
;		B/	BLK LEN,,FLAVOR
STASH:	STKVAR <FLV,LEN,DW>
	MOVEM A,DW		;REMEMBER DATA WORD
	HLRZM B,LEN		;REMEMBER LENGTH
	HRRZM B,FLV		;REMEMBER FLAVOR
	MOVE A,LEN		;GET LENGTH OF NEW BLOCK
	LOAD A,AR.LEN,ARG.HD(P2);GET LENGTH OF PREVIOUS BLOCK
	ADDB P2,A		;ADVANCE POINTER BEYOND THAT BLOCK
	ADD A,LEN		;GET ADDRESS BEYOND NEW BLOCK
	CAILE A,1000(P1)	;DOES EVERYTHING FIT?
	 ERROR <Too many switches>
	SUB A,P1		;COMPUTE NEW ENTIRE MESSAGE LENGTH
	STOR A,MS.CNT,.MSTYP(P1);STORE NEW LENGTH
	MOVE A,LEN		;GET LENGTH OF NEW BLOCK
	STOR A,AR.LEN,ARG.HD(P2);STORE LENGTH OF NEW BLOCK
	MOVE A,FLV
	STOR A,AR.TYP,ARG.HD(P2);STORE FLAVOR OF NEW BLOCK
	MOVE A,DW
	MOVEM A,ARG.DA(P2)	;STORE DATA WORD
	AOS .OARGC(P1)		;KEEP TRACK OF HOW MANY BLOCKS
	RET

DONREQ:	CALL UNMAP		;UNMAP SPECIAL PAGES
	RET			;RETURN TO CALLER

;ASK FOR OUTPUT-REQUEST LIST
PRLSTQ:	MOVX A,MSHSIZ+.OHDRS+2	;INITIAL SIZE OF REQUEST
	STOR A,MS.CNT,.MSTYP(P1)
	MOVX A,.QOLIS		;WE WANT A LIST
	STOR A,MS.TYP,.MSTYP(P1)
	SETZM .OFLAG(P1)	;NO FLAGS YET
	MOVX A,1		;WE'RE SENDING ONE BLOCK
	MOVEM A,.OARGC(P1)
	MOVX A,2		;ARG BLOCK LENGTH IS 2
	STOR A,AR.LEN,.OHDRS+ARG.HD(P1)
	MOVX A,.LSQUE		;WE WANT TO LIST THE QUEUES
	STOR A,AR.TYP,.OHDRS+ARG.HD(P1)
	MOVEI P2,.OHDRS(P1)	;INITIAL "LAST BLOCK" ADDRESS
	MOVX A,LIQBAT		;FIRST ASSUME BATCH
	CAIN P4,X%PR		;BUT IF DOING OUTPUT REQUESTS,
	 MOVX A,LIQOUT		;THEN SPECIFY THAT
	CAIN P4,X%MO		;MOUNTS?
	 MOVX A,LIQMNT		;YES
	CAIN P4,X%RE		;RETRIEVES?
	 MOVX A,LIQRET		;YES
	MOVEM A,.OHDRS+ARG.DA(P1)
	RET

;ROUTINE TO PRINT QUEUES
REQX:	STKVAR <ARGCNT>
	SETZ P2,		;DENOTES THAT NO POINTER TO LIST ENTRIES IS SET
				;   UP YET 
REQ:	JUMPE P2,REQ9		;IF NO POINTER YET, THEN GO READ NEXT PAGE FROM
				;   QUASAR 
	SOSG ARGCNT		;ANY MORE BLOCKS LEFT?
	 JRST  [MOVX A,WT.MOR	;GET BIT FOR CHECKING FOR MORE
		TDNN A,IPCFP+.OFLAG
		 RET		;NO MORE, SO RETURN
		JRST REQ9]	;AT LEAST ONE MORE PAGE, GO GET IT
	LOAD A,AR.LEN,ARG.HD(P2) ;GET SIZE OF BLOCK JUST PROCESSED
	ADD P2,A		;STEP TO NEXT BLOCK
REQ1:	LOAD A,AR.TYP,ARG.HD(P2) ;GET FLAVOR OF ARG
	CAIE A,.CMTXT		;ONLY PRINT TEXT
	 JRST REQ		;SKIP OTHER TYPES FOR NOW
	UTYPE ARG.DA(P2)	;PRINT QUEUES LISTING
	JRST REQ		;GO GET THE REST

REQ9:	CALL GQPID		;GET QUASAR'S PID
	MOVE B,QIDX		;SAY WHICH MESSAGE WE WANT
	CALL IPCRCV		;RECEIVE NEXT PAGE OF DATA
	MOVE A,IPCFP+.OARGC
	MOVEM A,ARGCNT		;INITIALIZE NUMBER OF ARG BLOCKS AVAILABLE
	MOVEI P2,IPCFP+.OHDRS	;GET TO FIRST BLOCK
	JRST REQ1		;GO PROCESS THE BLOCKS

;INITIALIZATION ROUTINE FOR PRINTING QUEUES.
IPRINI:	MOVEI P1,BUF0		;ADDRESS OF IPCF PAGE FOR SENDING LISTING
				;   REQUEST TO QUASAR 
	RET

IDEADL:	PSWITCH <deadline:%2D %E>

IAFTER:	PSWITCH <after:%2D %E>

;ROUTINE TO PRINT NOTE. CALL WITH SIXBIT IN B'C.
INOTE:	HRROI A,[ASCIZ/note/]	;SAY DOING /NOTE
	CALLRET ICOMON		;USE COMMON ROUTINE

;ROUTINE TO PRINT DOUBLE SIXBIT SWITCH VALUE
;   OUTPUTS THE SWITCH IN A FORMAT THAT COULD BE INPUT WITH, I.E. WITH QUOTES
;   AROUND THE VALUE IF NECESSARY. 
;
;   ACCEPTS:	A/	ROUTINE POINTER TO NAME OF SWITCH
;		B,C/	DOUBLE SIXBIT DATA
;
ICOMON:	STKVAR <<SAVDAT,2>,NAMPT>
	MOVEM A,NAMPT		;REMEMBER POINTER TO NAME OF SWITCH
	DMOVE A,B		;MOVE NOTE INTO A'B
	DMOVEM A,SAVDAT		;SAVE THE DATA
PRN1:	LDB C,[POINT 6,A,5]	;LOOK AT NEXT CHARACTER OF NOTE
	CAIL C,'A'
	 CAILE C,'Z'
	  ABSKP
	   JRST PRN2		;LETTERS ARE ALWAYS ALL RIGHT
	CAIN C,'-'
	 JRST PRN2		;HYPHEN LEGAL TOO
	CAIL C,'0'
	 CAILE C,'9'
	  ABSKP
	   JRST PRN2		;DIGITS ALL RIGHT WITHOUT QUOTES TOO
	JUMPN C,PRN3		;PUT NOTE IN QUOTES IF FUNNY CHARACTER IN IT
	JUMPN A,PRN3
	JUMPN B,PRN3		;IF WE SEE AN IMBEDDED SPACE, JUMP
PRN4:	DMOVE B,SAVDAT		;NO IMBEDDED SPACES IN THE NOTE
	MOVE D,NAMPT		;GET POINTER TO NAME
	PSWITCH <%4M:%2'%%3'>

PRN2:	LSHC A,6		;WE'VE SEEN ALL NON-SPACES SO FAR, LOOK AT NEXT
				;   CHAR 
	JUMPN A,PRN1		;MAKE SURE THERE ARE SOME MORE!
	JUMPN B,PRN1
	JRST PRN4		;NO SPACES SEEN IN NOTE

PRN3:	MOVE D,NAMPT		;GET POINTER TO NAME
	ETYPE </%4M:">
	SETZ D,			;NULL FOR FINDING LAST NON-NULL CHARACTER OF
				;   NOTE 
	MOVE A,[POINT 6,SAVDAT]
PRN5:	CAMN A,[POINT 6,1+SAVDAT,35]
	 JRST PRN6		;DONE IF WE'VE DONE ALL TWELVE CHARACTERS
	ILDB B,A		;GET CHARACTER
	ADDI B,40		;CHANGE TO ASCII
	CALL COUTC		;TYPE CHARACTER
	CAIN B,""""		;QUOTE MARK IN NOTE?
	CALL COUTC		;YES, SO TYPE IT TWICE
	DPB D,A			;CLEAR OUT CHARACTER WE JUST PRINTED
	SKIPN SAVDAT
	 SKIPE 1+SAVDAT
	  JRST PRN5		;JUMP BACK FOR REST OF CHARACTERS

PRN6:	TYPE <" >		;TERMINATING QUOTE FOR SPECIAL NOTE
	RET			;DONE FINALLY!

IPRIOR:	PSWITCH <priority:%2Q>

IDESTI:	PSWITCH <destination-node:%2'::>

IPROCE:	PSWITCH <processing-node:%2'::>

;NODE WHERE BATCH JOB SHOULD BE RUN
.PN:	CALL GPNODE		;READ NODE NAME
	MOVE A,[IPROCE,,PNODE2]
	CALLRET STOR1

PNODE2:	MOVEM B,.EQROB+.ROBND(P1) ;STORE PROCESSING NODEE FOR QUASAR
	RET

GPNODE:	FNODEX <Network node where batch job should be run>
	 JRST GNODEA		;USE COMMON CODE FOR REST
	JRST GNODEB

;NODE SPECIFICATION
.NODE:	CALL GDNODE		;GET THE NODE
	MOVE A,[IDESTI,,NODE2]
	CALLRET STOR1		;REMEMBER IT

NODE2:	CAIE P4,X%SU		;DIFFERENT PLACE TO STASH DESTINATION NODE OF
				;   LOG FILE 
	 MOVEM B,.EQROB+.ROBND(P1)
	CAIN P4,X%SU
	 STOLIM B,.EQLIM(P1),ONOD
	RET

GDNODE:	FNODEX <Network node to receive output>
GNODEA:	 CMERRX <Invalid node>
GNODEB:	CALL GETSXB		;GET SIXBIT OF NODE
	MOVE B,A
	RET

;SPECIFIC UNIT NUMBER
.UNIT:	CALL GUNIT		;GET UNIT
	MOVE A,[IUNIT,,UNIT2]
	CALLRET STOR1

UNIT2:	STOR B,RO.UNI,.EQROB+.ROBAT(P1)
	MOVX A,1		;SAY "PHYSICAL UNIT SUPPLIED"
	STOR A,RO.PHY,.EQROB+.ROBAT(P1)
	RET

IUNIT:	PSWITCH <unit:%2O>

GUNIT:	OCTX <Octal unit number>
	 CMERRX <Invalid unit number>
	VERIFY B,C,RO.UNI	;MAKE SURE UNIT FITS IN FIELD
	 ERROR <Unit number out of range>
	RET

IFORMS:	PSWITCH <forms:%2'>

ITIME:	MOVE A,B		;GET NUMBER OF SECONDS IN A
	IDIVI A,^D3600		;LEAVE HOURS IN A, REST IN B
	IDIVI B,^D60		;LEAVE MINUTES IN B, SECONDS IN C
	PSWITCH <time:%1Q:%2Q:%3Q>

IASSIS:	HRROI C,[ASCIZ/no/]
	CAIE B,0
	 HRROI C,[ASCIZ/yes/]
	PSWITCH <assistance:%3M>

IRESTA:	HRROI C,[ASCIZ/no/]	;FIRST ASSUME NO
	CAIE B,0		;IS IT?
	 HRROI C,[ASCIZ/yes/]	;NO, YES
	PSWITCH <restartable:%3M>

IUNIQU:	HRROI C,[ASCII/NO/
		ASCII/YES/](B)
	PSWITCH <unique:%3M>
;MODIFY (REQUEST TYPE) REQUEST-TYPE (JOBNAME) JOBNAME /SW/SW/SW/SW

.MODIF::PRISTG			;ALLOCATE STORAGE
	CALL MODINI		;INITIALIZE MODIFY BLOCK
	CALL GQUEM		;GET CORRECT QUEUE NAME
	MOVEM B,IPCFP+MOD.OT
	NOISE <ID>
	SETZM ATMBUF		;FIRST ASSUME NO JOBNAME SPECIFIED
	CALL GJOB1		;GET MASK FOR NULL NAME
	MOVEM B,IPCFP+MOD.RQ+.RDBJB	;STORE JOB NAME, NULL
	MOVEM C,IPCFP+MOD.RQ+.RDBJM	;STORE MASK
	MOVEI B,[FLDDB. .CMNUM,CM%SDH,^D10,<a request ID number>,,[
		FLDBK. .CMFLD,CM%SDH,,<a jobname, six characters or less
  or * for all jobs>,,[BRMSK. FLDB0.,FLDB1.,FLDB2.,FLDB3.,<*%>]]]
	CALL FLDSKP		;READ NUMBER OR WORD
	 CMERRX
	GTFLDT C		;SEE WHAT WAS TYPED
	CAIN C,.CMNUM		;NUMBER?
	 JRST  [MOVEM B,IPCFP+MOD.RQ+.RDBRQ	;YES, REMEMBER IT
		JRST MOD1]	;GO GET REST OF SWITCHES
	CALL GJOB1		;JOBNAME, PROCESS IT
	MOVEM B,IPCFP+MOD.RQ+.RDBJB	;STORE JOB NAME
	MOVEM C,IPCFP+MOD.RQ+.RDBJM	;STORE MASK
MOD1:	MOVEI B,[FLDDB. .CMCFM,,,,,[
		FLDDB. .CMSWI,,$MODO,<a switch, or parameter to modify,>]]
	CAIN P4,X%SU		;DIFFERENT switch TABLE IF MODIFYING BATCH
				;   REQUEST 
	 MOVEI B,[FLDDB. .CMCFM,,,,,[
		FLDDB. .CMSWI,,$MODSU,<a switch, or parameter to modify,>]]
	CAIN P4,X%PR		;USE CORRECT SWITCH LIST
	 MOVEI B,[FLDDB. .CMCFM,,,,,[
		FLDDB. .CMSWI,,$MODPR,<a switch, or parameter to modify,>]]
	CALL FLDSKP		;READ END OF LINE OR SWITCH
	 CMERRX <Invalid MODIFY command>
	GTFLDT D		;SEE WHAT TYPE OF ITEM GOT READ
	CAIN D,.CMCFM		;END OF LINE?
	 JRST MODEOL		;YES
	JRST MODSWI		;NO, ASSUME A SWITCH

;GET QUEUE NAME
GQUE:	NOISE <request type>
	KEYWD $QUEUE
	 0			;NO DEFAULT
	 CMERRX <Invalid request type>
GQUE1:	HLRZ B,(P3)		;GET QUEUE NAME
	HRRZ P4,(P3)		;P4 REMEMBERS THE QUEUE NAME
	RET

GQUEM:	NOISE <request type>
	KEYWD $MQUEU
	 0			;NO DEFAULT
	 CMERRX <Invalid request type>
	JRST GQUE1


;TEMP DEFN OF .OTARC SINCE NOT REALLY USED
	.OTARC==73

$QUEUE:	TABLE
	T archive,,[.OTARC,,X%AR]
	T batch,,[.OTBAT,,X%SU]
ONEON <CDRD,CDPD,DECN>,<	;;713
	T cards,,[.OTCDP,,X%CP]> ;713
	T mount,,[.OTMNT,,X%MO]
ONEON <DECN,PTRD,PTPD>,<	;;713
	T paper-tape,,[.OTPTP,,X%TP]> ;713
ONEON <DECN,PLTD>,<		;;713
	T plot,,[.OTPLT,,X%PL]>	;713
ONEON <DECN,LPTD>,<		;;713
	T print,,[.OTLPT,,X%PR]> ;713
	T retrieve,,[.OTRET,,X%RE]
	TEND

$MQUEU:	TABLE
	T batch,,[.OTBAT,,X%SU]
ONEON <CDRD,CDPD>,<		;;713
	T cards,,[.OTCDP,,X%CP]> ;713
ONEON <PTRD,PTPD>,<		;;713
	T paper-tape,,[.OTPTP,,X%TP]> ;713
ONEON <DECN,PLTD>,<		;;713
	T plot,,[.OTPLT,,X%PL]>	;713
ONEON <DECN,LPTD>,<		;;713
	T print,,[.OTLPT,,X%PR]> ;713
	TEND

;INITIALIZE IPCFP BLOCK FOR MODIFY MESSAGE
	G0SIZ==20
	G1SIZ==20		;SIZE OF GROUPS

MODINI:	MOVX A,MSHSIZ+1+RDBSIZ+G0SIZ+G1SIZ
	STOR A,MS.CNT,IPCFP	;STORE MESSAGE SIZE (THE "1" IS FOR THE QUEUE
				;   NAME) 
	MOVX A,.QOMOD		;SPECIFY THAT THIS IS A MODIFY REQUEST
	STOR A,MS.TYP,IPCFP
	SETZM IPCFP+MOD.RQ	;CLEAR OUT DESCRIPTOR BLOCK
	MOVE A,[IPCFP+MOD.RQ,,IPCFP+MOD.RQ+1]
	BLT A,IPCFP+MOD.RQ+RDBSIZ-1
	SETOM IPCFP+MOD.FG	;FILL IN -1'S INITIALLY TO MEAN "DON'T MODIFY
				;   THIS PARAMETER" 
	MOVE A,[IPCFP+MOD.FG,,IPCFP+MOD.FG+1]
	BLT A,IPCFP+MOD.FG+G0SIZ+G1SIZ-1
	MOVEI P1,IPCFP+MOD.FG+1	;GROUP 0 POINTER
	MOVEI P2,G0SIZ(P1)	;LEAVE ROOM FOR GROUP 0 AND POINT TO GROUP 1
	MOVX A,G0SIZ
	STOR A,MODGLN,IPCFP+MOD.FG ;FILL IN SIZE OF BLOCK
	MOVX A,.GPMAJ		;FIRST BLOCK IS MAJOR PARAMETERS
	STOR A,MODGPN,IPCFP+MOD.FG ;FILL IN GROUP TYPE
	MOVX A,G1SIZ
	STOR A,MODGLN,IPCFP+MOD.FG+G0SIZ ;NUMBER OF MINOR GROUP (GROUP 1)
				;   ELEMENTS 
	MOVX A,.GPQUE		;PARAMETER TYPE
	STOR A,MODGPN,IPCFP+MOD.FG+G0SIZ
	RET

;END OF LINE SEEN, SEND OFF MODIFY REQUEST
MODEOL:	CALL QUASND		;COMMUNICATE WITH QUASAR
	CALLRET UNMAP		;CLEAN UP AND RETURN

;SWITCH TYPED DURING MODIFY COMMAND
MODSWI:	CALL EXSWI		;EXECUTE THE SWITCH
	JRST MOD1		;LOOP BACK FOR MORE INPUT

;SWITCH EXECUTION ROUTINE
EXSWI:	CALL GETKEY		;GET KEYWORD DATA
	CALLRET (P3)		;EXECUTE SWITCH

;MODIFY AFTER PARAMETER
.MAFTE:	CALL GAFT		;GET NEW AFTER PARAMETER
	MOVEM B,(P1)		;AFTER IS WORD 0 OF GROUP 0
	RET

;MODIFY DEADLINE
.MDEAD:	CALL GDEAD		;GET NEW PARAMETER
	MOVEM B,2(P1)		;WORD 2, GROUP 0
	RET

;MODIFY DEPENDENCY-COUNT
.MDEPE:	DECX <Decimal DEPENDENCY-COUNT, +n or -n for change, or n for 
absolute setting>
	 CMERRX <Invalid DEPENDENCY-COUNT>
	MOVX A,.MODAB		;FIRST ASSUME AN ABSOLUTE VALUE SUPPLIED
	CAIGE B,0		;BUT IF NEGATIVE NUMBER TYPED,
	 MOVX A,.MODMI		;THEN VALUE IS SUBTRACTIVE
	MOVM B,B		;KEEP ONLY POSITIVE VALUE
	LDB C,[FIRCHR ATMBUF]	;GET FIRST CHARACTER OF NUMBER AS TYPED BY USER
	CAIN C,"+"		;PLUS SIGN GIVEN?
	 MOVX A,.MODPL		;YES, SO QUANTITY IS ADDITIVE
	VERLIM B,SCRLIM,DEPN	;MAKE SURE NUMBER FITS IN ALLOTTED FIELD
	 ERROR <DEPENDENCY-COUNT out of range>
	HRL B,A			;PUT TYPE CODE IN WITH VALUE
	MOVEM B,6(P2)		;WORD 6 GROUP 1
	RET

;DESTINATION NODE OF LOG FILE
.MNODE:	CALL GDNODE		;GET NODE NAME
	MOVEM B,5(P1)		;SAVE IN GROUP 0 (MAJOR MOD)
	RET

;/LOWERCASE /UPPERCASE /GENERIC
.MLOWE:	MOVX A,OBDLLC
	JRST MCASE

.MGENE:	TDZA A,A
.MUPPE:	 MOVX A,OBDLUC
MCASE:	SETZM 4(P1)		;DEFAULT TO /GENERIC
	IORM A,4(P1)		;TURN ON NEW BITS
	RET

;OUTPUT DEVICE UNIT
.MUNIT:	CALL GUNIT
	STOR B,RO.UNI,4(P1)
	MOVX A,1		;SAY SPECIFIC UNIT SUPPLIED
	STOR A,RO.PHY,4(P1)
	RET

;PROCESSING-NODE FOR BATCH JOB (WHERE IT GETS RUN!)
.MPNOD:	CALL GPNODE
	MOVEM B,5(P1)
	RET

;FORMS
.MFORM:	CALL GFORMS
	MOVEM B,(P2)
	RET

;LIMIT
.MLIMI:	CALL GLIM
	XCT    [MOVEM B,1(P2)		;CARDS
		MOVEM B,1(P2)		;PRINT
		MOVEM B,2(P2)		;SUBMIT
		MOVEM B,1(P2)		;PAPER-TAPE
		MOVEM B,1(P2)](P4)	;PLOT
	RET

;NOTE
.MNOTE:	CALL GNOTE
	DMOVEM B,2(P2)
	RET

;HEADER, NOHEADER
.MNOHE:	TDZA A,A
.MHEAD:	 MOVX A,1
	MOVEM A,4(P2)
	RET

;SPACING
.MSPAC:	CALL GSPACE
	MOVEM B,5(P2)
	RET

;MODE
.MMODE:	CALL GMODE
	MOVEM B,6(P2)
	RET

;FILE STYLE
.MFILE:	CALL GFILE
	MOVEM B,7(P2)
	RET

;.MPRES: PRESERVE FILE AFTER PROCESSING
;.MDELE: DELETE FILE AFTER PROCESSING
.MPRES:	TDZA A,A
.MDELE:	 MOVX A,1
	MOVEM A,10(P2)
	RET

;NUMBER OF COPIES
.MCOPI:	CALL GCOPIE
	MOVEM B,11(P2)
	RET

;REPORT CODE TO START PRINTING AT
.MREPO:	CALL GREPOR
	DMOVEM B,12(P2)
	RET

;PAGE TO BEGIN PRINTING ON
.MPBEG:	CALL GPBEG
	MOVEM B,14(P2)
	RET

;PRIORITY
.MPRIO:	CALL GPRIO
	MOVEM B,1(P1)
	RET

;RESTART PARAMETER
.MREST:	CALL GRES
	CALL RESCVT		;CONVERT IT INTO QUASAR FORM
	MOVEM B,8(P2)
	RET

;LINE NUMBER TO BEGIN ON IN CONTROL FILE
.MSBEG:	CALL GSBEG		;READ NUMBER
	MOVEM B,12(P2)		;REMEMBER
	RET

;NUMBER OF SPOOLED PAGES TO ALLOW BATCH JOB TO PRINT
.MPAGE:	CALL GPAGES
	MOVEM B,2(P2)
	RET

;NUMBER OF SPOOLED CARDS JOB MAY PUNCH
.MCARD:	CALL GCARDS
	MOVEM B,3(P2)
	RET

;NUMBER OF FEET OF SPOOLED PAPERTAPE JOB MAY PUNCH
.MFEET:	CALL GFEET
	MOVEM B,4(P2)
	RET

;NUMBER OF MINUTES OF SPOOLED PLOTTER TIME JOB MAY REQUEST
.MTPLO:	CALL GTPLOT
	MOVEM B,5(P2)
	RET

;OUTPUT STATUS OF LOG FILE
.MOUTP:	CALL GOUTPU
	MOVEM B,9(P2)
	RET

;DESTINATION-NODE FOR LOG FILE
.MSNOD:	CALL GDNODE
	MOVEM B,13(P2)
	RET

;TIME
.MTIME:	CALL GTIME
	MOVEM B,1(P2)
	RET

;UNIQUENESS
.MUNIQ:	CALL GUNI
	CALL CVTUNI		;CONVERT TO QUASAR VALUE
	MOVEM B,7(P2)
	RET

;SWITCH TO HANDLE CASES LIKE "MODIFY PRINT /JOBNAME:5", WHICH IS THE ONLY WAY
;   TO MODIFY A BUNCH OF JOBS CALLED "5", SINCE "MODIFY PRINT 5" WOULD REFER TO
;   THE SPECIFIC JOB WHOSE REQUEST ID IS 5! 
.MJOB:	CALL GJOB		;READ THE JOB NAME
	MOVEM B,IPCFP+MOD.RQ+.RDBJB	;STORE JOB NAME
	MOVEM C,IPCFP+MOD.RQ+.RDBJM	;STORE MASK
	RET

;PRIVILEGED USERS MAY SPECIFY /USER TO SPECIFY WHOSE REQUEST IS BEING MODIFIED
.MUSER:	USERX <User who owns request(s) being modified>
	 CMERRX <Invalid request owner>
	HRROI A,IPCFP+MOD.RQ+.RDBOW ;STORE OWNER IDENTIFIER
	DIRST			;STORE USER NAME
	 ERCAL CJERRE		;IF FAILS, TELL USER WHY
	RET

;SPECIFY SEQUENCE NUMBER OF JOB BEING MODIFIED
.MSEQ:	CALL GSEQ		;GET SEQUENCE NUMBER
	MOVEM B,IPCFP+MOD.RQ+.RDBES ;STORE SEQUENCE NUMBER
	RET

;SWITCHES FOR MODIFYING OUTPUT REQUESTS
DEFINE SLIST 
   <	JOBS <TV after,,.MAFTE>
	JOBS <TV begin,,.MSBEG>,B%SU
ONEON <DECN,LPTD>,<			;;713
	JOBS <TV begin,,.MPBEG>,B%PR>	;;713
ONEON <CDPD,DECN>,<			;;713
	JOBS <TV cards,,.MCARDS>,B%SU>	;;713
	JOBS <TV copies,,.MCOPI>,,B%SU
DELETE,<JOBS <TV deadline,,.MDEAD>>
	JOBS <T delete,,.MDELE>,,B%SU
	JOBS <TV dependency-count,,.MDEPE>,B%SU
DECN,<	JOBS <TV destination-node,,.MNODE>,,B%SU ;;713
	JOBS <TV destination-node,,.MSNOD>,B%SU ;;713
       >				;;713
ONEON <DECN,PTPD>,<			;;713
	JOBS <TV feet,,.MFEET>,B%SU>	;;713
ONEON <DECN,LPTD>,<			;;713
	JOBS <TV file,,.MFILE>,B%PR>	;;713
	JOBS <TV forms,,.MFORM>,,B%SU
	JOBS <T generic,,.MGENE>,,B%SU
	JOBS <T header,,.MHEAD>,,B%SU
	JOBS <TV jobname,,.MJOB>
ONEON <DECN,LPTD>,<			;;713
	JOBS <TV limit,,.MLIMI>,,B%SU	;;713
	JOBS <T lowercase,,.MLOWE>,B%PR	;;713
       >				;;713
	JOBS <TV mode,,.MMODE>,,B%SU
	JOBS <T noheader,,.MNOHE>,,B%SU
	JOBS <TV note,,.MNOTE>,,B%SU
	JOBS <TV output,,.MOUTP>,B%SU
ONEON <DECN,LPTD>,<			;;713
	JOBS <TV pages,,.MPAGE>,B%SU>	;;713
	JOBS <T preserve,,.MPRES>
	JOBS <TV priority,,.MPRIO>
DECN,<	JOBS <TV processing-node,,.MPNOD>,B%SU> ;;713
ONEON <DECN,LPTD>,<			;;713
	JOBS <TV report,,.MREPO>,B%PR>	;;713
	JOBS <TV restartable,,.MREST>,B%SU
	JOBS <TV sequence,,.MSEQ>
ONEON <DECN,LPTD>,<			;;713
	JOBS <TV spacing,,.MSPAC>,B%PR>	;;713
	JOBS <TV time,,.MTIME>,B%SU
ONEON <DECN,PLTD>,<			;;713
	JOBS <TV tplot,,.MTPLO>,B%SU>	;;713
	JOBS <TV unique,,.MUNIQ>,B%SU
	JOBS <TV unit,,.MUNIT>,,B%SU
ONEON <DECN,LPTD>,<			;;713
	JOBS <T uppercase,,.MUPPE>,B%PR> ;;713
	JOBS <TV user,,.MUSER>
       >			;end SLIST

;TABLE OF MODIFY SWITCHES FOR PRINT
	WUTCMD==B%PR		;SPECIFY PRINT COMMAND
$MODPR:	TABLE
	BUILDJ			;BUILD TABLE OF FILE SWITCHES
	TEND

;TABLE OF MODIFY SWITCHES FOR SUBMIT
	WUTCMD==B%SU		;SPECIFY SUBMIT
$MODSU:	TABLE
	BUILDJ
	TEND

;TABLE OF MODIFY SWITCHES FOR EVERYTHING ELSE
	WUTCMD==0		;CATCH-ALL VALUE
$MODO:	TABLE
	BUILDJ
	TEND
;CANCEL (REQUEST TYPE) TYPE NAME /SW/SW/SW
.CANCE::PRISTG			;ALLOCATE STORAGE
	CALL KILINI		;INITIALIZE
	SETZM JNGF		;NO JOBNAME GIVEN YET
	CALL GQUE		;GET QUEUE NAME
	CAIN P4,X%AR		;CANCEL ARCHIVE?
	 JRST CANARC		;YES, GO TO EXEC1 TO DO THAT
	MOVEM B,IPCFP+KIL.OT	;STORE IT
	NOISE <ID>
	MOVSI A,[FLDBK. .CMFLD,CM%SDH,,<Name of request, six characters or 
less,
  or * to cancel all requests>,,[BRMSK. FILB0.,FILB1.,FILB2.,FILB3.]]
	HRRI A,FBLOCK		;PREPARE TO COPY BLOCK
	BLT A,FBLOCK+FBLLEN-1
	MOVEI B,[FLDDB. .CMSWI,,CSOTAB,,,[
		FLDDB. .CMNUM,CM%SDH,^D10,<a request ID number>,,FBLOCK]]
	CAIE P4,X%SU		;BATCH?
	 CAIN P4,X%MO		;OR MOUNT??
	  MOVE B,(B)		;YES, NO /SPOOLED-OUTPUT ALLOWED
	CAIN P4,X%RE		;CANCEL RETRIEVAL?
	 MOVE B,(B)		;YES, NO /SPOOL
	CALL FLDSKP		;GET SWITCH OR JOB NAME
	 CMERRX </SPOOLED-OUTPUT, request ID number,  or jobname required>
	GTFLDT C		;GET FLAVOR OF INPUT
	CAIN C,.CMSWI		;SWITCH?
	 JRST MCSO		;YES
	CAIN C,.CMNUM		;REQUEST ID TYPED?
	 JRST  [CAIG B,0		;7 SPR #:20-16176 zero cancels all
		 ERROR <Request ID must be positive> ;7
	 	MOVEM B,IPCFP+KIL.RQ+.RDBRQ ;YES, REMEMBER WHAT NUMBER WAS
				;   TYPED 
		SETOM JNGF	;PRETEND JOB NAME WAS GIVEN
		JRST KIL1]	;CHECK FOR SWITCHES
	MOVSI A,774000		;JOB NAME GIVEN.
	TDNN A,ATMBUF		;MAYBE "CANCEL PRINT /SWITCH"
	 JRST KIL1		;YES, NULL JOB NAME BEFORE SLASH DOESN'T COUNT!
	CALL GJOB1		;NO, JOBNAME.  GET INTERNAL FORM
	MOVEM B,IPCFP+KIL.RQ+.RDBJB
	MOVEM C,IPCFP+KIL.RQ+.RDBJM	;STORE NAME AND MASK
	SETOM JNGF		;REMEMBER JOB NAME GIVEN
KIL1:	MOVEI B,[FLDDB. .CMCFM,,,,,[
		FLDDB. .CMSWI,,$KILSW,<a switch,>]]
	CALL FLDSKP		;READ END OF LINE OR SWITCH
	 CMERRX <Invalid CANCEL command>
	GTFLDT D		;SEE WHAT TYPE OF ITEM GOT READ
	CAIN D,.CMCFM		;END OF LINE?
	 JRST KILEOL		;YES
	JRST KILSWI		;NO, ASSUME A SWITCH

MCSO:	CALL GETKEY		;SEE WHICH SWITCH
	CAIN P3,.CSO		;CANCELING SPOOLED OUTPUT?
	 JRST .CSO		;YES, GO DO IT
	CALL (P3)		;EXECUTE THE SWITCH
	JRST KIL1		;GET REST OF SWITCHES

;TABLE OF SWITCHES
CSOTAB:	TABLE
	T spooled-output,,.CSO	;CANCEL SPOOLED OUTPUT
	TEND

;SWITCH SEEN...
KILSWI:	CALL EXSWI		;EXECUTE THE SWITCH
	JRST KIL1		;GO BACK FOR MORE INPUT

;END OF LINE SEEN ON CANCEL COMMAND
KILEOL:	SKIPN JNGF		;MAKE SURE JOB NAME SPECIFIED
	 ERROR <Jobname or request ID required>
	CALL QUASND		;COMMUNICATE WITH QUASAR
	CALLRET UNMAP		;CLEAN UP AND RETURN

;SWITCH TABLE FOR CANCEL COMMAND
$KILSW:	TABLE
	TV jobname,,.KJOB
	TV sequence,,.KSEQ	;SPECIFY JOB SEQUENCE NUMBER
	TV user,,.KUSER
	TEND

;/JOBNAME TYPED ON KILL. FOR INSTANCE, IF THE USER HAS A BUNCH OF JOBS ALL OF
;   WHOSE NAME IS "5", HE KILLS THEM ALL WITH "CANCEL BATCH /JOBNAME:5". IN
;   THIS CASE, "CANCEL BATCH 5" LOSES, SINCE "5" IS INTERPRETED AS REQUEST ID
.KJOB:	CALL GJOB		;GET JOB NUMBER
	MOVEM B,IPCFP+KIL.RQ+.RDBJB
	MOVEM C,IPCFP+KIL.RQ+.RDBJM ;STORE NAME AND MASK
	SETOM JNGF		;REMEMBER THAT JOB NAME GIVEN
	RET

;SPECIFY WHOSE REQUEST IS TO BE KILLED (MUST BE ENABLED FOR SOMEONE ELSE TO BE
;   SPECIFIED) 
.KUSER:	USERX <User who owns request being canceled>
	 CMERRX <Invalid request owner>
	HRROI A,IPCFP+MOD.RQ+.RDBOW	;STORE OWNER IDENTIFIER
	DIRST			;STORE USER NAME
	 ERCAL CJERRE		;IF FAILS, TELL USER WHY
	RET

;SPECIFY JOB SEQUENCE NUMBER IN CANCEL COMMAND
.KSEQ:	CALL GSEQ		;GET SEQUENCE NUMBER FOR KILL REQUEST
	MOVEM B,IPCFP+KIL.RQ+.RDBES	;STORE SEQUENCE NUMBER
	RET

;INITIALIZATION ROUTINE FOR KILL COMMAND
KILINI:	MOVX A,MSHSIZ+1+RDBSIZ
	STOR A,MS.CNT,IPCFP	;STORE MESSAGE SIZE (THE "1" IS FOR THE QUEUE
				;   NAME) 
	MOVX A,.QOKIL		;SPECIFY THAT THIS IS A KILL REQUEST
	STOR A,MS.TYP,IPCFP
	SETZM IPCFP+KIL.RQ	;CLEAR OUT DESCRIPTOR BLOCK
	MOVE A,[IPCFP+KIL.RQ,,IPCFP+KIL.RQ+1]
	BLT A,IPCFP+KIL.RQ+RDBSIZ-1
	RET
;SET DEFAULT (FOR) CARDS
;SET DEFAULT (FOR) PRINT
;SET DEFAULT (FOR) SUBMIT
;SET DEFAULT (FOR) PAPER-TAPE
;SET DEFAULT (FOR) PLOT

.SDPL::	MOVX P4,X%PL
	JRST SD1

.SDC::	MOVX P4,X%CP
	JRST SD1		;PUNCH CARDS

.SDT::	MOVX P4,X%TP		;PUNCH PAPER-TAPE
	JRST SD1

.SDS::	MOVX P4,X%SU
	JRST SD1

.SDP::	MOVX P4,X%PR
SD1:	PRISTG			;ALLOCATE STORAGE
	SETOM SDF		;REMEMBER THAT WE'RE SETTING DEFAULTS
	MOVE A,[IOWD QSLEN,DCSTK
		IOWD QSLEN,DPSTK
		IOWD QSLEN,DSSTK
		IOWD QSLEN,DTSTK
		IOWD QSLEN,DPLSTK](P4)	;NO, INITIALIZE IT
	MOVEM A,IQPT		;REMEMBER INITIAL POINTER FOR STOR1
	SKIPN B,@[DCPT
		DPPT
		DSPT
		DTPT
		DPLPT](P4)	;PREVIOUS POINTER?
	 MOVE B,A		;NO, USE INITIAL POINTER
	MOVEM B,QPT		;SAVE STACK POINTER FOR ARGS
	SETZM ANYS		;SAY NO SWITCHES SEEN YET
SD2:	MOVE B,[SDCFDB
		SDPFDB
		SDSFDB
		SDTFDB
		SDPLFB](P4)	;DIFFERENT CHOICES FOR DIFFERENT COMMANDS
	SKIPN ANYS		;ANY SWITCHES TYPED YET?
	 MOVE B,(B)		;NO, SO CR NOT ALLOWED YET
	CALL FLDSKP		;GET SOME INPUT
	 JRST BADDEF		;BAD DEFAULT VALUE TYPED
	GTFLDT D		;FIND OUT WHAT GOT TYPED
	CAIN D,.CMCFM		;END OF LINE?
	 JRST SDEOL		;YES
	SETOM ANYS		;MARK THAT SWITCHES HAVE BEEN SEEN
	CALL EXSWI		;SWITCH TYPED, EXECUTE IT
	JRST SD2		;GO BACK FOR MORE DEFAULTS

BADDEF:	XCT    [CMERRX <Invalid SET DEFAULT CARDS command>
		CMERRX <Invalid SET DEFAULT PRINT command>
		CMERRX <Invalid SET DEFAULT SUBMIT command>
		CMERRX <Invalid SET DEFAULT PAPER-TAPE command>
		CMERRX <Invalid SET DEFAULT PLOT command>](P4)

;END OF LINE TYPED
SDEOL:	MOVE A,QPT		;GET FINAL POINTER TO DEFAULT LIST
	MOVEM A,@[DCPT
		DPPT
		DSPT
		DTPT
		DPLPT](P4)	;STORE POINTER IN CORRECT PLACE
	RET			;DONE

;SET NO DEFAULT (FOR) SUBMIT
.SNDS::	CONFIRM			;WAIT FOR COMMAND CONFIRMATION
	XMOVEI A,DSSTK		;XMOVEI IN CASE WE'RE IN ANOTHER SECTION
	XMOVEI B,DSPT		;SPECIFY ADDRESS OF STACK AND ADDRESS OF
				;   POINTER 
	CALL REMDEF		;RELEASE UP FREE SPACE
	ETYPE <All defaults for SUBMIT command cleared%_>
	RET

;SET NO DEFAULT (FOR) PAPER-TAPE
.SNDTP::CONFIRM			;WAIT FOR COMMAND CONFIRMATION
	XMOVEI A,DTSTK
	XMOVEI B,DTPT
	CALL REMDEF
	ETYPE <All defaults for PUNCH PAPER-TAPE command cleared%_>
	RET

;SET NO DEFAULT (FOR) PLOT
.SNDPL::CONFIRM			;WAIT FOR COMMAND CONFIRMATION
	XMOVEI A,DPLSTK
	XMOVEI B,DPLPT
	CALL REMDEF
	ETYPE <All defaults for PLOT command cleared%_>
	RET

;SET NO DEFAULT (FOR) CARDS
.SNDCP::CONFIRM			;WAIT FOR COMMAND CONFIRMATION
	XMOVEI A,DCSTK
	XMOVEI B,DCPT
	CALL REMDEF
	ETYPE <All defaults for PUNCH CARDS command cleared%_>
	RET

;SET NOT DEFAULT (FOR) PRINT
.SNDP::	CONFIRM
	XMOVEI A,DPSTK
	XMOVEI B,DPPT
	CALL REMDEF
	ETYPE <All defaults for PRINT command cleared%_>
	RET

;INFO DEF PLOT
.IDPL::	MOVX P4,X%PL
	JRST ID0

;INFORMATION (ABOUT) DEFAULTS (FOR) CARDS
.IDC::	MOVX P4,X%CP		;IDENTIFY
	JRST ID0		;JOIN COMMON CODE

;INFO DEF PAPER-TAPE
.IDP::	MOVX P4,X%TP
	JRST ID0

;INFO DEF PRINT
.IDPRT::MOVX P4,X%PR
	JRST ID0

;INFO DEF SUBMIT
.IDS::	MOVX P4,X%SU
ID0:	PRISTG			;ALLOCATE STORAGE
	TXO Z,INFOF		;SAY DOING INFORMATION
	SKIPN @[DCPT
		DPPT
		DSPT
		DTPT
		DPLPT](P4)	;ANY DEFAULTS?
	 RET			;NO!
	TYPE < set default >
	UTYPE @[[ASCIZ/cards/]
		[ASCIZ/print/]
		[ASCIZ/submit/]
		[ASCIZ/paper-tape/]
		[ASCIZ/plot/]](P4)
	CALL GRVDEF		;GROVEL THROUGH THE DEFAULTS
	ETYPE <%_>		;END OF LINE
	RET

;INFORMATION ROUTINES
ICONNE:	PSWITCH <connected-directory:%2R>

ISEQUE:	PSWITCH <sequence:%2Q>

IHEADE:	HRROI A,[0]
	CAIE B,0
	 HRROI A,[ASCIZ/no/]
	PSWITCH <%1M header>

INOTIF:	HRROI A,[ASCIZ/yes/]
	CAIN B,0
	 HRROI A,[ASCIZ/no/]
	PSWITCH <notify:%1M>

IDELET:	HRROI A,[ASCIZ/delete/]
	CAIN B,0
	 HRROI A,[ASCIZ/preserve/]
	PSWITCH <%1M>

ISPACI:	PSWITCH <spacing:%2Q>

IJOBNA:	PSWITCH <jobname:%2'>

IBEGIN:	PSWITCH <begin:%2Q>

ICARDS:	PSWITCH <cards:%2Q>

IDEPEN:	PSWITCH <dependency-count:%2Q>

IFEET:	PSWITCH <feet:%2Q>

IPAGES:	PSWITCH <pages:%2Q>

IPROTE:	PSWITCH <protection:%2O>

ITPLOT:	PSWITCH <tplot:%2Q>

ILOGNA:	MOVX A,GJ%SHT		;SHORT FORM
	STKVAR <SAVJ>
	MOVEM B,SAVJ		;REMEMBER POINTER IN CASE GTJFN FAILS
	CALL GTJFS		;GET JFN SO WE CAN PRINT FILESPEC IN STANDARD
				;   FORM 
	 JRST  [MOVE A,SAVJ	;GTJFN FAILED, JUST TYPE STRING
		PSWITCH <logname:%1M>]
	PSWITCH <logname:%1S>

ITAG:	PSWITCH <tag:%2'>

ICOPIE:	PSWITCH <copies:%2Q>

IUSER:	PSWITCH <user:%2R>

IOUTPU:	MOVE C,B		;COPY THE SWITCH VALUE
	CAIN C,%EQOLG		;GET APPROPRIATE VALUE
	 HRROI B,[ASCIZ/always/]
	CAIN C,%EQONL
	 HRROI B,[ASCIZ/nolog/]
	CAIN C,%EQOLE
	 HRROI B,[ASCIZ/errors/]
	PSWITCH <output:%2M>

IWRITE:	MOVE C,B		;COPY THE SWITCH VALUE
	CAIN C,%BAPND		;GET APPROPRIATE VALUE
	 HRROI B,[ASCIZ/append/]
	CAIN C,%BSCDE
	 HRROI B,[ASCIZ/supersede/]
	CAIN C,%BSPOL
	HRROI B,[ASCIZ/spool/]
	PSWITCH <batch-log:%2M>

ICASE:	HRROI C,[ASCIZ/lowercase/]
	CAIN B,PR%UC
	 HRROI C,[ASCIZ/uppercase/]
	CAIN B,PR%ANY
	 HRROI C,[ASCIZ/generic/]
	PSWITCH <%3M>

ILIMIT:	PSWITCH <limit:%2Q>

IMETER:	PSWITCH <meters:%2Q>

IREPOR:	HRROI A,[ASCIZ/report/]
	CALLRET ICOMON

;PRINT /SPOOLED-OUTPUT, PUNCH PAPER-TAPE /SPOOLED-OUTPUT ETC.
.RSO:	CONFIRM			;CONFIRM THE COMMAND
	MOVX A,.DFREL		;SAY RELEASE OUTPUT
	CALLRET DEFER		;DO THE WORK AND EXIT

;CANCEL PRINT /SPOOLED-OUTPUT
;CANCEL PAPER-TAPE /SPOOLED-OUTPUT
;   ETC.
.CSO:	CONFIRM			;CONFIRM THE COMMAND
	MOVX A,.DFKIL		;SAY WE'RE CANCELING
	CALLRET DEFER		;DO IT AND RETURN

;CALL THIS ROUTINE TO MUCK WITH DEFERRED OUTPUT. GIVE IT FUNCTION IN A.
DEFER:	SETZM IPCFP		;CLEAR OUT DESCRIPTOR BLOCK
	MOVE B,[IPCFP,,IPCFP+1]
	BLT B,IPCFP+DFR.SZ-1
	STOR A,DF.FNC,IPCFP+DFR.JB ;STORE FUNCTION
	MOVX A,DFR.SZ
	STOR A,MS.CNT,IPCFP	;STORE MESSAGE SIZE
	MOVX A,.QODFR		;SPECIFY THAT THIS IS A DEFER REQUEST
	STOR A,MS.TYP,IPCFP
	XCT GOTYP		;GET REQUEST TYPE
	MOVEM A,IPCFP+DFR.OT	;STORE OBJECT TYPE
	MOVE A,JOBNO		;GET JOB NUMBER
	STOR A,DF.JOB,IPCFP+DFR.JB ;TELL QUASAR JOB NUMBER
	CALL QUASND		;GAB WITH QUASAR
	CALLRET UNMAP		;CLEAN UP AND RETURN
;UTILITY ROUTINES FOR IPCF FACILITY

;GET PID FOR EXEC AND INIT PDB'S
;   RETURNS PID IN A
GETPID:	SKIPE A,MYPID		;HAVE ONE ALREADY?
	 RET			;YES - RETURN
	STKVAR <<GUTIL,3>>
	MOVE A,[1000,,IPCPN]
	MOVEM A,SNDPDB+.IPCFP	;PAGE TO USE FOR IPCF SEND
	MOVX A,.MUCRE		;FCN TO CREATE A PID
	MOVEM A,GUTIL		;STASH IN BLOCK
	LDF A,IP%NOA!.FHSLF	;MINE ONLY
	MOVEM A,1+GUTIL
	MOVX A,3		;SIZE OF BLOCK
	MOVEI B,GUTIL		;LOC OF BLOCK
	MUTIL			;GET PID
	 CALL CJERR		;OOPS
	MOVE A,2+GUTIL	;RETURNS PID HERE
	MOVEM A,MYPID		;STORE OF LATER
	MOVX A,.MUPIC		;WE WANT TO PUT PID ON INTERRUPT CHANNEL
	MOVE B,MYPID		;OUR PID
	DMOVEM A,GUTIL		;SET UP ARGS FOR MUTIL
	MOVX A,IPCCHN		;CHANNEL ON WHICH TO GET INTERRUPTS
	MOVEM A,2+GUTIL
	MOVX A,3		;LENGTH OF ARG BLOCK
	MOVEI B,GUTIL		;ADDRESS OF ARG BLOCK
	MUTIL			;POST INTERRUPT REQUEST
	 ERCAL JERR		;SHOULDN'T FAIL
	RET			;RETURN

;ROUTINE TO SEND REQUEST TO QUASAR AND HANDLE ACKNOWLEDGEMENT IT RETURNS UNIQUE
;   ID FOR IDENTIFYING RESPONSES 
QUASND::STKVAR <SAVQCX>
	AOS A,UNIQUE		;GET AN IDENTIFICATION NUMBER
	MOVEM A,IPCFP+.MSCOD
	MOVEM A,SAVQCX		;REMEMBER IT
	MOVX A,1		;SAY WE WANT AN ACKNOWLEDGEMENT
	STOR A,MF.ACK,.MSFLG+IPCFP
	CALL GQPID		;GET QUASAR'S PID
	MOVE B,A
	CALL SNDMS1		;SEND THE REQUEST
	 CALL CJERR		;FAILED, TELL USER WHY
PRITXT:	MOVE B,SAVQCX		;MATCH CODE WITH MESSAGE COMING BACK
	MOVE A,QSRPID		;RECEIVE FROM QUASAR
	CALL IPCRCV		;GET ANSWER
	HRROI B,IPCFP+.OHDRS+ARG.DA ;GET POINTER TO MESSAGE
	MOVE A,IPCFP+.MSFLG	;GET MESSAGE CONTROL BITS
	TXNE A,MF.NOM		;ANY MESSAGE?
	 JRST PRI2		;NO, SO WE MIGHT BE DONE
	TXNN A,MF.FAT+MF.WRN	;NOT WARNING OR FATAL ERROR?
	 JRST PRIT1		;RIGHT, SO JUST PRINT INFORMATIONAL MESSAGE
	TXNE A,MF.FAT		;FATAL?
	 UERR (B)		;RIGHT, SO PRINT MESSAGE AS AN ERROR AND DON'T
				;   RETURN 
	ETYPE <%%%2M%%_>	;WARNING MESSAGE, PRINT AS SUCH
PRI2:	TXNE A,MF.MOR		;MORE?
	 JRST PRITXT		;YES - GO GET IT
	MOVE A,SAVQCX		;RETURN ID IN A
	RET			;NO, WE'RE DONE

PRIT1:	LDB C,[POINT 7,0(B),6]
	CAIE C,"["
	 CAIN C,"%"
	  ABSKP
	   CAIN C,"?"
	    JRST [ETYPE <%2M%%_>
		JRST PRI2]
	ETYPE <[%2M]%_>
	JRST PRI2

;GET PID OF INFO
;  STORES IT IN INFPID AND A. ASSUMES THAT NON-ZERO INFPID IS GOOD PID.
GIPID:	SKIPE A,INFPID		;ALREADY EXIST?
	 RET			;YES, WE'RE DONE
	MOVX A,.SPINF		;SAY WE WANT INFO'S PID
	CALL GSPID		;GET PID OF INFO
	 CALL JERRE		;NO ERROR HANDLER (YET!)
	MOVEM A,INFPID		;REMEMBER IT
	RET

;GET PID OF MDA (MOBY DEVICE ANIMAL)
GMDPID:	SKIPE A,MDAPID		;GOT IT ALREADY?
	 RET			;YES
	MOVX A,.SPMDA		;SAY WE WANT MDA'S PID
	CALL GSPID		;GET SPECIAL PID
	 CALL JERRE		;FAILED
	MOVEM A,MDAPID		;REMEMBER IT SO NO GYRATIONS NEXT TIME THROUGH
	RET

;GET PID OF QUASAR
GQPID::	SKIPE A,QSRPID		;ALREADY HAVE ONE?
	 RET			;YES, DONE
	CALL GQPID1		;TRY TO GET PID
	 JRST GQPID2		;FAILED, PRINT MESSAGE AND TRY AGAIN
	RET			;GOT IT, RETURN

GQPID2:	ETYPE <%%Waiting for QUASAR to start...%_>
GQPID3:	MOVX A,^D3000		;SLEEP FOR 3 SECONDS AND TRY AGAIN
	DISMS
	CALL GQPID1		;TRY AGAIN
	 JRST GQPID3		;DIDN'T GET IT YET
	RET			;GOT IT

GQPID1:	MOVX A,.SPQSR		;SAY WE WANT QUASAR'S PID
	CALL GSPID		;GET SPECIAL PID
	 RET			;FAILED
	MOVEM A,QSRPID		;GOT IT
	RETSKP

;ROUTINE TO GET A SPECIAL PID.
;
;   ACCEPTS:	A/	FUNCTION CODE
;   RETURNS: +1	A/	ERROR CODE
;	     +2	A/	PID
GSPID:	STKVAR <SPID,<QUTILB,3>>
	MOVEM A,SPID		;REMEMBER SPECIAL FUNCTION
	MOVX A,3		;LENGTH OF ARGUMENT BLOCK
	MOVEI B,QUTILB		;ADDRESS OF ARG BLOCK
	MOVX C,.MURSP		;DESIRED FUNCTION (GET PID FROM SYSTEM PID
				;   TABLE) 
	MOVEM C,QUTILB		;STORE FUNCTION
	MOVE C,SPID		;GET SPECIAL FUNCTION
	MOVEM C,1+QUTILB	;STORE INDEX WE WANT
	MUTIL			;GET DESIRED PID
	 RET			;FAILED, SINGLE RETURN
	MOVE A,2+QUTILB		;GOT PID
	RETSKP
	SUBTTL	GQSRPD - GET PID OF USER'S PRIVATE QUASAR

;PID FORMAT IS [USERNAME]QUASAR
GQSRPD::
GQSR.1:	SETZM IPCFP+.IPCI1	;NO MESSAGE COPY
	SETO A,			;WANT THIS JOB
	HRROI B,C		;WANT RESULT IN C
	MOVX C,.JIUNO		;WANT USER NUMBER
	GETJI			;GET IT
	 CALL CJERR		;NO GOOD !!
	PUSH P,C		;SAVE USER NUMBER
	HRROI A,IPCFP+.IPCI2
	MOVX B,"["		;GET LEFT BRACKET
	BOUT			;PUT IT OUT
	POP P,B			;GET THE USER NUMBER BACK
	DIRST			;CONVERT IT TO THE USER NAME
	 CALL CJERR		;NO GOOD
	HRROI B,[ASCIZ/]QUASAR/] ;GET REST OF PID NAME
	SETZ C,			;END ON NULL
	SOUT			;END THE NAME '[USERNAME]QUASAR'
	MOVE A,[1,,.IPCIW] 	;CODE,,FCN
	SETZ B,			;SEND TO INFO
	CALL SNDMSG		;GO SEND MESSAGE
	 CALL CJERR

GQSR.2:	CALL GIPID		;GET PID OF INFO
	CALL IPCRCV		;RECEIVE MESSAGE FROM INFO
	TXNE A,IP%CFE!IP%CFM	;QUASAR THERE?
	 JRST NOPQSR		;NO QUASAR JOB YET...
	MOVE A,IPCFP		;GET RETURNED WORD
	CAME A,[1,,.IPCIW] 	;CHECK EXPECTED
	 JRST GQSR.2		;TRY AGAIN
	MOVE A,IPCFP+.IPCI1	;THIS IS THE PID WE WANT
	MOVEM A,QSRPID		;SAVE IT
	RET			;AND RETURN

;NO PRIVATE QUASAR YET!
NOPQSR:	ETYPE <%%Waiting for Private QUASAR to Start...%_>
	MOVX A,^D5000		;GET 5 SECONDS
	DISMS			;WAIT 5 SECONDS
	JRST GQSR.1		;AND TRY AGAIN
;ROUTINE TO DO RECEIVE (PACKET AND PAGE MODE)
;
;   ACCEPTS:	A/	PID IDENTIFYING WHOSE MESSAGES TO RECIEVE
;   RETURNS:	A/	FLAGS (AS RECIEVED IN .IPCFL)
;		B/	IF QUASAR'S MESSAGE, CONTAINS ID NUMBER YOU ARE
;			    RECIEVING  
;		IPCFP/	MESSAGE
IPCRCV::TRVAR <SAVIFG,MESIDN,QUAIDN,SAVIPP> ;MUST NOT BE STKVAR DUE TO SAVIPP
	MOVEM A,MESIDN		;REMEMBER IDENTIFIER OF MESSAGE
	MOVEM B,QUAIDN		;REMEMBER IDENTIFIER FOR QUASAR MESSAGE
	MOVEM P,SAVIPP		;REMEMBER STACK IN CASE NOTRANSPARENT INTERRUPT
				;   OUT OF SUBROUTINE 
IPCAGN:	MOVE P,SAVIPP		;IN CASE INTERRUPTED OUT OF SUBROUTINE
	CALL IPCOFF		;PREVENT NEW MESSAGES WHILE WE'RE PERUSING
	MOVE A,MESIDN		;GET IDENTIFYING INFORMATION
	MOVE B,QUAIDN
	CALL IPCFND		;FIND THE MESSAGE IN THE QUEUE
	 JRST NOMESS		;IT'S NOT THERE
	MOVE C,IPCFGS(B)	;GET FLAGS THAT GO WITH MESSAGE
	MOVEM C,SAVIFG		;REMEMBER FLAGS
	MOVEI A,IPCBPN(B)	;GET PAGE NUMBER OF MESSAGE
	LSH A,9+22		;9 TO MAKE ADDRESS, 22 TO PUT IT IN LEFT HALF
	HRRI A,IPCFP		;BLT POINTER TO MOVE MESSAGE TO IPCFP
	BLT A,IPCFP+777		;MOVE ENTIRE MESSAGE
	MOVE A,B		;SAY WHICH MESSAGE TO FLUSH
	CALL IPCFLS		;FLUSH MESSAGE FROM BUFFER
	CALL IPCON		;TURN COM CHANNEL BACK ON
	MOVE A,SAVIFG		;GIVE CALLER THE FLAGS
	RET			;DONE

;HERE WITH IPCF QUEUE INDEX TO FLUSH A MESSAGE FROM THE QUEUE. THIS IS DONE,
;   FOR INSTANCE, IF THE MESSAGE IS ONE WE'VE BEEN WAITING FOR AND HAVE JUST
;   RECEIVED, OR THE MESSAGE IS ONE WE'VE DECIDED WE NEVER WANT. 
IPCFLS:	HRRI B,IPCBPN(A)	;GET PAGE NUMBER OF PAGE BEING ERASED
	SETZM IPCTBL(A)		;CLEAR THE SLOT
	SETO A,			;PREPARE TO REMOVE PAGE FROM OUR MAP
	HRLI B,.FHSLF		;REMOVE FROM OURSELF
	SETZ C,			;NO REPETITION COUNT
	PMAP			;REMOVE PAGE
	SKIPL OLDIDX		;IS THERE A WAITING MESSAGE?
	 SETOM IPCWTF		;YES, SIGNAL INTERRUPT TO READ IT IN
	RET

;HERE IF MESSAGE WE WERE LOOKING FOR ISN'T RECEIVED YET
NOMESS:	MOVEI A,IPCAGN		;ADDRESS TO GO BACK TO NEXT TIME A MESSAGE
				;   COMES IN 
	MOVEM A,IPCCTL		;SET UP CONTROL WORD SAYING WHERE TO GO WHEN
				;   NEXT MESSAGE RECEIVED 
	CALL IPCON		;TURN ON INTERRUPTS AGAIN
	SKIPGE OLDIDX		;IS THERE A MESSAGE WAITING?
	 WAIT			;NO, WAIT FOR A COM INTERRUPT (TO IPCAGN)
	CALL IPCFLM		;YES, FLUSH OLD MESSAGE AND FORCE INTERRUPT

;ROUTINE TO SKIP IF A SOUGHT MESSAGE HAS ARRIVED.  
;   IF YOU GIVE QUASAR'S PID, THIS ROUTINE WILL MATCH A MESSAGE FROM EITHER
;   QUASAR OR MDA. THIS ROUTINE IS CAREFUL TO DELIVER OLDER MESSAGES BEFORE
;   NEWER ONES, AND TO THROW AWAY "DEAD LETTERS"
;
;   ACCEPTS:	A/	PID FROM WHOM YOU WANT A MESSAGE
;		B/	IF A IS QSRPID, .MSCOD		
;   RETURNS: +2 A/	ADDRESS OF MESSAGE
;		B/ 	BUFFER SLOT NUMBER OF MESSAGE
IPCFND::STKVAR <IPCIX,IPCCAN,IPCOLD,MESPID,QUAID2>
	MOVEM A,MESPID		;REMEMBER PID OF MESSAGE WE'RE LOOKING FOR
	MOVEM B,QUAID2		;REMEMBER QUASAR IDENTIFICATION
	SETOM IPCCAN		;SAY THERE ARE NO CANDIDATES YET
	HRLOI A,377777		;START WITH OLDEST BIRTHDAY SO FAR AS SOMETHING
				;   IN FUTURE 
	MOVEM A,IPCOLD
	MOVX A,IPCMAX		;INITIALIZE POINTER TO IPCF QUEUES
	MOVEM A,IPCIX
FM1:	SOSGE C,IPCIX		;STEP TO NEXT SLOT TO EXAMINE
	 JRST FM2		;NO, EVERYTHING'S BEEN CONSIDERED
	SKIPN IPCTBL(C)		;ANY MESSAGE IN THIS SLOT?
	 JRST FM1		;NO, SKIP IT
	MOVE A,MESPID		;GET PID OF MESSAGE WE'RE LOOKING FOR
	CAME A,IPCTBL(C)	;HAVE WE JUST FOUND ENTRY?
	 JRST  [CAME A,QSRPID	;DOESN'T MATCH.  ARE WE SEEKING A QUASAR
				;   MESSAGE? 
		 JRST FM4	;NO, SO DEFINITELY DOESN'T MATCH
		CALL GMDPID	;SEEKING QUASAR MESSAGE, GET MDA'S PID
		MOVE C,IPCIX
		CAMN A,IPCTBL(C);IS CURRENT MESSAGE FROM MDA?
		 JRST .+1	;YES, ACCEPT IT AS THOUGH FROM QUASAR
		JRST FM4]	;SEEKING QUASAR, BUT CURRENT ISN'T FROM EITHER
				;   QUASAR OR MDA, SO DOESN'T MATCH 
	MOVE A,MESPID
	CAME A,QSRPID		;WE MAY HAVE FOUND MESSAGE. ARE WE SEEKING A
				;   QUASAR MESSAGE? 
	 JRST FM3		;NO, SO WE'VE DEFINITELY WON
	MOVEI D,IPCBPN(C)	;YES, GET PAGE NUMBER CONTAINING MESSAGE
	LSH D,9			;MAKE ADDRESS OF MESSAGE
	MOVE D,.MSCOD(D)	;GET QUASAR IDENTIFICATION CODE
	CAME D,QUAID2		;IS IT THE CORRECT CODE?
	 JRST FM4		;NO, KEEP SEARCHING FOR MESSAGE
FM3:	MOVE A,IPCAGE(C)	;GET BIRTHDAY OF INTERESTING MESSAGE
	CAML A,IPCOLD		;IS THIS ONE OLDER THAN BEST SO FAR?
	 JRST FM1		;NO, NOT TIME TO DELIVER THIS ONE
	MOVEM A,IPCOLD		;YES, REMEMBER BIRTHDAY OF THIS ONE
	MOVEM C,IPCCAN		;REMEMBER CANDIDATE
	JRST FM1

FM2:	SKIPGE C,IPCCAN		;ANY CANDIDATES?
	 RET			;MESSAGE NOT FOUND
	MOVE B,C		;RETURN SLOT NUMBER IN B
	LSH C,9			;MAKE ADDRESS
	ADDI C,IPCBUF		;MAKE ABSOLUTE ADDRESS OF MESSAGE
	MOVE A,C		;RETURN MESSAGE ADDRESS IN A
	RETSKP			;SKIP TO SHOW MESSAGE FOUND

;GET TO HERE FROM ABOVE WHEN MESSAGE ENCOUNTERED IN THE QUEUE ISN'T ONE WE'RE
;   LOOKING FOR. VERIFY HERE IF ANYONE IS LOOKING FOR IT. IF NOT, FLUSH IT SO
;   AS TO FREE UP ITS SLOT IN THE QUEUE 
FM4:	SKIPN A,IPCTBL(C)	;GET PID THAT SENT THIS MESSAGE
	 JRST FM1		;EMPTY SLOT, SO ITS ALREADY FLUSHED
	CAME A,QSRPID		;DID QUASAR SEND IT?
	 JRST  [CAME A,MDAPID	;NO, DID MDA SEND IT?
		 JRST FM5	;NO, SO FLUSH IT
		JRST .+1]	;YES, TREAT LIKE QUASAR
	MOVEI B,IPCBPN(C)	;QUASAR SENT IT, GET ITS PAGE NUMBER
	LSH B,9			;GET ADDRESS OF MESSAGE IN BUFFER
	MOVE B,.MSCOD(B)	;GET ID OF MESSAGE WE'RE EXAMINING
	MOVEI D,NOWPTR		;SCAN PENDING MOUNTS
FMLUP:	SKIPN D,MLNK(D)		;MORE BLOCKS IN LINK?
	 JRST FM5		;NO, SO FLUSH MESSAGE
	CAME B,MQID(D)		;IS THIS MESSAGE ONE WE'RE WAITING FOR?
	 JRST FMLUP		;NO, KEEP LOOKING
	JRST FM1		;YES, DON'T FLUSH IT

;HERE IF WE'VE DECIDED TO FLUSH THE MESSAGE
FM5:	MOVE A,C		;INDEX OF MESSAGE TO FLUSH
	CALL IPCFLS		;FLUSH JUNK MESSAGE FROM QUEUE
	JRST FM1		;CONTINUE SCANNING FOR ORIGINAL MESSAGE

;IPCHEK - CALL TO PRINT RESPONSES FROM IPCF MESSAGES WHICH HAVE BEEN RECEIVED.
;   WHEN THIS IS DONE: 
;	1) AT COMMAND LEVEL, IF SOME MESSAGES HAVE ARRIVED
;	2) WITHIN IPCF INTERRUPT, IF BUFFER IS FULL
IPCHEK::CALLRET CHECKM		;CHECK FOR COMPLETED /NOWAITS AND RETURN

;INTERRUPT TO HERE WHEN AN IPCF MESSAGE IS SENT TO US
IPCINT::SKIPN IPCALF		;ALLOWED TO DO IPCF INTERRUPTS?
	 SETOM IPCWTF		;NO, SO REMEMBER THAT THERE'S ONE WAITING
	SKIPN IPCALF		;ALLOWED TO TAKE IPCF INTERRUPTS?
	 DEBRK			;NO, SO DON'T DO ANYTHING
	SETZM IPCWTF		;YES, SO SAY NONE WAITING ANYMORE
	CALL SAVACS		;DON'T CLOBBER CODE THAT WAS RUNNING WHEN INT
				;   OCCURED 
	CALL IPCIN1		;DO WORK IN INNER ROUTINE SO THAT STK/TRVARS
				;   MAY BE USED 
	MOVE A,IPCCTL		;GET SPECIAL PLACE TO DISMISS TO
	SETZM IPCCTL		;REQUIRE IPCCTL TO BE SET UP IF WANTED AGAIN
	CAIE A,0		;SPECIAL PLACE TO GO?
	 MOVEM A,PCTAB+LV.IPC	;YES, TELL MONITOR TO GO THERE
	CALL NACL		;SKIP IF NOT AT COMMAND LEVEL
	 JRST  [CALL IPCHEK	;AT COMMAND LEVEL, ANNOUNCE RECEIPT OF MESSAGE
		MOVEI A,CMDIN4
		MOVEM A,PCTAB+LV.IPC	;FORCE EXEC TO REPROMPT
		JRST .+1]
	CALL RESACS		;RESTORE AC'S
	DEBRK

;THE FOLLOWING ROUTINE RECEIVES ANY OUTSTANDING IPCF MESSAGES. IT IS CALLED AT
;   INTERRUPT LEVEL. DO NOT CALL IT OUTSIDE OF INTERRUPT LEVEL, SINCE IT  MAY
;   GET INTERRUPTED AND CALLED FROM THE MIDDLE OF ITSELF, CAUSING AN IPCF
;   MESSAGE TO BE LOST 
IPCIN1:	STKVAR <<RCVPDB,PDBSIZ+1>,IPSLOT,ISAGE>
	HRLOI A,377777		;START WITH VERY YOUNG MESSAGE AS OLDEST SO FAR
	MOVEM A,ISAGE
IPCMR1:	MOVX A,IPCMAX		;GET NUMBER OF SLOTS IN MESSAGE TABLE
IPB1:	SOJL A,IPBE2		;NO FREE SLOT, GO CREATE ONE
	SKIPE IPCTBL(A)		;FIND A FREE SLOT?
	 JRST  [MOVE B,IPCAGE(A) ;NO, GET BIRTHDAY OF OLD MESSAGE
		CAML B,ISAGE	;OLDEST SEEN SO FAR?
		 JRST IPB1	;NO
		MOVEM B,ISAGE	;YES, REMEMBER OLDEST AGE SEEN SO FAR
		MOVEM A,OLDIDX	;REMEMBER INDEX OF OLDEST SEEN
		JRST IPB1]	;CONTINUE LOOKING FOR FREE SLOT
IPBE3:	SETOM OLDIDX		;TELL IPCRCV AND CHECKM THERE'S A FREE SLOT
	MOVEM A,IPSLOT		;REMEMBER WHICH SLOT WE'RE USING
	MOVEI A,IPCBPN(A)	;GET IPCF BUFFER PAGE NUMBER
IPB3:	HRLI A,1000		;MESSAGE IS 1000 WORDS LONG
	MOVEM A,.IPCFP+RCVPDB
IPCMOR:	SETOM .IPCFR+RCVPDB	;WE WANT MESSAGE FOR ANY PID WE OWN
	MOVX A,IP%CFB!IP%CFV	;DON'T BLOCK, PAGE MODE
	MOVEM A,.IPCFL+RCVPDB
DORCV:	MOVX A,PDBSIZ		;PDB SIZE
	MOVEI B,RCVPDB		;PDB ADDR
	MRECV			;RECEIVE MSG
	 ERJMP [CAIE A,IPCF15	;NO PID CREATED YET? (SUCH AS AT STARTUP)
		 CAIN A,IPCFX2	;ERROR SAYS NO MORE MESSAGES?
		  RET		;YES, DONE
		CAIE A,IPCF16	;WRONG DATA MODE?
		 CALL JERRE	;NO, UNEXPECTED ERROR
		MOVX A,IP%CFV	;GET PAGE BIT
		ANDCAM A,.IPCFL+RCVPDB	;TRY NON-PAGE MODE
		LDB A,[001100,,.IPCFP+RCVPDB]	;GET PAGE NUMBER
		LSH A,9		;CHANGE TO ADDRESS
		HRRM A,.IPCFP+RCVPDB	;CHANGE TO ADDRESS
		JRST DORCV]
	MOVE A,.IPCFC+RCVPDB	;GET CAPS OF SENDER
	TXNN A,SC%WHL!SC%OPR	;PRIVILEGED?
	 JRST IPCMOR		;NO, IGNORE MESSAGE
	MOVE A,.IPCFS+RCVPDB	;GOOD MESSAGE, GET PID OF SENDER
	MOVE B,IPSLOT		;GET INDEX FOR STORING MESSAGE
	SETOM IPCRCF		;MARK THAT SOME MESSAGES HAVE BEEN RECEIVED
	MOVEM A,IPCTBL(B)	;SAVE THIS ENTRY
	MOVE A,.IPCFL+RCVPDB	;GET FLAGS
	MOVEM A,IPCFGS(B)	;SAVE FLAGS
	AOS A,UNIQUE		;GET A BIRTHMARK FOR THIS MESSAGE
	MOVEM A,IPCAGE(B)	;SO WE'LL KNOW WHAT ORDER TO DELIVER MESSAGES
	JRST IPCMR1		;LOOP FOR MORE MESSAGES

;GET HERE WHEN THERE'S NO ROOM TO PUT A WAITING MESSAGE
IPBE2:	SKIPE IPCCTL		;IS SOMEONE LOOKING FOR SOMETHING?
	 JRST  [SETOM IPCWTF	;YES, FORCE INTERRUPT TO HAPPEN AGAIN
		RET]		;MAYBE WHAT WE WANT HAS ARRIVED!
	MOVX A,20		;SEE IF THERE'S ANOTHER PACKET WAITING
	MOVEM A,RCVPDB
	SETOM 1+RCVPDB		;FOR ANY PID WE OWN
	MOVX A,PDBSIZ+1		;ARG BLOCK SIZE
	MOVEI B,RCVPDB		;ARG BLOCK ADDR
	MUTIL
	 ERJMP [CAIE A,IPCFX2	;ERROR SAYS NO MORE MESSAGES?
		 CALL JERRE	;NO, UNEXPECTED ERROR
		SETOM OLDIDX	;TELL IPCRCV AND CHECKM
		RET]		;THAT NO MESSAGE IS WAITING
	RET			;WE CAN'T RECEIVE MESSAGE, IPCRCV OR CHECKM CAN
				;   FLUSH 

IPCFLM::STKVAR <IOLDPD>		;SUBROUTINE TO FLUSH OLD MESSAGES
	CALL IPCOFF		;TURN OFF INTERRUPTS DURING FLUSH
	MOVE C,OLDIDX		;GET INDEX OF MESSAGE BEING FLUSHED (OLDEST IN
				;   QUEUE) 
	MOVE B,IPCTBL(C)	;GET SENDER OF MESSAGE WE'RE FLUSHING
	MOVEM B,IOLDPD		;REMEMBER PID OF MESSAGE BELING FLUSHED
	ETYPE <%_%%%EXEC: IPCF buffer full; discarding message(s)>
	CALL GQPID		;GET QUASAR'S PID
	CAMN A,IOLDPD		;IS THE MESSAGE FROM QUASAR?
	 ETYPE < from QUASAR%_>
	CALL GMDPID		;SEE IF FROM MDA
	CAMN A,IOLDPD
	 ETYPE < from MDA%_>	;FEEL FREE TO ADD!
	MOVE A,OLDIDX		;GET INDEX OF OLD MESSAGE
	CALL IPCFLS		;THROW IT AWAY
	CALL IPCON		;TURN ON INTERRUPTS (ONE WILL BE TAKEN)
	RET			;AND GO BACK (CLEANING UP)

;ROUTINE TO SEND MSG TO PID IN B, FCN CODE IN A
SNDMSG::MOVEM A,IPCFP+.IPCI0	;STASH CODE
SNDMS1::MOVEM B,SNDPDB+.IPCFR	;PID TO SEND TO
	CALL GETPID		;MAKE SURE WE HAVE A PID
	LDF A,IP%CFS!IP%CFV	;FLAGS
	MOVEM A,SNDPDB+.IPCFL
	MOVEI A,MYPID		;SET UP SENDERS PID
	MOVEM A,SNDPDB+.IPCFS
	MOVX A,4		;PDB SIZE
	MOVEI B,SNDPDB
	MSEND			;XMIT
	 ERJMP BADPID		;GO CHECK FOR INVALID PID
	RETSKP			;OK RETURN

;TABLE OF KNOWN SPECIAL SYSTEM PIDS
SPTBL:	QSRPID,,GQPID		;CELL HOLDING PID,,ROUTINE TO INIT PID
	MDAPID,,GMDPID
	INFPID,,GIPID
SPLEN==.-SPTBL			;NUMBER OF ENTRIES IN TABLE

BADPID:	CAIE A,IPCFX4		;IS PROBLEM "RECEIVER'S PID INVALID"?
	 RET			;NO, LET CALLER HANDLE IT
	MOVX A,SPLEN		;INDEX INTO SPECIAL PID TABLE
	MOVE B,.IPCFR+SNDPDB	;GET BAD PID
BAD1:	SOJL A,[MOVX A,IPCFX4	;MESSAGE WASN'T BEING SENT TO SPECIAL PID, LET
				;   CALLER HANDLE PROBLEM 
		RET]
	HLRZ C,SPTBL(A)		;GET ADDRESS OF CELL CONTAINING SPECIAL PID
	CAME B,(C)		;HAVE WE FOUND THE BAD PID?
	 JRST BAD1		;NOT YET, KEEP LOOKING
	SETZM (C)		;FORCE THIS PID TO BE RECALCULATED
	HRRZ A,SPTBL(A)		;GET ROUTINE TO CALL
	CALL (A)		;RECALCULATE REQUESTED PID
	MOVE B,A		;GET REVISED PID IN B
	JRST SNDMS1		;GO TRY TO RESEND MESSAGE

LITSQU:				;713 debugging aid: literals label
	END