Google
 

Trailing-Edge - PDP-10 Archives - SRI_NIC_PERM_SRC_3_19910112 - mit/exec/exec2.mac
There are 47 other files named exec2.mac in the archive. Click here to see a list.
;713 add literals label
;712 DEC release version
; UPD ID= 131, SNARK:<5.EXEC>EXEC2.MAC.8,  13-Jan-82 16:15:37 by TILLSON
;TCO 5.1671 Copy user settable word
; UPD ID= 120, SNARK:<5.EXEC>EXECIN.MAC.21,  28-Dec-81 11:14:01 by CHALL
;TCO 5.1644 - UPDATE COPYRIGHT NOTICE
; UPD ID= 33, SNARK:<5.EXEC>EXEC2.MAC.5,  14-Aug-81 19:12:18 by CHALL
;TCO 5.1454 CHANGE NAME FROM XDEF TO EXECDE
; UPD ID= 1816, SNARK:<5.EXEC>EXEC2.MAC.4,  16-Apr-81 18:20:36 by TILLSON
;TCO 5.1286 - Pass LBLSKP a JFN, not a device type
; UPD ID= 1808, SNARK:<5.EXEC>EXEC2.MAC.3,  15-Apr-81 11:12:56 by TILLSON
;TCO 5.1282 - Stop 512-page COPY from going long
; UPD ID= 1725, SNARK:<5.EXEC>EXEC2.MAC.2,  17-Mar-81 13:14:38 by SCHMITT
;TCO 5.1274 - Fix COPY from labelled EBCDIC tapes to use bytesize 7
;REMOVE MFRK CONDITIONALS
; UPD ID= 1190, SNARK:<5.EXEC>EXEC2.MAC.6,  23-Oct-80 14:08:40 by TILLSON
;tco 5.1178 - Fix COPY from labelled ANSI-ASCII tapes to use bytesize 7
; UPD ID= 803, SNARK:<5.EXEC>EXEC2.MAC.5,  28-Jul-80 09:53:36 by OSMAN
;tco 5.1113 - Don't type [OK] until after CLOSF
; UPD ID= 532, SNARK:<5.EXEC>EXEC2.MAC.4,  20-May-80 14:55:27 by MURPHY
;CHANGE SOME XTND TO NEWF OR MFRK
; UPD ID= 490, SNARK:<4.1.EXEC>EXEC2.MAC.6,  29-Apr-80 16:20:51 by TOMCZAK
;TCO 4.1.1152 - Add ERJMP after XCT in COPNCR, change SKIPE to JUMPE
;more 4.1.1099 - Handle files with page 777777
; UPD ID= 303, SNARK:<4.1.EXEC>EXEC2.MAC.2,   5-Mar-80 11:24:23 by OSMAN
;tco 4.1.1099 - Fix COPY to not go forever on files exactly one section long
;<4.EXEC>EXEC2.MAC.76,  8-Oct-79 15:32:41, EDIT BY OSMAN
;tco 4.2518 - Remove LIST
;<4.EXEC>EXEC2.MAC.75, 14-Sep-79 16:00:14, EDIT BY TOMCZAK
;TCO 4.2470  - Checking for nonexistent sections in long files at PREFLT
;TCO 4.2448 - Remove ERJMPs, so DATPSI can do its fancy analysis
;<4.EXEC>EXEC2.MAC.73,  6-Sep-79 11:08:51, Edit by HESS
; Fix DETACH (AND) CONTINUE (XTND only)
;<HESS.TEMP.E>EXEC2.MAC.2, 27-Jul-79 12:36:31, Edit by HESS
; Add extended features
;<4.EXEC>EXEC2.MAC.71, 10-Aug-79 15:12:28, EDIT BY OSMAN
;USE TYPFLS IN TYPE COMMAND
;<4.EXEC>EXEC2.MAC.69, 19-Jul-79 08:32:11, EDIT BY OSMAN
;tco 4.2335 - Use SYSTEM: instead of PS:[SYSTEM] in ^ESPEAK
;<4.EXEC>EXEC2.MAC.68, 21-Jun-79 13:34:46, EDIT BY OSMAN
;REMOVE EXTRANEOUS RLJFNS REF
;<4.EXEC>EXEC2.MAC.67, 19-Jun-79 14:19:35, EDIT BY OSMAN
;tco 4.2295 - fix BYTE-SIZE (TXO was wrong)
;<4.EXEC>EXEC2.MAC.66,  4-Jun-79 09:39:47, EDIT BY OSMAN
;CORRECTLY POSITION THE "MOVE D,DESTYP"
;<4.EXEC>EXEC2.MAC.59, 29-May-79 16:05:11, EDIT BY OSMAN
;WHEN WRITING IN ASCII TO STANDARD TAPE, PUT ONE TEXT LINE PER RECORD
;<4.EXEC>EXEC2.MAC.54,  2-May-79 10:24:33, EDIT BY OSMAN
;GET RID OF REFERENCES TO CJFN1 AND CJFN2
;<4.EXEC>EXEC2.MAC.53, 12-Mar-79 17:49:03, EDIT BY KONEN
;UPDATE COPYRIGHT FOR RELEASE 4
;<4.EXEC>EXEC2.MAC.52,  2-Feb-79 15:33:27, EDIT BY HEMPHILL
;TCO 4.2183 -- MAKE "BYTE" SUBCOMMAND VISIBLE
;<4.EXEC>EXEC2.MAC.48, 15-Sep-78 22:58:51, EDIT BY OSMAN
;REMOVE ALL REFS TO CSBUFP
;<4.EXEC>EXEC2.MAC.47, 14-Sep-78 11:57:45, EDIT BY OSMAN
;ONLY SEARCH XDEF, TTITLE NOW SEARCHES ALL ELSE
;<4.EXEC>EXEC2.MAC.45, 12-Aug-78 16:33:46, EDIT BY OSMAN
;TCO 4.1982 DON'T BOMB OUT ENTIRE COPY IF OPENF FAILS ON INPUT FILE
;<4.EXEC>EXEC2.MAC.43, 12-Aug-78 16:14:58, EDIT BY OSMAN
;CHANGE OPNERR TO RETURN AFTER PRINTING ERROR.
;<4.EXEC>EXEC2.MAC.30, 12-Aug-78 13:19:01, EDIT BY OSMAN
;TCO 4.1981 - PUT IN FASTER DISK-TO-DISK COPY
;<4.EXEC>EXEC2.MAC.24, 10-Aug-78 08:41:35, EDIT BY OSMAN
;<4.EXEC>EXEC2.MAC.23,  9-Aug-78 17:10:35, EDIT BY OSMAN
;TCO 1976 - DON'T ADVERTISE NONX SUBCOMMANDS IN TYPE COMMAND
;<4.EXEC>EXEC2.MAC.20, 18-Jul-78 17:03:03, EDIT BY OSMAN
;REMOVE ALL LIST COMMAND SUBCOMMANDS (THE COMMAND WILL BE REMOVED TOO
;WHEN /DISP:RENAME IS ADDED TO PRINT)
;<4.EXEC>EXEC2.MAC.12, 13-Jul-78 14:26:39, EDIT BY OSMAN
;MAKE POJFLG BE LOCAL
;<4.EXEC>EXEC2.MAC.11, 11-Jul-78 14:40:56, EDIT BY OSMAN
;MAKE TADBLK BE LOCAL
;<4.EXEC>EXEC2.MAC.9, 11-Jul-78 10:37:07, EDIT BY OSMAN
;MAKE PREPAG BE LOCAL VARIABLE
;<4.EXEC>EXEC2.MAC.8, 10-Jul-78 20:58:58, EDIT BY OSMAN
;MAKE TTY COPY USE LOCAL STORAGE, AND RENAME FROM TEXTIB TO TTBLK
;<4.EXEC>EXEC2.MAC.6, 28-Jun-78 16:20:06, EDIT BY OSMAN
;PUT ALL LIST COM VARIABLES IN TRVAR
;<4.EXEC>EXEC2.MAC.5, 26-Jun-78 11:14:39, EDIT BY OSMAN
;CHANGE "LIST"'S USE OF P6 TO CCOUNT TO FREE UP P6 FOR TRVAR
;(P.S.  LET'S THROW OUT LIST COMPLETELY! [MAYBE SOMEONE WOULD YELL])
;<4.EXEC>EXEC2.MAC.4, 23-Jun-78 21:06:01, EDIT BY OSMAN
;REMOVE ASCII1, LSTH2D (UNREFERENCED SYMS)
;<4.EXEC>EXEC2.MAC.3,  9-Jun-78 18:04:37, EDIT BY OSMAN
;CHANGE CALLS TO FIELD TO FLDSKP
;<4.EXEC>EXEC2.MAC.2, 31-Jan-78 16:23:37, Edit by PORCHER
;<4.EXEC>EXEC2.MAC.1,  9-Jan-78 16:55:32, EDIT BY HELLIWELL
;FIX IMAGE SUBCOMMAND AND MAKE IMAGE MODE TO/FROM PAPER TAPE
;USE LEAST SIGNIFICANT 8 BITS OF EACH 36 BIT WORD.
;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 EXEC2

;THIS FILE CONTAINS CODE TO EXECUTE SOME OF THE LONGER COMMANDS:
;   COPY/APPEND, TYPE, DETACH

;TYPE.  CAUSE SOURCE FILE(S) TO BE COPIED TO TTY. SETUP ARGS AND JOIN COPY.

.TYPE::	MOVX Q1,CP%TYP		;IDENTIFY
TYPE1::	MOVE A,COJFN		;USE COMMAND OUTPUT JFN
	MOVEM A,OUTDSG
	TLO Z,F1		;SIGNAL THAT THIS IS A COPY COMMAND
	CAIE Q1,CP%HEL		;NO NOISE IF ENTERING FROM HELP COMMAND
	 NOISE <file>
	SETZ Q2,
	TLZ Z,F2		;NOT APPEND
	CAIE Q1,CP%HEL		;WE'VE ALREADY GOT JFN IF COMING FROM "HELP"
				;   COMMAND 
	 CALL TYPFLS		;GET LIST OF FILESPECS
	SETZM TYPGRP		;DON'T PRINT NAME UNLESS GROUPF ON
	SETZM MCOJFN		;SAY NOT MULTI FILE OUTPUT
	SETOM TYPING		; SAY TYPING ON TERMINAL
	JRST COP1A		;GO JOIN COPY
;COPY COMMAND:  COPY <FILE GROUP> (TO) <FILE>
;APPEND COMMAND:  APPEND <FILE GROUP> TO <FILE>
;   BOTH TAKE SUBCOMMANDS.

;MODE SUBCOMMAND --   LEGAL FOR--	MODE-BYTESIZE USED--
;  ASCII	ANY DEVICES		1-7 WHERE LEGAL, ELSE 0-7
;  IMAGE	ONE DEVICE MUST ACCEPT	10-8 WHERE LEGAL, ELSE 0-8
;		   MODE 10, OTHER MUST
;		   NOT BE LPT:.
;  IMAGE BINARY	NEITHER DEVICE CAN	13-36 WHERE LEGAL, ELSE 0-36
;		   BE TTY: OR LPT:
;  BINARY	NEITHER DEVICE CAN	14-36 WHERE LEGAL, ELSE 0-36
;		   BE TTY: OR LPT:.
;  ASCII PARITY	PAPER TAPE SOURCE	SEE ASCII	NOT IMPLEMENTED
;  DUMP		NON-DIRECTORY DTA OR MTA		NOT IMPLEMENTED

;   ACS:	Z/	LH FLAGS:
;			    F1 ON FOR PAGES COPY, OTHERWISE OFF
;			    F2 ON FOR APPEND, OFF FOR COPY
;			    F3 ON IF OUTFILE WAS ALREADY OPEN (GROUP SOURCE
;				CASE) 
;			    F4 ON IF NOT DISK TO DISK XFER
;			RH FLAGS:
;			    BITS FOR MODES SPECIFIED BY SUBCOMMANDS
;			    B35-N ON FOR MODE N, AS IN DVCHR WORD. THAT IS:
				;1B20: DUMP
				;1B23: BINARY
				;1B24: IMAGE BINARY
				;1B27: IMAGE
	ASCF==2			;1B34: ASCII
	NRMF==1			;1B35: NORMAL - SET IF BYTE SIZE SPECIFIED
;   		Q1,Q2/	SEE 2 PAGES HENCE
;		P1/	-1 OR BYTE SIZE AND MODE OF PREVIOUS COPY IN GROUP TO
;			    SAME DEST 
;		P2/	- # BYTES PER PAGE WHEN COPYING BY BYTES
;		P3/	BYTE # OF EOF OF DISK SOURCE, # BYTES COPIED TO DSK
;			    DEST 
;		A,B,Q3/	ALSO USED LOCALLY
;SPEAK COMMAND = COPY (FILE) TTY: (TO) SYSTEM:SYSJOB.COMMANDS

.SPEAK::TRVAR <SJNUM>		;7 SYSJOB number
	MOVEI A,[ASCIZ/^ESPEA/]	;7 setup for program name setup
	HRROM A,COMAND		;7
	NOISE <to SYSJOB>
	DEFX <0>		;7 get SYSJOB number
	DECX <number of SYSJOB>	;7
	 CMERRX			;7
	CONFIRM
	CAIG B,SJMAX		;7 make sure its a good number
	 CAIGE B,0		;7
	  CMERRX <No such SYSJOB> ;7
	MOVEM B,SJNUM		;7 save number
	SETZM MCOJFN		;SETUP SOME THINGS FOR COPY CODE
	SETZM TYPGRP
	HRRO B,$SYSJB(B)	;7 get pointer to correct file name
	CALL TRYGTS		;7 get JFN, ignore job logical names
;7	HRROI B,[ASCIZ/SYSTEM:SYSJOB.COMMANDS/]
;7	CALL TRYGTO		;GET OUTPUT JFN
	 ERROR < Can't get JFN to SYSJOB command file>	;7 cosmetic
;7	 ERROR < Can't get JFN on SYSTEM:SYSJOB.COMMANDS>
	MOVEM A,OUTDSG
	HRROI B,[ASCIZ/TTY:/]
	CALL TRYGTJ		;INPUT FROM TTY
	 ERROR <Can't get JFN on TTY:>
	HRRZ A,JBUFP		;GET POINTER TO JFN JUST STACKED
	MOVEM A,INIFH1		;MAKE SINGLE JFN IN LIST
	MOVEM A,INIFH2
	MOVE A,SJNUM		;7 get back SYSJOB number
	ETYPE < [Please type SYSJOB %1Q commands - end with ^Z]%_> ;7 herald
;7	ETYPE < [Please type SYSJOB commands - end with ^Z]%_>
	MOVX Q1,CP%SPE		;IDENTIFY COMMAND
	CALL COP1A		;GO PERFORM COPY
	MOVE A,SJNUM		;7 wake up the correct job
;7	MOVX A,0		;SET TO WAKE JOB 0
	TWAKE			;...
	 ERJMP CJERRE		;JSYS LOSAGE
	RET			;RETURN

$SYSJB:	[ASCIZ/SYSTEM:SYSJOB.COMMANDS/] ;7 table of SYSJOB files
	[ASCIZ/SYSTEM:SYSJB1.COMMANDS/] ;7
SJMAX==.-$SYSJB-1		;7 top SYSJOB number
;COPY/APPEND

.COPY::	SETOM TYPGRP		;TYPE ALL FILES
	NOISE <from>
	TLZ Z,F2!F1		;NOT APPEND, AND NOT TYPE
	CALL .INFG		;GET INPUT FILE GROUP DESCRIPTOR, ALLOWS *'S,
				;   AND COMMAS IF THEY ARE IMMEDIATE FILE NAME
				;   TERMINATOR. 
	NOISE <to>
	CALL MFOUT		;MULTI FILE OUTPUT TERM
	SETOM TYPING		;MAYBE TYPING
	MOVX Q1,CP%COP		;IDENTIFY FLAVOR
	JRST COP1A

.APPEN::SETOM TYPGRP		;TYPE ALL FILES
	NOISE <source file>
	TLO Z,F2		;SAY APPEND, NOT COPY
	CALL .INFG		;GET INPUT FILE GROUP DESCRIPTOR, ALLOWS *'S,
				;   AND COMMAS IF THEY ARE IMMEDIATE FILE NAME
				;   TERMINATOR. 
	NOISE <to>
	HRROI A,0		;NO DEFAULTS FOR OUTPUT
	MOVX B,(GJ%MSG)		;PRINT NEW FILE, ETC.
	CALL SPECFN
	 JRST CERR
	MOVEM A,OUTDSG
	HRRZ A,OUTDSG
	DVCHR
	LDB D,[POINTR B,DV%TYP]
				;NO OTHER DEVICES WORK 12/3/70
	CAIE D,.DVNUL		;DEVICE NULL IS OK
	 JUMPN D,[ERROR <Destination file must be on disk>]
	SETZM MCOJFN		;SAY NOT MULTI FILE OUTPUT
	MOVX Q1,CP%APP		;SAY IT'S AN APPEND COMMAND
COP1A:	TRVAR <CERRF,<CFBUF,EXTSIZ>,POJFLG,<TADBLK,TADLEN>,<TTBLK,10>,SAVPN,
SRCTYP,DESTYP,PREPAG,SCRF>
	CAIE Q1,CP%APP		;APPEND?
	 CAIN Q1,CP%COP		;OR COPY?
	  ABSKP			;YES
	   JRST COPFL		;NO, CONFIRMATION DONE
	CALL SPRTR		;ANALYZE TERMINATOR, READING MORE IF NEC.
	 SUBCOM $COPY		;READ SUBCOMMANDS
	MOVEI A,MCOERR		;7 set up error return
	MOVEM A,CERET		;7
	MOVEM P,CMDACS+P	;7 setup stack frame
	MOVEI A,COPYQE		;7 set up quota exceeded dispatch
	MOVEM A,QTADSP		;7
COPFL:	SETO P1,		;SAY NO PREVIOUS COPY IN GROUP
	MOVE A,JBUFP
	MOVEM A,.JBUFP		;SAVE ALL JFNS SO FAR

;TOP OF LOOP OVER INPUT FILE NAMES
COPFLN:	CALL RLJFNS		;RELEASE ANY TEMPORARY JFNS
	IORM A,CERRF		;ACCUMULATE ERRORS DURING THIS FILE
	CALL CTPOK		;TYPE OK IF APPROPRIATE
	SETZM CERRF		;NO ERROR YET
	TLZ Z,F4		;OK SO FAR
	CALL NXFILE		;CHECK FOR NON-EX FILE TERM
	 JRST  [SKIPE INIFH1	;ALL TERMS DONE?
		 JRST COPFLN	;NO, NEXT
		JRST COPFLE]	;YES, DONE
	CALL TYPIF		;TYPE INPUT FILE NAME IF PROCESSING GROUP

;WHEN OUTPUT FILE GROUP DESCRIPTORS IMPLEMENTED, DETERMINE HERE THE
;   DESTINATION, AND SETO P1, UNLESS THE SAME AS BEFORE. 
	CALL MFSET		;SETUP JFN FOR MULTI FILE COPY
	 JRST MCOERR		;ERROR DETECTED, MESSAGE ALREADY PRINTED
	SETZM POJFLG		;ASSUME NOT OUTPUTTING TO PRIMARY JFN
	MOVE A,OUTDSG
	CAMN A,COJFN		;QUICK CHECK HERE
	 JRST ISPOJ		;WIN
	DVCHR
	LDB D,[POINTR B,DV%TYP]
	HLL D,C
	MOVE A,COJFN
	DVCHR
	LDB B,[POINTR B,DV%TYP]
	HLL B,C
	CAMN B,D		;SAME DEVICE?
ISPOJ:	 SETOM POJFLG		;YES, OUTPUTTING TO PRIMARY JFN
;COPY/APPEND...
;   CHOOSE MODE AND BYTE SIZE FOR COPY/APPEND AS A FUNCTION OF DEVICES AND
;   SUBCOMMANDS GIVEN. 
;
;   ACS:	Q1/	RH: BYTE(6) READ MODE,WRITE MODE,BYTE SIZE
;		Q2/	DISC SOURCE BYTE SIZE

;SET UP Q1 PER SUBCOMMAND, IGNORING FOR THE MOMENT WHETHER MODE IS LEGAL FOR
;   DEVICES. 
	TXNN Z,NRMF		;BYTE SIZE GIVEN MEANS MODE 0
	 SETZ Q1,		;FOR NO SUBCOMMAND, BYTE SIZE IS DEFAULTED
				;   LATER 
	TXNE Z,ASCF
	 MOVEI Q1,010107
	TRNE Z,400
	 MOVEI Q1,101044
	TRNE Z,4000
	 MOVEI Q1,131344
	TRNE Z,10000
	 MOVEI Q1,141444
;COPY/APPEND... DETERMINING MODE-BYTESIZE...
;   FOR EACH FILE: DO A "DVCHR" TO GET TYPE NUMBER AND TO SEE IF MODE IS LEGAL
;   FOR DEVICE. CHANGE MODE TO 0 IF NOT LEGAL. DESTINATION
	HRRZ A,OUTDSG
	DVCHR
	TXNN B,DV%OUT
	 ERROR <%1H: Can't do output>
	LDB D,[POINTR B,DV%TYP]
	MOVEM D,DESTYP		;REMEMBER DEVICE TYPE
	CAIE D,.DVDSK		;IS IT A DISK?
	 TLO Z,F4		;NO - SET FLAG
	TRZ B,.DVDES
	TRNN Z,(B)		;SKIP IF MODE SUBCOM GIVEN & OK FOR THIS DEVICE
	 JRST  [TRZ Q1,007700	;WRITE IN MODE 0
		TXNN B,DV%M0	;CAN DEVICE USE MODE 0 ?
		 ERROR <%1H: Can't do normal mode output>
		JRST .+1]

;SOURCE
	HRRZ A,@INIFH1
	DVCHR
	TXNN B,DV%IN
	 ERROR <%1H: Can't do input>
	LDB C,[POINTR B,DV%TYP]
	MOVEM C,SRCTYP		;REMEMBER DEVICE TYPE
	CAIE C,.DVDSK		;OUTPUT A DISK?
	 TLO Z,F4		;NO - SET FLAG
	CAIN C,.DVTTY		;INPUT A TERMINAL?
	 SETOM POJFLG		;YES - SET FLAG
	TRZ B,.DVDES
	TRNN Z,(B)		;SUBCOMMAND GIVEN & OK ?
	 JRST  [TRZ Q1,770000	;READ IN MODE 0
		TXNN B,DV%M0	;CAN DEVICE USE MODE 0?
		 ERROR <%1H: Can't do normal mode input>
		JRST .+1]
				;ALSO FOR DISK SOURCE GET BYTE SIZE IN Q2
	JUMPN C,COP2A
	HRRZ A,@INIFH1
	MOVE B,[1,,.FBBYV]	;BYTE SIZE IN B6-11
	MOVEI C,Q2
	CALL $GTFDB		;DO GTFDB, NO SKIP ON NO ACCESS
	ERROR <Access to source not allowed>
	LDB Q2,[POINTR Q2,FB%BSZ]
;COPY/APPEND... DETERMINING MODE-BYTESIZE...

;IF MODE SUBCOMMAND IS ACCEPTABLE TO ONE DEVICE, IT IS ACCEPTED AND MODE 0 USED
;   FOR OTHER DEVICE, PROVIDED OTHER DEVICE WILL ACCEPT THE BYTE SIZE (ONLY TTY
;   AND LPT ARE RESTRICTED). IF MODE IS ACCEPTABLE TO NEITHER, ACTION DEPENDS
;   ON SUBCOMMAND; IF UNACCEPTABLE A WARNING MESSAGE IS TYPED AND DEFAULT
;   EXECUTION PROCEEDS, SO THAT A WHOLE GROUP COPY DOESN'T GET ABORTED.
COP2A:	TRNN Z,177777		;ANY MODE SUBCOMMANDS GIVEN?
	 JRST COPDEF		;NO, GO DEFAULT MODE AND BYTE SIZE
	TXNN Z,NRMF		;MODE 0 REQUESTED, OR
	 TRNE Q1,777700		;EITHER MODE NON-0?
	  JRST COP3		;YES, SUBCOMMAND ACCEPTABLE TO ONE DEVICE

;SUBCOMMAND-DEPENDENT ACTION FOR SBCMD WHOSE MODE IS LEGAL FOR NEITHER SOURCE
;   NOR DESTINATION DEVICE 
	TXNE Z,ASCF
	 JRST  [MOVX Q1,7	;ASCII ALWAYS LEGAL, USE 0-7.
		JRST COP3]
	TRNN Z,4000		;TREAT "IMAGE BINARY" AS "BINARY"
	 TRNE Z,10000
	  JRST [MOVX Q1,44	;"BINARY", USE 0-36, LEGAL EXCEPT FOR
		JRST COP3]	;TTY OR LPT, DETECTED AT COP3. ONLY IMAGE GETS
				;   THRU TO HERE 
	JRST COPDF1		;GO TYPE MESSAGE AND DEFAULT 
				;IMAGE IS NOT INTERPRETED FOR DEVICES OTHER
				;   THAN PAPER TAPE BECAUSE ITS BYTE SIZE WILL
				;   PRESUMABLY BE DIFFERENT WHEN IT IS DEFINED
				;   FOR OTHER DEVICES. 

;IF HERE, ALL SET EXCEPT SUBCOMMAND MAY HAVE SPECIFIED A BYTE SIZE ILLEGAL FOR
;   DEVICE. CHECK FOR THAT. 
COP3:	LDB B,[POINT 6,Q1,35]	;CHOSEN BYTE SIZE
	MOVE C,SRCTYP
	CAIE C,12
	 MOVEM D,DESTYP		;GET DEVICE TYPE OF DESTINATION
	CAIN D,12
	 JRST  [CAIE B,7	;TTY TAKES 7 OR 8 ONLY
		 CAIN B,10
		  JRST .+1
		JRST COPDF1]	;TYPE MESSAGE AND DEFAULT
	CAIN D,7		;LPT TAKES 7 ONLY
	 CAIN B,7
	  JRST COP4		;ALL IS OK
;	JRST COPDF1
;COPY/APPEND... DETERMINING MODE-BYTESIZE... DEFAULT CASE...
;   NO ACCEPTABLE SUBCOMMAND GIVEN. DEFAULT MODE AND BYTE SIZE AS A FUNCTION OF
;   DEVICES USED. MODE ALWAYS 0 AT PRESENT.

COPDF1:	ETYPE < [Illegal mode subcommand being ignored]%_>
COPDEF:	JUMPN D,.+3
	SKIPN SRCTYP
				;DISK TO DISK USES SOURCE BYTE SIZE
	 SKIPA Q1,Q2		;DISK SOURCE BYTE SIZE IS IN Q2, MOST OTHER
				;   CASES USE 0-36 
	  MOVX Q1,^D36
				;IF TTY: OR LPT: INVOLVED, USE 0-7
	MOVE C,SRCTYP
	CAIN C,.DVCDR		;READING FROM CARD READER?
	 MOVX Q1,7		;YES, USE BYTE SIZE OF 7
	CAIE C,12
	 CAIN D,12
	  ABSKP
	   CAIN D,7
	    JRST [MOVX Q1,7
		JRST COP4]
;COPY/APPEND... DETERMINING MODE-BYTESIZE... DEFAULT CASE...
;   SPECIAL CASES FOR PAPER TAPE
	CAIE C,4		;PTR
	 JRST  [CAIE C,.DVMTA	;MAGTAPE?
		 JRST COPDF3
		HRRZ A,@INIFH1	;7 SPR #:20-18098 (the Nth to fix this!)
;7		MOVE A,@INIFH1 
		CALL LBLSKP	;LABELLED?
		 JRST COPDF3
		CAIE A,.LTANS	;ANSI-ASCII?
		 CAIN A,.LTEBC	;EBCDIC?
		  ABSKP		;YES, ASCII OR EBCDIC
		   JRST COPDF3
		MOVX Q1,7	;YES, SAY BYTESIZE 7
		JRST COPDF3]
	CAIN D,5		;PTP
	 JRST  [MOVX Q1,10	;USES 0-8 TO DUPLICATE PAPER TAPE
		JRST COP4]
	HRRZ B,OUTDSG		;PTR TO OTHER DEVICES DEPENDS ON DEST EXT
	JRST COPDF4

COPDF3:	CAIE D,5		;PTP
	 JRST COPDF6
	JUMPE C,[MOVE Q1,Q2	;DSK TO PTP
		CAIN Q2,7	;IF SC BYTE SIZE 7, USE IT, NO MESSAGE.
		 JRST COP4
		CAIE Q2,10	;IF 8, USE IT, TYPE MESSAGE
		 MOVX Q1,^D36	;OTHERWISE ASSUME 36 AND TYPE MESSAGE
		JRST COPDF5]	;NOTE THAT CAN'T TRUST SIZE OF 36 IN FILE
				;   BECAUSE OTHER SIZES CAN BECOME 36 IF FILE
				;   IS COPIED TO DTA AND BACK. 
	HRRZ B,@INIFH1		;OTHER DEVICES TO PTP, DEPENDS ON SC EXT
COPDF4:				;ONE IS PAPER TAPE, OTHER ISN'T. USE 0-36 FOR
				;   FILES WITH EXTENSION OF .REL OR .SAV, 0-7
				;   FOR OTHERS. TYPE MESSAGE. JFN OF
				;   NON-PAPERTAPE DEVICE NOW IN B. 
	HRROI A,CFBUF		;SOME STRING SPACE
	SETZM CFBUF		;MAKE SURE NULLS AFTER EXTENSION
	MOVX C,FLD(.JSAOF,JS%TYP) ;GET FILE TYPE
	JFNS
	 ERCAL JERRE
	MOVE A,CFBUF
	CAME A,[ASCIZ/REL/]
	 CAMN A,[GETSAVE()]
	  ABSKP			;REL OR SAV, USE 36 (ALREADY IN Q1)
	   MOVX Q1,7		;OTHER EXT OR NON-DIR DEVICE, USE 0-7
				;A MARGINAL ASSUMPTION HAS BEEN MADE ABOUT
				;   PAPER TAPE, TYPE EXPLANATORY MESSAGE.
COPDF5:	TYPE < [>
	CAIN Q1,7
	 TYPE <ASCII>
	CAIN Q1,10
	 TYPE <IMAGE>
	CAIN Q1,44
	 TYPE <BINARY>
	ETYPE < mode assumed.]%_>
;	JRST COP4
;COPY/APPEND...
;   HAVE FINISHED CHOOSING MODE-BYTESIZE. OPEN FILES NOW, SO FFUFP WILL WORK.
COPDF6:				;ADD CASES TO THE DEFAULTING STUFF HEHE
COP4:				;NOW HAVE MODES AND BYTE SIZE IN Q1
				;SOURCE
	LDF B,OF%RD		;OPEN FOR READ
	LDB A,[POINT 6,Q1,23]	;GET READ MODE FROM Q1
	DPB A,[POINTR B,OF%MOD]
	MOVE C,SRCTYP
	CAIN C,.DVPTR		;PAPER TAPE READER?
	 CAIE A,10		;YES, MODE 10?
	  ABSKP			;NO, USE SPECIFIED BYTE SIZE
	   SKIPA A,[10]		;YES, USE 8 BIT BYTES FOR IMAGE MODE
	LDB A,[POINT 6,Q1,35]	;BYTE SIZE
	DPB A,[POINTR B,OF%BSZ]
	HRRZ A,@INIFH1		;JFN
	TXO B,OF%PLN		;PASS LINE SEQUENCE NUMBERS
	CAIN C,.DVTTY		;OPEN TERMINAL FOR WRITE ALSO, SO TEXTI WILL
				;   WORK 
	 TXO B,OF%WR
	CALL OPENX		;OPENF WITH CHECK FOR PRI IO FILES AND FANCY
				;   ERROR MESSAGES DESTINATION
	 JRST MCOERR		;FAILED, ERROR PRINTED, GO TO NEXT FILE
	HRRZ A,OUTDSG
	GTSTS
	JUMPGE B,COP5A
				;DEST ALREADY OPEN, ITS ANOTHER COPY IN GROUP,
				;   SEE IF MODE-BYTESIZE CONSISTENT, CHANGE
				;   WHERE POSSIBLE 
	TLO Z,F3		;SAY IT WAS ALREADY OPEN
	MOVE B,Q1		;MODES-BYTESIZE CHOSEN FOR THIS COPY
	XOR B,P1		;COMPARE TO THOSE USED FOR LAST COPY
	CAME P1,[-1]		;FIRST TIME, ALWAYS OK.
	 TRNN B,7777		;OUTPUT MODE & SIZE THE SAME?
	  JRST COP5B		;YES, ALL IS OK
	MOVE D,DESTYP
	CAIN D,0		;IF DEST NOT DSK, CHANGE ILLEGAL
	 TRNE B,7700		;FOR DSK SIZE CAN CHANGE BUT MODE CAN'T
	  ERROR <Illegal mode or byte size change,
 multiple source copy cannot procede>
	LDB B,[POINT 6,Q1,35]
	JUMPE B,[TYPE < [Byte size = 0, will use 36]>
		MOVEI B,^D36
		JRST .+1]
	SFBSZ
	 CALL JERR
	JRST COP5B

COP5A:				;DEST WASN'T OPEN (NORMAL CASE), OPEN IT
	TLZ Z,F3		;SAY JUST OPENED (HENCE PAGE COPY OK)
	LDF B,OF%WR		;"WRITE" BIT FOR OPENF
	TLNE Z,F2		;SKIP IF "COPY" NOT "APPEND"
	 LDF B,OF%APP		;"APPEND" BIT FOR OPENF
	LDB A,[POINT 6,Q1,29]	;GET WRITE MODE FROM Q1
	DPB A,[POINTR B,OF%MOD]
	MOVE C,DESTYP
	CAIN C,.DVPTP		;PAPER TAPE PUNCH?
	 CAIE A,10		;YES, MODE 10?
	  ABSKP			;NO, USE SPECIFIED BYTE SIZE
	   SKIPA A,[10]		;YES, USE 8 BIT BYTES FOR IMAGE MODE
	    LDB A,[POINT 6,Q1,35] ;BYTE SIZE
	DPB A,[POINTR B,OF%BSZ]
	HRRZ A,OUTDSG		;JFN
	CALL OPENX		;OPEN THE OUTPUT FILE
	 JRST MCOERR		;FAILED, DON'T BOMB ENTIRE COPY JUST FOR THIS
				;   ONE FILE! 
	SETZM SCRF		;NOT STRIPPING CARRIAGE RETURNS
	MOVE D,DESTYP		;GET DEVICE TYPE
	CAIN D,.DVMTA		;MAGTAPE?
	 JRST  [MOVE A,OUTDSG	;YES, SEE IF LABELED
		CALL LBLSKP
		 JRST .+1	;NOT
		TXNN Z,ASCF	;WRITING IN ASCII?
		 JRST .+1	;NO
		MOVE A,OUTDSG	;PREPARE TO SET MODE OF TAPE
		MOVX B,.MOSMV	;SAY WE'RE SETTING MODE
		MOVX C,.TPFNC	;SAY THERE ARE NO FORMATTERS (ONE LINE OF TEXT
				;   ASSUMED PER TAPE RECORD) 
		MTOPR
		SETOM SCRF	;REMEMBER TO STRIP CRLF'S AND USE SOUTR
		JRST .+1]
COP5B:	MOVE P1,Q1		;SAVE MODE AND BYTE SIZE (NEEDED IF ANOTHER
				;   COPY TO SAME FILE OCCURS IN GROUP)
;COPY/APPEND...
;   HAVE ESTABLISHED MODE-BYTESIZE AND OPENED FILES. NOW DECIDE WHETHER A COPY
;   WITH DISK SOURCE IS TO BE DONE BY BYTES OR PAGES (SET F1 FOR PAGES),
;   BECAUSE BYTES CASE REQUIRES SPECIAL CHECKS BELOW.
	TLZ Z,F1		;SAY BYTES FOR NOW
	SKIPE SRCTYP
	 JRST COP6Z		;NON-DISC SOURCE, NO SPECIAL CHECK
	MOVE D,DESTYP
	TLNN Z,F2!F3		;"APPEND" COMMAND AND OUTFILE ALREADY OPEN
				;   (GROUP CASE) CAUSE BYTE COPYING
	 JUMPE D,[		;NON-DISK DEST ALWAYS REQUIRES BYTE COPY. BUT
				;   IF HERE, DEST IS ALSO DISK, CAN COPY BY
				;   PAGES. 
		TRNN Z,177777	;DON'T CPY BY PAGES IF MODES SPECIFIED
		 TLO Z,F1	;SAY COPY BY PAGES
		JRST COP6Z]	;SKIP SPECIAL CHECK
;COPY/APPEND...
;   SPECIAL WARNING CHECKS FOR COPYING/APPENDING FROM DSK BY BYTES. (OTHER
;   CASES BRANCHED AROUND THIS CODE ABOVE.) CHECK FOR HOLES NOT BEYOND EOF AND
;   ANY PAGES BEYOND EOF IN SOURCE FILE AND TYPE WARNING MESSAGES IF FOUND.
				;GET PAGE # OF LAST DATA BYTE INTO B
	HRRZ A,@INIFH1
	SIZEF			;BYTE # OF EOF INTO B
	 CALL JERR
	SUBI B,1		;CONVERT BYTE # OF EOF TO BYTE # LAST DATA BYTE
	JUMPL B,COP6C		;IF IT WAS 0, ITS NOW -1, WHICH IS PAGE #.
	MOVX C,^D36
	IDIV C,Q2		;36 / BYTESIZE = # BYTES PER WORD
	IDIV B,C		;BYTE # / THAT   MAKES IT WORD #
	IDIVI B,1000		;MAKE IT PAGE # OF LAST DATA BYTE

;TEST FOR FIRST FREE PAGE NOT BEING AFTER LAST DATA BYTE'S PAGE
COP6C:	HRRZ A,@INIFH1
	FFFFP			;FIND FIRST FREE FILE PAGE
	CAMN A,[-1]
	 JRST .+3		;NO FREE PAGES IN FILE
	CAIL B,(A)
	 ETYPE < [Holes in file]%_>
				;CHECK FOR USED PAGES AFTER LAST DATA BYTE PAGE
	HRL A,@INIFH1
	HRR A,B			;LAST DATA BYTE'S PAGE
	CALL $FNUFP		;INCREMENT A AND FIND NEXT USED PAGE
	CAIE A,0		;0 RETURNED MEANS NO USED PAGE
	 ETYPE < [Pages after EOF will not be copied]%_>
;COPY/APPEND...
;   IF WE WISH TO CONFIRM EACH COPY IN GROUP, HERE IS WHERE TO DO IT. HERE WE
;   TYPE <CRLF> IF OUTPUTTING TO PRIMARY JFN THIS IS TO END FILE NAME
;   PREVIOUSLY TYPED OUT 
COP6Z:	SKIPN POJFLG
	 JRST COP6Y		;SKIP IF TTY NOT INVOLVED
	SKIPN TYPGRP		;PRINT IF FORCED
	 TLNE Z,GROUPF		;BUT ONLY IF NAME TYPED BEFORE
	  ETYPE <%_%%_>

;NOW, AT LAST, WE ARE READY TO COPY. WELL, ALMOST. THERE ARE SEVERAL CASES:
;   DISK TO DISK - DONE BY PAGES, REPRODUCING "HOLES" AND PAGES AFTER BYTE EOF 
;   TTY TO ANYTHING - TERMINATED BY ^Z
;   DISK TO OTHER DEVICE OR DISK, DISK FOR APPEND OR OUTFILE ALREADY OPEN -
;	PAGE READ AND BYTE WRITE. 
;   OTHER DEVICE TO DISK - USUALLY BYTE READ AND PAGE WRITE.
;   ANY OTHER COMBINATION - DONE ENTIRELY BY BYTES.
COP6Y:				;COMPUTE NEGATIVE NUMBER OF BYTES PER PAGE INTO
				;   P2 (DONE NOW CAUSE CAN CLOBBER P3)
	MOVX P2,^D36		;# BITS PER WORD
	LDB P3,[POINT 6,Q1,35]	;# BITS PER BYTE
	IDIV P2,P3		;FORM # BYTES PER WORD
	IMUL P2,[-1000]		;FORM - # BYTES PER PAGE
				;GET DISK SOURCE BYTE EOF IN P3
	HRRZ A,@INIFH1
	MOVE C,SRCTYP
	JUMPN C,COP7A
	SIZEF			;GETS BYTE # OF EOF IN FILE'S BYTESIZE INTO B
	 CALL JERR

;TRANSLATE FROM BYTE SIZE OF FILE TO BYTE SIZE OF COPY.
;   NEW PTR = (OLD PTR*(36/NEW BYTE SIZE))/(36/OLD BYTE SIZE)
;   WITH ALL DIVISIONS INTEGER AND OUTERMOST ONE ROUNDED UP
	MOVX C,^D36
	IDIV C,Q2		;Q2: SOURCE FILE (OLD) BYTE SIZE
	MOVE P3,C
	MOVX C,^D36
	LDB D,[POINT 6,Q1,35]	;COPY (NEW) BYTE SIZE
	IDIV C,D
	MUL B,C
	DIV B,P3
	CAIE C,0		;REMAINDER 0 ?
	 ADDI B,1		;NO, ROUND UP.
	MOVE P3,B		;BYTE # OF EOF IN COPY BYTE SIZE
COP7A:	TLNE Z,F1		;COPY BY PAGES FLAG ON?
	 JRST PAGES		;YES, GO COPY BY PAGES
;COPY/APPEND... DISPATCHING TO VARIOUS EXECUTION CASES...
;   COPY BY BYTES OR A COMBINATION OF BYTES AND PAGES.
;	HRRZ A,@INIFH1		;ONE JFN IN A
	HRRZ Q2,OUTDSG		;OTHER ALWAYS IN Q2
				;GENERATE POINTER TO BUFFER W PROPER BYTE SIZE
				;   IN Q3 
	MOVE Q3,[POINT 0,BUF1]	;P FIELD AND ADDRESS
	DPB Q1,[POINT 6,Q3,11]	;BYTE SIZE = S FIELD
				;NOW DISPATCH TO THE VARIOUS CASES
	MOVE C,SRCTYP
	MOVE D,DESTYP
	CAIN C,.DVTTY		;SOURCE TTY: ?
	 JRST COPTTY		;YES, SPECIAL CODE TO END ON ^Z.
	SKIPE SCRF		;STRIPPING CRLF'S?
	 JRST COPBY		;YES, SO DO BY BYTES
	JUMPE C,CPGBYT		;JUMP IF SOURCE DISK
	JUMPN D,COPBY		;JUMP IF DEST NOT DISK
	TLNE Z,F2!F3		;PG OUTPUT OK IF NOT "APPEND" AND
	 JRST COPBY		;OUTFILE WASN'T ALREADY OPEN (GROUP)
	JRST CBYTPG		;USE PAGES TO WRITE ON DISK

;COPY BY BYTES WITH TELETYPE SOURCE, DO BYTE BY BYTE, WATCHING FOR ^Z
;   TERMINATOR 
COPTTY:	MOVEI B,CTTEOF		;WHERE TO GO ON EOF PSI
	MOVEM B,EOFDSP		;(DON'T THINK IT CAN OCCUR 11/20/70)
	MOVX B,4		;ONLY 4 WORD TEXTI HERE
	MOVEM B,.RDCWB+TTBLK
	MOVX B,RD%BRK!RD%BEL!RD%JFN
	MOVEM B,.RDFLG+TTBLK
	MOVEM A,.RDIOJ+TTBLK
	HRLM A,.RDIOJ+TTBLK
	SETZM .RDBFP+TTBLK
	SETZM .RDRTY+TTBLK
COPTT0:	MOVE B,[ASCPTR BUF0]	;INPUT TO FREE PAGE
	MOVEM B,.RDDBP+TTBLK
	MOVX B,1000*5		;MAX NUMBER OF CHRS
	MOVEM B,.RDDBC+TTBLK
COPTT1:	MOVEI A,TTBLK
	TEXTI
	 CALL JERR
	LDB B,.RDDBP+TTBLK	;GET LAST BYTE STORED
	CAIN B,CTRLZ
	 JRST COPTT2
	CAIE B,.CHLFD		;END OF LINE?
	 JRST COPTT1		;NO, READ MORE BEFORE DUMPING (IN CASE SCRF)
	CALL COPTTS		;DUMP STRING
	JRST COPTT0		;GET MORE

COPTTS:	SKIPN SCRF		;STRIPPING CRLF'S?
	 JRST COPNCR		;NO
	SETO A,			;REMOVE LINEFEED
	ADJBP A,.RDDBP+TTBLK
	MOVEM A,.RDDBP+TTBLK
	AOS .RDDBC+TTBLK	;SAY THERE'S ROOM FOR ONE MORE CHAR NOW
	LDB A,.RDDBP+TTBLK	;GET CHARACTER BEFORE LINEFEED
	CAIE A,.CHCRT		;CARRIAGE RETURN BEFORE LINEFEED?
	 JRST COPNCR		;NO
	SETO A,			;YES, REMOVE IT.
	ADJBP A,.RDDBP+TTBLK	;FIX BYTE POINTER TO NO LONGER INCLUDE CR.
	MOVEM A,.RDDBP+TTBLK	;STORE NEW BYTE POINTER
	AOS .RDDBC+TTBLK	;SAY THERE'S ROOM FOR ANOTHER CHAR NOW
COPNCR:	MOVE A,Q2
	MOVE B,[POINT 7,BUF0]
	MOVNI C,1000*5
	ADD C,.RDDBC+TTBLK	;NUMBER OF BYTES TO SEND
	MOVE D,[SOUT]		;FIRST ASSUME STANDARD OUTPUT
	SKIPE SCRF		;STRIPPING CRLF'S?
	 MOVE D,[SOUTR]		;YES, OUTPUT TO INDIVIDUAL RECORD
	JUMPE C,R		;JUST IN CASE NO BYTES
	XCT D
	ERJMP CJERRE		;To catch problems
	RET

COPTT2:	AOS .RDDBC+TTBLK	;FUDGE CHAR COUNT TO NOT SEND ^Z
	CALL COPNCR		;NO CRLF TO REMOVE IF JUST TYPED ^Z
CTTEOF:	HRRZ A,.RDIOJ+TTBLK
	HRROI B,[ASCIZ/
/]
	SETZ C,
	SOUT			;CRLF AFTER ^Z
	JRST CBYEF1		;GO DELETE EXTRA PAGES IF DEST IS DSK
;COPY/APPEND...
;   COPY/APPEND BY BYTES, NON-TTY-SOURCE CASE - USE FULL PAGE SINS AND SOUTS
;   FOR SPEED. 
COPBY:	MOVEI B,CBYEOF
	MOVEM B,EOFDSP		;WHERE TO GO ON EOF PSI
	SKIPE SCRF		;STRIPPING CRLF'S?
	 JRST COPSCR		;YES, USE DIFFERENT LOOP
COPB1:	MOVE B,Q3		;BYTE PTR
	MOVE C,P2		;BYTE COUNT, NEG FOR NO SPECIAL TERM CHARACTER
	SIN			;INPUT A STRING (JFN ALL SET IN A)
				;SIN CAUSES EOF PSI AFTER READING WHATEVER
				;   CHARACTERS THERE ARE IF NOT A WHOLE
				;   "COUNT"'S WORTH LEFT IN FILE 
	EXCH A,Q2		;GET DESTINATION JFN, SAVE SOURCE JFN
	MOVE B,Q3		;BYTE PTR AGAIN
	MOVE C,P2		;SAME COUNT
	SOUT			;OUTPUT STRING
	EXCH A,Q2		;BACK TO SOURCE JFN
	JRST COPB1		;LOOP TILL EOF PSI

;EOF PSI WHILE COPYING BY BYTES (NON-TTY CASE)
;   OUTPUT PARTIAL STRING INPUT BEFORE EOF OCCURRED 
;   (NOTE THAT C IS UPDATED TO REFLECT THOSE BYTES WHICH WERE READ) 
CBYEOF:	EXCH A,Q2		;GET DEST JFN
	MOVE B,Q3		;THAT GOOD OLD BYTE PTR
	SKIPN SCRF		;COUNT IS POSITIVE IF STRIPPING CRLF'S
	 SUBM P2,C		;CREATE COUNT IN C OF CHARS THAT WERE INPUT
	SKIPE SCRF
	 ADD C,P2		;C HAS POSITIVE NUMBER IF STRIPPING CRLF'S
	CAIE C,0		;0 COUNT, NO SOUT!
	 SOUT			;OUTPUT THE LAST PART

;IF DESTINATION WAS DISK, DELETE ANY ADDITIONAL PAGES
;   (CLOSF DOES NOT DO THIS, BUT WILL LATER ZERO REST OF LAST PAGE).
;   TTY CASE JOINS HERE.
CBYEF1:	HRRZ A,OUTDSG
	DVCHR
	LDB A,[POINTR B,DV%TYP]	;DEVICE TYPE 0 IS DSK
	JUMPN A,COPEOF		;IF NOT DISK, DONE HERE
	LDB D,[POINT 6,Q1,35]	;GET BYTE SIZE USED IN COPYING
	HRRZ A,OUTDSG
	RFPTR			;GETS BYTE # OF LAST DATA BYTE IN B
	 CALL JERR
	MOVX C,^D36
	IDIV C,D		;36/BYTESIZE = # BYTES PER WORD
	IDIV B,C		;BYTE # /THAT = WORD # OF LAST DATA BYTE
	IDIVI B,1000		;MAKE IT PAGE #
	HRR A,B
	HRL A,OUTDSG
CBYEF2:	CALL $FNUFP		;FIND A PAGE
	JUMPE A,COPEOF		;NO MORE PAGES IN FILE, DONE
	MOVE B,A
	SETO A,
	HRLZI C,1
	PMAP			;DELETE THE PAGE
	MOVE A,B
	JRST CBYEF2
;COPY INDIVIDUAL LINES OF TEXT TO INDIVIDUAL OUTPUT RECORDS
;
;   ACS:	A,Q2/	JFNS
;		P2/	NEGATIVE COUNT OF BUFFER SPACE
;		Q3/	POINTER TO BUFFER SPACE
COPSCR:	MOVE B,Q3		;READ DATA INTO BUFFER SPACE
	MOVN C,P2		;USE POSITIVE COUNT SO WE CAN FIND END OF LINE
	MOVX D,.CHLFD		;SEARCH FOR END OF LINE
	SIN			;READ NEXT LINE (TRAP TO CBYEOF IF END OF FILE)
	ADD C,P2		;CALCULATE NEGATIVE NUMBER OF BYTES TO OUTPUT
	SETZ D,			;PUT NULL ON LINEFEED IN CASE BUFFER NOW NULL
	DPB D,B
	SETO D,
	ADJBP D,B		;FIX POINTER TO POINT AT POSSIBLE CR
	AOJE C,COPSC1		;IF ONLY LINEFEED, THERE'S NO CR BEFORE IT!
	 LDB B,D		;NOW GET CHARACTER BEFORE LINEFEED
	CAIE B,.CHCRT		;CARRIAGE RETURN?
	 JRST COPSC1		;NO
	SETZ B,			;YES, NULLIFY IT IN CASE BUFFER NOW NULL
	DPB B,D
	ADDI C,1		;SHRINK BUFFER DUE TO CR (MIGHT BE 0 LENGTH
				;   NOW!) 
COPSC1:	EXCH A,Q2		;GET OUTPUT JFN, SAVE INPUT JFN
	MOVE B,Q3		;POINT AT BUFFER
	SOUTR			;WRITE A RECORD WITHOUT THE END-OF-LINE (MIGHT
				;   BE 0 IN C) 
	EXCH A,Q2		;GET INPUT JFN AGAIN
	JRST COPSCR		;LOOP FOR REST OF DATA
;COPY/APPEND...
;   COPY FROM DISK, READING BY PAGES AND WRITING BY BYTES. TRANSFERS ZEROS FOR
;   HOLES OR BEYOND BYTE EOF. ADDED TO SPEED UP DISK TO LPT COPY.
;
;   ACS:(ENTRY)	A,Q2/	JFNS
;		Q3/	BYTE PTR TO BUFFER PAGE
;		P2/	- # BYTES / PAGE
;		P3/	BYTE # OF EOF
;	(LATER)	A/	SOURCE JFN,,PAGE #
CPGBYT:	SETOM PREPAG		;INITIALIZE PREFAULTED PAGE WORD
	HRLZ A,@INIFH1
CPGBY2:	MOVEM A,SAVPN		;SAVE PAGE NUMBER
	CALL PREFLT		;PERHAPS IT'S TIME FOR PREFAULTING
	MOVE A,SAVPN		;RESTORE PAGE NUMBER
	RPACS
	TXNN B,PA%PEX		;PAGE EXISTS?
	 JRST .+4		;NO, DON'T MAP IT
	MOVE B,[.FHSLF,,BUF1PN]
	LDF C,PM%RD
	PMAP			;MAP IN THE PAGE

;HAVE A PAGE IN SOURCE FILE, DECIDE WHAT TO DO WITH IT BY COMPARING PAGE # AND
;   FILE'S BYTE EOF 
	HRRZ C,A		;PAGE #
	IMUL C,P2		; - BYTE # OF FIRST BYTE IN PAGE
	ADD C,P3		;P3: BYTE # OF EOF
	MOVN C,C		;FORM - # BYTES IN OR BEYOND THIS PAGE
	JUMPGE C,CPBEOF		;NONE, DONE.

;TRANSFER PARTIAL PAGE IF THIS IS EOF PAGE, ELSE WHOLE PAGE.
	CAMGE C,P2		;- # BYTES/PAGE
	 MOVE C,P2		;MAXIMUM TRANSFER
	RPACS
	TXNN B,PA%PEX		;PAGE EXISTS?
	 JRST CPGBY4		;NO, USE ZEROS

;OUTPUT # BYTES IN C
	EXCH A,Q2		;GET DEST JFN
	MOVE B,Q3		;STRING PTR TO BUFFER
	SOUT			;STRING OUTPUT
CPGBY3:	EXCH A,Q2
	AOJA A,CPGBY2		;DO NEXT PAGE

CPGBY4: EXCH A,Q2
	SETZ 2,
	BOUT			;DO PAGE WORTH OF ZEROS
	AOJL C,.-1
	JRST CPGBY3

;COPY BY PAGES-BYTES EOF. CLEAR BUFFER.
CPBEOF:	SETO A,
	MOVE B,[.FHSLF,,BUF1PN]
	SETZ C,
	PMAP
	HRRI B,<BUFPRE>_-9	;GET RID OF PREFAULT PAGES
	MOVX C,PM%CNT!FLD(NPRE,PM%RPT) ;COUNT BIT+THE COUNT
	PMAP
	JRST COPEOF
;COPY/APPEND...
;   COPY NON-DISK TO DISK IN NON-APPEND, NON MULTIPLE SOURCE CASE. USES BYTES
;   FOR INPUT, PAGES FOR OUTPUT. 
;
;   OTHER ACS:	Q2/	DEST JFN,,PAGE #
;   		P3/	# BYTES TRANSFERRED+1, USED TO SET DEST EOF PTR.
CBYTPG:	HRLZ Q2,OUTDSG
	MOVEI B,CBPGEF
	MOVEM B,EOFDSP		;WHERE TO GO ON EOF
	SETZ P3,
CBYPG2:	SETO A,			;CLEAR BUFFER AT TOP OF LOOP TO MAKE SURE
	MOVE B,[.FHSLF,,BUF1PN] ;...OF EOF PAGE IS 0
	SETZ C,
	PMAP
	HRRZ A,@INIFH1
	MOVE B,Q3
	MOVE C,P2		;NEG # BYTES/PAGE
	SUB P3,C		;COUNT BYTES TRANSFERRED
	SIN			;READ A PAGE'S WORTH OF BYTES
	MOVE B,Q2
	MOVE A,[.FHSLF,,BUF1PN]
	LDF C,PM%WT
	PMAP			;MAP OUT THE PAGE
	AOJA Q2,CBYPG2		;NEXT PAGE AND LOOP

;BYTES-PAGES END OF FILE
CBPGEF: ADD P3,C		;ADJUST FOR UNUSED PART OF BYTE COUNT
	CAMN C,P2		;WHOLE PAGE UNUSED?
	 SKIPA A,[-1]		;YES, PUT NO PAGE IN DESTINATION
	  MOVE A,[.FHSLF,,BUF1PN]
	MOVE B,Q2
	LDF C,PM%WT
	PMAP			;MAP OUT LAST PAGE OR DELETE PAGE

;FAKE THINGS UP AND ENTER PAGES-PAGES ROUTINE TO DELETE RESET OF DEST AND SET
;   EOF AND BYTE SIZE 
	SETZ D,			;SAYS NO MORE SOURCE "PAGES"
	JRST PAGE5A
;COPY/APPEND...
;   COPY DISK TO DISK BY PAGES 
;   NOTE: THAT BYTE SIZE IN Q1 MUST BE PRESERVED
NPAGES:	^D25			;MOUTH SIZE (LOOK HOW MUCH I GOT IN ONE BITE,
				;   MA!) 
PAGES:	MOVE A,@INIFH1		;GET SOURCE JFN
	MOVE B,OUTDSG		;AND DESTINATION JFN
	CALL DSKCPY		;COPY THE DATA
	MOVE C,NPAGES		;GET SIZE OF BUFFER
	LSH C,1			;THERE ARE TWO OF THEM
	IORX C,PM%CNT		;REPEATE COUNT
	HRROI A,-1		;SAY REMOVING PAGES
	MOVE B,[.FHSLF,,BUF0PN]	;START FROM BEGINNING OF BUFFER
	PMAP			;REMOVE (ONLY SO CLOSF WILL SUCCEED) 
				;POSSIBLE SPEEDUP WOULD BE TO NOT DO CLOSF
				;   UNTIL JFN'S WERE USED UP. THAT WOULD MEAN
				;   ONLY HAVING TO DO THIS PMAP ABOUT ONCE PER
				;   100 FILES (BUT AT LEAST ONCE PER COPY
				;   COMMAND) 
	JRST PAGES1		;GO PUT ON FINISHING TOUCHES

;DISK TO DISK COPY LOOP.
;   THIS LOOP DOES NOTHING EXCEPT COPY THE DATA, I.E. DOES NO CLOSF OR CHFDB'S.
;
;   ACCEPTS:	A/	CALL WITH SOURCE JFN 
;		B/	DESTINATION JFN 
DSKCPY:	STKVAR <NXTBEG,DESBFR,DESPN,BLTPTR,ENDPTR,SAVBLT,SRCJFN,DESJFN,ENDPT0>
	MOVEM A,SRCJFN
	MOVEM B,DESJFN		;REMEMBER JFN'S
	SETZM NXTBEG		;INITIALIZE NEXT PAGE TO BEGIN BUFFER WITH
	MOVE A,NPAGES		;GET NUMBER OF PAGES
	LSH A,9			;MAKE RELATIVE ADDRESS OF DESTINATION BUFFER
	ADDI A,BUF0		;MAKE ACTUAL ADDRESS
	MOVEM A,DESBFR		;REMEMBER WHERE DESTINATION BUFFER STARTS
	LSH A,-9		;CALCULATE DESTINATION PAGE NUMBER
	MOVEM A,DESPN		;REMEMBER THAT TOO
	ADD A,NPAGES		;CALCULATE FIRST PAGE NUMBER BEYOND DESTINATION
				;   BUFFER 
	LSH A,9			;MAKE ADDRESS
	SUBI A,1		;GET LAST ADDRESS IN DESTINATION
	MOVEM A,ENDPTR		;REMEMBER END OF DESTINATION
	MOVEM A,ENDPT0		;REMEMBER VERSION FOR NORMAL FULL FILE CHUNKS
DSKLUP:	HRL A,SRCJFN		;MAP FROM SOURCE JFN
	HRR A,NXTBEG		;STARTING WITH FIRST PAGE OF NEW GROUP
	MOVE B,[.FHSLF,,BUF0PN]	;MAP INTO OUR BUFFER AREA
	MOVX C,PM%RD!PM%PLD!PM%CNT ;READ, PRELOAD, REPEAT COUNT GIVEN
	HRR C,NPAGES		;DO AS MANY AS OUR BUFFER SIZE
	PMAP			;MAP SOME SOURCE PAGES IN
	 ERJMP [CALL DGETER	;PMAP FAILED, SEE WHY
		CAIE A,LNGFX1	;OFF INTO NONEXISTENT SECTION
		 CAIN A,ARGX06	;OR OFF THE END OF ALL POSSIBLE PAGES?
		  JRST DSKNEW	;YES, EXPECTED
		CALL JERR]	;NO, UNEXPECTED
DSKLP1:	HRL A,DESJFN		;MAP FROM DESTINATION
	HRR A,NXTBEG		;CORRESPONDING PAGES OF SOURCE
	MOVE B,DESPN		;MAP INTO DESTINATION BUFFER
	HRLI B,.FHSLF		;OURSELF
	MOVX C,PM%WR!PM%CNT	;WRITE, REPEAT COUNT
	HRR C,NPAGES
	MOVE D,ENDPTR		;GET END POINTER
	CAMN D,ENDPT0		;WAS IT CHANGED
	 JRST DSKLP2		;NO, PROCEED WITH PMAP
	ADDI D,1		;YES, HOW MUCH DO WE REALLY NEED TO MAP?
	SUB D,DESBFR		;NUMBER OF WORDS
	LSH D,-9		;MAKE IT PAGES
	HRR C,D			;MAP THAT MANY FROM THE DESTINATION FILE
DSKLP2:	PMAP			;SET UP DESTINATION PAGES
	 ERJMP [CALL DGETER	;FAILED, PRESUMABLY BECAUSE TRYING TO GO OFF
				;   END OF WORLD 
		CAIE A,ARGX06	;MAKE SURE THAT'S THE PROBLEM
		 CALL JERR	;NO, SO UNEXPECTED ERROR
		JRST .+1]	;ENDPTR HAS ALREADY ACCOUNTED FOR THIS
	HRLI A,BUF0		;COPY FROM SOURCE
	HRR A,DESBFR		;TO DESTINATION
	MOVEM A,BLTPTR		;REMEMBER BLT POINTER
DSKBLT:	MOVE B,ENDPTR		;GET ADDRESS OF LAST WORD OF DESTINATION BUFFER
	BLT A,(B)		;COPY THE DATA
	 ERJMP DSKDIS		;DISCONTINUITY, PROBABLY END OF FILE, HOLE, OR
				;   QUOTA EXCEEDED 
	MOVEM A,SAVBLT		;SAVE HOW FAR WE GOT BEFORE ERROR
	MOVE B,ENDPTR		;GET POINTER TO END OF DESTINATION WE JUST SET
				;   UP 
	CAME B,ENDPT0		;IS IT A FULL BUFFERFUL?
	 JRST DSKDS1		;NO, WE'VE HIT HOLE OR END.
	MOVE A,NPAGES		;GET NUMBER OF PAGES PER BUFFER
	ADDM A,NXTBEG		;UPDATE PAGE TO START WITH
	JRST DSKLUP		;LOOP FOR NEXT PAGE GROUP

DSKDIS:	MOVEM A,SAVBLT		;SAVE HOW FAR WE GOT BEFORE ERROR
	MOVEI A,.FHSLF
	GETER			;GET TYPE OF ERROR
	CAMN B,[.FHSLF,,IOX11]	;NO ROOM?
	 CALL CJERRE		;YES
	CAME B,[.FHSLF,,ILLX01]	;NOT ROOM PROBLEM, HIT HOLE OR END?
	 CALL JERRE		;NO, UNEXPECTED PROBLEM
DSKDS1:	MOVE A,ENDPT0		;RESTORE BLT POINTER FOR FULL CHUNKS
	MOVEM A,ENDPTR
	LDB A,[POINT 9,SAVBLT,8] ;GET MEMORY PAGE NUMBER ASSOCIATED WITH NONX
				;   SOURCE PAGE 
	SUBI A,BUF0PN-1		;GET RELATIVE POSITION IN BUFFER
	ADD A,NXTBEG		;GET ACTUAL FILE PAGE NUMBER
DSKDS2:	TLNE A,-1		;ARE WE OFF THE END OF THE WORLD?
	 RET			;YES, SO WE MUST BE DONE
	HRL A,SRCJFN		;SET UP FOR FFUFP
	FFUFP			;FIND NEXT USED PAGE
	 ERJMP DSKMEF		;FAILED, PROBABLY END OF FILE
	HRRZ C,A		;COPY PAGE NUMBER
	SUB C,NXTBEG		;SEE WHERE IN BUFFER PAGE IS
	CAML C,NPAGES		;IN SUBSEQUENT BUFFER?
	 JRST DSKNXT		;YES
	LSH C,9			;NO, IN THIS BUFFER.  MAKE MEMORY OFFSET
	MOVE A,BLTPTR		;GET ORIGINAL BLT POINTER
	ADJSP A,(C)		;ADJUST FOR CONTINUATION
	JRST DSKBLT		;CONTINUE THIS BUFFER

DSKNXT:	HRRZM A,NXTBEG		;REMEMBER NEXT PAGE TO START WITH
	JRST DSKLUP		;GO START NEW BUFFER

DSKMEF:	MOVEI A,.FHSLF
	GETER			;GET REASON FOR FFUFP FAILING
	CAME B,[.FHSLF,,FFUFX3]	;NO MORE USED PAGES?
	 CALL JERRE		;NO, UNEXPECTED ERROR
	RET			;YES, DONE!

;COME HERE WHEN PMAP FAILS SOMEWHERE IN THE MIDDLE OF A SOURCE CHUNK. THIS IS
;   BECAUSE WE HAVE HIT A NONEXISTENT FILE SECTION. WE NOW ASSUME THAT SOME
;   PORTION OF THE SOURCE BUFFER HAS BEEN MAPPED, AND THE REST OF THE SOURCE
;   BUFFER IS STILL MAPPED TO PART OF THE PREVIOUS CHUNK. HENCE WE CAN'T RELY
;   ON THE BLT TO STOP AT THE END OF THE CURRENT CHUNK! 
DSKNEW:	LDB A,[POINT 9,NXTBEG,35] ;SEE WHERE IN SECTION WE STARTED
	JUMPE A,[MOVE A,NXTBEG	;ABORTED CHUNK HAD NONE, START IN VOID.
		JRST DSKDS2]	;GO FIND NEXT EXISTING CHUNK
	MOVN A,A		;NEGATE TO PREPARE TO SUBTRACT
	ADDI A,1000		;SEE HOW MANY PAGES WE MAPPED IN IN ABORTED
				;   CHUNK 
	LSH A,9			;GET NUMBER OF WORDS MAPPED IN
	ADD A,DESBFR		;GET FIRST WORD OUT OF BOUNDS IN DESTINATION
				;   BUFFER 
	SUBI A,1		;GET LAST WORD TO BE USED IN DESTINATION BUFFER
	MOVEM A,ENDPTR		;SET UP SHORTENED BLT POINTER
	JRST DSKLP1		;GO DO SHORTENED VERSION

;COPY BY BYTES-PAGES COMES HERE AFTER EOF WITH D 0 AND P2,P3,Q2 CORRECT TO
;   DELETE REST OF DEST FILE AND SET ITS PTR AND BYTE SIZE. 
PAGE5A:	MOVE A,Q2
	CALL $FNUFP		;NEXT PAGE IN DEST
	MOVE Q2,A
PAGES6:	MOVE A,D
	CALL $FNUFP		;ALWAYS NEXT PAGE IN SOURCE
	MOVE D,A

;HAVE A PAGE IN EACH FILE. DECIDE WHAT TO DO WITH THEM.
PAGES3:	JUMPE Q2,[		;NO MORE PAGES IN DEST
		JUMPE D,PAGES9	;ALSO NO MORE IN SOURCE, DONE.
		JRST PAGES5]	;GO COPY PAGE
	JUMPE D,PAGES4		;NO MORE PAGES IN SOURCE, DELETE REST OF DEST
	MOVEI A,(D)
	CAIG A,(Q2)		;COMPARE SOURCE PAGE # TO DEST PAGE #
	 JRST PAGES5

;DELETE DEST PAGES CORRESPONDING TO "HOLE" IN SOURCE
PAGES4:	SETO A,
	MOVE B,Q2
	HRLZI C,1		;PMAP DISPOSAL INFO
	PMAP
	MOVE A,Q2
	CALL $FNUFP		;NEXT PAGE IN DEST
	MOVE Q2,A
	JRST PAGES3		;GO DECIDE AGAIN
;COPY/APPEND... COPY BY PAGES... COPY A PAGE
PAGES5:	MOVE A,D		;SOURCE JFN AND PAGE NUMBER
	CALL PREFLT		;PERHAPS IT'S TIME FOR PREFAULTING
	MOVE A,D		;SOURCE JFN AND PAGE NUMBER
	MOVE B,[.FHSLF,,BUF1PN]
	LDF C,PM%RD
	PMAP			;MAP SOURCE PAGE INTO BUFFER
	HRL A,OUTDSG		;DON'T USE Q2 HERE, MAY BE 0!
	HRRI B,BUF2PN
	LDF C,PM%WT
	PMAP			;MAP DESTINATION PAGE INTO ANOTHER BUFFER
	 ERJMP CJERRE		;REPORT FAILURE (PROBABLY OVER QUOTA)
	MOVE A,[BUF1,,BUF2]
	BLT A,BUF2+777		;COPY DATA
	MOVEI A,(D)		;MASK PAGE # OF PAGE JUST COPIED
	CAIGE A,(Q2)		;COMPARE TO DEST PAGE #
	 JRST PAGES6		;PAGE WAS COPIED INTO A HOLE IN DEST
;COPY/APPEND... FINISH UP COPY BY PAGES.
;   ALSO USED FOR BYTES-PAGES, SO NOTHING DISK-DEPENDENT CAN BE DONE HERE.
PAGES9:	SETO A,			;CLEAR BUFFERS
	MOVE B,[.FHSLF,,BUF1PN]
	SETZ C,
	PMAP
	HRRI B,BUF2PN
	PMAP
	HRRI B,<BUFPRE>_-9	;CLEAR PREFAULT PAGES
	MOVE C,[PM%CNT!FLD(NPRE,PM%RPT)] ;DESIGNATE HOW MANY PAGES TO CLEAR
	PMAP			;CLEAR 'EM

;SET END POINTER OF DESTINATION FILE
PAGES1:	MOVE B,P3		;BYTE COUNT OF SOURCE EOF
	HRRZ A,OUTDSG		;SET POINTER FOR THIS OPENING OF FILE, IN CASE
	SFPTR			;SEQUENTIAL I/O FOLLOWS (GROUP SOURCE CASE)
	 CALL JERR
	HRLI A,.FBSIZ		;SET EOF PTR IN FILE (CLOSF DOES NOT WHEN
	MOVE C,B		;NO SEQUENTIAL OUTPUT HAS BEEN DONE)
	SETO B,
	CALL $CHFDB		;SET FILE DESCRIPTOR BLOCK
	 CALL JERR

;SET BYTE SIZE OF DESTINATION FILE
;   (CLOSF DOES NOT SET IT WHEN NO SEQUENTIAL OUTPUT HAS BEEN DONE)
	HRLI A,.FBBYV
	SETZ C,
	DPB Q1,[POINTR C,FB%BSZ] ;BYTE SIZE STILL IN Q1
	HRLZI B,(77B11)
	CALL $CHFDB
	 CALL JERR

;COPY OR APPEND COMPLETE.
;   PAGE-COPY FALLS IN, ALL OTHER CASES BRANCH HERE.
COPEOF:	TDNE Z,[F2,,-1]		;APPEND/LIST OR ANY SUBCOMMANDS?
	 JRST COPDON		;YES, LEAVE NEW DATES
	TLNE Z,F4		;DISK DEVICE?
	 JRST COPEF1		;NO - SKIP THIS
	HRRZ A,@INIFH1		;INPUT JFN
	MOVE B,[1,,.FBCTL]	;GET CTL WORD FROM FDB
	MOVEI C,C		;WHERE TO PUT IT
	CALL $GTFDB		;GET IT
	  CALL JERR		;SHOULDN'T
	HRRZ A,OUTDSG		;OUTPUT JFN
	HRLI A,.FBCTL		;WORD TO CHANGE
	AND C,[FB%FCF]		;BITS TO SET
	LDF B,FB%FCF		;MAKE A MASK
	CALL $CHFDB		;SET IN OUTPUT FILE
	  CALL JERR		;CHFDB DIED
	HRRZ A,@INIFH1		;INPUT JFN
	HRLI B,1
	HRRI B,.FBUSW		;USER SETTABLE WORD
	MOVEI C,C		;WHERE TO PUT IT
	CALL $GTFDB		;GET IT
	  CALL JERR		;LOSAGE
	HRRZ  A,OUTDSG		;OUTPUT JFN
	HRLI A,.FBUSW		;USER SETTABLE WORD
	SETO B,
	CALL $CHFDB		;PUT USER WORD INTO NEW FDB
	  CALL JERR		;LOSAGE
COPEF1:	HRRZ A,@INIFH1		;INPUT JFN
	MOVEI B,TADBLK		;WHERE TO PUT DATES
	MOVX C,TADLEN		;HOW MUCH TO GET
	RFTAD			;READ DATES
	 ERJMP [CALL %MESS
		TYPE <Failed to read dates from source file - >
		JRST TDERR]	;MESSAGE AND WRAPUP
	MOVE C,.RSWRT+TADBLK	;GET WRITE DATE
	CAMN C,[-1]		;IF NO WRITE DATE,
	 JRST COPDON		;THEN ASSUME NO DATES AVAILABLE
	MOVE D,.RSCRV+TADBLK	;GET CREATION DATE
	CAMN D,[-1]		;IF NO CREATE DATE,
	 MOVE D,C		;USE WRITE DATE
	SETOM TADBLK		;CLEAR BLOCK FOR SFTAD
	HRLI A,TADBLK
	HRRI A,1+TADBLK		;MAKE BLT POINTER
	BLT A,TADLEN-1+TADBLK
	MOVEM C,.RSWRT+TADBLK
	MOVEM D,.RSCRV+TADBLK	;STORE DATES TO SET
	MOVE A,OUTDSG
	MOVX C,TADLEN
	SFTAD
	 ERJMP [CALL %MESS
		TYPE <Failed to set dates for destination file - >
		JRST TDERR]	;MESSAGE AND WRAPUP
COPDON:	SETZM EOFDSP		;(REDUNDANT EXCEPT IN ^Z ON TTY CASE)
	CALL GNFIL		;GET NEXT FILE IN INPUT GROUP
	 JRST COPFLE
	SKIPE POJFLG		;IF OUTPUT TO COJFN
	 ETYPE<%_>		;THEN SEPARATE FILENAMES
	JRST COPFLN

MCOERR:	SETOM CERRF		;REMEMBER THAT THIS FILE HAD ERROR
	JRST COPDON

COPFLE: CALL CTPOK		;TYPE OK ON LAST FILE IF APPROPRIATE
COPFL0:	MOVEI A,RERET		;7 restore regular error return
	MOVEM A,CERET		;7
	RET			;7

;CTPOK TYPES [OK] IF APPROPRIATE.
CTPOK:	SKIPE CERRF		;ERRORS?
	 RET			;YES, SO NOT OK.
	SKIPN POJFLG		;IF NOT OUTPUTTING TO PRIMARY JFN, TYPE [OK]
				;   HERE 
	 CALL TYPOK
	RET

TDERR:	CALL %GETER		;GET ERROR CODE
	MOVE A,ERCOD		;...
	CALL $ERSTR		;PRINT MSG
	ETYPE<%_>		;CRLF
	JRST COPDON		;FINISH UP

;7 here on quota exceeded interrupt
COPYQE:	ERROR <Quota exceeded or disk full> ;7 give the error
	MOVE C,NPAGES		;7 get size of buffer
	LSH C,1			;7 double for two buffers
	IORX C,PM%CNT		;7 remove pages (only so CLOSF will succeed)
	SETO A,			;7 
	MOVE B,[.FHSLF,,BUF0PN]	;7 beginning of buffer
	PMAP			;7 
	CALL RLJFNS		;7 release any file handles
	JRST COPFL0		;7 clean up and exit
;COPY/APPEND...

;SUBROUTINE TO GET NEXT USED PAGE # OF DISK FILE.
;   MUST BE NEAR COPY TO MINIMIZE PAGE FAULTS
;
;   ACCEPTS:	A/	JFN,,CURRENT PAGE #
;   RETURNS:	A/	0 IF NO MORE PAGES.
$FNUFP:	JUMPE A,[RET]		;ALREADY AT END, NOP.
	ADDI A,1		;NEXT PAGE NUMBER
	TRNN A,-1
	 JRST  [SETZ A,		;WRAP-AROUND FROM MAX PAGE NUMBER
		RET]

;ENTRY TO GET FIRST USED PAGE NUMBER. DOESN'T INCREMENT FIRST.
$FFUFP:	FFUFP
	 CALL  [CAIE A,FFUFX3	;"NO MORE PAGES" ERROR?
		 JRST JERR
		SETZ A,
		RET]
	RET

;ROUTINE TO PREFAULT DISK PAGES IN.   
;   THIS ROUTINE LOOKS IN VARIABLE "PREPAG" TO DETERMINE WHICH PAGE NUMBER
;   STARTS THE LAST GROUP OF PAGES THAT WAS PREFAULTED IN. IF THE PAGE NUMBER
;   IN R.H. OF A ISN'T IN THIS GROUP, THIS ROUTINE PREFAULTS IN THE GROUP OF
;   WHICH R.H. A IS A MEMBER. THE PAGES ARE PREFAULTED IN TO MEMORY STARTING AT
;   LOCATION "BUFPRE", ASSUMED TO BE ON A PAGE BOUNDARY. "NPRE" (DEFINED IN
;   EXECDE) DEFINES HOW MANY PAGES TO PREFAULT IN. ALSO ASSUMES INIFH1 POINTS
;   TO WORD CONTAINING JFN OF FILE OPEN AS SOURCE
;
;   ACCEPTS:	A/	RH IS PAGE NUMBER
;   RETURNS: +1		ALWAYS
PREFLT:	HRRZ A,A		;KEEP ONLY PAGE NUMBER
	IDIVI A,NPRE
	IMULI A,NPRE		;CALCULATE FIRST PAGE OF THE GROUP
	CAMN A,PREPAG		;IS THIS GROUP ALREADY IN?
	 JRST PREOUT		;YES, WE'RE DONE

;THE FOLLOWING WAS ADDED TO CORRECTLY HANDLE LONG FILES. IF AN ATTEMPT IS MADE
;   TO PRELOAD A PAGE FROM A NONEXISTENT SECTION, A FILE OPENED FOR READ-ONLY
;   ACCESS (OF%RD IN OPENF) PMAP WILL BARF SINCE IT CAN'T CREATE A PAGE TABLE
;   WITHOUT WRITE ACCESS TO THE FILE. ALL THIS CODE DOES IS ELIMINATE THE
;   ANNOYING ERROR MESSAGE GENERATED BY JWARN WHEN THIS OCCURS.
;					- B.TOMCZAK 9/14/79
	HRRZ A,A		;NO - CLEAR OUT ANY OTHER TRASH
	CAIG A,777		;SEC GREATER THAN 0?
	 JRST PREMAP		;NO, SEC 0 ALWAYS EXISTS
	PUSH P,A		;SAVE THE PAGE NUMBER DESIRED
	SKIPGE B,PREPAG		;HAVE WE ALREADY DONE A MAPPING?
	 JRST CHKSEC		;NO, SO JUST CHECK CURRENT
	ADDI B,NPRE-1		;GET LAST PG# OF LAST GROUP
	XOR B,A			;CHECK SEC#'S
	TRNE B,777000		;CURR IN SAME SEC AS PREVIOUS?
CHKSEC:	 JRST  [ANDI A,777000	;NO, GET 1ST PG IN CURRENT SEC
		MOVEM A,B	;AND SAVE IT
		HRL A,@INIFH1	;A/   JFN,,PG#
		CALL $FFUFP	;FIND NEXT USED PAGE
		JUMPE A,[POP P,A ;ZERO MEANS NOTHING IN USE AFTER THIS
			RET]
		XOR B,A
		TRNN B,777000	;NEXT USED PAGE IN SAME SEC?
		 JRST .+1	;YES, MAPPING WILL BE OKAY
		POP P,A		;NO, NONEXISTENT SEC
		RET]		;MAPPING WILL FAIL
	POP P,A			;RESTORE T1 TO PREVIOUS GLORY
PREMAP:	MOVEM A,PREPAG		;READ IN THIS GROUP
	HRL A,@INIFH1		;GET HANDLE ON FIRST PAGE OF GROUP TO BE READ
				;   IN 
	MOVE B,[.FHSLF,,<BUFPRE>_-9] ;GET HANDLE ON AREA WE'RE READING INTO
	MOVX C,PM%CNT!PM%PLD!FLD(NPRE,PM%RPT) ;COUNT GIVEN, PREFAULT, HOW
				;   MANY PAGES
	PMAP			;START THE PAGES IN
	 JWARN			;GIVE WARNING IF THIS PMAP FAILS
PREOUT:	RET
;COPY/APPEND SUBCOMMAND TABLE AND ROUTINES
$COPY:	TABLE
	T ascii
	IT bcd,ONEWRD,NIYE
	T binary,ONEWRD
	T byte
	IT dump,ONEWRD,NIYE
	T image
	IT record
	TEND

	PARF==1B18		;PARITY CHECK

.ASCII::KEYWD $ASCII
	 T noparity,,ASCF
	 JRST CERR
	CONFIRM
ASCII2:	TXNE P3,PARF
	 ETYPE < ["ASCII PARITY" not implemented yet, will treat as "ASCII"]%_>
	HRR Z,P3		;NEW FLAGS FROM TABLE ENTRY
	RET

$ASCII:	TABLE
	T noparity,,ASCF
	T parity,,PARF!ASCF	;PARF: PARITY CHECK. ASCF: ASCII MODE
	TEND

.BINAR::HRRI Z,10000		;"BINARY" MODE BIT (MODE 14)
	RET

.BYTE:	NOISE <size>
	DECX <Byte size in decimal>
	 CMERRX
	CONFIRM
	MOVEI Q1,(B)		;BYTE SIZE GOES IN Q1 WITH MODES 0
	TXO Z,NRMF		;SAY NORMAL MODE
	RET

.IMAGE::MOVEI B,[FLDDB. .CMCFM,,,,,[
		FLDDB. .CMKEY,,$IMAGE]]
	CALL FLDSKP		;CONFIRMATION OR KEYWORD
	 CMERRX <"BINARY" or nothing>
	GTFLDT C		;PICK UP FUNCTION CODE
	CAIN C,.CMCFM		;NO ARG TO "DETACH"?
	 MOVEI B,[T ,,400]	;DUMMY ARG FOR NOTHING TYPED
	CAIE C,.CMCFM
	 CONFIRM		;IF NO CONFIRMATION YET, DO IT NOW
	MOVE P3,(B)		;GET TABLE ENTRY
	MOVE P3,(P3)		;GET CONTENTS OF WORD POINTED TO BY TABLE ENTRY
	JRST ASCII2		;GO PROCESS MODE

$IMAGE:	TABLE
	T binary,,4000
	TEND

.RECOR::NOISE <length>
	JRST NIYE
;OPEN FILE SUBROUTINE
;   DOES OPENF, CHECKS FOR AND DOES NOT RE-OPEN PRI I/O FILES
;   (PRI FILES ARE SOMETIMES DEFAULT ARG VALUES).
;
;   ACCEPTS:	A,B/	SET UP FOR OPENF
;   RETURNS:		IF SUCESSFUL (GIVES MESSAGE ON FAILURE)
$OPEN7::HRLI B,(<FLD(7,OF%BSZ)>) ;ENTER HERE FOR 7 BIT BYTES NORMAL MODE
$OPENF::CALL OPENX		;TRY TO OPEN FILE
	 JRST ERRFIN		;GO BACK TO TOP LEVEL IF FAILS
	RET			;SUCCEEDED

;ROUTINE LIKE ABOVE, BUT SKIPS IFF SUCCESS.
OPENX:	STKVAR <OFJFN>
	MOVEM A,OFJFN
	CALL $IOCHK		;SPECIAL CHECK FOR PRIMARIES AND EXEC IO
	 RETSKP			;SPECIAL (ALREADY OPEN)
	OPENF			;OPEN FILE
	 ABSKP			;FAILED
	  RETSKP
	MOVE C,OFJFN		;RETRIEVE JFN FOR %S

;ENTER HERE WITH ERROR CODE IN A AND JFN IN C
;   SHOULD BE CALLED WITH "CALL OPNERR" SO JERR PRINTS CORRECT PC
OPNERR::SETZ D,			;SO WE'LL KNOW IF WE CATCH A FISH
	CAIN A,OPNX2		;NONX FILE?
	 MOVE D,[LERROR <File is empty: %3S>]
	CAIN A,OPNX3
	 MOVE D,[LERROR <Read protection violation for: %3S>]
	CAIN A,OPNX4
	 MOVE D,[LERROR <Write protection violation for: %3S>]
	CAIN A,OPNX6
	 MOVE D,[LERROR <Append protection violation for: %3S>]
	CAIN A,OPNX7
	 JRST  [MOVE A,C
		DVCHR
		HLRZ C,C
		MOVE D,[LERROR <%1H: is assigned to job %3Q>]
		JRST OPNE1]
	CAIN A,OPNX8
	 MOVE D,[LERROR <%3H: is not on-line>]
	CAIN A,OPNX9
	 MOVE D,[LERROR <File is busy: %3S>]
	CAIN A,OPNX13		;7 SPR #:20-18729 a little more info
	 MOVE D,[ETYPE <%_%%%Invalid access requested: %3S %_>]	;7
	CAIN D,0		;IF OTHER ERROR, USE SYSTEM'S VERSION
	 MOVE D,[LERROR <%?: %3S>]
OPNE1:	XCT D			;PRINT ERROR MESSAGE
	RET			;SINGLE SKIP RETURN

;ENTER HERE TO CHECK FOR PRIMARY OR EXEC IO ALREADY OPEN 
;   IF PRIMARY OR EXEC IO, CHECK MODE AND BYTE SIZE
$IOCHK:	CAIE A,.PRIIN		;DON'T OPEN PRIMARY IO
	 CAIN A,.PRIOU
	  RET
	CAME A,CIJFN		;DON'T OPEN EXEC IO FILES
	 CAMN A,COJFN
	  RET
	RETSKP			;TELL CALLER NOT SPECIAL
;"REDIRECT" AND "DETACH" COMMANDS

;REDIRECT (INFILE) <NAME>/* (OUTFILE) <NAME>/* (AND) START/REENTER/CONT

;DETACH IS SAME SYNTAX AND HAS SAME MEANING EXCEPT IT DETACHES TERMINAL AFTER
;   REDIRECTING IO. ALL ARGUMENTS CAN BE OMITTED AND DEFAULT TO NULL

.DETAC::TLO Z,DTACHF		;SET "DETACH" FLAG

;START/REENTER/CONTINUE ARGUMENT
	NOISE <and>
	MOVEI B,[FLDDB. .CMCFM,,,,,[
		FLDDB. .CMKEY,,$REDIR]]
	CALL FLDSKP		;CONFIRMATION OR KEYWORD
	 CMERRX <"START", "REENTER", "CONTINUE", or nothing>
	GTFLDT C		;PICK UP FUNCTION CODE
	CAIN C,.CMCFM		;NO ARG TO "DETACH"?
	 MOVEI B,[T nothing,,<[..DTCH,,[RET]]>]	;DUMMY ARG FOR NOTHING TYPED
	CAIE C,.CMCFM
	 CONFIRM		;IF NO CONFIRMATION YET, DO IT NOW
	MOVE P3,(B)		;GET TABLE ENTRY
	MOVE P3,(P3)		;GET CONTENTS OF WORD POINTED TO BY TABLE ENTRY

;P3 POINTS TO A WD WHOSE RH POINTS TO A SUBR TO FINISH DECODING
;  AND CHECK THE ARGUMENT.
	MOVE A,FORK		; SET FORK HANDLE OF CURRENT FORK
	MOVE B,(P3)
	CALL (B)		;CALL ARGUMENT-DEPENDENT DECODE & CHECK SUBR
	TLNE Z,DTACHF
	 ETYPE < Detaching job # %J%%_>
;7 SPR #:20-15097 do this correctly
;7 	MOVEI Q1,ETTYMD		;TTY MODES FOR USE WHEN EXEC IS RUNNING
;7	CALL LTTYMD		;PUT SAME INTO EFFECT NOW.
	HLRZ A,(P3)
	JRST (A)		;DISPATCH TO
				;FINAL-ARGUMENT-DEPENDENT EXECUTION ROUTINE

;TABLE FOR THIRD ARGUMENT
;VALUE POINTS TO A WORD --
;	RH: DECODE-AND-CHECK SUBR ADDRESS
;	LH: EXECUTION DISPATCH ADDRESS

$REDIR:	TABLE
	T continue,,<[..CONT,,$CONTI]>
	T reenter,,<[..REEN,,$REENT]>
	T start,,<[..STRT,,$START]>
	TEND

;EXECUTION ROUTINE FOR NULL THIRD ARGUMENT
..DTCH::TLNE Z,DTACHF
	 CALL BLANK1		;7 blank screen
	MOVE A,JOBNO		;7 type out message
	ETYPE <Detach Job %J, User %N, Account > ;7
	CALL PRACCT		;7
	ETYPE <, %L, %_ at %D %A, Used %B in %C %_> ;7
	DTACH
	 ERCAL CJERRE		;7 SPR #:20-15097
DTCH1::	MOVEI Q1,ETTYMD		;7 SPR #:20-15097
	CALL LTTYMD		;7 SPR #:20-15097
	SETOM ATTINI		;7 set to run ATTACH.CMD stuff
        MOVEI A,.CTTRM		;7 wait around for attach
	MOVEI B,BELL		;7 
	BOUT			;7 
	DOBE			;7 use JRST (instead of RET), to speed up
	JRST CMDIN4

;..CONT, ..REEN, ..STRT ARE WITH THE CORRESPONDING COMMANDS.

LITS2:				;713 debugging aid: literals label
	END