Google
 

Trailing-Edge - PDP-10 Archives - BB-5255D-BM - language-sources/ddt.mac
There are 55 other files named ddt.mac in the archive. Click here to see a list.
SUBTTL	DDT	/TW/PFC/TWE/DAL/DLM/EJW/JNG/RDH/DIB/DZN	6-Nov-79



	COMMENT	\

DDT  --  "Dynamic Debugging Technique" for TOPS-10/TOPS-20

COPYRIGHT (C) 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979
BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.


THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
ONLY  IN  ACCORDANCE  WITH  THE  TERMS  OF  SUCH LICENSE AND WITH THE
INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR ANY  OTHER
COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF THE  SOFTWARE  IS  HEREBY
TRANSFERRED.


THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT  NOTICE
AND  SHOULD  NOT  BE  CONSTRUED  AS A COMMITMENT BY DIGITAL EQUIPMENT
CORPORATION.

DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY  OF  ITS
SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.

\


;			*** NOTE ***
;
;DDT.MAC is a common source file shared by the TOPS-10 and TOPS-20 groups.
;If either group changes it, they are responsible for coordinating their
;changes with the other group, so that the sources do not diverge and the
;latest version is always released on both systems.



;DDT VERSION IDENTIFICATION

MAJVER==41	;MAJOR VERSION LEVEL
MINVER==0	;MINOR (MAINTENANCE RELEASE) LEVEL
CSTVER==0	;CUSTOMER VERSION (WHO LAST . . .)
EDTVER==265	;EDIT LEVEL

%%DDT==:<BYTE (3)CSTVER(9)MAJVER(6)MINVER(18)EDTVER>

	IF2	<PURGE MAJVER,MINVER,CSTVER,EDTVER>
;               TABLE OF CONTENTS FOR DDT
;
;
;                        SECTION                                   PAGE
;    1. REVISION HISTORY..........................................   5
;    2. DDT ASSEMBLY SWITCHES.....................................  10
;    3. TITLE AND VERSION SETTING.................................  11
;    4. OPDEFS, MACROS, ETC.......................................  12
;    5. DDT SYMBOLS...............................................  16
;    6. GLOBAL SYMBOLS FOR USE BY THE OUTSIDE WORLD...............  17
;    7. MEMORY ALLOCATION PARAMETERS..............................  18
;    8. MISCELLANEOUS DDT SYMBOLS.................................  20
;    9. FILDDT
;         9.1   COMMAND SCANNER...................................  25
;         9.2   SETUP PAGE BUFFERS AND SYMBOLS....................  53
;   10. START DDT.................................................  59
;   11. DDT COMMAND PARSER........................................  60
;   12. COMMAND DISPATCH TABLE....................................  65
;   13. COMMAND ROUTINES
;        13.1   CLASS 1...........................................  66
;        13.2   CLASS 2...........................................  84
;        13.3   CLASS 3...........................................  85
;        13.4   CLASS 4...........................................  86
;        13.5   CLASS 5...........................................  87
;        13.6   CLASS 6...........................................  89
;        13.7   REGISTER DEPOSIT AND OPEN.........................  89
;        13.8   RETYPE LAST QUANTITY..............................  97
;        13.9   TYPEOUT MODE CONTROL..............................  98
;        13.10  LIMITS AND PATCHING............................... 100
;        13.11  MEMORY AND PAGING CONTROL......................... 105
;        13.12  BREAKPOINT FACILITY............................... 111
;        13.13  EXECUTE AND SINGLE STEP........................... 118
;        13.14  PUNCH PAPER TAPE.................................. 144
;        13.15  SEARCHING......................................... 148
;        13.16  COMMAND FILE INPUT................................ 150
;        13.17  MISCELLANEOUS COMMANDS............................ 153
;   14. FILE SPECIFICATION PARSING AND ERROR ROUTINES............. 159
;                        SECTION                                   PAGE
;   15. ENTER AND LEAVE DDT
;        15.1   SAVE.............................................. 169
;        15.2   RESTOR............................................ 174
;        15.3   SWAP.............................................. 176
;        15.4   BCOM.............................................. 177
;   16. WORD TYPEOUT AND FORMATTING ROUTINES...................... 180
;   17. OUTPUT SUBROUTINES........................................ 187
;   18. SYMBOL TABLE ROUTINES
;        18.1   CHECK POINTERS.................................... 192
;        18.2   CONVERT SYMBOL TO VALUE........................... 194
;        18.3   CONVERT VALUE TO SYMBOL........................... 196
;        18.4   HARDWARE OPCODE PROCESSING........................ 199
;        18.5   FIND PROGRAM NAME................................. 209
;        18.6   REMOVE AN UNDEFINED SYMBOL........................ 210
;        18.7   SYMSET, USYSET, AND ADVSYM........................ 211
;   19. MEMORY MANAGEMENT ROUTINES
;        19.1   FETCH............................................. 218
;        19.2   DEPOSIT........................................... 226
;        19.3   ADDRESS MAPPING................................... 238
;        19.4   PHYSICAL MEMORY................................... 243
;        19.5   FILDDT I/O........................................ 246
;        19.6   SYMBOL TABLE ACCESS............................... 252
;        19.7   ADDRESS CHECKING.................................. 259
;        19.8   MISCELLANEOUS..................................... 270
;   20. PRESERVATION ROUTINES..................................... 286
;   21. TELETYPE IO LOGIC
;        21.1   DEFINITIONS....................................... 288
;        21.2   INPUT ROUTINES.................................... 291
;        21.3   LINE BUFFERING ROUTINES........................... 295
;        21.4   UTILITY ROUTINES.................................. 312
;        21.5   OUTPUT SUBROUTINES................................ 319
;        21.6   SAVE/RESTORE...................................... 324
;   22. STORAGE
;        22.1   LITERALS AND END OF CODE.......................... 336
;        22.2   ALLOCATION MACROS................................. 337
;        22.3   MISCELLANEOUS..................................... 339
;        22.4   $X LOGIC AND PATCH COMMAND........................ 341
;        22.5   BREAKPOINTS....................................... 342
;        22.6   SYMBOL TABLE LOGIC................................ 344
;        22.7   ADDRESSING DATA................................... 346
;        22.8   SAVE AREAS FOR PREVIOUS CONTEXT................... 347
;        22.9   STATE VARIABLES................................... 349
;        22.10  FILDDT............................................ 350
;        22.11  PUSH DOWN LIST.................................... 353
SUBTTL	REVISION HISTORY

;THE REVISION HISTORY STARTS SUDDENLY AT EDIT 200
;
;	DDT %37(200)   RDH   14-NOV-76

;200	RDH	14-NOV-76	SPR 10-17714
;	VALIDITY-CHECK THE SYMBOL POINTER FOR THE HIGH-SEG SYMBOL
;	TABLE (.JBHSM) RATHER THAN ARBITRARILY BELIEVING IT (AND
;	SUBSEQUENTLY ILL MEM REF'ING, ETC.).

;201	RDH	14-NOV-76	SPR 10-18806
;	MORE OF EDIT 200, AT DEF1:

;202	RDH	14-NOV-76	SPR 10-19661
;	TREAT THE MAP INSTRUCTION "E" FIELD AS AN IMMEDIATE QUANTITY
;	RATHER THAN AS A MEMORY REFERENCE.

;203	RDH	14-NOV-76
;	EXPAND FILDDT TO HANDLE FULL 22-BIT ADDRESSING IN EXE-FORMAT
;	FILES (SPECIFICALLY CRASH.EXE).

;204	RDH	14-NOV-76	SPR 10-20165
;	IMPLEMENT SPECIAL BYTE-FORMAT TYPEOUT FOR THE VARIOUS
;	BYTE MANIPULATION INSTRUCTIONS. CODE COURTESY OF THE
;	UNIVERSITY OF ARIZONA.

;205	RDH	15-NOV-76
;	PUT TAG PTDFLG: UNDER FTYANK RATHER THAN FTEXEC!FTFILE FOR
;	THOSE SITES THAT WISH TO TAKE THEIR CHANCES WITH $Y IN EITHER
;	UDDT OR VMDDT (NOTE: $Y USES I/O CHANNEL 17 - BE WARNED)

;206	RDH	4-DEC-76
;	REWRITTEN CODE IN CHKADR (TO BETTER HANDLE KL'S) FORGOT HOW
;	KA'S WORKED AND LOST THE APR PI ASSIGNMENT.

;207	RDH	4-DEC-76
;	IMPLEMENT "/D" FOR FILDDT  --  TREAT FILE SPECIFIED AS PURE
;	DATA FILE - DON'T CRUMP ON FIRST 20 LOCATIONS (THE "ACS"),
;	DON'T LOOK FOR SYMBOL TABLE. IF NOT .EXE FORMAT AND NOT .XPN
;	FORMAT THEN "/D" IS ASSUMED.

;210	RDH	6-DEC-76
;	EXTEND THE $M COMMAND  --  <M>$<N>M  --  WHERE <N> IS THE
;	MASK NUMBER AND <M> IS THE ASSOCIATED MASK.
;
;	<N> =  0 OR NOT-SPECIFIED THEN <M> IS THE SEARCH MASK
;	<N> = 1 THEN <M> IS TTY CONTROL MASK:
;		1B35 = 1 THEN "ECHO" <DEL>'S AS <BS><SP><BS>
;211	RDH	6-DEC-76
;	NEW ASSEMBLY PARAMETER "SKPMAX" TO SET MAXIMUM NUMBER OF
;	LOCATIONS SKIPPED FOR $X LOGIC. IF <INSTR>$X THEN TYPE
;	<SKP> FOR EACH LOCATION SKIPPED. IF $$X THEN DO INDEFINITE
;	$X UNTIL OLD-PC .LT. NEW-PC .LE. OLD-PC+SKPMAX

;212	RDH	7-DEC-76
;[214]	MATCH ANGLE BRACKETTS  --  <<
;	WHEN PATCHING ($>) DON'T INSERT A 0 WORD UNLESS USER EXPLICITLY
;	TYPED IT - I.E., ALLOW THE $> TO APPEAR BY ITSELF - THE WAY MOST
;	PEOPLE TEND TO USE IT.

;213	RDH	9-DEC-76
;	CHANGE SKIPN'S TO SKIPE'S IN [207] AND CAILE TO CAIL IN [210]

;214	RDH	18-DEC-76
;	MATCH ANGLE BRACKETTS IN EDIT [212] COMMENTS TO KEEP VARIOUS
;	AND SUNDRY PEOPLE HAPPY.

;215	RDH	19-DEC-76
;	IF SPYSEG THEN NO HISEG SYMBOL TABLE.

;216	RDH	19-DEC-76
;	CHKHSM ROUTINE ([200],[201]) IS TOO RESTRICTIVE, WON'T ALLOW
;	.JBHSM TO POINT TO LOW SEG; CHKADR ROUTINE WON'T ALLOW RANDOM
;	NON-CONTIGUOUS PAGES.

;217	RDH	19-DEC-76
;	NAMSET ROUTINE (TO HANDLE MODULE$:) ASSUMES HIGH SEGMENT ALWAYS
;	STARTS AT 400000, LEADING TO SUBSEQUENT ILL MEM REF'S.

;220	JNG	28-JAN-77
;	PREVENT ILL MEM REF ON PATCH CLOSE WHEN USING A WRITE-LOCKED
;	(E.G. HISEG) SYMBOL TABLE.

;DDT %40(220) MARCH, 1977

;221	TAH	13-MAR-77
;	ADD COMMAND FRONT END TO INTERFACE FILDDT TO TOPS-20 SYSTEM.
;	ADD KL PAGING CODE TO CVTADR, ALL UNDER FTFD20 CONDITIONAL
;	(FTFILE MUST STILL BE ON ALSO).

;222	ASM	13-MAR-77
;	IN EXEC DDT DETERMINE EXEC VIRTUAL ADDRESS OF EPT BY SCANNING
;	EXEC VIRT ADR SPACE IF PAGING IS ON.

;223	TAH	13-MAR-77
;	MAKE LPDL LARGER FOR TOPS-20 MDDT
;224	RDH	13-MAR-77
;	MAKE SEARCHES HANDLE NON-CONTIGUOUS CORE/FILE IMAGES, ADD
;	TWO NEW ASSEMBLY PARAMETERS:
;
;	    INDPTH	;MAX INDIRECT NESTING FOR $E SEARCHES
;	    LISCNT	;NUM OF <PUSHJ P,LISTEN>'S TWEEN INCHRS'S

;225	RDH	13-MAR-77
;	HANDLE TYPEOUT RADIX .GE. 10 (E.G., HEX) MORE GRACEFULLY

;226	RDH	13-MAR-77
;	EDIT 215 IS WRONG, .GTSGN == 14

;227	JNG	13-MAR-77
;	ADD CODE TO DDT TO WRITE-ENABLE PAGES ON TOPS-20 BEFORE
;	ATTEMPTING TO WRITE THEM - E.G., FOR BREAKPOINTS, PATCHS,
;	AND SO FORTH. IF PAGE NOT WRITE-ENABLED, SET COPY-ON-WRITE
;	SO AS NOT TO ZAP OTHER USERS "SHARING" THE PAGE.

;230	RDH	13-MAR-77
;	WHEN IN A COMMAND FILE ($Y) THEN DO NOT CHECK THE COMMAND
;	FILE FOR INPUT ON CALLS TO LISTEN - ONLY ACCEPT PHYSICAL
;	TTY INPUT.

;231	RDH	14-MAR-77
;	CLEAR $U POINTERS IN FILDDT ON ^Z, START SEQUENCE

;232	RDH	14-MAR-77
;	UPDATE LH(.JBSA) ON PATCH END IF .JBFF WAS DEFAULTED TO
;	ON PATCH BEGIN. THIS WAY THE PATCH IS AT LEAST SAVED ON
;	SAVE'S, RESET'S, AD NAUSEUM.

;233	RDH	14-MAR-77
;	REVAMP PATCH LOGIC ($< AND $>) TO DISPLAY LOCATION BEFORE
;	MODIFYING SAME LOCATION SO THAT FILDDT CAN PATCH RUNNING
;	MONITOR (ALSO LOOKS NEATER).

;234	RDH	23-MAR-77
;	ADD NEW "MASK" COMMAND <N>$2M TO SET THE SYMBOL OFFSET RANGE
;	(I.E. THE RANGE IN WHICH VALUES WILL BE TYPED IN THE FORM
;	SYMBOL+<OFFSET>) TO <N>. ADD ASSEMBLY PARAMETER "ADRNGE"
;	AS THE DEFAULT VALUE. ALSO MAKE $1M/ ETC. WORK.

;235	RDH	24-MAR-77
;	REVAMP BYTE TYPEOUT LOGIC: ADD <N>$3M AS BYTE TYPEOUT MASK
;	(EACH "1" BIT IN THE MASK MARKS THE END OF A BYTE, BIT 35
;	IS ALWAYS CONSIDERED THE END OF A BYTE). FOR VALUES OF <N>
;	SUCH THAT 1 .LE. <N> .LE. 36(10) THE COMMANDS $<N>O & $$<N>O
;	WORK AS USUAL BY SETTING AN INTERNAL BYTE MASK. FOR <N> = 0
;	THE $3M BYTE MASK WILL BE USED. FOR <N> = <NULL> (I.E. THE
;	$O COMMAND) THE CURRENTLY PREVAILING $O OR $$O MASK WILL
;	BE USED IF NON-BLANK, ELSE THE $3M MASK WILL BE USED.
;	$$O MAKES PERMANENT THE CURRENTLY PREVAILING $O (OR $$O)
;	BYTE MASK.
;236	RDH	14-APR-77
;	ADD IFN FTYANK CONDITIONALS SO THAT FILDDT CAN BE ASSEMBLED
;	WITH FTYANK TURNED OFF

;237	RDH	17-APR-77
;	GENERAL CLEANUP AND REARRANGEMENT. MAKE TOPS-10 DDT SEARCH
;	THE "C" UNIVERSAL FILE. TYPE OUT "DDT" WHEN USER MODE DDT
;	IS ENTERED. PUT TOPS-10-SPECIFIC CODE UNDER "IFN FTDEC10"
;	RATHER THAN "IFE FTDEC20".

;240	RDH	15-JUN-77
;	ADD CODE TO TYPE OUT SYMBOLIC WORDS WITH USER-DEFINED SYMBOLS
;	SUCH AS THE CALLI OR JSYS MNEMONICS. ORDER OF SEARCH IS:
;	   1)	OPCODE & AC & I & X & Y FIELDS
;	   2)	OPCODE & I & X & Y FIELDS (E.G. CALLI OR JSYS)
;	   3)	OPCODE & AC FIELDS (E.G. TTCALLS)
;	   4)	OPCODE ONLY
;	   5)	HARDWARE-KNOWN OPCODE (JRST, ETC.)
;	PUT CODE UNDER FTOPX .NE. 0 CONDITIONAL SINCE UNTIL SORTED
;	SYMBOL TABLES AVAILABLE THIS CODE TAKES MUCH RUN TIME.
;	ALSO MAKE TRXX AND TLXX TYPE OUT ADDRESS AS OCTAL RATHER
;	THAN SYMBOL+OFFSET.

;241	RDH	15-SEP-77	SPR # 10-22011
;	"777777" COULD GET TYPED OUT AS "-1" WHEN $X'ING IF THE
;	AC BEING TYPED OUT WAS TYPED OUT IN XWD FORMAT.

;242	RDH	16-SEP-77	SPR # 10-22616
;	"AOS UND#(AC)" LOST BOTH THE UND SYMBOL AND THE AC IN
;	THE WORD BEING BUILT (I.E., LEFT ONLY THE AOS).

;243	RDH	16-SEP-77	SPR # 10-22788
;	PATCHING WITH FILDDT WRONG IF NONE OF THE USUAL PATCHING
;	SYMBOLS (PAT.., PAT, PATCH) ARE PRESENT AND THUS PATCHING
;	DEFAULTS TO C(.JBFF) - THE .JBFF USED WAS FILDDT'S, NOT
;	THE FILE'S.

;244	RDH	16-SEP-77	SPR # 10-22894
;	SOME RUBOUT'S STILL GET TYPED OUT.

;245	RDH	17-SEP-77	SPR # 10-23013
;	AFTER REFERENCING AN UNDEFINED SYMBOL, THE UNDEFINED SYMBOL
;	IS LEFT IN THE SYMBOL CACHE WITH ITS BOGUS VALUE (E.G., THE
;	ADDRESS TO FIX UP).

;246	RDH	25-SEP-77
;	BE MORE CHOOSEY ABOUT TYPE-IN INVOLVING UNDEFINEDS - CATCH ERRORS
;	SUCH AS "PUSHJ UND#,FOO" OR "MOVE 4,(UND#)"
;247	RDH/JNG	16-OCT-77 TO 28-JUN-78
;	MASSIVE DEVELOPMENT AND REVAMPING: EXTENDED ADDRESSING; JSYSIZE FILDDT;
;	REMOVE SYMBOL CACHE; ADD $0W AND $1W; DISK SUPER I/O (FILDDT);
;	PHYSICAL MEMORY ADDRESSING; KS-10 SUPPORT; KI/KL PAGING SUPPORT;
;	$Z; $8T AND $9T; $.; $U ENHANCEMENTS; $B ENHANCEMENTS; $X EN-
;	HANCEMENTS; DECOMMIT EXEC PAPER TAPE STUFF; SYMBOLIC TYPEOUT
;	ENHANCEMENTS; $Y ENHANCEMENTS (TOPS-10 ONLY); NUMEROUS RANDOM
;	BUG FIXES. CALL VERSION 41.

;250	JNG	15-AUG-78
;	SEARCH UUOSYM, MACTEN INSTEAD OF C.

;DDT %40A(250)	OCTOBER, 1978

;251	JNG/RDH	15-AUG-78 TO 26-JAN-79
;	CONTINUING AND FIXING BUGS IN 247: IMPLEMENT HISEG SYMBOL TABLES
;	IN FILDDT; ALLOW THE SYMBOL TABLE TO BE IN ANOTHER ADDRESS SPACE
;	FOR EDDT AND MDDT; ADD $: WITH NO ARGUMENT; ADD "M" ERROR.

;252	JNG	4-FEB-79
;	CHANGE HIDDEN SYMBOL LOGIC TO DO EXEC VIRTUAL BLT'S INSTEAD
;	OF SWITCHING THE EPT BASE ADDRESS.

;253	DIB	8-MAR-79
;	INSERT A NEW SYMBOL TABLE CACHE FOR OUTPUT ONLY.  ALSO MOVE
;	DATA PAGES BELOW CODE PAGES SO SYMBOL CACHE WILL FIT IN UDDT.

;254	JNG/RDH	8-MAR-79
;	GET FAKEAC LOGIC RIGHT IN $U COMMANDS.  BROKEN BY 251. ONLY
;	SETUP .JBVER IF FILDDT. ADD /A (ABORT ON COMMAND ERROR) FOR
;	$Y. MAKE ^W WORK MORE REASONABLY ON -10. MAKE FANCY RUBOUT
;	HANDLING AUTOMATIC ON -10 (7.01 ONLY). ADD $$. AS PREVIOUS
;	$. (USEFUL FOR $$.<$$X ETC.).
;	(MATCH ANGLE BRACKETS:>)

;255	RDH	31-MAR-79
;	LOST INSTRUCTION IN EDDT FOR KI-10'S. SUPPRESS ADDRESS BREAKS
;	IN FETCH AND STORE LOGIC. IF $$X'ING (OR $W'ING (SEARCHING)
;	OR $Z'ING (DEPOSITING)) AND USER TYPES A ? THEN GIVE A QUICKIE
;	TYPEOUT STATUS. SECOND FIELD TEST FOR TOPS-10 7.00.

;256	RDH	17-APR-79
;	RANDOM VERSION 41 BUGS (IN PARTICULAR $P OF A BREAKPOINT CAUSED
;	BY XCT'ING A BREAKPOINT LOCATION FAILED). HANDLE ERCAL/JMP ON
;	$P. HANDLE INIT UUO.

;257	JNG	21-APR-79
;	CONVERT $U COMMAND TO FUNCTION CODES.
;260	RDH	13-MAY-79
;	ADD ADR$V COMMAND TO "WATCH" A LOCATION AND REPORT ANY CHANGE IN
;	ITS CONTENTS (ADR DEFAULTS TO LAST LOCATION OPENED).

;261	RDH	22-MAY-79
;	STUPID LITTLE BUGS

;262	RDH	8-JUL-79
;	XJRSTF AND FRIENDS WANT ALL 36 BITS OF PC FLAGS, NOT JUST THE
;	LEFT-MOST 18 BITS. $I+3 IS 36-BIT PC FLAGS, $I+4 IS 36-BIT PC.

;263	RDH	16-JUL-79
;	MORE STUPID LITTLE BUGGIES. IN PARTICULAR, N$P BROKE.

;264	DZN	25-OCT-79
;	REPLACE SUB IN LOOKDN WITH EQUIVALENT CODE THAT DOESN'T OVERFLOW.

;265	DZN	6-NOV-79
;	REMOVE MULTIPLY-DEFINED GLOBALS $nB, $I, $M WHEN KDDT AND MDDT ARE
;	LOADED TOGETHER.
SUBTTL	DDT ASSEMBLY SWITCHES

;SWITCHES FOR DDT FEATURES

;FTDEC10	;TOPS-10 FACILITIES
;FTDEC20	;TOPS-20 FACILITIES
;FTEXEC		;EXEC MODE FACILITIES (ALSO RUNS IN USER MODE)
;FTEX20		;TOPS-20 MONITOR EDDT (LOADS ONLY WITH TOPS-20 MONITOR)
;FTPTP		;PAPER TAPE FACILITIES (EXEC MODE ONLY)
;FTFILE		;FILE DDT
;FTYANK		;PAPER TAPE INPUT FACILITIES ($Y)
;FTVMX		;BUILD DDT.VMX FOR TOPS-10 VIRTUAL MEMORY
;FTMON		;TOPS-20 MONITOR DDT
;FTOPX		;EXTENDED OPCODE DECODING FOR TYPEOUT
;FTDBUG		;DEBUGGING FACILITIES FOR DDT ITSELF (ESP EXEC MODE)

IFNDEF	FTDEC10,<
	IFNDEF	FTDEC20,<
		FTDEC10==-1
		FTDEC20==0>>
IFNDEF	FTDEC10,<FTDEC10==0>
IFNDEF	FTDEC20,<FTDEC20==0>
IFNDEF	FTFILE,<FTFILE==0>
IFNDEF	FTYANK,<FTYANK==0>
IFNDEF	FTEX20,<FTEX20==0>
IFNDEF	FTEXEC,<
	IFN	FTEX20,<FTEXEC==-1>
	IFE	FTEX20,<FTEXEC==0>>
IFNDEF	FTPTP,<FTPTP==0>
IFNDEF	FTVMX,<	FTVMX==0>
IFNDEF	FTMON,<	FTMON==0>
IFNDEF	FTOPX,<FTOPX==-1>
IFNDEF	FTDBUG,<FTDBUG==0>

;NORMALIZE ALL SWITCH VALUES TO 0 OR -1 SO BOOLEAN EXPRESSIONS IN
;CONDITIONALS WORK CORRECTLY.

DEFINE ..N (SW)<
	IRP	SW,<
IFN	SW,<SW==-1>>>

..N	<FTDEC10,FTDEC20,FTEXEC,FTEX20,FTPTP,FTFILE,FTYANK,FTVMX,FTMON>
..N	<FTOPX,FTDBUG>

IFN	FTDEC10&<FTDEC20!FTMON!FTEX20>,<PRINTX ? Illegal FTDEC10>
IFN	FTDEC20&<FTDEC10!FTYANK!FTVMX>,<PRINTX ? Illegal FTDEC20>
IFN	FTEXEC&<FTFILE!FTVMX!FTMON>,<PRINTX ? Illegal FTEXEC>
IFN	^-FTEXEC&<FTPTP!FTEX20>,<PRINTX ? Illegal ^-FTEXEC>
IFN	FTFILE&<FTEXEC!FTPTP!FTVMX!FTMON!FTEX20>,<PRINTX ? Illegal FTFILE>
SUBTTL	TITLE SETTING AND UNIVERSAL SEARCHING

	SALL			;CLEAN LISTINGS
	.DIREC	FLBLST		;CLEANER LISTINGS


IFN	FTDEC10,<		;TOPS-10 VERSIONS

	SEARCH	JOBDAT,MACTEN,UUOSYM	;ALL STANDARD TOPS-10 DEFINITIONS

IFE	FTDBUG,<
IFN	FTEXEC,<TITLE	EDDT -- TOPS-10 EXEC MODE DDT>
IFN	FTFILE,<TITLE	FILDDT -- TOPS-10 FILE DDT>
IFN	FTVMX,<TITLE	VMDDT -- TOPS-10 VM DDT>
IFE	FTFILE!FTEXEC!FTVMX,<TITLE	UDDT -- TOPS-10 USER MODE DDT>
> ;END OF IFE FTDBUG
> ;END OF TOPS-10 TITLES


IFN	FTDEC20,<		;TOPS-20 VERSIONS

	SEARCH	JOBDAT,MONSYM,MACSYM	;ALL STANDARD TOPS-20 DEFINITIONS

IFE	FTDBUG,<
IFN	FTEXEC&<^-FTEX20>,<TITLE	EDDT -- TOPS-20 EXEC MODE DDT>
IFN	FTEXEC&FTEX20,<TITLE	KDDT -- TOPS-20 MONITOR KERNAL DDT>
IFN	FTFILE,<TITLE	FILDDT -- TOPS-20 FILE DDT>
IFN	FTMON,<TITLE	MDDT -- TOPS-20 MONITOR DDT>
IFE	FTEXEC!FTFILE!FTMON,<TITLE	UDDT -- TOPS-20 USER MODE DDT>
> ;END IFE FTDBUG
> ;END OF TOPS-20 TITLES

IFN	FTDBUG,<TITLE	DEBDDT -- DEBUGGING VERSION OF DDT>


IFN	FTFILE,<		;ONLY FILDDTS SET UP VERSION NUMBER
	LOC	.JBVER		;WHERE THE TOPS-10 VERSION INFO GOES
	%%DDT			;SET THE VERSION WORD
	RELOC			;BACK TO NORMAL
> ;END IFN FTFILE
SUBTTL	OPDEFS, MACROS, ETC.

;GENERAL

OPDEF	SKPUSR	[SKIPL USRFLG]	;SKIP IN USER MODE
OPDEF	SKPEXC	[SKIPGE USRFLG]	;SKIP IN EXEC MODE
OPDEF	SKPKA	[SKIPN KAFLG]	;SKIP FOR KA10
OPDEF	SKPNKA	[SKIPE KAFLG]	;SKIP NOT KA10
OPDEF	SKPKI	[SKIPN KIFLG]	;SKIP FOR KI10
OPDEF	SKPNKI	[SKIPE KIFLG]	;SKIP NOT KI10
OPDEF	SKPKL	[SKIPN KLFLG]	;SKIP FOR KL10
OPDEF	SKPNKL	[SKIPE KLFLG]	;SKIP NOT KL10
OPDEF	SKPKS	[SKIPN KSFLG]	;SKIP FOR KS10
OPDEF	SKPNKS	[SKIPE KSFLG]	;SKIP NOT KS10
OPDEF	SKPKLS	[SKIPN KLSFLG]	;SKIP FOR KL10 OR KS10

OPDEF	SKPKIP	[SKIPN KIPAG]	;SKIP FOR KI-PAGING
OPDEF	SKPKLP	[SKIPN KLPAG]	;SKIP FOR KL-PAGING
OPDEF	SKPS0	[SKIPE SECDDT]	;SKIP IF IN ZERO SECTION 
OPDEF	SKPNS0	[SKIPN SECDDT]	;SKIP IF IN NON-ZERO SECTION

OPDEF	APRID	[700000,,000000];KL-10/KS-10 READ APR ID
OPDEF	RDAPR	[700240,,000000];KS-10 CONI APR,
OPDEF	WRAPR	[700200,,000000];KS-10 CONO APR,
OPDEF	RDCSB	[702040,,000000];KS-10 READ CST BASE
OPDEF	RDSPB	[702000,,000000];KS-10 READ SPT BASE
OPDEF	RDTIMS	[702200,,000000];KS-10 RDTIME
OPDEF	WRTIMS	[702600,,000000];KS-10 WRTIME

OPDEF	XMOVEI	[SETMI]		;MACRO HASN'T GOT IT YET
OPDEF	IFIW	[1B0]		; . . .
.NODDT	IFIW			;DON'T WANT TO OVERRIDE SETZ
;.PHASE AND .DEPHASE MACRO DEFINITIONS
;NEEDED BECAUSE PHASE AND DEPHASE DON'T NEST
;USE THESE IN ALL CASES INSTEAD OF PHASE AND DEPHASE


	..PLVL==0		;INITIAL PHASE NESTING LEVEL


;MACRO TO REFERENCE THE LAST LOCATION AT PHASE LEVEL N

DEFINE	..PL(N)<..PL'N>		;SYMBOL DEFINED BY .PHASE


;SUBSTITUTE FOR PHASE STATEMENT

DEFINE	.PHASE(N),<

	..==10			;;SAVE RADIX
	RADIX	10		;;MOST LEVELS PER CHAR
	..PL(\..PLVL)==.	;;REMEMBER WHERE WE ARE
	RADIX	..		;;RESTORE THE RADIX

IFE <..PLVL-^D99>,<PRINTX ? .PHASE NESTING OVERFLOW>
	..PLVL==..PLVL+1		;;BUMP NESTING LEVEL

	PHASE	N
> ;END OF .PHASE DEFINITION


;SUBSTITUTE FOR DEPHASE

DEFINE	.DEPHASE,<

	..PLVL==..PLVL-1

IFL ..PLVL,<PRINTX ? .PHASE NESTING UNDERFLOW>

IFG ..PLVL,<
	..==10			;;SAVE RADIX
	RADIX	10		;;USE RADIX WE WANT
	PHASE	.+..PL(\..PLVL)	;;BACK TO PREVIOUS PHASE LEVEL
	RADIX	..		;;BACK TO OLD RADIX
>

IFE ..PLVL,<
	DEPHASE			;;JUST DEPHASE AT OUTER LEVEL
>

> ;END OF .DEPHASE DEFINITION
;SYMBOLS NOT OTHERWISE DEFINED IN STANDARD UNIVSERALS

;TOPS-10 SPECIFIC

IFN	FTDEC10,<

DEFINE	TMSG(TEXT)<
	OUTSTR	[ASCIZ\TEXT\]	;;DEFINED IN MACSYM FOR TOPS-20
>
> ;END OF IFN FTDEC10



;TOPS-20 SPECIFIC

IFN	FTDEC20,<

DEFINE	ND(S,V),<IF2,<IFDEF S,<S==S>> IFNDEF S,<S==V>> ;NOT IN MACSYM

ND	.CHCNH,.CHBSP		;THE -10 AND THE -20 USE DIFFERENT NAMES
	IF2	<PURGE .CHBSP>	;DON'T CLUTTER UP THE SYM TABLE

	OPDEF	PJRST	[JRST]	;NOT IN MACSYM
	.NODDT	PJRST		;NO TYPEOUT IN OPCODE FIELD
	OPDEF	MRPAC% [JSYS 772]
> ;END OF IFN FTDEC20
SUBTTL	DDT SYMBOLS

;DEFINE ACCUMULATORS

F=0				;FLAGS
P=1				;PUSH DOWN
R=<A==2>			;POINTERS TO TABLES, CORE, ETC.
S=<B==3>
W=<C==4>			;CONTAINS DISPATCH ADDRESS IN WORD ASSEMBLER
T=5				;TRANSFER DATA
W1=6
W2=7
SCH=10				;MODE CONTROL SWITCH FOR OUTPUT
AR=11				;MODE CONTROL SWITCH FOR OUTPUT
ODF=12				;MODE CONTROL SWITCH FOR OUTPUT - CURRENT RADIX
TT=13				;TEMPORARY
TT1=14				;TEMPORARY
TT2=15				;TEMPORARY (USED FOR PTR INPUT ONLY)
				; AND FOR DTE COMMUNICATIONS

.XCREF	F, P, R, S, W, A, B, C, T, W1, W2, TT, TT1, TT2	;SAVE SOME PAPER

IFN	FTDEC20,<
T1=1
T2=2
T3=3
T4=4
P=17				;OVERRIDES P=1 ABOVE

.XCREF	T1, T2, T3, P	;SAVE SOME MORE PAPER
> ;END OF IFN FTDEC20

;DEFINE PUSHDOWN LIST LENGTH

	ND	LPDL,^D100	;100 WORDS IS ENOUGH FOR EVERYBODY

;DEFINE NUMBER OF DATA PAGES (MUST AGREE WITH MONITOR FOR MDDT)

	ND	NDDTPG,2	;HERE TO AVOID MACRO BUG WITH FORWARD REF BELOW
SUBTTL	GLOBAL SYMBOLS FOR USE BY THE OUTSIDE WORLD

IFE FTFILE,<			;FILDDT HAS NO GLOBAL SYMBOLS



  IFE FTMON,<			;DON'T CONFLICT MDDT WITH EDDT


	ENTRY	DDT		;DEFINE THE MAIN DDT START ADDRESS
				;USED ON "R DDT", "DDT$G", ETC.

    IFN FTEXEC,<
	ENTRY	DDTX		;ENTRY POINT USED BY MONITORS
				;ALSO ON TOPS-10 "DDT" MONITOR
				;COMMAND TO CLEAR $Y IN PROGRESS
    > ;END IFN FTEXEC

	INTERN	DDTEND		;END OF DDT, FOR USERS AND MONITOR


  > ;END IFE FTMON



  IFN FTDEC20,<			;TOPS-20 SPECIFIC DEFINITIONS


    IFN FTEX20,<		;TOPS-20 EDDT DEFINITIONS

	ENTRY	$EDDT		;FORCES LOADING OF EDDT IN LIB SEARCH
	$EDDT==0		;DON'T CARE ABOUT THE DEFINITION
    > ;END IFN FTEX20


    IFN FTMON,<			;TOPS-20 MDDT DEFINITIONS

	ENTRY	$MDDT		;FORCES LOADING OF MDDT IN LIBRARY SEARCH
	$MDDT==0		;DON'T CARE

	ENTRY	MDDTX		;MDDT EQUIVALENT OF DDTX
	MDDTX=DDTX

	EXTERN	DDTPGA		;MONITOR'S PLACE FOR MDDT'S VARIABLES
	EXTERN	.IMOPR		;INTERNAL MONITOR OPERATION SUBROUTINE

	INTERN	NDDTPG		;MUST AGREE WITH SPACE IN PSB

    > ;END IFN FTMON
  > ;END IFN FTDEC20
> ;END IFE FTFILE
SUBTTL	MEMORY ALLOCATION PARAMETERS

;THE FOLLOWING PARAMETERS CONTROL WHERE DDT GETS LOADED.

;RUNLOC		WHERE DDT'S CODE WILL GO AT RUNTIME.  IF NEGATIVE,
;		DDT'S CODE WILL START AT RELOCATABLE ZERO.  THIS
;		PARAMETER IS IGNORED IF FTMON OR FTEX20, SINCE THESE
;		FLAVORS OF DDT GO IN SPECIFIC PSECTS OF THE TOPS-20
;		MONITOR.
;
;VARLOC		WHERE DDT'S VARIABLES WILL GO AT RUNTIME.  IF
;		NEGATIVE, DDT'S VARIABLES WILL IMMEDIATELY
;		FOLLOW THE CODE.  IGNORED IF FTMON OR FTEX20.


;THE FOLLOWING VARIABLES DESCRIBE/REMEMBER DDT'S MEMORY LAYOUT

;BEG.C		THE FIRST LOCATION CONTAINING CODE
;END.C		THE LAST LOCATION CONTAINING CODE + 1
;LEN.C		THE LENGTH OF THE CODE (END.C-BEG.C)
;BEG.V		THE FIRST LOCATION CONTAINING VARIABLE STORAGE
;END.V		THE LAST LOCATION CONTAINING VARIABLE STORAGE + 1
;LEN.V		THE LENGTH OF THE VARIABLE AREA (END.V-BEG.V)
;PHVAR		THE LOCATION INSIDE THE CODE AREA WHERE A PURE
;		COPY OF THE VARIABLE AREA STARTS (MDDT ONLY).
;DDTBEG		THE LOWEST ADDRESS THAT IS PART OF DDT (FOR $$Z CODE)
;DDTEND		THE HIGHEST ADDRESS (+1) THAT IS PART OF DDT


;DEFAULT RUNLOC AND VARLOC

IFN	FTVMX,<
	ND	RUNLOC,700000	;VMDDT DEFAULT ORIGIN
>

IFN	FTDEC20&<^-FTEXEC>&<^-FTFILE>&<^-FTMON>,<
	ND	RUNLOC,770000	;TOPS-20 USER DDT'S DEFAULT ORIGIN
>

IFN	FTDEC20&<^-FTEXEC>&<^-FTFILE>&<^-FTMON>,<
	ND	VARLOC,RUNLOC-NDDTPG*1000	;ORIGIN OF -20 UDDT'S VARS
>

	ND	RUNLOC,-1	;DEFAULT TO RELOCATABLE IF NOT GIVEN
	ND	VARLOC,-1	; . . .
;SETUP TO ALLOCATE DDT'S CODE AT THE RIGHT PLACE

IFN	FTEX20,<
	.PSECT	INCOD		;-20 EDDT GOES IN INITIALIZATION CODE
> ;END IFN FTEX20


IFN	FTMON,<
	.PSECT	NRCOD		;-20 MDDT GOES IN NON-RESIDENT CODE
> ;END IFN FTMON


IFE	FTEX20!FTMON,<


  IFGE RUNLOC,<


    IFGE VARLOC,<
	.PSECT	DDTCOD/RONLY,RUNLOC	;READ-ONLY IF VARS GO ELSEWHERE
    > ;END IFGE VARLOC

    IFL VARLOC,<
	.PSECT	DDTALL/RWRITE,RUNLOC	;READ/WRITE IF WE GET VARS TOO
    > ;END IFL VARLOC
  > ;END IFGE RUNLOC


  IFL RUNLOC,<
	RELOC	0		;START AT RELOCATABLE 0 IF NO RUNLOC
  > ;END IFL RUNLOC
> ;END IFE FTEX20!FTMON


IFGE VARLOC,<IFGE RUNLOC,<IFL <VARLOC-RUNLOC>,<
;>>>	DDTBEG:!		;PUT DDTBEG HERE UNLESS SURE VARS ARE LOWER


BEG.C:!				;START OF CODE
DDTOFS:!			;OFFSET FOR COMMAND DISPATCH
SUBTTL	MISCELLANEOUS DDT SYMBOLS

;ASSEMBLY CONSTANTS

ND	PAGSIZ,1000		;"BLOCK" SIZE OF LOGICAL DISK/MEMORY ALLOCATION
	PAGMSK==PAGSIZ-1	;"AND" TO MASK TO ADDRESS WITHIN PAGE
	PG2WRD==^D36-^L<PAGSIZ-1>  ;"LSH" FOR PAGE TO WORD ADDRESS
	WRD2PG==-PG2WRD		;"LSH" FOR WORD TO PAGE ADDRESS

ND	BLKSIZ,200		;"BLOCK" SIZE OF PHYSICAL DISK ALLOCATION
	BLKMSK==BLKSIZ-1	;"AND" TO MASK TO ADDRESS WITHIN BLOCK
	BL2WRD==^D36-^L<BLKSIZ-1>  ;"LSH" FOR BLOCK TO WORD ADDRESS
	WRD2BL==-BL2WRD		;"LSH" FOR WORD TO BLOCK ADDRESS

	PG2BLK==PG2WRD-BL2WRD	;"LSH" FOR PAGE TO BLOCK ADDRESS
	BLK2PG==-PG2BLK		;"LSH" FOR BLOCK TO PAGE ADDRESS

ND	NBP,^D12		;NUMBER OF BREAKPOINTS
ND	NSAVTB,^D17		;NUMBER OF PC'S IN RING BUFFER ($<CR> ETC.)
ND	SKPMAX,3		;MAX NUMBER OF SKP'S IN $X LOGIC
ND	INDPTH,100		;MAX NESTING IN $E SEARCHES
ND	ADRNGE,1000		;ADDRESS RANGE FOR SYMBOL+VALUE TYPEOUT

IFN	FTFILE,<ND SCSIZ,^D200>	;SIZE OF SYMBOL TABLE CACHE FOR FILDDT
IFE	FTFILE,<ND SCSIZ,^D100>	; ALL OTHER DDTS
;ADDRESS (PAGE) ACCESS BIT DEFINITIONS

IFN	FTDEC10,<
	PG$EXI==PA.GNE		;PAGE EXISTS
	PG$REA==PA.GRD		;PAGE CAN BE READ
	PG$WRT==PA.GWR		;PAGE CAN BE WRITTEN
	PG$HGH==PA.GHI		;PAGE IS PART OF HIGH SEGMENT
	PG$SPY==PA.GSP		;PAGE IS ACTUALLY SPYING ON SOMEONE
	PG$ABZ==1B17		;PAGE IS ALLOCATED BUT ZERO
> ;END OF IFN FTDEC10

IFN	FTDEC20,<
	PG$EXI==PA%PEX		;PAGE EXISTS
	PG$REA==PA%RD		;PAGE CAN BE READ
	PG$WRT==PA%WT!PA%CPY	;PAGE CAN BE WRITTEN
	PG$HGH==0		;NONSENSE BIT
	PG$SPY==0		;NONSENSE BIT
	PG$ABZ==1B17		;PAGE IS ALLOCATED BUT ZERO
> ;END OF IFN FTDEC20



;PC BITS OF INTEREST

IFN	FTDEC10,<
	PC$AFI==PC.AFI		;ADDRESS FAILURE INHIBIT
> ;END IFN FTDEC10

IFN	FTDEC20,<
	PC$AFI==PC%AFI		;ADDRESS FAILURE INHIBIT
> ;END IFN FTDEC20



;TERMINAL CONTROL (IN TTYMSK, N$1M COMMAND)

;LEFT HALF BITS, PRESERVED AND SET ONLY BY USER

	TT$SPC==1B17		;3 SPACES OR TAB (0=SPACES, 1=TAB)
				; (CONTROLS ONLY TTAB; TEXT OUTPUT OK)

;RIGHT HALF BITS, SET AUTOMATICALLY ON USER DDT ENTRY (NOT APPLICABLE
;TO TOPS-20), PRESERVED IN EXEC DDT (WHERE THEY MUST MANUALLY BE SET).

	TT$TAB==1B34		;TAB CAPABILITY
				; (IF 1 THEN TERMINAL HANDLES TABS)
	TT$DEL==1B35		;FANCY DELETE HANDLING
				; (IF 1 THEN <BS><SP><BS>)
;FOR MONITOR DDT ONLY

IFN FTMON,<

ND	SYWLEN,1000		;SIZE (EVEN PAGES) OF SYMBOL WINDOW
SYWMSK==SYWLEN-1		;MASK FOR ABOVE

> ;END IFN FTMON


;FOR FILE DDT ONLY

IFN	FTFILE,<
FIL==1				;PRIMARY FILE I/O CHANNEL

ND	WINMAX,^D20		;PAGE "CACHE" SIZE - PAGES KEPT IN CORE
ND	MEXSIZ,^D512*^D32	;MAX PAGES IN REASONABLE .EXE FILE

;.EXE DIRECTORY INFORMATION

SV$HIS==SV%HIS			;PAGE IS PART OF HIGH SEGMENT
SV$MOD==1B17			;PAGE HAS BEEN MODIFIED (WINDIR BIT)
SV$FPN==777,,777777		;FILE PAGE NUMBER MASK

;************************************************************
;
;	TEMP DEFS TIL UNIVERSALS HAVE THEM INCORPORATED
;
;************************************************************

IFN	FTDEC10,<		;SOME TOPS-10 STUFF
> ;END OF TOPS-10 STUFF

IFN	FTDEC20,<		;AND SOME TOPS-20 STUFF
.SVDIR==1776			;EXE DIRECTORY HEADER TYPE
SV%HIS==1B0			;EXE DIRECTORY - PAGE IS HISEG PAGE
> ;END OF FTDEC20 STUFF
> ;END OF IFN FTFILE
;*** FLAGS IN F ***

FEF==	1B0			;"E" FLAG
COMF==	1B1			;COMMA TYPED
TIF==	1B2			;TRUNCATE TO 18 BITS - SET BY SPACE OR COMMA
DVF==	1B3			;DIVIDE
FPF==	1B4			;"." TYPED
CCF==	1B5			;"$$" TYPED
STF==	1B6			;SUPPRESS TYPEOUT
SAF==	1B7			;RIGHT ANGLEBRACKET TYPED
FAF==	1B8			;LEFT ANGLEBRACKET TYPED
SPF==	1B9			;SPACE TYPED (USED BY CEFFAD)
MLF==	1B10			;MULTIPLY
PTF==	1B11			;ARITHMETIC OPERATOR TYPED
CF==	1B12			;"$" TYPED
LTF==	1B13			;LETTER TYPED IN CURRENT SYLLABLE
ROF==	1B14			;REGISTER OPEN
SF==	1B15			;SYLLABLE
MF==	1B16			;MINUS SIGN TYPED
QF==	1B17			;QUANTITY TYPED IN TO WORD ASSEMBLER

; 18-19 NOT USED
TXF==1B20			;IN TEXT ([$]"/---/) COMMAND
USYMF==1B21			;R POINTS TO THE UNDEFINED SYMBOL TABLE
MDLCLF==1B22			;MULT DEF LOCAL SYMBOL (EVAL)
PNAMEF==1B23			;PROGRAM NAME SEEN IN SYM TABLE SEARCH
POWF==	1B24			;ARGUMENT FOR EXPONENT COMING
LF1==	1B25			;OUTPUT ONE REGISTER IN FORCED MODE
OLF==	1B26			;OUTSIDE LOCAL FLAG IN LOOK
CF1==	1B27			;OUTPUT ONE REGISTER AS CONSTANT
NAF==	1B28			;NEGATIVE ADDRESSES PERMISSABLE
FANYSF==1B29			;EVAL OR LOOK HAS FOUND A SYMBOL
OPTRYF==1B30			;WE'RE TRYING TO DECODE A SYMBOLIC OPCODE
HSYMF==	1B31			;R POINTS TO HISEG SYMBOL TABLE
OKAF==	1B32			;[240] OK AMBIGUOUS (LOOK ROUTINE)
OUTF==	1B33			;OUTPUT
ITF==	1B34			;INSTRUCTION TYPED
Q2F==	1B35			;NUMBER TYPED AFTER $

;DEFINE SYMBOL TABLE SYMBOL TYPES
GLOBL==	04B5			;GLOBAL SYMBOL
LOCL==	10B5
PNAME==	74B5			;PROGRAM NAME
DELI==	20B5			;DELETE INPUT
DELO==	40B5			;DELETE OUTPUT

;DEFINE UNDEFINED SYMBOL TABLE (.JBUSY) TYPES

STADD==	1B0			;IF 1, THEN ADDITIVE REQUEST
STLH==	1B1			;IF 1, THEN REQUEST FOR LEFT HALF
STNEG==	1B4			;IF 1, THEN NEGATIVE REQUEST
;RANDOM SYMBOL DEFINITIONS FOR TOPS-10

IFN	FTDEC10,<

IFN	FTEXEC!FTFILE,<
	XZLOW==40
> ;END IFN FTEXEC!FTFILE

ZLOW==140

;THE FSBLK BITS

FS$SWT==1B0		;SWITCH SPECIFIED
FS$DEV==1B2		;DEVICE SPECIFIED
FS$NAM==1B3		;FILENAME SPECIFIED
FS$EXT==1B4		;EXTENSION (FILE TYPE) SPECIFIED
FS$PTH==1B5		;DIRECTORY PATH SPECIFIED

FS$FIL==FS$DEV!FS$NAM!FS$EXT!FS$PTH  ;FILE SPEC WAS SPECIFIED


;I/O CHANNELS

IFN	FTYANK,<CM==17	;I/O CHANNEL TO READ COMMAND FILES
ND	YBFSIZ,203	;SIZE OF [INTERNAL] BUFFER FOR COMMAND FILES
> ;END IFN FTYANK

INTERNAL .JBDDT
.JBDDT=74

IFE	FTFILE!FTVMX,<
	LOC	.JBDDT
	XWD	DDTEND,DDTX
	RELOC
>
> ;END OF IFN FTDEC10
;RANDOM SYMBOL DEFINITIONS FOR TOPS-20

IFN	FTDEC20,<

	ZLOW==20		;START ZEROING ABOVE ACS

> ;END IFN FTDEC20
SUBTTL	FILDDT -- COMMAND SCANNER

IFN	FTFILE,<

;CODE COMMON TO ALL FLAVORS OF FILE DDTS

IFN	FTDBUG,<DEBDDT:>

DDT:	JFCL			;IN CASE OF CCL ENTRY
	MOVE	P,[IOWD LPDL,PDL]  ;PRESET PUSH DOWN LIST
IFN	FTYANK,<SETZM COMAND>	;[236] CLEAR $Y FLAG
	SETZM	MAPFN		;CLEAR $U POINTERS
	SETOM	EPTWRD		;CLEAR OTHER PAGING POINTERS
	SETOM	UPTWRD		; . . .
	SETOM	SPTWRD		; . . .
	SETOM	CSTWRD		; . . .
	SETZM	FAKEAC		;ASSUME TRUE 0 - 17
	SETZM	PATCHS		;PATCHING NOT LEGAL
	SETOM	LASTPG		;WE KNOW NOTHING ABOUT ANY PAGE
	SETZM	FWAZER		;CLEAR BLOCK OF STORAGE
	MOVE	T,[FWAZER,,FWAZER+1]
	BLT	T,LWAZER-1
	SETOM	FWAONE		;"CLEAR" BLOCK OF STORAGE
	MOVE	T,[FWAONE,,FWAONE+1]  ;BLT POINTER TO
	BLT	T,LWAONE-1	;INITIALIZE WINDOW POINTERS ET AL
	PUSHJ	P,CLRCSH	;ZERO OUT THE SYMBOL TABLE CACHE


;FALL INTO OPERATING-SYSTEM DEPENDENT STARTUP CODE
;STILL FTFILE

IFN	FTDEC10,<		;TOPS-10 STYLE COMMAND SCANNING

;SCAN COMMAND LINE AND FIGURE OUT WHAT TO DO
;NOTE THAT WE FALL HERE FROM FILDDT STARTUP

FDIFS:	RESET			;STOP THE WORLD
	MOVX	W1,.TODIS	;TERMINAL-IS-A-DISPLAY FUNCTION
	SKIPN	W2,TTDEV	;GOT AN $Y'ED TERMINAL?
	SETO	W2,		;NO, USE CONTROLLING TERMINAL
	MOVE	T,[2,,W1]	;TRMOP. ARG POINTER TO
	TRMOP.	T,		;READ DISPLAY SETTING
	 SETZ	T,		;DUH?
	DPB	T,[POINTR TTYMSK,TT$DEL]  ;SET <DEL> HANDLING
	MOVEI	T,1		;USER MODE TAB SUPPORT
	DPB	T,[POINTR TTYMSK,TT$TAB]  ;SET <TAB> LITERAL MODE

;NOW READ IN WHAT USER WANTS US TO DO

	TMSG	<File: >	;PROMPT USER FOR FILE SPEC
	MOVEI	S,FDISWT	;FILDDT SWITCH TABLE
	PUSHJ	P,FSCAN		;INPUT FILE SPEC ET ALL
	  JRST	FDIERR		;ERROR, MESSAGE ALREADY ISSUED
	SKIPN	TT,FSBLK	;ANYTHING EXCITING HAPPEN?
	JRST	FDIFS		;NO, TRY AGAIN
	SKIPE	FDIFSW		;/F SPECIFIED?
	TXNE	TT,FS$FIL	;SEE A FILE SPEC (ANY PORTION THEREOF)?
	CAIA			;YES, THEN OK
	 JRST	FDEENF		;NO, NULL FILE SPEC ILLEGAL WITH /F
	MOVE	T,FDIDSW	;SEE IF /D
	IOR	T,PHYSIO	;OR /U
	JUMPE	T,FDIFS2	;/D .OR. /U
	SKIPE	SYMGET		;.AND. /S ???
	 JRST	FDEEDS		;YES, ILLEGAL COMBINATION
FDIFS2:	SKIPE	JOBING		;/J?
	SETOM	FDIMSW		;YES, PRETEND /M
	MOVE	T,FDIDSW	;/D?
	IOR	T,FDIFSW	;OR /F
	IOR	T,SYMGET	;OR /S
	IOR	T,PHYSIO	;OR /U
	JUMPE	T,FDIFS4	;/D .OR. /F .OR. /S .OR. /U
	SKIPE	FDIMSW		;.AND. /M ???
	 JRST	FDEERM		;YES, ILLEGAL COMBINATION
FDIFS4:	SKIPN	FDIMSW		;/M SPECIFIED?
	 JRST	FDIDF		;NO, FILING OF SOME SORT

;FALL INTO MONITOR/MEMORY PEEKING INITIALIZATION
;STILL FTFILE & FTDEC10

;FALL HERE FROM PREVIOUS PAGE

;INITIALIZE FOR PEEKING AT RUNNING MONITOR/MEMORY

FDIDM:	SETZM	FILING		;NOTE NO FILE'ING IN PROGRESS
	SETOM	FAKEAC		;NEVER ANY MONITOR "ACS" FOR /M
	SETZM	AC0		;IT IS NICER TO GIVE 0'S
	MOVE	T,[AC0,,AC0+1]	;BLT POINTER TO
	BLT	T,AC17		;INITIALIZE MONITOR ACS
	MOVX	T,%NSMMS	;ASK FOR MEMORY SIZE
	SKIPN	JOBING		;/J?
	GETTAB	T,		;NO, MONITOR
	 MOVSI	T,1		;REASONABLE DEFAULT
	MOVEM	T,MAXSIZ	;SAVE FOR LATER CHECKING
	SKIPN	JOBING		;/J AGAIN?
	JRST	DD1		;NO, GO START THINGS OFF
	SETZ	TT,		;INITIALIZE JOB NUMBER
	MOVE	TT2,FSFIL	;JOB NUMBER (IN SIXBIT)
FDIDJ:	SETZ	TT1,		;MAKE READY FOR
	LSHC	TT1,6		;NEXT DIGIT
	IMULI	TT,^D10		;JOB NUMBERS ARE DECIMAL
	ADDI	TT,-'0'(TT1)	;THIS DECADE
	JUMPN	TT2,FDIDJ	;LOOP
	JUMPE	TT,FDEERJ	;0 IS ILLEGAL JOB NUMBER
	MOVX	TT1,%CNSJN	;SEGMENT/JOB NUMBERS
	GETTAB	TT1,		;-SEGN,,JOBN
	 MOVEI	TT1,^D511	;DEFAULT JOBN
	CAILE	TT,(TT1)	;REASONABLE JOB NUMBER?
	JRST	FDEERJ		;NO, ERROR
	MOVEM	TT,JOBING	;YES, REMEMBER IT
	JRST	DD1		;GO START UP NOW
;HERE FOR SOME TYPE OF (DISK) FILE I/O

FDIDF:	SKIPN	PHYSIO		;/U?
	 JRST	FDIDF3		;NO, REGULAR

;DEFAULTS FOR PHYSICAL UNIT I/O

	SETOM	FDIDSW		;YES, FORCE PURE DATA FORMAT
	SKIPN	FSDEV		;EXPLICIT STRUCTURE SUPPLIED?
	 JRST	FDEERU		;NO, ERROR
	JRST	FDIDF6		;CONTINUE WITH SETUP

;HERE FOR REGULAR FILE DEFAULTING

FDIDF3:	MOVSI	T,'DSK'		;DEFAULT INPUT DEVICE
	SKIPN	FSDEV		;USER GIVE A DEVICE?
	 MOVEM	T,FSDEV		;NO, SUPPLY DEFAULT
	SKIPN	FSFIL		;HOW ABUT A FILENAME?
	 JRST	FDENFI		;NULL FILENAME ILLEGAL
	SKIPE	FDIDSW		;/D?
	 JRST	FDIDF6		;YES, NO DEFAULT EXTENSION
	MOVSI	T,'EXE'		;DEFAULT EXTENSION
	SKIPN	FSEXT		;USER TYPE AN EXTENSION?
	 HLLOM	T,FSEXT		;NO, USE DEFAULT
;STILL FTFILE & FTDEC10

;INITIALIZE FOR FILE I/O

FDIDF6:	MOVEI	T,[FLPLEN,,FLPBLK  ;LEN,,ADR OF FILOP. BLOCK
		   LKPLEN,,LKPBLK  ;LEN,,ADR OF LOOKUP BLOCK
		   PTHLEN,,PTHBLK] ;LEN,,ADR OF PATH BLOCK
	PUSHJ	P,FSFSET	;INITIALIZE FILOP. BLOCK
	 HALT	DDT		;INTERNAL ERROR
	MOVEI	T,.FORED	;ASSUME WANT TO READ FILE
	SKIPE	PATCHS		;WANT TO WRITE AS WELL?
	MOVEI	T,.FOSAU	;YES, SINGLE ACCESS UPDATE THEN
	SKIPE	PHYSIO		;BUT WAIT - /U?
	MOVEI	T,.FOSIO	;YES, THEN REALLY WANT SUPER I/O
	HRLI	T,400000+FIL	;SLIP IN THE CHANNEL NUMBER
	MOVEM	T,FLPBLK+.FOFNC	;SETUP FUNCTION WORD
	MOVEI	T,.IODMP	;DUMP MODE I/O
	MOVEM	T,FLPBLK+.FOIOS	;SETUP I/O STATUS WORD
	MOVE	T,[FLPLEN,,FLPBLK]  ;ADDRESS OF FILOP. BLOCK TO
	FILOP.	T,		;GET AN INPUT FILE
	 JRST	FDIDF9		;ERROR
	MOVEI	T,FIL		;INPUT FILE CHANNEL
	DEVCHR	T,		;ASK ABOUT WHAT WE GOT
	TXNN	T,DV.DSK	;IS IT A DISK?
	JRST	NOTDSK		;NO, ERROR
	MOVE	T,LKPBLK+.RBSIZ	;FILE SIZE, IN WORDS
	MOVEM	T,MAXSIZ	;SET MAX SIZE ALLOWABLE
	JRST	FDIOPN		;GO PROCESS

;HERE ON FILOP. ERROR

FDIDF9:	SKIPE	PHYSIO		;/U?
	 PUSHJ	P,[CAIE	T,ERILU%	;"ILLEGAL UUO" ?
		POPJ	P,		;NO, THEN REAL ERROR
		OPEN	FIL,FLPBLK+.FOIOS ;YES, DO IT THE OLD WAY
		 JRST	[MOVEI	T,ERILU%  ;WHAT THE HEX
			POPJ	P,]	;RETURN WITH ERROR CODE
		POP	P,T		;ADJUST STACK
		JRST	FDIOPN]		;HANDLE OPEN FILE
	JRST	FDEFFF		;REAL FILOP. ERROR
;STILL FTFILE & FTDEC10

;FILDDT SWITCH TABLE

FDISWT:	JRST	FSEILS		;A - ILLEGAL
	JRST	FSEILS		;B - ILLEGAL
	JRST	FSEILS		;C - ILLEGAL
	SETOM	FDIDSW		;D - DATA FORMAT
	JRST	FSEILS		;E - ILLEGAL
	SETOM	FDIFSW		;F - FILDDT IT ANYWAY (WITH /S)
	JRST	FSEILS		;G - ILLEGAL
	JRST	FDIHLP		;H - HELP
	JRST	FSEILS		;I - ILLEGAL
	SETOM	JOBING		;J - LOOK AT A USER JOB
	JRST	FSEILS		;K - ILLEGAL
	JRST	FSEILS		;L - ILLEGAL
	SETOM	FDIMSW		;M - LOOK AT RUNNING MONITOR
	JRST	FSEILS		;N - ILLEGAL
	JRST	FSEILS		;O - ILLEGAL
	SETOM	PATCHS		;P - ENABLE PATCHING
	JRST	FSEILS		;Q - ILLEGAL
	JRST	FSEILS		;R - ILLEGAL
	SETOM	SYMGET		;S - EXTRACT SYMBOL TABLE
	JRST	FSEILS		;T - ILLEGAL
	SETOM	PHYSIO		;U - SUPER IO TO DISK UNITS
	JRST	FSEILS		;V - ILLEGAL
	JRST	FSEILS		;W - ILLEGAL
	JRST	FSEILS		;X - ILLEGAL
	JRST	FSEILS		;Y - ILLEGAL
	JRST	FSEILS		;Z - ILLEGAL
;STILL FTFILE & FTDEC10

FDIHLP:	TMSG	<
Type  dev:file.ext[path]/switches

/D	Treat file as pure binary data, not code
/F	FILDDT this file anyway (used with /S)
/H	Type this text
/M	Examine running monitor
/P	Patch monitor or file
	type ^Z to exit from file patching
/S	Load symbol table from file
/U	Physical ("super") I/O to disk unit

If nothing typed then "/M" is defaulted

>				;GIVE A HELP MESSAGE
	JRST	DDT		;RESET AND SCAN AGAIN


;GENERAL FILE DDT COMMAND ERRORS

FDEEDS:	TMSG	<? /S illegal with /D or /U>
	JRST	FDEERR

FDEENF:	TMSG	<? Null file spec with /F>
	JRST	FDEERR

FDEERU:	TMSG	<? Explicit structure required with /U>
	JRST	FDEERR		;COMMON ERROR EXIT

FDEERM:	TMSG	<? /M illegal with /D, /F, /S, or /U>
	JRST	FDEERR

FDEERJ:	TMSG	<? Illegal job number>
	JRST	FDEERR


;FILE DDT ERROR MESSAGES DUPLICATED IN FSCAN

FDENFI:	PUSHJ	P,FSENFI	;COMPLAIN
	JRST	FDIERR		;GO CLRBFI

FDEFFF:	PUSHJ	P,FSEFFF	;COMPLAIN
	JRST	FDIERR		;CLRBFI AND RESTART DDT
> ;END OF IFN FTDEC10
;STILL FTFILE

IFN	FTDEC20,<		;FILE SELECTION FOR TOPS-20

NCHPW==5		;NUMBER OF ASCII CHARACTERS PER WORD
BUFSIZ==200		;SIZE OF INPUT TEXT BUFFER
ATMSIZ==BUFSIZ		;SIZE OF ATOM BUFFER FOR COMND JSYS
GJFSIZ==.GJRTY+2	;SIZE OF GTJFN BLOCK USED BY COMND JSYS
FDBSIZ==.CMDEF+2	;SIZE OF FUNCTION DESCRIPTOR BLOCK
;STILL FTFILE & FTDEC20

;SCAN COMMAND LINE AND FIGURE OUT WHAT TO DO
;NOTE THAT WE FALL HERE FROM FILDDT STARTUP

CPARS:	MOVEI	T1,677777		;MAXIMUM SIZE WE WANT TO USE
	MOVEM	T1,.JBREL		;SAVE FOR TESTS
	HRROI	T1,PROMPT		;GET POINTER TO PROMPT STRING
	MOVEM	T1,CMDBLK+.CMRTY	;SAVE IN STATE BLOCK
	HRROI	T1,BUFFER		;GET POINTER TO INPUT TEXT BUFFER
	MOVEM	T1,CMDBLK+.CMPTR	;SAVE POINTER TO COMMAND STRING
	MOVEM	T1,CMDBLK+.CMBFP	;SAVE POINTER TO START-OF-BUFFER
	MOVE	T1,[.PRIIN,,.PRIOU]	;GET PRIMARY INPUT,, OUTPUT JFN'S
	MOVEM	T1,CMDBLK+.CMIOJ	;SAVE PRIMARY JFN'S
	SETZM	CMDBLK+.CMINC		;INITIALIZE # OF CHARS AFTER POINTER
	MOVEI	T1,BUFSIZ*NCHPW		;GET # OF CHARS IN BUFFER AREA
	MOVEM	T1,CMDBLK+.CMCNT	;SAVE INITIAL # OF FREE CHAR POSITIONS
	HRROI	T1,ATMBFR		;GET POINTER TO ATOM BUFFER
	MOVEM	T1,CMDBLK+.CMABP	;SAVE POINTER TO LAST ATOM INPUT
	MOVEI	T1,ATMSIZ*NCHPW		;GET # OF CHARACTERS IN ATOM BUFFER
	MOVEM	T1,CMDBLK+.CMABC	;SAVE COUNT OF SPACE LEFT IN ATOM BUFFER
PARSE:	HRROI	T1,PROMPT		;GET POINTER TO PROGRAM'S PROMPT STRING
	PUSHJ	P,CMDINI		;OUTPUT THE PROMPT

PARSE1:	MOVE	P,[IOWD LPDL,PDL]	;SET UP STACK AGAIN
	RESET				;CLEAR EVERYTHING
	SETZM	FCMZER			;ZERO VARIABLES IN CASE OF ERROR
	MOVE	T1,[FCMZER,,FCMZER+1]	;  SINCE SOME ROUTINES SET VALUES
	BLT	T1,LWAZER-1		;  THEN DISCOVER ERRORS

	MOVEI	T1,GJFBLK		;GET ADDRESS OF GTJFN BLOCK
	MOVEM	T1,CMDBLK+.CMGJB	;STORE POINTER TO GTJFN BLOCK
	MOVEI	T1,CMDBLK	;GET POINTER TO COMMAND STATE BLOCK
	MOVEI	T2,[FLDDB. (.CMKEY,,CMDTAB)]	;GET FUNCTION BLOCK
	COMND%			;DO INITIAL PARSE
	TXNN	T1,CM%NOP	;VALID COMMAND ENTERED ?
	JRST	PARSE5		;YES, GO DISPATCH TO PROCESSING ROUTINE
	HRROI	T1,[ASCIZ\No such command as\]
	PUSHJ	P,TYPATM	;COMPLAIN
	JRST	PARSE		;GO TRY TO GET A COMMAND AGAIN

PARSE5:	HRRZ	T1,(T2)		;GET DISPATCH ADDRESS
	PUSHJ	P,(T1)		;PERFORM REQUESTED FUNCTION
	JRST	PARSE		;GO PARSE NEXT COMMAND
;STILL FTFILE & FTDEC20

; HELP COMMAND

.HELP:	HRROI	T2,[ASCIZ/WITH FILDDT/]	;GET NOISE WORDS
	PUSHJ	P,SKPNOI	;GO PARSE NOISE FIELD
	 POPJ	P,		;FAILED, RETURN FAILURE
	PUSHJ	P,ENDCOM	;GO PARSE END OF COMMAND
	 POPJ	P,		;BAD CONFIRMATION, RETURN
	HRROI	T1,HLPMSG	;GET POINTER TO HELP MESSAGE
	PSOUT%			;OUTPUT HELP MESSAGE
	POPJ	P,		;GO PARSE NEXT COMMAND

; EXIT COMMAND

.EXIT:	HRROI	T2,[ASCIZ/TO MONITOR/]	;GET NOISE PHRASE
	PUSHJ	P,SKPNOI	;GO PARSE NOISE FIELD
	 POPJ	P,		;FAILED, RETURN FAILURE
	PUSHJ	P,ENDCOM	;GO PARSE END OF COMMAND
	 POPJ	P,		;BAD CONFIRMATION, RETURN
	RESET%			;CLEAN UP
	HALTF%			;BACK TO MONITOR
	JRST	DDT		;GO GET ANOTHER COMMAND

; PEEK COMMAND

.PEEK:	HRROI	T2,[ASCIZ /AT RUNNING MONITOR/]
	PUSHJ	P,SKPNOI	;TELL HIM
	 POPJ	P,
	PUSHJ	P,ENDCOM	;GET CR
	 POPJ	P,		;ERROR
	SKIPN	PATCHS		;DOES USER WANT TO PATCH THE MONITOR?
	JRST	PEEK2		;NO
	TMSG	<% Patching the running monitor is illegal
>				;YES, WARN THE USER
	SETZM	PATCHS		;FOR SAFETY
PEEK2:	SETZM	FILING		;NO FILE
	MOVX	T1,.INFIN	;NO ARTIFICAL RESTRICTIONS ON ADDRESSES
	MOVEM	T1,MAXSIZ	;SINCE PEEK JSYS WILL TELL US
	SETOM	FAKEAC		;USE ARTIFICIAL ACS
	SETZM	AC0		;IT'S BETTER TO GIVE HIM 0
	MOVE	T1,[AC0,,AC0+1]	;THAN OLD JUNK
	BLT	T1,AC0+17	; . . .
	JRST	FDIGO		;GO TO IT
;STILL FTFILE & FTDEC20

.GET:	HRROI	T2,[ASCIZ 'FILE']
	PUSHJ	P,SKPNOI
	 POPJ	P,
	SKIPN	FDIDSW		;DATA FILE?
	JRST	GET01		;NO, GO DEFAULT TO .EXE
	SETZM	GJFBLK+.GJEXT	;DATA FILES HAVE NO FILE DEFAULTS
	JRST	GET02		;OK, GO OPEN THE FILE
GET01:	HRROI	T1,[ASCIZ 'EXE']	;DEFAULT EXTENSION
	MOVEM	T1,GJFBLK+.GJEXT	;STORE FOR COMND
GET02:	SETZM	SYMGET		;INDICATE GET, NOT LOAD


;LOAD COMMAND ENTERS HERE TO OPEN THE FILE, WITH SYMGET SET TO -1

GET03:	MOVX	T1,GJ%OLD
	MOVEM	T1,GJFBLK+.GJGEN
	MOVEI	T1,CMDBLK
	MOVEI	T2,[FLDDB. (.CMFIL)]
	COMND%
	TXNN	T1,CM%NOP	;SPEC OK?
	JRST	GET10
	PUSHJ	P,TSTCOL	;SEE IF CRLF NEEDED
	TMSG	<? Invalid file specification, >
	PJRST	PUTERR		;OUTPUT ERROR STRING TO TERMINAL

GET10:	HRRZM	T2,FILJFN	;SAVE FILE JFN FOR LATER USE
	SKIPE	SYMGET		;LOAD OR GET COMMAND?
	SKIPA	T2,[CFMBLK]	;DON'T ALLOW SWITCHES ON LOAD
GET20:	MOVEI	T2,SWTBLK	;NOW ASK FOR SWITCHS OR EOL
	COMND%			;ASK THE USER
	TXNE	T1,CM%NOP	;DID IT WORK?
	JRST	CFMERR		;NO, GO COMPLAIN
	HRRZ	T3,T3		;ADDRESS OF BLOCK COMND FOUND
	CAIN	T3,CFMBLK	;EOL OR SWITCH?
	JRST	GET30		;EOL, GO PROCESS
	HRRZ	T2,(T2)		;GET SWITCH PROCESSING ADDRESS
	PUSHJ	P,(T2)		;CALL PROCESSING ROUTINE
	JRST	GET20		;LOOP FOR MORE SWITCHES
;STILL FTFILE & FTDEC20

;HERE WHEN THE LINE HAS BEEN SCANNED. CHECK SEMANTICS AND OPEN THE FILE.

GET30:	HRROI	T1,NAMBUF	;STORE FILE-SPEC
	MOVE	T2,FILJFN	;RETRIEVE JFN OF USER'S FILE
	MOVEI	T3,0
	JFNS%
	MOVE	T1,FILJFN	;JFN OF FILE USER TYPED
	DVCHR%			;FIND OUT ABOUT IT
	HLRZ	T1,T1		;GET DEVICE TYPE CODE
	CAIE	T1,.DVDES+.DVDSK	;IS THIS A DISK DEVICE?
	PJRST	NOTDSK		;NO, COMPLAIN AND RETURN
	MOVE	T1,FILJFN	;SETUP JFN TO OPEN
	SKIPN	FDIFSW		;USE PATCHS IF GET /S
	SKIPN	SYMGET		;ALWAYS READ-ONLY IF LOADING SYMBOLS
	SKIPN	PATCHS		;WANT PATCHING?
	SKIPA	T2,[OF%RD]	;NO, SET UP TO READ
	MOVX	T2,OF%RD!OF%WR	;YES, SET UP TO WRITE
	OPENF%			;OPEN USER'S FILE
	ERJMP	PUTERQ		;FAILED, COMPLAIN TO USER
	MOVX	T1,^D512*^D512*^D512	;MAX LONG FILE SIZE ON TOPS-20
	MOVEM	T1,MAXSIZ	;GIVE ERROR BEYOND (MONITOR WRAPS AROUND)
	JRST	FDIOPN		;ALL OPEN


;SWITCH PROCESSING ROUTINES (SOME SAME AS ENABLE KEYWORD ROUTINES)

.SYMBL:	SETOM	SYMGET		;READ THE SYMBOLS FROM THIS FILE
	SETOM	FDIFSW		;BUT READ IT IN ANYWAY
	POPJ	P,
;STILL FTFILE & FTDEC20

.LOAD:	HRROI	T2,[ASCIZ 'SYMBOLS FROM']
	PUSHJ	P,SKPNOI
	 POPJ	P,
	HRROI	T1,[ASCIZ 'EXE']
	MOVEM	T1,GJFBLK+.GJEXT	;DEFAULT EXTENSION IS EXE
	SETOM	SYMGET		;FLAG SYMBOL GET
	JRST	GET03		;JOIN COMMON CODE

.ENBLE:	MOVEI	T1,CMDBLK
	MOVEI	T2,[FLDDB. (.CMKEY,,KEYTAB)]
	COMND%
	TXNN	T1,CM%NOP
	JRST	ENAB10
	HRROI	T1,[ASCIZ \No keyword\]
	PJRST	TYPATM		;ILLEGAL KEYWORD, GO COMPLAIN

ENAB10:	PUSH	P,T2		;SAVE INDEX
	PUSHJ	P,ENDCOM
	 JRST	[POP P,T1
		POPJ P,]		;ERROR RETURN
	POP	P,T2		;RESTORE INDEX
	HRRZ	T1,(T2)		;GET DISPATCH
	JRST	(T1)		;GO DO IT

.PATCH:	SETOM	PATCHS		;SET PATCHING
	POPJ	P,

.DATA:	SETOM	FDIDSW		;SET DATA FILE
	POPJ	P,
;STILL FTFILE & FTDEC20

;PHYSICAL/SUPER I/O COMMANDS

.STRUC:	HRROI	T2,[ASCIZ 'FOR PHYSICAL I/O IS']
	PUSHJ	P,SKPNOI	;TELL USER WE WANT A STRUCTURE NAME
	  POPJ	P,
	MOVEI	T2,[FLDDB. (.CMDEV)]	;GET A DEVICE
	COMND%
	TXNE	T1,CM%NOP	;GET SOMETHING?
	JRST	PUTERQ		;NO, COMPLAIN
	MOVEM	T2,PHYSTR	;YES, STORE DESIGNATOR FOR DSKOP
	PUSHJ	P,ENDCOM	;CLOSE OFF COMMAND LINE
	  POPJ	P,		;ERROR, GIVE UP
	HLRZ	T1,PHYSTR	;GET DEVICE TYPE
	CAIE	T1,.DVDES+.DVDSK	;A DISK?
	PJRST	NOTDSK		;NO, GO COMPLAIN
	MOVX	T1,FLD(.DOPSR,DOP%AT)!DOP%SN
	MOVEM	T1,PHYSIO	;SET ARB STRUCTURE DSKOP ARG
	SETOM	FDIDSW		;FORCE DATA-FILE (NOT EXE)
	JRST	FDIOPN		;GO SETUP TO DO PHYSICAL I/O


.DRIVE:	HRROI	T2,[ASCIZ 'FOR PHYSICAL I/O IS ON CHANNEL']
	PUSHJ	P,SKPNOI	;TELL USER WHAT WE WANT
	  POPJ	P,		;ERROR
	MOVEI	T2,[FLDDB. (.CMNUM,,8)]
	COMND%			;PARSE AN OCTAL NUMBER
	TXNE	T1,CM%NOP	;ERROR?
	JRST	PUTERQ		;YES, GO COMPLAIN
	HRLZM	T2,PHYSTR	;STORE CHANNEL TEMPORARILY
	HRROI	T2,[ASCIZ 'UNIT']
	PUSHJ	P,SKPNOI	;WE NOW WANT A UNIT
	  POPJ	P,		;ERROR
	MOVEI	T2,[FLDDB. (.CMNUM,,8)]
	COMND%			;PARSE AN OCTAL UNIT NUMBER
	TXNE	T1,CM%NOP	;ERROR?
	JRST	PUTERQ		;YES, COMPLAIN
	HRRM	T2,PHYSTR	;STORE UNIT TEMPORARILY
	PUSHJ	P,ENDCOM	;END LINE
	  POPJ	P,		;ERROR
	MOVX	T1,FLD(.DOPPU,DOP%AT)	;DSKOP ARG FOR PHYSICAL DRIVE
	HLRZ	T2,PHYSTR	;RETRIEVE CHANNEL
	DPB	T2,[POINTR T1,DOP%CN]	;STORE
	HRRZ	T2,PHYSTR	;RETRIEVE UNIT
	DPB	T2,[POINTR T1,DOP%UN]	;STORE
	MOVEM	T1,PHYSIO	;STORE DSKOP ARG & FLAG PHYS I/O
	SETOM	FDIDSW		;REMEMBER NOT AN EXE FILE
	JRST	FDIOPN		;GO OPEN THINGS UP AND START DDT
;STILL FTFILE & FTDEC20

;COMMAND ERROR SUBROUTINES

; INVALID END-OF-COMMAND

CFMERR:	PUSHJ	P,TSTCOL	;TEST COLUMN POSITION
	TMSG	<? Garbage at end-of-command
>				;OUTPUT ERROR MESSAGE
	POPJ	P,		;RETURN TO WHENCE WE CAME ...


; ROUTINE TO OUTPUT THE JSYS MESSAGE ON AN ERROR FROM A GTJFN OR OPENF
;
; CALL:		PUSHJ P,PUTERR	;PUTERQ TO PREFIX A "?"
; RETURNS: +1 ALWAYS

PUTERQ:	PUSHJ	P,TSTCOL	;PUT QM IN COLUMN 1
	TMSG	<? >		;PREFIX ERROR MESSAGE
PUTERR:	MOVX	T1,.PRIOU	;GET PRIMARY OUTPUT JFN
	HRLOI	T2,.FHSLF	;OUR FORK, LAST ERROR CODE
	SETZM	T3		;
	ERSTR%			;OUTPUT ERROR STRING
	 JFCL			;IGNORE
	 JFCL			;IGNORE
	TMSG	<
>				;OUTPUT NEW LINE
	POPJ	P,		;RETURN TO WHENCE WE CAME ...


; SUBROUTINE TO TEST COLUMN POSITION AND OUTPUT CRLF IF NEEDED

TSTCOL:	MOVEI	T1,.PRIOU	;GET PRIMARY OUTPUT DESIGNATOR
	RFPOS%			;READ FILE POSITION
	HRRZ	T2,T2		;KEEP JUST THE COLUMN POSITION
	JUMPE	T2,CPOPJ	;IF AT COLUMN 1 DO NOT OUTPUT CRLF
	TMSG	<
>				;NO, OUTPUT A CRLF
	POPJ	P,		;RETURN
;STILL FTFILE & FTDEC20

;PUTATM - ROUTINE TO TYPE THE CONTENTS OF THE ATOM BUFFER
;
;ACCEPTS IN T1/	POINTER TO ASCIZ PREFIX STRING TO BE TYPED
;		PUSHJ P,TYPATM
;RETURNS: +1 ALWAYS

TYPATM:	PUSH	P,T1		;SAVE POINTER
	PUSHJ	P,TSTCOL	;ISSUE NEW LINE IF NEEDED
	TMSG	<? >		;OUTPUT INITIAL PART OF MESSAGE
	POP	P,T1		;RESTORE ATOM POINTER
	PSOUT%			;OUTPUT THE STRING
	TMSG	< ">		;OUTPUT PUNCTUATION
	HRROI	T1,ATMBFR	;GET POINTER TO THE ATOM BUFFER
	PSOUT%			;OUTPUT THE TEXT ENTERED
	TMSG	<"
>				;OUTPUT END OF LINE
	POPJ	P,		;RETURN
;STILL FTFILE & FTDEC20

;PARSING SUBROUTINES

; ROUTINE TO PARSE AN END-OF-COMMAND
;
; CALL:		PUSHJ P,ENDCOM
; RETURNS: +1	 BAD CONFIRMATION, MESSAGE ALREADY ISSUED
;	   +2	SUCCESS, COMMAND CONFIRMED

ENDCOM:	MOVEI	T1,CMDBLK	;GET ADDRESS OF COMMAND STATE BLOCK
	MOVEI	T2,[FLDDB. (.CMCFM)]	;GET FUNCTION BLOCK FOR CONFIM
	COMND%			;PARSE CONFIRMATION
	TXNE	T1,CM%NOP	;VALID END-OF-COMMAND SEEN ?
	PJRST	CFMERR		;NO, ISSUE ERRO MESSAGE AND RETURN
	JRST	CPOPJ1		;SUCCESS, RETURN


; ROUTINE TO PARSE NOISE PHRASE
;
; CALL:	T2/ POINTER TO NOISE PHRASE
;		PUSHJ P,SKPNOI
; RETURNS: +1	 ERROR, INVALID NOISE PHRASE
;	   +2 	SUCCESS, NOISE PHRASE PARSED OK

SKPNOI:	MOVE	T1,[NOIFDB,,NOIFDB+1]	;SET UP TO CLEAR FUNCTION DESCRIPTOR BLOCK
	SETZM	NOIFDB		;CLEAR FIRST WORD OF BLOCK
	BLT	T1,NOIFDB+FDBSIZ-1	;CLEAR FUNCTION DESCRIPTOR BLOCK
	MOVX	T1,.CMNOI	;GET FUNCTION TO PERFORM
	STOR	T1,CM%FNC,NOIFDB	;STORE FUNCTION CODE IN FDB
	MOVEM	T2,NOIFDB+.CMDAT	;STORE POINTER TO NOISE PHRASE IN FDB
	MOVEI	T1,CMDBLK	;GET ADDRESS OF COMMAND STATE BLOCK
	MOVEI	T2,NOIFDB	;GET ADDRESS OF FUNCTION BLOCK
	COMND%			;PARSE NOISE WORD
	TXNN	T1,CM%NOP	;NOISE PHRASE PARSED OK ?
	JRST	CPOPJ1		;YES - RETUR SUCCESS
	PUSHJ	P,TSTCOL	;ISSUE NEW LINE IF NEEDED
	HRROI	T1,[ASCIZ/Invalid guide phrase/]
	PJRST	TYPATM		;OUTPUT THE TEXT ENTERED AND RETURN
;STILL FTFILE & FTDEC20

;CMDINI - ROUTINE TO INITIALIZE COMMAND STATE BLOCK AND OUTPUT PROMPT
;
;ACCEPTS IN T1/	POINTER TO ASCIZ PROMPT STRING
;		PUSHJ P,CMDINI
;RETURNS: +1 ALWAYS,	WITH THE REPARSE ADDRESS SET TO THE ADDRESS OF THE
;			CALL TO CMDINI.


CMDINI:	MOVEM	T1,CMDBLK+.CMRTY	;SAVE PROMPT STRING IN STATE BLOCK
	POP	P,SAVRET	;SET UP RETURN ADR FROM CMDINI AND FROM REPARSE
	MOVEM	P,SAVREP	;SAVE STACK POINTER TO BE RESET ON REPARSE
	MOVEI	T1,REPARS	;GET ADDRESS OF REPARSE ROUTINE
	MOVEM	T1,CMDBLK+.CMFLG	;SAVE REPARSE ROUTINE IN STATE BLOCK
	MOVEI	T1,CMDBLK	;GET ADDRESS OF COMMAND STATE BLOCK
	MOVEI	T2,[FLDDB. (.CMINI)]	;GET FUNCTION DESCRIPTOR BLOCK
	COMND%			;INITIALIZE COMMAND SCANNER JSYS
	JRST	@SAVRET		;RETURN


; HERE TO PROCESS A REPARSE

REPARS:	MOVE	P,SAVREP	;RESET STACK POINTER
	JRST	@SAVRET		;RETURN TO CALLER OF CMDINI
;STILL FTFILE & FTDEC20

; CONSTANTS AND TABLES

DEFINE TB(RTN,TXT)
<	[ASCIZ/TXT/] ,, RTN
>

CMDTAB:	CMDSIZ,,CMDSIZ		;CURRENT,,MAX SIZE OF COMMAND TABLE
	TB	(.DRIVE,DRIVE)	;DRIVE (FOR PHYS I/O ON) CHAN UNIT
	TB	(.ENBLE,ENABLE)	;ENABLE (PATCHING/DATA-FILE)
	TB	(.EXIT,EXIT)	;EXIT TO MONITOR
	TB	(.GET,GET)	;GET (FILE) FILE-SPEC
	TB	(.HELP,HELP)	;OUTPUT HELP MESSAGE
	TB	(.LOAD,LOAD)	;LOAD (SYMBOLS FROM) FILE-SPEC
	TB	(.PEEK,PEEK)	;PEEK AT RUNNING MONITOR
	TB	(.STRUC,STRUCTURE)	;STRUCTURE (FOR PHYS I/O)

	CMDSIZ== .-CMDTAB-1	;DON'T COUNT 1ST WORD

KEYTAB:	KEYSIZ,,KEYSIZ
	TB	(.DATA,DATA-FILE)
	TB	(.PATCH,PATCHING)

	KEYSIZ== .-KEYTAB-1

SWTTAB:	SWTSIZ,,SWTSIZ
	TB	(.DATA,DATA)	;FILE IS A DATA FILE
	TB	(.PATCH,PATCH)	;ENABLE PATCHING
	TB	(.SYMBL,SYMBOL)	;EXTRACT SYMBOLS

	SWTSIZ== .-SWTTAB-1


SWTBLK:	FLDDB.	(.CMSWI,,SWTTAB,,,CFMBLK)	;BLOCK FOR SWITCHES OR EOL

CFMBLK:	FLDDB.	(.CMCFM)


;< (MATCH ANGLE BRACKETS)
PROMPT:	ASCIZ	/FILDDT>/	;PROMPT STRING
;STILL FTFILE & FTDEC20

HLPMSG:	ASCIZ	\

GET (FILE) file-spec /switch/switch
	Loads a file for DDT to examine it.
	Switches:
		/DATA	Assume the file is raw binary.
		/PATCH	Allow the file to be modified.
		/SYMBOL	Load symbols from the file before using.
			This is the default action for .EXE files
			if DDT does not yet have a symbol table.

LOAD (SYMBOLS FROM) file-spec
	Reads the specified file and builds an internal symbol table.

PEEK (AT RUNNING MONITOR)
	Examines the running monitor.  This command is currently
	limited to section 0 due to PEEK JSYS restrictions.

STRUCTURE (FOR PHYSICAL I/O IS) disk-structure
	Examines the specified disk structure.

DRIVE (FOR PHYSICAL I/O IS ON CHANNEL) c (UNIT) u
	Examines the specified disk unit.

EXIT (FROM FILDDT)
	Returns to command level. You then may type a SAVE command
	if a LOAD command was just done to pre-load symbols.

HELP
	Types this text.

ENABLE PATCHING
	Allows modification of whatever is being examined.

ENABLE DATA-FILE
	Assumes file is raw binary.

	DDT features:

n$U sets the page number of the EPT or UPT to be used for
	virtual addresses in examining the file.
n$$2U sets the SPT index of a section table or index block.
	This is the same as n$U in previous versions of FILDDT.
$U un-does the above commands.

<CTRL/E> closes the currently open file and restarts FILDDT.

\

> ;END OF IFN FTDEC20
;STILL FTFILE

;HERE WHEN FILE SELECTED AND OPENED FOR I/O

FDIOPN:	SETOM	FILING		;REMEMBER NOT PEEKING
	PUSHJ	P,FDIAPB	;ALLOCATE BUFFERS FOR FILE'ING
	  JRST	FDIERR		;ERROR--ASK FOR ANOTHER FILE
	SKIPE	PHYSIO		;SUPER I/O?
	JRST	FDIPHY		;YES, DIFFERENT FILE INITIALIZATION
	SKIPE	FDIDSW		;[207] "/D" TYPED
	JRST	FDIXPD		;[207] YEP - WE KNOW THE FORMAT

;VERIFY FILE IS .EXE FORMAT

	MOVEI	R,0		;GET FIRST WORD OF FILE
	PUSHJ	P,FETCH		; . . .
	JRST	FDIXPN		;NOT AN EXE FILE IF NO FIRST WORD
	HLRZ	TT,T		;GET BLOCK TYPE CODE
	CAIE	TT,.SVDIR	;IS THIS AN EXE FILE?
	JRST	FDIXPN		;NO
	HRRZ	W1,T		;GET COUNT OF WORDS IN THIS BLOCK
	TRZE	W1,1		;SUBTRACT HEADER WORD
	CAILE	W1,MEXSIZ*2	;A REASONABLE EXE FILE?
	JRST	BADEXE		;WRONG FORMAT
	LSH	W1,-1		;CONVERT WORDS TO ENTRIES

;FALL INTO NEXT PAGE
;STILL FTFILE

;NOW TO LOOP OVER THE EXE DIRECTORY TO DETERMINE THE
;LARGEST PROCESS PAGE DESCRIBED.  WE WILL THEN USE THIS INFO
;TO ALLOCATE PAGTBL

	SETO	W,		;LARGEST IS -1 (NONE YET SEEN)
	MOVE	W2,W1		;A COPY OF # OF ENTRIES FOR LOOPING
	MOVEI	R,2		;START AT 2ND WORD OF 1ST ENTRY

FDIOP2:	PUSHJ	P,FETCH		;GET 2ND WORD OF NEXT EXE ENTRY
	JRST	BADEXE		;NOT AN EXE FILE?
	LDB	TT,[POINT 9,T,8]	;GET REPEAT COUNT
	ANDX	T,SV$FPN	;REDUCE TO FILE PAGE NUMBER
	ADD	TT,T		;PUT LARGEST PROC PAGE IN TT
	CAMLE	TT,W		;TT LARGEST YET SEEN?
	MOVE	W,TT		;YES, REMEMBER IT
	ADDI	R,2		;NEXT ENTRY
	SOJG	W2,FDIOP2	;LOOP OVER ENTIRE EXE DIRECTORY

;NOW ALLOCATE PAGTBL

	JUMPL	W,BADEXE	;PROBLEM IF NO ENTRIES SEEN
	ADDI	W,1		;CONVERT TO # PAGES IN RANGE
	CAILE	W,MEXSIZ	;REASONABLE?
	JRST	BADEXE		;NO, DON'T TRY TO ALLOCATE IT
	MOVEM	W,PGTLEN	;YES, SAVE FOR CHKADR
	MOVE	T,.JBFF		;GET BASE OF NEW PAGTBL
	ADDB	W,.JBFF		;UPDATE .JBFF & GET END+1
	CAMG	W,.JBREL	;HAVE ENOUGH MEMORY?
	JRST	FDIOP4		;YES, PROCEED
IFN	FTDEC10,<CORE W,>	;NO, TRY TO GET MORE
	JRST	[TMSG	<? Insufficient memory to read EXE file directory>
		JRST	FDEERR]	;CAN'T
FDIOP4:	HRLI	T,(IFIW (TT1))	;MAKE T INTO AN IFIW TO PAGTBL
	MOVEM	T,PAGTBL	;SET POINTER FOR ALL TO SEE
	SETZM	(T)		;CLEAR PAGTBL IN CASE OF ^C START
	HRL	T,T		;PAGTBL,,PAGTBL
	ADDI	T,1		;PAGTBL,,PAGTBL+1
	MOVE	TT1,PGTLEN	;LENGTH
	SOSE	TT1		;LAST WORD: SAME AS FIRST?
	BLT	T,@PAGTBL	;NO, CLEAR REST OF TABLE

;FALL INTO NEXT PAGE
;STILL FTFILE

;FALL IN FROM ABOVE TO READ THE EXE DIRECTORY AND SETUP
;PAGTBL BASED ON THE EXE ENTRIES.

	MOVEI	R,1		;START AT FIRST WORD OF FILE
FDIXL0:	PUSHJ	P,FETCH		;GET FIRST WORD OF NEXT DIRECTORY ENTRY
	JRST	BADEXE		;BAD FORMAT
	MOVE	W2,T		;SAVE IN A PERMANANT PLACE
	ADDI	R,1		;POINT TO SECOND WORD OF ENTRY
	PUSHJ	P,FETCH		;GET IT
	JRST	BADEXE		;CAN'T
	HRRZ	TT1,T		;GET PROCESS PAGE NUMBER
	CAIL	TT1,MEXSIZ	;OUT OF RANGE
	JRST	BADEXE		;YES--FILE IS BAD
	LDB	TT,[POINT 9,T,8]	;GET COUNT
FDIXL1:	TLNN	W2,1777		;JUNK IN LH
	CAML	TT1,PGTLEN	;IN TABLE?
	JRST	BADEXE		;BAD DIRECTORY
	MOVEM	W2,@PAGTBL	;STORE IN PAGTBL
	TXNN	W2,SV$HIS	;"HIGH SEGMENT" PAGE?
	JRST	FDIXL2		;NO, SKIP
	SKIPN	JOBHSO		;THIS THE FIRST HISEG PAGE?
	HRRZM	T,JOBHSO	;YES, THEN START OF HISEG
FDIXL2:	ADDI	TT1,1		;INCREMENT POINTERS
	TRNE	W2,3777		;DO NOT CHANGE ALLOCATED BUT
				; ZERO TO PAGE 1
	ADDI	W2,1		; . . .
	SOJGE	TT,FDIXL1	;LOOP OVER THIS ENTRY
	ADDI	R,1		;STEP TO NEXT ENTRY
	SOJG	W1,FDIXL0	;LOOP OVER ENTIRE DIRECTORY
	MOVEI	TT2,PAGSIZ	;PAGE SIZE
	IMULM	TT2,JOBHSO	;CALCULATE HISEG START ADDRESS (IF ANY)
	SETOM	EXEFMT		;FLAG TO USE EXE FORMAT MAPPING
	SETOM	LASTPG		;CHKADR'S DATA NOT VALID FOR EXE MAPPING
	JRST	FDISET

;FILE IS IN .XPN FORMAT OR IS PURE DATA FORMAT (E.G., FDIDSW .NE. 0)

FDIXPN:	TMSG	<% Not in .EXE format -- Data file assumed.
>
FDIXPD:	SETZM	EXEFMT		;FLAG NOT .EXE FILE
	JRST	FDISET		;GO DO FINAL SYMBOL ET AL SETUP
;STILL FTFILE

;HERE TO INITIALIZE FOR PHYSICAL I/O TO DISK UNITS

IFN	FTDEC10,<
FDIPHY:	MOVE	T,FLPBLK+.FODEV	;GET INPUT DEVICE
	MOVEM	T,DSKBLK	;SAVE IT IN DSKCHR BLOCK
	MOVE	TT,[DSKLEN,,DSKBLK] ;DSKCHR POINTER
	DSKCHR	TT,		;ASK MONITOR ABOUT IT
	 JRST	FDIPH1		;NOT A DISK!
	LDB	T,[POINTR TT,DC.TYP]  ;WHAT FLAVOR OF DISK
	CAIE	T,.DCTPU	;PHYSICAL UNIT (E.G., RPB3:)
	CAIN	T,.DCTUF	;OR LOGICAL UNIT (E.G., DSKC1:)?
	JRST	FDIPH2		;YES, EASY CASE
	CAIN	T,.DCTFS	;NO, HOW ABOUT A FULL FILE STRUCTURE?
	JRST	FDIPH4		;YES, REQUIRES SOME GRUNGE
FDIPH1:	TMSG	<? Device must be a disk unit or a file structure>
	JRST	FDEERR		;COMMON ERROR EXIT

;HERE ON A SPECIFIC UNIT

FDIPH2:	MOVE	TT2,DSKBLK+.DCUSZ  ;UNIT SIZE IN BLOCKS
	JRST	FDIPH6		;CRUNCH AND SET WORD COUNT

;HERE ON A FILE STRUCTURE

FDIPH4:	MOVE	S,DSKBLK+.DCSNM	;REMEMBER STRUCTURE NAME
	SETZB	TT1,TT2		;INITIALIZE FOR SYSPHY SEARCH

FDIPH5:	SYSPHY	TT1,		;NEXT PHYSICAL UNIT IN SYSTEM
	 JRST	FDIPH6		;??? OH WELL, ASSUME ALL DONE
	JUMPE	TT1,FDIPH6	;0 IS DONE
	MOVEM	TT1,DSKBLK	;SET FOR ANOTHER DSKCHR
	MOVE	TT,[DSKLEN,,DSKBLK]  ;POINTER FOR DSKCHR
	DSKCHR	TT,		;QUERY MONITOR ABOUT THIS UNIT
	 HALT	.		;CANNOT HAPPEN
	CAMN	S,DSKBLK+.DCSNM	;UNIT PART OF INTERESTING STRUCTURE?
	ADD	TT2,DSKBLK+.DCUSZ  ;YES, ACCUMULATE BLOCKS COUNT
	JRST	FDIPH5		;LOOP

FDIPH6:	LSH	TT2,BL2WRD	;MAKE WORD COUNT
	MOVEM	TT2,MAXSIZ	;SET MAX SIZE ADDRESSABLE
	JRST	FDISET		;GO SETUP FOR DISK I/O
> ;END OF IFN FTDEC10
;STILL FTFILE

;INITIALIZE FOR PHYSICAL I/O ON TOPS-20
;WE NEED TO CHECK TO MAKE SURE DRIVES ARE THERE, PACKS ARE
;SPINNING, CHECK WRITE-LOCK ETC., AND SETUP MAXSIZ.

IFN	FTDEC20,<
FDIPHY:	SKIPGE	PHYSIO		;DOES USER WANT STRUCTURE OR UNIT?
	JRST	FDISTR		;STRUCTURE, GO PROCESS
	LDB	T,[POINTR PHYSIO,DOP%CN]	;UNIT, GET CHANNEL #
	MOVEM	T,MBLK+.MSRCH	;STORE FOR MSTR
	SETOM	MBLK+.MSRCT	;INIT CONTROLLER WORD
	LDB	T,[POINTR PHYSIO,DOP%UN]	;GET UNIT #
	MOVEM	T,MBLK+.MSRUN
	HRROI	T,STRBUF	;POINTER TO STRUCTURE NAME BUFFER
	MOVEM	T,MBLK+.MSRSN	;STORE IN BLOCK
	HRROI	T,ALIBUF	;POINTER TO ALIAS NAME BUFFER
	MOVEM	T,MBLK+.MSRSA	;STORE
	MOVX	T1,<MBLKL,,.MSRUS>	;ASK MSTR TO RETURN UNIT STATUS
	MOVEI	T2,MBLK		;USING MBLK
	MSTR%			;FILL IN MBLK
	 ERJMP	PUTERQ		;FAILED, COMPLAIN TO USER
	MOVE	T,MBLK+.MSRST	;GET STATUS FLAGS
	TXNE	T,MS%OFL	;IS UNIT OFF LINE?
	PJRST	OFLINE		;YES, COMPLAIN
	TXNN	T,MS%MNT	;IS IT PART OF A MOUNTED STRUCTURE?
	JRST	FDIPH2		;NO, CONTINUE
	TMSG	<[Unit is part of structure >	;YES, TELL USER
	HRROI	T1,ALIBUF	;DOING THIS AVOIDS SAD ERRORS
	PSOUT%			;TYPE STRUCTURE ALIAS
	TMSG	<:]
>				;CLOSE OFF MESSAGE
FDIPH2:	PUSHJ	P,CHKUNI	;TELL USER IF OTHER FUNNY STATUS BITS
	MOVE	T,MBLK+.MSRSU	;GET SECTORS PER UNIT
	LSH	T,BL2WRD	;CONVERT TO NUMBER OF WORDS
	MOVEM	T,MAXSIZ	;SET AS MAXIMUM SIZE TO EXAMINE
	JRST	FDISET		;GO START DDT
;STILL FTFILE & FTDEC20

;HERE IF USER SPECIFIED A STRUCTURE. LOOP OVER ALL UNITS IN THE
;SYSTEM TO COUNT THE TOTAL SPACE AVAILABLE ON THIS STRUCTURE.

FDISTR:	HRROI	T1,NAMBUF	;STORE STR NAME IN NAMBUF
	MOVE	T2,PHYSTR	;STRUCTURE DESIGNATOR COMND RETURNED
	DEVST%			;GET NAME OF STRUCTURE
	 ERJMP	PUTERQ		;COMPLAIN IF FAILURE
	SETOM	MBLK+.MSRCH	;INIT MBLK TO LOOP OVER ALL UNITS
	SETOM	MBLK+.MSRCT	; . . .
	SETOM	MBLK+.MSRUN	; . . .
	SETZM	MAXSIZ		;WE DON'T HAVE ANY SIZE YET
	MOVX	W2,.LHALF	;DON'T YET KNOW # UNITS IN STR

FDIST2:	HRROI	T,STRBUF	;POINTER TO STRUCTURE NAME BUFFER
	MOVEM	T,MBLK+.MSRSN	;STORE FOR MSTR
	HRROI	T,ALIBUF	;POINTER TO STRUCTURE ALIAS BUFFER
	MOVEM	T,MBLK+.MSRSA	;STORE
	SETZM	ALIBUF		;CLEAR TO AVOID SPURIOUS MATCHES
	MOVX	T1,<MBLKL,,.MSRNU>	;GET THE NEXT UNIT FUNCTION
	MOVEI	T2,MBLK		;USING MBLK
	MSTR%			;GET INFO ON FIRST OR NEXT UNIT
	 ERJMP	FDIST6		;CHECK ALL DONE IF ERROR
	HRROI	T1,NAMBUF	;THE STRUCTURE THAT WE WANT
	HRROI	T2,ALIBUF	;THE ALIAS OF THIS UNIT
	STCMP%			;SEE IF THEY ARE THE SAME
	JUMPN	T1,FDIST2	;LOOP BACK FOR NEXT UNIT IF NOT
	MOVE	T,MBLK+.MSRST	;GET STATUS BITS
	TXNE	T,MS%OFL	;IS UNIT OFF LINE?
	 PJRST	OFLINE		;YES, COMPLAIN AT USER
	PUSHJ	P,CHKUNI	;TELL USER ABOUT OTHER STATUS BITS
	MOVE	T,MBLK+.MSRSU	;GET SECTORS ON THIS UNIT
	LSH	T,BL2WRD	;CONVERT TO WORDS
	ADDM	T,MAXSIZ	;THE STRUCTURE IS THAT MUCH BIGGER
FDIST4:	SOJGE	W2,FDIST2	;COUNT ANOTHER UNIT AND LOOK FOR MORE
	AOJE	W2,MISUNI	;TELL USER IF TOO MANY UNITS
	HRRZ	W2,MBLK+.MSRNS	;FIRST TIME THROUGH, GET NUMBER OF UNITS
	JRST	FDIST4		;AND COUNT THE ONE WE JUST FOUND

FDIST6:	MOVEI	T1,.FHSLF	;WE GOT AN ERROR FROM MSTR. WHAT WAS IT?
	GETER%			;ASK THE MONITOR
	HRRZ	T2,T2		;ERROR CODE ONLY
	CAIE	T2,MSTX18	;RAN OUT OF UNITS?
	PJRST	PUTERQ		;NO, GO TELL USER ABOUT OUR ERROR
	JUMPN	W2,MISUNI	;GO COMPLAIN IF DIDN'T FIND ALL UNITS
	JRST	FDISET		;ALL DONE
;STILL FTFILE & FTDEC20

;SUBROUTINES TO TALK ABOUT UNITS

CHKUNI:	MOVE	T,MBLK+.MSRST	;GET UNIT STATUS
	TXNN	T,MS%HBB	;BAD HOME BLOCKS?
	JRST	CHKUN2		;NO, CHECK BAT BLOCKS
	TMSG	<% >		;YES, TYPE PREFIX
	PUSHJ	P,TYPUNI	;TYPE UNIT NAME
	TMSG	< has a bad HOME block
>				;TELL USER ABOUT STATUS BIT
	MOVE	T,MBLK+.MSRST	;RESTORE T FROM TYPUNI
CHKUN2:	TXNN	T,MS%BBB	;BAT BLOCKS BAD?
	JRST	CHKUN4		;NO, PROCEED
	TMSG	<% >		;YES, ISSUE PREFIX
	PUSHJ	P,TYPUNI	;TYPE THE UNIT NAME
	TMSG	< has a bad BAT block
>				;TELL USER
	MOVE	T,MBLK+.MSRST	;RESTORE T
CHKUN4:	TXNE	T,MS%WLK	;WRITE LOCKED?
	SKIPN	PATCHS		;YES, BUT DOES THE USER WANT TO PATCH?
	POPJ	P,		;NO TO EITHER, DON'T CARE
	TMSG	<% >		;PREFIX
	PUSHJ	P,TYPUNI	;TYPE THE UNIT NAME
	TMSG	< is write locked
>				;TELL USER
	POPJ	P,		;RETURN
OFLINE:	TMSG	<? >		;OFF LINE UNIT IS FATAL
	PUSHJ	P,TYPUNI	;TELL UNIT
	TMSG	< is off line>	;TELL SAD STORY
	JRST	FDEERR		;ERROR RETURN


TYPSTR:	SKIPL	PHYSIO		;DRIVE OR STRUCTURE?
	JRST	TYPST2		;DRIVE, TELL USER WHICH ONE
	TMSG	<file structure >	;STRUCTURE, TELL USER
	HRROI	T1,NAMBUF	;POINT TO STR NAME
	PSOUT%			;TELL USER WHICH STR
	TMSG	<:>		;TERMINATE WITH COLON
	POPJ	P,
TYPST2:	TMSG	<unit >		;DRIVE, SAY "UNIT"
	JRST	TYPUN4		;JOIN TYPUNI

TYPUNI:	SKIPGE	PHYSIO		;STRUCTURE OR UNIT?
	JRST	TYPUN2		;STRUCTURE, NEED TO TELL WHICH UNIT
	TMSG	<Unit>		;UNIT, USER KNOWS WHICH ONE
	POPJ	P,		;RETURN
TYPUN2:	TMSG	<Unit >		;TELL USER UNIT NUMBER COMING UP
TYPUN4:	MOVEI	ODF,8		;RADIX TO USE
	MOVE	T,MBLK+.MSRUN	;GET UNIT NUMBER
	PUSHJ	P,TOC		;TYPE UNIT NUMBER IN OCTAL
	TMSG	< on channel >	;TELL USER CHANNEL NUMBER COMING UP
	MOVE	T,MBLK+.MSRCH	;GET CHANNEL NUMBER
	PJRST	TOC		;TYPE IN OCTAL AND RETURN


MISUNI:	JUMPL	W2,MISUN1	;BETTER MESSAGE IF NO UNITS FOUND
	TMSG	<? Missing or extra units in structure> ;COMPLAIN AT USER
	JRST	FDEERR		;TYPE CRLF AND RETURN

MISUN1:	TMSG	<? No such file structure>	;DIDN'T FIND IT AT ALL
	JRST	FDEERR		;TYPE CRLF AN RETURN

> ;END IFN FTDEC20
SUBTTL	FILDDT -- SETUP PAGE BUFFERS AND SYMBOLS

;STILL FTFILE

;SETUP PAGE BUFFERS, SYMBOLS (IF APPROPRIATE) AND FETCH THE
;USER ACS (CRSHAC/BUGACS - IF ANY)

FDISET:	SKIPN	FILING		;LOOKING AT MONITOR/MEMORY?
	JRST	FDIGO		;YES, THEN NEVER EXTRACT SYMBOLS
	SKIPE	EXEFMT		;LOOKING AT A DATA FILE?
	JRST	FDIEXE		;NO, PROCEED WITH EXE FILE PROCESSING


;HERE ON A DATA FILE.  SEE IF USER WANTS SYMBOLS EXTRACTED.

	SKIPN	SYMGET		;DATA FILE. USER WANT SYMBOL LOADED?
	JRST	FDIGO		;NO, GO FILDDT THE FILE.
	SKIPE	FDIFSW		;USER WANT TO LOOK AT THE FILE?
	JRST	FDISE2		;YES, JUST WARN HIM
	TMSG	<? >		;EXTRACT SYMBOL ONLY, FATAL ERROR
	JRST	FDISE4		;FINISH MESSAGE
FDISE2:	TMSG	<% >		;WARN COMMAND ONLY HALF DONE
FDISE4:	TMSG	<Symbols cannot be extracted from a data file
>				;FINISH WARNING OR ERROR
	SKIPE	FDIFSW		;WANT TO FILDDT THE FILE ANYWAY?
	JRST	FDIGO		;YES, GO TO IT.
	PUSHJ	P,CLSFIL	;NO, CLOSE OFF THE USELESS FILE
	JRST	DDT		;RESTART COMMAND PROCESSING


;HERE ON AN .EXE FILE

FDIEXE:	SKIPE	SYMGET		;/S SPECIFIED?
	 JRST	FDISY		;YES, ALWAYS EXTRACT SYMBOLS
	SKIPGE	FISPTR		;NO /S. DO WE ALREADY HAVE SYMBOLS
	JRST	FDIAC		;YES, JUST LOOK FOR ACS THEN

;EXTRACT SYMBOLS FROM .EXE FILE

FDISY:	PUSHJ	P,SYMFIX	;READ IN THE SYMBOLS
	JRST	FDEERR		;BAD SYMBOL TABLE FORMAT, MSG ALREADY ISSUED
	SKIPE	FDIFSW		;FILDDT THE FILE (/F)?
	JRST	FDIAC		;YES, LOOK FOR ACS
	SKIPN	SYMGET		;JUST /S (NO /F)?
	JRST	FDIAC		;NO, GO FILDDT THE FILE
	PUSHJ	P,CLSFIL	;YES, CLOSE THE SYMBOL FILE
	JRST	DDT		;GO AROUND AND ASK FOR NEW FILE
;EXTRACT THE ACS FROM THE .EXE FILE

FDIAC:
IFN	FTDEC10,<MOVE T,[RADIX50 0,CRSHAC]>
IFN	FTDEC20,<MOVE T,[RADIX50 0,BUGACS]>
	MOVEM	T,SYM		;LOOKUP CRSHAC
	PUSHJ	P,EVAL		; IN SYMBOL TABLE
	 SETZ	T,		;NOT THERE, USE VIRTUAL 0 TO 17
	MOVSI	W1,-20		;NUMBER OF ACS
	MOVE	R,T		;WHERE THE ACS ARE
	MOVEM	R,FAKEAD	;SET ADDRESS FOR USER TO SEE
FDIGAC:	PUSHJ	P,FETCH		;GET THE AC
	 JRST	FDIGO		;CAN NOT FETCH
	MOVEM	T,AC0(W1)	;STORE AC
	ADDI	R,1		;POINT TO NEXT CELL
	AOBJN	W1,FDIGAC	;GET THE ACS
	CAIN	R,20		;USING CRSHAC/BUGACS?
	JRST	FDIAC4		;NO
IFN	FTDEC10,<
	TMSG	<[ACs copied from CRSHAC to 0-17]
>   >				;[221]
IFN	FTDEC20,<
	TMSG	<[ACs copied from BUGACS to 0-17]
>   >				;[221]
FDIAC4:	SETOM	FAKEAC		;[207] FLAG USING FAKE LOC 0 - 17
IFN	FTDEC20,<
	MOVE	T,[RADIX50 0,SPT]
	MOVEM	T,SYM
	PUSHJ	P,EVAL
	 JRST	FDIGO
	MOVEM	T,SPTWRD
> ;END OF IFN FTDEC20
;STILL FTFILE

FDIGO:
IFN	FTDEC20,<
	TMSG	<[Looking at >	;HEADER OF MESSAGE
	SKIPN	PHYSIO		;PHYSICAL I/O?
	JRST	FDIGO2		;NO
	PUSHJ	P,TYPSTR	;YES, TYPE WHAT WE'RE LOOKING AT
	JRST	FDIGO6		;END THE LINE AND START DDT

FDIGO2:	SKIPN	FILING		;LOOKING AT A DISK FILE
	JRST	FDIGO4		;NO
	TMSG	<file >		;YES, SAY IT'S A FILE
	HRROI	T1,NAMBUF	;POINT TO THE FILE SPEC
	PSOUT%			;TYPE IT TOO
	JRST	FDIGO6		;END LINE

FDIGO4:	TMSG	<the running monitor>	;ONLY POSSIBILITY LEFT
FDIGO6:	TMSG	<]
>				;END THE LINE
> ;END IFN FTDEC20
	JRST	DD1		;GO START DDT



;SOME ERRORS COMMON TO ALL SYSTEMS

NOTDSK:	TMSG	<? Input device must be a disk>
	JRST	FDEERR		;CRLF AND RETURN

BADEXE:	TMSG	<? Bad format for .EXE file>


;HERE TO TYPE A CRLF, CLEAR THE INPUT BUFFER, AND SCAN A NEW COMMAND

FDEERR:	TMSG	<
>				;TYPE A CRLF
FDIERR:	PUSHJ	P,TTYCLR	;CLEAR INPUT BUFFER
IFN	FTDEC10,<JRST DDT>	;RESTART DDT ON TOPS-10
IFN	FTDEC20,<POPJ P,>	;GIVE ERROR RETURN TO PARSER ON TOPS-20
;STILL FTFILE

;ALLOCATE FILE PAGE BUFFERS

FDIAPB:	SKIPE	WIND0		;ALREADY BEEN HERE?
	JRST	CPOPJ1		;YES, GIVE GOOD RETURN
	MOVE	T,.JBFF		;START OF FREE MEMORY
	TRNE	T,PAGMSK	;PAGE BOUNDRY?
	ADDI	T,PAGSIZ	;NO, ROUND UP TO
	ANDCMI	T,PAGMSK	;PAGE BOUNDRY
	MOVEM	T,WIND0		;SET AS BASE ADDRESS FOR BUFFERS
	ADDI	T,WINMAX*PAGSIZ-1  ;AMOUNT OF ROOM NEEDED
	CAMG	T,.JBREL	;WITHIN ADDRESSABLE MEMORY?
	 JRST	FDIAP4		;YES, NO NEED TO BOTHER MONITOR
	PUSH	P,T		;PRESERVE T ACROSS MONITOR CALL
IFN	FTDEC10,<CORE T,>	;ASK MONITOR FOR SOME SPACE
	 JRST	[TMSG	<? Not enough memory for file pages>
		POP	P,T	;RESTORE STACK
		POPJ	P,]	;PROPOGATE FAILURE
	POP	P,T		;GET BACK ADDRESS
FDIAP4:	ADDI	T,1		;POINT TO NEW FIRST FREE LOCATION
	MOVEM	T,.JBFF		;SAVE IT FOR OTHERS TO LOOK AT
	JRST	CPOPJ1		;ALL DONE
;STILL FTFILE

SYMFIX:	PUSHJ	P,CLRCSH	;ZERO THE SYMBOL TABLE CACHE
	MOVEI	R,.JBSYM	;GET .JBSYM
	PUSHJ	P,FETCH		; . . .
	  SETZ	T,		;NOT VALID, DON'T USE IT
	MOVEM	T,FISPTR	;SAVE IN FISPTR FOR A WHILE
	MOVEM	T,FOSPTR	;ALSO IN FOSPTR FOR CLSFIL
	MOVEI	R,.JBUSY	;GET .JBUSY
	PUSHJ	P,FETCH		; . . .
	  SETZ	T,		;NOT VALID, DON'T USE IT
	MOVEM	T,FIUPTR	;SAVE IN FIUPTR FOR A WHILE
	PUSHJ	P,SYMCHK	;SET UP SAVHSM, CHECK OTHER PTRS
	MOVE	T,FIUPTR	;GET (POSSIBLY DIFFERENT) USY PTR
	MOVEM	T,FOUPTR	;SAVE FOR CLSFIL
	MOVE	T,SAVHSM	;ALSO SAVE SAVHSM
	MOVEM	T,OLDHSM	;CLSFIL NEEDS THEM ALL
	MOVE	W1,.JBFF	;GET CURRENT FIRST FREE
	MOVEM	W1,FISBEG	;SAVE FOR DEPSYM
	ADDI	W1,1000		;1P FOR PATCHING
	HLRE	T,FISPTR	;GET .JBSYM SIZE
	MOVN	W,T		;COUNT CORE NEEDED
	HLRE	T,FIUPTR	;GET .JBUSY SIZE
	SUB	W,T		;BUMP AGAIN
	HLRE	T,SAVHSM	;GET .JBHSM SIZE
	SUBB	W,T		;BUMP A THIRD TIME
	LSH	T,-1		;CONVERT TO NUMBER OF SYMBOLS
	MOVEM	T,FISCNT	;SAVE FOR MESSAGE
	ADD	W,W1		;BEGINNING+COUNT=END
	HRRZM	W,.JBFF		;UPDATE MONITOR TO END FOR ITS BUFFER
	HRLM	W,.JBSA		; ALLOCATION MECHANISMS
	HRLM	W,.JBCOR	;INDICATE SYMBOLS FOR SAVE
	SUBI	W,1		;CONVERT TO LAST LOC NEEDED
	MOVEM	W,FISEND	;SAVE FOR DEPSYM
	CAMG	W,.JBREL	;DO WE NEED MORE MEMORY?
	 JRST	SYMFI4		;NO, WE ALREADY HAVE PLENTY
IFN	FTDEC10,<CORE W,>	;ALLOCATE SOME MEMORY
	 JRST	[TMSG	<? Not enough memory for symbols> ;COMPLAIN TO USER
		POPJ	P,]	;GIVE ERROR TO CALLER

;CONTINUED ON NEXT PAGE
;STILL FTFILE

;CONTINUED FROM PREVIOUS PAGE

;NOW TO COPY THE FILE'S SYMBOL TABLES INTO DDT'S ADDRESS SPACE.

SYMFI4:	MOVE	R,FIUPTR	;GET USY POINTER
	HRRM	W1,FIUPTR
	JUMPGE	R,SYMCPY	;SKIP IF NONE
UCOPY:	PUSHJ	P,FETCHL	;READ ANOTHER SYMBOL WORD
	 JRST	BADSTF		;SYMBOL TABLE MESSED UP
	MOVEM	T,(W1)
	AOS	W1
	AOBJN	R,UCOPY

SYMCPY:	MOVE	R,FISPTR	;WHEREABOUTS OF MONITOR SYMBOLS
	HRRM	W1,FISPTR	;NOW POINT TO FILDDT SYMBOLS
	JUMPGE	R,HSYCPY	;IF NO TABLE, GO CHECK HI SEG
TCOPY:	PUSHJ	P,FETCHL	;GET A WORD
	  JRST	BADSTF		;SYMBOL TABLE PTR IS WRONG
	MOVEM	T,0(W1)		;STASH IT
	AOS	W1
	AOBJN	R,TCOPY

HSYCPY:	MOVE	R,SAVHSM	;FILE'S HISEG SYMBOLS
	HRRM	W1,SAVHSM	;POINT SAVHSM TO FILDDT'S COPY
	JUMPGE	R,SYMFIN	;DONE IF NONE TO COPY
HCOPY:	PUSHJ	P,FETCHL	;GET NEXT WORD OF SYMBOL TABLE
	  JRST	BADSTF		;ERROR
	MOVEM	T,(W1)		;STORE IN FILDDT'S AREA
	AOS	W1		;BUMP FILDDT'S POINTER
	AOBJN	R,HCOPY		;LOOP THROUGH ALL SYMBOLS

SYMFIN:	SETOM	SYMGOT		;FLAG IN-CORE SYMBOLS ARE FROM THIS FILE

IFN FTDEC20,<
	TMSG	<[>		;START MESSAGE
	MOVE	A,FISCNT	;GET COUNT OF SYMS LOADED
	PUSHJ	P,FP7		;TYPE IN DECIMAL
	TMSG	< symbols loaded from file]
>
> ;END IFN FTDEC20

	JRST	CPOPJ1		;TELL CALLER WE DID IT


BADSTF:	TMSG	<? Incorrect symbol table pointer>
	POPJ	P,		;GIVE ERROR RETURN

> ;END FTFILE
SUBTTL	START DDT

IFE	FTFILE,<

IFN	FTDBUG,<DEBDDT::>

DDTX:
DDT:
IFN	FTYANK,<SETZM COMAND>	;INDICATE NO COMMAND FILE IF
				;STARTING BY DDT COMMAND

IFN	FTDEC20&<^-FTEXEC>&<^-FTMON>,< ;USER -20 DDT ONLY
	JRST	.+2		;SKIP SYMTAB PTRS
	SETA	DDSYM		;NO-OP THAT LOOKS LIKE IFIW
	SETA	DDUSY		;SO JRST .+2 CAN FALL THROUGH HERE
> ;END USER -20 DDT

IFN	FTMON,<
	MOVEM	T,SETRT1	;SAVE AN AC
	MOVE	T,BPT$B+B$JSR
	CAMN	T,[JSR BCOM]	;VARIABLES AREA INITIALIZED?
	JRST	DDTIN1		;YES
	MOVE	T,[PHVAR,,BEG.V]	;NO, DO IT
	BLT	T,VAREND-1
DDTIN1:	MOVE	T,SETRT1	;RESTORE SCRATCH AC
> ;END IFN FTMON

	JSR	SAVE
	 PUSHJ	P,REMOVB
IFE	FTVMX,<MOVE W1,[ASCII /DDT/]>	;IDENTIFY USER MODE DDT
IFN	FTVMX,<MOVE W1,[ASCII /VMDDT/]>	;IDENTIFY TOPS-10 VM DDT
IFN	FTMON,<MOVE W1,[ASCII /MDDT/]>	;IDENTIFY TOPS-20 MDDT
IFN	FTEXEC&<^-FTMON>,<
	SKPUSR				;IF EXEC MODE, THEN
	MOVE	W1,[ASCII /EDDT/]	;IDENTIFY EXEC MODE DDT
>					;END OF IFN FTEXEC
	PUSHJ	P,TEXT2		;TYPE MESSAGE SAYING WHICH DDT
IFN	FTDBUG,<
	MOVEI	W1,[ASCIZ/ (debugging)/]
	PUSHJ	P,TSTRG		;DIFFERENTIATE FROM REGULAR DDT(S)
> ;END IFN FTDBUG
>				;END IFE FTFILE
SUBTTL	DDT COMMAND PARSER

DD1:	PUSHJ	P,TCRLF
DD1.5:	TXZ	F,ROF		;CLOSE ANY OPEN REGISTER
	MOVE	T,[XWD SCHM,SCH]
	BLT	T,ODF		;LOAD ACS
	MOVE	T,[PSVBTS,,SVBTS]
	BLT	T,SVBTS+1
DD2:	MOVE	T,[SCH,,SCHR]	;SAVE CURRENT TYPEOUT MODES
	BLT	T,ODFR		;IN CASE REPARSE NEEDED
	SETZM	PRNC		;PARENTHESES COUNT
	MOVE	P,[IOWD LPDL,PDL]
	SETZM	WAKALL		;SET WAKEUP SET TO PUNCT AND CTRLS
	XMOVEI	T,RET		;INIT TOP OF STACK TO RET
	MOVEM	T,XPDL		;SO COMMAND ROUTINES CAN POPJ
	MOVE	T,@USYMP	;GET ORIGINAL UNDEFINED SYMBOL PTR
	MOVEM	T,ESTUT		;INIT UNDEFINED SYM ASSEMBLER
LIS0C:	TXZ	F,<^-<ROF!STF>&<-1,,0>>!LF1!CF1!OKAF!ITF!Q2F
LIS0E:	TXZ	F,<^-<ROF!STF!FAF!SAF>&<-1,,0>>!NAF
	SETZM	WRD
LIS1:	SETZM	FRASE
LIS2:	MOVEI	T,1
	MOVEM	T,FRASE1
	TXZ	F,MLF!DVF
L1:	TXZ	F,CF!CCF!SF!FPF!Q2F!LTF!TXF	;TURN OFF CONTROL, SYL, PERIOD FLAG
L1A:	SETZM	SYL
L1RPR:	SETZM	SYM
	MOVEI	T,6
	MOVEM	T,TEM		;INIT SYMBOL COUNTER
	MOVE	T,[POINT 7,OPTXT]
	MOVEM	T,CHP		;SETUP FOR OPEVAL SYMBOL
	SETZM	DEN
	SETZM	WRD2D
	SETZM	WRD2O

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

L2:	PUSHJ	P,TIN		;PICK UP CHARACTER
	CAIL	T,"A"+40	;LOWER CASE A
	CAILE	T,"Z"+40	;LOWER CASE Z
	JRST	.+2
	TRC	T,40		;CHANGE LOWER CASE TO UPPER CASE
	TXNE	F,CF		;CONTROL FLAG
	JRST	L21
	CAIG	T,"Z"		;Z
	CAIGE	T,"A"		;A
	JRST	.+2
	JRST	LET
L21:	MOVE	R,T
	CAILE	T,137		;DISPATCH TABLE HAS ENTRIES ONLY .LE. 137
	JRST	ERR
	IDIVI	R,3		;REMAINDER GIVES COLUMN, QUOTIENT GIVES ROW
	LDB	W,BDISP(R+1)	;GET 12 BIT ADDRESS FROM DISPATCH TABLE
	CAIGE	W,MULT-DDTOFS	;FIRST EVAL ROUTINE
	JRST	DDTOFS(W)
	MOVE	T,SYL
	TXNN	F,LTF
	JRST	POWER


;TIME TO EVALUATE A SYMBOL.  IF THIS IS IN THE OPCODE FIELD (1ST THING
;TYPED AND TERMINATED WITH A SPACE), THEN SEARCH ORDER IS:
;1. OPDEFS FROM THE S.T. (B0-8 .NE. 0) 2. BUILT-IN OPCODES 3. REST OF S.T.
;IF THE SYMBOL TYPED IS NOT IN THE OPCODE FIELD, THEN THE ORDER IS:
;1. ANY MATCH IN THE S.T. 2. DDT'S BUILT-IN OPCODES.
;THE FLAG OPTRYF INDICATES THAT WE ARE TRYING TO SEARCH FOR AN OPCODE.

	TXO	F,OPTRYF	;ASSUME WE ARE IN THE OPCODE FIELD
	CAIN	W,SPACE-DDTOFS	;IS TERMINATOR A SPACE?
	SKIPE	WRD		;IS CONSTRUCTED WORD SO FAR ZERO?
	TXZ	F,OPTRYF	;NO, NOT AN OPCODE
	PUSHJ	P,EVAL		;TRY FOR A MATCH IN THE S.T.
	  JRST	[TXZ F,OPTRYF	;SO UNDEF TEST BELOW WILL WORK
		JRST L27]	;TRY BUILT-IN OPCODES
	TXNE	F,OPTRYF	;ONLY WANT OPDEFS?
	TXNE	T,777B8		;YES, IS THIS ONE?
	JRST	L3		;WE'LL TAKE ANYTHING OR THIS IS AN OPCODE
	MOVEM	T,TENSYM	;ONLY NON-OPCODE FOUND, SAVE TENATIVE MATCH
L27:	PUSHJ	P,OPEVAL	;SEARCH FOR A (BETTER?) MATCH IN OPCODES
	  SKIPA	T,TENSYM	;NOTHING, HAD BETTER BE A SAVED VAL
	JRST	L3		;BETTER MATCH FOUND, GO WITH IT
	TXZN	F,OPTRYF	;DID EARLIER EVAL FIND ANYTHING?
	JRST	UND1		;NO, GIVE UP

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

L3:	CAIN	W,ASSEM-DDTOFS	;DEFINED SYMBOL FOLLOWED BY #?
	JRST	ERR		;IF DEFINED, DON'T ALLOW #
L4:	TXZE	F,MF
	MOVN	T,T
	TXNN	F,SF
	CAIE	W,LPRN-DDTOFS
	JRST	.+2
	JRST	LPRN

	EXCH	T,FRASE1
	TXNN	F,DVF
	IMULB	T,FRASE1
	TXZE	F,DVF
	IDIVB	T,FRASE1
	CAIGE	W,ASSEM-DDTOFS
	JRST	DDTOFS(W)	;MULTIPLY OR DIVIDE
	ADDB	T,FRASE
	CAIGE	W,SPACE-DDTOFS
	JRST	DDTOFS(W)	; + - @ ,

	ADD	T,WRD
	TXNE	F,TIF		;TRUNCATE INDICATOR FLAG
	HLL	T,WRD		;TRUNCATE
	MOVEM	T,WRD
	TXNN	F,QF
	MOVE	T,LWT
	SETZM	R
	MOVE	W1,ESTUT
	CAMN	W1,@USYMP	;IF THERE ARE ANY UNDEFINED SYMBOLS IN
	JRST	L5		;THE CURRENT EXPRESSION, ANYTHING EXCEPT
	CAILE	W,CARR-DDTOFS	;FURTHER EXPRESSION INPUT, OR DEPOSITING
	JRST	ERR		;  INTO MEMORY IS ILLEGAL
L5:	CAIG	W,RPRN-DDTOFS
	JRST	DDTOFS(W)
	SKIPN	PRNC		;WHEN INSIDE ( ), CURRENT EXPRESSION INVALID
	JRST	DDTOFS(W)	;FOR ANYTHING OTHER THAN MORE EXPRESSION INPUT
	JRST	ERR
;HANDLE AN UNDEFINED SYMBOL

UND1:	SKIPN	ESTUT		;ANY UNDEFINED SYMBOL TABLE?
	JRST	UNDEF		;NO, CAN'T DO THIS
	PUSHJ	P,EVALU		;SEE IF SYM IS IN THE UNDEFINED TABLE
	 JRST	UND3		;[245] SYMBOL DOES NOT EXIST
	TXNE	F,ROF		;[245] SYM EXISTS, LOCATION OPEN
	CAILE	W,CARR-DDTOFS	;[245] AND STILL BUILDING WORD FOR IT?
	 JRST	UNDEF		;[245] NO - THEN "U" ERROR (E.G. "=" CMD)
	CAIE	W,ACCF-DDTOFS	;[246] EXPRESSION INVOLVING A COMMA?
	SKIPE	PRNC		;[246] OR INSIDE PARENTHESIS?
	 JRST	UNDEF		;[246] YES - "U" ERROR
	JRST	UND4		;[245] NO, CONTINUE

UND3:	CAIN	W,ASSEM-DDTOFS	;[245] DEFINING SYMBOL VIA "#" CMD
	TXNN	F,ROF		;[245] FOR A LOCATION THAT IS OPEN?
	 JRST	UNDEF		;[245] NO - THEN "U" ERROR
	SKIPE	PRNC		;[246] YES - INSIDE PARENTHESIS?
	 JRST	ERR		;[246] YES - ILLEGAL, "?" ERROR

UND4:	MOVEI	T,"#"
	CAIE	W,ASSEM-DDTOFS
	PUSHJ	P,TOUT
	MOVN	R,[XWD 2,2]
	ADDM	R,ESTUT
	MOVE	T,SYM
	TXO	T,GLOBL
	MOVX	R,1B1		;DEPOSIT INTO 1ST WORD OF UNDEF TABLE
	PUSHJ	P,DSYMER	;DEPOSIT AND TYPE ? IF IT FAILS
	HRRZ	T,LLOCO
	TXNE	F,MF
	TXO	T,STNEG		;SET FLAG TO SHOW SUBTRACTIVE REQUEST
	TXO	T,STADD		;SET FLAG TO SHOW UNCHAINED REQUEST
	ADDI	R,1
	PUSHJ	P,DSYMER
	MOVEI	T,0
	JRST	L4
;DDT'S COMMAND PARSER DETERMINES WHAT TYPE OF COMMAND THIS IS BY
;RANGE-CHECKING THE DISPATCH ADDRESS OF THE COMMAND TO SEE WHICH
;ONE OF THE BELOW REGIONS IT FALLS INTO, THEREFORE:
;
;
;			***** WARNING ******
;
;DO NOT MOVE A COMMAND ROUTINE ACROSS A REGION BOUNDARY UNLESS YOU KNOW
;WHAT YOU ARE DOING!  THE PARSER IS VERY UNFORGIVING IN THIS RESPECT!
;
;
;THE FOLLOWING CLASSES OF COMMAND EXIST:
;
;CLASS 1:	COMMANDS THAT TAKE NO ARGUMENT, OR THAT TAKE A SYMBOL
;		NAME WITHOUT EVALUATION.
;
;CLASS 2:	MULTIPLY AND DIVIDE.
;
;CLASS 3:	COMMANDS THAT ADD SOME FUNCTION OF THE UPCOMING QUANTITY
;		TO THE ACCUMULATING RESULT.
;
;CLASS 4:	LAST COMMANDS THAT ARE LEGAL INSIDE PARENTHESES.
;
;CLASS 5:	LAST COMMANDS THAT ARE LEGAL WHEN THE EXPRESSION
;		CONTAINS UNDEFINED SYMBOLS.
;
;CLASS 6:	EVERYTHING ELSE.  THESE COMMANDS TYPICALLY TAKE A
;		COMPLETELY EVALUATED EXPRESSION, THAT CANNOT CONTAIN
;		REFERENCES TO UNDEFINED SYMBOLS.
;
;
;NOTE THAT THESE CLASSES ARE ONLY APPROXIMATE.  REFER TO THE CODE IN
;THE COMMAND PARSER FOR DEFINITIVE INFORMATION.
SUBTTL	COMMAND DISPATCH TABLE

BDISP:	POINT	12,DISP(R),11
	POINT	12,DISP(R),23
	POINT	12,DISP(R),35
DISP:
DEFINE D (Z1,Z2,Z3)<
	BYTE	(12) Z1-DDTOFS,Z2-DDTOFS,Z3-DDTOFS
IFN	<<Z1-DDTOFS>!<Z2-DDTOFS>!<Z3-DDTOFS>>&<-1,,770000>,
	<PRINTX Z1, Z2, OR Z3 TOO LARGE FOR DISPATCH TABLE> >
;THIS MACRO PACKS 3 ADDRESSES INTO ONE WORD; EACH ADR IS 12 BITS


D (ERR,ERR,ERR);	(0)	^@   ^A   ^B
D (CNTRLZ,ERR,CNTRLE);	(3)	^C   ^D   ^E
D (ERR,ERR,VARRW);	(6)	^F   ^G   ^H
D (TAB,LINEF,ERR);	(11)	^I   ^J   ^K
D (ERR,CARR,ERR);	(14)	^L   ^M   ^N
D (ERR,ERR,ERR);	(17)	^O   ^P   ^Q
D (PUNCH,ERR,ERR);	(22)	^R   ^S   ^T
D (ERR,ERR,ERR);	(25)	^U   ^V   ^W
D (ERR,ERR,CNTRLZ);	(30)	^X   ^Y   ^Z
D (CONTROL,ERR,ERR);	(33)	^[   ^\   ^]
D (ERR,ERR,SPACE);	(36)	^^   ^_     
D (SUPTYO,TEXI,ASSEM);	(41)	 !    "    #
D (DOLLAR,PERC,ERR);	(44)	 $    %    &
D (DIVD,LPRN,RPRN);	(47)	 '    (    )
D (MULT,PLUS,ACCF);	(52)	 *    +    ,
D (MINUS,PERIOD,SLASH);	(55)	 -    .    /
D (NUM,NUM,NUM);	(60)	 0    1    2
D (NUM,NUM,NUM);	(63)	 3    4    5
D (NUM,NUM,NUM);	(66)	 6    7    8
D (NUM,TAG,SEMIC);	(71)	 9    :    ;
D (FIRARG,EQUAL,ULIM);	(74)	 <    =    >
D (QUESTN,INDIRE,ABSA);	(77)	 ?    @    A
D (BPS,CON,SYMD);	(102)	 B    C    D
D (EFFEC,SFLOT,GO);	(105)	 E    F    G
D (HWRDS,PILOC,BLKEND);	(110)	 H    I    J
D (KILL,LOADER,MASK);	(113)	 K    L    M
D (NWORD,BITO,PROCD);	(116)	 N    O    P
D (QUAN,RELA,SYMBOL);	(121)	 Q    R    S
D (TEXO,SETPAG,WATCH);	(124)	 T    U    V
D (DBLU,XEC,TAPIN);	(127)	 W    X    Y
D (ZERO,OCON,ICON);	(132)	 Z    [    \
D (OSYM,VARRW,UNDRL);	(135)	 ]    ^    _

;THIS TABLE DOES NOT HAVE ENTRIES FOR CHARS .GE. 140; THESE
; ARE DETECTED AS ERRORS NEAR L21:
SUBTTL	COMMAND ROUTINES -- CLASS 1

;*************** START OF CLASS ONE COMMANDS ***************

;"ERR" IS THE DISPATCH FOR ALL UNDEFINED COMMANDS.  VARIOUS COMMANDS
;ALSO JUMP TO ERR, WRONG, ETC. IF THEY DETECT SOME KIND OF ERROR.

WRONG:	MOVE	W1,[ASCII /XXX/]
	PUSHJ	P,TEXT
	JRST	WRONG6

ERR:	MOVEI	T,"?"		;DDT'S UBIQUITOUS QUESTION MARK
	JRST	WRONG2		;JOIN COMMON ERROR PROCESSING

MULDEF:	SKIPA	T,["M"]		;MULTIPLY-DEFINED SYMBOL
UNDEF:	MOVEI	T,"U"		;UNDEFINED SYMBOL
WRONG2:	MOVE	P,[IOWD LPDL,PDL]  ;ENSURE FRESH STACK
	PUSHJ	P,TOUT		;ISSUE ERROR MESSAGE
	PUSHJ	P,TBEL		;AND DINK THE USER

IFN	FTYANK,<		;IF COMMAND FILES SUPPORTED
	SKIPE	COMAND		;IN A COMMAND FILE?
	SKIPN	YASWF		;YES, ABORT ON COMMAND ERROR?
	JRST	WRONG4		;KEEP ON GOING (IGNORE ERROR)
	PUSHJ	P,PTRKIL	;KILL OFF THE COMMAND FILE
	PUSHJ	P,TBEL		;DINK THE USER
	PUSHJ	P,TBEL		; AGAIN
	TXZ	F,ROF		;ARBITRARILY CLOSE OPEN LOCATION
> ;END IFN FTYANK

WRONG4:	PUSHJ	P,TTYCLR	;CLEAR INPUT BUFFER
WRONG6:	TXNN	F,ROF		;REGISTER OPEN?
	JRST	DD1		;NO, CRLF.  OTHERWISE, FALL INTO RET

RET:	MOVE	P,[IOWD LPDL,PDL]
	PUSHJ	P,TTAB		;COMMON RETURN
	JRST	DD2
;HERE ON A DIGIT

NUM:	ANDI	T,17		;T HOLDS CHARACTER
	TXNE	F,CF!FPF
	JRST	NM1
	MOVE	W,SYL
	LSH	W,3
	ADD	W,T
	MOVEM	W,SYL
	MOVE	W,DEN
	IMULI	W,12		;CONVERT TO DECIMAL
	ADD	W,T
	MOVEM	W,DEN
	AOJA	T,LE1A

DOLLAR:	SKIPA	T,[46+101-13]	;RADIX 50 $ TO BE
PERC:	MOVEI	T,47+101-13	;PERCENT SIGN
LET:	TXC	F,SF!FPF	;EXPONENT IFF (LTF)'*(FEF)'*(T=105)*(SF)*(FPF)=1
	TXZN	F,LTF!FEF!SF!FPF
	CAIE	T,105		; E
	TXOA	F,LTF
	TXOA	F,FEF
	JRST	LET1
	TXZN	F,MF
	SKIPA	W1,SYL
	MOVN	W1,SYL
	MOVEM	W1,FSV
	CLEARM	DEN
LET1:	SUBI	T,101-13	;FORM RADIX 50 SYMBOL
LE1A:	TXO	F,SF!QF
LE2:	SOSGE	TEM		;IGNORE CHARACS AFTER 6
	JRST	L2
	MOVEI	W,50
	IMULM	W,SYM		;MULTIPLY BY RADIX 50
	ADDM	T,SYM		;  AND ADD NEW CHAR INTO SYM
	MOVEI	T,"A"-13(T)	;CONVERT LETTERS BACK TO ASCII
	IDPB	T,CHP
	JRST	L2
NUM1:	MOVE	W,WRD2O		;OCTAL FORM OF NUMBER AFTER $
	LSH	W,3
	ADD	W,T
	MOVEM	W,WRD2O
	EXCH	T,WRD2D		;DECIMAL FORM OF NUMBER AFTER $
	IMULI	T,12
	ADDM	T,WRD2D
	TRO	F,Q2F
	JRST	L2

NM1:	TXNE	F,CF
	JRST	NUM1
	MOVEI	W1,6		;FORM FLOATING POINT NUMBER
	AOS	NM1A
	XCT	NM1A		;MOVEI W2,..
	MOVSI	R,201400
NM1A1:	TRZE	W2,1
	FMPR	R,FT(W1)
	JUMPE	W2,NM1B
	LSH	W2,-1
	SOJG	W1,NM1A1
NM1B:	MOVSI	W1,211000(T)
	FMPR	R,W1		;COMPUTE VALUE OF NEW DIGIT
	FADRB	R,FH		;ADD VALUE INTO FLOATING NO.
	MOVEM	R,SYL
	AOJA	T,LE1A

POWER:	TXNN	F,FEF
	JRST	L4		;NO EXPONENT
	CAIE	W,PLUS
	CAIN	W,MINUS
	TROE	F,POWF
	TRZA	F,POWF
	JRST	(W)		; E+-

	MOVE	W2,DEN
	CLEARM	FRASE
	MOVEI	W1,FT-1
	TXZE	F,MF
	MOVEI	W1,FT01
	SKIPA	T,FSV
POW2:	LSH	W2,-1
	TRZE	W2,1
	FMPR	T,(W1)
	JUMPE	W2,L4
	SOJA	W1,POW2
PERIOD:	TXNN	F,CF!CCF	;$. OR $$. COMMAND?
	JRST	PERIO2		;NO, JUST . CHARACTER BY ITSELF
IFE	FTFILE,<		;YES
	SKIPN	BPTIP		;BREAKPOINT IN PROGRESS?
	JRST	ERR		;NO, THEN NOT LEGAL AFTER ALL
	TXNN	F,CCF		;$. OR $$. COMMAND?
	SKIPA	T,PCWRD		;$.  -- CURRENT $X PC
	MOVE	T,I.NPC		;$$. -- PREVIOUS $X PC
	TXZA	F,CF!CCF	;CLEAR CONTROL FLAGS
> ;END IFE FTFILE

IFN	FTFILE,<JRST ERR>	;ILLEGAL IN FILDDT

PERIO2:	MOVE	T,LLOC		;JUST ".", LAST LOCATION OPENED
	TXNE	F,SF
	MOVE	T,DEN
	MOVEM	T,SYL
	TXNE	F,FPF		;HAS A PERIOD BEEN SEEN BEFORE?
	TXO	F,LTF		;YES, TWO PERIODS MAKES A SYMBOL
	TXON	F,FPF!SF!QF
	MOVEI	T,0
	IDIVI	T,400
	SKIPE	T
	TLC	T,243000
	TLC	W1,233000
	FAD	T,[0]		;NORMALIZE T AND W1
	FAD	W1,[0]
	FADR	T,W1
	MOVEM	T,FH
	HLLZS	NM1A
	MOVEI	T,45		;RADIX 50 PERIOD
	JRST	LE2

IFE	FTFILE,<
PILOC:	MOVEI	T,SAVPI>	;GET ADDRESS FOR $I
QUANIN:	JRST	QUAN1

QUAN:	TXNN	F,CCF		;$Q OR $$Q, WHICH?
	SKIPA	T,LWT		;$Q STRAIGHT
	MOVS	T,LWT		;$$Q SWAPPED
QUAN1:	MOVEM	T,SYL
QUAN2:	TXO	F,SF!QF		;WRD,SYL STARTED
	TXZ	F,CF!CCF
	JRST	L2

;HERE WHEN ESC TYPED

CONTRO:	TXOE	F,CF
	TXO	F,CCF
	SETOM	WAKALL		;SET WAKEUP ON EVERYTHING
	JRST	L2

IFN	FTFILE,<PILOC==ERR>
QUESTN:	PUSHJ	P,TCRLF		;HERE FOR "?"
	TXNE	F,LTF		;HAS A SYMBOL BEEN TYPED?
	JRST	QLIST		;YES
	PUSHJ	P,USYSET	;NO, LIST UNDEFINED SYMBOLS

QUEST2:	SOSGE	R		;POINT TO NAME WORD OF PREVIOUS SYMBOL
	PUSHJ	P,ADVSYM	;DONE, SEE IF ANY MORE TABLE
	SKIPA	W2,@SYPTR	;GET THE NAME
	JRST	DD1		;ALL DONE, <CRLF> AND RESTART
	TXZ	W2,PNAME	;CLEAR FLAGS
	PUSHJ	P,PSYM		;TYPE THE SYMBOL
	PUSHJ	P,TCRLF		;END WITH A CRLF
	SOJA	R,QUEST2	;SKIP VAL WORD OF NEXT SYMBOL AND LOOP


;HERE TO LIST ALL REFERENCES TO A SYMBOL

QLIST:	PUSHJ	P,SYMSET	;SET UP TO WALK THROUGH TABLE

QLIST2:	SOSGE	R		;ANY MORE TABLE?
	PUSHJ	P,ADVSYM	;MAYBE NOT, CHECK IT OUT
	SKIPA	W1,@SYPTR	;YES, GET THE NEXT NAME
	JRST	DD1		;ALL DONE, <CRLF> AND GET NEXT COMMAND
	TXZE	W1,PNAME	;IS THIS THE NEXT MODULE NAME?
	JRST	QLIST4		;NO, GO SEE IF THE SYMBOL NAME MATCHES
	MOVE	W2,W1		;SAVE THIS MODULE NAME IN CASE WE MATCH
	SOJA	R,QLIST2	;GET NEXT NAME

QLIST4:	CAME	W1,SYM		;A MATCH?
	SOJA	R,QLIST2	;NO, PROCEED
	PUSHJ	P,PSYM		;YES, TYPE CURRENT MODULE NAME
	MOVE	W1,@SYPTR	;RETRIEVE FLAGS
	TXNN	W1,GLOBL	;A GLOBAL SYMBOL?
	JRST	QLIST6		;NO, GO TYPE CRLF
	PUSHJ	P,TSPC		;YES, TYPE " G"
	MOVEI	T,"G"		; . . .
	PUSHJ	P,TOUT		; . . .

QLIST6:	PUSHJ	P,TCRLF		;END LINE
	SOJA	R,QLIST2	;ON TO ANOTHER SYMBOL
;$K COMMAND -- SUPPRESS A SYMBOL TO DDT TYPEOUT OR DELETE IT ENTIRELY

KILL:	TXNN	F,LTF		;DELETE SYMBOLS
	JRST	ERR
	MOVE	S,SYM		;GET SYMBOL
	PUSHJ	P,DELCSH	;REMOVE SYMBOL FROM SYMBOL TABLE CACHE
	PUSHJ	P,EVAL
	JRST	KILL2
	MOVE	R,W1		;SYMBOL INDEX INTO R
	MOVE	T,W2		;FLAGS INTO T
	TXO	T,DELO		;ASSUME DELETE OUTPUT
	TXNE	F,CCF		;$$K?
	MOVX	T,DELO!DELI!37777B17	;MAKE SYM DELETED IN AND OUT
	PJRST	DSYMER		;DEPOSIT IF POSSIBLE


KILL2:	SKIPN	ESTUT		;ANY UNDEFINED TABLE?
	JRST	UNDEF		;NO, CAN'T FIND THE SYMBOL

KILL4:	PUSHJ	P,EVALU		;SEE IF ANY MORE OCCURENCES OF SYM
	  POPJ	P,		;NO, DONE
	PUSHJ	P,REMUN
	 JRST	ERR		;CAN'T MODIFY SYMTAB
	JRST	KILL4		;LOOK FOR MORE OCCURENCES


;$D ;DELETE LAST SYM & PRINT NEW

SYMD:	MOVE	R,SPSAV		;PICK UP POINTER TO LAST SYM
	JUMPE	R,ERR
	PUSHJ	P,FETSYM	;PICK UP SYMBOL
	  JRST	ERR		;CAN'T GET IT?
	MOVE	S,T		;COPY SYMBOL
	PUSHJ	P,DELCSH	;REMOVE IT FROM THE SYMBOL TABLE CACHE
	TXO	T,DELO		;TURN ON "SUPPRESS OUTPUT" BIT
	PUSHJ	P,DSYMER	;STORE BACK IN SYMBOL TABLE
	MOVE	T,LWT
	JRST	CONSYM		;PRINT OUT NEXT BEST SYMBOL
;COLON OR ALT COLON COMMANDS

TAG:	TXNE	F,CF		;DEFINE SYMBOL OR OPEN SYMBOL TABLE?
	JRST	NAMSET		;OPEN (SELECT) LOCAL SYMBOL TABLE
	TXNN	F,LTF		; NO LETTERS IS ERROR
	JRST	ERR		; GO SAY ERROR
	TXNE	F,FAF		; DEFINE SYMBOLS
	JRST	DEFIN		;A.LT.B:
	MOVE	W,LLOCO		;DEFINE SYMBOL (TAG) TO BE "."
	MOVEM	W,LLIMIT	;SAVE NEW TAG VALUE

DEFIN:	MOVE	S,LLIMIT	;GET VALUE BEING DEFINED
	PUSHJ	P,DELCSV	;REMOVE ANY CACHE SYMBOL USING THIS VALUE
	PUSHJ	P,EVAL		;DEFINED SYMBOL?
	JRST	DEF1		;NO - DEFINE
	MOVE	S,SYM		;YES - GET SYMBOL NAME BEING DEFINED
	PUSHJ	P,DELCSH	;REMOVE THE SYMBOL FROM THE CACHE
	MOVE	R,W1		;REMEMBER SYMBOL INDEX IN R
	JRST	DEF4		;REDEFINE EXISTING SYMBOL

DEF1:	TXZ	F,HSYMF		;ASSUME LOWSEG SYMBOL TABLE
	SKIPL	R,@SYMP		;DEFINE A NEW SYMBOL
	JRST	[PUSHJ	P,GETHSO	;NO ST, TRY HI SEG PTR
		JUMPE	T,ERR		;DIE IF NONE
		MOVEI	R,.JBHSM	;HI SEG SYMBOL TABLE PTR
		ADD	R,T		;ABSOLUTE
		SKIPL	T,SAVHSM	;GET CURRENT VALUE OF PTR
		JRST	ERR		;NONE THERE EITHER
		SUB	T,[2,,2]	;MAKE ROOM FOR NEW SYMBOL
		PUSHJ	P,DMEMER	;TRY TO UPDATE HISEG ST PTR
		MOVE	R,T		;PUT UPDATED PTR IN RIGHT AC
		TXO	F,HSYMF		;REMEMBER HISEG TABLE USED
		SKIPL	PRGM		;AN OPEN MODULE IN THE HIGH SEG?
		JRST	DEF2		;NO, CONTINUE
		AOS	PRGM		;YES, COMPENSATE FOR SUBTRACTING 2
		AOS	PRGM		;  FROM THE SYMBOL TABLE POINTER
		JRST	DEF2]		;CONTINUE
	SUB	R,[2,,2]
	MOVEM	R,@SYMP		;DECREMENT LO SEG SYM POINTER
	SKIPG	PRGM		;AN OPEN MODULE IN THE LOWSEG TABLE?
	JRST	DEF2		;NO, CONTINUE
	AOS	PRGM		;YES, COMPENSATE FOR THE SUB
	AOS	PRGM		; . . .
DEF2:	SOS	ESTUT		;EAT TWO WORDS OF PATCH SPACE
	SOS	ESTUT		;  FOR NEW SYMBOL TO LIVE IN
	SKIPL	ESTUT		;DOES AN UNDEFINED TABLE EXIST?
	JRST	DEF3		;NO

;FALL THROUGH TO NEXT PAGE
;HERE WHEN WE WANT TO INSERT A NEW SYMBOL, BUT THE UNDEFINED SYMBOL
;TABLE IS IN THE WAY.  MOVE THE LAST SYMBOL OF THE UNDEFINED TABLE TO
;RIGHT BEFORE THE FIRST ONE, AND USE THE WORDS FREED TO INSERT THE NEW
;DEFINED SYMBOL.  THIS IS OK BECAUSE THE UNDEFINED TABLE IS NOT ORDERED.

	HLRE	R,ESTUT		;GET -LENGTH OF UNDEFINED TABLE
	MOVN	R,R		;POINT TO 1ST WORD NOT IN UNDEFINED TABLE
	TXO	R,1B1		;FORM AN UNDEFINED ST SYMBOL INDEX
	PUSHJ	P,FETSYM	;GET 1ST WORD OF LAST SYMBOL
	  JRST	ERR		;ERROR?
	MOVE	W1,R		;SAVE WHERE WE GOT IT
	MOVX	R,1B1		;POINT TO 1ST WORD (USED TO BE IN PATCH AREA)
	PUSHJ	P,DSYMER	;STORE SYMBOL IN NEW HOME
	AOS	R,W1		;POINT TO 2ND WORD OF LAST SYMBOL
	PUSHJ	P,FETSYM	;GET IT
	  JRST	ERR		;ERROR
	MOVX	R,1B1+1		;2ND WORD OF TABLE
	PUSHJ	P,DSYMER	;DEPOSIT


;NOW TO STORE THE SYMBOL TO BE DEFINED.  ENTER AT DEF3 TO APPEND TO THE
;SYMBOL TABLE AS A GLOBAL DEFINITION IN MODULE PAT.., AND AT DEF4 TO
;UPDATE AN EXISTING SYMBOL.

DEF3:	MOVE	T,ESTUT		;IT ALL WORKED, MAKE OUR WORKING COPY OFFICIAL
	MOVEM	T,@USYMP	;BY STORING IT IN THE GLOBAL PLACE
	PUSH	P,SYM		;IF APPENDING, NEED TO UPDATE THE MODULE
	MOVX	R,<RADIX50 0,PAT..>	;  LENGTH FOR THE MODULE "PAT.."
	MOVEM	R,SYM		;SAVE WHERE NAMSRH CAN FIND IT
	PUSHJ	P,NAMSRH	;LOOK UP PAT.. IN THE TABLE
	  JRST	DEF3A		;NOT THERE, GIVE UP
	PUSHJ	P,FETSYM	;GET ITS VALUE WORD
	  JRST	DEF3A		;NOT ACCESSIBLE?
	JUMPGE	T,DEF3A		;DON'T IF COUNT IS 0 (OLD LINK BUG)
	SUB	T,[2,,0]	;COUNT ANOTHER SYMBOL
	PUSHJ	P,DEPSYM	;STORE NEW VALUE
	  JFCL			;??
DEF3A:	POP	P,SYM		;RESTORE SYM FOR DEF4
	TXNN	F,HSYMF		;CHANGING HISEG TABLE?
	TDZA	R,R		;NO, POINT TO 0'TH WORD OF LOWSEG TABLE
	MOVX	R,1B0		;YES, POINT TO 0'TH WORD OF HISEG TABLE
DEF4:	MOVX	T,GLOBL
	IOR	T,SYM
	PUSHJ	P,DSYMER
	MOVE	T,LLIMIT
	ADDI	R,1
	PUSHJ	P,DSYMER

;FALL THROUGH TO NEXT PAGE
;NOW TO SEARCH THE UNDEFINED TABLE, LOOKING FOR REFERENCES TO THIS SYMBOL.
;IF WE FIND ANY, FIX UP THE LOCATION(S) THEY POINT TO, AND REMOVE THEM
;FROM THE UNDEFINED TABLE.

DEF5:	PUSHJ	P,EVALU		;SEARCH UNDEFINED TABLE
	  POPJ	P,		;NOT FOUND, ALL DONE
	SKIPL	R,T		;ADDITIVE OR CHAINED FIXUP?
	JRST	DEF7		;CHAINED, GO HANDLE
	PUSHJ	P,FETCHL	;GET OBJECT CELL
	 JRST	ERR
	TXNN	R,STNEG		;ADDITIVE OR SUBTRACTIVE?
	SKIPA	S,LLIMIT	;ADDITIVE
	MOVN	S,LLIMIT	;SUBTRACTIVE
	TXNE	R,STLH		;RIGHT OR LEFT HALF?
	JRST	[HRLZS	S	;LEFT HALF
		ADD	T,S	;ADD INTO LEFT HALF
		JRST	DEF6]
	ADD	S,T		;RIGHT HALF, ADD HALVES
	HRR	T,S		;  AND REPLACE RIGHT HALF
DEF6:	PUSHJ	P,STOREL	;STORE RESULT BACK INTO LOCAL SECTION MEMORY
	 JRST	ERR		;FAILED
	JRST	DEF8		;GO REMOVE SYMBOL AND TRY AGAIN

DEF7:	JUMPE	R,DEF8		;IF CHAIN REACHES 0, WE'RE DONE
	PUSHJ	P,FETCHL	;GET OBJECT CELL
	 JRST	ERR
	HRRZ	S,T		;SAVE CHAIN POINTER
	HRR	T,LLIMIT	;REPLACE WITH NEW VALUE
	PUSHJ	P,STOREL	;AND STORE BACK INTO LOCAL SECTION MEMORY
	 JRST	ERR		;FAILED
	HRRZ	R,S		;LOOP TO END
	JRST	DEF7		;  OF CHAIN

DEF8:	PUSHJ	P,REMUN
	 JRST	ERR		;CAN'T MODIFY SYMTAB
	JRST	DEF5
;HERE ON A NAME$: COMMAND -- OPEN A MODULE'S SYMBOL TABLE

NAMSET:	TXNE	F,QF		;ANYTHING TYPED?
	JRST	NAMS2		;YES, SET NEW MODULE
	SETZM	PRGM		;NO, JUST CLEAR CURRENT MODULE
	SETZM	SEGNAM		;AND HISEG IT CAME FROM
	PJRST	CLRCSH		;ZERO THE SYMBOL TABLE CACHE AND RETURN


;HERE TO SET A NEW MODULE NAME.

NAMS2:	PUSHJ	P,NAMSRH	;SEARCH FOR THE NAME
	  JRST	UNDEF		;NOT FOUND
	PUSHJ	P,CLRCSH	;FOUND IT, CLEAR THE SYMBOL TABLE CACHE
	MOVEM	R,PRGM		;STORE AS NEW OPEN MODULE
	JUMPGE	R,CPOPJ		;DONE IF R POINTS TO LOW SEG
	MOVEI	R,.JBHNM	;POINTS TO HI SEG, POINT TO SEGMENT NAME
	PUSHJ	P,HFETCH	;GET IT
	  MOVEI	T,0		;NO HI SEG, OR EXEC MODE
	MOVEM	T,SEGNAM	;STORE SEGMANT NAME FOR SYMCHK
	POPJ	P,		;DONE
;TEXT COMMANDS:	"X$, $"X$, "/.../, $"/.../, XXXX$5"

TEXI:	TRZE	F,Q2F		;QUANT AFTER $ ?
	JRST	[MOVE	T,WRD2D	;YES
		CAIE	T,5	; $5" ?
		JRST	ERR	;NO, ONLY CASE KNOWN
		MOVE	T,SYM	;YES, TAKE PREVIOUS SYL AS RADIX50
		TXZ	F,FPF!FEF!LTF	;REINIT SYL
		JRST	QUAN1]
	TXO	F,TXF		;FLAG PROCESSING TEXT 
	MOVE	T,LLOCO		;GET ADR OF OPEN REG
	MOVEM	T,TEM		;SAVE IT FOR LOCAL USE
	PUSHJ	P,TEXIN0	;GET TERMINATOR
	MOVEM	T,SYL		;SAVE TERMINATOR
	PUSHJ	P,TIN		;GET FIRST CHARACTER
	CAIN	T,.CHESC	;ESC?
	JRST	QUAN2		;YES, EQUALS ONE ASCII/SIXBIT CHAR
	PUSHJ	P,TEXIN1	;CONVERT TO SIXBIT IF NECESSARY
TEXI4:	MOVE	W1,[POINT 7,W]	;SETUP TO BUILD WORD IN W
	TXNE	F,CF		;SIXBIT?
	HRLI	W1,(POINT 6,0)	;YES, MODIFY BYTE POINTER
	MOVEI	W,0		;INIT WORD TO 0
TEXI2:	CAMN	T,SYL		;REACHED TERMINATOR?
	JRST	[MOVE	R,TEM	;LAST ADDRESS
		MOVEM	R,LLOC	;SET LOC TO END OF INPUT
		MOVEM	R,LLOCO
		MOVE	T,W	;GET LAST WORD
		JRST	QUAN1]	;GO USE AS QUANTITY
	TXNN	W1,76B5		;ROOM FOR ANOTHER BYTE IN WORD?
	JRST	TEXI3		;NO
	IDPB	T,W1		;YES, STORE IT
	PUSHJ	P,TEXIN0	;GET ANOTHER INPUT CHARACTER
	JRST	TEXI2
;HERE WHEN WORD FULL

TEXI3:	MOVSI	W1,(POINT 0,0)
	TXNN	F,ROF		;REGISTER OPEN?
	JRST	TEXI2		;NO, LOSE ANY ADDITIONAL INPUT
	PUSH	P,T		;SAVE CHARACTER
	MOVE	T,W		;GET FULL WORD
	MOVE	R,TEM		;GET LOC OF NEXT REGISTER
	PUSHJ	P,DMEMER	;STORE WORD IF POSSIBLE
	AOS	TEM		;BUMP LOC
	POP	P,T		;RECOVER CHARACTER
	JRST	TEXI4		;GO REINIT WORD AND CONTINUE INPUT

;GET INPUT CHARACTER, CONVERT TO SIXBIT IF NECESSARY

TEXIN0:	PUSHJ	P,TIN		;GET CHAR
TEXIN1:	TXNN	F,CF		;SIXBIT MODE?
	POPJ	P,		;NO
	CAIL	T,"A"+40	;IS CHAR BETWEEN LOWER CASE "A" AND
	CAILE	T,"Z"+40	; LOWER CASE "Z"?
	SKIPA			;NO
	TRC	T,40		;YES, CONVERT TO UPPER CASE
	CAIL	T," "		;IS CHAR IN SIXBIT SET?
	CAILE	T,"_"
	JRST	ERR		;NO
	ANDI	T,77		;YES, MASK TO 6 BITS
	TRC	T,40		;CONVERT TO SIXBIT FORM
	POPJ	P,
;$L COMMAND -- PUNCH RIM10B LOADER

IFN FTPTP,<

LOADER:	SKPUSR
	TXNE	F,QF
	JRST	ERR
	MOVEI	T,400
	PUSHJ	P,FEED
	MOVE	R,LOADE
LOAD1:	MOVE	T,0(R)
	PUSHJ	P,PWRD
	AOBJN	R,LOAD1
	MOVEI	T,20
LOAD2:	PUSHJ	P,FEED
	JRST	RET


;RIM10B CHECKSUM LOADER

LOADB:

.PHASE 0
	XWD	-16,0
BEG:	CONO	PTR,60
	HRRI	AA,RD+1
RD:	CONSO	PTR,10
	JRST	.-1
	DATAI	PTR,@TBL1-RD+1(AA)
	XCT	TBL1-RD+1(AA)
	XCT	TBL2-RD+1(AA)
AA:	SOJA	AA,

TBL1:	CAME	CKSM,ADR
	ADD	CKSM,1(ADR)
	SKIPL	CKSM,ADR

TBL2:	JRST	4,BEG
	AOBJN	ADR,RD
ADR:	JRST	BEG+1
CKSM=ADR+1

.DEPHASE

LOADE:	XWD	LOADB-.,LOADB


> ;END IFN FTPTP

IFE FTPTP,<LOADER==ERR>
;DDT EXIT AND RESTART COMMANDS (^C, ^E, AND ^Z)

;FIRST, THE NON-FILDDT CASE

IFE	FTFILE,<
CNTRLZ:

IFN FTEXEC,<
	SKPUSR			;SEE IF USER MODE
	JRST	ERR		;NO--ERROR  
> ;END IFN FTEXEC

IFN	FTDEC10,<MOVE	T,[EXIT 1,]>	;GET MONRET
IFN	FTDEC20,<MOVE	T,[HALTF%]>	;HALT THIS FORK

	JRST	XEC0		;GO EXECUTE IT


	CNTRLE==ERR		;^E ONLY WORKS IN FILDDT

>; END IFE FTFILE


;NOW THE FILDDT ROUTINES

IFN FTFILE,<

CNTRLZ:	PUSHJ	P,CLSFIL	;CLOSE OFF THE INPUT FILE
	RESET			;CLEAN UP THE WORLD

IFN	FTDEC10,<EXIT 1,>	;RETURN TO THE MONITOR
IFN	FTDEC20,<HALTF%>	; . . .

	JRST	DDT		;USER SAID "CONTINUE"


;HERE ON ^E COMMAND.  CLOSE THE CURRENTLY-OPEN FILE AND RESTART.


CNTRLE:	PUSHJ	P,CLSFIL	;CLOSE OFF THE INPUT FILE
	RESET			;MAKE SURE
	JRST	DDT		;RESTART
;STILL FTFILE

;HERE TO WRITE OUT THE MODIFIED WINDOWS AND CLOSE THE INPUT FILE

CLSFIL:	SKIPN	FILING		;SEE IF NOT /M
	POPJ	P,		;NO FILE CLOSE ON /M
	SKIPN	PATCHS		;/P?
	JRST	FILREL		;NO, JUST RELEASE THE CHANNEL
	SKIPN	CHGSFL		;SEE IF SYMBOL TABLE CHANGED
	JRST	SCPDON		;JUMP IF NOT
	SKIPE	SYMGOT		;YES, DID IT COME FROM ANOTHER FILE?
	SKIPE	PHYSIO		;OR ARE WE DOING PHYSICAL I/O?
	JRST	SCPDON		;YES TO EITHER, NO RE-WRITING SYM TAB


;WE KNOW WE WANT TO WRITE THE SYMBOLS BACK, NOW SEE IF SAFE TO DO SO.
;DON'T WANT TO IF THE USER CHANGED A SYMBOL TABLE POINTER, SINCE HE
;PROBABLY KNOWS WHAT'S GOING ON BETTER THAN WE DO.

	MOVEI	R,.JBSYM	;RE-FETCH FILE'S .JBSYM
	PUSHJ	P,FETCH		;GET FROM THE FILE
	  SETCM	T,FOSPTR	;NOT THERE? MAKE SURE COMPARE FAILS
	CAME	T,FOSPTR	;SAME AS WHEN SYMS WERE COPIED?
	JRST	SCPERR		;NO, USER DEPOSITED .JBSYM -- ABORT
	EXCH	T,FISPTR	;STORE CURRENT .JBSYM IN FISPTR
	MOVEM	T,FOSPTR	;STORE PTR INTO FILDDT IN FOSPTR
	MOVEI	R,.JBUSY	;POINT TO FILE'S .JBUSY
	PUSHJ	P,FETCH		;FETCH IT
	  SETCM	T,FOUPTR	;GONE??
	MOVE	W,FIUPTR	;SAVE FILDDT'S UNDEFINED PTR
	MOVE	W1,SAVHSM	;AND FILDDT'S HISEG PTR
	MOVEM	T,FIUPTR	;SET UP PTRS FOR SYMCHK
	PUSHJ	P,SYMCHK	;MAKE SURE VALID, SETUP FIUPTR & SAVHSM
	EXCH	W,FOUPTR	;STORE FILDDT'S PTRS IN OLD SYM VARS
	EXCH	W1,OLDHSM	;  AND FETCH FILE VALUES ON ENTRY
	CAMN	W,FIUPTR	;DID .JBUSY CHANGE?
	CAME	W1,SAVHSM	;DID .JBHSM CHANGE?
	JRST	SCPERR		;YES, DON'T COPY BACK
	XOR	W1,OLDHSM	;DOES FILDDT'S COUNT AGREE WITH FILE'S?
	TLNE	W1,-1		;MUST AGREE, SINCE NO ROOM FOR PATCHING
	JRST	SCPERR		;DIFFERENT, GIVE UP

;FALL THROUGH TO NEXT PAGE
;STILL FTFILE

;FALL IN FROM PREVIOUS PAGE

;IT'S OK TO UPDATE THE FILE'S SYMBOL TABLE.  NOW PUT THE FILE'S NEW
;POINTERS INTO FI?PTR AND SAVHSM (FILDDT'S PTRS ARE ALREADY IN FO?PTR
;AND OLDHSM).

	HLLO	T,FISPTR	;GET OLD SYMBOL COUNT
	SUB	T,FOSPTR	;SUBTRACT TO GET DIFF IN LH
	HLR	T,T		;FORM N,,N
	EXCH	T,FISPTR	;GET OPERANDS IN ORDER FOR SUBTRACT
	SUBB	T,FISPTR	;BACK .JBSYM UP INTO PATCH SPACE
	HLRE	S,FOUPTR	;GET -COUNT OF NEW UNDEF S.T.
	ADD	T,S		;GET START ADDRESS OF NEW UNDEF S.T.
	HLL	T,FOUPTR	;FORM -N,,ADDR (.JBUSY FORMAT)
	MOVEM	T,FIUPTR	;SAVE FOR LATER UPDATE


;NOW COPY THE UNDEFINED TABLE INTO THE FILE.

	HRRZ	R,FIUPTR	;WHERE IN THE FILE TO PUT THE DATA
	SKIPL	W1,FOUPTR	;AOBJN PTR TO FILDDT'S UNDEFS, IF ANY
	JRST	NOUCPY		;NOTHING TO COPY, JUST GO UPDATE .JBUSY
OUCPY:	MOVE	T,(W1)
	PUSHJ	P,DEPMEM
	JRST	SCPERR		;GIVE UP COPY IF CAN'T STORE
	AOS	R
	AOBJN	W1,OUCPY


;NOW UPDATE .JBUSY (EVEN IF NO UNDEFS), THEN COPY THE DEFINED SYMBOLS

NOUCPY:	MOVE	T,FIUPTR	;DATA TO STORE
	MOVEI	R,.JBUSY	;WHERE TO STORE IT
	PUSHJ	P,DEPMEM	;DO THE STORE
	  JRST	SCPERR		;FAILED

	HRRZ	R,FISPTR	;WHERE IN THE FILE TO PUT THE SYMS
	SKIPL	W1,FOSPTR	;AOBJN PTR TO FILDDT'S SYMS
	JRST	NOSCPY		;NONE TO COPY, GO LOOK FOR HIGH SEG SYMS
OSCPY:	MOVE	T,(W1)
	PUSHJ	P,DEPMEM
	JRST	SCPERR		;ERROR
	AOS	R
	AOBJN	W1,OSCPY

;FALL THROUGH TO NEXT PAGE
;STILL FTFILE

;FALL IN FROM PREVIOUS PAGE

;NOW UPDATE .JBSYM, THEN COPY ANY HIGH SEG SYMBOLS.  NOTE THAT WE DON'T
;UPDATE .JBHSM, SINCE IT'S AN ERROR ABOVE IF IT CHANGED.

NOSCPY:	MOVE	T,FISPTR	;THE DATA TO STORE
	MOVEI	R,.JBSYM	;WHERE TO STORE IT
	PUSHJ	P,DEPMEM	;STORE NEW POINTER
	  JRST	SCPERR		;COMPLAIN IF ERROR

	HRRZ	R,SAVHSM	;WHERE TO STORE THE HIGH SEG SYMS
	SKIPL	W1,OLDHSM	;GET AOBJN PTR TO FILDDT'S, IF ANY
	JRST	SCPDON		;NONE, ALL DONE WITH COPY
HSCPY:	MOVE	T,(W1)		;GET NEXT DATA WORD
	PUSHJ	P,DEPMEM	;STORE IN FILE
	  JRST	SCPERR		;ERROR?
	AOS	R		;BUMP PTR INTO FILE
	AOBJN	W1,HSCPY	;LOOP OVER ALL OF FILDDT'S SYMBOLS
	JRST	SCPDON		;DONE UPDATING SYMBOLS


;HERE IF WE TRIED BUT FAILED TO UPDATE THE FILE'S SYMBOL TABLE.

SCPERR:	TMSG	<
% Update of file's symbol table failed
>

;FALL INTO SCPDON
;STILL UNDER FTFILE

;FALL HERE FROM PREVIOUS PAGE

;OPERATING SYSTEM DEPENDENT ROUTINES TO CLOSE OUT THE FILE

SCPDON:
IFN	FTDEC20,<
	SKIPN	PHYSIO		;PHYSICAL I/O?
	JRST	FILREL		;NO, JUST UNMAP THE PAGES
>
	SETZM	WINNUM		;START WITH WINDOW ZERO
WRTLP:	MOVE	TT2,WINNUM	;GET WINDOW NUMBER
	MOVE	T,WINDIR(TT2)	;GET PAGTBL ADDRESS
	TXNN	T,SV$MOD	;DID THIS PAGE GET MODIFIED?
	JRST	WRTLP2		;NO
	MOVE	TT1,WINFPN(TT2)	;YES, FILE PAGE NUMBER
	PUSHJ	P,WRTWIN	;WRITE THE WINDOW
	  JFCL			; SIGH
WRTLP2:	AOS	TT2,WINNUM	;STEP TO NEXT WINDOW
	CAIGE	TT2,WINMAX	;MORE?
	JRST	WRTLP		;YES--KEEP GOING

;ALL WINDOWS WRITTEN OUT, CLOSE OFF THE FILE

IFN	FTDEC10,<
FILREL:	CLOSE	FIL,		;TELL MONITOR WE'RE DONE WITH FILE
	STATZ	FIL,IO.ERR	;ALL OK?
	TMSG	<
? OUTPUT error on CLOSE
>
	RELEAS	FIL,		;GIVE UP CHANNEL
	POPJ	P,		;AND RETURN
> ;END OF IFN FTDEC10

IFN	FTDEC20,<
FILREL:	SKIPE	PHYSIO		;PHYSICAL I/O?
	POPJ	P,		;YES, DON'T BOTHER
	SETO	T1,		;WANT TO "CLOSE" THE FILE
	MOVE	T2,WIND0	;BASE ADDRESS OF "BUFFERS"
	LSH	T2,WRD2PG	;BASE PAGE NUMBER
	HRLI	T2,.FHSLF	;THIS PROCESS
	MOVX	T3,PM%CNT!WINMAX;GET ALL INTERNAL "WINDOWS"
	PMAP%			;UNMAP ALL POSSIBLE MAPPED FILE PAGES
	MOVE	T1,FILJFN	;JFN OF OPEN FILE
	CLOSF%			;CLOSE OFF THE FILE
	 JFCL			; ???
	POPJ	P,		;RETURN
> ;END OF IFN FTDEC20

> ;END IFN FTFILE FROM PAGES AGO
SUBTTL	COMMAND ROUTINES -- CLASS 2

;*************** START OF CLASS TWO COMMANDS ***************

MULT:	TXOA	F,PTF!MLF	;*
DIVD:	TXO	F,DVF!PTF	;SINGLE QUOTE
	JRST	L1
SUBTTL	COMMAND ROUTINES -- CLASS 3

;*************** START OF CLASS THREE COMMANDS ***************

ASSEM:	JRST	LIS2		;[242] #
MINUS:	TXO	F,MF
PLUS:	TXO	F,PTF
	JRST	LIS2

LPRN:	PUSH	P,F		;RECURSE FOR OPEN PAREN
	PUSH	P,WRD
	PUSH	P,FRASE
	PUSH	P,FRASE1
	AOS	PRNC
	SETZM	WAKALL		;[242] SET WAKEUP SET TO PUNCT AND CTRLS
	JRST	LIS0C		;[242] AND READ NEW EXPRESSION

INDIRE:	HRLZI	W,20		;@
	IORB	W,WRD
	TXO	F,QF
	JRST	LIS2


ACCF:	MOVE	R,ESTUT		;[246] GET UNDEFINED PROCESSOR SO FAR
	CAME	R,@USYMP	;[246] ANY UNDEFINED'S CREATED YET?
	 JRST	ERR		;[246] YES, ERROR
				;[246] (CAN ONLY GET HERE ON "FOO#," ETC.)
	MOVE	R,T		;COMMA PROCESSOR
	XCT	ACCCF		;MOVEI T,..
	TXOE	F,COMF		;COMMA TYPED BEFORE?
	JRST	ACCF1		;YES
	HRRM	R,ACCCF		;NO, SAVE LEFT HALF OF A,,B
	HLLZ	T,R
	LDB	W1,[POINT 3,WRD,2]	;CHECK FOR IO INSTRUCTION
	CAIE	W1,7		;7XX?
	JRST	ACCF0		;NO, ASSUME AC FIELD
	MOVX	W1,774B11	;YES, CHECK DEVICE CODE FIELD
	TDNE	W1,WRD		;DEVICE CODE FILLED IN YET?
ACCF0:	TDZA	W1,W1		;YES, OPCODE WAS UMOVE, RDTIME, ETC.
				;  ASSUME AC FIELD
	MOVEI	W1,1		;NO, OPCODE WAS CONO, DATAO, ETC.
				;  ASSUME DEVICE CODE
	LSH	R,27(W1)	;MOVE QUANTITY TO CORRECT FIELD
	ADD	T,R
	ADDB	T,WRD
	JRST	SPACE1

ACCF1:	ADD	T,WRD		; FOR ",," GET LEFT HALF TOGETHER
	HRLZM	T,WRD		; AND PUT IT IN LEFT HALF
	JRST	SPACE1
SUBTTL	COMMAND ROUTINES -- CLASS 4

;*************** START OF CLASS FOUR COMMANDS ***************

SPACE:	TXO	F,SPF		;(E.G., "JRST PAT..") FLAG SPACE TYPED
SPACE1:	TXO	F,TIF		;FLAG TRUNCATE (ADD MOD 2**18)
	TXZ	F,MF!PTF
	JRST	LIS1


RPRN:	TXNN	F,QF		;)
	MOVEI	T,0
	MOVS	T,T
	SOSGE	PRNC
	JRST	ERR
	POP	P,FRASE1
	POP	P,FRASE
	POP	P,WRD
	POP	P,F
	TXNE	F,PTF
	TXNE	F,SF
	JRST	RPRN1
	MOVEM	T,SYL
	TXO	F,QF!SF
	JRST	L1RPR
RPRN1:	ADDB	T,WRD
	TXO	F,QF
	JRST	L1A
SUBTTL	COMMAND ROUTINES -- CLASS 5

;*************** START OF CLASS FIVE COMMANDS ***************

;CRLF AND OPEN NEXT REGISTER SUBROUTINE

LI0:	PUSHJ	P,TCRLF		;TYPE <CR><LF>
	JRST	LINEF0		;JOIN COMMON CODE


;"^" COMMAND - CLOSE CURRENT AND OPEN PREVIOUS SEQUENTIAL LOCATION

VARRW:	PUSHJ	P,DEPRA		;^
	PUSHJ	P,TCRLF		;TYPE <CR><LF>
	SOS	T,LLOC		;DECREMENT CURRENT LOCATION COUNTER
	JRST	LI1		;JOIN COMMON CODE


;<LF> COMMAND, CLOSE CURRENT AND OPEN NEXT SEQUENTIAL LOCATION

LINEF:	PUSHJ	P,DEPRA		;NEXT REGISTER
	PUSHJ	P,TCR		;DO CR ONLY
LINEF0:	AOS	T,LLOC		;BUMP LOC
LI1:	MOVEM	T,LLOC		;NEW LAST LOCATION
	MOVEM	T,LLOCO		;NEW LAST LOCATION OPEN
	PUSHJ	P,PADR		;PRINT AS ADDRESS
	MOVEI	T,"/"		;"/" TO INDICATE OPEN ADDRESS
	CAME	SCH,SCHM	;TEMP MODE SAME AS PERM?
	JRST	[CAIN	SCH,FTOC  ;NO, CONSTANT?
		MOVEI	T,"["	;YES - INDICATE "[" MODE
		CAIN	SCH,PIN	;INSTRUCTION?
		MOVEI	T,"]"	;YES - INDICATE "]" MODE
		JRST	.+1]	;USE APPROPRIATE INDICATION
	TXNE	F,STF		;SUPPRESSING OUTPUT?
	MOVEI	T,"!"		;YES - THEN OVER-RIDE WITH "!" MODE
	PUSHJ	P,TOUT		;TELL USER WHAT IS HAPPENING
LI2:	PUSHJ	P,TTAB		;TYPE A <TAB>
	TXO	F,ROF		;MARK REGISTER OPEN
	TXNE	F,STF		;SUPPRESS TYPEOUT OF LOCATION?
	POPJ	P,		;YES, DONE
	MOVE	R,LLOCO		;GET ADDRESS OF OPEN LOC
	MOVEI	W1,"?"		;TYPE ? IF FETCH FAILS
	PUSHJ	P,FETCH		;FETCH CONTENTS
	 JRST	TEXT		;CAN'T -- GO TYPE ?
	PJRST	CONSYM		;LIST CONTENTS OF OPEN LOC
;<CR> COMMAND - CLOSE CURRENT LOCATION

CARR:	PUSHJ	P,DEPRA		;CLOSE REGISTER
	PUSHJ	P,TIN		;GLOBBLE UP FOLLOWING LINEFEED
	SETZM	CHINP		;REINIT INPUT LINE
	SETZM	CHINC
	MOVE	T,LLOC		;GET CURRENT LOC
	TXNE	F,CF		; $ PRECEEDED?
	JRST	LI1		;YES, GO OPEN REGISTER
	JRST	DD1.5		;NO, JUST GO AWAIT COMMAND
SUBTTL	COMMAND ROUTINES -- CLASS 6

;*************** START OF CLASS SIX COMMANDS ***************

SUBTTL	COMMAND ROUTINES -- REGISTER DEPOSIT AND OPEN

;"\" COMMAND - OPEN NEW LOCATION, PRESERVING PC SEQUENCE

ICON:	PUSHJ	P,DEPRA		;BACKSLASH
	PUSHJ	P,CEFFAD	;COMPUTE EFF ADR
	 JRST	ERR		;MEMORY READ ERROR
	JRST	SLASH4		;JOIN COMMON CODE


;<TAB> COMMAND - OPEN NEW LOCATION, BREAKING PC SEQUENCE

TAB:	PUSHJ	P,DEPRA		;OPEN REGISTER OF Q
	PUSHJ	P,CEFFAD	;COMPUTE EFF ADR
	 JRST	ERR		;MEMORY READ ERROR
	SUBI	T,1		;CAUSE LI0 AOS'S LLOC
	PUSHJ	P,PSHLLC	;PUSH OLD SEQUENCE
	MOVEM	T,LLOC		;SETUP NEW SEQUENCE
	JRST	LI0		;JOIN COMMON OPEN/TYPEOUT CODE


;"[" COMMAND - OPEN LOCATION IN CONSTANT TYPEOUT MODE

OCON:	TXNE	F,QF		;QUANT TYPED?
	MOVEI	SCH,FTOC	;YES, CHANGE TEMP MODE TO CONSTANT
	TRO	F,LF1+CF1	;OPEN AS CONSTANT
	JRST	SLASH		;TYPE
;"]" COMMAND - OPEN LOCATION IN SYMBOLIC TYPEOUT MODE

OSYM:	TXNE	F,QF		;QUANT TYPED?
	MOVEI	SCH,PIN		;YES, CHANGE TEMP MODE TO INSTRUCTION
	TRZ	F,CF1		;OPEN SYMBOLICALLY
	TROA	F,LF1		; . . .
				;SKIP/FALL INTO SLASH ROUTINE


;"!" COMMAND - OPEN LOCATION SUPPRESSING TYPEOUT OF CONTENTS

SUPTYO:	TXOA	F,STF		;SUPPRESS TYPEOUT
				;SKIP/FALL INTO COMMON CODE


;"/" COMMAND - OPEN A NEW LOCATION IN CURRENT TYPEOUT MODE

SLASH:	TXZ	F,STF		;TYPE OUT NOT SUPPRESSED
	PUSHJ	P,CEFFAD	;COMPUTE EFF ADR
	 JRST	ERR		;MEMORY READ ERROR
	TXNN	F,QF		;WAS ANY QUANTITY TYPED?
	JRST	SLASH4		;NO. DO NOT CHANGE MAIN SEQUENCE
	PUSHJ	P,PSHLLC	;PUSH OLD SEQUENCE
	MOVEM	T,LLOC		;SETUP NEW SEQUENCE
SLASH4:	MOVEM	T,LLOCO		;SET NEW OPEN LOCATION
	JRST	LI2		;AND GO HANDLE TYPEOUT
;CEFFAD - CALCULATE ADDRESS ARGUMENT FOR "/", "!", ETC.
;CALL IS:
;
;	MOVX	T,<ADDR-EXPR>
;	PUSHJ	P,CEFFAD
;	 ERROR RETURN
;	NORMAL RETURN
;
;WHERE <ADDR-EXPR> IS THE EXPLICITLY-TYPED ADDRESS EXPRESSION (IF
;ANY).
;
;BASICALLY ADDRESSING NOW WORKS AS FOLLOWS:
;
;IF AN EXPLICIT QUANTITY HAS NOT BEEN TYPED BY THE USER THEN
;THE LAST WORD TYPED IS USED AS THE BASIS FOR ADDRESS CALCU-
;LATION. IF THE DDT COMMAND (E.G., "/") WAS PREFIXED WITH A
;SINGLE <ESC> THEN THE FULL-WORD VALUE FROM ABOVE WILL BE TREA-
;TED AS AN INSTRUCTION-FORMAT-INDIRECT-WORD (IFIW) WHOSE EFFEC-
;TIVE ADDRESS "E" WILL BE CALCULATED AS IT WOULD BE BY THE HARD-
;WARE WERE IT TO EXECUTE THE WORD AS AN INSTRUCTION (ASSUMING
;A VALID OPCODE); IF THE DDT COMMAND IS PRECEDED WITH A DOUBLE
;<ESC> (E.G., $$/) THEN THE FULL WORD VALUE FROM ABOVE WILL BE
;TREATED AS AN EXTENDED-FORMAT-INDIRECT-WORD (EFIW) WHOSE EF-
;FECTIVE ADDRESS "E" WILL BE CALCULATED AS IT WOULD BE BY THE
;HARDWARE WERE IT TO ENCOUNTER THE WORD AS AN INDIRECTED WORD
;IN AN EFFECTIVE ADDRESS CALCULATION IN A NON-ZERO SECTION. IF
;NO <ESC>'S WERE TYPED THEN IF EITHER A SPACE WAS TYPED IN THE
;EXPLICIT ADDRESS EXPRESSION OR IF THE LAST WORD TYPED IS BEING
;USED (I.E., NO EXPLICIT ADDRESS WAS TYPED-IN) THEN THE HIGH-
;ORDER 18-BITS (I.E., THE "SECTION ADDRESS") OF THE 36-BIT
;ADDRESS-TO-BE-OPENED WILL BE SUPPLIED FROM THE CURRENTLY OPENED
;SECTION (I.E., THE LEFT HALF OF ".").
;
;IF A FETCH ERROR OCCURS OR ILLEGAL EFIW WORD FOUND THE ERROR
;RETURN IS TAKEN OTHERWISE THE SUCCESSFUL (SKIP) RETURN IS TAKEN
;WITH THE 36-BIT GLOBAL ADDRESS IN REGISTER T.
;
;USES ACS R, S, W.
CEFFAD:	TXNN	F,QF		;EXPLICIT ADDRESS EXPRESSION TYPED?
	MOVE	T,LWT		;NO, USE LAST WORD TYPED
	TXNE	F,CCF		;DOUBLE <ESC> TYPED?
	JRST	CEFFE		;YES, EFIW ADDRESS CALCULATION
	TXNE	F,CF		;SINGLE <ESC> TYPED?
	JRST	CEFFI		;YES, IFIW ADDRESS CALCULATION
	TXNE	F,QF		;IMPLICIT ADDRESS BEING USED, OR
	TXNE	F,SPF		;SPACE TYPED IN EXPLICIT ADR EXPR?
	TLZA	T,-1		;YES, SECTION RELATIVE ADDRESS
	JRST	CPOPJ1		;RETURN WITH GLOBAL ADDRESS IN T
	CAILE	T,17		;LOCAL REFERENCE TO A REGISTER?
	HLL	T,LLOCO		;NO, MEMORY, RELOCATE INTO LOCAL SECTION
	JRST	CPOPJ1		;RETURN WITH GLOBAL ADDRESS IN T
;SETUP TO CALCULATE IFIW EFFECTIVE ADDRESS

CEFFI:	HLLZ	S,LLOCO		;PRELOAD (FAKE) CURRENT SECTION
CEFFIX:	MOVEI	W,INDPTH	;MAX LOOP COUNT FOR INDIRECTION
	MOVEM	W,TEM		;SO WE DON'T GET CAUGHT

;CALCULATE IFIW

CIFIW:	PUSH	P,T		;SAVE FOR LATER INDIRECTION CHECK
	MOVEM	T,LASEAF	;ALSO SAVE FOR JRSTF BITS IN $X
	HRRZ	W,T		;IFIW: Y FIELD (18 BITS)
	LDB	R,[POINT 4,T,17];IFIW: X FIELD
	HLL	T,S		;GLOBAL ADR IN CASE ONLY INDIRECTION
	JUMPE	R,CIFIW6	;SKIP INDEXING IF NO INDEX REGISTER

;DO IFIW INDEXING

	MOVE	T,AC0(R)	;FETCH THE INDEX REGISTER
	MOVEM	T,LASEAF	;SAVE FOR JRSTF BITS IN $X
	MOVE	R,T		;SCRATCH COPY
	JUMPE	S,CIFIW2	;IF SECTION 0 INDEX
	JUMPL	R,CIFIW2	;OR LH(X) .LT. 0
	TLNN	R,-1		;OR LH(X) .EQ. 0
CIFIW2:	TLZA	T,-1		;THEN ONLY 18-BITS OF INDEXING
	HRRE	W,W		;ELSE SIGN-EXTEND Y TO 36-BITS
	ADD	T,W		;DO THE INDEXING
	JUMPE	S,CIFIW4	;IF SECTION 0
	JUMPL	R,CIFIW4	;OR LH(X) .LT. 0
	TLNN	R,-1		;OR LH(X) .EQ. 0
CIFIW4:	HLL	T,S		;THEN E STAYS IN LOCAL SECTION
	TLZ	T,770000	;LEAVE ONLY EFIW Y FIELD
	HLLZ	S,T		;UPDATE S TO NEW CURRENT SECTION

;CHECK IFIW INDIRECTION

CIFIW6:	TXNN	T,777760	;IS LOCAL REFERENCE TO A REGISTER?
	ANDI	T,17		;YES, REDUCE TO UNABIGUOUS AC
				; (NOTE "SECTION-NESS" STILL IN S)
	POP	P,R		;GET BACK ORIGINAL WORD
	TXNN	R,@		;IFIW I BIT ON?
	JRST	CPOPJ1		;NO, ALL DONE
CIFIW8:	MOVE	R,T		;YES, ADDRESS OF NEW ADDRESS
	PUSHJ	P,FETCH		;GO GET INDIRECTED WORD
	 POPJ	P,		;CAN'T ACCESS WORD, DIE
	SOSG	TEM		;INFINITE LOOP?
	 POPJ	P,		;APPARENTLY, GO COMPLAIN AT USER
CIFIW9:	JUMPE	S,CIFIW		;ONCE IN SECTION 0, ALWAYS IN SECTION 0
	JUMPG	T,CEFIW		;IF BIT 0 .EQ. 0 THEN EFIW
	TXNN	T,1B1		;BIT 0 AND BIT 1 ON?
	JRST	CIFIW		;JUST BIT 0, IFIW FORMAT
	POPJ	P,		;ILLEGAL COMBINATION
;SETUP TO CALCULATE EFIW EFFECTIVE ADDRESS

CEFFE:	HLLZ	S,LLOCO		;PRE-LOAD CURRENT SECTION
	MOVEI	W,INDPTH	;MAX LOOP COUNT FOR INDIRECTION
	MOVEM	W,TEM		;SO WE DON'T GET CAUGHT
	JRST	CIFIW9		;DISPATCH ON TYPE OF INDIRECTION

;EFIW FORMAT

CEFIW:	PUSH	P,T		;SAVE FOR LATER INDIRECTION CHECK
	LDB	W,[POINT 30,T,35]  ;EFIW: Y FIELD (30 BITS)
	LDB	R,[POINT 4,T,5]	;EFIW: X FIELD
	TLZ	T,770000	;IN CASE ONLY INDIRECTION
	JUMPE	R,CEFIW6	;SKIP INDEXING IF NO INDEX REGISTER

;DO EFIW INDEXING

	MOVE	T,AC0(R)	;GET INDEX REGISTER
	ADD	T,W		;INDEX THE Y FIELD
	TLZ	T,770000	;LEAVE ONLY Y FIELD

;CHECK EFIW INDIRECTION

CEFIW6:	POP	P,R		;GET BACK ORIGINAL WORD
	TXNN	R,1B1		;EFIW I BIT ON?
	JRST	CPOPJ1		;NO, ALL DONE
	HLLZ	S,T		;YES, SET NEW CURRENT SECTION
	JRST	CIFIW8		;AND LOOP ON INDIRECTION
;HERE WHEN REGISTER CLOSED TO DEPOSIT NEW CONTENTS AND SET NEXT LOCATION

DEPRA:	TXNE	F,CF		;$ PRECEEDED?
	PUSHJ	P,POPLLC	;YES, POP OLD SEQUENCE
	TXNE	F,ROF		;IF REGISTER IS BEING CHANGED
	TXNN	F,QF		;REMOVE ALL PREVIOUS UNDEFINED
	JRST	DEPRS		;SYMBOL REFERENCES TO IT
	MOVE	R,@USYMP	;GET POINTER TO ALL OLD UNDEF ITEMS
	MOVEM	W1,@USYMP	;INCLUDE THE NEW ITEMS IN UNDEF LIST
	MOVEM	R,ESTUT		;FAKE OUT USYSET
IFN	FTFILE,<
	SKIPN	FILING		;SEE IF /M
	JRST	DEPRS		;YES--NO UNDEF FIXUPS
>
	MOVEM	T,LWT		;SAVE T IN LWT, DEPRS DOES IT ANYWAY
DEPRA1:	PUSHJ	P,USYSET	;SETUP TO SEARCH UNDEFINEDS
	ADDI	R,1		;WANT VALUE WORDS THIS TIME

DEPRA2:	SOSGE	R		;ANY MORE SYMBOLS?
	PUSHJ	P,ADVSYM	;MAYBE, MAKE SURE
	SKIPA	W,@SYPTR	;YES, GET VALUE WORD
	JRST	DEPRA6		;ALL DONE, GO DO THE STORE
	JUMPG	W,DPRS3		;1B0=0 IMPLIES CHAINING
	HRRZ	T,W		;GET ADDRESS OF FIXUP
	SKIPE	T		;DELETE ENTRY IF ADR=0, OR
	CAMN	T,LLOCO		; IF ADR IS BEING CHANGED
	SKIPA	W1,R2IDX	;WANT TO DELETE IT, FORM SYM INDEX
	SOJA	R,DEPRA2	;KEEP IT, GET NEXT VALUE
	ADD	W1,R		;SYM INDEX NOW IN W1
	SUBI	W1,1		;POINT TO 1ST WORD OF SYMBOL PAIR
	PUSHJ	P,REMUN		;GET RID OF THE SYMBOL
	  JRST	DEPRA6		;CAN'T, SKIP ALL THIS
	JRST	DEPRA1		;RESTART, SINCE REMUN CALLED SYWSET

DEPRA6:	MOVE	T,LWT		;RESTORE QUANTITY
	JRST	DEPRS		;DO THE STORE
;HERE IF THE UNDEFINED SYMBOL REQUESTS A CHAINED FIXUP.

DPRS3:	PUSH	P,R		;SAVE R OVER ALL THIS
	SETO	S,		;FLAG TO USE DEPSYM
DPRS4:	HRRZ	R,W		;GET NEXT ADR (AFTER ADR IN W1)
	JUMPE	R,DEPRA8	;STOP ON 0 ADR
	PUSHJ	P,FETCHL	;GET CONTENTS OF ADR IN R
	 JRST	DEPRA8		;****UNDEFINED SYMBOL TABLE OR FIXUP
				; CHAIN POINTS TO ILL. MEM. TRY
				; TO CONTINUE.
	EXCH	T,W
	EXCH	W1,R
	CAME	W1,LLOCO	;IS THIS WORD BEING CHANGED?
	JRST	DPRS4		;NO, CONTINUE SEARCHING LIST
	HRR	T,W		;PATCH CHAIN ADR AROUND ITEM
	AOSE	S		;SEE IF NEED TO USE DSYMER
	TDZA	TT1,TT1		;NO--USE DMEMER
	MOVEI	TT1,DSYMER-DMEMER ;YES.
	PUSHJ	P,DMEMER(TT1)	;CALL EITHER DMEMER OR DSYMER
	JRST	DPRS4		;CONTINUE DOWN CHAIN

DEPRA8:
IFN FTEXEC,<
	PUSHJ	P,SYMSPC	;MAKE SURE AFTER FETCHL AND DMEMER
> ;END IFN FTEXEC

	POP	P,R		;RESTORE R
	SOJA	R,DEPRA2	;GET NEXT SYMBOL
;ROUTINES TO HANDLE RING BUFFER OF LOCATIONS

;'PUSH' CURRENT LOCATION

PSHLLC:	AOS	TT,SAVLP	;BUMP POINTER
	CAIL	TT,NSAVTB	;AT END OF TABLE?
	SETZB	TT,SAVLP	;YES, WRAPAROUND
	PUSH	P,LLOC		;GET CURRENT LOCATION
	POP	P,SAVLTB(TT)	;ADD IT TO TABLE
	POPJ	P,

;'POP' CURRENT LOCATION

POPLLC:	MOVE	TT,SAVLP	;GET POINTER
	MOVE	TT,SAVLTB(TT)	;REMOVE FROM TABLE
	MOVEM	TT,LLOC		;SET AS CURRENT LOC
	SOS	TT,SAVLP	;DECREMENT PTR
	JUMPGE	TT,POPLC1	;AT TOP OF TABLE?
	MOVEI	TT,NSAVTB-1	;YES, WRAPAROUND
	MOVEM	TT,SAVLP
POPLC1:	POPJ	P,
SUBTTL	COMMAND ROUTINES -- RETYPE LAST QUANTITY

SEMIC:	MOVEM	T,LWT		;SEMICOLON TYPES IN CURRENT MODE
	JRST	(SCH)

EQUAL:	TROA	F,LF1+CF1	;=
UNDRL:	TRZ	F,CF1		;_
	TRO	F,LF1
	PUSHJ	P,CONSYM
	JRST	RET
SUBTTL	COMMAND ROUTINES -- TYPEOUT MODE CONTROL

TEXO:	TXNN	F,Q2F		;$NT?
	MOVEI	R,TEXTT-HLFW	;$T ASSUME 7 BIT ASCII
	MOVE	T,WRD2D		;GET "RADIX" OF TEXT
	CAIN	T,9		;CHECK FOR $9T
	MOVEI	R,TEXT9T-HLFW	;SET MODE FOR NINE-BIT ASCII
	CAIN	T,8		;CHECK FOR $8T
	MOVEI	R,TEXT8T-HLFW	;SET MODE FOR EIGHT-BIT ASCII
	CAIN	T,7		;CHECK FOR $7T
	MOVEI	R,TEXTT-HLFW	;SET MODE FOR SEVEN-BIT ASCII
	CAIN	T,6		;CHECK FOR $6T
	MOVEI	R,SIXBP-HLFW	;SET MODE SWITCH FOR SIXBIT ASCII
	CAIN	T,5		;CHECK FOR $5T
	MOVEI	R,R50PNT-HLFW	;SET MODE SWITCH FOR RADIX 50
	JUMPE	R,ERR		;ERROR IF NOT A KNOWN TEXT "RADIX"
HWRDS:	ADDI	R,HLFW-TFLOT	;H
SFLOT:	ADDI	R,TFLOT-PIN	;F
SYMBOL:	ADDI	R,PIN-FTOC	;S
CON:	ADDI	R,FTOC		;C
	HRRZM	R,SCH
	JRST	BASE1

RELA:	TRZE	F,Q2F		;CHANGE ADDRESS MODE TO RELATIVE
	JRST	BASECH
	MOVEI	R,PADSO-TOC
ABSA:	ADDI	R,TOC		;A
	HRRZM	R,AR
	JRST	BASE1S

BASECH:	MOVE	T,WRD2D		;$NR  CHANGE OUTPUT RADIX TO N, N .GT. 1
	CAIGE	T,2
	JRST	ERR
	HRRZM	T,ODF
BASE1:	SKIPE	S,OLDAR
	MOVE	AR,S
BASE1S:	SETZM	OLDAR
BASE1O:	MOVS	S,[XWD SCHM,SCH]
	TXNN	F,CCF
	JRST	LIS1
	BLT	S,ODFM		;WITH $$, MAKE MODES PERMANENT
	MOVE	S,[SVBTS,,PSVBTS]
	BLT	S,PSVBTS+1
	JRST	RET
;BYTE COMMAND AND TYPEOUT ROUTINES

BITO:	TRZN	F,Q2F		;DOES <N> EXIST FOR $<N>O?
	 JRST	BITO5		;NO, DEFAULT TO CURRENT MASK

	SETZB	W2,SVBTS	;MAKE ROOM FOR A NEW MASK
	MOVEI	W1,1		;PROTOTYPE BIT
	MOVN	T,WRD2D		;FOR SHIFTING THE PROTOTYPE BIT
BITO2:	LSHC	W1,(T)		;POSITION TO A BYTE BOUNDRY
	IORM	W2,SVBTS	;MARK NEXT BYTE BOUNDRY
	JUMPN	W2,BITO2	;LOOP FOR ALL BYTES

BITO5:	SKIPN	OLDAR		;GOT A SAVED AR ALREADY?
	MOVEM	AR,OLDAR	;NO, THEN SAVE THE CURRENT ONE
	MOVEI	AR,TOC		;SET OCTAL TYPEOUT BY DEFAULT
	MOVEI	SCH,BITT	;AND BYTE TYPEOUT
	PJRST	BASE1O		;HANDLE $$ IF NEED BE . . .



;HERE FOR ACTUAL BYTE TYPEOUT

BITT:	PUSH	P,LWT		;SAVE LAST WORD TYPED . . .
	SKIPN	T,SVBTS		;GET CURRENTLY PREVAILING $O MASK
	MOVE	T,BYTMSK	;BLANK, USE $3M MASK INSTEAD
	IORI	T,1B35		;BIT 35 ALWAYS MARKS END OF A BYTE
	PUSH	P,T		;SET WORKING COPY OF MASK
	PUSH	P,LWT		;WORKING COPY OF WORD TO BE TYPED
	JRST	BITT4		;ENTER LOOP

BITT2:	MOVEI	T,","		;SEPARATE BYTES WITH A COMMA
	PUSHJ	P,TOUT		;TYPE IT OUT
BITT4:	POP	P,T		;[REMNANTS OF] WORD TO BE TYPED
	POP	P,W1		;[REMNANTS OF] BYTE MASK
	JFFO	W1,.+3		;GET NEXT COUNT OF BITS
	 POP	P,LWT		;DONE, RESTORE LWT FOR OTHERS
	 POPJ	P,		;RETURN
	LSH	W1,1(W2)	;UPDATE MASK
	PUSH	P,W1		;SAVE AWAY FOR NEXT ROUND
	LSHC	T,-^D36+1(W2)	;GET NEXT BYTE TO BE TYPED
	MOVEM	T,LWT		;SET IN COMMON STORAGE PLACE
	PUSH	P,W1		;SAVE REMAINING BYTES FOR NEXT ROUND
	CAIN	AR,TOC		;NUMERIC OUTPUT?
	 PUSHJ	P,TOCA		;YES, OUTPUT ACCORDINGLY
	CAIN	AR,PADSO	;SYMBOLIC OUTPUT?
	 PUSHJ	P,PIN		;YES, OUTPUT ACCORDINGLY
	SKIPE	-1(P)		;MORE BYTES COMING UP?
	JRST	BITT2		;YES, TYPE A COMMA
	JRST	BITT4		;NO, CLEAN UP STACK AND LEAVE
SUBTTL	COMMAND ROUTINES -- LIMITS AND PATCHING

FIRARG:	TXNE	F,CF!CCF	;$ PRECEEDED?
	JRST	PTCH		;YES, PATCH COMMAND
	MOVEM	T,LLIMIT	;NO, SET FIRST ARG
	TXO	F,FAF
	JRST	ULIM1

ULIM:	TXNE	F,CCF		;$$ PRECEEDED?
	JRST	ERR		;YES, NO SUCH COMMAND
	TXNE	F,CF!CCF	;$ PRECEEDED?
	JRST	PTCHE		;YES, PATCH END COMMAND
	TXO	F,SAF		;NO, SET SECOND ARG
	MOVEM	T,ULIMIT
ULIM1:	TXNN	F,QF
	JRST	ERR
	JRST	LIS0E		;[242]
;HERE FOR THE PATCH BEGIN COMMAND

PTCH:	TXNN	F,ROF		;NO REGISTER OPEN?
	JRST	ERR		;YES, ERROR
	SETZM	PTORG		;ASSUME EXPRESSION TYPED
	TXNE	F,TIF!COMF!PTF!MF  ;EXPRESSION TYPED?
	JRST	PTCH2		;YES, JUST GO USE IT
	TXNE	F,QF		;ANYTHING AT ALL TYPED?
	TXNE	F,LTF		;NUMBER OR SYMBOL?
	  CAIA			;NOTHING OR SYMBOL TYPED
	JRST	PTCH2		;NUMBER, JUST GO USE IT
	TXNE	F,QF		;ANYTHING TYPED?
	JRST	[PUSHJ	P,EVAL	;YES, LOOKUP SYMBOL
		 JRST	ERR	;STRANGE TYPEIN, LOSE
		JRST	PTCH4]	;FOUND, USE VALUE AS PATCH LOC
	MOVSI	W,-NPSYM	;SETUP TO SCAN PATCH SYMBOLS
PTCH1:	MOVE	T,PCHSYM(W)	;GET A POSSIBLITY
	MOVEM	T,SYM		;SET IT UP FOR EVAL
	PUSHJ	P,EVAL		;TRY TO FIND VALUE
	 AOBJN	W,PTCH1		;NOT FOUND, TRY NEXT SYMBOL
	JUMPL	W,PTCH4		;FOUND A SYMBOL, USE IT
IFN	FTEXEC,<SKPUSR		;USER MODE?
	JRST	ERR>		;EXEC MODE LOSES HERE
	MOVEI	R,.JBFF		;NONE OF THE SYMBOLS EXIST, USE .JBFF
	PUSHJ	P,FETCH		;GET CONTENTS OF .JBFF
	 JRST	ERR		;USER LOSES
	AOS	PTORG		;PTORG = 1 TO FLAG FROM .JBFF
	JRST	PTCH2		;FAKE PATCH SYMBOL FOUND
PTCH4:	SETOM	PTORG		;PTORG = -1 TO FLAG A SYMBOL
	MOVE	R,SYM		;GET SYMBOL BEING USED
	MOVEM	R,PTSYM		;SAVE FOR CLOSING PATCH LATER
	AOS	R,W1		;POINT TO VALUE WORD
PTCH2:	CAIGE	T,.JBDA		;HAVE REASONABLE PATCH ADDRESS?
	JRST	ERR		;NO
	TLNN	T,-1		;SYMBOL HAVE 0 LH?
	JRST	PTCH6		;YES, ASSUME OK
	XOR	T,LLOCO		;CHECK SECTION NUMBER
	TLNE	T,-1		;PATCH IN SAME SECTION AS OPEN LOC?
	JRST	ERR		;NO, DIE (JUMPA ONLY HAS 18-BITS OF ADR)
	XOR	T,LLOCO		;RESTORE T (ADDRESS)
PTCH6:	MOVEM	T,PTLOC		;YES, SAVE IT
	MOVEM	R,PTFIX		;SAVE WHERE IT CAME FROM
	MOVE	R,LLOCO		;LOC OF OPEN REGISTER
	MOVEM	R,PTLLC		;SAVE IT
	PUSHJ	P,FETCH		;GET CONTENTS
	 JRST	ERR		;FETCH FAILED
	MOVEM	T,PTWRD		;SAVE ORIGINAL WORD
	PUSHJ	P,DMEMER	;BE SURE IT CAN BE CHANGED, ERR IF NOT
	SETZM	PTAFTR		;ASSUME PATCH BEFORE
	TXNE	F,CCF		;SAVE BEFORE/AFTER FLAG
	SETOM	PTAFTR		;0 MEANS BEFORE, -1 MEANS AFTER
	PUSHJ	P,TCRLF		;OUTPUT <CR><LF>
	MOVE	T,PTLOC		;START OF PATCHING AREA
	PUSHJ	P,LI1		;OPEN LOCATION AND TYPEOUT
	SKIPL	PTAFTR		;PATCH BEFORE OR AFTER?
	POPJ	P,		;BEFORE, DONE FOR NOW
	MOVE	R,LLOCO		;CURRENT OPEN LOCATION
	MOVE	T,PTWRD		;ORIGINAL INSTRUCTION
	PUSHJ	P,DMEMER	;PUT AS FIRST IN PATCH AREA
	PUSHJ	P,LI2		;NOW TYPE OUT SO USER CAN SEE
	PJRST	LI0		;AND OPEN/TYPE NEXT LOCATION

;TABLE OF SYMBOLS IDENTIFYING PATCH AREAS

PCHSYM:
IFN	FTDEC10&FTEXEC,<RADIX50 0,PAT>		;TOPS-10 MONITOR PATCH AREA
IFN	FTEX20!FTMON,<RADIX50 0,FFF>	;TOPS-20 MONITOR PATCH AREA
	RADIX50	0,PAT..		;USUAL LINK SYMBOL
	RADIX50	0,PATCH		;ANOTHER LIKELY POSSIBILITY
IFE	FTDEC10!FTEXEC,<RADIX50 0,PAT>		;LOOK LAST IF NOT -10 EDDT
NPSYM==.-PCHSYM
;HERE FOR THE PATCH END COMMAND

PTCHE:	SKIPN	PTLOC		;PATCH IN PROGRESS?
	JRST	ERR		;NO, ERROR
	TXZ	F,CF!CCF	;FLUSH FLAGS BEFORE DEPRA
	TXZN	F,STF		;DID USER SEE LAST LOC? (CLEAR FLAG FOR LI0)
	SKIPE	LWT		;AND WAS IT ZERO?
	JRST	PTCHE0		;NO, PROCEED
	TXNE	F,ROF		;REGISTER OPEN?
	TXNE	F,QF		;AND NOTHING YET TYPED?
	JRST	PTCHE0		;NO.
	SOS	LLOC		;YES - DO NOT STORE A 0 WORD.
PTCHE0:	PUSHJ	P,DEPRA		;STORE LAST WORD IF ANY
	SKIPGE	PTAFTR		;PATCH BEFORE?
	JRST	PTCHE1		;NO
	PUSHJ	P,LI0		;OPEN AND TYPE NEXT LOCATION
	MOVE	R,LLOCO		;CURRENT OPEN LOCATION
	MOVE	T,PTWRD		;USER ORIGINAL INSTRUCTION
	PUSHJ	P,DMEMER	;PUT AT END OF PATCH CODE
	PUSHJ	P,LI2		;AND TYPE OUT FOR USER TO SEE
PTCHE1:	PUSHJ	P,LI0		;OPEN AND TYPE NEXT LOCATION
	MOVE	R,LLOCO		;CURRENT OPEN LOCATION
	HRRZ	T,PTLLC		;ORIGINAL USER LOCATION
	ADD	T,[JUMPA 1,1]	;NON-SKIP CONTINUE/RETURN
	PUSHJ	P,DMEMER	;PUT IN PATCH AREA
	PUSHJ	P,LI2		;KEEP USER UPDATED
	PUSHJ	P,LI0		;ADVANCE TO NEXT LOCATION
	MOVE	R,LLOCO		;CURRENT OPEN LOCATION
	HRRZ	T,PTLLC		;ORIGINAL USER LOCATION
	ADD	T,[JUMPA 2,2]	;SKIP CONTINUE/RETURN INSTRUCTION
	PUSHJ	P,DMEMER	;PUT IN PATCH AREA
	PUSHJ	P,LI2		;AND TELL USER

;CONTINUED ON NEXT PAGE
;FALL IN FROM ABOVE

;NOW TO DECIDE WHAT POINTER (IF ANY) TO UPDATE

	SKIPN	PTORG		;ANYTHING TO UPDATE?
	JRST	PTCHE4		;NO, GO INSTALL JUMPA TO PATCH
	AOS	T,LLOC		;GET NEXT FREE PATCH LOC
	SKIPG	PTORG		;SYMBOL OR .JBFF?
	JRST	PTCHE3		;SYMBOL, PROCEED
	MOVEI	R,.JBFF		;.JBFF, SET UP TO UPDATE IT
	PUSH	P,T		;SAVE T
	PUSHJ	P,DMEMER	;UPDATE C(.JBFF) ACCORDINGLY
	MOVEI	R,.JBSA		;C(.JBFF) ALSO STORED IN LH(.JBSA)
	PUSHJ	P,FETCH		;SO GET .JBSA
	 JRST	ERR		;BZZZT?
	HRL	T,(P)		;NEW LH(.JBSA)
	PUSHJ	P,DMEMER	;SET AND HOPE FOR BEST
	POP	P,T		;RESTORE STACK
	JRST	PTCHE4		;AND FINISH OFF PATCH

PTCHE3:	MOVE	R,PTFIX		;WHERE VALUE CAME FROM
	PUSHJ	P,DSYMER	;DEPOSIT NEW SYMBOL VALUE
	MOVE	S,PTSYM		;GET SYMBOL USED FOR PATCHING
	PUSHJ	P,DELCSH	;REMOVE FROM THE SYMBOL TABLE CACHE
	MOVE	S,T		;GET VALUE SYMBOL WAS REDEFINED AS
	PUSHJ	P,DELCSV	;REMOVE VALUE FROM CACHE TOO
PTCHE4:	PUSHJ	P,TCRLF		;TYPE <CR><LF>
	MOVE	T,PTLLC		;ORIGINAL USER LOCATION
	PUSHJ	P,LI1		;OPEN AND TYPE ORIGINAL LOCATION
	MOVE	R,LLOCO		;CURRENT OPEN LOCATION
	MOVSI	T,(JUMPA)	;JUMP TO PATCH AREA INSTRUCTION
	HRR	T,PTLOC		;ADDRESS OF START OF PATCH
				; NOTE ADDRESS IN LOCAL SECTION
	PUSHJ	P,DMEMER	;PUT IN JUMP INSTRUCTION
	PUSHJ	P,LI2		;AND SHOW USER
	SETZM	PTLOC		;SAY NO PATCH IN PROGRESS
	POPJ	P,		;DONE
SUBTTL	COMMAND ROUTINES -- MEMORY AND PAGING CONTROL

;HERE ON AN $W OR $$W.
;
;IF FORM WAS "LOWER<UPPER>WORD$W" THEN IS WORD SEARCH, OTHERWISE
;COMMAND IS TO ENABLE MEMORY-MANAGEMENT FLAGS.
;
;A SINGLE <ESC> ENABLES THE CONDITION, A DOUBLE <ESC> CLEARS IT:
;
;	$[$]0W		;ENABLE [DISABLE] AUTO WRITE-ENABLE
;	$[$]1W		;ENABLE [DISABLE] AUTO PAGE CREATE

DBLU:	TXNE	F,QF		;USER TYPE AN ARG?
	JRST	WORD		;YES, THIS IS A WORD SEARCH
IFN	FTFILE,<
	SKIPN	PHYSIO		;ARE WE EXAMINING A REAL DISK FILE?
	SKIPN	FILING		;MAYBE, ARE WE?
	CAIA			;NO
	JRST	ERR		;YES, CAN'T CHANGE PATCHS WITHOUT
				;  RE-OPENING THE FILE
> ;END IFN FTFILE
	TXNE	F,CCF		;$$W?
	TDZA	T,T		;YES, CLEAR FLAG
	SETO	T,		;NO, SET FLAG
	TXNE	F,Q2F		;USER TYPE SECOND ARG?
	SKIPA	R,WRD2D		;YES, GET INDEX
	SETZ	R,		;NO, DEFAULT IS 0 (WRITE ENABLE)
	JUMPL	R,ERR		;MUST BE .GE. 0
	CAIL	R,PAMAX		;AND .LT. PAMAX
	JRST	ERR		;NOT IN RANGE, CALL ERROR
	MOVEM	T,PATCHS(R)	;STORE NEW WRITE-ENABLE WORD
IFN	FTFILE,<SETOM DEPNCT>	;RESET PATCHING TRIED FLAG
	JRST	RET
;COMMAND TO MAKE LIFE EASIER ON VIRTUAL ADDRESSING MACHINES
;FORMAT IS ARG$NU, WHERE N IS:
;
;	BLANK	SAME AS 0
;	0	MAP THROUGH EPT AT PAGE ARG (ON -10, CAN BE UPT<EPT$U)
;	1	MAP THROUGH UPT AT PAGE ARG
;	2	MAP THROUGH SECTION MAP AT PAGE ARG
;	3	FAKEAC FLAG: NON-ZERO TO USE FAKE ACS
;	4	SET AC BLOCK TO ARG (EDDT ONLY)
;	5	LOAD ACS FROM 20 WORD BLOCK AT ARG
;	6	SET SPT BASE TO ARG
;	7	SET CST BASE TO ARG
;	8	SET ADDRESS RELOCATION (ADDED TO ALL USER ADDRESSES)
;	9	SET ADDRESS PROTECTION (MAX LEGAL USER ADDRESS)
;	10	SET KI-PAGING MODE (FOR EMULATION, IGNORED IN EDDT)
;	11	SET KL-PAGING MODE (FOR EMULATION, IGNORED IN EDDT)
;
;(MATCH ANGLE BRACKETS:>)
;
;FOR MAPPING FUNCTIONS, TWO ALTS MEANS ARG IS AN SPT INDEX INSTEAD OF
;A PAGE NUMBER.
;
;$U WITH NO ARGUMENTS CLEARS 0,1,2,8 ANDS SETS 3 (I.E., RESTORES "NORMAL
;VIRTUAL ADDRESSING"). $$U WITH NO ARGUMENTS SET PHYSICAL ADDRESSING
;MODE.
;
;$NU OR $$NU WILL RETURN THE ADDRESS OF THE APPROPRIATE WORD INTERNAL
;TO DDT WHICH CORRESPONDS TO THE FUNCTION. FOR FUNCTIONS 0, 1, AND 2
;THE $$ FORM RETURNS THE MAPPING FUNCTION WORD (I.E., PHYSICAL OR
;VIRTUAL OR SPT-RELATIVE ADDRESSING) WHILE THE $ FORM RETURNS THE
;USER ARGUMENT. FOR ALL OTHER FUNCTION CODES AN ERROR OCCURS.
SETPAG:	TXNE	F,QF		;ANY ARG?
	JRST	SETPA2		;YES, A FUNCTION TO PERFORM
	TXNE	F,Q2F		;WANT TO READ BACK?
IFE	FTFILE,<JRST SETPA4>	;YES, CONCOCT A DDT ADDRESS
IFN	FTFILE,<JRST ERR>	;YES, ILLEGAL
	TXNE	F,FAF!SAF	;$U OR $$U, ANY SUPERFLUOUS ARGS?
	JRST	ERR		;YES, ILLEGAL
	TXNE	F,CCF		;$U OR $$U?
	JRST	SETPHY		;$$U, SET PHYSICAL ADDRESSING
	SETZM	MAPFN		;UNMAPPED VIRTUAL ADDRESSING
IFN	FTFILE,<		;SPECIAL FILDDT DEFAULTING
	SETZM	FAKEAC		;UNMAPPED 0-17 ALSO, UNLESS
	SKIPN	PHYSIO		;IF DOING SUPER I/O
	SKIPN	EXEFMT		;OR IF LOOKING AT A DATA FILE
	SKIPA			;DO NOT USE FAKE ACS
> ;END OF IFN FTFILE
	SETOM	FAKEAC		;ASSUME BACK TO INTERNAL FAKE ACS
	POPJ	P,		;THAT'S IT


;HERE ON AN $U WITH AN ARGUMENT.  FIGURE OUT WHICH FUNCTION TO PERFORM.

SETPA2:	TXNN	F,Q2F		;ANY FUNCTION CODE?
	TDZA	W,W		;NO, ASSUME 0
	MOVE	W,WRD2D		;YES, GET IT (DECIMAL)
	JUMPL	W,ERR		;NEGATIVE IS ILLEGAL
	CAIL	W,PFNMAX	;TOO BIG?
	JRST	ERR		;ILLEGAL
	HLLO	TT,F		;FLAGS,,-1
	AND	TT,PFNDSP(W)	;CHECK FOR ILLEGAL FLAGS
	SKPKLP			;KI PAGING?
	TXNN	F,CCF		;YES, $$ ALWAYS ILLEGAL. WAS IT TYPED?
	TLNE	TT,-1		;OR ANY ILLEGAL FLAGS SET?
	JRST	ERR		;YES, ILLEGAL
	ADDI	W,1		;BASE FUNCTIONS AT 1 FOR STORE
	JRST	0(TT)		;DISPATCH
;HERE TO RETURN ADDRESS OF DDT WORD FOR USER TO SEE

IFE	FTFILE,<
SETPA4:	SKIPL	W,WRD2D		;GET FUNCTION CODE
	CAIL	W,PFNMAX	;TOO BIG?
	JRST	ERR		;ILLEGAL
	TXNN	F,CCF		;$ OR $$ TYPED?
	SKIPA	T,PFNADR(W)	;$NU
	MOVS	T,PFNADR(W)	;$$NU
	TRNN	T,-1		;SOMETHING THERE?
	JRST	ERR		;NO, USER ERROR
;	HLL	T,SECDDT	;CONCOCT AN INTERNAL-TO-DDT ADDRESS
;	PJRST	MASK2		;AND RETURN VALUE AS IF USER TYPED IT

;***;	TEMP CODE TILL DDT CAN DISTINGUISH THIS TYPE OF SPECIAL ADDRESS

	PUSH	P,(T)		;***;SAVE VALUE
	MOVEI	W1,[ASCIZ\/	\]  ;***;SEPARATING TEXT
	PUSHJ	P,TSTRG		;***;TYPE OUT SEPARATOR
	POP	P,T		;***;GET THE VALUE BACK
	PUSHJ	P,CONSYM	;***;AND DISPLAY IT FOR THE USER
	PJRST	TCRLF		;***;AND CAP OFF LINE SO USER NOT TEMPTED TO
				;***; TYPE IN A NEW VALUE, <CR><LF>
> ;END IFE FTFILE
;DISPATCH TABLE FOR $U FUNCTION CODES.
;FORMAT IS:   ILLEGAL FLAG BITS,,DISPATCH ADDRESS
;CHANGES HERE SHOULD ALSO GO IN MFNDSP AND COMMENT ON PREVIOUS PAGE.

PFNDSP:	SAF+		SETEPT	;(00) SET EPT
	FAF!SAF+	SETMAP	;(01) SET UPT
	FAF!SAF+	SETSEC	;(02) SET SECTION MAP
	FAF!SAF!CCF+	SETFAC	;(03) SET FAKE ACS
	FAF!SAF!CCF+	SETACB	;(04) SET AC BLOCK
	FAF!SAF!CCF+	SETCAC	;(05) LOAD "CRASH ACS" FROM ADDRESS
	FAF!SAF!CCF+	SETSPT	;(06) SET SPT BASE
	FAF!SAF!CCF+	SETCST	;(07) SET CST BASE
	FAF!SAF!CCF+	SETREL	;(08) SET RELOCATION
	FAF!SAF!CCF+	SETPRT	;(09) SET PROTECTION
	FAF!SAF!CCF+	SETKIP	;(10) SET KI-PAGING EMULATION
	FAF!SAF!CCF+	SETKLP	;(11) SET KL-PAGING EMULATION
PFNMAX==.-PFNDSP


PFNADR:	MAPFN,,	MAPPG		;(00) SET EPT (ADDRESSING MODE)
	MAPFN,,	MAPPG		;(01) SET UPT (ADDRESSING MODE)
	MAPFN,,	MAPPG		;(02) SET SECTION MAP (ADDRESSING MODE)
	0,,	FAKEAC		;(03) SELECT INTERNAL FAKE ACS
	0,,	ACWRD		;(04) SELECT HARDWARE AC BLOCK
	0,,	FAKEAD		;(05) ADDRESS OF ORIGIN OF FAKE ACS
	0,,	SPTWRD		;(06) BASE ADDRESS OF SPT
	0,,	CSTWRD		;(07) BASE ADDRESS OF CST
	0,,	UBASE		;(08) RELOCATION ADDRESS
	0,,	UPROT		;(09) PROTECTION ADDRESS
	0,,	KIPAG		;(10) KI-PAGING FLAG
	0,,	KLPAG		;(11) KL-PAGING FLAG
;SET PHYSICAL ADDRESSING

SETPHY:	SETZM	FAKEAC		;USE REAL 0-17
	SETO	W,		;-1 IN MAPFN MEANS PHYSICAL ADDRESSING
	JRST	SETMA4		;JOIN COMMON CODE



;SET EPT (AND POSSIBLY UPT FOR PER-PROCESS AREA IF KI PAGING)

SETEPT:	SKPKIP			;KI PAGING?
	JRST	SETMAP		;NO, JUST LIKE UPT
	TXNE	F,FAF		;USER GIVE UPT?
	SKIPA	TT,LLIMIT	;YES, USE IT
	SETO	TT,		;NO, -1 MEANS PER-PROCESS AREA INACCESSIBLE
	HRL	T,TT		;STORE USER,,EXEC IN MAPPG
	JRST	SETMA2		;JOIN COMMON CODE



;SET SECTION MAP

SETSEC:	SKPKLP			;ONLY LEGAL IF KL PAGING
	JRST	ERR		;OTHERWISE FORGET IT


;SET ANY MAP-THE-ADDRESS-SPACE FUNCTION.  $U FUNCTION CODE IS STILL IN W.

SETMAP:	TXNE	F,FAF		;EXTRA ARG?
	JRST	ERR		;YES, COMPLAIN
SETMA2:	TXNE	F,CCF		;TWO ALTS?
	TXO	W,1B1		;YES, 1B1 MEANS FETCH SPT INDEX
	SETOM	FAKEAC		;USE FAKE ACS BY DEFAULT
SETMA4:	MOVEM	W,MAPFN		;STORE FUNCTION FOR MAPADR
	MOVEM	T,MAPPG		;PAGE OR SPT OFFSET
	POPJ	P,		;DONE



;SET FAKE ACS


SETFAC:	CAIE	T,0		;USER SAY TO USER FAKE ACS?
	SETO	T,		;YES, FLAG IT AS SUCH
	MOVEM	T,FAKEAC	;STORE USER ARG
	POPJ	P,		;DONE



;SET AC BLOCK

IFE FTEXEC,<SETACB==ERR>	;EDDT ONLY

IFN FTEXEC,<
SETACB:	SKPEXC			;EXEC MODE?
	JRST	ERR		;NO, ILLEGAL IN USER MODE
	MOVE	W2,T		;ARG WHERE SELAC WANTS IT
	PUSHJ	P,SELAC		;SELECT AC BLOCK
	  JRST	ERR		;SOMETHING'S WRONG
	POPJ	P,		;DONE
> ;END IFN FTEXEC
;LOAD ACS FROM ADDRESS

SETCAC:	MOVE	R,T		;ADDRESS IN R
	MOVEM	R,FAKEAD	;SAVE FOR USER TO READ LATER
	MOVSI	S,-20		;LOOP COUNT/INDEX
	SETZM	FAKEAC		;DON'T GET FAKE ACS FROM FAKE ACS
SETCA2:	PUSHJ	P,FETCH		;GET A WORD FROM MEMORY
	 JRST	ERR		;ERROR
	MOVEM	T,AC0(S)	;SAVE AC AWAY IN INTERNAL AC BLOCK
	ADDI	R,1		;ADVANCE TO NEXT AC
	AOBJN	S,SETCA2	;GET ALL 20 ACS
	SETOM	FAKEAC		;FLAG USING FAKE 0 - 17
	POPJ	P,		;DONE




;SET SPT BASE

SETSPT:	MOVEM	T,SPTWRD	;STORE USER ARG
	POPJ	P,		;DONE


;SET CST BASE

SETCST:	MOVEM	T,CSTWRD	;STORE USER ARG
	POPJ	P,		;DONE
;SET PROTECTION AND RELOCATION

SETREL:	MOVEM	T,UBASE		;STORE RELOCATION ADDRESS
	POPJ	P,		;DONE

SETPRT:	MOVEM	T,UPROT		;STORE PROTECTION ADDRESS
	POPJ	P,		;DONE



;SET PAGING MODE (KI/KL), ERROR IF IN EXEC MODE

SETKIP:	SKIPE	W1,T		;TURNING ON OR OFF?
	SETO	W1,		;ON
	SETZ	W2,		;THEREFORE NO KL-PAGING
	JRST	SETKXP		;COMMON CODE

SETKLP:	SKIPE	W2,T		;TURNING ON OR OFF?
	SETO	W2,		;ON
	SETZ	W1,		;THEREFORE NO KL-PAGING

SETKXP:
IFN	FTEXEC,<		;EXEC MODE IS ILLEGAL
	SKPUSR			;IN USER OR EXEC MODE?
	JRST	ERR>		;EXEC, THEN DON'T DO IT ERE DEATH RESULT

	MOVEM	W1,KIPAG	;SET APPROPRIATE KI-PAGING FLAG
	MOVEM	W2,KLPAG	;SET APPROPRIATE KL-PAGING FLAG
	POPJ	P,		;END OF COMMAND
SUBTTL	COMMAND ROUTINES -- BREAKPOINT FACILITY

IFE FTFILE,<

;ALL $B COMMANDS GET HERE IN FORM: <A>$<N>B
;
;NOTE THAT BREAKPOINT 0 IS TREATED SPECIAL IN THAT IT IS RESERVED FOR
;"UNSOLICITED" BREAKPOINTS - I.E., OCCASIONS WHEREIN CONTROL ARBITRA-
;RILY PASSES TO DDT WITHOUT DDT'S EXPECTING IT - EITHER BY THE USER PRO-
;GRAM EXECUTING A "JSR $0BPT" OR VIA A MONITOR/EXEC INTERRUPT. IN EITHER
;CASE THERE IS NO INSTRUCTION TO BE SAVED/RESTORED/EXECUTED, NO PROCEED
;COUNT, NO CONDITIONAL BREAK INSTRUCTION, ETC. ON PROCEED CONTROL IS
;SIMPLY RETURNED TO THE "INTERRUPTED" PROGRAM.

BPS:	TXNN	F,SAF		;USER TYPE .GT. ARG (NOT USED)?
	SKIPE	MAPFN		;ANY MAPPING IN EFFECT
	 JRST	ERR		;EXTRA ARGS OR NOT STRAIGHT VIRTUAL
	TXNE	F,QF		;HAS <A> BEEN TYPED?
	JRST	BPS1		;YES
	TXNE	F,FAF		;HAS ADDR TO TYPEOUT BEEN TYPED?
	JRST	ERR		;YES, ILLEGAL UNLESS WE SAW <A> TOO
	TXNE	F,Q2F		;HAS <N> BEEN TYPED?
	JRST	BPS2		;YES
	MOVE	T,[BPT$B+B$SIZ,,BPT$B+B$SIZ+1]  ;NO - COMMAND IS $B
	SETZM	BPT$B+B$SIZ	;ZERO FIRST WORD OF BREAKPOINT STUFF
	BLT	T,BPT$E-1	;CLEAR OUT ALL BREAKPOINTS
	POPJ	P,
;STILL IFE FTFILE

BPS1:	SKIPN	R,T		;SAVE COPY OF BREAKPOINT ADDRESS
	JRST	BPS1A		;<A> = 0 MEANS CLEAR A BPT, NOT SET ONE
	PUSHJ	P,FETCH		;CAN BREAKPOINT BE INSERTED HERE?
	  SETZ	T,		;PAGE DOESN'T EXIST, BUT WE MIGHT CREATE IT
	PUSHJ	P,DMEMER	;CAN'T SET BPT IF CAN'T WRITE
	PUSH	P,R		;HANG ON TO R FOR MOMENT
	HRRI	R,DDT		;HANDY DANDY LOCATION WE KNOW ABOUT
	PUSHJ	P,FETCH		;READ THAT SECTION ADDRESS IN OTHER SECTION
	  JRST	ERR		;CAN'T READ, ERGO NO DDT, ERGO ERROR
	CAME	T,DDT		;DO WE SEEM TO BE IN OTHER SECTION?
	JRST	ERR		;NO, SO NO BREAKPOINT THERE
	POP	P,R		;NOW RESTORE R
BPS1A:	TXNN	F,Q2F		;HAS <N> BEEN TYPED?
	JRST	BPS3		;NO
BPS2:	MOVE	S,WRD2D		;YES - GET DESIRED BREAKPOINT NUMBER
	CAIL	S,0		;WITHIN RANGE?
	CAILE	S,NBP		; . . .
	JRST	ERR		;NO - COMPLAIN AT USER
	IMULI	S,B$SIZ		;YES, MAKE INTO BREAKPOINT "INDEX"
	TXNN	F,QF		;NOW - WAS <A> SPECIFIED?
	JRST	[XMOVEI	T,BPT$B(S)  ;NO - RELOCATE INTO BREAKPOINT AREA
		JRST	MASK2]	;TREAT AS NORMAL ADDRESS
	JUMPE	R,[SETZM BPT$B+B$ADR(S)	;IF 0$<N>B, JUST CLEAR BPT N
		POPJ	P,]	;DONE
	MOVE	T,R		;BREAKPOINT ADDRESS INTO T
	MOVEI	R,B$SIZ		;START WITH $1B
BPS2E:	CAMN	T,BPT$B+B$ADR(R);SOME OTHER BREAKPOINT HAVE THIS ADDRESS?
	SETZM	BPT$B+B$ADR(R)	;YES - BUT NOT ANYMORE!
	ADDI	R,B$SIZ		;ADVANCE TO NEXT BREAKPOINT SLOT
	CAIGE	R,B$SIZ*<NBP+1>	;CHECKED THEM ALL YET?
	JRST	BPS2E		;NOPE - GO GET THE REST
	JRST	BPS5		;YES - GO DEFINE THIS (NEW) BREAKPOINT
;STILL IFE FTFILE

BPS3:	SKIPN	T,R		;PUT THE BREAKPOINT ADR BACK IN T
	JRST	ERR		;0$B IS ILLEGAL
	MOVEI	S,B$SIZ		;PROCESS THE COMMAND A$B

;FIRST SEARCH FOR BREAKPOINT ALREADY ASSIGNED TO REQUESTED ADDRESS

BPS4:	CAMN	T,BPT$B+B$ADR(S);THIS BREAKPOINT HAVE ADDRESS ALREADY?
	JRST	BPS5		;YES - PUT BREAKPOINT HERE
	ADDI	S,B$SIZ		;ADVANCE TO NEXT SLOT
	CAIGE	S,B$SIZ*<NBP+1>	;TRIED THEM ALL YET?
	JRST	BPS4		;NO - KEEP ON LOOKING

;NOW SEARCH FOR A UNUSED BREAKPOINT

	MOVEI	S,B$SIZ		;START AT $1B
BPS4E:	SKIPN	BPT$B+B$ADR(S)	;IS THIS BREAKPOINT IN USE?
	JRST	BPS5		;NO - USE IT
	ADDI	S,B$SIZ		;YES, ADVANCE TO NEXT SLOT
	CAIGE	S,B$SIZ*<NBP+1>	;TRIED THEM ALL YET?
	JRST	BPS4E		;NO - KEEP ON LOOKING
	JRST	ERR		;YES, NO MORE BREAKPOINTS LEFT

;NOW HAVE ADDRESS IN T, BREAKPOINT INDEX IN S, SET NEW BREAKPOINT

BPS5:	MOVEM	T,BPT$B+B$ADR(S);SET NEW BREAKPOINT ADDRESS
	MOVSI	T,(JFCL)	;A HANDY NOOP (ALBEIT SLOW ON KL-10'S)
	MOVEM	T,BPT$B+B$XCT(S);PRESET USER CONDITIONAL BREAK INSTRUCTION
	MOVEI	T,1		;DEFAULT PROCEED COUNT
	MOVEM	T,BPT$B+B$CNT(S);SET THAT ALSO
	TXZE	F,FAF		;USER SPECIFY ADDRESS TO BE OPENED ON BREAK?
	SKIPA	T,LLIMIT	;YES
	SETO	T,		;NO
	MOVEM	T,BPT$B+B$OPN(S);REMEMBER WHICH
	SETZM	BPT$B+B$FLG(S)	;CLEAR OUT ALL BREAKPOINT FLAGS
	MOVX	T,BP$PRO	;AUTO PROCEED FLAG
	TXNE	F,CCF		;AUTO-PROCEEDING BREAKPOINT ($$B)?
	IORM	T,BPT$B+B$FLG(S);YES, MARK ACCORDINGLY
	MOVE	T,[JSR BCOM]	;BREAKPOINT JSR'S TO
	MOVEM	T,BPT$B+B$JSR(S);THIS INSTRUCTION
	POPJ	P,		;RETURN WITH NEW BREAKPOINT SET
;STILL IFE FTFILE

;HERE ON $P COMMAND -- PROCEED FROM A BREAKPOINT

PROCD:	SKIPN	BPTIP		;BREAKPOINT IN PROGRESS?
	JRST	ERR		;NO, $P ILLEGAL
	SKIPE	S,BPTDX		;GET BREAKPOINT INDEX
	TXNN	F,QF		;EXPLICIT PROCEED COUNT?
	MOVEI	T,1		;NO (OR PROCEED FROM $0B)
	MOVEM	T,BPT$B+B$CNT(S);SET NEW PROCEED COUNT
	MOVX	T,BP$PRO	;AUTO PROCEED FLAG
	ANDCAM	T,BPT$B+B$FLG(S);CLEAR AUTO PROCEED
	TXNE	F,CCF		;UNLESS AUTO PROCEED ($$P)
	IORM	T,BPT$B+B$FLG(S);IN WHICH CASE SET AUTO PROCEED
IFN	FTEXEC,<PUSHJ P,RSTAC>	;MAKE SURE HAVE RIGHT CONTEXT ACS
PROCD2:	PUSHJ	P,TCRLF		;<CR><LF> FOR NEATNESS
	SKIPE	I.LOG		;STILL AT BREAKPOINT PC?
	SETZM	BPTDX		;NO, NO NEED TO SIMULATE, JUST JUMP TO USER
				; NOTE THAT THIS MEANS THAT IF THE USER
				; HAS $X'ED AWAY FROM THE BREAKPOINT AND
				; BACK AGAIN THEN AN IMMEDIATE BREAKPOINT
				; WILL RESULT.

;HERE FROM A BREAKPOINT WHEN IT IS NOT YET TIME TO BREAK. THE BREAKPOINT
;INSTRUCTION MUST BE SIMULATED AND CONTROL RETURNED TO THE USER PROGRAM.

PROCD4:	SKIPN	BPTDX		;NEED TO SIMULATE AN INSTRUCTION FIRST?
	JRST	PROCD8		;NO, RETURN DIRECTLY TO USER PROGRAM
	PUSHJ	P,$PX		;SIMULATE ONE INSTRUCTION (HANDLES ERCAL/JMP)
	 JRST	ERR		;FATAL ERROR SOMEWHERE
				; (NOTE THAT AT THIS POINT THE USER HAS
				;  NOT YET BEEN INFORMED DDT EVEN HAS
				;  CONTROL IF THIS IS A NON-BREAKING
				;  BREAKPOINT!)

PROCD8:	PUSHJ	P,INSRTB	;INSERT USER PROGRAM BREAKPOINTS
	SETZM	BPTIP		;CLEAR BREAKPOINT IN PROGRESS (NO 2ND $P)
	SETZM	I.NPC		;ALSO CLEAR PREVIOUS $X PC
	MOVE	T,PCWRD		;ADDRESS IN USER PROGRAM AT WHICH TO RESUME
	JRST	RESTOR		;RETURN TO USER PROGRAM

> ;END IFE FTFILE FROM PAGES AGO

IFN	FTFILE,<BPS==<PROCD==ERR>>
SUBTTL	COMMAND ROUTINES -- EXECUTE AND SINGLE STEP

IFE FTFILE,<

XEC:	SKIPE	MAPFN		;STRAIGHT VIRTUAL ADDRESSING?
	JRST	ERR		;NO - ERROR
	TXNN	F,QF		;SKIP IF QUANTITY TYPED
	TDZA	T,T		;MAKE SURE COUNT IS ZERO
	TXNN	T,777B8		;SKIP IF VALID INSTRUCTION
	JRST	$X		;GOTO SINGLE STEP EXECUTE ROUTINE
XEC0:	MOVEM	T,TEM
	PUSHJ	P,TCRLF
IFN	FTEXEC,<PUSHJ P,RSTAC>	;ENSURE PROPER CONTEXT AC BLOCK
	PUSHJ	P,INSRTB
	SETZM	SKPCT		;INIT SKIP COUNT
	JSP	T,RESTORE
	XCT	TEM
XEC1:	REPEAT	SKPMAX,<AOS SKPCT>	;[211] NOTE COUNT OF LOCS SKIPPED
XEC2:	JSR	SAVE		;SAVE CONTEXT
	 PUSHJ	P,REMOVB	;REMOVE BRKPTS
	MOVEI	TT,SKPMAX	;[211]
	SUB	TT,SKPCT	;COMPUTE AMOUNT OF PC INCREMENT
	SETZM	SKPCT		;[211] DON'T CONFUSE OTHERS
	MOVEI	T,"<"		;INDICATE INSTRUCTION RETURNED
	PUSHJ	P,TOUT		;SINCE LINE-FEED ISN'T VERY VISIBLE
	JUMPE	TT,XEC4		;IF INST DIDN'T SKIP, JUST CLOSE BRACKETS
	MOVEI	W1,[ASCIZ "SKIP"]	;MAKE SURE IT IS CLEAR
	PUSHJ	P,TSTRG		; THAT THIS WAS A SKIP
	CAIG	TT,1		;SINGLE SKIP?
	JRST	XEC4		;YES, JUST CLOSE OFF
	PUSHJ	P,TSPC		;TYPE A SPACE
	MOVEI	T,"0"(TT)	;GET ASCII CHAR COUNT
	PUSHJ	P,TOUT		;TYPE IT
XEC4:	MOVEI	T,">"		;CLOSE OFF SKIP MESSAGE
	PUSHJ	P,TOUT		;WITH A CLOSE ANGLE BRACKET
	PUSHJ	P,TCRLF		;TYPE 2 CR-LFEEDS
	JRST	DD1
;STILL IFE FTFILE

;$X IS A  FEATURE THAT OPERATES AS FOLLOWS:
;	$X OR N$X OR $$X OR N$$X, WHERE N .LT. 2^27, WILL DISPATCH TO
;	THIS CODE.  THE FOLLOWING ACTIONS WILL BE PERFORMED:
;
;   $X EXECUTE A SINGLE INSTRUCTION, THEN INCREMENT THE PC.  THE
;	OPERANDS TO THE INSTRUCTION WILL BE PRINTED OUT AS THEY
;	EXIST **AFTER** EXECUTION OF THE INSTRUCTION. <SKP>
;	OR <JMP> WILL BE PRINTED IF THE INSTRUCTION SKIPPED OR
;	JUMPED.  THE NEXT INSTRUCTION WILL THEN BE PRINTED.
;	$P WILL ALWAYS DO THE RIGHT THING AFTER ANY NUMBER OF $X'S.
;
;  N$X REPEAT THE $X CYCLE N TIMES.
;
; N$$X SAME AS N$X EXCEPT THAT ALL PRINTOUT IS SUPPRESSED FOR
;	ALL BUT THE LAST $X CYCLE.
;
;  $$X PERFORM A NON-PRINTING $X CYCLE UNTIL THE PC REACHES
;	.+SKPMAX; I.E. UNTIL ONE OF THE NEXT SKPMAX+1 INSTRUCTIONS IS
;	EXECUTED.  THIS IS USEFUL FOR TREATING A SUBROUTINE CALL
;	AS A SINGLE INSTRUCTION FOR THE PURPOSES OF $X.
;
;  L<U>$$X IS LIKE $$X ONLY "L" IS THE EXPLICIT LOWER ADDRESS AND
;	"U" IS THE EXPLICIT UPPER ADDRESS WHICH, IF THE PC ENTERS
;	L .LE. PC .LE. U THE $$X TERMINATES.

IFL	SKPMAX-3,<PRINTX ?SKPMAX TOO SMALL, MUST BE AT LEAST THREE>
;STILL IFE FTFILE

;FLAGS USED IN $X LOGIC ONLY

FAC==	400000			;AC TO BE PRINTED
DFAC==	200000			;INSTRUCTION USES 2 ACS
QFAC==	100000			;INSTRUCTION USES 4 ACS
FLG==	040000			;INSTRUCTION MODIFIES FLAGS (JRST,JFCL)
IMM==	020000			;IMMEDIATE MODE INSTRUCTION
EA==	010000			;MEMORY REFERENCE INSTRUCTION
DEA==	004000			;INSTRUCTION REFERENCES 2 MEM LOCATIONSS
QEA==	002000			;INSTRUCTION REFERENCES 4 MEM LOCATIONSS
FLA==	001000			;FLOATING AC OPERAND
FLE==	000400			;FLOATING MEM OPERAND
EA2==	000200			;EA HAS AN EA (E.G., BYTE POINTER)
BPA==	000100			;BYTE POINTER AC OPERAND
BPE==	000040			;BYTE POINTER MEM OPERAND
IMM2==	000020			;SECOND EA IS IMMEDIATE
FECJ==	000010			;INSTRUCTION FOLLOWED BY ERCAL THAT JUMPED
FEJJ==	000004			;INSTRUCTION FOLLOWED BY ERJMP THAT JUMPED
FECJS==	000002			;ERCAL/ERJMP GOT SKIPPED
XIMM==	000001			;EXTENDED IMMEDIATE MODE INSTRUCTION


$XW$L==	100			;ALL OPCODES .LT. $XW$L ARE DANGEROUS
$XW$U==	677			;ALL OPCODES .GT. $XW$U ARE DANGEROUS


IFE	FTEXEC,<
MONUI== JUSTI			;IF USER DDT, TREAT MONITOR UUOS
MONUE== JUSTE			;  AS HARDWARE INSTRUCTIONS
MONUAI==SETI
MONUAE==SETEA
>
;STILL IFE FTFILE

;COME HERE FROM $X COMMAND, WITH T SET TO ZERO IF NO QUANTITY WAS
;   TYPED.

$X:	SKIPN	BPTIP		;HAVE WE HIT A BREAKPOINT?
	JRST	ERR		;NO, $X IS ILLEGAL
	MOVEM	T,I.REP		;STORE REPETITION COUNT
	JUMPG	T,$X0		;JUMP IF POSITIVE COUNT
	MOVE	T,PCWRD		;ZERO, FETCH CURRENT PC
	MOVEM	T,LOCSAV	;AND REMEMBER IT
	HRRI	T,1(T)		;INSTRUCTION PC + 1
	TXNE	F,FAF		;USER GIVE BASE PC AT WHICH TO STOP?
	SKIPA	T,LLIMIT	;YES, FETCH IT
	MOVEM	T,LLIMIT	;NO, SUPPLY OUR DEFAULT
	JUMPL	T,ERR		;NEGATIVE BOUNDARY IS NOT ACCEPTABLE
	HRRI	T,SKPMAX(T)	;DEFAULT STOPPING PLACE
	TXNN	F,SAF		;USER SUPPLY EXPLICIT STOPPING BOUNDRY?
	MOVEM	T,ULIMIT	;NO, SUPPLY OUR DEFAULT
	SKIPL	T,ULIMIT	;GET UPPER BOUNDARY
	CAMGE	T,LLIMIT	;IS UPPER BOUNDARY ABOVE LOWER BOUNDARY?
	JRST	ERR		;NO, ERROR
	SETOM	I.REP		;SET REPETITION COUNT NEGATIVE
	TXNN	F,CCF		;$$X WITH NO ARG?
	MOVNS	I.REP		;NO, ONLY $X. TREAT AS 1$X
$X0:	PUSHJ	P,TCRLF		;OUTPUT CRLF TO START
	SETZM	I.PXC		;CLEAR IN CASE STICKY
	PUSHJ	P,$X01		;DO INSTRUCTION SIMULATION/TRACE STUFF
	 JRST	ERR		;SOMETHING SOMEWHERE KROAKED
	POPJ	P,		;RETURN FROM $X COMMAND



;HERE FROM ANYPLACE ($P) TO QUIETLY EXECUTE ONE USER INSTRUCTION
;(ADDRESS IN PCWRD) AND RETURN WITHOUT OTHERWISE CHANGING THE WORLD
;AS IN TYPING THE INSTRUCTION OR "<ERSKP>" OR SO FORTH.

$PX:	MOVEM	F,I.PXF		;SAVE FLAGS OF CALLER
	TXO	F,CCF		;INDICATE TO BE QUIET
	MOVNI	T,2		;AND STAY QUIET
	MOVEM	T,I.REP		; . . .
	SETOM	I.PXC		;AND FURTHER, RETURN AFTER ONE ITERATION
	PUSHJ	P,$X01		;DO INSTRUCTION SIMULATION/TRACE STUFF
	 SOS	(P)		;SOMETHING SOMEWHERE KROAKED
	MOVE	F,I.PXF		;RESTORE CALLERS FLAGS
	JRST	CPOPJ1		;AND RETURN TO CALLER
;STILL IFE FTFILE

;HERE ON REPEATED $X CYCLES

$X01:	AOS	I.LOG		;COUNT $X CYCLES FOR $P
	SOSN	I.REP		;DECREMENT AND TEST COUNTER
	TXZ	F,CCF		;CLEAR $$ FLAG TO END REPETITIONS
	TXZ	F,QF!CF!STF	;TURN OFF QUANT, $, ! FLAGS
	MOVEM	F,FLAGS		;SAVE REGULAR DDT FLAGS
	HRRZI	T,INDPTH	;SETUP MAX XCT DEPTH
	HRRZM	T,XCTS
	MOVE	R,PCWRD		;FETCH ADR OF CURRENT INST
	SKIPL	I.REP		;INDEFINITE $$X BEING EXECUTED?
	MOVEM	R,LOCSAV	;NO, REMEMBER OLD PC FOR THIS INST
	MOVEM	R,I.NPC		;SAVE INSTRUCTION PC
$X02:	PUSHJ	P,FETCH		;FETCH CURRENT INSTRUCTION
	 POPJ	P,		;ERROR
$X03:	MOVEM	T,I.NST		;STORE CURRENT INSTRUCTION
IFN	FTEXEC,<		;SPECIAL JUNK KS-10
	SKPUSR			;IF USER MODE
	SKPKS			;OR NOT ON A KS-10
	JRST	$X05		;JUST DO IT "NORMALLY"
	LDB	W2,[POINT 9,I.NST,8]  ;OPCODE ABOUT TO BE EXECUTED
	CAIE	W2,704		;IF UMOVE
	CAIN	W2,705		;OR UMOVEM
	JRST	$X08		;LEAVE ALONE
	CAIL	W2,710		;SIMILARLY, IF A
	CAILE	W2,727		;UNIBUS-FONDLING INSTRUCTION
	CAIA			;(ISN'T - TREAT NORMALLY)
	JRST	$X08		;LEAVE INSTRUCTION ALONE
> ;END OF IFN FTEXEC
$X05:	HLLZ	S,PCWRD		;SETUP "SECTIONESS" FOR EFFECTIVE ADR CALC
	EXCH	F,FLAGS		;RETURN TO REAL DDT FLAGS
	PUSHJ	P,CEFFIX	;CALCULATE REAL EFFECTIVE ADDRESS
	 POPJ	P,		;MEMORY READ ERROR
	EXCH	F,FLAGS		;BACK TO $X FLAGS
	MOVEM	T,I.NSTE	;SAVE EFFECTIVE ADDRESS
	MOVE	T,[Z @I.NSTE]	;SETUP INTERCEPT ADDRESS POINTER
	DPB	T,[POINT 23,I.NST,35]	;STORE INTERCEPT ADR IN CURRENT INST
IFN	FTEXEC,<		;MORE KS-10 KROCKS
	CAIA			;JUST SKIP IF NORMAL
$X08:	SETOM	I.KRCK		;FLAG KS-10 SPECIAL (NO TYPEOUT)
> ;END OF IFN FTEXEC

;CONTINUED ON NEXT PAGE
;STILL IFE FTFILE

;CONTINUED FROM PREVIOUS PAGE

	SETZM	I.NXIT		;ASSUME SAFE INSTRUCTION
	LDB	W1,[POINT 9,I.NST,8]  ;GET OPCODE
	CAIL	W1,$XW$L	;KNOWN TO BE
	CAILE	W1,$XW$U	;A DANGEROUS INSTRUCTION?
	JRST	$X12		;YES
	SUBI	W1,$XW$L	;NO, MUST CHECK IT, SHIFT IT DOWN
	IDIVI	W1,^D36		;W1:=INDEX; W2:=BIT NUMBER
	MOVX	TT,1B0		;THE TEST BIT
	MOVN	W2,W2		;POSITION COUNTER
	LSH	TT,(W2)		;POSITION TO BIT "N"
	TDNE	TT,$XWTBL(W1)	;"DANGEROUS" BIT SET?
$X12:	SETOM	I.NXIT		;FLAG DANGEROUS INSTRUCTION
	LDB	W1,[POINT 4,I.NST,12]	;EXTRACT AC FIELD
	MOVEM	W1,I.NSTAC	;STORE IT AWAY
	SETOM	I.NJMP		;FLAG NO JUMP TRANSFER ADDRESS (YET)
	MOVSI	T,777000	;MASK FOR OPCODE
	AND	T,I.NST		;FETCH OPCODE
	HLRZ	F,T		;SAVE IN RH FOR LATER
	SETZ	TT,		;START OF TABLE INDEX
	CAMLE	T,$XTBL(TT)	;IN RANGE OF CURRENT TABLE ENTRY?
	AOJA	TT,.-1		;NO, KEEP SEARCHING
	HRRZ	TT,$XTBL(TT)	;FETCH INSTRUCTION HANDLER
				;NOTE R, W1 SETUP FOR INSTRUCTION HANDLERS
	JRST	(TT)		;DISPATCH TO INSTRUCTION HANDLER
;STILL IFE FTFILE

;$XWTBL - TABLE OF DANGEROUS OPCODES - I.E., INSTRUCTIONS AFTER
;WHICH DDT CAN NO LONGER TRUST SYMBOL TABLE POINTERS ETC., OR
;WHICH MAY USE/SET TERMINAL AND OTHER CHARACTERISTICS THAT DDT
;CHANGES.

IF1	<			;;INIT FLAG WORDS PASS 1
DEFINE	$$XW0 (NDX),<$XW.'NDX==0>  ;;INITIALIZE ALL BITS TO 0

$$XW..==-1			;;INITIALIZE INITIALIZATION COUNTER
REPEAT	<<$XW$U-$XW$L>/^D36>,<	;;ONCE FOR EACH BLOCK OF 36 OPCODES
	$$XW..==$$XW..+1	;;NEXT BLOCK OF 36 OPCODES
	$$XW0 (\$$XW..) >	;;SET ALL TO ZERO (END OF REPEAT)

	PURGE	$$XW0,$$XW..	;;DON'T NEED GARBAGE SYMBOLS ANYMORE
> ;END IF1

IF2	<			;;SET THE BITS ON PASS2
DEFINE	$$XW (OP),<		;;THE SET-THE-BIT MACRO
$$XW.1==<<<<OP>_-^D27>-$XW$L>/^D36>  ;;"INDEX" INTO BIT TABLE
$$XW.2==<<<<OP>_-^D27>-$XW$L> - <<<<<OP>_-^D27>-$XW$L>/^D36>*^D36>>
				;;BIT WITHIN INDEX WORD IN BIT TABLE
$$XW1	(\$$XW.1,\$$XW.2)>	;;SET THE BIT (END OF MACRO DEFINITION)

DEFINE	$$XW1 (NDX,BIT),<$XW.'NDX==$XW.'NDX ! 1B^O'BIT>  ;;SET THE BIT

;NOW FLAG ALL OPCODES WHICH WE CONSIDER "DANGEROUS"

	$$XW	JSYS
	$$XW	DMOVEM
	$$XW	DMOVNM
	$$XW	IDPB
	$$XW	DPB
	$$XW	FADM
	$$XW	FADB
	$$XW	FADRM
	$$XW	FADRB
	$$XW	FSBM
	$$XW	FSBB
	$$XW	FSBRM
	$$XW	FSBRB
	$$XW	FMPM
	$$XW	FMPB
	$$XW	FMPRM
	$$XW	FMPRB
	$$XW	FDVM
	$$XW	FDVB
	$$XW	FDVRM
	$$XW	FDVRB
	$$XW	MOVEM
	$$XW	MOVSM
	$$XW	MOVSS
	$$XW	MOVNM
	$$XW	MOVNS
	$$XW	MOVMM
	$$XW	MOVMS
	$$XW	IMULM
	$$XW	IMULB
	$$XW	MULM
	$$XW	MULB
	$$XW	IDIVM
	$$XW	IDIVB
	$$XW	DIVM
	$$XW	DIVB
	$$XW	EXCH
	$$XW	BLT
	$$XW	XCT
	$$XW	ADDM
	$$XW	ADDB
	$$XW	SUBM
	$$XW	SUBB
	$$XW	AOS
	$$XW	AOSL
	$$XW	AOSE
	$$XW	AOSLE
	$$XW	AOSA
	$$XW	AOSGE
	$$XW	AOSN
	$$XW	AOSG
	$$XW	SOS
	$$XW	SOSL
	$$XW	SOSE
	$$XW	SOSLE
	$$XW	SOSA
	$$XW	SOSGE
	$$XW	SOSN
	$$XW	SOSG
	$$XW	SETZM
	$$XW	SETZB
	$$XW	ANDM
	$$XW	ANDB
	$$XW	ANDCAM
	$$XW	ANDCAB
	$$XW	ANDCMM
	$$XW	ANDCMB
	$$XW	SETAM
	$$XW	SETAB
	$$XW	XORM
	$$XW	XORB
	$$XW	IORM
	$$XW	IORB
	$$XW	ANDCBM
	$$XW	ANDCBB
	$$XW	EQVM
	$$XW	EQVB
	$$XW	SETCAM
	$$XW	SETCAB
	$$XW	ORCAM
	$$XW	ORCAB
	$$XW	SETCMM
	$$XW	SETCMB
	$$XW	SETOM
	$$XW	SETOB
	$$XW	HLLM
	$$XW	HLLS
	$$XW	HRLM
	$$XW	HRLS
	$$XW	HLLZM
	$$XW	HLLZS
	$$XW	HRLZM
	$$XW	HRLZS
	$$XW	HLLOM
	$$XW	HLLOS
	$$XW	HRLOM
	$$XW	HRLOS
	$$XW	HLLEM
	$$XW	HLLES
	$$XW	HRLEM
	$$XW	HRLES
	$$XW	HRRM
	$$XW	HRRS
	$$XW	HLRM
	$$XW	HLRS
	$$XW	HRRZM
	$$XW	HRRZS
	$$XW	HLRZM
	$$XW	HLRZS
	$$XW	HRROM
	$$XW	HRROS
	$$XW	HRREM
	$$XW	HRRES
	$$XW	HLREM
	$$XW	HLRES
	PURGE	$$XW,$$XW1,$$XW.1,$$XW.2
> ;END IF2

DEFINE	$$XWRD (NDX),<EXP	$XW.'NDX>

$XWTBL:				;;DANGEROUS OPCODE BIT TABLE
$$XW..==-1			;;INITIALIZE BIT TABLE INDEX
REPEAT	<<$XW$U-$XW$L>/^D36>,<
	$$XW..==$$XW..+1	;;NEXT WORD OF BIT TABLE
	$$XWRD	(\$$XW..)
> ;;END OF REPEAT

IF2	<PURGE	$$XWRD,$$XW..>	;;JUNK SYMBOLS
;STILL IFE FTFILE

;OPCODE DISPATCH TABLE.
;   LH OF EACH ENTRY CONTAINS LARGEST OPCODE COVERED BY THAT ENTRY,
;   RH CONTAINS DISPATCH ADDRESS.

$XTBL:	SETZB	SET		; 400-403  SETZX
	SETM	CHECKI		; 404-414  ALL LOGICAL EXCEPT SETX
	XMOVEI	SETIX		;     415  XMOVEI
	ORCBB	CHECKI		; 416-473  ALL LOGICAL EXCEPT SETX
	SETOB	SET		; 474-477  SETOX
	HLRES	CHEKIS		; 500-577  HALFWORD
	TSON	TESTS		; 600-677  TEST CLASS
	777000,,IOTS		; 700-777  I/O INSTRUCTIONS
	0 ,, CPOPJ		;     000  ALWAYS ILLEGAL
	037000,,USRUUO		; 001-037  USER UUOS
	040000,,MONUAE		;     040  OLD TOPS-10 CALL
	INIT	MONINI		;     041  INIT
	CALLI	MONUAI		; 042-047  UNDEFINED AND CALLI
	TTCALL	MONUE		; 050-051  OPEN,TTCALL
	054000,,MONUAI		; 052-054  UNDEFINED
	OUT	MONUE		; 055-057  RENAME,IN,OUT
	STATO	MONUI		; 060-061  SETSTS,STATO
	GETSTS	MONUE		;     062  GETSTS
	OUTBUF	MONUI		; 063-065  STATZ,INBUF,OUTBUF
	OUTPUT	MONUE		; 066-067  INPUT,OUTPUT
	USETO	MONUI		; 070-075  CLOSE,RELEAS,MTAPE,UGETF,USETI,USETO
	ENTER	MONUE		; 076-077  LOOKUP,ENTER
	103000,,SETI		; 100-103  UNDEFINED
	JSYS	DOIT		;     104  JSYS
	ADJSP	SETI		; 105      ADJSP
	107000,,SETI		; 106-107  UNDEFINED
	DFDV	DFLOT		; 110-113  DFAD,DFSB,DFMP,DFDV		*** KI10
	DSUB	DMOV		; 114-115  DADD,DSUB
	DDIV	SETQFA		; 116-117  DMUL,DDIV
	DMOVN	DMOV		; 120-121  DMOVE,DMOVN			*** KI10
	FIX	FXAFLE		;     122  FIX				*** KI10
	123000,,SETI		;     123  UNDEFINED
	DMOVNM	DMOV		; 124-125  DMOVEM,DMOVNM		*** KI10
	FIXR	FXAFLE		;     126  FIXR				*** KI10
	FLTR	FLAFXE		;     127  FLTR				*** KI10
	UFA	IUFA		;     130  UFA
	DFN	IDFN		;     131  DFN
	FSC	IFSC		;     132  FSC
	IBP	IIBP		;     133  IBP
	ILDB	IIXBP		;     134  ILDB
	LDB	IXBP		;     135  LDB
	IDPB	IIXBP		;     136  IDPB
	DPB	IXBP		;     137  DPB
	FDVRB	FLOAT		; 140-177  FADXX,FSBXX,FMPXX,FDVXX
;STILL IFE FTFILE

;CONTINUATION OF OPCODE DISPATCH TABLE.

	MOVMS	CHEKIS		; 200-217  MOVXX
	IMULB	CHECKI		; 220-223  IMULX
	DIVB	MULDIV		; 224-237  MULX,XDIVX
	LSH	SETI		; 240-242  ASH,ROT,LSH
	JFFO	IJFFO		;     243  JFFO
	LSHC	DBLI		; 244-246  ASHC,ROTC,LSHC
	247000,,SETI		;     247  UNDEFINED
	EXCH	SETEA		;     250  EXCH
	BLT	SETI		;     251  BLT
	AOBJN	IAOBJ		; 252-253  AOBJP,AOBJN
	JRST	IJRST		;     254  JRST
	JFCL	IJFCL		;     255  JFCL
	XCT	IIXCT		;     256  XCT
	MAP	SETI		;     257  MAP				*** KI10
	PUSHJ	IIPUSHJ		;     260  PUSHJ
	POP	SETEA		; 261-262  PUSH,POP
	POPJ	IPOPJ		;     263  POPJ
	JSR	I.JSR		;     264  JSR
	JSP	I.JSP		;     265  JSP
	JSA	I.JSA		;     266  JSA
	JRA	IAOBJ		;     267  JRA
	SUBB	CHECKI		; 270-277  ADDX,SUBX
	CAIG	SETI		; 300-307  CAIXX
	CAMG	SETEA		; 310-317  CAMXX
	SOSG	JMPSKP		; 320-377  JUMPXX,SKIPXX,AOJXX,AOSXX,SOJXX,SOSXX
;STILL IFE FTFILE

;ALL OPCODES LESS THAN 100 END UP HERE
;MONITOR UUO HANDLER

IFN	FTEXEC,<
MONINI:	SKPEXC			;HANDLE USER AND EXEC DIFFERENTLY
	JRST	USRINI		;USER-MODE INIT
	JRST	MONUE0		;EXEC-MODE INIT

MONUAI:	TLO	F,FAC		;REMEMBER TO PRINT AC
MONUI:	SKPEXC			;SKIP IF EXEC MODE
	JRST	JUSTI		;USER MODE, TREAT UUO AS SINGLE INST
	JRST	MONUE0		;EXEC MODE, TRACE THE UUO

MONUAE:	TLO	F,FAC		;REMEMBER TO PRINT AC
MONUE:	SKPEXC			;SKIP IF EXEC MODE
	JRST	JUSTE		;USER MODE, TREAT UUO AS SINGLE INST
MONUE0:	SKPNKA			;CAN SIMULATE ON A KA
	JRST	USRUUO		;KA-10 EXEC MODE, TRACE THE UUO
	POPJ	P,		;KI/KL/KS EXEC MODE LOSES FOR THE MOMENT
> ;END IFN FTEXEC

;HANDLE INIT UUO (USER MODE ONLY)

IFE	FTEXEC,<MONINI:>	;USER INIT
USRINI:	MOVE	T,I.NST		;USER INIT INSTRUCTION
	TXZ	T,<@(17)>	;CLEAR BLETCH BITS
	HRR	T,I.NSTE	;GET I/O BITS AND MODE (TOPS-10)
	MOVEM	T,I.NJR0	;SET IN SCRATCH BLOCK
	MOVE	R,PCWRD		;ADDRESS OF INIT UUO
	HRRI	R,1(R)		;ADDRESS OF DEVICE WORD
	PUSHJ	P,FETCH		;GET IT
	 POPJ	P,		;MEMORY READ ERROR
	MOVEM	T,I.NJR1	;SET SECOND WORD OF SCRATCH BLOCK
	HRRI	R,1(R)		;ADDRESS OF BUFFER RING HEADER(S)
	PUSHJ	P,FETCH		;GET IT(THEM)
	 POPJ	P,		;MEMORY READ ERROR
	MOVEM	T,I.NJR2	;SET THIRD WORD OF SCRATCH BLOCK
	MOVE	T,[JRST DOITX0+3]  ;INIT "NON-SKIP" RETURN
	MOVEM	T,I.NJR3	;SET FOURTH WORD OF SCRATCH BLOCK
	HRRI	T,1(T)		;INIT "SKIP" RETURN
	MOVEM	T,I.NJR4	;FINISH OFF SCRATCH BLOCK
	MOVE	T,[JRST I.NJR0]	;NOW INTERCEPT DOITX'S XCT
	MOVEM	T,I.NST		;SET TO EXECUTE I.NJR? BLOCK
	JRST	DOITX		;GO DO IT
;USER UUO HANDLER

USRUUO:	MOVE	S,PCWRD		;PC OF USER INSTRUCTION
	TLNE	S,-1		;IN SECTION 0?
	JRST	SETEA		;TEMP . . .
	MOVEI	R,.JBUUO	;SETUP JOBUUO
	EXCH	F,FLAGS		;RESTORE REGULAR FLAGS
	MOVE	T,I.NST		;FETCH INST WITH EFF ADR @ I.NSTE
	TXZ	T,@		;CLEAR @ BIT
	HRR	T,I.NSTE	;MERGE IN COMPUTED EFFECTIVE ADDR
	PUSHJ	P,DEPMEM	;STORE USER UUO IN .JBUUO IF POSSIBLE
	 POPJ	P,		;MEMORY WRITE ERROR (?)
	EXCH	F,FLAGS		;RESTORE $X FLAGS
	MOVE	T,[XCT 41]	;PRETEND INSTRUCTION WAS AN XCT
	JRST	$X03
;STILL IFE FTFILE

;INTERPRET FSC

IFSC:	TLO	F,FAC+FLA+IMM	;FLOATING AC, FIXED IMMEDIATE E
	JRST	DOIT

;INTERPRET UFA

IUFA:	TLOA	F,FLA+FLE+DFAC	;REMEMBER FLTG PT, USES 2 ACS

;INTERPRET DFN

IDFN:	TLO	F,FLA!FLE	;DFN, REMEMBER AC AND E FLOAT
	JRST	SETEA

;INTERPRET FIX, FIXR, FLTR

FXAFLE:	TLOA	F,FLE		;REMEMBER THAT E FLOATS (FIX,FIXR)
FLAFXE:	TLO	F,FLA		;REMEMBER THAT AC FLOATS (FLTR)
	JRST	SETEA

;INTERPRET FLOATING POINT INSTRUCTIONS

FLOAT:	ANDI	F,7000		;FLOATING PT, GET MODE
	CAIN	F,1000		;LONG MODE?
	TLOA	F,DFAC		;YES, PRINT 2 ACS
	CAIE	F,5000		;IMMEDIATE MODE?
	TLOA	F,FLA+FLE+FAC+EA	;NO, PRINT AC AND E BOTH FLOATING
	TLO	F,FLA+FLE+FAC+IMM	;YES, PRINT AC AND E IMMEDIATE FLTG
	JRST	DOIT
;STILL IFE FTFILE

;INTERPRET JRST

IJRST:	JRST	@IJ$DSP(W1)	;DISPATCH TO JRST NN, HANDLER

IJ$DSP:	IFIW	IJ$00		;JRST 0,
	IFIW	IJ$01		;JRST 01, (PORTAL)
	IFIW	IJ$02		;JRST 02, (JRSTF)
	IFIW	IJ$03		;JRST 03,
	IFIW	IJ$04		;JRST 04, (HALT)
	IFIW	IJ$05		;JRST 05, (XJRSTF)
	IFIW	IJ$06		;JRST 06, (XJEN)
	IFIW	IJ$07		;JRST 07, (XPCW)
	IFIW	IJ$10		;JRST 10,
	IFIW	IJ$11		;JRST 11,
	IFIW	IJ$12		;JRST 12, (JEN)
	IFIW	IJ$13		;JRST 13,
	IFIW	JUSTE		;JRST 14, (XSFM) (TREAT LIKE SETOM)
	IFIW	IJ$15		;JRST 15,
	IFIW	IJ$16		;JRST 16,
	IFIW	IJ$17		;JRST 17,


;JRST 00, - NORMAL UNCONDITIONAL JRST

IJ$00:	TLO	F,IMM!XIMM	;PRINT "E"
	MOVE	R,I.NSTE	;NEW USER PC
	MOVEI	T,NOSKIP	;DDT TRANSFER ADDRESS
	JRST	IJ$RS		;COMMON CODE


;JRST 01, - PORTAL

IFE	FTEXEC,<SYN IJ$00,IJ$01>;USER PORTAL IS NORMAL JRST
IFN	FTEXEC,<
IJ$01:	TLO	F,IMM!XIMM	;PRINT "E"
	SKPUSR			;SPECIAL ONLY IF EXEC MODE
	SKPKA			;ON A KA-10
	JRST	IJ$00		;TREAT AS NORMAL JRST
	JRST	PROCD2		;RETURN TO USER MODE - CAN'T TRACE
> ;END OF IFN FTEXEC
;STILL IFE FTFILE

;JRST 02, - JRSTF

IJ$02:	TLO	F,IMM!XIMM!FLG	;PRINT "E" AND PC FLAGS
	HLLZ	T,LASEAF	;GET NEW PC FLAGS
IFN	FTEXEC,<JSP TT,IJ$US>	;ENTERING USER MODE?
	HRRI	T,NOSKIP	;DDT TRANSFER ADDRESS
	MOVEM	T,I.NJR0	;SET IN INTERNAL INTERCEPT BLOCK
	MOVE	T,[Z @I.NJR0]	;INDIRECT ADDR FOR JRSTF @
	MOVE	R,I.NSTE	;NEW USER PC
	JRST	IJ$RS		;COMMON CODE


;JRST 03,
;JRST 04, - HALT

	SYN	IJ$00,IJ$03	;JRST 03, IS UNKNOWN
	SYN	IJ$00,IJ$04	;JRST 04, IS LIKE JRST 00,


;JRST 05, - XJRSTF

IJ$05:	TLO	F,FLG!EA!DEA	;PRINT FLGS AND FLAG-PC DOUBLE WORD
	MOVE	R,I.NSTE	;EFFECTIVE ADDRESS OF FLAG-PC DOUBLE WORD
	JSP	W1,IJ$05F	;SETUP I.NJRXX
	XMOVEI	T,NOSKIP	;DDT INTERCEPT ADDRESS
	MOVEM	T,I.NJR3	;SET IN INTERCEPT BLOCK
	MOVEI	T,I.NJR2	;ADDR OF INTERCEPT BLOCK
	JRST	IJ$RS		;COMMON CODE

IJ$05F:	PUSHJ	P,FETCH		;GET FLAGS OF FLAG-PC DOUBLE WORD
	 POPJ	P,		;FAILURE
IFN	FTEXEC,<JSP TT,IJ$US>	;GOING FROM EXEC TO USER MODES?
	MOVEM	T,I.NJR2	;SET FLAGS IN FLAG WORD
	HRRI	R,1(R)		;EFFECTIVE ADDRESS + 1
	PUSHJ	P,FETCH		;GET DESIRED NEW USER PC
	 POPJ	P,		;FAILURE
	MOVE	R,T		;RETURN IN R
	JRST	(W1)		;RETURN TO CALLER


;JRST 06, - XJEN

	SYN	IJ$05,IJ$06	;JRST 06, - XJEN - TREAT LIKE XJRSTF
;STILL IFE FTFILE

;JRST 07, - XPCW

IJ$07:	TLO	F,FLG!EA!DEA!QEA  ;PRINT FLAGS AND 4 MEM LOCS
	MOVE	R,I.NSTE	;ADDRESS OF MEM BLOCK
	HRRI	R,2(R)		;ADDRESS OF NEW FLAG-PC DOUBLE WORD
	JSP	W1,IJ$05F	;SETUP I.NJRXX
	XMOVEI	T,IJ$07I	;DDT INTERCEPT ADDRESS
	MOVEM	T,I.NJR3	;SET IN INTERCEPT BLOCK
	MOVEI	T,I.NJR0	;ADDRESS OF INTERCEPT BLOCK
	JRST	IJ$RS		;COMMON CODE

IJ$07I:	JSR	SWAP		;SWAP TO DDT CONTEXT
	SKIPGE	I.NXIT		; . . .
	PUSHJ	P,TTYRET	; . . .
	MOVE	R,I.NSTE	;ADDRESS OF FOUR-WORD BLOCK
	MOVE	T,I.NJR0	;SAVED FLAGS
	PUSHJ	P,DEPMEM	;WRITE INTO USERS BLOCK
	 POPJ	P,		;MEMORY WRITE ERROR
	MOVE	T,I.NPC		;ADDRESS OF USER INSTRUCTION
	HRRI	T,1(T)		;PLUS ONE
	PUSHJ	P,DEPMEM	;FINISH USERS SAVED FLAG-PC DOUBLE WORD
	 POPJ	P,		;MEMORY WRITE ERROR
	JRST	TELLX		;FINISH UP THE $X


;JRST 10, ;JRST 11, ;JRST 12, ;JRST 13, ;JRST 15, ;JRST 16, ;JRST 17,

	SYN	IJ$00,IJ$10	;JRST 10, - TREAT LIKE JRST 00,
	SYN	IJ$00,IJ$11	;JRST 11, - TREAT LIKE JRST 00,
	SYN	IJ$02,IJ$12	;JRST 12, - JEN - TREAT LIKE JRSTF
	SYN	IJ$00,IJ$13	;JRST 13, - TREAT LIKE JRST 00,
	SYN	IJ$00,IJ$15	;JRST 15, - TREAT LIKE JRST 00,
	SYN	IJ$00,IJ$16	;JRST 16, - TREAT LIKE JRST 00,
	SYN	IJ$00,IJ$17	;JRST 17, - TREAT LIKE JRST 00,


IJ$RS:	MOVEM	R,I.NJMP	;SAVE NEW (JUMP) INSTRUCTION PC
	DPB	T,[POINT 23,I.NST,35]  ;SET DDT INTERCEPT ADDRESS
	JRST	DOIT		;AND GO DOIT

IFN	FTEXEC,<
IJ$US:	SKPUSR			;EXEC MODE?
	TXNN	T,1B5		;GOING INTO USER MODE?
	JRST	(TT)		;NO
	JRST	PROCD2		;YES, CAN'T TRACE, JUST DO IT
> ;END OF IFN FTEXEC
;STILL IFE FTFILE

;INTERPRET XCT

IIXCT:	JUMPN	W1,JUSTE	;IF A PXCT JUST DO IT BLINDLY
	MOVE	F,FLAGS		;GET BACK NORMAL DDT FLAGS
	SOSG	XCTS		;CHECK XCT COUNTER
	POPJ	P,		;CHECK XCT DEPTH COUNTER
	TXNE	F,CCF		;$$X?
	JRST	IIXCT1		;YES, DON'T PRINT ANYTHING
	MOVE	T,I.NSTE	;GET EFF ADR OF XCT
	PUSHJ	P,PINST		;PRINT INST BEING XCT'ED
	PUSHJ	P,TCRLF		;OUTPUT CRLF AFTER INST
IIXCT1:	MOVE	R,I.NSTE	;GET EFF ADR OF XCT AGAIN
	JRST	$X02		;PROCESS EXECUTED INST

;INTERPRET PUSHJ

IIPUSH:	PUSHJ	P,IIXPCF	;FETCH PC+1 AND (MAYBE) FLAGS
	MOVEM	T,I.NSTP	;STORE AWAY TO BE STACKED
	MOVSI	T,(1B4)		;CLEAR BIS FLAG IN NEW PC WORD
	ANDCAM	T,PCFLG
	MOVE	T,I.NSTE	;NEW USER PC
	MOVEM	T,I.NJMP	;SET NEW USER PC
	HRLZI	T,(<PUSH>-<PUSHJ>)	;WANT TO TURN PUSHJ INTO A PUSH
	DPB	T,[POINT 5,I.NST,17]	;CLEAR I AND AC FIELD
	JRST	IPOPJ2		;REST OF CODE COMMON WITH POPJ

;INTERPRET POPJ

IPOPJ:	EXCH	F,FLAGS		;POPJ, RESTORE NORMAL DDT FLAGS
	MOVE	R,AC0(W1)	;FETCH CONTENTS OF CORRECT USER AC
	MOVE	S,I.NPC		;PC OF INSTRUCTION
	SKIPL	R		;SKIP IF LOCAL STACK POINTER
	TLNN	S,-1		;OR GLOBAL POINTER IN NON-ZERO SECTION
	HLL	R,S		;RELOCATE POINTER TO CURRENT SECTION
	PUSHJ	P,FETCH		;FETCH PCWORD IT POINTS TO
	 POPJ	P,		;ERROR
	EXCH	F,FLAGS		;RESTORE $X FLAGS
	TLNN	S,-1		;INSTRUCTION FROM NON-ZERO SECTION?
	ANDI	T,-1		;NO, THEN PC ALWAYS BACK TO SECTION 0
	MOVEM	T,I.NJMP	;STORE AS CURRENT PC
	HRLZI	T,(<POP>-<POPJ>)  ;SETUP TO TURN POPJ INTO POP

;COMMON CODE FOR PUSHJ, POPJ

IPOPJ2:	ADDM	T,I.NST		;TURN PUSHJ INTO PUSH OR POPJ INTO POP
	HRRZI	T,I.NSTP	;SETUP ADR OF PC WORD FOR PUSHJ
	DPB	T,[POINT 23,I.NST,35]  ;SET DDT INTERCEPT ADDRESS
JUSTAC:	TLO	F,FAC		;REMEMBER TO PRINT AC
	JRST	DOIT		;GO OFF AND EXECUTE THE INSTRUCTION
;STILL IFE FTFILE

;INTERPRET JSA

I.JSA:	MOVE	T,I.NPC		;FETCH INSTRUCTION PC
	HRRI	T,1(T)		;PLUS ONE
	MOVEM	T,I.NJMP	;BECOMES NEW USER PC
	HRL	T,I.NSTE	;PUT EFF ADR IN LH LIKE JSA DOES
	EXCH	T,AC0(W1)	;STORE IN USER AC, GET OLD CONTENTS
	JRST	I.JSR2		;STORE OLD CONTENTS LIKE JSR, THEN JUMP

;INTERPRET JSR

I.JSR:	PUSHJ	P,IIXPCF	;NEW PC AND (MAYBE) FLAGS
	TLO	F,FAC		;REMEMBER NOT TO PRINT AC FIELD
	MOVX	W1,1B4		;CLEAR BIS FLAG IN NEW PC WORD
	ANDCAM	W1,PCFLG
I.JSR2:	TLO	F,EA		;PRINT E NORMALLY
	EXCH	F,FLAGS		;RESTORE NORMAL DDT FLAGS
	MOVE	R,I.NSTE	;FETCH EFF ADR OF JSR OR JSA
	PUSHJ	P,DEPMEM	;STORE PC WORD
	 POPJ	P,		;MEMORY WRITE ERROR
	EXCH	F,FLAGS		;RESTORE $X FLAGS
	MOVE	T,I.NSTE	;GET EFF ADR AGAIN
	HRRI	T,1(T)		;INC PAST STORED PC WORD
	JRST	I.JSR4		;SET NEW USER PC

;INTERPRET JSP

I.JSP:	PUSHJ	P,IIXPCF	;GET NEW PC AND (MAYBE) FLAGS
	MOVEM	T,AC0(W1)	;STORE IN USER AC
	MOVSI	T,(1B4)		;CLEAR BIS FLAG IN NEW PC WORD
	ANDCAM	T,PCFLG
	MOVE	T,I.NSTE	;GET BACK EFF ADR
I.JSR4:	MOVEM	T,I.NJMP	;STORE NEW PC
	TLC	F,FAC		;REMEMBER TO PRINT AC
	JRST	TELL		;GO PERFORM PRINTOUT

;CALCUATE FLAG-PC WORD A LA JSP/PUSHJ

IIXPCF:	MOVE	T,I.NPC		;INSTRUCTION PC
	HRRI	T,1(T)		;PLUS ONE
	TLNN	T,-1		;IN SECTION ZERO?
	HLL	T,PCFLG		;YES, L.H. GETS PC FLAGS
	POPJ	P,		;RETURN WITH FLAG-PC WORD
;STILL IFE FTFILE

;INTERPRET DOUBLE (OR MORE) WORD INSTRUCTIONS

SETQFA:	TLOA	F,QFAC		;FLAG QUADRUPLE ACS
DFLOT:	TLO	F,FLA+FLE	;REMEMBER THAT AC AND E ARE FLOATING
DMOV:	TLO	F,DFAC+DEA	;REMEMBER AC AND E BOTH DOUBLE
	JRST	SETEA

;HERE TO INTERPRET BYTE MANIPULATION INSTRUCTIONS
;TREAT ILDB/IDPB AS IBP THEN LDB/DPB

IIXBP:	MOVX	T,1B8		;CONVERT TO LDB/DPB
	IORM	T,I.NST		; . . .
	MOVE	T,PCFLG		;GET USER PC FLAGS
	TXZE	T,1B4		;CLEAR BIS, WAS IT SET?
	JRST	[MOVEM	T,PCFLG	;YES, CLEAR IT
		JRST	IXBP]	;SKIP INCREMENTING THE PTR
	JSR	SWAP		;GET USER CONTEXT
	IBP	@I.NSTE		;INCREMENT THE USER'S BYTE PTR
	JSR	SWAP		;BACK TO DDT CONTEXT
IXBP:	EXCH	F,FLAGS		;BACK TO DDT FLAGS
	MOVE	R,I.NSTE	;GET ADDRESS OF BYTE POINTER
	PUSHJ	P,FETCH		;FETCH BYTE POINTER
	 POPJ	P,		;FAILURE
	HLLZ	S,I.NSTE	;PRESET SECTION
	PUSHJ	P,CEFFIX	;CALCULATE BYTE POINTER EFFECTIVE ADDRESS
	 POPJ	P,		;MEMORY READ ERROR
	MOVEM	T,I.NEA2	;REMEMBER IT FOR LATER TYPEOUT
	EXCH	F,FLAGS		;BACK TO $X FLAGS
	TLO	F,FAC!EA!EA2!BPE  ;SET FLAGS
	JRST	DOIT		;AND GO DO GRUNGE

IIBP:	TLO	F,BPE!EA	;IBP (MAYBE)
	JUMPE	W1,DOIT		;IF SO, GO DO IT
	TLO	F,BPA!FAC	;ADJBP INSTRUCTION
	JRST	DOIT		;NOW GO DO IT
;STILL IFE FTFILE

;INTERPRET JFFO

IJFFO:	TLO	F,DFAC		;REMEMBER JFFO USES 2 ACS

;INTERPRET JUMP AND SKIP INSTRUCTIONS

JMPSKP:	TRNE	F,10000		;JUMP/SKIP, WHICH IS IT?
	JRST	SKP		;SKIP CLASS

;INTERPRET AOBJN AND AOBJP

IAOBJ:	TLOA	F,FAC+IMM!XIMM	;HANDLE AS IMMEDIATE MODE INST WITH AC

;INTERPRET JFCL

IJFCL:	TLO	F,FLG		;REMEMBER TO PRINT FLAGS
	MOVEI	T,JMP		;JUMP CLASS OR AOBJ, COME BACK TO $X
	DPB	T,[POINT 23,I.NST,35]  ;STORE INTERCEPT ADDRESS
	JRST	DOIT		;GO EXECUTE CONDITIONAL INST

;HERE AFTER EXECUTING CONDITIONAL JUMP INSTRUCTION THAT ACTUALLY
;   DOES JUMP

JMP:	EXCH	T,I.NSTE	;SAVE T, GET EFF ADR OF JUMP
	MOVEM	T,PCWRD		;STORE EFF ADR AS NEW PC
	EXCH	T,I.NSTE
	JRST	NOSKIP		;NOW DO PRINTOUT

;HERE FOR ALL SKIP INSTRUCTIONS

SKP:	JUMPN	W1,SETEA	;SKIP CLASS - AC FIELD ZERO?
JUSTE:	TLOA	F,EA		;YES, JUST PRINT E

;INTERPRET SHIFT COMBINED INSTRUCTIONS

DBLI:	TLO	F,FAC+DFAC+IMM	;REMEMBER 2 ACS USED, IMMEDIATE
	JRST	DOIT		;EXECUTE NORMALLY

;INTERPRET TEST CLASS INSTRUCTIONS

TESTS:	TRNN	F,10000		;SKIP ON TD OR TS BUT NOT ON TR OR TL
	TLOA	F,FAC+IMM	;IMMEDIATE MODE
	TLO	F,FAC+EA	;NORMAL MODE
	JRST	DOIT


;HERE FOR XMOVEI

SETIX:	TLO	F,IMM!XIMM	;EXTENDED IMMEDIATE INSTRUCTION
	JRST	DOIT		;GO PRINT
;STILL IFE FTFILE

;I/O INSTRUCTIONS

IOTS:	AOSN	I.KRCK		;SPECIAL KS-10 KROCK FLAG SET?
	JRST	JUSTAC		;YES, JUST PRINT THE AC
	TRNE	W1,4		;SKIP IF BLKI,DATAI,BLKO,DATAO
	CAIN	W1,5		;SKIP IF NOT CONI
	TLOA	F,EA		;MEM REF INSTRUCTION
JUSTI:	TLO	F,IMM		;IMMEDIATE INST
	JRST	DOIT

;ALL PATHS CONVERGE HERE

CHEKIS:	TRC	F,3000		;HERE TO TEST FOR IMMEDIATE OR SELF MODE
	TRCE	F,3000		;SKIP IF SELF MODE
	JRST	CHECKI		;NO, CHECK IMMEDIATE
	JRST	SKP		;YES, GO TEST FOR NONZERO AC FIELD
SET:	ANDI	F,3000		;HERE FOR SETZX,SETOX
	CAIE	F,2000		;SETZM,SETOM?
	TLO	F,FAC		;NO, AC IS ALWAYS AFFECTED
	TRNE	F,2000		;SETZM,SETZB,SETOM,SETOB?
	TLO	F,EA		;YES, MEM IS ALWAYS AFFECTED
	JRST	DOIT

;FIXED POINT MULTIPLY AND DIVIDE (NOT INCLUDING IMULX)

MULDIV:	ANDI	F,3000		;MASK MODE BITS
	CAIE	F,2000		;TO MEMORY ONLY?
	TLO	F,DFAC		;NO, INST USES 2 AC'S
CHECKI:	TRNE	F,1000		;TEST FOR IMMEDIATE MODE INST
	TRNE	F,2000
SETEA:	TLOA	F,FAC+EA	;MEM REF INSTRUCTION
SETI:	TLO	F,FAC+IMM	;IMMEDIATE MODE INSTRUCTION

;CONTINUED ON NEXT PAGE
;STILL IFE FTFILE

;CONTINUED FROM PREVIOUS PAGE

DOIT:	EXCH	F,FLAGS		;RESTORE NORMAL DDT FLAGS

IFN	FTDEC20,<		;HANDLE TOPS-20 ERCAL/ERJMP
	MOVE	R,I.NPC		;ADDRESS OF INSTRUCTION ABOUT TO BE XCT'ED
	HRRI	R,1(R)		;ADDRESS FOLLOWING
	PUSHJ	P,FETCH		;SEE WHAT FOLLOWS INSTRUCTION
	JRST	DOITX		;WHO KNOWS - JUST GO DO IT
	MOVEM	T,I.NECJ	;SAVE INCASE ERCAL/ERJMP
	LSH	T,<^L<@>-^D36>	;WANT JUST OP AND AC FIELDS
	CAIN	T,<<ERJMP>_<^L<@>-^D36>> ;ERJMP INSTRUCTION?
	JRST	DOITJ		;YES - SPECIAL HANDLING
	CAIE	T,<<ERCAL>_<^L<@>-^D36>> ;ERCAL INSTRUCTION?
	JRST	DOITX		;NO - TREAT NORMALLY

;HERE IF INSTRUCTION FOLLOWED BY ERCAL

DOITC:	SKIPGE	I.NXIT		;IF DANGEROUS INSTRUCTION
	PUSHJ	P,TTYLEV	;THEN RESTORE TTY ET AL
IFN	FTEXEC,<PUSHJ P,RSTAC>	;ENSURE RIGHT CONTEXT ACS
	JSR	SWAP		;SWAP TO USER CONTEXT
	XCT	I.NST		;EXECUTE THE INSTRUCTION
	ERJMP	DOITC3		;CATCH ANY ERRORS
	JRST	DOITJ1		;COMMON CODE

DOITC3:	MOVEM	T,SAFETY	;HOLD T FOR MOMENT
	MOVSI	T,FECJ		;FLAG ERCAL JUMPED
	JRST	DOITJ5		;COMMON CODE
;STILL FTDEC20 &  IFE FTFILE

;HERE IF INSTRUCTION FOLLOWED BY ERJMP

DOITJ:	SKIPGE	I.NXIT		;IF DANGEROUS INSTRUCTION THEN
	PUSHJ	P,TTYLEV	;THEN RESTORE TTY ET AL
IFN	FTEXEC,<PUSHJ P,RSTAC>	;ENSURE RIGHT CONTEXT ACS
	JSR	SWAP		;SWAP TO USER CONTEXT
	XCT	I.NST		;EXECUTE THE INSTRUCTION
	ERJMP	DOITJ3		;CATCH ANY ERRORS
DOITJ1:	MOVEM	T,SAFETY	;HOLD T FOR MOMENT
	MOVSI	T,FECJS		;FLAG ERCAL/JMP DIDN'T
	IORM	T,FLAGS		;SET IN $X FLAGS
	MOVEI	T,2		;USER PC INCREMENTS BY 2
				;NOTE THAT WE HAVE NO WAY OF DETERMINING
				;IF THE ERCAL/JMP EVEN GOT EXECUTED - 
				;CONSIDER MOVE/ERJMP VERSUS SKIPA/ERJMP
	JRST	DOITX4		;COMMON CODE

DOITJ3:	MOVEM	T,SAFETY	;HOLD T FOR MOMENT
	MOVSI	T,FEJJ		;FLAG ERJMP JUMPED
DOITJ5:	IORM	T,FLAGS		;SET IN $X FLAGS
	MOVEI	T,1		;USER PC INCREMENTS BY ONE
	JRST	DOITX4		;COMMON CODE
> ;END IFN FTDEC20

DOITX:	SKIPGE	I.NXIT		;IF DANGEROUS INSTRUCTION THEN
	PUSHJ	P,TTYLEV	;RESTORE TTY ET AL
IFN	FTEXEC,<PUSHJ P,RSTAC>	;ENSURE PROPER CONTEXT AC BLOCK
	SETZM	SKPCT		;[211] NOTE NUMBER OF SKIPS
	JSR	SWAP		;SWAP TO USER CONTEXT
DOITX0:	XCT	I.NST		;EXECUTE THE INSTRUCTION
				;(IF IN EXEC MODE THIS MAY BE PXCT)
	REPEAT	SKPMAX,<AOS SKPCT>	;[211] NOTE COUNT OF SKIPS
	MOVEM	T,SAFETY	;SAVE USER T
	MOVEI	T,SKPMAX + 1	;[211] MAX AMOUNT CAN BE SKIPPED
	SUB	T,SKPCT		;[211] MINUS THOSE NOT SKIPPED
DOITX4:	ADD	T,PCWRD		;ADJUST USER PC ACCORDINGLY
	HRRM	T,PCWRD		;SET NEW USER PC
	MOVE	T,SAFETY	;[211] RESTORE T
;STILL IFE FTFILE

;HERE AFTER SIMULATING OR EXECUTING INSTRUCTION. PERFORM REQUIRED PRINTOUT.

NOSKIP:	JSR	SWAP		;RESTORE DDT CONTEXT
	SETOM	LASTPG		;IN CASE PAGE FAULT EVEN ON "SAFE" INST.
	SKIPGE	I.NXIT		;IF WAS DANGEROUS INSTRUCTION
	PUSHJ	P,TTYRET	;THEN RESTORE DDT TTY MODES
	JRST	TELLX
TELL:	EXCH	F,FLAGS		;GET DDT'S FLAGS
TELLX:	SKIPL	T,I.NJMP	;UNCONDITIONAL JUMP ADDRESS SPECIFIED?
	MOVEM	T,PCWRD		;YES, BECOMES NEW USER PC
	TXNE	F,CCF		;IF $$X, DON'T PRINT ANYTHING
	JRST	NXTIT
	EXCH	F,FLAGS		;RESTORE $X'S FLAGS
	PUSH	P,SCH		;SAVE CURRENT OUTPUT MODE
	TLNE	F,FLA		;FLOATING AC?
	MOVEI	SCH,TFLOT	;YES, SETUP TO OUTPUT IN FLOATING PT
	TLNE	F,BPA		;BYTE POINTER AC?
	MOVEI	T,TBPNT		;YES, SET TO TYPE BYTE POINTER
	TLNE	F,FAC		;AC TO BE PRINTED?
	PUSHJ	P,FAC0		;YES, DO IT
	TLNE	F,DFAC		;INST USE 2 ACS?
	PUSHJ	P,DBL0		;YES, PRINT LOW-ORDER AC
	TLNE	F,QFAC		;INST USE 4 ACS?
	PUSHJ	P,QDBL0		;YES, PRINT LOWER-ORDER ACS
	TLNE	F,FLG		;INSTRUCTION ACCESS THE FLAGS?
	PUSHJ	P,FLG0		;YES, PRINT FLAGS
	MOVE	SCH,(P)		;RESTORE OLD MODE
	TLNE	F,FLE		;FLOATING MEMORY OPERAND?
	MOVEI	SCH,TFLOT	;YES, SETUP FLTG OUTPUT
	TLNE	F,BPE		;C(E) A BYTE POINTER
	MOVEI	SCH,TBPNT	;YES - TYPE AS SUCH
	TLNE	F,IMM		;IMMEDIATE MODE?
	PUSHJ	P,IMM0		;YES, JUST PRINT E
	TLNE	F,EA		;MEM REF INST?
	PUSHJ	P,PEA		;YES, PRINT C(E)
	TLNE	F,DEA		;DOUBLE-WORD MEM OPERAND?
	PUSHJ	P,DEA0		;YES, OUTPUT 2ND WORD
	TLNE	F,QEA		;QUAD-WORD MEM OPERAND?
	PUSHJ	P,QDEA0		;YES, PRINT 3RD AND 4TH WORDS
	POP	P,SCH		;RESTORE CURRENT OUTPUT MODE
	TLNN	F,EA2		;SECOND EFFECTIVE ADDRESS?
	JRST	NOSKIQ		;NO
	MOVE	T,I.NEA2	;YES - GET E(C(E))
	EXCH	T,I.NSTE	;E:=E(C(E))
	MOVEM	T,I.NEA2	;REMEMBER E
	TLNE	F,IMM2		;SECOND E IMMEDIATE?
	PUSHJ	P,IMM0		;YES - TYPE E(C(E))
	TLNN	F,IMM2		;SECOND E IMMEDIATE?
	PUSHJ	P,PEA		;NO - TYPE E(C(E))/C(E(C(E)))
	MOVE	T,I.NEA2	;GET FIRST E BACK
	EXCH	T,I.NSTE	;AND RESTORE TO RIGHTFUL PLACE(S)
NOSKIQ:	EXCH	F,FLAGS		;RESTORE DDT FLAGS
	PUSHJ	P,TCRLF		;OUTPUT CRLF
;STILL IFE FTFILE

;NOW TEST WHETHER TO CONTINUE, AND PRINT NEXT INST IF REQUIRED.

NXTIT:

IFN	FTDEC20,<		;HANDLE TOPS-20 ERCAL/ERJMP
	EXCH	F,FLAGS		;BACK TO $X FLAGS
	TLZE	F,FECJ		;FORCED ERCAL TO JUMP?
	JRST	NXTIT2		;YES
	TLZN	F,FEJJ		;DID AN ERJMP JUMP?
	JRST	NXTIT6		;NO
	SKIPA	T,[<<JRST>_<^L<@>-^D36>>] ;FAKE AN ERJMP
NXTIT2:	MOVEI	T,<<PUSHJ 17,>_<^L<@>-^D36>>  ;FAKE AN ERCAL
	DPB	T,[POINT 13,I.NECJ,12]  ;FAKE OUT THE ERCAL/ERJMP
	MOVE	R,I.NPC		;PC OF ORIGINAL USER INSTRUCTION
	HRRI	R,1(R)		;ADVANCE BY ONE (ADDR OF ERCAL/ERJMP)
	MOVEM	R,I.NPC		;NOTE NEW INSTRUCTION PC
	SKIPL	I.REP		;INDEFINITE $$X'ING?
	MOVEM	R,LOCSAV	;NO, UPDATE LOCSAV TOO
	EXCH	F,FLAGS		;BACK TO DDT FLAGS
	TXNE	F,CCF		;$$X MODE?
	JRST	NXTIT4		;YES, DON'T TYPE ANYTHING
	MOVE	T,R		;ADDRESS OF ERCAL/ERJMP INTO T
	PUSHJ	P,PINST		;SHOW USER WHAT WE ARE ABOUT TO DO
	PUSHJ	P,TCRLF		;<CR><LF>
NXTIT4:	EXCH	F,FLAGS		;BACK TO $X FLAGS
	MOVE	R,I.NPC		;GET R BACK
	MOVE	T,I.NECJ	;FETCH FAKE ERCAL/ERJMP
	JRST	$X03		;AND GO SIMULATE THE REAL THING

NXTIT6:	EXCH	F,FLAGS		;BACK TO DDT FLAGS
> ;END OF IFN FTDEC20

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;STILL IFE FTFILE

	AOSN	I.PXC		;CALL FROM $PX?
	JRST	CPOPJ1		;YES, RETURN NOW, QUIETLY
	MOVE	T,PCWRD		;FETCH NEW PC
	XMOVEI	W1,XEC1		;INTERNAL LIMITS
	XMOVEI	W2,XEC2		;OF INSTR$X RETURNS
	CAML	T,W1		;DID WE JUST $X A RETURN FROM
	CAML	T,W2		;(E.G.) PUSHJ P,SUBRTN$X WHICH BREAKPOINTED?
	JRST	NXTIT8		;NO
	SETZM	BPTIP		;YES, NO LONGER BREAKPOINT IN PROGRESS
	JRST	(T)		;JUST QUIT (DON'T $X DDT ITSELF)
NXTIT8:	SKIPL	I.REP		;INDEFINITE $$X IN PROGRESS?
	JRST	NXT0		;NO
	CAML	T,LLIMIT	;YES, IS USER PC NOW WITHIN
	CAMLE	T,ULIMIT	;STOPPING LIMITS?
	CAIA			;NO.
	JRST	$XQUIT		;YES, STOP ITERATION NOW
NXT0:	PUSHJ	P,LISCK		;HAS USER TYPED ANYTHING?
	  JRST	NXT1		;NO, CONTINUE
	 JRST	$XQUIT		;YES, ABORT THE $$X
	MOVEI	W1,[ASCIZ\Executing: \]  ;YES, NICE TEXT
	PUSHJ	P,TSTRG		;TELL USER
	MOVE	T,PCWRD		;GET THE NEW $X PC
	PUSHJ	P,LI1		;AND TELL USER THAT TOO
	PUSHJ	P,TCRLF		;CAP OFF LINE
	JRST	NXT1		;AND CONTINUE $X'ING
;STILL IFE FTFILE

$XQUIT:	SETZM	I.REP		;YES, STOP ITERATION BY ZEROING COUNTER
	TXZ	F,CCF		;  AND CLEARING CONTROL FLAG
NXT1:	TXNE	F,CCF		;$$ STILL IN EFFECT?
	JRST	NXT2		;YES, DON'T PRINT ANYTHING
IFN FTDEC20,<
	EXCH	F,FLAGS		;GET $X FLAGS AGAIN
	TLZN	F,FECJS		;NEED TO INDICATE ERCAL/ERJMP?
	JRST	NXT1A		;NO, CONTINUE
	EXCH	F,FLAGS		;BACK TO DDT FLAGS
	MOVEI	W1,[ASCIZ "<ERSKP>"]	;MESSAGE
	JRST	NXT1D		;JOIN COMMON TYPEOUT CODE
NXT1A:	EXCH	F,FLAGS		;BACK TO DDT FLAGS
> ;END OF IFN FTDEC20
	MOVE	T,PCWRD		;NO, GET CURRENT PC AGAIN
	MOVE	W1,LOCSAV	;AND OLD PC
	HRRI	W1,1(W1)	;INCREMENT OLD PC
	CAMN	T,W1		;DID PC SIMPLY GO TO PC+1?
	JRST	NXT1P		;YES--JUST CONTINUE
	MOVE	W2,W1		;W1:=LOWER LIMIT
	ADDI	W2,SKPMAX	;W2:=UPPER LIMIT
	CAML	T,W1		;IS THE NEW USER PC
	CAMLE	T,W2		;WITHIN "SKIP" RANGE?
	JRST	NXT1C		;NO, GO TYPE <JUMP>
	SUB	T,W1		;GET COUNT OF SKIPS
	PUSH	P,T		;SAVE FOR ITERATION
	MOVEI	W1,[ASCIZ "<SKIP"]	;SKIP
	PUSHJ	P,TSTRG		;TYPE IT
	SOSG	0(P)		;MULTIPLE SKIPS?
	JRST	NXT1B		;NO, JUST CLOSE
	PUSHJ	P,TSPC		;TYPE A SPACE
	MOVE	T,0(P)		;GET # BACK
	ADDI	T,"0"+1		;TO ASCII, COMPENSATE FOR SOSG
	PUSHJ	P,TOUT		;TYPE # OF SKIPS
NXT1B:	POP	P,0(P)		;CLEAN UP STACK
	MOVEI	T,">"		;CLOSE OFF SKIP MESSAGE
	PUSHJ	P,TOUT		;TYPE IT
	JRST	NXT1E		;COMMON CODE TO END LINE

NXT1C:	MOVEI	W1,[ASCIZ "<JUMP>"]	;JUMP
NXT1D:	PUSHJ	P,TSTRG		;SAY IT
NXT1E:	PUSHJ	P,TCRLF		;ADD CRLF

NXT1P:	MOVE	T,PCWRD		;FETCH CURRENT PC AGAIN
	PUSHJ	P,PINST		;PRINT INSTRUCTION ABOUT TO BE EXECUTED
	SKIPE	I.REP		;ARE WE STILL LOOPING?
	PUSHJ	P,TCRLF		;YES, PRINT CRLF AFTER INST
NXT2:	SKIPE	I.REP		;SKIP IF REPEAT COUNTER IS ZERO
	PJRST	$X01		;NONZERO, REPEAT $X CYCLE AGAIN
	AOS	(P)		;TIME TO RETURN, MARK SUCCESSFUL COMPLETION
	PJRST	TTYCLR		;FLUSH ANY WAITING INPUT CHARACTERS
				; AND RETURN TO $X COMMAND
;STILL IFE FTFILE

;OUTPUT ROUTINES

;ROUTINE TO PRINT THIRD AND FOURTH ACCUMULATORS

QDBL0:	PUSHJ	P,DBL0		;PRINT ANOTHER AC
				;AND FALL INTO PRINTING FOURTH AC

;ROUTINE TO PRINT SECOND ACCUMULATOR

DBL0:	AOS	T,I.NSTAC	;INCREMENT AC NUMBER
	TRZA	T,777760	;ENSURE 17 WRAPS AROUND TO 0

;ROUTINE TO PRINT CONTENTS OF ACCUMULATOR

FAC0:	MOVE	T,I.NSTAC	;FETCH AC NUMBER
	JRST	PEA2

;ROUTINE TO PRINT THE FLAGS

FLG0:	PUSHJ	P,TTAB		;PRINT TAB
	MOVE	T,PCWRD		;GET NEW INSTRUCTION PC
	TLNE	T,-1		;USER PC IN NON-ZERO SECTION?
	MOVE	T,PCFLG		;YES, GET FULL WORD PC FLAGS
	HLRZ	T,PCFLG		;NO, GET HALF WORD PC FLAGS
	PJRST	TOC		;AND OUTPUT PC FLAGS

;ROUTINE TO PRINT JUST E FOR AN IMMEDIATE MODE INSTRUCTION

IMM0:	PUSHJ	P,TTAB		;PRINT TAB
	MOVE	T,I.NSTE	;FETCH E
	TLNN	F,XIMM		;WANT ALL 30 BITS?
	TLZ	T,-1		;NO, JUST TYPE 18 BITS
	TLNE	F,FLE		;FLTG PT MEM OPERAND?
	HRLZ	T,T		;YES, IMMEDIATE USES E,,0
IMM1:	EXCH	F,FLAGS		;RESTORE DDT FLAGS
	PUSHJ	P,CONSYM	;OUTPUT CONTENTS OF T
	JRST	PEA6		;RESTORE $X FLAGS AND RETURN
;STILL IFE FTFILE

;ROUTINE TO PRINT 3RD AND 4TH MEMORY OPERANDS

QDEA0:	PUSHJ	P,DEA0		;PRINT 3RD MEMORY OPERAND
				;AND FALL INTO PRINTING FOURTH OPERAND
;ROUTINE TO PRINT 2ND MEMORY OPERAND

DEA0:	MOVE	T,I.NSTE	;FETCH ADDRESS OF OPERAND
	HRRI	T,1(T)		;ADVANCE TO NEXT ONE
	MOVEM	T,I.NSTE	;SAVE FOR EVEN MORE CALLS

;ROUTINE TO PRINT MEMORY OPERAND

PEA:	MOVE	T,I.NSTE	;FETCH ADR OF MEM OPERAND
PEA2:	EXCH	F,FLAGS		;HERE FROM DBL0,FAC0
	PUSH	P,T		;SAVE ARG
	PUSHJ	P,TTAB		;OUTPUT TAB
	POP	P,T		;RESTORE ADR OF LOC TO BE PRINTED
	PUSHJ	P,LI1		;PRINT ADR/ CONTENTS
PEA6:	EXCH	F,FLAGS		;RESTORE $X FLAGS
	POPJ	P,

;ROUTINE TO PRINT INSTRUCTION ALWAYS IN SYMBOLIC DESPITE CURRENT MODE

PINST:	PUSH	P,SCH		;SAVE CURRENT OUTPUT MODE
	MOVEI	SCH,PIN		;SET TO PRINT SYMBOLIC INST MODE
	PUSHJ	P,LI1		;OUTPUT INST
	POP	P,SCH		;RESTORE CURRENT MODE
	POPJ	P,


;HERE TO PRINT A WORD IN BYTE POINTER FORMAT:
;	P S [@][[Y](X) ! Y]

TBPNT:	LDB	T,[POINT 6,LWT,5]	;GET "P" BYTE FIELD
	PUSHJ	P,TOC		;TYPE OUT
	PUSHJ	P,TSPC		;FOLLOWED BY SPACE
	LDB	T,[POINT 6,LWT,11]	;SET "S" BYTE FIELD
	PUSHJ	P,TOC		;TYPE IT OUT
	PUSHJ	P,TSPC		;CAP OFF WITH ANOTHER SPACE
	JRST	PI4		;GO DO I, X, AND Y FIELDS

> ;END IFE FTFILE FROM PAGES AGO

IFN FTFILE,<XEC==ERR>
SUBTTL	COMMAND ROUTINES -- PUNCH PAPER TAPE

IFN FTPTP,<

;HERE ON ^R COMMAND - PUNCH OUT CORE

PUNCH:	SKPEXC
	JRST	ERR		;PAPER TAPE STUFF ILLEGAL IN USER MODE
	TXC	F,FAF!QF
	TXCE	F,FAF!QF
	JRST	ERR		;ONE ARGUMENT MISSING
PUN2:	ADDI	T,1
	HRRZM	T,TEM1
	SUB	T,DEFV
	JUMPLE	T,ERR

PUN1:	MOVEI	T,4		;PUNCH 4 FEED HOLES
	PUSHJ	P,FEED
	TXNE	F,CF		;PUNCH NON-ZERO BLOCKS?
	JRST	PUNZ		;YES
	HRRZ	R,DEFV
	IORI	R,37
	ADDI	R,1
	CAMLE	R,TEM1
	MOVE	R,TEM1
	EXCH	R,DEFV
	MOVE	T,R
	SUB	T,DEFV
	HRL	R,T
	JUMPGE	R,RET		;EXIT OR PUNCH

PBLK:	MOVE	T,R
	SOS	W,T		;INIT CHECKSUM
	PUSHJ	P,PWRD
PBLK1:	PUSHJ	P,FETCH
	JRST	ERR
	ADD	W,T
	PUSHJ	P,PWRD
	AOBJN	R,PBLK1
	MOVE	T,W
	PUSHJ	P,PWRD
	JRST	PUN1
;STILL FTPTP

;PUNCH NON-ZERO BLOCKS

PUNZ0:	AOS	DEFV		;LOOK AT NEXT WORD
PUNZ:	HRRZ	W,DEFV		;ENTER HERE - GET STARTING ADDRESS
	MOVE	R,W
	SUB	W,TEM1		;CALCULATE NEGATIVE LENGTH
	HRL	R,W		;SET UP AOBJN POINTER
	JUMPGE	R,RET		;FINISHED?
	CAMG	R,[XWD -40,0]	;BLOCK LONGER THAN 40?
	HRLI	R,-40		;YES, FIX IT UP
	MOVSI	W1,400000	;W1 NEGATIVE MEANS FLUSH 0 WORDS
PUNZ2:	PUSHJ	P,FETCH		;GET WORD FROM MEMORY
	JRST	ERR
	JUMPE	T,[AOJA W1,PUNZ4]	;IF WORD IS 0, INDEX 0 WORD COUNTER
	MOVEI	W1,0		;CLEAR 0 WORD COUNTER
PUNZ4:	JUMPL	W1,PUNZ0	;FLUSH 0 WORD, GET ANOTHER
	CAIL	W1,3		; NOSKIP FOR 3RD 0 WORD AFTER NON 0 WORD
	AOSA	R		;ADVANCE R TO LAST ADR+1
	AOBJN	R,PUNZ2
	ADD	W1,DEFV		;CALCULATE DEFV-R+W1=-WORD COUNT
	SUB	W1,R
	HRLM	W1,DEFV		;PUT -WC IN LEFT HALF OF FA
	EXCH	R,DEFV		;SAVE ADR FOR NEXT BLOCK, GET POINTER
	JRST	PBLK
;STILL FTPTP

;HERE ON $J COMMAND -- PUNCH END (START) BLOCK

BLKEND:	SKPEXC
	JRST	ERR
	TXNN	F,QF		;BLOCK END
	MOVE	T,[JRST 4,DDT]
	TXNN	T,777B8		;INSERT JRST IF NO OPCODE
	TXO	T,<JRST>
	PUSH	P,T
	MOVEI	T,20
	PUSHJ	P,FEED
	POP	P,T
	PUSHJ	P,PWRD
	PUSHJ	P,PWRD		;EXTRA WORD FOR READER TO STOP ON
	MOVEI	T,400
	JRST	LOAD2
;STILL FTPTP

;COMMON SUBROUTINES USED BY ALL PAPER TAPE CODE

;PUNCH A WORD ROUTINE

PWRD:	MOVEI	W1,6
PWRD2:	ROT	T,6
	CONSZ	PTP,20
	JRST	.-1
	CONO	PTP,50
	DATAO	PTP,T
	SOJG	W1,PWRD2
	POPJ	P,0


;PUNCH NULLS (FEED) ROUTINE

FEED:	CONSZ	PTP,20
	JRST	.-1
	CONO	PTP,10
	DATAO	PTP,FEED1
	SOJN	T,FEED
FEED1:	POPJ	P,0		;ADDRESS USED AS A CONSTANT

> ;END IFN FTPTP

IFE FTPTP,<BLKEND==<PUNCH==ERR>>
SUBTTL	COMMAND ROUTINES -- WATCHING

WATCH:	TXZE	F,FAF!SAF!Q2F	;WE TAKE ONLY A SINGLE ARGUMENT
	JRST	ERR		;AND USER TYPED SOMETHING ELSE
	TXNN	F,QF		;USER TYPE EXPLICIT ADDRESS TO WATCH?
	MOVE	T,LLOCO		;NO, USE LAST LOCATION OPENED
	MOVEM	T,WTCHA		;SAVE ADDRESS
	PUSHJ	P,TCRLF		;START A NEW LINE
	MOVE	R,WTCHA		;GET ADDRESS TO BE WATCHED
	PUSHJ	P,FETCH		;GET IT
	 JRST	ERR		;ADDRESSING ERROR
	JRST	WATCH3		;AND TYPE IT OUT

;LOOP LOOKING AT THE WORD, WATCHING FOR A CHANGE

WATCH1:

IFN	FTDEC10,<		;TOPS-10 QUICK NAP
	MOVEI	T,0		;0 SECONDS = 1 CLOCK TICK
IFN	FTEXEC,<SKPEXC>		;BUT NO MONITOR CALLS IN EXEC MODE
	SLEEP	T,		;PAUSE A MOMENT
> ;END IFN FTDEC10

IFN	FTDEC20,<		;TOPS-20 QUICK NAP
	MOVEI	T1,^D16		;16 MILLISECONDS = 1 CLOCK TICK
IFN	FTEXEC,<SKPEXC>		;BUT NO MONITOR CALLS IN EXEC MODE
	DISMS%			;PAUSE A MOMENT
> ;END IFN FTDEC20

	MOVE	R,WTCHA		;ADDRESS AGAIN
	PUSHJ	P,FETCH		;READ IT
	 JRST	ERR		;BLETCH - THE WORD WENT AWAY
	CAMN	T,WTCHW		;HAS THE WORD CHANGED?
	JRST	WATCH5		;NO

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

WATCH3:	MOVEM	T,WTCHW		;SAVE NEW WORD VALUE
	MOVE	T,R		;GET WORD ADDRESS
	PUSHJ	P,PADR		;AND PRINT IT
	MOVEI	W1,[ASCIZ\/	\]  ;SEPARATOR TEXT TO
	PUSHJ	P,TSTRG		;SEPARATE ADDRESS AND ITS CONTENTS
	MOVE	T,WTCHW		;GET THE NEW WORD VALUE
	PUSHJ	P,CONSYM	;AND TYPE IT OUT TOO
	PUSHJ	P,TCRLF		;CAP OFF THE LINE
	SETOM	WTCHC		;AND DO A LISTEN
WATCH5:	SOSL	WTCHC		;TIME FOR A LISTEN?
	JRST	WATCH1		;NO, JUST KEEP WATCHING
	MOVEI	W,^D60		;YES, RESET LISTEN COUNTER
	MOVEM	W,WTCHC		; . . .
	PUSHJ	P,LISCK		;ANYTHING TYPED?
	  JRST	WATCH1		;NO, KEEP WATCHING
	 JRST	DD1		;YES, ABORT THE WATCH

;HERE TO ISSUE "STATUS" WITHOUT ABORTING THE WATCH

	MOVEI	W1,[ASCIZ\Watching: \]  ;NICE TEXT
	PUSHJ	P,TSTRG		;TYPE IT OUT
	MOVE	T,WTCHA		;CURRENT ADDRESS
	PUSHJ	P,LI1		;TYPE IT OUT
	PUSHJ	P,TCRLF		;CAP OFF TEXT MESSAGE
	MOVE	T,LWT		;GET THE DISPLAYED CONTENTS
	MOVEM	T,WTCHW		;AND SAVE IT AS THE LAST VALUE SEEN
	JRST	WATCH1		;LOOP BACK AND CHECK AGAIN
SUBTTL	COMMAND ROUTINES -- SEARCHING

EFFEC:	MOVSI	R,(CAIE T,0)	;FAILS IF ANY BITS DIFFER
	TXO	F,LTF		;FLAG EFFECTIVE ADDRESS SEARCH
	JRST	WORD1		;ENTER MAIN SEQUENCE

NWORD:	SKIPA	R,[CAIN T,0]	;NOT-WORD, FAILS IF ALL BITS SAME
WORD:	MOVSI	R,(CAIE T,0)	;WORD SEARCH, FAILS IF ANY BITS DIFFER
	TXZ	F,LTF		;INDICATE NO EFFECTIVE ADDR SEARCH
WORD1:	MOVEM	R,SEAXCT	;[224] SET MODE "FLAG" (XCT'ED AT SEAR2)
	TXNN	F,CCF!Q2F	;TWO <ESC>'S OR SECOND QUANTITY?
	TXZN	F,QF		;[224] QUANTITY TO SEARCH FOR TYPED?
	JRST	ERR		;SYNTAX ERROR
	SETCAM	T,WRD		;SAVE SO AS TO NOT FIND IN SEARCH
;	MOVSI	T,FRASE-DEN-1	;PREVENT TYPE OUT OF DDT PARTS
	MOVSI	T,-6		;*****TEMP***** AVOID MACRO BUG WITH MDDT
	SETCMM	FRASE(T)	;COMPLEMENT SO WON'T BE MATCHED
	AOBJN	T,.-1		;ONE BY ONE
	TXZ	F,STF		;DO NOT SUPPRESS TYPEOUT (IN LI1)
	MOVE	T,ULIMIT	;END ADDRESS OF SEARCH RANGE
	TXNE	F,SAF		;WAS GIVEN EXPLICITLY?
	TXO	F,QF		;YES, SIMULATE A $Q TYPED
	PUSHJ	P,SETUP		;SETUP DEFAULT LIMITS
	PUSHJ	P,TCRLF		;CLEAN OUTPUT
	PUSHJ	P,PSHLLC	;PRESERVE PC SEQUENCE

;FALL INTO MAIN SEARCH LOOP ON NEXT PAGE
;FALL HERE FROM PREVIOUS PAGE

SEAR1:	CAMLE	R,ULIMIT	;REACHED END OF SEARCH LIMIT?
	JRST	SEARFN		;YES, END OF SEARCH
	PUSHJ	P,FETCH		;GET CURRENT WORD TO SEE IF IT MATCHES
	 JRST	[MOVEI	R,777	;FETCH FAILED, BUMP TO NEXT PAGE
		IORB	R,LLIMIT  ;PUT AT BOTTOM OF NONEX PAGE
		JRST	SEAR2A]	;CONTINUE SEARCH
	TXNN	F,LTF		;CHECK FOR EFFECTIVE ADDRESS SEARCH
	JRST	SEAR1B		;NORMAL WORD SEARCH
	HLLZ	S,LLIMIT	;EFFEC ADR - PRESET CURRENT SECTION
	PUSHJ	P,CEFFIX	;CALCULATE EFFECTIVE ADDRESS
	 JRST	SEAR2A		;SKIP THIS WORD IF MEMORY READ ERROR
SEAR1B:	EQV	T,WRD		;FLIP SOME BITS
	TXNN	F,LTF		;EFFECTIVE ADDRESS OR WORD SEARCH?
	AND	T,MSK		;WORD SEARCH, CLEAR EXCLUDED BITS
SEAR2:	XCT	SEAXCT		;DO WE HAVE A MATCH?
	JRST	SEAR2A		;NO, ADVANCE TO NEXT LOCATION
	MOVE	T,LLIMIT	;GET MATCHED ADDRESS AGAIN
	PUSHJ	P,LI1		;CALL REGISTER EXAMINATION LOGIC TO TYPE OUT
	PUSHJ	P,TCRLF		;POSITION TO NEXT LINE
	PUSHJ	P,PSHLLC	;SAVE CURRENT MATCH ON "STACK"
	SETCMM	LWT		;DON'T MATCH DDT'S INNARDS
	SETCMM	TEM		; DITTO
	AOS	R,LLIMIT	;[224] GET NEXT ADDRESS
	JRST	SEAR2B		;[224] AND ALWAYS DO A LISTEN

SEAR2A:	AOS	R,LLIMIT	;GET NEXT LOCATION
	TRNN	R,777		;CHECK LISTEN ONLY ONCE PER PAGE
SEAR2B:	PUSHJ	P,LISCK		;ANYTHING TYPED?
	  JRST	SEAR1		;NO, KEEP SEARCHING
	 JRST	SEARFN		;YES, ABORT THE SEARCH
				;YES (A "?"), LIST STATUS

;HERE TO ISSUE "STATUS" WITHOUT ABORTING THE SEARCH

	MOVEI	W1,[ASCIZ\Searching: \]  ;NICE TEXT
	PUSHJ	P,TSTRG		;TYPE IT OUT
	MOVE	T,R		;CURRENT ADDRESS
	PUSHJ	P,LI1		;TYPE IT OUT
	PUSHJ	P,TCRLF		;CAP OFF TEXT MESSAGE
	MOVE	R,LLIMIT	;RESTORE R (=CURRENT ADDRESS)
	JRST	SEAR2B		;LOOP BACK AND CHECK AGAIN

;HERE AT THE END OF THE SEARCH - FOR ANY REASON

SEARFN:	SETCMM	LWT		;COMPLEMENT BITS BACK AND STOP SEARCH
	SUBI	R,1		;BACKUP R TO LAST WORD ADDRESS
	MOVEM	R,LLOC		;SET "." TO LAST WORD SEARCHED
	JRST	DD1
SUBTTL	COMMAND ROUTINES -- COMMAND FILE INPUT

IFN	FTDEC10,<

;$Y   --  READ COMMAND FILE
;$$Y  --  READ SYMBOL FILE (NOT YET IMPLEMENTED)

IFN	FTYANK,<
TAPIN:	SETZM	COMAND		;IN CASE ISSUED FROM COMMAND FILE
IFN	FTEXEC,< SKPEXC		;SKIP IF EXEC MODE
	JRST	UTAPIN		;USER MODE
	CONSO	PTR,400		;TAPE IN READER?
	JRST	ERR		;NO - ERROR
	SETZM	EPTPTR		;YES. INDICATE START READING IN
	SETOM	COMAND		;SHOW THERE IS A COMMAND FILE
	JRST	DD1		;TYPE <CR><LF> AND DO COMMANDS
> ;END IFN FTEXEC

UTAPIN:	TXNN	F,QF		;USER TYPE OLD WAY?
	JRST	TAPIN4		;NO, PROMPT FOR FILE SPEC
	SETZM	FSBLK		;CLEAR SPEC AREA
	MOVE	R,[FSBLK,,FSBLK+1]  ;BLT POINTER TO
	BLT	R,FSBLK+FSLEN-1	;ZERO FILE SPEC SCAN AREA
	MOVEM	T,FSFIL		;TAKE HIS FILENAME
	PUSHJ	P,TCRLF		;GIVE A <CR><LF> FOR NEATNESS
	MOVX	TT,FS$NAM	;SAY HE TYPED IN A FILENAME
	MOVEM	TT,FSBLK	;BUT NOTHING ELSE
	JRST	TAPIN6		;AND GO DEFAULT TO DSK:.DDT[-]
;HERE TO PROMPT USER FOR FULL FILE SPECIFICATION

TAPIN4:	TMSG	<
File: >				;PROMPT USER
	MOVEI	S,TAPSWT	;$Y SWITCHES TABLE
	SETZM	YASWF		;INITIALIZE SWITCHES
	PUSHJ	P,FSCAN		;READ FILE SPEC
	 PJRST	TTYCLR		;ERROR, GIVE UP
	SKIPN	TT,FSBLK	;ANYTHING TYPED?
	POPJ	P,		;NO, JUST RETURN
TAPIN6:	MOVSI	T,'DSK'		;DEFAULT DEVICE
	TXNN	TT,FS$DEV	;EXPLICIT DEVICE?
	MOVEM	T,FSDEV		;NO, USE DEFAULT
	MOVSI	T,'DDT'		;DEFAULT EXTENSION FOR COMMAND FILE
	TXNE	F,CCF		;COMMAND OR SYMBOL FILE?
	MOVSI	T,'SYM'		;SYMBOL FILE DEFAULT EXTENSION
	TXNN	TT,FS$EXT	;EXPLICIT EXTENSION?
	MOVEM	T,FSEXT		;NO, USE DEFAULT
	MOVEI	T,[YFLLEN,,YFLBLK  ;LEN,,ADR OF FILOP. BLOCK
		   YLKLEN,,YLKBLK  ;LEN,,ADR OF LOOKUP BLOCK
		   YPTLEN,,YPTBLK] ;LEN,,ADR OF PATH. BLOCK
	PUSHJ	P,FSFSET	;SETUP FILOP. BLOCK
	 HALT	ERR		;INTERNAL ERROR
	MOVE	T,[400000+CM,,.FORED]  ;READ FILE ON CHANNEL CM
	MOVEM	T,YFLBLK+.FOFNC	;SETUP FUNCTION WORD
	MOVEI	T,.IOASL	;ASCII MODE
	TXNE	F,CCF		;SYMBOL FILE?
	MOVEI	T,.IODMP	;YES, USE DUMP I/O
	MOVEM	T,YFLBLK+.FOIOS	;SETUP "OPEN" BLOCK I/O STATUS
	MOVEI	T,CBUF		;BUFFER HEADER
	MOVEM	T,YFLBLK+.FOBRH	;SET IN OPEN BLOCK
	MOVEI	T,1		;ONLY WANT ONE INPUT BUFFER
	MOVEM	T,YFLBLK+.FONBF	;SET IT ALSO
	MOVEI	R,YBFBUF	;COMMAND BUFFER (PRE-ALLOCATED)
	EXCH	R,.JBFF		;PERSUADE MONITOR TO PUT BUFFER THERE
	MOVE	T,[YFLLEN,,YFLBLK]  ;FILOP. POINTER TO
	FILOP.	T,		;OBTAIN INPUT FILE
	 JRST	[EXCH	R,.JBFF	;RESET .JBFF
		 JRST	FSEFFF]	;TYPE FILOP. ERROR
	EXCH	R,.JBFF		;RESTORE .JBFF
	TXNE	F,CCF		;SYMBOL FILE?
	JRST	TAPSY		;YES, GO READ IN THEN
	CAILE	R,YBFBUF+YBFSIZ	;MAKE SURE BUFFER NOT TOO BIG
	JRST	ERR		;WAS, FORGET IT
	SETZM	CHINP		;FLAG WE
	SETZM	CHINC		;NOW HAVE
	SETOM	COMAND		;COMMAND FILE
	JRST	DD1		;TYPE <CR><LF> AND DO COMMANDS
;HERE TO HANDLE SYMBOL FILES

TAPSY:	JRST	ERR		;CODE NOT YET WRITTEN . . .
;$Y SWITCHES

TAPSWT:	SETOM	YASWF		;A - ABORT ON COMMAND ERRORS
	JRST	FSEILS		;B - ILLEGAL
	JRST	FSEILS		;C - ILLEGAL
	JRST	FSEILS		;D - ILLEGAL
	JRST	FSEILS		;E - ILLEGAL
	JRST	FSEILS		;F - ILLEGAL
	JRST	FSEILS		;G - ILLEGAL
	JRST	FSEILS		;H - ILLEGAL
	JRST	FSEILS		;I - ILLEGAL
	JRST	FSEILS		;J - ILLEGAL
	JRST	FSEILS		;K - ILLEGAL
	JRST	FSEILS		;L - ILLEGAL
	JRST	FSEILS		;M - ILLEGAL
	JRST	FSEILS		;N - ILLEGAL
	JRST	FSEILS		;O - ILLEGAL
	JRST	FSEILS		;P - ILLEGAL
	JRST	FSEILS		;Q - ILLEGAL
	JRST	FSEILS		;R - ILLEGAL
	JRST	FSEILS		;S - ILLEGAL
	JRST	FSEILS		;T - ILLEGAL
	JRST	FSEILS		;U - ILLEGAL
	JRST	FSEILS		;V - ILLEGAL
	JRST	FSEILS		;W - ILLEGAL
	JRST	FSEILS		;X - ILLEGAL
	JRST	FSEILS		;Y - ILLEGAL
	JRST	FSEILS		;Z - ILLEGAL
> ;END OF IFN FTYANK
> ;END IFN FTDEC10


IFE FTYANK,<TAPIN==ERR>
SUBTTL	COMMAND ROUTINES -- MISCELLANEOUS COMMANDS

IFE FTFILE,<

;HERE ON AN $G COMMAND TO START AT USER'S ARGUMENT OR THE START ADDRESS

GO:	SKIPE	MAPFN		;STRAIGHT VIRTUAL ADDRESSING?
	JRST	ERR		;NO, DISALLOW
	TXNE	F,QF		;EXPLICIT START ADDRESS GIVEN?
	JRST	GO4		;YES, GO USE IT

;NO START ADDRESS, MAKE A GUESS AT ONE

IFN	FTEXEC,<
	SKPUSR>			;OK IN EDDT IN USER MODE
IFN	FTEXEC!FTMON,<
	JRST	ERR>		;NO SUCH COMMAND IN EDDT OR MDDT
IFN	FTDEC20,<
	MOVEI	T1,.FHSLF
	GEVEC%			;GET ENTRY VECTOR
	HLRZ	TT,T2		;GET ITS LENGTH
	CAIN	TT,(JRST)	;TOPS10 FORMAT?
	JRST	GO2		;YES
	CAIL	TT,1000		;REASONABLE?
	JRST	ERR		;NO
	HRRZ	T,T2		;SETUP FIRST LOCATION
	TXNN	F,Q2F		;SECOND QUANT? (I.E. $1G)
	SETZM	WRD2O		;NO, ASSUME ZERO
	CAMG	TT,WRD2O	;WITHIN RANGE?
	JRST	ERR		;NO
	ADD	T,WRD2O		;ADD OFFSET WITHIN VECTOR
	JRST	GO4		;NOW HAVE ADDR IN T, GO START THERE
GO2:> ;END IFN FTDEC20
	MOVEI	R,.JBSA		;WHERE START ADDRESS LIVES
	PUSHJ	P,FETCH		;GO GET IT
	  JRST	ERR		;OOPS
	TLZ	T,-1		;FORM START ADDRESS ONLY
	JUMPE	T,ERR		;ILLEGAL IF RH(.JBSA) IS ZERO

;CONTINUED ON NEXT PAGE
;STILL IFE FTFILE

;FALL IN FROM ABOVE

;HERE WITH ADDRESS TO START AT IN T.
;WE LET RESTORE JUMP TO THE USER TO GET OUT OF DDT AS FAST AS POSSIBLE,
;IN CASE AN INTERRUPT IS PENDING.

GO4:	PUSH	P,T		;SAVE OVER TCRLF
	PUSHJ	P,TCRLF		;NEATNESS
IFN FTEXEC,<PUSHJ P,RSTAC>	;INSURE CORRECT AC BLOCK
	PUSHJ	P,INSRTB	;INSERT BREAKPOINTS
	POP	P,T		;RESTORE START ADDRESS
	SKPNS0			;IN SECTION 0?
	TLNN	T,-1		;AND ADDRESS ISN'T?
	JRST	RESTOR		;NO, DO NORMAL THING
	JRST	RESTRX		;YES, USE XJRSTF EVEN IN SECTION 0

> ;END IFE FTFILE

IFN FTFILE,<GO==ERR>
;HERE ON AN $M COMMAND -- SET DDT CONTROL REGISTERS

MASK:	TXNE	F,QF
	JRST	MASK1
IFE	FTFILE,<
	TXZN	F,Q2F		;[234] SECOND ARG TYPED?
	 TDZA	TT1,TT1		;[234] NO - DEFAULT TO SEARCH MASK
	SKIPL	TT1,WRD2D	;[234] YES - PICK UP MASK NUMBER
	CAIL	TT1,MSKMAX	;[234] WITHIN LEGAL LIMITS?
	 JRST	ERR		;[234] NO - COMPLAIN AT USER
	MOVEI	T,@MSKADR(TT1)	;[234] YES - GET RELEVANT MASK ADDRESS
MASK2:	MOVEI	W,1
	MOVEM	W,FRASE1
	JRST	QUANIN
>
IFN	FTFILE,<JRST ERR>

MASK1:	TRZN	F,Q2F		;[210] SECOND ARG TYPED?
	 TDZA	TT1,TT1		;[210] NO - DEFAULT TO SEARCH MASK
	SKIPL	TT1,WRD2D	;[210] YES - PICK UP MASK NUMBER
	CAIL	TT1,MSKMAX	;[213] LEGAL RANGE?
	  JRST	ERR		;[210] NO - COMPLAIN AT USER
	MOVEM	T,@MSKADR(TT1)	;[210] YES - STORE NEW MASK
	JRST	RET


MSKADR:	IFIW	MSK		;[210] SEARCH MASK
	IFIW	TTYMSK		;[210] TTY FORMAT CONTROL MASK
	IFIW	SYMOFS		;[234] SYMBOL + OFFSET RANGE "MASK"
	IFIW	BYTMSK		;[235] BYTE TYPEOUT MASK

	MSKMAX==.-MSKADR ;[210] MAX MASK "FUNCTION"
;HERE ON AN $Z COMMAND -- STORE DATA INTO MEMORY

ZERO:	TXNE	F,CCF		;$Z OR $$Z (OLD FORM)?
	JRST	ZEROLD		;$$Z - GO HANDLE OLD FORM
	TXNE	F,FAF		;MUST HAVE EXPLICIT LOWER
	TXNN	F,SAF		;AND UPPER ADDRESS LIMITS
	JRST	ERR		;DON'T - SYNTAX ERROR
	TXNN	F,QF		;EXPLICIT QUANTITY TYPED IN?
	SETZM	WRD		;NO, DEFAULT TO 0 THEN
	SKIPL	R,LLIMIT	;START ADDRESS
	CAMLE	R,ULIMIT	;MAKE SURE BEFORE END ADDRESS
	JRST	ERR		;ERROR
	PUSHJ	P,TCRLF		;NICE OUTPUT (IN CASE ^X ETC.)
	PUSHJ	P,PSHLLC	;SAVE PREVIOUS PC SEQUENCE

;LOOP DEPOSITING INTO EACH WORD BETWEEN LIMITS

ZERO2:	MOVE	T,WRD		;GET QUANTITY TO DEPOSIT
	PUSHJ	P,DEPMEM	;DEPOSIT INTO MEMORY
	TROA	R,PAGMSK	;CAN'T WRITE THIS PAGE
	CAIA			;OK - SKIP TO NEXT WORD
	IORM	R,LLIMIT	;ADVANCE TO END OF THIS PAGE
	AOS	R,LLIMIT	;ADVANCE TO NEXT WORD
	CAMLE	R,ULIMIT	;AT END LIMIT YET?
	JRST	ZERO4		;YES
	TRNN	R,PAGMSK	;START OF NEW PAGE?
ZERO3:	PUSHJ	P,LISCK		;YES, DO A LISTEN THEN
	  JRST	ZERO2		;KEEP GOING
	 JRST	ZERO4		;ABORT
	MOVEI	W1,[ASCIZ\Depositing: \]  ;NICE TEXT
	PUSHJ	P,TSTRG		;TELL USER
	MOVE	T,R		;CURRENT LOCATION
	PUSHJ	P,LI1		;TELL USER THAT TOO
	PUSHJ	P,TCRLF		;CAP OFF THE LINE
	MOVE	R,LLIMIT	;RESTORE R TO CURRENT LOCATION
	JRST	ZERO3		;AND CHECK AGAIN

ZERO4:	MOVEM	R,LLOC		;SET NEW "." TO LAST LOCATION ZAPPED
	PUSHJ	P,TCRLF		;END OF LOOP DEPOSITING MEMORY
	JRST	DD1		;RETURN
;HERE TO DO IT THE OLD WAY WHICH MAY GO AWAY ANYTIME

ZEROLD:	PUSHJ	P,SETUP
	HRRZ	S,@SYMP		;GET 1ST ADR OF SYMBOL TABLE
	HLRE	W1,@SYMP	;GET LENGTH OF SYM TABLE
	SUB	W1,S		;GET NEG OF LAST ADR
	MOVNS	W1		;GET POS LAST ADR
	MOVEI	T,0		;0 TO STORE IN MEMORY
ZEROL1:	TRNN	R,777760
	JRST	ZEROLR		;OK TO ZERO ACS
IFN	FTDEC10,<
IFN	FTEXEC,<
	SKPUSR
>
IFN	FTEXEC!FTFILE,<
	JRST	[CAIGE	R,XZLOW
		MOVEI	R,XZLOW		;IN EXEC MODE, DON'T ZERO 20-40
		JRST	ZEROL3 ] >
>
IFE	FTFILE,<
	CAIGE	R,ZLOW
	MOVEI	R,ZLOW		;DON'T ZERO 20 THRU ZLOW
ZEROL3:	CAIL	R,DDTBEG
	CAILE	R,DDTEND
	JRST	.+2
	MOVEI	R,DDTEND	;DON'T ZERO DDT
	CAML	R,S
	CAMLE	R,W1
	JRST	.+2
	HRRZ	R,W1		;DON'T ZERO SYMBOL TABLE
>
IFN	FTFILE,<
ZEROL3:>
ZEROLR:	CAMLE	R,ULIMIT	;ABOVE LIMITS?
	JRST	DD1		;YES, STOP
	PUSHJ	P,DEPMEM	;DEPOSIT T
IFE	FTFILE,<
	 TROA	R,377777	;
	AOJA	R,ZEROL1
	TRNN	R,400000	;HI SEGMENT?
	AOJA	R,ZEROL1	;NO, KEEP GOING
>
	JRST	DD1		;FINISH
IFN	FTFILE,<AOJA R,ZEROL1>
;SETUP (DEFAULT) LOWER AND UPPER LIMITS FOR $W AND $Z

SETUP:	TXNE	F,FAF		;LOWER LIMIT GIVEN?
	SKIPA	R,LLIMIT	;YES, PICK IT UP
IFE	FTFILE,<HLLZ	R,LLOC>	;NO, USE 000000 IN LOCAL SECTION
IFN	FTFILE,<SETZ	R,>	;NO, USE START OF FILE
	MOVEM	R,LLIMIT	;SET LOWER LIMIT WORD
	MOVE	T,ULIMIT	;UPPER LIMIT WORD
	TXNE	F,SAF		;UPPER LIMIT GIVEN?
	JRST	SETUP5		;YES, PICK IT UP
IFE	FTFILE,<HLLO	T,LLOC>	;NO, USE 777777 IN LOCAL SECTION
IFN	FTFILE,<
	MOVE	T,MAXSIZ	;NO, USE EOF
	SUBI	T,1		;(MAXSIZ ONE TOO BIG FOR THIS CASE)
	SKIPN	FILING		;IF LOOKING AT MONITOR/MEMORY
	JRST	SETUP3		;THIS IS UPPER LIMIT
	SKIPN	EXEFMT		;IF DATA FORMAT
	JRST	SETUP4		;THEN UPPER LIMIT AT EOF
	HLLO	T,LLOC		;777777 IN CURRENT SECTION
	SKIPE	MAPFN		;PAGE MAPPING IN EFFECT?
	JRST	SETUP4		;YES, UPPER LIMIT IN CURRENT SECTION
	MOVE	T,PGTLEN	;EXE FILE SANS MAPPING, MAX VIRT PAGE
	LSH	T,PG2WRD	;MAKE INTO WORD ADDRESS
	SUBI	T,1		;LAST WORD OF LAST VIRTUAL PAGE
	JRST	SETUP4		;BECOMES UPPER LIMIT
SETUP3:	SKIPL	MAPFN		;IF NOT PHYSICAL MEMORY
	HLLO	T,R		;THEN LIMIT TO SINGLE SECTION
> ;END OF IFN FTFILE
SETUP4:	MOVEM	T,ULIMIT	;SET UPPER LIMIT WORD
SETUP5:	CAMLE	R,T		;LIMITS IN A REASONABLE ORDER?
	JRST	ERR		;NO
	POPJ	P,		;YES, RETURN

;************** END OF COMMAND PROCESSING ROUTINES ***************
SUBTTL	FILE SPECIFICATION PARSING AND ERROR ROUTINES

IFN	FTDEC10&<FTFILE!FTYANK>,<

;FSCAN  --  ROUTINE TO INPUT (PARSE) ONE FILE SPEC
;CALL IS:
;
;	MOVEI	S,<SWTABLE>
;	PUSHJ	P,FSCAN
;	 ERROR RETURN (MESSAGE ALREADY TYPED)
;	OK RETURN, FSBLK FILLED IN
;
;WHERE <SWTABLE> IS THE ADDRESS OF A 26 (DECIMAL) WORD TABLE OF
;INSTRUCTIONS TO BE EXECUTED WHEN A SWITCH IS SEEN - THE FIRST
;WHEN "/A", THE SECOND ON "/B", ETC.
;
;THE AREA FSBLK HAS THE INPUT INFORMATION AS FOLLOWS:
;
;	FSBLK:		;.NE. 0 IF NOT A BLANK LINE
;		FS$SWT	;AT LEAST ONE SWITCH SPECIFIED
;		FS$DEV	;DEVICE WAS SPECIFIED
;		FS$NAM	;FILENAME WAS SPECIFIED
;		FS$EXT	;EXTENSION WAS SPECIFIED
;		FS$PTH	;PATH WAS SPECIFIED
;	FSDEV:		;THE DEVICE SPECIFIED
;	FSFIL:		;THE FILENAME SPECIFIED
;	FSEXT:		;THE EXTENSION (RH .NE. 0 IF ANYTHING TYPED)
;	FSPPN:		;THE PPN SPECIFIED
;	FSSFD:		;THE SFD'S (UP TO 5)
;
;NOTE THAT THE BITS IN FSBLK ARE ARRANGED SUCH THAT FS$SWT IS THE
;SIGN BIT SO THAT A SKIPN WILL TEST IF ANYTHING WAS TYPED, A SKIPG
;IF ONLY A FILE SPEC TYPED, A SKIPL IF ANY SWITCHES TYPED.
;
;IF EXTENSION "UFD" WAS SPECIFIED THEN THE DIRECTORY SPECIFIED
;IS USED AS THE FILENAME AND [1,1] IS RETURNED AS THE DIRECTORY.
;
;AC "T" CONTAINS CHARACTER WHICH TERMINATED FILE SCAN.
;
;USES ACS T, TT, TT1, TT2
;STILL FTDEC10

FSCAN:	SETZM	FSBLK		;CLEAR START OF FILESPEC AREA
	MOVE	T,[FSBLK,,FSBLK+1]  ;BLT POINTER TO
	BLT	T,FSBLK+FSLEN-1	;CLEAR ALL OF FILE SPEC AREA
	GETPPN	T,		;READ IN DEFAULT PPN
	 JFCL			;(BLOODY JACCT BIT)
	MOVEM	T,MYPPN		;SAVE FOR PATH DEFAULTING

;TOP LEVEL PARSE LOOP TO READ FILE SPEC

FSCSPC:	PUSHJ	P,FSCSIX	;READ A SOMETHING OR OTHER
FSCSP1:	CAIN	T,":"		;DEVICE SPECIFIED?
	JRST	FSCDEV		;YES - GO STORE
	JUMPE	TT,FSCSP2	;IF NO NAME, SKIP NAME SAVE
				;IF GOT HERE, MUST BE FILENAME IN TT
	SKIPE	FSFIL		;FILENAME ALREADY SPECIFIED?
	JRST	FSEDFI		;YES - ERROR
	MOVEM	TT,FSFIL	;SAVE FILENAME AWAY
	MOVX	TT,FS$NAM	;FILENAME SEEN
	IORM	TT,FSBLK	;REMEMBER FOR OTHERS
FSCSP2:	CAIN	T,"."		;EXTENSION COMING UP?
	JRST	FSCEXT		;YES - READ IT IN
	CAIN	T,"["		;PATH COMING UP?
	JRST	FSCPTH		;YES - READ IT IN
	CAIN	T,"/"		;SWITCH COMING UP?
	JRST	FSCSWT		;YES - GO SEE WHAT'S UP
	CAIE	T,.CHTAB	;RANDOM <TAB>?
	CAIN	T," "		;RANDOM SPACE?
	JRST	FSCSPC		;YES - JUST EAT IT, KEEP LOOKING
	HLRZ	TT1,FSEXT	;GET EXTENSION (IF ANY)
	CAIE	TT1,'UFD'	;USER FILE DIRECTORY?
	JRST	CPOPJ1		;NO, ALL DONE
	MOVE	TT1,FSPPN	;YES, THEN THE DIRECTORY
	MOVEM	TT1,FSFIL	;IS REALLY THE FILE NAME
	MOVE	TT1,[1,,1]	;AND [1,1]
	MOVEM	TT1,FSPPN	;IS REALLY THE DIRECTORY
	SETZM	FSSFD		;DISALLOW ANY SFD'S
	MOVX	TT1,FS$NAM	;NOTE WE HAVE SEEN THE FILENAME
	IORM	TT1,FSBLK	;ALBEIT IN A STRANGE PLACE
	JRST	CPOPJ1		;OK RETURN
;STILL FTDEC10

;HERE TO SET DEVICE NAME

FSCDEV:	JUMPE	TT,FSENDI	;NULL DEVICE ILLEGAL
	SKIPE	FSDEV		;DEVICE ALREADY SEPCIFIED?
	JRST	FSEDDI		;YES - ERROR
	MOVEM	TT,FSDEV	;SET NEW DEVICE NAME
	MOVX	TT,FS$DEV	;DEVICE SEEN
	IORM	TT,FSBLK	;REMEMBER FOR OTHERS
	JRST	FSCSPC		;CONTINUE PARSING


;HERE TO HANDLE EXTENSION COMING UP

FSCEXT:	SKIPE	FSEXT		;ALREADY SEEN EXTENSION?
	JRST	FSEDEI		;YES - ERROR
	PUSHJ	P,FSCSIX	;READ IN EXTENSION
	HLLOM	TT,FSEXT	;SET NEW EXTENSION
	MOVX	TT,FS$EXT	;EXTENSION SEEN
	IORM	TT,FSBLK	;REMEMBER FOR OTHERS TO SEE
	SETZ	TT,		;DON'T CONFUSE ANYBODY ELSE
	JRST	FSCSP1		;SEE WHAT ELSE TO DO


;HERE TO READ IN A DIRECTORY PATH SPECIFICATION

FSCPTH:	SKIPE	FSPPN		;PATH ALREADY BEEN SPECIFIED?
	JRST	FSEDPI		;YES - ERROR
	PUSHJ	P,FSCOCP	;READ IN OCTAL PROJECT NUMBER
	 JRST	FSEIPP		;ILLEGAL PROJECT/PROGRAMMER NUMBER
	CAIN	TT,0		;EXPLICIT PROJECT NUMBER?
	 HLR	TT,MYPPN	;NO - USE IMPLICIT LOGGED IN
	HRLM	TT,FSPPN	;SET UP
	CAIE	T,","		;MUST BE COMMA HERE
	JRST	FSEIPP		;NO COMMA - ERROR
	PUSHJ	P,FSCOCH	;READ IN OCTAL PROGRAMMER
	 JRST	FSEIPP		;ILLEGAL PROJECT/PROGRAMMER NUMBER
	CAIN	TT,0		;EXPLICIT PROGRAMMER?
	 HRR	TT,MYPPN	;NO - USE IMPLICIT LOGGED IN ONE
	HRRM	TT,FSPPN	;SET UP
	MOVE	TT2,[-6,,FSSFD] ;AOBJN POINTER FOR SFD'S
FSCPT5:	CAIE	T,","		;MORE TO DO?
	 JRST	FSCPT8		;NO - END OF PATH
	AOBJP	TT2,FSETMS	;MAKE SURE HAVE ROOM
	PUSHJ	P,FSCSIX	;YES - READ IN NEXT SFD
	JUMPE	TT,FSENSI	;NULL SFD ILLEGAL
	MOVEM	TT,-1(TT2)	;REMEMBER AWAY IN PATH BLOCK
	JRST	FSCPT5		;LOOP FOR NEXT SFD
FSCPT8:	MOVX	TT,FS$PTH	;PATH SEEN
	IORM	TT,FSBLK	;REMEMBER FOR OTHERS
	JUMPE	T,CPOPJ1	;EOL IS VALID END OF PATH CHAR
	CAIE	T,"]"		;"]" IS ONLY OTHER VALID TERMINATOR
	JRST	FSEIPP		;FUNNY CHARACTER - CALL ERROR
	JRST	FSCSPC		;CONTINUE PARSING
;STILL FTDEC10

;HERE TO HANDLE (IN AN ELEMENTARY FASHION) SWITCHES

;SWITCHES WILL BE IDENTIFIED BY THEIR FIRST CHARACTER ONLY,
;ALTHOUGH THE ENTIRE "WORD" WILL BE READ IN ON G.P.'S
;
;ADDRESS IN S IS 26 (DECIMAL) ENTRIES FOR THE 26 POSSIBLE
;SWITCHES. EACH SWITCH ENTRY WILL BE AN INSTRUCTION TO BE
;XCT'ED BY THE SWITCH PROCESSOR. IF A "COMPLICATED" ROUTINE
;IS NEEDED TO HANDLE THE SWITCH THEN THE SWITCH ENTRY IN
;SWTBL SHOULD BE A PUSHJ TO THE ROUTINE TO HANDLE THAT PAR-
;TICULAR SWITCH, WHICH ROUTINE SHOULD RETURN CPOPJ0.
;
;UNUSED SWITCH ENTRIES SHOULD BE "JRST FSEILS"

FSCSWT:	PUSHJ	P,FSCSIX	;READ IN A SWITCH NAME
	JUMPE	TT,FSENWI	;NULL SWITCH ILLEGAL
	LSH	TT,-^D30	;REDUCE TO SINGLE CHARACTER
	JUMPE	S,FSEILS	;IF NO SWITCHES THEN ALWAYS ERROR
	CAIL	TT,'A'		;IN RANGE
	CAILE	TT,'Z'		;I.E., ALPHA?
	 JRST	FSEILS		;NO - ERROR
	MOVEI	TT1,-'A'(TT)	;GET SWITCH OFFSET (A = 0, ETC.)
	ADDI	TT1,(S)		;POINT INTO SWITCH TABLE PASSED US
	XCT	(TT1)		;DO SWITCH-SPECIFIC PROCESSING
	MOVX	TT,FS$SWT	;SWITCH SEEN
	IORM	TT,FSBLK	;REMEMBER FOR OTHERS
	SETZ	TT,		;DON'T CONFUSE THE ISSUE
	JRST	FSCSP1		;CONTINUE PARSE
;STILL FTDEC10

;FSCSIX  --  READ IN A SIXBIT WORD
;CALL IS:
;
;	PUSHJ	P,FSCSIX
;	RETURN
;
;RETURNS SIXBIT WORD (LEFT JUSTIFIED) IN AC "TT" AND TERMINATING
;CHARACTER IN AC "T".  ANY CHARACTERS AFTER THE FIRST SIX WILL BE
;IGNORED - I.E., TOSSED OUT.
;
;USES T, TT, TT1

FSCSIX:	MOVE	TT1,[POINT 6,TT] ;LOAD BYTE POINTER
	SETZ	TT,		;WHAT WE'VE SEEN SO FAR
FSCSI0:	PUSHJ	P,FSCTIN	;NEXT CHARACTER
	 POPJ	P,		;END OF SCAN
	CAIL	T,"0"		;POSSIBLE VALID ALPHANUMERIC?
	CAILE	T,"Z"		; . . .
	 POPJ	P,		;NO - END OF SCAN
	CAILE	T,"9"		;TO BE MORE PRECISE -
	CAIL	T,"A"		;IS IT A VALID ALPHANUMERIC?
	CAIA			;YES
	 POPJ	P,		;NO - END OF SCAN
	SUBI	T,40		;MAKE INTO SIXBIT CHARACTER
	TXNE	TT1,77B5	;ROOM LEFT IN TT?
	IDPB	T,TT1		;YES - SO STUFF IN LATEST CHAR
	JRST	FSCSI0		;LOOP BACK
;STILL FTDEC10

;FSCOCT  --  READ IN OCTAL NUMBER
;FSCOCH  --  READ IN OCTAL HALFWORD
;FSCOCP  --  READ IN OCTAL 17-BIT WORD (PROJECT NUMBER)
;CALL IS:
;
;	PUSHJ	P,FSCOC-
;	 ERROR RETURN
;	NORMAL RETURN
;
;THE ERROR RETURN IS TAKEN IF THE NUMBER READ IS TOO LARGE
;FOR A PPN, OTHERWISE THE NORMAL RETURN WILL BE TAKEN AND
;THE OCTAL INTEGER WILL BE RETURNED IN AC "TT" WITH THE TERMI-
;NATING CHARACTER IN AC "T".
;
;USES T, TT

FSCOCP:	PUSHJ	P,FSCOCT	;GET OCTAL VALUE
	TDNE	TT,[777777400000] ;MORE THAN 17 BITS?
	POPJ	P,		;YEP - TAKE ERROR RETURN
	JRST	CPOPJ1		;NOPE, GIVE GOOD RETURN

FSCOCH:	PUSHJ	P,FSCOCT	;GET OCTAL VALUE
	TLNE	TT,-1		;MORE THAN 18 BITS?
	POPJ	P,		;YEP - CALL ERROR
	JRST	CPOPJ1		;NOPE - GIVE GOOD RETURN

FSCOCT:	SETZ	TT,		;INITIALIZE
FSCOC0:	PUSHJ	P,FSCTIN	;NEXT CHARACTER
	 POPJ	P,		;C'EST TOUT
	CAIL	T,"0"		;SEE IF VALID OCTAL
	CAILE	T,"7"		; . . .
	 POPJ	P,		;NOPE - END OF SCAN
	TXNN	TT,7B2		;ROOM LEFT IN TT?
	LSH	TT,3		;YES - SHIFT UP ONE OCTADE
	IORI	TT,-"0"(T)	;AND ADD IN THIS ONE
	JRST	FSCOC0		;MORE, MORE, MORE!
;STILL FTDEC10

;FSCTIN  --  READ IN ONE COMMAND CHARACTER
;CALL IS:
;
;	PUSHJ	P,FSCTIN
;	 EOL RETURN
;	NORMAL RETURN
;
;IF CHARACTER READ IS LINE-FEED OR ESCAPE (I.E., END OF LINE)
;THEN RETURN IS CPOPJ0 WITH AC "T" CONTAINING 0.
;
;NORMAL RETURN IS CPOPJ1 WITH AC "T" CONTAINING THE NEXT SEVEN-BIT
;ASCII COMMAND CHARACTER, LOWER CASE SHIFTED TO UPPER CASE AND
;TABS CONVERTED TO SPACES.

FSCTIN:	INCHWL	T		;NEXT COMMAND CHARACTER
	CAIE	T,.CHDEL	;<DEL>
	CAIN	T,.CHCRT	;OR <CR>?
	 JRST	FSCTIN		;YES, JUST EAT IT
	CAIN	T,.CHTAB	;<TAB>?
	 MOVEI	T," "		;YES, CONVERT TO SPACE
	CAIE	T,.CHLFD	;<LF>
	CAIN	T,.CHESC	;OR <ESC>?
	 SETZ	T,		;YES, BREAK CHAR, RETURN 0
	JUMPE	T,CPOPJ		;IF A BREAK JUST RETURN NOW
	CAIL	T,"A"+40	;LOWER CASE
	CAILE	T,"Z"+40	; . . .
	CAIA			;NO
	 SUBI	T,40		;YES, SHIFT TO UPPER CASE
	CAIE	T,.CHCNC	;<ETX>
	CAIN	T,.CHCNZ	;OR <SUB>?
	 JRST	FSCTIZ		;YES, EXIT
	JRST	CPOPJ1		;NO, RETURN VALID CHARACTER IN T

FSCTIZ:	EXIT	1,		;RETURN TO MONITOR
	POPJ	P,
;STILL FTDEC10

;ERROR ROUTINES FOR FSCAN AND FRIENDS

FSEDDI:	TMSG	<? Duplicate device illegal>
	JRST	FSEERR

FSEDEI:	TMSG	<? Duplicate extension illegal>
	JRST	FSEERR

FSEDFI:	TMSG	<? Duplicate filename illegal>
	JRST	FSEERR

FSEDPI:	TMSG	<? Duplicate path illegal>
	JRST	FSEERR

FSEFFF:	TMSG	<? FILOP. failure (>
	PUSHJ	P,TOC		;ISSUE ERROR CODE
	TMSG	<) for input file>
	JRST	FSEERR

FSEILS:	TMSG	<? Illegal switch ">
	ADDI	TT,"A"-'A'	;MAKE INTO 7-BIT ASCII
	OUTCHR	TT		;AND LIST THE SWITCH
	TMSG	<" specified>
	JRST	FSEERR

FSEIPP:	TMSG	<? Illegal path specification>
	JRST	FSEERR

FSENDI:	TMSG	<? Null device illegal>
	JRST	FSEERR

FSENFI:	TMSG	<? Null filename illegal>
	JRST	FSEERR

FSENSI:	TMSG	<? Null SFD illegal>
	JRST	FSEERR

FSENWI:	TMSG	<? Null switch illegal>
	JRST	FSEERR

FSETMS:	TMSG	<? Too many SFD's>
	JRST	FSEERR

;COMMON ERROR EXIT

FSEERR:	TMSG	<
>
	POPJ	P,
;STILL FTDEC10

;FSFSET  --  BUILD A FILOP. BLOCK GIVEN SCAN DATA
;CALL IS:
;
;	MOVX	T,<BLKPTR>
;	PUSHJ	P,FSFSET
;	 ERROR
;	RETURN
;
;WHERE <BLKPTR> IS A POINTER TO A 3 WORD TABLE CONTAINING:
;   BLKPTR + 0/	LENGTH,,ADDRESS OF FILOP. BLOCK
;	   + 1/	LENGHT,,ADDRESS OF LOOKUP BLOCK
;	   + 2/	LENGTH,,ADDRESS OF PATH BLOCK
;
;THE ERROR RETURN IS TAKEN IF ANY OF THE BLOCKS ARE TOO SHORT
;
;RETURNS WITH FILOP. BLOCK SETUP, POINTING TO OTHER BLOCKS, ALL
;BLOCKS ZEROED EXCEPT FOR DEVICE, FILENAME, FILETYPE, AND FILEPATH
;WORDS.

FSFSET:	MOVE	TT,0(T)		;LENGTH,,ADDRESS OF FILOP. BLOCK
	PUSHJ	P,FSFCLR	;CLEAR BLOCK
	CAIGE	TT1,.FOLEB	;IS FILOP. BLOCK LONG ENUF?
	 POPJ	P,		;NO, ERROR
	MOVE	TT1,FSDEV	;GET DEVICE
	MOVEM	TT1,.FODEV(TT)	;SET IN DEVICE WORD
	MOVE	TT1,1(T)	;POINTER TO LOOKUP BLOCK
	HRRM	TT1,.FOLEB(TT)	;SET IN FILOP. BLOCK
	MOVE	TT,1(T)		;POINTER TO LOOKUP BLOCK AGAIN
	PUSHJ	P,FSFCLR	;CLEAR IT OUT
	SOJ	TT1,		;COUNT WORD DOESN'T COUNT
	CAIGE	TT1,.RBEXT	;IS LOOKUP BLOCK LONG ENOUGH?
	 POPJ	P,		;NO, ERROR
	MOVEM	TT1,.RBCNT(TT)	;SET LOOKUP BLOCK LENGTH
	MOVE	TT1,FSFIL	;FILE NAME
	MOVEM	TT1,.RBNAM(TT)	;SET IN LOOKUP BLOCK
	HLLZ	TT1,FSEXT	;FILE TYPE
	MOVEM	TT1,.RBEXT(TT)	;SET IN LOOKUP BLOCK
	MOVE	TT1,FSBLK	;THE SCANNER BITS
	TXNN	TT1,FS$PTH	;WAS A DIRECTORY PATH SPECIFIED?
	JRST	CPOPJ1		;NO, ALL DONE
	MOVE	TT1,2(T)	;YES - ADDRESS OF PATH BLOCK
	HRRZM	TT1,.RBPPN(TT)	;SET IN LOOKUP BLOCK
	MOVE	TT,2(T)		;PATH POINTER
	PUSHJ	P,FSFCLR	;CLEAR IT OUT
	CAIGE	TT1,.PTPPN+5+1	;IS IT LONG ENUF FOR A REAL PATH?
	 POPJ	P,		;NO, ERROR
	MOVSI	TT1,FSPPN	;START OF SCANNED PATH
	HRRI	TT1,.PTPPN(TT)	;START OF PATH BLOCK PATH INFO
	BLT	TT1,.PTPPN+5+1(TT) ;SETUP PATH BLOCK
	JRST	CPOPJ1		;RETURN WITH FILOP. BLOCK SETUP
;STILL FTDEC10

;FSFCLR  --  ROUTINE TO CLEAR A BLOCK
;CALL IS:
;
;	MOVX	TT,<LENGTH,,ADDRESS>
;	PUSHJ	P,FSFCLR
;	RETURN
;
;RETURNS ADDRESS IN TT AND LENGTH IN TT1, USES TT2

FSFCLR:	HRR	TT1,TT		;START ADDRESS
	SETZM	(TT1)		;CLEAR FIRST WORD
	ADDI	TT1,1		;RH OF BLT POINTER
	HRL	TT1,TT		;LH OF BLT POINTER
	HLRZ	TT2,TT		;LENGTH TO ZERO
	ADDI	TT2,(TT)	;LAST WORD TO BE ZEROED
	BLT	TT1,(TT2)	;ZERO BLOCK
	HLRZ	TT1,TT		;RETURN LENGTH IN TT1
	ANDI	TT,-1		;AND ADDRESS IN TT
	POPJ	P,		;DONE
> ;END OF IFN FTDEC10&<FTFILE!FTYANK>
SUBTTL	ENTER AND LEAVE DDT -- SAVE

IFE FTFILE,<

;SAVE -- SUBROUTINE TO SAVE USER CONTEXT ON ENTRY TO DDT
;CALL:
;	JSR	SAVE
;	 NORMAL RETURN
;	HERE IF CONTEXT ALREADY SAVED
;
;SAVES USER CONTEXT IF NOT ALREADY SAVED AWAY (AS FLAGGED BY SARS).
;ALWAYS SETS UP DDT CONTEXT SO DDT WILL BE IN A KNOWN STATE.

;FIRST, SAVE AND SETUP "ALWAYS" STUFF.  ALSO SHUT OFF PI IN EXEC MODE
;NOW SO WE CAN SET UP STUFF LIKE ACS THAT MIGHT BE USED AT INTERRUPT LEVEL.

SAVEG:	MOVEM	T,SWTEM		;SAVE AC FOR MOMENT
	XMOVEI	T,-1		;GET SECTION NUMBER FOR OUR PC
	HLLZM	T,SECDDT	;AND SAVE IT FOR OTHERS
	HLLZ	T,SAVE		;GET SECTION 0 PC FLAGS
	SKPS0			;IN NON-ZERO SECTION?
	XSFM	T		;YES, ASK CPU FOR PC FLAGS
	MOVEM	T,XSAVE		;SAVE PC FLAGS FOR LATER XJRSTF
	ROT	T,5		;ROTATE USER MODE BIT TO SIGN
	MOVEM	T,USRFLG	; AND SAVE IT
	MOVE	T,XSAVE		;RETRIEVE CURRENT PC FLAGS
	XOR	T,PCFLG		;CHECK USER FLAG AGAINST LAST SAVE
	TXNE	T,1B5		;SAME?
	SETZM	SARS		;NO, SAVE ACS AND PC FOR EXIT
				; SO EXEC/USER MODE FLOP RESTORED AS ENTERED
IFN FTEXEC,<
	SKPEXC			;IN EXEC MODE?
	JRST	SAVE1		;NO, SKIP THIS
	SKIPN	SARS		;WANT TO SAVE OLD PI STATUS?
	CONI	PI,SAVPI	;YES, SAVE FOR EXIT
	CONO	PI,@SAVPI+1	;SET UP PI SYSTEM FOR DDT
SAVE1:
> ;END OF IFN FTEXEC
	MOVE	T,SWTEM		;RESTORE THE AC 

;CONTINUED ON NEXT PAGE
;STILL IFE FTFILE

;CONTINUED FROM PREVIOUS PAGE

;NOW SAVE NON-EXEC MODE THINGS THAT SHOULD ONLY BE SAVED IF SARS=0,
;THEN SET UP ALL NON-EXEC MODE THINGS THAT DDT WANTS SET UP.

	AOS	SAVE		;ASSUME SKIP RETURN (ALREADY SAVED)
	SKIPE	SARS		;ALREADY SAVED?
	JRST	SAVE2		;YES, DON'T SAVE THESE AGAIN
	SOS	SAVE		;ASSUMPTION NOT VALID, UN-DO SKIP RETURN
	MOVEM	17,AC17		;SAVE ACS
	HRRZI	17,AC0
	BLT	17,AC0+16
	SETOM	FAKEAC		;NOTE LOCATIONS 0 - 17 SAVED AWAY
	MOVE	T,XSAVE		;GET FRESH PC FLAGS
	MOVEM	T,PCFLG		;AND SAVE THEM FOR OTHERS

SAVE2:	MOVE	P,[IOWD LPDL,PDL]	;SETUP ALL ACS
	SETZ	F,		;NO FLAGS YET
	MOVE	T,[SCHM,,SCH]	;DDT TYPEOUT MODES
	BLT	T,ODF		;SET THEM UP
	SETZM	MAPFN		;NO MAPPING ($U) IN EFFECT


;NOW SAVE USER MODE ONLY ITEMS.

IFN FTDEC20,<
  IFN FTEXEC,<
	SKPEXC			;DON'T DO THIS IF IN EXEC MOE
  > ;END OF IFN FTEXEC
	SKIPE	SARS		;ALREADY SAVED?
	JRST	SAVE4		;YES, DON'T SAVE AGAIN
	SETOM	SAVSTS		;ASSUME PSI SYSTEM IS ON
	MOVEI	T1,.FHSLF	;BUT CHECK...
	SKPIR%			;IS IT?
	SETZM	SAVSTS		;NO, REMEMBER THAT IT'S OFF

;CONTINUED ON NEXT PAGE
;STILL IFE FTFILE

;FALL IN FROM ABOVE

;HERE TO ATTEMPT TO RUN IN NON-ZERO SECTIONS IN USER MODE WITH
;MONITORS THAT ALWAYS SET PCS TO ZERO.  THIS IS TEMPORARY CODE
;THAT SHOULD BE DELETED WHEN USER MODE EXTENDED ADDRESSING IS DONE.

IFE FTMON,<
	SKPNS0			;USER MODE EXTENDED ADDRESSING?
	JRST	SAVE4		;NO, FORGET IT
	MOVEI	R,BEG.V		;OUR DATA AREA IN SECTION 0
	SETOM	LASTPG		;CLEAR THIS BEFORE CALLING CHKADR
	PUSHJ	P,CHKADR	;SEE ABOUT THE PAGE
	TXNE	TT,PG$EXI	;PAGE EXISTS ALREADY?
	JRST	SAVE4		;YES, DON'T OVERWRITE IT


;SET UP AN INDIRECT POINTER FROM OUR DATA PAGE TO THE CORRESPONDING
;PAGE IN SECTION 0, SO THAT THE MONITOR WILL FIND OUR ARGUMENTS TO
;JSYSES LIKE TEXTI% THAT TAKE ARGUMENTS IN MEMORY.  AS LONG AS PCS
;IS ZERO, THE MONITOR HAS NO WAY TO FETCH OUT OF NON-ZERO USER SECTIONS.

	XMOVEI	T1,BEG.V	;YES, SET UP AN @ POINTER
	LSH	T1,WRD2PG	;  SO JSYSES LIKE TEXTI% WORK
	HRLI	T1,.FHSLF	;OUR FORK TO OUR FORK
	MOVX	T2,<.FHSLF,,BEG.V_WRD2PG>	;TO SECTION 0
	MOVX	T3,PM%RWX	;READ, WRITE, AND EXECUTE
	PMAP%			;SET UP THE INDIRECT POINTER
	  ERJMP	.+1		;WE TRIED
> ;END IFE FTMON
> ;END IFN FTDEC20

;CONTINUED ON NEXT PAGE
;STILL IFE FTFILE

;CONTINUED FROM PREVIOUS PAGE

;NOW SAVE ALWAYS-SAVE EXEC MODE STATUS.  THIS INCLUDES CPU TYPE,
;PAGING TYPE, ETC.

SAVE4:
IFN FTEXEC,<
	SKPEXC			;IN EXEC MODE?
	JRST	SAVE8		;NO, DON'T BOTHER (FAILS FOR KS10 ANYWAY)
SAV4A:	MOVE	T,[BZ$FLG,,BZ$FLG+1]	;ZERO FLAGS
	SETZM	BZ$FLG		; . . .
	BLT	T,ZZ$FLG-1	; . . .
	MOVNI	T,1		;LOAD T WITH ALL ONES
	AOBJN	T,.+1		;ADD ONE TO BOTH HALVES
	JUMPE	T,SAV4I		;IF T=0 THEN PROCESSOR AFTER KA-10
	SETOM	KAFLG		;RH CARRIED INTO LH, MUST BE KA-10
	JRST	SAVE6		;CONTINUE

SAV4I:	BLT	T,0		;SEE WHAT PROCESSOR DOES WITH BLT
	JUMPN	T,SAV4L		;KL-10 WILL LEAVE BEHIND 1,,1
	SETOM	KIFLG		;T=0 IF KI-10
	SETOM	KIPAG		;KI-10'S ALWAYS DO KI-PAGING
	JRST	SAVE6		;CONTINUE

SAV4L:	APRID	T		;GET PROCESSOR SERIAL NUMBER
	ANDI	T,17777		;SERIAL NUMBER ONLY
	CAIL	T,^D1024	;IN RANGE OF
	CAILE	T,^D4095	;KL-10 PROCESSORS?
	CAIA			;NOPE
	SETOM	KLFLG		;IS A KL-10
	CAIL	T,^D4096	;IN RANGE OF
	CAILE	T,^D8191	;KS-10 PROCESSORS?
	CAIA			;NOPE
	SETOM	KSFLG		;IS A KS-10
	SKPKL			;ON A KL-10
	SKPNKS			;OR A KS-10?
	CAIA			;YES
	HALT	.		;EXEC DDT ON AN UNKNOWN PROCESSOR TYPE
	SETOM	KLSFLG		;EITHER A KL-10 OR A KS-10

;CONTINUED ON NEXT PAGE
;STILL IFE FTFILE AND IFN FTEXEC

;CONTINUED FROM PREVIOUS PAGE

;NOW SAVE THE THINGS THAT SHOULD ONLY BE SAVED IN EXEC MODE IF SARS=0,
;LIKE APR STATUS.

SAVE6:	SKIPE	SARS		;ALREADY SAVED?
	JRST	SAVE8		;YES, SKIP THIS
	CONI	APR,T		;GET APR STATUS
  IFN FTDEC10,<
	SKPNKA			;ON A KA-10?
	TXNN	T,1B23		;YES, NXM SET?
	  CAIA			;NO OR NO
	TXO	T,1B0		;KA AND NXM SET, MOVE TO 1B0
  > ;END IFN FTDEC10
	MOVEM	T,SAVAPR	;SAVE APR STATUS FOR LATER
> ;END OF IFN FTEXEC


;NOW CALL TTYRET TO SAVE ALL TTY-RELATED STUFF.

SAVE8:	PUSHJ	P,TTYRET	;DO TTY-DEPENDENT STUFF FOR RETURN TO DDT
	SETOM	SARS		;STATUS SUCCESSFULLY SAVED
	JRST	@SAVE
SUBTTL	ENTER AND LEAVE DDT -- RESTOR

;STILL IFE FTFILE

;RESTOR -- ROUTINE TO RESTORE USER STATUS BEFORE RETURNING TO THE USER
;CALL:
;	JSP	T,RESTOR
;	RETURN
;
;HERE WHEN ALL USER STATES RESTORED.

RESTOR:	TDZA	TT,TT		;NORMAL ENTRY
RESTRX:	SETO	TT,		;FLAG USE XJRSTF REGARDLESS
	MOVEM	TT,RSTM1	;SAVE FLAG
	MOVEM	T,SAVE
	PUSHJ	P,TTYLEV	;RESTORE STATUS OF CONSOL TTY (EXEC MODE)
	MOVE	T,PCFLG		;SAVED PC FLAGS
	TLZ	T,010000	;DON'T TRY TO RESTORE USER MODE FLAG
	MOVEM	T,XSAVE		;SET PC FLAGS FOR POSSIBLE XJRSTF
	SKPNS0			;IN NON-ZERO SECTION?
	SKIPE	RSTM1		;OR NEED XJRSTF REGARDLESS?
	CAIA			;YES, DON'T WIPE OUT SAVE
	HLLM	T,SAVE		;NO, SET ZERO SECTION PC FLAGS
IFN	FTEXEC,<
	SKPEXC
	JRST	RESTR2
	MOVE	T,SAVPI		;GET SAVED PI SYSTEM ENABLE BITS
	AND	T,SAVPI+1
	IORI	T,2000		;TURN ON CHANNELS
	TRZ	T,1000		;MAKE SURE WE DON'T ASK FOR BOTH
	HRRZM	T,SAVPI
RESTR2:
> ;END FTEXEC
	HRLZI	17,AC0
	BLT	17,17
	SETZM	SARS
IFN FTEXEC,<
	SKPUSR			;IN USER MODE?
	SKIPL	SAVAPR		;EXEC, WANT NXM SET?
	CAIA			;USER OR NO
	MOVES	777777		;WANT NXM SET, ASSUME KA-10
> ;END IFN FTEXEC

;FALL INTO NEXT PAGE
;STILL IFE FTFILE

;FALL IN FROM ABOVE

;NOW TO RETURN TO THE CALLER, EITHER DDT OR THE USER PROGRAM ITSELF.
;IF IN EXEC MODE, WE TRY TO TURN THE PI ON AS LATE AS POSSIBLE, TO
;MAXIMIZE THE CHANCE THAT THE PC WILL GET OUT OF DDT BEFORE AN INTERRUPT
;OCCURS.

	SKPNS0			;WANT TO USE XJRSTF?
	SKIPE	RSTM1		;NOT UNLESS ENTERED AT RESTRX

IFE FTEXEC,<
	XJRSTF	XSAVE		;IN NON-ZERO SECTION, USE XJRSTF
	JRSTF	@SAVE		;IN SECTION 0, USE JRSTF
> ;END IFE FTEXEC

IFN FTEXEC,<
	JRST	RESTR6		;GO USE XJRSTF
	SKPUSR			;IN EXEC MODE?
	CONO	PI,@SAVPI	;YES, RESTORE USER'S PI
				; NOTE: MUST BE LAST INSTRUCTION BEFORE JRSTF
	JRSTF	@SAVE		;RETURN TO DDT OR USER

RESTR6:	SKPUSR			;IN EXEC MODE
	CONO	PI,@SAVPI	;YES, RESTORE USER'S PI
				; NOTE: MUST BE LAST INSTRUCTION BEFORE XJRSTF
	XJRSTF	XSAVE		;RETURN TO DDT OR USER
>; END IFN FTEXEC
SUBTTL	ENTER AND LEAVE DDT -- SWAP

;STILL FTFILE

;ROUTINE TO SWAP BETWEEN DDT AND USER CONTEXTS.
;   ACS AND FLAGS ARE SWAPPED, BUT BREAKPOINTS AND OTHER STUFF
;   ARE NOT TOUCHED, SINCE CONTROL IS EXPECTED TO RETURN TO DDT SOON.

SWAPG:	MOVEM	T,SWTEM		;SAVE T FOR MOMENT
	SKIPE	SARS		;GOING TO USER CONTEXT?
	JRST	SWAP2		;YES, JUST SET NEW FLAGS
	HLLZ	T,SWAP		;NO, NEED TO SAVE CURRENT FLAGS
	SKPS0			;VALID?
	XSFM	T		;NO, GET REAL PC FLAGS
	MOVEM	T,PCFLG		;SAVE OLD USER FLAGS
SWAP2:	MOVE	T,PCFLG		;SET USER FLAGS
	MOVEM	T,XSWAP		;SET UP FOR XJRSTF
	SKPNS0			;IN SECTION 0?
	HLLM	T,SWAP		;YES, SET UP FOR JRSTF
	MOVE	T,SWTEM		;RESTORE T
	EXCH	0,AC0		;SWAP AC 0
	MOVEM	0,SAV0		;SAVE 0 FOR WORK
	MOVE	0,[EXCH 1,AC0+1];SETUP INST FOR SWAPPING ACS
SWAPL:	XCT	0		;SWAP AN AC
	ADD	0,[Z 1,1]	;INC AC AND MEM FIELDS
	TXNE	0,<Z 17,>	;OVERFLOWED AC FIELD?
	JRST	SWAPL		;NO, LOOP
	MOVE	0,SAV0		;YES, RESTORE SAVED AC
	SETCMM	SARS		;REMEMBER WE HAVE SWAPPED CONTEXTS
	SKPNS0			;IN NON-ZERO SECTION?
	JRSTF	@SWAP		;RETURN, RESTORING NEW FLAGS
	XJRSTF	XSWAP		;RETURN, RESTORING NEW FLAGS
SUBTTL	ENTER AND LEAVE DDT -- SUPPRESS ADDRESS BREAKS

;STILL IFE FTFILE

;PCAFI  --  ROUTINE TO SUPPRESS ADDRESS BREAK
;CALL IS:
;
;	JSP	TT2,PCAFI
;	 INSTR
;
;THIS ROUTINE WILL RETURN TO "INSTR" WITH ADDRESS BREAK INHIBIT SET
;SO THAT THE INSTRUCTION WILL NOT CAUSE AN ADDRESS BREAK.
;
;USED PRIMARILY BY FETCH AND STORE LOGIC.
;
;USES TT1, TT2

PCAFI:	SKPS0			;IN NON-ZERO SECTION?
	JRST	PCAFI1		;YES, DIFFERENT CODE
PCAFI0:	TXO	TT2,PC$AFI	;SET ADDRESS FAILURE INHIBIT
	JRSTF	(TT2)		;AND RETURN ALLOWING ONE INSTRUCTION TO
				; EXECUTE FREE OF ADDRESS BREAK

PCAFI1:	XSFM	TT1		;MUST EXPLICITLY READ PC FLAGS
	TXO	TT1,PC$AFI	;SET ADDRESS FAILURE INHIBIT
	XJRSTF	TT1		;AND RETURN ALLOWING ONE INSTRUCTION TO
				; EXECUTE FREE OF ADDRESS BREAK
SUBTTL	ENTER AND LEAVE DDT -- BCOM

;STILL IFE FTFILE

;HERE FROM THE JSR IN THE BREAKPOINT BLOCK ON ANY BREAKPOINT.
;FIRST, DECIDE WHETHER OR NOT TO BREAK (CONDITIONS, PROCEED COUNT).

BCOMG:	SETZM	SARS		;ALWAYS SAVE REGISTERS
	JSR	SAVE		;SAVE THE WORLD
	 PUSHJ	P,REMOVB	;REMOVE ALL BREAKPOINTS

;NOW FIGURE OUT WHAT HAPPENED

	HRRZ	S,BCOM		;SEE WHICH BREAKPOINT WE CAME FROM
	SUBI	S,BPT$B+B$JSR+1	;S:=BREAKPOINT NUMBER * B$SIZ
	MOVEM	S,BPTDX		;SAVE "INDEX" FOR LATER
	MOVE	T,BPT$B+B$BPT(S);REAL ADDRESS (+1) FROM WHENCE WE CAME
	SKPNS0			;IN NON-ZERO SECTION?
	ANDI	T,-1		;NO, ONLY 18-BITS OF PC
	CAIE	S,0		;BREAKPOINT 0?
	HRRI	T,-1(T)		;NO - BACKUP PC BY 1
	MOVEM	T,PCWRD		;SAVE FOR $X ET AL
	SETOM	BPTIP		;FLAG BREAKPOINT IN PROGRESS
	JUMPE	S,BREAK		;BREAKPOINT 0 (UNSOLICITED) ALWAYS BREAKS

;NOW SEE WHETHER OR NOT TO BREAK

	XCT	BPT$B+B$XCT(S)	;(USER) CONDITIONAL BREAK INSTRUCTION
	SOSG	BPT$B+B$CNT(S)	;PROCEED COUNT HIT 0?
	JRST	BREAK		;USER OR COUNT SAYS TO BREAK

;NO BREAK, JUST CONTINUE THE PROGRAM AS IF NOTHING HAD HAPPENED

	JRST	PROCD4		;CONTINUE WITH USER PROGRAM
;STILL IFE FTFILE

;<< (MATCH ANGLE BRACKETS)

BREAK:	PUSHJ	P,TTYCLR	;FLUSH WAITING TTY CHARACTERS FOR INPUT
	SETZM	I.LOG		;NO $X'S YET SINCE THIS BREAKPOINT
	MOVE	S,BPTDX		;BREAKPOINT INDEX (NUMBER * B$SIZ)
	MOVEI	T,"$"		;START OF BREAKPOINT MESSAGE
	PUSHJ	P,TOUT		;SEND IT OUT
	MOVE	A,S		;COPY OF INDEX
	IDIVI	A,B$SIZ		;REDUCE TO BREAKPOINT NUMBER
	PUSHJ	P,FP7		;TYPE AS DECIMAL (SANS THE DOT)
	MOVSI	W1,(ASCII/B>/)	;REST OF BREAKPOINT TEXT
	PUSHJ	P,TEXT2		;TYPE IT OUT
	MOVEI	T,">"		;IN CASE CONDITIONAL BPT
	MOVE	S,BPTDX		;RESTORE BREAKPOINT INDEX
	SKIPG	BPT$B+B$CNT(S)	;DID WE STOP ON USER'S CONDITIONAL BPT?
	PUSHJ	P,TOUT		;NO, NORMAL BPTS HAVE 2 ANGLE BRACKETS
	MOVE	T,PCWRD		;GET BREAKPOINT PC + 1
	PUSHJ	P,PSHLLC	;SAVE IN PC RING BUFFER
	PUSHJ	P,PINST		;SHOW BREAKPOINT LOCATION/CONTENTS
	MOVE	S,BPTDX		;LI1 CRUMPS ON S
	SKIPGE	BPT$B+B$OPN(S)	;ADDRESS TO OPEN?
	JRST	BREAK4		;NO
	PUSHJ	P,TTAB		;YES, TAB OVER FOR NEATNESS
	MOVE	T,BPT$B+B$OPN(S);GET ADDRESS TO OPEN
	PUSHJ	P,PSHLLC	;PUT ADDRESS IN PC RING BUFFER TOO
	PUSHJ	P,LI1		;SHOW ADDRESS/CONTENTS
	MOVE	S,BPTDX		;AND AGAIN, LI1 CRUMPS ON S

BREAK4:	MOVE	R,BPT$B+B$FLG(S);GET BREAKPOINT FLAGS
	PUSHJ	P,LISTEN	;USER TYPING?
	TXNN	R,BP$PRO	;NO, AUTO-PROCEED IN EFFECT?
	JRST	RET		;REALLY TIME FOR A BREAK
	JRST	PROCD2		;AUTO-PROCEED FROM THIS BREAKPOINT
;STILL IFE FTFILE

;INSERT BREAKPOINTS

INSRTB:	PUSHJ	P,SAVRST	;SAVE A FEW HANDY REGISTERS
	MOVEI	S,B$SIZ		;START WITH $1B
INSRT1:	MOVE	R,BPT$B+B$ADR(S);NEXT BREAKPOINT ADDRESS
	JUMPE	R,INSRT3	;IF 0 THEN NO BREAKPOINT HERE
	PUSHJ	P,FETCH		;GET USER INSTRUCTION
	 JRST	INSRT3		;CAN'T READ, JUST IGNORE
	MOVEM	T,BPT$B+B$INS(S);SAVE USER INSTRUCTION FROM BREAKPOINT
	MOVSI	T,(JSR)		;FIRST HALF OF BREAKPOINT
	HRRI	T,BPT$B+B$BPT(S);CALCULATE ADDRESS TO BREAKPOINT TO
	PUSHJ	P,DEPMEM	;PUT THE JSR IN USER PROGRAM
	 JFCL			;HERE ONLY IF CAN'T WRITE IN HIGH SEG
INSRT3:	ADDI	S,B$SIZ		;ADVANCE TO NEXT BREAKPOINT
	CAIGE	S,B$SIZ*<NBP+1>	;DONE THEM ALL YET?
	JRST	INSRT1		;NO, GO DO NEXT ONE
	POPJ	P,		;YES, RETURN WITH BREAKPOINTS INSTALLED

;REMOVE BREAKPOINTS

REMOVB:	PUSHJ	P,SAVRST	;SAVE A FEW REGISTERS
	MOVEI	S,B$SIZ		;START WITH $1B
REMOV1:	MOVE	T,BPT$B+B$INS(S);INSTRUCTION THAT BELONGS AT THIS BREAKPOINT
	SKIPLE	R,BPT$B+B$ADR(S);ADDRESS OF THIS BREAKPOINT (IF ANY)
	PUSHJ	P,DEPMEM	;PUT USER INSTRUCTION BACK
	 JFCL			;HERE ONLY IF NO WRITE IN HIGH SEG
	ADDI	S,B$SIZ		;ADVANCE TO NEXT BREAKPOINT
	CAIGE	S,B$SIZ*<NBP+1>	;DONE THEM ALL YET?
	JRST	REMOV1		;NO, GO REMOVE NEXT ONE
	POPJ	P,		;YES, ALL BREAKPOINTS REMOVED

> ;END IFE FTFILE
SUBTTL	WORD TYPEOUT AND FORMATTING ROUTINES

;HERE TO TYPE OUT A WORD JUST FETCHED FROM MEMORY, AS WHEN A REGISTER
;HAS JUST BEEN OPENED.  USES THE CURRENT TYPEOUT MODE UNLESS LF1 IS SET.

CONSYM:	MOVEM	T,LWT
IFN	FTFILE,<
IFN	FTDEC10,<
	MOVEM	T,POKBLK+1>>	;STORE FOR /P/M LOGIC
	TRNN	F,LF1
	JRST	(SCH)		;PIN OR FTOC
	TRNE	F,CF1
	JRST	FTOC		;TYPE OUT AS CONSTANT

;PRINT OUT IN INSTRUCTION FORMAT

PIN:	TDC	T,[XWD -1,400000]	;IS THIS A NEGATIVE NUMBER?
	TDCN	T,[XWD -1,400000]
	JRST	PADS3B		;TYPE AS NEG NUM
	TXNN	T,777B8		;[240] GOT A VALID OPCODE?
	 JRST	HLFW		;[240] NO WAY! TYPE OUT XWD FORMAT
	TRO	F,OKAF		;[240] DON'T TYPE "#" AFTER OPERATOR
	PUSHJ	P,LOOK		;[240] DO 36-BIT OPERATOR SEARCH
	 JRST	PIN0B		;[240] NOPE
	 JRST	PIN0B		;[240] NOPE
	POPJ	P,		;[240] EXACT MATCH, ALL DONE

;[240] NOW TRY FOR OPERATORS OF FORM OPCODE + E-FIELD

PIN0B:	TLC	T,700000	;CHECK FOR AN I/O INSTRUCTION
	TLCN	T,700000	;NEED TO DECODE FIELDS DIFFERENTLY IF SO
	JRST	INOUT		;IS AN I/O INST, GO HANDLE
IFN	FTOPX,<			;SKIP THIS IF WE WANT TO BE FAST
	MOVE	T,LWT		;[240] FRESH COPY OF WORD
	TXZ	T,<Z 17,>	;[240] MASK OUT AC FIELD
	CAME	T,[TTCALL 0,]	;DON'T TYPE "INCHRW 17,"
	PUSHJ	P,LOOK		;[240] LOOK FOR SYMBOLIC OPERATOR
	 JRST	PIN0D		;[240] NOPE
	 JRST	PIN0D		;[240] NOPE
	PUSHJ	P,TSPC		;[240] MATCH!!! SPACE OVER
	LDB	T,[POINT 4,LWT,12]  ;[240] GET AC FIELD
	JUMPE	T,CPOPJ		;[240] AC FIELD NULL, ALL DONE
	PUSHJ	P,PAD		;[240] TYPE OUT SYMBOLIC AC FIELD
	MOVEI	T,","		;[240] CAP OFF AC FIELD WITH COMMA
	PJRST	TOUT		;[240] AND TYPEOUT IS COMPLETE
;[240] NOW TRY FOR OPCODE AND AC FIELD

PIN0D:	HLLZ	T,LWT		;[240] FRESH COPY OF WORD
	TXZ	T,37B17		;[240] REDUCE TO OPCODE AND AC FIELD
	CAME	T,[CALLI 0]	;CALLI?
	CAMN	T,[MTAPE 0]	;OR MTAPE?
	JRST	PIN0F		;YES, DON'T TYPE "RESET 1234"
	PUSHJ	P,LOOK		;[240] SEE IF ANY SUCH ANIMAL
	 JRST	PIN0F		;[240] NOPE
	 JRST	PIN0F		;[240] NOPE
	TXO	F,NAF		;[240] YEP, SO ALLOW NEGATIVE ADDRESS
	PUSHJ	P,TSPC		;[240] SPACE OVER ONE
	JRST	PI4		;[240] AND GO TYPE OUT I, X, AND Y
> ;END IFN FTOPX

;[240] LAST TRY FOR A USER SYMBOL - OPCODE FIELD ONLY

PIN0F:	HLLZ	T,LWT		;[240] FRESH COPY OF WORD
	TLZ	T,777		;[240] OPCODE ONLY
	CAME	T,[CALLI  0,0]	;[240] A CALLI?
	CAMN	T,[TTCALL 0,0]	;[240] OR A TTCALL?
	 JRST	PIN0H		;[240] YES, DON'T TYPE "RESET 200064" ETC.
	CAMN	T,[MTAPE  0,0]	;[240] AN MTAPE?
	 JRST	PIN0H		;[240] YES, DON'T TYPE "MTWAT. 37" ETC.
	PUSHJ	P,LOOK		;[240] SEE IF USER SYMBOL
	 JRST	PIN0H		;[240] NOPE
	 JRST	PIN0H		;[240] NOPE
	JRST	PIN2		;[240] GOT IT, TYPE AC, I, X, AND Y

;[240] LAST DITCH - LOOK AT NORMAL HARDWARE OPCODES

PIN0H:	TRZ	F,OKAF		;[240] CLEAR CROCK FLAG
	HLLZ	T,LWT		;[240] FRESH COPY OF WORD
	TLZ	T,777		;[240] OPCODE ONLY
	PUSHJ	P,OPTYPE	;[240] TRY INTERNAL TABLES
	TRNN	F,ITF		;[240] DID WE WIN?
	 PJRST	HLFW		;[240] COMPLETELY UNKNOWN OPERATOR

;[240] FALL INTO PIN2 ON NEXT PAGE
;[240] COMMON INSTRUCTION-FORMAT TYPEOUT CODE

PIN2:	TRO	F,NAF		;EXACT MATCH TYPED, ALLOW NEG ADDRESSES
	PUSHJ	P,TSPC
	LDB	T,[XWD 270400,LWT]	;GET AC FIELD
	JUMPE	T,PI4
	HLRZ	W,LWT
	CAIL	W,(JRST)
	CAILE	W,256777	;IS INST BETWEEN JRST AND XCT?
	JRST	[PUSHJ	P,PAD	;NO, PRINT SYMBOLIC AC
		JRST	PI3A]
	PUSHJ	P,TOC		;YES, PRINT NUMERIC AC
PI3A:	MOVEI	W1,","
	PUSHJ	P,TEXT
PI4:	MOVE	W1,LWT
	TXNE	W1,<@>		;CHECK FOR INDIRECT BIT
	JRST	PI80		;YES, ALWAYS SYMBOLIC ADDRESS
	HRRZ	T,LWT
	LDB	W,[XWD 331100,LWT]	;INSTRUCTION BITS
	MOVE	W1,W		;GET COPY
	TRC	W1,600
	TRNN	W1,710		;IS INST TRXX OR TLXX?
	JRST	[PUSHJ	P,TOC	;YES, PRINT ADDRESS NUMERIC
		JRST	PI7]	;CONTINUE WITH INDEX CHECK
	CAIL	W,240
	CAILE	W,247
	JRST	PI84		;ALL (EXCEPT ASH,ROT,LSH) HAVE SYMBOLIC ADRS
	CAIN	W,<JFFO>_-33	;JFFO?
	JRST	PI84		;SYMBOLIC ADDRESS
	PUSHJ	P,PADS3A	;ONLY ABSOLUTE ADDRESSING FOR LSH, ASH, AND ROT
PI7:	TRZ	F,NAF
	LDB	R,[XWD 220400,LWT]	;INDEX REGISTER CHECK
	JUMPE	R,CPOPJ		;EXIT
	MOVEI	T,"("
	PUSHJ	P,TOUT
	MOVE	T,R
	PUSHJ	P,PAD
	MOVEI	T,")"
	JRST	TOUT		;EXIT

PI80:	MOVEI	T,"@"		;SYMBOLIC INDIRECT BIT
	PUSHJ	P,TOUT		;TYPE IT
	HRRZ	T,LWT		;GET 18-BIT Y-FIELD FOR SYMBOLIC ADDRESS
PI84:	PUSHJ	P,PAD		;PRINT SYMBOLIC (UNLESS $A)
	JRST	PI7		;CHECK FOR INDEXING
HLFW:	HLRZ	T,LWT		;PRINT AS HALF WORDS
	JUMPE	T,HLFW1		;TYPE ONLY RIGHT ADR IF LEFT ADR=0
	TRO	F,NAF		;ALLOW NEGATIVE ADDRESSES
	PUSHJ	P,PAD		;PRINT AS 18-BIT "ADDRESS"
	MOVSI	W1,(ASCII /,,/)
	PUSHJ	P,TEXT2		;TYPE ,,
HLFW1:	HRRZ	T,LWT
	PUSHJ	P,PAD		;PRINT AS 18-BIT ADDRESS
	TRZ	F,NAF		;TURN NAF BACK OFF
	POPJ	P,		;DONE


;PRINT ADDRESSES (ARG USUALLY 18 BITS BUT CAN BE 36 BITS)

PAD:	ANDI	T,-1		;PRINT ONLY RIGHT HALF
PADR:	JRST	(AR)		;PADSO OR TOC

PADSO:	JUMPE	T,FP7B		;PRINT A ZERO
	PUSHJ	P,LOOK
	 JRST	PADS3		;NOTHING FOUND, TYPE NUMERIC
	 CAIA			;SOMETHING FOUND
	 POPJ	P,		;EXACT MATCH FOUND AND TYPED
	MOVE	TT1,S		;COPY OFFSET
	MOVE	TT2,SYMOFS	;AND GET HIGHEST ALLOWABLE OFFSET
	TXC	TT1,1B0		;TURN INTO UNSIGNED NUMBERS
	TXC	TT2,1B0		;SO CAN COMPARE THEM
	CAMGE	TT1,TT2		;ADR WITHIN SYMBOL + OFFSET RANGE?
	TXNN	W,-20		;PRINT ACS THAT DON'T MATCH EXACTLY NUMERICALLY
	JRST	PADS3		;PRINT ADDRESS NUMERICALLY
	TLNN	W,-1		;IS SYMBOL IN SECTION 0?
	TLNN	T,-1		;YES, IS ADDRESS NOT IN ZERO?
	CAIA			;CASE DOESN'T APPLY, CONTINUE
	JRST	PADS3		;YES, DONT TYPE DDT+10000 FOR 1,,0
	TXNN	F,NAF		;AM I GOING TO TYPE SYM+OFFS OR -1?
	JRST	PADS1		;ALWAYS TYPE SYM+OFFS, EVEN NEAR -1
	CAIL	T,-100		;IS ADDR BETWEEN 0,,-100 AND 0,,-1?
	CAILE	T,-1		; . . .
	  JRST	PADS1		;NO, TYPE AS SYM+OFFSET
	JRST	PADS3		;YES, TYPE AS -N FOR "MOVEI -1" TYPEOUT
PADS1:	MOVEM	S,TEM
	PUSHJ	P,PSYM0
	MOVEI	T,"#"
	TXNE	F,MDLCLF	;SYMBOL IS OUTSIDE LOCAL?
	PUSHJ	P,TOUT		;YES, FLAG
	MOVEI	T,"+"
PADS1A:	PUSHJ	P,TOUT
	MOVE	T,TEM
	JRST	TOCA		;TYPE WITHOUT COMMAS
PADS3:	TLNE	T,-1		;GLOBAL (30-BIT) ADDRESS?
	JRST	PADS5		;YES, TYPE AS SECNUM,,TAG
PADS3A:	TRNN	F,NAF		;NEGATIVE ADDRESSES ALLOWED?
	JRST	TOC		;NO, JUST TYPE OUT OCTAL (OR WHATEVER)
	CAIGE	T,776000	;".LT. -2000" ?
	JRST	TOC
PADS3B:	MOVN	T,T		;WANT TO TYPE OUT AS A NEGATIVE NUMBER
	HRRZM	T,TEM		;BUT ONLY 18-BITS WORTH
	MOVEI	T,"-"
	JRST	PADS1A

PADS5:	PUSH	P,T		;SAVE T FOR MOMENT
	HLRZ	T,T		;GET GLOBAL SECTION NUMBER
	PUSHJ	P,TOC		;TYPE OUT AS NUMBER
	MOVSI	W1,(ASCII/,,/)	;SEPARATE TWO HALVES
	PUSHJ	P,TEXT2		; WITH ,,
	POP	P,T		;GET BACK T
	PJRST	PAD		;AND TYPE LOW-ORDER 18 BITS
INOUT:
IFN	FTOPX,<			;[240] LOOK FOR USER OPERATORS
	AND	T,[777740,,0]	;[240] OPERATOR & DEVICE CODE
	TRO	F,OKAF		;[240] NO "#" AFTER OPERATOR SYMBOL
	PUSHJ	P,LOOK		;[240] LOOK FOR USER-DEFINED OPERATOR
	 JRST	INOUT1		;[240] NOPE
	 JRST	INOUT1		;[240] NOPE
	TRZ	F,OKAF		;[240] FOUND ONE, CLEAR KROCK FLAG
	PUSHJ	P,TSPC		;[240] SPACE OVER FROM OPERATOR SYMBOL
	JRST	PI4		;[240] GO TYPE OUT I, X, AND Y FIELDS

INOUT1:	MOVSI	T,777000	;JUST THE OPCODE FIELD
	AND	T,LWT		;(IN CASE KS-10 STYLE I/O INSTRUCTION)
	TLNN	T,077000	;OPCODE 700?
	JRST	INOUT3		;FLICK IT IN (DON'T TYPE APRID 14, ETC.)
	PUSHJ	P,LOOK		;SEE IF ANY SUCH ANIMAL
	 JRST	INOUT3		;NOPE
	 JRST	INOUT3		;NOPE
	TRZ	F,OKAF		;FOUND A MATCH, CLEAR KROCK FLAG
	JRST	PIN2		;AND TYPE AC, I, X, AND Y FIELDS NORMALLY

INOUT3:	TRZ	F,OKAF		;[240] CLEAR KROCK FLAG
	MOVE	T,LWT		;[240] RESTORE T
> ;[240] END OF IFN FTOPX

	LDB	R,[POINT 7,T,9]	;PICK OUT IO DEVICE BITS
	CAIL	R,700_-2	;IF DEVICE .L. 700, THEN TYPE
	JRST	HLFW		;TYPE AS HALF WORDS
	LDB	R,[POINT 3,T,12]
	DPB	R,[POINT 6,T,8]	;MOVE IO BITS OVER FOR OP DECODER
	PUSHJ	P,OPTYPE
	PUSHJ	P,TSPC
	MOVSI	T,077400
	AND	T,LWT
	JUMPE	T,INOUT4	;TYPE "APR,"
	PUSHJ	P,LOOK		;LOOK FOR DEVICE NUMBER
	 JRST	INOUT2		;NOTHING FOUND, PRINT AS OCTAL
	 JRST	INOUT2		;NO EXACT MATCH, PRINT AS OCTAL
	 JRST	PI3A		;EXACT MATCH TYPED
INOUT2:	LSH	T,-30
	PUSHJ	P,TOC
	JRST	PI3A

INOUT4:	MOVE	T,[ASCIZ/APR/]	;AS IN "CONO APR,BITS"
	PUSHJ	P,TEXTT		;TYPE IT OUT
	JRST	PI3A		;GIVE COMMA AND REST OF I, X, AND Y
SUBTTL OUTPUT SUBROUTINES

FTOC:				;NUMERIC OUTPUT SUBROUTINE
TOC:	HRRZ	W1,ODF
	CAIN	W1,10		;IS OUPUT RADIX NOT OCTAL, OR
	TLNN	T,-1		;ARE THERE  NO LEFT HALF BITS?
	JRST	TOCA		;YES, DO NOTHING SPECIAL
	HRRM	T,TOCS		;NO, TYPE AS HALF WORD CONSTANT
	HLRZS	T		;GET LEFT HALF
	PUSHJ	P,TOC0		;TYPE LEFT HALF
	MOVSI	W1,(ASCII /,,/)
	PUSHJ	P,TEXT2		;TYPE ,,
	XCT	TOCS		;GET RIGHT HALF BACK
TOCA:	HRRZ	W1,ODF		;IS OUTPUT RADIX DECIMAL?
	CAIN	W1,12
	JRST	TOC4		;YES,TYPE SIGNED WITH PERIOD
TOC0:	LSHC	T,-43
	LSH	W1,-1		;W1=T+1
	DIVI	T,(ODF)
	PUSH	P,W1
	SKIPE	T
	PUSHJ	P,TOC0
	POP	P,T
	ADDI	T,"0"
	CAILE	T,"9"		;[225] RADIX-DIGIT .GT. 9?
	ADDI	T,"A"-"9"-1	;[225] YES, SHIFT TO LETTERS
	JRST	TOUT

TOC4:	MOVE	A,T		;TYPE AS SIGNED DECIMAL INTEGER
	JUMPGE	T,TOC5
	MOVEI	T,"-"
	PUSHJ	P,TOUT
TOC5:	PUSHJ	P,FP7		;DECIMAL PRINT ROUTINE
TOC6:	MOVEI	T,"."
	JRST	TOUT
;SYMBOL OUTPUT SUBROUTINE

PSYM0:	MOVEM	W1,SPSAV	;SAVE POINTER TO TYPED SYM
PSYM:				;RADIX 50 SYMBOL PRINT
	MOVE	T,W2		;GET SYMBOL
	TXZ	T,PNAME		;CLEAR OUT FLAGS
PSYM1:	IDIVI	T,50
	PUSH	P,W1
	JUMPE	T,PSYM2
	PUSHJ	P,PSYM1
PSYM2:	POP	P,T
	JUMPE	T,[MOVEI T," "	;SHOW EMBEDDED SPACES
		JRST	TOUT]
	ADDI	T,260-1
	CAILE	T,271
	ADDI	T,301-272
	CAILE	T,332
	SUBI	T,334-244
	CAIN	T,243
	MOVEI	T,256
	JRST	TOUT
;FLOATING POINT OUTPUT

TFLOT:	MOVE	A,T
	JUMPGE	A, TFLOT1
	MOVNS	A
	MOVEI	T,"-"
	PUSHJ	P,TOUT
	TLZE	A,400000
	JRST	FP1A
TFLOT1:	TLNN	A, 400
	JRST	TOC5		;IF UNNORMALIZED, TYPE AS DECIMAL INTEGER

	MOVEI	B,0
	CAMGE	A,FT01
	JRST	FP4
	CAML	A,FT8
	AOJA	B,FP4
FP1A:	MOVEI	C,0

FP3:	MULI	A,400
	ASHC	B,-243(A)
	SETZM	TEM1		;INIT 8 DIGIT COUNTER
	SKIPE	A,B		;DON'T TYPE A LEADING 0
	PUSHJ	P,FP7		;PRINT INTEGER PART OF 8 DIGITS
	PUSHJ	P,TOC6		;PRINT DECIMAL POINT
	MOVNI	A,10
	ADD	A,TEM1
	MOVE	W1,C
FP3A:	MOVE	T,W1
	MULI	T,12
	PUSHJ	P,FP7B
	SKIPE	W1
	AOJL	A,FP3A
	POPJ	P,

FP4:	MOVNI	C,6
	MOVEI	W2,0
FP4A:	ASH	W2,1
	XCT	FCP(B)
	JRST	FP4B
	LDB	W1,[POINT 23,FCP+1(B),35]
	TXO	W1,<IFIW 0>
	FMPR	A,@W1
	IORI	W2,1
FP4B:	AOJN	C,FP4A
	PUSH	P,W2		;SAVE EXPONENT
	PUSH	P,FSGN(B)	;SAVE "E+" OR "E-"
	PUSHJ	P,FP3		;PRINT OUT FFF.FFF PART OF NUMBER
	POP	P,W1		;GET "E+" OR "E-" BACK
	PUSHJ	P,TEXT
	POP	P,A		;GET EXPONENT BACK
FP7:	IDIVI	A,12		;DECIMAL OUTPUT SUBROUTINE
	MOVMS	B		;MAKE POSITIVE
	AOS	TEM1
	PUSH	P,B
	JUMPE	A,FP7A1
	PUSHJ	P,FP7

FP7A1:	POP	P,T
FP7B:	ADDI	T,260
	JRST	TOUT

	353473426555		;1.0E32
	266434157116		;1.0E16
FT8:	233575360400		;1.0E8
	216470400000		;1.0E4
	207620000000		;1.0E2
	204500000000		;1.0E1
FT:	201400000000		;1.0E0
	026637304365		;1.0E-32
	113715126246		;1.0E-16
	146527461671		;1.0E-8
	163643334273		;1.0E-4
	172507534122		;1.0E-2
FT01:	175631463146		;1.0E-1
FT0=FT01+1

FCP:	CAMLE	A, FT0(C)
	CAMGE	A, FT(C)
	Z	FT0(C)

FSGN:	ASCII	.E-.
	ASCII	.E+.
;TEXT OUTPUT SUBROUTINES

;ROUTINE TO OUTPUT TEXT A LA $9T

TEXT9T:	MOVE	W1,T		;FOR LATER LSHC'S
	TLNN	W1,777000	;LEFT JUSTIFIED UNLESS
	LSH	W1,^D36-^D9	;LEFT-MOST CHAR NULL
TEXT9V:	SETZ	T,		;CLEAR OUT GARBAGE
	LSHC	T,^D9		;GET NEXT CHARACTER
	PUSHJ	P,TOUT		;OUTPUT ONE ASCII CHARACTER
	JUMPN	W1,TEXT9V	;LOOP FOR ALL FOUR CHARACTERS POSSIBLE
	POPJ	P,		;ALL DONE

;ROUTINE TO OUTPUT TEXT A LA $8T

TEXT8T:	MOVE	W1,T		;COPY OF WORD FOR LSHC'S
	TLNN	W1,776000	;LEFT JUSTIFIED TEXT UNLESS
	LSH	W1,^D36-^D8	;LEFT-MOST CHARACTER NULL
TEXT8V:	SETZ	T,		;CLEAR OUT GARBAGE
	LSHC	T,^D8		;GET NEXT CHARACTER
	PUSHJ	P,TOUT		;OUTPUT ONE ASCII CHARACTER
	JUMPN	W1,TEXT8V	;LOOP FOR ALL FOUR CHARACTERS
	POPJ	P,		;DONE

;ROUTINE TO OUTPUT TEXT A LA $7T

TEXTT:	MOVE	W1,T
TEXT:	TLNN	W1,774000	;LEFT JUSTIFIED UNLESS LEFT CHAR IS NULL
	LSH	W1,35
TEXT2:	MOVEI	T,0		;7 BIT ASCII TEXT OUTPUT SUBROUTINE
	LSHC	T,7
	PUSHJ	P,TOUT
	JUMPN	W1,TEXT2
	POPJ	P,

R50PNT:	LSH	T,-36		;RADIX 50 SYMBOL PRINTER
	TRZ	T,3
	PUSHJ	P,TOC
	PUSHJ	P,TSPC
	LDB	T,[POINT 32,LWT,35]	;GET SYMBOL WITHOUT FLAGS
	JRST	PSYM1

SIXBP:	MOVNI	W2,6		;SIXBIT PRINTER
	MOVE	W1,LWT
SIXBP1:	MOVEI	T,0
	ROTC	T,6
	ADDI	T,40
	PUSHJ	P,TOUT
	AOJL	W2,SIXBP1
	POPJ	P,
SUBTTL	SYMBOL TABLE ROUTINES -- CHECK POINTERS

;SYMCHK -- SUBROUTINE TO CHECK OUT SYMBOL TABLE PTRS
;CALL IS:
;
;	PUSHJ	P,SYMCHK
;	RETURN
;
;ARBITRARILY SETZM'S ANY POINTERS THAT ARE INVALID.  IF THE UNDEFINED
;PTR IS INVALID, IT IS FIXED TO POINT TO THE END OF ONE OF THE
;DEFINED PTRS.
;
;USES R, S, AND T

SYMCHK:
IFE FTFILE,<
	SKIPE	SYMVAL		;HAS THIS ALREADY BEEN DONE?
	POPJ	P,		;YES, DON'T DO IT AGAIN
> ;END IFE FTFILE

	SKIPGE	T,@SYMP		;GET MAIN SYMBOL PTR
	PUSHJ	P,CHKSYP	;CHECK IT OUT
	  SETZM	@SYMP		;INVALID
	MOVEI	R,.JBHSM	;HIGH SEG SYMBOL TABLE PTR
	PUSHJ	P,HFETCH	;GET IT
	  TDZA	T,T		;NO HIGH SEG
	PUSHJ	P,CHKSYP	;CHECK OUT THE HIGH SEG PTR
	  SETZ	T,		;NO GOOD
	MOVEM	T,SAVHSM	;STORE COPY OF HIGH SEG PTR OR ZERO

;NOW SEE IF .JBSYM AND .JBHSM POINT TO THE SAME TABLE. IGNORE .JBHSM IF SO.

	SKIPGE	@SYMP		;GOT A GOOD .JBSYM POINTER?
	SKIPL	SAVHSM		;AND A GOOD .JBHSM POINTER?
	JRST	SYMCH1		;ONLY ONE, JUST USE IT
	HRLO	T,@SYMP		;GET START OF .JBSYM TABLE INTO LH
	SUB	T,@SYMP		;FORM END OF THE TABLE
	HRLO	S,SAVHSM	;GET START OF .JBHSM TABLE INTO LH
	SUB	S,SAVHSM	;FORM END OF ITS TABLE
	XOR	S,T		;COMPARE END ADDRESSES (IN LH'S)
	TLNN	S,-1		;POINTING TO SAME TABLES?
	SETZM	SAVHSM		;YES, IGNORE .JBHSM POINTER

;NOW CHECK .JBUSY FOR VALIDITY, AND FIX IT IF IT'S WRONG.

SYMCH1:	SKIPL	R,@SYMP		;GOT A VALID SYMBOL TABLE?
	MOVE	R,SAVHSM	;NO, USE HISEG PTR IF ANY TO FIX UNDEF PTR
	SKIPGE	T,@USYMP	;GET UNDEFINED PTR IF ANY
	PUSHJ	P,CHKSYP	;A REAL ONE; CHECK IT OUT
	  JRST	SYMCH2		;BAD OR POSITIVE, FIX IT
	JRST	SYMCH4		;POINTER IS OK
;HERE TO MAKE A BAD OR POSITIVE UNDEF PTR POINT TO THE END OF THE S.T.

SYMCH2:	HRRZ	R,R		;RH ONLY
	MOVEM	R,@USYMP	;STORE FOR OTHERS
	MOVEM	R,ESTUT		;STORE FOR UNDEFINED SYM ASSEMBLER

;HERE WHEN SYMBOL PTRS CHECKED OUT, NOW CHECK PRGM ($: PTR).

SYMCH4:
IFE FTFILE,<
	SKIPN	S,PRGM		;GET PTR, ONE THERE?
	JRST	SYMCH8		;NO, PROCEED
	JUMPGE	S,SYMCH6	;PROCEED IF S POINTS TO LOWSEG
	MOVEI	R,.JBHNM	;PRGM POINTS TO HISEG, GET HISEG NAME
	PUSHJ	P,HFETCH	; . . .
	  JRST	SYMCH8		;NO GOOD, CLEAR PRGM
	CAME	T,SEGNAM	;SAME HISEG?
	JRST	SYMCH8		;NO, CLEAR PRGM
	SKIPA	T,SAVHSM	;YES, GET THE PTR THAT PRGM POINTS INTO
SYMCH6:	MOVE	T,@SYMP		;GET THE PTR THAT PRGM POINTS INTO
	JUMPGE	T,SYMCH8	;IF NO TABLES, PRGM CERTAINLY INVALID
	TXZ	S,1B0		;CONVERT S TO OFFSET INTO TABLE
	HLRE	R,T		;-LENGTH OF SYMBOL TABLE
	MOVN	R,R		;MAKE +LENGTH OF TABLE
	CAML	S,R		;PRGM INVALID UNLESS S IS WITHIN THE TABLE
SYMCH8:	  SETZM	PRGM		;PRGM INVALID IN SOME WAY
	SETOM	SYMVAL		;WE NOW KNOW ABOUT SYMBOL TABLE PTRS
> ;END OF IFE FTFILE

	POPJ	P,		;RETURN
SUBTTL	SYMBOL TABLE ROUTINES -- CONVERT SYMBOL TO VALUE

;EVAL -- ROUTINE TO FIND THE VALUE OF THE RADIX-50 SYMBOL IN SYM.
;EVALU -- LIKE EVAL, BUT SEARCHES THE UNDEFINED SYMBOL TABLE.
;CALL:
;	<SET UP SYM>
;	PUSHJ	P,EVAL/EVALU
;	  NOT FOUND
;	NORMAL RETURN
;
;CAN ALSO GO TO ERR IF SYMBOL TABLE FORMAT IS WRONG, OR MULDEF IF THE
;SYMBOL IS MULTIPLY-DEFINED.
;
;ON A NORMAL RETURN, THE ACS ARE SET UP AS FOLLOWS:
;
;	T	VALUE OF THE SYMBOL FOUND
;	W1	SYMBOL INDEX OF SYMBOL FOUND
;	W2	FLAGS OF SYMBOL FOUND

EVALU:	PUSHJ	P,USYSET	;SET UP TO LOOP OVER THE UNDEFINED SYMBOLS
	AOJA	R,EVAL1		;LOOK AT ALL SYMBOLS, CONTINUE IN EVAL

EVAL:	MOVE	S,SYM		;GET SYMBOL
	SETZ	TT,		;INITIALIZE FOR CALLING LOKCSH
EVAL00:	PUSHJ	P,LOKCSH	;SEE IF IT IS IN THE CACHE
	JRST	EVAL0		;NO, MUST SEARCH SYMBOL TABLE
	MOVE	T,SCAGE(TT)	;GET LOCAL FLAG FOR SYMBOL
	TRNE	T,1		;WAS THIS AN OUTSIDE LOCAL SYMBOL?
	JRST	EVAL00		;YES, SEARCH SOME MORE
	MOVE	T,SCVAL(TT)	;GET VALUE OF SYMBOL
	TXC	T,1B0		;CHANGE TO SIGNED NUMBER
	MOVE	W1,SCIDX(TT)	;GET INDEX
	MOVE	W2,SCSYM(TT)	;AND SYMBOL NAME
	JRST	CPOPJ1		;DONE
EVAL0:	PUSHJ	P,SYMSET	;SET UP TO LOOP OVER ALL SYMBOLS
	SUBI	R,1		;SKIP FIRST MODULE NAME
EVAL1:	TXZ	F,MDLCLF!FANYSF	;NOT MULT DEFINED, HAVEN'T FOUND ANY YET

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;LOOP BACK HERE TO LOOK AT EACH NEW SYMBOL

EVAL2:	SOSGE	R		;POINT TO VALUE WORD OF NEXT SYMBOL
	PUSHJ	P,ADVSYM	;THIS POINTER USED UP, SEE IF MORE
	SKIPA	T,@SYPTR	;POINTING TO A GOOD SYMBOL, GET VALUE INTO T
	JRST	EVAL6		;ALL DONE, GO SEE IF ANYTHING TO RETURN
	SOSGE	R		;POINT TO FLAGS AND NAME FOR THIS SYMBOL
	PUSHJ	P,ADVSYM	;WENT OFF END OF SYMBOL WINDOW?
	SKIPA	W2,@SYPTR	;OK, FETCH FLAGS AND NAME
	JRST	ERR		;VALUE BUT NO SYMBOL? BAD FORMAT!
	TXZN	W2,PNAME	;PROGRAM NAME OR ZERO WORD?
	JRST	[JUMPE W2,EVAL2	;YES, IGNORE ZERO WORDS
		TXO F,PNAMEF	;REMEMBER NO LONGER SEARCHING $:'D MODULE
		JRST EVAL2]	;GET NEXT SYMBOL
	CAME	W2,SYM		;SYMBOL NAME MATCH WHAT WE'RE LOOKING FOR?
	JRST	EVAL2		;NO, GET NEXT NAME

;HERE ON A MATCH.  SEE IF WE SHOULD IGNORE IT, REMEMBER IT, OR RETURN IT.

	MOVE	W2,@SYPTR	;FETCH FLAGS AGAIN
	TXNE	W2,DELI		;SYMBOL DELETED FOR INPUT?
	JRST	EVAL2		;YES, IGNORE IT
	TXNN	W2,GLOBL	;A GLOBAL SYMBOL?
	TXNN	F,PNAMEF	;OR A LOCAL IN THE $:'D MODULE?
	JRST	EVAL8		;YES, STOP SEARCH AND RETURN IT TO CALLER
	TXOE	F,FANYSF	;NEED TO REMEMBER FOR LATER, FIRST TIME?
	CAMN	T,EVVAL		;OR SAME VALUE AS BEFORE?
	JRST	EVAL4		;YES, ALL OK.  REMEMBER NEW SYMBOL
	TXO	F,MDLCLF	;MULTIPLE MATCHES WITH DIFFERENT VALUES
	JRST	EVAL2		;BUT KEEP LOOKING IN CASE WE FIND A GLOBAL
;HERE ON A MATCH WITH AN OUTSIDE LOCAL.  REMEMBER IT, THEN KEEP LOOKING.

EVAL4:	MOVEM	W2,EVFLG	;REMEMBER FLAGS
	MOVEM	T,EVVAL		;REMEMBER VALUE
	ADD	R,R2IDX		;CONVERT R TO SYMBOL INDEX
	MOVEM	R,EVIDX		;SAVE SYMBOL INDEX OF TENTATIVE MATCH
	SUB	R,R2IDX		;PUT R BACK AS IT WAS
	JRST	EVAL2		;KEEP LOOKING IN CASE WE FIND A GLOBAL


;HERE WHEN THE SEARCH IS ALL FINISHED.  WE DIDN'T FIND A GLOBAL OR A
;LOCAL IN THE OPEN MODULE, SO SEE IF WE FOUND SOMETHING USEFUL ELSEWHERE.

EVAL6:	TXNN	F,FANYSF	;FIND ANYTHING?
	POPJ	P,		;NO, JUST GIVE AN ERROR
	TXNE	F,MDLCLF	;WAS WHAT WE FOUND UNIQUE?
	JRST	MULDEF		;NO, GO GIVE "M" ERROR
	MOVE	W1,EVIDX	;YES, SET IT UP IN RETURN ACS
	MOVE	W2,EVFLG	; . . .
	MOVE	T,EVVAL		; . . .
	JRST	CPOPJ1		;RETURN OUTSIDE LOCAL TO CALLER


;HERE WHEN WE HAVE A MATCHING GLOBAL OR LOCAL IN THE OPEN MODULE.
;STOP THE SEARCH IMMEDIATELY AND RETURN THE VALUE TO THE CALLER.

EVAL8:	MOVE	W1,R2IDX	;T AND W2 SET UP, BUT NEED TO PUT INDEX IN W1
	ADD	W1,R		;CONVERT R TO SYMBOL INDEX IN W1
	JRST	CPOPJ1		;RETURN GLOBAL OR INSIDE LOCAL TO CALLER
SUBTTL	SYMBOL TABLE ROUTINES -- CONVERT VALUE TO SYMBOL

;THE SYMBOL TABLE CACHE ALGORITHMS:
;
;
;TO SPEED UP THE EXEC MODE DDTS (EXPECIALLY TOP-20 WITH HIDDEN SYMBOLS),
;A NEW SYMBOL TABLE CACHE EXISTS.  ENTRIES ARE ADDED DYNAMICALLY AS
;DDT SEARCHES FOR THE PROPER SYMBOLS FOR TYPEOUT.  SYMBOLS WHICH ARE
;TYPED INTO DDT DO NOT GET ADDED TO CACHE SINCE THAT WOULD INTRODUCE SOME
;OBSCURE BUGS IN SYMBOL TYPEOUT.  BUT THE CACHE IS SEARCHED ON TYPEIN IN
;CASE WE ARE LUCKY AND THE SYMBOL IS ALREADY THERE.  CARE MUST BE TAKEN
;THOUGH, SINCE ONLY LOCAL OR GLOBAL SYMBOLS ARE VALID FOR TYPEIN.
;
;THE CACHE REMEMBERS SYMBOL NAMES, ALONG WITH THEIR VALUE.  BUT MOST
;IMPORTANTLY, THE RANGE OF A SYMBOL IS ALSO REMEMBERED, AND THE SYMBOL
;TABLE LOOKUP CODE WILL FIND THE RANGE FOR ANY SYMBOL IT RETURNS.  THIS
;MAKES THE CACHE EXTREMELY GOOD, SINCE THOUSANDS OF VALUES MIGHT BE
;ASSOCIATED WITH A SINGLE SYMBOL NAME.  ALONG WITH THE VALUE AND RANGE,
;THE SYMBOL TABLE INDEX, THE AGE OF THE SYMBOL, AND THE "SYMBOL IS LOCAL"
;FLAG IS REMEMBERED (SO THAT SYMBOLS WILL TYPE "#" PROPERLY).  EVERY
;REFERENCE TO A SYMBOL UPDATES ITS AGE.  IF THE CACHE IS FULL, THEN
;THE OLDEST SYMBOL IS DELETED TO MAKE ROOM FOR THE NEW SYMBOL.  THE
;AGE VALUE FOR A SYMBOL IS SHIFTED LEFT 3 BITS, TO MAKE ROOM FOR THE
;"#" FLAG.  THIS DOES NOT AFFECT COMPARISONS OF THE AGES.
;
;THE RANGE OF A SYMBOL MIGHT NOT BE KNOWN TOTALLY IN ALL CASES.
;THIS CAN OCCUR DUE TO THE DELETION OF ANOTHER SYMBOL WHICH PREVIOUSLY
;RESTRICTED THE RANGE OF A SYMBOL.  OR THE SYMBOL MIGHT BE GLOBAL OR BE
;IN THE LOCAL MODULE.  IN SUCH A CASE, SINCE THE SYMBOL TABLE SEARCHING
;CODE STOPS EARLY, THE RANGE IS KNOWN ONLY TO THE VALUE SEARCHED FOR.
;IF EVER THE RANGE NEEDS EXTENDING, THE CACHE LOGIC WILL DO THIS.
;
;NOTICE THAT THE SYMBOL CACHE WILL ONLY CONTAIN A SINGLE ENTRY FOR
;ANY PARTICULAR VALUE, BUT CAN CONTAIN MULTIPLE ENTRIES FOR A PARTICULAR
;SYMBOL NAME.  THIS IS BECAUSE A NON-LOCAL SYMBOL MAY BE DEFINED TO HAVE
;DIFFERENT VALUES IN TWO SEPARATE MODULES, AND YET EACH SYMBOL IS THE
;BEST ONE TO USE FOR SOME RANGE OF NUMBERS.
;THE VALUE OF A SYMBOL STORED IN THE CACHE IS IN UNSIGNED FORMAT.  THIS
;MEANS THAT BIT ZERO IS COMPLEMENTED.  THE PURPOSE OF THIS IS SO THAT
;A SYMBOL RANGE WHICH CROSSES THE 0 AND 400000000000 BOUNDARIES WORKS
;PROPERLY.  COMPLEMENTING THE SIGN BIT ORDERS ALL VALUES SO THAT ZERO
;IS LOWEST, UP THROUGH 377777,,-1, TO 400000,,0 AND UP TO -1,,-1.
;THIS IS THE PREFERED ORDER, SINCE THEN ZERO WILL NEVER BE FOO+N, AND
;A VALUE OF 400000,,0 WILL PROPERLY TYPE OUT AS FOO+N.
;
;ENTRIES IN THE CACHE HAVE TO BE DELETED AT THE PROPER TIME.  WHENEVER
;A SYMBOL IS REDEFINED, THE CACHE HAS TO BE CLEARED OF BOTH THE SYMBOL
;NAME, AND ALSO OF THE NEW VALUE.  OTHERWISE, WRONG TYPEOUT WILL RESULT.
;THIS HAPPENS EXPLICITLY FOR A SYMBOL WHEN YOU GO SYMBOL:, OR IMPLICITLY
;WHEN YOU USE THE PATCHING FEATURE.  THE CACHE HAS TO BE CLEARED TOTALLY
;WHENEVER THE PROGRAM MODULE IS CHANGED, SINCE ALL NON-EXACT SYMBOLS CAN
;NOW BE WRONG.  THIS FEATURE CAN BE USED TO CLEAR THE CACHE AT ANY TIME,
;IN CASE YOU THINK THAT THE CACHE CONTAINS WRONG DATA.
;
;ALL OF THE SYMBOL NAMES WHICH ARE USED IN THE CACHE LOGIC HAVE THE
;FORM OF SC???.
;LOOK -- ROUTINE TO FIND A NAME FOR THE VALUE IN T.
;CALL:
;	MOVE	T,<VALUE>
;	PUSHJ	P,LOOK
;	NOTHING USEFUL FOUND
;	SOMETHING, BUT NO EXACT MATCH
;	EXACT MATCH FOUND AND TYPED
;
;
;THIS ROUTINE RETURNS THE FOLLOWING (ON WHICH RETURNS):
;
;	T	ORIGINAL VALUE		(ALL)
;	W	VALUE OF SYMBOL FOUND	(+2,+3)
;	W2	SYMBOL FOUND		(+2,+3)
;	S	DIFFERENCE, T-W		(+2)
;
;NOTE THAT THE COMPUTATIONS DONE BY THIS ROUTINE USE UNSIGNED INTEGERS,
;WHICH HAVE BIT 0 COMPLEMENTED.  THE SYMBOL VALUES STORED IN THE CACHE
;ARE OF THIS FORMAT ALSO.

LOOK:	TXC	T,1B0		;CONVERT TO UNSIGNED FORMAT
	TXZ	F,MDLCLF	;INITIALIZE FLAG
	HRLOI	W1,377777	;SET UP INFINITE AGE
	HRLZ	TT,SCNUM	;GET NUMBER OF SYMBOLS NOW IN CACHE
	JUMPE	TT,CSHEMP	;SKIP SOME IF CACHE IS EMPTY
	MOVN	TT,TT		;CONVERT TO AN AOBJN POINTER

SRCCSH:	CAMG	W1,SCAGE(TT)	;THIS ENTRY OLDER THAN PREVIOUS ONES?
	JRST	SRCCH1		;NO
	MOVE	W1,SCAGE(TT)	;YES, REMEMBER ITS AGE
	HRRZ	W2,TT		;AND THE INDEX OF IT
SRCCH1:	CAML	T,SCVAL(TT)	;VALUE LESS THAN THIS SYMBOL?
	CAMLE	T,SCMAX(TT)	;OR GREATER THAN MAXIMUM VALUE FOR SYMBOL?
	AOBJN	TT,SRCCSH	;YES, LOOK AT NEXT SYMBOL IN CACHE
	JUMPL	TT,[MOVE TT1,SCAGE(TT)	;IF FOUND SYMBOL, GET FLAGS
		TRNE 	TT1,1		;SEE IF SHOULD HAVE # AFTER IT
		TXO	F,MDLCLF	;YES, REMEMBER THAT
		JRST	LOOKDN]		;PROCEED
	CAIL	TT,SCSIZ	;IS THE CACHE FILLED UP?
	MOVE	TT,W2		;YES, THEN WE'LL REPLACE THE OLDEST SYMBOL
CSHEMP:	MOVEM	TT,SCTMP	;REMEMBER INDEX WE MIGHT REPLACE
	PUSHJ	P,LOKSYM	;SEARCH SYMBOL TABLE FOR A SYMBOL
	MOVE	S,W2		;MOVE FOUND SYMBOL TO RIGHT AC
	SETZ	TT,		;INITIALIZE FOR LOOP
CSHEM1:	PUSHJ	P,LOKCSH	;SEE IF HAVE THE SYMBOL IN THE CACHE
	 JRST	NEWSCH		;NO, HAVE TO INSERT IT
	CAME	W,SCVAL(TT)	;FOUND THE RIGHT ENTRY FOR THIS SYMBOL?
	JRST	CSHEM1		;NO, LOOK SOME MORE
	CAMLE	R,SCMAX(TT)	;YES, SEE IF MAXIMUM CAN BE RAISED
	MOVEM	R,SCMAX(TT)	;YES, RAISE IT
	JRST	LOOKDN		;GO FINISH UP
NEWSCH:	TXZ	W2,74B5		;CLEAR SYMBOL FLAGS
	MOVE	TT,SCTMP	;GET BACK INDEX TO USE IN CACHE
	MOVEM	W2,SCSYM(TT)	;REMEMBER THE SYMBOL NAME
	MOVEM	W1,SCIDX(TT)	;REMEMBER ITS INDEX
	MOVEM	W,SCVAL(TT)	;AND ITS VALUE
	MOVEM	R,SCMAX(TT)	;SET MAXIMUM KNOWN VALUE FOR SYMBOL TOO
	HRRZ	TT1,TT		;GET INDEX WITHOUT JUNK IN LEFT HALF
	CAMN	TT1,SCNUM	;INSERTED A NEW ENTRY IN THE CACHE?
	AOS	SCNUM		;YES, INCREMENT SYMBOL COUNT

LOOKDN:	AOS	TT1,SCTIM	;INCREMENT AGE TIMER
	LSH	TT1,3		;MAKE ROOM FOR FLAGS
	TXNE	F,MDLCLF	;WAS THIS SYMBOL FOUND OUTSIDE LOCAL MODULE?
	IORI	TT1,1		;YES, REMEMBER THAT
	MOVEM	TT1,SCAGE(TT)	;SET NEW AGE FOR THIS SYMBOL
	MOVE	W2,SCSYM(TT)	;GET SYMBOL NAME WE FOUND
	MOVE	W1,SCIDX(TT)	;GET INDEX OF THIS SYMBOL
	MOVE	W,SCVAL(TT)	;AND THE VALUE OF THE SYMBOL
	TXC	W,1B0		;CONVERT BACK TO SIGNED NUMBERS
	TXC	T,1B0		;FROM UNSIGNED
	MOVE	S,T		;[264] COMPUTE DIFFERENCE BETWEEN VALUES
	XOR	T,W		;[264] TEMPORARILY TRASH T TO COMPARE SIGNS
	JUMPGE	T,LOOKD1	;[264] EASY CASE IF SIGNS THE SAME
	TXC	S,1B0		;[264] HARD CASE--MAKE SIGNS THE SAME
	SUB	S,W		;[264] NOW SUB IS SAFE
	TXCA	S,1B0		;[264] FIX UP THE RESULT
LOOKD1:	SUB	S,W		;[264] NORMAL SUB WORKS IF SIGNS THE SAME
	XOR	T,W		;[264] RESTORE T
	JUMPE	W2,CPOPJ	;ALWAYS IGNORE A NULL SYMBOL
	JUMPN	S,CPOPJ1	;IF NOT EXACT, GIVE SINGLE SKIP
	PUSHJ	P,PSYM0		;PRINT AND REMEMBER FOR $D
	TXNE	F,MDLCLF	;IS IT NOT AMBIGUOUS?
	TXNE	F,OKAF		;OR IS IT OK TO BE SO?
	JRST	CPOPJ2		;YES, DON'T TYPE SOMETHING
	PUSH	P,T		;SAVE T
	MOVEI	T,"#"		;FLAG POSSIBLY AMBIGUOUS
	PUSHJ	P,TOUT		;TYPE THE #
	POP	P,T		;RESTORE AC
CPOPJ2:	AOS	(P)		;DOUBLE SKIP RETURN
CPOPJ1:	AOS	(P)		;SINGLE SKIP RETURN
CPOPJ:	POPJ	P,		;RETURN
;SUBROUTINE TO SEARCH FOR A SYMBOL NAME IN THE SYMBOL CACHE.  CALL:
;
;	SETZ	TT,		;(FIRST CALL ONLY) INITIALIZE FOR LOOP
;	MOVE	S,SYMBOL	;GET SYMBOL
;	PUSHJ	P,LOKCSH	;SEARCH CACHE FOR IT
;	 (NOT FOUND RETURN)	;NOT THERE
;	(FOUND RETURN)		;FOUND IT, INDEX INTO CACHE IN TT
;
;EACH SUCCESSIVE CALL WITHOUT DESTROYING AC TT WILL RETURN THE NEXT
;OCCURANCE OF THE SPECIFIED SYMBOL IN THE CACHE.  ONLY USES AC'S S AND TT.

LOKCSH:	JUMPL	TT,LOKCS1	;GO ON IF JUST CONTINUING SEARCH
	TXZ	S,74B5		;CLEAR FLAG BITS FROM SYMBOL
	HRLZ	TT,SCNUM	;GET NUMBER OF SYMBOLS IN CACHE
	JUMPE	TT,CPOPJ	;QUIT IF NO SYMBOLS IN CACHE
	MOVN	TT,TT		;MAKE INTO AOBJN POINTER
	CAME	S,SCSYM(TT)	;IS THIS THE SYMBOL?
LOKCS1:	AOBJN	TT,.-1		;NO, SEARCH SOME MORE
	JUMPL	TT,CPOPJ1	;SKIP RETURN IF FOUND IT
	POPJ	P,		;OTHERWISE NON-SKIP



;SUBROUTINE TO CLEAR THE SYMBOL TABLE CACHE.  CACHE IS INITIALIZED WHEN
;DDT IS ENTERED, MODULE NAME IS CHANGED, NEW SYMBOL IS DEFINED, ETC.
;NO AC'S ARE USED.  TO MAKE DEBUGGING FASTER, EXEC-MODE DDTS WILL NOT
;CLEAR THE CACHE WHENEVER CONTROL RETURNS TO DDT (SUCH AS A BREAKPOINT).
;LOCATION .CLCSH CAN BE PATCHED TO DO SO IF THE PROBLEM CHANGES THE
;SYMBOL TABLE, AND THE CACHE CODE HAS TO BE "RIGHT".  SIMILARLY, IF THE
;SYMBOL TABLE ISN'T BEING MESSED UP IN USER MODE, .CLCSH CAN BE PATCHED
;TO MAKE DEBUGGING FASTER THERE TOO.

.CLCSH:	IFN	FTEXEC!FTMON!FTEX20,<POPJ P,>	;HERE FOR EXEC DDTS
	IFE	FTEXEC!FTMON!FTEX20,<JFCL>	;ALL OTHER DDTS

CLRCSH:	SETZM	SCNUM		;CLEAR NUMBER OF SYMBOLS IN CACHE
	SETZM	SCTIM		;RESET AGE TIMER
	POPJ	P,		;DONE
;SUBROUTINES TO FIND AN ENTRY IN THE CACHE AND REMOVE IT.  CALL
;DELCSH WITH SYMBOL NAME IN S, OR CALL DELCSV WITH THE VALUE OF
;A SYMBOL (NORMAL FORMAT) IN S.

DELCSV:	HRLZ	TT,SCNUM	;GET NUMBER OF SYMBOLS
	JUMPE	TT,CPOPJ	;IF NONE, DONE
	MOVN	TT,TT		;MAKE AN AOBJN POINTER
	TXC	S,1B0		;TURN INTO UNSIGNED FORMAT FOR COMPARES
	CAML	S,SCVAL(TT)	;THIS SYMBOL VALUE TOO SMALL?
	CAMLE	S,SCMAX(TT)	;OR TOO LARGE?
	AOBJN	TT,.-2		;YES, TRY NEXT ENTRY
	JUMPL	TT,CSHREM	;JUMP IF FOUND SYMBOL TO DELETE
	POPJ	P,		;NOT FOUND, DONE

DELCSH:	SETZ	TT,		;BEGIN AT THE BEGINNING
	PUSHJ	P,LOKCSH	;FIND THE SYMBOL IN THE CACHE
	 POPJ	P,		;NOT THERE, SO ALL DONE
	PUSHJ	P,CSHREM	;REMOVE THE ENTRY
	JRST	DELCSH		;LOOK FOR ANOTHER OCCURANCE

CSHREM:	SOS	TT1,SCNUM	;DECREMENT NUMBER OF ENTRIES IN CACHE
	MOVE	TT2,SCSYM(TT1)	;GET SYMBOL AT END
	MOVEM	TT2,SCSYM(TT)	;WRITE OVER DELETED SYMBOL
	MOVE	TT2,SCIDX(TT1)	;GET INDEX
	MOVEM	TT2,SCIDX(TT)	;WRITE OVER OLD INDEX
	MOVE	TT2,SCVAL(TT1)	;GET VALUE
	MOVEM	TT2,SCVAL(TT)	;WRITE OVER VALUE
	MOVE	TT2,SCMAX(TT1)	;GET MAXIMUM VALUE
	MOVEM	TT2,SCMAX(TT)	;REPLACE IT TOO
	MOVE	TT2,SCAGE(TT1)	;FINALLY GET AGE
	MOVEM	TT2,SCAGE(TT)	;REPLACE IT
	POPJ	P,		;DONE
	SUBTTL	NON-CACHE ROUTINE TO CONVERT A VALUE TO A SYMBOL

;THIS ROUTINE SEARCHES THE NORMAL SYMBOL TABLE FOR THE SPECIFIED VALUE,
;AND RETURNS THE APPROPRIATE SYMBOL FOR THAT VALUE.  CALL:
;
;	MOVE	T,VALUE
;	PUSHJ	P,LOKSYM
;	(RETURN)
;
;WITH:	W2/	SYMBOL WHICH WAS FOUND.  ZERO IF NONE.
;	W1/	SYMBOL INDEX OF SYMBOL IN W2.
;	W/	VALUE OF THE FOUND SYMBOL.
;	R/	HIGHEST VALUE THE FOUND SYMBOL IS USEFUL FOR IN TYPEOUT.
;	T/	NOT CHANGED.
;
;ALL VALUES IN THIS ROUTINE ARE IN UNSIGNED FORMAT (BIT 0 IS COMPLEMENTED).

LOKSYM:	PUSH	P,T		;SAVE SOUGHT VALUE OVER SYMSET
	HRLOI	T,377777	;GET INFINITY AS A BOUND
	MOVEM	T,LKMAX		;INITIALIZE VALUE SYMBOL IS GOOD FOR
	PUSHJ	P,SYMSET	;SET UP TO LOOP OVER ALL SYMBOLS
	POP	P,T		;RESTORE T
	SUBI	R,1		;SKIP FIRST MODULE NAME
	TXZ	F,FANYSF	;HAVEN'T FOUND ANYTHING YET

;LOOP BACK HERE TO LOOK AT EACH NEW SYMBOL.

LOOK2:	SOSGE	R		;ANY MORE SYMBOLS TO LOOK AT?
	PUSHJ	P,ADVSYM	;MAYBE NOT, GO SEE
	SKIPA	W,@SYPTR	;GOT ANOTHER ONE, GET ITS VALUE INTO W
	JRST	LOOK10		;ALL DONE, GO SEE IF ANYTHING TO RETURN
	TXC	W,1B0		;CONVERT TO UNSIGNED FORMAT
	SOSGE	R		;BACK UP TO NAME WORD
	PUSHJ	P,ADVSYM	;HAPPENS ONLY IF WINDOWING
	SKIPA	W2,@SYPTR	;FETCH THE NAME
	JRST	ERR		;NO NAME?? BAD FORMAT!
	TXNN	W2,PNAME	;IS THIS A PROG NAME OR ZERO WORD?
	JRST	[JUMPE W2,LOOK2	;IGNORE ZERO WORDS
		TXO F,PNAMEF	;REMEMBER NO LONGER IN $:'D MODULE
		JRST LOOK2]	;GET NEXT SYMBOL
	TXNN	W2,DELI!DELO	;IS SYMBOL DELETED?
	TXNN	W2,-1-PNAME	;OR IS IT BLANK?
	JRST	LOOK2		;YES, DON'T CONSIDER IT
	CAMLE	W,T		;ONLY CONSIDER SYMS .LE. WHAT WE'RE LOOKING FOR
	SOJA	W,[CAMGE W,LKMAX	;VALUE OF SYMBOL LESS THAN OLD MAX?
		MOVEM	W,LKMAX		;YES, REDUCE VALIDITY OF SYMBOL
		JRST	LOOK2]		;CONTINUE LOOKING
	TXNN	W2,GLOBL	;IS THIS A GLOBAL SYMBOL?
	TXNN	F,PNAMEF	;OR A LOCAL IN THE OPEN MODULE?
	JRST	LOOK4		;YES, SEE IF WE CAN RETURN IT IMMEDIATELY
	CAMGE	T,[400000,,000020]	;IN AC RANGE?
	JRST	LOOK2		;YES, IGNORE OUTSIDE LOCALS
	TXO	F,OLF		;REMEMBER LAST SYMBOL SAVED WAS OUTSIDE LOCAL
	JRST	LOOK6		;SAVE THE SYMBOL IN CASE BEST EVER FOUND
;HERE WHEN A GLOBAL OR INSIDE LOCAL IS CLOSE ENOUGH.  IF IT MATCHES EXACTLY,
;THEN STOP THE SEARCH AND RETURN IT IMMEDIATELY.  IF NOT, SAVE IT IN CASE
;WE NEVER FIND AN EXACT MATCH, THEN CONTINUE SEARCHING.

LOOK4:	TXZ	F,OLF		;REMEMBER NOT AN OUTSIDE LOCAL
	CAME	W,T		;EXACT MATCH?
	JRST	LOOK6		;NO, JUST GO REMEMBER IT
	MOVE	W1,R2IDX	;YES, WANT TO RETURN SYMBOL INDEX IN W1
	ADD	W1,R		;FORM INDEX
	TXZ	F,MDLCLF	;REMEMBER NOT AN OUTSIDE LOCAL
	MOVE	R,T		;ONLY KNOW SYMBOL IS GOOD FOR GIVEN VALUE
	POPJ	P,		;RETURN

;HERE WHEN WE HAVE A POSSIBLE MATCH.  IF A BETTER OUTSIDE LOCAL OR A
;GLOBAL OR INSIDE LOCAL AT LEAST AS GOOD AS THE SYMBOL ALREADY SAVED
;(IF ANY), SAVE IT IN CASE IT'S THE BEST EVER FOUND.  MDLCLF IS USED
;TO REMEMBER WHETHER WHAT WE HAVE SAVED IS AN OUTSIDE LOCAL OR NOT.

LOOK6:	TXON	F,FANYSF	;IS THIS THE FIRST SYMBOL?
	JRST	LOOK8		;YES, JUST GO SQUIRREL IT AWAY
	CAMGE	W,LKVAL		;IS OUR NEW SYMBOL DEFINITELY WORSE?
	JRST	LOOK2		;YES, DON'T WASTE ANY MORE TIME
	TXNE	F,OLF		;AN OUTSIDE LOCAL?
	CAME	W,LKVAL		;YES, MUST BE BETTER TO BE SAVED, IS IT?
	JRST	LOOK8		;WE WANT TO SAVE THIS SYMBOL
	JRST	LOOK2		;DON'T SAVE THIS SYMBOL, JUST KEEP LOOKING

;HERE TO SAVE THE CURRENT SYMBOL.

LOOK8:	TXNN	F,OLF		;IS THIS SYMBOL AN OUTSIDE LOCAL?
	TXZA	F,MDLCLF	;NO, REMEMBER THAT
	TXO	F,MDLCLF	;YES, REMEMBER THAT
	MOVEM	W,LKVAL		;SAVE VALUE
	MOVEM	W2,LKFLG	;SAVE FLAGS
	ADD	R,R2IDX		;FORM SYMBOL INDEX
	MOVEM	R,LKIDX		;SAVE THAT TOO
	SUB	R,R2IDX		;AS BEFORE
	JRST	LOOK2		;RESUME THE SEARCH

;HERE WHEN WE HAVE SEARCHED THE ENTIRE SYMBOL TABLE.  RETURN THE BEST
;SYMBOL WE FOUND, IF ANY.

LOOK10:	MOVE	R,LKMAX		;GET HIGHEST VALUE THAT SYMBOL IS GOOD FOR
	TXNN	F,FANYSF	;FIND ANYTHING?
	JRST	[SETZ	W2,	;NO, CLEAR SYMBOL NAME
		MOVX	W,1B0	;AND GET VALUE OF MINUS INFINITY
		POPJ	P,]	;RETURN
	MOVE	S,T		;YES, FIGURE OUT HOW FAR OFF IT WAS
	SUB	S,LKVAL		;OFFSET INTO S
	MOVE	W,LKVAL		;PUT VALUE INTO W FOR RETURN
	MOVE	W1,LKIDX	;INDEX INTO W1
	MOVE	W2,LKFLG	;FLAGS INTO W2
	POPJ	P,		;RETURN
SUBTTL	SYMBOL TABLE ROUTINES -- HARDWARE OPCODE PROCESSING

;DESCRIPTION OF OP DECODER FOR DDT:
;
;         THE ENTIRE INSTRUCTION SET FOR THE PDP-6 CAN BE COMPACTED INTO
;A SPACE MUCH SMALLER THAN ONE REGISTER FOR EVERY SYMBOL.  THIS OCCURS
;BECAUSE OF THE MACHINE ORGANIZATION AND INSTRUCTION MNEMONICS CHOSEN
;FOR THE PDP-6.  FOR EXAMPLE, IF BITS (0-2) OF AN INSTRUCTION EQUAL
;101(2) THE INSTRUCTION IS A HALF WORD INSTRUCTION AND AN "H" MAY
;BE ASSUMED. "T" MAY BE ASSUMED FOR ALL TEST INSTRUCTIONS (WHICH
;BEGIN WITH 110(2).
;
;      THE TABLE TBL IN DDT CONSISTS OF 9 BIT BYTES, 4 TO A WORD.
;THE NUMBERS IN THE BYTES HAVE THE FOLLOWING SIGNIFICANCE:
;0-37(8):	THIS IS A DISPATCH COMMAND FOR THE OP-DECODER INTERPRETER.
;	LET THE RIGHT MOST TWO BITS EQUAL N; LET THE NEXT 3 BITS
;	EQUAL P.
;
;	THE CONTENTS OF INST (INSTRUCTION) CONTAIN IN THE RIGHT
;	MOST NINE BITS THE BINARY FOR THE MACHINE INSTRUCTION.
;	P AND N REFER TO THE CONTENTS OF INST, AND THE OP DECODER
;	WILL PRODUCE AN ANSWER D GIVEN P, N, AND THE CONTENTS
;	OF INSTX N+1 GIVES THE NUMBER OF BITS IN INST; P GIVES THE
;	POSITION (FROM THE RIGHT EDGE) OF THE N+1 BITS.
;
;	EXAMPLE: P = 6
;	         N = 2
;
;	C(INST) = .010 101 100(2)
;
;	THE RESULT = D = 010(2) = 2(8)
;
;	D IS USED AS A DISPATCH ON THE NEXT BYTES IN THE TABLE.
;	IF D = 5, 5 BYTES IN THE TABLE (DON'T COUNT THE BYTES WHICH
;	PRINT TEXT OR ARE THE EXTEND BYTE, 41-73(8))
;	ARE SKIPPED OVER AND THE 6TH BYTE RESUMES
;	THE INTERPRETATION.
;
;40(8) THIS IS A STOP CODE; WHEN THIS IS REACHED INTERPRETATION
;	IS FINISHED.
;41(8)-72(8) THE ALPHABET IS ENCODED INTO THIS RANGE.
;	41- A
;	42- B
;	72- Z
;	WHEN A BYTE IN THIS RANGE IS REACHED, ITS CORRESPONDING
;	LETTER IS TYPED.
;73(8) THIS IS THE "EXTEND" BYTE. THE NEXT BYTE IN THE TABLE
;	IS A TRANSFER BYTE BUT MUST HAVE THE ADDRESS EXTENDED
;	BY <1000-74*2+FIR.> FIRST.
;
;74(8)-777(8) THIS IS A TRANSFER BYTE.  IF THE BYTE IN THIS RANGE IS
;	CONSIDERED TO BE A, TRANSFER INTERPRETATION TO THE 
;	<A-74(8)+FIR.>RD BYTE IN THE TABLE.
;
;MACROS ASSEMBLE THE TABLE TBL:
; 1.   A NUMBER FOLLOWED BY ^ ASSEMBLES A DISPATCH BYTE.  THE FIRST
;	DIGIT IS THE POSITION; THE SECOND DIGIT IS THE SIZE.
; 2.   A POINT (.) ASSEMBLES A STOP CODE.
; 3.   A NAME FOLLOWED BY A SLASH ASSEMBLES A TRANSFER TO THE
;	SYMBOLICALLY NAMED BYTE.
; 4.   A STRING OF LETTERS TERMINATED BY A SPACE, COMMA, OR POINT,
;	ASSEMBLE INTO A STRING OF BYTES, EACH BYTE BEING ONE LETTER.
;
;EXAMPLE OF BINARY TO SYMBOLIC DECODING:
;	THE MACHINE CODE FOR JRST IS 254
;		INST    0  1  0  1  0  1  1  0  0
;	THE INTERPRETER STARTS WITH THE FIRST BYTE IN THE TABLE (63^).
;	THE RESULT OF APPLYING THIS TO C(INST) GIVES 2.  SKIPPING OVER
;	2 BYTES IN THE TABLE AND INTERPRETING THE THIRD RESULTS IN
;	HAK/ BEING INTERPRETED.  AT HAK:, THERE IS A 33^.  APPLYING
;	THIS TO C(INST) RESULTS IN 5 NON PRINTING BYTES BEING SKIPPED
;	OVER:
;		1.  MV/
;			MOV PRINTING TEXT
;		2.  MO/
;		3.  ML/
;		4.  DV/
;		5.  SH/
;
;H1/ IS THE NEXT BYTE INTERPRETER.  AT H1: 03^ IS FOUND SO
;4 BYTES ARE SKIPPED OVER:
;		EXC PRINTING TEXT
;		1.  S3/
;		BL PRINTING TEXT
;		T PRINTING TEXT
;		2.  .
;		3.  AO/
;		4.  AOB/
;		THE NEXT LETTERS JRS ARE TYPED OUT.  THEN T/ IS FOUND.  AT
;T; A T IS TYPED OUT; THEN A "." IS FOUND AND EVERYTHING STOPS.
;
;		THE TABLE IS ALSO USED GOING FROM SYMBOLIC TO BINARY BUT A
;	TREE SEARCH METHOD IS USED.
;.ADR - DECLARE TAG; .TRA - TRANSFER BYTE; .TRAX - EXTENDED TRANSFER
;BYTE; .DIS - DISPATCH BYTE; .TXT - TEXT BYTES; .END - TEXT BYTES
;FOLLOWED BY STOP BYTE.

DEFINE BYT9 (A) <
	XLIST
	IRP	A,<
A>
	LIST>

	IF1,<

DEFINE .ADR (A) <
%'A== CLOC
FIR.== CLOC
DEFINE .ADR (B) <
%'B== CLOC
LASTB==CLOC+74-FIR.>>

DEFINE .TRA (A)<CLOC==CLOC+1>
DEFINE .TRAX (A)<CLOC==CLOC+2>

SYN .TRA, .DIS

DEFINE .TXT (A) <
IFNB	<A>, <IRPC A,<CLOC==CLOC+1>>>

DEFINE .END (A) <
IFNB	<A>, <IRPC A,<CLOC==CLOC+1>>
CLOC== CLOC+1>

>				;END OF IF1
	IF2,<

DEFINE .ADR (A)<IFN %'A-CLOC,<PRINTX PHASE ERR AT: %'A>>

DEFINE .TRA (A) <OUTP %'A+74-FIR.>

DEFINE .TRAX (A),<OUTP 73
	OUTP	74+<Z1==%'A-FIR.-1000+74>
IFL	Z1,<PRINTX "A" TOO SMALL FOR .TRAX>>

DEFINE .DIS (A) <OUTP A&70/2+A&7-1>

DEFINE .TXT (A) <IFNB <A>,<IRPC A,<OUTP "A"-40>>>

DEFINE .END (A) <
IFNB	<A>, <IRPC A,<OUTP "A"-40>>
OUTP 40>

DEFINE OUTP (A)<
IFGE	<A>-1000,<PRINTX OPTABLE BYTE "A" TOO BIG>
IFE	<BINC==BINC-9>-^D27,<BINR1==A>
IFE	BINC-^D18,<BINR2==A>
IFE	BINC-9,<BINR3==A>
IFE	BINC,< BYTE (9) BINR1,BINR2,BINR3,<A>
	BINC==^D36>
CLOC==CLOC+1 >
>
TBL:	.XCREF			;OPDECODER BYTE TABLE

CLOC== 0			;SET BYTE LOCATION COUNTER TO 0
BINC== ^D36			;INIT BYTES/WORD COUNTER

;**********THE ARGUMENT FOR THE FOLLOWING "BYT9" MACRO
;**************TERMINATES AT THE NEXT COMMENT WITH: **************

;NOTE UUO'S LEFT IN TOPS-20 USER DDT (FOR NOW) FOR DEBUGGING
;COMPATIBLE PROGRAMS

IFN	FTDEC20&<FTEXEC!FTMON>,<
	BYT9	<
.DIS 63,.END,.TRA FLO,.TRA HAK,.TRA ACCP,.TRA BOOLE
	.TXT H,.TRA HWT,.TXT T,.TRA ACBM>
>				;END IFN FTDEC20

IFE	FTDEC20&<FTEXEC!FTMON>,<
	BYT9	<
.DIS 63,.TRA UUO,.TRA FLO,.TRA HAK,.TRA ACCP,.TRA BOOLE
	.TXT H,.TRA HWT,.TXT T,.TRA ACBM>
>				;END IFE FTDEC20

	BYT9	<

;IO INSTRUCTIONS

.DIS 21,.TRA BD,.TXT CON,.DIS 11,.TRA OI,.TXT S,.DIS 01,.TRA Z,.TRA O
.ADR BD,.DIS 01,.TXT BLK,.TRA IO,.TXT DATA,.ADR IO,.DIS 11,.TRA I,.TRA O
	.ADR OI,.DIS 01,.TRA O,.TRA I
;UUOS

.ADR UUO,.DIS 51,.END,.TXT,.DIS 32,.TRA U40,.TRAX U50,.TRA U60
	.DIS 21,.TRAX U703,.DIS 11,.TRA USET,.DIS 01
.TXT LOOKU,.TRA P,.TXT ENTE,.TRA R,.ADR USET,.TXT USET,.DIS 01,.TRA I,.TRA O
.ADR U40,.DIS 03,.END,.TXT INI,.TRA T,.END,.END,.END,.END,.END,.TXT CALL,.TRA I
.ADR U60,.DIS 21,.TRA U603,.DIS 01,.TXT IN,.TRA BPUT,.TXT OUT
	.ADR BPUT,.DIS 11,.TXT BU,.ADR F,.END F,.TXT,.TXT PU,.TRA T
.ADR U603,.DIS 01,.TRA U6062,.TXT STAT,.DIS 11,.ADR O,.END O,.TXT,.ADR Z,.END Z,.TXT
	.ADR U6062,.DIS 11,.TXT S,.TRA U62,.TXT G,.ADR U62,.TXT ETST,.TRA S

;BYTE AND FLOATING INSTRUCTIONS

.ADR FLO,.DIS 51,.TRA BYTE,.TXT F,.DIS 32,.TXT,.TXT AD,.TRA A,.TXT SB
	.TRA A,.TXT MP,.TRA A,.TXT DV,.ADR A
.DIS 21,.TRA LMB,.TXT R,.TRA IMB,.ADR LMB,.DIS 02,.END,.TXT
	.ADR L,.END L,.TXT,.ADR M,.END M,.TXT
.ADR B,.END B,.TXT,.ADR BYTE,.DIS 32,.TRAX I100,.TRAX I110,.TRA I120,.TXT
	.DIS 03,.TXT UF,.TRA PA,.TXT DF,.TRA N
.TXT FS,.TRA C,.TXT IB,.ADR P,.END P,.TXT,.TXT I,.TRA LD
	.ADR LD,.TXT LD,.TRA B,.TXT I,.TRA DP,.ADR DP,.TXT DP,.TRA B
;FWT-FIXED POINT ARITH-MISC

.ADR HAK,.DIS 33,.TRA MV,.ADR MV,.TXT MOV,.TRA MO,.TRA ML,.TRA DV
	.TRA SH,.TRA H1,.TRA JP
.DIS 21,.TXT ADD,.TRA IMB,.TXT SU,.ADR BIMB,.TXT B,.ADR IMB,.DIS 02,.END,.TXT
	.ADR I,.END I,.TXT,.TRA M,.TRA B,.ADR MO,.DIS 22
.ADR EIMS,.TXT E,.TRA IMS,.TXT S,.TRA IMS,.TXT N,.TRA IMS,.TXT M
	.ADR IMS,.DIS 02,.END,.TXT,.TRA I,.TRA M,.ADR S,.END S,.TXT
.ADR ML,.DIS 21,.TXT I,.TRA ML1,.ADR ML1,.TXT MUL,.TRA IMB
	.ADR DV,.DIS 21,.TXT I,.TRA DV1
.ADR DV1,.TXT DI,.ADR DV2,.TXT V,.TRA IMB,.ADR H1,.DIS 03,.TXT EXC,.TRA S3,.TXT BL
	.ADR T,.END T,.TXT,.TRA AO,.ADR AO,.TXT AOBJ
.TRA AOB,.TXT JRS,.TRA T,.TXT JFC,.TRA L,.TXT XC,.TRA T,.TXT MA,.TRA P
	.ADR AOB,.DIS 01,.TRA P,.TRA N
.ADR JP,.DIS 03,.TRA PU,.ADR PU,.TXT PUSH,.TRA PUS,.TRA PO
	.ADR PO,.TXT POP,.TRA POP,.TXT JS,.ADR R,.END R,.TXT
.TXT JS,.TRA P,.TXT JS,.ADR PA,.END A,.TXT,.TXT JR,.TRA PA
	.ADR PUS,.DIS 01,.ADR J,.END J,.END,.TXT,.ADR POP
.DIS 01,.END,.TXT,.TRA J,.ADR SH,.DIS 02,.TXT A,.TRA S2,.TXT ROT,.TRA S1,.TXT L
	.ADR S2,.TXT S,.ADR S3,.TXT H,.TRA S1,.DIS 21,.TXT JFF,.TRA O,.END
	.ADR S1,.DIS 21,.END,.TXT,.ADR C,.END C,.TXT

;ARITH COMP-SKIP-JUMP

.ADR ACCP,.DIS 42,.TXT CA,.TRA CA1,.TRA SJ,.TXT A,.TRA JS,.TXT S
	.ADR JS,.TXT O,.DIS 31
.TXT J,.TRA COMP,.TXT S,.TRA COMP,.ADR CA1,.DIS 31,.TXT I,.TRA COMP,.TXT M,.TRA COMP
.ADR SJ,.DIS 31,.TXT JUM,.TRA PSJ,.TXT SKI,.ADR PSJ,.TXT P,.ADR COMP
.DIS 03,.END,.TXT,.TRA L,.ADR E,.END E,.TXT,.TXT L,.TRA E,.TRA PA,.TXT G,.TRA E
	.ADR N,.END N,.TXT,.END G,.TXT
;HALF WORDS

.ADR HWT,.DIS 51,.TRA HW1,.DIS 21,.TXT R,.TRA HW2,.TXT L,.ADR HW2,.TXT R,.TRA HW3
.ADR HW1,.DIS 21,.TXT L,.TRA HW4,.TXT R,.ADR HW4,.TXT L
	.ADR HW3,.DIS 32,.TRA IMS,.TXT Z,.TRA IMS,.TXT O,.TRA IMS,.TRA EIMS

;TEST INSTRUCTIONS

.ADR ACBM,.DIS 31,.TRA AC1,.DIS 01,.TXT D,.TRA AC2,.TXT S,.TRA AC2
	.ADR AC1,.DIS 01,.TXT R,.TRA AC2,.TXT L
.ADR AC2,.DIS 42,.TXT N,.TRA EAN,.TXT Z,.TRA EAN,.TXT C,.TRA EAN,.TXT O
	.ADR EAN,.DIS 12,.END,.TXT,.TRA E,.TRA PA,.TRA N

;BOOLEAN

.ADR BOOLE,.DIS 24,.TRA ST,.ADR AN,.TXT AND,.TRA B2,.TRA AN,.TRA ST,.TRA AN,.TRA ST
.TXT X,.ADR OR,.TXT OR,.TRA B2,.TXT I,.TRA OR,.TRA AN,.TXT EQ
	.TRA DV2,.TRA ST,.TRA OR,.TRA ST,.TRA OR,.TRA OR
.ADR ST,.TXT SET,.ADR B2,.DIS 24,.TXT Z,.TRA IMB,.TRA IMB
	.ADR CA,.TXT C,.TRA TA,.ADR TM,.TXT M,.TRA IMB
.ADR CM,.TXT C,.TRA TM,.ADR TA,.TXT A,.TRA IMB,.TRA IMB,.TRA IMB
	.ADR CB,.TXT C,.TRA BIMB,.TRA IMB,.TRA CA
.TRA CA,.TRA CM,.TRA CM,.TRA CB,.TXT O,.TRA IMB
;INSTRUCTION GROUP 120
.ADR I120,.DIS 11,.TRAX DMOV,.DIS 01,.TXT FIX,.TRAX FIX2,.DIS 21,.END EXTEND
	.TXT FLT,.ADR FIX2,.DIS 21,.END,.TRA R
.ADR DMOV,.TXT DMOV,.DIS 01,.TXT E,.TRAX EM,.TXT N
	.ADR EM,.DIS 21,.END,.TRA M

;MORE UUO'S

.ADR U50,.DIS 03,.TXT OPE,.TRA N,.TXT TT,.ADR CAL,.TXT CAL,.TRA L,.END,.END,.END
	.TXT,.TXT RENAM,.TRA E,.TXT I,.TRA N,.TXT OU,.TRA T
.ADR U703,.DIS 02,.TXT CLOS,.TRA E,.TXT RELEA,.TRA S
	.TXT MTAP,.TRA E,.TXT UGET,.TRA F

;INSTRUCTION GROUP 110 - DF ARITHMETIC
.ADR I110,.DIS 21,.TXT DF,.TRAX DF,.TXT D,.TRAX FXDP,.ADR DF,.DIS 02
	.END AD,.END SB,.TXT M,.TRA P,.END DV

;KL10 FIXED POINT DOUBLE PRECISION OPERATIONS
.ADR FXDP,.DIS 02,.END ADD,.END SUB,.END MUL,.END DIV

;OPCODES 100 TO 107 COME HERE
.ADR I100,.DIS 21,.END,.DIS 02,.END JSYS,.END ADJSP,.END,.END
;**********THIS TERMINATES THE "BYT9" MACRO ARGUMENT******
>

	IF1,< BLOCK <CLOC+3>/4>
	IF2,< IFN BINC-^D36,<BYTE (9) BINR1,BINR2,BINR3,0> >

IFNDEF	CLOC.,<CLOC.==CLOC>
IFN	CLOC.-CLOC,<PRINTX PHASE ERROR IN OPTABLE>

	.CREF			;TURN CREF BACK ON
BTAB:	POINT	9,TBL		;TABLE USED TO GET NEXT BYTE POINTER
	POINT	9,TBL,8		;FOR TRANSFER BYTE
	POINT	9,TBL,17
	POINT	9,TBL,26

OPEVAL:	MOVEI	T,0		;EVALUATE FOR AN OP CODE
	IDPB	T,CHP		;INSERT NULL IN TEXT FOR SYMBOL
	MOVEM	P,SAVPDL
	TRZA	F,OUTF
OPTYPE:	TRO	F,OUTF		;TYPE AN OPCODE SYMBOLICALLY
	LSH	T,-33
	MOVEM	T,INST		;GET OPCODE INTO RIGHT 9 BITS
	MOVE	T,[POINT 7,OPTXT]
	MOVEM	T,CHP		;FOR OPEVAL,SETUP POINTER TO INPUT TEXT
	TRZ	F,ITF		;CLEAR INSTRUCTION TYPED FLAG
	CLEARB	R,W1
	MOVE	W2,BTAB
DC1:	ILDB	T,W2		;GET NEXT BYTE IN TBL
	CAILE	T,40
	CAIL	T,74
	SOJGE	R,DC1		;SKIP OVER # BYTES = C(R)
	JUMPG	R,DC1		;SKIP OVER ALPHA TEXT (AND EXTEND BYTES) WITHOUT COUNTING
	SUBI	T,40
	JUMPE	T,DECX		;TRANSFER ON ASTOP CODE
	JUMPG	T,DC2
	DPB	T,[XWD 340500,PNTR]	;SETUP R ON A DISPATCH BYTE
	TRZ	T,-4
	AOS	T
	DPB	T,[XWD 300600,PNTR]
	TRNN	F,OUTF
	JRST	DC6		;FOR OPEVAL ONLY
	LDB	R,PNTR		;GET # BYTES TO SKIP OVER
	JRST	DC1

DC2:	HRREI	T,-33(T)	;TOTAL SUBTRACTED NOW IS 73
	JUMPL	T,DECT		;TYPE OUT A LETTER
	JUMPG	T,DC3		;XFER IF BYTE .GE. 74
	ILDB	T,W2		;BYTE IS EXTEND BYTE (73), GET NEXT
	MOVEI	T,1000-74*2+1(T)	; BYTE AND ADD IN EXTENSION (-OFFSET)
DC3:	MOVEI	W1,FIR.-1(T)	;BYTE IS AN XFER (1ST XFER IS 74)
	IDIVI	W1,4
	MOVE	W2,BTAB(W2)	;CALCULATE POINTER TO NEXT BYTE
	ADDI	W2,(W1)
	JRST	DC1
DECT:	TRNE	F,OUTF
	JRST	DC8		;TYPE OUT A LETTER
	ILDB	W1,CHP		;GET NEXT INPUT LETTER
	CAIE	W1,133(T)	;COMPARE WITH ASSUMED NEXT LETTER
	JRST	NOMAT		;DOESNT MATCH
	JRST	DC1		;MATCHES, TRY NEXT

DECX:	TRNE	F,OUTF		;STOP (CODE 40) HAS BEEN SEEN
	POPJ	P,		;IF FOR OUTPUT, RETURN
	ILDB	W1,CHP		;GET NEXT INPUT CHAR IF ANY
	JUMPE	W1,DC7		;DOES # OF CHARS MATCH
NOMAT:	POP	P,R		;NO, BACK UP AND TRY SOME MORE
	POP	P,W2
	POP	P,PNTR
	POP	P,CHP
NOMAT1:	AOS	R		;ASSUME NEXT NUMBER FOR BIN VALUE
	DPB	R,PNTR		;STUFF INTO ANSWER
	LDB	R,PNTR
	JUMPN	R,DC6AA		;IF =0, BYTE WAS TOO BIG
	CAME	P,SAVPDL
	JRST	NOMAT		;NOT AT TOP LEVEL
	POPJ	P,		;UNDEFINED, FINALLY

DC6:	MOVEI	R,0		;ASSUME 0 FOR INITIAL BINARY VALUE
	DPB	R,PNTR
DC6AA:	CAMN	P,SAVPDL
	JRST	DC6BB
	LDB	T,-2(P)		;OLD VALUE OF PNTR
	CAME	T,(P)
	JRST	NOMAT1
DC6BB:	PUSH	P,CHP
	PUSH	P,PNTR
	PUSH	P,W2
	PUSH	P,R
	JRST	DC1

DC7:	MOVE	P,SAVPDL	;RESTORE PUSH DOWN POINTER
	MOVE	T,INST
	LSH	T,33		;PUSH BINARY INTO POSITION FOR OPEVAL
	LDB	R,[POINT 3,T,8]
	TLC	T,700000
	TLCN	T,700000
	DPB	R,[POINT 10,T,12]	;ONLY DONE FOR IO INSTRUCTIONS
	JRST	CPOPJ1		;SYMBOL FOUND, SKIP RETURN

DC8:	TRO	F,ITF		;SET INSTRUCTION TYPED FLAG
	MOVEI	T,133(T)
	PUSHJ	P,TOUT		;OUTPUT A LETTER
	CLEARM	SPSAV		;SO $D WONT TRY TO DELETE OP CODES
	JRST	DC1
SUBTTL	SYMBOL TABLE ROUTINES -- FIND PROGRAM NAME

;NAMSRH -- ROUTINE TO FIND THE PROGRAM NAME IN SYM IN THE SYMBOL TABLE
;CALL:
;	<SET UP SYM>
;	PUSHJ	P,NAMSRH
;	  NOT FOUND
;	OK RETURN
;
;RETURNS THE SYMBOL INDEX TO THE 2ND WORD OF THE PROGRAM NAME PAIR IN R.
;CAN GO TO ERR IF BAD SYMBOL TABLE FORMAT.

NAMSRH:	PUSHJ	P,SYMSET	;SET UP TO LOOP OVER THE SYMBOL TABLE
	SUBI	R,1		;ACCOUNT FOR AOSGE BELOW

;BACK HERE TO LOOK AT THE NEXT MODULE NAME.

NAMSR2:	AOSGE	R		;ANY MORE SYMBOLS LEFT?
	PUSHJ	P,ADVSYM	;NO, GET MORE SYMBOLS IF ANY
	SKIPA	T,@SYPTR	;FOUND MORE SYMBOLS, GET VALUE WORD
	POPJ	P,		;NOT FOUND, RETURN
	HLRE	T,T		;NEGATIVE # WORDS IN THIS MODULE
	SOSGE	R		;BACK R UP TO NAME WORD
	PUSHJ	P,ADVSYM	;OFF END OF WINDOW?
	SKIPA	W2,@SYPTR	;GET NAME
	JRST	ERR		;VAL BUT NO NAME, BAD FORMAT!
	TXNE	W2,PNAME	;IS THIS A PROGRAM NAME?
	JRST	ERR		;NO, BAD FORMAT
	CAMN	W2,SYM		;MATCH?
	JRST	NAMSR8		;YES, RETURN IT TO CALLER
	JUMPE	T,[SETO R,	;IF 0, WAS PAT.. BEFORE LINK BUG FIXED
		SOJA R,NAMSR2]	;SO GOTO END OF SYMBOL TABLE AND TRY AGAIN
	ADD	R,T		;NO, REDUCE R BY APPROPRIATE AMOUNT
	JRST	NAMSR2		;AND TRY AGAIN

;HERE WHEN WE HAVE FOUND THE PROGRAM NAME.  CONVERT R TO SYMBOL IDX AND RETURN.

NAMSR8:	ADD	R,R2IDX		;CONVERT TO SYMBOL INDEX
	ADDI	R,1		;POINT TO THE SECOND WORD
	JRST	CPOPJ1		;RETURN
SUBTTL	SYMBOL TABLE ROUTINES -- REMOVE AN UNDEFINED SYMBOL

;REMUN -- ROUTINE TO DELETE A SYMBOL FROM THE UNDEFINED SYMBOL TABLE.
;CALL:
;	MOVE	W1,<SYMBOL INDEX OF SYMBOL TO DELETE>
;	PUSHJ	P,REMUN
;	  ERROR
;	NORMAL
;
;DESTROYS R, T, AND W1.

REMUN:	MOVX	R,1B1		;GET 1ST WORD IN THE UNDEFINED TABLE
	PUSHJ	P,FETSYM	; . . .
	  POPJ	P,		;PROPAGATE ERRORS
	MOVE	R,W1		;OVERWRITE 1ST WORD OF SYMBOL TO DELETE
	PUSHJ	P,DEPSYM	; . . .
	  POPJ	P,		;ERROR
	MOVX	R,1B1+1		;NOW GET 2ND WORD OF TABLE
	PUSHJ	P,FETSYM	; . . .
	  POPJ	P,		;ERROR
	AOS	R,W1		;OVERWRITE 2ND WORD OF SYMBOL TO DELETE
	PUSHJ	P,DSYMER	; . . .
	MOVX	T,<2,,2>	;DECREMENT COUNT OF UNDEFINED SYMBOLS
	ADDB	T,@USYMP	; . . .
	MOVEM	T,ESTUT		;KEEP ESTUT UP TO DATE FOR DEPRA
	JRST	CPOPJ1		;GIVE GOOD RETURN
SUBTTL	SYMBOL TABLE ROUTINES -- SYMSET, USYSET, AND ADVSYM

;SYMSET -- ROUTINE TO SET UP TO SEARCH THE SYMBOL TABLE.
;CALL:
;	PUSHJ	P,SYMSET
;	RETURN
;
;SETS UP R AND SYPTR TO FETCH LAST WORD OF TABLE.  ALSO SETS UP
;INTERNAL VARIABLES SO ADVSYM WILL KNOW WHAT TO DO.  HANDLES
;WINDOWING IF NEEDED.

SYMSET:
IFN FTEXEC,<
	PUSHJ	P,SYMSPC	;MAKE SURE SEARCHING DONE IN SYMBOL VAS
> ;END IFN FTEXEC

IFE FTFILE,<
	PUSHJ	P,SYMCHK	;MAKE SURE WE TRUST THE SYMBOL TABLE POINTERS
> ;END IFE FTFILE

IFN FTMON,<
	SETZM	CT2GO		;MAKE SURE IN CASE NO ST TO SEARCH
> ;END IFN FTMON

	HLRE	R,@SYMP		;GET NUMBER OF SYMBOLS IN LOWSEG TABLE
	HLRE	S,SAVHSM	;AND NUMBER IN HISEG TABLE
	ADD	R,S		;TOTAL NUMBER OF SYMBOL WORDS TO LOOK AT
	MOVNM	R,SY2GO		;SEARCH STOPS WHEN THIS WORD GOES TO ZERO
	SKIPN	SY2GO		;ANY SYMBOLS TO LOOK AT?
	SOJA	R,CPOPJ		;NO, RETURN -1 TO START
	TXO	F,HSYMF!PNAMEF	;SEARCH LOWSEG FIRST, ASSUME NO $: POINTER
	TXZ	F,USYMF		;NOT SEARCHING THE UNDEFINED TABLE
	SKIPN	R,PRGM		;IS THERE AN OPEN MODULE?
	JRST	NEWSYP		;NO, JUST SELECT THE NEXT TABLE TO LOOK AT
	TXZ	F,PNAMEF	;TELL CALLER HE IS LOOKING AT THE OPEN MODULE
	TXZN	R,1B0		;IS OPEN MODULE IN THE HIGH SEG TABLE?
	SKIPA	S,@SYMP		;NO, FETCH LOWSEG TABLE POINTER
	SKIPA	S,SAVHSM	;YES, FETCH HISEG TABLE POINTER
	TXZA	F,HSYMF		;LOSEG: REMEMBER THAT FACT
	TXO	F,HSYMF		;HISEG: REMEMBER THAT FACT
	JRST	PTRSET		;GO SEARCH S'S TABLE STARTING AT OFFSET IN R
;USYSET -- ROUTINE TO SET UP TO SEARCH THE UNDEFINED TABLE.
;CALL:
;	PUSHJ	P,USYSET
;	RETURN
;
;DOES EVERYTHING SYMSET DOES, EXCEPT FOR THE UNDEFINED SYMBOL TABLE.

USYSET:
IFN FTEXEC,<
	PUSHJ	P,SYMSPC	;MAKE SURE SEARCHING DONE IN SYMBOL VAS
> ;END IFN FTEXEC

IFE FTFILE,<
	PUSHJ	P,SYMCHK	;MAKE SURE WE TRUST THE SYMBOL TABLE POINTERS
> ;END IFE FTFILE

IFN FTMON,<
	SETZM	CT2GO		;MAKE SURE IN CASE ST EMPTY
> ;END IFN FTMON

	MOVE	S,ESTUT		;GET OUR UNDEFINED TABLE
	HLRE	R,S		;GET - COUNT OF WORDS IN IT
	SETCAB	R,SY2GO		;PUT +COUNT-1 INTO R AND SY2GO
	AOSG	SY2GO		;WANT FULL COUNT IN SY2GO
	POPJ	P,		;RETURN NOW IF NOTHING TO LOOK AT
	TXO	F,USYMF		;REMEMBER LOOKING AT THE UNDEFINED TABLE
	TXZ	F,HSYMF		;AND NOT AT THE HISEG TABLE
	JRST	PTRSET		;SET THIS POINTER UP FOR ADVSYM
;ADVSYM -- ROUTINE TO ADVANCE TO NEXT BLOCK OF SYMBOLS TO BE SEARCHED
;CALL:
;	MOVEI	R,-<COUNT OF WORDS TO BACK UP>
;	PUSHJ	P,ADVSYM
;	MORE SYMBOLS TO LOOK AT, R UPDATED
;	ALL DONE
;
;R WILL NORMALLY CONTAIN -1 ON THE CALL TO FETCH THE NEXT (PREVIOUS) WORD.
;IF R IS SMALLER THAN -1, THE CALLER WANTS TO SKIP BACKWARDS, AS WHEN
;SEARCHING FOR A MODULE NAME.
;
;MAY GET MORE SYMBOLS BY ADVANCING A SYMBOL WINDOW (IF WINDOWING), OR
;BY ADVANCING TO THE NEXT OF SEVERAL SYMBOL TABLES TO BE SEARCHED.

ADVSYM:	AOJG	R,ERR		;ERROR IF + OR 0, CONVERT TO COUNT

IFN FTMON,<
	SKIPG	CT2GO		;WINDOWING?
	JRST	ADVSY4		;NO OR DONE.  SEE IF ANOTHER TABLE.
	ADDM	R,CT2GO		;DECREMENT WORDS TO LOOK AT IN THIS TABLE
	SKIPG	CT2GO		;THIS TABLE FINISHED YET?
	JRST	ADVSY2		;YES, SEE IF ANOTHER ONE
	ADD	R,R2IDX		;GET SYMBOL INDEX OF NEXT WORD TO LOOK AT
	SOJA	R,SYWADV	;ADJUST FOR AOJG AND GO MAP IT IN

ADVSY2:	MOVE	R,CT2GO		;CT2GO WENT - OR 0, ADJUST SY2GO INSTEAD
ADVSY4:
> ;END IFN FTMON

	ADDM	R,SY2GO		;DECREMENT SY2GO SINCE WE'RE SKIPPING SYMBOLS
	SKIPG	SY2GO		;ANY SYMBOLS LEFT TO LOOK AT?
	JRST	CPOPJ1		;NO, GIVE ALL DONE RETURN

;FALL INTO NEWSYP
;FALL IN FROM ABOVE

;NEWSYP -- ROUTINE TO SELECT THE NEXT SYMBOL TABLE (& POINTER) TO SEARCH
;CALL:
;	MOVX	R,-<COUNT OF SYMBOLS TO SKIP>
;	PUSHJ	P,NEWSYP
;	RETURN
;
;ON RETURN, A NEW SYMBOL TABLE HAS BEEN SELECTED, AND R AND SYPTR HAVE BEEN
;SETUP TO SEARCH IT.  ALSO SETS UP VARIOUS INTERNAL CELLS SO THAT THE NEXT
;CALL TO ADVSYM WILL KNOW WHAT TO DO.

NEWSYP:	TXNN	F,HSYMF		;WHICH TABLE DID WE SEARCH LAST?
	SKIPL	SAVHSM		;LOWSEG -- IS THERE A HISEG TABLE TO SEARCH?
	SKIPL	S,@SYMP		;HISEG LAST OR NO HISEG TABLE, HOW ABOUT LOWSEG?
	SKIPA	S,SAVHSM	;HISEG'S TURN OR NO LOWSEG TABLE, GET .JBHSM
	TXZA	F,HSYMF		;GOING TO SEARCH LOWSEG TABLE: REMEMBER IT
	TXO	F,HSYMF		;GOING TO SEARCH HISEG TABLE: REMEMBER IT
	HLRE	TT1,S		;WANT TO COMPUTE OFFSET TO LAST WORD IN TABLE
	SUB	R,TT1		;GET COUNT TO WORD TO LOOK AT
	JUMPLE	R,NEWSYP	;LOOP IF WE SHOULD SKIP THIS ENTIRE TABLE
	SOJA	R,PTRSET	;FORM OFFSET TO LAST WORD, AND GO SETUP
;PTRSET -- ROUTINE TO SETUP TO SEARCH A NEW SYMBOL TABLE
;CALL:
;	MOVE	S,<POINTER TO TABLE TO SEARCH>
;	MOVE	R,<OFFSET FROM START OF TABLE OF WORD TO LOOK AT FIRST>
;	PUSHJ	P,PTRSET
;	RETURN
;
;ON RETURN, R AND SYPTR ARE SET UP, THE SYMBOL WINDOW HAS BEEN SET
;IF NEEDED, AND THE VARIABLES THAT ADVSYM LOOKS AT HAVE BEEN SET UP.

PTRSET:
IFN FTMON,<
	SKIPN	HSBLK		;ANY SYMBOL WINDOWING GOING ON?
	JRST	PTRSE2		;NO, DON'T SET UP CT2GO
	MOVEM	R,CT2GO		;ASSUME WILL LOOK AT ENTIRE TABLE
	AOS	CT2GO		;R IS AN OFFSET, NOT A COUNT
	SKIPA	TT1,SYWIN	;INTERNAL FETCHES ARE FROM THE WINDOW
PTRSE2:
> ;END IFN FTMON

	HRRZ	TT1,S		;IF NOT WINDOWING, POINT AT TABLE ITSELF

IFE FTMON,<
	HLL	TT1,SECDDT	;IN DDT'S SECTION
> ;END IFE FTMON

	SKPNS0			;IN SECTION 0?
	TXOA	TT1,<Z (R)>	;NO, CONVERT TO SYPTR WITH IFIW INDEX
	TXO	TT1,<BYTE(2)0(4)R> ;YES, USE EFIW INDEX FOR SYPTR
	MOVEM	TT1,SYPTR	;STORE FOR CALLERS
	MOVN	TT1,R		;DECREMENT SY2GO BY NUMBER OF SYMBOLS
	ADDM	TT1,SY2GO	;  THAT WE PLAN TO LOOK AT
	SOS	TT1,SY2GO	;R IS AN OFFSET, NOT A COUNT

;FALL THROUGH TO NEXT PAGE
;FALL IN FROM ABOVE

IFN FTMON,<
	SKIPN	HSBLK		;WINDOWING?
	JRST	PTRSE6		;NO, TREAT LIKE NOT MDDT
	SKIPGE	TT1		;DID WE OVERFLOW SY2GO?
	ADDM	TT1,CT2GO	;YES, THERE ARE FEWER WORDS IN CURRENT TABLE TOO
	TXNE	F,HSYMF		;CONVERT R INTO A SYMBOL INDEX
	TXO	R,1B0		;  BY BRUTE FORCE
	TXNE	F,USYMF		; . . .
	TXO	R,1B1		; . . .
	PJRST	SYWADV		;GO SETUP R2IDX, MAP IN A WINDOW, ETC.
PTRSE6:
> ;END IFN FTMON

	TXNN	F,HSYMF		;LOOKING AT HISEG TABLE?
	TDZA	TT2,TT2		;NO, R2IDX IS ZERO
	MOVX	TT2,1B0		;YES, R2IDX IS 1B0
	TXNE	F,USYMF		;REALLY UNDEFINED TABLE?
	MOVX	TT2,1B1		;YES, R2IDX IS 1B1 INSTEAD
	MOVEM	TT2,R2IDX	;SET UP FOR CALLERS
	JUMPGE	TT1,CPOPJ	;DONE IF DIDN'T OVERFLOW SY2GO
	ADD	R,TT1		;IF WE DID, THERE ARE FEW WORDS TO FETCH
	MOVN	TT1,TT1		;NEED TO BUMP SYPTR
	ADDM	TT1,SYPTR	;SO FIXING R WON'T CHANGE WHICH WORDS WE GET
	ADDM	TT1,R2IDX	;ADJUST SO SYMBOL INDEX WON'T CHANGE
	POPJ	P,		;ALL DONE
IFN FTMON,<

;SYWADV -- ROUTINE TO ADVANCE TO A NEW WINDOW AND MAP IN THE SYMBOLS
;CALL:
;	MOVEI	R,<SYMBOL INDEX OF LAST WORD TO MAP IN>
;	<PUT # WORDS TO LOOK AT IN CT2GO>
;	PUSHJ	P,SYWADV
;	RETURN
;
;ON RETURN, R IS SET UP TO BE USED BY CALLERS OF SYMSET (AS @SYPTR), AND
;R2IDX CONTAINS THE NUMBER TO ADD TO R TO FORM A SYMBOL INDEX.
;
;CT2GO HAS ALSO BEEN DECREMENTED, AND THE SYMBOLS HAVE BEEN MAPPED IN.

SYWADV:	SETZ	TT,		;INDICATE READ ONLY TO SYWSET
	PUSHJ	P,SYWSET	;MAP SYMBOL INDEX IN R INTO THE WINDOW
	MOVE	S,R		;SAVE A PERMANANT COPY
	ANDX	R,77B5		;POINT TO THE 0'TH WORD IN THIS TABLE
	PUSHJ	P,R2ADDR	;FIND BASE OF TABLE
	MOVE	TT1,R		;SCRATCH COPY
	ANDCMI	TT1,SYWMSK	;BASE OF TABLE ROUNDED DOWN TO WINDOW BOUND
	SUBB	R,TT1		;PUT # WORDS OFF OF ALIGNMENT IN BOTH ACS
	ADDB	R,S		;SYMBOL INDEX IF TABLE HAD BEEN ALIGNED
	ANDI	R,SYWMSK	;OFFSET FROM SYPTR IN LAST WINDOW
	ANDCMI	S,SYWMSK	;SAVE REST OF WINDOWS FOR NEXT TIME
	SUB	S,TT1		;REMEMBER TABLE WASN'T REALLY ALIGNED
	MOVEM	S,R2IDX		;SAVE FOR COMPUTATION OF SYMBOL INDEX
	MOVN	TT1,R		;NOW TO DECREMENT CT2GO
	ADDM	TT1,CT2GO	;DOWN IT GOES
	SOS	TT1,CT2GO	;R IS AN OFFSET, NOT A COUNT
	JUMPGE	TT1,CPOPJ	;DONE IF CT2GO DIDN'T OVERFLOW
	ADD	R,TT1		;IT DID, SO LOOK AT LESS SYMBOLS
	MOVN	TT1,TT1		;NEED TO INCREMENT SYPTR
	ADDM	TT1,SYPTR	;SO DECREMENTING R WON'T CHANGE WORDS FETCHED
	ADDM	TT1,R2IDX	;ANOTHER FUDGE FOR ADJUSTING R
	POPJ	P,		;DONE

> ;END IFN FTMON
SUBTTL	MEMORY MANAGEMENT ROUTINES -- FETCH

;FETCH FROM MEMORY SUBROUTINE

;HFETCH GETS A WORD FROM THE HISEG GIVEN AN OFFSET INTO THE SEGMENT
;CALL WITH:
;	R = HISEG OFFSET
;	PUSHJ P,HFETCH
;	  NO HISEG RETURN
;	HERE WITH WORD IN T
;

HFETCH:
IFN	FTEXEC,<
	SKPUSR			;NO HISEG SYMBOLS IN EXEC MODE
	POPJ	P,0>		; . . .
	PUSHJ	P,GETHSO	;GET START OF HISEG
	JUMPE	T,CPOPJ		;EXIT IF NONE
	ADD	R,T		;RELOCATE
	PJRST	FETCH		;NOW JUST USE FETCH
;FETCH   --  GENERAL FETCH FROM MEMORY ROUTINE
;FETSYM  --  FETCH FROM SYMBOL VIRTUAL ADDRESS SPACE
;FETCHL  --  VIRTUAL FETCH FROM CURRENT "LOCAL" SECTION
;FETCHP  --  FETCH FROM PHYSICAL ADDRESS (NO MAPPING, ETC.)
;FETCHV  --  FETCH FROM USER VIRTUAL ADDRESSING SPACE
;CALL IS:
;
;	MOVX	R,<ADR>
;	PUSHJ	P,FETCH
;	 ERROR
;	NORMAL RETURN
;
;WHERE <ADR> IS THE ADDRESS IN THE "USER" ADDRESS SPACE WHOSE CON-
;TENTS ARE DESIRED.
;
;THE ERROR RETURN IS TAKEN IF THE ADDRESSED WORD IS INACCESSIBLE
;FOR SOME REASON.  THE ERROR RETURN IS ALSO TAKEN IF THE PAGE DOES
;NOT EXIST, SINCE THE "?" PRINTED GIVES MORE INFO THAN THE 0 THAT
;WOULD BE PRINTED IF WE TOUCHED A NON-EXISTENT PAGE AND CREATED IT.
;IT ALSO DISTURBS OUR ENVIRONMENT LESS.
;
;THE NORMAL RETURN IS TAKEN WITH THE CONTENTS OF <ADR> IN AC T.
;
;R IS PRESERVED, TT1 AND TT2 DESTROYED.

IFE	FTFILE,<
FETSYM:	PUSHJ	P,SAVR		;SAVE R FOR CALLER

IFN FTMON,<
	SKIPN	HSBLK		;WINDOWING?
	JRST	FETSY2		;NO, DON'T DO ANY OF THIS
	SETZ	TT,		;INDICATE READ ONLY
	PUSHJ	P,SYWSET	;PUT SYMBOL INTO OUR WINDOW
	PUSHJ	P,R2ADDR	;CONVERT R TO AN ADDRESS
	ANDI	R,SYWMSK	;GET OFFSET FROM BEGINNING OF WINDOW
	IOR	R,SYWIN		;POINT INTO SYMBOL WINDOW AREA
	JRST	FETCHS		;GO DO THE FETCH
FETSY2:
> ;END IFN FTMON

IFN FTEXEC,<
	PUSHJ	P,SYMSPC	;PUT OURSELF IN THE SYMBOL SPACE
> ;END IFN FTEXEC

	PUSHJ	P,R2ADDR	;CONVERT R TO ADDRESS TO USE
	JRST	FETCHS		;JOIN COMMON CODE BELOW

> ;END OF IFE FTFILE
;HERE FOR A GENERAL USER FETCH, AS IN RESPONSE TO <LOCATION>/

FETCH:	CAIL	R,0		;ADDRESS MUST BE .GE. 0
	CAMLE	R,UPROT		;AND .LE. PROTECTION ADDRESS
	 POPJ	P,		;NO, FAIL IMMEDIATELY
	PUSHJ	P,SAVR		;PRESERVE VIRTUAL ADDRESS FOR CALLER
	ADD	R,UBASE		;RELOCATE PER USER REQUEST
	JSP	TT1,FETFAC	;POSSIBLY FETCH FROM FAKE AC
	PUSHJ	P,MAPADR	;DO ANY MAPPING NECESSARY
	 POPJ	P,		;ACCESS FAILURE
	SKIPN	MAPFN		;PHYSICAL OR VIRTUAL FETCHING NEEDED?
	JRST	FETCH6		;ORDINARY VIRTUAL FETCH
	JRST	FETCH3		;PHYSICAL FETCH
;FIRST, USER AND EXEC DDT STYLE HANDLING

IFE	FTFILE,<

;HERE TO FETCH A WORD FROM "PHYSICAL" MEMORY SPACE

IFN	FTEXEC,<		;ONLY VALID IN EXEC DDT
FETCHP:	PUSHJ	P,SAVR		;PRESERVE R AS ADVERTISED
FETCH3:	SKPUSR			;IN EXEC MODE AT MOMENT?
	PUSHJ	P,OKPAG		;AND PAGING ON?
	JRST	FETCH5		;NO, THEN ORDINARY VIRTUAL FETCH
	MOVSI	TT2,(<MOVE T,@0>)  ;FETCH FROM MEMORY OPERATION
	PJRST	PHYIN		;DO INSTRUCTION IN PHYSICAL MEM SPACE
> ;END OF IFN FTEXEC

;HERE TO DO A VIRTUAL FETCH FROM CURRENT LOCAL SECTION

FETCHL:	PUSHJ	P,SAVR		;SAVE R AS ADVERTISED
	HLL	R,SECDDT	;GET DDT'S (SYMBOL'S) LOCAL SECTION ADDRESS
	JRST	FETCH5		;CONTINUE IN VIRTUAL FETCH

;HERE TO DO A VIRTUAL FETCH FROM "USER" ADDRESS SPACE

FETCHV:	PUSHJ	P,SAVR		;SAVE R AS ADVERTISED
FETCH5:	JSP	TT1,FETFAC	;SEE IF FAKE AC REFERENCE
FETCH6:
IFN FTEXEC,<
	PUSHJ	P,NORSPC	;MAKE SURE IN NORMAL ADDRESS SPACE
> ;END IFN FTEXEC
FETCHS:	PUSHJ	P,CHKADR	;SEE IF ACCESSIBLE ADDRESS
	TXNE	TT,PG$EXI	;DOES PAGE EXIST?
	TXNN	TT,PG$REA	;AND CAN WE READ IT?
	 POPJ	P,		;NO TO ONE OF THE ABOVE
	JSP	TT2,PCAFI	;SUPPRESS ADDRESS BREAK AND
	MOVE	T,@R		;FETCH DESIRED VIRTUAL WORD
IFN	FTDEC20,<ERJMP CPOPJ>	;RETURN FAILURE IF THIS JUST ISN'T OUR DAY
	JRST	CPOPJ1		;RETURN SUCCESSFULLY

> ;END OF IFE FTFILE
;NOW FILDDT'S HANDLING

IFN	FTFILE,<

;FETCH FROM LOCAL SECTION

FETCHL:	PUSHJ	P,SAVR		;PRESERVE R
	HLL	R,SECDDT	;DDT'S (SYMBOL'S) LOCAL SECTION ADDRESS
	JRST	FETCH5		;CONTINUE IN VIRTUAL FETCH


;"VIRTUAL" FETCH

FETCHV:	PUSHJ	P,SAVR		;SAVE R AS ADVERTISED
FETCH5:	JSP	TT1,FETFAC	;CHECK REGISTER REFERENCE
FETCH6:	SKIPN	FILING		;LOOKING AT FILE?
	JRST	MONPEK		;NO, RUNNING MONITOR/MEMORY
	PUSHJ	P,CHKADR	;SEE IF WORD ACCESSIBLE
	TXNE	TT,PG$EXI	;DOES WORD EXIST?
	TXNN	TT,PG$REA	;AND CAN IT BE READ?
	 POPJ	P,		;NO TO ONE OF ABOVE
	SETZ	T,		;IN CASE ABZ
	TXNE	TT,PG$ABZ	;ALLOCATED BUT ZERO?
	JRST	CPOPJ1		;YES, RETURN A 0 WORD

;ACCESSIBLE ADDRESS, SEE IF ALREADY IN MEMORY

	PUSHJ	P,SRHWIN	;LOOK FOR PAGE ALREADY IN MEMORY
	  CAIA			;NOT THERE, READ IT IN
	JRST	FETCH7		;FOUND IT

;NOT THERE, READ IN SELECTED FILE PAGE NUMBER

	PUSHJ	P,FREWIN	;FREE UP A WINDOW TO READ INTO
	PUSHJ	P,REDWIN	;READ INTO MEMORY WINDOW
	 POPJ	P,		;I/O ERROR OR SOMETHING
FETCH7:	MOVEI	T,PAGMSK	;MASK TO
	AND	T,R		;GET WORD INDEX INTO PAGE
	LSH	TT2,PG2WRD	;WORD ADDRESS OF BASE OF WINDOW
	ADD	T,TT2		;WORD ADDRESS OF DESIRED WORD
	ADD	T,WIND0		;RELOCATE INTO FILDDT MEMORY
	MOVE	T,(T)		;GET THE DESIRED WORD
IFN	FTDEC20,<ERJMP CPOPJ>	;CAN'T GET THE DATA
	JRST	CPOPJ1		;RETURN HAPPILY
;STILL FTFILE

IFN	FTDEC10,<
MONPEK:	SKIPE	JOBING		;JOBPEK'ING?
	JRST	JOBPEC		;YES
	PUSHJ	P,CHKADR	;VERIFY ADDRESS
	TXNE	TT,PG$EXI	;DOES PAGE EXIST?
	TXNN	TT,PG$REA	;AND CAN WE READ IT?
	 POPJ	P,		;NO TO ONE OF ABOVE
	MOVE	T,R		;ADDRESS DESIRED IN T
	SKIPE	MAPFN		;PHYSICAL OR VIRTUAL "PEEK"
	JRST	PHYPEK		;PHYSICAL
	PEEK	T,		;VIRTUAL, PEEK AT RUNNING MONITOR
	JRST	CPOPJ1		;ASSUME SUCCESS (?)

PHYPEK:	CAML	T,MAXSIZ	;IS ADDRESS IN PHYSICAL MEMORY?
	POPJ	P,		;NO, GIVE AN ERROR
	PEEK	T,UU.PHY	;EXAMINE PHYSICAL MEMORY SPACE
	JRST	CPOPJ1		;ASSUME SUCCESS . . .

JOBPEC:	MOVEI	TT,TT1		;ADDRESS OF ARGUMENT LIST
	HRLZ	TT1,JOBING	;JOB NUMBER WHOSE MEMORY IS TO BE READ
	HRRI	TT1,1		;ONLY READ ONE WORD
	HRLZ	TT2,R		;ADDRESS TO BE READ
	HRRI	TT2,T		;ADDRESS TO PUT IT IN (OURS)
	TLNN	R,-1		;BY THE WAY, ADDRESS WITHIN REASON?
	JOBPEK	TT,		;ASK MONITOR FOR OTHER JOB'S MEMORY
	 POPJ	P,		;ERROR
	JRST	CPOPJ1		;SUCCESS!! HOW ABOUT THAT!
> ;END OF IFN FTDEC10

IFN	FTDEC20,<
MONPEK:	SKIPE	MAPFN		;NEED TO PEEK AT PHYSICAL MEMORY?
	POPJ	P,		;YES, TOPS-20 PROVIDES NO WAY TO DO IT
	TLNE	R,-1		;NEED TO PEEK AT OTHER SECTIONS?
	POPJ	P,		;YES (SIGH), PEEK JSYS IS 18 BITS
	PUSHJ	P,SAVT4		;SAVE JSYS ACS
	HRRZ	T1,R		;GET ADDRS
	HRLI	T1,1
	MOVEI	T2,T		;RETURN IN T
	PEEK
	 POPJ	P,		;FAILED
	JRST	CPOPJ1		;OK
> ;END OF IFN FTDEC20
;STILL FTFILE

;SYMBOL FETCHING FOR FILDDT

FETSYM:	PUSHJ	P,SAVR		;PRESERVE FOR CALLERS
	PUSHJ	P,R2ADDR	;CONVERT TO AN ADDRESS
	CAML	R,FISBEG	;BELOW BEGINNING OF SYMS?
	CAMLE	R,FISEND	;OR BEYOND END?
	POPJ	P,		;YES, GIVE ERROR ERTURN
	MOVE	T,(R)		;FETCH VALUE
	JRST	CPOPJ1		;RETURN
> ;END OF IFN FTFILE


;PHYSICAL AND VIRTUAL FETCHES ARE IDENTICAL IN UDDT AND FILDDT.
;AC PROCESSING MAY DIFFER, BUT THAT IS CONTROLLED BY THE FAKEAC FLAG.
;FOR FILDDT, PHYSICAL ONLY PEEK IS HANDLED BY MONPEK IN EITHER CASE.

IFE	FTEXEC,<
FETCHP==FETCHV			;NON-EDDT PHYSICAL FETCH
FETCH3==FETCH6			; DITTO
> ;END OF IFE FTEXEC
SUBTTL	MEMORY MANAGEMENT ROUTINES -- DEPOSIT

DEPRS:	MOVEM	T,LWT		;DEPOSIT REGISTER AND SAVE AS LWT
	MOVE	R,LLOCO		;QUAN TYPED IN REGIS EXAM
	TXZE	F,ROF
	TXNN	F,QF
	POPJ	P,0

;FALL INTO DMEMER



;DMEMER  --  DEPOSIT INTO MEMORY, GO TO ERR IF FAILURE

DMEMER:	PUSHJ	P,DEPMEM	;TRY TO DEPOSIT INTO MEMORY
	 JRST	ERR		;CAN'T, GO DIE
	POPJ	P,		;SUCCESS, JUST RETURN



;DSYMER  --  DEPOSIT INTO SYMBOL TABLE, GO TO ERR IF FAILURE

DSYMER:	PUSHJ	P,DEPSYM	;TRY TO DEPOSIT INTO SYMBOL TABLE
	 JRST	ERR		;CAN'T, GO DIE
	POPJ	P,		;JUST RETURN
;DEPMEM  --  DEPOSIT INTO MEMORY
;DEPSYM  --  DEPOSIT INTO SYMBOL TABLE (E.G., FILDDT)
;STOREL  --  STORE INTO LOCAL SECTION
;STOREP  --  STORE INTO PHYSICAL ADDRESS
;STOREV  --  STORE INTO VIRTUAL ADDRESS
;CALL IS:
;
;	MOVX	R,<ADR> (SYMBOL INDEX IF DEPSYM)
;	MOVX	T,<WORD>
;	PUSHJ	P,DEPMEM/DEPSYM/STORE?
;	 ERROR
;	NORMAL RETURN
;
;WHERE <WORD> IS THE 36-BIT QUANTITY TO BE DEPOSITED INTO THE
;ADDRESS REFERENCED BY <ADDR> (AS APPROPRIATE TO ROUTINE CALLED)
;
;THE ERROR RETURN IS TAKEN IF THE DESIRED ADDRESS CANNOT BE
;WRITTEN INTO.
;
;THE NORMAL RETURN IS TAKEN WITH THE CONTENTS OF AC "T" WRITTEN INTO
;THE ADDRESS CONTAINED IN R.
;
;USES TT, TT1, TT2

IFE	FTFILE,<
DEPSYM:	PUSHJ	P,SAVR		;SAVE R FOR CALLER

IFN FTMON,<
	SKIPN	HSBLK		;WINDOWING?
	JRST	DEPSY2		;NO, DON'T DO ANY OF THIS
	MOVX	TT,1B0		;TELL SYWSET WE WANT TO WRITE
	PUSHJ	P,SYWSET	;SET UP WINDOW TO INCLUDE R
	PUSHJ	P,R2ADDR	;CONVERT R TO AN ADDRESS
	ANDI	R,SYWMSK	;GET OFFSET FROM BEGINNING OF WINDOW
	IOR	R,SYWIN		;POINT INTO SYMBOL WINDOW AREA
	JRST	STORES		;GO DO THE DEPOSIT
DEPSY2:
> ;END IFN FTMON

IFN FTEXEC,<
	PUSHJ	P,SYMSPC	;PUT OURSELF IN THE SYMBOL SPACE
> ;END IFN FTEXEC

	PUSHJ	P,R2ADDR	;CONVERT R TO ADDRESS TO USE
	JRST	STORES		;JOIN COMMON CODE BELOW

> ;END OF IFE FTFILE
;HERE FOR THE GENERAL DEPOSIT INTO MEMORY FUNCTION.

DEPMEM:	CAIL	R,0		;ADR MUST BE .GE. 0
	CAMLE	R,UPROT		;AND .LE. PROTECTION ADDRESS
	 POPJ	P,		;NOPE, USER LOSES
	PUSHJ	P,SAVR		;PRESERVE USER R FOR CALLER
	ADD	R,UBASE		;RELOCATE PER USER REQUEST
	JSP	TT1,STOFAC	;CHECK POSSIBLE AC REFERENCE
IFN	FTFILE,<		;FOR FILDDT
	SKIPN	PATCHS		;MUST SPECIFICALLY ENABLE FOR DEPOSITS
	JRST	DEPNPT >	;WASN'T, ERROR
	PUSHJ	P,MAPADR	;DO ANY PAGE MAPPING NEEDED
	 POPJ	P,		;ACCESS FAILURE
	SKIPN	MAPFN		;DO PHYSICAL OR VIRTUAL STORE?
	JRST	STORE6		;ORDINARY VIRTUAL STORE
	JRST	STORE3		;PHYSICAL STORE
;FIRST, USER AND EXEC DDT STYLE

IFE	FTFILE,<

;HERE TO STORE A WORD INTO A "PHYSICAL ADDRESS"

IFN	FTEXEC,<
STOREP:	PUSHJ	P,SAVR		;SAVE R AS ADVERTISED
STORE3:	SKPUSR			;CURRENTLY IN EXEC MODE?
	PUSHJ	P,OKPAG		;AND PAGING ON?
	JRST	STORE5		;NO, DO REGULAR VIRTUAL STORE
	MOVSI	TT2,(<MOVEM T,@0>)  ;DEPOSIT INTO MEMORY OPERATION
	PUSHJ	P,PHYIN		;DO IT IN PHYSICAL MEMORY
	  SOS	0(P)		;PROPAGATE ERROR RETURN
	SETZM	SYMVAL		;MIGHT CRUNCH A POINTER; DON'T TRUST SYMBOLS
	SETZM	PAGVAL		;MIGHT GET AN EPT; INVALIDATE PAGING INFO
	SETZM	PAGVAS		;INVALIDATE ALTERNATE PAGING INFO
	JRST	CPOPJ1		;GIVE GOOD RETURN
> ;END OF IFN FTEXEC


;HERE TO STORE INTO LOCAL SECTION

STOREL:	PUSHJ	P,SAVR		;PRESERVE R FOR CALLER
	HLL	R,SECDDT	;RELOCATE INTO DDT'S (SYMBOL'S) LOCAL SECTION
	JRST	STORE5		;CONTINUE IN VIRTUAL FETCH

;HERE TO DO REGULAR VIRTUAL STORE

STOREV:	PUSHJ	P,SAVR		;SAVE R AS ADVERTISED
STORE5:	JSP	TT1,STOFAC	;CHECK FOR AC REFERENCE
STORE6:	SETZM	SYMVAL		;WE NO LONGER TRUST .JBSYM ETC
IFN FTEXEC,<
	SKPEXC			;IN EXEC MODE?
	JRST	STORES		;NO, CONTINUE
	SETZM	PAGVAL		;YES, INVALIDATE PAGING PTRS
	SETZM	PAGVAS		;AND ALTERNATE PAGING POINTERS
	PUSHJ	P,NORSPC	;MAKE SURE IN NORMAL ADDRESS SPACE
> ;END OF IFN FTEXEC
STORES:	PUSHJ	P,CHKADR	;SEE ABOUT DESTINATION ADDRESS
	TXNN	TT,PG$EXI	;DOES PAGE EXIST?
	JRST	STORE8		;NO - SEE IF USER WANTS TO CREATE IT
	TXNE	TT,PG$WRT	;IS PAGE WRITEABLE (I.E., MOVEM-ABLE)?
	JRST	STORE9		;YES, GO DO MOVEM
	SKIPN	PATCHS		;YES - SHOULD WE TRY TO WRITE-ENABLE?
	POPJ	P,		;NO, ERROR RETURN

;FALL INTO NEXT PAGE
;FALL IN FROM PREVIOUS PAGE

IFN	FTEXEC,<
	SKPUSR			;IF EXEC MODE
	JRST	STORE7		;THEN DIFFERENT HANDLING
> ;END IFN FTEXEC

IFN	FTDEC10,<		;TOPS-10 WRITE ENABLE CODE
	TXNN	TT,PG$HGH	;A HIGH SEGMENT STORE?
	 POPJ	P,		;NO, THEN DEFINITELY A LOSER
	SETZ	TT1,		;YES, CLEAR HISEG WRITE PROTECT
	SETUWP	TT1,		;TELL (ASK) MONITOR
	 POPJ	P,		;USER LOSES
	PUSH	P,TT1		;SAVE WRITE BIT
	JSP	TT2,PCAFI	;SUPPRESS ADDRESS BREAK AND
	MOVEM	T,@R		;DO THE STORE
	POP	P,TT1		;RESTORE WRITE BIT
	TRNE	TT1,1		;WAS HISEG WRITE-PROTECTED?
	SETUWP	TT1,		;YES, RE-WRITE-PROTECT IT AGAIN
	 JRST	CPOPJ1		;SUCCESSFUL RETURN
	JRST	CPOPJ1		;SUCCESSFUL RETURN
> ;END OF IFN FTDEC10
;FALL IN FROM ABOVE

IFN	FTDEC20&<^-FTMON>,<	;WRITE-ENABLE CODE FOR TOPS-20
	MOVE	TT1,R		;SAVE R
	MOVE	T1,R		;GET R FOR SPACS% JSYS
	LSH	T1,WRD2PG	;CONVERT TO PAGE NUMBER
	HRLI	T1,.FHSLF	;SET ACCESS FOR THIS FORK
	ANDX	TT,PA%RD!PA%WT!PA%EX!PA%CPY	;ONLY LEAVE BITS SPACS% USES
	MOVE	T2,TT		;GET RPACS% BITS FROM CHKADR
	TXO	T2,PA%CPY	;SET COPY-ON-WRITE
	SPACS%			;CHANGE PAGE PROPERTIES
	 ERJMP	CPOPJ		;ERROR IF FAILS
	MOVE	R,TT1		;RESTORE R
	JSP	TT2,PCAFI	;SUPPRESS ADDRESS BREAK AND
	MOVEM	T,@R		;DO THE STORE
	ERJMP	[SOS (P)	;FORCE ERROR RETURN IF FAILS
		JRST .+1]	;CONTINUE TO RE-WRITE LOCK
	SETOM	LASTPG		;STORE COULD HAVE CHANGED PROPERTIES
	MOVE	T2,TT		;RESTORE BITS AS CHKADR RETURNED THEM
	SPACS%			;RESTORE PAGE ACCESS
	 ERJMP	CPOPJ1		;WE ALREADY CHANGED IT
	JRST	CPOPJ1		;GIVE GOOD RETURN
> ;END IFN FTDEC20&<^-FTMON>

IFN	FTMON,<			;MDDT'S WRITE ENABLE CODE
	MOVE	TT1,R		;PRESERVE R OVER SWPMWE
	PUSHJ	P,SAVT4		;PRESERVE JSYS ACS
	PUSHJ	P,SWPMWE##	;WRITE-ENABLE SWAPPABLE MONITOR
	SETOM	LASTPG		;ACCESS INFO NO LONGER VALID
	MOVE	R,TT1		;RESTORE R
	PUSHJ	P,CHKADR	;SEE IF THAT HELPED
	TXNN	TT,PG$WRT	;PAGE NOW WRITEABLE?
	PJRST	SWPMWP##	;NO, GIVE UP
	JSP	TT2,PCAFI	;YES, SUPPRESS ADDRESS BREAK AND
	MOVEM	T,@R		;DO THE STORE
	ERJMP	[SOS	(P)	;IF FAILS, FORCE ERROR RETURN
		JRST	.+1]	;BUT CONTINUE TO RE-WRITE PROTECT
	SETOM	LASTPG		;STORE COULD HAVE CHANGED PROPERTIES
	PUSHJ	P,SWPMWP##	;RE-WRITE PROTECT THE MONITOR
	JRST	CPOPJ1		;RETURN SUCCESS TO CALLER
> ;END IFN FTMON
;HERE TO WRITE-ENABLE AND DO THE WRITE ANYWAY

IFN	FTEXEC,<
STORE7:	SKPKI			;KA WILL NEVER GET HERE
	JRST	STOR7L		;NOT A KI EITHER
	MAP	TT1,(R)		;GET PHYSICAL PAGE NUMBER
	LSH	TT1,PG2WRD	;MAKE INTO WORD ADDRESS
	ANDI	R,PAGMSK	;WORD WITH PAGE ADDRESS
	IOR	R,TT1		;PHYSICAL WORD ADDRESS + BITS
	JRST	STOR7M		;COMMON CODE

STOR7L:	SKPKLS			;KL-10 OR KS-10?
	HALT	ERR		;NO?????
	MAP	R,(R)		;GET PHYSICAL WORD ADDRESS
STOR7M:	TLZ	R,777760	;ONLY 22-BITS OF MEMORY BUS ADDRESS
	JRST	STORE3		;TREAT AS PHYSICAL REFERENCE
> ;END IFN FTEXEC


;HERE TO TRY TO CREATE THE PAGE THAT DOESN'T EXIST

STORE8:	IFN	FTEXEC,<SKPEXC>	;NEVER NEVER TRY THIS IN EXEC MODE
	SKIPN	PATCHC		;AUTO-PAGE-CREATE ON?
	POPJ	P,		;NO, DON'T CREATE PAGE, JUST RETURN
IFN	FTDEC10,<		;CREATE PAGE FOR TOPS-10
	MOVE	TT,[.PAGCD,,TT1];PAGE CREATE FUNCTION FOR PAGE.
	MOVEI	TT1,1		;ONLY 1 ARGUMENT
	MOVE	TT2,R		;WORD ADDRESS
	LSH	TT2,WRD2PG	;DESIRED PAGE NUMBER
	SETOM	LASTPG		;FORGET ANY REMEMBERED ACCESS BITS
	PAGE.	TT,		;ASK MONITOR TO CREATE NEW PAGE FOR US
	  POPJ	P,		;NO CAN DO
> ;END OF IFN FTDEC10
IFN FTDEC20,<
	TXNN	TT,PG$WRT	;WRITEABLE?
	POPJ	P,		;NO, DON'T TRY TO CREATE THE PAGE
> ;END IFN FTDEC20

STORE9:	JSP	TT2,PCAFI	;SUPPRESS ADDRESS BREAK AND
	MOVEM	T,@R		;DO THE STORE
IFN FTDEC20,<
	ERJMP	CPOPJ		;FAIL IF DOESN'T WORK FOR SOME REASON
	SETOM	LASTPG		;STORE COULD HAVE CHANGED PROPERTIES
> ;END OF IFN FTDEC20
	JRST	CPOPJ1		;SUCCESSFUL RETURN

> ;END OF IFE FTFILE
;NOW FILDDT'S HANDLING

IFN	FTFILE,<

;STORE INTO LOCAL SECTION

STOREL:	PUSHJ	P,SAVR		;PRESERVE R
	HLL	R,SECDDT	;DDT'S (SYMBOL'S) LOCAL SECTION
	JRST	STORE5		;CONTINUE IN VIRTUAL STORE

;REGULAR USER VIRTUAL STORE

STOREV:	PUSHJ	P,SAVR		;SAVE R AS ADVERTISED
STORE5:	JSP	TT1,STOFAC	;CHECK AC REFERENCE
	SKIPN	PATCHS		;PATCHING LEGAL?
	JRST	DEPNPT		;NO, GIVE AN ERROR
STORE6:	SKIPN	FILING		;FILE I/O OR RUNNING MONITOR/MEMORY?
	JRST	MONPOK		;RUNNING MONITOR/MEMORY
	PUSHJ	P,CHKADR	;CHECK ADDRESS ACCESSIBLE
	TXNN	TT,PG$ABZ	;CAN NEVER WRITE ABZ PAGES
	TXNN	TT,PG$WRT	;CAN WE WRITE THE PAGE?
	 POPJ	P,		;NO
	TXNE	TT,PG$EXI	;DOES THE PAGE EXIST?
	JRST	STORF8		;YES, GO READ IT IN
	PUSH	P,R		;SAVE ORIGINAL R
	TRZN	R,PAGMSK	;ROUND DOWN TO START OF PAGE
	JRST	STORF3		;ALREADY THERE, DON'T BOTHER
	PUSHJ	P,CHKADR	;SEE IF THIS PAGE EXISTS AT ALL
	TXNN	TT,PG$WRT	;START OF PAGE WRITEABLE?
	JRST	[POP P,R	;NO?? RETURN ERROR
		POPJ P,]	; . . .
STORF3:	PUSH	P,T		;SAVE WORD TO DEPOSIT
	TXNE	TT,PG$EXI	;DOES START OF PAGE EXIST?
	JRST	STORF4		;YES, GO READ IT IN

;FALL THROUGH TO NEXT PAGE
;STILL FTFILE, FALL IN FROM ABOVE

;HERE WHEN THE PAGE WE'RE DEPOSITING INTO DOESN'T EXIST AT ALL.
;FREE UP A WINDOW PAGE, THEN CALL NEWWIN TO INITIALIZE IT.

	PUSHJ	P,FREWIN	;FREE UP A WINDOW
	POP	P,T		;RESTORE CORRECT ACS FOR NEWWIN
	POP	P,R		; . . .
	PUSHJ	P,NEWWIN	;SET IT UP TO POINT TO THE FILE PAGE
	 POPJ	P,		;FAILED, PROPAGATE ERROR
	JRST	STORF9		;OK, UPDATE EOF AND DO THE STORE


;HERE WHEN THE ADDRESS WE WANT DOESN'T EXIST, BUT AN EARLIER PART OF
;THE SAME PAGE DOES.  READ IN THE PART THAT EXISTS, THEN DO THE STORE.

STORF4:	PUSHJ	P,SRHWIN	;SEE IF ALREADY IN MEMORY
	 CAIA			;NO, NEED TO READ IT IN
	JRST	STORF6		;YES, JUST GO STORE INTO IT
	PUSHJ	P,FREWIN	;FREE UP A WINDOW
	PUSHJ	P,REDWIN	;READ OUR FILE PAGE INTO IT
	 JRST	[POP P,T	;ERROR, POP ACS AND RETURN
		POP P,R		; . . .
		POPJ P,]	; . . .


;HERE WHEN WE ARE CREATING A NEW FILE PAGE.  SEE IF THE END-OF-FILE
;POINTER (IN FILDDT) NEEDS TO BE UPDATED, AND DO SO IF NEEDED.

STORF6:	POP	P,T		;RESTORE DATA TO BE DEPOSITED
	POP	P,R		;RESTORE ADDRESS TO DEPOSIT INTO
	CAMGE	R,MAXSIZ	;BEYOND EOF?
	JRST	STORF9		;NO, JUST GO STORE
	MOVEM	R,MAXSIZ	;YES, UPDATE TO NEW LAST WORD
	AOS	MAXSIZ		;MAKE NUMBER OF WORDS IN FILE
	JRST	STORF9		;NOW GO DO THE STORE
;STILL FTFILE

;HERE WHEN THE WORD WE ARE DEPOSITING INTO ALREADY EXISTS.  JUST
;READ IT IN AND DO THE DEPOSIT.

STORF8:	PUSHJ	P,SRHWIN	;ALREADY IN MEMORY?
	 CAIA			;NO, NEED TO READ IT IN
	JRST	STORF9		;YES, JUST GO DEPOSIT
	PUSH	P,T		;SAVE DATA TO STORE OVER ???WIN
	PUSHJ	P,FREWIN	;FREE UP A WINDOW
	PUSHJ	P,REDWIN	;READ IN OUR PAGE
	 JRST	[POP P,T	;ERROR, RESTORE AC AND RETURN
		POPJ P,]	; . . .
	POP	P,T		;RESTORE T


;HERE WHEN A WINDOW IS SET UP, WITH T=DATA TO STORE, R=ADDRESS TO
;STORE INTO, TT2=WINDOW CONTAINING THE ADDRESS R.

STORF9:	MOVE	TT,TT2		;GET WINDOW NUMBER
	LSH	TT,PG2WRD	;CONVERT TO OFFSET INTO WINDOW AREA
	ADD	TT,WIND0	;MAKE A REAL ADDRESS
	MOVEI	TT1,PAGMSK	;WORD INDEX INTO PAGE MASK
	AND	TT1,R		;GET WORD INDEX
	ADD	TT1,TT		;POINT INTO BUFFER AREA
	MOVEM	T,(TT1)		;DO THE STORE
IFN	FTDEC20,<ERJMP CPOPJ>	;GIVE ERROR IF CAN'T DO THE STORE
	SETOM	LASTPG		;STORE COULD HAVE CHANGED PROPERTIES
	MOVX	TT1,SV$MOD	;THE PAGE MODIFIED BIT
	IORM	TT1,WINDIR(TT2)	;SET THE MODIFIED BIT
	JRST	CPOPJ1		;SUCCESSFUL RETURN
;STILL FTFILE

IFN	FTDEC10,<
MONPOK:	SKIPE	JOBING		;JOBPEK'ING?
	JRST	JOBPOK		;YES
	PUSHJ	P,CHKADR	;VERIFY ADDRESS
	TXNN	TT,PG$WRT	;CAN WE WRITE IT?
	 POPJ	P,		;NO
	PUSH	P,T		;SAVE ARGUMENT
	MOVEM	T,POKBLK+2	;SET AS NEW VALUE
	MOVEM	R,POKBLK	;NOTE--LAST TYPEOUT IS IN POKBLK+1
				;  SO THAT USER MUST KNOW WHAT
				;  HE IS CHANGING
	MOVE	T,[3,,POKBLK]	;GET POINTER
	SKIPE	MAPFN		;PHYSICAL OR VIRTUAL POKING?
	JRST	PHYPOK		;PHYSICAL
	POKE.	T,		;ORDINARY [MONITOR] VIRTUAL
	JRST	[POP	P,T	;CLEAN UP STACK ON ERROR
		POPJ	P,]	;PASS ERROR ON TO CALLER
	POP	P,T		;RESTORE VALUE
	JRST	CPOPJ1		;SKIP RETURN

PHYPOK:	POKE.	T,UU.PHY	;PHYSICAL POKE OF RUNNING MEMORY
	JRST	[POP	P,T	;RESTORE T ON ERROR
		POPJ	P,]	;PASS ERROR ON TO CALLER
	POP	P,T		;RESTORE STACK
	JRST	CPOPJ1		;RETURN SUCCESSFULLY

JOBPOK:	MOVEI	TT,TT1		;ADDRESS OF ARG LIST
	HRLZ	TT1,JOBING	;JOB WHOSE MEMORY IS TO BE WRITTEN
	IOR	TT1,[1B0+1]	;WRITE ONLY ONE WORD
	HRRZ	TT2,R		;ADDRESS TO BE WRITTEN (HIS JOB)
	HRLI	TT2,T		;ADDRESS TO WRITE FROM (OUR JOB)
	TLNN	R,-1		;BY THE WAY, ADDRESS WITHIN LIMITS?
	JOBPEK	TT,		;ASK MONITOR TO WRITE MEMORY
	 POPJ	P,		;ERROR
	JRST	CPOPJ1		;SUCCESS
> ;END OF IFN FTDEC10


IFN	FTDEC20,< MONPOK==CPOPJ >	;NO POKING ON TOPS-20

DEPNPT:	AOSE	DEPNCT		;FIRST TIME THROUGH HERE?
	POPJ	P,		;NO
	TMSG	<
? Patching is not enabled
>
	JRST	CPOPJ1
;STILL FTFILE

;SYMBOL STORING FOR FILDDT

DEPSYM:	PUSHJ	P,SAVR		;PRESERVE FOR CALLERS
	PUSHJ	P,R2ADDR	;CONVERT TO AN ADDRESS
	CAML	R,FISBEG	;BELOW BEGINNING OF SYMS?
	CAMLE	R,FISEND	;OR BEYOND END?
	POPJ	P,		;YES, GIVE ERROR ERTURN
	CAME	T,(R)		;SEE IF DIFFERENT
	SETOM	CHGSFL		;YES--FLAG THAT SYMBOLS CHANGED
	MOVEM	T,(R)		;STORE NEW VALUE
	JRST	CPOPJ1		;RETURN
> ;END OF IFN FTFILE


IFE	FTEXEC,<
STOREP==STOREV			;NON-EDDT PHYSICAL STORE GOES TO VIRTUAL
STORE3==STORE6			; DITTO
> ;END IFE FTEXEC
;FETCH AND DEPOSIT INTO REGISTERS (FAKE 0 - 17)
;CALL WITH A "JSP TT1," SINCE LOCATIONS 0 - 17 MAY NOT ALWAYS
;BE FAKED (DATA FILE FORMAT OR PHYSICAL MEMORY)

FETFAC:	TDNN	R,[777776,,777760]	;FETCH TO AN AC?
	SKIPN	FAKEAC		;USING FAKE 0 - 17?
	 JRST	(TT1)		;NO, CONTINUE IN MAIN SEQUENCE
	ANDI	R,17		;YES, REDUCE TO AC NUMBER
	MOVE	T,AC0(R)	;FETCH FAKE 0 - 17
	JRST	CPOPJ1		;ALWAYS SUCCESSFUL

STOFAC:	TDNN	R,[777776,,777760]	;STORE TO AN AC?
	SKIPN	FAKEAC		;USING FAKE 0 - 17?
	 JRST	(TT1)		;NO, CONTINUE IN MAIN SEQUENCE
	ANDI	R,17		;YES, REDUCE TO AC NUMBER
	MOVEM	T,AC0(R)	;DEPOSIT FAKE 0 - 17
	JRST	CPOPJ1		;ALWAYS SUCCESSFUL
SUBTTL	MEMORY MANAGEMENT ROUTINES -- ADDRESS MAPPING

;MAPADR  --  MAP USER VIRTUAL ADDRESS GIVEN $U PAGE MAP
;CALL IS:
;
;	MOVX	R,<ADR>
;	PUSHJ	P,MAPADR
;	 ERROR
;	NORMAL RETURN
;
;WHERE <ADR> IS THE VIRTUAL ADDRESS TO BE MAPPED.
;
;ERROR RETURN IS TAKEN IF SOME WORD (E.G., A PAGE TABLE ENTRY)
;IS INACCESSIBLE OR A PAGE TABLE ENTRY DOESN'T EXIST
;
;NORMAL RETURN IS TAKEN WITH R RELOCATED INTO PHYSICAL MEMORY
;SPACE AS PER THE PAGE MAP IN MAPFN AND MAPPG.
;
;USES TT, TT1, TT2

MAPADR:	SKIPG	MAPFN		;NO MAPPING OR PHYSICAL ADDRESSING?
	JRST	CPOPJ1		;YES, ALL DONE
	PUSHJ	P,SAVT		;PRESERVE T
	MOVE	T,MAPFN		;GET MAPPING FUNCTION AND FLAG(S)
	MOVEI	TT1,-1(T)	;FUNCTION (BASED AT 0) IN TT1
	TXNE	T,1B1		;SPT INDEX FLAG
	SKPKIP			;CAN'T HAVE SPT INDEX WITH KI PAGING
	CAIL	TT1,MFNMAX	;LEGAL FUNCTION?
	JRST	ERR		;SOMETHING'S WRONG
	JRST	@MFNDSP(TT1)	;DISPATCH ON $U FUNCTION CODE


;DISPATCH TABLE FOR MAPPING FUNCTIONS.  FIRST FUNCTION IS 1.

MFNDSP:	IFIW	MAPEPT		;MAP THRU EPT IN MAPPG
	IFIW	MAPUPT		;MAP THRU UPT IN MAPPG
	IFIW	MAPSEC		;MAP THRU SECTION MAP IN MAPPG
MFNMAX==.-MFNDSP

IFL <PFNMAX-MFNMAX>,<PRINTX ? TOO MANY MAPADR FUNCTIONS>
;MAP THROUGH EPT IN MAPPG

MAPEPT:	SKPKIP			;KI PAGING?
	JRST	MAPKL		;NO, GO SEE IF KL PAGING
	TLNE	R,-1		;KI-PAGING ONLY ALLOWS 18-BIT VIRTUAL ADR
	POPJ	P,		;ILLEGAL ADDRESS
	LDB	T,[POINT 9,R,26];GET PAGE #
	CAIGE	T,340		;IS THERE A MAP ENTRY?
	JRST	CPOPJ1		;NO--LOOK IN PHYSICAL CORE
	CAIL	T,400		;PER PROCESS
	JRST	MAPKI		;NO--JUST LIKE USER
	PUSH	P,R		;SAVE ARGUMENT
	LSH	T,-1		;CONVERT TO 1/2 WORD
	HLRE	R,MAPPG		;GET ADDRESS OF UPT
	JUMPL	R,MAPAD9	;NO ACCESS IF NO UPT SPECIFIED
	ANDI	R,17777		;JUST PAGE NUMBER
	LSH	R,PG2WRD	;CONVERT TO WORD
	ADDI	R,400-<340/2>(T);FOR THIS PAGE
	JRST	MAPKI2		;GO FETCH PAGE TABLE ENTRY


;MAP THROUGH UPT IN MAPPG

MAPUPT:	SKPKIP			;KI PAGING?
	JRST	MAPKL		;NO, JUST LIKE EPT


;HERE TO FETCH AN ENTRY FROM A MAP SLOT

MAPKI:	LDB	T,[POINT 12,MAPPG,35]	;FETCH PAGE NUMBER OF PT
	PUSH	P,R		;SAVE R FOR CALLER
	LSH	T,PG2WRD	;CONVERT TO WORD
	LSH	R,-12		;CONVERT TO 1/2 WORD IN MAP
	ANDI	R,377		;MASK OUT JUNK
	ADD	R,T		;ADDRESS OF MAP ENTRY
MAPKI2:	PUSHJ	P,FETCHP	;FETCH PAGE TABLE ENTRY
	 MOVEI	T,017000	;ERROR
	POP	P,R		;RESTORE R
	TRNN	R,1000		;ODD PAGE
	HLRZ	T,T		;NO--FLIP ENTRY
	TRZN	T,400000	;VALID ENTRY
	POPJ	P,0		;NO--ERROR
	ANDI	T,17777		;JUST PAGE #
	LSH	T,PG2WRD	;CONVERT TO WORD ADDRESS
	ANDI	R,PAGMSK	;GET NEW ADDRESS
	IOR	R,T		; . . .
	JRST	CPOPJ1		;GIVE GOOD RETURN
;HERE TO MAP THROUGH SECTION TABLE IN MAPPG

MAPSEC:	TLNN	R,-1		;SECTION TABLE ONLY HAS 18 BITS OF ADDRESS
	SKPKLP			;AND IS ONLY AVAILABLE IF KL PAGING
	POPJ	P,		;ERROR
	PUSH	P,R		;SAVE VIRTUAL ADDRESS
	MOVE	T,MAPPG		;GET PAGE # OR SPT SLOT
	MOVE	R,MAPFN		;GET FLAGS
	TXNN	R,1B1		;AN SPT SLOT?
	JRST	MAPSE6		;A PAGE NUMBER, JUST GO USE THE SECTION TABLE
	TXO	T,2B2		;AN SPT SLOT, FAKE A SHARE POINTER
	PUSHJ	P,MAPTY		;FIND EFFECTIVE ADDRESS
	  JRST	MAPAD9		;ACCESS ERROR
	JRST	MAPKL6		;JOIN COMMON CODE


;HERE WHEN T CONTAINS A PAGE NUMBER.  PUT WORD NUMBER INTO T.

MAPSE6:	LSH	T,PG2WRD	;MAKE INTO ADDRESS
	JRST	MAPKL6		;JOIN COMMON CODE
;HERE WHEN NOT KI PAGING FOR AN EPT OR UPT.  SEE IF KL PAGING.

MAPKL:	SKPKLP			;KL-PAGING?
	POPJ	P,		;NO, THEN DON'T KNOW WHAT TO DO
	HLRZ	T,R		;SECTION DESIRED
	CAILE	T,37		;WITHIN RANGE?
	POPJ	P,		;NO, ERROR
	PUSH	P,R		;SAVE R
	MOVE	T,MAPPG		;GET PAGE # OR SPT INDEX
	MOVE	R,MAPFN		;FUNCTION AND FLAGS
	TXNN	R,1B1		;SPT INDEX OR PAGE NUMBER?
	JRST	MAPKL2		;PAGE NUMBER, PROCEED
	TXO	T,2B2		;FAKE SHARE POINTER
	PUSHJ	P,MAPTY		;CONVERT TO ADDRESS OF PAGE
	 JRST	MAPAD9		;ERROR
	SKIPA			;ALREADY A WORD ADDRESS
MAPKL2:	LSH	T,PG2WRD	;WORD ADDRESS OF UPT/EPT
	MOVE	R,T		;SAVE IN R
	HLRZ	T,0(P)		;RE-FETCH SECTION NUMBER
	ADDI	R,540(T)	;YES, GET DESIRED SECTION TABLE POINTER
	PUSHJ	P,FETCHP	;FETCH SECTION TABLE POINTER
	  JRST	MAPAD9		;INACCESSIBLE, ERROR
	PUSHJ	P,MAPTY		;EVALUATE SECTION TABLE POINTER
	  JRST	MAPAD9		;SOMETHING WRONG SOMEWHERE
MAPKL6:	LDB	R,[POINTR <0(P)>,<PAGMSK_PG2WRD>]  ;PAGE NUMBER WITHIN SECTION
	ADD	R,T		;POINT TO PAGE POINTER IN SECTION TABLE
	PUSHJ	P,FETCHP	;GET PAGE POINTER
	  JRST	MAPAD9		;INACCESSIBLE, ERROR
	PUSHJ	P,MAPTY		;EVALUATE PAGE POINTER
	  JRST	MAPAD9		;INACCESSIBLE
	POP	P,R		;RETRIEVE ORIGINAL ADDRESS
	ANDI	R,PAGMSK	;FORM OFFSET WITHIN PAGE
	IOR	R,T		;R:=PHYSICAL WORD ADDRESS
	JRST	CPOPJ1		;RETURN SUCCESSFULLY



;HERE ON SOME TYPE OF ACCESS FAILURE

MAPAD9:	POP	P,R		;POP OLD ADDRESS OFF OF STACK
	POPJ	P,		;GIVE ERROR RETURN TO USER
;MAPTY  --  DECODE MAP POINTER TYPE AND RETURN PHYSICAL PAGE ADDRESS
;CALL IS:
;
;	MOVX	T,<MAP POINTER>
;	PUSHJ	P,MAPTY
;	 ERROR RETURN
;	NORMAL RETURN
;
;WHERE <MAP POINTER> IS A HARDWARE TYPE MAP POINTER FROM A UPT/SPT
;OR A SECTION TABLE.
;
;THE ERROR RETURN IS TAKEN IF AN ILLEGAL POINTER TYPE IS ENCOUNTERED
;OR A WORD IN THE POINTER CHAIN IS INACCESSIBLE.
;
;THE NORMAL RETURN IS TAKEN WITH T CONTAINING THE PHYSICAL ADDRESS
;OF THE BASE OF THE PAGE POINTED AT BY THE ORIGINAL POINTER.
;
;USES R, T

MAPTY:	LDB	R,[POINT 3,T,2]	;GET TYPE CODE
	JRST	@MAPTBL(R)	;DISPATCH ON CODE

;HANDLE IMMEDIATE MODE POINTER

MAPTY1:	TLNE	T,17		;INCORE?
	POPJ	P,		;NO, THEREFORE INACCESSIBLE
	ANDI	T,17777		;YES - GET PAGE #
	LSH	T,PG2WRD	;MAKE INTO WORD ADDRESS
	JRST	CPOPJ1		;SUCCESS

;HANDLE SHARED POINTER

MAPTY2:	HRRZ	R,T		;GET SPT INDEX AGAIN
	PUSHJ	P,GVSPT		;GET BASE ADDRESS OF SPT
	  POPJ	P,		;NOT IN ADDRESS SPACE!
	ADD	R,TT		;RELOCATE INTO SPT
	PUSHJ	P,FETCHP	;GET THE POINTER WORD
	 POPJ	P,		;INACCESSIBLE, ERROR
	JRST	@MAPTBL+1	;TREAT LIKE TYPE 1 (IMMEDIATE)
;HANDLE INDIRECT POINTER

MAPTY3:	LDB	R,[POINT 9,T,17];GET PAGE # (INDIRECT)
	TLZ	T,-1		; AND NEW SPTX
	PUSH	P,R		;SAVE PAGE #
	PUSHJ	P,GVSPT		;GET BASE ADDR OF SPT
	  POPJ	P,		;NO IN ADDRESS SPACE
	MOVE	R,TT		;PUT INTO AC R
	ADD	R,T		;ADD IN INDEX
	PUSHJ	P,FETCHP	;GET SPT ENTRY
	 MOVEI	T,0
	POP	P,R		;RESTORE PAGE #
	JUMPE	T,CPOPJ		;ERROR
	TLNE	T,17		;IN CORE?
	POPJ	P,		;NO, ERROR
	ANDI	T,17777		;PAGE # OF PT
	LSH	T,PG2WRD	;CONVERT TO CORE ADDRESS
	ADD	R,T		;ADD IN PAGE #
	PUSHJ	P,FETCHP	;GET PAGE POINTER
	 POPJ	P,		;INACCESSIBLE, ERROR
	JRST	MAPTY		;AND START OVER

MAPTBL:	IFIW	CPOPJ		;0 - NO PAGE
	IFIW	MAPTY1		;1 - IMMEDIATE POINTER
	IFIW	MAPTY2		;2 - SHARED POINTER
	IFIW	MAPTY3		;3 - INDIRECT POINTER
	IFIW	CPOPJ		;4 - ILLEAGL
	IFIW	CPOPJ		;5 - ILLEGAL
	IFIW	CPOPJ		;6 - ILLEGAL
	IFIW	CPOPJ		;7 - ILLEGAL
SUBTTL	MEMORY MANAGEMENT ROUTINES -- PHYSICAL MEMORY

IFE	FTFILE,<
IFN	FTEXEC,<

;PHYIN  --  EXECUTE INSTRUCTION REFERING TO PHYSICAL MEMORY SPACE
;CALL IS:
;
;	MOVX	R,<PHY-ADR>
;	MOVX	TT2,<INSTR>
;	PUSHJ	P,PHYIN
;	 ERROR RETURN
;	NORMAL RETURN
;
;WHERE <PHY-ADR> IS THE DESIRED PHYSICAL MEMORY ADDRESS TO BE REFER-
;ENCED; AND <INSTR> IS THE INSTRUCTION TO REFERENCE (OPERATE ON) THE
;PHYSICAL MEMORY LOCATION INDIRECTING THROUGH REGISTER "R" (E.G.,
;"MOVE T,@R"). NOTE THAT THIS ROUTINE SUPPLIES THE LOCAL INDIRECT
;ADDRESS (IN THIS CASE, "R") SO CALLER ONLY HAS TO PROVIDE OPERATOR
;AND AC FIELDS - THE REST OF TT2 MAY BE BLANK.
;
;THE ERROR RETURN IS TAKEN IF THE DESIRED PHYSICAL ADDRESS CANNOT BE
;REFERENCED, OTHERWISE THE NORMAL RETURN IS TAKEN AFTER HAVING EXE-
;CUTED THE INSTRUCTION IN AC "TT2".

PHYIN:	SKPKIP			;KI-PAGING IN EFFECT?
	JRST	PHYI20		;NO
	PUSHJ	P,GVEPT		;FIND VIRTUAL ADR OF EPT
	 POPJ	P,		;NO EPT (E.G., A KA-10)
	PUSH	P,377(TT)	;SAVE A HANDY MAP SLOT
	PUSH	P,TT		;AND ADDRESS ALSO
	MOVE	TT1,R		;WORKING COPY OF PHYSICAL ADR
	LSH	TT1,WRD2PG	;PHYSICAL PAGE NUMBER
	CAILE	TT1,17777	;WITHIN CONCEPTUAL LIMITS?
	JRST	PHYI17		;NO, ERROR, ADDRESS TOO BIG
	IORI	TT1,700000	;ACCESSIBLE, READ, WRITE, PUBLIC
	HRRM	TT1,377(TT)	;MAP PHYSICAL ADDRESS
	PUSHJ	P,CLRAM		;CLEAR THE ASSOCIATIVE MEMORY
	ANDI	R,000777	;OFFSET WITHIN PAGE
	IORI	R,777000	;RELOCATE THROUGH VIRTUAL PAGE
	PUSHJ	P,CHKADR	;SEE WHAT TYPE OF PAGE IT IS
	TXNN	TT,PG$EXI	;DOES PAGE EXIST?
	JRST	PHYI17		;NO
	TXNE	TT,PG$REA	;CAN WE READ
	TXNN	TT,PG$WRT	;AND WRITE IT?
	JRST	PHYI17		;NO??!!
	HRRI	TT2,R		;SUPPLY INDIRECT ADDRESS
	PUSH	P,TT2		;SAVE THE INSTRUCTION
	JSP	TT2,PCAFI	;SUPPRESS ADDRESS BREAK AND
	XCT	(P)		;EXECUTE THE OPERATION
	AOS	-3(P)		;TAKE SUCCESSFUL RETURN
	POP	P,TT2		;RESTORE STACK
PHYI17:	POP	P,TT		;VIRTUAL ADDRESS OF EPT
	POP	P,377(TT)	;RESTORE MAP SLOT
	PJRST	CLRAM		;AND RESET THE ASSOCIATIVE MEMORY
;STILL IN IFE FTFILE & IFN FTEXEC

PHYI20:	SKPKLP			;KL-PAGING?
	POPJ	P,		;NO CAN DO
	PUSHJ	P,GVEPT		;FIND VIRTUAL ADDRESS OF EPT
	 POPJ	P,		;ERROR
	SKIPL	CSTWRD		;DO WE HAVE A CST?
	SKIPGE	SPTWRD		;AND AN SPT?
	POPJ	P,		;NO, CAN'T DO IT
	MOVE	TT,540(TT)	;GET THE SECTION 0 POINTER
PHYI22:	LDB	TT1,[POINT 3,TT,2]  ;EXTRACT POINTER TYPE FIELD
	CAIN	TT1,1		;IMMEDIATE POINTER?
	JRST	PHYI24		;YES, TRIVIAL
	CAIE	TT1,2		;SHARED POINTER?
	POPJ	P,		;NO, DON'T HANDLE INDIRECT OR OTHERS
	ANDI	TT,777777	;SHARED - REDUCE TO SPT INDEX
	ADD	TT,SPTWRD	;RELOCATE INTO SPT
	MOVE	TT,@TT		;GET [IMMEDIATE] POINTER
PHYI24:	ANDI	TT,17777	;REDUCE TO PHYSICAL PAGE NUMBER
	PUSHJ	P,FPVPG		;VIRTUAL ADDRESS (SECTION 0 PAGE TABLE)
	 POPJ	P,		;ERROR - NOT MAPPED
	ADD	TT,CSTWRD	;POINT TO CST WORD FOR SECTION TABLE
	PUSH	P,@TT		;SAVE IT
	PUSH	P,TT		;SAVE ADDRESS ALSO
	SUB	TT,CSTWRD	;BACK TO PHYSICAL PAGE NUMBER
	LSH	TT,PG2WRD	;WORD ADDRESS OF SECTION TABLE
	ADDI	TT,777		;PAGE 777 IN SECTION 0
	PUSH	P,@TT		;SAVE PAGE 777 POINTER
	PUSH	P,TT		;AND ADDRESS OF POINTER
	MOVE	TT1,R		;COPY OF REQUESTED ADDRESS
	LSH	TT1,WRD2PG	;PHY PAGE OF DESIRED WORD
	CAILE	TT1,17777	;WITHIN REASON?
	JRST	PHYI27		;NO, ERROR
	TXO	TT1,1B2!1B4	;MAKE INTO WRITE-ENABLE IMMEDIATE PTR
	MOVEM	TT1,@TT		;UPDATE SECTION TABLE
	TXZ	TT1,1B2!1B4	;BACK TO PAGE NUMBER
	ADD	TT1,CSTWRD	;CST ENTRY FOR THAT PAGE
	PUSH	P,@TT1		;SAVE CST ENTRY FOR DESIRED PAGE
	PUSH	P,TT1		;AND ITS ADDRESS (WHEW!)
	MOVSI	TT,(100B8)	;REASONABLE AGE FIELD FOR CST ENTRY
	MOVEM	TT,@TT1		;TO PREVENT AGE FAULT FROM DDT

;FALL THROUGH TO NEXT PAGE
;STILL IN IFE FTFILE & IFN FTEXEC

	PUSHJ	P,CLRAM		;CLEAR PAGING MEMORY
	ANDI	R,000777	;OFFSET WITHIN PAGE
	IORI	R,777000	;RELOCATE PHYSICAL TO VIRTUAL ADDRESS
	PUSHJ	P,CHKADR	;MAKE SURE IT REALLY EXISTS
	TXNN	TT,PG$EXI	;DOES PAGE EXIST?
	JRST	PHYI26		;NO - ALL FOR NAUGHT (SIGH)
	TXNE	TT,PG$REA	;YES, CAN WE READ
	TXNN	TT,PG$WRT	;AND WRITE IT?
	JRST	PHYI26		;NO??!! IMPOSSIBLE
	HRRI	TT2,R		;SETUP FOR INDIRECTION
	PUSH	P,TT2		;SAVE THE INSTRUCTION
	JSP	TT2,PCAFI	;SUPPRESS ADDRESS BREAK AND
	XCT	(P)		;REFERENCE DESIRED PHYSICAL ADDRESS
	AOS	-7(P)		;SUCCESSFUL RETURN
	POP	P,TT2		;RESTORE STACK
PHYI26:	POP	P,TT1		;ADDR OF CST ENTRY FOR REFERENCED PAGE
	MOVEI	TT,1		;THE CST "MODIFIED" BIT
	TDNE	TT,@TT1		;SET IN REAL CST?
	IORM	TT,0(P)		;YES, PRESERVE IT THEN
	POP	P,@TT1		;RESTORE CST ENTRY (WITH UPDATED M BIT)
PHYI27:	POP	P,TT		;ADDRESS OF SECTION 0 SECTION TABLE
	POP	P,@TT		;RESTORE PAGE 777 POINTER
	POP	P,TT1		;CST ADDRESS FOR SECTION TABLE
	POP	P,@TT1		;RESTORE IT VERBATIM
	PJRST	CLRAM		;AND CLEAR PAGING MEMORY AGAIN
> ;END IFN FTEXEC
> ;END IFE FTFILE
SUBTTL	MEMORY MANAGEMENT ROUTINES -- FILDDT I/O

IFN	FTFILE,<

;REDWIN  --  READ FILE PAGE INTO FILDDT MEMORY WINDOW
;WRTWIN  --  WRITE FILE PAGE FROM FILDDT MEMORY WINDOW
;CALL IS:
;
;	MOVX	TT1,<FPN>
;	MOVX	TT2,<WIN>
;	MOVX	R,<ADDRESS DESIRED>
;	PUSHJ	P,REDWIN/WRTWIN
;	 ERROR
;	NORMAL RETURN
;
;WHERE <FPN> IS THE DESIRED FILE PAGE NUMBER AND <WIN> IS THE
;FILDDT MEMORY WINDOW NUMBER.
;
;ON ERROR RETURN THE DESIRED I/O CANNOT BE PERFORMED.
;
;ON NORMAL RETURN THE WINDOW NAMED BY TT2 WILL HAVE BEEN READ/WRITTEN
;AS APPROPRIATE TO/FROM THE FILE PAGE NUMBER OF TT1, WINFPN HAS BEEN
;SET TO THE APPROPRIATE FILE PAGE NUMBER, AND SV$MOD HAS BEEN CLEARED.
;
;DESTROYS ACS T AND TT.

REDWIN:	TDZA	T,T		;FLAG READING
WRTWIN:	SETO	T,		;FLAG WRITING
	MOVEM	TT1,WINTT1	;SAVE TT1 AS ADVERTISED
	MOVEM	TT2,WINTT2	;SAVE TT2 . . .

IFN	FTDEC10,<		;FIRST, TOPS-10 STYLE
	MOVE	TT2,TT1		;REALLY WANT PAGE NUMBER IN TT2
	LSH	TT2,PG2BLK	;AND REALLY WANT DISK BLOCK NUMBER
	SKIPE	PHYSIO		;SUPER I/O TO DISK?
	 JRST	FILIO4		;YES, GO DO SUSET RATHER THAN FILOP.
	AOJ	TT2,		;"RELOCATE" PAST BLOCK 0 (FIRST RIB)
	MOVE	TT,[2,,TT1]	;FILOP. POINTER
	MOVSI	TT1,FIL		;I/O CHANNEL NUMBER
	JUMPN	T,FILIO2	;IF WRITE, GO DO "USETO"
	HRRI	TT1,.FOUSI	;"USETI" FUNCTION
	FILOP.	TT,		;POINT I/O TO DESIRED BLOCK NUMBER
	 JRST	FILIOE		;FAILED
	JRST	FILIO6		;GO DO I/O

FILIO2:	HRRI	TT1,.FOUSO	;"USETO" FUNCTION
	FILOP.	TT,		;POINT I/O TO DESIRED BLOCK
	 JRST	FILIOE		;FAILED
	JRST	FILIO6		;GO DO I/O
;STILL IN FTFILE & FTDEC10

;HERE TO SET FOR SUPER I/O (PHYSICAL I/O TO UNIT/STRUCTURE)

FILIO4:	TXO	TT2,<Z FIL,>	;SLIP IN CHANNEL NUMBER
	SKIPE	T		;READ OR WRITE
	TXO	TT2,SU.SOT	;WRITE
	SUSET.	TT2,		;SELECT BLOCK NUMBER
	 JRST	FILIOE		;FAILED
	TXZ	TT2,<<Z FIL,>!SU.SOT>  ;FALL INTO I/O


;HERE TO DO ACTUAL I/O ONCE BLOCK IS SELECTED

FILIO6:	MOVE	TT1,WINTT2	;WINDOW NUMBER
	LSH	TT1,PG2WRD	;CONVERT TO WORD ADDRESS (INDEX)
	ADD	TT1,WIND0	;RELOCATE INTO FILDDT BUFFER AREA
	HRLI	TT1,-PAGSIZ	;CONCOCT AN IOWD POINTER
	SKIPE	EXEFMT		;AN EXE FILE?
	JRST	FILIO7		;YES, MAXSIZ IS IRRELEVANT
	MOVE	TT2,R		;ACTUAL ADDRESS DESIRED
	IORI	TT2,PAGMSK	;ROUND TO BOTTOM OF PAGE
	CAMGE	TT2,MAXSIZ	;PAST EOF?
	JRST	FILIO7		;NO, NOTHING TO WORRY ABOUT
	AND	TT2,MAXSIZ	;YES, GET LOW ORDER ADDRESS BITS
	ANDI	TT2,PAGMSK	;AND ONLY LOW ORDER BITS
	MOVNI	TT2,(TT2)	;NEGATE (FOR IOWD COUNT)
	HRL	TT1,TT2		;AND ADJUST I/O COMMAND LIST
FILIO7:	SOJ	TT1,		;RH(IOWD) IS ADDRESS MINUS ONE
	SETZ	TT2,		;END OF I/O LIST
	JUMPN	T,FILIO8	;READ OR WRITE
	IN	FIL,TT1		;READ
	 JRST	FILIOS		;SUCCESS
	JRST	FILIO9		;FAILURE

FILIO8:	OUT	FIL,TT1		;WRITE
	 JRST	FILIOS		;SUCCESS
FILIO9:	SETSTS	FIL,.IODMP	;CLEAR ERROR BITS
	TMSG	<
? I/O error
>				;WARN USER
	JRST	FILIOS		;LET USER SEE WHATEVER WE GOT
> ;END OF IFN FTDEC10
;STILL FTFILE

IFN	FTDEC20,<		;TOPS-20 STYLE
	SKIPE	PHYSIO		;SUPER I/O?
	 JRST	FILIO4		;YES, SPECIAL CODE
	JUMPN	T,FILIOS	;MONITOR WILL RE-WRITE AUTOMATICALLY
	PUSHJ	P,SAVT4		;PRESERVE SOME ACS
	MOVE	T1,TT1		;FILE PAGE NUMBER
	HRL	T1,FILJFN	;JFN OF FILE
	MOVE	T2,TT2		;GET WINDOW NUMBER
	LSH	T2,PG2WRD	;MAKE WORD ADDRESS
	ADD	T2,WIND0	;RELOCATE INTO BUFFER AREA
	LSH	T2,WRD2PG	;BACK TO PAGE NUMBER
	HRLI	T2,.FHSLF	;THIS PROCESS
	MOVX	T3,PM%RD	;WE WANT TO READ
	SKIPE	PATCHS		;PATCHING ENABLED?
	TXO	T3,PM%WR	;YES, SAY WE WANT TO WRITE ALSO
	PMAP%			;GET THE FILE PAGE
	ERJMP	FILIOE		;CAN'T
	JRST	FILIOS		;PAGE IS MAPPED
;STILL FTFILE & FTDEC20
;HERE FOR SUPER I/O TO DISK UNIT/STRUCTURE

FILIO4:	PUSHJ	P,SAVT4		;SAVE ACS FOR REST OF FILDDT
	SKIPL	T1,PHYSIO	;WANT PHYSICAL UNIT OR STRUCTURE?
	SKIPA	TT,[POINTR T1,DOP%UA]	;PHYS UNIT, ADDR GOES IN DOP%UA
	MOVE	TT,[POINTR T1,DOP%RA]	;STRUCTURE, ADDR GOES IN DOP%RA
	LSH	TT1,PG2BLK	;DSKOP WANTS BLOCK NUMBER
	DPB	TT1,TT		;PUT BLOCK NUMBER IN RIGHT FIELD IN T1
	LDB	TT,TT		;GET BLOCK NUMBER BACK FROM T1
	CAME	TT,TT1		;DID WHOLE THING GET STORED?
	JRST	FILIOE		;BLOCK # TOO BIG! DON'T WRAP AROUND
	LSH	TT1,BL2WRD	;CONVERT ADDRESS TO WORDS
	MOVX	T2,PAGSIZ	;ASSUME WE'LL READ A PAGE
	IORI	TT1,PAGMSK	;ROUND WORD ADDR UP TO END OF PAGE
	CAMGE	TT1,MAXSIZ	;WOULD READING A PAGE BE TOO MUCH?
	JRST	FILIO5		;NO, PROCEED
	MOVE	T2,MAXSIZ	;YES, WE'LL ONLY READ LAST PARTIAL PAGE
	ANDI	T2,PAGMSK	;CLEAR EXTRANEOUS BITS
FILIO5:	DPB	T,[POINTR T2,DOP%WR]	;SET READ OR WRITE FLAG
	MOVE	T3,TT2		;GET INTERNAL PAGE NUMBER
	LSH	T3,PG2WRD	;CONVERT TO WORDS
	ADD	T3,WIND0	;ADD BUFFER BASE ADDRESS
	MOVE	T4,PHYSTR	;GET STRUCTURE DESIGNATOR IF STR
	DSKOP%			;DO THE I/O
	ERJMP	FILIOE		;FAILED, COMPLAIN
	JUMPE	T1,FILIOS	;IF NO I/O ERROR, GIVE OK RETURN
	TMSG	<
? I/O error
>				;TELL THE USER WHAT'S UP
	JRST	FILIOS		;GIVE OK RETURN

> ;END OF IFN FTDEC20



;HERE TO STORE THE FPN INTO WINFPN, CLEAR SV$MOD, AND
;GIVE A SKIP RETURN FROM REDWIN/WRTWIN.

FILIOS:	MOVE	TT1,WINTT1	;RESTORE TT1 AS ADVERTISED
	MOVE	TT2,WINTT2	;RESTORE TT2
	MOVEM	TT1,WINFPN(TT2)	;UPDATE WINFPN
	MOVX	T,SV$MOD	;GET MODIFIED BIT
	ANDCAM	T,WINDIR(TT2)	;CLEAR
	JRST	CPOPJ1		;GIVE GOOD RETURN.


;HERE TO GIVE AN ERROR RETURN FROM REDWIN/WRTWIN.

FILIOE:	MOVE	TT1,WINTT1	;RESTORE TT1
	MOVE	TT2,WINTT2	;RESTORE TT2
	POPJ	P,		;GIVE ERROR RETURN
;STILL FTFILE

;SRHWIN -- ROUTINE TO SEARCH INTERNAL WINDOWS FOR THE FILE
;		PAGE IN TT1.
;CALL:
;	MOVE	TT1,<FILE PAGE>
;	PUSHJ	P,SRHWIN
;	  NOT FOUND
;	FOUND
;
;ON A NORMAL RETURN, THE FILE PAGE NUMBER IS RETURNED IN TT2.
;USES NO OTHER ACS.


SRHWIN:	MOVEI	TT2,WINMAX-1	;COUNT OF WINDOWS
	CAME	TT1,WINFPN(TT2)	;PAGE IN THIS WINDOW?
	SOJGE	TT2,.-1		;NO, TRY NEXT WINDOW
	MOVEM	TT2,WINTT2	;SAVE WINDOW NUMBER FOR OTHERS
	JUMPGE	TT2,CPOPJ1	;JUMP IF WINDOW ALREADY HAS FILE PAGE
	POPJ	P,		;NOT FOUND



;FREWIN -- ROUTINE TO FREE UP AN INTERNAL WINDOW
;CALL:
;	PUSHJ	P,FREWIN
;	RETURN
;
;ON RETURN, TT2 CONTAINS THE WINDOW NUMBER OF A FREE WINDOW.
;
;DESTROYS ACS T AND TT.

FREWIN:	AOS	TT2,WINNUM	;NEXT (ROUND ROBIN) WINDOW TO GO
	CAIL	TT2,WINMAX	;GONE OFF END (MODULO WINMAX)?
	SETZB	TT2,WINNUM	;YES, LOOP BACK TO 0
	MOVX	TT,SV$MOD	;THE MODIFIED BIT
	TDNN	TT,WINDIR(TT2)	;THIS PAGE BEEN MODIFIED?
	POPJ	P,		;NO, THEN DON'T HAVE TO RE-WRITE IT
	PUSH	P,TT1		;SAVE TT1 AS ADVERTISED
	MOVE	TT1,WINFPN(TT2)	;OLD (MODIFIED) FILE PAGE NUMBER
	PUSHJ	P,WRTWIN	;WRITE OUT MODIFIED PAGE
	  JFCL			;INTERNAL ERROR
	POP	P,TT1		;RESTORE TT1
	POPJ	P,		;RETURN TO CALLER
;STILL FTFILE

;NEWWIN -- ROUTINE TO INITIALIZE A WINDOW TO POINT TO A NEW
;		(CURRENTLY NON-EXISTENT) FILE PAGE.
;CALL:
;	MOVX	TT1,<FILE PAGE>
;	MOVX	TT2,<WINDOW NUMBER>
;	MOVX	R,<FILE ADDRESS>
;	PUSHJ	P,NEWWIN
;	 ERROR (I/O)
;	NORMAL RETURN
;
;DESTROYS AC TT.

NEWWIN:	PUSHJ	P,SAVRST	;SAVE T, AND R & S FOR TOPS-20
	MOVE	T,TT2		;WINDOW NUMBER
	LSH	T,PG2WRD	;OFFSET WITHIN WINDOW AREA
	ADD	T,WIND0		;ABSOLUTE MEMORY ADDRESS

	MOVE	S,MAXSIZ	;SAVE OLD MAXSIZ IN CASE OF ERROR
	CAMGE	R,MAXSIZ	;LARGEST ADDRESS YET WRITTEN?
	JRST	NEWWI2		;NO, NEVER DECREASE MAXSIZ
	MOVEM	R,MAXSIZ	;UPDATE MAXSIZ
	AOS	MAXSIZ		;WE WANT # WORDS, NOT LAST USED

NEWWI2:
IFN	FTDEC10,<			;ON TOPS-10, ZERO THE PAGE & WRITE IT
	SETZM	(T)		;CLEAR THE FILE PAGE
	HRLZ	TT,T		; . . .
	HRRI	TT,1(T)		; . . .
	BLT	TT,PAGSIZ-1(T)	; . . .
	PUSHJ	P,WRTWIN	;EXTEND THE FILE TO THE NEW SIZE
	 JRST	[MOVEM S,MAXSIZ	;ERROR, FILE DIDN'T GROW AFTER ALL
		POPJ P,]	;PROPAGATE ERROR
> ;END IFN FTDEC10

IFN	FTDEC20,<
	MOVE	T1,TT1		;SOURCE IS FILE PAGE #
	HRL	T1,FILJFN	;FROM THE CURRENTLY OPEN FILE
	MOVE	T2,T		;DESTINATION IS ADDRESS IN T
	LSH	T2,WRD2PG	;PMAP% WANTS A PAGE NUMBER
	HRLI	T2,.FHSLF	;THIS FORK
	MOVX	T3,PM%RD!PM%WR	;ONLY GET HERE IF WRITING
	PMAP%			;SET UP THE MAPPING (SHOULD NEVER FAIL)
> ;END IFN FTDEC20

	MOVEM	TT1,WINFPN(TT2)	;SET UP WINFPN
	MOVX	TT,SV$MOD	;CLEAR SV$MOD
	ANDCAM	TT,WINDIR(TT2)	;SINCE PAGE HASN'T YET BEEN MODIFIED
	JRST	CPOPJ1		;GIVE OK RETURN TO CALLER

> ;END OF IFN FILDDT
SUBTTL	MEMORY MANAGEMENT ROUTINES -- SYMBOL TABLE ACCESS

IFN FTMON,<

;SYWSET -- ROUTINE TO SET UP THE SYMBOL WINDOW
;CALL:
;	MOVX	TT,FLAGS
;	MOVE	R,<SYMBOL INDEX OR ADDRESS TO PUT IN WINDOW>
;	PUSHJ	P,SYWSET
;	RETURN
;
;ALSO ALLOCATES THE WINDOW AREA IF NEEDED.
;FLAGS:
;	1B0	WRITE-ENABLE THE MAP
;	1B1	R IS AN ADDRESS (OTHERWISE, IT IS A SYMBOL INDEX)


SYWSET:	PUSHJ	P,SAVT4		;SAVE TEMP ACS OVER .IMOPR
	SKIPE	SYWIN		;SYMBOL WINDOW ALLOCATED YET?
	JRST	SYWS2		;YES, JUST GO MAP IT
	PUSH	P,R		;SAVE R OVER .IMOPR
	MOVEI	T1,.IMALC	;ALLOCATION FUNCTION
	MOVEI	T2,SYWLEN_WRD2PG;NUMBER OF PAGES TO ALLOCATE
	PUSHJ	P,.IMOPR	;CALL THE MONITOR TO ALLOCATE IT
	  JRST	SYWERR		;CAN'T -- ASSUME NO SYMBOLS
	LSH	T1,PG2WRD	;CONVERT PAGE # TO ADDRESS
	MOVEM	T1,SYWIN	;STORE
	IORM	T1,SYPTR	;ADJUST FOR PTRSET STORING ZERO
	POP	P,R		;RESTORE SYMBOL INDEX

;CONTINUED ON NEXT PAGE
;STILL FTMON

;HERE WHEN SYWIN IS SET UP.

SYWS2:	MOVEI	T1,.IMMAP	;MAP SYMBOLS FUNCTION
	TXZN	TT,1B1		;NEED TO MAKE R INTO AN ADDRESS?
	PUSHJ	P,R2ADDR	;CONVERT R FROM SYMBOL INDEX TO ADDRESS
;	MOVE	T2,R		;PUT ADDRESS WHERE .IMOPR WANTS IT
	ANDCMI	T2,SYWMSK	;START MAPPING AT EVEN WINDOW BOUND
	LSH	T2,WRD2PG	;CONVERT TO PAGE NUMBER IN SYMBOL VAS
	MOVE	T3,SYWIN	;GET ADDRESS OF OUR WINDOW AREA
	LSH	T3,WRD2PG	;CONVERT TO PAGE NUMBER IN OUR VAS
	MOVEI	T4,1000		;NUMBER OF PAGES IN SECTION 0
	SUB	T4,T2		;FIND OUT HOW FAR FROM END WE ARE
	CAILE	T4,SYWLEN_WRD2PG;LET THAT BE COUNT IF CLOSE TO END
	MOVEI	T4,SYWLEN_WRD2PG;OTHERWISE, FILL OUR WINDOW
	IOR	T4,TT		;SET USER'S WRITE BIT APPROPRIATELY
	SETOM	LASTPG		;THIS MAY CHANGE THE ACCESS OF THESE PAGES
	PUSHJ	P,.IMOPR	;CALL MONITOR TO DO THE MAPPING
	  JRST	SYWERR		;ERROR
	POPJ	P,		;DONE


;HERE ON AN ERROR FROM .IMOPR

SYWERR:	SETZM	@SYMP		;DON'T TRY TO SEARCH ANY MORE
	SETZM	SAVHSM		; . . .
	JRST	ERR		;TELL USER SOMETHING'S WRONG

> ;END IFN FTMON
IFN FTEXEC,<

;SYMSPC -- PUT DDT INTO THE ADDRESS SPACE CONTAINING THE SYMBOLS
;NORSPC -- PUT DDT BACK INTO THE NORMAL ADDRESS SPACE
;CALL IS:
;	PUSHJ	P,SYMSPC/NORSPC
;	RETURN
;
;DESTROYS TT1.

SYMSPC:	SKIPE	HSBLK		;SYMBOLS HIDDEN?
	SKIPE	@ADRSPC		;ALREADY IN SYMBOL SPACE?
	POPJ	P,		;NO NEED TO DO ANYTHING
	SETOM	@ADRSPC		;INDICATE NOW IN ALTERNATE SPACE
	JRST	NEWSPC		;GO SWITCH


NORSPC:	SKIPE	HSBLK		;SYMBOLS HIDDEN?
	SKIPN	@ADRSPC		;ALREADY IN NORMAL SPACE?
	POPJ	P,		;NOTHING TO DO
	SETZM	@ADRSPC		;REMEMBER WHERE WE'RE GOING

;FALL INTO NEWSPC
;STILL FTEXEC

;FALL IN FROM ABOVE

;HERE TO SWITCH ADDRESS SPACES.  @ADRSPC TELLS US WHICH WAY TO GO.
;HSBLK POINTS TO A BLOCK IN THE FOLLOWING FORMAT:
;
;	COUNT OF WORDS FOLLOWING
;	<SUB-BLOCKS>
;
;WHERE EACH SUB-BLOCK LOOKS LIKE:
;
;	COUNT OF WORDS TO TRANSFER
;	ADDRESS OF HARDWARE PAGE POINTERS
;	ADDRESS OF ALTERNATE PAGE POINTERS
;	ADDRESS OF BLOCK TO SAVE HARDWARE POINTERS IN
;
;TO SWITCH TO THE ALTERNATE ADDRESS SPACE, WE SAVE THE CONTENTS OF
;HARDWARE PAGE POINTERS THRU HARDWARE PAGE POINTERS + COUNT TO TRANSFER - 1
;IN THE SAVE BLOCK, THEN MOVE THE ALTERNATE PAGE POINTERS INTO THE HARDWARE
;BLOCK.
;
;TO SWITCH BACK TO NORMAL SPACE, WE SIMPLY COPY THE ORIGINAL HARDWARE
;POINTERS FROM THE SAVE AREA BACK INTO THE HARDWARE BLOCK.

NEWSPC:	SKPUSR			;ARE WE IN EXEC MODE?
	PUSHJ	P,OKPAG		;IS PAGING ON?
	POPJ	P,		;NOTHING WE CAN DO
	PUSHJ	P,SAVRST	;NEED SOME ACS
	MOVE	R,HSBLK		;GET ADDRESS OF WONDEROUS BLOCK
	SKPNS0			;IN SECTION 0?
	TLNN	R,-1		;YES, 30-BIT ADDRESS?
	SKIPA	S,0(R)		;ALL OK
	POPJ	P,		;CAN'T SWITCH
	ADD	S,R		;FIND END OF BLOCK
	SKPNS0			;SECTION 0?
	CAMG	S,[1,,0]	;YES, IS LAST ADDRESS OK?
	SKIPA	S,0(R)		;YES, FETCH TOTAL COUNT AGAIN
	POPJ	P,		;BLOCK IS ILLEGAL
	SUBI	S,1		;ALREADY PASSED COUNT WORD

;FALL THRU
;STILL FTEXEC

;FALL IN FROM ABOVE

;LOOP BACK HERE TO PROCESS EACH SUB-BLOCK

NEWSP2:	MOVE	R,S		;COUNT OF WORDS TO GO
	SUBI	R,3		;+1:INITIAL COUNT WORD, -4:LENGTH OF A BLOCK
	ADD	R,HSBLK		;POINT TO NEXT SUB-BLOCK TO PROCESS
	SKIPN	@ADRSPC		;WHICH WAY ARE WE GOING?
	JRST	NEWSP4		;BACK TO NORMAL


;HERE WHEN GOING TO HIDDEN SYMBOLS.

	MOVE	TT,0(R)		;COUNT
	MOVE	TT1,1(R)	;SOURCE IS HARDWARE BLOCK
	MOVE	TT2,3(R)	;DESTINATION IS SAVE BLOCK
	PUSHJ	P,DOXBLT	;DO THE COPY
	  JRST	SPCERR		;ERROR, GET OUT
	MOVE	TT,0(R)		;COUNT
	MOVE	TT1,2(R)	;SOURCE IS SYMBOL BLOCK
	MOVE	TT2,1(R)	;DESTINATION IS HARDWARE BLOCK
	PUSHJ	P,DOXBLT	;TURN ON HIDDEN SYMBOLS
	  JRST	SPCERR		;CAN'T, GET OUT
	JRST	NEWSP6		;GO FIND NEXT SUB-BLOCK


;HERE WHEN GOING BACK INTO THE NORMAL SPACE

NEWSP4:	MOVE	TT,0(R)		;COUNT
	MOVE	TT1,3(R)	;SOURCE IS SAVE AREA
	MOVE	TT2,1(R)	;DESTINATION IS HARDWARE BLOCK
	PUSHJ	P,DOXBLT	;DO THE COPY
	  JRST	SPCERR		;ERROR, GET OUT


;HERE WHEN A SUB-BLOCK IS DONE.  ADVANCE TO THE NEXT, IF ANY

NEWSP6:	SUBI	S,3		;BLOCKS ARE 4 WORDS
	SOJG	S,NEWSP2	;LOOP IF ANY MORE BLOCKS
;FALL THROUGH TO NEXT PAGE
;STILL FTEXEC

;FALL IN FROM ABOVE

;NOW TO SWITCH THE ???WRD CELLS TO THEIR ALTERNATE VALUES.

	MOVE	T,EPTWRD	;CURRENT VALUE
	EXCH	T,EPTWRS	;SWAP WITH SAVED VALUE
	MOVEM	T,EPTWRD	;UPDATE NEW CURRENT VALUE
	MOVE	T,UPTWRD	;CURRENT VALUE
	EXCH	T,UPTWRS	;SWAP WITH SAVED VALUE
	MOVEM	T,UPTWRD	;UPDATE NEW CURRENT VALUE
	MOVE	T,SPTWRD	;CURRENT VALUE
	EXCH	T,SPTWRS	;SWAP WITH SAVED VALUE
	MOVEM	T,SPTWRD	;UPDATE NEW CURRENT VALUE
	MOVE	T,CSTWRD	;CURRENT VALUE
	EXCH	T,CSTWRS	;SWAP WITH SAVED VALUE
	MOVEM	T,CSTWRD	;UPDATE NEW CURRENT VALUE
	MOVE	T,PAGVAL	;CURRENT VALUE
	EXCH	T,PAGVAS	;SWAP WITH SAVED VALUE
	MOVEM	T,PAGVAL	;UPDATE NEW CURRENT VALUE
	PJRST	CLRAM		;CLEAR PAGER AND RETURN


;HERE ON AN ERROR.  IF WE WERE TRYING TO GET BACK TO NORMAL SPACE,
;THEN THERE IS NOTHING WE CAN DO.  IF WE WERE TRYING TO GET TO THE
;SYMBOL SPACE, THEN CALL THE ROUTINE TO GO BACK, AND HOPE IT WILL
;FAIL IN THE SAME PLACE.

SPCERR:	SKIPE	@ADRSPC		;WHERE WERE WE GOING?
	PJRST	NORSPC		;TO ALTERNATE, TRY TO GET BACK
	POPJ	P,		;TO NORMAL, ALL DONE

> ;END IFN FTEXEC
;R2ADDR -- ROUTINE TO CONVERT A SYMBOL INDEX IN R TO AN ADDRESS
;CALL:
;	MOVE	R,<SYMBOL INDEX>
;	PUSHJ	P,R2ADDR
;	RETURN
;
;DESTROYS ONLY R.

R2ADDR:	PUSHJ	P,SAVT		;NEED AN AC
	TXZN	R,1B0		;LOOKING AT HISEG TABLE?
	SKIPA	T,@SYMP		;NO, GET LOWSEG PTR
	MOVE	T,SAVHSM	;YES, GET HISEG PTR
	TXZE	R,1B1		;REALLY UNDEFINED TABLE?
	MOVE	T,ESTUT		;YES, POINT TO IT INSTEAD
	ADD	R,T		;FORM VIRTUAL ADDRESS IN SYMBOL VAS

IFE FTMON,<
	HLL	R,SECDDT	;SYMBOLS ARE USUALLY IN DDT'S SECTION
> ;END IFE FTMON

IFN FTMON,<
	TLZ	R,-1		;EXCEPT THAT THEY ARE IN SECTION 0 IN MDDT
> ;END IFN FTMON

	POPJ	P,		;DONE
SUBTTL	MEMORY MANAGEMENT ROUTINES -- ADDRESS CHECKING

;CHKSYP  --  VALIDITY CHECK SYMBOL TABLE POINTER
;CALL IS:
;
;	MOVX	T,<PTR>
;	PUSHJ	P,CHKSYP
;	 ERROR
;	NORMAL
;
;WHERE <PTR> IS THE [SYMBOL-TABLE] POINTER TO BE VALIDITY CHECKED
;TO MAKE SURE EACH PAGE REFERENCED IN THE POINTER EXITS, CAN BE READ,
;AND IS A PART OF THIS PROCESS (I.E., IS NOT SPYING ON MONITOR OR
;SOMETHING).
;
;ERROR RETURN IS TAKEN IF THE POINTER IS INVALID OTHERWISE THE NORMAL
;RETURN IS TAKEN.
;
;USES TT, TT1

CHKSYP:	JUMPGE	T,CPOPJ		;POINTER MUST BE .LT. 0
	PUSHJ	P,SAVRST	;NEED SOME ACS
	HRRZ	R,T		;GET BASE ADDRESS OF TABLE
	HLRE	S,T		;GET NEGATIVE LENGTH
	MOVN	S,S		;CONVERT TO POSITIVE LENGTH
IFN FTMON,<
	SKIPE	HSBLK		;WINDOWING SYMBOLS?
	JRST	CHKSY4		;YES, CHECK DIFFERENTLY
> ;END IFN FTMON
	HLL	R,SECDDT	;SYMBOLS ARE IN DDT'S SECTION
	XMOVEI	T,SYBITS	;ADDRESS OF ROUTINE TO LOOK AT CHKADR RESULTS
	PJRST	CHKRNG		;CALL COMMON ROUTINE TO LOOK AT TABLE
IFN FTMON,<
;HERE IF SYMBOLS WINDOWING.  MAP TABLE A PAGE AT A TIME, AND
;MANUALLY CALL CHKADR ON EACH PAGE WINDOWED.  FAIL IF ANYTHING WRONG.

CHKSY4:	ADD	S,R		;PUT LAST ADDRESS INTO S
	TRZ	R,PAGMSK	;ROUND DOWN TO TOP OF PAGE
	SUBI	S,1		;FIRST UNUSED TO LAST USED
	TRZ	S,PAGMSK	;START OF LAST PAGE
CHKSY6:	MOVX	TT,1B1		;PASS SYWSET AN ADDRESS
	PUSHJ	P,SYWSET	;SET UP A WINDOW TO IT
	MOVE	T,R		;SAVE WHERE WE ARE
	MOVE	R,SYWIN		;POINT TO SYMBOL WINDOW
	PUSHJ	P,CHKADR	;GET ACCESS BITS
	PUSHJ	P,SYBITS	;CHECK THEM OUT
	POPJ	P,		;NO GOOD
	MOVE	R,T		;RESTORE CURRENT PLACE
	ADDI	R,PAGSIZ	;ADVANCE TO NEXT PAGE
	CAMG	R,S		;DONE YET?
	JRST	CHKSY6		;NO, KEEP GOING
	JRST	CPOPJ1		;ALL DONE, POINTER IS OK

> ;END IFN FTMON
;SYBITS -- CHECK A SINGLE SYMBOL TABLE PAGE
;CALL:
;	MOVE	TT,<CHKADR BITS>
;	PUSHJ	P,SYBITS
;	  BAD
;	OK
;
;DESTROYS TT, USES NO OTHER ACS.

SYBITS:	TXC	TT,PG$REA!PG$EXI ;COMPLEMENT BITS THAT MUST BE OFF
	TXNN	TT,PG$REA!PG$EXI!PG$SPY!PG$ABZ ;PAGE LEGAL?
	AOS	(P)		;YES, SKIP RETURN
	POPJ	P,		;GIVE RETURN TO CALLER
;CHKRNG -- CHECK ACCESSIBILITY OF A RANGE OF ADDRESSES
;CALL:
;	R/ FIRST ADDRESS TO CHECK
;	S/ COUNT OF ADDRESSES
;	T/ ROUTINE TO CALL TO DECIDE LEGALITY
;	PUSHJ	P,CHKRNG
;	  BAD
;	OK
;
;ROUTINE IN T ALSO RETURNS NON-SKIP FOR BAD, SKIP FOR OK.
;DESTROYS R,S,T,TT,TT1,TT2

CHKRNG:	ADD	S,R		;PUT LAST ADDRESS IN S
	TRZ	R,PAGMSK	;START OF FIRST PAGE
	SUBI	S,1		;MAKE LAST ADDRESS TO CHECK
	TRZ	S,PAGMSK	;START OF LAST PAGE TO CHECK
CHKRN2:	PUSHJ	P,CHKADR	;GET ACCESS BITS INTO TT
	PUSHJ	P,0(T)		;CHECK THE BITS
	  POPJ	P,		;CALLER DOESN'T LIKE THEM
	ADDI	R,PAGSIZ	;ADVANCE TO NEXT PAGE
	CAMG	R,S		;ALL DONE?
	JRST	CHKRN2		;NO, KEEP LOOPING
	JRST	CPOPJ1		;YES, LIKED THEM ALL
;CHKADR  --  CHECK ADDRESS ACCESSIBILITY
;CALL IS:
;
;	MOVX	R,<ADR>
;	PUSHJ	P,CHKADR
;	RETURN
;
;WHERE <ADR> IS THE PHYSICAL ADDRESS TO BE CHECKED.
;
;RETURNS ACCESS BITS IN AC TT:
;	PG$EXI - PAGE EXISTS
;	PG$REA - PAGE CAN BE READ
;	PG$WRT - PAGE CAN BE WRITTEN (I.E., MOVEM'ED TO)
;	PG$HGH - PAGE IS PART OF [TOPS-10] HIGH SEGMENT
;	PG$SPY - PAGE IS SPYING ON SOMEONE ELSE (MONITOR)
;	PG$ABZ - PAGE IS ALLOCATED BUT ZERO
;
;USES TT1, ALL OTHER ACS PRESERVED.

IFE	FTFILE,<
CHKADR:	MOVE	TT,R		;SCRATCH COPY OF ADDRESS
	ANDCMI	TT,PAGMSK	;REDUCE TO JUST PAGE ADDRESS
	XOR	TT,LASTPG	;COMPARE AGAINST LAST PAGE CHECKED
	JUMPE	TT,CHKAD7	;SAME PAGE, ALREADY HAVE ACCESS BITS
	XORB	TT,LASTPG	;DIFFERENT PAGE, REMEMBER FOR NEXT CALLER
IFN	FTEXEC,<		;EXEC IS DIFFERENT
	SKPUSR			;SEE IF USER OR EXEC MODE
	JRST	CHKADX >	;EXEC, REQUIRES SPECIAL HANDLING
;STILL IFE FTFILE

IFN	FTDEC10,<		;TOPS-10 STYLE
	SKPNS0			;IN NON-ZERO SECTION?
	TLNN	R,-1		;NO, ADDRESS MUST BE .LT. 2**18
	TLNE	R,770000	;MUST ALWAYS BE .LT. 2**30
	JRST	CHKAD4		;NO WAY
	MOVE	TT,R		;ADDRESS
	IORI	TT,PAGMSK	;ROUND TO BOTTOM OF PAGE
	CAMG	TT,.JBREL	;PART OF CONTIGUOUS LOW SEG?
	JRST	CHKAD5		;YES, THEN RESULTS A FORGONE CONCLUSION
	LSH	TT,WRD2PG	;PAGE NUMBER
	TLNE	TT,-1		;HUGE PAGE NUMBER?
	JRST	CHKAD4		;YES, NO WAY
	HRLI	TT,.PAGCA	;GET PAGE ACCESS BITS FUNCTION
	PAGE.	TT,		;ASK MONITOR
	 CAIA			;MAYBE A KA?
	JRST	CHKAD6		;REMEMBER NEW BITS
	TLNE	TT,-1		;PAGE. UNIMPLEMENTED?
	SKIPN	.JBHRL		;GOT A HISEG?
	 JRST	CHKAD4		;NO GO
	PUSH	P,T		;PRESERVE T OVER GETHSO
	PUSHJ	P,GETHSO	;FIND START OF HISEG
	MOVE	TT,R		;ADDRESS OF INTEREST
	SUB	TT,T		;OFFSET INTO HISEG
	POP	P,T		;ADJUST STACK
	JUMPL	TT,CHKAD4	;NOT IN HISEG, NO ACCESS
	HRRZ	TT,.JBHRL	;TOP OF HISEG
	CAIL	TT,(R)		;ADDRESS IN R .LE. TOP OF HISEG?
	JRST	CHKAD4		;NO, ADDRESS NOT IN HISEG
	MOVX	TT,PG$REA!PG$HGH  ;ASSUME CAN READ
	HRROI	TT1,.GTSGN	;HISEG INFO
	GETTAB	TT1,		;ASK MONITOR
	 SETZ	TT1,		;???
	TXNE	TT1,SN%SPY	;SPY-SEG?
	TXO	TT,PG$SPY	;YES, TELL WORLD
	JRST	CHKAD6		;SET BITS

CHKAD4:	SKIPA	TT,[PG$EXI]	;NO ACCESS (PAGE DOES NOT EXIST)
CHKAD5:	MOVX	TT,<PG$REA!PG$WRT>  ;FULL READ/WRITE ACCESS
CHKAD6:	TXCA	TT,PG$EXI	;PAGE. RETURNS COMPLIMENT OF EXISTENCE
CHKAD7:	SKIPA	TT,LASTAC	;GET ACCESS BITS FROM LAST CALL
CHKAD8:	MOVEM	TT,LASTAC	;SAVE ACCESS BITS FOR NEXT CALL
	POPJ	P,		;RETURN WITH BITS IN TT
> ;END OF IFN FTDEC10
;STILL IFE FTFILE

IFN	FTDEC20,<		;TOPS-20 STYLE
	SETZ	TT,		;INITIALLY NO ACCESS
	SKPNS0			;IN NON-ZERO SECTION?
	TLNN	R,-1		;NO, ADDRESS MUST BE .LT. 2**18
	TLNE	R,770000	;ADDRESS MUST AWAYS BE .LT. 2**30
	JRST	CHKAD8		;NO WAY
	PUSHJ	P,SAVR		;SAVE R OVER (M)RPACS%
	MOVE	T1,R		;GET ADDRESS

IFE	FTMON,<
	LSH	T1,WRD2PG	;GET PAGE NUMBER
	HRLI	T1,.FHSLF
	RPACS%			;READ PAGE ACCESS
> ;END IFE FTMON

IFN	FTMON,<
	MRPAC%			;READ MONITOR PAGE ACCESS
> ;END IFN FTMON

	TXZ	T2,PA%IND	;KEEP SDDT.EXE CHECKSUM CONSISTENT
	TXNE	T2,PG$WRT	;IS THE PAGE WRITEABLE?
	TXO	T2,PG$WRT	;YES, SET ALL BITS FOR BOOLEAN TESTS ELSEWHERE
	SKIPN	T2		;DOES THE PAGE EXIST?
				; (MRPAC% RETURNS PA%PRV ONLY FOR ILL PAGE)
	TXO	T2,PG$REA!PG$WRT ;NO, NON-EXISTENT PAGES ARE R/W'ABLE
	MOVEM	T2,LASTAC	;SAVE ACCESS
CHKAD7:	SKIPA	TT,LASTAC	;RETURN ACCESS IN TT
CHKAD8:	MOVEM	TT,LASTAC	;SAVE ACCESS BITS FOR NEXT CALLER
	POPJ	P,
> ;END IFN FTDEC20
;STILL IFE FTFILE

IFN	FTEXEC,<

;HERE TO CHECK ADDRESS ACCESSIBILITY FOR EXEC MODE

CHKADX:	PUSHJ	P,CHKAEX	;SEE ABOUT THIS ADDRESS
	TXNE	TT,PG$EXI!PG$REA!PG$WRT  ;DO WE KNOW ANYTHING ABOUT THE PAGE?
	POPJ	P,		;YES, RETURN

;NO ACCESS, ASSUME ADDRESS BREAK, SNIFF AROUND A LITTLE HARDER . . .

	XORI	R,1		;A DIFFERENT ADDRESS IN THE SAME PAGE
	PUSHJ	P,CHKAEX	;CHECK OUT THE OTHER ADDRESS
				; IF PREVIOUS FAILURE WAS DUE TO AN
				; ADDRESS BREAK THEN THIS CALL WILL
				; RETURN REAL PAGE ACCESS ABILITY. IF
				; THE PAGE IS TRULY INACCESSIBLE THEN
				; THAT WILL STILL BE REFLECTED IN THE
				; ACCESS BITS RETURNED FROM CHKAEX HERE.
	XORI	R,1		;RESTORE R FOR CALLER
	POPJ	P,		;AND RETURN WITH ACCESS CODE IN TT
;STILL IFE FTFILE AND IFN FTEXEC

;HERE TO DO THE REAL EXEC MODE ADDRESS ACCESSIBILITY GRUNDGE . . .

CHKAEX:	MOVX	TT,<PG$EXI!PG$REA!PG$WRT>  ;ASSUME FULL ACCESS

;CHECK FOR KA-10

	SKPKA			;ON A KA-10?
	JRST	CHKAE0		;NO
	CONO	APR,1B23	;CLEAR NXM FLAG
	SKIP	(R)		;SEE WHAT MEMORY SAYS
	TLNN	R,-1		;MUST ALWAYS BE .LE. 777777
	CONSZ	APR,1B23	;DID NXM FLAG SET?
	SETZ	TT,		;YES, NO ACCESS
	MOVE	TT1,SAVAPR	;GET APR CONI WORD
	ANDI	TT1,7		;APR PI LEVEL
	CONO	APR,1B23(TT1)	;CLEAR NXM, RESTORE APR PI
	JRST	CHKAD8		;RETURN WITH ACCESS BITS IN TT

;CHECK FOR KI-10

CHKAE0:	SKPKI			;ON A KI-10?
	JRST	CHKAE2		;NO
	MAP	TT1,(R)		;SEE WHAT PAGER THINKS ABOUT ADR
	TRNE	TT1,1B18	;PAGE FAIL
	TRNN	TT1,1B22	;WITH NO MATCH?
	CAIA			;NO - ADR IS OK SO FAR
	SETZ	TT,		;YES, NO ACCESS
	TRNN	TT1,1B20!1B22	;WRITE ACCESS OR NO MATCH (UNMAPPED)?
	TXZ	TT,PG$WRT	;NO, READ ONLY
	JUMPE	TT,CHKAD8	;IF NO ACCESS DON'T BOTHER
	CONO	APR,1B29	;CLEAR NXM FLAG
	SKIP	(R)		;SEE IF MEMORY RESPONDS
	TLNN	R,-1		;MUST ALWAYS BE .LE. 777777
	CONSZ	APR,1B29	;DID NXM SET?
	SETZ	TT,		;YES, NO ACCESS
	MOVE	TT1,SAVAPR	;GET APR CONI WORD
	ANDI	TT1,77		;APR PI LEVEL(S)
	CONO	APR,1B29(TT1)	;CLEAR NXM, RESTORE APR PI LEVEL(S)
	JRST	CHKAD8		;RETURN WITH ACCESS BITS IN TT
;STILL IFE FTFILE & IFN FTEXEC

;CHECK FOR KL-10

CHKAE2:	SKPKLS			;ON A KL-10 OR A KS-10?
	JRST	CHKAE4		;NO
	PUSHJ	P,OKPAG		;IS PAGING ENABLED?
	JRST	CHKAE3		;NO, JUST CHECK FOR NXM
	MAP	TT1,(R)		;ASK PAGER'S OPINION
	TXNN	TT1,1B1		;PAGE FAIL?
	TXNN	TT1,1B2		;OR NO ACCESS ALLOWED?
	SETZ	TT,		;YES, NO ACCESS
	SKPKIP			;KI-PAGING?
	JRST	.+3		;NO (MUST BE KL-PAGING)
	TXNN	TT1,1B3		;WRITE ACCESS?
	TXZ	TT,PG$WRT	;NO
	SKPKLP			;KL-PAGING?
	JRST	.+3		;NO (MUST HAVE BEEN KI-PAGING)
	TXNN	TT1,1B4		;WRITE ACCESS?
	TXZ	TT,PG$WRT	;NO
	JUMPE	TT,CHKAD8	;IF NO ACCESS DON'T BOTHER
CHKAE3:	PUSHJ	P,SAVT		;NEED ANOTHER AC
	EXCH	T,TT		;SAVE TT FOR MOMENT
	PUSHJ	P,GVUPT		;FIND VIRTUAL ADDRESS OF UPT
	 JRST	[EXCH	TT,T	;UPT NOT IN EXEC VIRTUAL ADDRESS SPACE
		JRST	CHKAD8]	;SO JUST TRY THE MEM REF AND SEE WHAT HAPPENS
	PUSHJ	P,SAVFL		;SAVE PC FLAGS OVER POSSIBLE PAGE FAULT
	EXCH	TT,T		;T:=ADDR OF UPT; TT:=ACCESS BITS
	PUSH	P,500(T)	;SAVE PAGE-FAIL WORD
	PUSH	P,501(T)	;PAGE-FAIL OLD PC//PAGE-FAIL OLD PC FLAGS
	PUSH	P,502(T)	;PAGE-FAIL NEW PC//PAGE-FAIL OLD PC
	PUSH	P,503(T)	;----------------//PAGE-FAIL NEW PC
				; (NOTE CST WILL SHOW UPT MODIFIED)
	XMOVEI	TT1,KLNXM	;OUR VERY OWN PAGE-FAIL NEW PC
	MOVEM	TT1,502(T)	;SET FOR KI-PAGING
	MOVEM	TT1,503(T)	;SET FOR KL-PAGING
	CONO	APR,1B22!1B25!1B27	;CLEAR NXM FLAG
	SKIP	(R)		;REFERENCE MEMORY
	SKPNS0			;RESTRICTED TO SECTION 0 ADDRESSING?
	TLNN	R,-1		;YES, MUST BE .LE. 777777
	CONSZ	APR,1B25	;DID NXM FLAG SET?
KLNXM:	SETZ	TT,		;YES, NO ACCESS
	POP	P,503(T)	;RESTORE
	POP	P,502(T)	; OLD
	POP	P,501(T)	;  PAGE-FAIL
	POP	P,500(T)	;   WORDS
	MOVE	TT1,SAVAPR	;APR CONI WORD
	ANDI	TT1,7		;APR PI LEVEL
	CONO	APR,1B22!1B25!1B27(TT1)  ;CLEAR NXM, RESTORE APR PI
	JRST	CHKAD8		;RETURN WITH ACCESS BITS IN TT
;STILL IN IFN FTEXEC & IFE FTFILE

;UNKNOWN PROCESSOR

CHKAE4:	HALT	ERR		;UNKNOWN PROCESSOR TYPE
> ;END OF IFN FTEXEC
> ;END OF IFE FTFILE
;FILDDT CHKADR
;FOR FILDDT, CHKADR RETURNS THE FILE PAGE NUMBER THAT
;SHOULD BE READ IN TT1. THIS IS EITHER R SHIFTED RIGHT BY 9,
;OR, IF EXEFMT, THE APPROPRIATE FILE PAGE FROM THE EXE DIRECTORY.

IFN	FTFILE,<
IFN	FTDEC10,<		;TOPS-10 STYLE
CHKADR:	MOVE	TT1,R		;FILE WORD NUMBER
	LSH	TT1,WRD2PG	;FILE PAGE NUMBER
	SETZ	TT,		;INITIALLY NO ACCESS
	SKIPE	EXEFMT		;EXE OR DATA?
	JRST	CHKAEX		;EXE FORMAT
	SKIPN	FILING		;READING A FILE?
	JRST	CHKAD2		;NO, GO RANGE CHECK MONITOR ADDRESS
	CAMGE	R,MAXSIZ	;IS ADDRESS BEFORE EOF?
	TXO	TT,PG$EXI!PG$REA  ;YES, SET EXISTS AND READABLE
	JRST	CHKAE8		;GO CHECK PATCHS TO SET PG$WRT

;MONITOR OR PHYSICAL MEMORY

CHKAD2:	SKIPE	MAPFN		;GOING TO DO A PHYSICAL PEEK/POKE?
	CAMGE	R,MAXSIZ	;YES, WITHIN PHYSICAL MEMORY?
	TXOA	TT,PG$EXI!PG$REA ;OK TO TRY FOR IT
	  POPJ	P,		;OFF END OF MEMORY, GIVE ERR
	JRST	CHKAE8		;GO CHECK WRITE ACCESS

;EXE FORMAT FILE

CHKAEX:	CAMGE	TT1,PGTLEN	;PAGE WITHIN REASON?
	SKIPN	TT1,@PAGTBL	;AND DOES IT EXIST?
	 POPJ	P,		;NO TO ONE OF THE ABOVE
	TXO	TT,PG$EXI!PG$REA  ;YES,
	ANDX	TT1,SV$FPN	;PHYSICAL FILE PAGE NUMBER
	JUMPN	TT1,CHKAE8	;IF REAL PAGE SEE IF CAN WRITE
	TXO	TT,PG$ABZ	;ALLOCATED BUT ZERO PAGE
	POPJ	P,		;RETURN ACCESS BITS

CHKAE8:	SKIPE	PATCHS		;PATCHING ENABLED?
	TXO	TT,PG$WRT	;YES, THEN CAN ALSO WRITE
	POPJ	P,		;RETURN ACCESS BITS
> ;END OF IFN FTDEC10
;STILL IFN FTFILE

IFN	FTDEC20,<		;TOPS-20 STYLE
CHKADR:	SETZ	TT,		;INITIALLY NO ACCESS
	MOVE	TT1,R		;FILE WORD NUMBER
	LSH	TT1,WRD2PG	;FILE PAGE NUMBER
	XOR	TT1,LASTPG	;SEE IF WE ALREADY KNOW THE ACCESS
	JUMPE	TT1,CHKAD7	;YES, GO FETCH IT
	XORB	TT1,LASTPG	;NO, SET LASTPG FOR NEXT TIME
	JUMPL	R,CHKAD8	;FORGET NEGATIVE ADDRESSES
	CAML	R,MAXSIZ	;BEFORE END OF DISK OR FILE?
	JRST	CHKAD8		;NO
	SKIPN	PHYSIO		;PHYSICAL I/O?
	JRST	CHKAD1		;NO, CHECK /D OR EXE FORMAT
	MOVX	TT,PG$EXI!PG$REA	;YES, EXISTS AND IS READABLE
	JRST	CHKAD5		;GO CHECK PATCHS FOR WRITE ACCESS

CHKAD1:	SKIPN	EXEFMT		;EXE OR DATA FORMAT?
	JRST	CHKAD2		;DATA, NO MAPPING NEEDED
	CAMGE	TT1,PGTLEN	;EXE, PAGE # WITHIN REASON?
	SKIPN	TT1,@PAGTBL	;AND DOES PAGE EXIST?
	JRST	CHKAD8		;NO TO ONE OF THE ABOVE
	ANDX	TT1,SV$FPN	;REDUCE TO PHYSICAL FILE PAGE NUMBER
	JUMPN	TT1,CHKAD2	;AND CHECK ACCESS
	MOVX	TT,PG$EXI!PG$REA!PG$ABZ  ;ALLOCATED BUT ZERO
	JRST	CHKAD5		;GO SEE IF WE CAN WRITE

CHKAD2:	PUSHJ	P,SAVR		;SAVE R OVER RPACS%
	MOVE	T1,TT1		;FILE PAGE NUMBER
	HRL	T1,FILJFN	;JFN FOR FILE
	RPACS%			;GET ACCESS BITS
	MOVE	TT,T2		;PUT ACCESS IN RIGHT PLACE


;HERE WITH MONITOR'S ACCESS IN TT. MODIFY WRITE ACCORDING TO PATCHS.

CHKAD5:	SKIPE	PATCHS		;PATCHING?
	TXOA	TT,PG$WRT	;YES, ALLOW WRITES
	TXZ	TT,PG$WRT	;NO, DON'T ALLOW THEM
CHKAD8:	MOVEM	TT,LASTAC	;SAVE FOR NEXT CALL
	MOVEM	TT1,LSTNPG	;SAVE TRANSLATED PAGE NUMBER
	POPJ	P,		;RETURN

CHKAD7:	MOVE	TT,LASTAC	;RETURN PAGE ACCESS BITS
	MOVE	TT1,LSTNPG	;AND PAGE NUMBER
	POPJ	P,		;RETURN WITH BITS IN TT
> ;END OF IFN FTDEC20
> ;END OF IFN FTFILE
SUBTTL	MEMORY MANAGEMENT ROUTINES -- MISCELLANEOUS

;GETHSO  --  RETURN ORIGIN OF HIGH SEGMENT
;CALL IS:
;
;	PUSHJ	P,GETHSO
;	RETURN
;
;ON RETURN AC T IS EITHER 0 IF THERE IS NO HIGH SEGMENT OR IS
;THE START OF THE HIGH SEGMENT IN THE USER VIRTUAL ADDRESS SPACE.

IFE	FTFILE,<		;FIRST NON-FILDDT CASES
GETHSO:	SETZ	T,		;ASSUME NO HISEG
IFN	FTEXEC,<		;EXEC MODE HAS NO HIGH SEG
	SKPUSR			;USER OR EXEC MODE?
	POPJ	P, >		;EXEC, NO HIGH SEG TO SPEAK OF
	PUSHJ	P,SAVR		;SAVE R TO POINT TO .JBHRL
	MOVEI	R,.JBHRL	;HIGH SEG ORIGIN WORD
	PUSHJ	P,FETCH		;GET IT
	  SETZ	T,		;ASSUME NO HIGH SEG
	TRNN	T,-1		;HIGH SEG EXIST?
	JRST	[SETZ	T,	;NO, SO INDICATE
		POPJ	P,]	;RETURN TO CALLER

IFN	FTDEC10,<		;TOPS-10 CASE
	MOVE	T,[-2,,.GTUPM]	;GETTAB CODE TO
	GETTAB	T,		;OBTAIN HISEG ORIGIN
	 JRST	GETHSQ		;FAILED - ASSUME KA
	HLRZ	T,T		;PUT IN RH
	ANDI	T,777000	;CLEAR GARBAGE
	POPJ	P,		;RETURN

GETHSQ:	MOVEI	T,377777	;DEFAULT ORIGIN-1
	CAMG	T,.JBREL	;HUGE LOWSEG?
	MOVE	T,.JBREL	;YES
	ADDI	T,1		;BUMP TO START AT HIGHSEG
	POPJ	P,		;RETURN
> ;END OF IFN FTDEC10

IFN	FTDEC20,<
	MOVEI	R,.JBHSO	;NOW FETCH ORIGIN WORD
	PUSHJ	P,FETCH		;SHOULD BE SET UP BY LINK-20
	  SETZ	T,		;??
	SKIPN	T		;SET UP?
	MOVEI	T,400		;DEFAULT ORIGIN
	LSH	T,PG2WRD	;CONVERT TO ADDRESS
	POPJ	P,		;RETURN
> ;END OF IFN FTDEC20
> ;END OF IFE FTFILE
;FILDDT GETHSO

IFN	FTFILE,<
GETHSO:	MOVE	T,JOBHSO	;GET LOWEST HISEG ADDR, IF ANY
IFN FTDEC20,<
	JUMPN	T,CPOPJ		;RETURN IF FOUND IT
	PUSHJ	P,SAVR		;NO, TRY FOR .JBHSO; SAVE R
	MOVEI	R,.JBHSO	;POINT TO HI SEG ORIGIN WORD
	SKIPE	EXEFMT		;ONLY IF EXE FORMAT
	PUSHJ	P,FETCHP	;GET THE DATA
	  SETZ	T,		;NOT THERE
	LSH	T,PG2WRD	;FORM BASE ADDRESS
> ;END IFN FTDEC20
	POPJ	P,		;RETURN
> ;END OF IFN FTFILE
IFN	FTEXEC,<

;OKPAG  --  SEE IF PAGING IS TURNED ON FOR PHYSICAL ADDRESSING
;CALL IS:
;
;	PUSHJ	P,OKPAG
;	 ERROR RETURN
;	NORMAL RETURN
;
;THE ERROR RETURN IS TAKEN IF PAGING IS NOT CURRENTLY ENABLED (E.G.,
;IF RUNING ON A KA-10 OR A KL-10 BEFORE THE MONITOR HAS STARTED AND
;ENABLED PAGING), OTHERWISE THE NORMAL RETURN IS TAKEN INDICATING
;THAT PAGING IS ENABLED (SO THAT, FOR EXAMPLE, THE PHYSICAL ADDRES-
;SING CODE CAN DIDDLE THE PAGE MAP).
;
;USES NO ACS

OKPAG:	SKPNKA			;ON A KA-10?
	POPJ	P,		;YES, ALWAYS FAILURE

;SEE IF A KI-10

	SKPKI			;ON A KI-10?
	JRST	OKPAG2		;NO
	JRST	CPOPJ1		;YES, PAGING ALWAYS ON

;TRY FOR A KL-10 OR A KS-10

OKPAG2:	SKPKLS			;ON A KL-10 OR A KS-10?
	JRST	OKPAG4		;NO
	PUSH	P,T		;NEED A SCRATCH AC
	CONI	PAG,T		;(CONSZ PAG, FAILS ON KS-10)
	TXNE	T,1B22		;IS PAGING (ET AL) ENABLED?
	AOS	-1(P)		;YES - INDICATE WITH SKIP RETURN
	POP	P,T		;RESTORE T
	POPJ	P,		;TELL USER

;UNKNOWN PROCESSOR TYPE

OKPAG4:	HALT	ERR		;UNKNOWN PROCESSOR TYPE
> ;END OF IFN FTEXEC
;GV??? -- ROUTINES TO GET THE EXEC VIRTUAL ADDRESS OF THE EPT/UPT/CST/SPT
;CALL:
;	PUSHJ	P,GV???
;	 NOT IN ADDRESS SPACE
;	OK RETURN
;
;ON A SUCCESSFUL RETURN, THE BASE ADDRESS OF THE SPECIFIED TABLE IS
;RETURNED IN AC TT.
;
;PRESERVES ALL ACS.

GVEPT:
IFN FTEXEC,<
	PUSHJ	P,FNDPAG	;MAKE SURE PAGING DATA KNOWN
> ;END OF IFN FTEXEC
	SKIPL	TT,EPTWRD	;GET BASE ADDR, SKIP IF NOT IN ADDR SPACE
	AOS	(P)		;IT'S THERE, SKIP RETURN
	POPJ	P,		;RETURN


GVUPT:
IFN FTEXEC,<
	PUSHJ	P,FNDPAG	;MAKE SURE PAGING DATA KNOWN
> ;END OF IFN FTEXEC
	SKIPL	TT,UPTWRD	;GET BASE ADDR, SKIP IF NOT IN ADDR SPACE
	AOS	(P)		;IT'S THERE, SKIP RETURN
	POPJ	P,		;RETURN


GVCST:
IFN FTEXEC,<
	PUSHJ	P,FNDPAG	;MAKE SURE PAGING DATA KNOWN
> ;END OF IFN FTEXEC
	SKIPL	TT,CSTWRD	;GET BASE ADDR, SKIP IF NOT IN ADDR SPACE
	AOS	(P)		;IT'S THERE, SKIP RETURN
	POPJ	P,		;RETURN


GVSPT:
IFN FTEXEC,<
	PUSHJ	P,FNDPAG	;MAKE SURE PAGING DATA KNOWN
> ;END OF IFN FTEXEC
	SKIPL	TT,SPTWRD	;GET BASE ADDR, SKIP IF NOT IN ADDR SPACE
	AOS	(P)		;IT'S THERE, SKIP RETURN
	POPJ	P,		;RETURN
IFE FTFILE,<
IFN FTEXEC,<

;FNDPAG -- ROUTINE TO FIND THE VIRTUAL ADDRESSES OF ALL THE PAGING TABLES
;CALL:
;	PUSHJ	P,FNDPAG
;	RETURN
;
;ON RETURN, THE ???WRD'S ARE SET TO THE BASE ADDRESS OF THE CORRESPONDING
;TABLE, OR -1 IF THE TABLE IS NOT IN THE EXEC ADDRESS SPACE.
;
;DESTROYS ONLY TT.

FNDPAG:	SKIPN	PAGVAL		;ALREADY BEEN HERE?
	SKPEXC			;OR IN USER MODE?
	POPJ	P,		;YES, CAN'T DO THIS
	PUSHJ	P,FVEPT		;FIND THE EPT
	  SETO	TT,		;NOT THERE
	MOVEM	TT,EPTWRD	;STORE THE ADDRESS
	PUSHJ	P,FVUPT		;FIND THE UPT
	  SETO	TT,		;NOT THERE
	MOVEM	TT,UPTWRD	;STORE THE ADDRESS
	PUSHJ	P,FVCST		;FIND THE CST
	  SETO	TT,		;NOT THERE
	MOVEM	TT,CSTWRD	;STORE THE ADDRESS
	PUSHJ	P,FVSPT		;FIND THE SPT
	  SETO	TT,		;NOT THERE
	MOVEM	TT,SPTWRD	;STORE THE ADDRESS
	SETOM	PAGVAL		;THE ???WRD'S ARE VALID
	POPJ	P,		;RETURN
> ;END OF IFN FTEXEC
> ;END OF IFE FTFILE
IFE	FTFILE,<
IFN	FTEXEC,<

;FVEPT  --  GET EXEC VIRTUAL ADDRESS OF EPT
;CALL IS:
;
;	PUSHJ	P,FVEPT
;	 ERROR RETURN
;	NORMAL RETURN
;
;THE ERROR RETURN IS TAKEN IF THERE IS NO EPT (E.G., IF ON A KA-10)
;OTHERWISE THE EXEC VIRTUAL ADDRESS OF THE HARDWARE EPT IS
;RETURNED IN AC TT.
;
;PRESERVES ALL ACS.

FVEPT:	SKPNKA			;ON A KA-10?
	POPJ	P,		;YES, NO EPT

;SEE IF ON A KI-10

	SKPKI			;ON A KI-10?
	JRST	FVEPT2		;NO
	DATAI	PAG,TT		;YES, READ IN UPT/EPT
	JRST	FVEPT3		;AND TRANSLATE INTO VIRTUAL ADDRESS

;CHECK FOR A KL-10 OR A KS-10

FVEPT2:	SKPKLS			;ON A KL-10 OR A KS-10?
	JRST	FVEPT4		;NO
	CONI	PAG,TT		;READ KL EPT
FVEPT3:	ANDI	TT,17777	;REDUCE TO MAX PHYSICAL PAGE NUMBER
	PUSHJ	P,FPVPG		;TRANSLATE INTO VIRTUAL PAGE NUMBER
	 POPJ	P,		;CAN'T, ERROR
	LSH	TT,PG2WRD	;MAKE INTO VIRTUAL WORD ADDRESS
	JRST	CPOPJ1		;TAKE SUCCESSFUL RETURN

;UNKNOWN PROCESSOR TYPE

FVEPT4:	HALT	CPOPJ		;DIE
> ;END IFN FTEXEC
> ;END OF IFE FTFILE
IFE	FTFILE,<
IFN	FTEXEC,<

;FVUPT  --  GET EXEC VIRTUAL ADDRESS OF UPT
;CALL IS:
;
;	PUSHJ	P,FVUPT
;	 ERROR RETURN
;	NORMAL RETURN
;
;THE ERROR RETURN IS TAKEN IF THERE IS NO UPT (E.G., IF ON A KA-10)
;OTHERWISE THE EXEC VIRTUAL ADDRESS OF THE HARDWARE UPT IS
;RETURNED IN AC TT.
;
;PRESERVES ALL ACS.

FVUPT:	SKPNKA			;ON A KA-10?
	POPJ	P,		;YES, NO UPT

;SEE IF ON A KI-10

	SKPKI			;ON A KI-10?
	JRST	FVUPT2		;NO
	DATAI	PAG,TT		;YES, READ IN UPT/EPT
	MOVS	TT,TT		;PUT UPT IN RIGHT HALF
	JRST	FVUPT3		;AND TRANSLATE INTO VIRTUAL ADDRESS

;CHECK FOR A KL-10 OR A KS-10

FVUPT2:	SKPKLS			;ON A KL-10 OR A KS-10?
	JRST	FVUPT4		;NO
	DATAI	PAG,TT		;READ KL UPT
FVUPT3:	ANDI	TT,17777	;REDUCE TO MAX PHYSICAL PAGE NUMBER
	PUSHJ	P,FPVPG		;TRANSLATE INTO VIRTUAL PAGE NUMBER
	 POPJ	P,		;CAN'T, ERROR
	LSH	TT,PG2WRD	;MAKE INTO VIRTUAL WORD ADDRESS
	JRST	CPOPJ1		;TAKE SUCCESSFUL RETURN

;UNKNOWN PROCESSOR TYPE

FVUPT4:	HALT	CPOPJ		;DIE
> ;END IFN FTEXEC
> ;END OF IFE FTFILE
IFE	FTFILE,<
IFN	FTEXEC,<

;FVCST  --  FIND EXEC VIRTUAL ADDRESS OF CST BASE
;FVSPT  --  FIND EXEC VIRTUAL ADDRESS OF SPT BASE
;CALL IS:
;
;	PUSHJ	P,FVCST/FVSPT
;	 ERROR RETURN
;	NORMAL RETURN
;
;THE ERROR RETURN IS TAKEN IF THE HARDWARE BASE OF THE CST OR SPT
;(AS APPROPRIATE) IS INACCESSIBLE FROM EXEC VIRTUAL ADDRESS SPACE.
;
;THE NORMAL RETURN IS TAKEN WITH THE EXEC VIRTUAL ADDRESS OF THE
;BASE OF THE CST OR SPT (AS APPROPRIATE) IN REGISTER TT.
;
;PRESERVES ALL ACS.

FVCST:	SKIPA	TT,[MOVEM 2,FVTEM3]  ;FLAG CST READ
FVSPT:	MOVE	TT,[MOVEM 3,FVTEM3]  ;FLAG SPT READ
	MOVEM	TT,FVTEM1	;SAVE CST/SPT FLAG
	SKPKLP			;KL PAGING IN EFFECT?
	POPJ	P,		;NO, NO CST/SPT THEN
	SKPKL			;ON A KL-10?
	JRST	FVSPT4		;NO
	PUSHJ	P,SAVT		;NEED ANOTHER T
	DATAI	PAG,TT		;READ CURRENT AC BLOCK SELECTION
	TXO	TT,1B0		;SET TO SELECT NEW AC BLOCKS
	TXZ	TT,1B1!1B2	;AND NOTHING ELSE
	MOVEM	TT,FVTEM2	;SAVE IN NON-REGISTER
	DATAO	PAG,[1B0+6B8]	;SWITCH TO AC BLOCK 6
	XCT	FVTEM1		;READ CST/SPT BASE
	DATAO	PAG,FVTEM2	;SWITCH BACK TO OLD ACS
	JRST	FVSPT9		;TRANSLATE TO VIRTUAL ADDRESS

;CONTINUED ON NEXT PAGE
;STILL IN FTEXEC AND FTFILE

;CONTINUED FROM PREVIOUS PAGE

FVSPT4:	SKPKS			;ON A KS-10?
	HALT	ERR		;NO???
	PUSHJ	P,SAVT		;NEED ANOTHER AC
	LDB	T,[POINT 4,FVTEM1,12]  ;AC FIELD FROM FVCST0/FVSPT0
	CAIN	T,2		;T = 2??
	RDCSB	FVTEM3		;YES - CST BASE ADDRESS
	CAIN	T,3		;T = 3??
	RDSPB	FVTEM3		;YES - SPT BASE ADDRESS

FVSPT9:	MOVE	TT,FVTEM3	;RETRIEVE DESIRED BASE ADDRESS
	MOVEI	T,PAGMSK	;WORD-WITHIN-PAGE MASK
	AND	T,TT		;GET WORD OFFSET WITHIN PAGE
	LSH	TT,WRD2PG	;PHY PAGE OF BASE OF CST/SPT
	PUSHJ	P,FPVPG		;FIND CORRESPONDING VIRTUAL ADDRESS
	 POPJ	P,		;NOT MAPPED, DIE
	LSH	TT,PG2WRD	;VIRTUAL WORD ADDRESS OF BASE PAGE
	ADD	TT,T		;VIRTUAL ADRESS OF BASE OF CST/SPT
	JRST	CPOPJ1		;SUCCESSFUL RETURN
> ;END IFN FTEXEC
> ;END IFE FTFILE
IFE	FTFILE,<
IFN	FTEXEC,<

;FPVPG  --  FIND PHYSICAL TO VIRTUAL PAGE CORRESPONDENCE
;CALL IS:
;
;	MOVX	TT,<PAGE NUMBER>
;	PUSHJ	P,FPVPG
;	 ERROR RETURN
;	NORMAL RETURN
;
;WHERE <PAGE NUMBER> IS THE PHYSICAL MEMORY PAGE NUMBER (E.G., THE
;EPT) FOR WHICH AN EXEC VIRTUAL PAGE NUMBER IS DESIRED.
;
;THE ERROR RETURN IS TAKEN IF THE SPECIFIED PHYSICAL PAGE NUMBER IS
;NOT MAPPED INTO THE EXEC VIRTUAL ADDRESS SPACE.
;
;THE NORMAL RETURN IS TAKEN WITH REGISTER TT CONTAINING THE EXEC VIRTUAL
;PAGE NUMBER WHICH IS MAPPED INTO THE SPECIFIED PHYSICAL PAGE.
;
;PRESERVES ALL ACS.

FPVPG:	SKPKA			;KA-10?
	PUSHJ	P,OKPAG		;NO, ON A MAPPING MACHINE, PAGING ON?
	JRST	CPOPJ1		;VIRTUAL AND PHYSICAL EQUIVILENT
	PUSH	P,TT1		;SAVE SOME ACS
	PUSH	P,TT2		; . . .
	SKPNKI			;KI-10?
	JRST	FPVP10		;YES
	SKPKLS			;KL-10 OR A KS-10?
	CAIA			;NO
	JRST	FPVP20		;YES
	HALT	CPOPJ		;UNKNOWN PROCESSOR TYPE
;STILL IN IFE FTFILE & IFN FTEXEC

;HANDLE KI-10 PAGING

FPVP10:	MOVEI	TT1,777777	;MAX VIRTUAL ADDRESS ON KI-10
	PUSH	P,TT1		;SAVE UPPER LIMIT
	MOVEI	TT1,777		;STARTING POINT

FPVP12:	MAP	TT2,0(TT1)	;MAP VIRTUAL ADDRESS
	TXNE	TT2,1B18	;PAGE BOX PAGE FAILURE?
	JRST	FPVP16		;YES, FORGET THIS VIRTUAL PAGE
	ANDI	TT2,17777	;NO, REDUCE TO JUST PAGE NUMBER
	CAME	TT2,TT		;THIS THE DESIRED PAGE?
	JRST	FPVP16		;NO
FPVP14:	MOVE	TT,TT1		;YES, EXEC VIRTUAL ADDRESS
	LSH	TT,WRD2PG	;MAKE INTO PAGE ADDRESS
	AOS	-3(P)		;TAKE SUCCESSFUL RETURN
	JRST	FPVP18		;GO RETURN

FPVP16:	ADDI	TT1,PAGSIZ	;NEXT VIRTUAL PAGE
	CAMG	TT1,0(P)	;PASSED MAXIMUM ADDRESS YET?
	JRST	FPVP12		;NOT YET
FPVP18:	POP	P,TT2		;POP GARBAGE WORD
	POP	P,TT2		;RESTORE TT2
	POP	P,TT1		;RESTORE TT1
	POPJ	P,		;RETURN AS APPROPRIATE

;HANDLE KL-10 OR KS-10

FPVP20:	XMOVEI	TT1,777777	;MAX KL ADDRESS WITHIN SECTION
	TXNE	TT1,37B17	;IN NON-ZERO SECTION?
	TXO	TT1,37B17	;YES THEN 37 SECTION LIMIT
	PUSH	P,TT1		;SAVE UPPER LIMIT
	MOVEI	TT1,777		;START AT PAGE 0
FPVP22:	MAP	TT2,@TT1	;MAP EXEC VIRTUAL ADDRESS
	TXNN	TT2,1B1		;PAGE FAIL?
	TXNN	TT2,1B2		;ACCESSIBLE?
	JRST	FPVP26		;NO
	LSH	TT2,WRD2PG	;YES, MAKE INTO PAGE NUMBER
	ANDI	TT2,17777	;AND NUTHING BUT PAGE NUMBER
	CAMN	TT2,TT		;THIS THE DESIRED PHYSICAL PAGE?
	JRST	FPVP14		;YES
FPVP26:	ADDI	TT1,PAGSIZ	;ADVANCE TO NEXT PAGE
	CAMG	TT1,0(P)	;REACHED LIMIT YET?
	JRST	FPVP22		;NOT YET
	JRST	FPVP18		;YES, ERROR RETURN - NOT MAPPED
> ;END IFN FTEXEC
> ;END IFE FTFILE
IFE	FTFILE,<
IFN	FTEXEC,<

;CLRAM  --  CLEAR THE [PAGING] ASSOCIATIVE MEMORY
;CALL IS:
;
;	PUSHJ	P,CLRAM
;	RETURN
;
;ON RETURN THE ASSOCIATIVE MEMORY FOR THE PAGING SYSTEM HAS BEEN
;RESET (CLEARED).
;
;USES TT1, ALL OTHER ACS PRESERVED

CLRAM:	SETOM	LASTPG		;FORGET LAST PAGE ACCESS
	SKPNKA			;ON A KA?
	POPJ	P,		;ABOUT AS EASY AS THEY COME

;LOOK FOR A KI-10

	SKPKI			;ON A KI-10?
	JRST	CLRAM2		;NO
	DATAI	PAG,TT1		;GET CURRENT EPT
	TRO	TT1,400000	;SET AS NEW EPT
	DATAO	PAG,TT1		;CLEARING THE ASSOCIATIVE MEMORY
	POPJ	P,		;DONE

;LOOK FOR A KL-10 OR A KS-10

CLRAM2:	SKPKLS			;ON A KL-10 OR A KS-10?
	JRST	CLRAM4		;NO
	CONI	PAG,TT1		;GET EPT
	IORI	TT1,600000	;JUICY BITS
	CONO	PAG,(TT1)	;CLEAR "ASSOCIATIVE" MEMORY
	POPJ	P,		;RETURN

;UNKNOWN PROCESSOR TYPE

CLRAM4:	HALT	ERR		;DIE
> ;END IFN FTEXEC
> ;END IFE FTFILE
IFE	FTFILE,<
IFN	FTEXEC,<

;SELAC  --  SELECT DIFFERENT AC BLOCK
;CALL IS:
;
;	MOVX	W2,<ACBLK>
;	PUSHJ	P,SELAC
;	 ERROR RETURN
;	NORMAL RETURN
;
;WHERE <ACBLK> IS THE AC BLOCK NUMBER DESIRED.
;
;THE ERROR RETURN IS TAKEN IF THE AC BLOCK NUMBER IS OUT OF RANGE
;OR IF RUNNING ON A KA-10 OR KI-10; OTHERWISE THE NORMAL RETURN 
;IS TAKEN WITH AC0 TO AC0+17 LOADED WITH THE NEW ACS AND DDT'S
;ACS LOADED IN THE NEW HARDWARE AC BLOCK. IF PHYSICAL ADDRESSING
;IS CURRENTLY ENABLED THEN VIRTUAL ADDRESSING IS RE-ESTABLISHED.
;
;USES W1 AND W2.

SELAC:	SKPKA			;ON A KA-10?
	SKPNKI			;OR A KI-10?
	POPJ	P,		;YES, LOSES

;LOOK FOR A KL-10 OR A KS-10 PROCESSOR

	SKPKLS			;ON A KL-10 OR A KS-10?
	JRST	SELAC4		;NO
	CAILE	W2,7		;MUST BE 0 .LE. <ACBLK> .LE. 7
	POPJ	P,		;ILLEGAL AC BLOCK NUMBER
	LSH	W2,<^D35-^D8>	;POSITION FOR DATAO
	DATAI	PAG,W1		;READ CURRENT AC BLOCK NUMBER
	TXO	W1,1B0		;FLAG TO SET AC BLOCK
	TXZ	W1,1B1!1B2	;BUT NOTHING ELSE (UPT, ETC)
	SKIPN	ACWRD		;BEEN HERE BEFORE?
	MOVEM	W1,ACWRD	;NO, REMEMBER ORIGINAL AC BLOCK
	TXZ	W1,7B8		;CLEAR OUT CURRENT AC BLOCK FIELD
	IOR	W1,W2		;SET NEW CURRENT AC BLOCK FIELD
	MOVEM	W1,TEM		;SAVE AWAY WHERE WE CAN FIND IT AGAIN
	JSR	SWAP		;RESTORE ACS TO HARDWARE AC BLOCK
	DATAO	PAG,TEM		;SELECT NEW AC BLOCK
	JRST	SELAC9		;CLEAN UP AND RETURN
;STILL IFE FTFILE & IFN FTEXEC

;UNKNOWN PROCESSOR TYPE

SELAC4:	HALT	ERR		;UNKNOWN PROCESSOR TYPE

;COMMON EXIT FROM SELAC

SELAC9:	JSR	SWAP		;RESTORE DDT ACS
	SETOM	FAKEAC		;FLAG AGAIN USING FAKE ACS
	SKIPGE	MAPFN		;VIRTUAL ADDRESSING?
	SETZM	MAPFN		;PHYSICAL - RESET TO VIRTUAL
	JRST	RET		;ALL DONE
> ;END OF IFN FTEXEC
> ;END OF IFE FTFILE
IFE	FTFILE,<
IFN	FTEXEC,<

;RSTAC  --  RESTORE AC BLOCK CONTEXT TO PRE-DDT ENTRY
;CALL IS:
;
;	PUSHJ	P,RSTAC
;	RETURN
;
;IF NO $$U COMMAND HAS BEEN ISSUED OR IF USER MODE THEN SIMPLY
;SO NOTHING AND RETURN, ELSE RESTORE MACHINE TO AC BLOCK IN USE
;PREVIOUS TO THE FIRST $$NU COMMAND ISSUED SINCE LAST DDT ENTRY
;(E.G., FROM A BREAKPOINT). CALLED FROM $G, $P, AND $X COMMANDS.
;
;PRESERVES ALL [DDT] ACS

RSTAC:	SKIPE	ACWRD		;HAS USER $$NU'ED?
	SKPEXC			;WHILE IN EXEC MODE?
	POPJ	P,		;NO, JUST RETURN HARMLESSLY
	SKPKA			;YES, ON A KA-10?
	SKPNKI			;OR A KI-10?
	POPJ	P,		;YES (SHOULD NEVER GET HERE)

;HANDLE KL-10 OR A KS-10 PROCESSOR

	SKPKLS			;ON A KL-10 OR A KS-10 PROCESSOR?
	JRST	RSTAC4		;NO
	JSR	SWAP		;RESTORE HARDWARE ACS
	DATAO	PAG,ACWRD	;RETURN TO PRE-DDT AC BLOCK
	JRST	RSTAC9		;COMMON EXIT CODE

;UNKNOWN PROCESSOR

RSTAC4:	HALT	ERR		;UNKNOWN PROCESSOR

;COMMON EXIT FROM RSTAC

RSTAC9:	JSR	SWAP		;RESTORE DDT ACS
	SETZM	ACWRD		;FLAG WE'VE DONE WHAT WE JUST DID
	POPJ	P,		;AND RETURN
> ;END OF IFN FTEXEC
> ;END OF IFE FTFILE
IFN FTEXEC,<

;DOXBLT -- SUBROUTINE TO DO A BLT OR AN XBLT
;CALL:
;	TT/ COUNT
;	TT1/ FIRST SOURCE
;	TT2/ FIRST DEST
;	PUSHJ	P,DOXBLT
;	  ERROR
;	OK
;
;ASSUMES ADDRESSES ARE LEGAL, FAILS ONLY IF CAN'T GET TO THEM
;BECAUSE THEY ARE IN NON-ZERO SECTION AND DDT ISN'T.
;DESTROYS TT,TT1,TT2.

DOXBLT:	SKPNS0			;XBLT AVAILABLE?
	JRST	DOXBL2		;NO, GO USE BLT IF POSSIBLE
	EXTEND	TT,[XBLT]	;COPY THE DATA
	JRST	CPOPJ1		;DONE


;HERE TO TRY USING A BLT, IF EVERYTHING IS IN SECTION 0.

DOXBL2:	JUMPLE	TT,CPOPJ	;BACKWARDS BLTS DON'T WORK
	TLNN	TT1,-1		;SOURCE IN 0?
	TLNE	TT2,-1		;DEST IN 0?
	POPJ	P,		;SOMETHING NOT IN SECTION 0
	ADD	TT,TT2		;FORM LAST+1 IN TT
	SUBI	TT,1		;GET LAST
	TLNE	TT,-1		;CROSS SECTION 0 END?
	POPJ	P,		;YES, ERROR
	HRL	TT2,TT1		;SOURCE,,DEST
	BLT	TT2,(TT)	;COPY THE DATA
	JRST	CPOPJ1		;ALL DONE

> ;END IFN FTEXEC
SUBTTL	PRESERVATION ROUTINES

;SAVR    --  PRESERVE "R"

SAVR:	PUSH	P,R		;SAVE R ON STACK
	PUSHJ	P,@-1(P)	;"RETURN" TO CALLER
	 SOS	-2(P)		;NON-SKIP RETURN
	POP	P,R		;RESTORE REGISTER
	POP	P,(P)		;CLEAN UP STACK
	AOS	(P)		;SKIP RETURN (UNLESS SOS'ED ABOVE)
	POPJ	P,		;RETURN WITH PRESERVED R



;SAVT    --  PRESERVE "T"

SAVT:	PUSH	P,T		;SAVE T ON STACK
	PUSHJ	P,@-1(P)	;"RETURN" TO CALLER
	 SOS	-2(P)		;NON-SKIP RETURN
	POP	P,T		;RESTORE T
	POP	P,(P)		;CLEAN UP STACK
	AOS	(P)		;SKIP RETURN (UNLESS SOS'ED ABOVE)
	POPJ	P,		;RETURN WITH PRESERVED R



;SAVRST  --  PRESERVE "R", "S", "T"

SAVRST:	PUSH	P,R		;SAVE R ON STACK
	PUSH	P,S		;SAVE S ON STACK
	PUSH	P,T		;SAVE T ON STACK
	PUSHJ	P,@-3(P)	;"RETURN" TO CALLER
	 SOS	-4(P)		;NON-SKIP RETURN
	POP	P,T		;RESTORE T
	POP	P,S		;RESTORE S
	POP	P,R		;RESTORE R
	POP	P,(P)		;DUMP JUNK
	AOS	(P)		;SKIP RETURN (UNLESS SOS'ED ABOVE)
	POPJ	P,		;RETURN WITH PRESERVED R, S, AND T
IFN	FTDEC20,<	;T1 - T4 ONLY FOR TOPS-20

;SAVT4   --  PRESERVE "T1", "T2", "T3", "T4"

SAVT4:	PUSH	P,T1		;SAVE T1 ON STACK
	PUSH	P,T2		;SAVE T2 ON STACK
	PUSH	P,T3		;SAVE T3 ON STACK
	PUSH	P,T4		;SAVE T4 ON STACK
	PUSHJ	P,@-4(P)	;"RETURN" TO CALLER
	 SOS	-5(P)		;NON-SKIP RETURN
	POP	P,T4		;RESTORE T4
	POP	P,T3		;RESTORE T3
	POP	P,T2		;RESTORE T2
	POP	P,T1		;RESTORE T1
	POP	P,(P)		;DUMP JUNK
	AOS	(P)		;SKIP RETURN (UNLESS SOS'ED ABOVE)
	POPJ	P,		;RETURN WITH PRESERVED T1, T2, T3, AND T4
> ;END OF IFN FTDEC20


IFN FTEXEC,<

;SAVFL -- PRESERVE PC FLAGS

SAVFL:	PUSH	P,T		;NEED A TEMP AC
	JSP	T,.+1		;GET SECTION 0 FLAGS
	EXCH	T,0(P)		;SAVE FLAGS, RESTORE T
	SKPS0			;DID WE PUT ANY FLAGS ON THE STACK?
	XSFM	0(P)		;NO, PUT THEM THERE
	PUSHJ	P,@-1(P)	;CALL CALLER
	 SOS	-2(P)		;NON-SKIP RETURN
	EXCH	T,0(P)		;TEMP AC AGAIN
	MOVEM	T,SATEM1	;STORE FLAGS FOR (X)JRSTF
	XMOVEI	T,SAVFL8	;WHERE THE JRST SHOULD GO
	SKPNS0			;WANT FLAGS IN SAME WORD?
	HLL	T,SATEM1	;YES
	MOVEM	T,SATEM2	;STORE PC OR FLAGS,,PC
	SKPNS0			;WHICH JRSTF TO DO?
	 JRSTF	@SATEM2		;OLD STYLE
	XJRSTF	SATEM1		;NEW

SAVFL8:	POP	P,T		;RESTORE TEMP AC
	POP	P,0(P)		;DUMP JUNK RETURN ADDRESS
	JRST	CPOPJ1		;RETURN TO CALLER'S CALLER

> ;END IFN FTEXEC
SUBTTL TELETYPE IO LOGIC -- DEFINITIONS

IFN	FTEXEC,<

;KL10 TELETYPE I/O DEFINITIONS (DTE AND PROTOCOLS)

	DTE==200
	DTEII=142		;DTE20 INTERRUPT INST
	DTEUNS=143		;UNUSED
	DTEEPW=144		;EXAMINE PROTECTION WORD
	DTEERW=145		;EXAMINE RELOCATION WORD
	DTEDPW=146		;DEPOSIT PROTECTION WORD
	DTEDRW=147		;DEPOSIT RELOCATION WORD
	DTEFLG=444
	DTEF11=450
	DTECMD=451
	DTEMTD=455
	DTEMTI=456
	.DTMTO==10B27
	.DTMMC==11B27
	.DTNMC==12B27

	DTEN==4			;MAX NUMBER OF DTE'S
	TO11DB==1B22		;TO 11 DOORBELL
	CL11PT==1B26		;CLEAR TO 10 DOORBELL
	PI0ENB==1B32		;PI CHANNEL 0 ENABLE
	PIENB==1B31		;ENABLE PI SETTING
	DTERES==1B20		;RESTRICTED BIT
;STILL FTEXEC

;KL10 APR INTERNAL CLOCK SERVICE DEFINITIONS

;CONI/CONO MTR,

MTR==024			;DEVICE CODE

MTRLOD==1B18			;LOAD  BITS 21-23
;	19-20			;UNUSED, MBZ
MTREPA==1B21			;ENABLE EXEC PI ACCOUNTING
MTRENA==1B22			;ENABLE EXEC NON-PI ACCOUNTING
MTRAMN==1B23			;ACCOUNTING METERS ON
MTRTBF==1B24			;TIME BASE OFF
MTRTBN==1B25			;TIME BASE ON
MTRCTB==1B26			;CLEAR TIME BASE
;	27-32			;UNUSED, MBZ
MTRPIA==7B35			;PI ASSIGNMENT


;CONI/CONO TIM

TIM==020			;DEVICE ASSIGNMENT

TIMCIC==1B18			;CLEAR INTERVAL COUNTER
;	19-20			;UNUSED, MBZ
TIMITO==1B21			;INTERVAL TIMER ON
TIMDON==1B22			;DONE/CLEAR DONE
TIMICO==1B23			;COUNTER OVERFLOW
;STILL FTEXEC

;KS10 TELETYPE I/O DEFINITIONS

RLWORD==31			;RELOAD CONTROL WORD
KPACT==1B5			;KEEP-ALIVE ACTIVE BIT

CTYIWD==32			;CTY INPUT WORD
CTYIRD==400			;CTY INPUT READY FLAG

CTYOWD==33			;CTY OUTPUT WORD
CTYORD==400			;CTY OUTPUT READY FLAG

INT80==1B23!1B25		;INTERRUPT 8080

> ;END IFN FTEXEC
SUBTTL TELETYPE IO LOGIC -- INPUT ROUTINES

;TIN -- ROUTINE TO READ THE NEXT INPUT CHARACTER
;CALL:
;	PUSHJ	P,TIN
;
;RETURNS +1 WITH NEXT CHARACTER IN T.


TIN:	SOSGE	CHINC		;CHARACTER LEFT IN LINE BUFFER?
	JRST	CHIN1		;NO, GO REFILL BUFFER
	ILDB	T,CHINP		;GET CHARACTER
	POPJ	P,		;RETURN WITH CHARACTER IN T

;REFILL LINE BUFFER WITH EDITING

IFN	FTDEC20,<
CHIN1:
IFN	FTEXEC,<
	SKPUSR			;EXEC MODE?
	JRST	XCHIN1>		;YES, USE SIMULATION ROUTINES
	SKIPE	T1,CHINP	;REINIT LINE?
	JRST	CHIN2		;NO
	MOVEI	T1,NLINBF*5	;YES, SETUP MAX CHAR COUNT
	MOVEM	T1,LINSPC
	MOVE	T1,LINBP	;SETUP POINTER
	MOVEM	T1,CHINP
CHIN2:	MOVEM	T1,TEXTIB+.RDBKL	;SET BACKUP LIMIT
	SKIPG	LINSPC		;ROOM LEFT IN BUFFER?
	JRST	ERR		;NO, TOO MUCH TYPIN
	SETZ	T1,
	SKIPE	WAKALL		;WAKEUP ON EVERYTHING?
	XMOVEI	T1,ONES4	;YES, USE WAKEUP TABLE
	MOVEM	T1,ETXTB
	PUSH	P,LINSPC	;SAVE CURRENT SPACE
	PUSH	P,CHINP		;AND POINTER
	XMOVEI	T1,TEXTIB	;POINT TO ARG BLOCK
	TEXTI%			;INPUT TO NEXT BREAK CHAR
	 JRST	ERR		;BAD ARGS (IMPOSSIBLE)
	POP	P,CHINP		;RESTORE POINTER TO CHARS JUST TYPED
	MOVE	T1,TEXTIB+.RDFLG	;GET FLAGS
	TXNE	T1,RD%BFE+RD%BLR	;DELETIONS?
	JRST	CHIN3		;YES
	POP	P,T1		;RECOVER OLD SPACE COUNT
	SUB	T1,LINSPC	;COMPUTE NUMBER CHARS JUST TYPED
	MOVEM	T1,CHINC	;SETUP COUNT
	JRST	TIN		;GO RETURN NEXT CHAR
;USER HAS DELETED BACK INTO TEXT ALREADY PROCESSED, THEREFORE
;LINE MUST BE REPROCESSED FROM BEGINNING.  POSSIBLY ALL TEXT HAS BEEN
;DELETED.

CHIN3:	MOVEI	T1,NLINBF*5	;COMPUTE NUMBER CHARS NOW IN LINE
	SUB	T1,LINSPC
	JUMPE	T1,WRONG	;JUMP IF WHOLE LINE DELETED
	MOVEM	T1,CHINC	;LINE NOT NULL, SETUP CHAR COUNT
	MOVE	T1,LINBP	;REINIT POINTER
	MOVEM	T1,CHINP
	MOVE	T1,[SCHR,,SCH]	;RESTORE TYPEOUT MODES
	BLT	T1,ODF		; . . .
	JRST	DD2		;CLEAR WORLD AND REDO LINE
>				;END IFN FTDEC20
	IFN	FTDEC10!FTEXEC,<
IFNDEF	T1,<
	T1==A
	PURGT1==-1
>
IFN	FTDEC10,<
CHIN1:>
XCHIN1:	SKIPE	T1,CHINP	;REINIT LINE?
	JRST	XCHIN2		;NO
	MOVEI	T1,NLINBF*5	;YES, SETUP MAX CHAR COUNT
	MOVEM	T1,LINSPC
	MOVE	T1,LINBP	;SETUP POINTER
	MOVEM	T1,CHINP
XCHIN2:	MOVEM	T1,LINDB	;SET BEGINNING OF DELETE BUFFER
	SKIPG	LINSPC		;ROOM LEFT IN BUFFER?
	JRST	ERR		;NO, TOO MUCH TYPIN
	MOVEI	T1,LINBP-TEXTIB	;SIZE OF BLOCK
	SKIPE	WAKALL		;WAKEUP ON EVERYTHING?
	MOVEI	T1,ETXTB-TEXTIB	;YES, INCLUDE WAKEUP TABLE
	MOVEM	T1,TEXTIB	;SET SIZE IN BLOCK
	PUSH	P,LINSPC	;SAVE CURRENT SPACE
	PUSH	P,CHINP		;AND POINTER
	MOVEI	T1,TEXTIB	;POINT TO ARG BLOCK
	PUSHJ	P,TXTI
	 JRST	ERR		;BAD ARGS (IMPOSSIBLE)
	POP	P,CHINP		;RESTORE POINTER TO CHARS JUST TYPED
	POP	P,T1		;RECOVER OLD SPACE COUNT
IFN	FTYANK,<
	AOSN	PTDFLG		;EOF ON COMMAND FILE
	JRST	[SETZM	CHINC
		SETZM	CHINP
		JRST	DD2]	;GET BACK TO TOP LEVEL
>				;END FTYANK
	SKIPN	0(P)		;REPROCESS NEEDED?
	JRST	[MOVEI	T1,NLINBF*5
		SUB	T1,LINSPC	;YES, COMPUTE NUMBER CHARS IN LINE
		JUMPE	T1,WRONG	;JUMP IF WHOLE LINE DELETED
		MOVEM	T1,CHINC	;LINE NOT NULL, SETUP CHAR COUNT
		MOVE	T1,LINBP	;REINIT POINTER
		MOVEM	T1,CHINP
		MOVE	T1,[SCHR,,SCH]	;RESTORE TYPEOUT ETC. MODES
		BLT	T1,ODF		; . . .
		JRST	DD2]		;CLEAR WORLD AND REDO LINE
	SUB	T1,LINSPC	;COMPUTE NUMBER CHARS JUST TYPED
	JUMPG	T1,[MOVEM T1,CHINC	;SETUP COUNT
		JRST	TIN]		;GO RETURN NEXT CHAR

;CONTINUED ON NEXT PAGE
;USER HAS DELETED BACK INTO TEXT ALREADY PROCESSED, THEREFORE LINE
;MUST BE REPROCESSED FROM BEGINNING. POSSIBLY ALL TEXT HAS BEEN
;DELETED.

	PUSHJ	P,RDBKIN
	SETZM	0(P)		;REQUEST REPROCESS OF LINE
	MOVE	T1,LINBP	;RESET DELETE BOUNDARY TO BEGINNING OF LINE
	JRST	XCHIN2

IFDEF	PURGT1,<IFL PURGT1,< PURGE PURGT1,T1>>
SUBTTL TELETYPE IO LOGIC -- LINE BUFFERING ROUTINES

TXTI:
DOTXTI:	PUSH	P,A		;SAVE ALL ACS USED
	PUSH	P,B
	PUSH	P,C
	PUSH	P,T
	PUSH	P,W1
	PUSH	P,W2
	MOVE	W1,LINSPC	;COUNT OF BYTES IN DESTINATION
	SKIPN	W2,LINDB	;WAS IT NON-ZERO?
	MOVE	W2,CHINP	;NO. USE DEFAULT

; VERIFY ALL OF THE STRING POINTERS

RDTXT1:	MOVE	A,CHINP		;HAVE A DEST POINTER?
	PUSHJ	P,RDCBP		;YES. CHECK IT OUT
	MOVEM	A,CHINP		;GET CONVERTED POINTER
	SKIPN	A,LINBP		;HAVE A ^R BUFFER?
	JRST	RDTOPM		;NO. GO AROUND THEN
	PUSHJ	P,RDCBP		;YES. VERIFY IT
	MOVEM	A,LINBP		;STORE VERIFIED POINTER
RDTOPM:	MOVE	A,W2		;GET TOP OF BUFFER
	PUSHJ	P,RDCBP		;VERIFY IT
	MOVE	W2,A		;ALL VERIFIED NOW
	JUMPLE	W1,WRAP0	;MAKE SURE COUNT HAS ROOM IN IT

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;MAIN LOOP - DOES INPUT OF BYTE AND DISPATCH ON CHARACTER CLASS
;ACTION ROUTINES EXIT TO:
; INSRT - APPEND CHARACTER AND CONTINUE
; NINSRT - CONTINUE WITHOUT APPENDING CHARACTER
; DING - BUFFER NOW EMPTY, POSSIBLE RETURN TO USER
; WRAP, WRAP0 - RETURNS TO USER

NINSRT:	MOVEM	W1,LINSPC	;STORE COUNT
	PUSHJ	P,RDBIN		;DO BIN
	MOVE	A,B		;SAVE BYTE
	IDIVI	B,CHRWRD	;SETUP TO GET CHAR CLASS
	LDB	B,CCBTAB(C)	;GET IT FROM BYTE TABLE
	IDIVI	B,2		;SETUP TO REF DISPATCH TABLE
	JUMPE	C,[HLRZ T,DISPTC(B)	;GET LH ENTRY
		JRST	.+2]
	HRRZ	T,DISPTC(B)	;GET RH ENTRY
	MOVE	B,A		;ROUTINES GET BYTE IN B
	JRST	0(T)		;DISPATCH TO ACTION ROUTINE

;RETURN FROM ACTION ROUTINE TO APPEND CHARACTER AND CONTINUE.
; B/ CHARACTER

INSRT:	SKIPE	WAKALL		;BREAK ON EVERYTHING?
	JRST	WRAP		;YES. WRAP IT UP THEN
	IDPB	B,CHINP		;APPEND BYTE TO USER STRING
	SOJG	W1,NINSRT	;CONTINUE IF STILL HAVE COUNT
	JRST	WRAP0		;COUNT EXHAUSTED, RETURN
;RETURNS TO USER.

;RETURN TO USER IF BUFFER EMPTY

NDING:	CAME	W2,CHINP	;BUFFER EMPTY?
	JRST	NINSRT		;NO, GO GET MORE INPUT
	JRST	WRAP0

;APPEND LAST CHARACTER AND RETURN

WRAP:	IDPB	B,CHINP		;APPEND BYTE
	SUBI	W1,1		;UPDATE COUNT

;STORE NULL ON STRING AND RETURN

WRAP0:	JUMPLE	W1,WRAP1	;DON'T STORE NULL IF COUNT EXHAUSTED
	SETZ	B,
	MOVE	A,CHINP
	IDPB	B,A		;STORE NULL WITHOUT CHANGING USER PTR

;UPDATE USER VARIABLES AND RETURN

WRAP1:	MOVEM	W1,LINSPC	;UPDATE USER'S BYTE COUNT
	POP	P,W2
	POP	P,W1
	POP	P,T
	POP	P,C
	POP	P,B
	POP	P,A
	JRST	CPOPJ1
;PARAMETERS FOR CLASS TABLE

CCBITS==4			;BITS/BYTE
CHRWRD==^D36/CCBITS		;BYTES/WORD

;DEFINED CHARACTER CLASSES:

TOP==0				;TOPS10 BREAK
BRK==1				;REGULAR BREAK SET
ZER==2				;NULL
EOLC==3				;EOL
PUN==4				;PUNCTUATION
SAFE==5				;ALL OTHERS
RUBO==6				;DELETE A CHARACTER
RTYP==7				;RETYPE THE LINE
KLL==10				;DELETE THE LINE
KWRD==11			;DELETE A WORD
RDCRC==12			;CARRIAGE RETURN
RDQTC==13			;QUOTE CHARACTER
;TABLE OF BYTE PTRS TO REFERENCE CLASS TABLE

	XX==CCBITS-1
	XALL
CCBTAB:	REPEAT	CHRWRD,<
	 POINT	CCBITS,CTBL(B),XX
	 XX=XX+CCBITS>
	SALL

;CLASS DISPATCH TABLE

DISPTC:	WRAP,,WRAP
	ZNULL,,EOL1
	WRAP,,INSRT
	DELC,,RTYPE
	DELL,,DELW
	RDCR,,RDQT
;CHARACTER CLASS TABLE

DEFINE CCN (A,B)<
	REPEAT	B,<
	 CC1	(A)>>

DEFINE CC1 (C)<
	QQ=QQ+CCBITS
IFG	QQ-^D35,<
	 QW
	 QW=0
	 QQ=CCBITS-1>
	QW=QW+<C>B<QQ>>

	QW==0
	QQ==-1

CTBL:	CC1(ZER)		;0
	CCN(PUN,6)		;1-6
	CC1(TOP)		;7
	CCN(PUN,2)		;10-11
	CC1(EOLC)		;12
	CC1(PUN)		;VT
	CC1(TOP)		;FF
	CC1(RDCRC)		;CR
	CCN(PUN,4)		;16-21 (^N-^Q)
	CC1(RTYP)		;^R
	CCN(PUN,2)		;^S,^T
	CC1(KLL)		;^U
	CC1(RDQTC)		;^V
	CC1(KWRD)		;^W
	CCN(PUN,2)		;^X,^Y
	CCN(BRK,2)		;^Z,$
	CCN(PUN,4)		;34-37
	CCN(PUN,^D16)		;40-/
	CCN(SAFE,^D10)		;0-9
	CCN(PUN,7)		;:-@
	CCN(SAFE,^D26)		;A-Z
	CCN(PUN,6)		;]-140
	CCN(SAFE,^D26)		;A-Z
	CCN(PUN,4)		;173-176
	CC1(RUBO)		;177
	QW			;GET LAST WORD IN
;LOCAL ROUTINES TO DO LOGICAL BIN AND BOUT.

RDBIN:	SKIPN	B,SAVCHR	;WANT TO BACK UP?
	JRST	RDBIN0		;NO
	SETZM	SAVCHR		;ONLY ONCE
	 POPJ	P,		;RETURN

RDBIN0:

IFN	FTEXEC,<
	SKPEXC
	JRST	RDBIN2		;USER MODE

;READ AN EXEC-MODE COMMAND CHARACTER

	PUSH	P,T		;SAVE T
IFN	FTYANK,<
	SKIPE	COMAND
	PUSHJ	P,XPTRIN>
	PUSHJ	P,XTIN		;GET A BYTE
	MOVE	B,T		;PUT IN CORRECT PLACE
	JRST	RDBIN8		;EXIT WITH CHARACTER
RDBIN2:
> ;END IFN FTEXEC

;READ A TOPS-10 USER-MODE COMMAND CHARACTER

IFN	FTYANK,<
	PUSH	P,T		;SAVE AN AC
	SKIPE	COMAND		;COMMAND FILE OPEN?
	PUSHJ	P,PTRIN		;READ COMMAND FILE
	CAIA			;READ FROM TTY
	JRST	RDBIN6		;GOT A CHARACTER (ALREADY ECHOED)
	MOVEI	T," "		;ASSUME EOF
	SKIPL	PTDFLG		;WAS IT EOF?
> ;END IFN FTYANK

	INCHRW	T		;READ A BYTE FROM COMMAND TTY
	PUSHJ	P,TOUT6		;"ECHO" (COUNT) THE CHARACTER
RDBIN6:	MOVE	B,T		;COPY BYTE
RDBIN8:	POP	P,T		;RESTORE T
	MOVEM	B,LASCHR	;SAVE LAST CHAR READ
	POPJ	P,0		;RETURN
;RDSOUT - OUTPUT STRING ALA ECHOB
; B/ STRING PTR
;	PUSHJ P,RDSOUT
; RETURN +1 ALWAYS

RDSOUT:	MOVE	A,B		;COPY POINTER
	PUSHJ	P,RDCBP
RDSL:	ILDB	B,A
	JUMPE	B,CPOPJ		;EXIT ON NULL
	PUSHJ	P,ECHOB		;"ECHO" THE CHARACTER
	JRST	RDSL

;CHECK BYTE POINTER GIVEN AS ARGUMENT
; A/ BYTE POINTER
;	PUSHJ P,RDCBP
; RETURN +1: OK, LH INITIALIZED IF NECESSARY

RDCBP:	HLRZ	B,A		;GET LH
	CAIN	B,-1		;IS DEFAULT?
	HRLI	A,(<POINT 7,0>)	;YES, FILL IN 7-BIT
	LDB	B,[POINT 6,A,11]	;CHECK BYTE SIZE
	CAIGE	B,7		;7 OR GREATER?
	HALT	.		;BAD BYTE SIZE
	IBP	A		;INCR IT AND DECR IT ONCE SO WILL
	JRST	DBP		; BE IN KNOWN STATE FOR COMPARES
;GET TYPEIN CHARACTER - EXEC MODE

IFN FTEXEC,<

XTIN:	PUSHJ	P,XLISTE	;TELETYPE CHARACTER INPUT
	 JRST	.-1
	SETZM	TTSUP		;CLEAR ^O SUPPRESSION ON ANY INPUT
	JUMPE	T,XTIN		;FILTER NULLS
	CAIE	T,175
	CAIN	T,176
	MOVEI	T,.CHESC	;CHANGE ALL ALT MODES TO NEW
	CAIE	T,.CHDEL	;DON'T ECHO EDIT CHARACTERS
	CAIN	T,.CHCNU
	POPJ	P,
	CAIE	T,.CHCNR
	CAIN	T,.CHCNW
	POPJ	P,
	CAIN	T,.CHTAB	;A <TAB> CHARACTER
	TXNE	F,TXF		;YES, DON'T ECHO UNLESS TEXT MODE
	CAIA			;NOT A <TAB> OR TEXT MODE
	POPJ	P,		;A <TAB> AND NOT TEXT MODE
	CAIN	T,.CHCRT	;CR?
	JRST	[MOVEI T,.CHLFD	;YES, PRESET LF FOR NEXT TIME
		MOVEM	T,XNXTCH
		MOVEI	T,.CHCRT	;ECHO AND RETURN CR NOW
		JRST	.+1]
	PJRST	ECHO		;ECHO THE CHARACTER
> ;END IFN FTEXEC
;LOCAL ROUTINES FOR EDITING FUNCTIONS

;DELETE CHARACTER FROM DESTINATION - BACKUP PTR AND CHECK
;FOR TOP OF BUFFER
;	PUSHJ P,BACK
; RETURN +1: AT TOP OF BUFFER, NO CHARACTER TO DELETE
; RETURN +2: CHARACTER DELETED
;
;ON SKIP RETURN, AC A HAS OLD BYTE POINTER, AC B HAS CHARACTER
;THAT WAS JUST "DELETED".

BACK:	CAMN	W2,CHINP	;AT TOP OF BUFFER?
	POPJ	P,0		;YES
	MOVE	A,CHINP		;GET DEST PTR
	PUSHJ	P,DBP		;DECREMENT IT
	MOVEM	A,CHINP		;PUT IT BACK
	ILDB	B,A		;GET CHARACTER JUST "DELETED"
	AOJA	W1,CPOPJ1	;UPDATE COUNT AND RETURN

;PUT BYTE BACK INTO SOURCE
; B/ BYTE
;	PUSHJ P,RDBKIN
; RETURN +1 ALWAYS

RDBKIN:
DOBKIN:	MOVE	A,LASCHR	;GET LAST BYTE READ
	MOVEM	A,SAVCHR	;MAKE NEXT BYTE READ
	POPJ	P,0
;FIND BEGINNING OF CURRENT LINE.
;	PUSHJ P,FNDLIN
; RETURN +1: AT TOP OF BUFFER
; RETURN +2: A/ BACKED-UP BYTE PTR TO BEGINNING OF LINE
;	B/ BYTE COUNT CONSISTENT WITH CHINP IN A

FNDLIN:	CAMN	W2,CHINP	;AT TOP OF BUFFER?
	POPJ	P,0		;YES
	PUSH	P,CHINP		;SAVE CURRENT LINE VARIABLES
	PUSH	P,W1
FNDLN1:	MOVE	A,CHINP		;BACKUP ONE CHARACTER
	PUSHJ	P,DBP
	MOVEM	A,CHINP
	ADDI	W1,1
	CAMN	W2,CHINP	;NOW AT TOP OF BUFFER?
	JRST	FNDLN2		;YES, RETURN
	LDB	B,CHINP		;NO, LOOK AT NEXT CHAR TO BE DELETED
	CAIN	B,.CHLFD	;EOL OR LF?
	JRST	FNDLN2		;YES, RETURN
	JRST	FNDLN1		;NO, KEEP LOOKING

FNDLN2:	MOVE	A,CHINP		;RETURN NEW LINE VARIABLES
	MOVE	B,W1
	POP	P,W1		;RESTORE OLD LINE VARIABLES
	POP	P,CHINP
	JRST	CPOPJ1

;ACTION ROUTINES

;ZERO BYTE

ZNULL:	SKIPE	WAKALL		;USER HAVE A MASK?
	JRST	INSRT		;YES. GO SEE ABOUT IT THEN
	JRST	WRAP0		;NO. ALWAYS BREAK THEN
;CARRIAGE RETURN - IF LINE FEED FOLLOWS, TREAT LIKE EOL

RDCR:	CAIGE	W1,2		;ROOM FOR CR AND LF?
	JRST	[PUSHJ P,RDBKIN	;NO, PUT THE CR BACK
		JRST	WRAP0]	;WILL GET IT NEXT TIME
	PUSHJ	P,RDBIN		;GET THE NEXT CHAR
	CAIN	B,.CHLFD	;LF?
	JRST	RDCR1		;YES, NORMAL NEWLINE
	PUSHJ	P,RDBKIN	;NO, PUT BACK THE SECOND BYTE
	MOVEI	B,.CHCRT	;APPEND A REAL CR
	JRST	WRAP

RDCR1:	MOVEI	B,.CHCRT
	IDPB	B,CHINP		;APPEND CR
	SOS	W1
RDCR2:	MOVEI	B,.CHLFD
EOL1:	JRST	WRAP		;YES

;QUOTE CHARACTER (^V) - INHIBITS EDITING ACTION OF FOLLOWING CHARACTER

RDQT:	CAIGE	W1,2		; ROOM FOR BOTH?
	JRST	[PUSHJ P,RDBKIN	; NO. BACK UP
		JRST	WRAP0]	; AND WAIT FOR NEXT TIME
	IDPB	B,CHINP		;STORE QUOTE
	SOS	W1		; ONE LESS
	PUSHJ	P,RDBIN		;GET THE NEXT CHAR
	JRST	WRAP		;YES
;DELETE CHARACTER (RUBOUT)

DELC:	PUSHJ	P,DELCH		;DELETE A CHARACTER
	 JRST	WRAP0		;NONE TO BE DELETED
	JUMPL	B,RTYPE		;IF FUNNY CHARACTER FORCE A ^R
	JRST	NINSRT		;CONTINUE INPUT UNLESS BUFFER EMPTY ETC.



;DELETE WORD (CONTROL-W)

DELW:	PUSHJ	P,BACK		;DELETE AT LEAST ONE CHARACTER
	 JRST	WRAP0		;WASN'T ONE
	CAIN	B,.CHLFD	;LF OR EOL?
	JRST	BWRD3		;YES, DON'T DELETE
	MOVX	T,TT$DEL	;FANCY DELETE HANDLING
IFE	FTEXEC,<
	TDNN	T,TTYMSK >	;DO WE HAVE IT?
IFN	FTEXEC,<
	TDNE	T,TTYMSK	;DO WE HAVE IT
	SKPUSR >		;OR ARE WE IN EXEC MODE?
	JRST	BWRD1		;DON'T WORRY ABOUT ^W ON SCREEN
	PUSHJ	P,DELCH4	;WIPE OUT THE "^" CHARACTER
	 JFCL			;DON'T GET HERE
	PUSHJ	P,DELCH4	;WIPE OUT THE "W" CHARACTER
	 JFCL			;DON'T GET HERE EITHER
	MOVE	A,CHINP		;GET DELETED BYTE POINTER
	IBP	A		;RESET A FOR DELCH0
BWRD1:	LDB	B,A		;GET COPY OF CHARACTER TO BE ZAPPED
	PUSHJ	P,DELCH0	;DELETE CHARACTER FROM SCREEN
	 JFCL			;CAN'T HAPPEN
	JUMPL	B,RTYPE		;IF (E.G.) TAB THEN FORCE A ^R
	PUSHJ	P,BACK		;DELETE NEXT CHARACTER
	 JRST	BWRD2		;NO MORE LEFT
	IDIVI	B,CHRWRD	;GET ITS CHARACTER CLASS
	LDB	B,CCBTAB(C)
	CAIN	B,SAFE		;IS IT A WORD SEPARATOR?
	JRST	BWRD1		;KEEP DELETING
BWRD3:	IBP	CHINP		;YES, KEEP THAT CHARACTER
	SUBI	W1,1
BWRD2:	JRST	NINSRT		;CONTINUE INPUT UNLESS BUFFER EMPTY ETC.



;DELETE LINE (CONTROL-U)

DELL:	PUSHJ	P,FNDLIN	;FIND BEGINNING OF LINE
	 JRST	NDING		;NOTHING IN BUFFER
	LDB	C,CHINP		;GET LAST CHAR IN BUFFER
	MOVEM	A,CHINP		;SET LINE VARIABLES TO BEGINNING
	MOVEM	B,W1
	JRST	NDING		;CONTINUE INPUT UNLESS BUFFER EMPTY ETC.
;DELCH -- DELETE A CHARACTER FROM BUFFER AND TERMINAL
;CALL IS:
;
;	PUSHJ	P,DELCH
;	 EMPTY
;	NORMAL
;
;DELCH DELETES THE PREVIOUS INPUT CHARACTER, BOTH INTERNALLY
;(A LA BACK ROUTINE) AND ON THE TERMINAL (HANDLING ANY FANCY
;VIDEO EDITING NEEDED).
;
;DELCH4 CAN BE CALLED TO BLANK OUT THE PREVIOUS CHARACTER ON
;THE SCREEN VIA A <BS><SP><BS> SEQUENCE.
;
;DELCH8 CAN BE CALLED TO OUTPUT A <CR><LF> PAIR.
;
;ON SKIP RETURN AC B HAS THE CHARACTER WHICH WAS JUST DELETED.

DELCH:	PUSHJ	P,BACK		;BACKUP PTR
	 POPJ	P,		;NOTHING LEFT IN BUFFER
DELCH0:	CAIN	B,.CHLFD	;WAS IT LF?
	JRST	DELCH6		;YES
	MOVE	T,TTYMSK	;[210] GET FORMAT MASK
	TXNE	T,TT$DEL	;[210] FANCY <DEL>'S?
	JRST	DELCH4		;[210] YES - <BS><SP><BS>
	PUSHJ	P,ECHOB		;TYPE IT OUT (AND COUNT UP TOHPS)
	MOVEI	B,"\"		;INDICATE DELETION
	PUSHJ	P,ECHOB		;COUNT IT TOO
DELCH3:	MOVE	A,CHINP		;INPUT POINTER
	ILDB	B,A		;RETURN CHARACTER JUST DELETED IN B
	CAIN	B,.CHTAB	;DELETED A <TAB>?
	SETO	B,		;YES, WARN NEED A ^R FOR SCREEN
	JRST	CPOPJ1		;SUCCESSFULL RETURN

DELCH4:	MOVEI	B,.CHCNH	;A BACKSPACE CHARACTER
	PUSHJ	P,ECHOB		;OUTPUT IT
	MOVEI	B," "		;A SPACE CHARACTER
	PUSHJ	P,ECHOB		;OUTPUT IT
	MOVEI	B,.CHCNH	;AND FINALLY A BACKSPACE CHARACTER
	PUSHJ	P,ECHOB		;OUTPUT IT TOO
	JRST	DELCH3		;[210] REJOIN COMMON CODE

DELCH6:	CAMN	W2,CHINP	;AT BEGINNING OF DEST BUFFER?
	JRST	DELCH8		;YES
	LDB	B,CHINP		;NO, CHECK CHARACTER PRECEEDING LF
	CAIE	B,.CHCRT	;A CR?
	JRST	DELCH8		;NO, LEAVE IT ALONE
	PUSHJ	P,BACK		;YES, DELETE IT ALSO
	 POPJ	P,		;(CAN'T HAPPEN)
				; (TAKE SUCCESSFUL RETURN WITH <LF>)
DELCH8:	MOVEI	B,.CHCRT	;A <CR> CHARACTER
	PUSHJ	P,ECHOB		;OUTPUT IT
	MOVEI	B,.CHLFD	;A <LF> CHARACTER
	PUSHJ	P,ECHOB		;OUTPUT IT TOO
	JRST	CPOPJ1		;SUCCESSFUL RETURN
;RETYPE LINE (CONTROL-R)

RTYPE:	PUSHJ	P,RTYPES	;DO THE WORK
	JRST	NINSRT

;SUBROUTINE TO RETYPE LINE

RTYPES:	PUSHJ	P,DELCH8	;OUTPUT A <CR><LF>
	 JFCL			; (DON'T GET HERE)
	PUSHJ	P,FNDLIN	;FIND BEGINNING OF LINE
	 MOVE	A,W2		;AT TOP OF BUFFER - USE IT
	MOVE	T,A		;SAVE PTR TO BEGINNING OF LINE
	CAME	T,W2		;BEG OF LINE IS TOP OF BUFFER?
	JRST	RTYP1		;NO, DON'T TYPE ^R BFR
	SKIPE	T,LINBP		;GET ^R BFR IF ANY
RTYW1:	CAMN	T,W2		;UP TO TOP OF BFR?
	JRST	RTYP4		;YES, DONE WITH ^R BFR
	ILDB	B,T		;GET CHAR FROM ^R BFR
	JUMPN	B,[PUSHJ P,ECHOB;RE-ECHO IT
		JRST	RTYW1]
RTYP4:	MOVE	T,W2		;DONE WITH ^R BFR, NOW DO MAIN BFR
RTYP1:	CAMN	T,CHINP		;BACK TO END OF LINE?
	POPJ	P,		;YES
	ILDB	B,T		;NO, GET NEXT BYTE
	PUSHJ	P,ECHOB		;RE-ECHO IT
	JRST	RTYP1		;LOOP UNTIL AT END OF BUFFER
;DECREMENT BYTE POINTER
; A/ BYTE PTR
;	PUSHJ P,DBP
; RETURNS +1, CLOBBERS B AND C

DBP:	LDB	B,[POINT 6,A,5]	;GET P
	LDB	C,[POINT 6,A,11]	;GET S
	ADD	B,C		;NEW P = P + S
	CAIGE	B,^D36		;NEW P .GE 36?
	JRST	DBP1		;NO, BYTE IS IN SAME WORD.
	HRRI	A,-1(A)		;DECREMENT ADDRESS
	MOVEI	B,^D36		;MAKE P = REMAINDER (36,S)
	IDIV	B,C
	MOVEI	B,0(C)
DBP1:	DPB	B,[POINT 6,A,5]
	POPJ	P,0
>				;END IFN FTDEC10...
SUBTTL TELETYPE IO LOGIC -- UTILITY ROUTINES

;LISCK -- SUBROUTINE USED BY $$X, $W, AND $Z TO CHECK FOR INPUT
;CALL IS:
;
;	PUSHJ	P,LISCK
;	  NOTHING TYPED
;	 SOMETHING TYPED, ABORT
;	"?" TYPED, GIVE STATUS
;
;USES AC T, TT2.

LISCK:	PUSHJ	P,LISTEN	;ANYTHING TYPED?
	 POPJ	P,		;NO, "NOTHING TYPED" RETURN
	AOS	(P)		;SOMETHING TYPED
	CAIN	T,"?"		;USER TYPE A "?" CHARACTER?
	AOS	(P)		;YES, "GIVE STATUS" RETURN
	POPJ	P,		;NO, "ABORT" RETURN
;LISTEN -- SUBROUTINE TO TEST IF INPUT IS READY
;CALL:
;	PUSHJ	P,LISTEN
;	  NONE
;	INPUT READY
;
;ALSO READS ONE CHARACTER INTO T.  THIS CHARACTER IS EITHER
;REAL COMMAND INPUT, OR IS THROWN OUT SO A CHAR TYPED TO STOP A
;DDT LOOP WILL NOT AFFECT FUTURE COMMAND INPUT.


LISTEN:
IFN	FTEXEC,<
	SKPUSR			;IN EXEC MODE?
	JRST	XLISTN		;[230] YES, USE SPECIAL EXEC CODE
> ;END OF IFN FTEXEC

IFN	FTFILE&FTYANK,<		;FILDDT?
	SKIPE	COMAND		;STILL READING COMAND FILE?
	POPJ	P,0		; IF YES, DO NOT LOOK FOR INPUT
				; 1. SPEED UP FILDDT AND
				; 2. ALLOW USER TO TYPE AHEAD
				;  (ONE CONTROL C)
> ;END OF IFN FTFILE&FTYANK

IFN FTDEC10,<
	INCHRS	T		;GET NEXT CHAR, NO IO WAIT
	POPJ	P,		;NO CHARACTER EXISTED, RETURN
	JRST	CPOPJ1		;CHARACTER WAS THERE, SKIP RETURN
> ;END IFN FTDEC10

IFN FTDEC20,<
	PUSHJ	P,SAVR		;SAVE R(=T2) OVER SIBE%
	EXCH	T1,T
	MOVEI	T1,.PRIIN	;PRIMARY INPUT (TTY)
	SIBE%			;INPUT BUFFER EMPTY?
	 AOSA	0(P)		;NO, GIVE SKIP RETURN
	JRST	LISTN6		;YES, JUST RETURN NON-SKIP
	PBIN%			;READ CHAR INTO T1
LISTN6:	EXCH	T1,T
	POPJ	P,		;RETURN
> ;END IFN FTDEC20
IFN FTEXEC,<

;HERE TO LISTEN IF IN EXEC MODE

XLISTE:	SKIPE	T,XNXTCH	;PRESET CHAR?
	JRST	[SETZM XNXTCH	;YES, RETURN IT ONCE
		JRST	XLIST8]
IFN	FTYANK,<
	SKIPE	COMAND		;COMAND FILE?
	JRST	XPTRIN		;YES, READ IT
>

;ENTRY POINT FROM LISTEN.
;SEE IF A KL10, AND DO KL10 LISTEN IF SO.

XLISTN:	SKPKL			;A KL10?
	JRST	XLIST2		;NOT KL, CHECK OTHER CPUS
	EXCH	TT,TT2		;SAVE TT
	PUSHJ	P,GVEPT		;GET EPT BASE IN TT
	  HALT	.		;NOT IN ADDRESS SPACE!
	EXCH	TT,TT2		;PUT ADDRESS IN TT2
	SKIPN	DTEMTI(TT2)	;ANY INPUT YET?
	POPJ	P,		;NO
	MOVE	T,DTEF11(TT2)	;GET IT
	SETZM	DTEMTI(TT2)	;YES
	JRST	XLIST8		;AND CHAR DOWN AND RETURN
;STILL FTEXEC

;HERE IF NOT ON A KL10.  TRY A KS10.

XLIST2:	SKPKS			;ON A KS10?
	JRST	XLIST4		;NO, GO DO OLD (KA/KI) WAY
	MOVE	T,CTYIWD	;PICK UP INPUT WORD
	TXNN	T,CTYIRD	;ANYTHING THERE?
	POPJ	P,		;NO CHARACTER, RETURN CPOPJ0
	SETZM	CTYIWD		;YES, SAY WE GOT IT
	MOVE	TT2,SAVAPR	;GET APR STATE
	ANDI	TT2,7		;REDUCE TO PI ASSIGNMENT
	WRAPR	INT80(TT2)	;TELL 8080
	JRST	XLIST8		;AND CHAR DOWN AND GIVE GOOD RETURN
;HERE TO DO OLD STYLE (KA/KI) LISTEN TO REAL HARDWARE CTY

XLIST4:	CONSO	TTY,40		;DO KA OR KI TTY INPUT
	POPJ	P,		;NO CHARACTER
	DATAI	TTY,T		;READ IN PHYSICAL CHARACTER


;HERE FROM ALL CPU'S TO AND CHAR DOWN TO 7 BITS AND GIVE SKIP RETURN.

XLIST8:	ANDI	T,177		;STRIP OFF GARBAGE
	CAIE	T,.CHCNO	;USER TYPE A ^O?
	JRST	XLIST9		;NO, RETURN CHARACTER IN AC T
	SETCMM	TTSUP		;TOGGLE ^O SUPPRESSION FLAG
	JRST	XLISTN		;AND SEE IF ANY MORE INPUT

XLIST9:	SETZM	TTSUP		;CLEAR SUPPRESSION FLAG
	JRST	CPOPJ1		;AND RETURN WITH CHARACTER IN T

> ;END IFN FTEXEC
IFN FTDEC10,<
IFN	FTYANK,<
IFN	FTEXEC,<
XPTRIN:	PUSHJ	P,PTRXNX	;GET NEXT CHAR FROM PTR
	 JRST	PTRDON		;THROUGH
	JRST	PTRCHR		;PROCESS THE CHAR.
>
PTRIN:	PUSHJ	P,PTRNX		;GET NEXT CHAR
	 JRST	PTRDON		;EOF ON COMMAND FILE
PTRCHR:	CAIE	T,.CHDEL	;RUBOUT?
	SKIPN	TT2,T		;NULL?
	JRST	PTRNXT		;IGNORE IT
IFN	FTEXEC,<
	SKPEXC			;EXEC MODE?
	JRST	PTRCH2
	CAIE	T,.CHCRT	;YES. CR?
	JRST	CPOPJ1		;NO. ECHO OF CHAR WILL HAPPEN LATER
	PUSHJ	P,PTRXNX	;READ (AND IGNORE) NEXT CHAR
	 JFCL			; WHICH OUGHT TO BE A LINE-FEED
	MOVEI	T,.CHCRT	;RETURN CR AS CHAR
	JRST	CPOPJ1
PTRCH2:		>;END IFN FTEXEC
	PUSHJ	P,ECHO		;ECHO CHAR
	JRST	CPOPJ1		;SKIP-RETURN WITH DATA

PTRNXT:
IFN	FTEXEC,< SKPUSR
	JRST	XPTRIN>
	JRST	PTRIN

;THROUGH WITH  COMMAND FILE

PTRKIL:	PUSHJ	P,PTRNX2	;GO ZAPETH THE COMMAND FILE
				;AND FALL INTO EOF CODE

PTRDON:	SETZM	COMAND		;NO LONGER PROCESSING COMMAND FILE
	SETOM	PTDFLG		;FLAG EOF REACHED
	PUSHJ	P,DELCH8	;TYPE A <CR><LF>
	 JFCL			;DON'T GET HERE
	PUSHJ	P,DELCH8	;TYPE ANOTHER <CR><LF>
	 JFCL			;DON'T GET HERE EITHER
	POPJ	P,		;NON-SKIP RETURN
;STILL FTDEC10 & FTYANK

;COMMAND FILE IO

PTRNX:	SOSLE	CBUF+2		;DATA LEFT?
	JRST	PTRNX1		;YES
	IN	CM,		;GET NEXT BUFFER
	JRST	PTRNX1		;GET NEXT CHARACTER
	GETSTS	CM,T		;ERROR, SEE WHAT KIND
	TXNE	T,IO.EOF	;END OF FILE?
	JRST	PTRNX2		;YES, OK, JUST QUIT
	TMSG	<
? I/O error reading command file
>				;WARN USER OF LOSAGE
	JRST	PTRNX2		;YES

;RETURN NEXT CHARACTER

PTRNX1:	ILDB	T,CBUF+1
	JRST	CPOPJ1		;SKIP-RETURN WITH DATA

;RELEASE COMMAND FILE

PTRNX2:	RELEASE	CM,		;EOF - DONE
	POPJ	P,		;NON-SKIP MEANS DONE WITH COMMAND FILE
;STILL FTDEC10 & FTYANK

IFN	FTEXEC,<
PTRXNX:	SKIPE	TT2,EPTPTR	;DATA IN PTR BUF?
	JRST	PTRXN3		;YES
	MOVE	TT2,[POINT 7,EPTRBF]	;NO SET UP TO STORE IN PTR BUFFER
	SETZM	EPTRBF		;SWITCH FOR END OF TAPE TEST
	CONO	PTR,20		;START PTR GOING
PTRXN1:	CONSO	PTR,400		;EOT?
	JRST	PTRXN4		;YES
	CONSO	PTR,10		;DATA?
	JRST	PTRXN1		;WAIT SOME MORE
	DATAI	PTR,T		;READ A CHAR
	JUMPE	T,PTRXN1	;IGNORE NULLS
PTRXN2:	IDPB	T,TT2		;SAVE IN DATA BUFFER
	CAIE	T,.CHLFD	;LF
	CAMN	TT2,EPTRND	; OR BUFFER FULL?
	SKIPA	TT2,[POINT 7,EPTRBF]	;YES. START TAKING CHARS OUT OF BUF
	JRST	PTRXN1		;NO - READ ANOTHER
	CONO	PTR,0		;SHUT OFF PTR BEFORE READING NEXT CHAR

PTRXN3:	ILDB	T,TT2		;GET A CHAR
	CAIE	T,.CHLFD	;LF
	CAMN	TT2,EPTRND	; OR END OF BUFFER?
	SETZ	TT2,		;YES, START PTR FOR NEXT CHAR
	MOVEM	TT2,EPTPTR	;SAVE PNTR FOR NEXT CHAR
	JRST	CPOPJ1		;HAVE A CHAR RETURN

;EOT
PTRXN4:	SKIPN	EPTRBF		;ANY DATA?
	POPJ	P,		;NO - DONE RETURN
	SETZ	T,		;YES -  FILL REST OF BUFFER WITH 0'S
	JRST	PTRXN2
> ;END IFN FTEXEC
> ;END IFN FTYANK
> ;END IFN FTDEC10
;TTYCLR -- ROUTINE TO CLEAR ANY PENDING TTY INPUT
;CALL:
;	PUSHJ	P,TTYCLR
;	 RETURN
;
;DESTROYS R, T, TT2, AND T1 ON TOPS20


TTYCLR:
IFN FTEXEC,<
	SKPUSR
	JRST	TTYCL6		;SKIP CLEARING INPUT BUFFER AND ^O IF EXEC
> ;END IFN FTEXEC

IFN FTDEC10,<
	SKPINL			;CLEAR ^O
	  JFCL			;(DON'T CARE)
	CLRBFI			;CLEAR TYPEAHEAD
> ;END IFN FTDEC10

IFN FTDEC20,<
	MOVEI	T1,.PRIIN	;PRIMARY INPUT
	RFMOD%			;GET MODES
	TXZE	T2,TT%OSP	;CLEAR ^O, SKIP IF WASN'T SET
	SFMOD%			;^O WAS SET, CLEAR IT
	CFIBF%			;CLEAR INPUT BUFFER
> ;END IFN FTDEC20


;HERE AFTER CLEARING ^O AND INPUT BUFFER TO EAT LAST PENDING CHAR, IF ANY.

TTYCL6:	PUSHJ	P,LISTEN
	 JFCL
	POPJ	P,0
SUBTTL TELETYPE IO LOGIC -- OUTPUT SUBROUTINES

;TSTRG -- SUBROUTINE TO TYPE OUT AN ASCIZ STRING.
;CALL:
;	MOVEI	W1,ADDRESS OF STRING
;	PUSHJ	P,TSTRG
;	  RETURN
;
;USES W1, T, TT2

TSTRG:	HRLI	W1,(POINT 7,)	;MAKE 7-BIT BYTE POINTER
	CAIA			;ENTER LOOP
TSTRG3:	PUSHJ	P,TOUT		;TYPE THIS BYTE
	ILDB	T,W1		;NEXT ASCII CHARACTER
	JUMPN	T,TSTRG3	;IF NOT YET AT NULL KEEP TYPING
	POPJ	P,		;ALL DONE, RETURN


;Txxx ROUTINES -- ROUTINES TO TYPE COMMON CHARACTER(S) TO THE TTY.
;CALL:
;	PUSHJ	P,TCR/TCRLF ETC.
;	RETURN
;
;USES T, TT2.

TBEL:	MOVEI	T,.CHBEL	;A <BEL> CHARACTER
	PJRST	TOUT		;GO TYPE IT OUT

TBSP:	MOVEI	T,.CHCNH	;A <BS> CHARACTER
	PJRST	TOUT		;GO TYPE IT OUT

TTAB:	MOVEI	T,.CHTAB	;A <TAB> CHARACTER
	MOVX	TT2,TT$SPC	;SPACE OR TAB BIT
	TDNE	TT2,TTYMSK	;SPACES OR TAB?
	PJRST	TOUT		;TAB, GO TYPE IT OUT
	PUSHJ	P,TSPC		;SPACES
	PUSHJ	P,TSPC		;SPACES
	PJRST	TSPC		;SPACES

TCRLF:	PUSHJ	P,TCR
TLF:	MOVEI	T,.CHLFD	;LINE FEED
	PJRST	TOUT

TCR:	MOVEI	T,.CHCRT	;A <CR> CHARACTER
	PJRST	TOUT		;GO TYPE IT OUT

TSPC:	MOVEI	T," "		;SPACE
	PJRST	TOUT
;TOUT  -- SUBROUTINE TO CLEAR LINE INPUT BUFFER AND TYPE CHAR IN T
;TOUTB -- TOUT WITH CHARACTER IN AC B
;ECHO  -- ENTRY POINT TO AVOID CLEARING LINE BUFFER FOR EXEC-MODE ECHOING
;ECHOB -- ECHO WITH CHARACTER IN AC B
;CALL:
;	MOVEI	T,CHAR		;OR MOVEI B,CHAR
;	PUSHJ	P,TOUT/ECHO	;OR TOUTB/ECHOB
;	RETURN
;
;TOUT[B] IS THE ROUTINE TO CALL WHEN THE OUTPUT IS TO COUNT AGAINST
;THE HORIZONTAL CARRIAGE POSITION (I.E., THE CHARACTER IS REAL DDT
;OUTPUT). TOUT ALSO CLEARS THE COMMAND TYPEIN BUFFER.
;
;ECHO[B] IS THE ROUTINE TO CALL WHEN THE OUTPUT DOESN'T COUNT AGAINST
;THE HORIZONTAL CARRIAGE POSITION (I.E., THE CHARACTER WILL BE READ
;BY HIGHER-LEVEL ROUTINES AS A COMMAND CHARACTER (AND WILL GET COUNTED
;UP AT TIN).
;
;PRESERVES RIGHTMOST 7 BITS OF T, USES TT2

ECHOB:	EXCH	B,T		;CHARACTER TO BE ECHOED IS IN B
	PUSHJ	P,ECHO		;ECHO THE CHARACTER
	EXCH	T,B		;RESTORE AC T (AND B AS WELL)
	POPJ	P,		;RETURN

TOUTB:	EXCH	B,T		;CHARACTER TO BE OUTPUT IS IN B
	PUSHJ	P,TOUT		;OUTPUT THE CHARACTER
	EXCH	T,B		;RESTORE AC T (AND B AS WELL)
	POPJ	P,		;RETURN

TOUT:	SETZM	CHINP		;RESET INPUT LINE
	SETZM	CHINC

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;HERE TO CONVERT CONTROLS TO ^X, ESCAPES TO $, ETC.

ECHO:
TOUT0:	CAIE	T,.CHCRT	;CR OR LF?
	CAIN	T,.CHLFD
	JRST	TOUT4		;YES, NO CONVERSION
	CAIE	T,.CHBEL	;BELL?
	CAIN	T,.CHCNH	;[210] OR BACKSPACE?
	JRST	TOUT4		;NO CONVERSION
	CAIE	T,.CHTAB	;TAB?
	JRST	ECHO3		;NO, LOOK FOR CONTROL CHARACTERS
	PUSHJ	P,SAVR		;NEED A SCRATCH AC FOR A MOMENT
	MOVX	R,TT$TAB	;TAB SIMULATION BIT
	TDNE	R,TTYMSK	;CAN TERMINAL HANDLE TABS?
	JRST	TOUT4		;YES, OUTPUT LITERAL TAB
	MOVEI	R,7		;MASK FOR TAB-ALIGNEDNESS
	MOVEI	T," "		;SPACE FOR TAB-FAKEDNESS
	PUSHJ	P,TOUT4		;PRINT A SPACE
	TDNE	R,TOHPS		;REACHED A TAB-STOP YET?
	JRST	.-2		;NO, KEEP SIMULATING
	MOVEI	T,.CHTAB	;TRUTH IN ADVERTISING (ETC.)
	POPJ	P,		;AND RETURN HAVING OUTPUT A <TAB>

ECHO3:	CAIN	T,.CHESC	;CONVERT ESC
	JRST	[PUSH	P,T	;SAVE ORIG CHAR
		MOVEI	T,"$"
		JRST	TOUT3]
	CAIL	T," "		;CONTROL CHAR?
	JRST	TOUT4		;NO
	PUSH	P,T		;YES, INDICATE
	MOVEI	T,"^"		;VIA ^x
	PUSHJ	P,TOUT4
	MOVE	T,(P)		;RECOVER ORIG CHAR
	ADDI	T,100		;CONVERT TO PRINTING EQUIVALENT
				;FALL INTO TOUT3

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
;HERE TO TYPE CHAR IN T, RESTORE ORIG CHAR FROM STACK, AND RETURN

TOUT3:	PUSHJ	P,TOUT4		;TYPE LITERAL CHARACTER
	POP	P,T		;RESTORE ORIGINAL
	POPJ	P,		;RETURN FROM TOUT/ECHO

TOUT4:				;OUTPUT THE CHARACTER

IFN FTEXEC,<
	SKPUSR			;EXEC MODE?
	JRST	XTOUT		;YES, USE EXEC TYPEOUT ROUTINES
> ;END IFN FTEXEC

IFN FTDEC10,<
	OUTCHR	T		;OUTPUT A CHARACTER
> ;END IFN FTDEC10

IFN FTDEC20,<
	EXCH	T1,T
	PBOUT%			;CHAR TO TTY FROM T1
	EXCH	T1,T
> ;END IFN FTDEC20

TOUT6:	CAIN	T,.CHTAB	;OUTPUT A <TAB>?
	JRST	TOUT7		;YES, SPECIAL ADDITION
	CAIN	T,.CHCNH	;A <BS>?
	JRST	TOUT8		;YES, NEGATIVE ADDITION
	CAIE	T,.CHLFD	;NO, HOW ABOUT A <LF>?
	CAIN	T,.CHBEL	;OR A <BEL>?
	POPJ	P,		;YES, DON'T CHANGE HORIZONTAL POSITION
	CAIE	T,.CHCNU	;A ^U (DOESN'T ECHO EVEN IN USER MODE)
	CAIN	T,.CHDEL	;A <DEL>?
	POPJ	P,		;YES, DON'T CHANGE HORIZONTAL POSITION
	AOS	TOHPS		;NO, ADVANCE ONE PRINTING CHARACTER
	CAIN	T,.CHCRT	;A <CR>?
	SETOM	TOHPS		;YES, BACK TO LEFT MARGIN
	CAIGE	T," "		;LEFT WITH A CONTROL CHARACTER?
	AOS	TOHPS		;YES, ACCOUNT FOR "^" FORM OF ECHO
				; (THIS CAN ONLY HAPPEN IN USER MODE)
	POPJ	P,		;RETURN FROM TOUT/ECHO

TOUT7:	MOVEI	T,10		;TABS MAY MOVE 8 SPACES
	ADD	T,TOHPS		;ACCOUNT FOR THAT MUCH
	ANDCMI	T,7		;MAKE IT MOD 8 (SORT OF)
	MOVEM	T,TOHPS		;NEW CARRIAGE POSITION
	MOVEI	T,.CHTAB	;RESTORE T
	POPJ	P,		;RETURN

TOUT8:	SOS	TOHPS		;BACKSPACES MOVE BACKWARDS
	POPJ	P,		;RETURN
IFN FTEXEC,<

;HERE TO TYPE THE CHAR IN AC T IF IN EXEC MODE.

XTOUT:	SKIPE	TTSUP		;SUPPRESSING OUTPUT?
	JRST	XTOUT8		;YES, JUST RETURN

;FIRST CHECK FOR KA/KI STYLE I/O

	SKPKA			;ON A KA-10?
	SKPNKI			;OR A KI-10?
	CAIA			;YES TO ONE OF THE ABOVE
	JRST	XTOUT0		;NO, TRY OTHERS
	MOVE	TT2,T		;WORKING COPY OF CHARACTER
	IMULI	TT2,200401	;GENERATE PARITY
	AND	TT2,[11111111]
	IMUL	TT2,[11111111]
	TLNE	TT2,10
	TRC	T,200		;MAKE PARITY EVEN
	CONSZ	TTY,20
	JRST	.-1
	DATAO	TTY,T
	JRST	XTOUT8		;CLEAN UP AND RETURN

;CHECK TO SEE IF ON A KL10 AND DO KL10 XTOUT IF SO.

XTOUT0:	SKPKL			;KL10?
	JRST	XTOUT2		;NO, GO CHECK KS10
	EXCH	TT,TT2		;SAVE TT
	PUSHJ	P,GVEPT		;GET EPT BASE IN TT
	  HALT	.		;NOT IN ADDRESS SPACE!
	EXCH	TT,TT2		;PUT ADDRESS IN TT2
	MOVEI	T,.DTMTO(T)	;GET MONITOR OUTPUT COMMAND AND CHAR IN T
	MOVEM	T,DTECMD(TT2)	;PUT IN COMMAND WORD
	SETZM	DTEMTD(TT2)	;CLEAR DONE FLAG.
	XCT	DING11		;RING THE DOORBELL
	SKIPN	DTEMTD(TT2)	;DONE YET?
	JRST	.-1		;NO, LOOP
	JRST	XTOUT8		;YES, GO RESTORE CHAR AND RETURN
;STILL FTEXEC

;HERE IF NOT ON A KL10.  CHECK TO SEE IF WE ARE ON A KS10.

XTOUT2:	SKPKS			;KS-10?
	JRST	XTOUT4		;NO, GO CHECK OTHERS
	MOVE	TT2,CTYOWD	;ON A KS10, GET OUTPUT ADDRESS
	TXNN	TT2,CTYORD	;OUTPUT READY?
	JRST	XTOUT3		;YES
	MOVE	TT2,SAVAPR	;NO, GET APR STATE
	ANDI	TT2,7		;GET PI ASSIGNMENT
	WRAPR	INT80(TT2)	;INTERRUPT 8080
XTOUT3:	MOVE	TT2,CTYOWD	;OUTPUT WORD
	TXNE	TT2,CTYORD	;OUTPUT READY?
	JRST	XTOUT3		;NO WAIT
	IORI	T,CTYORD	;YES FLAG CHARACTER
	MOVEM	T,CTYOWD	;STORE CHARACTER FOR 8080
	MOVE	TT2,SAVAPR	;GET APR STATE
	ANDI	TT2,7		;REDUCE TO PI ASSIGNMENT
	WRAPR	INT80(TT2)	;NUDGE 8080
	JRST	XTOUT8		;GO RESTORE CHAR AND RETURN


;UNKNOWN PROCESSOR TYPE

XTOUT4:	HALT	.		;UNKNOWN PROCESSOR TYPE


;HERE TO RESTORE T AND RETURN FROM XTOUT.

XTOUT8:	ANDI	T,177		;AND T DOWN TO ORIGINAL 7 BITS
	JRST	TOUT6		;UPDATE COUNTERS

> ;END IFN FTEXEC
SUBTTL TELETYPE IO LOGIC -- SAVE/RESTORE

IFE FTFILE,<

;TTYRET -- SUBROUTINE TO SAVE USER TTY STATE ON RETURN TO DDT
;CALL:
;	PUSHJ	P,TTYRET
;	RETURN

TTYRET:	PUSHJ	P,.CLCSH	;CLEAR THE CACHE, MAYBE
	SETOM	LASTPG		;DON'T KNOW ABOUT ANY PAGES
	SETZM	SYMVAL		;DON'T TRUST THE SYMBOL TABLE POINTERS

IFN FTEXEC,<
	SKPUSR
	JRST	XTTYRE
> ;END IFN FTEXEC

IFN FTDEC10,<
	MOVE	T,[2,,W1]	;SENSE. UUO: 2 ARGS, IN W1 AND W2
	MOVX	W1,SIXBIT/TTY/	;DEVICE TO READ STATUS OF IS TTY:
	MOVE	W2,[3,,A]	;MONITOR STORES STATUS IN A-C
	SENSE.	T,UU.PHY	;READ STATUS
	  JFCL			;OLD MONITOR?
	SKIPN	SAVTTY		;ALREADY SAVED?
	HRROM	B,SAVTTY	;REMEMBER STATUS, INSURE NON-ZERO
	MOVE	T,[2,,W1]	;CLRST. UUO: 2 ARGS, IN W1 AND W2
	MOVX	W1,SIXBIT/TTY/	;DEVICE TO SET IS TTY:
	SETZ	W2,		;SET TO NORMAL (ZERO) STATUS (TURN ON ECHO ETC)
	CLRST.	T,UU.PHY	;DO IT
	  JFCL			;OLDER MONITOR?
	MOVX	W1,.TODIS	;THE TERMINAL-IS-A-DISPLAY CODE
	SKIPN	W2,TTDEV	;GOT AN $Y'ED TERMINAL?
	SETO	W2,		;NO, -1 := US
	MOVE	T,[2,,W1]	;TRMOP. ARG POINTER TO
	TRMOP.	T,		;READ DISPLAY MODE
	 SETZ	T,		;???
	DPB	T,[POINTR TTYMSK,TT$DEL]  ;SET <DEL> HANDLING
	MOVEI	T,1		;TAB SUPPORT
	DPB	T,[POINTR TTYMSK,TT$TAB]  ;SET <TAB> LITERAL MODE
> ;END IFN FTDEC10

;CONTINUED ON NEXT PAGE
;STILL IFE FTFILE

;FALL IN FROM ABOVE

IFN FTDEC20,<
	MOVEI	T1,.FHSLF
	DIR%
	SKIPE	SAVTTY		;ALREADY SAVED?
	JRST	TTYRE4		;YES, DON'T SAVE IT AGAIN
	RTIW%			;GET INTERRUPT MASK
	MOVEM	T2,SAVTIW	;SAVE IT
	MOVEI	T1,.PRIIN
	RFMOD%			;GET MODES
	MOVEM	T2,SAVTTY
	RFCOC%			;GET CC MODES
	DMOVEM	T2,SAVTT2
	MOVEI	T1,1		;TAB SIMULATION BIT
	DPB	T1,[POINTR TTYMSK,TT$TAB]  ;MONITOR ALWAYS DOES TABS

TTYRE4:	DMOVE	T1,[EXP .FHSLF,0] ;NEW MASK FOR THIS FORK IS ZERO
	STIW%			;SET NEW INTERRUPT MASK
	MOVEI	T1,.PRIIN	;TIME TO SETUP OUR TERMINAL
	MOVE	T2,SAVTTY	;GET OLD RFMOD% WORD
	TXZ	T2,TT%WAK+TT%DAM
	TXO	T2,<TT%WKF+TT%WKN+TT%WKP+TT%ECO+FLD(.TTASC,TT%DAM)>
	SFMOD%
	DMOVE	T2,[BYTE (2) 1,1,1,1,1,1,1,2,1,2,2,1,1,2,1,1,1,1
		    BYTE (2) 1,1,1,1,1,1,1,1,1,3,1,1,1,1]
	SFCOC%			;SETUP PROPER DDT MODES
> ;END IFN FTDEC20


IFN FTEXEC!FTMON,<JRST TTYRE6>	;GO CHECK HIDDEN SYMBOL PROCESSING
IFE FTEXEC!FTMON,<POPJ P,>	;ALL DONE WITH TTYRET
;STILL IFE FTFILE

IFN FTEXEC,<

;HERE TO SAVE TTY STATUS IF IN EXEC MODE.

XTTYRE:	SETZM	PAGVAL		;DON'T TRUST PAGING DATA
	SETZM	PAGVAS		;OR ALTERNATE PAGING DATA
	SKPKL			;ON A KL-10?
	JRST	XTTYR6		;NO, GO CHECK OTHER CPUS


;HERE IF ON A KL10.  NEED TO FIND THE MASTER -11, SAVE ITS DTE STATE,
;AND THEN SAVE THE ACCOUNTING METERS IN THE EPT (MAY NEED TO BE IN SAVEG).

	SKIPE	SAVTTY		;PGM MODES IN EFFECT?
	JRST	XTTYR5		;NO, DON'T SAVE
	CONI	MTR,MTRCNI	;SAVE MTR STATE
	CONI	TIM,TIMCNI	;SAVE TIM STATE
	CONI	PAG,T		;GET PAGING BITS
	SETZM	KIPAG		;CLEAR FLAGS TO RESET THEM
	SETZM	KLPAG		; . . .
	TXNN	T,1B21		;1B21 = KL-PAGING
	SETOM	KIPAG		;IS KI-PAGING
	TXNE	T,1B21		;1B21 = KL-PAGING
	SETOM	KLPAG		;IS KL-PAGING
	MOVSI	T,-DTEN		;POLL ALL DTES
	MOVE	W2,[CONSO DTE,DTERES]	;GET TEST WORD
	MOVE	W1,[CONSZ DTE,PI0ENB+7]	;TEST FOR PI0 ENABLED
				;   OR PI ASSIGNMENT UP
	MOVE	W,[CONO DTE,0]	;PROTOTYPE CONO
XTTYR1:	XCT	W1		;PI 0 UP ON THIS GUY?
	JRST	XTTYR2		;YES, CHECK TO SEE IF MASTER
	HRRI	W,PIENB+PI0ENB	;NO. SET PI0
	XCT	W		;CONO TO SET PI0
	XCT	W1		;NOW UP?
	TRZA	W,PI0ENB	;YES, TURN OFF ZERO
	JRST	XTTYR3		;NO. DOESN'T EXIST THEN
	XCT	W		;TURN PI 0 BACK OFF
XTTYR2:	XCT	W2		;THIS THE MASTER?
	JRST	XTTYR4		;YES, GO REMEMBER IT
XTTYR3:	ADD	W2,[1B9]	;NEXT DTE
	ADD	W,[1B9]
	ADD	W1,[1B9]	;ADJUST ALL I/O INSTRUCTIONS
	AOBJN	T,XTTYR1	;POLL ALL OF THEM
	HALT	.		;WHAT CAN WE DO?

;CONTINUED ON NEXT PAGE
;STILL FTEXEC & NOT FTFILE

;CONTINUED FROM PREVIOUS PAGE

;HERE WHEN WE HAVE FOUND THE MASTER DTE

XTTYR4:	MOVEI	T,0(T)		;GET NUMBER OF MASTER DTE
	MOVEM	T,MSTRDT	;SAVE IT
	LSH	T,^D<35-9>	;POSITION CODE IN B9
	ADD	T,[CONO DTE,TO11DB]	;GET THE INSTRUCTION
	MOVEM	T,DING11	;SAVE IT
	EXCH	TT,T		;SAVE TT
	PUSHJ	P,GVEPT		;GET EPT BASE IN TT
	  HALT	.		;NOT IN ADDRESS SPACE!
	EXCH	TT,T		;PUT ADDRESS IN T
	MOVE	W2,MSTRDT	;GET MASTER'S NUMBER
	LSH	W2,3		;HIS CHUNK
	ADDB	T,W2		;THE POSITION IN THE EPT
	MOVSI	T,DTEII(T)	;START OF EPT LOCATIONS TO SAVE
	HRRI	T,SAVTTY	;WHERE TO SAVE THEM
	BLT	T,SAVDRW
	SKIPN	DTEEPW(W2)	;USING PRIMARY PROTOCAL?
	JRST	XTTYR5		;NO. GO ON
	MOVE	T,MSTRDT	;GET MASTER'S ID
	LSH	T,^D<35-9>	;POSITION CODE IN B9
	ADD	T,[CONSZ DTE,TO11DB]	;GET TEST INSTRUCTION
	XCT	T		;WAIT FOR -11 TO ANSWER ALL DOORBELLS
	JRST	.-1		;THE WAIT
XTTYR5:	CONO	MTR,MTRLOD+MTRTBF	;TURN OFF ALL METERS AND TIME BASE
	CONO	TIM,0		;TURN OFF INTERVAL TIMER
	MOVSI	T,(HALT)
	MOVEM	T,DTEII(W2)	;NO INTERRUPTS
	SETZM	DTEEPW(W2)	;CLEAR EXAMINE PROTECTION WORD
	MOVEI	T,.DTMMC	;TURN ON SECONDARY TTY I/O SYSTEM
	PUSHJ	P,DTEDCM	;TELL THE -11 TO DO IT
	JRST	TTYRE6		;GO CHECK HIDDEN SYMBOL PROCESSING
;STILL FTEXEC & NOT FTFILE

;HERE IF NOT ON A KL10.  CHECK TO SEE IF ON A KS10.

XTTYR6:	SKPKS			;ON A KS10?
	JRST	XTTYR8		;NO, GO CHECK OTHER PROCESSORS
	MOVE	T,RLWORD	;GET KEEP ALIVE STATE
	SKIPE	SAVTTY		;ALREADY HAVE IT?
	JRST	XTTYR7		;YES, DON'T SAVE AGAIN
	MOVEM	T,SAVTTY	;NO, SAVE IT
	RDTIMS	SAVTIM		;SAVE TIMEBASE
	CONI	PAG,TT1		;GET PAGING BITS
	TXNN	TT1,1B21	;1B21 = KL-PAGING
	SETOM	KIPAG		;IS KI-PAGING
	TXNE	TT1,1B21	;1B21 = KL-PAGING
	SETOM	KLPAG		;IS KL-PAGING
XTTYR7:	TXZ	T,KPACT		;STOP KEEP ALIVE
	MOVEM	T,RLWORD	;TELL 8080
	JRST	TTYRE6		;GO CHECK HIDDEN SYMBOLS


;NOT ON A KL10 OR A KS10.  MUST BE ON A KA10 OR A KI10

XTTYR8:	SKIPE	SAVTTY		;ALREADY HAVE IT?
	JRST	XTTYR9		;YES
	CONI	TTY,SAVTTY	;SAVE PI ASSMT
	CONO	TTY,0		;SET PI ASSMT TO 0
	MOVSI	W2,1
	CONSZ	TTY,120		;WAIT FOR PREVIOUS ACTIVITY TO FINISH
	SOJG	W2,.-1		;BUT DON'T WAIT FOREVER
	CONI	TTY,W2		;UPDATE STATUS BITS
	DPB	W2,[POINT 15,SAVTTY,32]
	DATAI	TTY,W2
	HRLM	W2,SAVTTY
XTTYR9:	CONO	TTY,3410	;INIT TTY FOR DDT
	JRST	TTYRE6		;GO CHECK HIDDEN SYMBOLS

> ;END IFN FTEXEC
;STILL IFE FTFILE

IFN FTEXEC!FTMON,<

;HERE TO INVESTIGATE WHETHER THE SYMBOL TABLE IS IN AN ALTERNATE
;ADDRESS SPACE OR NOT, AND SET UP TO SWITCH MAPS IN SYMSET IF SO.

TTYRE6:

IFN FTEXEC,<
	SKPEXC			;IN EXEC MODE?
	JRST	TTYRE8		;NO, DON'T LOOK AT .JBEDV
> ;END IFN FTEXEC

	SETZM	HSBLK		;DO ALL FETCHS IN CURRENT SPACE FOR NOW
	MOVEI	R,.JBEDV	;POINTER TO EXEC DATA VECTOR
	PUSHJ	P,FETCHV	;GET IT
	  JRST	TTYRE8		;NOT THERE
	JUMPE	T,TTYRE8	;POINTER NOT SET UP
	MOVE	R,T		;POINT TO BLOCK
	ADDI	R,.EDCNT	;GET COUNT WORD
	PUSHJ	P,FETCHV	; . . .
	  JRST	TTYRE8		;ILLEGAL ADDRESS
	TXC	T,SIXBIT/EDV/	;CHECK FIRST 3 CHARS FOR RIGHT VALUE
	TLNN	T,-1		;ARE THEY 'EDV'?
	CAIGE	T,.EDHSF+1	;YES, BUT IS THE BLOCK LONG ENOUGH?
	JRST	TTYRE8		;NO, PRETEND WE DIDN'T SEE IT
	ADDI	R,.EDHSB-.EDCNT	;POINT TO HIDDEN SYMBOL SWAP BLOCK
	PUSHJ	P,FETCHV	;GET CONTENTS
	  JRST	TTYRE8		;NOT THERE
	JUMPE	T,TTYRE8	;0 MEANS SYMBOLS NOT HIDDEN
	MOVEM	T,TTEM1		;STORE ADDRESS OF BLOCK

;FALL INTO NEXT PAGE
;STILL IFE FTFILE AND IFN FTEXEC!FTMON

;FALL IN FROM ABOVE

IFN FTEXEC,<
;NOW LOOP OVER THE HIDDEN SYMBOL BLOCK, CHECKING ALL THE SUB-BLOCKS FOR
;LEGALITY.

	MOVEM	R,TTEM2		;SAVE R FOR A WHILE
	MOVE	R,T		;ADDRESS OF BLOCK
	PUSHJ	P,FETCHV	;GET FIRST WORD (TOTAL COUNT)
	  JRST	TTYRE8		;NOT ACCESSIBLE
	SUBI	T,1		;WE JUST PASSED ONE OF THE WORDS


;BACK HERE FOR EACH SUB-BLOCK

TTYRE7:	MOVEM	T,TTEM3		;SAVE CURRENT COUNT
	MOVE	R,T		;CALCULATE POINTER TO NEXT BLOCK
	SUBI	R,3		;OFFSET TO BEGINNING OF SUB-BLOCK
	ADD	R,TTEM1		;ADDRESS OF NEXT SUB-BLOCK
	PUSHJ	P,FETCHV	;FIRST WORD OF SUB-BLOCK
	  JRST	TTYRE8		;NOT ACCESSIBLE
	MOVE	W,T		;SAVE COUNT
	ADDI	R,1		;POINT TO HARDWARE BLOCK ADDRESS
	PUSHJ	P,FETCHV	;GET ADDRESS
	  JRST	TTYRE8		;NOT THERE
	MOVE	S,T		;SAVE IN S FOR A WHILE
	ADDI	R,1		;POINT TO SYMBOL BLOCK ADDRESS
	PUSHJ	P,FETCHV	;GET ADDRESS
	  JRST	TTYRE8		;NOT THERE
	MOVE	W1,T		;SAVE IN W1
	ADDI	R,1		;POINT TO SAVE BLOCK ADDRESS
	PUSHJ	P,FETCHV	;GET ADDRESS
	  JRST	TTYRE8		;NOT THERE
	MOVE	W2,T		;SAVE IN W2

;FALL INTO NEXT PAGE
;STILL IFE FTFILE AND IFN FTEXEC!FTMON AND IFN FTEXEC

;FALL IN FROM ABOVE

;NOW THAT WE HAVE THE ADDRESS OF EACH SUB-SUB-BLOCK, CHECK THEM OUT.

	MOVE	R,S		;PUT HARDWARE BLOCK ADDRESS IN R
	MOVE	S,W		;COUNT IN S
	XMOVEI	T,HSBITS	;VALIDATION ROUTINE
	PUSHJ	P,CHKRNG	;CHECK BLOCK
	  JRST	TTYRE8		;NO GOOD
	MOVE	R,W1		;SYMBOL BLOCK ADDRESS IN R
	MOVE	S,W		;COUNT IN S
	XMOVEI	T,HSBITS	;VALIDATION ROUTINE
	PUSHJ	P,CHKRNG	;CHECK BLOCK
	  JRST	TTYRE8		;NO GOOD
	MOVE	R,W2		;SAVE BLOCK ADDRESS IN R
	MOVE	S,W		;COUNT IN S
	XMOVEI	T,HSBITS	;VALIDATION ROUTINE
	PUSHJ	P,CHKRNG	;CHECK BLOCK
	  JRST	TTYRE8		;NO GOOD
	MOVE	T,TTEM3		;GET CURRENT COUNT
	SUBI	T,3		;BLOCKS ARE 4 WORDS LONG
	SOJG	T,TTYRE7	;LOOP OVER ALL BLOCKS

	MOVE	R,TTEM2		;ALL DONE, RESTORE R
> ;END IFN FTEXEC

	ADDI	R,.EDSYM-.EDHSB	;ADVANCE TO SYMBOL TABLE WORD
	PUSHJ	P,CHKADR	;MAKE SURE ACCESSIBLE
	TXC	TT,PG$EXI!PG$REA!PG$WRT	;COMPLEMENT BITS THAT MUST BE ON
	TXNE	TT,PG$EXI!PG$REA!PG$WRT!PG$SPY!PG$ABZ	;ADDR OK?
	JRST	TTYRE8		;NO, ABORT
	ADDI	R,.EDUSY-.EDSYM	;POINT TO USY TABLE WORD
	PUSHJ	P,CHKADR	;MAKE SURE ACCESSIBLE
	TXC	TT,PG$EXI!PG$REA!PG$WRT	;COMPLEMENT BITS THAT MUST BE ON
	TXNE	TT,PG$EXI!PG$REA!PG$WRT!PG$SPY!PG$ABZ	;ADDR OK?
	JRST	TTYRE8		;NO, ABORT

;CONTINUED ON NEXT PAGE
;STILL IFE FTFILE AND IFN FTEXEC!FTMON

;FALL IN FROM ABOVE

IFN FTEXEC,<
	ADDI	R,.EDHSF-.EDUSY	;POINT TO HIDDEN SYMBOL FLAG POINTER
	PUSHJ	P,FETCHV	;GET THE ADDRESS
	  JRST	TTYRE8		;NO GOOD
	EXCH	R,T		;SAVE IN T FOR A WHILE
	PUSHJ	P,CHKADR	;SEE ABOUT ADDRESS
	TXC	TT,PG$EXI!PG$REA!PG$WRT	;BITS THAT MUST BE ON
	TXNE	TT,PG$EXI!PG$REA!PG$WRT!PG$SPY	;IS BLOCK OK?
	JRST	TTYRE8		;NO, DON'T USE IT
	MOVEM	R,ADRSPC	;SAVE FOR NEWSPC
	SKIPE	@ADRSPC		;HIT BREAKPOINT INSIDE OTHER COPY OF DDT
				;WHILE THAT DDT WAS IN ALTERNATE SPACE?
	SETZM	TTEM1		;YES, WE WILL ALWAYS STAY IN SYMBOL SPACE
	EXCH	R,T		;BACK TO OLD R
	SUBI	R,.EDHSF-.EDUSY	;BACK TO GOOD UNDEFINED POINTER
> ;END IFN FTEXEC

	HRRM	R,USYMP		;OK, SET UP TO USE THAT UNDEFINED POINTER
	SUBI	R,.EDUSY-.EDSYM	;BACK TO SYM WORD
	HRRM	R,SYMP		;SET UP TO USE IT
	MOVE	T,TTEM1		;ADDRESS OF MONITOR'S BLOCK OR ZERO
	MOVEM	T,HSBLK		;*** TURN ON HIDDEN SYMBOL PROCESSING ***
	POPJ	P,		;DONE, RETURN FROM TTYRET


;HERE IF WE AREN'T GOING TO USE AN ALTERNATE SYMBOL ADDRESS SPACE.

TTYRE8:	SETZM	HSBLK		;REMEMBER NOT TO
	MOVEI	R,.JBSYM	;WHERE SYMBOL TABLE POINTER COMES FROM
	HRRM	R,SYMP		;STORE FOR SYMBOL TABLE ROUTINES
	MOVEI	R,.JBUSY	;WHERE UNDEFINEDS COME FROM
	HRRM	R,USYMP		;STORE
	POPJ	P,		;RETURN FROM TTYRET


IFN FTEXEC,<

;ROUTINE TO CHECK SUB-SUB HIDDEN SYMBOL BLOCKS FOR VALIDITY.
;CALLED FROM CHKRNG.

HSBITS:	TXC	TT,PG$EXI!PG$REA!PG$WRT	;BITS THAT MUST BE ON
	TXNN	TT,PG$EXI!PG$REA!PG$WRT!PG$SPY	;BITS THAT MUST NOW BE OFF
	AOS	(P)		;GOOD, GIVE OK RETURN
	POPJ	P,		;RETURN TO CALLER

> ;END IFN FTEXEC
> ;END IFN FTEXEC!FTMON
;STILL IFE FTFILE

;TTYLEV -- SUBROUTINE TO RESTORE THE TTY STATE BEFORE LEAVING DDT
;CALL:
;	PUSHJ	P,TTYLEV
;	RETURN

TTYLEV:
IFN FTEXEC,<
	SKPUSR
	JRST	XTTYLE
> ;END IFN FTEXEC

IFN FTDEC10,<
	MOVE	T,[2,,W1]	;CLRST. UUO: 2 ARGS, IN W1 AND W2
	MOVX	W1,SIXBIT/TTY/	;DEVICE IS TTY:
	HRRZ	W2,SAVTTY	;RESTORE OLD SETSTS BITS
	TRNE	W2,-1		;ANY STATUS TO [RE-]SET TO?
	CLRST.	T,UU.PHY	;DO IT
	  JFCL			;??
	JRST	TTYLE8		;NOTE USER MODES AND RETURN
> ;END IFN FTDEC10

IFN FTDEC20,<
	MOVEI	T1,.PRIIN
	MOVE	T2,SAVTTY
	SFMOD%			;RESTORE MODES
	MOVE	T2,SAVTT2
	MOVE	T3,SAVTT3
	SFCOC%			;RESTORE CC MODES
	MOVEI	T1,.FHSLF
	MOVE	T2,SAVTIW	;RESTORE OLD TTY INTERRUPT MASK
	STIW%			;DO IT
	SKIPGE	SAVSTS		;PSI SYSTEM ON FOR USER?
	EIR%			;YES
	JRST	TTYLE8		;NOTE USER MODES AND RETURN
> ;END IFN FTDEC20
;STILL IFE FTFILE

IFN FTEXEC,<

;HERE TO RESTORE USER STATE (LEAVE DDT) WHEN IN EXEC MODE.

XTTYLE:	PUSHJ	P,NORSPC	;GET BACK TO PROGRAM'S ADDRESS SPACE
	SKPKL			;ON A KL-10?
	JRST	XTTYL2		;NO, GO CHECK OTHER CPUS

;HERE IF ON A KL10.  RESTORE THE DTE STATUS BLOCK STARTING AT DTEII,
;AND RESTORE THE ACCOUNTING AND TIMING METERS.

	MOVE	T,MSTRDT	;GET ID OF MASTER DTE
	LSH	T,3		;FIND EPT CHUNK
	EXCH	TT,W2		;SAVE TT
	PUSHJ	P,GVEPT		;GET EPT BASE IN TT
	  HALT	.		;NOT IN ADDRESS SPACE!
	EXCH	TT,W2		;PUT ADDRESS IN W2
	ADDI	W2,0(T)		;POINT TO BEGINNING OF EPT CHUNK
	MOVEI	T,DTEII(W2)	;WHERE TO DO RESTORE
	HRLI	T,SAVTTY	;WHERE TO RESTORE FROM
	BLT	T,DTEDRW(W2)	;UP THROUGH DEPOSIT, LAST WORD
	HRRZ	T,MTRCNI	;GET SAVED MTR CONI
	CONO	MTR,MTRLOD(T)	;RESTORE ALL STATES
	HRRZ	T,TIMCNI	;GET SAVED TIM CONI
	TRZ	T,TIMDON+TIMICO	;FLUSH CONI-ONLY BITS
	CONO	TIM,0(T)	;RESTORE STATE
	SETZM	SAVTTY		;NOTE PGM MODES NOW IN EFFECT
	CONSZ	PAG,1B22	;IS PAGING NOW ENABLED?
	SKIPN	DTEEPW(W2)	;YES SECONDARY PROTOCOL IN EFFECT,
	POPJ	P,		;JUST RETURN, DON'T TURN IT OFF
	MOVEI	T,.DTNMC	;WE WERE IN REGULAR PROTOCOL, SETUP OFF COMMAND
				;FALL INTO DTEDCM


;KL10 ROUTINE TO SEND A COMMAND TO THE MASTER 11 THROUGH THE DTE.

DTEDCM:	EXCH	TT,TT2		;SAVE TT
	PUSHJ	P,GVEPT		;GET EPT BASE IN TT
	  HALT	.		;NOT IN ADDRESS SPACE!
	EXCH	TT,TT2		;PUT ADDRESS IN TT2
	SETZM	DTEFLG(TT2)	;CLEAR DONE FLAG
	MOVEM	T,DTECMD(TT2)	;STORE COMMAND FOR 11
	XCT	DING11		;RING HIS DOORBELL
	SKIPN	DTEFLG(TT2)	;WAIT FOR FINISH
	JRST	.-1
	POPJ	P,		;RETURN
;STILL FTEXEC & NOT FTFILE

;HERE IF NOT ON A KL10.  CHECK TO SEE IF ON A KS10.

XTTYL2:	SKPKS			;ON A KS10?
	JRST	XTTYL4		;NO, SKIP ON
	DMOVE	TT1,[EXP 0,1000] ;GET A LITTLE TIME
	DADD	TT1,SAVTIM	;BUMP TIME A LITTLE TO KEEP KEEP ALIVE ALIVE
	WRTIMS	TT1		;WRITE NEW TIMEBASE
	MOVE	T,SAVTTY	;GET BACK KEEP ALIVE
	MOVEM	T,RLWORD	;RESTORE ORIGINAL STATE
	JRST	TTYLE8		;NOTE USER MODES AND RETURN


;HERE IF NOT ON A FANCY CPU.  MUST BE ON A KA10 OR KI10.

XTTYL4:	CONSZ	TTY,120		;WAIT FOR LAST OUTPUT
	JRST	.-1
	CONO	TTY,1200	;CLEAR DONE FLAGS
	MOVE	T,SAVTTY
	CONO	TTY,0(T)	;RESTORE USER STATE
;FALL INTO TTYLE8

> ;END IFN FTEXEC


;COMMON RETURN FROM TTYLEV

TTYLE8:
IFN	FTEXEC,<
	SKPEXC			;USER MODE?
	HLLZS	TTYMSK		;YES, CLEAR FANCY <DEL> HANDLING IN CASE
				; WE LATER GET ENTERED AT EXEC LEVEL
> ;END IFN FTEXEC
	SETZM	SAVTTY		;NOTE USER MODES NOW IN EFFECT
	POPJ	P,		;RETURN TO CALLER

> ;END IFE FTFILE
SUBTTL	STORAGE -- LITERALS AND END OF CODE

	XLIST			;THE LITERALS
	LIT
	LIST


IFGE RUNLOC,<IFGE VARLOC,<IFL <VARLOC-RUNLOC>,<
DDTEND:>>>			;DEFINE HERE IF VARIABLES BELOW CODE

END.C:				;END OF CODE

	LEN.C==END.C-BEG.C	;DEFINE HERE TO NOT CONFUSE MACRO


IFGE VARLOC,<			;IF VARIABLES WANT TO GO SOMEWHERE,
				;WE NEED TO CLOSE OFF THE CODE
  IFN FTEX20,<
	.ENDPS	INCOD		;CLOSE OFF -20 EDDT PSECT
  >
  IFGE RUNLOC,<
    IFE FTEX20,<
	.ENDPS	DDTCOD		;CLOSE OFF USER CODE PSECT
    >
  >


;NOW START THE VARIABLES IN THE RIGHT PLACE

 IFE FTEX20!FTMON,<
	.PSECT	DDTVAR/RWRITE,VARLOC	;PUT VARS WHERE THEY BELONG
  >
>

IFN FTMON,<
PHVAR:!				;MDDT ONLY: PURE COPY OF VARIABLES
>


IFGE RUNLOC,<IFGE VARLOC,<IFL <VARLOC-RUNLOC>,<
DDTBEG:!>>>			;DEFINE HERE IF VARIABLES BELOW CODE
SUBTTL	STORAGE -- ALLOCATION MACROS

;MACROS TO DEFINE DATA

IFE FTMON,<				;NORMAL DDTS

DEFINE	DD(NAME,SIZE,CONTENTS)<
IFNB <NAME>,<
NAME:>
	..DD==.
IFNB <CONTENTS>,<
IRP <CONTENTS>,<CONTENTS>>
	BLOCK	<SIZE>-<.-..DD>
> ;END OF DD DEFINITION


;SUPPRESSED DD

DEFINE	DDS(NAME,SIZE,CONTENTS)<
IFNB <NAME>,<
NAME:!>
	..DD==.
IFNB <CONTENTS>,<
IRP <CONTENTS>,<CONTENTS>>
	BLOCK	<SIZE>-<.-..DD>
> ;END OF DDS DEFINITION

> ;END IFE FTMON
IFN FTMON,<				;IN MDDT, THE TAGS ARE OFFSETS
					;FROM DDTPGA.

	..DDPC==0			;HOW MANY LOCATIONS ALLOCATED SO FAR

DEFINE DD(NAME,SIZE,CONTENTS)<
IFNB <NAME>,<
	NAME=DDTPGA+..DDPC>
	..DDPC==..DDPC+<SIZE>
	..DD==.
IFNB <CONTENTS>,<
IRP <CONTENTS>,<CONTENTS>>
	BLOCK	<SIZE>-<.-..DD>
> ;END OF DD DEFINITION

DEFINE DDS(NAME,SIZE,CONTENTS)<
IFNB <NAME>,<
	NAME==DDTPGA+..DDPC>
	..DDPC==..DDPC+<SIZE>
	..DD==.
IFNB <CONTENTS>,<
IRP <CONTENTS>,<CONTENTS>>
	BLOCK	<SIZE>-<.-..DD>
> ;END OF DDS DEFINITION

> ;END OF IFN FTMON
SUBTTL	STORAGE -- MISCELLANEOUS

	DDS(BEG.V,0)		;BEGINNING OF VARIABLES

	DD(NM1A,1,<<MOVEI W2,0>>)	
	DD(ACCCF,1,<<MOVEI T,.-.>>);LEFT HALF OF A,,B
	DD(SEAXCT,1)		;XCT'ED BY SEAR2 IN [NOT]WORD SEARCH
	DD(TOCS,1,<<MOVEI T,.-.>>);GET RIGHT HALF BACK

;WATCH COMMAND ($V) STORAGE

	DD(WTCHA,1)		;ADDRESS BEING WATCHED
	DD(WTCHC,1)		;COUNTER FOR WATCH CYCLES TILL NEXT LISTEN
	DD(WTCHW,1)		;LAST WORD VALUE WATCHED
;VARIABLES FOR LINE BUFFER INPUT

	DD(TTYMSK,1)		;[210] FANCY TTY HANDLING MASK
	DD(TTDEV,1)		;$Y'ED TERMINAL (IF ANY)
IFN	FTEXEC,<DD(TTSUP,1)>	;EXEC-MODE ^O SUPPRESSION FLAG

	DD(CHINC,1)		;COUNT OF CHARACTERS
	DD(WAKALL,1)		;NON-0 TO WAKEUP ON EVERYTHING
	DD(ONES4,4,<-1,-1,-1,-1>);WAKEUP MASK

;*** DO NOT REORDER THE FOLLOWING ***
	DD(TEXTIB,1,<10>)	;TEXTI ARG BLOCK - SIZE
IFN	FTDEC20,<
	DD(,1,<RD%BRK+RD%TOP+RD%PUN+RD%RND+RD%JFN+RD%BBG+RD%SUI>) ;FLAGS
	DD(,1,<<.PRIIN,,.PRIOU>>) ;INPUT/OUTPUT JFNS
>
	DD(CHINP,1)		;POINTER TO NEXT CHAR
	DD(LINSPC,1)		;FREE SPACE COUNT
	DD(LINDB,1,<<POINT 7,LINBF>>);BEGINNING OF BUFFER
	DD(LINBP,1,<<POINT 7,LINBF>>);BEGINNING OF ^R BUFFER
	DD(ETXTB,1)		;WAKEUP TABLE (ALL ONES)
	DD(,1)			;BACKUP LIMIT POINTER
;***END OF "DO NOT REORDER" BLOCK***

IFN	FTDEC10!FTEXEC,<
	DD(SAVCHR,1)		;PRESET RESULT FOR NEXT CALL TO RDBIN
	DD(LASCHR,1)		;ANSWER FROM LAST CALL TO RDBIN
>

	NLINBF==^D20
	DD(LINBF,NLINBF)	;LINE BUFFER

IFN	FTYANK,<
IFN	FTEXEC,<
	DD(EPTPTR,1)		
	DD(EPTRBF,5)		;BUFFER SO PTR WONT CHATTER
	DD(EPTRND,1,<<POINT 7,EPTRBF+4,34>>);PNTR FOR LAST CHAR IN BUF
> ;END IFN FTEXEC
	DD(COMAND,1)		;.NE. 0 IF IN COMMAND FILE
	DD(PTDFLG,1)		;EOF SEEN ON COMMAND FILE
	YFLLEN==.FOLEB+1
	DD(YFLBLK,YFLLEN)	;FILOP. BLOCK FOR COMMAND FILE
	YLKLEN==.RBSIZ+1
	DD(YLKBLK,YLKLEN)	;LOOKUP BLOCK FOR COMMAND FILE
	YPTLEN==.PTPPN+5+2
	DD(YPTBLK,YPTLEN)	;PATH BLOCK FOR COMMAND FILE
	DD(YASWF,1)		;.NE. 0 THEN ABORT $Y ON COMMAND ERROR
	DD(CBUF,3)		;COMMAND FILE BUFFER RING HEADER
	DD(YBFBUF,YBFSIZ)	;BUFFER FOR READING COMMAND FILE
> ;END FTYANK

	DD(TOHPS,1)		;"CARRIAGE" POSITION (FOR OUTPUT)
SUBTTL	STORAGE -- $X LOGIC AND PATCH COMMAND

IFE	FTFILE,<
;VARIABLES USED IN $X LOGIC

	DD(I.PXC,1)		;-1 IF $X01 CALLED FROM $PX
	DD(I.PXF,1)		;SAVED FLAGS IN $PX ROUTINE

	DD(I.REP,1)		;$X REPEAT COUNTER
	DD(I.LOG,1)		;$X COUNTER (FOR $P)
	DD(I.NST,1)		;INSTRUCTION BEING EXECUTED
	DD(I.NSTA,1)		;AC FIELD OF INST BEING EXECUTED
	DD(I.NSTE,1)		;E FIELD OF INST BEING EXECUTED
	DD(I.NEA2,1)		;SECOND EA (E.G., FOR BYTE POINTER)
	DD(I.NSTP,1)		;PC (A LA JSP) OF INST BEING EXECUTED
	DD(I.NPC,1)		;ORIGINAL USER PC OF INSTRUCTION
				; (BEFORE LAST $X CYCLE)
	DD(I.NJMP,1)		;UNCONDITIONAL (JRST, ETC.) JUMP ADDRESS
	DD(I.NECJ,1)		;COPY OF ERCAL/ERJMP IF PRESENT
	DD(I.NJR0,1)		;FIRST JRST INTERCEPT BLOCK WORD
	DD(I.NJR1,1)		;SECOND . . .	*****************************
	DD(I.NJR2,1)		;THIRD . . .	* NOTE THIS BLOCK ALSO USED *
	DD(I.NJR3,1)		;FOURTH . . .	*  FOR INIT UUO SIMULATION  *
	DD(I.NJR4,1)		;FIFTH . . .	*****************************
	DD(I.KRCK,1)		;KS-10 KROCK TYPEOUT FLAG
	DD(I.NXIT,1)		;DANGEROUS INSTRUCTION FLAG
	DD(FLAGS,1)		;SAVES DDT FLAG REGISTER
	DD(LOCSAV,1)		;SAVES LOCATION OF INST BEING EXECUTED
	DD(SAFETY,1)		;SAVES T
	DD(SAV0,1)		;SAVES AC 0 IN SWAP ROUTINE
	DD(XCTS,1)		;XCT DEPTH COUNTER
> ;END FTFILE

;VARIABLES FOR PATCH COMMAND

	DD(PTLOC,1)		;PATCH ADDRESS
	DD(PTLLC,1)		;OLD LLOCO VALUE
	DD(PTWRD,1)		;ORIGINAL WORD AT OLD LLOCO
	DD(PTFIX,1)		;ADDRESS OF SYM TO FIX UP
	DD(PTORG,1)		;-1 IF PTLOC FROM SYMBOL, 1 IF .JBFF, 0 NEITHER
	DD(PTAFTR,1)		;[233] 0 IF BEFORE, -1 IF AFTER
	DD(PTSYM,1)		;SYMBOL USED IN PATCHING
SUBTTL  STORAGE -- BREAKPOINTS

IFE	FTFILE,<
	DD(XSAVE,1)		;FLAGS FOR 30-BIT SAVE PC
	IF1,<PURGE SAVE>	;BYPASS MACRO BUG, SAVE IS A JSYS TOO
	DD(SAVE,1)		;SAVE THE ACS AND PI SYSTEM
	DD(,1,<JRST SAVEG>)

	DD(BPT$B,0)		;START OF BREAKPOINT STORAGE

	.PHASE	0		;DEFINE TAGS RELATIVE TO ZERO

B$ADR:!	DD(,1)			;.GT. 0 THEN ADDRESS OF BREAKPOINT
B$XCT:!	DD(,1)			;	CONDITIONAL BREAK INSTRUCTION
B$CNT:!	DD(,1)			;	PROCEED COUNT (BREAK WHEN 0)
B$OPN:!	DD(,1,-1)		;.GE. 0 THEN ADDRESS TO OPEN ON BREAKPOINT
B$FLG:!	DD(,1)			;	BREAKPOINT FLAGS
	BP$PRO==1B0		;		AUTO-PROCEED
B$INS:!	DD(,1)			;	USER INSTRUCTION WHEN USER RUNNING
B$BPT:!	DD(,1)			;	BREAKPOINT JSR'S TO HERE
B$JSR:!	DD(,1,<JSR BCOM>)	;	JSR BCOM

	B$SIZ==.-B$ADR		;LENGTH OF BREAKPOINT BLOCK

	.DEPHASE		;BACK TO NORMAL ADDRESSING

	DD(,B$SIZ*NBP)		;STORAGE FOR REST OF BREAKPOINTS

	DDS(BPT$E,0)		;LAST LOCATION + 1 USED BY BREAKPOINTS

;$0BPT IS A GLOBAL LOCATION WHICH ANY USER PROGRAM MAY USE (JSR TO) IN
;ORDER TO CAUSE AN UNSOLICITED BREAKPOINT TO OCCUR (RATHER THAN MERELY
;JRST'ING TO DDT## - THE JSR TO $0BPT IS $P'ABLE). ALSO, OPERATING SYS-
;TEMS MAY UTILIZE THIS ENTRY POINT TO ENABLE USERS TO ARBITRARILY BREAK
;PROGRAM EXECUTION AND ENTER DDT IN A PROGRAM-CONTINUABLE FASHION.

	$0BPT==BPT$B+B$BPT
IFE FTMON,<INTERN	$0BPT>
	DD(BCOM,1)		;BREAKPOINTS JSR TO HERE FIRST
	DD(,1,<JRST BCOMG>)	;BCOMG DOES ALL THE REAL WORK

	DD(XLEAVE,1)		;PC FLAGS FOR NON-ZERO SECTION ON BREAKPOINT
	DD(LEAVE,1)		;PC ON BREAKPOINT TO GO TO IXCT8

	DD(BPTIP,1)		;.NE. 0 IF BREAKPOINT IN PROGRESS ($P LEGAL)
	DD(BPTDX,1)		;BREAKPOINT INDEX (NUMBER TIMES B$SIZE)

	DD(SWTEM,1)		;TEMP FOR SWAP (HOLDS REGISTER T)
	DD(XSWAP,1)		;30-BIT PC FLAGS FOR SWAP
	DD(SWAP,1)		
	DD(,1,<JRST SWAPG>)
> ;END IFE FTFILE

	DD(SVBTS,1)		;BYTE MASK FOR $O TYPEOUT
	DD(OLDAR,1)		
	DD(PSVBTS,2)		;SAVE BLOCK FOR ABOVE 2 ON $$O

	DD(BYTMSK,1)		;[235] $3M BYTE MASK
SUBTTL	STORAGE -- SYMBOL TABLE LOGIC

	DD(PNTR,1,<Z INST>)	;POINTER TO BITS IN INST
	DD(INST,1)		;BINARY FOR INSTRUCTION
	DD(CHP,1)		;CHAR POINTER INTO OPTXT, OPTXT+1
	DD(OPTXT,2)		;STORE INPUT TEXT FOR OPEVAL
	DD(SAVPDL,1)		;SAVE PUSH DOWN LIST POINTER
	DD(WRD,1)		
	DD(WRD2D,1)		;QUANTITY AFTER $ IN DECIMAL
	DD(WRD2O,1)		;QUANTITY AFTER $ IN OCTAL

	DD(PRNC,1)		

	DD(FRASE,1)		;DONT CHANGE ORDER, SEE WORD+6
	DD(SYL,1)		
	DD(LWT,1)		
	DD(SYM,1)		
	DD(FRASE1,1)		
	DD(DEN,1)		

	DD(SAVHSM,1)		;C(.JBHSM), USED BY EVAL, LOOK
	DD(SEGNAM,1)		;THE HIGH SEGMENT NAME (OR 0)
				;WHEN $: IS SUCCESSFULLY DONE
	DD(PRGM,1)		;$:'D MODULE POINTER
				;  (SYMBOL INDEX TO 2ND WORD)
	DD(SYPTR,1)		;BASE OF CURRENT SYMTAB OR WINDOW (R)
	DD(SY2GO,1)		;NUMBER OF SYMBOLS LEFT IN CURRENT TABLE
	DD(R2IDX,1)		;OFFSET TO MAKE R A SYMBOL INDEX

	DD(EVFLG,1)		;FLAGS OF CURRENT SYMBOL IN EVAL
	DD(EVVAL,1)		;VALUE OF CURRENT SYMBOL IN EVAL
	DD(EVIDX,1)		;SYMBOL INDEX OF CURRENT SYMBOL IN EVAL

	DD(LKFLG,1)		;FLAGS OF CURRENT SYMBOL IN LOOK
	DD(LKVAL,1)		;VALUE OF CURRENT SYMBOL IN LOOK
	DD(LKIDX,1)		;SYMBOL INDEX OF CURRENT SYMBOL IN EVAL
	DD(LKMAX,1)		;THE HIGHEST KNOWN VALUE SUCH THAT THE
				;FOUND SYMBOL WILL STILL BE USED FOR IT

IFN FTMON,<
	DD(CT2GO,1)		;NUMBER OF WORDS LEFT TO BE WINDOWED
	DD(SYWIN,1)		;BASE OF OUR SYMBOL WINDOW
> ;END IFN FTMON

	DD(ESTUT,1)		
	DD(FSV,1)		
	DD(FH,1)		
IFE	FTFILE,<
IFN	FTDEC10,<
	DD(SYMP,1,<IFIW .JBSYM>);POINTS TO LOW SEG SYM TABLE POINTER
	DD(USYMP,1,<IFIW .JBUSY>);POINTS TO UNDEF SYM TABLE POINTER
>
IFN	FTDEC20,<
IFN	FTEXEC!FTMON,<
	DD(SYMP,1,<IFIW .JBSYM>)
	DD(USYMP,1,<IFIW .JBUSY>)
>
IFE	FTEXEC!FTMON,<
	DD(SYMP,1,<IFIW DDSYM>)
	DD(USYMP,1,<IFIW DDUSY>)
>>>

IFN	FTFILE,<
	DD(SYMP,1,<IFIW FISPTR>)
	DD(USYMP,1,<IFIW FIUPTR>)
>

IFN FTEXEC!FTMON,<
	DD(HSBLK,1)		;0 IF SYMBOLS NOT HIDDEN, ELSE BLOCK ADDRESS
> ;END IFN FTEXEC!FTMON



;SYMBOL TABLE CACHE DATA:


	DD(SCNUM,1)		;NUMBER OF SYMBOLS IN THE CACHE
	DD(SCTIM,1)		;TIME COUNTER FOR SETTING AGES OF SYMBOLS
	DD(SCTMP,1)		;INDEX TO USE FOR A NEW SYMBOL
	DD(SCSYM,SCSIZ)		;SYMBOLS IN THE CACHE
	DD(SCIDX,SCSIZ)		;INDEX INTO SYMBOL TABLE FOR THIS SYMBOL
	DD(SCVAL,SCSIZ)		;VALUES OF THE SYMBOLS
	DD(SCMAX,SCSIZ)		;MAXIMUM VALUES SYMBOLS ARE GOOD FOR
	DD(SCAGE,SCSIZ)		;AGE OF EACH SYMBOL
SUBTTL	STORAGE -- ADDRESSING DATA

	DD(SPSAV,1)		;POINTER TO LAST SYMBOL TYPED
	DD(LLIMIT,1)		;LOWER LIMIT WORD (SEARCHES, ETC)
				; ALSO VALUE FOR DEFINING SYMBOL
	DD(ULIMIT,1)		;UPPER LIMIT WORD (SEARCHES, ETC)
	DD(LLOC,1)		;LAST LOCATION (E.G., LOCATION/, ETC.)
	DD(LLOCO,1)		;LAST LOCATION OPEN
	DD(SAVLP,1)		;POINTER TO SAVLOC TABLE
	DD(SAVLTB,NSAVTB)	;SAVLOC (PC RING BUFFER) TABLE (FOR $<CR> ETC.)
	DD(TENSYM,1)		;HOLDS TENTATIVE VALUE WHEN EVAL'ING SYMBOLIC OP
	DD(SKPCT,1)		;SKIP COUNT FOR XCT
	DD(LASEAF,1)		;LAST WORD USED IN EFFECTIVE ADDRESS CALCULATION

	DD(UBASE,1)		;RELOCATION BASE ADDED TO USER ADDRESS
	DD(UPROT,1,<<377777,,777777>>);PROTECTION LIMIT FOR USER ADDRESS

;ORDER OF PATCH? ENTRIES IS CRITICAL!!!!!

	DD(PATCHS,1,<<FTDEC10&<^-FTFILE>>>);-1 IF PATCHING ENABLED
				;	DEFAULT ON FOR TOPS10 ^-FILDDT
				;	DEFAULT OFF FOR TOPS20
	DD(PATCHC,1,<FTDEC20>)	;-1 IF AUTO-PAGE-CREATE
				;	DEFAULT OFF FOR TOPS10
				;	DEFAULT ON FOR TOPS20
	PAMAX==2		;MAX INDEX FOR $[$]NW

	DD(LASTPG,1)		;LAST PAGE ADDRESS REFERENCED
	DD(LASTAC,1)		;PAGE ACCESS BITS FOR LASTPG


;STORAGE FOR SAVFL TO RESTORE FLAGS AFTER PAGE FAULT

	DD(SATEM1,1)		;FLAGS IN NON-0 SECTIONS
	DD(SATEM2,1)		;PC OR FLAGS,,PC

;STORAGE FOR RESTOR

	DD(RSTM1,1)		;NON-ZERO IF ENTERED AT RESTRX

;STORAGE FOR TTYRET

	DD(TTEM1,1)		;TENTATIVE HSBLK
	DD(TTEM2,1)		;SAVED R
	DD(TTEM3,1)		;TOTAL BLOCK COUNT
SUBTTL	STORAGE -- SAVE AREAS FOR PREVIOUS CONTEXT

;SAVED CPU STUFF - AVAILABLE VIA $I "ADDRESS". ALTHOUGH THE APR AND
;PI CONTEXTS ARE MEANINGFUL ONLY TO EDDT ALL WORDS ARE PRESENT IN
;ALL FLAVORS OF DDT SO THAT $I MAY SOMEDAY BE MADE TO WORK MEANING-
;FULLY EVEN IN FILDDT.

	DD(SAVPI,1)		;($I+00) SAVED (CONI) PI IN EXEC MODE
	DD(,1,1177)		;($I+01) PI CHANNELS TURNED OFF BY EDDT
	DD(SAVAPR,1)		;($I+02) SAVED (CONI) APR IN EXEC MODE
	DD(PCFLG,1)		;($I+03) SAVED PC FLAGS
	DD(PCWRD,1)		;($I+04) SAVED PC WORD (A LA JSR)
	DD(EPTWRD,1)		;($I+05) EXEC PROCESS TABLE PAGE NUMBER
	DD(UPTWRD,1)		;($I+06) USER PROCESS TABLE PAGE NUMBER
	DD(CSTWRD,1)		;($I+07) CST BASE ADDRESS (VIRTUAL)
	DD(SPTWRD,1)		;($I+10) SPT BASE ADDRESS (VIRTUAL)

;STATE VARIABLES SUCH AS EXEC-MODE FLAG AND CPU-TYPE
;
;ALTHOUGH ONLY SET FROM EXEC-MODE DDT THESE VARIABLES ARE ALWAYS
;PRESENT SO THAT IN THE FUTURE EVEN FILDDT MAY BE ABLE TO UTILIZE
;THEM (FOR LOOKING AT CRASHES, ETC.).

	DD(SECDDT,1)		;SECTION IN WHICH DDT IS RUNNING,,0
	DD(USRFLG,1)		;.LT. 0 IF IN USER MODE (EXEC DDT ONLY)

	DDS(BZ$FLG,0)		;START OF FLAGS TO BE CLEARED ON ENTRY
	DD(KAFLG,1)		;.NE. 0 IF CPU IS KA-10
	DD(KIFLG,1)		;.NE. 0 IF CPU IS KI-10
	DD(KLFLG,1)		;.NE. 0 IF CPU IS KL-10
	DD(KSFLG,1)		;.NE. 0 IF CPU IS KS-10
	DD(KLSFLG,1)		;.NE. 0 IF CPU IS KL-10 OR KS-10
	DD(KIPAG,1,<FTDEC10>)	;.NE. 0 IF KI-PAGING
	DD(KLPAG,1,<FTDEC20>)	;.NE. 0 IF KL-PAGING
	DDS(ZZ$FLG,0)		;END OF FLAGS TO BE CLEARED

;SOME TEMPORARIES FOR FV??? ROUTINES

IFN	FTEXEC,<
	DD(FVTEM1,1)		
	DD(FVTEM2,1)		
	DD(FVTEM3,1)		
> ;END OF IFN FTEXEC


;STATE VARIABLES FOR $U COMMANDS

	DD(ACWRD,1)		;DATAO PAG, TO SET OLD AC BLOCK BACK
	DD(FAKEAC,1)		;NON-ZERO TO USE FAKE 0-17
	DD(FAKEAD,1)		;LAST ADDRESS SPECIFIED IN $5U
	DD(MAPFN,1)		;FLAGS,,FUNCTION WHEN $U MAPPING IN EFFECT:
				; WHOLE WORD NEGATIVE IF PHYSICAL ADDRESSING
				; 1B1 MEANS CONTENTS OF MAPPG IS SPT OFFSET
				; FUNCTIONS ARE DEFINED IN PFNDSP AND MFNDSP
	DD(MAPPG,1)		;DATA PER MAPFN, PAGE # OR SPT OFFSET
;THESE LOCATIONS MUST BE IN ORDER - THEY ARE USED TO SAVE AND
;RESTORE THE STATE OF DTE FOR KL10

	DD(SAVTTY,1)		;**** MUST BE IN ORDER

IFN	FTEXEC,<

;KL10 SAVE LOCATIONS
	DD(SAVUNS,1)		
	DD(SAVEPW,1)		
	DD(SAVERW,1)		
	DD(SAVDPW,1)		
	DD(SAVDRW,1)		;**** END OF MUST BE IN ORDER BLOCK

	DD(MTRCNI,1)		;RESULT OF CONI MTR,
	DD(TIMCNI,1)		;RESULT OF CONI TIM,
	DD(MSTRDT,1)		;ID OF MASTER -11
	DD(DING11,1)		;PROTOTYPE CONO WORD FOR DTE

;KS10 SAVE LOCATIONS
	DD(SAVTIM,2)		;SAVED TIME BASE
> ;END IFN FTEDDT

IFN FTDEC20,<
	DD(SAVTT2,1)		;SAVED RFCOC% WORDS
	DD(SAVTT3,1)		
	DD(SAVTIW,1)		;SAVED TERMINAL INTERRUPT MASK
	DD(SAVSTS,1)		;SAVED PSI STATE
> ;END IFN FTDEC20

	DD(MSK,1,-1)		;INITIAL SEARCH MASK

IFE FTFILE,<
	DD(SYMVAL,1)		;NON-ZERO IF WE TRUST @USYMP ETC.
> ;END IFE FTFILE
IFN FTEXEC,<
	DD(PAGVAL,1)		;NON-ZERO IF WE TRUST ???WRD
				;WE ALWAYS TRUST ???WRD IN NON-EDDTS
	DD(PAGVAS,1)		;IF SAVED PAGING DATA IS VALID

	DD(EPTWRS,1)		;SAVED EPTWRD IN OTHER SPACE
	DD(UPTWRS,1)		;SAVED UPTWRD IN OTHER SPACE
	DD(SPTWRS,1)		;SAVED SPTWRD IN OTHER SPACE
	DD(CSTWRS,1)		;SAVED CSTWRD IN OTHER SPACE

	DD(ADRSPC,1)		;NON-ZERO IF IN SYMBOL SPACE
> ;END OF IFN FTEXEC


	DD(AC0,17)		;STORAGE FOR FAKE 0 - 17
	DD(AC17,1)		; . . .
SUBTTL	STORAGE -- STATE VARIABLES

	DD(SCHM,1,<EXP PIN>)	;DO NOT CHANGE ORDER
	DD(ARM,1,<EXP PADSO>)	
	DD(ODFM,1,<EXP 10>)	

	DD(SCHR,1)		;CELLS TO STORE TYPEOUT MODES AT START
	DD(ARR,1)		;  OF COMMAND, IN CASE REPARSE NEEDED
	DD(ODFR,1)		;** DO NOT CHANGE ORDER OF THESE 3 **

	DD(SARS,1)		
	DD(TEM,1)		
	DD(TEM1,1)		

	DD(SYMOFS,1,<EXP ADRNGE>);[234] RANGE FOR SYMBOL+OFFSET TYPEOUT

IFN	FTEXEC,<
	DD(XNXTCH,1)		;PRESET INPUT CHAR AT XLISTE
>				;END IFN FTEXEC

IFN	FTDEC10,<		;SUNDRY TOPS-10 STUFF
	DD(MYPPN,1)		;USED BY FSCAN
	DD(FSBLK,1)		;.NE. 0 IF FSCAN SAW SOMETHING EXCITING
	DD(FSDEV,1)		;DEVICE
	DD(FSFIL,1)		;FILENAME
	DD(FSEXT,1)		;FILETYPE
	DD(FSPPN,1)		;FILE PPN
	DD(FSSFD,5)		;FILE PATH SFD'S
	FSLEN==.-FSBLK		;LENGTH OF AREA FOR FSCAN TO CLEAR
> ;END IFN FTDEC10
SUBTTL	STORAGE -- FILDDT

IFN	FTFILE,<		;FILDDT STUFF
	DDS(FWAZER,0)		;START OF AREA TO ZERO

IFN	FTDEC10,<		;TOPS-10 SPECIFIC FILDDT STUFF
	FLPLEN==.FOLEB+1	;LENGTH OF FILOP. BLOCK
	DD(FLPBLK,FLPLEN)	;FILOP. BLOCK
	LKPLEN==.RBSIZ+1	;LENGTH OF LOOKUP BLOCK
	DD(LKPBLK,LKPLEN)	;LOOKUP BLOCK
	PTHLEN==.PTPPN+5+2	;LENGTH OF PATH BLOCK
	DD(PTHBLK,PTHLEN)	;PATH BLOCK
	DSKLEN==.DCUSZ+1	;LENGTH OF DSKCHR BLOCK
	DD(DSKBLK,DSKLEN)	;DSKCHR BLOCK (FOR /U)
	DD(POKBLK,3)		;FOR POKE'ING THE MONITOR
> ;END OF IFN FTDEC10

IFN	FTDEC20,<		;TOPS-20 SPECIFIC FILDDT STUFF
	DD(SAVRET,1)		;RETURN ADDRESS OF CMDINI CALLER
	DD(SAVREP,1)		;SAVED STACK POINTER TO RESTORE ON REPARSE
	DD(CMDBLK,.CMGJB+5)	;COMMAND STATE BLOCK FOR COMND JSYS
	DD(BUFFER,BUFSIZ)	;INPUT TEXT STORED HERE
	DD(ATMBFR,ATMSIZ)	;ATOM BUFFER FOR COMND JSYS
	DD(NOIFDB,FDBSIZ)	;FUNCTION DESCRIPTOR BLOCK FOR NOISE WORDS
> ;END OF IFN FTDEC20
;STILL FTFILE

	DD(LBUF,3)		
	DD(SYMGOT,1)		;SYMBOL TABLE CAME FROM CURRENTLY OPEN FILE
	DD(FILING,1)		;-1 IF FILE I/O; 0 IF PEEK AT RUNNING MONITOR
	DD(FDIDSW,1)		;[207] "/D" TYPED IF .NE. 0
	DD(FDIFSW,1)		;-1 IF "/F" TYPED
	DD(JOBING,1)		;.NE. 0 THEN JOB NUMBER RATHER THAN MONITOR
	DD(FDIMSW,1)		;-1 IF "/M" TYPED
	DD(CHGSFL,1)		;CHANGED SYMBOL TABLE
	DD(WINNUM,1)		;WINDOW TO READ OR WRITE
	DD(WINTT1,1)		;TEMP HOLD OF TT1 (WINDOW NUMBER)
	DD(WINTT2,1)		;TEMP HOLD OF TT2 (FILE PAGE NUMBER)
	DD(WINDIR,WINMAX)	;MODIFIED BIT FOR MEMORY WINDOW
	DD(MAXSIZ,1)		;HIGHEST LOC (+1) IN MONITOR OR FILE
				;(USED SO WE WON'T EXAMINE PAST END)
	DD(JOBHSO,1)		;START OF HISEG IN .EXE FILE
	DD(LSTNPG,1)		;LAST XLATED PAGE IN CHKADR
	DD(EXEFMT,1)		;.NE. 0 IF FILE IS IN .EXE FORMAT
;STILL FTFILE

	DDS(FCMZER,0)		;HERE TO LWAZER CLEAR ON EVERY TOPS-20
IFN	FTDEC20,<		;PROMPT.
	DD(GJFBLK,GJFSIZ)	;GTJFN BLOCK FOR COMND JSYS
	DD(NAMBUF,50)		;BUFFER FOR NAME OF INPUT FILE
	DD(FILJFN,1)		;JFN OF OPEN FILE
	DD(PHYSTR,1)		;DEV DESIGNATOR OF STRUCTURE ON /U
	DD(STRBUF,2)		;STORAGE FOR STRUCTURE NAME
	DD(ALIBUF,2)		;STORAGE FOR STRUCTURE ALIAS
	MBLKL==.MSRSU+1		;LENGTH OF MSTR BLOCK
	DD(MBLK,MBLKL)		;MSTR ARG BLOCK
> ;END IFN FTDEC20
	DD(SYMGET,1)		;-1 IF /S, 0 IF NOT
	DD(PHYSIO,1)		;DSKOP ARG (T1) IF SUPER I/O (-1 ON -10)
	DDS(LWAZER,0)		;END OF AREA TO ZERO + 1

	DDS(FWAONE,0)		;START OF AREA TO ONE
	DD(DEPNCT,1)		;COUNT OF POKE FAILURES
	DD(WINFPN,WINMAX)	;FILE PAGE NUMBER FOR THIS WINDOW
	DDS(LWAONE,0)		;END OF AREA TO SET TO -1

	DD(WIND0,1)		;BASE ADDRESS OF WINDOW BUFFER AREA

	DD(FISBEG,1)		;FIRST LOC OF FILDDT'S COPY OF SYMS
	DD(FISEND,1)		;LAST LOC
	DD(FISCNT,1)		;NUMBER OF SYMBOLS FILDDT FOUND

	DD(FISPTR,1)		;POINTER TO SYMBOLS
	DD(FIUPTR,1)		;POINTER TO UNDEF SYMS

	DD(FOSPTR,1)		;FISPTR ON FILDDT STARTUP
	DD(FOUPTR,1)		;FIUPTR ON FILDDT STARTUP
	DD(OLDHSM,1)		;SAVHSM ON FILDDT STARTUP

	DD(PAGTBL,1)		;PTR TO .EXE DIRECTORY
				;1 WORD FOR EVERY VIRT. PAGE
				;BITS 0-4 .EXE FORMAT FLAGS
				;RH - FILE PAGE NUMBER
	DD(PGTLEN,1)		;LENGTH OF PAGTBL (HIGHEST PAGE+1)
> ;END IFN FTFILE
SUBTTL	STORAGE -- PUSH DOWN LIST

	DD(XPDL,1)		;USED TO STORE RET FOR TOP-LEVEL POPJ'S
	DD(PDL,LPDL-1)		;STORAGE FOR PUSH DOWN LIST

IFN	FTDEC20&<^-FTEXEC>,<
	DDS(VAREND,0)		;END OF INITIALIZED VARIABLES AREA
	DD(DDSYM,1)		;SYMTAB PTR (COPIED FROM .JBSYM USUALLY)
	DD(DDUSY,1)		;UNDEF SYMTAB PTR (COPIED FROM .JBUSY " )

IFN FTMON,<
	DD(SETRT1,1)		;SCRATCH FOR VARIABLE INITIALIZATION
>>

	DDS(END.V,0)		;END OF VARIABLES


IFGE RUNLOC,<IFGE VARLOC,<IFL <VARLOC-RUNLOC>,<
;>>>	DDTEND:			;DDTEND GOES HERE UNLESS WE'RE SURE
				;THAT VARIABLES ARE BELOW CODE

IFE FTMON,<
	LEN.V==END.V-BEG.V	;LENGTH OF VARIABLE AREA
> ;END IFE FTMON

IFN FTMON,<
	LEN.V==.-PHVAR		;AVOID E ERROR IN PRINTX
> ;END IFN FTMON
DEFINE PRROOM(WORDN,AREAN),<
	IF2,<
	PRINTX	[WORDN words left in AREAN area]
	>
>

DEFINE PRFULL(WORDN,AREAN),<
	IF2,<
	PRINTX	? The AREAN area has overflowed by WORDN words
	>
>

	RADIX 10

IFN <<VARLOC+1>!FTMON>,<
	VARSPC==NDDTPG_PG2WRD-LEN.V		;ROOM IN DATA PAGE

  IFGE VARSPC,<	PRROOM(\VARSPC,<data>) >
  IFL  VARSPC,< PRFULL(\<-VARSPC>,<data>) >
>

IFGE RUNLOC,<IFE FTMON,<
  IFGE <VARLOC-RUNLOC>,<CODSPC==VARLOC-<RUNLOC+LEN.C>>		;ROOM TILL DATA
  IFL <VARLOC-RUNLOC>,<CODSPC==^O1000000-<RUNLOC+LEN.C>>	;ROOM TILL END

  IFGE CODSPC,< PRROOM(\CODSPC,<code>) >
  IFL  CODSPC,< PRFULL(\<-CODSPC>,<code>) >
>>

	RADIX	8
;THE FOLLOWING DEFINES CERTAIN SYMBOLS RELEVANT TO HARDWARE OR TO
;DDT ITSELF.  THESE ARE *NOT* NEEDED FOR THE ASSEMBLY OF DDT AND
;IN FACT MAY BE IN CONFLICT WITH DEFINITIONS WHICH ARE USED
;DURING ASSEMBLY (E.G. TTY).  HENCE, THESE DEFINITIONS ARE ASSEMBLED
;LAST AND ON PASS 2 ONLY.  THE SYMBOLS ARE ALL DECLARED INTERNAL
;SO THAT THEY WILL BE KEPT IN THE PROGRAM SYMBOL TABLE AFTER
;LOADING.  THESE SYMBOLS ARE THEN USED DURING DDT INSTRUCTION
;ASSEMBLY OR DEASSEMBLY ONLY.

IF2,<			;ONLY DEFINE GLOBALS PASS 2
IFE FTFILE,<		;NOT NEEDED IN FILDDT
IFE	FTDBUG,<	;ONLY DEFINE GLOBALS FOR REGULAR DDTS
DEFINE XP (SS,VV)<
	PURGE	SS	;AVOID MACRO BUG
	SS=:VV		;DEFINE
>

IFE FTMON,<		;[265] AVOID MULT. DEF. GLOBALS WITH KDDT, MDDT
;DEFINE $ SYMBOLS INTERNAL TO DDT

RADIX 10

DEFINE DBPNT (Z.)<XP $'Z.'B,<BPT$B+<B$SIZ*Z.>>>

ZZ==-1
REPEAT NBP+1,<DBPNT \<ZZ==ZZ+1>>
RADIX 8

XP $M,<MSK>
XP $I,<SAVPI>
> ;[265] END IFE FTMON
> ;END IFE FTDBUG
;DEFINE I/O DEVICE MNEMONICS

IFN	FTEXEC,<
IFE FTDEC20,<		;CONFLICTS WITH TOPS-20 DEFINITION OF PI, ETC.

XP  PI,004B11
XP PAG,010B11
XP CCI,014B11
XP DLB,060B11
XP DLC,064B11
XP CLK,070B11
XP PTP,100B11
XP PTR,104B11
XP CDP,110B11
XP CDR,114B11
XP TTY,120B11
XP LPT,124B11
XP DIS,130B11
XP PLT,140B11
XP  CR,150B11
XP DSK,170B11
XP DTE,200B11
XP UTC,210B11
XP UTS,214B11
XP MTC,220B11
XP MTS,224B11
XP MTM,230B11
XP DLS,240B11
XP DPC,250B11
XP DCSA,300B11
XP DCSB,304B11
XP DTC,320B11
XP DTS,324B11
XP TMC,340B11
XP TMS,344B11 >>

;DEFINE EXTENDED OPERATIONS

XP PORTAL,PORTAL
XP JRSTF,JRSTF
XP HALT,HALT
XP XJRSTF,XJRSTF
XP XJEN,XJEN
XP XPCW,XPCW
XP JEN,JEN
XP XSFM,XSFM

XP JOV,JOV
XP JFOV,JFOV
XP JCRY0,JCRY0
XP JCRY1,JCRY1
XP JCRY,JCRY
> ;END IFE FTFILE
> ;END IF2
;ONLY STARTING ADDRESS FOR FILDDT AND VMDDT ON TOPS-10.
;NO START ADDRESS FOR EXEC OR USER DDT
;BECAUSE USER PROGRAMS AND MONITOR ARE LOADED
;WITH EXEC OR USER DDT
;BUT STILL WANT TO BE STARTED AT THEIR OWN START ADDRESSES.
;
;ON TOPS-20, ALL USER DDTS HAVE START ADDRESSES.
;THE MONITOR IGNORES THEM UNLESS USER RUNS DDT BY ITSELF

IFE	FTDBUG,<
IFN	FTFILE!FTVMX,<
	END	DDT>		;FILDDT OR VMDDT START ADDRESS

IFN	FTDEC20&<^-FTEXEC>&<^-FTMON>&<^-FTFILE>,<
	END	<1,,DDT>>	;TOPS-20 ENTRY VECTOR
> ;END IFE FTDBUG

IF2,<			;ONLY KILL SYMBOLS PASS 2 WHEN DONE WITH THEM
IFN	FTDBUG,<
IFN	FTFILE!FTVMX,<
	END	DEBDDT>		;FILDDT OR VMDDT START ADDRESS

IFN	FTDEC20&<^-FTEXEC>&<^-FTMON>&<^-FTFILE>,<
	END	<1,,DEBDDT>>	;TOPS-20 ENTRY VECTOR

	PURGE	DDT,DDTEND

IFE	FTFILE,<
	SYN	$0BPT,$0DPT	;GENERATE DEBUGGING JSR ENTRY POINT
	PURGE	$0BPT
> ;END IFN FTFILE

IFN	FTEXEC,<PURGE	DDTX>
IFN	FTMON,<PURGE	MDDTX>
> ;END IFN FTDBUG
> ;END IF2

	END