Google
 

Trailing-Edge - PDP-10 Archives - bb-h138f-bm - 7-sources/rsxfmt.mac
There are 14 other files named rsxfmt.mac in the archive. Click here to see a list.
;<5.UTILITIES>RSXFMT.MAC.2, 28-Oct-81 15:36:06, EDIT BY GRANT
;Change major version to 5
;<4.UTILITIES>RSXFMT.MAC.4,  3-Jan-80 15:26:47, EDIT BY R.ACE
;UPDATE COPYRIGHT DATE
;<4.UTILITIES>RSXFMT.MAC.3,  3-Jan-80 14:57:08, EDIT BY R.ACE
;<SAUTER.TKB20>RSXFMT.MAC.2, 14-Jun-78 14:33:41, Edit by SAUTER
; ADD "IMAGE" AND "ELEVEN" MODES TO ALLOW PROCESSING OF CORE IMAGE FILES
;<3-UTILITIES>RSXFMT.MAC.3, 16-Nov-77 14:31:20, EDIT BY KIRSCHEN
;UPDATE VERSION FOR RELEASE 3
;<3-UTILITIES>RSXFMT.MAC.2,  8-Nov-77 10:50:29, EDIT BY KIRSCHEN
;MORE COPYRIGHT UPDATING...
;<3-UTILITIES>RSXFMT.MAC.1, 26-Oct-77 11:16:16, EDIT BY KIRSCHEN
;UPDATE COPYRIGHT FOR RELEASE 3
;<2-UTILITIES>RSXFMT.MAC.4, 27-Dec-76 17:07:52, EDIT BY HURLEY
	TITLE RSXFMT -- FILE CONVERSION PROGRAM


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

	SEARCH MONSYM,MACSYM
	.REQUIRE SYS:MACREL
	SALL
	ifdef .psect,<
	.direct flblst>
	ifndef .psect,<
	.direct .xtabm>
;
F=	0			;FLAGS:
	F.IBCR==1B0		;MODE IS IMBEDDED <CR><LF>
	F.IPCR==1B1		; . . IMPLIED <CR><LF>
	F.TIBC==1B2		;THIS FILE IS IMBEDDED <CR><LF> *** CANNOT BE 1B0 ***
	F.ADDR==1B3		;ADDRESS WORDS EXIST
	F.NO==	1B4		;"NO" WAS TYPED BEFORE COMMAND
	F.TEMP==1B5		;TEMPORARY OUTPUT FILES
	F.RSCN==1B6		;RESCAN COMMAND IN PROGRESS
	F.EXIT==1B7		;EXIT WHEN DONE WITH COMMAND (RESCAN)
	F.IGNR==1B8		;IGNORE FILE FORMAT ERRORS
	F.LFSS==1B9		;CONVERT LF TO SINGE SPACE
	F.TLFS==1B10		;TEMP SAME *** CANNOT BE 1B0 ***
	F.CRMA==1B11		; PROCESSING CRAM ADDRESS FLAG
	F.TTEM==1B12		;TEMPORARY TEMPORARY OUTPUT FILES
T1=	1			;TEMP REGISTERS
T2=	2			; . .
T3=	3			; . .
T4=	4			; . .
;
P1=	5			;GENERAL STORAGE REGISTERS
P2=	6			; . .
P3=	7			; . .
P4=	10			; . .
;
C=	11			;RANDOM CHARACTERS
IC=	12			;TEMP INPUT CHARACTER BUFFER FOR 8-BIT BYTES
OC=	13			; . . OUTPUT . .
;
IM=	14			;INPUT FILE MODE (CONVERT)
OM=	15			;OUTPUT . .
;
INDX=	16			;RAMS STORAGE INDEX REGISTER
P=	17			;PDL POINTER
;
;
; MACROS
;
DEFINE ERR (MSG),<
	 JRST [	HRROI P1,TXTPTR<MSG>
		JRST CMDERR]
>
;
DEFINE ERRJ (MSG),<
 IFNB <MSG>,<
	 JRST [	HRROI T2,<TXTPTR (<MSG>)>
		JRST CMDERJ]
 >
 IFB <MSG>,<
	 JRST CMDJSE
 >
>
DEFINE ERRI(MSG,GOTO),<
	 JRST [	HRROI P1,TXTPTR<MSG>
		CALL CMDERI
		JRST GOTO]
>
;
DEFINE TB(DATA,TEXT),<XWD [ASCIZ\TEXT\],DATA>
DEFINE TXTPTR(TEXT),<XWD -1,[ASCIZ\TEXT\]>
;
OPDEF CALL [PUSHJ P,]
OPDEF CALLR [JRST]
OPDEF RETURN [POPJ P,]
DEFINE RETSKP,<JRST CRET1>
DEFINE CALLRX (WHERE),<IF2,<IFN <.-WHERE>,<PRINTX ? CALLRX WHERE NOT VALID>>>
;
;
; MISC. IMPURE DATA
;
CLRBEG==.
;
PDL:	BLOCK <PDLEN==^D50>
;
INJFN:	BLOCK 1			;JFN OF INPUT FILE
OUTJFN:	BLOCK 1			;JFN OF OUTPUT FILE
MFOJFN:	BLOCK 1			;MULTI-FILE OUTPUT JFN
CMDJFN:	BLOCK 1			;LH: JFN TO GET COMMANDS FROM, RH: LOG JFN
MODE:	BLOCK 1			;LH: INPUT MODE, RH: OUTPUT MODE
RCDSIZ:	BLOCK 1			;RECORD SIZE FOR NON-FORMATTED IMAGE RECORDS
INADR:	BLOCK 1			;CURRENT INPUT IMAGE-BINARY INPUT ADDRESS
OUTADR:	BLOCK 1			;CURRENT OUTPUT ADDRESS
INCHK:	BLOCK 1			;INPUT CHECKSUM
OUTCHK:	BLOCK 1			;OUTPUT CHECKSUM
INPTR:	BLOCK 1			;POINTER TO INPUT DATA IN SCRBUF
;
CHN1PC:	BLOCK 1			;PC OF CHANNEL 1 INTERRUPTS
;
; COMND DATA
;
CMDBUF:	BLOCK <CMDSIZ==^D200/5>	;COMMAND BUFFER
ATMBUF:	BLOCK <ATMSIZ==^D200/5>	;ATOM BUFFER
;
CMDBLK:	BLOCK .CMGJB+1		;COMND JSYS CONTROL BLOCK
CMDBKE==.-1
GJFBLK:	BLOCK .GJBFP+1		;GTJFN JSYS CONTROL BLOCK
GJFBKE==.-1
;
CLREND==.-1
;
; SCRATCH BUFFER FOR ALL TO USE
;
	LOC 100K
SCRBUF:
	RELOC
	SUBTTL PURE DATA
;
; ENTRY VECTORS
;
ENTVEC:
	JRST RSXFMT
	JRST CMDRST
	BYTE (3)<VWHO==0> (9)<VRSXFMT==5> (6)<VMINOR==0> (18)<VEDIT==31>
;
; COMMAND TABLE
;
DEFINE CMD(A),<TB $'A,<A>>
CMDTAB:
	XWD CMDNUM,CMDNUM
	CMD ADDRESS
	CMD CONVERT
	CMD CRLF
	CMD EXIT
	CMD HELP
	CMD IGNORE
	CMD INFORMATION
	CMD MODE
	CMD NO
SIZE==0
	CMD RECORD-SIZE
	CMD TAKE
	CMD TCONVERT
	CMD TEMPORARY
CMDNUM==.-CMDTAB-1
;
; DISPATCH TABLE FOR "NO" COMMANDS
;
NOCTAB:
	XWD NOCNUM,NOCNUM
	CMD ADDRESS
	CMD IGNORE
	CMD NO
	CMD TEMPORARY
NOCNUM==.-NOCTAB-1
;
; FORMAT TYPE TABLES
;
; NEMONIC,KEYWORD,INPUT BYTE-SIZE,DEFAULT OUTPUT MODE
;
DEFINE FORMAT,<
X DSA,7-BIT-ASCII,7,RSA
X DEF,DEFAULT,0,DEF
X DSB,DOS-BINARY,18,RSB
X ELV,ELEVEN,18,ELV
X IMG,IMAGE,36,ELV
X IMB,IMAGE-BINARY,18,DSB
X RAM,MICROCODE,7,RSB
X RSA,RSX-ASCII,18,DSA
X RSB,RSX-BINARY,18,DSB
X SAV,SAVE,36,RSB
>
;
DEFINE X(A,B,C,D,E),<
M$'A==.-MSGTAB
	TB <M$'D>,<B>
>
FMTTAB:
	XWD FMTSIZ,FMTSIZ
MSGTAB:
	FORMAT
FMTSIZ==.-FMTTAB-1
;
DEFINE X(AAA,BBB,C,DDD,E),<EXP ^D<C>B5>
BSZTAB:
	FORMAT
;
; GRC=GET RECORD BYTE COUNT
; PRC=PUT RECORD BYTE COUNT
; GBY=GET BYTE
; PBY=PUT BYTE
; EIR=END INPUT RECORD
; EOR=END OUTPUT RECORD
;
DEFINE DSP(NAME),< IRP NAME,<
 DEFINE X(A,B,C,D,E),<Z A''NAME>
NAME'TAB:
	FORMAT
>>
	DSP <GRC,PRC,GBY,PBY,EIR,EOR>
;
; TABLE OF DEFAULT FILE TYPES
;
EXTTAB:
	XWD EXTSIZ,EXTSIZ
	TB M$RSB,BIN
	TB <<1B0!F.TIBC>_-^D18>,DIR
	TB M$SAV,EXE
	TB <<1B0!F.TLFS>_-^D18>,LST
	TB <<1B0!F.TIBC>_-^D18>,MAP
	TB M$RSB,OBJ
	TB M$RSB,OLB
	TB M$RAM,RAM
	TB M$SAV,SAV
	TB M$RSB,STB
	TB M$IMG,SYS
EXTSIZ==.-EXTTAB-1
;
; PSI TABLES
;
LEVTAB:
	EXP CHN1PC
;
CHNTAB==.-^D10
	XWD 1,EOFTRP
	SUBTTL INITIALIZE
;
;
RSXFMT:
	MOVE P,[IOWD PDLEN,PDL]
	RESET			;RESET I/O STATE
;
	SETZM CLRBEG		;SET TO CLEAR
	MOVE T1,[XWD CLRBEG,CLRBEG+1]
	BLT T1,CLREND		;CLEAR ALL LOCAL VARIABLES
;
	MOVE T1,[XWD ICMBLK,CMDBLK]
	BLT T1,CMDBKE
;
	MOVE T1,ICMBLK+.CMIOJ	;GET STANDARD JFNS
	MOVEM T1,CMDJFN		;SAVE THEM
	MOVX T1,<XWD M$DEF,M$DEF> ;SET DEFAULT MODES
	MOVEM T1,MODE		; . .
	MOVEI T1,^D256		;ASSUME 256 BYTE RECORDS
	MOVEM T1,RCDSIZ		;SAVE THAT
	MOVX F,F.ADDR		;DEFAULT TO ADDRESSES
;
; SEE IF "RSXFMT <FILE>" WAS TYPED
;
	MOVEI T1,0		;SET TO GET
	RSCAN			;ANY COMMAND THAT WAS THERE
	 JRST CMDRST		;NONE THERE
	JUMPLE T1,CMDRST		;NONE THERE
	MOVE P4,T1		;SAVE IT
	GETNM			;GET NAME OF OUR PROGRAM IN T1
	MOVE P2,T1		;COPY IT FOR SAFE KEEPING
	CALL RSCHSK		;SKIP SPACES IN INPUT, NON-SPACE IN T1
	 JRST CMDRST		;OOPS-- MUST GIVE UP AT EOL
RSCAN1:	SETZ P1,		;CLEAR COMPARE CHARACTER
	LSHC P1,6		;SHIFT A CHARACTER IN FROM T2
	JUMPE P1,RSCAN3		;MATCH (TO SIX CHARACTERS, AT LEAST)
	CAIE T1," "-' '(P1)	;MATCH INPUT?
	 JRST NORSCN		;NO-- EAT REMAINING CHARACTERS
RSCAN2:
	CALL RSCHAR		;GET A RESCANNED CHAR
	 JRST CMDRST		;EOL-- GIVE UP
	JRST RSCAN1		;NOT EOL-- CHECK IT OUT
;
RSCAN3:
	CAIE T1," "		;THIS SPACE?
	CAIN T1,"	"	; OR TAB?
	 JRST RSCAN2		;YES-- GET ANOTHER CHAR
	MOVEI T1,.PRIIN		;NO-- WE GOT AN EXTRA CHAR
	BKJFN			; SO BACK OVER IT AGAIN
	 JRST NORSCN		;OOPS
	TXO F,F.RSCN		;NOTE RESCANNING
	JRST CMDRST		;GO GET COMMAND
;
NORSCN:
	CALL RSCHAR		;GET CHAR
	 JRST CMDRST		;ALL DONE AT EOL
	JRST NORSCN		;EAT WHOLE LINE
;
; RSCHSK -- SKIP BLANKS IN RESCANNED COMMAND
;
RSCHSK:
	CALL RSCHAR		;GET CHAR
	 RETURN			;RETURN EOL
	CAIE T1," "		;SPACE?
	CAIN T1,"	"	; OR TAB?
	 JRST RSCHSK		;YES-- SKIP IT
	RETSKP			;NO-- RETURN IT
;
; RSCHAR -- GET RESCANNED CHAR TO T1
;
RSCHAR:
	SOJL P4,CRET		;GIVE UP NOW IF NO MORE CHARS LEFT
	PBIN			;GET NEXT CHAR
	CAIE T1,.CHCUN		;EOL?
	CAIN T1,.CHLFD		; . .?
	 RETURN			;YES-- NO SKIP
	RETSKP			;NO-- SKIP BACK WITH CHAR IN T1
	SUBTTL ERROR PROCESSING
;
; HERE ON IGNORE-ABLE ERROR
;
CMDERI:
	TXNN F,F.IGNR		;IGNORE SUCH ERRORS?
	 JRST CMDERR		;NO-- GIVE FATAL ERROR
	MOVEI T1,.PRIOU		;TTY
	CALL TYPTST		;<CRLF> IF NEEDED
	HRROI T2,TXTPTR<% >	;WARN
	CALL TYPSTR		; . .
	MOVE T2,P1		;GET STRING
	CALLR TYPSTC		;THEN <CRLF>
;
; HERE ON JSYS ERROR FROM COMMAND, WITH ADDITIONAL TEXT IN T2
;
CMDERJ:
	HRROI T1,SCRBUF		;POINT TO SCRATCH
	CALL TYPSTR		;SEND STRING
	HRROI T2,TXTPTR< >
	CALL TYPSTR		;TERMINATE
	JRST CMDJS1		;DOWN TO COMMOMN CODE
;
; HERE ON JSYS ERROR FROM COMMAND
;
CMDJSE:
	HRROI T1,SCRBUF		;POINT TO SCRATCH
CMDJS1:
	HRLOI T2,.FHSLF		;LAST ERROR, CURRENT PROCESS
	MOVX T3,0		;NO LIMIT
	ERSTR			;TYPE THE ERROR
	 JFCL			;OOPS
	 JFCL			;OOPS
	HRROI P1,SCRBUF		;SET POINTER
;	JRST CMDERR		;DO ERROR WORK
;
; HERE ON COMMAND ERRORS, STRING POINTER TO ERROR MESSAGE IN P1
;
CMDERR:
	MOVEI T1,.PRIIN		;CLEAR
	CFIBF			; EXTRA TYPE-IN
;
	MOVEI T1,.PRIOU		;GET TTY
	CALL TYPTST		;SEE IF WE NEED A <CRLF>
	HRROI T2,TXTPTR<? >	;MAKE IT AN ERROR
	CALL TYPSTR		; . .
	MOVE T2,P1		;GET ERROR STRING POINTER
	CALL TYPSTR		;TYPE THE STRING
;
	HRRZ T3,CMDBLK+.CMIOJ	;GET OUTPUT JFN
	CAIN T3,.PRIOU		;TTY?
	 JRST CMDER2		;YES-- SKIP THIS STUFF
	HRROI T2,[ASCIZ/:
  RSXFMT>/]
	CALL TYPSTR		;TYPE PROMPT
	MOVE T2,CMDBLK+.CMBFP	;GET COMMAND BUFFER POINTER
	CALL TYPSTR		;TYPE STRING
CMDER2:
	CALL TYPTST		;SEE IF CRLF NEEDED NOW
	CALLRX CMDRST		;RESTART COMMAND
	SUBTTL GET AND PROCESS COMMAND
;
; HERE TO RESTART, AFTER ERROR
;
CMDRST:
	CALL CLSCMD		;CLOSE COMMAND/LOG FILES, IF ANY
	RESET			;GET RID OF ANY OPEN FILES
	MOVX T1,.FHSLF		;SET TO OUR FORK
	MOVE T2,[XWD LEVTAB,CHNTAB] ;CHANNELS TO USE
	SIR			;SET INTERRUPT TABLES
	MOVX T2,1B10		;ONLY CHANNEL 10 (EOF)
	AIC			;ACTIVATE THE CHANNEL
	EIR			; AND THE SYSTEM
;	JRST CMDINI		;AND RESTART
;
; HERE TO INIT COMND JSYS
;
CMDINI:
	TXZE F,F.EXIT		;TIME TO LEAVE?
	 HALTF			;YES-- BYE FOR NOW
	MOVE T1,CMDJFN		;GET CURRENT COMMAND JFN'S
	MOVEM T1,CMDBLK+.CMIOJ	;PUT THEM AWAY
;
	MOVE T2,ICMBLK+.CMRTY	;GET GOOD PROMPT STRING
	TXNN F,F.RSCN		;RESCANNING?
	CAME T1,ICMBLK+.CMIOJ	;OUT TO TTY?
	 HRROI T2,TXTPTR<>;	;NO-- GET NULL PROMPT
	MOVEM T2,CMDBLK+.CMRTY	;SAVE PROMPT STRING
;
	MOVEI T1,CMDBLK
	MOVEI T2,[FLDDB. (.CMINI)]
	COMND
;
	TXZN F,F.RSCN		;RESCANNING?
	 JRST CMDREP		;NO-- JUST GO ON
	TXO F,F.EXIT		;YES-- NOTE TO DO TRICKS
	MOVE T1,CMDBLK+.CMPTR	;GET BUFFER POINTER
	HRROI T2,TXTPTR<CONVERT (FILE) >
	CALL TYPSTR		;PUT CONVERT COMMAND IN BUFFER
	MOVEI T1,.NULIO		;GET NUL JFN
	HRRM T1,CMDBLK+.CMIOJ	;SAVE IT
	MOVEI T1,^D15		;THAT'S 15 CHARACTERS
	MOVEM T1,CMDBLK+.CMINC	;SAVE COUNT
CMDREP:
	TXZ F,F.NO		;NO LONGER A NO COMMAND
	MOVE P,[IOWD PDLEN,PDL]
	MOVX T1,-1		;RELEASE
	RLJFN			; ALL UNUSED JFN'S
	 JSHLT			;GO AWAY
	MOVEI T1,CMDBLK
	MOVEI T2,[FLDDB. (.CMKEY,,CMDTAB)]
CMDCMD:
	COMND
	ERJMP [ERRJ ()]		;OOPS
	TXNE T1,CM%NOP		;PARSE FAIL?
	 ERR <UNKNOWN COMMAND>
	HRRZ T2,(T2)		;GET ADDRESS FROM TABLE
	CALL (T2)		;CALL COMMAND ROUTINE
	 JRST CMDINI		;(NORMAL COMMAND DONE) BACK FOR ANOTHER
	JRST CMDCMD		;(COMMAND WITH MORE DISPATCHES) CONTINUE COMMAND
;
; NO
;
$NO:
	TXC F,F.NO		;NOW NOT WHAT YOU THOUGHT IT WAS
	MOVEI T2,[FLDDB. (.CMKEY,,NOCTAB)]
	RETSKP			;CONTINUE COMMAND
;
; INITIAL COMND JSYS BLOCK
;
ICMBLK:
	XWD 0,CMDREP		;FLAGS, REPARSE
	XWD .PRIIN,.PRIOU	;IN, OUT JFNS
	POINT 7,[ASCIZ/RSXFMT>/] ;^R POINTER TO PROMPT
	POINT 7,CMDBUF		;TOP OF BUFFER
	POINT 7,CMDBUF		;NEXT INPUT TO BE PARSED
	EXP CMDSIZ*5		;SIZE OF BUFFER
	EXP 0			;CHARACTERS FOLLOWING POINTER
	POINT 7,ATMBUF		;ATOM BUFFER POINTER
	EXP ATMSIZ*5		;ATOM BUFFER SIZE
	EXP GJFBLK		;GTJFN BLOCK ADDRESS
	SUBTTL "TAKE" COMMAND
;
; HERE ON "TAKE" COMMAND
;
$TAKE:
	MOVX T1,GJ%OLD		;OLD FILE TO GET
	SETZ T2,		;NO DEFAULT FILE-NAME
	HRROI T3,TXTPTR<CMD>	;DEFAULT TYPE
	MOVEI T4,[FLDDB. (.CMNOI,,TXTPTR<COMMANDS FROM FILE>)]
	CALL FILE		;GET A FILE
	HRLZ P1,T2		;SAVE JFN
;
	SETZM SCRBUF		;TO BE SURE . .
	HRROI T1,SCRBUF		;POINT TO SCRATCH
	MOVX T3,1B8		;OUTPUT NAME ONLY
	JFNS			;GET COMMAND FILE NAME
;
	MOVX T1,GJ%FOU!GJ%MSG	;OUTPUT LOG FILE
	SKIPE T2,SCRBUF		;IF NO FILE...
	 HRROI T2,SCRBUF	;DEFAULT NAME FROM INPUT
	HRROI T3,TXTPTR<LOG>	;FILE TYPE
	CALL CLRGFB		;RESET GTJFN BLOCK
	MOVEI T2,[FLDDB. (.CMNOI,,TXTPTR<LOGGING OUTPUT ON>)]
	CALL NOISE		;GET NOISEY
	MOVEI T2,[FLDDB. (.CMFIL,,,,<TTY:>)]
	CALL FILE1		;GET FILE-SPEC & CHECK FOR ERRORS
	HRR P1,T2		;SAVE IT
	CALL CONFRM		;GET CONFIRMATION
	CALL CLSCMD		;CLOSE OLD COMMAND/LOG FILE
;
	HLRZ T1,P1		;GET INPUT JFN FIRST
	MOVX T2,^D7B5+OF%RD	;READ ACCESS
	OPENF			;OPEN THE COMMAND FILE
	 ERRJ
;
	HRRZ T1,P1		;GET OUTPUT
	MOVX T2,^D7B5+OF%APP	;APPEND ACCESS
	OPENF			;OPEN COMMAND FILE
	 ERRJ
	MOVEM P1,CMDJFN		;SAVE IN,,OUT JFNS
	RETURN			;GO BACK AND READ THE FILE
	SUBTTL "EXIT", "HELP" COMMANDS
;
; EXIT
;
$EXIT:
	MOVEI T2,[FLDDB. (.CMNOI,,TXTPTR<FROM RSXFMT>)]
	CALL NOICFM		;TYPE NOISE, GET CONFIRMATION
	HALTF			;EXIT NOW,
	RETURN			;BUT BACK FOR MORE
;
; HELP (WITH RSXFMT)
;
$HELP:
	MOVEI T2,[FLDDB. (.CMNOI,,TXTPTR<WITH RSXFMT>)]
	CALL NOICFM		;NOISEY CONFIRM
	MOVX T1,GJ%SHT!GJ%OLD	;SET TO GET
	HRROI T2,TXTPTR<SYS:RSXFMT.HLP>
	GTJFN			;OUR HELP FILE
	 ERRJ <SYS:RSXFMT.HLP>
	MOVX T2,OF%RD+^D7B5	;ASCII, READ
	OPENF			;OPEN THE HELP FILE
	 ERRJ <SYS:RSXFMT.HLP>
	HRROI T2,SCRBUF		;POINT TO SCRATCH
	MOVX T3,3*1000*5	;THREE PAGES OF TEXT, MAX
	MOVX T4,0		; OR ASCIZ
	SIN			;READ HELP FILE
	ERJMP .+1		;IGNORE EOF, ERRORS
	SETZ T1,		;TERMINATE
	IDPB T1,T2		;THE STRING OF INPUT
	HRRZ T1,CMDJFN		;GET COMMAND OUTPUT JFN
	HRROI T2,SCRBUF		;POINT TO HELP TEXT
	CALLR TYPSTR		;SEND STRING, AND RETURN FROM HELP
	SUBTTL "TEMPORARY", "IGNORE", "ADDRESS" COMMANDS
;
; TEMPORARY (OUTPUT FILES)
;
$TEMPORARY:
	MOVEI T2,[FLDDB. (.CMNOI,,TXTPTR<OUTPUT FILES>)]
	MOVX P1,F.TEMP		;FLAG TO SET
	CALLR NOSETF		;SET F ACCORDING TO NOAND RETURN FROM TEMPORARY
;
; IGNORE (FILE FORMAT ERRORS)
;
$IGNORE:
	MOVEI T2,[FLDDB. (.CMNOI,,TXTPTR<FILE FORMAT ERRORS>)]
	MOVX P1,F.IGNR		;IGNORE FLAG
	CALLR NOSETF		;SET/CLEAR, RETURN FROM IGNORE
;
; ADDRESS (WORDS EXIST IN IMAGE FILES)
;
$ADDRESS:
	MOVEI T2,[FLDDB. (.CMNOI,,TXTPTR<WORDS EXIST IN IMAGE FILES>)]
	MOVX P1,F.ADDR		;GET FLAG TO SET
	CALLRX NOSETF		;SET/CLEAR, RETURN FROM ADDRESS
;
; NOSETF -- SET/CLEAR FLAG IN F FROM P1 ACCORDING TO "NO"
;
NOSETF:
	CALL NOICFM		;TYPE NOISE, GET CONFIRMATION
	TXNE F,F.NO		;NO?
	 TDZA F,P1		;YES-- CLEAR FLAG
	TDO F,P1		;NO-- SET FLAG
	RETURN			;FROM NOSETF
	SUBTTL "MODE", "CRLF",  "RECORD-SIZE" COAMMNDS
;
; MODE (OF INPUT)
;
$MODE:
	MOVEI T2,[FLDDB. (.CMNOI,,TXTPTR<OF INPUT>)]
	CALL GETMOD		;GET A MODE
	HRLZ P1,T2		;SAVE THAT
	MOVEI T2,[FLDDB. (.CMNOI,,TXTPTR<AND OUTPUT>)]
	CALL GETMOD		;GET THE MODE
	HRR P1,T2		;SAVE THAT MODE
	CALL CONFRM		;GET CONFIRMATION
	MOVEM P1,MODE		;STORE THE MODE
	RETURN			;AND RETURN FROM MODE
;
; GETMOD -- GET A MODE, WITH A LITTLE NOISE
;
GETMOD:
	CALL NOISE
	MOVEI T2,[FLDDB. (.CMKEY,,FMTTAB,,<DEFAULT>)]
	COMND
	ERJMP [ERRJ ()]
	TXNE T1,CM%NOP		;GOT A KEYWORD?
	 ERR <INVALID MODE>
	SUBI T2,MSGTAB		;MAKE OFFSET INTO TABLES
	RETURN			;FROM GETMOD, MODE INDEX IN T2
;
; CRLF (IN ASCII FILES IS)
;
$CRLF:
	MOVEI T2,[FLDDB. (.CMNOI,,TXTPTR<IN ASCII FILES IS>)]
	CALL NOISE
	MOVEI T2,[FLDDB. (.CMKEY,,ASCTAB,,<DEFAULT>)]
	COMND
	ERJMP [ERRJ ()]
	TXNE T1,CM%NOP		;FOUND ONE?
	 ERR <INVALID RESPONSE>
	HRLZ P1,(T2)		;GET THE BIT TO SET
	CALL CONFRM		;GET CONFIRMATION
	TXZ F,F.IBCR!F.IPCR!F.LFSS ;CLEAR CURRENT FLAGS
	TDO F,P1		;SET THE BIT
	RETURN			;ALL DONE
;
; RESPONSES FOR "CRLF" COMMAND
;
ASCTAB:
	XWD ASCSIZ,ASCSIZ
	TB <F.LFSS_-^D18>,<CARRIAGE-RETURN-SINGLE-SPACE>
	TB 0,<DEFAULT>
	TB <F.IBCR_-^D18>,<IMBEDDED>
	TB <F.IPCR_-^D18>,<IMPLIED>
ASCSIZ==.-ASCTAB-1
;
; RECORD-SIZE (FOR IMAGE FILES IS)
;
$RECORD:
	MOVEI T2,[FLDDB. (.CMNOI,,TXTPTR<FOR IMAGE FILES IS>)]
	CALL NOISE
	MOVEI T2,[FLDDB. (.CMNUM,,^D10,,<256>)]
	COMND			;GET A NUMBER
	ERJMP [ERRJ ()]
	TXNN T1,CM%NOP		;OK?
	SKIPG P1,T2		;GET NUMBER, IF +VE
	 ERR <INVALID DECIMAL NUMBER>
	CALL CONFRM		;GET CONFIRMATION
	MOVEM P1,RCDSIZ		;STORE THE RECORD-SIZE
	RETURN			;FROM RECORD-SIZE
	SUBTTL "INFORMATION" COMMAND
;
; INFORMATION (ABOUT)
;
$INFORMATION:
	MOVEI T2,[FLDDB. (.CMNOI,,TXTPTR<ABOUT>)]
	CALL NOISE
	MOVEI T2,[FLDDB. (.CMKEY,,INFTAB,,<ALL>)]
	COMND			;GET WHAT HE WHATS
	ERJMP [ERRJ ()]
	TXNE T1,CM%NOP		;OOPS?
	 ERR <INVALID RESPONSE>
	HRRZ P1,(T2)		;GET DISPATCH ADDRESS
	CALL CONFRM		;GET CONFIRMATION
	HRRZ T1,CMDJFN		;GET COMMAND OUTPUT JFN
	MOVX P4,-1		;FLAG TO PREVENT ALL(ALL(ALL(...)))
	CALLR (P1)		;CALL THE WHAT-EVER AND RETURN
;
; RESPONSES FOR "INFORMATION" COMMAND
;
INFTAB:
	XWD INFSIZ,INFSIZ
	TB INFADR,<ADDRESS>
	TB INFALL,<ALL>
	TB INFCR,<CRLF>
	TB INFIGN,<IGNORE>
	TB INFMOD,<MODE>
	TB INFRCD,<RECORD-SIZE>
	TB INFTMP,<TEMPORARY>
INFSIZ==.-INFTAB-1
;
;
INFALL:
	AOJN P4,CRET		;GIVE UP NOW IF RECURSING
	MOVSI P3,-INFSIZ	;AOBJN POINTER TO ALL THEM GOODIES
INFAL1:
	HRRZ T4,INFTAB+1(P3)	;GET AN ENTRY
	CALL (T4)		;CALL PROCESSOR
	AOBJN P3,INFAL1		;FOR ALLL OF ALL
	RETURN			;FROM WHAT ALL
;
;
INFADR:
	MOVX P1,F.ADDR
	HRROI P2,TXTPTR< ADDRESS (WORDS EXIST IN IMAGE FILES)>
	CALLR INFNOC
;
;
INFCR:
	HRROI T2,TXTPTR< CRLF (IN ASCII FILES IS) >
	CALL TYPSTR
	HRROI T2,TXTPTR<DEFAULT>
	TXNE F,F.IBCR
	 HRROI T2,TXTPTR<IMBEDDED>
	TXNE F,F.IPCR
	 HRROI T2,TXTPTR<IMPLIED>
	TXNE F,F.LFSS
	 HRROI T2,TXTPTR<CARRIAGE-RETURN-SINGLE-SPACE>
	CALLR TYPSTC
;
;
INFIGN:
	MOVX P1,F.IGNR
	HRROI P2,TXTPTR< IGNORE (FILE FORMAT ERRORS)>
	CALLR INFNOC
;
;
INFMOD:
	HRROI T2,TXTPTR< MODE (OF INPUT) >
	CALL TYPSTR
	HLRZ T2,MODE
	HLRO T2,MSGTAB(T2)
	CALL TYPSTR
	HRROI T2,TXTPTR< (AND OUTPUT) >
	CALL TYPSTR
	HRRZ T2,MODE
	HLRO T2,MSGTAB(T2)
	CALLR TYPSTC
;
;
INFRCD:
	HRROI T2,TXTPTR< RECORD-SIZE (OF IMAGE FILES IS) >
	CALL TYPSTR
	MOVE T2,RCDSIZ
	MOVX T3,^D10
	NOUT
	 JSHLT
	CALLR TYPCR
;
;
INFTMP:
	MOVX P1,F.TEMP
	HRROI P2,TXTPTR< TEMPORARY (OUTPUT FILES)>
	CALLRX INFNOC
;
; INFNOC -- INFO ABOUT NO COMMAND
;
INFNOC:
	HRROI T2,TXTPTR< NO>
	TDNN F,P1
	 CALL TYPSTR
	MOVE T2,P2
	CALLR TYPSTC
	SUBTTL "CONVERT" COMMAND
;
; CONVERT (FILE) (OUTPUT AS)
;
$CONVERT:
	TXZA F,F.TTEM		;NOTE NOT TEMP FILES
;
; TCONVERT (FILE) (OUTPUT AS)
;
$TCONVERT:
	TXO F,F.TTEM		;NOTE TEMP OUTPUT FILES
	MOVX T1,GJ%OLD!GJ%IFG
	SETZB T2,T3
	MOVEI T4,[FLDDB. (.CMNOI,,TXTPTR<FILE>)]
	CALL FILE
	MOVEM T2,INJFN		;SAVE THE INPUT JFN
;
	SETZM SCRBUF
	HRROI T1,SCRBUF		;POINT TO SCRATCH
	MOVX T3,1B8		;NAME ONLY
	JFNS			;GET IT FOR DEFAULT
;
	SETZM SCRBUF+10
	HRROI T1,SCRBUF+10	;MORE OF SAME
	MOVX T3,1B11		;TYPE ONLY
	JFNS			;GET IT
;
	MOVX T1,GJ%FOU!GJ%MSG	;FOR OUTPUT USE FILE, [NEW/OLD FILE/GENERATION]
	TXNE T2,77B5		;INDEXABLE (I.E. WILD) INPUT FILE?
	 TXO T1,GJ%OFG		;YES-- GET OUTPUT FILE GROUP
	TXNE F,F.TEMP!F.TTEM	;TEMP OUTPUT FILES?
	 TXO T1,GJ%TMP		;YES-- MAKE IT SUCH
	SKIPE T2,SCRBUF		;IF NAME GET
	 HRROI T2,SCRBUF	; DEFAULT NAME
	SKIPE T3,SCRBUF+10	; . .
	 HRROI T3,SCRBUF+10	; . . TYPE
	MOVEI T4,[FLDDB. (.CMNOI,,TXTPTR<OUTPUT AS>)]
	CALL FILE
	MOVEM T2,MFOJFN		;SAVE THAT JFN
	CALL CONFRM
;
NXTFIL:
	HRRZ T1,CMDJFN		;GET COMMAND OUTPUT JFN
	HRRZ T2,INJFN		;FILE-NAME WE HAVE GOTTEN
	MOVX T3,0		;DEFAULT TYPE-OUT
	JFNS			;TYPE FILE-NAME
;
	TXZ F,F.TIBC!F.TLFS	;NO IMBEDDED CR, YET
	HLRZ IM,MODE		;GET THE MODE
	CAIE IM,M$DEF		;DEFAULT MODE?
	 JRST OUTFIL		;NO-- WE GOT THE MODE
;
; DETERMINE DEFAULT FILE MODE
;
	HRRZ T1,INJFN		;GET THE JFN AGAIN
	MOVX T2,OF%RD+^D18B5	;READ WORDS
	OPENF			;OPEN THE FILE
	 ERRJ
	BIN			;READ THE FIRST WORD OF THE FILE
	ERJMP .+1		;IGNORE EOF/ERRORS HERE
	MOVE IC,T2		;COPY THE WORD
	TXO T1,1B0		;DON'T RELEASE THE JFN
	CLOSF			;CLOSE THE FILE
	 ERRJ
;
	HRROI T1,SCRBUF		;POINT TO FILE-NAME BLOCK
	HRRZ T2,INJFN		;INPUT FILE NAME
	MOVX T3,1B11		;FILE-TYPE ONLY
	JFNS			;GET THE FILE TYPE
	MOVEI T1,EXTTAB		;POINT TO TABLE OF BINARY FILE TYPES
	HRROI T2,SCRBUF		;ALSO TO THE TYPE TO LOOK UP
	TBLUK			;LOOK UP FILE TYPE IN TABLE
	TXNN T2,TL%EXM		;EXACT MATCH?
	 JRST ASCFIL		;NO-- ASSUME ASCII
	HRRE IM,(T1)		;SAVE MODE
	JUMPL IM,ASCFL0		;ASCII WITH SPECIAL FLAGS-- GO SET THEM
	CAIE IM,M$RSB		;RSX-BINARY? (REALLY ANY BINARY)?
	 JRST OUTFIL		;NO-- WE HAVE THE MODE
	TXNN IC,177776		;DOS FORMATTED BINARY (FIRST WORD=0 OR 1)?
	 MOVX IM,M$DSB		;YES-- MARK AS SUCH
	JRST OUTFIL		;GOT TYPE
;
ASCFL0:
	HRLZ IM,IM		;GET THE FLAGS TO RIGHT (LEFT) HALF
	TXZ IM,1B0		;CLEAR SIGN SET AS FLAG
	TXNN F,F.IBCR!F.IPCR!F.LFSS ;CRLF EXPLICTLY SPECIFIED?
	 TDO F,IM		;NO-- SET BITS FOR THIS FILE TYPE
ASCFIL:
	MOVEI IM,M$RSA		;ASSUME RSX-ASCII
	TXNE IC,177B<17+7>	;IS THIS 7-BIT ASCII FILE?
	 MOVEI IM,M$DSA		;YES-- MARK AS SUCH
;
;
OUTFIL:
	HRRZ T1,CMDJFN
	HRROI T2,TXTPTR< [>
	CALL TYPSTR
	HLRO T2,MSGTAB(IM)	;GET PROPER INPUT MESSAGE
	CALL TYPSTR
	HRROI T2,[ASCIZ /] ==> /]
	CALL TYPSTR		;TYPE STRING
;
	HRRZ OM,MODE		;GET OUTPUT MODE
	CAIN OM,M$DEF		;DEFAULT?
	 HRRZ OM,MSGTAB(IM)	;YES-- GET DEFAULT TYPE
;
	MOVE T1,MFOJFN		;GET OUTPUT JFN
	MOVE T2,INJFN		;ALSO INPUT, FOR A SEC
	TXNN T2,77B5		;INPUT INDEXABLE?
	 JRST OUTFI2		;NO-- OUTPUT JFN ALREADY EXISTS
;
	HRROI T1,SCRBUF		;POINT TO SCRATCH NAME
	MOVSI T4,-FILLEN	;GET AOBJN POINTER TO WHAT WE NEED IN FILE SPEC
OUTFI1:
	SKIPE T2,FILTAB(T4)	;GET BIT TO TEST IN OUTPUT FILE HANDLE
	TDNN T2,MFOJFN		;IS THIS FIELD WILD?
	 SKIPA T2,MFOJFN	;NO-- USE IT
	HRRZ T2,INJFN		;YES-- COPY FIELD FROM INPUT
	AOBJN T4,.+1		;MOVE TO NEXT WORD IN TABLE
	MOVE T3,FILTAB(T4)	;GET THE BITS TO GET THIS FIELD ONLY FROM JFNS
	JFNS			;GET THIS FIELD
	AOBJN T4,OUTFI1		;LOOP FOR ALL FIELDS
;
	MOVX T1,GJ%FOU!GJ%SHT!GJ%PHY ;OUTPUT USE, PHYSICAL
	TXNE F,F.TEMP!F.TTEM	;TEMP OUTPUT FILES?
	 TXO T1,GJ%TMP		;YES-- MAKE IT SUCH
	HRROI T2,SCRBUF		;POINT TO NAME
	GTJFN			;GET OUTPUT FILE JFN
	 ERRJ
OUTFI2:
	MOVEM T1,OUTJFN		;SAVE THAT JFN
	HRRZ T2,T1		;COPY THE OUTPUT JFN
	HRRZ T1,CMDJFN		;GET COMMAND JFN BACK
	MOVEI T3,0		;DEFAULT OUTPUT
	JFNS			;TYPE OUTPUT FILE NAME
;
	HRROI T2,TXTPTR< [>
	CALL TYPSTR
	HLRO T2,MSGTAB(OM)	;GET OUTPUT MODE TEXT
	CALL TYPSTR
	HRROI T2,TXTPTR<]>
	CALL TYPSTC
;
	HRRZ T1,INJFN		;GET BACK THE INPUT JFN
	HLLZ T2,BSZTAB(IM)	;GET THE BYTE SIZE OF INPUT FILE
	TXO T2,OF%RD		;READ INPUT FILE
	OPENF			;OPEN INPUT FILE IN RIGHT BYTE SIZE
	 ERRJ
	HRRZ T1,OUTJFN		;OUTPUT ALSO
	HLLZ T2,BSZTAB(OM)	;OUTPUT SIZE
	TXO T2,OF%WR		;WRITE
	OPENF			;OPEN OUTPUT
	 ERRJ
	SETZB IC,INADR		;RESET INPUT CHAR, ADDR
	SETZB OC,OUTADR		; . . OUTPUT . .
;
; LOOP THROUGH FILE AND PROCESS
;
CNVTLP:
	CALL @GRCTAB(IM)		;GET AN INPUT RECORD BYTE COUNT
	 JRST DONE		;EOF-- GIVE UP
	MOVE P1,C		;COPY THE BYTE COUNT
	CALL @PRCTAB(OM)		;WRITE THE BYTE COUNT
	JUMPE P1,ENDRCD		;END OF RECORD-- FINISH UP
;
; COPY THE RECORD, BYTE COUNT IN P1
;
COPYLP:
	CALL @GBYTAB(IM)		;GET AN INPUT BYTE
	 ERRI <PREMATURE END-OF-FILE>,DONE
	CALL @PBYTAB(OM)		;STORE IT
	SOJG P1,COPYLP		;LOOP FOR WHOLE RECORD
;
ENDRCD:
	CALL @EORTAB(OM)		;FINISH OUTPUT RECORD
	CALL @EIRTAB(IM)		;FINISH INPUT RECORD
	JRST CNVTLP		;GET NEXT RECORD
;
; HERE WHEN DONE WITH CURRENT FILE
;
DONE:
	SKIPGE C,OC		;SKIP IF CHARACTER ALREADY OUTPUT
	 CALL PUTCHR		;NOPE-- PUT THE LAST WORD OUT INTO THE FILE
;
	HRRZ T1,OUTJFN		;GET OUTPUT FILE JFN
	CLOSF			;CLOSE THE JFN
	 ERRJ
	HRRZ T1,INJFN		;GET THE INPUT ONE,TOO
	TXO T1,1B0		;DON'T RELEASE THE JFN THOUGH
	CLOSF			;CLOSE INPUT FILE
	 ERRJ
;
	MOVE T1,INJFN		;GET INDEXABLE FILE HANDLE
	TXNE T1,77B5		;INDEXABLE?
	GNJFN			;GET NEXT JFN
	 RETURN			;DONE-- RETURN FROM CONVERT
	JRST NXTFIL		;PROCESS THIS NEW FILE
;
; THINGS IN A FILE-SPEC THAT WE MUST GET
;
FILTAB:
	EXP GJ%DEV,2B2+1B35	;DEVICE
	EXP GJ%DIR,2B5+1B35	;DIRECTORY
	EXP GJ%NAM,1B8+1B35	;FILE-NAME
	EXP GJ%EXT,1B11+1B35	;FILE-TYPE
	EXP GJ%VER,2B14+1B35	;GENERATION
	EXP 0,2B17+1B35		;PROTECTION
	EXP 0,2B20+1B35		;ACCOUNT
	EXP 0,1B21+1B35		;TEMPORARY
FILLEN==.-FILTAB
;
	SUBTTL	SAVE FILE ROUTINES
;
; BOOT FILE PROCESSING ROUTINE
;
SAVGRC:	MOVE P2,[POINT 8,SCRBUF] ;POINT TO SCRATCH
	MOVEM P2,INPTR
	SETZB P1,P3		;ZERO BYTE COUNTS
	CALL GETCHR		;GET A CHARACTER
	 JRST CRET		;EOF - EXIT
	JUMPL C,SAVGR1		;GO SAVE <-WC,,ADDR>
	HRRZI	T2,0(C)		; MAKE A REAL TRANSFER WORD
	JRST SAVGR2		; LOAD THE TRANSFER WORD IN THE FILE
SAVGR1:	HLRE P1,C		;SAVE THE WORD COUNT
	MOVEI T2,1(C)		;COMPUTE ADDRESS+1
SAVGR2:
	LDB T1,[POINT 8,T2,35]
	IDPB T1,P2
	LDB T1,[POINT 8,T2,27]
	IDPB T1,P2
	LDB T1,[POINT 8,T2,19]
	IDPB T1,P2
	LDB T1,[POINT 8,T2,11]
	IDPB T1,P2		;SAVE 4-BYTE ADDRESS
	ADDI P3,4
	JUMPGE C,SAVGR4		;ALL DONE IF TRANSFER WORD
SAVGR3: CALL GETCHR		;GET DATA
	 ERRI <PREMATURE END-OF-FILE>,CRET
	LDB T1,[POINT 8,C,35]	;PUT BITS 28-35 IN -11 BUFFER
	IDPB T1,P2
	LDB T1,[POINT 8,C,27]	;PUT BITS 20-27 IN -11 BUFFER
	IDPB T1,P2
	LDB T1,[POINT 8,C,19]	;PUT BITS 12-19 IN -11 BUFFER
	IDPB T1,P2
	LDB T1,[POINT 8,C,11]	;PUT BITS 4-11 IN -11 BUFFER
	IDPB T1,P2
	LDB T1,[POINT 4,C,3]	;PUT BITS 0-3 IN -11 BUFFER
	IDPB T1,P2
	ADDI P3,5		;ADD TO -11 BYTE COUNT
	AOJL P1,SAVGR3		;CONTINUE UNTIL WORD COUNT EXHAUSTED
SAVGR4:	MOVE C,P3		;END OF RECORD - COPY OUTPUT BYTE COUNT
	RETSKP			;RETURN, BYTE COUNT IN C
;
SAVEIR:
	RETURN
SAVPRC:
SAVPBY:
SAVEOR:
	ERRI <SAVE FILE OUTPUT NOT IMPLEMENTED>,CRET
SUBTTL	RAMGRC --  CONVERT ASCIIZED RAM FILE TO BINARY 7-JUL-76/RAB

; HERE TO GET A BYTE FROM THE CONVERTED FILE
; THE BYTE IS RETURNED IN AC "C". "RAMGBY" ALWAYS TAKES A SKIP RETURN.

RAMGBY:
	ILDB	C,INPTR		; CURRENT BYTE TO "C"
	RETSKP			; OFF INTO THE COSMIC VOID

; HERE TO CONVERT ONE LINE OF THE INPUT FILE AND RETURN THE BYTE COUNT IN "C"
; COMMENTS, NULL LINES, AND ZERO COMMANDS ARE IGNORED. CHARACTERS
; WHICH BEGIN A LINE OTHER THAN "C", "D", "Z", OR ";" ARE FLAGGED AS
; ERRORS AND THAT LINE IS IGNORED. "RAMGRC" ALWAYS TAKES A SKIP RETURN,
; EXCEPT ON END-OF-FILE, WHERE IT TAKES A DIRECT RETURN.

RAMGRC:	JUMPN	IC,CRET		; EXIT IF E-O-F FLAG SET
	MOVE	P4,[POINT 16,SCRBUF]
	SETZ	P3,0		; RESET THE BYTE COUNT
	CALL	GETCHR		; READ THE FIRST CHARACTER OF THIS LINE
	 JRST RAMEOF		; E-O-F -- EXIT
	JUMPE	C,RAMGRC	; IGNORE NULLS
	CAIE	C,12		; NEW-LINE?
	CAIN	C,15		; CARRIAGE-RETURN?
	JRST	RAMGRC		; YES -- IGNORE NULL LINE
	CAIN	C,"C"		; C(RAM)?
	JRST	RAMCRM		; YES
	CAIN	C,"D"		; D(RAM)?
	JRST	RAMDRM		; YES
	CAIE	C,"Z"		; Z(ERO CRAM)?
	CAIN	C,";"		; COMMENT?
	SKIPA	0,0		; YES, SKIP OVER ERROR
	 ERRI	<ILLEGAL RAM INPUT CHARACTER>,RAMSKP
	;

; HERE TO GET OVER A NULL LINE. THE LINE IS SCANNED UNTIL A
; <NEW-LINE> CHARACTER IS SEEN AND CONTROL IS PASSED TO "RAMGRC"

RAMSKP:
	CALL	RAMNUL		; GET OVER THE NULL LINE
	JRST	RAMGRC		; AND LOOK AT THE NEXT LINE

; HERE TO READ OVER A NULL OR ERRONEOUS LINE IN THE INPUT FILE

RAMNUL:
	CALL	GETCHR		; READ A CHARACTER
	 JRST	RAMEOF		; DONE -- GO GET THE NEXT LINE
	CAIE	C,12		; IS THIS A NEW-LINE?
	JRST	RAMNUL		; NO -- GO GET THE NEXT CHARACTER
	RETURN			; YES -- EXIT

; HERE TO PROCESS THE CRAM ADDRESS (FLAG IT WITH 1B16)

RAMCRM:
	CALL	RAMCNT		; GET THE WORD COUNT
	CALL	RAMCRA		; CONVERT THE ADDRESS
	JRST	RAMCMN		; DO COMMON CODE

; HERE TO PROCESS THE DRAM WORD

RAMDRM:
	CALL	RAMCNT		; GET THE WORD COUNT
	CALL	RAMWRD		; CONVERT THE ADDRESS
	JRST	RAMCMN		; CONVERT THE DATA

; HERE TO GET OVER THE BYTE COUNT AND PROCESS THE REST OF THE LINE

RAMCNT:
	MOVE	P2,P4		; SAVE THE BYTE POINTER IN P2
	CALL	RAMWRD		; CONVERT THE WORD COUNT
	JUMPE	P1,RMCNTN	; IGNORE NULL LINES
	SUBI	P3,2		; RESET THE BYTE COUNT
	MOVE	P4,P2		; RESET THE BYTE POINTER
	LSH	P1,-^D8		; STRAIGHTEN THE WORD COUNT OUT
	MOVE	P2,P1		; WORD COUNT TO P2
	RETURN			; WORD COUNT IN P2
RMCNTN:
	HRRI	T1,RAMSKP	; GET OVER NULL LINE
	HRRM	T1,0(P)		; FUDGE RETURN ADDRESS
	RETURN			; SO
RAMCMN:
	CALL	RAMWRD		; CONVERT THE WORD
	SOJN	P2,RAMCMN	; AND LOOP TILL DONE
	CALL	RAMNUL		; END THIS LINE
RAMEOL:
	MOVE	C,P3		; BYTE COUNT TO "C"
	MOVE	T1,[POINT 8,SCRBUF]
	MOVEM	T1,INPTR	; SET UP THE BYTE POINTER
	RETSKP			; BYTE COUNT FOR THIS LINE IS IN "C"

; HERE TO PROCESS END OF FILE

RAMEOF:	SETO	IC,0		; FLAG THE E-O-F
	MOVEI	P3,2		; BYTE COUNT TO P3
	MOVX	T1,1B<15-7>	; FLAG THE XFER ADDRESS
	MOVEM	T1,SCRBUF	; SET IT IN THE BUFFER
	JRST	RAMEOL		; EXIT THRU RAMEOL

; HERE TO CONVERT THE CRAM ADDRESS

RAMCRA:
	TXO	F,F.CRMA	; SAY THIS IS A CRAM ADDRESS

; HERE TO CONVERT ONE WORD

RAMWRD:
	SETZ	P1,0		; CLEAR P1
	CALL	RAMCHR		; CONVERT THE FIRST CHARACTER
	 JRST	RAMEND		; END OF THIS WORD
	MOVE	P1,T2		; SAVE IT IN "P1"
	CALL	RAMCHR		; CONVERT THE SECOND CHARACTER
	 JRST	RAMEND		; END OF THIS WORD
	LSH	P1,^D6		; POSITION PREVIOUS
	IOR	P1,T2		; AND STASH IT AWAY
	CALL	RAMCHR		; CONVERT THE THIRD CHARACTER
	 JRST	RAMEND		; END OF THIS WORD
	LSH	P1,^D6		; POSITION PREVIOUS
	IOR	P1,T2		; FINISH THE WORD UP
RAMEND:
	CAIE	C,12		; WAS THE LAST CHARACTER A <NEW-LINE>?
	CAIN	C,","		; OR A COMMA?
	JRST	RAMENX		; YES -- JUST EXIT
	CALL	GETCHR		; NO -- GET OVER THE TRAILING WHATEVER
	 ERRI	<PREMATURE END-OF-FILE>,CRET
	CAIE	C,12		; IS IT A <NEW-LINE>?
	CAIN	C,","		; OR A <COMMA>?
	JRST	RAMENX		; YES -- ALL OK
	 ERRI	<ILLEGAL RAM FILE FORMAT>,CRET
RAMENX:
	TXZE	F,F.CRMA	; WAS THIS A CRAM ADDRESS?
	IORI	P1,1B<35-15>	; YES -- FLAG IT
	LDB	T1,[POINT 8,P1,27]
	LSH	P1,^D8		; FINISHED -- SWAP THE BYTES
	IOR	P1,T1		; SET THE HIGH BYTE
	IDPB	P1,P4		; LOAD THE BYTE
	ADDI	P3,2		; INCREMENT THE BYTE COUNT
	RETURN			; AND EXIT

; HERE TO CONVERT A SINGLE CHARACTER

RAMCHR:
	CALL	GETCHR		; GET A CHARACTER
	 ERRI	<PREMATURE END-OF-FILE>,CRET
	JUMPE	C,RAMCHR	; FLUSH NULLS
	CAIE	C,11		; TAB?
	CAIN	C,40		; SPACE?
	JRST	RAMCHR		; YES -- FLUSH THOSE TOO
	CAIN	C,15		; CARRIAGE RETURN?
	JRST	RAMCHR		; YES -- FLUSH IT
	CAIE	C,","		; COMMA?
	CAIN	C,12		; NEW-LINE?
	 RETURN			; YES -- GIVE EOL RETURN
	CAIGE	C,75		; IS THIS CHARACTER LEGAL?
	 ERRI	<ILLEGAL RAM CHARACTER>,RAMCHR
	MOVE	T2,C		; PUT THE CHARACTER IN AC "T2"
	ANDI	T2,77		; CONVERT THE CHARACTER
	RETSKP			; SKIP RETURN

RAMEIR:
	RETURN			; INTO THE GREAT BEYOND

RAMPRC:
RAMPBY:
RAMEOR:
	ERRI	<RAM FILE OUTPUT NOT IMPLEMENTED>,CRET
	SUBTTL	7-BIT-ASCII ROUTINES
;
; 7-BIT ASCII ROUTINES
;
DSAGRC:
	MOVE P2,[POINT 7,SCRBUF] ;POINT TO SCRATCH
	MOVEM P2,INPTR		;SAVE THE FRESH POINTER FOR FETCHING BYTES
	SETZ P1,		;NO BYTES YET
DSAGR1:
	CALL GETCHR		;GET A CHARACTER FROM INPUT
	 JRST DSAGR3		;EOF-- THAT'S IT IF NULL RECORD
	JUMPE C,DSAGR1		;IGNORE NULLS
	CAIE C,.CHFFD		;<FF> OR
	TXNE F,F.IBCR		;IMBEDDED <CR><LF>'S?
	 AOJA P1,DSAGR2		;YES-- PUT CHAR AWAY
	CAIN C,.CHCRT		;<CR>?
	 JRST DSAGR1		;YES-- IGNORE
	CAIE C,.CHLFD		;<LF>?
	CAIN C,.CHCNS		;SINGLE SPACE?
	 JRST DSAGR4		;YES-- END OF RECORD
	IDPB C,P2		;NO-- STORE BYTE
	AOJA P1,DSAGR1		; AND GET ANOTHER
;
DSAGR2:
	IDPB C,P2		;STORE BYTE
	CAIE C,.CHLFD		;<LF>?
	CAIN C,.CHFFD		; OR <FF>?
	 JRST DSAGR4		;YES-- END OF RECORD
	JRST DSAGR1		;NO-- GET NEXT CHARACTER
;
DSAGR3:
	JUMPE P1,CRET		;EOF-- DONE NOW IF NULL RECORD
DSAGR4:
	MOVE C,P1		;END OF RECORD-- COPY THE BYTE COUNT
	RETSKP			;AND SKIP BACK FROM DSAGRC
;
;
DSAEOR:
	CAIE C,.CHFFD		;LAST CHAR = <FF>?
	TXNE F,F.IBCR!F.TIBC	;IMBEDDED CR'S?
	 RETURN			;YES-- DON'T ADD ANY
	MOVEI C,.CHCRT		;GET <CR>
	CALL @PBYTAB(OM)	;AND OUTPUT IT
	MOVEI C,.CHLFD		;AND THE <LF>
	TXNE F,F.LFSS!F.TLFS	;LINE-FEED = SINGLE SPACE?
	 MOVEI C,.CHCNS		;YES-- USE SINGE-SPACE (^S)
	CALLR @PBYTAB(OM)	; AND RETURN FROM DSAEOR
	SUBTTL	DOS-BINARY ROUTINES
;
; DOS-BINARY ROUTINES
;
DSBGRC:
	SETZM INCHK		;RESET INPUT CHECKSUM
DSBGR1:
	CALL GETBYT		;GET AN INPUT BYTE
	 RETURN			;THAT'S ALL, FOLKS
	JUMPE C,DSBGR1		;LOOP FOR NON-ZERO BYTE
	CAIE C,1		;FIRST BYTE= 1?
BADBLK:	 ERRI <BAD BLOCK FORMAT>,DSBGR1
	CALL GETBYT		;GET THE HIGH BYTE OF THE 1
	 ERRI <PREMATURE END-OF-FILE>,CRET
	JUMPN C,BADBLK		;MUST BE ZERO
	CALL GET2BY		;GET BYTE COUNT WHICH FOLLOWS
	 ERRI <PREMATURE END-OF-FILE>,CRET
	SUBI C,4		;REAL BYTE COUNT, LESS OVERHEAD WORDS
	RETSKP			;RETURN, BYTE COUNT IN C
;
;
DSBEIR:
	CALL GETBYT		;GET THE CHECKSUM
	 ERRI <PREMATURE END-OF-FILE>,CRET
	MOVE T1,INCHK		;ALL TOGETHER NOW
	TXNE T1,377		; SHOULD BE ZERO BYTE
	 ERRI <BAD CHECKSUM>,CRET
	RETURN			;OK FROM DSBEIR
;
;
DSBPRC:
	SETZM OUTCHK		;RESET OUTPUT CHECKSUM
	MOVEI C,1		;FIRST BYTES =1,0
	CALL PUT2BY		;PUT 'EM AWAY
	MOVEI C,4(P1)		;GET THE BYTE COUNT BACK
	CALLR PUT2BY		;PUT THE WORD AWAY, AND RETURN FROM DSBPRC
;
;
DSBEOR:
	MOVN C,OUTCHK		;GET OUTPUT CHECKSUM
	CALL PUTBYT		;PUT IT AWAY
	MOVX C,0		;NULL
	CALL PUT2BY		;2 BYTES OF NULL
	CALL PUT2BY		;4 BYTES OF NULL
	CALLR PUT2BY		;6 BYTES OF NULL, AND RETURN
	SUBTTL	IMAGE-BINARY ROUTINES
;
; IMAGE-BINARY ROUTINES
;
IMBGRC:
	SETZ P1,		;RESET BYTE COUNT
	MOVE P2,[POINT 8,SCRBUF] ;POINT TO SCRATCH
	MOVEM P2,INPTR		;SAVE THE POINTER FOR GET BYTES,ALSO
	MOVE P3,RCDSIZ		;COPY RECORD-SIZE, ALSO
	TXNN F,F.ADDR		;NO ADDRESS WORDS ON OUTPUT?
	 JRST IMBGR1		;YES-- SKIP THEM
	MOVE T1,INADR		;GET CURRENT INPUT ADDRESS
	IDPB T1,P2		;STORE THE LOW BYTE ADDRESS
	LSH T1,-^D8		;GET HIGH BYTE
	IDPB T1,P2		;STORE THAT,TOO
	SUBI P3,2		;DECREMENT RECORD COUNT
IMBGR1:
	CALL GETBYT		;GET AN INPUT BYTE
	 JRST IMBGR2		;EOF-- FINISH OFF
	IDPB C,P2		;STORE THE BYTE
	ADDI P1,1		;BUMP COUNT
	SOJG P3,IMBGR1		;COUNT DOWN ONE FROM RECORD SIZE
IMBGR2:
	JUMPE P1,CRET		;ZERO BYTES-- RETURN ON EOF
	ADDM P1,INADR		;BUMP ADDRESS
	TXNE F,F.ADDR		;NO ADDRESSES?
	 ADDI P1,2		;NO-- ADD TWO BYTES OF ADDRESS
	MOVE C,P1		;COPY BYTE COUNT
	RETSKP			;SKIP BACK FROM IMBGRC
;
;
SAVGBY:
DSAGBY:
IMBGBY:
	ILDB C,INPTR		;GET A BYTE FROM SCRBUF
	RETSKP			;ALWAYS OK
;
;
IMBPRC:
	TXNN F,F.ADDR		;ADDRESSES IN FILE?
	 TDZA T1,T1		;NO-- SKIP NOT
	MOVEI T1,2		;YES-- SKIP 2 BYTES
	MOVEM T1,OUTADR		;SAVE THAT COUNT
	RETURN			;RETURN FROM IMBPRC
;
;
IMBPBY:
	SOSGE OUTADR		;SKIPED ADDRESS YET?
	 CALL PUTBYT		;YES-- PUT THE BYTE AWAY
	RETURN			;FROM IMBPBY
	SUBTTL	IMAGE ROUTINES
;
; IMAGE ROUTINES
;
IMGGRC:
	CALL GETCHR		;SEE IF THERE IS ANOTHER BYTE IN FILE
	 RETURN			;NO, GIVE EOF RETURN
	MOVEM C,INCHK		;YES, SAVE THE BYTE
	MOVEI C,1		;ONE CHARACTER IN THIS RECORD
	RETSKP			;GIVE GOOD RETURN
;
IMGGBY:	MOVE C,INCHK		;GET SAVED BYTE (ONLY ONE IN RECORD)
	RETSKP			;GIVE GOOD RETURN
;
IMGEIR:
IMGPRC:
IMGEOR:
	RETURN			;IGNORE THESE CALLS
;
IMGPBY:	JRST PUTCHR		;OUTPUT IS JUST STORE BYTE
;
	SUBTTL	ELEVEN ROUTINES
;
; ELEVEN ROUTINES
;
ELVGRC:
	CALL GETBYT		;SEE IF THERE IS ANOTHER WORD IN FILE
	 RETURN			;NO, GIVE EOF RETURN
	MOVEM C,INCHK		;YES, SAVE THE BYTE
	MOVEI C,1		;ONE CHARACTER IN THIS RECORD
	RETSKP			;GIVE GOOD RETURN
;
ELVGBY:	MOVE C,INCHK		;GET SAVED BYTE
	RETSKP			;GIVE GOOD RETURN
;
ELVEIR:	RETURN			;NO USE FOR THIS ENTRY POINT
;
;
ELVPRC:	RETURN			;NOR THIS ONE
;
ELVPBY:	JRST PUTBYT		;OUTPUT IS JUST WRITE BYTE
;
ELVEOR:	RETURN			;NO USE FOR THIS ENTRY POINT
;
	SUBTTL	COMMON I/O ROUTINES
;
; GET2BY -- GET A WORD FROM TWO BYTES OF INPUT
;
GET2BY:
	CALL GETBYT		;GET FIRST BYTE
	 RETURN			;JUST GIVE UP
	HRLM C,(P)		;SAVE THE BYTE ON STACK
	CALL GETBYT		;GET HIGH BYTE
	 RETURN			;EOF-- RETURN +1
	LSH C,^D8		;SHIFT TO HIGH BYTE
	HLRZ T1,(P)		;GET LOW BYTE AGAIN
	IOR C,T1		;SAVE ASSEMBLED WORD
	RETSKP			;FROM GET2BY
;
; GETBYT -- GET AN 8-BIT BYTE FROM INPUT
;
GETBYT:
	SKIPGE C,IC		;GET OLD BYTE, IF ANY
	 JRST GETBY2		;GOT IT-- GO ON
	CALL GETWRD		;DON'T HAVE IT-- GET NEXT TWO BYTES
	 RETURN			;EOF-- RETURN +1
	TXOA C,1B0		;NOTE WE HAVE A BYTE HERE
GETBY2:	 LSH C,-^D8		;GET HIGH BYTE
	MOVE IC,C		;AND SAVE THE WORD FOR NEXT CALL
	ANDI C,377		;TRIM TO A BYTE
	ADDM C,INCHK		;ACCUMULATE INPUT CHECKSUM
	RETSKP			;FROM GETBYT
;
; GETWRD -- GET A WORD FROM INPUT FILE
;
GETWRD:
	SETZ IC,		;NO LONGER A BYTE TO INPUT
	CALLRX GETCHR		;GET THE NEXT CHAR
;
; GETCHR -- GET A CHARACTER FROM THE INPUT FILE
;
GETCHR:
	HRRZ T1,INJFN		;GET THE INPUT JFN
	BIN			;GET THE BYTE
GETEOF:
	MOVE C,T2		;GET THE CHARACTER TO C
CRET1:
	 AOS(P)			;SKIP RETURN
CRET:
	RETURN			;RETURN +1
;
; PUT2BY -- PUT 2 BYTES FROM A WORD INTO OUTPUT FILE
;
PUT2BY:
	HRLM C,(P)		;SAVE THE CHARACTER
	CALL PUTBYT		;STORE LOW BYTE
	HLRZ C,(P)		;GET THE WORD AGAIN
	LSH C,-^D8		;BUT HIGH BYTE THIS TIME
	CALLRX PUTBYT		;STORE IN OUTPUT, RETURN FROM PUT2BY
;
; PUTBYT -- PUT BYTE IN OUTPUT FILE
;
PUTBYT:
	ANDI C,377		;TRIM TO A BYTE
	ADDM C,OUTCHK		;ACCUMULATE OUTPUT CHECKSUM
	JUMPL OC,PUTBY2		;SKIP IF ALREADY A BYTE TO OUTPUT
	TXO C,1B0		;NOPE-- SAY WE HAVE A BYTE
	MOVE OC,C		; AND SAVE IT
	RETURN			;FROM PUTBYT
;
PUTBY2:
	LSH C,^D8		;SHIFT NEW BYTE TO HIGH BYTE
	IOR C,OC		;PUT IN THE LOW BYTE FROM LAST CALL
	SETZ OC,		; AND RESET THE BYTE
	CALLRX PUTWRD		;PUT WORD, AND RETURN FROM PUTBYT
;
; PUTWRD -- PUT A WORD IN OUTPUT FILE
;
PUTWRD:
	EXCH C,OC		;GET OUTPUT BYTE, IF ANY
	SKIPGE C		;ANY LEFT-OVER BYTE?
	 CALL PUTCHR		;YES-- OUTPUT IT
	MOVE C,OC		;GET THE CURRENT CHARACTER
	SETZ OC,		;RESET THE OLD CHARACTER
	CALLRX PUTCHR		;OUTPUT THE CURRENT WORD
;
; PUTCHR -- PUT A CHARACTER IN THE OUTPUT FILE
;
PUTCHR:
	HRRZ T1,OUTJFN		;GET OUTPUT FILE JFN
	MOVE T2,C		;ALSO CURRENT CHARACTER
	BOUT			;DO THE BYTE OUTPUT
	RETURN			;ALL DONE
;
; HERE ON EOF TRAP
;
EOFTRP:
	HRRZ T1,CHN1PC		;GET PC OF TRAP
	MOVEI T2,CRET		;ASSUME EOF FROM GETCHR
	CAIN T1,GETEOF		;EOF FROM GETCHR?
	 JRST EOFTRX		;YES-- RETURN +1
;
	HLRZ T1,CMDJFN		;GET INPUT JFN
	GTSTS			;GET STATUS
	TXNN T2,GS%EOF		;EOF ON COMMAND FILE?
	 ERR <UNEXPECTED END-OF-FILE TRAP>
	TMSG <[END OF COMMAND FILE]
>
	MOVEI T2,CMDRST		;RE-INIT COMMAND
EOFTRX:
	MOVEM T2,CHN1PC		;STORE RETURN PC
	DEBRK			;EXIT FROM INTERRUPT
;
;
DEFGRC==<DEFPRC==<DEFEIR==<DEFEOR==<DEFGBY==<DEFPBY==< CRET >>>>>>
DSAPRC==<DSAEIR==<RSAEIR==<RSAEOR==<RSBEIR==<RSBEOR==< CRET >>>>>>
IMBEIR==<IMBEOR==< CRET >>
;
DSBGBY==<RSAGBY==<RSBGBY==< GETBYT >>>
RSAGRC==<RSBGRC==< GETWRD >>
DSBPBY==<RSAPBY==<RSBPBY==< PUTBYT >>>
RSAPRC==<RSBPRC==< PUTWRD >>
DSAPBY==< PUTCHR >
	SUBTTL COMMAND ROUTINES
;
; NOICFM -- NOISE AND CONFIRM
;
NOICFM:
	CALL NOISE		;TYPE NOISE
	CALLRX CONFRM		;GET CONFIRMATION
;
; CONFRM -- GET COMMAND CONFIRMATION
;
CONFRM:
	MOVEI T1,CMDBLK		;
	MOVEI T2,[FLDDB. (.CMCFM)]
	COMND
	ERJMP [ERRJ ()]
	TXNE T1,CM%NOP		;OK?
	 ERR <INVALID CONFIRMATION>
	RETURN			;RETURN FROM CONFIRM
;
; NOISE -- PROCESS NOISE WORD
;
NOISE:
	MOVEI T1,CMDBLK
	COMND
	ERJMP [ERRJ ()]
	RETURN			;NO-- HOPE WE LIKE IT
;
; FILE -- DO A FILE SPEC, WITH A NOISE WORD
;
FILE:
	PUSH P,T4		;SAVE NOISE
	CALL CLRGFB		;RESET GTJFN BLOCK
	POP P,T2		;RESTORE THE NOISE
	CALL NOISE		;DO THE NOISE
	MOVEI T2,[FLDDB. (.CMFIL)]
FILE1:
	COMND			;GET A FILE SPEC
	ERJMP [ERRJ ()]
	TXNE T1,CM%NOP		;SUCCESS?
	 ERRJ
	RETURN			;YES-- RETURN FROM FILE
;
; CLRGFB -- CLEAR GETJFN BLOCK AND STORE FLAGS/GENERATION
;
CLRGFB:
	SETZM GJFBLK		;CLEAR
	MOVE T4,[XWD GJFBLK,GJFBLK+1]
	BLT T4,GJFBKE		; TO END
	MOVEM T1,GJFBLK+.GJGEN	;STORE THE FLAGS
	MOVEM T2,GJFBLK+.GJNAM	;STORE DEFAULT NAME
	MOVEM T3,GJFBLK+.GJEXT	;STORE DEFAULT EXT
	RETURN			;ALL DONE
;
; CLSCMD -- CLOSE COMMAND/LOG FILES IF OPEN
;
CLSCMD:
	MOVE T3,ICMBLK+.CMIOJ	;GET STANDARD JFNS
	EXCH T3,CMDJFN		;SAVE THEM
	HRRZ T1,T3		;GET OUTPUT
	CLOSF			;CLOSE IT
	 ERRJ
	HLRZ T1,T3		;AND INPUT
	CLOSF			; . .
	 ERRJ
	RETURN			;FROM CLSCMD
;
; TYPTST -- SEE IF <CRLF> NEEDED, IF SO SUPPLY ONE
;
TYPTST:
	DOBE			;WAIT UNTIL OUTPUT FINISHED
	RFPOS			;GET COLUMN COUNT
	SKIPE T2		;IF ZERO, THEN NOT A TTY
	TRNE T2,-1		;COLUMN ZERO?
	 CALL TYPCR		;NO-- OUTPUT A CRLF FIRST
	RETURN			;FROM TYPTST
;
; TYPSTC -- TYPE STRING, FOLLOWED BY <CRLF> (SEE TYPSTR)
;
TYPSTC:
	CALL TYPSTR
	CALLRX TYPCR
;
; TYPCR -- TYPE <CRLF>
;
TYPCR:
	HRROI T2,TXTPTR<
>
	CALLRX TYPSTR
;
; TYPSTR -- TYPE A STRING
;	T1 -- JFN TO OUTPUT ON
;	T2 -- STRING POINTER
;
TYPSTR:
	SETZ T3,		;ASCIZZZZ
	SOUT			;SEND THE DATA
	RETURN			;ALL DONE
	SUBTTL END
	END XWD 3,ENTVEC