Google
 

Trailing-Edge - PDP-10 Archives - SRI_NIC_PERM_SRC_3_19910112 - utilities/encr.mac
There are no other files named encr.mac in the archive.
	TITLE	SCRAM	PROGRAM TO ENCODE A FILE


	SEARCH	MACSYM,MONSYM	;GET SYMBOLS
	SALL			;NICE LOOKING MACROS


	VMAJOR==1		;MAJOR VERSION
	VMINOR==0		;MINOR VERSION
	VEDIT==100		;EDIT NUMBER
	VWHO==0			;WHO MODIFIED



;ACCUMULATORS:


	F=0			;FLAGS
	T1=1			;TEMPORARY AC'S
	T2=2
	T3=3
	T4=4
	T5=5
	T6=6
	P1=7			;ANOTHER AC
	P=17			;STACK



;FLAGS:

	FR.NEC==1		;WE ARE NO ECHOED
	FR.TYP==2		;WE ARE DOING TYPING


;DEFAULT PARAMETERS:


	PDLSIZ==50		;SIZE OF PUSHDOWN STACK
	PAGSIZ==1000		;SIZE OF A PAGE
	TMPSIZ==100		;SIZE OF TEMPORARY BUFFER AREA
	TXTLEN==^D200		;SIZE OF COMMAND BUFFERS
	BUFLEN==^D40		;MAXIMUM SIZE OF PASSWORD
	INPAG==200		;PAGE TO READ FILES INTO
	OUTPAG==201		;PAGE TO WRITE FILES FROM
	PREPAG==202		;PAGE TO PREFAULT INPUT FILE TO
	PAGCNT==10		;NUMBER OF PAGES TO PREFAULT
	INPGA=INPAG*PAGSIZ	;ADDRESS TO READ FILES INTO
	OUTPGA=OUTPAG*PAGSIZ	;ADDRESS TO WRITE FILES FROM
	INTCHN==0		;CHANNEL FOR ^E INTERRUPT
;MACROS AND OPDEFS:



	OPDEF	CALL	[PUSHJ P,]	;TO CALL A SUBROUTINE
	OPDEF	RET	[POPJ P,]	;TO RETURN
	OPDEF	PJRST	[JRST]		;PUSHJ/POPJ




	DEFINE	AA(NAME,DATA),<		;;MACRO FOR COMMAND TABLES
	XWD	[ASCIZ/NAME/],DATA
>



	DEFINE	TEXT(STRING),<		;;MACRO FOR ASCIZ TEXT
	XLIST
	ASCIZ	@STRING@
	LIST
>



	DEFINE	DIE(TEXT,FLAG<0>,ADDR<REEN>),<	;;MACRO FOR ERRORS

	JRST	[
IFN	<FLAG>,<
		HRROI T1,[ASCIZ/
? TEXT - /]
		HRROI	T4,ADDR
		JRST	DIEADR]
>

	IFE	<FLAG>,<
		HRROI T1,[ASCIZ/
? TEXT

/]
		MOVEI	T4,ADDR
		JRST	DIEADR]
>
>
	DEFINE	CMMD(ARG),<		;;MACRO TO DO A GENERAL COMMAND
	MOVEI	T2,ARG
	CALL	DOCMMD
>




	DEFINE	NOISE(TEXT),<		;;MACRO FOR NOISE
	MOVEI	T2,[ASCIZ/TEXT/]
	CALL	DONOIS
>




	DEFINE	CONFRM,<		;MACRO FOR CONFIRMING A LINE
	CALL	DOCNFM
>
	SUBTTL	COMMAND SCANNER AND INITIALIZATION




ENTRY:	JRST	START		;START ADDRESS
	JRST	REEN		;REENTER ADDRESS
	BYTE	(3)VWHO(9)VMAJOR(6)VMINOR(18)VEDIT	;VERSION




START:	RESET			;CLEAR EVERYTHING
	SETZB	F,ZERBEG	;CLEAR FLAGS AND FIRST ZERO AREA
	MOVE	T1,[ZERBEG,,ZERBEG+1]	;GET READY
	BLT	T1,ZEREND	;CLEAR SOME VARIABLES
	MOVEI	T1,.FHSLF	;GET MY PROCESS
	MOVE	T2,[LEVTAB,,CHNTAB]	;POINT TO INTERRUPT TABLES
	SIR			;TELL MONITOR WHERE THEY ARE
	  ERJMP	ERROR		;SHOULDN'T FAIL
	MOVEI	T1,.FHSLF	;GET READY
	MOVX	T2,1B<INTCHN>	;GET BIT FOR CHANNEL
	AIC			;ACTIVATE THE CHANNEL
	  ERJMP	ERROR		;LOSE
	MOVEI	T1,.FHSLF	;ONE MORE TIME
	EIR			;ENABLE INTERRUPTS
	  ERJMP	ERROR		;CAN'T

REEN:	MOVE	P,[IOWD	PDLSIZ,PDL]	;SET UP STACK


NEWCMD:	MOVEM	P,SAVEP		;SAVE STACK FOR REPARSING
	MOVE	T1,[PASBUF,,PASBUF+1]	;GET READY
	SETZM	PASBUF		;TO CLEAR THE PASSWORD
	BLT	T1,PASEND	;MAKE SURE IT IS GONE
	CALL	ECHO		;TURN ON ECHOING
	MOVEI	T1,NEWPAR	;GET REPARSE ADDRESS
	MOVEM	T1,CMDBLK+.CMFLG	;SET IT <
	HRROI	T1,[ASCIZ/SCRAM>/]	;GET PROMPT
	MOVEM	T1,CMDBLK+.CMRTY	;SET IT TOO
	MOVEI	T1,CMDBLK	;POINT TO COMMAND BLOCK
	CMMD	[FLDDB. (.CMINI)]	;INITIALIZE

NEWPAR:	MOVE	P,SAVEP		;RESTORE THE STACK
	SKIPE	T1,JFN		;INPUT JFN OPEN?
	RLJFN			;YES
	ERJMP	.+1
	SETZM	JFN		;THEN CLEAR IT
	SKIPE	T1,JFNOUT	;OUTPUT JFN OPEN?
	RLJFN			;YES, CLEAR IT
	ERJMP	.+1
	SETZM	JFNOUT		;THEN CLEAR IT
	MOVEI	T1,CMDBLK	;POINT TO THE COMMAND BLOCK
	CMMD	[FLDDB. (.CMKEY,,CMDTAB)]	;GET A COMMAND
	MOVE	T2,(T2)		;GET ADDRESS OF ROUTINE
	CALL	(T2)		;PROCESS THE COMMAND
	JRST	NEWCMD		;AND GET A NEW COMMAND
;TABLE OF COMMANDS:



CMDTAB:	CMDLEN,,CMDLEN			;HEADER
	AA	CODE,CMDCOD		;CODE A FILE
	AA	DECODE,CMDDEC		;DECODE A FILE
	AA	EXIT,CMDXIT		;EXIT COMMAND
	AA	HELP,CMDHLP		;TYPE HELP MESSAGE
	AA	TYPE,CMDTYP		;TYPE A SCRAMBLED FILE

	CMDLEN==.-CMDTAB-1		;NUMBER OF COMMANDS
	SUBTTL	THE SIMPLE COMMANDS



;HERE TO DO THE TRIVIAL COMMANDS, SUCH AS HELP AND EXIT.




CMDXIT:	NOISE	(FROM PROGRAM)	;DO NOISE
	CONFRM			;CONFIRM THE LINE
	HALTF			;QUIT FOR NOW
CPOPJ:	RET			;RETURN




CMDHLP:	CONFRM			;CONFIRM THE LINE
	HRROI	T1,HLPTXT	;POINT TO HELP MESSAGE
	PSOUT			;TYPE IT
	RET			;DONE
;THE HELP TEXT FOR THE HELP COMMAND:




HLPTXT:	TEXT	<
Commands are the following:

	CODE in out	Read the input file and code it using a password
			to produce the output file.

	DECODE in out	Read the scrambled input file and decode it using
			a password to produce the output file.

	EXIT		Leave the program.

	HELP		Type this text.

	TYPE  file	Read the scrambled input file and decode it
			using a password and type the result to the
			terminal.
>
	SUBTTL	COMMAND TO CODE OR UNCODE A FILE




CMDTYP:	NOISE	(FILE)		;NOISE
	CMMD	[FLDDB. (.CMIFI)]	;GET SPEC
	MOVEM	T2,JFN		;DONE
	NOISE	(TO TERMINAL)	;MORE NOISE
	CONFRM			;THEN CONFIRM IT
	MOVX	T1,GJ%SHT	;GET READY
	HRROI	T2,[ASCIZ/TTY:/]	;TO GET A JFN
	GTJFN			;GET IT FOR THE TERMINAL
	  ERJMP	ERROR		;FAILED
	MOVEM	T1,JFNOUT	;SAVE OUTPUT JFN
	SETZM	CODFLG		;WE ARE DECODING
	TXO	F,FR.TYP	;AND WE ARE TYPING
	JRST	HAVFIL		;PROCEED



;HERE FOR CODE AND DECODE COMMANDS:


CMDDEC:	TDZA	T2,T2		;SET FLAG ZERO
CMDCOD:	SETO	T2,		;OR NONZERO
	MOVEM	T2,CODFLG	;REMEMBER FOR LATER
	NOISE	(FILE)		;DO NOISE
	SETZM	JFNBLK+.GJNAM	;CLEAR DEFAULTS
	SETZM	JFNBLK+.GJEXT	;THAT WE CHANGE
	CMMD	[FLDDB. (.CMIFI)]	;GET AN INPUT FILE
	MOVEM	T2,JFN		;REMEMBER THE JFN
	HRROI	T1,DEFNAM	;POINT TO DEFAULT NAME
	MOVEM	T1,JFNBLK+.GJNAM	;SAVE POINTER IN BLOCK
	MOVX	T3,1B8		;WANT TO OUTPUT JUST THE NAME
	JFNS			;DO IT
	HRROI	T1,DEFEXT	;POINT TO DEFAULT EXTENSION
	MOVEM	T1,JFNBLK+.GJEXT	;SAVE POINTER IN BLOCK
	MOVX	T3,1B11		;WANT TO OUTPUT JUST THE EXTENSION
	JFNS			;DO IT
	MOVX	T1,GJ%FOU!GJ%MSG	;GET FLAGS
	MOVEM	T1,JFNBLK+.GJGEN	;SAVE THEM
	MOVEI	T1,CMDBLK	;RESET UP POINTER
	NOISE	(OUTPUT AS)	;MORE NOISE
	CMMD	[FLDDB. (.CMFIL)]	;GET AN OUTPUT FILE
	MOVEM	T2,JFNOUT	;REMEMBER THE JFN
	CONFRM			;THEN CONFIRM THE LINE
	TXZ	F,FR.TYP	;WE ARE NOT TYPING
;HERE WHEN HAVE THE FILE SPECS READY:



HAVFIL:	CALL	OPNFIL		;OPEN THE FILES
	CALL	GETPSW		;GO READ IN THE PASSWORD STRING
	CALL	INIRAN		;INITIALIZE THE RANDOM NUMBER GENERATOR
	CALL	GETBSZ		;READ THE BYTE SIZE OF THE INPUT FILE
	MOVEM	P,INTSTK	;REMEMBER STACK POINTER
	MOVE	T1,[.TICCE,,INTCHN]	;GET CODE AND CHANNEL
	TXNE	F,FR.TYP	;TYPING OUT A FILE?
	ATI			;YES, SET UP INTERRUPT
	  ERJMP	ERROR		;ERROR
	CALL	MAPPER		;DO THE REAL WORK
	CALL	SETBSZ		;SET BYTE SIZE OF OUTPUT FILE
	MOVEI	T1,.TICCE	;GET READY
	TXZE	F,FR.TYP	;TYPING A FILE?
	DTI			;YES, TURN OFF INTERRUPT AGAIN
	CALL	CLSFIL		;CLOSE THE FILES
	RET			;DONE



;HERE IF A ^E WAS TYPED DURING THE TYPEOUT:


TYPINT:	MOVE	P,INTSTK	;RESTORE STACK TO GOOD PLACE
	TXZ	F,FR.TYP	;NO LONGER TYPING A FILE
	MOVEI	T1,.TICCE	;GET CHARACTER CODE TO RELEASE
	DTI			;REMOVE CONTROL-E INTERRUPT
	MOVEI	T1,.PRIOU	;GET READY
	CFOBF			;CLEAR OUTPUT BUFFER
	HRROI	T1,[ASCIZ/
Output stopped...

/]				;GET SOME TEXT
	PSOUT			;TYPE IT
	CALL	UNMAP		;UNMAP PAGES
	CALL	CLSFIL		;CLOSE THE FILES
	MOVEI	T1,CPOPJ	;GET ADDRESS OF A RETURN
	MOVEM	T1,CHNPC1	;SET LOCATION TO GO TO
	DEBRK			;RETURN
	  ERJMP	ERROR		;FAILED
	SUBTTL	SUBROUTINES TO OPEN THE INPUT AND OUTPUT FILES




OPNFIL:	MOVE	T1,JFN
	MOVX	T2,OF%RD	;OPEN INPUT JFN FOR READING
	OPENF
	  ERJMP	ERROR
	DVCHR			;SEE WHAT KIND OF DEVICE THIS IS
	LDB	T1,[POINTR T2,DV%TYP]
	SKIPE	T1		;IT MUST BE A DISK
	  DIE	Input device must be a disk
	MOVE	T1,JFNOUT	;GET OUTPUT JFN
	DVCHR			;READ TYPE OF DEVICE
	MOVEM	T1,DEVCHR	;SAVE IT
	LDB	T1,[POINTR T2,DV%TYP]	;GET DEVICE TYPE
	MOVEM	T1,DEVFLG	;REMEMBER FOR LATER
	CAIN	T1,.DVTTY	;IS THIS A TERMINAL?
	SKIPA	T2,[7B5+OF%WR]	;YES, USE SEVEN BIT BYTES
	MOVX	T2,OF%WR	;NO, THEN USE 36 BIT BYTES
	MOVE	T1,JFNOUT	;GET JFN AGAIN
	OPENF			;OPEN OUTPUT FILE
	  ERJMP	ERROR		;FAILED
	RET			;OK
	SUBTTL	SUBROUTINES TO CLOSE THE INPUT AND OUTPUT FILES




CLSFIL:	MOVE	T1,JFNOUT	;GET OUTPUT JFN
	CLOSF			;CLOSE IT
	  ERJMP	ERROR
	SETZM	JFNOUT		;CLEAR JFN
	MOVE	T1,JFN		;GET INPUT JFN
	CLOSF			;CLOSE IT TOO
	  ERJMP	ERROR
	SETZM	JFN		;CLEAR JFN WORD
	RET			;DONE
	SUBTTL	ROUTINE TO DO THE MAPPING



MAPPER:	SETOM PREPGN			;NO PRE-FAULTED PAGES YET
	HRLZ P1,JFN			;INPUT JFN IN LEFT HALF OF P1
	MOVE T1,P1			;INPUT JFN,,PAGE 0
	CALL $FFUFP			;FIND FIRST FILE PAGE

MAP3:	JUMPL T1,UNMAP			;NO MORE PAGES, GO UNMAP
	HRRZM T1,CURPAG			;SAVE PAGE NUMBER
	MOVE P1,T1			;SAVE PAGE NUMBER IN P1
	MOVE T2,[.FHSLF,,INPAG]		;MAPPING TO MEMORY
	MOVX T3,PM%RD			;REQUEST READ ACCESS
	CALL PREFLT			;PRE-FAULT PAGES IN
	PMAP				;MAP THE PAGE
	HRL T1,JFNOUT			;SAME PAGE OF OUTPUT FILE
	HRRI T2,OUTPAG			;MAPPING TO MEMORY
	MOVX T3,PM%WR			;REQUEST WRITE ACCESS
	SKIPN DEVFLG			;DON'T PMAP NON-DISKS
	PMAP				;MAP THE PAGE
	CALL ENCODE			;CODE THE PAGE
	SKIPE DEVFLG			;WRITING TO DISK?
	CALL DOSOUT			;NO, OUTPUT IT BY HAND
	MOVE T1,P1			;GET PAGE NUMBER
	CALL $FNUFP			;FIND NEXT PAGE OF INPUT FILE
	JRST MAP3			;CONTINUE MAPPING


UNMAP:	SETOM CURPAG			;WE ARE NO LONGER MAPPING
	SETO T1,			;UNMAP PAGES
	MOVE T2,[.FHSLF,,INPAG]		;MEMORY PAGE TO UNMAP
	SETZ T3,			;NO BITS NEEDED
	PMAP				;UNMAP THE PAGE
	HRRI T2,OUTPAG			;MEMORY PAGE TO UNMAP
	PMAP				;UNMAP THE PAGE
	HRRI T2,PREPAG			;MEMORY PAGES TO UNMAP
	MOVE T3,[PM%CNT+PAGCNT]		;NUMBER OF PAGES TO UNMAP
	PMAP				;UNMAP THEM
	RET				;ALL DONE
	SUBTTL	SUBROUTINE TO WRITE OUTPUT PAGE TO A FILE



;CALLED FOR NON-DISK FILES, TO DO THE OUTPUT.  (DISK FILES ARE WRITTEN
;USING PMAPS, WHICH ARE AUTOMATIC).



DOSOUT:	MOVE	T1,DEVFLG	;SEE IF THIS IS A TERMINAL
	CAIN	T1,.DVTTY	;IS IT?
	  JRST	TTYOUT		;YES, GO DO SPECIAL
	MOVE	T1,JFNOUT	;GET THE JFN
	HRROI	T1,OUTPGA	;POINT TO THE OUTPUT
	MOVNI	T3,PAGSIZ	;PAGE WORTH OF BYTES
	SOUT			;WRITE IT
	RET			;DONE



TTYOUT:	MOVE	T4,[POINT 7,OUTPGA]	;GET A POINTER TO THE BUFFER
	MOVE	T5,[POINT 7,TEMP]	;AND ONE TO THE SMALL BUFFER
	MOVEI	T6,PAGSIZ*5	;GET A COUNT TOO
	SETZM	TEMP+4		;INITIALIZE THE ZERO

TTYOUL:	SOJL	T6,PUNT		;DONE IF THE COUNT IS DONE
	ILDB	T1,T4		;GET THE NEXT CHARACTER
	JUMPE	T1,TTYOUL	;IGNORE NULLS
	IDPB	T1,T5		;PUT INTO THE BUFFER
	SKIPE	TEMP+4		;TIME TO OUTPUT SOME?
	CALL	PUNT		;YES, FORCE SOME OUTPUT
	JRST	TTYOUL		;LOOP


PUNT:	SETZ	T1,		;GET A NULL
	IDPB	T1,T5		;MAKE THE STRING ASCIZ
	HRRZ	T1,DEVCHR	;GET THE DEVICE DESIGNATOR
	IOR	T1,[TL%COR+TL%CRO+.TTDES]	;FINISH THE ARGUMENT
	MOVEI	T2,-1		;ALL REMOTES
	TLINK			;CLEAR LINKS IN CASE WE HAVE SPYERS
	  ERJMP	.+1		;IGNORE FAILURES
	MOVE	T1,JFNOUT	;GET READY
	HRROI	T2,TEMP		;READ FROM SMALL BUFFER
	SETZ	T3,		;TYPE UNTIL A NULL IS REACHED
	SOUT			;DO IT
	SETZM	TEMP+4		;RESET THE WORD
	MOVE	T5,[POINT 7,TEMP]	;AND THE POINTER
	RET			;DONE
	SUBTTL	PRE-FAULT PAGES




PREFLT:	ADJSP P,4			;MAKE ROOM ON STACK FOR AC'S
	DMOVEM T1,-3(P)			;SAVE A AND B
	DMOVEM T3,-1(P)			;SAVE C AND D
	HRRZ T1,T1			;GET PAGE NUMBER IN A
	IDIVI T1,PAGCNT			;GET GROUP NUMBER OF PAGE
	IMULI T1,PAGCNT			;PAGE NUMBER OF FIRST IN GROUP
	CAMN T1,PREPGN			;HAVE WE ALREADY PREFAULTED IT?
	 JRST PREOUT			;YES, GO LEAVE
	MOVEM T1,PREPGN			;SAY WE'VE PREFAULTED IT
	HRL T1,JFN			;GET INPUT JFN IN LEFT HALF
	MOVE T2,[.FHSLF,,PREPAG]		;MAPPING TO MEMORY
	MOVX T3,PM%CNT+PM%PLD+PAGCNT	;MAPPING A GROUP OF PAGES
	PMAP				;MAP THEM (WITH PRELOADING)
PREOUT:	DMOVE T3,-1(P)			;RESTORE C AND D
	DMOVE T1,-3(P)			;RESTORE A AND B
	ADJSP P,-4			;RESTORE STACK POINTER
	RET				;DONE
	SUBTTL	FIND FIRST (OR NEXT) INPUT FILE PAGE




$FNUFP:	ADDI	T1,1		;TRY NEXT PAGE
	TRNN	T1,-1		;IS PAGE NUMBER OUT OF BOUNDS?
	  JRST	FFDON		;YES, NO MORE PAGES

$FFUFP:	FFUFP			;FIND FIRST USED FILE PAGE
	  SKIPA			;FAILED, GO SEE WHY
	RET			;SUCCESSFUL
	CAIE	T1,FFUFX3	;WAS THIS THE LAST PAGE?
	  JRST	ERROR		;NO, SOMETHING ELSE
FFDON:	SETO	T1,		;YES, SAY ALL DONE
	RET			;DONE
	SUBTTL	SUBROUTINES TO READ OR SET BYTE SIZES




GETBSZ:	SKIPE	DEVFLG
	RET
	MOVE T1,JFN
	MOVE T2,[XWD 2,.FBBYV]
	MOVEI T3,FILBSZ
	GTFDB
	RET


SETBSZ:	SKIPE DEVFLG
	RET
	MOVE T1,JFNOUT
	HRLI T1,.FBBYV(CF%NUD)
	MOVX T2,FB%BSZ
	MOVE T3,FILBSZ
	CHFDB
	HRLI T1,.FBSIZ
	SETO T2,
	MOVE T3,FILLEN
	CHFDB
	RET
	SUBTTL	SUBROUTINE TO READ IN THE PASSWORD




;CALLED TO INPUT THE PASSWORD FOR THE FILES.  PASSWORD IS ASKED FOR
;ONLY ONCE IF THE OUTPUT IS TO A TERMINAL, BUT TWICE OTHERWISE.  THIS
;IS SO THAT MISTAKES IN TYPING THE PASSWORD CAN BE CAUGHT.



GETPSW:	CALL	NOECHO		;DON'T ECHO THE TERMINAL HERE
	HRROI	T1,[ASCIZ/Password: /]	;GET THE TEXT
	MOVEI	T2,PASBUF	;AND AREA TO READ INTO
	CALL	PSWIN		;ACTUALLY READ IT IN
	MOVE	T1,JFNOUT	;GET READY
	DVCHR			;GET THE DEVICE TYPE
	LDB	T1,[POINTR T2,DV%TYP]
	CAIE	T1,.DVNUL	;NULL DEVICE?
	CAIN	T1,.DVTTY	;OR A TERMINAL?
	  RET			;YES, ALL DONE
	SKIPE	CODFLG		;CODING THE PROGRAM?
	  JRST	PSWVER		;YES, ALWAYS ASK FOR VERIFICATION
	MOVX	T1,.WLJFN	;WANT TO COMPARE THE JFNS
	HRRZ	T2,JFN		;THE INPUT
	HRRZ	T3,JFNOUT	;AND THE OUTPUT
	WILD%			;SEE WHAT PARTS MATCH
	  ERJMP	PSWVER		;FAILED, THEN VERIFY IT
	TXNE	T1,WL%DEV!WL%DIR!WL%NAM!WL%EXT	;SAME FILE SPEC?
	  RET			;NO, SAFE TO DECODE

PSWVER:	HRROI	T1,[ASCIZ/Again: /]	;ASK FOR IT AGAIN
	MOVEI	T2,PASBF2	;ANOTHER AREA TO READ IT INTO
	CALL	PSWIN		;READ IT IN AGAIN
	MOVE	T1,[POINT 7,PASBUF]	;GET READY
	MOVE	T2,[POINT 7,PASBF2]	;TO COMPARE THE BUFFERS
PSWCMP:	ILDB	T3,T1		;GET CHAR FROM FIRST PASSWORD
	ILDB	T4,T2		;AND FROM SECOND PASSWORD
	CAME	T3,T4		;THEY MUST MATCH
	  DIE	Password not verified,0,GETPSW
	JUMPN	T3,PSWCMP	;CONTINUE UNTIL DONE
	RET			;GOT IT OK
;ROUTINE TO ACTUALLY INPUT THE PASSWORD.  T1 HAS THE POINTER TO
;THE PROMPT, T2 HAS THE AREA TO READ THE PASSWORD INTO.



PSWIN:	SETZM	CMDBLK+.CMFLG	;WE DON'T HAVE A REPARSE ADDRESS
	SETZM	ATMBUF		;CLEAR THE ATOM BUFFER
	MOVEM	T1,CMDBLK+.CMRTY	;SET UP THE PROMPT
	MOVEM	T2,TEMP		;REMEMBER AREA TO COPY TO
PSWINA:	MOVEI	T1,CMDBLK	;POINT TO THE COMND BLOCK
	CMMD	[FLDDB. (.CMINI)]	;INITIALIZE THE LINE
	CMMD	[FLDDB. (.CMTXT)]	;THEN READ IT IN
	HRROI	T1,[ASCIZ/
/]				;GET A CRLF
	PSOUT			;TYPE IT SO HE KNOWS HE IS DONE
	MOVE	T1,ATMBUF	;GET FIRST WORD OF THE TEXT
	TXNN	T1,177B6	;MAKE SURE IT ISN'T NULL
	  JRST	PSWINA		;IF SO, ASK AGAIN
	MOVE	T1,TEMP		;GET BACK THE ADDRESS
	MOVEI	T2,TXTLEN/5(T1)	;GET LAST ADDRESS TO BLT TO
	HRLI	T1,ATMBUF	;FINISH BLT POINTER
	BLT	T1,(T2)		;MOVE THE PASSWORD
	RET			;DONE
	SUBTTL	ROUTINE TO INITIALIZE THE RANDOM NUMBER GENERATOR




INIRAN:	MOVEI T4,1
	MOVEI T5,1
	MOVEI T6,1
	MOVE T1,[POINT 7,PASBUF]
NXTCHR:	ILDB T2,T1
	JUMPE T2,GOTPAS
	IMULI T4,^D4099
	IMULI T5,^D4111
	IMULI T6,^D4127
	CAIL T2,140
	SUBI T2,40
	ADDI T4,-40(T2)
	ADDI T5,-40(T2)
	ADDI T6,-40(T2)
	JRST NXTCHR

GOTPAS:	TLZ T4,774000
	TLZ T5,774000
	TLZ T6,774000
	MOVEM T4,NX
	MOVEM T5,NY
	MOVEM T6,NS
	RET
	SUBTTL	SUBROUTINE TO COMPUTE PSEUDO-RANDOM NUMBERS




;ROUTINE RANDOM
;GENERATE A RANDOM NUMBER BETWEEN 0 AND 43777

;RETURNS +1 ALWAYS WITH NUMBER IN T1

RANDOM:	MOVE T1,NX
	LSH T1,1
	CAML T1,[^D999999893]
	SUB T1,[^D999999893]
	MOVEM T1,NX
	MOVE T1,NY
	LSH T1,1
	CAML T1,[^D999999883]
	SUB T1,[^D999999883]
	MOVEM T1,NY
	ADD T1,NS
	CAML T1,[^D1000000000]
	SUB T1,[^D1000000000]
	ADD T1,NX
	CAML T1,[^D1000000000]
	SUB T1,[^D1000000000]
	MOVEM T1,NS
	IDIVI T1,44000
	MOVE T1,T2
	RET
;ROUTINE ENCODE
;COPY CONTENTS OF INPAG TO OUTPAG, ONLY SCRAMBLED
;RETURNS +1 ALWAYS

ENCODE:	MOVSI T6,-44000
	HRRZM T6,BITMAP(T6)
	AOBJN T6,.-1

	MOVSI T6,-44000
CREMAP:	CALL RANDOM
	MOVE T2,BITMAP(T1)
	EXCH T2,BITMAP(T6)
	MOVEM T2,BITMAP(T1)
	AOBJN T6,CREMAP

	MOVSI T6,-22000
LOOP:	MOVE T1,BITMAP(T6)
	MOVE T2,BITMAP+22000(T6)
	ADJBP T1,[POINT 1,INPGA,0]
	ADJBP T2,[POINT 1,INPGA,0]
	LDB T3,T1
	LDB T4,T2
	ADD T1,[EXP OUTPGA-INPGA]
	ADD T2,[EXP OUTPGA-INPGA]
	DPB T4,T1
	DPB T3,T2
	AOBJN T6,LOOP
	RET
	SUBTTL	SUBROUTINES TO ECHO AND NOECHO THE TERMINAL




ECHO:	SKIPN	ECHOFF		;ALREADY ECHOING?
	RET			;YES, DONE
	MOVEI	T1,.PRIIN	;GET READY
	RFMOD			;READ THE TERMINAL MODE
	TXO	T2,TT%ECO	;TURN ON ECHOING
	SFMOD			;SET IT
	SETZM	ECHOFF		;SAY ECHOING AGAIN
	RET			;DONE



NOECHO:	SKIPE	ECHOFF		;ALREADY NO ECHOED?
	RET			;YES, DONE
	SETOM	ECHOFF		;SAY ECHOING IS TURNING OFF
	MOVEI	T1,.PRIIN	;GET READY
	RFMOD			;READ TERMINAL MODE
	TXZ	T2,TT%ECO	;TURN OFF ECHOING
	SFMOD			;DO IT
	RET			;DONE
	SUBTTL	COMMAND JSYS SUBROUTINES



;SUBROUTINES TO DO THE COMND JSYS.  THESE ROUTINES RETURN TO THE COMMAND
;SCANNER FOR A NEW COMMAND IF AN ERROR OCCURS, UNLESS THE CALL TO THEM
;WAS FOLLOWED BY AN ERJMP, IN WHICH CASE IT IS TAKEN.




DONOIS:	HRROM	T2,NOIBLK+.CMDAT	;SAVE AS DATA
	MOVEI	T2,NOIBLK	;POINT TO BLOCK
	JRST	DOCMMD		;AND GO DO COMND JSYS



DOCNFM:	MOVEI	T2,[FLDDB. (.CMCFM)]	;GET CONFIRM FUNCTION
DOCMMD:	COMND			;PARSE THE FUNCTION
	  ERJMP	BADCMD		;ERROR, GO COMPLAIN
	TXNN	T1,CM%NOP	;PARSED CORRECTLY?
	  RET			;YES, DONE

BADCMD:	HLLZ	T2,(P)		;GET THE FOLLOWING INSTRUCTION
	TLZ	T2,(<@(17)>)	;REMOVE INDIRECT AND INDEX FIELDS
	CAMN	T2,[ERCAL]	;IS THIS AN ERCAL?
	JRST	@(P)		;YES, GO WHERE HE WANTS
	POP	P,T3		;NO, RESTORE ADDRESS
	CAMN	T2,[ERJMP]	;IS THIS AN ERJMP?
	JRST	@T3		;YES, GO TO IT
	JRST	ERROR		;NO, GO COMPLAIN
	SUBTTL	ERROR HANDLING



;HERE ON SOME ERRORS.  LOCATION DIEADR TYPES OUT A SPECIFIED TEXT AND
;A POSSIBLE ERROR MESSAGE, LOCATION ERROR JUST TYPES THE ERROR TEXT.
;MOST ERRORS GO TO THE REENTER ADDRESS OF THE PROGRAM.  LOCATION QUIT
;EXITS AND STAYS THAT WAY.



DIEADR:	PSOUT			;TYPE THE STRING
	JUMPL	T4,ERRTYP	;GO TYPE ERROR STRING IF DESIRED
	JRST	(T4)		;OTHERWISE GO WHERE WE SHOULD


ERROR:	MOVEI	T1,.TICCE	;GET READY
	TXZE	F,FR.TYP	;TYPING A FILE?
	DTI			;YES, TURN OFF INTERRUPT AGAIN
	HRROI	T1,[ASCIZ/
? /]				;GET READY
	PSOUT			;TYPE BEGINNING OF STRING
	MOVEI	T4,REEN		;SET UP ROUTINE TO GO TO


ERRTYP:	MOVEI	T1,.PRIOU	;PRIMARY OUTPUT
	HRLOI	T2,.FHSLF	;MY FORK, LAST ERROR
	SETZ	T3,		;INFINITE OUTPUT
	ERSTR			;TYPE THE STRING
	JFCL
	JFCL
	HRROI	T1,[ASCIZ/

/]				;GET ENDING TEXT
	PSOUT			;OUTPUT IT
	JRST	(T4)		;GO TO PROPER PLACE




QUIT:	RESET			;CLEAR ALL I/O
	HALTF			;STOP
	JRST	.-1		;STAY THERE
	SUBTTL	IMPURE STORAGE



CMDBLK:	EXP	0		;FLAGS AND REPARSE ADDRESS
	XWD	.PRIIN,.PRIOU	;INPUT,,OUTPUT JFNS
	EXP	0		;CONTROL-R BUFFER FILLED IN AT RUNTIME
	XWD	-1,TXTBUF	;POINTER TO TEXT BUFFER
	XWD	-1,TXTBUF	;POINTER TO CURRENT POSITION
	EXP	TXTLEN		;NUMBER OF CHARS IN BUFFER
	EXP	0		;COUNT
	XWD	-1,ATMBUF	;POINTER TO ATOM BUFFER
	EXP	TXTLEN		;NUMBER OF CHARACTERS IN BUFFER
	EXP	JFNBLK		;POINTER TO GTJFN BLOCK


JFNBLK:	EXP	GJ%OLD		;FLAGS,,GENERATION NUMBER
	XWD	.PRIIN,.PRIOU	;INPUT,,OUTPUT JFNS
	BLOCK	20		;NO DEFAULTS



NOIBLK:	FLDDB.	(.CMNOI)	;BLOCK FOR NOISE FUNCTION



LEVTAB:	EXP	CHNPC1		;PLACE TO STORE PC
	BLOCK	2		;OTHER LEVELS UNUSED

CHNTAB:	XWD	1,TYPINT	;LEVEL 1, INTERRUPT ROUTINE
	BLOCK	^D35		;OTHER CHANNELS UNUSED
	SUBTTL	PURE STORAGE


	XLIST			;DUMP THE LITERALS
	LIT
	LIST


PDL:	BLOCK	PDLSIZ		;STACK ROOM
INTSTK:	BLOCK	1		;STACK POINTER TO RESTORE ON INTERRUPT
CHNPC1:	BLOCK	1		;INTERRUPT PC
SAVEP:	BLOCK	1		;STORAGE OF STACK POINTER
TXTBUF:	BLOCK	TXTLEN/5+1	;BUFFER FOR COMMAND JSYS
ATMBUF:	BLOCK	TXTLEN/5+1	;BUFFER FOR ATOM BUFFER
PASBUF:	BLOCK	TXTLEN/5+1	;PASSWORD STRING
PASBF2:	BLOCK	TXTLEN/5+1	;DUPLICATE COPY
PASEND:	BLOCK	1		;LAST WORD TO CLEAR
TEMP:	BLOCK	TMPSIZ		;TEMPORARY STORAGE
BITMAP:	BLOCK	44000		;WHICH BITS ARE TO BE SWAPPED TABLE
DEVFLG:	BLOCK	1		;NON-DISK FLAG
DEVCHR:	BLOCK	1		;THE DEVICE DESIGNATOR
CODFLG:	BLOCK	1		;NONZERO IF WE ARE CODING
PREPGN:	BLOCK	1		;PAGE NUMBER OF PRE-FAULTED PAGE
CURPAG:	BLOCK	1		;PLACE TO PUT PAGE NUMBER
FILBSZ:	BLOCK	1		;INPUT FILE'S BYTE SIZE
FILLEN:	BLOCK	1		;INPUT FILE'S BYTE COUNT
DEFNAM:	BLOCK	20		;DEFAULT OUTPUT FILENAME
DEFEXT:	BLOCK	20		;DEFAULT OUTPUT EXTENSION
TTYMOD:	BLOCK	1		;SAVED TERMINAL MODE
NX:	BLOCK	1		;PSEUDO RANDOM NUMBERS FOR ENCRYPTION
NY:	BLOCK	1
NS:	BLOCK	1



	ZERBEG==.		;FIRST LOCATION TO ZERO ON STARTUP

JFN:	BLOCK	1		;INPUT JFN
JFNOUT:	BLOCK	1		;OUTPUT JFN
ECHOFF:	BLOCK	1		;NONZERO IF ECHOING IS OFF

	ZEREND==.-1		;LAST LOCATION TO CLEAR



	END	<3,,START>