Google
 

Trailing-Edge - PDP-10 Archives - bb-kl11m-bm - lngsrc/ddt.mac
There are 55 other files named ddt.mac in the archive. Click here to see a list.
SUBTTL	DDT	/TW/PFC/TWE/EJW/JNG/RDH/DIB/DLM/JBS/PTR/JM/RCB 18-Sep-89


	COMMENT	\

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

;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1970,1980,1983,1984,1987,1988,1989.
;ALL RIGHTS RESERVED.
;
;
;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 THAT IS NOT SUPPLIED BY DIGITAL.

\


;DDT VERSION IDENTIFICATION

MAJVER==45	;MAJOR VERSION LEVEL
MINVER==1	;MINOR (MAINTENANCE RELEASE) LEVEL
CSTVER==0	;CUSTOMER VERSION (WHO LAST . . .)
EDTVER==715	;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
;	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.

;DDT %41(265) RELEASED MAY, 1980
;VERSION 41A BEGINS

;266	DIB	18-FEB-80
;	ADD RP20 SUPPORT TO FILDDT.

;267	BPK	11-APR-80
;	REPLACE SUB IN LOOK10 WITH EQUIVALENT CODE THAT DOESN'T OVERFLOW.

;270	BPK	17-APR-80
;	TURN OFF CTRL-O WHENEVER WE STOP AT A BREAKPOINT.

;271	DLM	4-OCT-79
;	FLAG IN TTYMSK FOR INST TYPEOUT ON BPT; WARNING IF BPT INSERTION/REMOVAL
;	FAILS; DIAGNOSTICS ON MEM REF FAILURE; RUN IN NON-0 SEC IF POSSIBLE.

;272	JBS	9-NOV-80	SPR 10-30155
;	ADD ^E TEXT TO -10 HELP MESSAGE.

;273	JBS	10-NOV-80	SPR 10-30019
;	FIX OVERFLOW IN ADD INSTR. AT L4+18.

;274	JBS	12-NOV-80	SPR 10-30058
;	FIX SUB AT DOITX0 THAT SET CARRY1 AND CARRY0 IN USER CONTEXT.

;275	JBS	14-NOV-80
;	FIX ERJMP/ERCAL $X ROUTINES TO AGREE WITH EDIT 274.

;276	JBS	17-NOV-80	SPR 10-30156
;	MOVE "PUSH" OUT OF CONDITIONALS TO AGREE WITH "POP" IN RDBIN.
;277	JBS	18-NOV-80	SPR 20-15067
;	FIX $<RET> AFTER $<TAB>.

;300	JBS	19-NOV-80	SPR 10-30237
;	ADD USER TTY CONTROL BIT FOR $Y ECHO DURING FILE READ/EXECUTION.

;301	JBS	25-NOV-80
;	ALL KINDS OF MISC. EDITS TO FIX LITTLE THINGS HERE AND THERE.

;302	JBS	3-DEC-80	SPR 10-30277
;	FIX MOVING OF PAT.. IN $< MODE.

;303	JBS	4-DEC-80
;	MAKE $Z ABORT WITH "?" IF ANY MEM. WRITE FAILS, REMOVE $$Z,
;	MOVE /H TEXT AROUND FOR -10 VERSION, FIX EXTENDED ADDRESSING BUG.

;304	JBS	10-DEC-80	SPR 10-30337
;	FIX ILDB TYPEOUT IN EXTENDED ADDRESSING MODE - WAS MESSING UP SECTION #
;	WHEN AN AC WAS USED.

;305	JBS	29-DEC-80
;	REMOVE TEMPORARY PATCH THAT BYPASSED MACRO BUG, REVISE EDIT 300.

;306	JBS	29-DEC-80	SPR 10-30404
;	ADD $$1X FEATURE TO DO QUICKER $$X BY NOT CHECKING FOR DANGEROUS
;	INSTRUCTIONS.  USED OVER LONG BUT SAFE PUSHJ'S, ETC.

;307	JBS/RDH	30-JAN-81
;	SETUP LOCATION .JBBPT WITH $0BPT FOR TOPS-10 USER/EXEC DDT'S,
;	CHANGE FLOATING OUTPUT SUBROUTINE "TFLOT" TO USE "FLOUT" JSYS ON
;	TOPS-20, ADD $2F DOUBLE-PRECISION FLOATING TYPEOUT ON TOPS-20,
;	ALLOW READING $M AND $U MASKS IN FILDDT (SPECIAL-CASE THEM),
;	REMOVE $L PAPER TAPE PUNCH CODE, ADD $[ANY DIGIT] COMMAND TO 
;	ABORT PATCH INSERT MODE, MAKE $[ANY DIGIT]< ILLEGAL,
;	CLEAR "PATCH MODE" FLAG AND RESET LOCATION POINTERS AT START-UP,
;	DON'T ALLOW NESTED PATCHING, CHANGE <LF> AND ^H TO RECOGNIZE
;	DOUBLE-WORD MODE ON TOPS20 (I.E., DOUBLE PRECISION FLOATING TYPEOUT),
;	CHANGE $X CODE TO CLEAR INPUT BUFFER AND RESET ^O BEFORE NEXT
;	INSTRUCTION TYPEOUT.
;	(MATCH ANGLE BRACKETS IN [302] >)

;310	JBS	22-JAN-81	SPR 20-15518
;	CHANGE HANDLING OF TEXT INSERTION - AUTOMATICALLY CLOSE LOCATION
;	UPON RECEIPT OF TEXT DELIMITER.

;311	JBS	6-FEB-81
;	REDEFINE PATCH ABORT COMMAND TO $0>, FIX BREAKPOINT TYPEAHEAD
;	CLEARING BUG - WAS MUNCHING FIRST CHR. TYPED AFTER BREAKPOINT
;	STUFF BEGAN TYPING OUT, FIX FILDDT BUG WHICH WOULD SETUP PAGTBL
;	WRONG (SOMETIMES) FOR PAGES OVER 4000, CHANGE TEXT INSERTION MODE
;	SO IT WON'T FORCE A CRLF IF A LOCATION IS OPEN BUT NOTHING HAS
;	BEEN DEPOSITED YET (REVISION OF EDIT 310), REINSTALL EDIT 273
;	WITH A CHANGE (EDIT 303 REMOVED EDIT 273).
;312	RDH/JBS	4-MAR-81
;	(<<MATCH ANGLE BRACKETS)
;	FIX BROKEN NEGATIVE INTEGER TYPEOUT, FIX TOPS-10 OUTPUT BROKEN BY
;	EDIT 305, MAKE $7T MODE DO RIGHT-JUSTIFIED TYPEOUT ONLY IF LEFT 29
;	BITS ARE ALL NULL, CHANGE PATCH ABORT (AGAIN) TO $$0>, MAKE A BOTCHED
;	PATCH-INSERT FIX PTLOC BEFORE LOSING, MAKE $N> SET MAXIMUM SKIP
;	RETURNS FROM PATCH (N=1 GIVES 1 JUMPA, ETC.), FIX BUG THAT WOULD SET
;	"." TO ZERO AFTER ^C/DDT COMMANDS, ADD $0T/$$0T COMMAND TO TYPE THE
;	ASCIZ STRING STARTING AT ".", MAKE XMOVEI TYPE OUT AC CONTENTS AFTER
;	$X.

;313	JBS	10-APR-81
;	EDITS 302 AND 312 MUST BE INSTALLED FIRST -
;	ADD <ADDR.>$0T TO TYPE ASCIZ STRING AT <ADDR.>, CHANGE $0T CODE TO
;	BE MORE EFFICIENT, ALLOW USER TO STOP $0T TYPEOUT ANYTIME, MORE WORK
;	TO GET $T TO WORK RIGHT FOR RIGHT-JUSTIFIED SINGLE CHR., HANDLE RPACS%
;	ERROR IF SECTION DOESN'T EXIST, MAKE FILDDT STOP SEARCHING AFTER EOF
;	ON DATA FILES, FIX MOVING OF PAT.. WHEN AN UNDEFINED SYMBOL EXISTS
;	AND A NEW DEFINITION IS MADE (CACHE PROBLEM), MAKE CONDITIONAL
;	BREAKPOINT INSTRUCTION EXECUTE IN USER CONTEXT, DON'T FORCE $P
;	DEFAULT TO 1 IF USER HAS SPECIFIED OWN NUMBER.

;314	JBS	10-AUG-81
;	REMOVE AUTO CRLF AFTER LONG STRING INSERTION, FIX ANOTHER BUG WITH
;	UNDEFINED SYMBOLS NOT GETTING FIXED UP.

;315	JBS	13-AUG-81	SPR 10-31459
;	OUTPUT RADIX WASN'T SETUP BEFORE TYPING FILOP. ERROR CODE, CAUSING
;	GARBAGE TO PRINT OUT.  FILDDT-10 ONLY.

;316	JBS	17-AUG-81
;	FIND "REAL" EOF FOR A TOPS-20 FILE - EDIT 313 BROKE THIS BECAUSE IT
;	ASSUMED SIZEF% RETURNED EOF.  BUT EOF DOESN'T REALLY EXIST IN TOPS-20!

;317	JBS/RDH	19-AUG-81
;	[JBS] FIX FILDDT FOR BIG DATA FILES AGAIN.
;	[RDH] HANDLE ^S/^Q IN EXEC MODE, IMPLEMENT EXEC MODE TYPEAHEAD,
;	IMPLEMENT XXX<ADR>N$B WHERE "ADR" IS ADDRESS OF COMMAND STRING TO
;	BE EXECUTED ON BREAKPOINT (DEPENDS ON FTYANK), HANDLE $X'ING IN
;	THE ACS IN NON-ZERO SECTION (PC ALWAYS LOCAL, THEREFORE ALWAYS
;	A "REGISTER" ADDRESS)

;THIS SOURCE FILE IS MADE FROM FIELD-IMAGE DDT 42(320), AS RELEASED WITH
;TOPS-20 V5.  IT INCLUDES SOME PUBLISHED AND UNPUBLISHED EDITS MADE TO DDT
;41A.

;320	RDH/JBS	30-SEP-81
;	EDIT 317 BROKE TYPING SOMETHING TO GET OUT OF A (E.G.) SEARCH LOOP 
;	(EXEC MODE ONLY), PRESERVE APR BITS IN EXEC MODE, TYPE "/" INSTEAD OF A
;	SPACE IN $0T COMMAND.  NOTE: THIS EDIT IS NOT IN 42(320).

;321	JBS	30-SEP-81	10-31641
;	REMOVE DEFINITION OF RADIX50 PAT FROM LIST OF PATCH LOCATIONS IN
;	USER MODE.

;322	JBS	6-OCT-81
;	PHYSICALLY REMOVE DESUPPORTED $L CODE.

;323	ALREADY INSTALLED IN 42(320).


;324	JBS	27-JAN-82
;	FIX TYPO IN EDIT 317 THAT CAUSED EDDT-10 TO HANG ON STARTUP.

;DDT %41A(324) RELEASED FEB, 1982
;%42(320) RELEASED ON TOPS-20 VERSION 5 SYSTEMS SUMMER 1982.

;325	RDH/JBS	3-FEB-82
;	FIX PUSH/POPJ MISMATCH THAT HAPPENS IF NO SPT SETUP IN KL-PAGING.

;326	JBS/RDH	19-MAR-82
;	CHANGE CONDITIONAL BREAKPOINT CODE TO COMPLETELY RESTORE THE WORLD
;	BEFORE EXECUTING (IN CASE OF CONSZ PI, ETC. IN EXEC MODE).

;327	JBS	12-MAY-82	20-17648
;	TYPE SYMBOL IN OPEN MODULE IN PREFERENCE TO A GLOBAL, IF THEY BOTH HAVE
;	THE SAME VALUE.

;330	NOT INSTALLED.

;331	JBS/RDH	17-DEC-82	20-17727
;	REWORK $X CODE TO MINIMIZE PROBLEMS WITH PSI SWITCHING.  USER WOULD
;	GET PSI TRAPS WITH DDT'S ACS SET UP, OR NOT GET PSI AT ALL.  THIS DOES
;	NOT ELIMINATE THE PROBLEM COMPLETELY (CAN'T BE DONE ANYWAY), IT JUST
;	HELPS IT A LOT.

;332	JBS	1-SEP-82	10-32308
;	MAKE RDIO NOT CRASH THE SYSTEM WHEN $X'ED ON A KS.  FIXED ON TOPS-10
;	AND EDDT-20; S/UDDT DON'T HAVE ENOUGH ROOM LEFT TO BE FIXED.

;333	DLM/RDH	25-DEC-82
;	NOTE: THIS EDIT IS NOT INSTALLED.  IT IS ONLY FOR FURTHER DOCUMENTATION
;	OF 42(320) AS RELEASED.
;	CREATE SECTIONS AS NEEDED FOR TOPS-20 USER-MODE DDTS; DEFAULT
;	THE SECTION IN ADDRESS EXPRESSION IF ADDRESS IS .LT. 18 BITS, OR
;	IF SPACE OR COMMA TYPED, BUT NEVER IF COMMA-COMMA TYPED; IMPLEMENT
;	"INTERNAL" ADDRESSES (E.G., FOR $M, $I, ETC.) - MAKE $NI, $NM, AND
;	$NU CONSISTENT (ALLOW SETTING AS WELL AS READING OF ALL).

;334	JBS	31-JAN-83	10-33035, 10-33811
;	TYPE I/O INSTRUCTIONS CORRECTLY.

;335	NOT INSTALLED.

;336	JBS	25-MAR-83
;	FIX ERROR MESSAGE TYPEOUT AT REMOER.

;337	JBS	2-FEB-83
;	FIX INEFFICIENT CODE AFTER SYMBOL TABLE CACHE FEATURE TEST WAS ADDED.

;< (match angle brackets)
;340	JBS	2-FEB-83
;	REMOVE $$0> AS PATCH ABORT COMMAND.  LEAVE $0< AS THE COMMAND.
;> (more matching anglies)

;341	NOT INSTALLED.

;342	JBS	16-FEB-83
;	FIX $G TO USE 30 BIT START ADDRESSES ON TOPS-20.

;343	JBS	25-FEB-83
;	REMOVE EXEC-MODE ONLY CODE FROM USER DDTS.  EDIT 331 MUST BE INSTALLED
;	FIRST.

;344	JBS	14-MAR-83
;	DON'T DIE IF USER GIVES BAD FORK NUMBER IN FORK<$$?.
;(MATCH ANGLE BRACKETS:>)

;345	JBS	4-APR-83
;	MOVE SOME CODE TO PAGES 764 AND 765 IN UDDT-20 TO GET CODE SPACE.

;346	JBS	4-APR-83
;	FIX EDIT 343 SO TOPS-10 USER MODE WORKS.  EDIT 343 MUST BE INSTALLED.

;347	JBS	6-APR-83
;	EXPAND EDIT 332 TO WORK IN UDDT-20 AND SDDT-20 ON THE KS.  EDIT 345
;	MADE ENOUGH ROOM TO INSTALL THIS BUG FIX.

;350	JBS	8-APR-83
;	FIX EXEC TYPEAHEAD CHECK AT LOOK2 + A FEW.

;351	JBS	8-APR-83
;	REMOVE DEFINITION OF MRPAC% JSYS FROM SOURCE.

;352	JBS	8-APR-83	20-19074
;	FIX $W IN FILDDT-20.

;353	JBS	6-MAY-83
;	FIX $? COMMAND TO NOT TYPE GARBAGE STRINGS.

;354	JBS	9-MAY-83
;	REMOVE $$? COMMAND FROM FILDDT-20.

;355	JBS	8-JUL-83
;	MOVE SAVE4 LABEL SO EXEC DDT'S START.  FIX TO EDIT 331 AND 332.

;356	NOT INSTALLED.

;357	JBS	26-JUL-83
;	FIX $W FOR DISKS - PAGE ACCESS BITS WERE NOT UPDATED.

;360	JBS	28-JUL-83
;	DO MONITOR FIXUPS RIGHT - PEEK JUST BEFORE POKE.'ING.

;361	RDH	15-NOV-83
;	KEEP THE LAWYERS HAPPY - PUT COPYRIGHT IN THE BINARIES

;362	PTR	20-DEC-83	20-17198
;	FIX NON-ZERO SECTION $X OF XMOVEI, XHLLI, LDB ET AL. BY
;	REMEMBERING THE LOCAL/GLOBAL PART OF THE EA CALC.
;	MAKE A NEW ENTRY IN $XTBL FOR XHLLI, SO SECTION NO. IS PRINTED.
;	ADD CODE TO TBPNT TO DECODE ALL FORMS OF BYTE POINTERS.
;	FIX EA CALC OF BYTE POINTERS AT IXBP; HANDLE ALL THE FORMATS.

;DDT %42A(362) SHIPPED WITH TOPS-10 7.02

;363	JBS	1-FEB-84	RAW
;	MAKE PSECT XCODE READ-ONLY.

;364	PTR	 7-FEB-84	10-34464
;	WRTWIN THOUGHT THE REFERENCED ADDRESS WAS ALWAYS IN R; IT ISN'T.
;	USE THE FILE PAGE NUMBER INSTEAD.

;365	RDH	21-FEB-84
;	ONLY GIVE HARDWARE 8 BITS OF CHAR IN EXEC MODE.

;366	PTR	21-FEB-84
;	DON'T CONFUSE FLOAT INPUT AND SYMBOLS STARTING WITH ".E" SO MUCH

;367	JM	21-JUN-84
;	FIX $O TYPEOUT MODE (N-BIT BYTES) SO THAT ADDRESSES ARE RENDERED
;	SYMBOLICALLY RATHER THAN ABSOLUTELY.

;370	JM	30-AUG-84	10-34852
;	MOVE TYPEOUT MODE SAVE FROM DD2: TO AFTER LIS1:

;371	JM	 2-OCT-84
;	CAUSE RUBOUT OF TEMPORARY TYPEOUT MODE TO WORK AGAIN (BROKEN BY
;	EDIT 370).

;372	JM	21-NOV-84
;	FIX SINGLESTEP OF XPCW:  RESTORE CORRECT CONTEXT; DON'T OVERWRITE
;	SAVED FLAGS WITH SAVED PC.

;373	PTR	 6-DEC-84
;	NOT INSTALLED, EQUIVALENT TO EDIT 621.

;374	PTR	 6-DEC-84
;	ALREADY INSTALLED AS EDIT 601.

;375	PTR	 6-DEC-84
;	NOT INSTALLED, EQUIVALENT TO EDIT 622.

;376	PTR	 6-DEC-84
;	NOT INSTALLED (PARTLY INSTALLED AS EDIT 422).

;377	PTR	 6-DEC-84
;	ALLOW < > AS PATH DELIMITERS AS WELL AS [ ] IN TOPS-10 FILESPECS.
;	MINOR BUG IN <LF> RE TYPEOUT MODE FLAG.
;EDIT NUMBERS THRU 417 RESERVED FOR DDT V42 SPR'S.
;DDT V43 DEVELOPMENT BEGINS AT EDIT 420.

;420	PTR	 9-JAN-84
;	CREATE THIS SOURCE FILE FROM DDT V42(362).  CLEAN UP COMMENTS,
;	MAKE CODE FORMAT CONSISTENT AS POSSIBLE.  NO CODE CHANGES.

;421	PTR	 9-JAN-84
;	SUPPORT INTER-SECTION BREAKPOINTS.  IMPLEMENT $4M.

;422	PTR	18-JAN-84
;	ADD SUPPORT FOR $X OF XJRST INSTRUCTION.  FIX IO INSTRUCTION
;	RESULTS TYPEOUT.

;423	PTR	19-JAN-84
;	NOT INSTALLED.

;424	PTR	19-JAN-84
;	REVISE INSTRUCTION TYPEOUT CODE TO ALLOW FOR SYMBOLS WITH
;	NON-ZERO LEFT HALVES.

;425	PTR	20-JAN-84
;	FIX $X OF STACK INSTRUCTIONS TO WORK WITH LOCAL STACK POINTERS
;	IN NON-DDT SECTIONS.

;426	PTR	23-JAN-84
;	ALWAYS INSERT/REMOVE BREAKPOINTS AROUND INSTRUCTIONS.  JSYS CAN
;	CAUSE RANDOM DISPATCHES, INTERRUPT OR ARITH OVL MAY OCCUR;
;	MAKE SURE DDT HAS A CHANCE OF RECOVERING.

;427	PTR	24-JAN-84
;	REDO SAVEG: A BIT.  MOVE SOME EXEC MODE TYPEAHEAD CHECKS.

;430	PTR	24-JAN-84
;	INSTALL DLM'S SYMBOL TABLE CHANGES VERBATIM -- WILL CHANGE TO
;	MEET SPEC LATER.  INCLUDES MDDT STUFF; RIP OUT WINDOWING CODE.
;	NO MORE "HIDDEN" SYMBOLS ON -20.

;431	PTR	25-JAN-84
;	ADD STACK/ARITH TRAP-CAUSING INSTRUCTIONS TO DANGEROUS OPCODE
;	TABLE; FIX [426] TO INSERT/REMOVE BPTS ONLY FOR DANGEROUS
;	INSTRUCTIONS.  REORGANIZE DANGEROUS OPCODE TABLE DEFINITION.

;432	PTR	26-JAN-84
;	FIX UP SYTSEC TO ASSUME -1,,N FORMAT.  IF WORD IS 0, DEFAULT
;	TO SECDDT.  CLEAR CACHE IF STUFFING NEW SYMBOL POINTERS (SYMCHK).

;433	PTR	30-JAN-84
;	MAKE FILDDT ASSEMBLE AGAIN.  CNTRLZ/CNTRLE WERE TOO BIG FOR COMMAND
;	DISPATCH TABLE.

;434	PTR	 3-FEB-84
;	KEEP SYMCHK FROM SWITCHING SYMBOL TABLES IN MDDT/KDDT.
;	NEVER LOOK OUTSIDE SECTION 0 FOR SYMBOL TABLES IF RUNNING IN ZERO.
;435	PTR	 3-FEB-84
;	FIX [430] TO USE IFIW WHEN ZEROING "@SYMP".
;	CHANGE MAP AC,(R) AND SKIP (R) TO USE @R (SO SEC. 0 REFS FROM
;	NON-ZERO WILL WORK).

;436	PTR	 6-FEB-84
;	FIX [430] SO DOESN'T REFERENCE .EDSEC ON -10.

;437	PTR	 6-FEB-84
;	SPECIAL MDDT BREAKPOINT INTERLOCK; ONLY ONE FORK CAN SET BREAKPOINTS
;	AT A TIME.  SET DEFAULT MDDT/KDDT BREAKPOINT BLOCKS.
;	CHANGE MDDT/KDDT PSECT NAMES.

;440	PTR	15-FEB-84
;	MAKE <FOO>$X DO THE INSTRUCTION IN USER'S SECTION, NOT DDT'S SECTION.
;	FIX CNTRLZ NOT TO USE $X CODE.

;441	PTR	15-FEB-84
;	MAKE $V DEFAULT SECTION IF NONE TYPED.

;442	PTR	16-FEB-84
;	FIX HANDLING OF SYTSEC SO SDDT STILL WORKS.
;	MAKE HISEG S.T. CHECKS DO LOCAL FETCHES.

;443	PTR	23-FEB-84
;	DEFAULT BPBLK TO LAST N WORDS IN SECTION.  MAKE SURE IT HAS ROOM
;	FOR $X NEEDS.

;444	PTR	24-FEB-84
;	FIX SYTSEC HANDLING SOME MORE SO S.T. STUFFING (INCL SDDT) WORKS IN
;	NON-ZERO SECTIONS.

;445	PTR	27-FEB-84
;	MAKE MDDT STACK POINTER GLOBAL.  OTHERS SHOULD STILL BE LOCAL.

;446	PTR	27-FEB-84
;	DON'T DIDDLE PSI STATUS IN MDDT. STACK NOT SET UP AT THAT POINT ANYWAY.

;447	PTR	27-FEB-84
;	IN <INSTR>$X, DON'T INSERT BREAKPOINTS UNLESS WE'RE REALLY GOING
;	TO EXECUTE THE INSTRUCTION.

;450	PTR	27-FEB-84
;	TURN SOME RAW NUMBERS INTO SYMBOLS IN KL PAGING STUFF.
;	FIX EXEC MODE $W, INCLUDE CST WRITE BIT.

;451	PTR	27-FEB-84
;	IMPLEMENT "PERMANENT DEFAULT SECTION," $6M.  IF SET, USE IT INSTEAD
;	OF LLOCS IN DEFSEC.  REWRITE DEFSEC TO INCLUDE NEW ROUTINE GDFSEC
;	(GET DEFAULT SECTION).
;452	PTR	28-FEB-84
;	WHEN A LOCAL AND GLOBAL HAVE THE SAME VALUE, CONSISTENTLY PICK
;	THE GLOBAL FOR TYPEOUT.  IMPROVEMENT ON [327].

;453	PTR	28-FEB-84
;	FIX PROBLEM WITH OKAF.  CLEAR IT IN MORE PLACES, SO # APPEARS
;	AFTER LOCALS CONSISTENTLY.

;454	PTR	 2-MAR-84
;	FIX PROBLEM WITH [447].  INSTR$X COULD DIE IF BREAKPOINTS SET.

;455	PTR	 5-MAR-84
;	IN KDDT USER MODE, JUMP INTO MONITOR ON ^Z SO IT CAN PLAY MAPPING
;	GAMES.  THIS IS SO "@GET SYSTEM:MONITR  @START 140" WILL WORK.

;456	PTR	21-MAR-84
;	OPDEF SOME OPCODES SO THAT DECREPIT VERSIONS OF MACRO CAN STILL
;	ASSEMBLE DDT.

;457	PTR	22-MAR-84
;	FIX SYMCHK NOT TO STEP ON FILDDT'S SYMBOL POINTERS.  FOR NOW
;	FILDDT WILL IGNORE $5M.

;460	PTR	30-MAR-84
;	MAKE $X OF PC-SECTION-REF INSTRUCTIONS (BYTE, EXTEND, BLT, JSYS)
;	EXECUTE IN ORIGINAL PC SECTION.

;461	PTR	18-APR-84
;	MASSIVE EDIT TO RECOGNIZE PDV'S AND THEIR SYMBOL VECTORS.
;	THE IOWD IS HEREBY DEFUNCT.  SYMBOL TABLE POINTERS ARE NOW KEPT
;	INTERNALLY AS TWO-WORD ADDRESS/LENGTH PAIRS.  SYMP AND FRIENDS ARE
;	NOW BLOCKS OF SYMBOL TABLE INFORMATION.  THIS CHANGES HOW SYMBOL
;	TABLES ARE HANDLED ALL OVER DDT.  IN PARTICULAR, SYMFIX, SYMCHK
;	AND CLSFIL HAVE BASICALLY BEEN REWRITTEN.  ALL OTHER PLACES THAT
;	TOUCH SYMBOL TABLE POINTERS HAVE BEEN CHANGED TO ACCOUNT FOR THE
;	NEW FORMAT.  NOTE THIS EDIT NEVER REFLECTS CHANGES TO SYMBOL TABLE
;	POINTERS IN THE USER'S ORIGINAL COPY (EXCEPT FILDDT).

;462	PTR	18-APR-84
;	PROHIBIT PATCHING ACROSS SECTION BOUNDARIES.  USE PATCHED SECTION'S
;	.JBFF, NOT SECTION ZERO'S, WHEN NO SYMBOLS EXIST.

;463	PTR	18-APR-84
;	SIMULATE $X OF JRSTF IN SECTION ZERO WHEN RUNNING IN NON-ZERO.

;464	PTR	19-APR-84
;	PRESERVE SECTION NUMBER OF PATCH SYMBOL.

;465	PTR	19-APR-84
;	PERMANENTLY WRITE-ENABLE BREAKPOINT BLOCK WHEN DOING AN $X,
;	SO THE "SOS FOO" DOESN'T CAUSE AN ILL MEM WRITE.
;466	PTR	23-APR-84
;	IMPLEMENT $$:/TEXT/ TO LOOK UP FIRST PDV WITH NAME TEXT AND
;	SET $5M TO ITS ADDRESS.  USER-FRIENDLY VERSION OF $5M.
;	$$1: TYPES OUT CURRENT PDV NAME IF ANY.

;467	PTR	23-APR-84
;	FIX [461] SO DEFINING NEW SYMBOLS WORKS.

;470	PTR	24-APR-84
;	NEW ROUTINE INCSYP TO UPDATE INTERNAL SYMBOL TABLE POINTERS AS
;	WELL AS USER'S ORIGINAL POINTERS (EXCEPT FILDDT, WHICH UPDATES
;	POINTERS ONLY ON CLOSE).

;471	PTR	25-APR-84
;	FIX SYMCHK TO ALWAYS SET ESTUT (PREVENTS STARTUP PROBLEMS).

;472	PTR	27-APR-84
;	HAVE TTYSAV CALL SYMCHK, SO POINTERS WILL REALLY BE SET UP
;	ON ENTRY.  THAT WAY IF THE FIRST THING THE USER DOES IS "$5M/"
;	IT WILL ALREADY BE SET UP.  MAKE AN EFFORT TO KEEP TOPS-10 EDDT
;	WORKING WITH THIS (NOT TESTED).  NUDGE CONDITIONALS TO PREVENT
;	SOME UNDEFINEDS.

;473	PTR	30-APR-84
;	BYTE POINTERS GIVEN TO A JSYS IN SECTION ZERO MUST BE 1-WORD LOCALS.

;474	PTR	 1-MAY-84
;	TURN ON FTPAGM IN -20 EXEC MODE.

;475	PTR	 3-MAY-84
;	LOOK FOR HISEG TABLE EVEN IF POINTERS ARE STUFFED.

;476	PTR	 7-MAY-84
;	TEACH INCSYP ABOUT 0$5M.  DON'T CALL SYMCHK SO OFTEN (DEPRA).
;	LET FILDDT READ DUMPS AGAIN.  MAKE ERROR MESSAGE IF USER TRIES TO
;	CREATE A PAGE WHEN $$1W.

;477	PTR	 8-MAY-84
;	FIX $NM (OTHER THAN $5M) IN FILDDT TO LOOK LIKE IT ALWAYS DID.

;500	PTR	 8-MAY-84
;	IF DDT IN NON-ZERO, PC IN ZERO, XMOVEI BECOMES PC REF INSTRUCTION.
;	(XMOVEI 1,0 WOULD RETURN 1,,0 INSTEAD OF 0,,0.)
;	FIX TYPEOUT OF XMOVEI 1,0 SO 0 TYPES OUT.

;501	PTR	 9-MAY-84
;	SWITCH MONITOR DDTS BACK TO USING EDV ([430] AND OTHERS HAD THEM
;	USING JOBDAT).  MAKE TTYRE6 LOOK MORE LIKE V42.

;502	PTR	12-MAY-84
;	MAKE SYMCHK SET .JBUSY IF CREATING AN UNDEFINED SYMBOL POINTER
;	OUT OF THIN AIR (JOBDAT ONLY).  MAKE IOWBLK WORK FOR MONITORS.
;	MAKE SURE SYMBOL BLOCKS CLEARED IF NO POINTERS FOUND.
;503	PTR	14-MAY-84
;	IN SAVEG, DON'T SET LLOCS IF IN AN $X SITUATION (SCREWED UP
;	HISEG SYMBOL TABLE).  FIX BUG IN [502].  DON'T MAKE TTYSAV CALL
;	SYMCHK, IT'LL HAPPEN TOO OFTEN -- CALL SYMCHK DIRECTLY WHEN DDT
;	IS STARTED.  DON'T NEED TO ON BREAKPOINT, DISPLAY ROUTINES WILL
;	TAKE CARE OF IT.

;504	PTR	22-MAY-84
;	MAKE UDDT-20 LIVE IN ITS OWN SECTION.  CREATE AN "EXPORT" VECTOR
;	TO BE POINTED TO BY DDT'S PDV.  KEEP DDT FROM FINDING ITS OWN
;	PDV UNLESS RUNNING ALONE IN THE FORK (DETERMINED VIA ENTRY VECTOR).
;	DEFAULT LLOCS TO STUB'S SECTION OR ENTRY VECTOR SECTION (USER-20)
;	OR DDT'S SECTION (MONITOR-20, ALL-10).

;505	JM	31-MAY-84
;	GET DDT TO UNDERSTAND $N"C$ AND $N"/.../ SYNTAX.  REPLACE PEEK
;	JSYS WITH XPEEK% IN FILDDT.

;506	PTR	 5-JUN-84
;	FIX OVERFLOW AT NUM+10.  FIX 3.2E2$F; BUG.  MAKE SURE WE HAVE
;	AN IFIW AT HIDPD1.  ONLY LOOK IN DDT'S SECTION FOR ITS PDV.

;507	PTR	 5-JUN-84
;	TEACH CODE AT UND1, DEF5, AND DEPRA THAT UNDEFINED SYMS HAVE 30-BIT
;	ADDRESS VALUES, SO FIXUPS CAN BE OUTSIDE SYM TAB'S SECTION.
;	CHAINS STILL CAN'T CROSS SECTION BOUNDARIES THOUGH.
;	FIX WHERE [505] BROKE $$: COMMAND.

;510	PTR	 7-JUN-84
;	SUPPORT ERJMPR/ERCALR/ERJMPS/ERCALS IN $X CODE.

;511	PTR	 7-JUN-84
;	TURN HIDPDV INTO ONCE-ONLY CODE TO PROTECT OURSELVES AGAINST OLD LINKS.
;	DDT 43 WILL GO OUT BEFORE LINK 6 SO WE HAVE TO BE CAREFUL.

;512	PTR	 8-JUN-84
;	SPLIT THE "DANGEROUS OPCODE" TABLE INTO TWO PARTS, THE MEMORY MUNGERS
;	AND THE TRULY DANGEROUS.  MEMORY MUNGERS FORCE RECHECK OF SYMTAB,
;	TRULY DANGEROUS GET FULL ENVIRONMENT AND BREAKPOINTS AROUND THE XCT.
;	RESTORE TEMP DISPLAY MODES AT TELLX, SINCE DANGEROUS XCT SMASHES THEM.

;513	PTR	 8-JUN-84
;	$G WOULDN'T WORK FOR A TOPS-10 STYLE ENTRY VECTOR IN A NON-ZERO SECTION.
;	MAKE IT LOOK AT <ENTRY VECTOR SECTION>,,.JBSA INSTEAD OF 0,,.JBSA TO
;	DETERMINE THE SECTION-RELATIVE START ADDRESS.

;514	PTR	12-JUN-84
;	$X OF A DANGEROUS INSTRUCTION FROM SECTION ZERO MUST BE EXECUTED
;	IN ZERO SO ANY GENERATED TRAP/INTERRUPT CAN BE DEALT WITH BY A
;	SECTION ZERO HANDLER.

;515	JM	13-JUN-84
;	FILDDT(TOPS-20):  ADD "ENABLE THAWED" COMMAND AND "GET <FILE>/THAWED"
;	OPTION.  OPEN FILE FOR UNRESTRICTED READ ACCESS WHEN READ ONLY.
;516	PTR	14-JUN-84
;	ADD XMOVEI AND XHLLI TO THE HARDWARE OPCODE TABLE, PERSERVING
;	HLLI AND SETMI FOR TYPEIN.

;517	PTR	14-JUN-84
;	IMPLEMENT $1: COMMAND TO TYPE OUT CURRENT OPEN MODULE (GIVEN IN
;	LAST $: COMMAND).

;520	JM	14-JUN-84
;	IMPLEMENT $1T COMMAND TO SET BYTE POINTER TYPEOUT MODE.

;521	PTR	15-JUN-84
;	REDO $XBLK NOT TO USE SOS'S, SINCE SOS CAN CHANGE USER'S FLAGS.
;	FIX DANGEROUS JRST'S (E.G. XJEN) TO SET DANGEROUS FLAG.
;	HANDLE LUUO'S OUTSIDE SECTION ZERO ON TOPS-20.

;522	PTR	15-JUN-84
;	CLEAN UP WHAT KINDS OF $$? ARE LEGAL IN WHAT FLAVORS.

;523	PTR	18-JUN-84
;	MAKE XDDT BE PSECTED LIKE UDDT WAS (SO CODE PSECT IS WRITE-LOCKED).
;	FIX HIDPDV SO XDDT CAN MODIFY THE (WRITE-LOCKED) PDV, AND SO RDDT
;	WON'T FALL OVER DEAD IN A USER PROGRAM.

;524	PTR	20-JUN-84
;	ON TOPS-20, IF A SECTION ZERO PROGRAM USES OLD-STYLE PSI TABLES TO
;	TRAP PAGE CREATES (E.G. PA1050) AND DDT CAUSES A PAGE CREATE FROM
;	OUTSIDE SECTION ZERO, THE MONITOR TERMINATES THE PROCESS SINCE THE
;	SECTION ZERO TABLE HAS NO PLACE FOR A 30-BIT PC.  TURNING OFF THE
;	PSI SYSTEM ONLY DEFERS THE INTERRUPT, WE MUST ACTUALLY DEACTIVATE
;	THE CHANNEL TO PREVENT TERMINATION.

;525	PTR	20-JUN-84
;	MISCELLANEOUS MINOR FIXES, MOSTLY COSMETIC.  UNDEFINE FLAG POWF
;	(BIT 24) SINCE IT WASN'T DOING ANYTHING USEFUL.

;526	JM	20-JUN-84
;	MOVE THE ROUTINE "TBPNT" OUT OF SINGLE STEPPING CODE INTO GENERAL
;	TYPEOUT SECTION.  THIS WILL MAKE EDIT 520 WORK FOR FILDDT.

;527	PTR	22-JUN-84
;	REDO $X SOME MORE TO LET $X OF ERSTR% JSYS WORK.

;530	JM	25-JUN-84
;	SET DEFAULT SECTION WITH $V, $G, $B, $W, $N, $E, $Z, AND $U.

;531	JM	26-JUN-84
;	MAKE $Z CONSISTENT WITH $W, $N, AND $E IN SETTING "." TO THE LAST
;	LOCATION ZAPPED.

;532	PTR	26-JUN-84
;	CLEAN UP REFERENCES TO SECUDD, ONLY USE IT IN USER DDT.
;	SINCE FETCHL NOW USED ONLY TO CHASE JOBDAT STUFF, MAKE IT RETURN
;	FAILURE IF SYTLOC INDICATES A PDV.
;533	PTR	26-JUN-84
;	CLEAN UP SYMBOL STUFF IN EDDT SO USER MODE EDDT IS MORE LIKE NORMAL
;	USER DDT.  MAKE GEVECS SKIP IF ENTRY VECTOR EXISTS, NON-SKIP IF NOT.
;	FIX SOME SYMBOLS SO DDT STILL ASSEMBLES FOR TOPS-10.
;	HAVE TOPS-20 MONITOR DDTS CHECK MONPDV IN CASE TOPS-20 HAS A PDV.

;534	JM	27-JUN-84
;	SAVE THE STATE OF THE COMF FLAG FOR OBJECTS SCANNED BY THE SYNTAX
;	"LOWER<UPPER>".  USE THIS INFORMATION IN SECTION DEFAULTING FOR THE
;	COMMANDS $Z, $E, $W, AND $N.

;535	JM	29-JUN-84
;	EXECUTE THE CONDITIONAL BREAKPOINT INSTRUCTION IN THE SECTION OF THE
;	BREAKPOINT.

;536	PTR	 2-JUL-84
;	DON'T FORCE SECTION-REF $X TO BE DANGEROUS.  CLEAR I.CJMP FLAG IN THE
;	CONDITIONAL BREAKPOINT INSTRUCTION CODE.

;537	PTR	 2-JUL-84
;	KEEP XDDT FROM INCORRECTLY REMEMBERING TTY STATE AFTER ONCE-ONLY CODE.

;540	JM/PTR	 3-JUL-84
;	PARSE SIGNED EXPONENTS CORRECTLY IN FLOATING POINT TYPEIN.  BAD
;	BEHAVIOR ASCRIBED TO EDIT 506.

;541	PTR	 5-JUL-84
;	FIX HIDPDV TO HANDLE LINK 5.1 CASE CORRECTLY.

;542	JM	 9-JUL-84
;	MAKE LEFT HALF OF ACCCF A DOUBLE COMMA FLAG SO THAT DEFAULT SECTIONING
;	WORKS PROPERLY WITH <TAB> AND "\".  (CF. TOPS-10 MAINTENANCE VERSION)

;543	PTR	10-JUL-84
;	IN DEPMEM WHEN WRITE-ENABLING A PAGE, TURN ON FH%EPN SO REFS TO
;	SECTION 0 WORK.

;544	PTR	10-JUL-84
;	FIX INCSYP ET AL. TO NOT INVALIDATE THE SYMBOL POINTER THEY JUST
;	UPDATED.  ALSO DO BETTER ERROR CHECKING IN DEFIN:.  THIS MAKES
;	DEFINING NEW SYMBOLS WORK (BROKEN SINCE [470]).
;	DON'T CHECK FOR INDIRECTION IN PDV OR SYMBOL VECTOR, ADDRESSES
;	MUST BE EITHER "IFIW LOCAL-ADDR" OR "GLOBAL-ADDR".

;545	PTR	11-JUL-84
;	FIX DEF5 NOT TO STOMP ON W1 (NEEDED FOR THE CALL TO REMUN).  THIS
;	WILL CAUSE DEFINING UNDEFINED SYMBOLS TO WORK AGAIN.
;	REPLACE SAVE OF W DONE IN SYMCHK (REMOVED BY 544).

;546	PTR	11-JUL-84
;	IN WRTSYM, DON'T CHECK FOR HISEG SYMTAB IF PDV.

;547	JM	11-JUL-84
;	GET/SET CORRECT DEFAULT SECTION FOR EFFECTIVE ADDRESS SEARCH.
;550	PTR	13-JUL-84
;	MAKE REFS TO TOPS-20 DATA/CODE BE GLOBAL REFS TO SECTION 1 WHERE
;	NECESSARY, SO SEC. 1 DOESN'T NEED TO BE MAPPED TO DDT'S SECTION.

;551	PTR	17-JUL-84
;	FIX $D SO YOU CAN SUPPRESS THE FIRST SYMBOL IN THE TABLE.

;552	PTR	19-JUL-84
;	MAKE SURE DDTSYV POINTS TO SYMTAB LOCALLY.

;553	PTR	19-JUL-84
;	ADD AN ERJMP AFTER THE PDVOP% IN PDVSE2, JUST IN CASE.
;	.POLOC CAN BE PRONE TO CAUSING ILL INSTR TRAPS.

;554	JM	23-JUL-84
;	SET FLOATING DEFAULT SECTION WHEN OPENING LOCATIONS VIA THE LOCATION
;	SEQUENCE STACK.

;555	PTR	23-JUL-84
;	TRY DOING A PEEK IF XPEEK% FAILS (SO FILDDT WILL RUN ON 5.1 SYSTEMS).

;556	PTR	25-JUL-84
;	IF RESTOR IS GOING BACK TO SEC. 0 AND THE PSI NEEDS TO BE TURNED
;	BACK ON, DON'T DO IT TILL WE'RE ALREADY IN SEC. 0.  THAT WAY DEFERRED
;	INTERRUPTS WON'T CAUSE THE FORK TO HALT.  DON'T BOTHER TREATING
;	PAGE-CREATES AS A SPECIAL CASE ANYMORE (REMOVE [524]).
;	MAKE ^Z RETURN TO THE STUB IF THERE IS ONE (SO PA1050 WILL SEE A HALT
;	PC IN SEC. 0).  EDIT 6 OF UDDT.MAC MUST BE INSTALLED.

;557	JM	 2-AUG-84
;	FILDDT:  IF A LOCATION IS OPENED WITH AN EXPLICIT SECTION TYPED IN,
;	USE THAT SECTION VALUE TO SET THE FLOATING DEFAULT SECTION.  ALSO,
;	DON'T SET THE FLOATING DEFAULT SECTION IF AN ACCUMULATOR IS POPPED
;	OFF OF THE LOCATION SEQUENCE STACK.

;560	PTR	 2-AUG-84
;	RESERVE A FULL 100 WORDS FOR THE BREAKPOINT BLOCK.  MAKE SYMBOLS
;	FOR PC FLAGS.  DON'T REF SECUDD IN EDDT.

;561	PTR	 8-AUG-84
;	MOVE DEFINITION OF SKPUSR ETC. TO AFTER THE .PSECT STATEMENT (SO
;	KDDT CAN BE LOADED IN A NON-ZERO SECTION, AND NOT HAVE THE OPDEFS
;	GET FIXED UP WITH SECTION NUMBERS).

;562	PTR	10-AUG-84
;	REDO $X OF PUSH(J) SO WE DON'T USE STACK MEMORY BEFORE ALLOCATING
;	IT IN THE STACK POINTER.  CAN KILL US IF PSI TRAPS WAITING.

;563	PTR	11-AUG-84
;	MAKE BUNCHES OF EDDT REFS TO EPT (AND OTHERS) BE INDIRECT INSTEAD
;	INDEXED.  THEN THE EPT DOESN'T HAVE TO BE IN EDDT'S SECTION.

;564	PTR	13-AUG-84
;	[461] INADVERTENTLY REMOVED THE LENGTH CHECK FROM CHKSYP.  PUT
;	IN A LENGTH CHECK.
;565	PTR	16-AUG-84
;	ADD FAKDDT ROUTINE TO KDDT.  CALLED DIRECTLY BY MONITOR AFTER KDDT
;	HAS CHANGED SECTIONS, SO BREAKPOINTS BREAK TO PROPER PLACES.

;566	JM	23-AUG-84
;	DEFSEC:  WHEN AN EXPLICIT SECTION IS TYPED IN (EITHER WITH ",," OR BY
;	USING A SYMBOL WITH A SECTION NUMBER IN THE LEFT HALF, ALWAYS SET THE
;	DEFAULT SECTION, EVEN WHEN REFERENCE IS MADE TO AN ACCUMULATOR
;	(E.G. 1,,7).

;567	PTR	23-AUG-84
;	MAKE KDDT USE MONEDV IN PREFERENCE TO JOBDAT, EVEN IN USER MODE.

;570	PTR	 7-SEP-84
;	PREVENT PAGE CREATES FROM GENERATING PAGE-CREATE INTERRUPTS.  THIS
;	IS SO CREATING THE PAGE WHERE THE BREAKPOINT BLOCK SITS DOESN'T MAKE
;	TROUBLE.  THIS ALSO ALLOWS THE USER TO CREATE RANDOM PAGES WITHOUT
;	CAUSING AN INTERRUPT (FORMERLY, CREATING A PAGE WOULD CAUSE AN
;	INTERRUPT WHICH MOST LIKELY WOULD BE ASYNCHRONOUSLY HANDLED/REPORTED).

;571	JM	10-SEP-84
;	NEVER "FIX UP" A BLT INSTRUCTION FOR SINGLESTEPPING.  ADD THE SPECIAL
;	ENTRY "FETCHI" TO THE "FETCH" PROCEDURE.  "FETCHI" IS FOR FETCHING
;	INSTRUCTIONS, AND IT TREATS MEMORY ADDRESSES WITH RIGHT HALF IN THE
;	RANGE 0 THROUGH 20 AS ACCUMULATOR ADDRESSES.

;572	JM	10-SEP-84
;	MONITOR EDDT RUNNING IN USER MODE WILL NOT ATTEMPT TO LEAVE SECTION 0
;	IF IT SHOULD HAPPEN TO FIND ITSELF THERE.

;573	JM	10-SEP-84
;	WHEN PRINTING AN IFIW SECOND WORD OF A 2-WORD BYTE POINTER DISPLAY
;	"<2>" AS WITH AN EFIW WORD.

;574	PTR	12-SEP-84
;	USER-MODE KDDT SHOULD REF MONPDV IN SECTION ZERO, NOT SECTION 1.

;575	PTR	13-SEP-84
;	USER-MODE KDDT SHOULD BE MORE LIKE USER DDT.  DO NORMAL PDV
;	SEARCHING FOR 6.1, STILL WIND UP WITH JOBDAT IN 6.0.

;576	PTR	13-SEP-84
;	GIVE SINGLE-STEP $X AND INSTR$X DISTINCT PORTIONS OF THE BREAKPOINT
;	BLOCK, SO THEY DON'T INTERFERE WITH ONE ANOTHER (WILL HAPPEN IF
;	"CALL FOO$X" AND FOO HAS A BREAKPOINT IN IT).  REQUIRES RECLAIMING
;	THE BREAKPOINT BLOCK SPACE RESERVED FOR BREAKPOINT 0 (WHICH WILL
;	NEVER BE USED).

;577	PTR	19-SEP-84
;	IN FILDDT, CHECK FOR THE LAST EXISTING PAGE IN THE FILE INSTEAD OF
;	ALWAYS USING THE MAXIMUM POSSIBLE LENGTH.  THAT WAY SEARCHES ETC.
;	WILL STOP AT "REAL EOF."
;600	PTR	26-SEP-84
;	SPEED UP FNDPAG, FPVPG AND FRIENDS BY TRYING TO GUESS WHAT THE
;	VIRTUAL PAGE IS GOING TO BE, INSTEAD OF PLODDING THROUGH EVERY
;	PAGE EVERY TIME.

;601	PTR	27-SEP-84
;	ADD "FOO$?" COMMAND TO TYPE ALL SYMBOLS BEGINNING WITH CHARS "FOO".

;602	JM	29-SEP-84
;	IF DDT WAS STARTED FROM THE STUB (UDDT) AND $5M POINTS TO JOBDAT IN
;	THE SAME SECTION OR $5M IS 0, CHECK FOR STUFFED SYMBOL TABLE VALUES
;	ON EACH PASS THROUGH SYMCHK.

;603	PTR	10-OCT-84
;	ADD NEW $L COMMANDS TO TYPE OUT SECTION/PAGE ACCESSES.

;604	PTR	10-OCT-84
;	REVISE [600] SO ONE NEED NOT SUPPLY A GUESS TO FPVPG.

;605	PTR	15-OCT-84
;	CALL LISTEN DURING "FOO$?" SO USER CAN ABORT HIS FOOLISH CHOICE OF
;	PREFIX CHARACTERS.

;606	PTR	18-OCT-84
;	HAVE FILDDT-20 PARSE UNIT, CHANNEL, CONTROLLER NUMBERS IN DECIMAL
;	INSTEAD OF OCTAL.

;607	PTR	18-OCT-84
;	GROW DATA PAGES TO THREE, INCREASE STACK SIZE SO MDDT WON'T
;	FALL OVER FROM DECNET, REVERT MDDT TO LOCAL STACK POINTER IN 6.1.

;610	PTR	18-OCT-84
;	FIX HIDPDV AGAIN SO $W DEFAULT IS PRESERVED.

;611	PTR	22-OCT-84
;	FIX $L NOT TO REPORT BOTH WRITE AND COPY-ON-WRITE FOR THE SAME PAGE.

;612	JM	22-OCT-84
;	DEFINE A GENERAL PURPOSE CHECKPOINT FOR MDDT, AND INSTALL IT AROUND
;	THE BREAKPOINT BLOCK.

;613	PTR	31-OCT-84
;	FIX [600]/[604] AGAIN.

;614	JM	 7-NOV-84
;	CORRECT MDDT INTERLOCK LOGIC (CF. [612]); ALSO MIGRATE TBPNT TO WORD
;	TYPEOUT ROUTINES FROM COMMAND ROUTINES.

;615	JM	 9-NOV-84
;	IF NO ENTRY VECTOR IN FORK, USER DDT20 SETS $5M TO -1,,0 RATHER THAN
;	-1,,SECDDT.  VT2XX COMPATIBILITY FEATURE:  "`" WORKS LIKE "<ESC>".

;616	PTR	12-NOV-84
;	MAKE "ADDR$0T" DO DEFAULT SECTIONING.
;617	PTR	12-NOV-84
;	MINOR BUGS IN FOO$? COMMAND.

;620	JM	16-NOV-84
;	USER DDT:  IF NO ENTRY VECTOR AND NO STUB, SET FLOATING DEFAULT
;	SECTION TO 0 ON ENTRY.  ANALOGOUS TO [615].

;621	RCB/PTR	 6-DEC-84
;	ALLOW TYPEOUT AND TYPEIN OF N-BIT ASCII STRINGS.  $NT AND $N"
;	NOW ALLOW N FROM 5 THRU 36 (DECIMAL).

;622	JMF/PTR	 6-DEC-84
;	PREVENT CLOBBERING PREVIOUS-CONTEXT SECTION WHEN JUMPING INTO
;	NON-ZERO SECTION IN EDDT.

;623	DPM/PTR	 6-DEC-84
;	FIXES TO $L: MAKE SURE NOT IN SYMBOL SPACE IN TOPS-10 EXEC MODE,
;	DON'T MAKE RASH ASSUMPTIONS ABOUT LOWSEG IN CHKADR, DO MORE
;	RATIONAL ARG CHECKING IN FILDDT.

;624	JM	 8-DEC-84
;	FIX SINGLESTEP OF ILDB/IDPB WITH LOCAL ACCUMULATOR REFERENCE TO BYTE
;	POINTER.	

;625	PTR	12-DEC-84
;	SPEED UP CHKADR IN FILDDT-20 BY NOT DOING AN RPACS% ON EVERY
;	CALL.  INSTEAD DO THE RPACS% WHEN THE PAGE IS MAPPED IN AND
;	REMEMBER THE BITS.  THIS WINS BIG ESPECIALLY IN SEARCHES WHEN
;	THE USER HAS SPECIFIED SOME KIND OF MAPPING (E.G. EP$U).

;626	PTR	22-MAR-85
;	FIX TEXTNT TO NOT TYPE GARBAGE FROM THE LEFTOVER BITS IN THE WORD.

;627	JM	10-APR-85
;	TEXTNT TYPES OUT LEFT-JUSTIFIED BYTES ONLY.

;DDT %43(627) SHIPPED WITH TOPS-20 6.1

;630	PTR/RCB/RDH	25-SEP-85
;	FOR TOPS-10, IF .JBSYM .GT. 0 THEN IT IS THE GLOBAL ADDRESS OF A
;	SYMBOL TABLE VECTOR.  DITTO $5M.  LOOK FOR TOPS-10 ENTRY VECTOR
;	ON $G.  FIX UP $L, $Y COMMANDS.  CHKADR, FETCH, STORE CAN SEE
;	BEYOND SEC. 0 FROM SEC. 0 (TOPS-10 EDDT ONLY).  FIX EXEC-MODE CHKSEC.

;631	RCB	 3-OCT-85
;	MAKE DEFAULT PAGING BE KL ALWAYS.  ADD BLTBU/BLTUB TO $X (KS-10).

;632	RDH	7-OCT-85
;	MAKE IO INSTRUCTION TYPEOUT PAY ATTENTION TO CPU TYPE (KS HAS DIFFERENT
;	IO INSTRUCTION SET).  ADD $20/21/22/23U TO SET KA/KI/KL/KS CPU TYPE.

;633	RDH/PTR	 8-OCT-85
;	MAKE SYMBOL "$NB" GLOBAL AS # BREAKPOINTS AVAILABLE (EDDT-10 ONLY);
;	ENHANCE BREAKPOITN INSERT/REMOVE TO DEAL WITH ERRORS (PARTICULARLY
;	BREAKPOINTS THAT MOVED); ONLY TYPE ONE ERROR MESSAGE PER BREAKPOINT
;	FAILURE.

;634	RDH	29-OCT-85
;	MAKE DDT %43 WORK ON TOPS-10 (ASSORTED TYPOS, ETC.). *NEVER* INSERT
;	BREAKPOINTS ON $X (IT CAN'T WORK). IF AN $4M BLOCK HAS BEEN SPECIFIED,
;	UNCONDITIONALLY USE IT (ALWAYS 3-WORD JSR'S, ETC.), OTHERWISE VERIFY
;	THAT DDT IS MAPPED INTO THE APPROPRIATE SECTION AND BLINDLY JUMP
;	INTO THAT SECTION FOR $X'ING. ALLOW NZS REFERENCES FROM SECTION ZERO
;	(RENAMES NZSXCT INTO PZAFI, CALLED LIKE PCAFI; RENAMES DEFSEC INTO
;	CEFFAS). FIX $L. IF NZS SYMBOL TABLE(S) AND DDT IN SECTION 0 THEN
;	TRY FOR NZS, MAPPING SECTION 0 INTO SECTION 1 (USER MODE ONLY) IF
;	POSSIBLE. MAKE <INSTR>$$NX TRY TO EXECUTE THE INSTRUCTION IN SECTION
;	"N" (IF BLANK, THEN OK TO EXECUTE IN DDT SECTION). ALLOW BOTH .JBSYM
;	AND .JBHSM TO POINT TO GLOBAL SYMBOL VECTOR ADDRESS (BUT UNDEFINEDS
;	ONLY FROM .JBSYM).

;635	RCB	9-JAN-86
;	FIX $X OF NZS LUUO (TOPS10). FIX USAGE OF ENTVC. UUO (TOPS10)
;	IN PARTICULAR TO HELP LOCATE USER'S SYMBOL TABLE FOR RUN/USE:N WHERE
;	PROGRAM CAN GET "RELOCATED" TO DIFFERENT SECTION.

;636	RDH	10-JAN-86
;	$M, $I, AND $U DON'T RETURN ADDRESS AS VALUE (EDIT 333 LOST).

;637	RDH	11-JAN-86
;	FILDDT CAN'T UPDATE 7.03 EXE FILE SYMBOL TABLE.

;640	RDH	19-JAN-86
;	MAKE THE "N" OF $NM AND $NI COMMANDS BE *DECIMAL*.

;641	PTR	30-JAN-86
;	MAKE CEFFAS DEAL WITH IMPOSSIBLE SECTION NUMBERS A BIT BETTER.
;	MAKE <INSTR>$X ALWAYS EXECUTE IN THE DEFAULT SECTION, INSTEAD OF
;	SOMETIMES IN DDT'S SECTION.

;642	RDH	4-MAR-86
;	MAKE TAG DEFINITIONS TAKE FULL 36-BIT VALUE, RATHER THAN JUST THE
;	RIGHT-HALF (18-BIT) VALUE OF "."

;DDT %44(642) Released with TOPS10 version 7.03, Spring 1986

;643	RDH	12-Apr-86	QAR 869027
;	$4M falls off end of literal, Ill Mem Refs (typo in [636]).

;DDT %44A(643) Released on Autopatch tape 14, Summer 1986

;644	RCB	1-Jul-86
;	Introduce $X to PMOVE & PMOVEM.  Add them to the opcode tables.

;645	RCB	10-Jul-86
;	Fix effective address calculation wrt global references to ACs.
;	Needed for LUUO handlers and $1T typeout.

;646	RCB	11-Jul-86
;	Fix some problems with supporting $$Y.  Only changes the I/O setup,
;	doesn't add any logic for interpreting .SYM files.

;647	RCB	11-Jul-86
;	Prepare for further changes to TOPS-10 entry vector format by allowing
;	IFIW as well as global address in $[n]G.

;650	RCB	11-Jul-86
;	I don't know what the authors of 626 & 627 meant to accomplish, but
;	those edits broke the symmetry of $nT with $7T.  Restore it, this
;	time correctly.

;651	RCB	15-Jul-86
;	Finally teach EDDT about CPNDDT.  Accomplished via new EDV words:
;	.EDCPN (physical address of CPNDDT) and .EDCPU (AOBJN-style pointer
;	to table of APR serial numbers).

;652	RCB	15-Jul-86
;	Finally teach FILDDT about the EDV.  This allows FILDDT to set up
;	mapping on a crash dump (if MCO 12993 is installed).  Requires EDV
;	word .EDCAC (pointer to crash ACs).

;653	RCB	16-Jul-86
;	Enhance foo$? (ABBREV) to accept LLIMIT, ULIMIT, and WRD2O for
;	additional constraints upon symbol value, flags, and module.
;	$1? will dump the open module (error if none).  $4? will dump only
;	globals.  $40? will dump only half-killed symbols.  The 74 mask
;	is anded and then compared.  2 is reserved.  LLIMIT and ULIMIT are
;	used in the obvious fashion for restricting possible values of
;	symbols to be displayed.

;654	RCB	19-Sep-86
;	Fix up changing sections for NZS symbol table access to account for
;	the fact that the flags are changed by PUSHJ, and hence not always
;	what we expect at the first entry in PDL.

;655	RCB	30-Sep-86
;	Fix up changing sections for $X of pc-reference instructions.  Always
;	do RESTOR/SAVE (rather than SWAP) so that SECDDT and the various
;	SKPS0/SKPNS0 side-effects will be right.

;656	DPM	30-Sep-86
;	Enhance FILDDT-10 by making it type the filespec being examined
;	or patched like the -20 version does.  Also type filespec of
;	file being yanked and the number of symbols loaded.

;DDT %44B(656) released on Autopatch tape 15, Fall 1986

;657	RCB	4-Nov-86
;	Fixup symbol table information typed out by $1: in FILDDT.

;660	RCB	21-Nov-86
;	Fix 0$nB in non-zero sections not to set 1,,0 as the B.P. address.

;661	RCB	6-Jan-87
;	Fix global breakpoints using the breakpoint block not to assume the
;	JSR came from section 0.

;662	RCB	16-Jan-87
;	Fix hidden symbol processing problems with TOPS-10 EDDT, especially
;	for SMP.  This has the side-effect of replacing edit 657.

;663	RCB	21-Jan-87
;	Finally physically remove the papertape code.  This finishes edits 247,
;	307, and 322.  FTPTP has been completely removed.

;664	RCB	26-Jan-87
;	Fix up all symbol tables in the ring of EDVs when using hidden symbol
;	processing.  EDDT-10 only.

;665	RCB	 1-Feb-87
;	Fix up $? for NZS DDT examining a program's symbols in S0.

;666	RCB	 6-Mar-87
;	Fix up $X of ILDB/IDPB with byte pointer in an AC and PC not in DDT's
;	section to not increment the B.P. twice.

;667	RCB	 6-Mar-87
;	Fix up for "3/-1,,400<SP><TAB>" nonsense.
;	Don't mistake garbage for an attempt at a DDT internal address, and
;	allow space after a comma to override the left half for section
;	defaulting.

;670	RCB	10-Mar-87
;	Revoke the second half of 667.

;671	RCB	15-May-87
;	Fix PDFSEC.  It gets in TOPS-20's way, too.

;672	RCB	02-Jun-87
;	Fixup some definitions for TOPS-20 to account for the continued
;	existance of 4.1 monitors.

;673	RCB	03-Jun-87
;	672 is incomplete.  Forgot about FILDDT and XPEEK%.  Deal with it.

;674	RCB	28-Aug-87
;	CEFFAS calls too many low core address ACs.  Fix the mask.

;675	RCB	28-Aug-87
;	Default MDDT's initial floating section to MSEC1 rather than to MDDT's
;	own executing section.  Too many problems with ill-advised $X'ing from
;	section 6 happen otherwise.

;676	RCB	26-Feb-88
;	Fix the copyrights for TOPS-20 7.0 and TOPS-10 7.04.

;677	RCB	26-Feb-88
;	Fix problem with building WHO and with the TOPS-10 monitor's symbol
;	table size in general.  Add FTDSYM, debugging symbols, which defaults
;	off for FTEX10 and on for all other cases.  If FTDSYM is off, then
;	all of DDT's local symbols will be expunged at assembly time.

;700	RCB	26-Feb-88
;	Add the clearm<setm>value$nM flavor of $M.  The 'clearm' is a mask
;	to clear and the 'setm' is a mask to set.  The masking arguments
;	are applied after the 'value' argument if it is also present.
;	This applies to $I as well as to $M, but it's more useful for $M.

;701	RCB	26-Feb-88
;	Fix DEPMEM to be able to handle SEGOP. and .PAGWL for 7.04.

;702	RCB	06-Oct-88
;	Add the $$ flavors of searches to type out the number of matches.

;703	RCB	08-Nov-88
;	Finally handle SEGOP.s for 7.04.  $$:/text/ looks for a hiseg named
;	'text' to use for the hiseg symbol table on a -10.  Also handle
;	name$$: appropriately (even for the -20).

;Become version 45 (due mainly to SEGOP.)

;704	RCB	10-Jan-88
;	Fix "c$ (single-character ASCII input).  Probably broken by edit 703,
;	but I'm not sure.

;705	RCB	11-Mar-89
;	Fix $L typeout for spy pages.  They are off by one when adjacent to any
;	(different) existing pages within a section.

;706	RCB	27-Apr-89
;	Fix $L for virtual spy pages.  The virtual bit was getting lost.

;707	RCB	20-Jun-89
;	Fix $$W, $$N, $$E to type match count again.

;710	RCB	20-Jun-89
;	Fix $U in FILDDT on a crash file when the EDV was good.  Re-use the EDV
;	information rather than reverting to $$U.

;711	RCB	21-Jun-89
;	Fix $L in FILDDT for a .EXE file with mapping in use.  Don't compare
;	virtual page numbers against physical limits.  Translate first.

;712	RCB	22-Jun-89
;	Clean up some symbol definitions (PC$xxx and PG$xxx) by borrowing SYSPRM
;	from GLXMAC.

;713	RCB	23-Jun-89
;	Add FTPURE for starting to do XDDT on the -10.

;714	RCB	23-Jun-89
;	Make $G and ^Z clear BPTIP so that we won't allow $X after a restart.

;715	RCB	18-Sep-89
;	Fix reference to JOBEDV in FILDDT startup (broken on TOPS-20).
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)
;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)
;FTPAGM		;PAGE MAPPING FEATURES
;FTSCSH		;SYMBOL TABLE CACHE
;FTUD20		;TOPS-20 USER DDT (SHORTHAND SYMBOL)
;FTEX10		;TOPS-10 EXEC DDT (SHORTHAND FOR FTDEC10&FTEXEC)
;FTUE10		;TOPS-10 NON-FILE DDT (SHORTHAND SYMBOL)
;FTDSYM		;DEBUGGING SYMBOLS (DDT'S OWN SYMBOLS INCLUDED)
;FTPURE		;READ-WRITE PSECT STARTS OUT EMPTY (TWOSEG ON -10)

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	FTVMX,<	FTVMX==0>
IFNDEF	FTMON,<	FTMON==0>
IFNDEF	FTOPX,<FTOPX==-1>
IFNDEF	FTDBUG,<FTDBUG==0>
IFNDEF FTPAGM,<FTPAGM==FTFILE!FTEXEC!FTDEC10> ;NEVER ON TOPS20 USER MODE
IFNDEF FTSCSH,<FTSCSH==-1>	;HAVE CACHE UNLESS EXCLUDED

;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,FTFILE,FTYANK,FTVMX,FTMON>
..N	<FTOPX,FTDBUG,FTPAGM,FTSCSH>

	FTUD20==FTDEC20&<^-FTEXEC>&<^-FTFILE>&<^-FTMON>	;USER -20
	FTEX10==FTDEC10&FTEXEC			;EDDT-10
	FTUE10==FTDEC10&<^-FTFILE>		;NON-FILE -10

IFNDEF	FTDSYM,<FTDSYM==FTDBUG!<^-FTEX10>>
IFNDEF	FTPURE,<FTPURE==FTMON>		;MDDT INITIALIZES IN THE PSB
..N	<FTDSYM,FTPURE>

  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&<FTEX20>,<PRINTX ? Illegal ^-FTEXEC>
  IFN FTFILE&<FTEXEC!FTVMX!FTMON!FTEX20>,<PRINTX ? Illegal FTFILE>
  IFN FTPURE&FTEXEC,<PRINTX ? Illegal FTPURE>
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,<
    IFN FTPURE,<TITLE	XDDT -- TOPS-10 EXTENDED DDT>
    IFE FTPURE,<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>
	SUBTTL	PROGRAM (JOB CONTEXT) PARAMETERS

  IFN FTFILE!FTVMX,<		;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!FTVMX

  IFN FTDEC10,<			;ONLY TOPS-10 USES .JBDDT
    IFE FTFILE,<
	LOC	.JBDDT		;CONTAINS DDT END AND START ADDRESSES
	XWD	DDTEND,DDTX	;SET DDT END AND START ADDRESS
	RELOC			;BACK TO NORMAL
    > ;END IFE FTFILE
				;ONLY TOPS-10 USES .JBBPT
    IFE FTFILE,<		;BUT ONLY IF NOT FILDDT
	LOC	.JBBPT		;WHERE THE BREAKPOINT PROCESSOR GOES
	$0BPT			;ADDRESS OF UNSOLICITED BREAKPOINT HANDLER
	RELOC			;BACK TO NORMAL
    > ;END IFE FTFILE
  > ;END IFN FTDEC10
SUBTTL	MACROS, ETC.

;.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

  > ;END OF IFN FTDEC20

;GENERAL MACROS

;SAVE ERROR MESSAGE STRING FOR POSSIBLE LATER TYPEOUT

;REMOVE IFN FTDEC20
DEFINE SMERS (MSG)<
	PUSH P,[[ASCIZ \MSG\]]
	POP P,MEMERS>

;TYPE LITERAL STRING

DEFINE TSTR (MSG)<
	MOVEI W1,[ASCIZ \MSG\]
	PUSHJ P,TSTRG>

;INIT DDT STACK

IFN FTMON,<
  DEFINE INIPDL<
	MOVEI	P,DDTPGA	;;WHERE MDDT THINKS ITS VARS ARE
	CAIN	P,DDTPXA	;;DIRECTLY MAPPED INTO PSB?
	SKIPA	P,[IOWD	LPDL,PDL] ;;YES, WE CAN USE A LOCAL STACK POINTER
	XMOVEI	P,PDL-1>	;;MDDT STACK PTR IS GLOBAL
> ;END IFN FTMON

IFE FTMON,<
  DEFINE INIPDL<MOVE	P,[IOWD LPDL,PDL]>> ;OTHERS ARE LOCAL
;MDDT CHECKPOINT DEFINITIONS

IFN FTMON,<
  DEFINE CHKIN (%CKLAB) <
	SKIPLE	CHKCNT			;;DO WE ALREADY HAVE THE LOCK?
	JRST	%CKLAB			;;YES
	AOSE	@[MSEC1,,MDDLCK]	;;NO, ATTEMPT TO TAKE LOCK
	JRST [	TSTR	<?MDDT BREAKPOINT BLOCK ALREADY IN USE>
		POPJ	P,]		;;FAIL
	PUSH	P,@[MSEC1,,FORKX]	;;SUCCEED
	POP	P,@[MSEC1,,MDDFX]	;;SHOW THE LOCK IS OURS.
%CKLAB:	AOS	CHKCNT>			;;INCREMENT OUR USE COUNT.

  DEFINE CHKOUT<
	SKIPG	CHKCNT			;;DO WE HAVE THE LOCK?
	JRST	.+3			;;NO, DON'T TOUCH IT.
	SOSG	CHKCNT			;;DECREMENT USE COUNT.
	SETOM	@[MSEC1,,MDDLCK]>	;;GIVE UP THE LOCK.

  DEFINE BRKLCK<
	SKIPG	CHKCNT			;;DO WE HAVE THE LOCK?
	JRST	.+3			;;NO, DON'T TOUCH IT.
	SETZM	CHKCNT			;;YES, CLEAR USE COUNT
	SETOM	@[MSEC1,,MDDLCK]>	;;GIVE UP THE LOCK.

> ;END IFN FTMON
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
TT3=16				;TEMPORARY

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

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

.XCREF	T1, T2, T3, T4, P		;SAVE SOME MORE PAPER
.XCREF	..MX1, ..MX2, ..TX1, ..TX2	;SUPPRESS JUNK SYMBOLS
  > ;END OF IFN FTDEC20

;DEFINE PUSHDOWN LIST LENGTH

	ND	LPDL,400	;400 WORDS IS ENOUGH FOR EVERYBODY
				;(INCLUDING MDDT)

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

	ND	NDDTPG,3	;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 FTUD20,<		;TOPS-20 USER DDT DEFINITIONS
	INTERN	DDTEXP		;"EXPORT" VECTOR FOR STUB
      > ;END IFN FTUD20

      IFN FTEX20,<		;TOPS-20 EDDT DEFINITIONS
	ENTRY	$EDDT		;FORCES LOADING OF EDDT IN LIB SEARCH
	$EDDT==0		;DON'T CARE ABOUT THE DEFINITION
	EXTERN	EDDBLK		;BREAKPOINT BLOCK FOR KDDT
	EXTERN	DDTCZ		;KDDT USER-MODE EXIT ROUTINE
	INTERN	FAKDDT		;RECOVER AFTER CHANGING SECTIONS
      > ;END IFN FTEX20

      IFN FTEX20!FTMON,<	;COMMON TOPS-20 MONITOR DEFINITIONS
	EXTERN	MSEC1		;USEFUL MONITOR SECTION
	EXTERN	MONPDV		;MONITOR'S PDVA IF ANY
      > ;END IFN FTEX20!FTMON

      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,DDTPXA	;MONITOR'S PLACE FOR MDDT'S VARIABLES
	EXTERN	FORKX,MDDLCK,MDDFX  ;MONITOR BPT INTERLOCK LOCATIONS
	EXTERN	MDDBLK		;BREAKPOINT BLOCK FOR MDDT
	EXTERN	MRETN		;MDDT RETURN ON ^Z
	EXTERN	SWPMWE,SWPMWP	;WRITE-ENABLE/LOCK SWAPPABLE MONITOR
	EXTERN	KIEPT,SPT	;ADDRESSES OF USEFUL TABLES
	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.
;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 FTPURE,<ND VARLOC,770000>	;TWOSEG VERSION'S VARIABLES
>

  IFN FTUD20,<
	ND	RUNLOC,740000	;TOPS-20 USER DDT'S DEFAULT ORIGIN
	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	ERCOD		;-20 EDDT IN EXTENDED RESIDENT CODE
  > ;END IFN FTEX20


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


  IFE FTEX20!FTMON,<


    IFGE RUNLOC,<


	IFGE VARLOC,<
	IFN FTPURE&FTDEC10,<.PSECT .HIGH.,RUNLOC>	;HISEG ON -10
	IFE FTPURE&FTDEC10,<.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	OPDEFS

;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

;PROCESSOR

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	BLTBU	[716000,,000000];KS-10 BLT BYTE TO UNIBUS
OPDEF	BLTUB	[717000,,000000];KS-10 BLT UNIBUS TO BYTE
OPDEF	PMOVE	[052000,,000000];KL-10 PHYSICAL MOVE
OPDEF	PMOVEM	[053000,,000000];KL-10 PHYSICAL MOVEM

OPDEF	GFAD	[102B8]		;G-FLOATING ADD
OPDEF	GFSB	[103B8]		;G-FLOATING SUBTRACT
OPDEF	GFMP	[106B8]		;G-FLOATING MULTIPLY
OPDEF	GFDV	[107B8]		;G-FLOATING DIVIDE
OPDEF	XMOVEI	[SETMI]		;MACRO HASN'T GOT IT YET
OPDEF	IFIW	[1B0]		; . . .
.NODDT	IFIW			;DON'T WANT TO OVERRIDE SETZ
OPDEF	NOP	[TRN]		;FAST NO-OP
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
	VMADR==7777,,777777	;MASK FOR VIRTUAL MEMORY ADDRESS
	VSECNO==7777,,0		;VIRTUAL SECTION NUMBER MASK
	PCFLGS==777740,,0	;PC FLAG MASK
	DDAF==1B0		;DDT INTERNAL ADDRESS
	EFIWX==17B5		;INDEX FIELD IN EFIW
	EFIWI0==1B0		;EFIW INDIRECT BIT 0
	EFIWI1==1B1		;EFIW INDIRECT BIT 1

	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 SKPMAX,3		;MAX NUMBER OF SKP'S IN $X LOGIC
	ND NSAVTB,^D17		;NUMBER OF PC'S IN RING BUFFER ($<CR> ETC.)
	ND INDPTH,100		;MAX NESTING IN $E SEARCHES
	ND ADRNGE,1000		;ADDRESS RANGE FOR SYMBOL+VALUE TYPEOUT
	ND XTYPAV,4321		;EXEC-MODE TYPEAHEAD CHECK INTERVAL
	ND XTYPAW,4		;WORDS OF BUFFER FOR EXEC-MODE TYPEAHEAD
	ND PVNAML,^D39		;PDV NAME LENGTH FOR TYPEIN
	PVNMSZ==<PVNAML/5>+1	;WORDS TO STORE PDV NAME

  IFN FTFILE,<ND SCSIZ,^D200>	;SIZE OF SYMBOL TABLE CACHE FOR FILDDT
  IFE FTFILE,<ND SCSIZ,^D100>	; ALL OTHER DDTS

;BREAKPOINT SYMBOLS, BREAKPOINT BLOCK ALLOCATION
;  REPEAT NBP,<BLOCK NBPBW>	;STORAGE FOR EACH BREAKPOINT (1-12)
;				;(NOTE: BREAKPOINT 0 DOESN'T NEED SPACE HERE)
;  BLOCK BPBRST			; FOR USE BY RESTOR
;  BLOCK BPB$XL			; FOR USE BY $X CODE
;  BLOCK BPI$XL			; FOR USE BY INSTR$X CODE

	ND NBP,^D12		;NUMBER OF BREAKPOINTS
  IFN FTEX10,<$NB==:NBP>	;FOR TOPS-10 MONITOR
	ND NBPBW,3		;WORDS PER ENTRY IN BREAKPOINT BLOCK
	BPBRST==NBP*NBPBW	;1ST BPBLK WORD AVAIL TO RESTOR
	ND BPBRSL,4		;WORDS NEEDED BY RESTOR IN BPBLK
	BPB$X==BPBRST+BPBRSL	;1ST BPBLK WORD AVAIL TO $X
	ND BPB$XL,2*<SKPMAX+1>+5;WORDS NEEDED BY $X IN BPBLK
	BPI$X==BPB$X+BPB$XL	;1ST BPBLK WORD AVAIL TO INSTR$X
	ND BPI$XL,2*<SKPMAX+1>+1;WORDS NEEDED BY INSTR$X IN BPBLK
	BPBLEN==BPI$X+BPI$XL	;TOTAL LENGTH OF USED BREAKPOINT BLOCK
	BPBMAX==100		;ADVERTISED LENGTH OF BREAKPOINT BLOCK
				; (MUST AGREE W/ TOPS-20 EDDBLK, MDDBLK)
  IF2,<IFL <BPBMAX-BPBLEN>,<PRINTX ?BREAKPOINT BLOCK TOO LONG>>
;ADDRESS (PAGE) ACCESS BIT DEFINITIONS

DEFINE	SYSPRM(NAM,T10,T20),<
	IFN FTDEC10,<NAM==<T10>>
	IFN FTDEC20,<NAM==<T20>>>

SYSPRM	PG$EXI,	PA.GNE,	PA%PEX	;PAGE EXISTS
SYSPRM	PG$REA,	PA.GRD,	PA%RD	;PAGE CAN BE READ
SYSPRM	PG$WRT,	PA.GWR,	1B15	;PAGE HAS SOME KIND OF WRITE ACCESS
SYSPRM	PG$WT,	PG$WRT,	PA%WT	;PAGE IS REALLY WRITABLE
SYSPRM	PG$CPY,	0,	PA%CPY	;PAGE IS COPY-ON-WRITE
SYSPRM	PG$EXE,	0,	PA%EX	;PAGE IS EXECUTABLE
SYSPRM	PG$ACC,	PA.GAA,	0	;PAGE ACCESS ALLOWED
SYSPRM	PG$PRV,	0,	PA%PRV	;PAGE IS PRIVATE
SYSPRM	PG$SHR,	PA.GSH,	0	;PAGE IS SHARABLE
SYSPRM	PG$HGH,	PA.GHI,	0	;PAGE IS PART OF HIGH SEGMENT
SYSPRM	PG$ABZ,	PA.GAZ,	1B17	;PAGE IS ALLOCATED BUT ZERO
SYSPRM	PG$SPY,	PA.GSP,	0	;PAGE IS ACTUALLY SPYING ON SOMEONE
SYSPRM	PG$VIR,	PA.GVR,	0	;SPY PAGE IS VIRTUAL (ON MONITOR)
SYSPRM	PG$NPG,	PA.GCP,	0	;PAGE CANNOT BE PAGED OUT
SYSPRM	PG$PGO,	PA.GPO,	0	;PAGE IS PAGED OUT
SYSPRM	PG$LCK,	PA.GLK,	0	;PAGE IS LOCKED IN MEMORY
SYSPRM	PG$NCA,	PA.GNC,	0	;PAGE IS NOT CACHED
SYSPRM	PG$SXI,	PA.GSN,	PA%PEX	;SECTION EXISTS
SYSPRM	PG$SMA,	PA.GIN,	1B12	;SECTION MAPPED ELSEWHERE
SYSPRM	PG$SIN,	PA.GIN,	SM%IND	;SECTION MAPPED INDIRECTLY
SYSPRM	PG$SFJ,	0,	1B11	;SECTION MAPPED TO FORK OR JFN
SYSPRM	PG$SEC,	PA.GSC,	37B17	;SECTION NUMBER MAPPED TO
SYSPRM	PG$FRK,	0,	777777	;FORK/JFN MAPPED TO


;BITS AND FIELDS RELEVANT TO KL PAGING.

  IFN FTEXEC!FTMON!FTPAGM,<
	AGEMSK==777B5		;AGE FIELD
	CSWRB==1B18		;CST WRITE ENABLE BIT
	CORMB==1B35		;CST MODIFIED BIT
	PTRCOD==7B2		;POINTER CODE FIELD
	 IMMCOD==1		;IMMEDIATE POINTER CODE
	 SHRCOD==2		;SHARED POINTER CODE
	 INDCOD==3		;INDIRECT POINTER CODE
	IMMPTR==<IMMCOD>B2	;IMMEDIATE POINTER
	PTPUB==1B3		;POINTER PUBLIC BIT
	PTWR==1B4		;POINTER WRITE BIT
	PTCACH==1B6		;POINTER CACHE BIT
	MSECTB==540		;MONITOR SECTION TABLE IN EPT
	PGKLMD==1B21		;KL PAGING MODE (IN CONI PAG,)
	PGTPEN==1B22		;TRAP ENABLE (PAGING ON) (IN CONI PAG,)
	TWUSR==1B0		;USER MODE BIT IN PF AND MAP WORD
	TWHPFF==1B1		;HARD FAILURE BIT
	TWVALD==1B2		;VALID BIT
	TWWRT==1B5		;WRITE REF BIT
  > ;END OF IFN FTEXEC!FTMON!FTPAGM
;PC BITS OF INTEREST

SYSPRM	PC$AFI,	PC.AFI,	PC%AFI	;ADDRESS FAILURE INHIBIT
SYSPRM	PC$USR,	PC.USR,	PC%USR	;USER MODE
SYSPRM	PC$BIS,	PC.BIS,	PC%BIS	;FIRST PART DONE
SYSPRM	PC$UIO,	PC.UIO,	PC%UIO	;USER IO MODE


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

;LEFT HALF BITS, PRESERVED AND SET ONLY BY USER

	TT$EYB==1B15		;ECHO $Y BIT (0=ECHO, 1=SUPPRESS)
	TT$BPI==1B16		;PRINT INSTRUCTION ON BPT (0=YES, 1=NO)
	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 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$SHR==SV%SHR			;PAGE IS SHARABLE
SV$WRT==SV%WRT			;PAGE IS WRITABLE
SV$CON==SV%CON			;PAGE IS CONCEALED
SV$ABZ==SV%ABZ			;PAGE IS ZERO
SV$MOD==1B17			;PAGE HAS BEEN MODIFIED (WINDIR BIT)
SV$FPN==777,,777777		;FILE PAGE NUMBER MASK

  > ;END OF IFN FTFILE

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

    IFN FTDEC10,<		;SOME TOPS-10 STUFF
.PVCNT==0			;PDV LENGTH
.PVNAM==1			;POINTER TO NAME STRING
.PVSYM==6			;SYMBOL VECTOR WORD
.PVLVR==12			;LINK VERSION WORD
SV%ABZ==0			;EXE DIRECTORY - PAGE IS ZERO
    > ;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
SV%SHR==1B1			;EXE DIRECTORY - PAGE IS SHARABLE
SV%WRT==1B2			;EXE DIRECTORY - PAGE IS WRITABLE
SV%CON==0			;EXE DIRECTORY - PAGE IS CONCEALED
SV%ABZ==1B3			;EXE DIRECTORY - PAGE IS ZERO
.PVEXP==.PVSTR			;"EXPORT" VECTOR (USED TO BE START ADR)
    > ;END OF FTDEC20 STUFF

.SVVEC==1775			;EXE DIRECTORY ENTRY VECTOR TYPE
.SVPDV==1774			;EXE DIRECTORY PDV TYPE

;PDV SYMBOL VECTOR SYMBOLS
.STLEN==0			;LENGTH WORD IN SYMBOL VECTOR
.STDAT==0			;TYPE/LENGTH WORD IN SUBTABLE
.STPTR==1			;ADDRESS WORD IN SUBTABLE
ST%TYP==77B5			;TYPE FIELD IN .STDAT WORD
ST%LEN==^-ST%TYP		;LENGTH FIELD IN .STDAT WORD
.UNDFD==0			;UNDEFINED SYMBOL TYPE CODE
.R50D==1			;RADIX-50 DEFINED TYPE CODE
.R50U==2			;RADIX-50 UNDEFINED TYPE CODE
;*** 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
DTF==	1B14			;DIGIT TYPED
SF==	1B15			;SYLLABLE
MF==	1B16			;MINUS SIGN TYPED
QF==	1B17			;QUANTITY TYPED IN TO WORD ASSEMBLER
DDLF==	1B18			;DDT INTERNAL SYMBOL TYPED
ROF==	1B19			;REGISTER OPEN
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
;BIT 24 AVAILABLE
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			;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,<

;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
  > ;END OF IFN FTDEC10
SUBTTL	START DDT

  IFE FTFILE,<

  IFN FTDBUG,<
DEBDDT::>

DDTX:
DDT:

IFN FTPURE&FTDEC10,<DEFINE SETRT1<@[0,,.JBBLT]>>
  IFN FTPURE,<
	MOVEM	T,SETRT1	;SAVE AN AC
    IFN FTDEC10,<
	DMOVEM	TT1,@[0,,.JBBLT+1] ;SAVE SOME MORE ACS
	MOVNI	TT1,<<END.V!PAGMSK+1>-<BEG.V&<^-PAGMSK>>>/PAGSIZ
	XMOVEI	TT2,BEG.V	;GET -VE LENGTH AND ADDRESS
	LSH	TT2,WRD2PG	;CONVERT TO STARTING PAGE NUMBER
	TXO	TT2,PA.GDC	;OK IF PAGES ALREADY EXIST
	MOVE	T,[.PAGCD,,TT1]	;UUO ARGUMENT POINTER
	PAGE.	T,		;TRY TO CREATE THE PAGES
	  TRNA			;CAN'T CREATE IN PHYSICAL MEMORY
	JRST	DDTIN0		;PAGES CREATED
	TXO	TT2,PA.GSL	;TRY TO MAKE THE PAGES ABZ INSTEAD
	MOVE	T,[.PAGCD,,TT1]	;UUO ARGUMENT POINTER
	PAGE.	T,		;TRY TO ALLOCATE THE PAGES
	  TRN			;GIVE UP AND HOPE FOR THE BEST
DDTIN0:	DMOVE	TT1,@[0,,.JBBLT+1] ;RESTORE UUO ARGUMENT ACS
    > ;END OF IFN FTDEC10
	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
    IFN FTDEC10,<
	XMOVEI	T,$0BPT		;WHERE ^D SHOULD GO
	MOVEM	T,@[0,,.JBBPT]	;SET IT UP
	SKIPE	@[0,,.JBDDT]	;IF ALREADY HAVE THIS,
	JRST	DDTIN1		;DON'T WASTE THE UUO
	MOVE	T,[DDTEND,,DDT]	;NO--WE NEED TO SET THIS UP
	SETDDT	T,		;SO DO IT
    > ;END OF IFN FTDEC10
DDTIN1:	MOVE	T,SETRT1	;RESTORE SCRATCH AC
  > ;END IFN FTPURE

  IFN FTYANK,<
	SETZM	COMAND>		;INDICATE NO COMMAND FILE IF
				;STARTING BY DDT COMMAND
	JSR	SAVE
	 PUSHJ	P,REMOVB
  IFN FTUD20,<			;CHECK DDTPDV BEFORE CALLING SYMCHK
	SKIPN	DDTPDV		;DID WE LOOK FOR IT YET?
	PUSHJ	P,HIDPDV	;NO, FIND IT.  COME BACK IF NON-EXISTANT.
	SKIPL	T,DDTPDV	;ALREADY LOCATE DDT'S PDV?
	HLL	T,SECDDT	;YES, FIX UP SECTION NUMBER
	MOVEM	T,DDTPDV	;REMEMBER PDVA IN OUR SECTION
  > ;END IFN FTUD20
	PUSHJ	P,SYMCHK	;MAKE SURE SYMBOLS ARE OK
  IFE FTVMX!FTMON,<MOVE W1,[ASCII /DDT/]> ;IDENTIFY USER MODE DDT
  IFN FTVMX,<
    IFE FTPURE,<MOVE W1,[ASCII /VMDDT/]>	;IDENTIFY TOPS-10 VM DDT
    IFN FTPURE,<MOVE W1,[ASCII /XDDT/]>	;IDENTIFY TOPS-10 X 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
	JRST	DD1.0		;GO FOR IT!
  >				;END IFE FTFILE

;RUDE HACK TO TRY TO GET THE COPYRIGHT TO BE INTACT IN DDT.REL

	.ORG	0
	EXP	0
	.ORG

;LEGAL NOTICE FOR BINARIES

	ASCIZ	"
COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1970,1989. ALL RIGHTS RESERVED.
"
SUBTTL	DDT COMMAND PARSER
DD1.0:	SKIPE	T,PTLLC		;GET LAST PATCH LOCATION CHANGED
	MOVEM	T,LLOC		;SET . TO IT, IF WE WERE PATCHING
	SETZM	PTLOC		;DEFINE NO PATCH IN PROGRESS
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
	MOVEM	T,SVBTS
	MOVE	T,PBYSS
	MOVEM	T,BYSS
	SKIPA			;SKIP TAB TYPEOUT
RET:	PUSHJ	P,TTAB		;TYPE A TAB AND FALL THROUGH TO DD2
  IFN FTMON,<BRKLCK>		;GIVE UP MDDT LOCK IF HOLDING IT.
DD2:	MOVE	T,[SCH,,SCHR]	;SAVE CURRENT TYPEOUT MODES
	BLT	T,ODFR		;IN CASE REPARSE NEEDED
	SETZM	PRNC		;PARENTHESES COUNT
	INIPDL			;INIT STACK POINTER
	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
	DMOVE	T,USYMP+S$ADR	;GET ORIGINAL UNDEFINED SYMBOL PTR
	DMOVEM	T,ESTUT		;INIT UNDEFINED SYM ASSEMBLER COPY
LIS0C:	TXZ	F,<^-<STF>&<-1,,0>>!LF1!CF1!OKAF!ITF!Q2F
LIS0E:	TXZ	F,<^-<STF!FAF!SAF>&<-1,,0>>!NAF!DDLF
	SETZM	ACCCF		;CLEAR COMMACOMMA FLAG/VALUE
	SETZM	WRD
LIS1:	SETZM	FRASE
	TXZ	F,FEF		;TURN OFF SCIENTIFIC EXPONENT FLAG
LIS2:	MOVEI	T,1
	MOVEM	T,FRASE1
	TXZ	F,MLF!DVF
L1:	TXZ	F,CF!CCF!SF!FPF!Q2F!LTF!TXF!DTF ;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:	CAIN	T,"`"		;<GRAVE> MAPPED TO <ESC>
	MOVEI	T,.CHESC
	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)
L0:	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)	; + - @ ,

	MOVE	W1,T		;GET A WORKING COPY OF ARGUMENT
	XOR	W1,WRD		;WILL ADD OVERFLOW?
	JUMPL	W1,SKP311	;NO, DO IT NORMALLY
	TLC	T,(1B0)		;YES, TURN OFF SIGN BIT
	ADD	T,WRD		;NOW DO THE ADD
	TLCA	T,(1B0)		;FIX THE SIGN BIT AND SKIP
SKP311:	ADD	T,WRD
	TXNE	F,TIF		;TRUNCATE INDICATOR FLAG
	HLL	T,WRD		;TRUNCATE
	MOVEM	T,WRD
	TXNN	F,QF
	MOVE	T,LWT
	SETZM	R
	DMOVE	W1,ESTUT	;GET ADR AND LENGTH FOR DEPRA
	CAMN	W1,USYMP+S$ADR	;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

;CALL TO EVAL ARGUMENT IF NOT ALREADY DONE (I.E. CODE WAS IN "NO-EVAL"
;ADDRESS RANGE)

XEVAL:	MOVEI	W,[POPJ P,]	;COUNT ON THIS LITERAL BEING AFTER EVERYTHING
	SUBI	W,DDTOFS	;ADJUST FOR OFFSET
	JRST	L0		;GO EVAL, THEN JUMP TO THE POPJ
;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		;SYMBOL DOES NOT EXIST
	TXNE	F,ROF		;SYM EXISTS, LOCATION OPEN
	CAILE	W,CARR-DDTOFS	;AND STILL BUILDING WORD FOR IT?
	 JRST	UNDEF		;NO - THEN "U" ERROR (E.G. "=" CMD)
	CAIE	W,ACCF-DDTOFS	;EXPRESSION INVOLVING A COMMA?
	SKIPE	PRNC		;OR INSIDE PARENTHESIS?
	 JRST	UNDEF		;YES - "U" ERROR
	JRST	UND4		;NO, CONTINUE

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

UND4:	MOVEI	T,"#"
	CAIE	W,ASSEM-DDTOFS
	PUSHJ	P,TOUT
	SOS	ESTUT		;MAKE ROOM IN UNDEF TABLE
	SOS	ESTUT
	AOS	ESTUTL		;UPDATE LENGTH TOO
	AOS	ESTUTL
	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
	MOVE	T,LLOCO		;WANT 30-BIT FIXUP ADDRESS
	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
	SETZ	T,
	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 (ERR,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 (LLIM,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,ERR);	(110)	 H    I    J
D (KILL,PAGMAP,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

RERR:	SETZ	T,		;ERROR RETURN WO PRINTING ANYTHING
	JRST	WRONG2

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:	INIPDL			;ENSURE FRESH STACK
  IFN FTYANK,<			;IF COMMAND FILES SUPPORTED
	SKIPE	COMAND		;IN A COMMAND FILE?
	SKIPN	YASWF		;YES, ABORT ON COMMAND ERROR?
	JRST	WRONG3		;NO,KEEP ON GOING (IGNORE ERROR)
	PUSH	P,T		;YES, SAVE ERROR SYMBOL
	PUSHJ	P,PTRKIL	;KILL OFF THE COMMAND FILE
	POP	P,T		;RESTORE ERROR SYMBOL
	TXZ	F,ROF		;ARBITRARILY CLOSE OPEN LOCATION
  > ;END IFN FTYANK
WRONG3:	JUMPE	T,WRONG4	;SKIP DINK IF NOTHING TO TYPE HERE
	PUSHJ	P,TOUT		;ISSUE ERROR MESSAGE
	PUSHJ	P,TBEL		;AND DINK THE USER

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

NUM:	TXO	F,DTF		;DIGIT TYPED
	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	W1,DEN
	MULI	W1,12		;CONVERT TO DECIMAL WITHOUT OVERFLOW
	ADD	W2,T
	MOVEM	W2,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!DTF	;EXPONENT IFF (LTF)'*(FEF)'*(T=105)*(SF)*(FPF)*(DTF)=1
	TXZN	F,LTF!FEF!SF!FPF!DTF
	CAIE	T,"E"
	TXOA	F,LTF
	TXOA	F,FEF
	JRST	LET1
	TXZN	F,MF
	SKIPA	W1,SYL
	MOVN	W1,SYL
	MOVEM	W1,FSV
	SETZM	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
	PUSHJ	P,PSYMT		;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
				;REMOVE USELESS CODE
	MOVE	W2,DEN
	SETZM	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
	SETZ	T,
	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

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
QUESTN:	PUSHJ	P,TCRLF		;HERE FOR "?"
IFN FTDEC20,<
	TXNE	F,CCF		;TWO ESC?
	JRST [	PUSHJ	P,XEVAL		;YES, EVAL PREV EXPRESSION
		MOVEI	T1,.PRIOU
		HRLOI	T2,.FHSLF	;ASSUME THIS FORK, LAST ERROR
  IFN FTEXEC,<
		SKPUSR			;ONLY LEGAL IN USER MODE
		JRST	ERR		;EXEC MODE, ERROR
  > ;END IFN FTEXEC
  IFN FTFILE,<
		TXC	F,QF		;TEST FOR ILLEGAL COMBINATIONS
		TXNE	F,QF!FAF	;FOO$$? IS ONLY LEGAL FORM
		JRST	ERR		;FORK OR NO ERR CODE, NO GOOD
  > ;END IFN FTFILE
  IFE FTFILE,<
		TXNE	F,FAF		;FORK SPECIFIED?
		HRL	T2,LLIMIT	;YES
		TXNE	F,QF		;ERROR CODE SPECIFIED?
  > ;END IFE FTFILE
		HRR	T2,WRD		;YES
		SETZ	T3,
		ERSTR%
		 ERJMP	ERR		;TRAP ILLEGAL FORK NUMBER FROM USER
		 JRST	ERR
		JRST	DD1]		;DONE
> ;END IFN FTDEC20

	TXNE	F,CF		;ONE ESC?
	 JRST [	TXNE	F,QF!SAF!FAF!Q2F ;YES, ANYTHING TYPED IN FRONT?
		JRST	ABBREV		;YES, GO TYPE SOME SYMBOLS
		SKIPE	W1,MEMERS	;YES, TYPE LAST ERROR MESSAGE
		PUSHJ	P,TSTRG
		JRST	DD1]
	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
;FOO$? COMMAND -- TYPE OUT SYMBOLS STARTING WITH FOO

ABBREV:	TXNE	F,TIF!COMF!PTF!MF!CCF ;CHECK FOR LEGAL ARGUMENTS
	JRST	ERR		;$$ AND EXPRESSION ARE ILLEGAL
	SKIPN	W1,SYM		;ANYTHING RESEMBLING A SYMBOL TYPED?
	TXNE	F,SAF!FAF!Q2F	;NO, IS IT OK ANYWAY?
	SKIPA	W2,W1		;YES, GET ANOTHER COPY
	JRST	ERR		;NO, COMPLAIN
	TXNN	F,Q2F		;DID WE GET ANY FLAGS?
	SETZM	WRD2O		;NO, MAKE SURE WE KNOW IT
	MOVX	T,1B0		;NEGATIVE INFINITY
	TXNN	F,FAF		;HAVE A LOWER LIMIT?
	MOVEM	T,LLIMIT	;NO, SET IT UP
	TXNE	F,FAF		;CHECK AGAIN
	SKIPA	T,LLIMIT	;YES, COPY IT
	MOVX	T,<^-<1B0>>	;NO, USE POSITIVE INFINITY
	TXNN	F,SAF		;IF NO UPPER LIMIT GIVEN,
	MOVEM	T,ULIMIT	;USE WHAT WE JUST SET UP
	MOVE	T,ULIMIT	;GET UPPER LIMIT
	CAMGE	T,LLIMIT	;LIMITS IN THE RIGHT ORDER?
	JRST	ERR		;NO, COMPLAIN
	MOVEI	T,75		;ONLY MASKS CURRENTLY DEFINED
	ANDCA	T,WRD2O		;SEE IF ANY UNKNOWN BITS ARE ON
	JUMPN	T,ERR		;COMPLAIN IF SO
ABBRE1:	CAMLE	W2,[RADIX50 0,%%%%%]	;PADDED ENOUGH YET?
	JRST	ABBRE2		;YES
	IMULI	W1,50		;SHIFT SYM ONE PLACE TO THE LEFT
	IMULI	W2,50		;THIS ONE TOO
	ADDI	W2,47		;AND PAD TO BE UPPER LIMIT
	JRST	ABBRE1		;SEE IF IT'S ENOUGH

;HERE WITH W1 LEFT JUSTIFIED, BLANK PADDED, AND W2 LEFT JUSTIFIED, MAX PADDED.

ABBRE2:	DMOVEM	W1,ABBSY1	;SAVE THE PADDED SYMBOLS
	PUSHJ	P,SYMSET	;SET UP TO LOOK AT SYMBOL TABLE
	MOVE	T,WRD2O		;GET FLAGS AGAIN
	TRZE	T,1		;WANT ONLY OPEN SYMBOL TABLE?
	TXNN	F,PNAMEF	;YES, IS THERE ONE OPEN?
	CAIA			;IT'S OK, PROCEED
	JRST	ERR		;NO, GIVE UP
	ANDCAM	T,WRD2O		;MAKE 0/NON-0 FLAG FOR LATER
	ROT	T,-6		;SHIFT TO MATCH PNAME
	MOVEM	T,ABBSY3	;SAVE FOR FLAG TESTING
ABBRE3:	TRNN	R,36		;EVERY FEW SYMBOLS
	JRST [	PUSHJ	P,LISTEN	;CHECK FOR TYPEIN
		 JRST	.+1		;NOTHING, KEEP GOING
		 JRST	DD1]		;USER WANTS TO ABORT
	SOSGE	R		;COUNT DOWN SYMBOLS
	PUSHJ	P,ADVSYM	;REACHED END, ANY MORE?
	SKIPA	W2,@SYPTR	;FETCH THE SYMBOL
	JRST	DD1		;NO MORE SYMBOLS, ALL DONE
	MOVE	T,W2		;KEEP A COPY WITH THE FLAGS
	TXZE	W2,PNAME	;IS IT A MODULE NAME?
	TDZA	W1,W1		;NO, REMEMBER THAT
	SETO	W1,		;YES, REMEMBER THAT
ABBRE5:	CAMG	W2,[RADIX50 0,%%%%%]	;PADDED TO SIX CHARS?
	JRST [	IMULI	W2,50		;NO, SHIFT ONE PLACE
		JRST	ABBRE5]		;AND TRY AGAIN
	JUMPE	W1,ABBRE7	;IS IT A MODULE NAME?
	MOVE	W,W2		;YES, SAVE (PADDED) NAME
	SKIPN	WRD2O		;IF ALL MODULES DESIRED,
	SOJA	R,ABBRE3	;TRY NEXT SYMBOL
	AOS	T,WRD2O		;INCREMENT COUNTER
	CAIN	T,2		;IF JUST PASSING OUR DESIRED MODULE NAME,
	SOJA	R,ABBRE3	;KEEP GOING
	JRST	DD1		;ELSE DONE
ABBRE7:	CAML	W2,ABBSY1	;IS IT IN RANGE?
	CAMLE	W2,ABBSY2
	SOJA	R,ABBRE3	;NO, TRY NEXT SYMBOL
	AND	T,ABBSY3	;YES, GET ITS FLAGS
	CAME	T,ABBSY3	;SEE IF A MATCH
	SOJA	R,ABBRE3	;NO, TRY NEXT
	XMOVEI	T,@SYPTR	;POINT TO SYMBOL ENTRY
	AOJ	T,		;WANT VALUE WORD
	MOVE	T,@T		;FETCH IT
	CAML	T,LLIMIT	;IN RANGE?
	CAMLE	T,ULIMIT	;BOTH WAYS?
	SOJA	R,ABBRE3	;NO, TRY NEXT SYMBOL
	PUSH	P,R		;YES, SAVE SYMBOL INDEX
	PUSH	P,T		;AND VALUE
	PUSHJ	P,PSYM		;YES, TYPE OUT THE (PADDED) SYMBOL
	PUSHJ	P,TTAB		;WHITE SPACE
	MOVE	W2,W		;GET MODULE NAME
	PUSHJ	P,PSYM		;TYPE THAT TOO (ALSO PADDED)
	PUSHJ	P,TSPC		;A SPACE
	MOVE	W1,@SYPTR	;GET SYMBOL FLAGS
	MOVEI	T,"G"		;INDICATE GLOBAL SYMBOL
	TXNN	W1,GLOBL	;UNLESS OF COURSE...
	MOVEI	T," "		;IT'S A LOCAL
	PUSHJ	P,TOUT		;TYPE THE INDICATOR
	PUSHJ	P,TTAB		;MORE WHITE SPACE
	MOVE	T,(P)		;RETRIEVE VALUE
	PUSHJ	P,TOC		;TYPE VALUE NUMERICALLY
	POP	P,W1		;GET VALUE BACK
	MOVN	W2,W1		;(X .AND. -X) = RIGHTMOST BIT OF X
	AND	W2,W1		;FIND THE BIT
	CAMN	W2,W1		;TYPE BIT NUMBER ONLY IF SINGLE-BIT VALUE
	 JFFO	W1,.+2		;FIND THE BIT NUMBER INTO W2
	  JRST	ABBRE9		;NOT EXACTLY ONE BIT, DON'T TYPE IT
	MOVE	W1,[ASCII /	(1B/]	;SEPARATING TEXT
	PUSHJ	P,TEXT		;TYPE IT OUT
	MOVE	A,W2		;GET THE NUMBER (NOTE: A=R)
	PUSHJ	P,FP7		;TYPE IT IN DECIMAL
	MOVEI	T,")"		;CLOSING TEXT
	PUSHJ	P,TOUT		;TYPE IT
ABBRE9:	POP	P,R		;RESTORE SYM INDEX
	PUSHJ	P,TCRLF		;CLOSE OUT THE LINE
	SOJA	R,ABBRE3	;AND GO FOR NEXT 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
  IFN FTSCSH,<			;ONLY IF USING SYMBOL TABLE CACHE
	PUSHJ	P,DELCSH	;REMOVE SYMBOL FROM SYMBOL TABLE CACHE
  > ;END IFN FTSCSH
	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:	SKIPL	R,SPSAV		;PICK UP POINTER TO LAST SYM
	PUSHJ	P,FETSYM	;PICK UP SYMBOL
	  JRST	ERR		;CAN'T GET IT?
	MOVE	S,T		;COPY SYMBOL
  IFN FTSCSH,<			;ONLY IF USING SYMBOL TABLE CACHE
	PUSHJ	P,DELCSH	;REMOVE IT FROM THE SYMBOL TABLE CACHE
  > ;END IFN FTSCSH
	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 OR ALT ALT COLON COMMANDS

TAG:	TXNE	F,CCF		;SYMBOL OR PDV?
	JRST	PDVSET		;PDV NAME
	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
  IFN FTSCSH,<			;ONLY IF USING SYMBOL TABLE CACHE
	PUSHJ	P,DELCSV	;REMOVE ANY CACHE SYMBOL USING THIS VALUE
  > ;END IFN FTSCSH
	PUSHJ	P,EVAL		;DEFINED SYMBOL?
	 JRST	DEF1		;NO - DEFINE
	MOVE	S,SYM		;YES - GET SYMBOL NAME BEING DEFINED
  IFN FTSCSH,<			;ONLY IF USING SYMBOL TABLE CACHE
	PUSHJ	P,DELCSH	;REMOVE THE SYMBOL FROM THE CACHE
  > ;END IFN FTSCSH
	MOVE	R,W1		;REMEMBER SYMBOL INDEX IN R
	JRST	DEF4		;REDEFINE EXISTING SYMBOL

DEF1:	TXZ	F,HSYMF		;ASSUME LOWSEG SYMBOL TABLE
	SKIPN	SYMP+S$ADR	;DEFINE A NEW SYMBOL
	JRST [	SKIPN	HSYMP+S$ADR	;NO ST, TRY HISEG PTR
		JRST	ERR		;NONE THERE EITHER
		MOVEI	W1,HSYMP	;WANT TO UPDATE HISEG POINTER
		PUSHJ	P,INCSYP	;GO TRY
		 JRST	DMER1		;COULDN'T, GO SAY WHY
		TXO	F,HSYMF		;REMEMBER HISEG TABLE USED
		SKIPL	PRGM		;AN OPEN MODULE IN THE HIGH SEG?
		JRST	DEF2		;NO, CONTINUE
		JRST	DEFF]		;YES, COMPENSATE FOR SUB FIRST
	MOVEI	W1,SYMP		;WANT TO UPDATE LO SEG POINTER
	PUSHJ	P,INCSYP	;GO DO IT
	 JRST	DMER1		;CAN'T, GO SAY WHY
	SKIPG	PRGM		;AN OPEN MODULE IN THE LOWSEG TABLE?
	JRST	DEF2		;NO, CONTINUE
DEFF:	AOS	PRGM		;YES, COMPENSATE FOR THE SUB
	AOS	PRGM		; . . .
DEF2:	AOS	PTFIX		;COMPENSATE FOR THE SUB HERE TOO
	AOS	PTFIX		;SO PAT.. WILL BE MOVED
  IFN FTSCSH,<			;ONLY IF USING SYMBOL TABLE CACHE
	PUSHJ	P,CLRCSH	;CLEAR CACHE, ALL INDEXES NOW WRONG
  > ;END IFN FTSCSH
	SOS	ESTUT		;EAT TWO WORDS OF PATCH SPACE
	SOS	ESTUT		;  FOR NEW SYMBOL TO LIVE IN
	SKIPN	R,ESTUTL	;DOES AN UNDEFINED TABLE EXIST?
	JRST	DEF3		;NO, JUST DEC ADDRESS OF WHERE IT WOULD EXIST

;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.

	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:	MOVEI	W1,USYMP	;IT ALL WORKED, MAKE OUR WORKING COPY
	PUSHJ	P,DECSYA	; OFFICIAL BY DECREMENTING UNDEF PTR
	 JRST	DMER1		;BUT... BUT...
	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
	MOVE	W2,R		;GET A COPY OF THE FIXUP FLAGS
	ANDX	R,VMADR		;REDUCE R TO 30-BIT ADDRESS
	PUSHJ	P,FETCHV	;GET OBJECT CELL
	 JRST	ERR
	TXNN	W2,STNEG	;ADDITIVE OR SUBTRACTIVE?
	SKIPA	S,LLIMIT	;ADDITIVE
	MOVN	S,LLIMIT	;SUBTRACTIVE
	TXNE	W2,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:				;DO FIXUPS RIGHT IN TOPS-10 MONITOR
  IFN FTFILE&FTDEC10,<		;PEEK BEFORE POKE
	SKIPE	FILING		;POKING MONITOR?
	 JRST	DEF60		;NO, SKIP AHEAD
	PUSH	P,T		;SAVE NEW WORD TO POKE
	PUSHJ	P,FETCHV	;YES, GET CURRENT WORD IN MONITOR
	 JRST	ERR		;PEEK FAILED
	MOVEM	T,POKBLK+1	;PUT INTO POKE. BLOCK
	POP	P,T		;RESTORE T
DEF60:
  > ;END IFN FTFILE&FTDEC10
	PUSHJ	P,STOREV	;STORE RESULT BACK INTO MEMORY
	 JRST	ERR		;FAILED
	JRST	DEF8		;GO REMOVE SYMBOL AND TRY AGAIN

DEF7:	MOVE	S,R		;COPY INITIAL FIXUP ADDRESS
DEF7A:	JUMPE	S,DEF8		;IF CHAIN REACHES 0, WE'RE DONE
	PUSHJ	P,FETCHV	;GET OBJECT CELL
	 JRST	ERR
	HRRZ	S,T		;SAVE CHAIN POINTER
	HRR	T,LLIMIT	;REPLACE WITH NEW VALUE
	PUSHJ	P,STOREV	;AND STORE BACK INTO MEMORY
	 JRST	ERR		;FAILED
	HRR	R,S		;LOOP IN-SECTION TO END
	JRST	DEF7A		;  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,Q2F		;2ND QUANTITY TYPED?
	SKIPA	TT,WRD2D	;YES, FETCH IT
	SETZ	TT,		;NO, DEFINITELY OURS
	JUMPN	TT,NAMTYP	;IF NOT $0:, GO SEE IF $1:
	TXNE	F,FAF!SAF!TIF!COMF!PTF!MF ;MOST ARGS BEFORE $0: ARE ILLEGAL
	JRST	ERR		;RESERVE THEM
	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
IFN FTSCSH,<
	JRST	CLRCSH>	;CLEAR SYMBOL TABLE CACHE
IFE FTSCSH,<
	POPJ	P,>

;HERE TO SET A NEW MODULE NAME.

NAMS2:	PUSHJ	P,NAMSRH	;SEARCH FOR THE NAME
	  JRST	UNDEF		;NOT FOUND
  IFN FTSCSH,<			;ONLY IF USING SYMBOL TABLE CACHE
	PUSHJ	P,CLRCSH	;FOUND IT, CLEAR THE SYMBOL TABLE CACHE
  > ;END OF IFN FTSCSH
	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
	 SETZ	T,		;NO HI SEG, OR EXEC MODE
	MOVEM	T,SEGNAM	;STORE SEGMENT NAME FOR SYMCHK
	POPJ	P,		;DONE

;HERE TO TYPE OUT CURRENT OPEN MODULE NAME

NAMTYP:	SOJN	TT,NAMLST	;IF NOT $1:, SEE IF $2:
	TXNE	F,QF!FAF!SAF!SF	;MOST ARGS ILLEGAL FOR $1:
	JRST	ERR		;RESERVE THEM
	SKIPN	T,PRGM		;IS THERE AN OPEN MODULE?
	POPJ	P,		;NO, JUST RETURN
	SOS	R,T		;POINT TO FIRST WORD OF SYMBOL ENTRY
	PUSHJ	P,FETSYM	;GET THE WORD
	 JRST	ERR		;CAN'T HAPPEN
	PUSH	P,T		;SAVE OVER TOUT CALL
	MOVEI	T,"/"		;SEPARATE TEXT FROM COMMAND
	PUSHJ	P,TOUT		; WITH A SLASH
	POP	P,W2		;GET SYMBOL BACK
	PUSHJ	P,PSYM		;TYPE IT OUT
	SKIPG	PRGM		;HISEG MODULE?
	SKIPN	T,SEGNAM	;WITH A NAME?
	POPJ	P,		;NO OR NO, ALL DONE
	MOVEM	T,LWT		;YES, SAVE IT AWAY
	PUSHJ	P,TTAB		;SEPARATE THE NAMES
	PJRST	SIXBP		;AND GO TYPE THE HISEG NAME

;HERE FOR $2: TO LIST ALL KNOWN MODULES

NAMLST:	SOJN	TT,ERR		;$2: WAS YOUR LAST CHANCE
	TXNE	F,QF!FAF!SAF!SF	;MOST ARGS ILLEGAL FOR $2:
	JRST	ERR		;RESERVE THEM
	PUSHJ	P,SYMCHK	;MAKE SURE OF SYMBOLS BEFORE HFETCH
	MOVEI	R,.JBHNM	;OFFSET FOR HISEG NAME
	PUSHJ	P,HFETCH	;GET THE NAME
	  SETZ	T,		;NONE THERE
	MOVE	W,T		;SAVE THE HISEG NAME FOR LATER USE
	PUSHJ	P,SYMSET	;SETUP TO SEARCH THE SYMBOL TABLE
	SOJ	R,		;ACCOUNT FOR AOSGE BELOW
	PUSHJ	P,TCRLF		;START AT LEFT MARGIN

;HERE TO GET NEXT MODULE

NAMLS2:	AOSGE	R		;IF OUT OF SYMBOLS IN THIS TABLE,
	PUSHJ	P,ADVSYM	;THEN ADVANCE THE POINTER
	SKIPA	T,@SYPTR	;GET NEXT VALUE WORD
	JRST	DD1		;DONE WITH LISTING
	HLRE	T,T		;GET -VE LENGTH OF THIS TABLE
	SOSGE	R		;BACK OFF TO MODULE NAME WORD
	PUSHJ	P,ADVSYM	;ADVANCING IF NECESSARY
	SKIPA	W2,@SYPTR	;GET THE NAME
	JRST	ERR		;VALUE BUT NO NAME IS BAD FORMAT
	TXNE	W2,PNAME	;MUST LOOK LIKE A MODULE NAME
	JRST	ERR		;ELSE IS BAD FORMAT
	ADD	R,T		;BACKUP POINTER TO NEXT MODULE
	SKIPN	T		;ZERO IS PAT.. BEFORE LINK BUG WAS FIXED,
	MOVNI	R,2		;SO SET TO ADVANCE TABLES
	PUSHJ	P,PSYM		;TYPE THE MODULE NAME
	TXNE	F,HSYMF		;IF NOT HISEG,
	SKIPN	W		;OR NAME NOT KNOWN,
	JRST	NAMLS3		;SKIP TYPING THE SEGMENT NAME
	MOVE	W1,TOHPS	;GET CURRENT HPOS
	SUBI	W1,7		;GET -VE DISTANCE UNTIL WE'VE PADDED ENOUGH
	MOVEI	T," "		;LOAD UP A SPACE
	PUSHJ	P,TOUT		;TYPE ONE
	AOJL	W1,.-1		;PAD UNTIL DONE
	MOVE	W1,W		;GET THE SEGMENT NAME
	PUSHJ	P,TSIXN		;TYPE IT IN SIXBIT
NAMLS3:	PUSHJ	P,TCRLF		;END THE LINE
	JRST	NAMLS2		;TYPE ALL KNOWN MODULES
;HERE ON $$: COMMAND -- READ PDV NAME AND SET $5M

  IFN FTEX20!FTMON!<FTDEC10&FTFILE>,<PDVSET==ERR>  ;ILLEGAL IN MONITORS, -10

  IFE FTEX20!FTMON!<FTDEC10&FTFILE>,<

PDVSET:
  IFN FTFILE,<
	SKIPE	FILING		;MUST BE LOOKING AT A FILE
	SKIPN	EXEFMT		;IN .EXE FORMAT
	JRST	ERR		;OR WE CAN'T DO IT
  > ;END IFN FTFILE
  IFN FTEXEC,<
	SKPUSR			;MUST BE IN USER MODE
	JRST	ERR		;OR WE CAN'T DO IT
  > ;END IFN FTEXEC
	TXNE	F,Q2F		;$$1: ?
	SKIPA	T,WRD2D		;MAYBE, GET THE FLAG
	SETZ	T,		;NO, IT'S OURS
	JUMPN	T,PDVTYP	;IF NOT $$0:, GO SEE IF $$1:
	TXNE	F,FAF!SAF!TIF!COMF!PTF!MF ;MOST ARGS BEFORE $$0: ARE ILLEGAL
	JRST	ERR		;BAD SYNTAX
IFN FTDEC20,<
	TXZ	F,CF!TXF	;CLEAR SOME FLAGS FOR TEXI
	XMOVEI	T,1(P)		;STORE PDV NAME ON STACK
	MOVEM	T,TEM		;REMEMBER WHERE
	MOVEM	T,WRD		;KEEP AN ORIGINAL COPY
	ADJSP	P,PVNMSZ	;MAKE ROOM FOR NAME
	ADDI	T,PVNMSZ-1	;GET LAST ADDRESS OF BLOCK
	MOVEM	T,TEM1		;SAVE THAT TOO
	MOVEI	T,7		;NORMAL ASCII BYTE SIZE
> ;END IFN FTDEC20
IFN FTDEC10,<
	TXZ	F,ROF!TXF	;CLEAR SOME FLAGS FOR TEXI
	MOVEI	T,6		;BYTE SIZE FOR SIXBIT TYPEIN
> ;END IFN FTDEC10
	MOVEM	T,WRD2D		; FOR BUILDING BYTE POINTERS
	TXNN	F,QF		;IF NO ARG,
	JRST	TEXI1		;GO READ THE STRING
	SETZ	T,		;GET A NULL
	IDPB	T,CHP		;FINISH THE SYMBOL TYPEIN
IFN FTDEC20,<
	DMOVE	TT,OPTXT	;GET THE TEXT
	DMOVEM	TT,@WRD		;PUT IT WHERE WE LOOK FOR IT
	MOVE	R,TEM1		;POINT PAST THE COPIED OPTXT
	;FALL INTO PDVSE2
> ;END IFN FTDEC20
IFN FTDEC10,<
	MOVE	TT,[POINT 7,OPTXT] ;SOURCE BYTE POINTER
	MOVE	W2,[POINT 6,W]	;DESTINATION BYTE POINTER
	SETZ	W,		;CLEAR ACCUMULATOR
PDVSE1:	ILDB	T,TT		;GET SOURCE BYTE
	JUMPE	T,PDVSE2	;DONE AT END OF STRING
	SUBI	T," "		;CONVERT TO SIXBIT
	IDPB	T,W2		;APPEND TO SEGMENT NAME
	JRST	PDVSE1		;LOOP OVER THE PROPOSED NAME
> ;END IFN FTDEC10

;HERE AFTER THE STRING HAS BEEN READ IN

PDVSE2:
IFN FTDEC20,<
	CAMG	R,TEM1		;PAST END OF BLOCK?
	MOVEM	W,(R)		;NO, STORE END OF STRING
	MOVEI	R,377		;RIGHT-MOST BYTE
	ANDCAM	R,@TEM1		;MAKE SURE WE'RE ASCIZ

  IFE FTFILE,<			;FIRST THE NON-FILDDT CASE
	PUSHJ	P,PDVINI	;SET UP PDVOP% ARG BLOCK
	MOVEI	T1,.POLOC	;LOCATE FUNCTION
	XMOVEI	T2,PDVARG	;ADDRESS OF ARG BLOCK
	HRRO	T3,WRD		;MAKE A BYTE POINTER TO PDV NAME
	PDVOP%			;FIND THE PDV
	 ERJMP	ERR		;SOMETHING DIED, GUESS IT'S NOT THERE
	SKIPN	PDVARG+.POCT2	;ANYTHING FOUND?
	JRST	ERR		;NO, DON'T DIDDLE ANYTHING
	ADJSP	P,-PVNMSZ	;RECLAIM STACK SPACE
	MOVE	T1,PDVA		;GET THE PDVA
	MOVEM	T1,SYTLOC	;SET $5M
	SETZM	SYMVAL		;DON'T TRUST IT
	PJRST	SYMCHK		;GO CHECK IT OUT NOW
  > ;END IFE FTFILE
;STILL IFE FTEX20!FTMON!<FTDEC10&FTFILE> AND IFN FTDEC20

;FILDDT CASE AFTER THE STRING HAS BEEN READ IN

;FALL IN FROM PDVSE2

  IFN FTFILE,<
	SKIPG	W1,PDVNUM	;ANY PDVS EXIST?
	JRST	ERR		;NO, DON'T BOTHER LOOKING
	SETO	W2,		;START WITH FIRST ONE
PDVSE3:	PUSHJ	P,NXTPDV	;GET THE PDVA
	ADDI	R,.PVNAM	;GET NAME ENTRY
	PUSHJ	P,FETCH		;GRAB THE WORD
	 JRST	ERR		;NAUGHTY!
	TXNE	T,IFIW		;IS NAME POINTER LOCAL?
	HLL	T,R		;YES, SET REAL SECTION NUMBER
	MOVE	R,T		;MOVE INTO RIGHT AC
	SKIPN	@WRD		;USER TYPE NULL STRING?
	JRST [	JUMPE	R,PDVSE5	;YES, ZERO ADDRESS IS A MATCH
		PUSHJ	P,FETCH		;FETCH FIRST STRING WORD
		 JRST	ERR		;BAD POINTER
		TLNN	T,774000	;IS FIRST BYTE ZERO?
		JRST	PDVSE5		;YES, STRING IS NULL
		JRST	PDVSE4]		;NO, TRY TRY AGAIN
	JUMPE	R,PDVSE4	;ZERO ADDRESS WILL NEVER MATCH
	MOVE	T,WRD		;USER'S STRING ADDRESS
	PUSHJ	P,CMPSTR	;COMPARE NAMES
PDVSE4:	 SOJG	W1,PDVSE3	;NO MATCH, TRY AGAIN
	JUMPE	W1,ERR		;DIDN'T FIND ANY MATCHES
PDVSE5:	MOVE	T,@PDVTBL	;MATCHED, GET THE PDVA
	MOVEM	T,SYTLOC	;SET $5M
	ADJSP	P,-PVNMSZ	;RECLAIM STACK SPACE
	JRST	MASK5C		;GO TRADE SYMBOL TABLES
;STILL IFE FTEX20!FTMON!<FTDEC10&FTFILE> AND IFN FTDEC20 AND IFN FTFILE

;CMPSTR -- COMPARE TWO ASCIZ STRINGS
;CALL:
;	MOVX	T,<GLOBAL ADDRESS OF INTERNAL STRING>
;	MOVX	R,<GLOBAL ADDRESS OF PROG'S STRING>
;	PUSHJ	P,CMPSTR
;RETURNS +1: STRINGS NOT IDENTICAL
;	+2: STRINGS IDENTICAL
;USES ONLY TT,TT1,TT2

CMPSTR:	PUSHJ	P,SAVRST	;AS ADVERTISED
	PUSH	P,W1		;SAVE SOME MORE ACS
	PUSH	P,W2
	TLO	T,610000	;MAKE GLOBAL "POINT 7,"
	MOVE	W1,T		;SAVE IN ANOTHER AC
CMPST1:	MOVE	W2,[POINT 7,T]	;MAKE A POINTER FOR PROG
	PUSHJ	P,FETCH		;GET A WORD OF PROG'S STRING
	 JRST	ERR		;SIGH....
	MOVEI	TT,5		;FIVE BYTES TO A WORD
CMPST2:	ILDB	TT1,W1		;GET SOME BYTES
	ILDB	TT2,W2		; TO LOOK AT
	CAIL	TT1,"a"		;SEARCH MUST BE
	CAILE	TT1,"z"		; CASE INSENSITIVE
	CAIA			;DON'T CONVERT
	TRC	TT1,40		;CONVERT
	CAIL	TT2,"a"		;SEARCH MUST BE
	CAILE	TT2,"z"		; CASE INSENSITIVE
	CAIA			;DON'T CONVERT
	TRC	TT2,40		;CONVERT
	CAME	TT2,TT1		;SAME?
	JRST	CMPST4		;NO, ALL DONE
	JUMPE	TT1,CMPST3	;LOOP UNLESS WE GOT A NULL
	SOJG	TT,CMPST2	;LOOP THROUGH THIS WORD
	AOJA	R,CMPST1	;TRY NEXT WORD
CMPST3:	AOS	-2(P)		;SUCCESS!!
CMPST4:	POP	P,W2		;RESTORE THE ACS
	POP	P,W1
	POPJ	P,		;ALL DONE

  > ;END IFN FTFILE
;STILL IFE FTEX20!FTMON!<FTDEC10&FTFILE> AND IFN FTDEC20

;HERE TO TYPE OUT CURRENT PDV NAME

PDVTYP:	SOJN	T,PDVLST	;IF NOT $$1:, SEE IF $$2:
	TXNE	F,QF!FAF!SAF!SF!LTF ;NO ARGS DEFINED
	JRST	ERR		;RESERVE THEM
	SKIPG	R,SYTLOC	;PDV OR JOBDAT?
	POPJ	P,		;JOBDAT, DON'T TYPE ANYTHING
	ADDI	R,.PVNAM	;POINT TO NAME WORD
	PUSHJ	P,FETCH		;GET THE POINTER
	 JRST	ERR		;CAN'T DO IT
	JUMPE	T,CPOPJ		;AIN'T ONE
	TXNE	T,IFIW		;LOCAL POINTER?
	HLL	T,R		;YES, GET REAL ADDRESS
	PUSH	P,LLOCO		;TYPZ WILL BOMB THIS
	MOVEM	T,LLOCO		;WHERE TYPZ EXPECTS ADDR
	PUSHJ	P,TYPZ		;TYPE USER STRING
	POP	P,LLOCO		;RESTORE ADDRESS
	POPJ	P,		;ALL DONE

PDVLST:	SOJN	T,ERR		;$$2: WAS YOUR LAST CHANCE
	TXNE	F,QF!FAF!SAF!SF!LTF ;NO ARGS DEFINED
	JRST	ERR		;RESERVE THEM
	PUSHJ	P,TCRLF		;START OFF AT LEFT MARGIN
  IFN FTFILE,<			;FILDDT CASE
	SKIPG	W1,PDVNUM	;IF NO PDVS,
	JRST	DD1		;END COMMAND NOW
	SETO	W2,		;SETUP TO GET THE FIRST ONE
  > ;END IFN FTFILE
  IFE FTFILE,<			;NON-FILDDT SETUP
	PUSHJ	P,PDVINI	;SETUP THE ARG BLOCK
	SETZM	PDVA		;START FROM THE BEGINNING
	PUSHJ	P,NXTPDV	;GET THE FIRST PDVA
	HLRZ	W1,PDVARG+.POCT2 ;SEE HOW MANY PDVS EXIST
	JUMPE	W1,DD1		;GET OUT NOW IF NONE
	TRNA			;KEEP THIS ADDRESS FIRST TIME THROUGH
  > ;END IFE FTFILE
PDVLS1:	PUSHJ	P,NXTPDV	;GET NEXT ADDRESS
	ADDI	R,.PVNAM	;OFFSET TO THE NAME POINTER
	PUSHJ	P,FETCH		;GET NAME POINTER
	  SETZ	T,		;SIGH
	TXNE	T,IFIW		;IF SECTION-LOCAL,
	HLL	T,R		;MAKE IT GLOBAL
	SKIPN	R,T		;PUT IN RIGHT REGISTER
	JRST	PDVLS3		;ZERO NAME ADDRESS MEANS DON'T TYPE IT
	PUSHJ	P,FETCH		;GET FIRST WORD FROM NAME
	  SETZ	T,		;SIGH
	TLNN	T,(177B6)	;SEE IF NON-NULL
	JRST	PDVLS3		;SKIP NAME IF NULL
	PUSH	P,W1		;NO, SAVE SOME NEEDED REGISTERS
	PUSH	P,W2		;AROUND TYPZ0
	PUSH	P,LLOCO		;AND THE OPEN LOCATION
	MOVEM	R,LLOCO		;FAKE IT OUT
	PUSHJ	P,TYPZ0		;TYPE ASCIZ NAME WITHOUT LEADING SLASH
	POP	P,LLOCO		;RESTORE OPEN CELL ADDRESS
	POP	P,W2		;AND PDVTBL INDEX
	POP	P,W1		;AND REMAINING COUNT OF PDVS
	PUSHJ	P,TCRLF		;END THE LINE
PDVLS3:	SOJG	W1,PDVLS1	;LOOP OVER ALL KNOWN PDVS
	JRST	DD1		;TYPE EXTRA CRLF AND END WHEN DONE WITH LIST

> ;END IFN FTDEC20
;STILL IN FTEX20!FTMON!<FTDEC10&FTFILE>

;HERE FOR TOPS-10 CASES

  IFN FTDEC10,<
;REST OF PDVSET FOR TOPS-10

PDVSE2:	JUMPE	W,[SETZM SYTLOC	;0$5M
		   SETZM SYMVAL	;MAKE SURE WE CHECK
		   PJRST SYMCHK] ;GO VALIDATE IT
	MOVEM	W,SEGOPB+.SGSNM	;SET UP THE SEGMENT NAME
	SETZM	SEGOPB+.SGSGN	;DON'T KNOW THE NUMBER
	SETZM	SEGOPB+.SGFLG	;CLEAR THE STEP FLAG
	MOVSI	W,.SGORG+1	;GET THE DESIRED LENGTH
	HLLM	W,SEGOPB	;SET FOR THE UUO
	XMOVEI	W,SEGOPB	;POINT TO THE ARG BLOCK
	SEGOP.	W,		;FIND THE SEGMENT
	  JRST	PDVSE3		;CAN'T DO IT THIS WAY, SEE IF OLD WAY WORKS
	HRRZ	R,SEGOPB+.SGORG	;GET LOCAL PAGE ORIGIN
	LSH	R,PG2WRD	;CONVERT TO ADDRESS
	JRST	PDVSE4		;HAVE THE HISEG ORIGIN, GO VALIDATE IT
PDVSE3:	MOVE	W1,SYTLOC	;SAVE THE CURRENT POINTER
	SETZM	SYTLOC		;MAKE GETHSO LOOK HARD
	PUSHJ	P,GETHSO	;SEE IF WE HAVE A HISEG ORIGIN
	MOVEM	W1,SYTLOC	;RESTORE CURRENT $5M
	JUMPE	T,ERR		;NO HISEG
	MOVE	R,T		;COPY THE POINTER
	ADDI	R,.JBHNM	;POINT AT THE SEGMENT NAME
	PUSHJ	P,FETCHV	;AND GRAB IT
	  JRST	ERR		;NO GO
	CAME	T,W		;IF NOT THE RIGHT SEGMENT,
	JRST	ERR		;CAN'T USE IT
	TRZ	R,PAGMSK	;BACK OFF TO THE ORIGIN AGAIN
				;FALL INTO PDVSE4
PDVSE4:	ADDI	R,.JBHSM	;POINT TO ITS SYMBOL TABLE POINTER
	PUSHJ	P,FETCHV	;GET ITS SYMBOL LIST
	  JRST	ERR		;NO GO
	JUMPE	T,[SMERS <No symbols> ;SAY WHAT'S WRONG
		   JRST  ERR]	;AND PUNT
	SKIPG	T		;IF GLOBAL POINTER, JUST USE IT
	MOVE	T,R		;NO, USE ADDRESS OF IOWBLK POINTER
	MOVEM	T,SYTLOC	;SET AS $5M ARGUMENT
	SETZM	SYMVAL		;DON'T TRUST IT YET
	PJRST	SYMCHK		;GO VALIDATE IT

PDVTYP:	SOJN	T,PDVLST	;IF NOT $$1:, SEE IF $$2:
	TXNE	F,QF!FAF!SAF!SF!LTF ;NO ARGS DEFINED
	JRST	ERR		;RESERVE THEM
	SKIPG	R,SYTLOC	;GET ADDRESS OF SYMBOL TABLE
	POPJ	P,		;BE SILENT IF JOBDAT FORMAT
	PUSHJ	P,CHKADR	;SEE IF WE KNOW ITS BITS
	TXNE	TT,PG$HGH	;MUST BE PART OF A HISEG
	TXNE	TT,PG$SPY	;AND NOT A SPY-SEG
	POPJ	P,		;WRONG, TYPE NOTHING
	PUSHJ	P,GETHSO	;GET THE START OF ITS SEGMENT
	JUMPE	T,CPOPJ		;SHOULD NEVER HAPPEN....
	MOVE	R,T		;COPY THE ADDRESS
	ADDI	R,.JBHNM	;POINT TO ITS NAME WORD
	PUSHJ	P,FETCHV	;GET ITS NAME
	  JRST	ERR		;THIS IS BAD NEWS
	MOVE	W1,T		;COPY THE NAME TO SOMEWHERE SAFE
	MOVEI	T,"/"		;INTRODUCER CHARACTER
	PUSHJ	P,TOUT		;TYPE IT
	PJRST	TSIXN		;TYPE THE SIXBIT SEGMENT NAME AND RETURN

PDVLST:	SOJN	T,ERR		;$$2: WAS YOUR LAST CHANCE
	TXNE	F,QF!FAF!SAF!SF!LTF ;NO ARGS DEFINED
	JRST	ERR		;RESERVE THEM
	PUSHJ	P,TCRLF		;START AT LEFT MARGIN
  IFE FTFILE,<
	SETZM	SEGOPB+.SGSGN	;START WITH FIRST SEGMENT
	SETZM	SEGOPB+.SGSNM	;NAME NOT KNOWN YET
	MOVSI	R,.SGSNM+1	;THE DESIRED LENGTH
	HLLM	R,SEGOPB	;SET UP FOR UUO
	MOVX	R,SG.STP	;THE STEP FLAG
	MOVEM	R,SEGOPB+.SGFLG	;SET TO FIND ALL HISEGS
PDVLS1:	XMOVEI	R,SEGOPB	;POINT AT UUO BLOCK
	SEGOP.	R,		;GET THE NEXT HISEG
	  JRST	PDVLS3		;OLD MONITOR?
	SKIPN	SEGOPB+.SGSGN	;IF NO NEXT SEGMENT NUMBER,
	JRST	DD1		;WE'RE DONE
	SKIPN	W1,SEGOPB+.SGSNM ;IF BLANK NAME,
	JRST	PDVLS1		;SKIP THIS SEGMENT
	PUSHJ	P,TSIXN		;TYPE THE NAME
	PUSHJ	P,TCRLF		;END THE LINE
	JRST	PDVLS1		;LOOP OVER ALL KNOWN SEGMENTS
  > ;END IFE FTFILE
PDVLS3:	MOVEI	R,.JBHNM	;OLD MONITOR
	PUSHJ	P,HFETCH	;TRY FOR NAME OF THE ONLY HISEG
	  JRST	DD1		;NONE AT ALL
	JUMPE	T,DD1		;DON'T BOTHER WITH A BLANK NAME
	MOVE	W1,T		;POSITION FOR TYPEOUT
	PUSHJ	P,TSIXN		;TYPE THE NAME
	PUSHJ	P,TCRLF		;END THE LINE
	JRST	DD1		;END THE COMMAND

  > ;END IFN FTDEC10

  > ;END IFE FTEX20!FTMON!<FTDEC10&FTFILE>
;TEXT COMMANDS:	$n"c$, $n"/.../, XXXX$5"
;			"X$	(same as $7c$),
;			$"X$		($6c$),
;			"/.../		($7"/.../),
;			$"/.../		($6"/.../)

TEXI:	MOVEI	T,7		;START OFF AS "X$ OR "/.../
	TXNE	F,CF		;<ESC> SEEN?
	SOS	T		;YES, CHANGE TO $"X$ OR $"/.../
	TXZN	F,Q2F		;NUMBER AFTER <ESC>?
	MOVEM	T,WRD2D		;NO, SIMULATE CORRECT VALUE.
	MOVE	T,WRD2D		;GET THE BYTE WIDTH.
	CAIL	T,5		;WIDTH MUST BE BETWEEN 5 AND
	CAILE	T,^D36		;36 INCLUSIVE.
	JRST	ERR
	CAIN	T,5		;XXXX$5" ?
	JRST [	MOVE	T,SYM		;YES, TAKE PREVIOUS SYL AS RADIX50
		TXZ	F,FPF!FEF!LTF	;REINIT SYL
		JRST	QUAN1]
	CAIE	T,6		;SIXBIT?
	TXZ	F,CF		;NO, CLEAR <ESC> SEEN FLAG.
	TXO	F,TXF		;FLAG PROCESSING TEXT 
	MOVE	T,LLOCO		;GET ADR OF OPEN REG
	MOVEM	T,TEM		;SAVE IT FOR LOCAL USE
TEXI1:	PUSHJ	P,TIN		;GET TERMINATOR
	MOVEM	T,SYL		;SAVE TERMINATOR
	PUSHJ	P,TIN		;GET FIRST CHARACTER
  IFE FTEX20!FTMON!<FTDEC10&FTFILE>,<	;IF USER MODE -20 OR -10,
	TXNN	F,TXF		;IN TEXT COMMAND?
	JRST	TEXI4		;NO, SKIP TEST
  > ;END IFE FTEX20!FTMON!<FTDEC10&FTFILE>
	TXNN	F,CCF		;DOUBLE-ESCAPE MEANS NO SINGLE-CHARACTER MODE
	CAIE	T,.CHESC	;ESC?
	JRST	TEXI4		;NO, HANDLE AS TEXT
	MOVE	T,SYL		;YES, RESTORE THE CHARACTER
	PUSHJ	P,TEXIN1	;CONVERT TO SIXBIT IF NECESSARY
	JRST	QUAN1		;EQUALS ONE ASCII/SIXBIT CHAR
TEXI4:	MOVE	W1,WRD2D	;FETCH BYTE SIZE
	LSH	W1,^D24		;SHIFT BYTE SIZE TO PROPER PLACE
	IOR	W1,[POINT 0,W]	;BUILD THE REST OF THE BYTE POINTER
	SETZ	W,		;INIT WORD TO 0
TEXI2:	CAMN	T,SYL		;REACHED TERMINATOR?
	JRST [	MOVE	R,TEM		;LAST ADDRESS
  IFE FTEX20!FTMON!<FTDEC10&FTFILE>,<	;MONITORS DON'T HAVE PDVS
		TXNN	F,TXF		;PDV NAME?
		JRST	PDVSE2		;YES, GO CHECK IT OUT
  > ;END IFE FTEX20!FTMON!<FTDEC10&FTFILE>
		MOVEM	R,LLOC		;SET LOC TO END OF INPUT
		MOVEM	R,LLOCO		;UPDATE LLOCO TOO
		MOVE	T,W		;GET LAST WORD
		JRST	QUAN1]		;NO, DONE
	IBP	W1		;POINT TO NEXT BYTE.
	TRNE	W1,^-W		;STILL POINTING TO W?
	JRST	TEXI3		;NO
	PUSHJ	P,TEXIN1	;CONVERT TO SIXBIT IF NECESSARY
	DPB	T,W1		;BYTE GOES INTO W.
	PUSHJ	P,TIN		;GET ANOTHER INPUT CHARACTER
	JRST	TEXI2
;HERE WHEN WORD FULL

TEXI3:	MOVEI	W1,W		;ONLY GET HERE ONCE IF NO LOC OPEN
	MOVE	R,TEM		;GET LOC OF NEXT REGISTER
  IFE FTMON!FTEX20!FTDEC10,<	;NO REAL PDV ON A -10 OR -20 MONITORS
	TXNN	F,TXF		;IF READING A PDV NAME
	JRST [	CAMLE	R,TEM1		;PAST END OF BLOCK?
		JRST	TEXI2		;YES, STOP STORING
		MOVEM	W,(R)		;NO, STORE THE WORD
		JRST	TEXI5]		;AND CONTINUE
> ;END IFE FTMON!FTEX20!FTDEC10
	TXNN	F,ROF		;REGISTER OPEN?
	JRST	TEXI2		;NO, LOSE ANY ADDITIONAL INPUT
	PUSH	P,T		;SAVE CHARACTER
	MOVE	T,W		;GET FULL WORD
	PUSHJ	P,DMEMER	;STORE WORD IF POSSIBLE
	POP	P,T		;RECOVER CHARACTER
TEXI5:	AOS	TEM		;BUMP LOC
	JRST	TEXI4		;GO REINIT WORD AND CONTINUE INPUT

;CONVERT INPUT CHARACTER TO SIXBIT IF NECESSARY

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,
;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 FTMON,<
	MOVE	T,[MSEC1,,MRETN]>  ;MDDT RETURN
  IFN FTEX20,<
	MOVEI	T,DDTCZ>	;KDDT USER-MODE RETURN
  IFE FTMON!FTEX20,<
	XMOVEI	T,HLTA		;NORMAL DDT RETURN
    IFN FTUD20,<		;NO STUB EXCEPT USER-20
	SKIPGE	R,SECUDD	;IS THERE A STUB?
	JRST	CTLZ1		;NO
	HRRI	R,770003	;RETURN @770003 OF STUB
	PUSHJ	P,FETCH		;GET THE ADDRESS
	 JRST	ERR		;CAN'T??
	HLL	T,R		;FIX UP SECTION NUMBER
CTLZ1:
    > ;END IFN FTUD20
  > ;END IFE FTMON!FTEX20
	JRST	GO1		;RESTORE CONTEXT AND JUMP

;HERE AFTER ^Z WITH ALL BREAKPOINTS INSERTED AND CONTEXT RESTORED.

  IFE FTMON,<
HLTA:
  IFN FTDEC10,<
	EXIT	1,>		;TOPS-10 MONRET
  IFN FTDEC20,<
	HALTF%>			;TOPS-20 MONRET
	JRST	DDT		;CONTINUE IS LIKE START NOW
  > ;END IFE FTMON


	CNTRLE==ERR		;^E ONLY WORKS IN FILDDT

  > ;END IFE FTFILE

;NOW THE FILDDT CASE

  IFN FTFILE,<
CNTRLZ:	JRST	CTLZ		;JUMP TO REAL ROUTINE

CNTRLE:	JRST	CTLE		;JUMP TO REAL ROUTINE

  > ;END IFN FTFILE

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		;#
MINUS:	TXO	F,MF
PLUS:	TXO	F,PTF
	JRST	LIS2

LPRN:	PUSH	P,F		;RECURSE FOR OPEN PAREN
	PUSH	P,ACCCF		;PUSH COMMACOMMA FLAG/VALUE
	PUSH	P,WRD
	PUSH	P,FRASE
	PUSH	P,FRASE1
	AOS	PRNC
	SETZM	WAKALL		;SET WAKEUP SET TO PUNCT AND CTRLS
	JRST	LIS0C		;AND READ NEW EXPRESSION

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


ACCF:	MOVE	R,ESTUT		;GET UNDEFINED PROCESSOR SO FAR
	CAME	R,USYMP+S$ADR	;ANY UNDEFINED'S CREATED YET?
	 JRST	ERR		;YES, ERROR
				;(CAN ONLY GET HERE ON "FOO#," ETC.)
	MOVE	R,T		;COMMA PROCESSOR
	TXOE	F,COMF		;COMMA TYPED BEFORE?
	JRST	ACCF1		;YES
	HRRZM	R,ACCCF		;NO, SAVE POTENTIAL "A" 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:	HRRZ	T,ACCCF		;RETRIEVE "A" OF "A,,B" EXPRESSION
	ADD	T,WRD		;FOR ",," GET LEFT HALF TOGETHER
	HRLZM	T,WRD		; AND PUT IT IN LEFT HALF
	HRROM	T,ACCCF		;FLAG COMMACOMMA CONSTRUCTION
	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		;)
	SETZ	T,
	MOVS	T,T
	SOSGE	PRNC
	JRST	ERR
	POP	P,FRASE1
	POP	P,FRASE
	POP	P,WRD
	POP	P,ACCCF		;POP COMMACOMMA FLAG/VALUE
	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>
	MOVE	T,LLOC
	HRRI	T,-1(T)		;DECREMENT CURRENT LOC
	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:	MOVE	T,LLOC		;BUMP LOC
	HRRI	T,1(T)		;BUT DON'T CHANGE SECTION
LI1:	MOVEM	T,LLOC		;NEW LAST LOCATION
	MOVEM	T,LLOCO		;NEW LAST LOCATION OPEN
LI1P:	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
		CAIE	SCH,PINQ	;EITHER KIND OF
		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
	TXZ	F,STF		;DON'T SUPPRESS TYPEOUT ANYMORE
	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,DEPRA0	;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,DEPRA0	;OPEN REGISTER OF Q
	PUSHJ	P,CEFFAD	;COMPUTE EFF ADR
	 JRST	ERR		;MEMORY READ ERROR
	HRRI	T,-1(T)		;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		;USING LWT?
	JRST	SLASH4		;YES. 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.
;CEFFAS - CALCULATE ADDRESS ARGUMENT FOR $G, ETC. (SECTION DEFAULT ONLY)
;CALL IS:
;
;	MOVX	T,<ADDR>
;	PUSHJ	P,CEFFAD
;	 ERROR RETURN
;	NORMAL RETURN
;
;WHERE <ADDR> IS THE EXPLICITLY-TYPED ADDRESS EXPRESSION (IF ANY).
;
;BASICALLY ADDRESSING NOW WORKS AS FOLLOWS:
;
; FOR CEFFAD (E.G., "/", <TAB>, ETC.) ONLY: IF AN EXPLICIT QUANTITY HAS
;  NOT BEEN TYPED BY THE USER THEN THE LAST WORD TYPED IS USED AS THE BASIS
;  FOR ADDRESS CALCULATION. IF THE COMMAND WAS PREFIXED WITH A SINGLE <ESC>
;  (E.G., $/) THEN THE FULL-WORD VALUE FROM ABOVE WILL BE TREATED AS AN
;  INSTRUCTION-FORMAT-INDIRECT-WORD (IFIW) WHOSE EFFECTIVE ADDRESS "E" WILL
;  BE CALCULATED AS IT WOULD BE BY THE HARDWARE WERE IT TO EXECUTE THE WORD
;  AS AN INSTRUCTION (ASSUMING A VALID OPCODE); IF THE 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 EFFECTIVE
;  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 CALCULA-
;  TION IN A NON-ZERO SECTION.
;
;  IF THE COMMAND WAS NOT PREFIXED BY ANY <ESC>'S, AND IF NO EXPLICIT QUANTITY
;  WAS TYPED, THEN THE ADDRESS VALUE (THE LAST WORD TYPED) IS REDUCED TO A
;  SECTION-LOCAL ADDRESS VALUE (I.E., RH ONLY, THE LH IS ZEROED).
;
; FOR CEFFAS (E.G., $G) AND CEFFAD (FROM ABOVE): IF ",," WAS USED IN THE
;  ADDRESS EXPRESSION THEN THE ADDRESS VALUE IS EXACTLY AS TYPED BY THE USER;
;  OTHERWISE IF EITHER A SPACE OR COMMA WAS USED IN THE ADDRESS EXPRESSION,
;  OR IF THE ADDRESS EXPRESSION IS A SECTION-LOCAL VALUE (AS ABOVE) THEN THE
;  SECTION-VALUE (LEFT HALF) OF THE ADDRESS VALUE WILL BE DEFAULTED FROM THE
;  CURRENT SECTION (I.E., LH OF ".").
;
;NOTE:	IF A DDT-INTERNAL ADDRESS VALUE WAS USED IN THE ADDRESS EXPRESSION
;	(LEGAL ONLY FOR CEFFAD, ERROR FOR CEFFAS-CLASS COMMANDS) THEN THE
;	ADDRESS VALUE IS ASSUMED TO BE A SECTION-LOCAL VALUE IN DDT'S
;	EXECUTING SECTION. THE VALUE IS FLAGGED "DDT-INTERNAL", AND LEFT
;	FOR FETCH/ETC TO ACTUALLY PROCESS.
;
;IF A FETCH ERROR OCCURS, OR AN ILLEGAL EFIW WORD IS ENCOUNTERED IN AN
;EFFECTIVE-ADDRESS CALCULATION, OR IF A DDT-INTERNAL ADDRESS IS SUPPLIED
;TO CEFFAS, THE ERROR RETURN IS TAKEN; OTHERWISE THE SUCCESSFUL (SKIP)
;RETURN IS TAKEN WITH THE 36-BIT GLOBAL ADDRESS VALUE IN REGISTER T.
;
;USES ACS R, S, W.
;CALCULATE EFFECTIVE ADDRESS

CEFFAD:	TXNE F,DDLF		;DDT INTERNAL LOCATION TYPED?
	JRST	[HRLI T,(DDAF)	;YES, FLAG IN ADDRESS
		JRST CPOPJ1]	;DO NOTHING ELSE
	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
	TXNN	F,QF		;EXPLICIT ADDRESS EXPRESSION TYPED?
	ANDI	T,-1		;NO, REDUCE TO SECTION-LOCAL LWT

;ENTER HERE TO GENERATE SECTION DEFAULT ADDRESS VALUE

CEFFAS:	TXNE	F,DDLF		;DDT INTERNAL LOCATION TYPED?
	POPJ	P,		;YES - TSK TSK - BOMB THE KLOWN
	SKIPGE	ACCCF		;COMMACOMMA PROCESSING ENCOUNTERED?
	JRST	CEFFAZ		;YES, USE ADDRESS VALUE EXACTLY AS IT WAS TYPED
	TDNN	T,[777777,,777760]  ;ADDRESS VALUE A "LOCAL REGISTER"?
	JRST	CEFFAC		;YES, CHECK NEED FOR GLOBAL REFERENCE
				; NOTE THAT "1,,REG" WILL BE HANDLED "RIGHT"
				; BY FETCH/ET AL, AND WILL ALSO SET THE
				; DEFAULT SECTION TO "1" . . . CAVEAT EMPTOR
	TXNN	F,SPF!COMF	;SPACE OR COMMA TYPED (I.E., AN INSTRUCTION)?
	TLNN	T,-1		;OR IS THE VALUE SECTION-LOCAL (LH = 0)?
	JRST	CEFFS5		;YES, DEFAULT THE SECTION
	TXNN	T,77B5		;IS THE LH OBVIOUSLY NOT A SECTION NUMBER?
	JRST	CEFFAZ		;ASSUME IT'S A SECTION NUMBER
CEFFS5:	HLL	T,LLOCS		;GET DEFAULT ADDRESS VALUE SECTION
	SKIPL	PDFSEC		;OVER-RIDING DEFAULT SECTION ($6M) SET?
	HLL	T,PDFSEC	;YES, IT OVERRIDES LLOCS DEFAULT
CEFFAZ:	HLLZM	T,LLOCS		;SET NEW DEFAULT SECTION
	JRST	CPOPJ1		;RETURN WITH ADDRESS VALUE IN T

CEFFAX:	PUSHJ	P,CEFFAS	;CALCULATE SECTION DEFAULT (IF NEEDED)
	 JFCL			;IGNORE NON-SKIP RETURN
	POPJ	P,		;AND RETURN NON-SKIP ALWAYS

CEFFAC:	HLL	T,LLOCS		;GET CURRENT DEFAULT SECTION
	TLZE	T,-1		;IS THIS GLOBAL?
	TLO	T,1		;YES, FLAG IT
	JRST	CPOPJ1		;RETURN SUCCESS TO CEFFAD



;GDFSEC -- GET DEFAULT SECTION NUMBER
;	PUSHJ	P,GDFSEC
; T/  <DEFAULT SECTION>,,0

GDFSEC:	SETZ	T,		;SECTION NUMBER ONLY
GDFSE0:	HLL	T,LLOCS		;USE TEMP DEFAULT
	SKIPL	PDFSEC		;PERM. DEFAULT SET?
	HLL	T,PDFSEC	;YES, USE PERM. DEFAULT
	POPJ	P,
;SETUP TO CALCULATE IFIW EFFECTIVE ADDRESS

CEFFI:	HLLZ	S,LLOCS		;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
	SETZM	EAGLOB		;IFIW'S GIVE LOCAL RESULTS
	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
	 JRST	CIFIW4		;THEN LOCAL INDEXING
	SETOM	EAGLOB		;ELSE GLOBAL INDEXING
	CAIA			;DON'T DIDDLE SECTION
CIFIW4:	HLL	T,S		;THEN E STAYS IN LOCAL SECTION
	ANDX	T,VMADR		;KEEP ONLY Y FIELD
	HLL	S,T		;UPDATE S TO NEW CURRENT SECTION

;CHECK IFIW INDIRECTION

	SKIPE	EAGLOB		;LOCAL INDEXING?
	TDNN	T,[777776,,777760]  ;NO, GLOBAL REFERENCE TO AC
CIFIW6:	TRNE	T,777760	;IS LOCAL REFERENCE TO A REGISTER?
	CAIA			;NO, MEM. REF.
	ANDI	T,17		;YES, REDUCE TO UNAMBIGUOUS AC
				; (NOTE "SECTION-NESS" STILL IN S)
	POP	P,R		;GET BACK ORIGINAL WORD
	TXNN	R,@		;IFIW I BIT ON?
	PJRST	CEFIW9		;NO, CHECK OUT AC'S AND RETURN
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
	JUMPGE	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,LLOCS		;PRE-LOAD CURRENT SECTION
CEFFEX:	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
	SETOM	EAGLOB		;EFIW'S GIVE GLOBAL RESULTS
	LDB	R,[POINTR T,EFIWX] ;EFIW: X FIELD
	ANDX	T,VMADR		;Y FIELD ONLY
	MOVE	W,T
	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
	ANDX	T,VMADR		;KEEP ONLY Y FIELD

;CHECK EFIW INDIRECTION

CEFIW6:	POP	P,R		;GET BACK ORIGINAL WORD
	HLLZM	T,LLOCS		;SAVE SECTION
	HLLZ	S,T		;SAVE FOR CEFIW9
	TXNE	R,EFIWI1	;EFIW I BIT ON?
	JRST	CIFIW8		;YES, LOOP ON INDIRECTION
				;NO, CHECK OUT AC'S AND RETURN

;CHECK AC ADDRESSING

CEFIW9:	TDNN	T,[-2,,-20]	;AC REFERENCE?
	TLNN	S,-1		;FROM NON-ZERO SECTION?
	JRST	CPOPJ1		;NO, JUST RETURN IT
	HRLI	T,1		;YES, MAKE IT GLOBAL
	JRST	CPOPJ1		;RETURN SUCCESS FROM CEFFAD
;HERE WHEN REGISTER CLOSED TO DEPOSIT NEW CONTENTS AND SET NEXT LOCATION

DEPRA:	TXNE	F,CF		;$ PRECEEDED?
	PUSHJ	P,POPLLC	;YES, POP OLD SEQUENCE
DEPRA0:	TXNE	F,ROF		;IF REGISTER IS BEING CHANGED
	TXNN	F,QF		;REMOVE ALL PREVIOUS UNDEFINED
	JRST	DEPRS		;SYMBOL REFERENCES TO IT
	DMOVE	TT,USYMP+S$ADR	;GET POINTER TO ALL OLD UNDEF ITEMS
	SUB	W2,TT1		;FIND OUT HOW MANY NEW ONES THERE ARE
	JUMPE	W2,DEPRA4	;DON'T UPDATE IF NO NEW SYMS
	DMOVEM	TT,ESTUT	;FAKE OUT USYSET
	MOVEI	W1,USYMP	;WANT TO UPDATE UNDEF BY THAT MANY
	PUSHJ	P,DECSYP	;DECREMENT EVERYBODY
	 JFCL			;??
DEPRA4:
  IFN FTFILE,<
	SKIPN	FILING		;SEE IF /M
	JRST	DEPRS		;YES--NO UNDEF FIXUPS
  > ;END IFN FTFILE
	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
	LDB	T,[POINTR W,VMADR]  ;GET ADDRESS OF FIXUP
	SKIPE	T		;DELETE ENTRY IF ADR=0, OR
	CAMN	T,LLOCO		; IF ADR IS BEING CHANGED
DEPRA3:	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
	JUMPE	W,DEPRA8	;DON'T BOTHER IF POINTS TO ZERO
	MOVE	W1,W		;INITIALIZE W1 SO EXCH WILL WORK
	MOVE	R,W		;FIRST TIME GET FULL ADDRESS
	JRST	DPRS5		;ALLOW CHAIN TO N,,0

DPRS4:	HRR	R,W		;GET NEXT ADR (AFTER ADR IN W1)
	TRNN	R,-1		;CHAIN REACHED 0?
	JRST	DEPRA8		;YES, ALL DONE
DPRS5:	PUSHJ	P,FETCHV	;GET CONTENTS OF ADR IN R
	 JRST	DEPRA8		;****UNDEFINED SYMBOL TABLE OR FIXUP
				; CHAIN POINTS TO ILL. MEM. TRY
				; TO CONTINUE.
	EXCH	T,W		;W/NEW LINK    T/OLD LINK
	EXCH	W1,R
	CAME	W1,LLOCO	;IS THIS WORD BEING CHANGED?
	AOJA	S,DPRS4		;NO, CHECK REST OF CHAIN
	HRR	T,W		;YES, PATCH CHAIN AROUND ADDRESS
	JUMPL	S,DPRS6		;FIRST ENTRY?
	PUSHJ	P,DMEMER	;NO, WRITE INTO USER ADDRESS SPACE
	JRST	DEPRA8		;CHECK REST OF UNDEFINEDS

DPRS6:	POP	P,R		;FIRST LINK IN CHAIN - GET SYMBOL ADDR.
	TRNN	T,-1		;CHAIN OF LENGTH 1?
	JRST	DEPRA3		;YES, JUST DELETE THE SYMBOL
	TXO	R,1B1		;CHAIN STARTS IN UNDEFINED TABLE
	PUSHJ	P,DSYMER	;NO, PATCH CHAIN AROUND MODIFIED ADDR.
	TXZ	R,1B1		;WANT A STRAIGHT INDEX AGAIN
	SOJA	R,DEPRA2	;CONTINUE

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

	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
	TDNE	TT,[-2,,-20]	;SKIP IF LOC IS ACCUMULATOR.
	HLLZM	TT,LLOCS	;SET FLOATING DEFAULT SECTION.
	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:	MOVEI	T,7		;$T, ASSUME 7 BIT ASCII
	TXNE	F,Q2F		;IF $NT,
	MOVE	T,WRD2D		;GET "RADIX" OF TEXT
	JUMPE	T,TYPZ		;TYPE ASCIZ STRING AT "." IF $0T/$$0T
	CAIN	T,7		;CHECK FOR $7T
	MOVEI	R,TEXTT		;SET MODE SWITCH FOR 7-BIT ASCII
	CAIN	T,6		;CHECK FOR $6T
	MOVEI	R,SIXBP		;SET MODE SWITCH FOR SIXBIT ASCII
	CAIN	T,5		;CHECK FOR $5T
	MOVEI	R,R50PNT	;SET MODE SWITCH FOR RADIX 50
	CAIN	T,1		;CHECK FOR $1T
	MOVEI	R,TBPNT		;SET MODE SWITCH FOR BYTE POINTERS
	JUMPN	R,SMOD1		;SET MODE IF ONE DETERMINED YET
	CAIL	T,7		;NOT DETERMINED, CHECK BYTE SIZE
	CAILE	T,^D36		;MUST BE 7 TO 36
	JRST	ERR		;BAD BYTE SIZE
	MOVEI	R,TEXTNT	;MODE IS N-BIT ASCII
	MOVEM	T,BYSS		;SAVE BYTE SIZE
	JRST	SMOD1		;GO SET MODE


;TYPE THE ASCIZ STRING AT CURRENTLY OPEN LOCATION

TYPZ:	MOVEI	T,"/"		;LOAD A SLASH
	PUSHJ	P,TOUT		;SEPARATE TEXT FROM USER COMMAND
	MOVE	T,WRD		;GET ADDRESS, IF SUPPLIED
	TXNN	F,QF		;EXPLICIT ADDRESS GIVEN?
	SKIPA	T,LLOCO		;NO, USE "."
	PUSHJ	P,CEFFAX	;YES, DEFAULT SECTION IF NEEDED
	MOVEM	T,LLOCO		;SAVE NEW "."
	MOVE	R,T		;GET LAST LOCATION OPEN
TYPZ0:	PUSHJ	P,LISTEN	;ANY USER TYPEIN?
	 SKIPA	W,[POINT 7,W1]	;NO, CONTINUE AND LOAD ASCII BYTE PTR.
	 POPJ	P,		;YES, EXIT
	MOVEI	W2,5		;LOAD LOOP COUNTER
	PUSHJ	P,FETCH		;FETCH 5 CHARACTERS FROM ADDRESS
	 JRST	ERR		;FAILED
	MOVE	W1,T		;PUT WORD IN T
TYPZ1:	ILDB	T,W		;GET THE NEXT BYTE
	JUMPE	T,[AOS	LLOCO		;YES, INCREMENT TO NEXT WORD
		   POPJ	P,]		;DONE
	PUSHJ	P,TOUT		;NO, TYPE THE CHARACTER
	SOJG	W2,TYPZ1	;LOOP UNTIL DONE
	AOS	R,LLOCO		;DONE, GO TO NEXT WORD IN STRING
	JRST	TYPZ0		;AND KEEP DOING IT

HWRDS:	MOVEI	R,HLFW		;H - HALFWORD OUTPUT FORMAT
	JRST	SMOD1
SFLOT:	MOVEI	R,TFLOT		;F - FLOATING POINT OUTPUT FORMAT
  IFN FTDEC20,<
	TXNN	F,Q2F>		;WAS AN ARGUMENT GIVEN TOO?
	JRST	SMOD1		;NO, NORMAL $F OR $$F FORMAT
  IFN FTDEC20,<			;DBL. PRECISION TYPEOUT ONLY ON TOPS-20
	SKIPE	TT,WRD2O	;YES, WAS IT 0?
	CAIN	TT,1		;OR A 1?
	JRST	SMOD1		;YES, TREAT LIKE $F OR $$F
	CAIE	TT,2		;NO, WAS IT 2?
	JRST	ERR		;NO, DON'T KNOW WHAT IT WAS
	MOVEI	R,DFLOUT	;YES, LOAD DBL. PRECISION ADDR.
	JRST	SMOD1
  > ;END IFN FTDEC20

SYMBOL:	MOVEI	R,PIN		;ASSUME REGULAR SYMBOL TYPEOUT
	SKIPE	WRD2D		;$1S?
	MOVEI	R,PINQ		;YES, OPTYPE FIRST FLAVOR
	JRST	SMOD1		;NO, KEEP OUR ASSUMPTION

CON:	MOVEI	R,FTOC		;C TYPEOUT FORMAT
SMOD1:	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	BASE1

BASECH:	MOVE	T,WRD2D		;$NR  CHANGE OUTPUT RADIX TO N, N .GT. 1
	CAIGE	T,2
	JRST	ERR
	HRRZM	T,ODF
BASE1:	TXNN	F,CCF
	JRST	LIS1
	MOVS	S,[XWD SCHM,SCH]	;SAVE SPACE IN LITERAL POOL
	BLT	S,ODFM		;WITH $$, MAKE MODES PERMANENT
	MOVE	S,SVBTS		;MAKE THE CURRENT FORMAT MASK
	MOVEM	S,PSVBTS	;THE PERMANENT FORMAT MASK.
	MOVE	S,BYSS
	MOVEM	S,PBYSS
	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:	MOVEI	SCH,BITT	;BYTE TYPEOUT
	PJRST	BASE1		;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
	PUSHJ	P,TOCA		;TYPE OUT A CONSTANT
	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

LLIM:	TXNE	F,CF!CCF	;$< OR $$< COMMAND?
	JRST	PTCHB		;YES, PATCH COMMAND
	MOVEM	T,LLIMIT	;NO, SET FIRST ARGUMENT
	TXO	F,FAF		;AND FLAG FIRST ARGUMENT SEEN
	MOVEM	F,LLREGF	;SAVE "F" FOR SETUP/LLMSEC/CEFFAS
	MOVE	TT1,ACCCF	;ALSO SAVE "ACCCF" FLAG
	MOVEM	TT1,LLACCF	; FOR SETUP/LLMSEC/CEFFAS
	JRST	ULIM1

ULIM:	TXNE	F,CCF		;$$> ?
	JRST	ERR		;YES, NOT DEFINED
	TXNE	F,CF		;NO, $> ?
	JRST	PTCHE		;YES, END PATCH
	MOVEM	T,ULIMIT	;NO, SET SECOND ARG
	TXO	F,SAF		;AND FLAG SECOND ARGUMENT SEEN
	MOVEM	F,ULREGF	;SAVE "F" FOR SETUP/ULMSEC/CEFFAS
	MOVE	TT1,ACCCF	;ALSO SAVE "ACCCF" FLAG
	MOVEM	TT1,ULACCF	; FOR SETUP/ULMSEC/CEFFAS
ULIM1:	TXNN	F,QF
	JRST	ERR
	JRST	LIS0E
;HERE FOR THE PATCH BEGIN COMMAND

PTCHB:	TXNE	F,Q2F		;SPECIAL FLAVOR?
	JRST	PTCHX		;YES, CANCEL PATCHING MAYBE
	SKIPN	PTLOC		;ALREADY IN PATCH MODE?
	TXNN	F,ROF		;OR NO LOCATION OPEN?
	JRST	ERR		;YES, CAN'T PATCH
	SETZM	PTORG		;NO, ASSUME EXPRESSION TYPED
	TXNE	F,TIF!COMF!PTF!MF  ;EXPRESSION TYPED?
	JRST	PTCHB4		;YES, JUST GO USE IT
	TXNE	F,QF		;ANYTHING AT ALL TYPED?
	TXNE	F,LTF		;NUMBER OR SYMBOL?
	  CAIA			;NOTHING OR SYMBOL TYPED
	JRST	PTCHB4		;NUMBER, JUST GO USE IT
	TXNE	F,QF		;ANYTHING TYPED?
	JRST [	PUSHJ	P,EVAL		;YES, LOOKUP SYMBOL
		 JRST	ERR		;STRANGE TYPEIN, LOSE
		JRST	PTCHB2]		;FOUND, USE VALUE AS PATCH LOC
	MOVSI	W,-NPSYM	;SETUP TO SCAN PATCH SYMBOLS
PTCHB1:	MOVE	T,PCHSYM(W)	;GET A POSSIBLITY
	MOVEM	T,SYM		;SET IT UP FOR EVAL
	PUSHJ	P,EVAL		;TRY TO FIND VALUE
	 AOBJN	W,PTCHB1	;NOT FOUND, TRY NEXT SYMBOL
	JUMPL	W,PTCHB2	;FOUND A SYMBOL, USE IT
  IFN FTEXEC,<
	SKPUSR			;USER MODE?
	JRST	ERR		;EXEC MODE LOSES HERE
  > ;END IFN FTEXEC
	MOVEI	R,.JBFF		;NONE OF THE SYMBOLS EXIST, USE .JBFF
	HLL	R,LLOCO		;IN THE PATCH SECTION
	PUSHJ	P,FETCH		;GET CONTENTS OF .JBFF
	 JRST	ERR		;USER LOSES
	AOS	PTORG		;PTORG = 1 TO FLAG FROM .JBFF
	JRST	PTCHB4		;FAKE PATCH SYMBOL FOUND
PTCHB2:	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
PTCHB4:	CAIL	T,.JBDA		;HAVE REASONABLE PATCH ADDRESS?
	TDNN	T,[777776,,777760]  ;CAN'T BE AN AC
	JRST	ERR		;NO
	TLNN	T,-1		;SECTION GIVEN?
	JRST	PTCHB5		;NO, SKIP THE CHECK
	HLLZ	TT,T		;YES, SEE IF THAT SECTION
	CAMN	TT,LLOCS	; IS SECTION OF "."
	JRST	PTCHB5		;YES, GO ON
	SMERS	<CAN'T PATCH ACROSS SECTIONS>	;SET MESSAGE
PTCHBE:	SETZM	PTLOC		;PATCH NEVER BEGAN
	JRST	DMER1		;ALTERNATE DMEMER ENTRY (ERR MSG)

PTCHB5:	MOVEM	T,PTVAL		;SAVE ORIGINAL SYMBOL VALUE
	HLL	T,LLOCO		;FORCE SECTION SAME AS OPEN REG
	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,DEPMEM	;TRY TO DEPOSIT INTO MEMORY
	 JRST	PTCHBE		;FAILED, STOMP ON THE PATCH
	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 FTEX10,<
	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
NPSYM==.-PCHSYM
;HERE FOR THE PATCH END COMMAND

PTCHE:	SKIPN	PTLOC		;PATCH IN PROGRESS?
	JRST	ERR		;NO, ERROR
	TXZ	F,CF		;NO, 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?
	TXNN	F,QF		;AND NOTHING YET TYPED?
	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:	TXNE	F,Q2F		;WAS "SKIPNESS" SUPPLIED?
	SKIPA	T,WRD2D		;YES, USE USER-REQUESTED COUNT
	MOVEI	T,2		;NO, DEFAULT SINGLE-SKIP
	JUMPE	T,PTCHE6	;DON'T BOTHER IF NOTHING TO DO
	PUSH	P,T		;ELSE SAVE ITERATION COUNTER
	PUSH	P,[JUMPA]	;AND BASIC PATCH RETURNER
PTCHE3:	PUSHJ	P,LI0		;OPEN AND TYPE NEXT LOCATION
	MOVE	R,LLOCO		;CURRENT OPEN LOCATION
	MOVE	T,[Z 1,1]	;INCREMENT
	ADD	T,(P)		;  THE RETURNER
	TXNN	T,<Z 17,>	;OVERFLOWED THE AC FIELD YET?
	HRLI	T,(JUMPA 17,)	;YES, LIMIT AT JUMPA 17,
	MOVEM	T,(P)		;SET BASIC JUMPA TEMPLATE
	HRRZ	T,PTLLC		;ORIGINAL USER LOCATION
	ADD	T,(P)		;GENERATE A JUMPA N,C(PTLLC)+N
	PUSHJ	P,DMEMER	;PUT IN PATCH AREA
	PUSHJ	P,LI2		;KEEP USER UPDATED
	SOSLE	-1(P)		;COMPLETED MAXIMUM SKIPNESS YET?
	JRST	PTCHE3		;NO, LOOP TILL DONE
	POP	P,T		;YES, ADJUST
	POP	P,T		;STACK POINTER

;CONTINUED ON NEXT PAGE
;FALL IN FROM ABOVE

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

PTCHE6:	SKIPN	PTORG		;ANYTHING TO UPDATE?
	JRST	PTCHE8		;NO, GO INSTALL JUMPA TO PATCH
	AOS	T,LLOC		;GET NEXT FREE PATCH LOC
	SKIPG	PTORG		;SYMBOL OR .JBFF?
	JRST	PTCHE7		;SYMBOL, PROCEED
	MOVEI	R,.JBFF		;.JBFF, SET UP TO UPDATE IT
	HLL	R,LLOCO		;IN PATCHED SECTION
	PUSH	P,T		;SAVE T
	HRRZ	T,T		;NEW VALUE EXCLUDES SECTION
	PUSHJ	P,DMEMER	;UPDATE C(.JBFF) ACCORDINGLY
	HRRI	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	PTCHE8		;AND FINISH OFF PATCH

PTCHE7:	MOVE	R,PTVAL		;GET ORIGINAL SYMBOL VALUE
	TLNN	R,-1		;DEFINED WITH SECTION NO.?
	HRRZ	T,T		;NEW SYMBOL VALUE EXCLUDES SECTION
	MOVE	R,PTFIX		;WHERE VALUE CAME FROM
	PUSHJ	P,DSYMER	;DEPOSIT NEW SYMBOL VALUE
	MOVE	S,PTSYM		;GET SYMBOL USED FOR PATCHING
  IFN FTSCSH,<			;ONLY IF USING SYMBOL TABLE CACHE
	PUSHJ	P,DELCSH	;REMOVE FROM THE SYMBOL TABLE CACHE
  > ;END IFN FTSCSH
	MOVE	S,T		;GET VALUE SYMBOL WAS REDEFINED AS
  IFN FTSCSH,<			;ONLY IF USING SYMBOL TABLE CACHE
	PUSHJ	P,DELCSV	;REMOVE VALUE FROM CACHE TOO
  > ;END IFN FTSCSH
PTCHE8:	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

PTCHX:	SKIPE	WRD2D		;$0< ?
	 JRST	ERR		;NO, UNDEFINED COMMAND
	MOVE	T,PTLLC		;YES, GET ADDR. OF PATCH INSERT
	MOVEM	T,LLOC		;DEFINE IT TO BE "."
	MOVEM	T,LLOCO		;AND LAST LOCATION OPEN
	SETZM	PTLOC		;DEFINE NO PATCH IN PROGRESS
	JRST	RET		;ABORT THE COMMAND

;(MATCH ANGLE BRACKETS: >)
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
	TXNE	F,FAF!SAF	;ANY ANGLIES TYPED?
	JRST	ERR		;YES, THAT'S BAD
  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
	SETOM	LASTPG		;DON'T KNOW PAGE ACCESS BITS ANYMORE
  > ;END IFN FTFILE
	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)
;	12-19	RESERVED FOR FUTURE
;	20	SET KA-10 CPU TYPE (FOR EMULATION, IGNORED IN EDDT)
;	21	SET KI-10 CPU TYPE (FOR EMULATION, IGNORED IN EDDT)
;	22	SET KL-10 CPU TYPE (FOR EMULATION, IGNORED IN EDDT)
;	23	SET KS-10 CPU TYPE (FOR EMULATION, IGNORED IN EDDT)
;	24+	RESERVED FOR FUTURE
;
;(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 AND SETS 3 (I.E., RESTORES "NORMAL
;VIRTUAL ADDRESSING"). $$U WITH NO ARGUMENTS SETS 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.
  IFN FTPAGM,<		;ONLY AVAILABLE IN FILDDT ON TOPS20
SETPAG:	TXNE	F,QF		;ANY ARG?
	JRST	SETPA2		;YES, A FUNCTION TO PERFORM
	TXNE	F,Q2F		;WANT TO READ BACK?
	JRST	SETPA4		;YES, GO TYPE IT OUT
	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
  IFN FTDEC10&FTFILE,<
	SKIPN	JOBEDV		;IF NOTHING FROM THE EDV WAS AVAILABLE,
	POPJ	P,		;GET OUT NOW
	MOVE	T,EDVEPT	;WE HAD SOMETHING
	MOVEM	T,MAPPG		;RESTORE THE EPT
	MOVE	T,EDVSPT	;THE SPT
	MOVEM	T,SPTWRD	;RESTORED
	MOVE	T,EDVCST	;AND THE CST
	MOVEM	T,CSTWRD	;...
	AOS	MAPFN		;ENABLE THE SIMULATION
  > ;END OF IFN FTDEC10&FTFILE
	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	(TT)		;DISPATCH
;STILL IFN FTPAGM

;HERE TO RETURN ADDRESS OF DDT WORD FOR USER TO SEE

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
	ANDI	T,-1		;CONCOCT AN INTERNAL-TO-DDT ADDRESS
	PJRST	MASK02		;AND RETURN VALUE AS IF USER TYPED IT
;STILL IFN FTPAGM

;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
	FAF!SAF!CCF+	ERR	;(12) RESERVED
	FAF!SAF!CCF+	ERR	;(13) RESERVED
	FAF!SAF!CCF+	ERR	;(14) RESERVED
	FAF!SAF!CCF+	ERR	;(15) RESERVED
	FAF!SAF!CCF+	ERR	;(16) RESERVED
	FAF!SAF!CCF+	ERR	;(17) RESERVED
	FAF!SAF!CCF+	ERR	;(18) RESERVED
	FAF!SAF!CCF+	ERR	;(19) RESERVED
	FAF!SAF!CCF+	SETKAC	;(20) SET KA-10 CPU TYPE
	FAF!SAF!CCF+	SETKIC	;(21) SET KI-10 CPU TYPE
	FAF!SAF!CCF+	SETKLC	;(22) SET KL-10 CPU TYPE
	FAF!SAF!CCF+	SETKSC	;(23) SET KS-10 CPU TYPE
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
	0,,	777777		;(12) RESERVED
	0,,	777777		;(13) RESERVED
	0,,	777777		;(14) RESERVED
	0,,	777777		;(15) RESERVED
	0,,	777777		;(16) RESERVED
	0,,	777777		;(17) RESERVED
	0,,	777777		;(18) RESERVED
	0,,	777777		;(19) RESERVED
	0,,	KAFLG		;(20) KA-10 FLAG
	0,,	KIFLG		;(21) KI-10 FLAG
	0,,	KLFLG		;(22) KL-10 FLAG
	0,,	KSFLG		;(23) KS-10 FLAG
;STILL IFN FTPAGM

;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
;STILL IFN FTPAGM

;SET FAKE ACS


SETFAC:	SKIPE	T		;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
	PUSHJ	P,CEFFAX	;DEFAULT SECTION IF NEEDED
	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
;STILL IFN FTPAGM

;LOAD ACS FROM ADDRESS

SETCAC:	PUSHJ	P,CEFFAX	;DEFAULT SECTION IF NEEDED
	MOVE	R,T		;ADDRESS IN R
SETCA1:	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:	PUSHJ	P,CEFFAX	;DEFAULT SECTION IF NEEDED
	MOVEM	T,SPTWRD	;STORE USER ARG
	POPJ	P,		;DONE


;SET CST BASE

SETCST:	PUSHJ	P,CEFFAX	;DEFAULT SECTION IF NEEDED
	MOVEM	T,CSTWRD	;STORE USER ARG
	POPJ	P,		;DONE
;STILL IFN FTPAGM

;SET PROTECTION AND RELOCATION

SETREL:	PUSHJ	P,CEFFAX	;DEFAULT SECTION IF NEEDED
	MOVEM	T,UBASE		;STORE RELOCATION ADDRESS
	POPJ	P,		;DONE

SETPRT:	PUSHJ	P,CEFFAX	;DEFAULT SECTION IF NEEDED
	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
  > ;END IFN FTEXEC

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

;SET KA/KI/KL/KS CPU TYPE, ERROR IF IN EXEC MODE

SETKAC:	PUSHJ	P,SETKZC	;INITIALIZE CPU FLAGS
	MOVEM	T,KAFLG		;SET KA-10 EMULATION
	POPJ	P,		;DONE

SETKIC:	PUSHJ	P,SETKZC	;INITIALIZE CPU FLAGS
	MOVEM	T,KIFLG		;SET KI-10 EMULATION
	POPJ	P,		;DONE

SETKLC:	PUSHJ	P,SETKZC	;INITIALIZE CPU FLAGS
	MOVEM	T,KLFLG		;SET KL-10 EMULATION
	MOVEM	T,KLSFLG	;SET KL/KS EMULATION
	POPJ	P,		;DONE

SETKSC:	PUSHJ	P,SETKZC	;INITIALIZE CPU FLAGS
	MOVEM	T,KSFLG		;SET KS-10 EMULATION
	MOVEM	T,KLSFLG	;SET KL/KS EMULATION
	POPJ	P,		;DONE

SETKZC:				;HELPER TO CLEAR CPU FLAGS AND SUCH
  IFN FTEXEC,<			;NEVER NEVER DO THIS IN EXEC MODE!
	SKPUSR			;USER MODE?
	JRST	ERR		;EXEC, DISALLOW UNDER THREAT OF DEATH
  > ;END IFN FTEXEC
	SETZM	BZ$CPF		;CLEAR START OF CPU FLAGS AREA
	MOVE	TT,[BZ$CPF,,BZ$CPF+1]	;BLT POINTER TO
	BLT	TT,ZZ$CPF-1	;CLEAR REST OF CPU FLAGS AREA
	CAIE	T,0		;ARG TO "SET" OR "CLEAR"?
	SETO	T,		;SET, NORMALIZE TO -1
	POPJ	P,		;GO SET/CLEAR APPROPRIATE FLAG
  > ;END IFN FTPAGM

IFE FTPAGM,<SETPAG==ERR>	;DOESN'T EXIST
;$L AND $$L COMMANDS - LIST PAGE (SECTION) ACCESSABILITY
;
;    $[$]L	TYPE ACCESS OF ALL PAGES (SECTIONS)
;   N$[$]L	TYPE ACCESS FOR SECTION N
; N<M$[$]L	TYPE ACCESS FOR SECTIONS N THRU M
;
;(MATCH ANGLE BRACKETS: >)

PAGMAP:	TXNN	F,Q2F		;$NL FORMAT?
	TXNE	F,SAF		;OR SECOND ANGLE?
	JRST	ERR		;USER IS CONFUSED
  IFN FTFILE,<			;FILDDT MIGHT LUCK OUT
	SKIPE	FILING		;IF IT'S MEMORY
	SKIPN	EXEFMT		; OR DATA FILE/DISK
	JRST	PGMA10		;THEN LIFE IS SIMPLER
  > ;END IFN FTFILE
	TXNN	F,QF		;UPPER LIMIT TYPED?
	MOVEI	T,37		;NO, DEFAULT TO MAX
	JUMPL	T,ERR		;NEG ARG IS NO GOOD
	CAILE	T,37		;CAN GO UP TO 37
	JRST	ERR		;OUT OF RANGE, SORRY
	MOVEM	T,ULIMIT	;SAVE UPPER LIMIT AWAY
	TXNN	F,FAF		;LOWER LIMIT GIVEN?
	JRST	[TXNN	F,QF	;NO, WAS THERE AN EXPLICIT ARG?
		SETZ	T,	;NO, DEFAULT TO ZERO
		MOVEM	T,LLIMIT ;SET THE LOWER LIMIT
		JRST	PAGMA2]	;JOIN COMMON CODE
	SKIPL	T,LLIMIT	;FETCH SPECIFIED LOWER LIMIT
	CAILE	T,37		;IN RANGE?
	JRST	ERR		;NO WAY
PAGMA2:	CAMLE	T,ULIMIT	;IS LOWER .LE. UPPER?
	JRST	ERR		;NO, FORGET THIS

;FALL THROUGH TO NEXT PAGE
;FALL IN FROM ABOVE

;HERE WITH A VALID RANGE OF SECTIONS TO LOOK AT

  IFN FTUE10,<
	SETZM	OLDSPY		;NOT YET KNOWN IF PA.GPN IS VALID
  > ;END IFN FTUE10
	PUSHJ	P,TCRLF		;START OFF RIGHT
	SOS	LLIMIT		;COMPENSATE FOR LATER AOS
  IFN FTEX10,<PUSHJ P,NORSPC>	; MAKE SURE WE'RE IN NORMAL SPACE
PAGMA3:	PUSHJ	P,LISCK		;USER WANT TO HANG IT UP?
	  JRST	PAGM30		;NO, KEEP SCANNING
	 JRST	DD1		;YES, QUIT
	MOVEI	W1,[ASCIZ\Scanning memory: \] ;"?", NICE TEXT
	PUSHJ	P,TSTRG		;TELL USER
	MOVE	T,LLIMIT	;LAST SECTION CHECKED
	ADDI	T,1		;CURRENT SECTION TO BE CHECKED
	HRLZ	T,T		;CURRENT WORD ADDRESS TO BE CHECKED
	PUSHJ	P,PADR		;TYPE OUT ADDRESS
	PUSHJ	P,TCRLF		;CAP OFF "?" SUMMARY WITH <CR><LF>
PAGM30:	AOS	TT,LLIMIT	;GET NEXT SECTION TO CHECK
	CAMLE	TT,ULIMIT	;PAST LAST SECTION?
	JRST	DD1		;YES, QUIT
	PUSHJ	P,CHKSEC	;GET ACCESS FOR THIS SECTION
	TXNN	TT,PG$SXI	;DOES IT EXIST?
	JRST	PAGMA3		;NO, TRY NEXT SECTION

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

	TSTR	< Section >	;YES, SAY WHAT WE ARE
	PUSH	P,ODF		;SAVE OUTPUT RADIX FOR A SECOND
	MOVEI	ODF,8		;SET TO OCTAL
	MOVE	T,LLIMIT	;GET THE SECTION NUMBER
	PUSHJ	P,TOC		;TYPE IT IN OCTAL
	TXNN	TT,PG$SMA	;SECTION MAPPED ELSEWHERE?
	JRST	PAGM34		;NO, JUST TYPE ACCESS BITS
	MOVEI	W1,[ASCIZ / shared/]	;ASSUME SHARED
	TXNE	TT,PG$SIN		;UNLESS PROVEN INDIRECT
	MOVEI	W1,[ASCIZ / indirect/]	;IT'S INDIRECT
	PUSHJ	P,TSTRG			;TELL 'EM
  IFN FTEXEC,<
	SKPUSR		;USER MODE?
	JRST PAGM34	;SKIP THIS STUFF
  > ;END IFN FTEXEC
  IFE FTMON,<
	MOVEI	W1,[ASCIZ / to section /] ;SAY WHERE TO
	PUSHJ	P,TSTRG			;TYPE IT
	LDB	T,[POINTR TT,PG$SEC]	;GET THE TARGET SECTION
	PUSHJ	P,TOC		;AND TYPE IT TOO
  IFN FTDEC20,<			;-20 CAN MAP TO FILES, OTHER FORKS
	TXNN	TT,PG$SFJ	;MAPPED TO EITHER FORK OR JFN?
	JRST	PAGM34		;NO, ALL DONE
	MOVEI	W1,[ASCIZ /, fork /]	;ASSUME FORK
	TXZN	TT,.FHSLF		;FORK OR FILE?
	MOVEI	W1,[ASCIZ /, JFN /]	;IT'S A FILE
	PUSHJ	P,TSTRG		;TYPE WHICH
	HRRZ	T,TT		;LOAD UP FORK/JFN NUMBER
	PUSHJ	P,TOC		;AND TYPE IT TOO
  > ;END IFN FTDEC20
  > ;END IFE FTMON
PAGM34:	POP	P,ODF		;RESTORE RADIX
	PUSHJ	P,TTAB		;SPACE OVER A LITTLE
	PUSHJ	P,TYPACC	;TYPE ACCESS INFO TO FINISH THE LINE
	TXNE	F,CCF		;ARE WE TALKING PAGES HERE?
	JRST	PAGMA3		;NO, JUST SECTIONS

;FALL THROUGH TO NEXT PAGE
;FALL IN FROM ABOVE

;HERE TO LOOP THROUGH ALL PAGES OF A SECTION, TYPING ACCESS OF EACH GROUP.

	SETOM	LOWPAG		;INIT LOW PAGE NUMBER
	MOVE	R,LLIMIT	;CURRENT SECTION NUMBER
	LSH	R,PG2WRD	;MAKE IT A PAGE NUMBER
	MOVEM	R,HGHPAG	;INIT HIGH PAGE NUMBER
	JRST	PAGMA5		;SKIP THE CHECK FIRST TIME AROUND
PAGMA4:	PUSHJ	P,LISCK		;USER WANT TO HANG IT UP?
	  JRST	PAGM40		;NO, PROCESS NEXT PAGE
	 JRST	DD1		;YES, ABORT
	MOVEI	W1,[ASCIZ\Scanning memory: \] ;"?" TEXT, NICE TEXT
	PUSHJ	P,TSTRG		;TELL USER
	MOVE	T,HGHPAG	;LAST PAGE CHECKED
	ADDI	T,1		;CURRENT PAGE TO BE CHECKED
	LSH	T,PG2WRD	;MAKE A WORD ADDRESS
	PUSHJ	P,PADR		;TYPE OUT ADDRESS
	PUSHJ	P,TCRLF		;CAP OFF "?" SUMMARY WITH <CR><LF>
PAGM40:	AOS	R,HGHPAG	;GET NEXT PAGE
	TRNN	R,PAGMSK	;REACHED END OF SECTION?
	JRST	[MOVE	TT,OLDBTS	;YES, GET MOST RECENT ACCESS BITS
		TXNN	TT,PG$EXI	;DID PAGE 777 EXIST?
		JRST	PAGMA3		;NO, GO FOR NEXT SECTION
		JRST	PAGMA7]		;YES, GO TYPE THE ACCESS
PAGMA5:	PUSHJ	P,PAGACC	;GET PAGE ACCESS BITS
	MOVE	T,HGHPAG	;GET CURRENT PAGE AGAIN
	SKIPGE	LOWPAG		;FIRST TIME THROUGH?
	JRST	PAGMA6		;YES, NO OLD ACCESS TO CHECK
  IFN FTUE10,<
	TXNN	TT,PG$SPY	;IF NOT A SPY PAGE,
	JRST	PAGM58		;WE DON'T CARE
	SKIPE	OLDSPY		;DO WE KNOW YET IF PA.GPN IS VALID?
	JRST	PAGM57		;YES, DON'T FIND OUT TWICE
	SETO	TT1,		;GET AN ILLEGAL ADDRESS
	TRNE	TT,PA.GPN	;IF FIELD IS NON-ZERO,
	TDZA	TT1,TT1		;THEN IT'S VALID
	IPCFM.	TT1,		;NO, CHECK FOR 7.03 OR LATER MONITOR
	MOVEM	TT1,OLDSPY	;NEGATIVE IF PA.GPN INVALID
	JUMPL	TT1,PAGM58	;DO IT OLD WAY IF NOT VALID
	AOS	OLDSPY		;MAKE SURE IT'S POSITIVE
PAGM57:	SKIPG	OLDSPY		;IF NOT VALID,
	JRST	PAGM58		;DO IT THE OLD WAY
	MOVE	TT1,OLDBTS	;YES, GET PREVIOUS FLAGS
	TXNN	TT1,PG$SPY	;IF NOT A SPY PAGE BEFORE,
	JRST	PAGM59		;THEN TIME TO TYPE
	AOS	TT1		;ADJUST COPY OF OLDBTS FOR COMPARISON
	CAME	TT1,TT		;IF NO MATCH,
	JRST	PAGM59		;THEN TIME TO TYPE
	AOS	OLDBTS		;YES, MAKE SURE SEQUENTIAL PAGES MATCH
	;PJRST	PAGM58		;NOW DO IT THE OLD WAY
  > ;END IFN FTUE10
PAGM58:	CAMN	TT,OLDBTS	;SAME ACCESS AS LAST TIME?
	JRST	PAGMA4		;YES, GO FOR NEXT PAGE
	MOVE	TT1,OLDBTS	;NO, GET OLD BITS
PAGM59:	TXNE	TT1,PG$EXI	;DID IT EXIST?
	JRST	PAGMA7		;YES, GO TYPE THE ACCESS
PAGMA6:	MOVEM	T,LOWPAG	;NO, SAVE LOW END PAGE NUMBER
	MOVEM	TT,OLDBTS	;AND ACCESS BITS
  IFN FTUE10,<
	TXNE	TT,PG$SPY	;IF NOT A SPY PAGE,
	SKIPE	OLDSPY		;OR WE ALREADY KNOW ABOUT PA.GPN
	JRST	PAGMA4		;GO FOR THE NEXT PAGE
	SETO	TT1,		;GET AN INVALID ADDRESS
	TRNE	TT,PA.GPN	;IF THE FIELD IS PRESENT,
	TDZA	TT1,TT1		;THEN WE ALREADY KNOW
	IPCFM.	TT1,		;NO, CHECK FOR 7.03 OR LATER MONITOR
	MOVEM	TT1,OLDSPY	;SETUP FLAG FOR LATER
	JUMPL	TT1,PAGMA4	;SKIP THIS IF OLD MONITOR
	AOS	OLDSPY		;MAKE SURE WE KNOW IT WORKS
  > ;END IFN FTUE10
	JRST	PAGMA4		;GO FOR NEXT PAGE
;HERE TO DO THE EASY FILDDT CASE, OF MEMORY/DATA FILE/DISK.
;ACCESS TO THE ENTIRE TARGET IS THE SAME, SO JUST REPORT IT ONCE.

  IFN FTFILE,<
PGMA10:	PUSHJ	P,TCRLF		;START OFF CLEAN
	SKIPE	FILING		;LOOKING AT A FILE?
	JRST	[MOVEI	W1,[ASCII /File/] ;YES, MAYBE
		SKIPE	PHYSIO		  ;COULD BE A DISK, THOUGH
		MOVEI	W1,[ASCII /Disk/] ;YEP, A DISK
		JRST	PGMA11]		  ;GO TYPE THE MESSAGE
	MOVEI	W1,[ASCII /Monitor/] ;ASSUME MONITOR
    IFN FTDEC10,<		;-10 CAN SEE JOBS TOO
	SKIPE	JOBING		;LOOKING AT A JOB?
	MOVEI	W1,[ASCII /Job memory/] ;YES, SAY IT IS
    > ;END IFN FTDEC10
PGMA11:	PUSHJ	P,TSTRG		;TYPE THE TARGET TYPE
	TSTR	< access is >	;MORE MESSAGE
	SETZ	R,		;ALL ADDRESSES ARE EQUAL IN THESE CASES
	PUSHJ	P,PAGACC	;GET THE USER'S ACCESS BITS
	PUSHJ	P,TYPACC	;TYPE 'EM OUT
	JRST	DD1		;ALL DONE
  > ;END IFN FTFILE
;HERE TO TYPE OUT THE RANGE OF THE PAGE GROUP AND ITS ACCESS

PAGMA7:	MOVE	W1,LOWPAG	;GET LOW PAGE NUMBER
	PUSHJ	P,PAGOUT	;TYPE IT OUT
	MOVE	W2,LOWPAG	;GET LOW PAGE AGAIN
	MOVE	W1,HGHPAG	;GET HIGH PAGE
	SOS	W1		;DECREMENT TO LAST PAGE OF THIS GROUP
	CAMN	W1,W2		;JUST ONE PAGE?
	JRST	[MOVE	W1,[ASCIZ /    /] ;YES, SPACE OVER SOME
		PUSHJ	P,TEXT2		;SO COLUMNS LINE UP NICELY
		JRST	PAGMA9]		;GO TYPE ACCESS
	MOVEI	T,"-"		;NO, TYPE DASH
	PUSHJ	P,TOUT		;AS SEPARATOR
	PUSHJ	P,PAGOUT	;AND SECOND PAGE NUMBER
PAGMA9:	PUSHJ	P,TTAB		;MOVE OVER FROM PAGE NUMBERS
	EXCH	TT,OLDBTS	;SWAP ACCESS BITS, GET OLD GROUP
	PUSHJ	P,TYPACC	;TYPE ALL THE BIT MEANINGS
	MOVE	T,HGHPAG	;GET NEXT PAGE NUMBER
	MOVEM	T,LOWPAG	;SET NEW LOW PAGE FOR NEXT GROUP
	TRNE	T,PAGMSK	;AT END OF SECTION?
	JRST	PAGMA4		;NO, GO FOR NEXT PAGE GROUP
	JRST	PAGMA3		;YES, GO FOR NEXT SECTION

;PAGOUT - TYPE A PAGE NUMBER IN EXACTLY THREE COLUMNS
;PAGE NUMBER IN W1, DESTROYS W1, W2

PAGOUT:	SETZ	W2,		;CLEAR DESTINATION
  REPEAT 3,<			;FOR EACH DIGIT,
	LSHC	W1,-3		;SHIFT THE OCTAL DIGIT
	LSH	W2,-4		;PLUS FOUR TO MAKE 7-BIT BYTES
  > ;END REPEAT 3
	ADD	W2,[ASCII /000/];TURN IT INTO TEXT
	MOVE	W1,W2		;PUT IT IN THE RIGHT PLACE
	PJRST	TEXT2		;AND TYPE IT OUT
;PAGACC - DETERMINE ACCESS TO A PAGE
;
;	MOVX	R,<PAGE NUMBER>
;	PUSHJ	P,PAGACC
;	RETURN
;
;RETURNS ACCESS BITS IN AC TT, ACCORDING TO CHKADR EXCEPT IN THE CASE
;OF FILDDT'ING AN EXE FILE.  IN THAT CASE PAGACC LOOKS AT THE EXE FILE'S
;DIRECTORY ACCESS BITS.
;
;CAN DESTROY TT1, SAVES ALL OTHER ACS

PAGACC:	PUSHJ	P,SAVR		;SAVE THIS OVER CALLS
  IFN FTFILE,<			;FILDDT HAS SOME THINGS TO CHECK FIRST
	SKIPE	FILING		;IF MEMORY,
	SKIPN	EXEFMT		;OR DATA FILE/DISK,
	CAIA			;JUST LIKE EVERYBODY ELSE.
	JRST	PAGAC5		;EXE FILES ARE DIFFERENT
  > ;END IFN FTFILE
	LSH	R,PG2WRD	;CHKADR WANTS AN ADDRESS
  IFN FTPAGM,<
	PUSHJ	P,MAPADR	;FIRST DO SPECIFIED MAPPING
	 TDZA	TT,TT		;CAN'T, CLAIM NO ACCESS
  > ;END IFN FTPAGM
	PUSHJ	P,CHKADR	;GET THE ACCESS
  IFN FTFILE,<
	TXZ	TT,PG$EXE!PG$SHR!PG$PRV	;CLEAR NONSENSE BITS
  > ;END IFN FTFILE
  IFN PG$CPY,<
	TXNE	TT,PG$WRT	;WRITE ACCESS ALLOWED?
	TXNE	TT,PG$CPY	;THAT ISN'T COPY-ON-WRITE?
	TRNA			;DON'T CLAIM WRITE IF ONLY COPY-ON-WRITE
	TXO	TT,PG$WT	;YES, SET BIT FOR TYPACC
  > ;END IFN PG$CPY
  IFN FTUE10,<
    IFN FTEXEC,<
	SKPUSR			;IF EXEC MODE,
	TXCA	TT,PG$EXI!PG$SXI ;NEUTER THE TXC BELOW (NO PAGE. UUO HERE)
    > ;END IFN FTEXEC
	MOVE	TT,LASTAF	;GET REAL BITS FROM PAGE. UUO
	TXC	TT,PG$EXI!PG$SXI ;FIX THE EXISTENCE FLAGS
	TXNE	TT,PG$SPY	;IF A SPY PAGE,
	TXZ	TT,PG$LCK!PG$NCA ;DON'T SAY LOCKED OR NOT CACHED
	TLZ	TT,^-<ACXBTS_-22>	;KEEP ONLY BITS WE CARE ABOUT
  > ;END IFN FTUE10
	POPJ	P,		;ALL DONE
;HERE TO DETERMINE ACCESS FOR EXE FILES IN FILDDT

  IFN FTFILE,<			;NOW THE REAL WORK
PAGAC5:	SETZ	TT,		;START WITH NO ACCESS
    IFN FTPAGM,<
	SKIPG	MAPFN		;IF NO REAL MAPPING,
	JRST	PAGAC7		;DON'T WASTE TIME WITH IT
	LSH	R,PG2WRD	;MAPADR WANTS AN ADDRESS
	PUSHJ	P,MAPADR	;DO ANY NECESSARY TRANSLATION
	  JRST	[SETZ TT,	;NONE POSSIBLE, CLEAR THE BITS
		 JRST PAGAC9]	;AND PUNT
	LSH	R,WRD2PG	;BACK TO A PAGE NUMBER FOR INDEXING INTO PAGTBL
	SETZ	TT,		;CLEAR THE BITS AGAIN (CLOBBERED BY MAPADR)
	PUSHJ	P,PAGAC7	;GET BITS FOR THE PAGE FROM THE FILE DIRECTORY
	JUMPE	TT,PAGAC9	;GET OUT NOW IF NO ACCESS
	SKPNKA			;IF A KA10
	JRST	PAGAC9		;THERE ARE NO BITS
	MOVE	TT1,MAPBTS	;GET THE ACCUMULATED ACCESS BITS
	SKPKLP			;SIGH--I CAN'T FIND MY KI10 MANUAL
	JRST	PAGAC9		;SO JUST RETURN THIS ACCESS FOR KI-STYLE PAGING
	TXNN	TT1,PTWR	;CHECK WHETHER MAP SAYS IT'S WRITABLE
	TXZA	TT,PG$WT	;NO--CLEAR BIT
	TXO	TT,PG$WT	;YES--SET BIT
      IFN FTDEC10,<
	TXNN	TT1,PTPUB	;CHECK STATUS OF PM.PUB
	TXZ	TT,PG$REA	;CONCEALED
	TXNN	TT1,PTCACH	;SIMILARLY FOR PM.CSH
	TXOA	TT,PG$NCA	;UNCACHED
	TXZ	TT,PG$NCA	;CACHED
      >
	JRST	PAGAC9		;FINALLY RETURN THE BITS
    >
PAGAC7:	MOVE	TT1,R		;NEED INDEX INTO PAGTBL
	CAMGE	TT1,PGTLEN	;PAST EOF?
	SKIPN	TT1,@PAGTBL	;OR NON-EXISTENT?
	JRST	PAGAC9		;YES, NO ACCESS POSSIBLE
	TXO	TT,PG$EXI!PG$SXI!PG$EXE!PG$REA  ;THE PAGE IS REAL AND READABLE
  IFN FTDEC10,<
	TXNE	TT1,SV$SHR	;SHARABLE?
	TXO	TT,PG$SHR	;YES, SET THE SHARE BIT
	TXNE	TT1,SV$HIS	;HISEG PAGE?
	TXO	TT,PG$HGH	;YES, SET THE BIT
	TXNE	TT1,SV$WRT	;WRITABLE?
	TXO	TT,PG$WT	;YES, SET THE BIT
	TXNE	TT1,SV$CON	;CONCEALED?
	TXZ	TT,PG$REA	;YES, NOT READABLE
	ANDX	TT1,SV$FPN	;REDUCE TO FILE PAGE NUMBER
	SKIPN	TT1		;IS IT A REAL PAGE?
	TXO	TT,PG$ABZ	;NO, FLAG ZERO PAGE
  > ;END IFN FTDEC10
  IFN FTDEC20,<
	TXNN	TT1,SV$WRT	;WRITABLE AT ALL?
	JRST	PAGAC8		;NO, SKIP ALL THIS
	TXNE	TT1,SV$SHR	;YES, SHARED WRITE?
	TXOA	TT,PG$WT	;YES, REALLY WRITABLE
	TXO	TT,PG$CPY	;NO, REALLY MEANS COPY-ON-WRITE
PAGAC8:	TXNE	TT1,SV$ABZ	;IS IT A ZERO PAGE?
	TXO	TT,PG$ABZ	;YES, SET THE BIT
  > ;END IFN FTDEC20
PAGAC9:	POPJ	P,		;ALL ACCESSES DETERMINED
  > ;END IFN FTFILE
;TYPACC - TYPE TEXT FOR PAGE (SECTION) ACCESS BITS.
;
;	MOVX	TT,<ACCESS BITS>
;	PUSHJ	P,TYPACC
;	RETURN
;
;TYPES TEXT FOR EACH KNOWN ACCESS BIT, AND TERMINATES WITH A CRLF.

TYPACC:	TXNN	TT,ACCBTS	;ANY ACCESS BITS SET?
	JRST	TYPAC9		;NO, DON'T BOTHER CHECKING INDIVIDUAL BITS
	SETZ	S,		;FLAG NOTHING TYPED YET
	MOVSI	W2,-NPGBTS	;LOOP OVER ALL BITS
TYPAC1:	TDNN	TT,PAGBTS(W2)	;THIS BIT SET?
	JRST	TYPAC3		;NO, GO CHECK NEXT ONE
	MOVE	W1,[ASCIZ /, /]	;GET SEPARATOR TEXT
	SKIPE	S		;FIRST FLAG FOUND?
	PUSHJ	P,TEXT2		;NO, TYPE THE COMMA
	MOVE	W1,PAGTXT(W2)	;GET TEXT ADDRESS
	PUSHJ	P,TSTRG		;TYPE IT OUT
	SETOM	S		;FLAG WE DID ONE
TYPAC3:	AOBJN	W2,TYPAC1	;GO BACK FOR NEXT BIT
  IFN FTUE10,<
	TXNN	TT,PG$SPY	;GUARD AGAINST SPY SEGS
	TXNN	TT,PG$HGH	;IS THIS A HISEG?
	JRST	TYPAC5		;NO, CHECK FOR SPY SEG/PAGES
	TXNN	TT,PA.GSG	;DO WE KNOW WHICH SEGMENT?
	JRST	TYPAC9		;NO, GIVE UP
	ANDI	TT,PA.GSG	;ISOLATE SEGMENT NUMBER
	MOVEM	TT,SEGOPB+.SGSGN ;SAVE FOR .SGINF
	SETZM	SEGOPB+.SGSNM	;DON'T KNOW THE NAME YET
	SETZM	SEGOPB+.SGFLG	;DON'T STEP PAST IT
	MOVSI	TT,.SGFSP+1	;LENGTH OF BLOCK DESIRED
	HLLM	TT,SEGOPB	;SET FOR UUO
	XMOVEI	TT,SEGOPB	;POINT TO THE BLOCK
	SEGOP.	TT,		;AND GET THE DATA
	  JRST	TYPAC9		;OLD MONITOR?
	SKIPN	SEGFIL+.SGFDV	;IF NO DEVICE,
	SKIPE	SEGOPB+.SGSNM	;AND NO NAME
	TRNA			;AT LEAST ONE, KEEP GOING
	JRST	TYPAC9		;NEITHER, GIVE UP
	MOVEI	T,","		;YES, GET MORE PUNCTUATION
	PUSHJ	P,TOUT		;TYPE IT
	MOVE	TT,SEGOPB+.SGSNM ;GET THE SEGMENT NAME
	CAMN	TT,SEGFIL+.SGFNM ;IS IT THE SAME AS ITS FILE NAME?
	JRST	TYPAC4		;YES, WE'RE DONE HERE
	MOVSI	W1,(ASCII / (/)	;GET TEXT TO TYPE
	PUSHJ	P,TEXT		;TYPE IT
	MOVE	W1,TT		;GET SIXBIT SEGMENT NAME
	PUSHJ	P,TSIXN		;AND TYPE IT OUT
	MOVEI	T,")"		;AND CLOSE PAREN
	PUSHJ	P,TOUT		;TYPE THAT AS WELL
TYPAC4:	SKIPN	SEGFIL+.SGFDV	;IF NO DEVICE,
	JRST	TYPAC9		;WE'RE DONE (NONSHARABLE)
	PUSHJ	P,TCRLF		;GET TO A NEW LINE
	MOVEI	T," "		;SPACE OVER
	MOVEI	W1,7		;THE WIDTH OF THE PAGE RANGE
	PUSHJ	P,TOUT		;TYPE THE SPACE
	SOJG	W1,.-1		;TYPE SEVERAL
	PUSHJ	P,TTAB		;FINALLY, MAKE SURE THE INDENTATION MATCHES
	MOVEI	W1,[ASCIZ /from /]
	PUSHJ	P,TSTRG		;SAY WHAT THIS IS
	MOVEI	TT,SEGFIL	;ADDRESS OF FILESPEC
	PUSHJ	P,TYPRFS	;TYPE THE FILESPEC
	JRST	TYPAC9		;DONE WITH SHARABLE HISEG
TYPAC5:	TXNN	TT,PG$SPY	;ARE THESE PAGES SPYING?
	JRST	TYPAC9		;NO, GIVE UP
	MOVSI	W1,(ASCII /, /)	;YES, GET SEPARATOR
	PUSHJ	P,TEXT		;TYPE IT
	MOVEI	W1,[ASCIZ /monitor/] ;ASSUME VIRTUAL
	TXNN	TT,PA.GVR	;IS THAT RIGHT?
	MOVEI	W1,[ASCIZ /core/] ;NO, CHANGE THE TEXT
	PUSHJ	P,TSTRG		;SAY WHICH KIND OF SPY PAGE
	MOVEI	W1,[ASCIZ / page/] ;ADD THE WORD
	PUSHJ	P,TSTRG		;TO SAY WHAT THIS IS
	MOVE	W1,HGHPAG	;GET FIRST NON-EX PAGE
	SUB	W1,LOWPAG	;GET NUMBER OF PAGES
	MOVEI	T,"s"		;CHARACTER TO MAKE PLURAL
	CAIE	W1,1		;IF NOT JUST ONE PAGE,
	PUSHJ	P,TOUT		;MAKE IT PLURAL
	SKIPG	OLDSPY		;IF NO TARGET INFORMATION,
	JRST	TYPAC9		;DON'T TYPE JUNK
	MOVEI	T," "		;SEPARATION
	PUSHJ	P,TOUT		;NEATNESS COUNTS
	SOJLE	W1,TYPAC6	;SKIP THIS IF NOT MULTIPLE PAGES
	SUBM	TT,W1		;BACK OFF TO ORIGINAL PAGE NUMBER
	ANDI	W1,PA.GPN	;ISOLATE TO JUST PAGE NUMBER
	PUSHJ	P,TOCTW		;TYPE THE STARTING PAGE NUMBER
	MOVEI	T,"-"		;INDICATE A RANGE
	PUSHJ	P,TOUT		;TYPE THE SEPARATOR
TYPAC6:	MOVE	W1,TT		;COPY BITS
	ANDI	W1,PA.GPN	;ISOLATE PAGE NUMBER
	PUSHJ	P,TOCTW		;TYPE IT IN OCTAL
	;PJRST	TYPAC9		;DONE WITH SPY PAGES
  > ;END IFN FTUE10
TYPAC9:	PUSHJ	P,TCRLF		;NO MORE BITS, FINISH OFF LINE
	POPJ	P,		;AND RETURN

DEFINE	BITS <
X	PG$REA,<Read>		;PAGE CAN BE READ
X	PG$WT,<Write>		;PAGE CAN BE WRITTEN
X	PG$CPY,<Copy-on-write>	;PAGE IS COPY-ON-WRITE
X	PG$EXE,<Execute>	;PAGE CAN BE EXECUTED FROM
X	PG$ACC,<AA>		;PAGE ACCESS ALLOWED
X	PG$PRV,<Private>	;PAGE IS A PRIVATE PAGE
X	PG$SHR,<Sharable>	;PAGE CAN BE SHARED
X	PG$HGH,<Hiseg>		;PAGE IS PART OF HIGH SEGMENT
X	PG$ABZ,<Zero>		;PAGE ALLOCATED BUT ZERO
X	PG$SPY,<Spying>		;PAGE IS ACTUALLY SPYING ON SOMEONE
X	PG$NPG,<Cannot page>	;PAGE CANNOT BE PAGED OUT
X	PG$PGO,<Paged out>	;PAGE IS PAGED OUT
X	PG$LCK,<Locked>		;PAGE IS LOCKED IN CORE
X	PG$NCA,<Not cached>	;PAGE IS NOT CACHED
>

DEFINE	X(B,S) <IFN <B>,<EXP B
	ACCBTS==ACCBTS!<B>>>
ACCBTS==0
PAGBTS:	BITS			;MAKE THE BIT TABLE
NPGBTS==.-PAGBTS

DEFINE	X(B,S) <IFN <B>,<EXP [ASCIZ /S/]>>
PAGTXT:	BITS			;MAKE THE TEXT TABLE

IFN FTUE10,<ACXBTS==ACCBTS!PG$EXI!PG$SXI!PG$SEC!PG$VIR> ;BIT MASK FOR PAGACC
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:	SKIPE	MAPFN		;ANY MAPPING IN EFFECT
	 JRST	ERR		;NOT STRAIGHT VIRTUAL
	TXNE	F,QF		;HAS <A> BEEN TYPED?
	JRST	BPS1		;YES
	TXNE	F,FAF!SAF	;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:	PUSHJ	P,CEFFAX	;DEFAULT SECTION IF NEEDED
	TDNN	T,[^-1,,^-17]	;IS THIS AN AC?
	HRRZS	T		;YES, FIX UP JUST IN CASE OF ZERO
	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?
	 JRST ERR		;NO
	PUSHJ	P,DMEMER	;CAN'T SET BPT IF CAN'T WRITE
	SKIPE	BPBLK		;INTER-SECTION BPT POSSIBLE?
	 JRST	BPS1A		;YES, DON'T NEED TO HAVE DDT THERE
	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 [	SMERS	<CAN'T SET BREAKPOINT, $4M NOT SET>	;CAN'T
		JRST	ERR]	;TELL 'EM WHY NOT
	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	MASK02]		;TREAT AS DDT INTERNAL 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
	TXZE	F,SAF		;USER SPECIFY ADDRESS OF COMMAND ON BREAK?
	SKIPA	T,ULIMIT	;YES
	SETZ	T,		;NO
	MOVEM	T,BPT$B+B$STR(S);SET COMMAND STRING (IF ANY)
				; (IGNORED IF FTYANK TURNED OFF)
	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
	PUSHJ	P,RSTAC		;RESTORE ACS
	SKIPE	S,BPTDX		;GET BREAKPOINT INDEX
	TXNN	F,QF		;EXPLICIT PROCEED COUNT?
	MOVEI	T,1		;NO (OR PROCEED FROM $0B)
	TXNN	F,QF		;EXPLICIT PROCEED COUNT?
	SKIPN	BPT$B+B$CNT(S)	;NO, STORE NEW VALUE IF OLD ONE'S ZERO
	MOVEM	T,BPT$B+B$CNT(S);YES, 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
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
  IFN FTEX10,<			;CPNDDT ONLY ON A -10
	SKIPN	T,CPNBIT	;DID WE LIGHT A BIT IN CPNDDT?
	JRST	PROCD9		;NO, DON'T CLEAR IT
	MOVE	R,CPNDDT	;YES, GET ADDRESS TO CLEAR
	SETZ	T,		;AND A ZERO TO PUT THERE
	PUSHJ	P,STOREP	;LET OTHER CPUS RUN AGAIN
	 JFCL			;C'EST LA VIE
PROCD9:
  > ;END IFN FTEX10
	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	RESTRX		;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
	MOVEM	T,I.NST		;SAVE INSTRUCTION
	PUSHJ	P,TCRLF
IFN FTEXEC,<PUSHJ P,RSTAC>	;ENSURE PROPER CONTEXT AC BLOCK
	SETZM	SKPCT		;INIT SKIP COUNT
IFN FTMON,<CHKIN>		;LOCK BREAKPOINT BLOCK
	TXNN	F,CCF		;<INSTR>$$X FORM?
	JRST	XEC2		;NO, CHECK OUT $X SECTION
	TXNN	F,Q2F		;EXPLICIT SECTION TYPED?
	JRST	XEC4		;NO, JUST XCT THE **** INSTRUCTION!
	MOVS	T,WRD2O		;YES, POSITION USER-SPECIFIED SECTION
	JRST	XEC3		;AND TRY TO EXECUTE IN THAT SECTION

;IF WE ARE RUNNING EXTENDED, THE USER MAY WANT TO EXECUTE THE
;INSTRUCTION AS IF IT WERE IN ANOTHER SECTION.  WE WILL ASSUME
;HE WANTS TO EXECUTE IT IN THE CURRENT DEFAULT SECTION.

XEC2:	PUSHJ	P,GDFSEC	;GET DEFAULT SECTION
XEC3:	CAMN	T,SECDDT	;SAME AS OURS?
	JRST	XEC4		;YES, JUST EXECUTE IT
	SKIPN	BPBLK		;GOT A GLOBAL BREAKPOINT/EXECUTE BLOCK?
	JRST	XEC3L		;NO, SEE IF MAPPED INTO SPECIFIED SECTION
	XMOVEI	W1,XEC5		;ADDRESS TO RETURN TO
	SETZM	I.CJMP		;FLAG WE WANT SKIPS CHECKED
	SETO	W2,		;FLAG WE'RE INSTR$X
	PUSHJ	P,$XBLK		;SET UP THE BLOCK
	PUSHJ	P,INSRTB	;INSTALL BREAKPOINTS
	JRST	RESTRX		;RESTORE CONTEXT AND JUMP TO IT

XEC3L:	MOVE	R,T		;POSITION SECTION NUMBER
	PUSHJ	P,RWEMAP	;ARE WE MAPPED IN DESIRED SECTION?
	 JRST	$XBLKE		;NO, CAN'T DO THE $X
	HRRI	R,XEC4		;YES, DDT ADDRESS IN TARGET SECTION
	JSP	TT,SECCHG	;PUT DDT IN THAT SECTION
	SKPNS0			;IF JUST LEFT NZS,
	SETZM	SYMVAL		;WE NEED TO CALL SYMCHK AGAIN
	XJRST	R		;GO DO THE XCT IN TARGET SECTION
				;NOTE THAT THIS HAS THE EFFECT OF
				;LEAVING DDT IN THE TARGET SECTION!
;STILL IFE FTFILE

XEC4:	PUSHJ	P,INSRTB	;INSTALL BREAKPOINTS
	JSP	T,RESTORE
	XCT	I.NST
XEC5:	REPEAT	SKPMAX,<AOS SKPCT> ;NOTE COUNT OF LOCS SKIPPED
XEC6:	JSR	SAVE		;SAVE CONTEXT
	 PUSHJ	P,REMOVB	;REMOVE BRKPTS
  IFN FTMON,<CHKOUT>		;UNLOCK BREAKPOINT BLOCK
	MOVEI	TT,SKPMAX
	SUB	TT,SKPCT	;COMPUTE AMOUNT OF PC INCREMENT
	SETZM	SKPCT		;DON'T CONFUSE OTHERS
	MOVEI	T,"<"		;INDICATE INSTRUCTION RETURNED
	PUSHJ	P,TOUT		;SINCE LINE-FEED ISN'T VERY VISIBLE
	JUMPE	TT,XEC8		;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	XEC8		;YES, JUST CLOSE OFF
	PUSHJ	P,TSPC		;TYPE A SPACE
	MOVEI	T,"0"(TT)	;GET ASCII CHAR COUNT
	PUSHJ	P,TOUT		;TYPE IT
XEC8:	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

;$XBLK - BUILD AN EXECUTE BLOCK IN A NON-DDT SECTION
;
;IF THE INSTRUCTION IS TO BE IN A DIFFERENT SECTION THAN DDT, WE HAVE TO
;PUT THE INSTRUCTION IN THAT SECTION AND JUMP TO IT.  WE THEN HAVE TO JUMP
;BACK, AND SOMEHOW TELL IF THE INSTRUCTION SKIPPED.  USING THE SPACE IN THE
;BREAKPOINT BLOCK, WE BUILD A SEQUENCE OF INSTRUCTIONS LIKE THIS:
;
;	C(I.NSTE)
;	<INSTR>			;T GETS THIS ADDRESS ON RETURN
;	XJRST	.+SKPMAX+1	;SKPMAX+1 OF THESE
;	...			;(MIGHT BE SEC. 0 SO CAN'T USE JRST @)
;	SECDDT,,<RETURN LOC>+0	;SKPMAX+1 RETURN ADDRESSES, CORRESPONDING
;	SECDDT,,<RETURN LOC>+1	; TO THE SKPMAX+1 XJRST'S
;	...
;	SECDDT,,<RETURN LOC>+SKPMAX
;
;<RETURN LOC> SHOULD BE THE ADDRESS OF THE FIRST "AOS SKPCT" AFTER THE
;USUAL "XCT I.NST".  THIS WILL CAUSE CONTROL TO RETURN TO DDT AT THE SAME
;POINT AS IF THE INSTRUCTION HAD BEEN EXECUTED BY THE USUAL XCT.  SKIPS ARE
;THEN COUNTED BY SKPCT IN THE USUAL WAY.
;NOTE IT IS THE RESPONSIBILITY OF THE CALLER TO FIX UP <INSTR> TO POINT
;INTO THE BREAKPOINT BLOCK (TO I.NSTE'S CONTENTS) IF NECESSARY.
;
;IF THE INSTRUCTION WAS FOLLOWED BY SOME KIND OF ERJMP, THE ERJMPX/ERCALX
;IS TRANSLATED (BY THE CALLER) INTO THE EQUIVALENT ERJMPX (E.G. ERCALR
;BECOMES ERJMPR) AND THAT INSTRUCTION IS PLACED AFTER THE INSTRUCTION TO
;EXECUTE.  THEN THE SEQUENCE LOOKS LIKE THIS:
;
;	C(I.NSTE)
;	<INSTR>			;T GETS THIS ADDRESS ON RETURN
;	ERJMPX	.+SKPMAX+1	;FIRST XJRST REPLACED BY ERJMPX
;	XJRST	.+SKPMAX+1	;SKPMAX OF THESE
;	...
;	XJRST	.+SKPMAX+1	;THE ERJMPX POINTS HERE
;	SECDDT,,<RETURN LOC>+0	;SKPMAX OF THESE, ONE FOR EACH
;	...			; "SKIP-STYLE" XJRST
;	SECDDT,,<RETURN LOC>+SKPMAX-1
;	SECDDT,,<ERJMP RETURN>	;THE ERJMPX'S XJRST POINTS HERE
;
;THE ERJMPX SEQUENCE IS ACTUALLY BUILT BY DOING THE NORMAL SEQUENCE FIRST,
;THEN REPLACING THINGS AS NECESSARY.
;
;IF THE INSTRUCTION IS A CONDITIONAL JUMP (E.G. AOJE) THEN THE INSTRUCTION
;IS FIXED UP TO POINT TO ANOTHER XJRST, LIKE THIS:
;
;	XJRST	.+1		;INCLUDED ONLY IF INSTR IS A CONDITIONAL JUMP,
;	SECDDT,,RH(INSTR)	; INSTR FIXED UP TO POINT TO THIS XJRST
;STILL IFE FTFILE

;$XBLK - BUILD AN EXECUTE BLOCK IN A NON-DDT SECTION
;CALL:
; T/	SECTION TO EXECUTE IN,,0 (ASSUMED DIFFERENT FROM DDT'S)
; W1/	ADDRESS TO RETURN TO NORMALLY
; W2/	-1 IF CALLED FROM INSTR$X
;	0 OR ERJMP RETURN ADDRESS IF CALLED FROM SINGLESTEP $X
;	PUSHJ	P,$XBLK
;RETURNS:  +1 ALWAYS
; T/	ADDRESS OF INSTRUCTION IN BLOCK

$XBLK:	SKIPN	R,BPBLK		;$4M SET?
$XBLKE:	JRST	[SMERS	<Inter-section reference and no $4M global breakpoint/execute block>
		JRST	ERR]	;NO, COMPLAIN
	HLL	R,T		;YES, FIND BP BLOCK IN GIVEN SECTION
	JUMPL	W2,[ADDI R,BPI$X	;IF INSTR$X, POINT TO RIGHT PLACE
		    JRST $XBLK0]	;AND SKIP THE "E" STUFF
	ADDI	R,BPB$X		;POINT TO $X PART OF IT
	MOVE	T,I.NSTE	;GET E OF INST (USUALLY)
	PUSHJ	P,DMEMER	;DROP IT IN
	HRRI	R,1(R)		;INCREMENT LOC
$XBLK0:	MOVE	T,I.NST		;GET INSTRUCTION
	PUSHJ	P,DMEMER	;DROP IT INTO BLOCK
	MOVEM	R,TEM		;HANG ONTO ADDRESS
	HRRI	R,1(R)		;STEP LOCATION
	PUSH	P,W1		;SAVE RETURN ADDRESS
	MOVEI	W1,SKPMAX+1	;WANT SKPMAX+1 OF THESE
	MOVX	T,XJRST		; TO COUNT SKIPS
$XBLK1:	HRRI	T,SKPMAX+1(R)	; AS "XJRST .+SKPMAX+1"
	PUSHJ	P,DMEMER	;DROP IT IN
	HRRI	R,1(R)		;NEXT ADDRESS
	SOJN	W1,$XBLK1	;LOOP BACK
	MOVEI	W1,SKPMAX+1	;NOW FILL IN SKPMAX+1 ADDRESSES
	POP	P,T		;GET FIRST RETURN ADDRESS
  IFN FTDEC20,<
	SKIPLE	W2		;WILL WE BE FILLING IN AN ERJMP LATER?
	SOS	T		;YES, ACCOUNT FOR EXTRA XJRST
  > ;END IFN FTDEC20
$XBLK2:	PUSHJ	P,DMEMER	;DROP IN ADDRESS
	HRRI	R,1(R)		;NEXT LOC
	HRRI	T,1(T)		;NEXT RETURN LOC
	SOJN	W1,$XBLK2	;DO ANOTHER ONE

;FALL INTO NEXT PAGE
;STILL IFE FTFILE

;FALL IN FROM ABOVE

;NOW CHECK TO SEE IF WE WANT TO FILL IN ERJMP STUFF

  IFN FTDEC20,<			;ERJMP EXISTS ONLY ON -20
	JUMPLE	W2,$XBLK3	;IS THERE AN ERJMP?
	MOVE	R,TEM		;GET INSTRUCTION'S ADDRESS
	HRRI	R,1(R)		; PLUS ONE
	MOVE	T,I.NERJ	;GET PROTO ERJMPX
	HRRI	T,SKPMAX+1(R)	;POINT IT PAST THE XJRSTS
	PUSHJ	P,DMEMER	;STOMP ON FIRST XJRST
	HRR	R,T		;POINT TO WHERE ERJMPX POINTS
	MOVX	T,XJRST		;WANT TO BUILD AN XJRST THERE
	HRRI	T,SKPMAX+1(R)	; POINTING PAST THE OTHER XJRST ADDRS
	PUSHJ	P,DMEMER	;STOMP ON AN ADDRESS
	HRR	R,T		;CHAIN TO OBJECT OF THE XJRST
	MOVE	T,W2		;GET ERJMP RETURN ADDRESS
	PUSHJ	P,DMEMER	;STUFF IT IN
	HRRI	R,1(R)		;POINT TO NEXT AVAILABLE LOCATION
  > ;END IFN FTDEC20

;NOW CHECK IF IT WAS A CONDITIONAL JUMP THAT NEEDS TO BE FIXED UP.

$XBLK3:	SKIPN	I.CJMP		;CONDITIONAL JUMP?
	JRST	$XBLK5		;NO, LEAVE IT ALONE
	MOVX	T,XJRST		;USUAL RETURN INSTRUCTION
	HRRI	T,1(R)		; TO .+1
	PUSHJ	P,DMEMER	;STUFF IT
	HRRI	R,1(R)		;WHERE TO PUT RETURN ADDR
	HLL	T,SECDDT	;RETURN INTO OUR SECTION
	HRR	T,I.NST		;WHEREVER IT WAS SUPPOSED TO BEFORE
	PUSHJ	P,DMEMER	;SET RETURN ADDR IN BLOCK
	HRRI	T,-1(R)		;BACK UP TO XJRST
	HLL	T,I.NST		;FIX UP REST OF INSTRUCTION
	MOVE	R,TEM		;GET ADDRESS OF INSTRUCTION
	PUSHJ	P,DMEMER	;STUFF NEW INSTRUCTION
$XBLK5:	MOVE	T,TEM		;GET ADDRESS OF INSTRUCTION
	POPJ	P,		;ALL SET UP


;MAKE SURE ENOUGH WORDS ARE ALLOCATED FOR BOTH KINDS OF $X

  IFL BPB$XL-<2*<SKPMAX+1>+5>,<
	PRINTX ? BPB$XL TOO SMALL, MUST BE AT LEAST 2*<SKPMAX+1>+5>
  IFL BPI$XL-<2*<SKPMAX+1>+1>,<
	PRINTX ? BPI$XL TOO SMALL, MUST BE AT LEAST 2*<SKPMAX+1>+1>
;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 ADJUST THE PC.  THE
;	OPERANDS TO THE INSTRUCTION WILL BE PRINTED OUT AS THEY
;	EXIST **AFTER** EXECUTION OF THE INSTRUCTION. <SKIP N>
;	OR <JUMP> WILL BE PRINTED IF THE INSTRUCTION SKIPPED OR
;	JUMPED.  THE ADDRESS OF THE NEXT INSTRUCTION, AS WELL AS
;	THE NEXT INSTRUCTION WILL THEN BE PRINTED (IF THE ADDRESS
;	IS A REFERENCE TO THE ACS THEN THE ADDRESS PRINTED WILL BE
;	JUST THE REGISTER, NOT THE ENTIRE GLOBAL ADDRESS).
;	$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
  > ;END IFE FTEXEC
;STILL IFE FTFILE

;DEFINE SOME MACROS FOR USE WITHIN $X CODE.

DEFINE	$XRET,<			;;RETURN TO USER CONTEXT BEFORE XCT
	SKIPL	I.NXIT		;;IF SAFE INSTRUCTION
	 JSR	SWAP		;;THEN JUST SWAP AC'S
	SKIPGE	I.NXIT		;;IF DANGEROUS INSTRUCTION
	 JSP	T,RESTOR	;;THEN RESTORE USER'S ENVIRONMENT
> ;END $XRET

DEFINE	$XSAVE,<		;;SAVE USER'S CONTEXT AFTER XCT
	SKIPGE	I.NXIT		;;IF DANGEROUS INSTRUCTION
	 JSR	SAVE		;;THEN SAVE USER'S NEW ENVIRONMENT
	SKIPL	I.NXIT		;;IF SAFE INSTRUCTION
	 JSR	SWAP		;;SWAP BACK TO USER CONTEXT
> ;END $XSAVE

  IFN FTDEC20,<
DEFINE	ERXCT	(ERINST),<	;;DO AN XCT FOLLOWED BY SUPPLIED ERJMPX.
  IFN FTEXEC,<
	PUSHJ	P,RSTAC>	;;ENSURE RIGHT CONTEXT ACS
	$XRET			;;RETURN TO USER CONTEXT
	XCT	I.NST		;;DO THE INSTRUCTION
	ERINST			;;FOLLOWED BY ERJMPX
> ;END ERXCT
  > ;END IFN FTDEC20
;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
	MOVE	T,[SCH,,SCHR]	;SAVE CURRENT TYPEOUT MODES
	BLT	T,ODFR		;TO BE RESTORED AFTER RETURN FROM USER
	SETZM	I.PXC		;CLEAR IN CASE STICKY
	PUSHJ	P,$X00		;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,$X00		;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

$X00:	PUSHJ	P,RSTAC		;RESTORE ACS
	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,FETCHI	;FETCH CURRENT INSTRUCTION
	 POPJ	P,		;ERROR
$X03:	MOVEM	T,I.NST		;STORE CURRENT INSTRUCTION
	SKPKS			;IF 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
	CAIE	W2,716		;IF BLTBU
	CAIN	W2,717		;OR BLTUB
	JRST	$X05		;TREAT NORMALLY
	CAIL	W2,710		;SIMILARLY, IF A
	CAILE	W2,727		;UNIBUS-FONDLING INSTRUCTION
	CAIA			;(ISN'T - TREAT NORMALLY)
	JRST	$X08		;LEAVE INSTRUCTION ALONE
$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
	TDNN	T,[-2,,-20]	;IF NOT AN AC
	SKIPE	EAGLOB		;OR IF GLOBAL REFERENCE
	SKIPA	T,[Z @I.NSTE]	;SETUP INTERCEPT ADDRESS POINTER
	ANDI	T,17		;ELSE KEEP TRACK OF AC REFERENCE
	DPB	T,[POINT 23,I.NST,35] ;STORE INTERCEPT ADR IN CURRENT INST
	MOVEM	S,I.NSTS	;KEEP TRACK OF SECTION-NESS OF EA
	CAIA			;JUST SKIP IF NORMAL
$X08:	SETOM	I.KRCK		;FLAG KS-10 SPECIAL (NO TYPEOUT)

;CONTINUED ON NEXT PAGE
;STILL IFE FTFILE

;CONTINUED FROM PREVIOUS PAGE

	SETZM	I.NXIT		;ASSUME SAFE INSTRUCTION
	TXNN	F,Q2F		;DID USER TYPE $$<N>X?
	JRST	$X10		;NO, CONTINUE NORMALLY
	MOVE	W1,WRD2O	;YES, LOAD THE VALUE OF <N>
	CAIN	W1,1		;IS IT 1?
	JRST	$X13		;YES, USER WANTS A QUICK $$X - TRUST HIM
	JUMPN	W1,ERR		;NO, COMPLAIN AT USER
$X10:	LDB	W1,[POINT 9,I.NST,8] ;GET OPCODE
	CAIL	W1,$XW$L	;KNOWN TO BE
	CAILE	W1,$XW$U	;A DANGEROUS INSTRUCTION?
	JRST	[SETZM	SYMVAL	;YES, MAKE SURE WE NOTE THAT FOR SYCHK
		 JRST	$X12]	;GO FLAG IT
	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,$XMTBL(W1)	;"MEMORY MUNGE" BIT SET?
	SETZM	SYMVAL		;YES, RECHECK SYMTABS AFTER EXECUTE
	TDNE	TT,$XDTBL(W1)	;"DANGEROUS" BIT SET?
$X12:	SETOM	I.NXIT		;FLAG DANGEROUS INSTRUCTION
$X13:	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)
	SETZM	I.PCREF		;FLAG NOT SPECIAL PC-REF CASE (YET)
	HLLZ	T,I.NPC		;IF THE INSTRUCTION IS FROM SECTION ZERO
	ORCM	T,I.NXIT	; AND IT'S DANGEROUS
	JUMPN	T,$X15		;  (SKIP IF NOT)
	SKPS0			; AND IF WE'RE NOT IN ZERO
	SETOM	I.PCREF		; THEN IT MUST BE EXECUTED IN ZERO
$X15:	HLLZ	S,I.NSTS	;IF EFFECTIVE ADDRESS
	JUMPE	S,$X16		;IS NOT IN SECTION 0,
	SKPS0			;BUT WE ARE,
	JRST	$X16		;(NO)
	LDB	T,[POINT 23,I.NST,35] ;YES, SEE WHAT WE STORED FOR OUR EA
	CAILE	T,17		;IF NOT A LOCAL AC REF,
	SETOM	I.PCREF		;THEN MUST CHANGE SECTIONS TO EXECUTE IT
$X16:	SETZM	I.CJMP		;NOT A CONDITIONAL JUMP (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
				;W1 SETUP FOR INSTRUCTION HANDLERS
  IFN FTMON,<CHKIN>		;LOCK BREAKPOINT BLOCK
	JRST	(TT)		;DISPATCH TO INSTRUCTION HANDLER
;STILL IFE FTFILE

;ADD STACK/ARITH TRAP INSTRUCTIONS; REORGANIZE NEXT FEW PAGES.
;SPLIT DANGEROUS OPCODES INTO TWO TABLES

;$XDTBL - TABLE OF DANGEROUS OPCODES - I.E., INSTRUCTIONS WHICH
;MAY CAUSE SOME ASPECT OF THE PROCESS ENVIRONMENT TO CHANGE.
;INCLUDES ALL INSTRUCTIONS WHICH:
;  MAY USE/SET TERMINAL AND OTHER CHARACTERISTICS THAT DDT CHANGES, OR
;  CAN CAUSE STACK OR ARITHMETIC TRAPS (AND THEREFORE COULD DISPATCH
;    TO LOCATIONS DDT DOESN'T KNOW ABOUT).
;THE $X CODE RESTORES THE COMPLETE USER ENVIRONMENT SHORT OF INSERTING
;BREAKPOINTS BEFORE EXECUTING A DANGEROUS INSTRUCTION.

;$XMTBL - TABLE OF MEMORY MUNGING OPCODES - INSTRUCTIONS WHICH
;  CAN MODIFY MEMORY (MAY MUNGE SYMBOL TABLE POINTERS ETC.)
;THE $X CODE FORCES REVALIDATION OF SYMBOL TABLES AFTER EXECUTING
;A MEMORY MUNGING INSTRUCTION.

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

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

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

  IF2	<			;SET THE BITS ON PASS 2
DEFINE	$$XW (TBL),<		;;DEFINE THE DEFINING MACRO
  DEFINE $$X'TBL (OP),<		;;THE SET-THE-BIT MACRO
    IRP <OP>,<			;;FOR EACH OPCODE GIVEN
      $$XW.1==<<<<OP>_-^D27>-$XW$L>/^D36>	;;"INDEX" INTO BIT TABLE
      $$XW.2==<<<<OP>_-^D27>-$XW$L> - $$XW.1*^D36>;;BIT WITHIN INDEX WORD
      $$XW1 (TBL,\$$XW.1,\$$XW.2)		;;SET THE BIT
    > ;;END IRP
  > ;;END OF $$X'TBL
> ;END OF $$XW

	$$XW (D)		;DEFINE $$XD
	$$XW (M)		;DEFINE $$XM

DEFINE $$XW1 (TBL,NDX,BIT),<$X'TBL'.'NDX==$X'TBL'.'NDX ! 1B^O'BIT> ;SET THE BIT
;STILL IFE FTFILE AND IF2

;NOW FLAG ALL OPCODES WHICH WE CONSIDER "DANGEROUS"

$$XD <	UJEN,		GFAD,	GFSB>
$$XD <	JSYS,	ADJSP,	GFMP,	GFDV>
$$XD <	DFAD,	DFSB,	DFMP,	DFDV>
$$XD <	DADD,	DSUB,	DMUL,	DDIV>
$$XD <		DMOVN,	FIX,	EXTEND>	;DMOVE
$$XD <		DMOVNM,	FIXR	>	;DMOVEM			FLTR
$$XD <	UFA,		FSC,	ADJBP>	;	DFN
					;ILDB,	LDB,	IDPB,	DPB
$$XD <	FAD,	FADL,	FADM,	FADB>

$$XD <	FADR,	FADRI,	FADRM,	FADRB>
$$XD <	FSB,	FSBL,	FSBM,	FSBB>
$$XD <	FSBR,	FSBRI,	FSBRM,	FSBRB>
$$XD <	FMP,	FMPL,	FMPM,	FMPB>
$$XD <	FMPR,	FMPRI,	FMPRM,	FMPRB>
$$XD <	FDV,	FDVL,	FDVM,	FDVB>
$$XD <	FDVR,	FDVRI,	FDVRM,	FDVRB>
					;MOVE,	MOVEI,	MOVEM,	MOVES
					;MOVS,	MOVSI,	MOVSM,	MOVSS

$$XD <	MOVN,		MOVNM,	MOVNS>	;	MOVNI
$$XD <	MOVM,		MOVMM,	MOVMS>	;	MOVMI
$$XD <	IMUL,	IMULI,	IMULM,	IMULB>
$$XD <	MUL,	MULI,	MULM,	MULB>
$$XD <	IDIV,	IDIVI,	IDIVM,	IDIVB>
$$XD <	DIV,	DIVI,	DIVM,	DIVB>
$$XD <	ASH			>	;	ROT,	LSH,	JFFO
$$XD <	ASHC			>	;	ROTC,	LSHC,	?
					;EXCH,	BLT,	AOBJP,	AOBJN

					;JRST,	JFCL,	XCT,	MAP
$$XD <	PUSHJ,	PUSH,	POP,	POPJ>
					;JSR,	JSP,	JSA,	JRA
$$XD <	ADD,	ADDI,	ADDM,	ADDB>
$$XD <	SUB,	SUBI,	SUBM,	SUBB>
					;CAIX
					;CAMX

					;JUMPX
					;SKIPX
$$XD <	AOJ,	AOJL,	AOJE,	AOJLE>
$$XD <	AOJA,	AOJGE,	AOJN,	AOJG>
$$XD <	AOS,	AOSL,	AOSE,	AOSLE>
$$XD <	AOSA,	AOSGE,	AOSN,	AOSG>
$$XD <	SOJ,	SOJL,	SOJE,	SOJLE>

$$XD <	SOJA,	SOJGE,	SOJN,	SOJG>
$$XD <	SOS,	SOSL,	SOSE,	SOSLE>
$$XD <	SOSA,	SOSGE,	SOSN,	SOSG>

					;BOOLEAN INSTRUCTIONS
					;HALFWORD INSTRUCTIONS
					;TXYZ INSTRUCTIONS
;STILL IFE FTFILE AND IF2

;NOW FLAG ALL OPCODES WHICH MODIFY MEMORY BUT ARE NOT "DANGEROUS"

$$XM <	DMOVEM			>
$$XM <			IDPB,	DPB>	;ILDB,	LDB

$$XM <			MOVEM	>	;MOVE,	MOVEI,		MOVES
$$XM <			MOVSM,	MOVSS>	;MOVS,	MOVSI

$$XM <	EXCH,	BLT		>	;		AOBJP,	AOBJN

$$XM <	JRST			>

$$XM <			SETZM,	SETZB>	;SETZ,	SETZI
$$XM <			ANDM,	ANDB>	;AND,	ANDI
$$XM <			ANDCAM,	ANDCAB>	;ANDCA,	ANDCAI
					;SETM,	XMOVEI,	SETMM,	SETMB
$$XM <			ANDCMM,	ANDCMB>	;ANDCM,	ANDCMI
$$XM <			SETAM,	SETAB>	;SETA,	SETAI

$$XM <			XORM,	XORB>	;XOR,	XORI
$$XM <			IORM,	IORB>	;IOR,	IORI
$$XM <			ANDCBM,	ANDCBB>	;ANDCB,	ANDCBI
$$XM <			EQVM,	EQVB>	;EQV,	EQVI
$$XM <			SETCAM,	SETCAB>	;SETCA,	SETCAI
$$XM <			ORCAM,	ORCAB>	;ORCA,	ORCAI
$$XM <			SETCMM,	SETCMB>	;SETCM,	SETCMI
$$XM <			ORCMM,	ORCMB>	;ORCM,	ORCMI
$$XM <			ORCBM,	ORCBB>	;ORCB,	ORCBI

$$XM <			SETOM,	SETOB>	;SETO,	SETOI
$$XM <			HLLM,	HLLS>	;HLL,	XHLLI
$$XM <			HRLM,	HRLS>	;HRL,	HRLI
$$XM <			HLLZM,	HLLZS>	;HLLZ,	HLLZI
$$XM <			HRLZM,	HRLZS>	;HRLZ,	HRLZI
$$XM <			HLLOM,	HLLOS>	;HLLO,	HLLOI
$$XM <			HRLOM,	HRLOS>	;HRLO,	HRLOI
$$XM <			HLLEM,	HLLES>	;HLLE,	HLLEI
$$XM <			HRLEM,	HRLES>	;HRLE,	HRLEI

$$XM <			HRRM,	HRRS>	;HRR,	HRRI
$$XM <			HLRM,	HLRS>	;HLR,	HLRI
$$XM <			HRRZM,	HRRZS>	;HRRZ,	HRRZI
$$XM <			HLRZM,	HLRZS>	;HLRZ,	HLRZI
$$XM <			HRROM,	HRROS>	;HRRO,	HRROI
$$XM <			HLROM,	HLROS>	;HLRO,	HLROI
$$XM <			HRREM,	HRRES>	;HRRE,	HRREI
$$XM <			HLREM,	HLRES>	;HLRE,	HLREI

					;TXYZ INSTRUCTIONS
;STILL IFE FTFILE AND IF2

	PURGE	$$XW,$$XM,$$XD,$$XW1,$$XW.1,$$XW.2
  > ;END IF2

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

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

$XDTBL:	$$XTBL(D)		;DANGEROUS OPCODE BIT TABLE
$XMTBL:	$$XTBL(M)		;MEMORY MUNGING OPCODE BIT TABLE

  IF2	<PURGE	$$XTBL,$$XWRD,$$XW..>	;ELIMINATE 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
	HLL	SETEA		;     500  HLL
	XHLLI	SETIX		;     501  XHLLI
	HLRES	CHEKIS		; 502-577  OTHER HALFWORD
	TSON	TESTS		; 600-677  TEST CLASS
	715000,,IOTS		; 700-715  I/O INSTRUCTIONS
	BLTUB	KSBBLT		; 716-717  KS BLT BYTE
	777000,,IOTS		; 720-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
	PMOVEM	PREF		; 052-053  PMOVE,PMOVEM
	054000,,MONUAI		;     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
	101000,,SETI		; 100-101  UNDEFINED
	GFSB	DMOV		; 102-103  GFAD,GFSB
	JSYS	IJSYS		;     104  JSYS
	ADJSP	SETI		;     105  ADJSP
	GFDV	DMOV		; 106-107  GFMP,GFDV
	DFDV	DFLOT		; 110-113  DFAD,DFSB,DFMP,DFDV
	DSUB	DMOV		; 114-115  DADD,DSUB
	DDIV	SETQFA		; 116-117  DMUL,DDIV
	DMOVN	DMOV		; 120-121  DMOVE,DMOVN
	FIX	FXAFLE		;     122  FIX
	EXTEND	IEXTEND		;     123  EXTEND
	DMOVNM	DMOV		; 124-125  DMOVEM,DMOVNM
	FIXR	FXAFLE		;     126  FIXR
	FLTR	FLAFXE		;     127  FLTR
	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	IBLT		;     251  BLT
	AOBJN	IAOBJ		; 252-253  AOBJP,AOBJN
	JRST	IJRST		;     254  JRST
	JFCL	IJFCL		;     255  JFCL
	XCT	IIXCT		;     256  XCT
	MAP	SETI		;     257  MAP
	PUSHJ	IPUSHJ		;     260  PUSHJ
	PUSH	IPUSH		;     261  PUSH
	POP	IPOP		;     262  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 DOITX3+2] ;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
	HRRI	T,I.NJR0	;NOW INTERCEPT DOITX'S XCT
	MOVEM	T,I.NST		;SET TO EXECUTE I.NJR? BLOCK
	JRST	DOITX		;GO DO IT
;STILL IFE FTFILE

;USER UUO HANDLER

USRUUO:	MOVE	S,PCWRD		;PC OF USER INSTRUCTION
	TLNE	S,-1		;IN SECTION 0?
	JRST	XUSRUU		;NO, HANDLED DIFFERENTLY
	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

;HERE TO HANDLE AN LUUO IN A NON-ZERO SECTION

XUSRUU:	PUSHJ	P,RDLUUB	;READ ADDRESS OF LUUO BLOCK
	SKIPN	R,T		;IS THERE ONE?
	JRST	SETEA		;NO, JUST TRUST TO LUCK
	MOVE	T,PCFLG		;BUILD LUUO INFO
	HRR	T,F		;PC FLAGS,,OPCODE
	DPB	W1,[POINT 4,T,30]  ;AND AC
	EXCH	F,FLAGS		;SWITCH TO NORMAL DDT FLAGS
	PUSHJ	P,DEPMEM	;FILL IN FIRST WORD IN LUUO BLOCK
	 POPJ	P,		;WRITE ERROR?
	AOS	R		;POINT TO SECOND WORD
	MOVE	T,I.NPC		;SECOND WORD GETS LUUO'S PC
	HRRI	T,1(T)		; PLUS ONE (I.E. LUUO RETURN ADDR)
	PUSHJ	P,DEPMEM	;FILL THAT IN
	 POPJ	P,		;CAN'T?
	AOS	R		;POINT TO THIRD WORD
	MOVE	T,I.NSTE	;3RD WORD GETS E OF LUUO
	PUSHJ	P,DEPMEM	;STUFF IT
	 POPJ	P,		;??
	AOS	R		;POINT TO FOURTH WORD
	MOVEM	R,I.NSTE	;PRETEND THE LUUO WAS REALLY
	MOVX	T,XJRST		; AN XJRST THROUGH THE FOURTH WORD
	MOVEM	T,I.NST		;SET PROTO INSTRUCTION
	EXCH	F,FLAGS		;BACK TO $X FLAGS
	JRST	IJ$15		;TREAT LIKE XJRST NOW

  IFN FTDEC10,<
RDLUUB:	MOVX	T,<.UTRED,,TT1>	;UUO ARG <READ,,BLOCK>
	MOVEI	TT1,2		;TWO WORDS FOLLOWING
	MOVX	TT2,.UTLUU	;TRAP TYPE IS LUUO BLOCK
	UTRP.	T,		;READ THE BLOCK ADDRESS
	  TDZA	T,T		;NONE AFTER ALL?
	MOVE	T,TT3		;RETURN IT IN CORRECT AC
	POPJ	P,		;GOT IT
  > ;END IFN FTDEC10

  IFN FTDEC20,<
RDLUUB:	PUSHJ	P,SAVT4		;PRESERVE JSYS ACS
	MOVX	T1,.FHSLF	;THIS PROCESS'
	MOVX	T2,.SWRLT	;LUUO BLOCK
	SWTRP%			;READ ADDRESS
	MOVE	T,T3		;RETURN IN A USEFUL AC
	POPJ	P,		;ALL DONE
  > ;END IFN FTDEC20
;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, (XJRST)
	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	IJ$US1		;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?
	MOVE	R,I.NSTE	;NEW USER PC
	SKPS0			;IN NON-ZERO SECTION?
	JRST	IJ$02X		;YES, TRANSLATE TO XJRSTF
	HRRI	T,NOSKIP	;DDT TRANSFER ADDRESS
	MOVEM	T,I.NJR0	;SET IN INTERNAL INTERCEPT BLOCK
	MOVE	T,[Z @I.NJR0]	;INDIRECT ADDR FOR JRSTF @
	JRST	IJ$RS		;COMMON CODE

IJ$02X:	MOVEM	T,I.NJR2	;STORE FLAGS IN BLOCK
	MOVEI	W1,5		;GET XJRSTF AC VALUE
	DPB	W1,[POINT 4,I.NST,12]	;DIDDLE INSTRUCTION
	JRST	IJ$05A		;JOIN XJRSTF 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
IJ$05A:	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

IJ$06:	SETOM	I.NXIT		;XJEN IS DANGEROUS
	JRST	IJ$05		;OTHERWISE JUST 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:	$XSAVE			;BACK TO DDT CONTEXT
	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
	HRRI	R,1(R)		;NEXT WORD IN FOUR-WORD BLOCK
	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,

IJ$10:	SETOM	I.NXIT		;JRST 10, IS DANGEROUS
	JRST	IJ$00		;OTHERWISE TREAT LIKE STRAIGHT JRST

;JRST 11,

	SYN	IJ$00,IJ$11	;JRST 11, - TREAT LIKE JRST 00,

;JRST 12, - JEN

IJ$12:	SETOM	I.NXIT		;JEN IS DANGEROUS
	JRST	IJ$02		;OTHERWISE TREAT LIKE JRSTF

;JRST 13,
;JRST 14, - XSFM

	SYN	IJ$00,IJ$13	;JRST 13, - TREAT LIKE JRST 00,
;	SYN	JUSTE,IJ$14	;JRST 14, - XSFM - TREAT LIKE SETOM
;STILL IFE FTFILE

;JRST 15, - XJRST

IJ$15:	TLO	F,EA		;PRINT EA AND CONTENTS
	MOVE	R,I.NSTE	;EFFECTIVE ADDRESS OF NEW PC
	PUSHJ	P,FETCH		;GET NEW PC
	 POPJ	P,		;CAN'T
	MOVE	R,T		;PUT WHERE IJ$RS WANTS IT
	XMOVEI	T,NOSKIP	;DDT INTERCEPT ADDRESS
	MOVEM	T,I.NJR0	;SET UP INTERNAL INTERCEPT LOCATION
	MOVEI	T,I.NJR0	;NEW "E" FOR INSTRUCTION
	JRST	IJ$RS		;COMMON CODE


;JRST 16, ;JRST 17,

	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
	SETZM	I.PCREF		;DON'T NEED TO CHANGE SECTIONS FOR THIS
	JRST	DOIT		;AND GO DOIT

  IFN FTEXEC,<
IJ$US:	SKPUSR			;EXEC MODE?
	TXNN	T,PC$USR	;GOING INTO USER MODE?
	JRST	(TT)		;NO
IJ$US1:	EXCH	F,FLAGS		;RESTORE NORMAL DDT FLAGS
	TXNE	F,CCF		;IF NOT $$X
	SKIPE	I.PXC		;OR NOT $P
	JRST	PROCD2		;CAN'T TRACE BUT DON'T CARE, JUST DO IT
	SMERS	<Can't $$X through user mode>	;LEAVE SOMETHING FOR $?
	JRST	ERR		;PUNT
  > ;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

IPUSHJ:	PUSHJ	P,IIXPCF	;FETCH PC+1 AND (MAYBE) FLAGS
	MOVEM	T,I.NSTP	;STORE AWAY TO BE STACKED
	MOVX	T,PC$BIS	;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
	JRST	IPUSHC		;REST COMMON WITH PUSH

;INTERPRET PUSH

IPUSH:	TLO	F,FAC!EA	;WANT AC AND MEMORY TYPED
	MOVE	R,I.NSTE	;ADR OF MEMORY OPERAND
	EXCH	F,FLAGS		;GET DDT FLAGS
	PUSHJ	P,FETCH		;GET MEMORY WORD
	 POPJ	P,		;CAN'T
	MOVEM	T,I.NSTP	;SAVE IT FOR PUSH
	EXCH	F,FLAGS		;GET $X FLAGS
IPUSHC:	MOVE	T,[ADJSP 0,1]	;SET UP STACK DIDDLE
	JRST	IPOPJ2		;JOIN COMMON CODE
;STILL IFE FTFILE

;INTERPRET POP

IPOP:	TLO	F,FAC!EA	;WANT AC AND MEMORY TYPED
	EXCH	F,FLAGS		;GET DDT FLAGS
	PUSHJ	P,ADRSTK	;GET STACK ADR IN R
	PUSHJ	P,FETCH		;GET POPPED WORD
	 POPJ	P,		;CAN'T
	MOVE	R,I.NSTE	;GET DESTINATION OF POP
	PUSHJ	P,DEPMEM	;STUFF IT
	 POPJ	P,		;CAN'T
	JRST	IPOPC		;COMMON WITH POPJ

;INTERPRET POPJ

IPOPJ:	EXCH	F,FLAGS		;POPJ, RESTORE NORMAL DDT FLAGS
	PUSHJ	P,ADRSTK	;GET STACK ADR IN R
	PUSHJ	P,FETCH		;FETCH PCWORD IT POINTS TO
	 POPJ	P,		;ERROR
	TLNN	S,-1		;INSTRUCTION FROM NON-ZERO SECTION?
	TLZA	T,-1		;NO, THEN PC ALWAYS BACK TO SECTION 0
	TLZ	T,770000	;YES, THEN GLOBAL 30 BIT PC
	MOVEM	T,I.NJMP	;STORE AS CURRENT PC
IPOPC:	MOVE	T,[ADJSP 0,-1]	;SET UP STACK DIDDLE
	EXCH	F,FLAGS		;GET $X FLAGS BACK
IPOPJ2:	MOVEM	T,I.NST		;DO THIS INSTRUCTION
	DPB	W1,[POINT 4,I.NST,12]  ;ON THIS AC
JUSTAC:	TLO	F,FAC		;REMEMBER TO PRINT AC
	JRST	DOIT		;GO OFF AND EXECUTE THE INSTRUCTION

;COMMON CODE FOR PUSHJ, POPJ

ADRSTK:	MOVE	S,I.NPC		;PC OF INSTRUCTION
	SKIPL	R,AC0(W1)	;SKIP IF LOCAL STACK POINTER
	TLNN	S,-1		;OR GLOBAL POINTER IN NON-ZERO SECTION
	HLL	R,S		;RELOCATE POINTER TO CURRENT SECTION
	POPJ	P,
;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,PC$BIS	;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
	MOVX	T,PC$BIS	;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,PC$BIS	;CLEAR BIS, WAS IT SET?
	JRST [	MOVEM	T,PCFLG	;YES, CLEAR IT
		JRST	IXBP]	;SKIP INCREMENTING THE PTR
	MOVE	T,[IBP	@I.NSTE] ;GET NEW INSTRUCTION
	MOVEM	T,I.NJR0	;XCT IT FROM HERE
	JSR	SWAP		;GET USER CONTEXT
	XCT	I.NJR0		;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
	LDB	S,[POINT 6,T,5]	;GET P FIELD
	CAIG	S,44		;ONE-WORD GLOBAL?
	 JRST	IXBP0		;NO, NORMAL
	ANDX	T,VMADR		;YES, GET 30-BIT ADDR
	JRST	IXBP5		;AND GO ON
;STILL IFE FTFILE

IXBP0:	HLLZ	S,I.NSTS	;GET SECTION OF B.P. REFERENCE
	CAME	S,SECDDT	; IF OUTSIDE DDT'S SECTION
	TDNE	R,[-2,,-20]	; AND BYTE POINTER IS IN AN AC
	CAIA			;NO, IT'S SAFE
	SETOM	I.PCREF		;YES, MUST CHANGE SECTIONS TO GET IT RIGHT
	JUMPE	S,IXBP2		;JUMP IF IN SECTION 0
	TLNN	T,(1B12)	;NON-ZERO SECTION - IS THIS EXTENDED?
	JRST	IXBP2		;NO, LUCKY - DO IT AS IF IN SECTION 0
	HRRI	R,1(R)		;POINT TO SECTION ADDR.
	PUSHJ	P,FETCH		;GET IT
	 POPJ	P,		;FAILED
	MOVE	S,I.NSTS	;RESTORE S
	PUSHJ	P,CEFFEX	;GET EA OF ITS TARGET BYTE
	 POPJ	P,		;FAILED
	JRST	IXBP5		;CONTINUE
IXBP2:	PUSHJ	P,CEFFIX	;CALCULATE BYTE POINTER EFFECTIVE ADDRESS
	 POPJ	P,		;MEMORY READ ERROR
IXBP5:	MOVEM	T,I.NEA2	;REMEMBER IT FOR LATER TYPEOUT
	SKIPN	I.PCREF		;IF MUST CHANGE SECTIONS
	JRST	IXBP6		;(NO, SKIP THIS)
	MOVE	R,I.NPC		;YES, GET INSTRUCTION
	PUSHJ	P,FETCHI	;UNCHANGED BY OUR FIXUPS
	 POPJ	P,		;CAN'T?!?
	TXO	T,1B8		;DON'T INCREMENT TWICE
	MOVEM	T,I.NST		;RESTORE FOR PROPER EA HANDLING
IXBP6:	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
	SETOM	I.CJMP		;FLAG CONDITIONAL JUMP
	SETZM	I.PCREF		;WE CAN SIMULATE IT
	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
;STILL IFE FTFILE

;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, XHLLI

SETIX:	TLO	F,FAC+IMM!XIMM	;EXTENDED IMMEDIATE INSTRUCTION
	HLLZ	T,I.NPC		;GET PC SECTION
	JUMPN	T,DOIT		;IS IT SECTION 0?
	SKPS0			;YES, ARE WE IN NON-ZERO?
	SETOM	I.PCREF		;YES, MUST EXECUTE IN ZERO
	JRST	DOIT		;GO PRINT
;STILL IFE FTFILE

;KS-10 BYTE BLT INSTRUCTIONS (BLTBU, BLTUB)

KSBBLT:	SKPKS			;ON A KS?
	JRST	IOTS		;NO, TREAT LIKE ANY OTHER IO INSTRUCTION
	SETOM	I.KRCK		;YES, SET THE SPECIAL FLAG
	PUSHJ	P,GETAID	;FETCH APRID
KSBBL1:	TXNE	T,1B3		;ARE BLTBU/BLTUB DEFINED?
	JRST	SETI		;YES, TREAT LIKE BLT
	JRST	IOTS		;NO, NORMAL IO INSTRUCTIONS

PREF:	SKPKLS			;ONLY DEFINED ON A KL
	POPJ	P,		;ILLEGAL OTHERWISE
	MOVE	T,PCFLG		;GET PC FLAGS
  IFN FTEXEC,<
	SKPEXC>			;IF EXEC MODE
	TXNE	T,PC$UIO	;OR USER-I/O
	JRST	PREF1		;OK TO PROCEED
	POPJ	P,		;ILLEGAL FOR NON-PRIV'ED USER
PREF1:	PUSHJ	P,GETAID	;FETCH APR OPTIONS
	TXNN	T,1B4		;TEST MAGIC BIT FOR PMOVE/PMOVEM
	POPJ	P,		;ILLEGAL IF UNDEFINED
	JRST	SETEA		;ELSE ACT LIKE MOVE/MOVEM

GETAID:	SKPKLS			;ONLY VALID FOR KL/KS
	JRST	GETAI0		;NO, RETURN ZERO
	MOVE	T,PCFLG		;FETCH THE USER'S FLAGS
  IFN FTEXEC,<
	SKPEXC>			;IF IN EXEC MODE
	TXNE	T,PC$UIO	;OR USER-IO
	JRST [	APRID	T	;THEN WE CAN DO STRAIGHT APRID
		POPJ	P,]	;RETURN IT
  IFN FTDEC10,<			;ASK MONITOR FOR APRID
	MOVX	T,%CCCSB	;CPU STATUS BLOCK POINTER
	GETTAB	T,		;FIND IT
	 JRST	GETAI0		;CAN'T, RETURN ZERO
	MOVSI	T,%CVSAI(T)	;INDEX INTO VARIABLES AREA
	HRRI	T,.GTC0V	;USE CPU0'S AREA
	GETTAB	T,		;ASK FOR THE APRID
  > ;END IFN FTDEC10
GETAI0:	SETZ	T,		;NO APRID AVAILABLE
	POPJ	P,		;RETURN OUR ANSWER

;I/O INSTRUCTIONS

IOTS:	AOSN	I.KRCK		;SPECIAL KS-10 KROCK FLAG SET?
	JRST	JUSTAC		;YES, JUST PRINT THE AC
	ANDI	W1,7		;ONLY 3 BITS OF I/O OPCODE
	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
;STILL IFE FTFILE

;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

;PC-SECTION REFERENCE INSTRUCTIONS

IBLT:	MOVE	R,I.NPC		;GET THE ORIGINAL INSTRUCTION
	PUSHJ	P,FETCHI	;UNDAMAGED BY DDT
	 POPJ	P,		;SOMETHING WENT WRONG
	MOVEM	T,I.NST		;ERASE ANY INSTRUCTION "FIX UP"
IEXTEND:HLLZ	T,I.NPC		;GET PC SECTION
	CAME	T,SECDDT	;SAME AS US?
	SETOM	I.PCREF		;NO, SPECIAL
	JRST	SETI		;GO SET FLAGS

IJSYS:	HLLZ	T,I.NPC		;GET PC SECTION
	CAME	T,SECDDT	;SAME AS US?
	SETOM	I.PCREF		;NO, SET FLAG
	JRST	DOIT		;AND GO EXECUTE

;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
	SETZM	SKPCT		;NOTE NUMBER OF SKIPS

  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,FETCHI	;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
	CAIL	T,<<ERJMPR>_<^L<@>-^D36>> ;IN RANGE OF ERJMPX/ERCALX
	CAILE	T,<<ERCAL>_<^L<@>-^D36>>  ;  INSTRUCTIONS?
	JRST	DOITX		;NO - TREAT NORMALLY
	XMOVEI	W2,DOITC3	;GET ERCAL RETURN ADDRESS
	TRZN	T,1		;ERCALX OR ERJMPX?
	XMOVEI	W2,DOITJ3	;ERJMPX, DIFFERENT RETURN
	SKIPE	I.PCREF		;EXECUTING OUT OF SECTION?
	JRST	DOIT1		;YES, DEAL WITH IT
	MOVEM	W2,I.ECJA	;NO, SAVE ERJMPX RETURN ADDRESS
	ANDI	T,17		;GET THE AC FIELD ONLY
	LSH	T,-1		;MAKE AN INDEX INTO ERTAB
	MOVE	S,T		;SAVE IT SOMEWHERE SAFE
	MOVE	R,I.NPC		;GET ORIGINAL INSTRUCTION
	PUSHJ	P,FETCHI	;WITHOUT DDT'S MUNGING ON IT
	 SETZ	T,		;CAN'T TELL?
	CAMN	T,[ERSTR%]	;IS IT A WIERD ONE?
	JRST	@ERSTAB(S)	;YES, HANDLE SPECIALLY
	JRST	@ERTAB(S)	;NO, NORMAL CASE

DOIT1:	LSH	T,<^D36-^L<@>>	;SHIFT BACK TO NORMAL OPCODE
	MOVEM	T,I.NERJ	;SAVE PROTO INSTRUCTION
	MOVE	R,I.NPC		;GET INSTRUCTION
	PUSHJ	P,FETCHI	; AS IT WAS BEFORE DDT MUNGED IT
	 SETZ	T,		;CAN'T??
	XMOVEI	W1,DOITJ1	;NORMAL ERJMP-NOT-TAKEN RETURN
	CAMN	T,[ERSTR%]	;FUNNY JSYS?
	XMOVEI	W1,DOITX3+1	;YES, TREAT LIKE NORMAL SKIP RETURN
	JRST	DOXX1		;GO DO OUT-OF-SECTION STUFF
;STILL IFE FTFILE AND IFN FTDEC20

ERSTAB:	IFIW	ERR		;NOT DEFINED
	IFIW	ERR		;NOT DEFINED
	IFIW	ERR		;NOT DEFINED
	IFIW	ERR		;NOT DEFINED
	IFIW	ERR		;NOT DEFINED
	IFIW	ERSCJR		;ERCALR/ERJMPR
	IFIW	ERSCJS		;ERCALS/ERJMPS
	IFIW	ERSCJ		;ERCAL/ERJMP

ERTAB:	IFIW	ERR		;NOT DEFINED
	IFIW	ERR		;NOT DEFINED
	IFIW	ERR		;NOT DEFINED
	IFIW	ERR		;NOT DEFINED
	IFIW	ERR		;NOT DEFINED
	IFIW	DO.CJR		;ERCALR/ERJMPR
	IFIW	DO.CJS		;ERCALS/ERJMPS
	IFIW	DO.CJ		;ERCAL/ERJMP

;HERE IF ERSTR% FOLLOWED BY AN ERCALX/ERJMPX IN DDT'S SECTION

ERSCJR:	ERXCT	<ERJMPR	@I.ECJA>;EXECUTE AND RETURN ERROR CODE
	JRST	DOITX3+1	;TREAT LIKE NORMAL SKIP
	JRST	DOITX3+2	;TREAT LIKE NORMAL DOUBLE SKIP

ERSCJS:	ERXCT	<ERJMPS	@I.ECJA>;EXECUTE AND SUPPRESS ERROR CODE
	JRST	DOITX3+1	;LIKE NORMAL SKIP
	JRST	DOITX3+2	;LIKE NORMAL DOUBLE SKIP

ERSCJ:	ERXCT	<ERJMP	@I.ECJA>;DO THE EXECUTE
	JRST	DOITX3+1	;NORMAL SKIP
	JRST	DOITX3+2	;NORMAL DOUBLE SKIP

  IFL <SKPMAX-2>,<PRINTX ? SKPMAX TOO SMALL, MUST BE AT LEAST TWO>
;STILL IFE FTFILE AND IFN FTDEC20

;HERE IF INSTRUCTION FOLLOWED BY ERCALX/ERJMPX IN DDT'S SECTION

DO.CJR:	ERXCT	<ERJMPR	@I.ECJA>;EXECUTE AND RETURN ERROR CODE
	JRST	DOITJ1		;JOIN COMMON CODE

DO.CJS:	ERXCT	<ERJMPS	@I.ECJA>;EXECUTE AND SUPPRESS ERROR CODE
	JRST	DOITJ1		;JOIN COMMON CODE

DO.CJ:	ERXCT	<ERJMP	@I.ECJA>;DO THE EXECUTE
DOITJ1:	$XSAVE			;SAVE USER'S NEW CONTEXT
	MOVSI	T,FECJS		;FLAG ER/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	DOITX7		;COMMON CODE

DOITC3:	$XSAVE			;SAVE USER'S CONTEXT
	MOVSI	T,FECJ		;FLAG ERCAL JUMPED
	JRST	DOITJ5		;COMMON CODE

DOITJ3:	$XSAVE			;SAVE USER'S CONTEXT
	MOVSI	T,FEJJ		;FLAG ERJMP JUMPED
DOITJ5:	IORM	T,FLAGS		;SET IN $X FLAGS
	MOVEI	T,1		;USER PC INCREMENTS BY ONE
	JRST	DOITX7		;COMMON CODE

  > ;END IFN FTDEC20
;STILL IFE FTFILE

;HERE FOR NORMAL INSTRUCTION EXECUTION

DOITX:	SKIPE	I.PCREF		;NORMAL EXECUTE?
	JRST	DOXX		;NO, IN ANOTHER SECTION
DOITX1:	$XRET			;RESTORE USER'S CONTEXT
DOITX2:	XCT	I.NST		;EXECUTE THE INSTRUCTION
				;(IF IN EXEC MODE THIS MAY BE PXCT)
DOITX3:	REPEAT	SKPMAX,<AOS SKPCT> ;NOTE COUNT OF SKIPS
DOITX5:	$XSAVE			;SAVE USER'S CONTEXT
DOITX6:	MOVEI	T,SKPMAX+1	;MAX AMOUNT CAN BE SKIPPED
	SUB	T,SKPCT		;MINUS THOSE NOT SKIPPED
DOITX7:	SETZM	SKPCT		;RESET SKIP COUNTER
	ADD	T,PCWRD		;ADJUST USER PC ACCORDINGLY
	HRRM	T,PCWRD		;SET NEW USER PC
	JRST	NOSKP1
;STILL IFE FTFILE

;HERE TO HANDLE EXECUTION IN ANOTHER SECTION

DOXX:	SETOM	I.NXIT		;IT'S DANGEROUS IF WE HAVE TO CHANGE SECTIONS
	SKIPN	BPBLK		;DO WE HAVE A GLOBAL BPT/EXECUTE BLOCK?
	JRST	DOXX5		;NO, SECTIONS MUST BE MAPPED TOGETHER
	XMOVEI	W1,DOITX3	;ADDRESS TO RETURN TO
	SETZ	W2,		;WANT SKIPS COUNTED
DOXX1:	LDB	T,[POINT 23,I.NST,35]  ;GET I,X,Y FROM I.NST
	CAME	T,[Z @I.NSTE]	;WAS IT FIXED UP INTERNALLY?
	JRST	DOXX2		;NO, LEAVE IT ALONE
	HRR	T,BPBLK		;YES, RE-FIX IT UP
	ADDI	T,BPB$X		;THIS IS WHERE INSTRUCTION BLOCK STARTS
	DPB	T,[POINT 23,I.NST,35]  ;PUT IT WHERE $XBLK CAN FIND IT
DOXX2:	HLLZ	T,I.NPC		;GET INSTRUCTION'S SECTION
	PUSHJ	P,$XBLK		;GO SET THE BLOCK
	SKIPGE	I.NXIT		;DANGEROUS INSTRUCTION?
	JRST	RESTRX		;YES, RESTORE USER CONTEXT FOR EXECUTION
	MOVEM	T,SWAP		;NO, JUST SET "RETURN" ADDRESS
	JRST	SWAP+1		;RESTORE CONTEXT AND EXECUTE


;HERE WITH NO $4M BLOCK, MUST EXECUTE IN ACTUAL USER-INSTRUCTION SECTION

DOXX5:	HLLZ	R,I.NPC		;GET INSTRUCTION'S PC SECTION
	CAMN	R,SECDDT	;SAME SECTION AS DDT?
	JRST	DOITX1		;YES, ALL SET THEN
	PUSHJ	P,RWEMAP	;NO, ARE WE MAPPED TO THAT SECTION?
	 JRST	$XBLKE		;NOT MAPPED, NO $4M BLOCK, ERROR
	XMOVEI	TT,DOXX9	;OUR-SECTION REFERENCE ADDRESS
	MOVEM	TT,I.XJRS	;SET THE RETURN-TO-SECTION FLAG
	HLLZM	R,SECDDT	;FORCE PROPER SKPS0/SKPNS0 ACTION
	HRRI	R,DOXX7		;OUR XCT WITHIN THAT SECTION
	XJRST	R		;EXECUTE USER INSTRUCTION IN USER SECTION
DOXX7:	JSP	T,RESTOR	;RESTORE FULL USER CONTEXT
	XCT	I.NST		;EXECUTE THE INSTRUCTION
				;(IF IN EXEC MODE THIS MAY BE PXCT)
	REPEAT	SKPMAX,<AOS SKPCT> ;NOTE COUNT OF SKIPS
	XJRST	I.XJRS		;NOW SECTION-CHANGE BACK TO DOXX9
DOXX9:	JSR	SAVE		;SAVE FULL USER CONTEXT
	JRST	DOITX6		;FINISH UP SIMULATION OF THIS INSTR
;STILL IFE FTFILE

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

NOSKIP:	$XSAVE			;SAVE USER'S CONTEXT
NOSKP1:	SETOM	LASTPG		;IN CASE PAGE FAULT EVEN ON "SAFE" INST.
	CAIA			;INSTEAD OF 	JRST	TELLX
TELL:	EXCH	F,FLAGS		;GET DDT'S FLAGS
TELLX:	MOVE	T,[SCHR,,SCH]	;RESTORE TEMP DISPLAY MODES SINCE
  IFN FTMON,<
	CHKOUT>			;GIVE UP MDDT LOCK.
	BLT	T,ODF		; DANGEROUS XCT RESTORES PERM MODES
	SKIPL	T,I.NJMP	;UNCONDITIONAL JUMP ADDRESS SPECIFIED?
	MOVEM	T,PCWRD		;YES, BECOMES NEW USER PC
	HRRZ	T,FLAGS		;GET ORIGINAL OPCODE
	CAIE	T,(PUSHJ)	;DO WE NEED TO PUT SOMETHING
	CAIN	T,(PUSH)	; ONTO THE STACK?
	CAIA			;YES, WE DO
	 JRST	TELLX1		;NOPE
	MOVE	W1,I.NSTA	;RECOVER THE STACK POINTER AC
	PUSHJ	P,ADRSTK	;FIND WHERE IT'S POINTING
	MOVE	T,I.NSTP	;GET THE QUANTITY TO BE PUSHED
	PUSHJ	P,DEPMEM	;AND "PUSH" IT
	 POPJ	P,		;CAN'T

;CONTINUED ON NEXT PAGE
;STILL IFE FTFILE

;CONTINUED FROM PREVIOUS PAGE

;NOW DETERMINE WHAT, IF ANYTHING, TO TYPE OUT

TELLX1:	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	SCH,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

;CONTINUED ON NEXT PAGE
;STILL IFE FTFILE

;CONTINUED FROM PREVIOUS PAGE

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

NXTIT:	AOS	I.LOG		;COUNT $X CYCLES

  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
;STILL IFE FTFILE

;CONTINUED FROM PREVIOUS PAGE

	AOSN	I.PXC		;CALL FROM $PX?
	JRST	CPOPJ1		;YES, RETURN NOW, QUIETLY
	MOVE	T,PCWRD		;FETCH NEW PC
	XMOVEI	W1,XEC5		;INTERNAL LIMITS
	XMOVEI	W2,XEC6		;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		;NO, 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:	PUSHJ	P,TTYCLR	;FLUSH ANY TYPEAHEAD AND RESET ^O
	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	$X00		;NONZERO, REPEAT $X CYCLE AGAIN
	AOS	(P)		;TIME TO RETURN, MARK SUCCESSFUL COMPLETION
	POPJ	P,		;AND RETURN
;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?
	TLZA	T,-1		;NO, JUST TYPE 18 BITS
	ANDX	T,VMADR		;YES, JUST TYPE 30 BITS
	TLNE	F,FLE		;FLTG PT MEM OPERAND?
	HRLZ	T,T		;YES, IMMEDIATE USES E,,0
	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
;
;IF THE PC IS "IN THE ACS" THEN THE ADDRESS TYPED WILL BE ONLY THE
;REGISTER ADDRESSED.

PINST:	PUSH	P,SCH		;SAVE CURRENT OUTPUT MODE
	MOVEI	SCH,PIN		;SET TO PRINT SYMBOLIC INST MODE
	MOVEM	T,LLOC		;NEW LAST LOCATION
	MOVEM	T,LLOCO		;NEW LAST LOCATION OPEN
	TRNN	T,777760	;PC IN THE ACS?
	ANDI	T,17		;YES, REDUCE TO JUST REGISTER ADDRESS
	PUSHJ	P,LI1P		;LIST "PC" AND INSTRUCTION
	POP	P,SCH		;RESTORE CURRENT MODE

  > ;END IFE FTFILE FROM PAGES AGO

  IFN FTFILE,<XEC==ERR>
	POPJ	P,
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?
	SKIPA	T,LLOCO		;NO, USE LAST LOCATION OPENED
	PUSHJ	P,CEFFAX	;DEFAULT SECTION IF NEEDED
	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
	SETZ	T,		;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
	PUSHJ	P,TSEP		;SEPARATOR TEXT
	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	;SET MODE "FLAG" (XCT'ED AT SEAR2)
	TXNN	F,Q2F		;SECOND QUANTITY?
	TXZN	F,QF		;QUANTITY TO SEARCH FOR TYPED?
	JRST	ERR		;SYNTAX ERROR
	TXNE	F,LTF		;EFFECTIVE ADDRESS SEARCH?
	PUSHJ	P,CEFFAX	;DEFAULT SECTION IF NEEDED
	SETCAM	T,WRD		;SAVE SO AS TO NOT FIND IN SEARCH
	MOVSI	T,FRASE-DEN-1	;PREVENT TYPE OUT OF DDT PARTS
	SETCMM	FRASE(T)	;COMPLEMENT SO WON'T BE MATCHED
	AOBJN	T,.-1		;ONE BY ONE
	TXZ	F,STF		;DO NOT SUPPRESS TYPEOUT (IN LI1)
	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
	TXNE	F,CCF		;IF WANT A COUNT,
	SETZM	SYL		;CLEAR THE COUNT OF MATCHES

;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
	TXNE	F,CCF		;IF WANT A COUNT,
	AOS	SYL		;COUNT THE MATCH
	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	;GET NEXT ADDRESS
	JRST	SEAR2B		;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
	HLLZM	R,LLOCS		;SET DEFAULT SECTION (CF. CEFIW6:)
	TXZN	F,CCF		;IF NOT DOUBLE-ESC,
	JRST	DD1		; JUST END COMMAND NOW
	MOVEI	W1,[ASCIZ / Found /] ;POINT TO TEXT
	PUSHJ	P,TSTRG		;START IT GOING
	MOVE	A,SYL		;GET MATCH COUNT
	JUMPE	A,[MOVEI W1,[ASCIZ /no matches/] ;SIMPLE TEXT
		   PUSHJ P,TSTRG	;TYPE IT
		   PUSHJ P,TCRLF	;END THE LINE
		   JRST DD1]	;TAKE THE EASY WAY OUT
	PUSHJ	P,FP7		;TYPE IN DECIMAL (WITHOUT THE DOT)
	MOVEI	W1,[ASCIZ / match/] ;TEXT SAYING WHAT WE FOUND
	PUSHJ	P,TSTRG		;TYPE IT
	MOVEI	W1,[ASCIZ /es/]	;TEXT TO MAKE IT PLURAL
	SOSE	SYL		;IF NOT SINGULAR,
	PUSHJ	P,TSTRG		; THEN MAKE PLURAL
	PUSHJ	P,TCRLF		;END THE LINE
	JRST	DD1		;FINALLY END COMMAND
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
	SETZM	COMCOR		; . . .
  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
		   YRFLEN,,YRFBLK] ;LEN,,ADR OF RETURNED FILESPEC 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,.IOBIN	;YES, USE BINARY 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)
	MOVEM	R,YFLBLK+.FOBSA	;SET UP AS STARTING ADDRESS
	EXCH	R,.JBFF		;PERSUADE MONITOR TO PUT BUFFER THERE
	MOVEI	T,YBFSIZ-2	;SIZE OF BUFFER (FUDGED FOR OVERHEAD)
	MOVEM	T,YFLBLK+.FOBSZ	;STORE FOR RING SETUP
	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
	CAILE	R,YBFBUF+YBFSIZ	;MAKE SURE BUFFER NOT TOO BIG
	JRST	ERR		;WAS, FORGET IT
	TXNE	F,CCF		;SYMBOL FILE?
	JRST	TAPSY		;YES, GO READ IN THEN
	TMSG	<[Processing commands from >
	MOVEI	TT,YFLBLK	;POINT TO FILOP BLOCK
	PUSHJ	P,TYPFIL	;PRINT FILSPEC
	TMSG	<]>		;END TEXT
	PUSHJ	P,TCRLF		;APPEND A CRLF
	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:
REPEAT 0,<
	TMSG	<[Loading symbols from >
	MOVEI	TT,YFLBLK	;POINT TO FILOP BLOCK
	PUSHJ	P,TYPFIL	;PRINT FILESPEC
	TMSG	<]>		;END TEXT
	PUSHJ	P,TCRLF		;APPEND A CRLF
>
	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
; STILL IN IFN FTDEC10

  IFN FTYANK!FTFILE,<
TYPFIL:	PUSH	P,TT		;SAVE FILOP BLOCK ADDRESS
	HRRZ	TT1,.FOFSP(TT)	;GET RETURNED FILESPEC BLOCK
	MOVEI	TT,.FOFDV(TT1)	;POINT AT ITS DEVICE WORD
	SKIPE	(TT)		;IF IT WAS RETURNED VALID,
	JRST	TYPRF1		;JUST USE IT
	MOVE	TT,(P)		;NO, RETRIEVE FILOP BLOCK ADDRESS
	MOVE	W1,.FODEV(TT)	;GET INITED DEVICE
	MOVEM	W1,.FOFDV(TT1)	;SAVE FOR TYPRFS
	HLRZ	W1,.FOFNC(TT)	;GET CHANNEL HALFWORD
	ANDI	W1,(FO.CHN)	;ISOLATE CHANNEL
	DEVCHR	W1,		;GET DEVICE TYPE BITS
	TXNN	W1,DV.TTY	;WATCH OUT FOR NUL:
	TXNN	W1,DV.DIR	;IF NOT A DIRECTORY DEVICE,
	JRST	TYPFI3		;DON'T TYPE JUNK
	HRRZ	TT,.FOLEB(TT)	;GET LOOKUP/ENTER BLOCK ADDRESS
	MOVE	W1,.RBNAM(TT)	;FILE NAME
	MOVEM	W1,.FOFFN(TT1)	;SAVE FOR TYPRFS
	HLLZ	W1,.RBEXT(TT)
	MOVEM	W1,.FOFEX(TT1)	;SAVE EXTENSION FOR TYPRFS
	HRRZ	TT,(P)		;GET FILOP BLOCK ADDRESS BACK
	HRRZ	TT,.FOPAT(TT)	;GET PATH BLOCK ADDRESS
	SKIPN	TT		;IF NONE,
	MOVEI	TT,[0]-.PTPPN	;FAKE UP TO POINT TO A ZERO EVENTUALLY
	SKIPN	.PTPPN(TT)	;IF HAVE NO PATH TO TYPE,
	JRST	TYPFI3		;THEN DON'T COPY IT
	HRLI	TT,.FOFPP-.FOFMX ;MAKE LH USEFUL FOR AOBJN
TYPFI2:	SKIPN	W1,.PTPPN(TT)	;IF END OF DIRECTORY,
	JRST	TYPFI3		;GO DO IT
	MOVEM	W1,.FOFPP(TT1)	;NO, STORE FOR TYPRFS
	ADDI	TT1,1		;UPDATE STORAGE ADDRESS
	AOBJN	TT,TYPFI2	;COPY ALL RELEVANT DIRECTORY WORDS
TYPFI3:	MOVE	TT,(P)		;RETRIEVE FILOP BLOCK POINTER
	HRRZ	TT,.FOFSP(TT)	;GET RETURNED FILESPEC BLOCK ADDRESS
	ADDI	TT,.FOFDV	;SKIP THE JUNK
	JRST	TYPRF1		;AND GO TYPE THE FILE
  > ;END IFN FTYANK!FTFILE

TYPRFS:	PUSH	P,TT		;SAVE ADDRESS OF OUR BLOCK
TYPRF1:	MOVE	W1,.SGFDV(TT)	;GET THE DEVICE NAME
	PUSHJ	P,TSIXN		;AND TYPE IT
	MOVEI	T,":"		;DEVICE TERMINATOR
	PUSHJ	P,TOUT		;TYPE IT
	SKIPN	W1,.SGFNM(TT)	;IF NO FILE NAME,
	JRST	TYPRF3		;THEN DON'T TYPE IT
	HLRZ	T,.SGFEX(TT)	;YES, GET THE EXTENSION
	CAIE	T,'UFD'		;IF NOT .UFD
	JRST	TYPRF2		;THEN TYPE NAME IN SIXBIT
	CAME	W1,[-1]		;EXCEPT FOR -1,
	JUMPL	W1,TYPRF2	;NEGATIVE NAME GETS SIXBIT ANYWAY
	MOVEI	T,"["		;NO, IT'S A PPN
	PUSHJ	P,TOUT		;SO INTRODUCE IT
	HLRZ	W1,.SGFNM(TT)	;GET PROJECT NUMBER
	PUSHJ	P,TOCTW		;TYPE IN OCTAL
	MOVEI	T,","		;GET THE COMMA
	PUSHJ	P,TOUT		;FOR A SEPARATOR
	HRRZ	W1,.SGFNM(TT)	;GET THE PROGRAMMER NUMBER
	PUSHJ	P,TOCTW		;TYPE IN OCTAL
	MOVEI	T,"]"		;END OF PPN
	PUSHJ	P,TOUT		;FLAG THAT
	JRST	TYPRF3		;SKIP SIXBIT CASE
TYPRF2:	PUSHJ	P,TSIXN		;TYPE FILE NAME IN SIXBIT
TYPRF3:	HLLZ	W1,.SGFEX(TT)	;GET EXTENSION
	LSH	W1,-6		;MAKE ROOM
	TLO	W1,'.  '	;FOR THE DOT
	SKIPN	.SGFEX(TT)	;IF EITHER AN EXTENSION
	SKIPE	.SGFNM(TT)	;OR A NAME,
	PUSHJ	P,TSIXN		;TYPE .EXT
	SKIPN	.SGFPP(TT)	;IF NO PPN,
	JRST	TYPRF9		;THEN SKIP THE PATH ENTIRELY
	HRLI	TT,.SGFPP-.SGFLN ;SETUP FOR FULL PATH AOBJN
	MOVEI	T,"["		;INTRODUCE OUR PATH
	PUSHJ	P,TOUT		; ...
	MOVE	W1,.SGFPP(TT)	;GET PPN WORD
	CAME	W1,[-1]		;IF NOT [%,%]
	JUMPL	W1,TYPRF5	;THEN TYPE EVEN THIS IN SIXBIT
	HLRZ	W1,.SGFPP(TT)	;NO, GET PROJECT NUMBER
	PUSHJ	P,TOCTW		;TYPE IN OCTAL
	MOVEI	T,","		;A COMMA
	PUSHJ	P,TOUT		;FOR A SEPARATOR
	HRRZ	W1,.SGFPP(TT)	;GET PROGRAMMER NUMBER
	PUSHJ	P,TOCTW		;TYPE IN OCTAL
	AOBJP	TT,TYPRF6	;ADVANCE POINTER PAST THE PPN
TYPRF4:	SKIPN	W1,.SGFPP(TT)	;IF NO MORE PATH,
	JRST	TYPRF6		;THEN CLOSE IT OFF
	MOVEI	T,","		;YES,
	PUSHJ	P,TOUT		;SEPARATE FROM PREDECESSOR
TYPRF5:	PUSHJ	P,TSIXN		;TYPE THIS SFD (OR UFD?) NAME
	AOBJN	TT,TYPRF4	;LOOP OVER ALL POSSIBLE PATH WORDS
TYPRF6:	MOVEI	T,"]"		;PUNCTUATION
	PUSHJ	P,TOUT		;END THE PATH
TYPRF9:	POP	P,TT		;RESTORE BLOCK ADDRESS
	POPJ	P,		;AND RETURN


> ;END IFN FTDEC10


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

IFN FTFILE,<GO==ERR>

IFE FTFILE,<

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

GO:	PUSHJ	P,RSTAC		;RESTORE ACS
	TXNN	F,QF		;EXPLICIT START ADDRESS GIVEN?
	JRST	GO3		;NO, MAKE AN EDUCATED GUESS
	PUSHJ	P,CEFFAX	;DEFAULT SECTION IF NEEDED

;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.

GO1:	PUSH	P,T		;SAVE OVER TCRLF
	PUSHJ	P,TCRLF		;NEATNESS
	PUSHJ	P,INSRTB	;INSERT BREAKPOINTS
	POP	P,T		;RESTORE START ADDRESS
	SETZM	BPTIP		;DON'T ALLOW $X'ING AFTER $G
	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
;STILL IFE FTFILE

;NO START ADDRESS, MAKE A GUESS AT ONE

GO3:
  IFN FTEXEC,<SKPUSR>		;OK IN EDDT IN USER MODE
  IFN FTEXEC!FTMON,<JRST ERR>	;NO SUCH COMMAND IN EDDT OR MDDT
  IFN FTDEC10,<
	MOVEI	T,TT		;ARG BLOCK IN TT
	SETZM	TT		;READ FUNC CODE
	ENTVC.	T,		;GET ENTRY VECTOR
	 SETZB	TT1,TT2		;CAN'T, JUST USE JOBDAT
	JUMPE	TT1,GO5		;NO ENTRY VECTOR, USE JOBDAT
	PUSH	P,TT1		;SAVE LENGTH A MOMENT
	MOVE	R,TT2		;GET ENTRY VECTOR ADDRESS
	PUSHJ	P,FETCH		;GET WHAT IT POINTS TO
	 JRST	ERR		;TSK TSK
	POP	P,TT1		;RESTORE LENGTH
	CAIE	TT1,(JRST)	;START-ADDR FORMAT MAKES THIS IRRELEVANT
	JRST	[TLNN	T,(IFIW)	;IF NOT IFIW,
		 TLNE	T,770000	;MUST NOT LOOK LIKE INSTRUCTION
		 TLNN	T,^-<(IFIW)>	;IFIW MUST BE PURE
		 JRST	.+2		;OK, KEEP THIS ADDRESS
		 JRST	.+1]		;NO, KEEP PREVIOUS ADDRESS
	SKIPA	T,R		;YES, USE THE ORIGINAL ADDRESS
	SETZ	TT1,		;NO, USE IT AND ALLOW ANY OFFSET
  > ;END IFN FTDEC10
  IFN FTDEC20,<
	MOVEI	T1,.FHSLF
	XGVEC%			;GET ENTRY VECTOR
	 ERJMP [GEVEC%		;DO A DIFFERENT WAY FOR PRE-5.0 MONITORS
		HRRZ	T3,T2		;PUT ADDR. IN T3
		HLRZS	T2		;0,,LENGTH IN T2
		JRST	.+1]		;CONTINUE EXECUTION
	CAIN	T2,(JRST)	;TOPS10 FORMAT?
	 JRST	GO5		;YES
	SKIPLE	T2		;MUST BE POSITIVE
	CAIL	T2,1000		;REASONABLE?
	 JRST	ERR		;NO
	MOVE	T,T3		;PUT START ADDR. IN T FOR RESTOR
	MOVE	TT1,T2		;MOVE LENGTH INTO COMMON PLACE
  > ;END IFN FTDEC20
	SKIPGE	T		;IF IFIW FORMAT,
	HLL	T,TT2		;RELOCATE TO EVEC SECTION
	TXNN	F,Q2F		;SECOND QUANT? (I.E. $1G)
	SETZM	WRD2O		;NO, ASSUME ZERO
	CAMG	TT1,WRD2O	;WITHIN RANGE?
	JUMPN	TT1,ERR		;NO
	ADD	T,WRD2O		;ADD OFFSET WITHIN VECTOR
	JRST	GO1		;NOW HAVE ADDR IN T, GO START THERE

GO5:				;HERE TO TRY JOBDAT
  IFN FTDEC10,<HLLZ R,TT2>	;SET START ADDRESS SECTION
  IFN FTDEC20,<HLLZ R,T3>	;SET START ADDRESS SECTION
	HRRI	R,.JBSA		;WHERE START ADDRESS LIVES
	PUSHJ	P,FETCH		;GO GET IT
	  JRST	ERR		;OOPS
	HLL	T,R		;SET START ADDRESS SECTION
	TRNN	T,-1		;ILLEGAL IF RH(.JBSA) IS ZERO
	JRST	ERR
	TXNE	F,Q2F		;IS THIS $NG FORM?
	ADD	T,WRD2O		;YES, ADD THE INCREMENT
	JRST	GO1		;CONTINUE WITH "GO" ADDRESS IN T
> ;END IFE FTFILE
;HERE ON AN $I COMMAND -- USER CONTEXT REGISTERS
;HERE ON AN $M COMMAND -- DDT CONTROL REGISTERS

PILOC:	SKIPA	TT2,[IFIW @ISKADR(TT1)]  ;$I TABLE
MASK:	MOVE	TT2,[IFIW @MSKADR(TT1)]  ;$M TABLE
	TXZN	F,Q2F		;WAS A MASK NUMBER GIVEN?
	TDZA	TT1,TT1		;NO, DEFAULT TO SEARCH MASK
	SKIPL	TT1,WRD2D	;YES, GET THE NUMBER - ERROR IF NEGATIVE
	CAML	TT1,-1(TT2)	;WITHIN LEGAL LIMITS?
	JRST	ERR		;NO, COMPLAIN AT USER
	TXNE	F,QF!FAF!SAF	;SETTING NEW VALUE, OR LOOKING AT OLD VALUE?
	JRST	MASK05		;SET NEW USER-TYPED VALUE
	MOVEI	T,@TT2		;LOOKING AT OLD VALUE, GENERATE MASK ADDRESS
MASK02:	MOVEI	W,1
	MOVEM	W,FRASE1
	TXO	F,DDLF		;NOTE DDT INTERNAL LOCATION
	JRST	QUAN1


;HERE TO SET NEW VALUE

MASK05:	TXNN	F,QF		;WAS A REAL ARGUMENT GIVEN?
	MOVE	T,@TT2		;NO, FETCH THE PREVIOUS
	TXNE	F,FAF		;ANY BITS TO CLEAR?
	TDZ	T,LLIMIT	;YES, DO SO
	TXNE	F,SAF		;ANY BITS TO SET?
	TDO	T,ULIMIT	;YES, SET THEM
	CAIN	TT1,04		;$4M?
	JRST	[SKIPG	-2(TT2)		;MAYBE
		JRST	.+1		;NOPE, WAS $4I, NOTHING SPECIAL
		TLZ	T,-1		;YES, LET ".$4M" WORK
		JUMPE	T,MASK07	;ZERO IS ALWAYS OK
		CAIL	T,20		;WILL IT FIT INSIDE THE
		CAILE	T,1000000-BPBMAX;LOCALLY-ADDRESSABLE SECTION?
		 JRST	[SMERS	<BAD $4M VALUE>	;NO, SAY WHY NOT
			JRST	ERR]		;AND COMPLAIN
		JRST	MASK07]		;OK, SET BPT BLOCK ADDRESS

MASK07:	MOVEM	T,@TT2		;SET NEW USER-TYPED VALUE
	CAIN	TT1,05		;$5M?
	JRST	MASK5		;MAYBE
	JRST	RET		;ALL DONE WITH $I/$M COMMAND
;HERE ON $5M

MASK5:	SKIPG	-2(TT2)		;$5I OR $5M COMMAND?
	JRST	RET		;$5I, ALL DONE

IFE FTFILE,<
	SETZM	SYMVAL		;$5M, FLAG TO RE-INIT SYMBOL TABLE PTRS
  IFN FTSCSH,<PUSHJ P,CLRCSH>	;AND THE CACHE
	JRST	RET		;NOW WE'RE DONE
> ;END IFE FTFILE

IFN FTFILE,<
MASK5C:	PUSHJ	P,TCRLF		;MAKE MESSAGE LOOK NICE
	PUSHJ	P,WRTSYM	;TRY TO WRITE OUT CURRENT SYMBOLS
	PUSHJ	P,SYMFIX	;GRAB SOME NEW SYMBOLS
	 JRST	[PUSHJ	P,TCRLF		;FAILED, FIRST DO CRLF
		SETZM	SYMP+S$ADR	;WIPE OUT ALL POSSIBLE POINTERS
		SETZM	USYMP+S$ADR	; SO NOBODY TRIES TO USE THE
		SETZM	HSYMP+S$ADR	; BAD SYMBOL TABLE
		JRST	DD2]		;ALL DONE
	JRST	DD2		;ALL DONE
> ;END IFN FTFILE
;$I MASK ADDRESS TABLE

	EXP	0		;	0 = $I COMMAND
	EXP	ISKMAX		;	LENGTH OF $I TABLE
ISKADR:	IFIW	SAVPI+00	;$00I	EXEC-MODE CONI PI
	IFIW	SAVPI+01	;$01I	EXEC-MODE PI CHANNELS TURNED OFF
	IFIW	SAVAPR		;$02I	EXEC-MODE CONI APR
	IFIW	PCFLG		;$03I	PC FLAGS
	IFIW	PCWRD		;$04I	PC ADDRESS
	IFIW	EPTWRD		;$05I	EXEC PROCESS TABLE PAGE ADDRESS
	IFIW	UPTWRD		;$06I	USER PROCESS TABLE PAGE ADDRESS
	IFIW	CSTWRD		;$07I	CST BASE ADDRESS (VIRTUAL)
	IFIW	SPTWRD		;$10I	SPT BASE ADDRESS (VIRTUAL)

	ISKMAX==.-ISKADR	;MAX $I "FUNCTION"


;$M MASK ADDRESS TABLE

	EXP	1		;	1 = $M COMMAND
	EXP	MSKMAX		;	LENGTH OF $M TABLE
MSKADR:	IFIW	MSK		;$00M	SEARCH MASK
	IFIW	TTYMSK		;$01M	TTY FORMAT CONTROL MASK
	IFIW	SYMOFS		;$02M	SYMBOL + OFFSET RANGE "MASK"
	IFIW	BYTMSK		;$03M	BYTE TYPEOUT MASK
	IFIW	BPBLK		;$04M	INTER-SECTION BPT BLOCK LOCATION
	IFIW	SYTLOC		;$05M	SYMBOL TABLE LOCATION INFO
	IFIW	PDFSEC		;$06M	"PERMANENT" DEFAULT SECTION

	MSKMAX==.-MSKADR 	;MAX $M "FUNCTION"
;HERE ON AN $Z COMMAND -- STORE DATA INTO MEMORY

ZERO:	TXNE	F,CCF		;$Z OR $$Z (OLD FORM)?
	JRST	ERR		;$$Z - USER LOSES
	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
	PUSHJ	P,SETUP		;SETUP LOWER AND UPPER ADDRESS LIMITS
	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
	JRST	ERR		;SOMETHING WENT WRONG - LOSE
	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:	SUBI	R,1		;BACKUP R TO LAST WORD ADDRESS
	MOVEM	R,LLOC		;SET NEW "." TO LAST LOCATION ZAPPED
	PUSHJ	P,TCRLF		;END OF LOOP DEPOSITING MEMORY
	JRST	DD1		;RETURN
;SETUP (DEFAULT) LOWER AND UPPER LIMITS FOR $W, $N, $E AND $Z

SETUP:	TXNE	F,FAF		;LOWER LIMIT GIVEN?
	JRST	[PUSHJ	P,LLMSEC	;GET/SET DEFAULT SECTION (LLIMIT)
		MOVE	R,T		;COPY START TO LOOP INDEX
		JRST	SETUP1]
  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
SETUP1:	TXNE	F,SAF		;UPPER LIMIT GIVEN?
	JRST	[PUSHJ	P,ULMSEC	;GET/SET DEFAULT SECTION (ULIMIT)
		JRST	SETUP5]
  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
;ROUTINES FOR GETTING/SETTING DEFAULT SECTION FROM/TO ULIMIT AND LLIMIT.

LLMSEC:	MOVEI	S,LLIMIT	;SETUP LLIMIT
	CAIA			;SKIP INTO COMMON CODE
ULMSEC:	MOVEI	S,ULIMIT	;SETUP ULIMIT
	PUSH	P,F		;SAVE TRUE REGISTER "F"
	PUSH	P,ACCCF		;AND TRUE FLAG "ACCCF"
	DMOVE	TT1,LLREGF-LLIMIT(S)  ;GET PRESERVED "F" AND "ACCCF"
	MOVEM	TT1,F		;SET PRESERVED STATE OF "F"
	MOVEM	TT2,ACCCF	; AND "ACCCF" FLAGS
	MOVE	T,LLIMIT-LLIMIT(S)  ;FETCH ARGUMENT FOR CEFFAS
	PUSHJ	P,CEFFAX	;DEFAULT SECTION IF NEEDED
	MOVEM	T,LLIMIT-LLIMIT(S)  ;COPY BACK IN CASE OF CHANGE
	POP	P,ACCCF		;RESTORE TRUE STATE OF "ACCCF"
	POP	P,F		;AND "F" FLAGS
	POPJ	P,

;************** 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
	CAIE	T,"<"		;EITHER KIND OF
	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

;(MATCH ANGLE BRACKETS: >)
;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
;(MATCH ANGLE BRACKETS: <)

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
	SKIPN	TT		;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
	SKIPN	TT		;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
	CAIN	T,">"		;EXCEPT FOR ANGLE
	JRST	FSCSPC		;CONTINUE PARSING
	JRST	FSEIPP		;FUNNY CHARACTER - CALL ERROR
;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
;	   + 3/	LENGTH,,ADDRESS OF RETURNED FILSPEC 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
	CAIG	TT1,.FOFSP	;IS FILOP. BLOCK LONG ENUF?
	 POPJ	P,		;NO, ERROR
	MOVE	TT1,2(T)	;POINTER TO PATH BLOCK
	MOVEM	TT1,.FOPAT(TT)	;SET IN FILOP. BLOCK
	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	FSFSE1		;NO
	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
FSFSE1:	HRRZ	TT1,0(T)	;GET FILOP BLOCK AGAIN
	MOVE	TT,3(T)		;RETURNED FILESPEC POINTER
	MOVEM	TT,.FOFSP(TT1)	;SAVE
	PUSHJ	P,FSFCLR	;CLEAR IT OUT
	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:	HRRZ	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,-1(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,^L<PC$USR>	;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,PC$USR	;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 USER MODE ONLY ITEMS.

  IFN FTDEC20&<^-FTMON>,<	;SAVE PSI STATE ON -20 EXCEPT MDDT
    IFN FTEXEC,<
	SKPEXC>			;DON'T DO THIS IF IN EXEC MOE
	SKIPE	SARS		;ALREADY SAVED?
	 JRST	SAVE4		;YES, DON'T SAVE AGAIN
	SETOM	SAVSTS		;ASSUME PSI SYSTEM IS ON
	MOVEM	T1,SWTEM	;SAVE T1 FOR A MOMENT
	MOVEI	T1,.FHSLF	;BUT CHECK
	SKPIR%			;IS IT?
	 SETZM	SAVSTS		;NO, REMEMBER THAT IT'S OFF
	DIR%			;TURN IT OFF EITHER WAY
	MOVE	T1,SWTEM	;RESTORE T1
  > ;END IFN FTDEC20&<^-FTMON>

;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.

SAVE4:	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:	INIPDL			;LOAD UP A FRESH STACK POINTER
	SKIPE	SAVP		;IF WE HAD ONE BEFORE, THOUGH...
	MOVE	P,SAVP		; GET IT BACK
	MOVE	F,SAVF		;GET FLAGS BACK, OR ZERO IF NONE YET
	MOVE	T,[SCHM,,SCH]	;DDT TYPEOUT MODES
	BLT	T,ODF		;SET THEM UP
	SETZM	MAPFN		;NO MAPPING ($U) IN EFFECT

;CONTINUED ON NEXT PAGE
;STILL IFE FTFILE

;CONTINUED FROM PREVIOUS PAGE

;NOW SET INITIAL DEFAULT SECTION.

  IFN FTDEC10,<
    IFN FTEXEC,<SKPEXC>		;NO ENTRY VECTOR IN EXEC MODE
	PUSHJ	P,GEVECS	;GET ENTRY VECTOR SECTION
	  SETZ	T,		;CAN'T, USE ZERO
  > ;END IFN FTDEC10
  IFN FTDEC20,<
    IFN FTUD20,<		;ONLY USER-20 HAS AN ENTRY VECTOR
	SKIPL	T,SECUDD	;IS THERE A STUB?
	JRST	SAVE2A		;YES, SKIP E.V. SECTION STUFF
	PUSHJ	P,GEVECS	;NO, GET ENTRY VECTOR SECTION IN T
	 SETZ	T,		;TRY SECTION 0
    > ;END IFN FTUD20
    IFE FTUD20!FTMON,<MOVE T,SECDDT> ;OTHERWISE DEFAULT TO DDT'S SECTION
    IFN FTMON,<MOVSI T,MSEC1>	;MDDT DEFAULTS TO NORMAL MONITOR CODE
  > ;END IFN FTDEC20
SAVE2A:	SKIPN	BPTIP		;ARE WE $X'ING?
	MOVEM	T,LLOCS		;NO, ENTERING FOR REAL
;STILL IFE FTFILE

;CONTINUED FROM PREVIOUS PAGE

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

	MOVE	T,[BZ$FLG,,BZ$FLG+1] ;ZERO FLAGS
	SETZM	BZ$FLG		; . . .
	BLT	T,ZZ$FLG-1	; . . .
  IFE FTDEC20,<			;DON'T CHECK FOR KA/KI ON TOPS-20
	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
    IFN FTEXEC,<		;ONLY SET PAGING IN EXEC MODE
	SKPUSR			;USER OR EXEC MODE?
	SETOM	KIPAG		;KI-10'S ALWAYS DO KI-PAGING
    > ;END IFN FTEXEC
	JRST	SAVE6		;CONTINUE
  > ;END IFE FTDEC20

SAV4L:	MOVEI	2,-1		;A LARGER-THAN-ONE-DIGIT VALUE
	SETZB	3,5		;CLEAR STRING BYTE PTR.
	MOVEI	4,1		;SET DOUBLE LENGTH BINARY RESULT
	EXTEND	1,[CVTBDO]	;CONVERT BINARY TO DECIMAL
	TLNN	4,200000	;KL10 MICROCODE SETS THIS BIT
	JRST	SAV4S		;NOT A KL, TRY NEXT CPU
	SETOM	KLFLG		;KL, SET FLAG
SAVKS:	SETOM	KLSFLG		;KL/KS FLAG TOO
    IFN FTEXEC,<		;SELECT KI/KL PAGING IF EXEC MODE
	SKPEXC			;USER OR EXEC MODE?
	JRST	SAVE6		;USER, NO PAGING THEN
	CONI	PAG,T		;GET PAGING BITS
	TXNN	T,PGKLMD	;KL-PAGING?
	SETOM	KIPAG		;NO, KI-PAGING ENABLED
	TXNE	T,PGKLMD	;KL-PAGING?
	SETOM	KLPAG		;YES, KL-PAGING ENABLED
    > ;END IFN FTEXEC
	JRST	SAVE6		;CONTINUE

SAV4S:	MOVE	TT1,PCFLG	;GET PC FLAGS
	TXO	TT1,PC$BIS	;TURN ON FIRST-PART-DONE
	XMOVEI	TT2,SAV4SB	;GET PC FOR XJRSTF
	HLLZ	TT,TT1		;GET FLAGS FOR JRSTF
	HRRI	TT,SAV4SB	;SET PC FOR JRSTF
	SKPS0			;IN SECTION ZERO?
	XJRSTF	TT1		;NO, CONTINUE WITH XJRSTF
	JRSTF	@TT		;YES, CONTINUE WITH JRSTF
SAV4SB:	MOVSI	TT,(POINT 7,)	;LOAD BYTE PTR.
	SETOM	KSFLG		;ASSUME IT'S A KS-10
	ILDB	TT1,TT		;INCREMENT PTR.
	JUMPLE	TT,SAVKS	;IT'S A KS, JUMP
	SETZM	KSFLG		;NOT A KS, CLEAR FLAG
BADCPU:	HALT	.		;UNKNOWN PROCESSOR TYPE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

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

SAVE6:
  IFN FTEXEC!FTDEC10,<
	SKPUSR			;DON'T SAVE APR STATUS IN USER MODE
	SKIPE	SARS		;ALREADY SAVED?
	 JRST	SAVE7		;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!FTDEC10

;NOW SEE IF EXTENDED ADDRESSING EXISTS

SAVE7:
  IFN FTDEC10,<			;ONLY FOR TOPS-10
	MOVSI	TT,-1		;INVALID ADDRESS MASK FROM SECTION ZERO
    IFN FTEXEC,<
	SKPUSR			;IN USER MODE?
	 JRST	SAVE7E		;NO, USE DIFFERENT CHECK
    > ;END IFN FTEXEC
	MOVX	T,%CNST2	;GETTAB FOR APRID-LIKE FUNCTION
	GETTAB	T,		;ASK THE MONITOR FOR SOME BITS
	 SETZ	T,		;ASSUME FALSE IF OLD MONITOR
	TXNE	T,ST%EXA	;EXTENDED ADDRESSING SUPPORTED?
	MOVX	TT,^-VMADR	;YES, REALLY CAN SEE ANYWHERE FROM 0
    IFN FTEXEC,<
	JRST	SAVE7X		;ALL DONE IF USER MODE
SAVE7E:	SKPNKL			;ONLY AVAILABLE ON A KL
	SKPKLP			;WITH KL-PAGING
	JRST	SAVE7X		;GIVE UP
	APRID	T		;GET PROCESSOR OPTIONS
	TXNE	T,1B1		;EXTENDED ADDRESSING ON?
	MOVX	TT,^-VMADR	;YES, CAN SEE EVERYWHERE
    > ;END IFN FTEXEC
SAVE7X:	MOVEM	TT,S0PLIM	;SAVE S0 VISIBILITY LIMIT
  > ;END IFN FTDEC10

;CONTINUED ON NEXT PAGE
;STILL IFE FTFILE

;CONTINUED FROM PREVIOUS PAGE

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

SAVE8:	PUSHJ	P,TTYSAV	;DO TTY-DEPENDENT STUFF FOR RETURN TO DDT
	SETOM	SARS		;STATUS SUCCESSFULLY SAVED
	JRST	@SAVE		;ALL DONE
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
	MOVEM	P,SAVP		;SAVE P
	MOVEM	F,SAVF		;AND F
	PUSHJ	P,TTYRES	;RESTORE STATUS OF CONSOL TTY (EXEC MODE)
	MOVE	T,PCFLG		;SAVED PC FLAGS
	TXZ	T,PC$USR	;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
	SKPKL			;ON A KL?
	 JRST	RESTR2		;NO, SKIP AHEAD
	HRRZ	T,SAVAPR	;YES, GET APR CONDITIONS
	TXC	T,1B22!1B24!1B25!1B27	;COMPLEMENT MEM PARITY ERROR BITS
	ANDI	T,1B22!1B24!1B25!1B27+7	;CLEAR ALL BITS THAT SHOULD BE
	CONO	APR,(T)		;DO IT
RESTR2:
  > ;END FTEXEC

;FALL INTO NEXT PAGE
;STILL IFE FTFILE

;FALL IN FROM ABOVE

;CHECK PSI STATUS TO RESTORE.  MAY HAVE TO DO IT IN SECTION 0, IN WHICH
;CASE WE USE PART OF THE BREAKPOINT BLOCK.

  IFN FTDEC20&<^-FTMON>,<	;TOPS-20 EXCEPT MDDT
    IFN FTEXEC,<		; AND MAYBE EXEC DDT
	SKPEXC>			;IN USER MODE?
	SKIPL	SAVSTS		;WAS PSI ON?
	JRST	RESTR4		;NO, WE'RE OK
	MOVE	T,SAVE		;GET OUR RETURN ADDRESS
	SKPS0			;IF WE'RE ALREADY IN ZERO,
	TLNE	T,-1		;OR WE'RE RETURNING TO NON-ZERO,
	JRST	RESTR4		;THERE'S NOTHING TO WORRY ABOUT.
	HRRZ	R,BPBLK		;SAFE PLACE TO DO THINGS
	JUMPE	R,RESTR4	;NOT SET? NOTHING WE CAN DO...
	ADDI	R,BPBRST	;GET PAST THE BREAKPOINTS
	MOVEI	T,.FHSLF	;WHAT WE WANT T1 TO HAVE
	EXCH	T,AC0+1		; WHEN WE DO THE EIR% CALL
	PUSHJ	P,DEPMEM	;DROP ORIGINAL WHERE SEC. 0 CAN FIND IT
	 JRST [	MOVEM	T,AC0+1	;CAN'T, RESTORE USER'S T1
		JRST	RESTR4]	;AND GIVE UP ON THE FANCY STUFF
	HRRI	R,1(R)		;STEP TO NEXT LOC
	MOVX	T,<EIR%>	;GET THE JSYS
	PUSHJ	P,DMEMER	;STUFF IT
	HRRI	R,1(R)		;NEXT
	MOVX	T,<MOVE	T1,>	;WANT TO RESTORE T1
	HRRI	T,-2(R)		;FROM WHERE WE LEFT IT BEFORE
	PUSHJ	P,DMEMER	;DO IT
	HRRI	R,1(R)		;NEXT
	MOVX	T,<JRST>	;FINALLY A JUMP TO THE REAL PLACE
	HRR	T,SAVE		; WHERE WE WANT TO RETURN
	PUSHJ	P,DMEMER	;DROP IT IN
	HRRI	R,-2(R)		;BACK UP TO THE JSYS
	MOVEM	R,SAVE		;SAVE ADDRESS
	SETZM	SAVSTS		;DON'T RESTORE PSI PREMATURELY
RESTR4:				;CONTINUE WITH NORMAL RETURN
  > ;END IFN FTDEC20&<^-FTMON>

	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

  IF2,<IFL BPBRSL-4,<PRINTX ? BPBRSL TOO SMALL, MUST BE AT LEAST FOUR>>

;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
	JRST	REST06		;NON-ZERO SECTION, NEED XJRSTF
  IFN FTEXEC,<			;EXEC-MODE ONLY CODE
    IFN FTDEC20,<
	SKPEXC			;NEED JRSTF - EXEC MODE?
	JRST	REST05		;NO, DO USER-MODE RETURN
    > ;END IFN FTDEC20
    IFE FTDEC20,<
	SKPUSR>
	CONO	PI,@SAVPI	;YES, RESTORE PI
	JRSTF	@SAVE		;AND RETURN TO USER
  > ;END IFN FTEXEC

  IFN FTDEC20&<^-FTMON>,<
REST05:	MOVEM	T1,SWTEM	;SAVE T1 FOR A MOMENT
	MOVEI	T1,.FHSLF	;POINT TO OUR FORK
	SKIPGE	SAVSTS		;HAVE TO TURN PSI SYSTEM BACK ON?
	EIR%			;YES, DO IT
	MOVE	T1,SWTEM	;NO, RESTORE T1 (MAY GET PSI TRAP FIRST)
  > ;END IFN FTDEC20&<^-FTMON>
	JRSTF	@SAVE		;AND RETURN TO USER

REST06:
  IFN FTEXEC,<			;EXEC-MODE ONLY CODE
    IFN FTDEC20,<
	SKPEXC			;IN EXEC MODE?
	JRST	REST07		;NO, GO TO USER-MODE CODE
    > ;END IFN FTDEC20
IFE FTDEC20,<
	SKPUSR>
	CONO	PI,@SAVPI	;YES, RESTORE PI
	XJRSTF	XSAVE		;RETURN TO DDT OR USER
  > ;END IFN FTEXEC

  IFN FTDEC20&<^-FTMON>,<
REST07:	MOVEM	T1,SWTEM	;SAVE T1 FOR A MOMENT
	MOVEI	T1,.FHSLF	;POINT TO OUR FORK
	SKIPGE	SAVSTS		;HAVE TO TURN PSI SYSTEM BACK ON?
	EIR%			;YES, DO IT
	MOVE	T1,SWTEM	;NO, RESTORE T1 (MAY GET PSI TRAP FIRST)
  > ;END IFN FTDEC20&<^-FTMON>
	XJRSTF	XSAVE		;AND RETURN TO USER
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
;SECCHG - SWITCH DDT'S SECTION
;CALL IS:
;
;	MOVX	R,<ADR>
;	JSP	TT,SECCHG
;	RETURN ALWAYS
;
;THE STACK IS (ULP!) UPDATED ACCORDINGLY . . .

SECCHG:	HRRZ	TT1,P		;CURRENT STACK LEVEL
	SKPS0			;ARE WE IN SECTION 0 GOING OUT?
	JRST	SECCH4		;NO

;LOOP CHANGING ALL SECTION-0 PC'S ON THE STACK INTO SECTION-LH(R)

SECCH1:	HLLZ	TT2,(TT1)	;CURRENT STACK ENTRY
	TDC	TT2,TT		;CONTRAST WITH SECTION-0 PC FLAGS
	TLNE	TT2,-1		;LOOK LIKE A PROBABLE PC?
	JRST	SECCH2		;NO
	HRRZ	TT2,(TT1)	;YEAH, GET SECTION-LOCAL PC
	CAIL	TT2,DDT		;IS WITHIN DDT RANGE?
	CAILE	TT2,DDTEND	; . . .
	CAIA			;NO
	HLLM	R,(TT1)		;YES, MAKE IT A SECTION-N PC THEN
SECCH2:	CAILE	TT1,PDL		;STILL ON THE STACK?
	SOJA	TT1,SECCH1	;YES, KEEP ON GOING
SECCH4:	HLLM	R,TT		;POSITION SECTION
	HLLZM	R,SECDDT	;NOTE DDT'S NEW SECTION
	HLLM	R,PDL		;TOP OF STACK IS ALWAYS A DDT PC
	HLLM	R,XPDL		;AS IS EMERGENCY RETURN
	TLNN	R,-1		;GOING INTO SECTION 0?
	SETZM	SYMVAL		;YES, MIGHT INVALIDATE SYMBOL TABLE POINTERS
	XJRST	TT		;RETURN TO CALLER IN NEW SECTION
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
	 TDZA	W1,W1		;FLAG BREAKPOINTS NEED TO BE REMOVED
	SETO	W1,		;FLAG BREAKPOINTS ALREADY REMOVED

;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	R,BPT$B+B$BPT(S);REAL ADDRESS (+1) FROM WHENCE WE CAME
	JUMPN	R,BCOMG2	;0 IF JUMPED FROM SEC 0 INTO NON-0
	MOVE	TT,S		;REAL PC IS IN BPT BLOCK
	IDIVI	TT,B$SIZ	;GET BPT NUMBER
	SOS	TT		;NO BPT 0 IN BPBLK
	IMULI	TT,NBPBW	;GET OFFSET INTO BLOCK
	HRRZ	R,BPBLK		;GET THE BLOCK BASE ADR
	ADD	R,TT		;WHERE BPT JSR'D TO
	HLL	R,BPT$B+B$ADR(S);IN THE RIGHT SECTION
	PUSHJ	P,FETCH		; FROM THE BLOCK IN ITS SECTION
	 JRST	ERR		;CAN'T GET ADR
	TLNN	R,-1		;IF FROM SECTION 0,
	TLZ	T,-1		;DON'T KEEP THE FLAGS
	SKIPA	R,T		;MOVE INTO PROPER AC
BCOMG2:	SKPS0			;RUNNING IN NON-ZERO SECTION?
	TRNA			;$4M OR NZS, KEEP FULL PC
	ANDI	R,-1		;NO, ONLY 18-BITS OF PC
	SKIPE	S		;BREAKPOINT 0?
	HRRI	R,-1(R)		;NO - BACKUP PC BY 1
	MOVEM	R,PCWRD		;SAVE FOR $X ET AL
	HLLZM	R,LLOCS		;SET CURRENT SECTION TO BPT SECTION
	SETOM	BPTIP		;FLAG BREAKPOINT IN PROGRESS
	PUSHJ	P,FETCH		;GET A COPY OF THE BPT INSTRUCTION
	 JRST	BCOMG4		;INACCESSIBLE?  TOO BAD...
	MOVE	W2,T		;SAVE IT AWAY
	PUSHJ	P,MAKBPT	;GET EXPECTED BPT INSTRUCTION
	CAMN	W2,T		;EXPECTED INSTRUCTION?
	MOVEM	R,BPT$B+B$ADR(S);YES, NOTE REAL PC OF THIS BREAKPOINT
BCOMG4:	SKIPN	W1		;NEED TO REMOVE BREAKPOINTS?
	PUSHJ	P,REMOVB	;YES, REMOVE ALL BREAKPOINTS
	JUMPE	S,BREAK		;BREAKPOINT 0 (UNSOLICITED) ALWAYS BREAKS
;STILL IFE FTFILE

;NOW SEE WHETHER OR NOT TO BREAK

	MOVS	T,BPT$B+B$XCT(S);GET CONDITIONAL BREAK INSTRUCTION
	CAIN	T,(JFCL	0)	;IS IT A JFCL?
	JRST	BCOMG1		;YES, OPTIMIZE - ONLY BREAK ON PROCEED CT
	MOVSM	T,I.NST		;NO, SAVE IT
	SETOM	SKPCT		;INIT. SKIP FLAG FOR CONDITIONAL INSTR.
  IFN FTMON,<CHKIN>		;TAKE MDDT LOCK.
	HLLZ	T,LLOCS		;GET THE SECTION OF THE BREAKPOINT
	CAME	T,SECDDT	;AND COMPARE IT TO DDT'S SECTION.
	JRST	[XMOVEI	W1,BCOMG3	;EVENTUAL RETURN
		SETZB	W2,I.CJMP	;COUNT SKIPS; NO SPECIAL CASES.
		PUSHJ	P,$XBLK		;PACKAGE INSTR FOR EXECUTION
		JRST	RESTRX]		;T WAS SET BY $XBLK
	JSP	T,RESTOR	;GO BACK TO USER CONTEXT
	XCT	I.NST		;(USER) CONDITIONAL BREAK INSTR.
BCOMG3:	AOS	SKPCT		;NON-SKIP, SKPCNT=1
	AOS	SKPCT		;SINGLE-SKIP, SKPCNT=0
	JSR	SAVE		;DOUBLE-SKIP, SKPCNT=-1, BACK TO DDT
	 JFCL			;SAVE COULD CONCEIVABLY SKIP
  IFN FTMON,<CHKOUT>		;GIVE UP MDDT LOCK.
	SKIPGE	SKPCT		;DOUBLE-SKIP?
	JRST	PROCD4		;YES, CONTINUE USER PROGRAM
	MOVE	S,BPTDX		;NO, GET BREAKPOINT NUMBER BACK
	SKIPE	SKPCT		;SINGLE OR NON-SKIP?
BCOMG1:	SOSG	BPT$B+B$CNT(S)	;NON-SKIP, BREAK ON PROCEED COUNT
	JRST	BREAK		;SINGLE-SKIP, BREAK
	JRST	PROCD4		;CONTINUE IF PROCEED COUNT SAYS NO
;STILL IFE FTFILE

;<< (MATCH ANGLE BRACKETS)

BREAK:	PUSHJ	P,TTYCLR	;FLUSH WAITING TTY CHARACTERS FOR INPUT
  IFN FTEX10,<			;CPNDDT ONLY FOR -10
	SKPUSR			;ONLY IN EXEC MODE
	SKIPN	R,JOBEDV	;GET .EDCNT ADDRESS
	JRST	BREAK0		;NO CPNDDT IF NONE
	SETZM	CPNBIT		;IN CASE OF FAILURE
	SKPKLS			;THIS ONLY WORKS ON A KL OR A KS
	JRST	BREAK0		;FORGET IT IF NOT
	ADDI	R,.EDCPN-.EDCNT	;OFFSET TO CPNDDT ADDRESS WORD
	PUSHJ	P,FETCHV	;FETCH IT
	 JRST	BREAK0		;DON'T BOTHER IF CAN'T
	JUMPE	T,BREAK0	;NOTHING TO DO IF NO CPNDDT
	MOVEM	T,CPNDDT	;SAVE CPNDDT ADDRESS
	ADDI	R,.EDCPU-.EDCPN	;OFFSET TO ASNTAB WORD
	PUSHJ	P,FETCHV	;RETRIEVE FROM MEMORY
	 JRST	BREAK0		;FORGET IT IF CAN'T
	JUMPE	T,BREAK0	;NO CPNDDT PROCESSING IF NOT THERE
	MOVE	W1,T		;COPY FOR AOBJN LOOPING
	PUSH	P,T		;SAVE A COPY
	APRID	W2		;GET OUR APR ID
	ANDI	W2,77777	;MASK GOOD FOR KS AND NOT BAD FOR KL
	SKPKS			;IF NOT A KS,
	ANDI	W2,7777		;MASK FURTHER FOR KL
BREAK2:	HRRZ	R,W1		;GET NEXT WORD TO TEST
	PUSHJ	P,FETCHV	;RETRIEVE FROM MEMORY
	 SETZ	T,		;NOT TOO BAD IF NOT THERE
	CAME	T,W2		;MATCHING APR SERIAL NUMBERS?
	AOBJN	W1,BREAK2	;NO, LOOP
	POP	P,W2		;YES OR EXPIRED, RESTORE INITIAL POINTER
	JUMPGE	W1,BREAK0	;LOSE IF NO MATCH
	SUB	W2,W1		;GET XWD JUNK,-CPU #
	MOVSI	T,(1B0)		;VALUE TO SHIFT
	LSH	T,(W2)		;GET BIT APPROPRIATE TO THIS CPU
	MOVEM	T,CPNBIT	;SAVE FOR PROCEED
	MOVE	R,CPNDDT	;WHERE TO STORE IT
	PUSHJ	P,STOREP	;STORE IT AWAY
	 SETZM	CPNBIT		;GIVE UP ON RESTORE IF CAN'T
BREAK0:
  > ;END FTEX10
	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
	MOVX 	TT2,TT$BPI
	TDNN	TT2,TTYMSK	;USER WANTS ADR AND INSTRUCTION?
	JRST [	PUSHJ	P,PINST	;YES, DO IT
		JRST	BREAK1]
	MOVEM	T,LWT		;NO, JUST ADR WILL DO
	MOVEM	T,LLOC		;SET "."
	PUSHJ	P,PADR		;PRINT ADDRESS
BREAK1:	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
	TXNN	R,BP$PRO	;AUTO-PROCEED IN EFFECT?
	JRST	BREAK6		;NO, JUST BREAKPOINT NORMALLY
	PUSHJ	P,LISTEN	;YES, ANYTHING TYPED BY USER?
	JRST	PROCD2		;NO, AUTO-PROCEED

BREAK6:
  IFN FTYANK,<
	SKIPN	T,BPT$B+B$STR(S);GOT A COMMAND STRING TO BE EXECUTED?
	JRST	RET		;NO, BREAKPOINT COMPLETE THEN
	MOVEM	T,COMAND	;YES, FLAG NOW IN A "COMMAND FILE"
	MOVEM	T,COMCOR	;AND NOTE IT IS FROM A MEMORY STRING
	HRLI	T,(POINT 7,)	;CONCOCT A BYTE POINTER
	MOVEM	T,CBUF+1	;TELL TIN WHERE TO FIND THE COMMAND
  > ;END IFN FTYANK
	JRST	RET		;BREAKPOINT NORMALLY
;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,INSRT8	;IF 0 THEN NO BREAKPOINT HERE
  IFN FTMON,<CHKIN>		;INTERLOCK IN MDDT
	MOVE	T,BPT$B+B$FLG(S);FETCH THIS BREAKPOINT'S FLAGS
	TXNE	T,BP$INS	;IS BPT STILL INSERTED (REMOVE FAILED)?
	JRST	INSRT8		;YES, LEAVE WELL ENOUGH ALONE
	PUSHJ	P,FETCH		;GET USER INSTRUCTION
	 JRST	INSRT5		;CAN'T, COMPLAIN
	MOVEM	T,BPT$B+B$INS(S);SAVE USER INSTRUCTION FROM BREAKPOINT
	PUSHJ	P,MAKBPT	;MAKE A BREAKPOINT INSTRUCTION
	PUSHJ	P,CHKBPT	;VERIFY THAT WE CAN USE IT
	 JRST	INSRT4		;OOPS, ERROR
	JUMPE	TT,INSRT6	;IF "LOCAL", JUST INSERT BPT DIRECTLY

;"GLOBAL" BREAKPOINT = JSR TO AN XJRST TO DDT'S "JSR BCOMG"

	SETZM	BPT$B+B$BPT(S)	;CLEAR JSR (E) FOR LOCAL/GLOBAL CHECK
	PUSHJ	P,DEPMEM	;PUT "GLOBAL" BREAKPOINT INTO PROGRAM
	 JRST	INSRT5		;CAN'T, COMPLAIN
	HRRI	R,1(T)		;ADDRESS FOR THE XJRST
	MOVSI	T,(XJRST)	;BUILD "XJRST .+1"
	HRRI	T,1(R)
	PUSHJ	P,DEPMEM	;PUT XJRST INTO GLOBAL BREAKPOINT BLOCK
	 JRST	INSRT5		;COMPLAIN
	HRRI	R,1(R)		;"E" OF "XJRST .+1"
	XMOVEI	T,BPT$B+B$JSR(S);ADDRESS OF DDT'S BPT ENTRY
INSRT6:	PUSHJ	P,DEPMEM	;STUFF INTO USER PROGRAM
	 JRST	INSRT5		;COMPLAIN
	MOVE	T,BPT$B+B$FLG(S);FETCH BREAKPOINT'S FLAGS
	TXO	T,BP$INS	;BREAKPOINT HAS BEEN INSTALLED
	TXZ	T,BP$ERM	;AND HAS NO COMPLAINTS
	MOVEM	T,BPT$B+B$FLG(S);REMEMBER THAT
INSRT8:	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

INSRT4:	SMERS	<IS IN DIFFERENT SECTION>	;CAN'T SET BPT
INSRT5:	PUSHJ	P,INSRER	;NOTIFY USER
  IFN FTMON,<CHKOUT>		;RELEASE ONE LOCK.
	MOVX	TT,BP$INS	;BREAKPOINT-INSTALLED FLAG
	ANDCAM	TT,BPT$B+B$FLG(S) ;THIS BPT NOT INSTALLED
	JRST	INSRT8		;TRY THE NEXT ONE
;STILL IFE FTFILE

;BUILD "LOCAL" OR "GLOBAL" BREAKPOINT INSTRUCTION
;
;BREAKPOINT INSTRUCTIONS COME IN TWO FLAVORS:
;	JSR	$NB+B$BPT		;LOCAL BREAKPOINT
;	JSR	BPBLK+N			;GLOBAL BREAKPOINT
;IN THE CASE OF A GLOBAL BREAKPOINT, THE CALLER MUST PUT THE XJRST AND
;THE FINAL DESTINATION ADDRESS ($NB+B$JSR) IN THE BREAKPOINT BLOCK.
;
;CALL:
; R/	ADDRESS OF BREAKPOINT
; S/	BREAKPOINT "INDEX"
;	PUSHJ	P,MAKBPT
; T/	BREAKPOINT INSTRUCTION OR 0 IF ERROR.
; TT/	0 IF "LOCAL" BREAKPOINT, ADDRESS FOR XJRST IF "GLOBAL" BREAKPOINT
;
;THE CALLER IS RESPONSIBLE FOR VALIDITY-CHECKING THINGS (CALLING CHKBPT).

MAKBPT:	HRRZ	T,BPBLK		;GET GLOBAL BREAKPOINT BLOCK (IF ANY)
	JUMPN	T,MAKBP3	;IF SET, THEN ALL BREAKPOINTS ARE "GLOBAL"
	MOVSI	T,(JSR)		;LOCAL BREAKPOINT, JUST NEED JSR
	HRRI	T,BPT$B+B$BPT(S); INTO BREAKPOINT AREA
	SETZ	TT,		;FLAG ZERO FOR "LOCAL" BREAKPOINT
	POPJ	P,		;ALL DONE

MAKBP3:	MOVE	TT,S		;NEED REAL BPT INDEX
	IDIVI	TT,B$SIZ	;GET BPT NUMBER
	SOS	TT		;NO BPT 0 IN BPBLK
	IMULI	TT,NBPBW	;GET BPBLK OFFSET
	ADD	T,TT		;OFFSET INTO GLOBAL BREAKPOINT BLOCK
	HRLI	T,(JSR)		;FINISH CONCOCTING "GLOBAL" BPT INST
	AOJA	TT,CPOPJ	;RETURN WITH T/INST AND TT/NONZERO
;STILL IFE FTFILE

;CHKBPT - VERIFY THAT BREAKPOINT FROM MAKBPT CAN BE INSERTED
;CALL IS:
;
;	PUSHJ	P,MAKBPT
;	PUSHJ	P,CHKBPT
;	 ERROR RETURN
;	NORMAL RETURN
;
;ON ENTRY, ASSUMES ACS AS SETUP VIA MAKBPT.
;
;ON ERROR RETURN, THE BREAKPOINT CAN'T BE SET - EITHER DDT IS NOT MAPPED
;INTO THE SECTION FOR A LOCAL BREAKPOINT, OR THE GLOBAL BREAKPOINT BLOCK
;DOESN'T EXIST/ISN'T WRITABLE.
;
;ON NORMAL RETURN, THE BREAKPOINT CAN SAFELY BE INSERTED.

CHKBPT:	PUSHJ	P,SAVRST	;SAVE THE REGS
	PUSH	P,TT		;SAVE TT ALSO
	JUMPN	TT,CHKBP5	;IF GLOBAL, VERIFY THE $4M BLOCK

;LOCAL BREAKPOINT, DDT MUST BE MAPPED IN THE BREAKPOINT SECTION

	ANDCMI	R,-1		;JUST SECTION NUMBER
	CAMN	R,SECDDT	;BREAKPOINT TO DDT'S SECTION?
	JRST	CHKBP7		;YES, OK THEN
	PUSHJ	P,RWEMAP	;ARE WE MAPPED IN THE RIGHT SECTION?
	 JRST	CHKBP8		;NO, THEN THIS BREAKPOINT CAN'T BE DONE
	JRST	CHKBP7		;YES, THIS BREAKPOINT IS OK

;GLOBAL BREAKPOINT, VERIFY THE $4M BLOCK

CHKBP5:	HRR	R,BPBLK		;SECTION-RELATIVE $4M BLOCK
	PUSHJ	P,CHKBP6	;CHECK PAGE ACCESSIBILITY
	  JRST	CHKBP8		;NO, CAN'T SET A BREAKPOINT HERE
	ADDI	R,BPBLEN	;RANGE-CHECK END OF BLOCK
	PUSHJ	P,CHKBP6	;GET PAGE ACCESSIBILITY
	TRNA			;NON-WRITABLE
CHKBP7:	AOS	-1(P)		;YES, SUCCESSFUL (SKIP) RETURN INDICATED
CHKBP8:	POP	P,TT		;RESTORE LOCAL/GLOBAL FLAG
	POPJ	P,		;RETURN AS APPROPRIATE

;HERE TO CHECK BP BLOCK ADDRESSES FOR WRITEABLE/CREATEABLE
CHKBP6:	PUSHJ	P,CHKADR	;GET PAGE ACCESSIBILITY
	TXNE	TT,PG$WRT	;IF ALREADY WRITABLE,
	JRST	CPOPJ1		;JUST RETURN SUCCESS
	TXNE	TT,PG$EXI	;IF NON-WRITABLE BUT IT EXISTS,
	POPJ	P,		;WE LOSE
	SETZ	T,		;GET A ZERO TO DEPOSIT
	PUSHJ	P,DEPMEM	;TRY TO CREATE THE PAGE
	  POPJ	P,		;LOSE IF WE CAN'T
	PUSHJ	P,CHKADR	;GET NEW PAGE ACCESSIBILTY
	TXNE	TT,PG$WRT	;IF NOW WRITABLE,
	AOS	(P)		;WE WILL SUCCEED
	POPJ	P,		;OTHERWISE FAIL
;RWEMAP - VERIFY THAT DDT IS MAPPED INTO SPECIFIED VIRTUAL SECTION
;CALL IS:
;
;	MOVX	R,<ADR>
;	PUSHJ	P,RWEMAP
;	 ERROR RETURN
;	NORMAL RETURN
;
;WHERE <ADR> IS THE "USER VIRTUAL ADDRESS" INTO WHICH SECTION DDT MUST BE
;MAPPED (CALLED FROM $X).
;
;ON ERROR RETURN DDT IS DEFINITELY NOT MAPPED INTO THE DESIRED VIRTUAL
;SECTION.
;
;ON NORMAL RETURN, DDT IS MOST PROBABLY MAPPED INTO THE DESIRED VIRTUAL
;SECTION.

RWEMAP:	PUSHJ	P,SAVRST	;SAVE CALLER'S "R", "S", AND "T" REGISTERS
	MOVE	T,PCFLG		;GET A RELATIVELY-RANDOM BIT PATTERN
	XOR	T,PCWRD		;MAKE IT A TAD MORE RANDOM
	PUSH	P,T		;MAKE A SCRATCHABLE COPY OF IT
	HRR	R,P		;GLOBAL REFERENCE TO RANDOM BIT PATTERN
	PUSHJ	P,FETCH		;FETCH OTHER-SECTION'S CONTENTS
	 JRST	RWEMA8		;WE DEFINITELY ARE *NOT* MAPPED
	CAME	T,0(P)		;THAT SECTION MATCH OUR SECTION?
	JRST	RWEMA8		;NO, THEN NOT MAPPED
	SETCMM	0(P)		;NOW CHANGE OUR LOCAL COPY
	PUSHJ	P,FETCH		;AND FETCH OTHER-SECTION'S COPY
	 JRST	RWEMA8		;DUH????
	CAME	T,0(P)		;DOES IT STILL MATCH?
	JRST	RWEMA8		;NO, THEN NOT MAPPED AFTER ALL (SNEAKY!)
	POP	P,T		;YES, ALMOST CERTAINLY MAPPED TOGETHER
	JRST	CPOPJ1		;TAKE GOOD (MAPPED) RETURN

RWEMA8:	POP	P,T		;PITCH RANDOM BIT PATTERN
	POPJ	P,		;TAKE BAD (UNMAPPED) RETURN
;STILL IFE FTFILE

;REMOVE BREAKPOINTS

REMOVB:	PUSHJ	P,SAVRST	;SAVE A FEW REGISTERS
	MOVEI	S,B$SIZ*NBP	;START WITH LAST BPT
REMOV1:	SKIPG	R,BPT$B+B$ADR(S);ADDRESS OF THIS BREAKPOINT (IF ANY)
	JRST	REMOV8		;NONE
	MOVE	T,BPT$B+B$FLG(S);FETCH BREAKPOINT'S FLAGS
	TXNN	T,BP$INS	;IS IT INSTALLED?
	JRST	REMOV8		;NO, AND USER ALREADY KNOWS
	PUSHJ	P,FETCH		;GET CURRENT BREAKPOINT INSTR
	 JRST	REMOV6		;CAN'T READ IT?  LET THE WRITE FAIL...
	MOVE	W2,T		;SAVE THE INSTRUCTION
	PUSHJ	P,MAKBPT	;GET THE EXPECTED INSTRUCTION
	CAME	W2,T		;IS OUR BREAKPOINT SAFE?
	JRST	REMOV4		;NO - TRASHED OR MOVED
REMOV6:	MOVE	T,BPT$B+B$INS(S);INSTRUCTION THAT BELONGS AT THIS BPT
	PUSHJ	P,DEPMEM	;PUT USER INSTRUCTION BACK
	 JRST	REMOV5		;CAN'T, COMPLAIN
	MOVX	T,BP$INS!BP$ERM	;BREAKPOINT-INSTALLED, ERROR FLAGS
	ANDCAM	T,BPT$B+B$FLG(S);NOTE BREAKPOINT SUCCESSFULLY REMOVED
REMOV7:
  IFN FTMON,<CHKOUT>		;RELEASE ONE LOCK.
REMOV8:	SUBI	S,B$SIZ		;ADVANCE TO NEXT BREAKPOINT
	CAIL	S,B$SIZ		;DONE THEM ALL YET?
	JRST	REMOV1		;NO, GO REMOVE NEXT ONE
	POPJ	P,		;YES, ALL BREAKPOINTS REMOVED

REMOV4:	SMERS	<BREAKPOINT INSTRUCTION TRASHED OR MOVED>
REMOV5:	PUSHJ	P,REMOER	;TELL USER CAN'T REMOVE BPT
	JRST	REMOV7		;TRY FOR THE REST
;STILL IFE FTFILE

;ISSUE DIAGNOSTIC IF BPT INSERTION/REMOVAL FAILS.  USER SHOULD KNOW HE
;IS BEING SCREWED.

REMOER:	SKIPA 	W1,[[ASCIZ /% CAN'T REMOVE $/]]
INSRER:	MOVEI	W1,[ASCIZ /% CAN'T INSERT $/]
	MOVX	TT,BP$ERM	;MESSAGE-TYPED FLAG
	TDNE	TT,BPT$B+B$FLG(S) ;ALREADY TOLD USER OF THIS PROBLEM?
	POPJ	P,		  ;YES, ONCE IS ENOUGH
	IORM	TT,BPT$B+B$FLG(S) ;NO, REMEMBER WE'RE ABOUT TO
	PUSH	P,S		;SAVE INDEX
	PUSHJ	P,TSTRG		;BEGIN MESSAGE
	MOVE	A,S
	IDIVI	A,B$SIZ		;GET BPT NUMBER
	PUSHJ	P,FP7		;TYPE IT
	MOVEI	W1,[ASCIZ /B BECAUSE /]
	PUSHJ	P,TSTRG
	SKIPN	W1,MEMERS	;HAVE SPECIFIC MESSAGE?
	MOVEI	W1,[ASCIZ /MEM REF FAILED/] ;NO, GENERAL ONE
	PUSHJ	P,TSTRG
	POP	P,S
	PJRST	TCRLF		;CRLF AND RETURN

  > ;END IFE FTFILE
SUBTTL	ENTER AND LEAVE DDT -- FAKDDT

  IFN FTEX20,<			;ONLY IN KDDT

;FAKDDT -- FAKE OUT BREAKPOINTS AFTER KDDT CHANGES SECTION.
;CALL:
;	JSR	@[SECDDT,,FAKDDT]
;	RETURN
;
;CALLED BY TOPS-20 DIRECTLY, AFTER KDDT HAS BEEN MOVED FROM ONE SECTION
;TO ANOTHER.  MAKES SURE THAT ALL BREAKPOINTS WILL BREAK TO THE CORRECT
;SECTION, AND DOES SOME MANIPULATION OF $5M AND $6M SO THE DEFAULTS
;WORK OUT OK UNDER ALL CIRCUMSTANCES.

FAKDDG:	JSR	SAVE		;ENTER DDT CONTEXT
	 PUSHJ	P,REMOVB	;PUT ORIGINAL BPT INSTRS BACK

	SETZM	SYTLOC		;0$5M (POSTLD CHANGES MONPDV)

	SKPEXC			;FIGURE OUT DEFAULT FOR $6M
	TDZA	T,T		;USER MODE DOESN'T HAVE SECTIONS 0 AND 1
	MOVX	T,<MSEC1,,0>	; MAPPED TOGETHER, EXEC MODE DOES
	MOVEM	T,PDFSEC	;SET $6M

	MOVE	T,FAKDDT	;GET RETURN ADDRESS
	SKPNS0			;IN SECTION ZERO?
	TLZ	T,-1		;CLEAR RANDOM FLAGS
	PUSHJ	P,INSRTB	;PUT IN BREAKPOINTS TO WHERE WE ARE NOW
	JRST	RESTOR		;BACK TO TOPS-20

  > ;END IFN FTEX20
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&FTDEC10,<
	MOVEM	T,POKBLK+1	;STORE FOR /P/M LOGIC
  > ;END IFN FTFILE&FTDEC10
	TRNN	F,LF1
	JRST	(SCH)		;PIN OR FTOC
	TRNE	F,CF1
	JRST	FTOC		;TYPE OUT AS CONSTANT

;PRINT OUT IN INSTRUCTION FORMAT
;LOOK FOR MACHINE INSTRUCTIONS BEFORE USER-DEFINED OPCODES

PINQ:	TDC	T,[XWD -1,400000] ;IS THIS A NEGATIVE NUMBER?
	TDCN	T,[XWD -1,400000]
	JRST	PADS3B		;TYPE AS NEG NUM
	HLLZ	T,LWT		;LOOK AT OPCODE ONLY
	TLZ	T,777
	JUMPE	T,HLFW		;DO HALFWORDS IF NOT A POSSIBLE OPCODE
	TXNE	T,700B8		;POSSIBLY A MACHINE CODE?
	CAMN	T,[JSYS]	;BUT NOT JSYS?
	 JRST	PIN0A
	TLC	T,700000	;CHECK FOR AN I/O INSTRUCTION
	TLCN	T,700000	;NEED TO DECODE FIELDS DIFFERENTLY IF SO
	 JRST	INOUTB		;IS AN I/O INST, GO HANDLE IT
	PUSHJ	P,OPTYPE	;YES, TRY FOR IT
	TRNE	F,ITF		;DID OPCODE?
	JRST	PIN2		;YES, CONTINUE WITH REST OF INST
	JRST	PIN0A		;NO, TRY COMBINATIONS FROM SYM TAB

;LOOK FOR USER-DEFINED OPCODES BEFORE MACHINE INSTRUCTIONS

PIN:	TDC	T,[XWD -1,400000] ;IS THIS A NEGATIVE NUMBER?
	TDCN	T,[XWD -1,400000]
	JRST	PADS3B		;TYPE AS NEG NUM
PIN0A:	MOVE	T,LWT		;GET FULL WORD
	TXNE	T,777B8		;IF THERE'S AN OPCODE,
	TRO	F,OKAF		;DON'T TYPE "#" AFTER OPERATOR
	PUSHJ	P,LOOK		;DO 36-BIT OPERATOR SEARCH
	 JRST	PIN0B		;NOPE
	 JRST [	CAMGE	S,SYMOFS	;WITHIN RANGE?
		TXNE	T,^-VMADR	;AND A GLOBAL ADDR?
		JRST	PIN0B		;NO, TRY SOMETHING ELSE
		JRST	PADSOE]		;YES, TYPE SYMBOL+OFFSET
	POPJ	P,		;EXACT MATCH, ALL DONE
;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
	TXNN	T,777B8		;0 OPCODE?
	JRST	HLFW		;YES, NEVER PRINT AS INSTRUCTION
  IFN FTOPX,<			;SKIP THIS IF WE WANT TO BE FAST
	MOVE	T,LWT		;FRESH COPY OF WORD
	TXNN	T,<Z @-1(17)>	;IS E-FIELD ALL ZERO?
	JRST	PIN0D		;YES, NO SPECIAL SEARCH
	TXZ	T,<Z 17,>	;MASK OUT AC FIELD
	CAME	T,[TTCALL 0,]	;DON'T TYPE "INCHRW 17,"
	PUSHJ	P,LOOK		;LOOK FOR SYMBOLIC OPERATOR
	 JRST	PIN0D		;NOPE
	 JRST	PIN0D		;NOPE
	PUSHJ	P,TSPC		;MATCH!!! SPACE OVER
	LDB	T,[POINT 4,LWT,12]  ;GET AC FIELD
	JUMPE	T,CPOPJ		;AC FIELD NULL, ALL DONE
	PUSHJ	P,PAD		;TYPE OUT SYMBOLIC AC FIELD
	MOVEI	T,","		;CAP OFF AC FIELD WITH COMMA
	PJRST	TOUT		;AND TYPEOUT IS COMPLETE
;STILL IFN FTOPX

;NOW TRY FOR OPCODE AND AC FIELD

PIN0D:	HLLZ	T,LWT		;FRESH COPY OF WORD
	TXZ	T,37B17		;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		;SEE IF ANY SUCH ANIMAL
	 JRST	PIN0F		;NOPE
	 JRST	PIN0F		;NOPE
	TXO	F,NAF		;YEP, SO ALLOW NEGATIVE ADDRESS
	PUSHJ	P,TSPC		;SPACE OVER ONE
	JRST	PI4		;AND GO TYPE OUT I, X, AND Y
  > ;END IFN FTOPX

;LAST TRY FOR A USER SYMBOL - OPCODE FIELD ONLY

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

;LAST DITCH - LOOK AT NORMAL HARDWARE OPCODES

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

;FALL INTO PIN2 ON NEXT PAGE
;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:	TRO	F,ITF		;FLAG INSTRUCTION IN PROGRESS
	CAIE	AR,TOC		;IF NOT $A
	HLL	T,LLOCS		;ADDRESS STARTS WITH CURRENT SECTION
	PUSHJ	P,PADR1		;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:	TXZ	F,ITF		;NOT IN INSTRUCTION TYPEOUT
PADR1:	TXZ	F,OKAF		;WANT # TO SHOW UP
	TLNN	T,377777	;DDAF VALID ONLY ON PURE IFIW
	TXZN	T,DDAF		;DDT INTERNAL ADDRESS?
	JRST	(AR)		;NO, PADSO OR TOC
	MOVE	TT,T
	PUSHJ	P,DDSYMC	;YES, LOOK IT UP
	 JRST [	MOVEI	T,"?"	;NOT VALID
		PJRST	TOUT]	;TYPE QMARK
	SUB	T,TT2		;CONVERT ADR TO OFFSET
	MOVEM	T,TEM		;SAVE OFFSET
	MOVE	W1,1(TT1)	;GET TEXT FOR INTERNAL NAME
	PUSHJ	P,TEXT2		;TYPE IT
	SKIPN	TEM		;OFFSET?
	POPJ	P,		;NO, DONE
	JRST	PADS2		;YES, GO TYPE IT

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
PADSOE:	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
PADS2:	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:	TRNE	F,ITF		;INSTRUCTION ALREADY TYPED?
	JRST	PAD		;YES, DON'T USE HALFWORD FORMAT
	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,<			;LOOK FOR USER OPERATORS
	AND	T,[777740,,0]	;OPERATOR & DEVICE CODE
	TRO	F,OKAF		;NO "#" AFTER OPERATOR SYMBOL
	PUSHJ	P,LOOK		;LOOK FOR USER-DEFINED OPERATOR
	 JRST	INOUTB		;NOPE
	 JRST	INOUTB		;NOPE
	TRZ	F,OKAF		;FOUND ONE, CLEAR KROCK FLAG
	PUSHJ	P,TSPC		;SPACE OVER FROM OPERATOR SYMBOL
	JRST	PI4		;GO TYPE OUT I, X, AND Y FIELDS

INOUTB:	MOVSI	T,777000	;JUST THE OPCODE FIELD
	AND	T,LWT		;(IN CASE KS-10 STYLE I/O INSTRUCTION)
	LDB	R,[POINT 6,T,8]	;EXTRACT MOST OF "DEVICE" FIELD
	CAIL	R,04		;IF 'LESS' THAN "UMOVE"
	SKPKS			;OR NOT KS-STYLE IO DECODE
	JRST	INOUT3		;THEN NO "NORMAL" OPCODE TYPEOUT
	TRO	F,OKAF		;NO "#" AFTER OPERATOR SYMBOL
	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		;CLEAR KROCK FLAG
	MOVE	T,LWT		;RESTORE T
  > ;END OF IFN FTOPX
  IFE FTOPX,<INOUTB==INOUT>

	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
	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
;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
	CAILE	T,44		;ONE-WORD GLOBAL?
	 JRST	TBPNT1		;YES, HANDLE DIFFERENTLY
TBPNT0:	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
	MOVE	T,LWT		;GET THE BYTE POINTER
	TLNN	R,-1		;GET HERE FOR SECTION 0?
	 JRST	PI4		;YES, DO NORMAL ADDR TYPEOUT
	MOVE	R,LLOCO		;GET THE BYTE POINTER'S LOC
	HLLZ	S,R		;FIND ITS SECTION
	TXNN	R,-20		;IN ACS?
	 HLLZ	S,PCWRD		;YES, USE PC SECTION INSTEAD
	JUMPE	S,PI4		;NORMAL IF FROM SECTION 0
	TLNN	T,(1B12)	;TWO-WORD POINTER?
	 JRST	PI4		;NO, DO NORMALLY
	HRRI	R,1(R)		;YES, GET SECOND WORD
	MOVEI	W1,"?"		;IN CASE NOT FOUND
	PUSHJ	P,FETCH		;LOOK FOR SECOND WORD
	 JRST	TEXT		;NOT FOUND
	MOVEM	T,LWT		;WORKING ON SECOND WORD NOW
	SKIPGE	W1,T		;IFIW ON?
	 JRST [	PUSHJ	P,PI4	;YES, DO NORMALLY
		JRST	FLAG2W]
	MOVEI	T,"@"		;INDIRECTION SYMBOL
	TXNE	W1,EFIWI1	;GLOBAL INDIRECTION?
	 PUSHJ	P,TOUT		;YES, TYPE IT
	LDB	T,[POINTR LWT,VMADR] ;GET GLOBAL ADDRESS
	PUSHJ	P,PADR		;TYPE IT OUT (WITH SECTION NO.)
	LDB	W1,[POINTR LWT,EFIWX] ;GET X FIELD
	JUMPE	W1,FLAG2W	;JUMP OVER INDEX TYPEOUT
	MOVEI	T,"("		;TYPE INDEX OUT
	PUSHJ	P,TOUT
	MOVE	T,W1
	PUSHJ	P,PAD		;WITH SYMBOL IF APPROPRIATE
	MOVEI	T,")"
	PUSHJ	P,TOUT
FLAG2W:	MOVE	W1,[ASCII \ <2>\]	;FLAG TWO-WORD POINTER
	JRST	TEXT2		;AND GO HOME
;HERE FOR ONE-WORD GLOBAL
TBPNT1:	CAIN	T,77		;IS IT LEGAL?
	 JRST	TBPNT0		;NO, DON'T FOOL WITH IT
	MOVEI	TT,-44(T)	;SUBTRACT 44 FROM CODE
	ADJBP	TT,[POINT 6,PTBL] ;COMPUTE TABLE LOCATION
	LDB	T,TT		;GET DECODED P NUMBER
	PUSHJ	P,TOC		;TYPE IT OUT
	MOVEI	T,"&"		;AS IN P&S
	PUSHJ	P,TOUT
	ADDI	TT,STBL-PTBL	;SAME PLACE IN S TABLE
	LDB	T,TT		;GET DECODED S NUMBER
	PUSHJ	P,TOC		;TYPE IT OUT
	PUSHJ	P,TSPC		;NEATLY
	LDB	T,[POINTR LWT,VMADR] ;GET THE 30-BIT ADDRESS
	JRST	PADR		;AND TYPE IT ALL OUT

PTBL:	BYTE(6)	44,36,30,22,14, 6
	BYTE(6)	 0,44,34,24,14, 4
	BYTE(6)	44,35,26,17,10, 1
	BYTE(6)	44,33,22,11, 0,44
	BYTE(6)	22, 0

STBL:	BYTE(6)	 6, 6, 6, 6, 6, 6
	BYTE(6)	 6,10,10,10,10,10
	BYTE(6)	 7, 7, 7, 7, 7, 7
	BYTE(6)	11,11,11,11,11,22
	BYTE(6)	22,22
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"		;RADIX-DIGIT .GT. 9?
	ADDI	T,"A"-"9"-1	;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
	PUSHJ	P,PSYMT		;CONVERT RADIX50 TO ASCII
	PJRST	TOUT		;TYPE IT AND RETURN

PSYMT:	ADDI	T,"0"-1		;CONVERT DIGIT
	CAILE	T,"9"		;WAS IT A DIGIT?
	ADDI	T,"A"-"9"-1	;NO, TRY A LETTER
	CAILE	T,"Z"		;DID THAT FIT?
	SUBI	T,"Z"+2-"$"	;NO, TRY FOR PUNCTUATION
	CAIN	T,"$"-1		;IS IT THE ODDBALL PUNCTUATION?
	MOVEI	T,"."		;YES, CONVERT TO THAT
	CAIN	T,"0"-1		;OH, BY THE WAY,
	MOVEI	T," "		;ACCOUNT FOR SPACE
	POPJ	P,		;RETURN THE CONVERTED CHARACTER
;FLOATING POINT OUTPUT

TFLOT:
  IFN FTDEC20,<			;USE "FLOUT" JSYS ON TOPS-20
    IFN FTEXEC,<
	SKPUSR			;IN USER MODE?
	JRST TFLOTE		;NO, CAN'T USE JSYSES
    > ;END IFN FTEXEC
	MOVEI	T1,"-"		;LOAD A MINUS SIGN IN CASE IT'S NEEDED
	TLNE	T,(1B0)		;IS NUMBER NEGATIVE?
	PBOUT%			;YES, TYPE THE MINUS SIGN
	MOVM	A,T		;NO, GET POSITIVE COPY OF NUMBER
	TLNN	A,400		;IS NUMBER NORMALIZED?
	JRST	TOC5		;NO, TYPE AS DECIMAL INTEGER
	MOVEI	T1,.PRIOU	;LOAD POINTER TO TTY,THEN FLOUT BITS
	MOVX	T3,FLD(.FLTSP,FL%JUS)!FLD(.FLEXE,FL%EXP)!FLD(.FLPLE,FL%ESG)
!FLD(37,FL%RND)!FLD(1,FL%FST)!FLD(7,FL%SND)!FLD(4,FL%THD)  ;GET FLOUT BITS
	FLOUT%			;TYPE THE NUMBER
	JRST	ERR		;SOMETHING FAILED, PUNT
	POPJ	P,		;DONE
  > ;END IFN FTDEC20

  IFN FTDEC10!FTEXEC,<		;FLOATING OUTPUT THE HARD WAY ON TOPS-10
TFLOTE:	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

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

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
	SETZ	W2,
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
  > ;END IFN FTDEC10!FTEXEC
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,"0"
	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

  IFN FTDEC10!FTEXEC,<		;CONTINUE TOPS-10 FLOATING STUFF
FT0=FT01+1

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

FSGN:	ASCII	.E-.
	ASCII	.E+.
  > ;END IFN FTDEC10!FTEXEC

  IFN FTDEC20,<			;DBL. PRECISION TYPEOUT ONLY ON TOPS-20
DFLOUT:
  IFN FTEXEC,<
	SKPUSR			;IN USER MODE?
	JRST	ERR		;NO, CAN'T DO THIS
  > ;END IFN FTEXEC
	PUSH	P,T		;SAVE FIRST WORD
	MOVE	R,LLOCO		;GET ADDR. OF FIRST WORD OF NUMBER
	AOS	R		;INCREMENT TO NEXT WORD
	PUSHJ	P,FETCH		;GET IT
	  JRST	ERR		;FAILED
	MOVE	T3,T		;PUT SECOND WORD IN T3
	POP	P,T2		;RESTORE FIRST WORD
	MOVEI	T1,.PRIOU	;LOAD POINTER TO TTY,THEN FLOUT BITS
	MOVX	T4,FLD(.FLSPC,FL%SGN)!FLD(.FLTSP,FL%JUS)!FLD(.FLEXD,FL%EXP)!
FLD(.FLPLE,FL%ESG)!FLD(37,FL%RND)!FLD(2,FL%FST)!FLD(^D17,FL%SND)!FLD(4,FL%THD)
	DFOUT%			;TYPE THE NUMBER
	JRST	ERR		;SOMETHING FAILED, PUNT
	POPJ	P,		;DONE
  > ;END IFN FTDEC20
	
;TEXT OUTPUT SUBROUTINES

;ROUTINE TO OUTPUT TEXT A LA $NT

TEXTNT:	MOVE	W1,T		;FREE T FOR TOUT LOOP BELOW
	MOVN	W2,BYSS		;GET RIGHT-SHIFT AMOUNT
	LSH	T,(W2)		;DROP LOW BYTE
	JUMPN	T,TEXTN1	;SKIP THIS IF NOT RIGHT-JUSTIFIED
	ROT	W1,(W2)		;LEFT-JUSTIFY ARGUMENT
TEXTN1:	LSHC	T,@BYSS		;FETCH NEXT BYTE TO TYPE
	ANDI	T,177		;TOUT ONLY WANTS 7 BITS
	PUSHJ	P,TOUT		;OUTPUT ONE ASCII CHARACTER
	JUMPN	W1,TEXTN1	;LOOP IF MORE IN WORD TO TYPE
	POPJ	P,		;RETURN WHEN DONE

;ROUTINE TO OUTPUT TEXT A LA $7T

TEXTT:	MOVE	W1,T
TEXT:	TDNN	W1,[-1,,777600]	;LEFT JUSTIFIED UNLESS ONLY 1 CHR.
	LSH	W1,35
TEXT2:	SETZ	T,		;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:	SETZ	T,
	ROTC	T,6
	ADDI	T,40
	PUSHJ	P,TOUT
	AOJL	W2,SIXBP1
	POPJ	P,
;LOOKUP DDT INTERNAL ADDRESS
; TT/ ADDRESS
;	PUSHJ	P,DDSYMC
; RETURNS +1: FAILED TO FIND ADDRESS
;	+2: FOUND,
;		TT1/ PTR TO BLOCK - 1(TT1) IS PTR TO NAME STRING
;		TT2/ FIRST ADDRESS OF RANGE OF INTERNAL LOCATIONS

DDSYMC:	MOVE	TT1,[-NDSYM,,DSYMT] ;INIT TO LOOK THRU TABLE
DDSYM1:	HRRZ	TT2,0(TT1)	;END OF RANGE FOR THIS SYMBOL
	CAML	TT,TT2		;ADR TOO HIGH?
	JRST	DDSYM2		;YES
	HLRZ	TT2,0(TT1)	;BEGINNING OF RANGE
	CAML	TT,TT2		;ADR TOO LOW?
	JRST	CPOPJ1		;RETURN GOOD
DDSYM2:	ADDI	TT1,1		;STEP TO NEXT BLOCK
	AOBJN	TT1,DDSYM1
	POPJ	P,		;FAILED

;TABLE OF DDT INTERNAL LOCATIONS

DEFINE DS (NAM,FST,LST)<
	FST,,LST
	ASCII /NAM/>

DEFINE DSB (N)<
	DS ($'N'B,BPT$B+B$SIZ*N,BPT$B+B$SIZ*N+B$SIZ)>

DSYMT:	DS $M,MSK,MSK+1
	DS $1M,TTYMSK,TTYMSK+1
	DS $2M,SYMOFS,SYMOFS+1
	DS $3M,BYTMSK,BYTMSK+1
	DS $4M,BPBLK,BPBLK+1
	DS $5M,SYTLOC,SYTLOC+1
	DS $6M,PDFSEC,PDFSEC+1

	DS $I,SAVPI,ENDPI

IFN FTPAGM,<
	DS $0U,MAPPG,MAPPG+1
	DS $$0U,MAPFN,MAPFN+1
	DS $3U,FAKEAC,FAKEAC+1
	DS $4U,ACWRD,ACWRD+1
	DS $5U,FAKEAD,FAKEAD+1
	DS $6U,SPTWRD,SPTWRD+1
	DS $7U,CSTWRD,CSTWRD+1
	DS $8U,UBASE,UBASE+1
	DS $9U,UPROT,UPROT+1
	DS $10U,KIPAG,KIPAG+1
	DS $11U,KLPAG,KLPAG+1
	DS $20U,KAFLG,KAFLG+1
	DS $21U,KIFLG,KIFLG+1
	DS $22U,KLFLG,KLFLG+1
	DS $23U,KSFLG,KSFLG+1
> ;END IFN FTPAGM

  IFE FTFILE,<
	YY==10			;SAVE RADIX
	RADIX 10		;SET TO DECIMAL FOR MACROS
	ZZ==0
  REPEAT NBP+1,<
	DSB (\ZZ)
	ZZ=ZZ+1			;DO ALL BREAKPOINTS INCLUDING $0B
  > ;END REPEAT
	RADIX YY		;RESTORE RADIX
  > ;END IFE FTFILE
NDSYM==<.-DSYMT>/2		;NUMBER OF INTERNAL LOCATIONS
SUBTTL	SYMBOL TABLE ROUTINES -- CHECK POINTERS

;SYMCHK -- SUBROUTINE TO CHECK OUT SYMBOL TABLE PTRS
;CALL IS:
;
;	PUSHJ	P,SYMCHK
;	RETURN
;
;DETERMINES THE SYMBOL TABLE POINTER TO USE, AND MAKES SURE THAT ALL
;PAGES OF IT ARE ACCESSIBLE.  IF PRGM IS SET ($: MODULE) IT CHECKS ITS
;VALIDITY ALSO.  IF THE UNDEFINED POINTER IS NO GOOD, IT IS FIXED UP TO
;POINT TO THE END OF ONE OF THE DEFINED TABLES.
;
;USES JUST ABOUT EVERY AC
;PRESERVES W (FOR COMMAND PARSER)

SYMCHK:	SKIPE	SYMVAL		;HAS THIS ALREADY BEEN DONE?
	POPJ	P,		;YES, DON'T DO IT AGAIN
	PUSH	P,W		;DECSYP ET AL TRASH THIS, PARSER NEEDS IT

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;FIRST THE CASE FOR MONITORS.

IFN FTEXEC!FTMON,<		;ALL MONITORS

SYMCX0:

  IFN FTDEC10,<			;TOPS-10
	SKPUSR			;IF USER MODE,
	SKIPN	HSBLK		;OR NOT HIDING SYMBOLS
	JRST	SYMCU0		;LOOK FOR SYMBOLS NORMALLY
				;EXEC HIDDEN SYMBOLS, USE AS SPECIFIED
				;IN S$SUB ENTRIES (SEE TTYRE7)
  > ;END IFN FTDEC10

  IFN FTDEC20,<
    IFN FTEXEC&<^-FTEX20>,<	;EDDT, NOT KDDT
	SKPEXC			;IF USER MODE,
	JRST	SYMCU0		;THEN DO LIKE USER DDT
    > ;END IFN FTEXEC&<^-FTEX20>
    IFN FTEX20!FTMON,<		;TOPS-20 MONITOR
	MOVE	R,[MSEC1,,MONPDV]  ;GLOBAL ADDR OF MONITOR PDV FLAG
      IFN FTEX20,<
	SKPUSR			;USER MODE, OR
	SKPNS0			;STILL IN SEC. ZERO?
	TLZ	R,-1		;YES, SEC. 0 REFERENCE
      > ;END IFN FTEX20
	SKIPE	R,@R		;MONITOR MIGHT HAVE A PDV
	JRST	SYMCP0		;IT DOES, USE IT
    > ;END IFN FTEX20!FTMON
    IFN FTEX20,<		;KDDT ONLY
	SKPEXC			;IF USER MODE AND NO MONPDV,
	JRST	SYMCU0		; DO LIKE USER DDT
    > ;END IFN FTEX20
  > ;END IFN FTDEC20

	MOVE	R,SYMP+S$SUB	;GET ADDR OF IOWD POINTER
	PUSHJ	P,FETCH		;GRAB THE POINTER
	 SETZ	T,		;SHOULDN'T HAPPEN
	MOVEI	W2,SYMP		;BLOCK TO SET UP
	PUSHJ	P,IOWBLK	;DO IT TO IT
	MOVE	R,USYMP+S$SUB	;SAME DEAL FOR UNDEFINEDS
	PUSHJ	P,FETCH		;GET POINTER
	 SETZ	T,		;SHOULD NEVER HAPPEN
	MOVEI	W2,USYMP	;UNDEF BLOCK
	PUSHJ	P,IOWBLK	;GO INIT IT
	JRST	SYMCP7		;BLAST HISEG POINTERS
> ;END IFN FTEXEC!FTMON
;HERE FOR THE USER MODES OF SYMCHK

;FALL IN FROM ABOVE

IFE FTMON,<			;NEVER DO THIS IN MDDT

SYMCU0:

  IFN FTUD20,<		;USER-20 CAN

;IF WE WERE STARTED FROM THE UDDT STUB AND SOMETHING USEFUL WAS STUFFED
;INTO IT, USE IT.  OTHERWISE LOOK FOR PDVS.
;NOTE THAT IF SOMETHING WAS STUFFED, $5M IS SET TO ZERO.

	SKIPL	R,SECUDD	;STARTED FROM UDDT STUB?
	SKIPLE	T,SYTLOC	;$5M CONTAINS JOBDAT SECTION OR 0?
	JRST	SYMCU2		;NO, CHECK $5M
	CAIE	T,0		;$5M SET TO "STUFFED"?
	TSC	T,R		;COMPLEMENT JOBDAT SEC WITH STUB SEC
	TRNE	T,-1		;DO THEY MATCH?
	JRST	SYMCU2		;NO, TRY SOMETHING ELSE
	HRRI	R,770001	;YES, LOOK AT MAGIC LOCATION
	PUSHJ	P,FETCH		;GO GET IT
	 JRST	SYMCU2		;CAN'T, CHECK $5M
	HRR	R,T		;LOOK WHERE MAGIC LOC POINTS TO
	PUSHJ	P,FETCH		;GET STUFFED POINTER IF ANY
	 JRST	SYMCU2		;CAN'T, CHECK $5M
	JUMPGE	T,SYMCU2	;IOWD STUFFED?
	MOVEI	W2,SYMP		;IOWD STUFFED, SET UP EVERYTHING
	PUSHJ	P,IOWBLK	; AS IF IT WERE A JOBDAT LOC
	HRRI	R,770002	;UNDEFINED'S MAGIC LOC
	PUSHJ	P,FETCH		;GET IT
	 JRST	SYMCU2		;NO, TRY $5M
	HRR	R,T		;CHAIN TO REAL PLACE
	PUSHJ	P,FETCH		;GET REAL WORD
	 JRST	SYMCU2		;NO SUCH LUCK
	MOVEI	W2,USYMP	;MADE IT!  SET UP UNDEF BLOCK
	PUSHJ	P,IOWBLK	;AS IF IT WERE JOBDAT
	SETZM	SYTLOC		;SHOW THAT WE HAVE "STUFFED" POINTERS
	JRST	SYMCU7		;NOW FOR HISEG POINTER

  > ;END IFN FTUD20

  IFN FTUE10,<
	SKIPG	R,SYTLOC	;$5M SET IN 'PDV' MODE?
	JRST	SYMCU2		;NO, DO IT THE OLD WAY
	PUSHJ	P,CHKADR	;YES, GET ITS BITS
	TXNE	TT,PG$HGH	;MUST BE A HISEG
	TXNE	TT,PG$SPY	;AND NOT A SPY-SEG
	JRST	SYMCU2		;NO, DO IT THE OLD WAY
	PUSHJ	P,GETHSO	;YES, GET THE HISEG ORIGIN
	JUMPE	T,SYMCU2	;DO IT THE OLD WAY IF NO ORIGIN
	ADDI	T,.JBHSM	;POINT TO ITS SYMBOL TABLE INTO
	CAMN	T,SYTLOC	;IF THAT'S WHAT $5M HAS, FIND THE LOWSEG ANYWAY
	JRST	SYMCU3		;YES, WE'LL USE SYTLOC FOR THE HISEG LATER
	JRST	SYMCU2		;NO, TRY THE OLD WAY
SYMCU1:	SETZM	SYTLOC		;$5M IS WRONG, DON'T USE IT
  > ;END IFN FTUE10

SYMCU2:	SKIPE	R,SYTLOC	;$5M SET?
	JRST	[JUMPG	R,SYMCP0	;IF POSITIVE, PDV ADDRESS
		HRLZS	R		;ELSE -1,,JOBDAT-SECTION
		JRST	SYMCU4]		;SETUP FROM .JBSYM/ETC.
  IFN FTDEC20,<JRST PDVSRH>	;NO, TRY PDVS

; -10 FALLS THRU TO SYMCU3, TO CHECK JOBDAT
;STILL IFE FTMON

;HERE TO SET UP A SECTION'S JOBDAT POINTERS
;DEFAULT TO STUB'S SECTION IF ANY, ELSE ENTRY VECTOR SECTION.

SYMCU3:

  IFE FTFILE,<			;FIRST THE NON-FILDDT CASE
    IFN FTDEC10,<
	PUSHJ	P,GEVECS	;GET ENTRY VECTOR SECTION
	  SETZ	T,		;SECTION ZERO IF NO VECTOR
    > ;END IFN FTDEC10
    IFN FTDEC20,<
      IFN FTUD20,<		;-20 HAS ENTRY VECTORS
	SKIPL	R,SECUDD	;GET STUB'S SECTION IF ANY
	JRST	SYMCU4		;STUB EXISTS, USE IT
	PUSHJ	P,GEVECS	;GET ENTRY SECTION IN T
	 SETZ	T,		;IF THERE'S ANYTHING IT'S IN SECT. 0
      > ;END IFN FTUD20
      IFE FTUD20,<MOVE T,SECDDT>;OTHERWISE DEFAULT TO DDT'S SECTION
    > ;END IFN FTDEC20
	HLLZ	R,T		;WANT SECTION IN R
SYMCU4:
    IFE FTDEC10,<		;IF NO SYMNZS,
	SKPNS0			;IN SECTION ZERO?
	SETZ	R,		;SET UP FOR SECTION ZERO
    > ;END IFE FTDEC10
  > ;END IFE FTFILE

  IFN FTFILE,<			;NOW THE FILDDT CASE
	HLLZ	R,EVADR		;DEFAULT IS ENTRY VECTOR (OR ZERO)
SYMCU4:
  > ;END IFN FTFILE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;STILL IFE FTMON

SYMCU5:
  IFN FTUE10,<SKIPG SYTLOC>	;IF NOT TRUSTING $5M FOR THE HISEG,
	HLROM	R,SYTLOC	;SET PROPER $5M
	HRRI	R,.JBSYM	;SET UP POINTERS FROM THAT SECTION
	PUSHJ	P,FETCH		;GET THE DEFINED POINTER
	 SETZ	T,		;THERE AIN'T ONE
	MOVEI	W2,SYMP		;PRIMARY SYMBOL POINTERS BLOCK ADDRESS
	JUMPG	T,[PUSHJ P,PDVBL4	;SET POINTERS FROM SYMBOL VECTOR
		JRST	SYMCU7]		;CHECK FOR HISEG SYMBOL TABLE
	PUSHJ	P,IOWBLK	;SET UP SYMBOL BLOCK
	HRRI	R,.JBUSY	;SAME FOR UNDEFINED POINTER
	PUSHJ	P,FETCH		;GET IT
	 SETZ	T,		;MAYBE NOT
	MOVEI	W2,USYMP	;BLOCK TO SET UP
	PUSHJ	P,IOWBLK	;DO IT
SYMCU7:	MOVEI	R,.JBHSM	;TRY FOR HISEG TABLE
	PUSHJ	P,HFETCH	;IS IT THERE?
	 SETZ	T,		;NO
	MOVEI	W2,HSYMP	;HISEG TABLE BLOCK
	JUMPG	T,[PUSHJ P,PDVBL4	;SET POINTERS FROM SYMBOL VECTOR
		JRST	.+2]		;CONTINUE ONWARDS
	PUSHJ	P,IOWBLK	;SET IT UP

> ;END IFE FTMON

	JRST	SYMCV0		;GO VERIFY THE SYMBOL TABLE POINTERS


;HERE WITH PDV ADDRESS IN R

SYMCP0:	MOVEI	W2,SYMP		;SYMBOL TABLE POINTERS BLOCK
	PUSHJ	P,PDVBLK	;EXTRACT THE SYMBOL TABLE VECTOR
SYMCP7:	MOVEI	W2,HSYMP	;HISEG TABLE BLOCK
	SETZ	R,		;ASSUME NONE
	PUSHJ	P,VECBLK	;CLEAR HISEG POINTERS
	JRST	SYMCV0		;GO VERIFY THE SYMBOL TABLE POINTERS
;HERE TO VALIDATE SYMBOL TABLE POINTERS

SYMCV0:
  IFE FTFILE,<IFN FTDEC10,<PUSHJ P,SYMNZS>>  ;CHECK FOR NZS SYMBOL TABLE
  IFN FTSCSH,<PUSHJ P,.CLCSH>	;WE JUST INVALIDATED IT.
	MOVEI	T,SYMP		;GET MAIN SYMBOL PTR
	PUSHJ	P,CHKSYP	;CHECK IT OUT
	 SETZM	SYMP+S$ADR	;NO GOOD, POINT TO ZERO
	MOVEI	T,HSYMP		;HIGH SEG SYMBOL POINTER
	PUSHJ	P,CHKSYP	;CHECK OUT THE HIGH SEG PTR
	 SETZM	HSYMP+S$ADR	;NO GOOD

;NOW SEE IF LOSEG AND HISEG POINT TO THE SAME TABLE. IGNORE HISEG IF SO.

	SKIPE	T,SYMP+S$ADR	;GOT A GOOD LOSEG POINTER?
	SKIPN	S,HSYMP+S$ADR	;AND A GOOD HISEG POINTER?
	JRST	SYMCV2		;ONLY ONE, JUST USE IT
	ADD	T,SYMP+S$LEN	;FORM END OF LOSEG TABLE
	ADD	S,HSYMP+S$LEN	;FORM END OF HISEG TABLE
	CAMN	S,T		;POINTING TO SAME TABLES?
	SETZM	HSYMP+S$ADR	;YES, IGNORE HISEG POINTER

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

SYMCV2:	MOVEI	T,USYMP		;GET UNDEFINED BLOCK
	PUSHJ	P,CHKSYP	;CHECK IT OUT
	 CAIA			;NO GOOD, FIX IT UP
	JRST	SYMCV4		;POINTER IS OK
	SKIPN	R,SYMP+S$ADR	;GOT A VALID SYMBOL TABLE?
	MOVE	R,HSYMP+S$ADR	;NO, USE HISEG PTR IF ANY TO FIX UNDEF PTR
	MOVEM	R,USYMP+S$ADR	;STORE FOR OTHERS
	SETZM	USYMP+S$LEN	;WITH LENGTH ZERO
	MOVEI	W1,USYMP	;GET UNDEF BLOCK ADR
	SETZ	W2,		;"UPDATE" BY ZERO WORDS
	PUSHJ	P,DECSYP	;GO SET .JBUSY
	 SETZM	USYMP+S$ADR	;CAN'T, FORGET LOCATION

;FALL THROUGH TO CHECK OPEN MODULE
;HERE WHEN SYMBOL PTRS CHECKED OUT, NOW CHECK PRGM ($: PTR).

SYMCV4:	SKIPN	S,PRGM		;GET PTR, ONE THERE?
	JRST	SYMCV8		;NO, PROCEED
	JUMPGE	S,SYMCV6	;PROCEED IF S POINTS TO LOWSEG
	MOVEI	R,.JBHNM	;PRGM POINTS TO HISEG, GET HISEG NAME
	PUSHJ	P,HFETCH	; . . .
	  JRST	SYMCV8		;NO GOOD, CLEAR PRGM
	CAME	T,SEGNAM	;SAME HISEG?
	JRST	SYMCV8		;NO, CLEAR PRGM
	MOVEI	T,HSYMP		;YES, GET THE PTR THAT PRGM POINTS INTO
	CAIA
SYMCV6:	MOVEI	T,SYMP		;GET THE PTR THAT PRGM POINTS INTO
	SKIPN	S$ADR(T)	;IS THERE A TABLE?
	JRST	SYMCV8		;NO, PRGM CAN'T BE VALID
	TXZ	S,1B0		;CONVERT S TO OFFSET INTO TABLE
	CAML	S,S$LEN(T)	;PRGM INVALID UNLESS S IS WITHIN THE TABLE
	JRST	SYMCV8		;INVALID

;CHECK IF PRGM POINTS TO A MODULE NAME SYMBOL

	MOVE	R,PRGM		;FETCH PROG SYMBOL AGAIN
	SUBI	R,1		;POINT TO FIRST WORD OF PAIR
	PUSHJ	P,FETSYM	;GRAB SYMBOL
	 JRST	SYMCV8		;OOPS
	TXNE	T,PNAME		;INVALID UNLESS A MODULE NAME
SYMCV8:	SETZM	PRGM		;PRGM INVALID IN SOME WAY
	SKIPN	SYMP+S$ADR	;DO WE HAVE A SYMBOL TABLE?
	SETZM	SYMP+S$LEN	;NO, DON'T CONFUSE ANYONE
	SKIPN	HSYMP+S$ADR	;HOW ABOUT HISEG TABLE?
	SETZM	HSYMP+S$LEN	;SAME DEAL THERE
	DMOVE	TT,USYMP+S$ADR	;GET UNDEFINED SYMBOL PTR/LEN
	DMOVEM	TT,ESTUT	;INIT UNDEFINED SYM ASSEMBLER COPY
	POP	P,W		;RESTORE THE AC FOR THE PARSER
	SETOM	SYMVAL		;WE NOW KNOW ABOUT SYMBOL TABLE PTRS
  IFN FTUE10,<
    IFN FTEXEC,<PUSHJ P,NORSPC>	;RETURN IN CORRECT ADDRESS SPACE
	XMOVEI	TT,-1		;GET CORRECT RETURN SECTION
	HLLM	TT,(P)		;JUST IN CASE WE LEFT S0
  > ;END IFN FTUE10
	POPJ	P,		;RETURN FROM SYMCHK
;HERE TO WORRY ABOUT THE SYMBOL TABLE IN A NZS SECTION WHILE DDT IS
;STUCK IN SECTION ZERO.
;
;CURRENTLY, THIS CHECK SEEMS NECESSARY ONLY FOR THE -10 . . .

IFE FTFILE,<			;FILDDT HAS ITS OWN WAY OF DOING THINGS
  IFN FTDEC10,<

SYMNZS:	SKPS0			;RUNNING NZS ALREADY?
	POPJ	P,		;YES, THEN NOT A PROBLEM BY DEFINITION

;DDT IN SECTION 0, SEE WHERE THE ASSORTED SYMBOL TABLES ARE . . .

	MOVE	R,SYMP+S$ADR	;STANDARD DEFINED SYMBOL TABLE (IF ANY)
	IOR	R,USYMP+S$ADR	;PLUS STANDARD UNDEFINED SYMBOL TABLE (IF ANY)
	IOR	R,HSYMP+S$ADR	;AND THE HISEG SYMBOL TABLE (IF ANY)
	TLNN	R,-1		;ANY SYMBOL TABLES IN NZS SPACE?
	POPJ	P,		;NO, ALL SET

;MUST FINAGLE DDT INTO NZS SPACE IN ORDER TO ACCESS THE SYMBOL TABLE!
;FIRST PASS, GO FOR SECTION 1.

	MOVSI	R,1		;SECTION 1
	PUSHJ	P,RWEMAP	;ARE WE MAPPED INTO SECTION 1?
	 CAIA			;NO, BE A MITE SNEAKY
	JRST	SYMNZ5		;YES, GO FOR SECTION 1

;TRY FOR SYMBOL TABLE SECTION(S)

	MOVE	R,SYMP+S$ADR	;STANDARD SYMBOL TABLE
	TLNE	R,-1		;IS THIS ONE NZS?
	PUSHJ	P,RWEMAP	;YES, ARE WE MAPPED INTO ITS SECTION?
	 CAIA			;NO TO EITHER, KEEP TRYING
	JRST	SYMNZ5		;YES! JUMP TO THAT SECTION
	MOVE	R,HSYMP+S$ADR	;TRY THE HISEG TABLE SECTION
	TLNE	R,-1		;IS THIS ONE NZS?
	PUSHJ	P,RWEMAP	;YES, ARE WE MAPPED INTO ITS SECTION?
	 CAIA			;NO TO EITHER, KEEP TRYING
	JRST	SYMNZ5		;YES! JUMP TO HISEG SYMBOL SECTION
	MOVE	R,USYMP+S$ADR	;TRY UNDEFINED SYMBOL TABLE SECTION
	TLNE	R,-1		;IS THIS ONE NZS?
	PUSHJ	P,RWEMAP	;YES, ARE WE MAPPED INTO ITS SECTION?
	 CAIA			;NO TO EITHER, BE SNEAKIER
	JRST	SYMNZ5		;YES! JUMP TO UNDEFINED SYMBOL SECTION

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;LAST DITCH EFFORT, MAP SECTION 0 INTO SECTION 1

  IFN FTEXEC,<			;EXEC MODE DOESN'T SUPPORT PAGE.'S
	SKPUSR			;USER OR EXEC MODE?
	JRST	SYMNZ9		;EXEC MODE, LOSES
  > ;END IFN FTEXEC

	MOVEI	TT,1		;SECTION 1
	PUSHJ	P,CHKSEC	;SEE WHAT SECTION 1'S STATE IS
	TXNE	TT,PG$SXI	;IF SECTION 1 ALREADY EXISTS
	JRST	SYMNZ9		;THEN JUST GIVE IT UP (WE TRIED!)
	MOVEI	TT1,1		;WANT TO MAP ONE SECTION
	MOVE	TT2,[PA.GMS!<0,,1>]  ;NAMELY SECTION 0 INTO SECTION 1
	MOVE	T,[.PAGSC,,TT1]	;PAGE. ARG POINTER TO
	PAGE.	T,		;MAP SECTION 0 INTO SECTION 1
	 JRST	SYMNZ8		;OH WELL, TIME TO GIVE UP
	MOVEI	W1,[ASCIZ\
[DDT - Section 0 mapped into section 1 for NZS symbol table access]
\]				;INFORMATIVE TEXT
	PUSHJ	P,TSTRG		;TO TELL THE USER WHAT HAPPENED
	MOVSI	R,1		;SECTION TO WHICH TO JUMP

;HERE TO SWITCH SECTIONS FOR NZS SYMBOL TABLE ACCESS

SYMNZ5:	JSP	TT,SECCHG	;GO CHANGE SECTIONS (UPDATING PDL)
	HLLM	TT,(P)		;FLAGS BEFORE FIRST PUSHJ ARE SUSPECT
	POPJ	P,		;DONE ALL WE CAN HERE . . .
;HERE WHEN CAN'T SWAP SECTIONS, CAN'T MAP SECTION 0 INTO SECTION 1

SYMNZ8:	MOVEI	W1,[ASCIZ\
[DDT - Can't map section 0 into section 1 for NZS symbol tables]
\]				;ERROR MESSAGE
	CAIA			;TELL USER OF WOES

;HERE WHEN GIVING UP ON NZS SYMBOLS

SYMNZ9:	MOVEI	W1,[ASCIZ\
[DDT - Can't access NZS symbol table(s) from section 0]
\]				;ERROR MESSAGE
	PUSHJ	P,TSTRG		;INFORM USER OF PROBLEMS
	MOVSI	R,-1		;SECTION BITS MASK
	TDNE	R,SYMP+S$ADR	;STANDARD SYMBOL TABLE IN NZS?
	SETZM	SYMP+S$ADR	;YES, PUNT IT
	TDNE	R,USYMP+S$ADR	;UNDEFINED SYMBOL TABLE IN NZS?
	SETZM	USYMP+S$ADR	;YES, PUNT IT
	TDNE	R,HSYMP+S$ADR	;HISEG SYMBOL TABLE IN NZS?
	SETZM	HSYMP+S$ADR	;YES, PUNT IT
	POPJ	P,		;LIMP ALONG AS BEST WE CAN
  > ;END IFN FTDEC10
> ;END IFE FTFILE
;GEVECS -- RETURN ENTRY VECTOR SECTION IN T
;	PUSHJ	P,GEVECS
;	 NO ENTRY VECTOR
;	ENTRY VECTOR SECTION IN T

  IFN FTUE10,<
GEVECS:	XMOVEI	T,1(P)		;BLOCK POINTER
	SETZM	(T)		;FUNCTION IS READ
	ENTVC.	T,		;GET ENTRY VECTOR DATA
	  POPJ	P,		;NONE TO BE HAD
	SKIPN	2(P)		;IF THERE IS NO DATA,
	POPJ	P,		;INDICATE THAT
	HLLZ	T,3(P)		;RETURN THE SECTION NUMBER
	JRST	CPOPJ1		;INDICATE SUCCESS
  > ;END IFN FTUE10

  IFN FTUD20,<
GEVECS:	PUSHJ	P,SAVT4		;SAVE JSYS ACS
	MOVEI	T1,.FHSLF	;THIS PROCESS
	XGVEC%			;GET ENTRY VECTOR
	JUMPE	T2,CPOPJ	;DOES ONE EXIST?
	HLLZ	T,T3		;RETURN IN PROPER AC
	JRST	CPOPJ1		;RETURN GOOD
  > ;END IFN FTUD20



;IOWBLK -- SET UP BLOCK FROM IOWD POINTER
;CALL:
; W2/	ADR OF SYMBOL BLOCK
; R/	ADR OF ORIGINAL SYMBOL POINTER
; T/	IOWD POINTER TO SYM TABLE
;	PUSHJ	P,IOWBLK
;	RETURN
;
;PRESERVES R,S,T,W2

IOWBLK:	PUSHJ	P,SAVRST	;AS ADVERTISED
  IFN FTFILE,<MOVEM T,S$OPT(W2)>;SAVE ORIGINAL IOWD
	HLRE	S,T		;GET NEG LENGTH
	MOVNM	S,S$LEN(W2)	;STORE POS LENGTH
	JUMPE	T,IOWBL1	;IF IT'S A REAL POINTER,
	HLL	T,R		;TACK ON CORRECT SECTION
IOWBL1:	MOVEM	T,S$ADR(W2)	;STORE TABLE ADDRESS
	MOVEM	R,S$SUB(W2)	;STORE ADDRESS OF POINTER
	HRROS	S$SUF(W2)	;FLAG S$SUB POINTS TO IOWD-FORMAT
	POPJ	P,		;RETURN
;HERE WITH *THE* PDVA IN R, TO CHECK OUT THE SYMBOL TABLE VECTOR
;CALL WITH ADDRESS OF SYMBOL TABLE BLOCK IN W2. IF "SYMP" THEN USYMP
;WILL BE SET, OTHERWISE UNAFFECTED.

;FLAGS IN W1 FOR SYMBOL TABLES SEEN

	R5DF==1B0		;RADIX-50 DEFINED TABLE FLAG
	R5UF==1B1		;RADIX-50 UNDEFINED TABLE FLAG

PDVBLK:	MOVEM	R,SYTLOC	;SAVE PDVA
	SETZ	W1,		;CLEAR FLAGS
IFN .PVCNT,ADDI	R,.PVCNT	;GET PDV LENGTH
	PUSHJ	P,FETCH		;INTO T
	 JRST	PDVS90		;CAN'T -- DONE EARLY
	CAIGE	T,.PVLVR	;DOES IT HAVE A LINK VERSION?
	JRST	PDVBL2		;NO, ASSUME GOOD ENOUGH
	ADDI	R,.PVLVR-.PVCNT	;POINT AT VERSION WORD
	PUSHJ	P,FETCH		;GET IT
	 JRST	PDVBL1		;IGNORE ERROR, ASSUME OK
	LDB	S,[POINT 9,T,11]  ;GET MAJOR VERSION
	CAIGE	S,6		;BUILT BY LINK 6.0 OR LATER?
	JRST	PDVS90		;NO, .PVSYM NO GOOD
PDVBL1:	SUBI	R,.PVLVR-.PVSYM	;DROP BACK TO SYMBOL VECTOR WORD
	JRST	PDVBL3		;AND CONTINUE

PDVBL2:	CAIGE	T,.PVSYM	;DOES IT HAVE A .PVSYM?
	JRST	PDVS90		;NO, ZAP POINTER
	ADDI	R,.PVSYM-.PVCNT	;GET SYMBOL VECTOR WORD
PDVBL3:	PUSHJ	P,FETCH		;INTO T
	 JRST	PDVS90		;CAN'T
	TXNE	T,IFIW		;IS IT LOCAL?
	HLL	T,R		;YES, SET THE SECTION NUMBER
	JUMPE	T,PDVS90	;NOT THERE, GIVE UP

;ENTER HERE WITH SYMBOL VECTOR ADDRESS IN T (E.G., FROM .JBSYM)

PDVBL4:	SETZ	W1,		;CLEAR FLAGS
	MOVE	R,T		;GET ADR IN RIGHT PLACE
IFN .STLEN,ADDI	R,.STLEN	;WANT LENGTH WORD
	PUSHJ	P,FETCH		;IN T
	 JRST	PDVS90		;SORRY
	ADD	T,R		;GET LAST ADDR OF VECTOR
	MOVEM	T,ENDSUB	;SAVE END OF SUBTABLES

;FALL THROUGH TO LOOK AT EACH SUBTABLE
;FALL THROUGH FROM ABOVE TO CHECK EACH SUBTABLE

	AOSA	R		;POINT TO FIRST SUBTABLE
PDVS10:	ADDI	R,3		;SUBTABLES HAVE FIXED LENGTH 3
	CAML	R,ENDSUB	;PAST THE END OF THE VECTOR?
	JRST	PDVS90		;YES, DONE
	PUSHJ	P,FETCH		;GRAB TYPE WORD
	 JRST	PDVS10		;SIGH
	LDB	TT,[POINTR T,ST%TYP]  ;GET JUST TYPE
	CAIE	TT,.R50D	;DEFINED TABLE?
	JRST	PDVS11		;NO, TRY NEXT TYPE
	TXOE	W1,R5DF		;FLAG DEFINED TABLE SEEN
	JRST	PDVS10		;ALREADY GOT ONE, THANKS
	PUSHJ	P,VECBLK	;SET UP BLOCK
	 TXZ	W1,R5DF		;BLEW IT, OH WELL
	JRST	PDVS10		;GO CHECK NEXT POINTER

PDVS11:	CAIE	TT,.R50U	;UNDEFINED TABLE?
	JRST	PDVS20		;NO, SOMETHING ELSE
	CAIN	W2,SYMP		;UNDEFINEDS ALLOWED ONLY FROM "MASTER"
	TXOE	W1,R5UF		;FLAG UNDEFINED TABLE SEEN
	JRST	PDVS10		;ALREADY GOT ONE, KEEP GOING
	MOVEI	W2,USYMP	;GET UNDEFINED BLOCK ADDR
	PUSHJ	P,VECBLK	;SET UP BLOCK
	 TXZ	W1,R5UF		;NO GOOD
	MOVEI	W2,SYMP		;RESTORE MASTER BLOCK ADDRESS
	JRST	PDVS10		;GO CHECK NEXT POINTER

PDVS20==PDVS10			;NO MORE DEFINED TYPES

;HERE WHEN ALL SUBTABLES LOOKED AT

PDVS90:	SETZ	R,		;SET UP ZERO POINTER
	TXNN	W1,R5DF		;DEFINED TABLE SEEN?
	PUSHJ	P,VECBLK	;NO, CLEAR THE BLOCK
	 NOP
	CAIE	W2,SYMP		;MASTER BLOCK ADDRESS?
	JRST	PDVS99		;NO, SKIP UNDEFINED CHECK
	MOVEI	W2,USYMP	;NEXT, UNDEFINED
	TXNN	W1,R5UF		;UNDEFINED TABLE SEEN?
	PUSHJ	P,VECBLK	;NO, POINT TO ZERO
	 NOP
	MOVEI	W2,SYMP		;RESTORE POINTER BLOCK ADDRESS
PDVS99:	POPJ	P,		;POINTERS SET FROM PDV/VECTOR
;VECBLK -- SET UP BLOCK BASED ON PDV SYMBOL VECTOR SUBTABLE
; W2/	ADDR OF SYMBOL BLOCK
; R/	SUBTABLE ADDRESS
;	PUSHJ	P,VECBLK
;RETURNS: +1/ SOMETHING DIED
;	+2/ GOOD
;
;PRESERVES R,S,T,W2

VECBLK:	MOVEM	R,S$SUB(W2)	;SAVE SUBTABLE ADDRESS
	HRRZS	S$SUF(W2)	;FLAG VECTOR-SUBTABLE ADDRESS
	JUMPE	R,[SETZM S$ADR(W2)	;IF NO SUBTABLE, ZAP SOME
		SETZM	S$LEN(W2)	; LOCATIONS
  IFN FTFILE,<
		SETZM	S$OLN(W2)
		SETZM	S$OPT(W2)
  > ;END IFN FTFILE
		JRST	CPOPJ1]		;ALWAYS "SUCCEEDS"
	PUSHJ	P,SAVRST	;AS ADVERTISED
IFN .STDAT,ADDI	R,.STDAT	;WANT LENGTH WORD
	PUSHJ	P,FETCH		;GRAB IT
	 POPJ	P,		;CAN'T
  IFN FTFILE,<MOVEM T,S$OLN(W2)>;SAVE ORIGINAL TYPE/LENGTH WORD
	ANDX	T,ST%LEN	;GET LENGTH
	MOVEM	T,S$LEN(W2)	;SAVE IT AWAY
	ADDI	R,.STPTR-.STDAT	;POINT TO POINTER
	PUSHJ	P,FETCH		;GET ADDRESS WORD
	 POPJ	P,		;SORRY
  IFN FTFILE,<MOVEM T,S$OPT(W2)>;SAVE ORIGINAL POINTER
	TXNE	T,IFIW		;IS POINTER LOCAL?
	HLL	T,R		;YES, MAKE A REAL ADDR
	MOVEM	T,S$ADR(W2)	;SAVE POINTER
	JRST	CPOPJ1		;RETURN GOOD
;PDVSRH - SEARCH FOR THE RIGHT PDV TO USE.
;
;THE SEARCH ALGORITHM IS AS FOLLOWS:
;
; 1) IF NO PDVS EXIST, USE ENTRY VECTOR (OR STUB'S) SECTION'S JOBDAT.
; 2) IF ONLY ONE PDV EXISTS IN MEMORY, USE IT.
; 3) IF MORE THAN ONE PDV EXISTS, LOOK AT ALL .PVSYM WORDS FOR
;    A NON-ZERO EFIW (I.E. C(.PVSYM) .GT. 0), AND TAKE THE FIRST ONE FOUND.
; 4) IF NO EFIW'S EXIST, USE FIRST PDV IN OR ABOVE THE ENTRY VECTOR SECTION.
; 5) IF NO ENTRY VECTOR OR NO SUCH PDV, USE THE FIRST PDV IN MEMORY.
;
;NOTE THAT NOT ALL PDVS WILL HAVE A .PVSYM WORD, AND THEREFORE THE
;DISTINCTION BETWEEN "PDV" AND ".PVSYM WORD" ABOVE IS SIGNIFICANT.
;
;IF THE ENTRY VECTOR IS DDT'S, WE ARE SDDT AND SHOULD USE DDT'S PDV.
;
;JUMPS TO SYMCU3 TO USE DEFAULT SECTION'S JOBDAT
;JUMPS TO SYMCP0 WHEN DECIDED ON A PDV.

  IFN FTDEC20&<^-FTMON>,<	;NO PDV SEARCHING IN MDDT

PDVSRH:
  IFE FTFILE,<			;FIRST THE NON-FILDDT SETUP
    IFN FTUD20,<		;CHECK FOR SDDT
	MOVEI	T1,.FHSLF	;ARE THIS FORK'S
	XGVEC%			; ENTRY VECTOR AND
	XMOVEI	T1,DDT		; OUR START ADDRESS
	CAMN	T1,T3		; THE SAME?
	JRST [	SKIPLE	R,DDTPDV	;YES, GET OUR OWN PDV
		JRST	SYMCP0		;GO SET UP OUR SYMBOLS
		JRST	.+1]		;HAVEN'T GOT ONE??
    > ;END IFN FTUD20
	PUSHJ	P,PDVINI	;SET UP PDVARG
	SETZM	PDVA		;"LAST" PDVA (SET START OF RANGE)
	PUSHJ	P,NXTPDV	;GET PDVA IN R
    IFN FTUD20,<
	CAMN	R,DDTPDV	;IS IT DDT'S PDV?
	PUSHJ	P,NXTPDV	;YES, GET ANOTHER ONE (AND NEW COUNT)
    > ;END IFN FTUD20
	HLRZ	W1,PDVARG+.POCT2 ;GET # PDVS EXISTING
  > ;END IFE FTFILE

  IFN FTFILE,<			;NOW THE FILDDT SETUP
	SETO	W2,		;"PREVIOUS" INDEX INTO PDVTBL
	PUSHJ	P,NXTPDV	;GET THE FIRST PDVA
	MOVE	W1,PDVNUM	;GET NUMBER OF PDVS
  > ;END IFN FTFILE

;FALL INTO NEXT PAGE
;STILL IFN FTDEC20&<^-FTMON>

;FALL IN FROM ABOVE

;HERE TO PICK A PDV WITH FIRST PDVA IN R, COUNT OF PDVS IN W1

	JUMPLE	W1,SYMCU3	;NONE EXIST, USE SECDDT'S JOBDAT
	SOJE	W1,SYMCP0	;ALL DONE IF JUST ONE PDV
PDVSR1:
IFN .PVCNT,ADDI	R,.PVCNT	;WANT LENGTH WORD
	PUSHJ	P,FETCH		;GO GET IT
	 JRST	PDVSR2		;NOT THERE, SKIP IT
	CAIGE	T,.PVSYM	;LONG ENOUGH?
	JRST	PDVSR2		;NO, SKIP IT
	ADDI	R,.PVSYM-.PVCNT	;POINT TO SYM WORD
	PUSHJ	P,FETCH		;GO GRAB IT
	 JRST	PDVSR2		;CAN'T
	SUBI	R,.PVSYM-.PVCNT	;BACK TO TOP OF PDV
	JUMPG	T,SYMCP0	;USE IT IF .PVSYM IS EFIW
PDVSR2:	SOJL	W1,PDVSR3	;NOT EFIW, COUNT THIS PDV
	PUSHJ	P,NXTPDV	;GET THE NEXT PDV
  IFE FTUD20,<
	JRST	PDVSR1		;AND GO LOOK AT IT
  > ;END IFE FTUD20
  IFN FTUD20,<
	CAME	R,DDTPDV	;DDT'S PDV?
	JRST	PDVSR1		;NO, KEEP GOING
	PUSHJ	P,NXTPDV	;YES, SKIP IT
	SOJA	W1,PDVSR1	;COUNT IT AND GO ON
  > ;END IFN FTUD20
;STILL IFN FTDEC20&<^-FTMON>

;HERE IF NO EFIW FOUND, BASE SEARCH ON ENTRY VECTOR.

  IFE FTFILE,<			;NON-FILDDT CASE

PDVSR3:
    IFN FTUD20,<		;ENTRY VECTORS ONLY ON -20
	SKPS0			;IN NON-ZERO SECTION?
	PUSHJ	P,GEVECS	;GET ENTRY VECTOR SECTION IN T
	 JRST	PDVSR5		;NO ENTRY VECTOR, START AT ZERO
	MOVEM	T,PDVA		;START AT SECTION,,0
	PUSHJ	P,NXTPDV	;GRAB THE PDVA
	CAMN	R,DDTPDV	;IS DDT'S FIRST?
	PUSHJ	P,NXTPDV	;YES, TRY AGAIN
	SKIPE	PDVARG+.POCT2	;DID ANY SHOW UP?
	JRST	SYMCP0		;YES, GO CHECK IT OUT
    > ;END IFN FTUD20

PDVSR5:	SETZM	PDVA		;NO, START FROM 0,,0 THIS TIME
	PUSHJ	P,NXTPDV	;SATISFACTION GUARANTEED
    IFN FTUD20,<		;EXCEPT IN USER-20
	CAMN	R,DDTPDV	;DDT'S?
	PUSHJ	P,NXTPDV	;NOW IT SHOULD WORK...
    > ;END IFN FTUD20
	JRST	SYMCP0		;AND CHECK IT OUT

  > ;END IFE FTFILE


  IFN FTFILE,<			;FILDDT CASE

PDVSR3:	SKIPE	T,EVLEN		;IF THERE'S AN EVEC
	HLLZ	T,EVADR		;GET START OF EVEC SECTION
	JUMPE	T,PDVSR5	;IF ZERO, JUST USE FIRST PDVA
	MOVE	W1,PDVNUM	;GET NUM PDVS
	SETO	W2,		;POINT TO "TOP" OF TABLE
PDVSR4:	PUSHJ	P,NXTPDV	;GET PDVA
	CAML	R,T		;CAN WE USE IT?
	JRST	SYMCP0		;YEP
	SOJG	W1,PDVSR4	;NO, TRY NEXT ONE
PDVSR5:	SETO	W2,		;NONE WORKED, JUST USE FIRST ONE
	PUSHJ	P,NXTPDV	;GET FIRST PDVA
	JRST	SYMCP0		;GO CHECK IT OUT

  > ;END IFN FTFILE
;STILL IFN FTDEC20&<^-FTMON>

;NXTPDV -- RETURNS NEXT PDVA IN SEQUENCE
;CALL:
;  IFN FTFILE,<W2 CONTAINS PDVTBL INDEX OF LAST PDVA LOOKED AT>
;  IFE FTFILE,<PDVA: CONTAINS LAST PDVA LOOKED AT>
;	PUSHJ	P,NXTPDV
;RETURNS:
;	+1 WITH NEXT PDVA IN R, UPDATED W2 (FILDDT)
;USES ONLY W2 AND R

  IFE FTFILE,<			;FIRST THE NON-FILDDT CASE
NXTPDV:	AOS	R,PDVA		;INCREMENT PAST LAST PDVA
	MOVEM	R,PDVARG+.POADR	;STORE AS LOW END OF RANGE
	MOVEI	R,1		;ONLY 1-WORD BLOCK
	MOVEM	R,PDVARG+.POCT2	;SET THE COUNT WORD
	PUSHJ	P,GETPDV	;DO THE PDVOP%
	MOVE	R,PDVA		;GET THE PDVA RETURNED
	POPJ	P,		;AND RETURN

;GETPDV PERFORMS A .POGET PDVOP% JSYS ACCORDING TO ARGS IN PDVARG.
GETPDV:	PUSHJ	P,SAVT4		;SAVE JSYS ACS
	XMOVEI	T2,PDVARG	;GET ARG BLOCK ADDRESS
	MOVX	T1,.POGET	;GET A PDVA
	PDVOP%			; . . .
	POPJ	P,		;RETURN

;PDVINI SETS UP PARAMETERS IN THE PDVOP% ARG BLOCK
PDVINI:	MOVEI	T,1		;ONLY 1-WORD BLOCK
	MOVEM	T,PDVARG+.POCT2	;SET THE COUNT WORD
	XMOVEI	T,PDVA		;POINT TO DATA "BLOCK"
	MOVEM	T,PDVARG+.PODAT	;SO PDVOP% CAN FIND IT
	SETZM	PDVARG+.POADR	;START RANGE AT ZERO
	MOVX	T,VMADR		;MAX POSSIBLE ADDRESS
	SKPNS0			;IN SECTION ZERO?
	TLZ	T,-1		;YES, STAY INSIDE IT
	MOVEM	T,PDVARG+.POADE	;SET END OF RANGE
	POPJ	P,		;ALL DONE

  > ;END IFE FTFILE

  IFN FTFILE,<
NXTPDV:	AOS	W2		;INCREMENT POINTER
	MOVE	R,@PDVTBL	;GET NEXT PDVA
	POPJ	P,		;AND RETURN
  > ;END IFN FTFILE

  > ;END IFN FTDEC20&<^-FTMON>
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
  IFN FTSCSH,<			;ONLY IF USING SYMBOL TABLE CACHE
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
  > ;END IFN FTSCSH

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:
  IFN FTEXEC,<
	SOSGE	XTYPAX		;TIME TO CHECK FOR TYPEAHEAD?
	PUSHJ	P,XTYPA		;YES, CHECK FOR EXEC MODE TYPEAHEAD
  > ;END IFN FTEXEC
	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:	JUMPE	T,CPOPJ		;NEVER FIND 0-VALUE SYMBOL
	TXC	T,1B0		;CONVERT TO UNSIGNED FORMAT
	TXZ	F,MDLCLF	;INITIALIZE FLAG
  IFN FTSCSH,<			;ONLY IF USING SYMBOL TABLE CACHE
	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
;STILL IFN FTSCSH

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
  > ;END IFN FTSCSH
  IFE FTSCSH,<			;IF NOT USING SYMBOL TABLE CACHE
	PUSHJ	P,LOKSYM	;LOOKUP IN REGULAR SYMBOL TABLE
  > ;END IFE FTSCSH
	TXC	W,1B0		;CONVERT BACK TO SIGNED NUMBERS
	TXC	T,1B0		;FROM UNSIGNED
	MOVE	S,T		;COMPUTE DIFFERENCE BETWEEN VALUES
	XOR	T,W		;TEMPORARILY TRASH T TO COMPARE SIGNS
	JUMPGE	T,LOOKD1	;EASY CASE IF SIGNS THE SAME
	TXC	S,1B0		;HARD CASE--MAKE SIGNS THE SAME
	SUB	S,W		;NOW SUB IS SAFE
	TXCA	S,1B0		;FIX UP THE RESULT
LOOKD1:	SUB	S,W		;NORMAL SUB WORKS IF SIGNS THE SAME
	XOR	T,W		;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
  IFN FTSCSH,<			;ONLY IF USING SYMBOL TABLE CACHE
;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
;STILL IFN FTSCSH

;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
  > ;END IFN FTSCSH
	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

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;LOOP BACK HERE TO LOOK AT EACH NEW SYMBOL.

LOOK2:
  IFN FTEXEC,<
	SOSGE	XTYPAX		;TIME TO CHECK FOR TYPEAHEAD?
	PUSHJ	P,XTYPA		;YES, CHECK FOR EXEC MODE TYPEAHEAD
  > ;END IFN FTEXEC
	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 AS GOOD?
	JRST	LOOK2		;NO, DON'T WASTE ANY MORE TIME
	CAME	W,LKVAL		;IS OUR NEW SYMBOL DEFINITELY BETTER?
	JRST	LOOK8		;YES, USE IT
	TXNN	F,OLF		;IF NEW SYMBOL IS OUTSIDE LOCAL,
	TXNN	F,MDLCLF	; OR OLD SYMBOL IS GLOBAL/INSIDE LOCAL,
	JRST	LOOK2		; DON'T STOMP ON IT

;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
				;GET OFFSET INTO S
	XOR	T,LKVAL		;TEMPORARILY TRASH T TO COMPARE SIGNS
	JUMPGE	T,LOOK11	;EASY CASE IF SIGNS THE SAME
	TXC	S,1B0		;HARD CASE--MAKE SIGNS THE SAME
	SUB	S,LKVAL		;NOW SUB IS SAFE
	TXCA	S,1B0		;FIX UP THE RESULT
LOOK11:	SUB	S,LKVAL		;NORMAL SUB WORKS IF SIGNS THE SAME
	XOR	T,LKVAL		;RESTORE T
	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
	.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
	.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,.TRAX 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,.TXT H,.DIS 21,.TXT R,.TRA HW2,.TXT L
	.ADR HW2,.TXT R,.TRA HW3
.ADR HW1,.DIS 21,.TRA XH,.TXT HR,.ADR HW4,.TXT L
	.ADR HW3,.DIS 32,.TRA IMS,.TXT Z,.TRA IMS,.TXT O,.TRA IMS,.TRA EIMS
.ADR XH,.DIS 32,.TRA XH1,.TRA HL,.TRA HL,.ADR HL,.TXT HL,.TRA HW4
.ADR XH1,.DIS 02,.TRA HL,.TXT X,.TRA HL,.TRA HL,.TRA HL

;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 XM,.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
.ADR XM,.DIS 02,.TRAX STMI,.TXT XMOV,.TRA EIMS,.TRAX STM,.ADR STM,.TXT SET,.TRA TM
;PRESERVE SETMI FOR TYPEIN
.ADR STMI,.DIS 41,.TRAX STM,.TRAX STM
;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,
	.TRAX PMV,.TRAX PMV,.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 03,.END,.END,.END GFAD,.END GFSB,.END JSYS,.END ADJSP
	.END GFMP,.END GFDV

;OPCODES 52 AND 53 COME HERE (PMOVE AND PMOVEM)
.ADR PMV,.TXT PMOVE,.DIS 01,.END,.TRA M
;**********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:	SETZ	T,		;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
	SETZB	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:	SETZ	R,		;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
	SETOM	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, W1, AND W2.

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	; . . .
	MOVEI	W1,USYMP	;WANT TO UPDATE UNDEF POINTERS
	MOVNI	W2,2		;BY ONE SYMBOL
	PUSHJ	P,DECSYP	;DO THE WORK
	 POPJ	P,		;BLEW IT SOMEWHERE
	DMOVE	TT,USYMP+S$ADR	;GET UNDEFINED'S ADR AND LEN
	DMOVEM	TT,ESTUT	;UPDATE TEMP COPY
	JRST	CPOPJ1		;GIVE GOOD RETURN
SUBTTL	SYMBOL TABLE ROUTINES -- UPDATE SYMBOL TABLE POINTERS

;INCSYP -- INCREASE SYMBOL TABLE SIZE BY ONE SYMBOL.
;DECSYP -- DECREASE SYMBOL TABLE SIZE BY N WORDS.
;DECSYA -- LOWER START ADDRESS OF A TABLE BY ONE SYMBOL.
;
;CALL:
;	MOVEI	W1,<INTERNAL SYMBOL BLOCK ADDRESS>
;	MOVNI	W2,<# WORDS TO DECREMENT>	;DECSYP ONLY
;	PUSHJ	P,INCSYP/DECSYP/DECSYA
;	 SOME KIND OF FAILURE (READ/WRITE)
;	SUCCESS, POINTER UPDATED
;
;USES W, W1, W2

DECSYP:	SETO	W,		;FLAG ADDRESS AND LENGTH
	JRST	INCSY0		;JOIN COMMON CODE

DECSYA:	TDZA	W,W		;FLAG ADDRESS ONLY
INCSYP:	SETO	W,		;FLAG ADDRESS AND LENGTH
	MOVEI	W2,2		;A SYMBOL USES TWO WORDS
INCSY0:	MOVEM	W2,TEM		;KEEP IT SAFE
	SKIPE	W		;IF DOING BOTH,
	ADDM	W2,S$LEN(W1)	;UPDATE LENGTH
	EXCH	W2,S$ADR(W1)	;SET UP FOR SUBM
	SUBM	W2,S$ADR(W1)	;UPDATE ADDRESS

  IFN FTFILE,<JRST CPOPJ1>	;FILDDT UPDATES WHEN FILE CLOSED

  IFE FTFILE,<
	PUSHJ	P,SAVRST	;SAVE SOME ACS
	SKIPN	R,S$SUB(W1)	;GET PDV SUBTABLE OR IOWD ADDRESS
	POPJ	P,		;NEITHER, SO DON'T UPDATE IT
	SKIPL	S$SUF(W1)	;WHICH FORMAT POINTER?
	JRST	INCSYV		;VECTOR SUBTABLE ADDRESS
	MOVN	T,S$LEN(W1)	;IOWD-FORMAT, SIMPLE CASE
	HRL	T,T		;NEG COUNT IN LH
	HRR	T,S$ADR(W1)	;ADDRESS IN RH
	JRST	INCSY4		;AND STUFF IT BACK IN
;STILL IFE FTFILE

;HERE TO UPDATE A SYMBOL TABLE VECTOR'S POINTERS

INCSYV:	ADDI	R,.STDAT	;WANT THE TYPE/LENGTH WORD
	JUMPE	W,INCSY2	;ARE WE UPDATING LENGTH?
	PUSHJ	P,FETCH		;YES, GO GET IT
	 POPJ	P,		;SHOULDN'T HAPPEN
	LDB	W2,[POINTR T,ST%LEN]  ;GET JUST THE LENGTH
	ADD	W2,TEM		;UPDATE IT
	DPB	W2,[POINTR T,ST%LEN]  ;PUT IT BACK IN THE RIGHT PLACE
	PUSHJ	P,DEPMEM	;AND STUFF IT INTO CORE
	 POPJ	P,		;WON'T GO
INCSY2:	ADDI	R,.STPTR-.STDAT	;NOW POINT TO ADDRESS WORD
	PUSHJ	P,FETCH		;GO GET THE XFIW
	 POPJ	P,		;NO GO
	SUB	T,TEM		;UPDATE ADDRESS WORD
INCSY4:	PUSHJ	P,DEPMEM	;GO STUFF NEW LENGTH
	 POPJ	P,		;COULDN'T?
	SETOM	SYMVAL		;SYM POINTERS ARE STILL VALID!
IFN FTEX10,<			;HIDDEN SYMBOLS ONLY ON A -10
	SKPUSR			;ONLY USE HIDDEN SYMBOLS IN EXEC MODE
	SKIPN	HSBLK		;AND ONLY IF WE HAVE THEM
	JRST	CPOPJ1		;NO, DON'T HAVE TO CHASE THEM DOWN
	SKIPE	R,JOBEDV	;NEED A LONG EDV FOR THIS
	SKIPL	S$SUF(W1)	;AND THIS ONLY MATTERS FOR IOWD-STYLE PTRS
	JRST	CPOPJ1		;NO NEED TO CHASE THE RING OTHERWISE
	PUSH	P,T		;SAVE THE WORD TO DEPOSIT
	MOVEI	S,.EDSYM-.EDCNT	;FORM INITIAL OFFSET TO WORD TO CHANGE
	CAIN	W1,USYMP	;UNLESS DOING UNDEFINEDS,
	MOVEI	S,.EDUSY-.EDCNT	;THEN USE THIS OFFSET
IFN .EDCNT,ADDI R,.EDCNT	;POINT TO THE COUNT WORD
	PUSHJ	P,FETCHV	;GET THE LENGTH WORD FOR THIS EDV
	  JRST	INCSY8		;OOPS
	TLZ	T,-1		;KEEP ONLY THE LENGTH
	CAIG	T,.EDLNK	;IS IT LONG ENOUGH FOR US?
	JRST	INCSY9		;NO, GIVE UP
INCSY6:	ADDI	R,.EDLNK-.EDCNT	;POINT TO LINK WORD
	PUSHJ	P,FETCHV	;GET ADDRESS OF NEXT EDV IN RING
	  JRST	INCSY8		;OOPS
	MOVE	R,T		;NEXT BLOCK WE WANT TO HACK
	CAMN	R,JOBEDV	;UNLESS WE'VE GONE ALL THE WAY AROUND
	JRST	INCSY9		;THEN WE'RE DONE
IFN .EDCNT,ADDI R,.EDCNT	;KEEP POINTING AT COUNT WORD
	ADD	R,S		;NOT DONE, SO POINT TO WORD TO CHANGE
	MOVE	T,(P)		;RETRIEVE WORD TO STORE
	PUSHJ	P,DEPMEM	;DEPOSIT INTO THIS EDV
	  JRST	INCSY8		;OOPS
	SUB	R,S		;BACK OFF TO START OF EDV
	SETOM	SYMVAL		;THEY'RE STILL VALID SO FAR
	JRST	INCSY6		;LOOP OVER ALL EDVS IN RING

INCSY8:	SETZM	SYMVAL		;SOMETHING GOT MESSED UP
INCSY9:	POP	P,T		;RESTORE STACK
> ;END IFN FTEX10
	JRST	CPOPJ1		;GIVE GOOD RETURN
  > ;END IFE FTFILE
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:
  IFE FTFILE,<PUSHJ P,SYMCHK>	;MAKE SURE WE TRUST THE SYMBOL POINTERS
  IFN FTEX10,<PUSHJ P,SYMSPC>	;SELECT SYMBOL SPACE

	MOVE	R,SYMP+S$LEN	;GET NUMBER OF SYMBOLS IN LOWSEG TABLE
	ADD	R,HSYMP+S$LEN	;TOTAL NUMBER OF SYMBOL WORDS TO LOOK AT
	MOVEM	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+S$ADR	;NO, FETCH LOWSEG TABLE POINTER
	SKIPA	S,HSYMP+S$ADR	;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:
  IFE FTFILE,<PUSHJ P,SYMCHK>	;MAKE SURE WE TRUST THE SYMBOL POINTERS
  IFN FTEX10,<PUSHJ P,SYMSPC>	;SELECT SYMBOL SPACE

	MOVE	S,ESTUT		;GET OUR UNDEFINED TABLE
	MOVE	R,ESTUTL	;GET COUNT OF WORDS IN IT
	MOVEM	R,SY2GO		;PUT COUNT INTO SY2GO
	SOJL	R,CPOPJ		;COUNT-1 INTO R, RETURN -1 IF NO SYMS
	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
	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


;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?
	SKIPN	HSYMP+S$ADR	;LOSEG - IS THERE A HISEG TABLE TO SEARCH?
	SKIPN	S,SYMP+S$ADR	;HISEG LAST OR NO TABLE, HOW ABOUT LOSEG?
	SKIPA	S,HSYMP+S$ADR	;HISEG'S TURN OR NO LOSEG TABLE, GET HISEG
	SKIPA	TT1,SYMP+S$LEN	;LOSEG, ALSO GET LENGTH
	SKIPA	TT1,HSYMP+S$LEN	;HISEG, ALSO GET LENGTH
	TXZA	F,HSYMF		;GOING TO SEARCH LOWSEG TABLE: REMEMBER IT
	TXO	F,HSYMF		;GOING TO SEARCH HISEG TABLE: REMEMBER IT
	ADD	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,<ADDRESS OF 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:	MOVE	TT1,S		;COPY ADDRESS OF TABLE
	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
	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
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,		; . . .
  > ;END IFN FTEXEC
	PUSHJ	P,GETHSO	;GET START OF HISEG
	JUMPE	T,CPOPJ		;EXIT IF NONE
	ADD	R,T		;RELOCATE
	PJRST	FETCHL		;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
;FETCHI  --  FETCH FROM MEMORY POINTED TO BY PC
;CALL IS:
;
;	MOVX	R,<ADR>		;DDT INTERNAL ADDRESS IF DDAF ON
;	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 FTEX10,<
	PUSHJ	P,SYMSPC	;PUT OURSELF IN THE SYMBOL SPACE
  > ;END IFN FTEX10

	PUSHJ	P,R2ADDR	;CONVERT R TO ADDRESS TO USE
	JRST	FETCHS		;JOIN COMMON CODE BELOW

  > ;END OF IFE FTFILE
;HERE TO FETCH A WORD POINTED TO BY PC
FETCHI:	TRNN	R,-20		;PC (BY DEFINITION "LOCAL") IN THE ACS?
	ANDI	R,17		;YES, REDUCE TO REGISTER ADDRESS

;HERE FOR A GENERAL USER FETCH, AS IN RESPONSE TO <LOCATION>/

FETCH:	SETZM	MEMERS		;CLEAR ERR MSG
	TXZE	R,DDAF		;INTERNAL ADDRESS?
	JRST	[TLNE	R,377777	;MUST BE PURE IFIW
		JRST	.+1		;NO, SO NOT INTERNAL
		MOVE	TT,R
		PUSHJ	P,DDSYMC	;YES, LOOK IT UP
		 JRST	[SMERS	<INVALID DDT INTERNAL ADDRESS>
			POPJ	P,]
		MOVE	T,0(R)		;FETCH IT
		JRST	CPOPJ1]
	ANDX	R,VMADR		;USE ONLY VALID 30 BITS
	CAMLE	R,UPROT		;AND .LE. PROTECTION ADDRESS
	JRST	[SMERS	<ABOVE PROTECTION REGISTER LIMIT>
		POPJ	P,]
	PUSHJ	P,SAVR		;PRESERVE VIRTUAL ADDRESS FOR CALLER
	ADD	R,UBASE		;RELOCATE PER USER REQUEST
	JSP	TT1,FETFAC	;POSSIBLY FETCH FROM FAKE AC
  IFN FTPAGM,<
	PUSHJ	P,MAPADR	;DO ANY MAPPING NECESSARY
	 POPJ	P,		;ACCESS FAILURE
    IFE FTFILE,<		;ALWAYS VIRTUAL FETCH IN FILDDT
	SKIPE	MAPFN		;PHYSICAL OR VIRTUAL FETCHING NEEDED?
	JRST	FETCH3		;PHYSICAL FETCH
    > ;END IFE FTFILE
  > ;END IFN FTPAGM
	JRST	FETCH6		;NO, ORDINARY VIRTUAL FETCH
;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
;USED ONLY FOR FINDING JOBDAT INFORMATION.  IF SYMTAB NOT FROM JOBDAT,
;OPERATION IS UNDEFINED.

  IFE FTDEC10,<
FETCHL:	SKIPLE	SYTLOC		;LOOKING AT JOBDAT SYMS?
	POPJ	P,		;NO, CAN'T FETCH ANYTHING
	HRL	R,SYTLOC	;YES, SECTION IS IN RIGHT HALF
    IFN FTUD20,<		;IF USER-20,
	SKIPN	SYTLOC		;IF 0$5M,
	HLL	R,SECUDD	; USE STUB'S SECTION
    > ;END IFN FTUD20
;	PJRST	FETCHV		;NOW DO A VIRTUAL FETCH
  > ;END IFE FTDEC10

;HERE TO DO A VIRTUAL FETCH FROM "USER" ADDRESS SPACE

  IFN FTDEC10,<
FETCHL:!
  > ;END IFN FTDEC10
FETCHV:	PUSHJ	P,SAVR		;SAVE R AS ADVERTISED
FETCH5:	JSP	TT1,FETFAC	;SEE IF FAKE AC REFERENCE
FETCH6:
  IFN FTEX10,<PUSHJ P,NORSPC>	;MAKE SURE IN NORMAL ADDRESS SPACE
FETCHS:	PUSHJ	P,CHKADR	;SEE IF ACCESSIBLE ADDRESS
	TXNN	TT,PG$EXI	;DOES PAGE EXIST?
	JRST	[SMERS	<PAGE DOES NOT EXIST>
		POPJ	P,]	;SET ERROR MSG AND RETURN
	TXNN	TT,PG$REA	;AND CAN WE READ IT?
	JRST	[SMERS	<NO READ ACCESS>
		POPJ	P,]	;SET ERROR MSG AND RETURN
	JSP	TT2,PZAFI	;MAY WANT TO BE IN SECTION 1
	MOVE	T,@R		;FETCH DESIRED VIRTUAL WORD
    IFN FTDEC20,<
	ERJMP	[SMERS	<ACTUAL REFERENCE FAILED>
		POPJ	P,]	;RETURN FAILURE IF THIS JUST ISN'T OUR DAY
    > ;END IFN FTDEC20
	JRST	CPOPJ1		;RETURN SUCCESSFULLY

> ;END OF IFE 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,

;FALL INTO DMEMER



;DMEMER  --  DEPOSIT INTO MEMORY, GO TO ERR IF FAILURE

DMEMER:	PUSHJ	P,DEPMEM	;TRY TO DEPOSIT INTO MEMORY
	 SKIPA
	POPJ	P,		;SUCCESS, JUST RETURN
DMER1:	MOVEI	T,"?"		;START ERR MSG
	PUSHJ	P,TOUT
	SKIPE	W1,MEMERS	;GIVE SPECIFIC MESSAGE IF THERE IS ONE
	PUSHJ	P,TSTRG
	JRST	RERR		;CLEAN UP


;DSYMER  --  DEPOSIT INTO SYMBOL TABLE, GO TO ERR IF FAILURE

DSYMER:	PUSHJ	P,DEPSYM	;TRY TO DEPOSIT INTO SYMBOL TABLE
	 SKIPA
	POPJ	P,		;JUST RETURN
	TSTR	<?CAN'T DEPOSIT INTO SYMBOL TABLE BECAUSE >
	SKIPN	W1,MEMERS
	MOVEI	W1,[ASCIZ /DEPOSIT FAILED/]
	PUSHJ	P,TSTRG
	JRST	RERR
;DEPMEM  --  DEPOSIT INTO MEMORY
;DEPSYM  --  DEPOSIT INTO SYMBOL TABLE (E.G., FILDDT)
;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 FTEX10,<
	PUSHJ	P,SYMSPC	;PUT OURSELF IN THE SYMBOL SPACE
  > ;END IFN FTEX10

	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:	SETZM	MEMERS		;CLEAR ERROR
	TXZE	R,DDAF		;INTERNAL ADDRESS?
	JRST	[TLNE	R,377777	;MUST BE PURE IFIW
		JRST	.+1		;ELSE IS NOT INTERNAL
		MOVE	TT,R
		PUSHJ	P,DDSYMC	;YES, LOOK IT UP
		 JRST	[SMERS	<INVALID DDT INTERNAL ADDRESS>
			POPJ	P,]
		MOVEM	T,0(R)		;FETCH IT
	IFE FTFILE,<SETZM SYMVAL>	;FORCE RECHECK OF SYMTAB POINTERS
		JRST	CPOPJ1]
	ANDX	R,VMADR		;USE ONLY VALID 30 BITS
	CAMLE	R,UPROT		;AND .LE. PROTECTION ADDRESS
	JRST	[SMERS	<ABOVE PROTECTION REGISTER LIMIT>
		POPJ	P,]
	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
  > ;END IFN FTFILE
  IFN FTPAGM,<
	PUSHJ	P,MAPADR	;DO ANY PAGE MAPPING NEEDED
	 POPJ	P,		;ACCESS FAILURE
    IFE FTFILE,<		;NO DIFFERENCE IN FILDDT
	SKIPE	MAPFN		;DO PHYSICAL OR VIRTUAL STORE?
	JRST	STORE3		;PHYSICAL STORE
    > ;END IFE FTFILE
  > ;END IFN FTPAGM
	JRST	STORE6		;ORDINARY VIRTUAL STORE
;USER AND EXEC DDT STYLE HANDLING

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	(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 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
    IFN FTDEC10,<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		;NO - SHOULD WE TRY TO WRITE-ENABLE?
	JRST	[SMERS	<NOT WRITABLE>
		POPJ	P,]

;FALL INTO NEXT PAGE
;STILL IFE FTFILE

;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
	PUSHJ	P,WEPAGE	;WRITE-ENABLE THE PAGE
	  JRST [SMERS	<Can't write-enable page>
		POPJ	P,]	;LOSE
	JSP	TT2,PZAFI	;MAY WANT TO SNEAK INTO SECTION 1
	MOVEM	T,@R		;DO THE STORE
	PUSHJ	P,WLPAGE	;WRITE-LOCK THE PAGE AGAIN
	  JRST	CPOPJ1		;SUCCEED EVEN IF CAN'T
	JRST	CPOPJ1		;SUCCESSFUL RETURN
  > ;END OF IFN FTDEC10
;STILL IFE FTFILE

;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!FH%EPN  ;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 [SMERS	<CAN'T BE WRITE ENABLED>
		POPJ	P,]
	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
		SMERS	<UNEXPECTED MOVEM FAILURE>
		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,@[MSEC1,,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	@[MSEC1,,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
		SMERS	<Unexpected MOVEM failure>
		JRST	.+1]	;BUT CONTINUE TO RE-WRITE PROTECT
	SETOM	LASTPG		;STORE COULD HAVE CHANGED PROPERTIES
	PUSHJ	P,@[MSEC1,,SWPMWP]  ;RE-WRITE PROTECT THE MONITOR
	JRST	CPOPJ1		;RETURN SUCCESS TO CALLER
  > ;END IFN FTMON
;STILL IFE FTFILE

;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?????
	JSP	TT2,PZAFI	;MAY WANT TO DO THIS IN SECTION 1
	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
;STILL IFE FTFILE

;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?
	JRST	[SMERS	<CAN'T CREATE PAGE>
		POPJ	P,]	;NO, DON'T CREATE PAGE

  IFN FTDEC10,<
	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
	 JRST	[SMERS	<CAN'T CREATE PAGE>
		POPJ	P,]
STORE9:	JSP	TT2,PZAFI	;MAY WANT TO DO THIS IN SECTION 1
	MOVEM	T,@R		;DO THE STORE
	JRST	CPOPJ1		;SUCCESSFUL RETURN
  > ;END IFN FTDEC10
;FALL THROUGH FROM STORE 8

  IFN FTDEC20,<
	TXNN	TT,PG$WRT	;WRITEABLE?
	JRST [	SMERS	<NOT WRITABLE>
		POPJ	P,]
	MOVE	TT2,R
	PUSHJ	P,CRESEC	;CHECK AND CREATE SECTION IF NECESSARY
	SKIPN	SAVSTS		;WAS PSI ON?
	JRST	STORE9		;NO, DON'T WORRY ABOUT PAGE-CREATE TRAPS
	DMOVEM	T1,TTEM1	;SAVE SOME TEMPS
	MOVEI	T1,.FHSLF	;FIND OUT OUR PROCESS'
	RCM%			; ACTIVE CHANNELS
	TXNN	T1,1B<.ICNXP>	;PAGE CREATES BEING TRAPPED?
	JRST [	DMOVE	T1,TTEM1	;NO, RESTORE THE ACS
		JRST	STORE9]		; AND KEEP GOING
	MOVEI	T1,.FHSLF	;PAGE CREATES BEING TRAPPED, WE HAVE
	MOVX	T2,1B<.ICNXP>	; TO DEACTIVATE THE CHANNEL IN ORDER
	DIC%			; TO PREVENT A LATER INTERRUPT
	SETOM	SAVNXP		;REMEMBER WE DID THIS
	DMOVE	T1,TTEM1	;RESTORE ACS
	CAIA			;AND FALL INTO STORE9
STORE9:	SETZM	SAVNXP		;PAGE CREATES NOT BEING TRAPPED
	JSP	TT2,PCAFI	;SUPPRESS ADDRESS BREAK AND
	MOVEM	T,@R		;DO THE STORE
	ERJMP [	SMERS	<UNEXPECTED MOVEM FAILURE>
		SOS	(P)	;FORCE LATER ERROR RETURN
		JRST	.+1]	;CHECK PSI CHANNEL
	SETOM	LASTPG		;STORE COULD HAVE CHANGED PROPERTIES
	SKIPN	SAVNXP		;DID WE DISABLE THE CHANNEL?
	JRST	CPOPJ1		;NO, ALL DONE
	DMOVEM	T1,TTEM1	;SAVE ACS AGAIN
	MOVEI	T1,.FHSLF	;WE NEED TO RE-ACTIVATE THE
	MOVX	T2,1B<.ICNXP>	; PSI CHANNEL SO THE USER CAN'T
	AIC%			; TELL WE FOOLED WITH IT
	DMOVE	T1,TTEM1	;GET ACS BACK
	JRST	CPOPJ1		;SUCCESSFUL RETURN

;CHECK FOR NONX SECTION AND CREATE IT

CRESEC:	HLRZ	TT,TT2		;GET SECTION INTO TT
	PUSHJ	P,CHKSEC	;SEE IF IT'S THERE
	TXNE	TT,PG$SXI	;SECTION EXIST?
	POPJ	P,		;YES, ALL DONE
	PUSHJ	P,SAVT4		;SAVE JSYS ARG ACS
	SETZ	T1,		;CREATE PRIV SECTION
	HLRZ	T2,TT2
	HRLI	T2,.FHSLF
	MOVX	T3,PM%RD+PM%WR+1 ;1 SECTION, READ AND WRITE
	SMAP%
	 ERJMP	CPOPJ		;FAILED, JUST CONTINUE
	POPJ	P,
  > ;END OF IFN FTDEC20
  IFE FTEXEC,<
STOREP==STOREV			;NON-EDDT PHYSICAL STORE GOES TO VIRTUAL
STORE3==STORE6			; DITTO
  > ;END IFE FTEXEC
> ;END OF IFE FTFILE
;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
  IFE FTPAGM,<
	MAPADR==CPOPJ1		;ALWAYS WIN
  > ;END IFE FTPAGM
  IFN FTPAGM,<

;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:	SETOM	MAPBTS		;KEEP TRACK OF THE ACCESS BITS
	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
	PUSH	P,FAKEAC	;MUST PRESERVE THIS
	SETZM	FAKEAC		;BUT PAGING USES PHYSICAL MEMORY
	PUSHJ	P,@MFNDSP(TT1)	;DISPATCH ON $U FUNCTION CODE
	  TRNA			;PROPAGATE NON-SKIP
	AOS	-1(P)		;AND SKIP
	POP	P,FAKEAC	;RESTORE THE FLAG
	POPJ	P,		;RETURN


;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 13,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,		;NO--ERROR
	ANDM	T,MAPBTS	;REMEMBER THE FLAGS (JUST IN CASE)
	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
;STILL IFN FTPAGM

;HERE TO MAP THROUGH SECTION TABLE IN MAPPG

MAPSEC:	TLNE	R,-1		;SECTION TABLE ONLY HAS 18 BITS OF ADDRESS
	JRST [	SMERS	<ADDRESS GREATER THAN 777777>
		POPJ	P,]
	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
;STILL IFN FTPAGM

;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,MSECTB(T)	;YES, GET DESIRED SECTION TABLE POINTER
	PUSHJ	P,FETCHP	;FETCH SECTION TABLE POINTER
	  JRST	MAPAD9		;INACCESSIBLE, ERROR
	ANDM	T,MAPBTS	;REMEMBER THE BIT MASK FOR WRITE & CACHE
	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
	ANDM	T,MAPBTS	;KEEP TRACK OF THE FLAGS
	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
;STILL IFN FTPAGM

;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?
	JRST [	SMERS	<NOT IN CORE>
		POPJ	P,]
	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)
;STILL IFN FTPAGM

;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
	 JRST [	POP	P,R	;NOT IN ADDRESS SPACE
		POPJ	P,]
	MOVE	R,TT		;PUT INTO AC R
	ADD	R,T		;ADD IN INDEX
	PUSHJ	P,FETCHP	;GET SPT ENTRY
	 SETZ	T,
	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
	ANDM	T,MAPBTS	;KEEP TRACK OF THE BITS
	JRST	MAPTY		;AND START OVER

MAPTBL:	IFIW	MAPTYB		;0 - NO PAGE
	IFIW	MAPTY1		;1 - IMMEDIATE POINTER
	IFIW	MAPTY2		;2 - SHARED POINTER
	IFIW	MAPTY3		;3 - INDIRECT POINTER
	IFIW	MAPTYB		;4 - ILLEAGL
	IFIW	MAPTYB		;5 - ILLEGAL
	IFIW	MAPTYB		;6 - ILLEGAL
	IFIW	MAPTYB		;7 - ILLEGAL

MAPTYB:	SMERS	<BAD POINTER ENCOUNTERED>
	POPJ	P,
  > ;END IFN FTPAGM
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:	HRRI	TT2,R		;ASSUME <INSTR> INDIRECTS THROUGH "R"
	MOVEM	TT2,SWTEM	;STASH <INSTR> IN TEMP HOLDING AREA
	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??!!
	JSP	TT2,PCAFI	;SUPPRESS ADDRESS BREAK AND
	XCT	SWTEM		;EXECUTE THE OPERATION
	AOS	-2(P)		;TAKE SUCCESSFUL RETURN FROM PHYIN
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
	ADDI	TT,MSECTB	;RELOCATE TO SECTION POINTERS
	MOVE	TT,@TT		;GET THE SECTION 0 POINTER
PHYI22:	LDB	TT1,[POINTR TT,PTRCOD]  ;EXTRACT POINTER TYPE FIELD
	CAIN	TT1,IMMCOD	;IMMEDIATE POINTER?
	JRST	PHYI24		;YES, TRIVIAL
	CAIE	TT1,SHRCOD	;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,IMMPTR!PTWR	;MAKE INTO WRITE-ENABLE IMMEDIATE PTR
	MOVEM	TT1,@TT		;UPDATE SECTION TABLE
	HRRZ	TT1,TT1		;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!)
	MOVX	TT,<AGEMSK!CSWRB> ;LEGAL AGE AND WRITE ENABLE CST WORD
	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
	JSP	TT2,PCAFI	;SUPPRESS ADDRESS BREAK AND
	XCT	SWTEM		;REFERENCE DESIRED PHYSICAL ADDRESS
	AOS	-6(P)		;SUCCESSFUL RETURN FROM PHYIN
PHYI26:	POP	P,TT1		;ADDR OF CST ENTRY FOR REFERENCED PAGE
	MOVX	TT,CORMB	;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
IFN FTEX10,<

;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 IFN FTEX10

;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 IFN FTEX10

;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 IFN FTEX10

;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:	SMERS	<FAILURE ON SWITCHING ADDRESS SPACE>
	SKIPE	@ADRSPC		;WHERE WERE WE GOING?
	PJRST	NORSPC		;TO ALTERNATE, TRY TO GET BACK
	POPJ	P,		;TO NORMAL, ALL DONE

  > ;END IFN FTEX10
;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+S$ADR	;NO, GET LOWSEG PTR
	MOVE	T,HSYMP+S$ADR	;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
	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 INTERNAL SYMBOL POINTER BLOCK (E.G. SYMP) WHICH
;CONTAINS THE ACTUAL SYMBOL TABLE ADDRESS/LENGTH 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 BLOCK IS INVALID OTHERWISE THE NORMAL
;RETURN IS TAKEN.
;
;USES TT, TT1

CHKSYP:	JUMPLE	T,CPOPJ		;POINTER MUST BE .GT. 0
  IFN FTEX10,<PUSHJ P,SYMSPC>	;MUST BE IN SYM VIRTUAL SPACE
	PUSHJ	P,SAVRST	;NEED SOME ACS
	MOVE	R,S$ADR(T)	;GET BASE ADDRESS OF TABLE
	JUMPE	R,CPOPJ		;FAIL IF NO TABLE
	MOVE	S,S$LEN(T)	;GET LENGTH
	JUMPL	S,CPOPJ		;CAN'T HAVE NEG. LENGTH SYM TAB!
	XMOVEI	T,SYBITS	;ADDRESS OF ROUTINE TO LOOK AT CHKADR RESULTS
	PJRST	CHKRNG		;CALL COMMON ROUTINE TO LOOK AT TABLE


;SYBITS -- CHKSYP ROUTINE TO 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
;CHKSEC -- CHECK SECTION ACCESSIBILITY
;CALL IS:
;
;	MOVX	TT,<SECTION>
;	PUSHJ	P,CHKSEC
;	RETURN
;
;WHERE <SECTION> IS THE SECTION NUMBER (NOT A PAGE OR ADDRESS).
;
;RETURNS WITH ACCESS BITS IN TT:
;	PG$SXI - SECTION EXISTS
;	PG$SMA - SECTION IS MAPPED ELSEWHERE
;	PG$SIN - SECTION IS MAPPED INDIRECTLY
;	PG$SEC - SECTION # MAPPED TO
; ON TOPS-20:
;	PG$SFJ - SECTION IS MAPPED TO ANOTHER FORK OR JFN
;	PG$FRK - FORK/JFN MAPPED TO
;	PG$REA - SECTION IS READABLE
;	PG$WT  - SECTION IS WRITABLE
;	PG$EXE - SECTION IS EXECUTABLE
;	PG$SHR - SECTION IS SHARABLE
;	PG$PRV - SECTION IS PRIVATE
;
;PRESERVES ALL OTHER ACS.

  IFE FTFILE!FTMON,<

    IFN FTDEC10,<
CHKSEC:
      IFN FTEXEC,<
	SKPUSR			;USER MODE?
	JRST	CHKSCX		;NO, SPECIAL CHECK
      > ;END IFN FTEXEC
	LSH	TT,PG2WRD	;MAKE SECTION # INTO PAGE #
	HRLI	TT,.PAGCA	;CHECK ACCESS
	PAGE.	TT,		;DO IT
	 MOVX	TT,PG$SXI	;CAN'T? RETURN NOTHING
	TXC	TT,PG$SXI	;-10 RETURNS "DOES NOT EXIST" BIT
	ANDX	TT,PG$SXI!PG$SMA!PG$SIN!PG$SEC	;ONLY SECTION-RELATED BITS
	POPJ	P,		;DONE
    > ;END IFN FTDEC10

    IFN FTDEC20,<
CHKSEC:
      IFN FTEXEC,<
	SKPUSR			;USER MODE?
	JRST	CHKSCX		;NO, SPECIAL CHECK
      > ;END IFN FTEXEC
	PUSHJ	P,SAVT4		;SAVE JSYS ACS
	MOVE	T1,TT		;GET SECTION NO.
	HRLI	T1,.FHSLF	;FOR THIS PROCESS
	RSMAP%			;GET ACCESS
	 ERJMP	CHKSE8		;FAILURE?  NO ACCESS
	AOJE	T1,CHKSE8	;NO MAPPING?  NO ACCESS
	SOSN	T1		;PRIVATE MAPPING?
	JRST [	TXO	T2,PG$PRV	;YES, FLAG IT
		JRST	CHKSE7]		;NOTHING ELSE TO CHECK
	TXO	T2,PG$SMA	;SECTION IS MAPPED SOMEWHERE
	DPB	T1,[POINTR T2,PG$SEC]	;REMEMBER WHERE TO
	HLRZS	T1		;GET FORK/JFN
	CAIN	T1,.FHSLF	;IS IT US?
	JRST	CHKSE7		;YES, ALL DONE
	TXO	T2,PG$SFJ	;NO, FLAG MORE INFO
	HRRM	T1,T2		;AND SAVE THE INFO
CHKSE7:	SKIPA	TT,T2		;RETURN ACCESS IN TT
CHKSE8:	SETZ	TT,		;RETURN NO ACCESS
	POPJ	P,		;ALL DONE
    > ;END IFN FTDEC20

  > ;END IFE FTFILE!FTMON
;CHKSEC FOR EDDT, MDDT

  IFN FTEXEC!FTMON,<
  IFN FTMON,<
CHKSEC:>
CHKSCX:	PUSHJ	P,SAVRST	;NEED SOME MORE ACS
	MOVX	S,PTWR!PTPUB!PTCACH	;START WITH FULL ACCESS
	MOVE	T,TT		;SAVE SECTION NUMBER
  IFN FTEXEC,<
	PUSHJ	P,GVEPT		;FIND THE EPT
	 JRST	CHKSC8		;NO CAN DO, NO ACCESS
  > ;END IFN FTEXEC
  IFN FTMON,<
	MOVEI	TT,KIEPT	;FIND THE EPT ADDRESS
  > ;END IFN FTMON
	ADDI	TT,MSECTB(T)	;RELOCATE TO SECTION POINTER
	MOVE	T,@TT		;FETCH THE POINTER
	SETZ	TT,		;CLEAR RETURN ACCESS BITS
CHKSC2:	AND	S,T		;REMEMBER THE ACCESS BITS
	LDB	R,[POINTR T,PTRCOD]	;GET THE POINTER TYPE
	CAIN	R,IMMCOD	;IMMEDIATE?
	JRST	CHKSC7		;YES, EASIEST
	CAIN	R,SHRCOD	;SHARED POINTER?
	JRST	CHKSC6		;YES, PRETTY EASY
	CAIE	R,INDCOD	;INDIRECT?
	JRST	CHKSC8		;UNKNOWN, NO ACCESS
	LDB	R,[POINT 9,T,17];FETCH NEW SECTION TABLE INDEX
	TLZ	T,-1		;REDUCE TO SPT INDEX
  IFN FTEXEC,<
	PUSHJ	P,GVSPT		;FIND THE SPT
	 JRST	CHKSC8		;CAN'T, NO SECTION
  > ;END IFN FTEXEC
  IFN FTMON,<
	MOVEI	TT,SPT		;FIND THE SPT ADDRESS
  > ;END IFN FTMON
	PUSH	P,R		;SAVE THE SECTION
	MOVE	R,TT		;GET THE SPT ADDRESS
	ADD	R,T		;GET THE PROPER SPT SLOT
	PUSHJ	P,FETCHV	;GET THE SPT ENTRY FOR THE NEW SECTION TABLE
	 SETZ	T,		;CAN'T, FLAG ERROR
	POP	P,R		;RESTORE THE SECTION INDEX
	JUMPE	T,CHKSC8	;NO ENTRY MEANS NO ACCESS
	TLNE	T,17		;PAGE IN CORE?
	JRST	CHKSC8		;NO, CAN'T READ THE NEW POINTER
	ANDI	T,17777		;GET PHYSICAL PAGE NUMBER
	LSH	T,PG2WRD	;MAKE IT AN ADDRESS
	ADD	R,T		;GET THE PROPER OFFSET INTO THE NEW TABLE
  IFN FTEXEC,<
	PUSHJ	P,FETCHP>	;GET THE NEW SECTION POINTER
  IFN FTMON,<
	PUSHJ	P,FETCHV>	;GET THE NEW SECTION POINTER
	 JRST	CHKSC8		;CAN'T, NO ACCESS ALLOWED
	MOVX	TT,PG$SMA!PG$SIN ;REMEMBER IT WAS INDIRECT
	JRST	CHKSC2		;GOT IT!  NOW LOOK AT THE NEW POINTER

;HERE WHEN A FINAL (DIRECT OR SHARED) POINTER IS FOUND

CHKSC6:	TXO	TT,PG$SMA	;SHARED POINTERS MEAN MAPPED
  IFN FTDEC10,<
CHKSC7:	TXOA	TT,PG$SXI	;-10 ONLY CARES ABOUT EXISTENCE
  > ;END IFN FTDEC10
  IFN FTDEC20,<
CHKSC7:	TXNE	S,PTPUB		;IS SECTION PUBLIC?
	TXOA	TT,PG$SHR	;YES, THAT MEANS SHARABLE
	TXO	TT,PG$PRV	;NO, THAT MEANS PRIVATE
	TXNE	S,PTWR		;WRITABLE?
	TXO	TT,PG$WT	;YES
	TXOA	TT,PG$SXI!PG$REA!PG$EXE	;ALL SECTIONS HAVE THIS ACCESS
  > ;END IFN FTDEC20
CHKSC8:	SETZ	TT,		;SAY NO ACCESS
	POPJ	P,		;RETURN
  > ;END IFN FTEXEC!FTMON
;CHKSEC FOR FILDDT

  IFN FTFILE,<
CHKSEC:	PUSHJ	P,SAVRST	;NEED SOME MORE ACS
	SETZ	T,		;START WITH NO ACCESS
	MOVE	R,TT		;GET SECTION IN R
	LSH	R,PG2WRD	;GET PAGE # OF FIRST PAGE IN SECTION
	MOVE	S,R		;COPY THAT PAGE
	IORI	S,PAGMSK	;LAST PAGE IN SECTION
	SKIPN	FILING		;LOOKING AT A FILE?
	JRST	CHKSE2		;NO, DON'T CHECK PGTLEN
	SKIPN	EXEFMT		;EXE FILE?
	JRST	CHKSE9		;SECTIONS MEANINGLESS IN A DATA FILE
    IFN FTPAGM,<
	SKIPLE	MAPFN		;IF MAPPING,
	JRST	CHKSE2		;CAN'T TELL HERE IF THE PAGES ARE IN RANGE
    > ;END OF IFN FTPAGM
	CAML	R,PGTLEN	;THIS SECTION PAST END OF EXE FILE?
	JRST	CHKSE9		;YES, SO NO ACCESS
	CAMGE	S,PGTLEN	;END OF SECTION PAST END OF EXE FILE?
	JRST	CHKSE2		;NO, LEAVE S ALONE
	MOVE	S,PGTLEN	;YES, ONLY GO TO END OF FILE (+1)
	SOS	S		;CORRECT TO END OF FILE
CHKSE2:	LSH	R,PG2WRD	;CHKADR WANTS ADDRESSES
	LSH	S,PG2WRD	;SO MAKE SOME ADDRESSES
CHKSE3:
    IFN FTPAGM,<
	PUSH	P,R		;SAVE THE VIRTUAL ADDRESS
	PUSHJ	P,MAPADR	;CONVERT VIRTUAL TO PHYSICAL
	  MOVX	R,.INFIN	;+VE INFINITY IF TRANSLATION FAILS
    > ;END OF IFN FTPAGM
	PUSHJ	P,CHKADR	;GET ACCESS OF A PAGE
	IOR	T,TT		;SAVE THE BITS
    IFN FTPAGM,<
	POP	P,R		;RESTORE VIRTUAL ADDRESS
    > ;END OF IFN FTPAGM
	ADDI	R,PAGSIZ	;BUMP TO NEXT PAGE
	CAMG	R,S		;DONE WHOLE SECTION YET?
	JRST	CHKSE3		;NO, GO FOR NEXT ONE
  IFE FTDEC10,<
	ANDX	T,PG$SXI!PG$REA!PG$WT!PG$EXE!PG$PRV!PG$SHR ;JUST WANT A FEW BITS
  >
  IFN FTDEC10,<
	TXNE	T,PG$EXI	;IF ANY PAGE EXISTS,
	TXO	T,PG$SXI	;SO DOES THE SECTION
	ANDX	T,PG$SXI	;ONLY NEED THIS BIT BACK ON THE -10
  >
CHKSE9:	MOVE	TT,T		;PUT ACCESS IN CORRECT PLACE
	POPJ	P,		;ALL DONE
  > ;END IFN FTFILE
;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, TT2, ALL OTHER ACS PRESERVED.

  IFE FTFILE,<

  IFN FTDEC10,<			;TOPS-10 STYLE
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
	SKPNS0			;IN NON-ZERO SECTION?
	TDNN	R,S0PLIM	;NO, ADDRESS MUST BE .LT. THIS
	TXNE	R,^-VMADR	;MUST ALWAYS BE .LT. 2**30
	JRST	CHKAD4		;NO WAY
  IFN FTEXEC,<			;EXEC IS DIFFERENT
	SKPUSR			;SEE IF USER OR EXEC MODE
	JRST	CHKADX		;EXEC, REQUIRES SPECIAL HANDLING
  > ;END IFN FTEXEC

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

	MOVE	TT,R		;ADDRESS
	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!PG$ACC  ;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:	MOVX	TT,PG$EXI!PG$SXI ;NO ACCESS (PAGE/SEC DOES NOT EXIST)
CHKAD6:	MOVEM	TT,LASTAF	 ;SAVE FULL AC FOR THOSE WHO CARE
	HLLZS	TT		 ;IGNORE RH FIELDS
	TXCA	TT,PG$EXI!PG$SXI ;PAGE. RETURNS COMPLEMENT 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
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
	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
  IFN FTEXEC,<			;EXEC IS DIFFERENT
	SKPUSR			;SEE IF USER OR EXEC MODE
	JRST	CHKADX		;EXEC, REQUIRES SPECIAL HANDLING
  > ;END IFN FTEXEC
	PUSHJ	P,SAVR		;SAVE R OVER (M)RPACS%
	MOVE	T1,R		;GET ADDRESS
  IFE FTMON,<
	LSH	T1,WRD2PG	;GET PAGE NUMBER
	HRLI	T1,.FHSLF!FH%EPN
	RPACS%			;READ PAGE ACCESS
	 ERJMP [TLZ	T1,FH%EPN	;FAILED, MAYBE MONITOR DOESN'T HAVE FH%EPN
		RPACS%			;TRY AGAIN
		 ERJMP [SETZ	T2,	;PROBABLY NO SECTION THERE
			JRST	.+1]	;NO SAY NO ACCESS
		JRST	.+1]		;HAVE IT NOW
  > ;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$CPY!PG$WT	;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
	JSP	TT2,PZAFI	;EXECUTE NEXT INSTR IN NON-0 SEC
	MAP	TT1,@R		;ASK PAGER'S OPINION
	TXNN	TT1,TWHPFF	;PAGE FAIL?
	TXNN	TT1,TWVALD	;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,PTWR	;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
	ADJSP	P,4		;MAKE STACK ROOM FOR PAGE FAIL WORDS
	ADDI	TT,500		;POINT TO PAGE FAIL BLOCK
	DMOVE	TT1,@TT		;SAVE FOUR PAGE-FAIL WORDS...
	DMOVEM	TT1,-3(P)	; PAGE-FAIL WORD
	ADDI	TT,2		; PAGE-FAIL OLD PC//PAGE-FAIL OLD PC FLAGS
	DMOVE	TT1,@TT		; PAGE-FAIL NEW PC//PAGE-FAIL OLD PC
	DMOVEM	TT1,-1(P)	; ----------------//PAGE-FAIL NEW PC
				; (NOTE CST WILL SHOW UPT MODIFIED)
	XMOVEI	TT1,KLNXM	;OUR VERY OWN PAGE-FAIL NEW PC
	MOVE	TT2,TT1		;FOR KI-PAGING AND KL-PAGING
	DMOVEM	TT1,@TT		;SET BOTH
	CONO	APR,1B22!1B25	;CLEAR NXM FLAG
	JSP	TT2,PZAFI	;SNEAK INTO NZS AS NEEDED FOR REF
	SKIP	@R		;REFERENCE MEMORY
	CONSZ	APR,1B25	;DID NXM FLAG SET?
KLNXM:	SETZ	T,		;YES, NO ACCESS
	DMOVE	TT1,-1(P)	;RESTORE
	DMOVEM	TT1,@TT		; OLD
	SUBI	TT,2		;  PAGE-FAIL
	DMOVE	TT1,-3(P)	;   WORDS
	DMOVEM	TT1,@TT		;    TO UPT
	ADJSP	P,-4		;RECLAIM STACK SPACE
	MOVE	TT,T		;ACCESS BITS BACK INTO TT
	MOVE	TT1,SAVAPR	;APR CONI WORD
	ANDI	TT1,7		;APR PI LEVEL
	CONO	APR,1B22!1B25(TT1) ;CLEAR NXM, RESTORE APR PI
	JRST	CHKAD8		;RETURN WITH ACCESS BITS IN TT
;STILL IFE FTFILE & IFN FTEXEC

;UNKNOWN PROCESSOR

CHKAE4:	HALT	ERR		;UNKNOWN PROCESSOR TYPE
  > ;END OF IFN FTEXEC
  > ;END OF IFE 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
  > ;END IFN FTEXEC
	PUSHJ	P,SAVR		;SAVE R TO POINT TO .JBHRL
  IFN FTDEC10,<			;TOPS-10 CASE
	HRROI	R,.GTSGN	;GETTAB TO SEE IF WE HAVE A SINGLE HISEG
	GETTAB	R,		;DO WE?
	  JRST	GETHS1		;NO, MUST TRY SEGOP. UUO
	JUMPLE	R,CPOPJ		;SPY SEG OR NONE, RETURN THE ZERO
	SETO	T,		;GET AN INVALID ADDRESS
	SEGOP.	T,		;TEST FOR 7.04 OR LATER MONITOR
	JUMPGE	T,GETHSS	;IF SO, USE SEGOP. TO FIND REAL SECTION
	HRLZ	T,R		;NO, USE SEGMENT NUMBER AS TABLE INDEX
	HRRI	T,.GTUPM	;TRY TO FIND ITS ORIGIN
	GETTAB	T,		;ASK THE MONITOR
	  JRST	GETHSQ		;KA?
	HLRZ	T,T		;POSITION ADDRESS WHERE IT BELONGS
	ANDI	T,^-PAGMSK	;MASK OUT JUNK
	HRROI	R,.GTSG2	;7.03 ONLY GETTAB
	GETTAB	R,		;GET SECTION ASSOCIATED WITH HISEG
	  SETZ	R,		;NON-EXTENDED MONITOR
	LSH	R,-<ALIGN.(SG%SCN)> ;ISOLATE SECTION NUMBER
	HRLI	T,(R)		;MAKE GLOBAL ADDRESS OF SEGMENT
	POPJ	P,		;RETURN IT TO CALLER

GETHSS:	MOVEM	R,SEGOPB+.SGSGN	;SAVE SEGMENT NUMBER OF INTEREST
	SETZM	SEGOPB+.SGSNM	;CLEAR SEGMENT NAME
	SETZM	SEGOPB+.SGFLG	;NO FLAGS
	MOVSI	R,.SGORG+1	;GET LENGTH WE DESIRE
	HLLM	R,SEGOPB	;SET FOR UUO
	XMOVEI	R,SEGOPB	;POINT TO THE BLOCK
	SEGOP.	R,		;GET THE INFORMATION
	  JRST [SETZ	T,	;SIGH, GIVE UP
		POPJ	P,]	;RETURN NONEXISTENCE TO CALLER
	HRRZ	T,SEGOPB+.SGORG	;GET LOCAL ORIGIN FOR SEGMENT
	LSH	T,PG2WRD	;CONVERT TO GLOBAL ADDRESS
	POPJ	P,		;RETURN TO CALLER

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

;HERE WE HAVE TO HUNT AROUND FOR A HISEG
GETHS1:	SKIPG	R,SYTLOC	;SEE IF A REAL $5M ARGUMENT WAS GIVEN
	JRST	GETHS2		;NO, GO TRY TO DEFAULT ONE
	LSH	R,WRD2PG	;YES, CONVERT TO A PAGE NUMBER
	HRLI	R,.PAGCA	;FUNCTION CODE
	PAGE.	R,		;GET ITS ACCESS BITS
	  JRST	GETHS2		;SKIP THIS ONE
	TXNE	R,PA.GHI	;MUST BE A HISEG
	TXNE	R,PA.GSP	;AND NOT A SPY-SEG
	JRST	GETHS2		;NO, TRY NEXT METHOD
	ANDI	R,PA.GSG	;YES, ISOLATE THE SEGMENT NUMBER
	JUMPE	R,GETHS2	;SHOULD NEVER HAPPEN....
	PJRST	GETHSS		;GET ITS ORIGIN AND RETURN IT
GETHS2:	MOVEI	R,.JBHRL	;HISEG END WORD
	PUSHJ	P,FETCHV	;GET FROM REAL JOBDAT
	  JRST	GETHS3		;NO SUCH LUCK
	TRNN	T,-1		;IS IT SET UP?
	JRST	GETHS3		;NO, TRY SOMETHING ELSE
	SKIPL	SYTLOC		;IF $5M SECTION SETUP, USE IT
	TLZA	T,-1		;JUST TRY S0 IF NOT A JOBDAT $5M
	HRL	T,SYTLOC	;YES, MAKE A GLOBAL ADDRESS
	LSH	T,WRD2PG	;CONVERT TO PAGE NUMBER
	HRLI	T,.PAGCA	;FUNCTION CODE
	PAGE.	T,		;GET ITS ACCESS BITS
	  JRST	GETHS3		;STALE DATA?
	TXNN	T,PA.GSP	;MUST NOT BE A SPY PAGE/SEGMENT
	TXNN	T,PA.GHI	;AND MUST BE IN A HISEG
	JRST	GETHS3		;WRONG, CAN'T USE IT
	ANDI	T,PA.GSG	;ISOLATE SEGMENT NUMBER
	JUMPE	T,GETHS3	;SIGH, STILL NO JOY
	MOVE	R,T		;YES, COPY SEGMENT NUMBER
	PUSHJ	P,GETHSS	;GET SEGMENT INFO
	SKIPN	R,T		;IF NOT THERE,
	JRST	GETHS3		;LOOK FOR SOMETHING ELSE
	PUSHJ	P,GETHSM	;CHECK FOR SYMBOLS IN THIS HISEG
	  POPJ	P,		;YES, RETURN ITS ORIGIN
GETHS3:	XMOVEI	R,1(P)		;SCRATCH SPACE
	SETZM	(R)		;FUNCTION TO READ ENTRY VECTOR
	ENTVC.	R,		;READ IT
	  JRST	GETHS4		;NONESUCH, TRY SOMETHING ELSE
	SKIPN	2(P)		;IF NO DATA,
	JRST	GETHS4		;TRY SOMETHING ELSE
	MOVE	R,3(P)		;YES, GET START OF VECTOR (OR START ADDRESS)
	LSH	R,WRD2PG	;CONVERT TO PAGE
	HRLI	R,.PAGCA	;FUNCTION CODE
	PAGE.	R,		;GET ITS ACCESS BITS
	  JRST	GETHS4		;SHOULD NEVER FAIL
	TXNE	R,PA.GHI	;MUST BE A HISEG
	TXNE	R,PA.GSP	;AND NOT A SPYSEG
	JRST	GETHS4		;WRONG, CAN'T USE IT
	ANDI	R,PA.GSG	;YES, ISOLATE SEGMENT NUMBER
	PUSHJ	P,GETHSS	;GET ITS ORIGIN
	SKIPN	R,T		;IF IT'S NOT THERE,
	JRST	GETHS4		;WE CAN'T USE IT
	PUSHJ	P,GETHSM	;CHECK FOR SYMBOLS
	  POPJ	P,		;YES, RETURN ITS ORIGIN
GETHS4:	MOVSI	R,.SGORG+1	;JUST IN CASE,
	HLLM	R,SEGOPB	;SETUP THE ARG BLOCK LENGTH WORD
	SETZM	SEGOPB+.SGSGN	;SET TO START FROM THE BEGINNING
	SETZM	SEGOPB+.SGSNM	;OF THE SEGMENT LIST
	MOVX	R,SG.STP	;GET THE STEP FLAG
	MOVEM	R,SEGOPB+.SGFLG	;SET SO WE CAN ITERATE THROUGH
	SETZ	T,		;NO REMEMBERED SEGMENT
GETHS5:	XMOVEI	R,SEGOPB	;POINT TO ARG BLOCK
	SEGOP.	R,		;GET INFO FOR THE NEXT SEGMENT
	  POPJ	P,		;RETURN WHATEVER WE LAST FOUND
	SKIPN	SEGOPB+.SGSGN	;IF OUT OF SEGMENTS,
	POPJ	P,		;RETURN WHATEVER WE LAST FOUND
	HRRZ	R,SEGOPB+.SGORG	;GET ITS LOCAL ORIGIN PAGE
	LSH	R,PG2WRD	;CONVERT TO AN ADDRESS
	HLRO	S,R		;GET -1,,SECTION NUMBER
	XOR	S,SYTLOC	;CHECK FOR MATCH WITH $5M LATER
	PUSHJ	P,GETHSM	;SEE IF THIS HISEG HAS SYMBOLS
	  MOVE	T,R		;YES, UPDATE LAST ADDRESS FOUND
	SKIPGE	SYTLOC		;IF WE CARE ABOUT $5M
	JUMPN	S,GETHS5	;THEN LOOP IF IT DIDN'T MATCH
	JUMPE	T,GETHS5	;LOOP ANYWAY IF NO SYMBOLS YET
	POPJ	P,		;FINALLY, WE HAVE SOMETHING

;HERE TO SEE IF THE HISEG POINTED TO BY R HAS SYMBOLS
;RETURN NON-SKIP IF YES WITH T, S, & R UNCHANGED
;RETURN SKIP IF NEED TO KEEP LOOKING
GETHSM:	PUSHJ	P,SAVRST	;HIDE THE SIDE EFFECTS
	ADDI	R,.JBHSM	;OFFSET TO FIND ITS SYMBOL TABLE
	PUSHJ	P,FETCHV	;DOES IT HAVE ANY?
	  JRST	CPOPJ1		;ASSUME NOT
	JUMPE	T,CPOPJ1	;GIVE CONTINUE RETURN IF NOT
	POPJ	P,		;YES, GIVE DONE RETURN
  > ;END OF IFN FTDEC10

  IFN FTDEC20,<			;TOPS-20 CASE
	MOVEI	R,.JBHRL	;HIGH SEG ORIGIN WORD
	PUSHJ	P,FETCHL	;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
	MOVEI	R,.JBHSO	;NOW FETCH ORIGIN WORD
	PUSHJ	P,FETCHL	;SHOULD BE SET UP BY LINK-20
	  SETZ	T,		;??
	SKIPN	T		;SET UP?
	MOVEI	T,400		;DEFAULT ORIGIN
	LSH	T,PG2WRD	;CONVERT TO ADDRESS
	HRL	T,SYTLOC	;PROPAGATE $5M SECTION
    IFN FTUD20,<		;IF HAVE A STUB
	SKIPN	SYTLOC		;IF 0$5M,
	HLL	T,SECUDD	;USE SECTION OF STUB
    > ;END IFN FTUD20
	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
	SKIPLE	SYTLOC		;IF NOT USING SOME SECTION'S JOBDAT,
	POPJ	P,		;RETURN IT UNCHANGED
	JUMPE	T,CPOPJ		;SIMILARLY IF NOT THERE
	HRL	T,SYTLOC	;YES, FILL IN SECTION FROM $5M
  > ;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,PGTPEN	;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
;WEPAGE AND WLPAGE -- ROUTINES TO WRITE-ENABLE AND WRITE-LOCK A PAGE
;CALL:
;	MOVE	R,VIRTUAL ADDRESS
;	PUSHJ	P,W?PAGE
;	  FAILURE RETURN
;	SUCCESS RETURN
;
;CLOBBERS ONLY TT-TT3

IFE FTFILE,<
  IFN FTDEC10,<
WEPAGE:	MOVE	TT,LASTAF	;GET THE PAGE. BITS FOR THIS PAGE
	TXNN	TT,PG$SPY	;CAN'T DO THIS FOR SPY PAGES
	TXNN	TT,PG$REA	;CAN WE READ IT?
	POPJ	P,		;NO--IT'S CONCEALED AND WE'RE NOT
	TXNE	TT,PG$HGH	;IS IT PART OF A HISEG?
	JRST	WEPAG1		;YES--GO TRY IT
	MOVE	TT3,R		;NO--COPY THE ADDRESS IN QUESTION
	LSH	TT3,WRD2PG	;CONVERT TO PAGE NUMBER FOR UUO
	MOVEI	TT2,1		;ONLY WANT TO HACK ONE PAGE
	MOVE	TT1,[.PAGWL,,TT2] ;UUO ARGUMENT TO WRITE-ENABLE A LOWSEG PAGE
	PAGE.	TT1,		;TRY IT
	  POPJ	P,		;PROPAGATE FAILURE
	JRST	CPOPJ1		;AND SUCCESS
WEPAG1:	TXNN	TT,PA.GSG	;DO WE HAVE A SEGMENT NUMBER?
	JRST	WEPAG2		;NO--MONITOR IS DEFINITELY TOO OLD FOR SEGOP.
	MOVE	TT3,TT		;COPY SEGMENT ARGUMENT
	ANDX	TT3,PA.GSG	;ISOLATE THE SEGMENT NUMBER
	SETZ	TT2,		;WE WISH TO CLEAR THE WRITE-PROTECT BIT
	MOVE	TT1,[3,,.SGSWP]	;SEGOP HEADER FOR 'SET-WRITE-PROTECT'
	MOVE	TT,[IFIW TT1]	;SECTION-LOCAL ADDRESS OF THE ARGUMENTS
	SEGOP.	TT,		;TRY TO WRITE-ENABLE THE SEGMENT
	  TRNA			;EXAMINE FAILURE
	JRST	CPOPJ1		;WE WON
	JUMPGE	TT,CPOPJ	;WE GOT AN ERROR CODE, PUNT
;HERE FOR MONITORS TOO OLD TO KNOW ABOUT SEGOP.
WEPAG2:	SETZ	TT,		;ARGUMENT TO CLEAR THE WRITE-PROTECT BIT
	SETUWP	TT,		;TRY TO CLEAR IT
	  POPJ	P,		;PROPAGATE FAILURE
	JRST	CPOPJ1		;AND SUCCESS

WLPAGE:	MOVE	TT,LASTAF	;GET THE PAGE. BITS FOR THIS PAGE
	TXNN	TT,PG$SPY	;CAN'T DO THIS FOR SPY PAGES
	TXNN	TT,PG$REA	;CAN WE READ IT?
	POPJ	P,		;NO--IT'S CONCEALED AND WE'RE NOT
	TXNE	TT,PG$HGH	;IS IT PART OF A HISEG?
	JRST	WLPAG1		;YES--GO TRY IT
	MOVE	TT3,R		;NO--COPY THE ADDRESS IN QUESTION
	LSH	TT3,WRD2PG	;CONVERT TO PAGE NUMBER FOR UUO
	TXO	TT3,PA.GAF	;ALTERNATE FUNCTION TO WRITE-LOCK
	MOVEI	TT2,1		;ONLY WANT TO HACK ONE PAGE
	MOVE	TT1,[.PAGWL,,TT2] ;UUO ARGUMENT TO WRITE-LOCK A LOWSEG PAGE
	PAGE.	TT1,		;TRY IT
	  POPJ	P,		;PROPAGATE FAILURE
	JRST	CPOPJ1		;AND SUCCESS
WLPAG1:	TXNN	TT,PA.GSG	;DO WE HAVE A SEGMENT NUMBER?
	JRST	WLPAG2		;NO--MONITOR IS DEFINITELY TOO OLD FOR SEGOP.
	MOVE	TT3,TT		;COPY SEGMENT ARGUMENT
	ANDX	TT3,PA.GSG	;ISOLATE THE SEGMENT NUMBER
	MOVEI	TT2,1		;WE WISH TO SET THE WRITE-PROTECT BIT
	MOVE	TT1,[3,,.SGSWP]	;SEGOP HEADER FOR 'SET-WRITE-PROTECT'
	MOVE	TT,[IFIW TT1]	;SECTION-LOCAL ADDRESS OF THE ARGUMENTS
	SEGOP.	TT,		;TRY TO WRITE-LOCK THE SEGMENT
	  TRNA			;EXAMINE FAILURE
	JRST	CPOPJ1		;WE WON
	JUMPGE	TT,CPOPJ	;WE GOT AN ERROR CODE, PUNT
;HERE FOR MONITORS TOO OLD TO KNOW ABOUT SEGOP.
WLPAG2:	MOVEI	TT,1		;ARGUMENT TO SET THE WRITE-PROTECT BIT
	SETUWP	TT,		;TRY TO SET IT
	  POPJ	P,		;PROPAGATE FAILURE
	JRST	CPOPJ1		;AND SUCCESS
  > ;END IFN FTDEC10
> ;END IFE FTFILE
;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,SAVT		;SAVE AN AC FOR THE GUESSES
	MOVE	T,EPTWRD	;PROBABLY SAME AS LAST TIME
	PUSHJ	P,FVEPT		;FIND THE EPT
	  SETO	TT,		;NOT THERE
	MOVEM	TT,EPTWRD	;STORE THE ADDRESS
	MOVE	T,UPTWRD	;MIGHT BE SAME AS LAST TIME
	PUSHJ	P,FVUPT		;FIND THE UPT
	  SETO	TT,		;NOT THERE
	MOVEM	TT,UPTWRD	;STORE THE ADDRESS
	MOVE	T,CSTWRD	;PROBABLY SAME AS LAST TIME
	PUSHJ	P,FVCST		;FIND THE CST
	  SETO	TT,		;NOT THERE
	MOVEM	TT,CSTWRD	;STORE THE ADDRESS
	MOVE	T,SPTWRD	;PROBABLY SAME AS LAST TIME
	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:
;
;	MOVE	T,<GUESS FOR EPT ADDRESS OR -1>
;	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
	ASH	T,WRD2PG	;MAKE GUESS A PAGE NUMBER (PRESERVE -1)
	PUSHJ	P,FPVPG0	;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:
;
;	MOVE	T,<GUESS FOR UPT ADDRESS OR -1>
;	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
	ASH	T,WRD2PG	;MAKE GUESS A PAGE NUMBER (PRESERVE -1)
	PUSHJ	P,FPVPG0	;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:
;
;	MOVE	T,<GUESS FOR CST/SPT ADDRESS OR -1>
;	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:	TDZA	TT,TT		;FLAG CST READ
FVSPT:	SETO	TT,		;FLAG SPT READ
	MOVNM	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
	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
	DMOVEM	2,FVTEM3	;READ CST AND SPT BASE
	DATAO	PAG,FVTEM2	;SWITCH BACK TO OLD ACS
	JRST	FVSPT9		;TRANSLATE TO VIRTUAL ADDRESS

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

;CONTINUED FROM PREVIOUS PAGE

FVSPT4:	SKPKS			;ON A KS-10?
	HALT	ERR		;NO???
	RDCSB	FVTEM3		;READ CST BASE ADDRESS
	RDSPB	FVTEM4		;AND SPT BASE ADDRESS

FVSPT9:	MOVE	TT,FVTEM1	;RETRIEVE CST/SPT FLAG
	MOVE	TT,FVTEM3(TT)	;GET APPROPRIATE BASE ADDRESS
	PUSHJ	P,SAVR		;NEED ANOTHER AC
	MOVEI	R,PAGMSK	;WORD-WITHIN-PAGE MASK
	AND	R,TT		;GET WORD OFFSET WITHIN PAGE
	PUSH	P,T		;SAVE GUESS FOR A SEC
	ANDI	T,PAGMSK	;GET IN-PAGE PART OF GUESS
	CAME	T,R		;SAME AS IN-PAGE PART OF PHY ADR?
	SETOM	(P)		;NO, GUESS IS BOGUS
	POP	P,T		;GET BACK REVISED GUESS
	ASH	T,WRD2PG	;MAKE GUESS A PAGE NUMBER (PRESERVE -1)
	LSH	TT,WRD2PG	;PHY PAGE OF BASE OF CST/SPT
	PUSHJ	P,FPVPG0	;FIND CORRESPONDING VIRTUAL ADDRESS
	 POPJ	P,		;NOT MAPPED, DIE
	LSH	TT,PG2WRD	;VIRTUAL WORD ADDRESS OF BASE PAGE
	ADD	TT,R		;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,<PHYSICAL PAGE NUMBER>
;	MOVX	T,<VIRTUAL PAGE GUESS OR -1>	;OPTIONAL
;	PUSHJ	P,FPVPG/FPVPG0			;FPVPG0 IF GUESS SUPPLIED
;	 ERROR RETURN
;	NORMAL RETURN
;
;WHERE <PHYSICAL PAGE NUMBER> IS THE PHYSICAL MEMORY PAGE NUMBER (E.G.,
;THE EPT) FOR WHICH AN EXEC VIRTUAL PAGE NUMBER IS DESIRED, AND
;<VIRTUAL PAGE GUESS> IS A PROBABLE VIRTUAL CORRESPONDENCE (OR -1 FOR
;NO GUESS).  IF -1 IS GIVEN, A ONE-TO-ONE VIRTUAL/PHYSICAL MAPPING WILL
;BE TRIED.
;
;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:	PUSHJ	P,SAVT		;DON'T BOMB T
	SETO	T,		; 'CAUSE IT COULD BE ANYTHING
FPVPG0:	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		; . . .
	SKIPG	T		;REASONABLE GUESS GIVEN?
	MOVE	T,TT		;NO, TRY ONE-TO-ONE MAPPING
	LSH	T,PG2WRD	;MAP WANTS ADDRESS, NOT PAGE
	MOVEI	TT1,777777	;MAX VIRTUAL ADDRESS IN SEC. 0
	SKPS0			;EXTENDED KL?
	HRLI	TT1,37		;YES, 37 SECTION LIMIT
	PUSH	P,TT1		;SAVE UPPER LIMIT
	MOVX	TT1,777-PAGSIZ	;STARTING POINT, PAGE "-1"
	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:	MAP	TT2,(T)		;MAP VIRTUAL ADDRESS OF GUESS
	CAIA			;DON'T LOSE THE DATA
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:	SKIPG	TT,TT1		;YES, EXEC VIRTUAL ADDRESS IS HERE
	MOVE	TT,T		;OR MAYBE HERE
	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:	MAP	TT2,@T		;MAP VIRTUAL ADDRESS OF GUESS
	CAIA			;DON'T LOSE THE DATA
FPVP22:	MAP	TT2,@TT1	;MAP EXEC VIRTUAL ADDRESS
	TXNN	TT2,TWHPFF	;PAGE FAIL?
	TXNN	TT2,TWVALD	;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
	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,<

;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:	SETZM	MAPFN
	SETOM	FAKEAC
	SETZM	UBASE		;RESET $U
	EXCH	T,UPROT		;SAVE T
	HRLOI	T,377777	;SET T TO LARGEST POSITIVE INTEGER
	EXCH	T,UPROT		;SET UPROT TO THIS VALUE
  IFN FTEXEC,<
	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
  > ;END OF IFN FTEXEC
	POPJ	P,		;AND RETURN
  > ;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
;PCAFI  --  ROUTINE TO SUPPRESS ADDRESS BREAK
;PZAFI  --  ROUTINE TO SUPPRESS ADDRESS BREAK, HANDLING NZS REFERENCES
;CALL IS:
;
;	JSP	TT2,PCAFI/PZAFI
;	 INSTR
;
;THIS ROUTINE WILL RETURN TO "INSTR" WITH ADDRESS BREAK INHIBIT SET
;SO THAT THE INSTRUCTION WILL NOT CAUSE AN ADDRESS BREAK.
;
;IF PZAFI IS CALLED IN SECTION ZERO, AND AC "R" REFERENCES A NON-ZERO
;ADDRESS, IT WILL PUT <INSTR> INTO THE SECTION 1 ACS TO BE EXECUTED.
;
;USED PRIMARILY BY FETCH AND STORE LOGIC.
;
;REGISTER R IS PRESUMED TO CONTAIN THE ADDRESS TO BE REFERENCED.
;
;<INSTR> MAY ***NOT*** REFERENCE TT1, TT2, OR TT3, NOR MAY IT EVER SKIP!!
;
;DESTROYS TT1, TT2, TT3

PZAFI:	TLNE	R,-1		;NON-ZERO-SECTION ADDRESS?
	SKPS0			;AND LOOKING FROM SECTION ZERO?
	PJRST	PCAFI		;NO, PRETEND WE'RE <JSP TT2,PCAFI>
	XSFM	TT1		;GET CURRENT PC FLAGS/PCS/ETC.
	TXO	TT1,PC$AFI	;SET ADDRESS-FAIL-INHIBIT PC FLAG
	MOVEM	TT1,NZSXJF	;SET XJRSTF PC FLAGS
	MOVE	TT1,[1,,TT1]	;SECTION-1 PC (IN THE ACS)
	MOVEM	TT1,NZSXJF+1	;SET XJRSTF PC ADDRESS
	MOVE	TT1,0(TT2)	;FETCH <INSTR> TO BE EXECUTED IN NZS SPACE
	HRRZI	TT3,1(TT2)	;SET INCREMENTED (SECTION-0) RETURN ADDRESS
	MOVE	TT2,[XJRST TT3]	;SET UP RETURN INSTRUCTION
	XJRSTF	NZSXJF		;NOW JUMP INTO SECTION 1 ACS


PCAFI:	SKPS0			;IN NON-ZERO SECTION?
	JRST	PCAFI1		;YES, DIFFERENT CODE
	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 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 IFN 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 IFN 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
  > ;END IFN FTEXEC
	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
  > ;END IFNDEF
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
;STILL IFN FTDEC10!FTEXEC

;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>>
;STILL IFN FTDEC10!FTEXEC

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
;STILL IFN FTDEC10!FTEXEC

;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
;STILL IFN FTDEC10!FTEXEC

;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
;STILL IFN FTDEC10!FTEXEC

;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
;STILL IFN FTDEC10!FTEXEC

;TABLE OF BYTE PTRS TO REFERENCE CLASS TABLE

	XX==CCBITS-1
	XALL
CCBTAB:	REPEAT	CHRWRD,<
	 POINT	CCBITS,CTBL(B),XX
	 XX=XX+CCBITS
	> ;END REPEAT
	SALL

;CLASS DISPATCH TABLE

DISPTC:	WRAP,,WRAP
	ZNULL,,EOL1
	WRAP,,INSRT
	DELC,,RTYPE
	DELL,,DELW
	RDCR,,RDQT
;STILL IFN FTDEC10!FTEXEC

;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
;STILL IFN FTDEC10!FTEXEC

;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:	PUSH	P,T		;SAVE T

  IFN FTEXEC,<
	SKPEXC
	JRST	RDBIN2		;USER MODE

;READ AN EXEC-MODE COMMAND CHARACTER

  IFN FTYANK,<
	SKIPE	COMAND
	PUSHJ	P,XPTRIN
  > ;END IFN FTYANK
	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,<
	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,		;RETURN
;STILL IFN FTDEC10!FTEXEC

;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
;STILL IFN FTDEC10!FTEXEC

;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
;STILL IFN FTDEC10!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,		;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,
;STILL IFN FTDEC10!FTEXEC

;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,		;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
;STILL IFN FTDEC10!FTEXEC

;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
;STILL IFN FTDEC10!FTEXEC

;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?
  > ;END IFE FTEXEC
  IFN FTEXEC,<
	TDNE	T,TTYMSK	;DO WE HAVE IT
	SKPUSR			;OR ARE WE IN EXEC MODE?
  > ;END IFN FTEXEC
	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.
;STILL IFN FTDEC10!FTEXEC

;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	;GET FORMAT MASK
	TXNE	T,TT$DEL	;FANCY <DEL>'S?
	JRST	DELCH4		;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		;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
;STILL IFN FTDEC10!FTEXEC

;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
;STILL IFN FTDEC10!FTEXEC

;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,

  > ;END IFN FTDEC10!FTEXEC
;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		;YES, USE SPECIAL EXEC CODE
  > ;END OF IFN FTEXEC

  IFN FTFILE&FTYANK,<		;FILDDT?
	SKIPE	COMAND		;STILL READING COMAND FILE?
	POPJ	P,		; 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
  > ;END IFN FTYANK
XLISTN:	SKIPN	XTYPAC		;GOT ANY TYPEAHEAD SAVED UP?
	 JRST	XLISTT		;NO, JUST TRY FOR TERMINAL INPUT
	SOS	XTYPAC		;COUNT DOWN TYPEAHEAD CHARACTERS
	SKIPN	TT2,XTYPAG	;GET CURRENT TYPEAHEAD BYTE GETTER
	 MOVE	TT2,[POINT 7,XTYPAB]	;NONE, INIT TO BEGINNING OF BUFFER
	CAMN	TT2,[POINT 7,XTYPAB+XTYPAW-1,34]  ;AT END OF BUFFER?
	MOVE	TT2,[POINT 7,XTYPAB]	;YES, WRAP TO BEGINING OF BUFFER
	ILDB	T,TT2		;GET NEXT SAVED TYPEAHEAD CHARACTER
	MOVEM	TT2,XTYPAG	;SET NEW TYPEAHEAD GETTER
	JRST	XLIST8		;EXIT WITH COMMAND CHARACTER IN T

;ENTRY POINT FROM LISTEN.
;SEE IF A KL10, AND DO KL10 LISTEN IF SO.

XLISTT:	SKPKL			;A KL10?
	JRST	XLIST2		;NOT KL, CHECK OTHER CPUS
	EXCH	TT,TT2		;SAVE TT
	PUSHJ	P,GVEPT		;GET EPT BASE IN TT
	  HALT	.-1		;NOT IN ADDRESS SPACE!
	EXCH	TT,TT2		;PUT ADDRESS IN TT2
	ADDI	TT2,DTEMTI	;POINT INTO DTE BLOCK
	SKIPN	@TT2		;ANY INPUT YET?
	POPJ	P,		;NO
	SUBI	TT2,DTEMTI-DTEF11  ;POINT TO DATA
	MOVE	T,@TT2		   ;GET IT
	ADDI	TT2,DTEMTI-DTEF11  ;BACK UP TO STATUS
	SETZM	@TT2		;RESET
	JRST	XLIST8		;AND CHAR DOWN AND RETURN
;STILL IFN 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
;STILL IFN FTEXEC

;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
	CAIN	T,.CHCNO	;USER TYPE A ^O?
	JRST [	SETCMM	TTSUP		;TOGGLE SUPPRESSION FLAG
		JRST	XLISTN]		;CHECK FOR FURTHER INPUT
	CAIN	T,.CHCNQ	;USER TYPE A ^Q?
	JRST [	SETZM	TTHLD		;YES, CLEAR THE HOLD-OUTPUT FLAG
		JRST	XLISTN]		;CHECK FOR FURTHER INPUT
	CAIN	T,.CHCNS	;USER TYPE A ^S?
	JRST [	SETOM	TTHLD		;YES, SET THE HOLD-OUTPUT FLAG
		JRST	XLISTN]		;CHECK FOR FURTHER INPUT
	SETZM	TTSUP		;CLEAR SUPPRESSION FLAG
	JRST	CPOPJ1		;AND RETURN WITH CHARACTER IN T
;STILL IFN FTEXEC

;HERE TO HANDLE EXEC-MODE TYPE-AHEAD

XTYPA:	PUSH	P,[XTYPAV]	;THE TYPE-AHEAD INTERVAL
	POP	P,XTYPAX	;RESET CHECK COUNTER (FOR EVAL/LOOK)
	SKPEXC			;ONLY DO THIS IN EXEC MODE
	POPJ	P,		;USER-MODE, NOTHING TO DO
	PUSHJ	P,SAVT		;WANT TO PROTECT "T"
XTYPA0:	PUSHJ	P,XLISTT	;SEE IF ANY INPUT AVAILABLE
	 POPJ	P,		;NO, NO TYPEAHEAD THEN
	AOS	TT2,XTYPAC	;YES, ADVANCE TYPEAHEAD COUNTER
	CAILE	TT2,XTYPAW*5	;TYPEAHEAD BUFFER STILL HAVE ROOM?
	JRST	XTYPA6		;NO, BOMB THIS CHARACTER
	SKIPN	TT2,XTYPAP	;GET CURRENT OUTPUT BYTE PUTTER
	MOVE	TT2,[POINT 7,XTYPAB]	;NONE, INITIALIZE PUTTER
	CAMN	TT2,[POINT 7,XTYPAB+XTYPAW-1,34]  ;AT END OF BUFFER?
	MOVE	TT2,[POINT 7,XTYPAB]	;YES, RESET TO BEGINNING
	IDPB	T,TT2		;STORE TYPEAHEAD CHARACTER
	MOVEM	TT2,XTYPAP	;SET NEW CURRENT OUTPUT BYTE PUTTER
	JRST	XTYPA0		;SEE IF ANYTHING ELSE CAME IN

;TYPEAHEAD BUFFER OVERFLOWED - GO DINK AT THE USER

XTYPA6:	SOS	XTYPAC		;ADJUST COUNTER BACK
	PUSH	P,TTHLD		;SAVE CURRENT XON/XOFF STATUS
	SETZM	TTHLD		;FORCE OUTPUT TO GO OUT ASAP
	MOVEI	T,.CHBEL	;A DINK CHARACTER
	PUSHJ	P,XTOUT		;GO DINK AT USER
	POP	P,TTHLD		;RESTORE XON/XOFF STATUS
	POPJ	P,		;AND EXIT THIS VALE OF TEARS

  > ;END IFN FTEXEC
IFN FTDEC10,<
  IFN FTYANK,<
  IFN FTEXEC,<
XPTRIN:	SKIPE	COMCOR		;IS COMMAND STRING FROM MEMORY?
	JRST	PTRIN		;YES, TREAT LIKE USER MODE, SORTA
	PUSHJ	P,PTRXNX	;GET NEXT CHAR FROM PTR
	 JRST	PTRDON		;THROUGH
	JRST	PTRCHR		;PROCESS THE CHAR.
  > ;END IFN FTEXEC

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,<
	SKPUSR			;EXEC MODE?
	SKIPE	COMCOR		;YES, FROM MEMORY?
	JRST	PTRCH2		;USER MODE (OR CLOSE ENOUGH)
	CAIE	T,.CHCRT	;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
  > ;END IFN FTEXEC
	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
	SETZM	COMCOR		;AND IT IS NOT FROM MEMORY EITHER
	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 IFN FTDEC10 & IFN FTYANK

;COMMAND FILE IO

PTRNX:	SKIPE	COMCOR		;COMMAND FILE FROM MEMORY STRING?
	JRST [	ILDB	T,CBUF+1	;YES, GET NEXT ASCIZ STRING CHR.
		CAIE	T,.CHCNZ	;IF A ^Z
		JUMPN	T,CPOPJ1	;NOT, RETURN WITH GOOD CHARACTER
		POPJ	P,]		;RETURN EOF IF ^Z OR NULL
	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 IFN FTDEC10 & IFN 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,<
	MOVX	T1,TT%OSP	;MAKE SURE USER'S ^O IS CLEARED
	ANDCAM	T1,SAVTTY	;NOW THAT WE KNOW WE'RE BREAKING
	MOVEI	T1,.PRIOU	;LOAD PRIMARY OUTPUT POINTER
	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,
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


;TSIXN AND TOCTW PART OF EDIT 656

;TSIXN -- SUBROUTINE TO TYPE A SIXBIT WORD
;CALL:	MOVE	W1, SIXBIT WORD
;	PUSHJ	P,TSIXN
;	RETURN
;
;USES T AND W1

TSIXN:	JUMPE	W1,CPOPJ	;RETURN IF NOTHING TO PRINT
TSIXN1:	LSHC	T,6		;GET A CHARACTER
	ANDI	T,77		;STRIP OFF JUNK
	ADDI	T,40		;CONVERT TO ASCII
	PUSHJ	P,TOUT		;PRINT IT
	JUMPN	W1,TSIXN1	;LOOP IF MORE
	POPJ	P,		;ELSE RETURN


;TOCTW -- SUBROUTINE TO TYPE A OCTAL WORD
;CALL:	MOVE	W1, OCTAL WORD
;	PUSHJ	P,TOCTW
;	RETURN
;
;USES T, W1, AND W2

TOCTW:	IDIVI	W1,10		;DIVIDE
	PUSH	P,W2		;SAVE REMAINDER
	SKIPE	W1		;DONE?
	PUSHJ	P,TOCTW		;RECURSE
	POP	P,T		;GET A DIGIT
	ADDI	T,"0"		;MAKE ASCII
	PJRST	TOUT		;PRINT CHARACTER AND 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

TSEP:	MOVEI	T,"/"		;TYPE SLASH-TAB SEPARATOR
	PUSHJ	P,TOUT		;FALL INTO TTAB
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
TSPC:	MOVEI	T," "		;SPACE
	PJRST	TOUT

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
;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	;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
	XORI	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,<
  IFN FTYANK,<
	MOVE	TT2,TTYMSK	;GET TTY MASK BITS
	SKIPE	COMAND		;ALWAYS ECHO IF NOT DOING $Y
	TXNN	TT2,TT$EYB	;ELSE ECHO $Y OUTPUT ONLY IF OK
  > ;END IFN FTYANK
	OUTCHR	T		;OUTPUT A CHARACTER
  > ;END IFN FTDEC10
  IFN FTDEC20,<
  IFN FTYANK,<
	SKIPN	COMAND		;DOING $Y?
	JRST	TOUT5		;NO, ALWAYS ECHO
	TXNE	TT2,TT$EYB	;IS IT OK TO ECHO?
	JRST	TOUT6		;NO, DON'T DO IT
  > ;END IFN FTYANK
TOUT5:	EXCH	T1,T		;YES, OUTPUT THE CHARACTER
	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
	SKIPE	TTHLD		;HOLDING OUTPUT (I.E., XOFF'ED)?
	JRST [	PUSHJ	P,XTYPA		;YES, CHECK FOR "TYPEAHEAD" (XON)
		JRST	XTOUT]		;SEE IF CLEAR YET
	ANDI	T,377		;DON'T CONFUSE THE HARDWARE WITH $9T/ETC

;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
	ADDI	TT2,DTECMD	;RELOCATE TO COMMAND WORD
	MOVEM	T,@TT2		;PUT IN COMMAND WORD
	ADDI	TT2,DTEMTD-DTECMD  ;POINT TO DONE FLAG
	SETZM	@TT2		;CLEAR DONE FLAG.
	XCT	DING11		;RING THE DOORBELL
	SKIPN	@TT2		;DONE YET?
	JRST	.-1		;NO, LOOP
	JRST	XTOUT8		;YES, GO RESTORE CHAR AND RETURN
;STILL IFN 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:	PUSHJ	P,XTYPA		;CHECK FOR TYPEAHEAD (AND ^S, ETC)
	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,<

;TTYSAV -- SUBROUTINE TO SAVE USER TTY STATE ON RETURN TO DDT
;CALL:
;	PUSHJ	P,TTYSAV
;	RETURN

TTYSAV:
  IFN FTSCSH,<			;ONLY IF USING SYMBOL TABLE CACHE
	PUSHJ	P,.CLCSH	;CLEAR THE CACHE, MAYBE
  > ;END IFN FTSCSH
	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,<
	SKIPE	SAVTTY		;ALREADY SAVED?
	JRST	TTYRE4		;YES, DON'T SAVE IT AGAIN
	MOVEI	T1,.FHSLF	;NO, LOAD PTR. TO OUR PROCESS
	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 NOW
;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
	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 IFE FTFILE & IFN FTEXEC

;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
	PUSHJ	P,GVEPDT	;GET BASE OF MASTER DTE'S CHUNK IN EPT
	MOVE	TT1,T		;COPY OF BASE ADDRESS
	ADDI	TT1,DTEII	;START OF EPT LOCATIONS TO SAVE
	XMOVEI	TT2,SAVTTY	;WHERE TO SAVE THEM
	MOVEI	TT,SAVDRW-SAVTTY+1  ;HOW MANY TO SAVE
	PUSHJ	P,DOXBLT	;GO SAVE THEM
	 HALT	.		;CAN'T
	ADDI	T,DTEEPW	;LOOK AT PROTOCOL FLAG
	SKIPN	@T		;USING PRIMARY PROTOCOL?
	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
	PUSHJ	P,GVEPDT	;FIND MASTER DTE'S CHUNK OF EPT
	ADDI	T,DTEII		;POINT TO INTERRUPT INSTR
	MOVSI	W2,(HALT)
	MOVEM	W2,@T		;NO INTERRUPTS
	ADDI	T,DTEEPW-DTEII	;POINT TO EXAMINE PROTECTION WORD
	SETZM	@T		;CLEAR IT
	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


;GVEPDT -- ROUTINE TO LOCATE MASTER DTE'S CHUNK IN EPT.
;CALL:
;	PUSHJ	P,GVEPDT
;	RETURN
; T/  ADDRESS OF MASTER DTE'S CHUNK OF EPT.
;
;USES NO OTHER ACS.

GVEPDT:	PUSH	P,TT		;SAVE AN AC
	PUSHJ	P,GVEPT		;START WITH EPT BASE
	 HALT	.		;AUGH!
	MOVE	T,MSTRDT	;GET MASTER DTE NUMBER
	LSH	T,3		;OFFSET FOR HIS CHUNK
	ADD	T,TT		;IN THE EPT
	POP	P,TT		;RESTORE AC
	POPJ	P,		;ALL DONE
;STILL IFE FTFILE & IFN FTEXEC

;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,PGKLMD	;KL-PAGING?
	SETOM	KIPAG		;NO
	TXNE	TT1,PGKLMD	;KL-PAGING?
	SETOM	KLPAG		;YES
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.
;TOPS-20 NOW USES EXTENDED ADDRESSING INSTEAD OF AN ALTERNATE ADDRESS
;SPACE, BUT STILL USES THE EXEC DATA VECTOR TO LOCATE THE SYMBOL TABLE.

TTYRE6:

  IFN FTEXEC,<			;EDDT OR KDDT
	SKPEXC			;IN EXEC MODE?
	POPJ	P,		;NO, DO LIKE USER DDTS
  > ;END IFN FTEXEC

  IFN FTEX20!FTMON,<		;TOPS-20 MONITOR
	MOVE	T,[MSEC1,,MONPDV]  ;GLOBAL ADDR OF PDV FLAG
    IFN FTEX20,<
	SKPNS0			;STILL IN SECTION ZERO?
	TLZ	T,-1		;YES, WANT SEC. 0 REF
    > ;END IFN FTEX20
	SKIPE	@T		;MONITOR HAVE A PDV?
	POPJ	P,		;IT DOES, JUST USE IT
  > ;END IFN FTEX20!FTMON

  IFN FTDEC10,<
	SETZM	HSBLK		;DO ALL FETCHES IN CURRENT SPACE FOR NOW
	SETZM	JOBEDV		;DON'T KNOW ABOUT CPNDDT YET
  > ;END IFN FTDEC10
	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
IFN .EDCNT,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
  IFN FTDEC10,<			;CPNDDT ONLY ON -10
	CAILE	T,.EDCPU	;IF LONG ENOUGH FOR BREAKPOINT STUFF,
	MOVEM	R,JOBEDV	;SAVE FOR LATER REFERENCING
  >

  IFN FTDEC10,<			;HIDDEN SYMS ONLY ON -10
	CAILE	T,.EDLNK	;IS IT LONG ENOUGH TO FIND THE RIGHT EDV?
	SKPKLS			;AND DO WE UNDERSTAND ITS PAGING WELL?
	JRST	TTYRR0		;NO, DON'T BOTHER TO TRY
TTYRR1:	ADDI	R,.EDEPT-.EDCNT	;POINT TO EPT WORD
	PUSHJ	P,FETCHV	;TRY TO GET IT
	  JRST	TTYRE8		;SYMBOLS NOT HIDDEN IF BUM EDV
	CONI	PAG,S		;GET EBR
	ANDI	S,17777		;MASK TO PHYSICAL PAGE NUMBER
	LSH	S,PG2WRD	;CONVERT TO PHYSICAL ADDRESS
	CAME	S,T		;DO THEY MATCH?
	JRST	TTYRR2		;NO, TRY TO FIND ANOTHER
	SUBI	R,.EDEPT-.EDCNT	;YES, POINT TO START AGAIN
	MOVEM	R,JOBEDV	;MAKE SURE IT'S SET UP FOR LATER
	JRST	TTYRR0		;WE GOT A GOOD ONE
TTYRR2:	ADDI	R,.EDLNK-.EDEPT	;POINT TO LINK WORD
	PUSHJ	P,FETCHV	;TRY TO GET POINTER TO NEXT
	  JRST	TTYRE8		;NO HIDDEN SYMBOLS IF NO GOOD EDV
	JUMPE	T,TTYRE8	;NO HIDDEN SYMBOLS IF NO NEXT
	CAMN	T,JOBEDV	;HAVE WE LOOPED ALL THE WAY AROUND?
	JRST	TTYRE8		;YES, CAN'T USE HIDDEN SYMBOLS
	MOVE	R,T		;NO, START OVER WITH THIS EDV
	JRST	TTYRR1		;TRY AGAIN
TTYRR0:	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 AND IFN FTDEC10

;FALL IN FROM ABOVE

;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 FTDEC10

;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
	ADDI	R,.EDSYM-.EDHSB	;ADVANCE TO SYMBOL TABLE WORD
  > ;END IFN FTDEC10

  IFN FTDEC20,<			;ONLY -20 HAS .EDSEC
	ADDI	R,.EDSEC-.EDCNT
	CAIGE	T,.EDSEC+1	;LONG ENOUGH TO HAVE SECTION SPECIFIED?
	JRST	TTYRE8		;NO, SKIP SECTION
	PUSHJ	P,FETCHV	;YES, GET SECTION NO.
	 JRST	TTYRE8
	HLROM	T,SYTLOC	;SAVE SECTION
	SUBI	R,.EDSEC-.EDSYM	;POINT TO SYMBOL TABLE WORD
  > ;END IFN FTDEC20

	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
	MOVEM	R,SYMP+S$SUB	;STASH ADDRESS FOR SYMCHK
  IFN FTEX20,<			;IN KDDT ONLY,
	PUSHJ	P,FETCHV	;SEE IF THE POINTER IS SET UP YET
	 JRST	TTYRE8		;CAN'T GET IT
	JUMPE	T,TTYRE8	;USE JOBDAT IF NOT SET UP YET
  > ;END IFN FTEX20
	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
	MOVEM	R,USYMP+S$SUB	;STASH FOR SYMCHK
	SETZM	HSYMP+S$SUB	;NO HISEG IN EXEC MODE

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

;FALL IN FROM ABOVE

  IFN FTDEC10,<
	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
	HLROM	T,SYTLOC	;SAVE SYMBOL SECTION NUMBER
	MOVE	T,TTEM1		;ADDRESS OF MONITOR'S BLOCK OR ZERO
	SKIPE	@ADRSPC		;HIT BREAKPOINT INSIDE OTHER COPY OF DDT
				;WHILE THAT DDT WAS IN ALTERNATE SPACE?
	SETZ	T,		;YES, WE WILL ALWAYS STAY IN SYMBOL SPACE
	MOVEM	T,HSBLK		;*** TURN ON HIDDEN SYMBOL PROCESSING ***
  > ;END IFN FTDEC10

	POPJ	P,		;ALL DONE WITH TTYSAV


;HERE IF WE AREN'T GOING TO USE AN ALTERNATE SYMBOL ADDRESS SPACE.

TTYRE8:
  IFN FTDEC10,<
	SETZM	HSBLK		;REMEMBER NOT TO
  > ;END IFN FTDEC10
	MOVE	R,SECDDT	;GET OUR SECTION
	HLROM	R,SYTLOC	;TELL SYMCHK WHERE TO FIND SYMS
	HRRI	R,.JBSYM	;USUAL SPOT FOR DEFINED SYM POINTER
	MOVEM	R,SYMP+S$SUB	;TELL SYMCHK
	HRRI	R,.JBUSY	;AND UNDEFINED POINTER
	MOVEM	R,USYMP+S$SUB	;DITTO
	SETZM	HSYMP+S$SUB	;NO HISEG IN EXEC MODE
	POPJ	P,		;ALL DONE WITH TTYSAV


  IFN FTDEC10,<

;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 FTDEC10
  > ;END IFN FTEXEC!FTMON
;STILL IFE FTFILE

;TTYRES -- SUBROUTINE TO RESTORE THE TTY STATE BEFORE LEAVING DDT
;CALL:
;	PUSHJ	P,TTYRES
;	RETURN

TTYRES:
  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
	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:
  IFN FTDEC10,<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.

	PUSHJ	P,GVEPDT	;FIND MASTER DTE'S CHUNK OF THE EPT
	MOVE	W2,T		;SAVE A COPY
	MOVE	TT2,T		;DESTINATION TO RESTORE
	ADDI	TT2,DTEII	; STARTS HERE
	XMOVEI	TT1,SAVTTY	;WHERE TO RESTORE FROM
	MOVEI	TT,SAVDRW-SAVTTY+1  ;HOW MANY TO RESTORE
	PUSHJ	P,DOXBLT	;GO STUFF 'EM
	 HALT	.		;CAN'T
	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
	ADDI	W2,DTEEPW	;POINT UP TO EXAMINE PROTECTION WORD
	CONSZ	PAG,PGTPEN	;IS PAGING NOW ENABLED?
	SKIPN	@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
	ADDI	TT2,DTEFLG	;POINT TO DONE FLAG
	SETZM	@TT2		;CLEAR DONE FLAG
	ADDI	TT2,DTECMD-DTEFLG  ;POINT UP TO COMMAND WORD
	MOVEM	T,@TT2		;STORE COMMAND FOR 11
	XCT	DING11		;RING HIS DOORBELL
	SUBI	TT2,DTECMD-DTEFLG  ;BACK TO FLAG
	SKIPN	@TT2		;WAIT FOR FINISH
	JRST	.-1
	POPJ	P,		;RETURN
;STILL IFE FTFILE & IFN FTEXEC

;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	HIDE DDT'S PDV

;FIND AND REMEMBER WHERE DDT'S PDV IS, SO THAT NORMALLY WE WON'T USE
;IT FOR SYMBOLS.  ASSUME A PDV IN OUR SECTION IS OUR PDV, SINCE THIS
;IS ONCE-ONLY CODE.

  IFN FTUD20,<			;USER-20 DDT ONLY

HIDPDV:	PUSHJ	P,PDVINI	;SET UP PDVOP% BLOCK
	HLLZ	T1,SECDDT	;ONLY LOOK IN OUR SECTION
	MOVEM	T1,PDVARG+.POADR  ;FOR OUR OWN PDV
	HLLOM	T1,PDVARG+.POADE
	MOVX	T1,.POLOC	;RETURN PDVS
	XMOVEI	T2,PDVARG	;ACCORDING TO THIS BLOCK
	HRROI	T3,[ASCIZ/DDT%/]  ;WITH THIS NAME
	PDVOP%			;DO IT TO IT
	SKIPE	PDVARG+.POCT2	;FIND ONE?
	SKIPA	R,PDVA		;YES, GET THE ADDRESS
	SETO	R,		;NO, SET AN IMPOSSIBLE VALUE
	MOVEM	R,DDTPDV	;SAVE FOR SYMCHK
	JUMPL	R,CPOPJ		;RETURN IF NO PDV

;SET UP PROPER SYMBOL TABLE VECTOR IF WE WERE LOADED BY AN EARLY LINK

	MOVE	T,.PVCNT(R)	;GET LENGTH OF PDV
	CAIGE	T,.PVLVR	;LONG ENOUGH FOR LINK VERSION?
	JRST	HIDPD1		;NO, ASSUME SYMBOL VECTOR IS OK
	LDB	T,[POINTR .PVLVR(R),VI%MAJ]	;GET LINK MAJOR VERSION
	CAIL	T,6		;LINK V6 GOT IT RIGHT
	JRST	HIDPD1
	MOVE	T,.PVSYM(R)	;GET IOWD-STYLE .PVSYM
	HRRM	T,DDTSYV+2	;SET DEFINED TABLE ADDRESS
	HRRM	T,DDTSYV+5	;AND UNDEFINED TABLE ADDRESS
	HLRE	T,T		;GET NEG LENGTH
	MOVN	T,T		;WANT POS LENGTH
	DPB	T,[POINTR DDTSYV+1,ST%LEN]	;SET DEFINED LENGTH
	MOVE	T,[IFIW	DDTSYV]	;OUR INTERNAL SYMBOL VECTOR
	ADDI	R,.PVSYM	;WANT TO WRITE TO .PVSYM WORD
	PUSH	P,PATCHS	;SAVE $W FLAG
	SETOM	PATCHS		;PRETEND $W IN EFFECT
	PUSHJ	P,STOREV	;STORE INTO PDV EVEN IF WRITE-LOCKED
	 JFCL			;CAN'T HAPPEN
	ADDI	R,.PVLVR-.PVSYM	;UPDATE LINK VERSION NUMBER
	MOVX	T,FLD(6,VI%MAJ)	; SO WE'LL USE THE SYMBOL VECTOR
	PUSHJ	P,STOREV	;STUFF FAKE VERSION
	 JFCL			;CAN'T HAPPEN
	SUBI	R,.PVLVR-.PVNAM	;BACK DOWN TO NAME WORD
	MOVX	T,IFIW		;NOW MAKE NAME WORD LOCAL FORMAT
	HRR	T,(R)		;PRESERVE RIGHT HALF
	PUSHJ	P,STOREV	;STUFF NEW VALUE
	 JFCL			;CAN'T HAPPEN
	POP	P,PATCHS	;RESTORE DEFAULT $W VALUE

HIDPD1:	SETZM	SARS		;PRETEND WE NEVER RAN
	SETZM	SAVTTY		;FORGET SAVED TTY STUFF TOO
	HALTF%			;ALL DONE, READY TO SAVE DDT

;DEFINE EXPORT VECTOR FOR USER-20 DDT

DDTEXP:	EXP	EXP.L		;LENGTH OF BLOCK
	IFIW	DDT		;DDT'S START ADDRESS
	IFIW	$0BPT		;UNSOLICITED BREAKPOINT ADDRESS
	IFIW	SYTLOC		;$5M (TO SPECIFY SYM TABLES)
	IFIW	SECUDD		;SECTION OF UDDT STUB

	EXP.L==.-DDTEXP

DDTXPT==:<IFIW	DDTEXP>		;HACK FOR /PVDATA:START: SWITCH

  > ;END IFN FTUD20
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!FTPURE,<
	.ENDPS	DDTCOD		;CLOSE OFF USER CODE PSECT
	>
    > ;END IFGE RUNLOC


;NOW START THE VARIABLES IN THE RIGHT PLACE

    IFE FTEX20!FTPURE,<
	.PSECT	DDTVAR/RWRITE,VARLOC	;PUT VARS WHERE THEY BELONG
    >
  > ;END IFGE VARLOC

  IFN FTPURE,<
PHVAR:!				;PURE COPY OF VARIABLES
  > ;END IFN FTPURE


IFGE RUNLOC,<IFGE VARLOC,<IFL <VARLOC-RUNLOC>,<
DDTBEG:!>>>			;DEFINE HERE IF VARIABLES BELOW CODE
SUBTTL	STORAGE -- ALLOCATION MACROS

;MACROS TO DEFINE DATA

  IFE FTPURE,<				;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 FTPURE
IFN FTPURE,<				;IN MDDT, THE TAGS ARE OFFSETS
					;FROM DDTPGA.
  IFE FTMON,<DDTPGA==VARLOC>		;OTHER PURE DDT'S WILL TRACK IT

	..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 FTPURE
SUBTTL	FILDDT -- COMMAND SCANNER

IFN FTFILE,<

;CODE COMMON TO ALL FLAVORS OF FILE DDTS

IFN FTDBUG,<
DEBDDT:>

DDT:	JFCL			;IN CASE OF CCL ENTRY
	INIPDL			;PRESET PUSH DOWN LIST
IFN FTYANK,<
	SETZM	COMAND>		;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 IFN 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
	SETZM	JOBEDV		;WE HAVE NO USEFUL EXEC DATA VECTOR
	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:	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:	SKIPE	JOBING		;/J?
	SETOM	FDIMSW		;YES, PRETEND /M
	SKIPN	FDIMSW		;/M SPECIFIED?
	 JRST	FDIDF		;NO, FILING OF SOME SORT

;FALL INTO MONITOR/MEMORY PEEKING INITIALIZATION
;STILL IFN FTFILE & IFN 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
	SKIPE	JOBING		;/J AGAIN?
	JRST	FDIJ0		;YES
	PUSHJ	P,FDINFO	;PRINT INTERESTING MESSAGE
	JRST	FDIGO		;GO FINISH UP
FDIJ0:	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
	SETZM	FAKEAC
	PUSHJ	P,FDINFO	;TYPE INTERESTING STUFF
	JRST	FDIGO		;DONE
;STILL IFN FTFILE & IFN FTDEC10

;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 IFN FTFILE & IFN 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
		   RFSLEN,,RFSBLK] ;LEN,,ADR OF RETURNED FILESPEC 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
	MOVEI	ODF,10		;SETUP TO TYPE OCTAL FILOP. ERROR CODE
	JRST	FDEFFF		;REAL FILOP. ERROR
;STILL IFN FTFILE & IFN 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 IFN FTFILE & IFN 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

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

>				;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 IFN 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 IFN FTFILE & IFN 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:	INIPDL				;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 IFN FTFILE & IFN 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	; . . .
	PUSHJ	P,FDINFO	;TYPE USEFUL INFO
	JRST	FDIGO		;GO TO IT
;STILL IFN FTFILE & IFN 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 IFN FTFILE & IFN 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
	SETZ	T3,
	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
	MOVX	T2,OF%RD!OF%WR!OF%THW	;SET UP FOR THAWED AND PATCH
	SKIPN	FDIFSW		;USE PATCHS IF GET /S
	SKIPN	SYMGET		;ALWAYS READ-ONLY IF LOADING SYMBOLS
	SKIPN	PATCHS		;WANT PATCHING?
	TXZ	T2,OF%WR	;NO, CLEAR WRITE BIT.
	SKIPN	THAWSW		;THAWED ACCESS?
	TXZ	T2,OF%THW	;NO, CLEAR THAWED BIT.
	TXNN	T2,OF%WR!OF%THW	;WRITE OR THAWED SET?
	TXO	T2,OF%RDU	;NO, SET UNRESTICTED READ
	OPENF%			;OPEN USER'S FILE
	ERJMP	PUTERQ		;FAILED, COMPLAIN TO USER
GET40:	FFFFP%			;LOOK FOR FIRST FREE PAGE
	JUMPL	T1,GET50	;NO FREE PAGES, USE LONG FILE CHECK
	HRRZ	T3,T1		;SAVE FIRST FREE PAGE NUMBER
	FFUFP%			;ANY USED PAST THAT? (COULD BE HOLE...)
	ERJMP [	CAIE	T1,FFUFX3	;SEE IF NO MORE USED PAGES
		JRST	GET50		;SOME OTHER PROBLEM
		JRST	GET60]		;NO MORE USED PAGES, WE HAVE EOF
	MOVSS	T1		;SET UP ARG FOR FFFFP%
	JRST	GET40		;AND MOVE PAST THIS HOLE

GET50:	MOVE	T1,FILJFN	;GET JFN FOR LONG FILE CHECK
	MOVE	T2,[1,,.FBCTL]	;WANT FLAG WORD FROM FDB
	MOVEI	T3,T4		;RETURN IN T4
	GTFDB%
	MOVX	T3,^D512	;NUM. PAGES IN SHORT FILE
	TXNE	T4,FB%LNG	;IS IT A SHORT FILE?
	MOVX	T3,^D512*^D512	;NO, LONG FILE HAS MORE PAGES
GET60:	LSH	T3,PG2WRD	;WANT NUM. WORDS IN FILE
	MOVEM	T3,MAXSIZ	;SAVE FOR FUTURE USE
	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 IFN FTFILE & IFN 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,

.THAWD:	SETOM	THAWSW		;SET THAWED ACCESS TO FILE
	POPJ	P,
;STILL IFN FTFILE & IFN 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,PHYARG	;YES, STORE DESIGNATOR FOR DSKOP
	PUSHJ	P,ENDCOM	;CLOSE OFF COMMAND LINE
	  POPJ	P,		;ERROR, GIVE UP
	HLRZ	T1,PHYARG	;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,,^D10)]
	COMND%			;PARSE AN DECIMAL NUMBER
	TXNE	T1,CM%NOP	;ERROR?
	JRST	PUTERQ		;YES, GO COMPLAIN
	SKIPL	T2		;CHANNEL NEGATIVE?
	CAILE	T2,<.RTJST(-1,DOP%C2)>	;OR TOO LARGE?
	JRST	ILLCHN		;YES, COMPLAIN
	STOR	T2,DOP%C2,PHYARG ;STORE CHANNEL AWAY
	HRROI	T2,[ASCIZ 'CONTROLLER']	;GET NOISE
	PUSHJ	P,SKPNOI	;SAY WHAT WE WANT
	 POPJ	P,		;ERROR
	MOVEI	T2,[FLDDB. (.CMNUM,,^D10,,<-1>)] ;PARSE DECIMAL NUMBER
	COMND%			;DO IT, WITH A DEFAULT OF -1
	TXNE	T1,CM%NOP	;ERROR?
	JRST	PUTERQ		;YES, GO COMPLAIN
	CAML	T2,[-1]		;TOO SMALL?
	CAILE	T2,<.RTJST(-1,DOP%K2)>-1  ;OR TOO LARGE?
	JRST	ILLCTL		;YES, COMPLAIN
	STOR	T2,DOP%K2,PHYARG ;STORE CONTROLLER NUMBER
	HRROI	T2,[ASCIZ 'UNIT']
	PUSHJ	P,SKPNOI	;WE NOW WANT A UNIT
	  POPJ	P,		;ERROR
	MOVEI	T2,[FLDDB. (.CMNUM,,^D10)]
	COMND%			;PARSE A DECIMAL UNIT NUMBER
	TXNE	T1,CM%NOP	;ERROR?
	JRST	PUTERQ		;YES, COMPLAIN
	SKIPL	T2		;SEE IF UNIT NUMBER IS NEGATIVE
	CAILE	T2,<.RTJST(-1,DOP%U2)>	;OR TOO LARGE
	JRST	ILLUNI		;YES, COMPLAIN
	STOR	T2,DOP%U2,PHYARG ;STORE UNIT NUMBER ALSO
	PUSHJ	P,ENDCOM	;END LINE
	  POPJ	P,		;ERROR
	MOVX	T1,FLD(.DOPPU,DOP%AT)!DOP%CN!DOP%UN	;PHYSICAL DRIVE CODE
				;AND LARGE CHANNEL TO CATCH OLD STYLE DSKOP
	MOVEM	T1,PHYSIO	;STORE DSKOP ARG
	SETOM	FDIDSW		;REMEMBER NOT AN EXE FILE
	JRST	FDIOPN		;GO OPEN THINGS UP AND START DDT
;STILL IFN FTFILE & IFN 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 ...



;ROUTINES TO TYPE ERRORS FOR INVALID DRIVE NUMBERS


ILLCHN:	PUSHJ	P,TSTCOL	;TEST COLUMN POSITION
	TMSG	<? Illegal channel number
>
	POPJ	P,		;RETURN


ILLCTL:	PUSHJ	P,TSTCOL	;TEST COLUMN POSITION
	TMSG	<? Illegal controller number
>
	POPJ	P,		;ERROR


ILLUNI:	PUSHJ	P,TSTCOL	;TEST COLUMN POSITION
	TMSG	<? Illegal unit number
>
	POPJ	P,		;ERROR
;STILL IFN FTFILE & IFN FTDEC20


; 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
	 NOP			;IGNORE
	 NOP			;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 IFN FTFILE & IFN 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 IFN FTFILE & IFN 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 IFN FTFILE & IFN 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 IFN FTFILE & IFN 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)
	TB	(.THAWD,THAWED)	;"ENABLE THAWED"

	KEYSIZ== .-KEYTAB-1

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

	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 IFN FTFILE & IFN 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.
		/THAWED Obtain thawed access to the file.

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

PEEK (AT RUNNING MONITOR)
	Examines the running monitor.

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

DRIVE (FOR PHYSICAL I/O IS ON CHANNEL) c (CONTROLLER) k (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.

ENABLE THAWED
	Obtains thawed access to a file.

	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 IFN 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		;"/D" TYPED
	JRST	FDIXPD		;YEP - WE KNOW THE FORMAT

;VERIFY FILE IS .EXE FORMAT

	SETZ	R,		;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 IFN 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,1		;START AT 1ST WORD OF 1ST ENTRY

FDIOP2:	PUSHJ	P,FETCH		;GET START OF NEXT EXE ENTRY
	  JRST	BADEXE		;NOT AN EXE FILE?
	TXNE	T,SV$HIS	;IF A HISEG,
	AOS	NUMSEG		;COUNT IT
	ADDI	R,1		;SET TO GET 2ND WORD
	PUSHJ	P,FETCH		;GET 2ND WORD OF THIS 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,1		;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 IFN 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
	TXNE	W2,SV$FPN	;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)

;SEE IF ENTRY VECTOR EXISTS

	PUSHJ	P,FETCH		;GET HEADER OF NEXT SECTION
	 JRST	BADEXE		;BAD FORMAT
	HLRZ	TT,T		;GET SECTION ID CODE
	CAIE	TT,.SVVEC	;ENTRY VECTOR SECTION?
	JRST	FDIXL3		;NO, SEE IF PDV SECTION

;FALL THROUGH TO READ ENTRY VECTOR
;STILL IFN FTFILE

;FALL IN FROM ABOVE

	HRRZ	TT,T		;GET LENGTH OF THIS SECTION
	CAIGE	TT,3		;LONG ENOUGH TO HAVE AN ADDRESS?
	JRST	BADEXE		;NO, BAD FORMAT
	MOVEM	TT,EVADR	;TEMPORARILY SAVE LENGTH
	ADDI	R,1		;INCREMENT TO LENGTH WORD
	PUSHJ	P,FETCH		;GET EV LENGTH
	 JRST	BADEXE		;BAD FORMAT
	MOVEM	T,EVLEN		;HANG ON TO IT
	ADDI	R,1		;INCREMENT TO ADR WORD
	PUSHJ	P,FETCH		;GRAB IT
	 JRST	BADEXE		;BAD FORMAT
	EXCH	T,EVADR		;SAVE ADDRESS, GET BLOCK LENGTH
	ADDI	R,-2(T)		;INCREMENT PAST END OF BLOCK
	PUSHJ	P,FETCH		;GET NEXT HEADER WORD
	 JRST	BADEXE		;BAD FORMAT
	HLRZ	TT,T		;GET ID CODE

;READ IN LIST OF PDVS (IF ANY)

FDIXL3:	CAIE	TT,.SVPDV	;PDV SECTION?
	JRST	FDIXL9		;NO, QUIT
	HRRZI	W,-1(T)		;GET # PDVS
	MOVEM	W,PDVNUM	;STORE WHERE SYMCHK CAN FIND IT
	MOVE	T,.JBFF		;GET ADDRESS OF PDV LIST
	ADDB	W,.JBFF		;MAKE SPACE FOR IT
	CAMG	W,.JBREL	;ENOUGH ROOM?
	JRST	FDIXL4		;YES, GO ON
  IFN FTDEC10,<
	CORE	W,>		;MAKE MORE ROOM?
	JRST [	TMSG	<? Insufficient memory to read PDV list>
		JRST	FDEERR]	;NO MORE ROOM
FDIXL4:	HRLI	T,(IFIW (W2))	;MAKE A POINTER TO PDV LIST
	MOVEM	T,PDVTBL	;PUT IT WHERE IT'S NEEDED
	MOVN	W2,PDVNUM	;GET NEG NUM PDVS
	HRLZ	W2,W2		;MAKE AOBJN POINTER
FDIXL5:	ADDI	R,1		;POINT R AT NEXT PDVA
	PUSHJ	P,FETCH		;GRAB ONE
	 JRST	BADEXE		;BAD FORMAT
	MOVEM	T,@PDVTBL	;STORE IN THE LIST
	AOBJN	W2,FDIXL5	;GO FOR ANOTHER
FDIXL9:	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 IFN 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!
	MOVEM	TT,DSKCHA	;SAVE CONTENTS OF AC
	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
	 JRST	FDIPH5		;IT WENT AWAY?
	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
;STILL IN IFN FTFILE AND FTDEC10
TYPSTR:	LDB	T,[POINTR (DSKCHA,DC.TYP)] ;GET TYPE FIELD
	MOVEI	W1,[ASCIZ /structure /]
	CAIE	T,.DCTFS	;CHECK FOR IT
	MOVEI	W1,[ASCIZ /unit /]
	PUSHJ	P,TSTRG		;PRINT TEXT
	MOVE	W1,FLPBLK+.FODEV ;DEVICE NAME
	PJRST	TSIXN		;PRINT IT AND RETURN

> ;END OF IFN FTDEC10
;STILL IFN 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
	LOAD	T,DOP%C2,PHYARG	;GET CHANNEL NUMBER
	MOVEM	T,MBLK+.MSRCH	;STORE FOR MSTR
	LOAD	T,DOP%K2,PHYARG	;GET CONTROLLER NUMBER
	CAIN	T,<.RTJST(-1,DOP%K2)>	;ANY CONTROLLER SPECIFIED?
	SETO	T,		;NO, SET TO -1
	MOVEM	T,MBLK+.MSRCT	;STORE CONTROLLER NUMBER
	LOAD	T,DOP%U2,PHYARG	;GET UNIT NUMBER
	MOVEM	T,MBLK+.MSRUN	;STORE FOR MSTR
	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	T1,MBLK+.MSRSP	;GET NUMBER OF SECTORS PER PAGE
	MOVEM	T1,PHYSPP	;REMEMBER FOR LATER USE
	MOVE	T1,MBLK+.MSRSU	;GET SECTORS PER UNIT
	IMULI	T1,PAGSIZ	;MULTIPLY BY WORDS TO A PAGE
	IDIV	T1,PHYSPP	;DIVIDE BY SECTORS PER PAGE
	MOVEM	T1,MAXSIZ	;SET AS MAXIMUM SIZE TO EXAMINE
	JRST	FDISET		;GO START DDT
;STILL IFN FTFILE & IFN 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,PHYARG	;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	T1,MBLK+.MSRSP	;GET SECTORS PER PAGE
	MOVEM	T1,PHYSPP	;REMEMBER FOR LATER USE
	MOVE	T1,MBLK+.MSRSU	;GET SECTORS ON THIS UNIT
	IMULI	T1,PAGSIZ	;MULTIPLY BY WORDS TO A PAGE
	IDIV	T1,PHYSPP	;DIVIDE BY SECTORS PER PAGE
	ADDM	T1,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 IFN FTFILE & IFN 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
;STILL IFN FTFILE & IFN FTDEC20

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
	SKIPGE	MBLK+.MSRCT	;ANY CONTROLLER NUMBER?
	JRST	TYPUN5		;NO, SKIP ON
	TMSG	< on controller > ;TELL USER CONTROLLER NUMBER COMING UP
	MOVE	T,MBLK+.MSRCT	;AND GET IT
	PUSHJ	P,TOC		;TYPE IN OCTAL
TYPUN5:	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:	PUSHJ	P,FDINFO	;TYPE USEFUL INFO
	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
	SKIPE	SYMP+S$ADR	;NO /S. DO WE ALREADY HAVE SYMBOLS
	JRST	FDIAC		;YES, JUST LOOK FOR ACS THEN

;EXTRACT SYMBOLS FROM .EXE FILE

FDISY:	SETZM	SYTLOC		;0$5M
	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
;STILL IFN FTFILE

;EXTRACT THE ACS FROM THE .EXE FILE

FDIAC:
IFN FTDEC10&FTPAGM,<		;ONLY DO THIS FOR A -10 WITH PAGING
	MOVEI	R,.JBEDV	;JOBDAT POINTER TO THE EDV
	PUSHJ	P,FETCHP	;TRY TO READ IT
	 JRST	FDIAC1		;DO OLD WAY IF CAN'T
	JUMPE	T,FDIAC1	;OR IF NOT THERE
	MOVE	R,T		;COPY THE POINTER
IFN .EDCNT,<ADDI R,.EDCNT>	;POINT TO THE COUNT WORD (0)
	PUSHJ	P,FETCHP	;FETCH IT
	  JRST	FDIAC1		;GIVE UP ON IT IF CAN'T
	TLC	T,'EDV'		;CHECK BITS
	TLNN	T,-1		;MUST HAVE 'EDV' IN LH
	CAIG	T,.EDCAC	;AND BE LONG ENOUGH
	JRST	FDIAC1		;NO OR NO, GO BACK TO THE OLD WAY
	ADDI	R,.EDDAT-.EDCNT	;YES, POINT TO DATA WORD
	PUSHJ	P,FETCHP	;READ IT
	  JRST	FDIAC1		;GIVE UP IF CAN'T
	SKIPN	S,T		;COPY TO A SAFER PLACE
	JRST	FDIAC1		;MUST BE NON-ZERO
	ADDI	R,.EDEPT-.EDDAT	;POINT TO EPT ADDRESS WORD
	PUSHJ	P,FETCHP	;GET PHYSICAL ADDRESS OF THE EPT
	  JRST	FDIAC1		;GIVE UP IF CAN'T
	MOVE	W2,T		;PRESERVE FOR LATER
	ADDI	R,.EDSPT-.EDEPT	;POINT TO SPT ADDRESS WORD
	PUSHJ	P,FETCHP	;GET PHYSICAL BASE ADDRESS OF SPT
	  JRST	FDIAC1		;WORD MUST BE THERE
	MOVE	W1,T		;COPY FOR LATER
	TXNE	S,ED.KLP	;IF KL PAGING IN USE,
	JUMPE	T,FDIAC1	;DEMAND A REAL SPT
	ADDI	R,.EDCST-.EDSPT	;POINT TO CST BASE WORD
	PUSHJ	P,FETCHP	;GET PHYSICAL BASE ADDRESS OF CST
	  JRST	FDIAC1		;WORD MUST BE THERE
	MOVE	W,T		;COPY FOR LATER
	ADDI	R,.EDCAC-.EDCST	;POINT TO CRASH AC POINTERS WORD
	PUSHJ	P,FETCHP	;GET ADDR OF ADDR OF CRASH ACS
	  JRST	FDIAC1		;WORD MUST BE THERE
	SKIPN	R,T		;COPY POINTER
	JRST	FDIAC1		;MUST POINT TO CORE
	PUSHJ	P,FETCHP	;FETCH ADDRESS OF SAVED ACS
	  JRST	FDIAC1		;WORD MUST BE LEGIT
	SKIPN	R,T		;SAVE POINTER AWAY
	JRST	FDIAC1		;MUST POINT TO CORE
	LSH	W2,WRD2PG	;CONVERT EPT ADDRESS TO PAGE NUMBER
	MOVEM	W2,MAPPG	;SAVE AS IF FROM $U
	MOVEM	W1,SPTWRD	;SIMILARLY FOR SPT BASE
	MOVEM	W,CSTWRD	;AND FOR CST BASE
	MOVE	W,S		;COPY .EDDAT WORD
	PUSHJ	P,SETKZC	;CLEAR OUT CPU TYPE FLAGS
	HRRZ	T,W		;GET CPU TYPE CODE
	CAIL	T,.CCKAX	;MUST BE AT LEAST A KA
	CAILE	T,.CCKSX	;AND NOT BEYOND A KS
	CAIA			;NO, DON'T STORE IT
	SETOM	KAFLG-.CCKAX(T)	;YES, SET CPU TYPE
	MOVE	T,KLFLG		;IF A KL
	IOR	T,KSFLG		;OR A KS
	MOVEM	T,KLSFLG	;LIGHT THE EITHER/OR FLAG
	SETZ	W1,		;ASSUME KL PAGING
	SETO	W2,		;NOT KI PAGING
	TXNN	W,ED.KLP	;VALID ASSUMPTION?
	EXCH	W1,W2		;NO, SWAP FLAGS
	PUSHJ	P,SETKXP	;SET UP PAGING FLAGS
	AOS	MAPFN		;FINISH UP THE $0U COMMAND
	PUSHJ	P,FETCHP	;VALIDATE START
	  JRST	FDIAC0		;NO, GIVE UP
	ADDI	R,17		;YES, POINT TO END
	PUSHJ	P,FETCHP	;VALIDATE THAT
	  JRST	FDIAC0		;NO, GIVE UP
	SUBI	R,17		;YES, BACK UP TO BASE OF BLOCK
	PUSHJ	P,SETCA1	;EMULATE $5U COMMAND
	TMSG	<[Paging and ACs set up from the Exec Data Vector]
>				;TELL WHAT WE JUST DID
	SETOM	JOBEDV		;REMEMBER THAT WE DID THIS
	MOVE	T,MAPPG		;GET EPT PAGE NUMBER
	MOVEM	T,EDVEPT	;SAVE FOR $U
	MOVE	T,SPTWRD	;AND INCOMING SPT ADDRESS
	MOVEM	T,EDVSPT	;SAVE FOR $U
	MOVE	T,CSTWRD	;SIMILARLY FOR CST
	MOVEM	T,EDVCST	;...
	JRST	FDIAC4		;FINISH UP WITH THIS

FDIAC0:	SETZM	MAPFN		;TURN OFF PAGING AGAIN

FDIAC1:
  > ;END IFN FTDEC10&FTPAGM
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]
>   > ;END IFN FTDEC10
IFN FTDEC20,<
	TMSG	<[ACs copied from BUGACS to 0-17]
>   > ;END IFN FTDEC20
FDIAC4:	SETOM	FAKEAC		;FLAG USING FAKE LOC 0 - 17
  IFN FTDEC10&FTPAGM,<		;ONLY NEED THIS FOR -10
	SETZM	LLOCS		;BACK TO NORMAL STARTING SECTION
  > ;END OF IFN FTDEC10&FTPAGM
  IFN FTDEC20,<
	MOVE	T,[RADIX50 0,SPT]
	MOVEM	T,SYM
	PUSHJ	P,EVAL
	 JRST	FDIGO
	MOVEM	T,SPTWRD
> ;END OF IFN FTDEC20
FDIGO:	JRST	DD1		;GO START DDT
;STILL IFN FTFILE

FDINFO:	MOVEI	W1,[ASCIZ /[Looking at /]
	SKIPE	SYMGET		;/S SPECIFIED?
	MOVEI	W1,[ASCIZ /[Extracting symbols from /]
	SKIPE	FDIFSW		;/F TYPED?
	MOVEI	W1,[ASCIZ /[Examining /]
	SKIPE	PATCHS		;PATCHING?
	MOVEI	W1,[ASCIZ /[Patching /]
	PUSHJ	P,TSTRG		;PRINT TEXT
	SKIPN	PHYSIO		;PHYSICAL I/O?
	JRST	FDINF1		;NO
	PUSHJ	P,TYPSTR	;TYPE STRUCTURE OR UNIT
	JRST	FDINF4		;END THE LINE AND START DDT

FDINF1:	SKIPN	FILING		;LOOKING AT A DISK FILE
	JRST	FDINF2		;NO
	TMSG	<file >		;YES, SAY IT'S A FILE
IFN FTDEC10,<
	MOVEI	TT,FLPBLK	;POINT TO FILOP BLOCK
	PUSHJ	P,TYPFIL	;PRINT FILESPEC
> ;END IFN FTDEC10
IFN FTDEC20,<
	HRROI	T1,NAMBUF	;POINT TO THE FILE SPEC
	PSOUT%			;TYPE IT
> ;END IFN FTDEC20
	JRST	FDINF4		;END LINE

FDINF2:
IFN FTDEC10,<
	SKIPN	A,JOBING	;/J?
	JRST	FDINF3		;NO
	TMSG	<job >		;LOOKING AT A JOB
	PUSHJ	P,FP7		;TYPE IN DECIMAL
	JRST	FDINF4		;ALMOST DONE
> ;END IFN FTDEC10
FDINF3:	TMSG	<the running monitor>	;ONLY POSSIBILITY LEFT
FDINF4:	TMSG	<]
>				;END THE LINE
	POPJ	P,		;RETURN



;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 IFN FTFILE

;ALLOCATE FILE PAGE BUFFERS

FDIAPB:	SKIPE	T,WIND0		;ALREADY BEEN HERE?
	CAML	T,.JBFF		;AND DID WE MEAN IT?
	SKIPA	T,.JBFF		;NO, GET START OF FREE MEMORY
	JRST	CPOPJ1		;GIVE GOOD RETURN IF ALREADY DONE
	TRNE	T,PAGMSK	;PAGE BOUNDARY?
	ADDI	T,PAGSIZ	;NO, ROUND UP TO
	ANDCMI	T,PAGMSK	;PAGE BOUNDARY
	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,]	;PROPAGATE 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 IFN FTFILE

SYMFIX:
  IFN FTSCSH,<
	PUSHJ	P,CLRCSH>	;ZERO THE SYMBOL TABLE CACHE
	SETZM	SYMVAL		;SYMBOLS NOT KNOWN YET
	PUSHJ	P,SYMCHK	;LOCATE AND VERIFY SYMBOL TABLE POINTERS
	MOVE	T,[SYMP,,FOSPTR]  ;SAVE DEFINED SYMBOL BLOCK
	BLT	T,FOSPTR+S$SIZ-1  ; FOR CLSFIL
	MOVE	T,[USYMP,,FOUPTR] ;UNDEFINED BLOCK TOO
	BLT	T,FOUPTR+S$SIZ-1  ;SAVE FOR CLSFIL
	MOVE	T,[HSYMP,,FOHPTR] ;AND THE HISEG POINTER
	BLT	T,FOHPTR+S$SIZ-1  ;CLSFIL NEEDS THEM ALL
	MOVE	W1,.JBFF	;GET CURRENT FIRST FREE
	MOVEM	W1,FISBEG	;SAVE FOR DEPSYM
	ADDI	W1,1000		;1P FOR PATCHING
	MOVE	W,SYMP+S$LEN	;COUNT CORE NEEDED
	ADD	W,USYMP+S$LEN	;FOR ALL TABLES
	ADD	W,HSYMP+S$LEN	;WHEN SYMBOLS COPIED
	MOVE	T,W		;COPY SIZE
	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 MORE MEMORY
	 JRST [	TMSG	<? Not enough memory for symbols> ;COMPLAIN TO USER
		POPJ	P,]	;GIVE ERROR TO CALLER

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

SYMFI4:	MOVE	R,USYMP+S$ADR	;GET USY ADDRESS
	MOVEM	W1,USYMP+S$ADR	;SAVE FILDDT ADDRESS
	SKIPN	W2,USYMP+S$LEN	;IS THERE A TABLE TO COPY?
	JRST	SYMCPY		;NO, SKIP THIS
UCOPY:	PUSHJ	P,FETCH		;READ ANOTHER SYMBOL WORD
	 JRST	BADSTF		;SYMBOL TABLE MESSED UP
	MOVEM	T,(W1)
	AOS	W1
	AOS	R
	SOJG	W2,UCOPY

;CONTINUED ON NEXT PAGE
;STILL IFN FTFILE

;CONTINUED FROM PREVIOUS PAGE

SYMCPY:	MOVE	R,SYMP+S$ADR	;WHEREABOUTS OF MONITOR SYMBOLS
	MOVEM	W1,SYMP+S$ADR	;NOW POINT TO FILDDT SYMBOLS
	SKIPN	W2,SYMP+S$LEN	;GET LENGTH
	JRST	HSYCPY		;IF NO TABLE, GO CHECK HI SEG
TCOPY:	PUSHJ	P,FETCH		;GET A WORD
	 JRST	BADSTF		;SYMBOL TABLE PTR IS WRONG
	MOVEM	T,(W1)		;STASH IT
	AOS	W1
	AOS	R
	SOJG	W2,TCOPY

HSYCPY:	MOVE	R,HSYMP+S$ADR	;FILE'S HISEG SYMBOLS
	MOVEM	W1,HSYMP+S$ADR	;POINT HSYMP TO FILDDT'S COPY
	SKIPN	W2,HSYMP+S$LEN	;GET LENGTH
	JRST	SYMFIN		;DONE IF NONE TO COPY
HCOPY:	PUSHJ	P,FETCH		;GET NEXT WORD OF SYMBOL TABLE
	 JRST	BADSTF		;ERROR
	MOVEM	T,(W1)		;STORE IN FILDDT'S AREA
	AOS	W1		;BUMP FILDDT'S POINTER
	AOS	R		;AND FILE'S POINTER
	SOJG	W2,HCOPY	;LOOP THROUGH ALL SYMBOLS

SYMFIN:	SETOM	SYMGOT		;FLAG IN-CORE SYMBOLS ARE FROM THIS FILE
	SETZM	CHGSFL		;AND HAVEN'T BEEN CHANGED YET
	TMSG	<[>		;START MESSAGE
	MOVE	A,FISCNT	;GET COUNT OF SYMS LOADED
	PUSHJ	P,FP7		;TYPE IN DECIMAL
	TMSG	< symbols loaded from file]
>
	JRST	CPOPJ1		;TELL CALLER WE DID IT


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

  > ;END FTFILE
;NOW THE FILDDT ROUTINES

  IFN FTFILE,<

CTLZ:	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.


CTLE:	PUSHJ	P,CLSFIL	;CLOSE OFF THE INPUT FILE
	RESET			;MAKE SURE
	JRST	DDT		;RESTART
;STILL IFN 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
	PUSHJ	P,WRTSYM	;COPY SYMBOLS BACK IF NEEDED

;OPERATING SYSTEM DEPENDENT ROUTINES TO CLOSE OUT THE FILE

  IFN FTDEC20,<
	SKIPN	PHYSIO		;PHYSICAL I/O?
	JRST	FILREL		;NO, JUST UNMAP THE PAGES
  > ;END IFN FTDEC20
	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
;STILL IFN FTFILE

;HERE TO COPY CHANGED SYMBOLS AND POINTERS BACK INTO THE FILE

WRTSYM:	SKIPN	CHGSFL		;SEE IF SYMBOL TABLE CHANGED
	POPJ	P,		;NO, DON'T COPY ANYTHING
	SKIPE	PHYSIO		;OR ARE WE DOING PHYSICAL I/O?
	POPJ	P,		;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 THAT WE DO.

	XMOVEI	W,SYMP		;MASTER SYMBOL TABLE POINTER BLOCK
	SKIPG	SYTLOC		;PDV OR JOBDAT BASIS?
	SKIPL	S$SUF(W)	;JOBDAT, POINTING TO VECTOR SUBTABLE?
	JRST	WRTSY2		;SYMBOL-TABLE-VECTOR-SUBTABLE STYLE

;ORIGINAL SYMBOL TABLE POINTER WERE IOWD-STYLE FROM .JBSYM/.JBUSY

	HRL	R,SYTLOC	;GET JOBDAT SECTION
	HRRI	R,.JBSYM	;RE-FETCH FILE'S .JBSYM
	PUSHJ	P,FETCH		;GET FROM THE FILE
	 JRST	SCPERR		;NOT THERE? CAN'T UPDATE IT THEN
	CAME	T,FOSPTR+S$OPT	;SAME AS WHEN SYMS WERE COPIED?
	JRST	SCPERR		;NO, USER DEPOSITED .JBSYM -- ABORT
	HRRI	R,.JBUSY	;POINT TO FILE'S .JBUSY
	PUSHJ	P,FETCH		;FROM FILE
	 JRST	SCPERR		;DIDN'T MAKE IT
	CAME	T,FOUPTR+S$OPT	;STILL THE SAME AS BEFORE?
	JRST	SCPERR		;NO, ABORT
	JRST	WRTSY4		;CHECK HISEG SYMBOL TABLE
;ORIGINAL SYMBOL TABLE POINTERS WERE IN SYMBOL TABLE VECTOR SUBTABLES,
;EITHER ADDRESSED INDIRECTLY BY A PDV OR DIRECTLY BY .JBSYM.

WRTSY2:	PUSHJ	P,ORGSYM	;CHECK IF ORIGINAL POINTERS THERE
	 JRST	SCPERR		;NOPE, ABORT
	XMOVEI	W,USYMP		;TRY UNDEFINED BLOCK
	PUSHJ	P,ORGSYM	;STILL THERE?
	 JRST	SCPERR		;NO, ABORT
				;FALL THROUGH TO CHECK HISEG SYMTAB, IF ANY

;NOW CHECK OUT HISEG SYMBOL TABLE, IF ANY

WRTSY4:	SKIPN	FOHPTR+S$ADR	;WAS THERE A HISEG POINTER?
	JRST	CLSFI1		;NO, DON'T CHECK IT
	XMOVEI	W,HSYMP		;HISEG SYMBOL TABLE POINTER BLOCK
	SKIPL	S$SUF(W)	;IOWD OR VECTOR SUBTABLE FORMAT?
	JRST	[PUSHJ	P,ORGSYM	;VECTOR SUBTABLE, STILL THERE?
		  JRST	SCPERR		;NOPE, CAN'T UPDATE
		JRST	WRTSY6]		;YUP, LOOKS GOOD SO FAR
	MOVEI	R,.JBHSM	;NOW TRY FOR HISEG TABLE
	PUSHJ	P,HFETCH	;FETCH FROM HISEG
	 JRST	SCPERR		;FAILED?
	CAME	T,FOHPTR+S$OPT	;CHANGED?
	JRST	SCPERR		;YES, DON'T COPY ANYTHING
WRTSY6:	MOVE	T,FOHPTR+S$LEN	;GET ORIG LENGTH
	CAME	T,HSYMP+S$LEN	;SAME AS FILDDT'S COUNT?
	JUMPN	T,SCPERR	;MUST AGREE, SINCE NO ROOM FOR PATCHING

;FALL THROUGH TO COPY SYMBOLS BACK
;STILL IFN FTFILE

;FALL THROUGH FROM ABOVE

;IT'S OK TO UPDATE THE FILE'S SYMBOL TABLE.  NOW UPDATE THE FILE'S
;COUNT AND ADDRESS, AND THE ORIGINAL POINTERS.

CLSFI1:	MOVE	T,FOSPTR+S$LEN	;OLD LENGTH
	SUB	T,SYMP+S$LEN	;GET -DIFFERENCE
	ADDM	T,FOSPTR+S$ADR	;UPDATE ADDRESS OF FILE'S TABLE
	SKIPG	SYTLOC		;PDV OR JOBDAT BASIS?
	SKIPL	SYMP+S$SUF	;JOBDAT, IOWD OR VECTOR SUBTABLE?
	JRST	CLSFI3		;SYMBOL TABLE VECTOR SUBTABLES
 	MOVN	T,T		;IOWD, GET POS DIFFERENCE
	HRL	T,T		;FORM N,,N
	EXCH	T,SYMP+S$OPT	;GET OPERANDS IN ORDER FOR SUB
	SUBB	T,SYMP+S$OPT	;BACK .JBSYM INTO PATCH SPACE
	MOVN	S,USYMP+S$LEN	;GET -LEN NEW UNDEF S.T.
	ADD	T,S		;GET START OF NEW UNDEF S.T.
	HRL	T,S		;FORM -N,,ADR
	MOVEM	T,USYMP+S$OPT	;SAVE FOR LATER UPDATE
	JRST	CLSFI5		;BACK TO COMMON CODE

CLSFI3:	MOVE	T,SYMP+S$LEN	;GET NEW TABLE LENGTH
	DPB	T,[POINTR SYMP+S$OLN,ST%LEN]	;STORE IT FOR UPDATE
	SUB	T,FOSPTR+S$LEN	;GET POSITIVE DIFFERENCE
	EXCH	T,SYMP+S$OPT	;GET OPERANDS IN ORDER FOR SUBTRACT
	SUBB	T,SYMP+S$OPT	;UPDATE STARTING ADDRESS
	MOVE	S,USYMP+S$LEN	;GET NEW UNDEF S.T. LENGTH
	DPB	S,[POINTR USYMP+S$OLN,ST%LEN]	;STORE FOR UPDATE
	SUB	T,S		;FIND NEW UNDEF S.T. START ADR
	MOVEM	T,USYMP+S$OPT	;SAVE IT FOR LATER UPDATE
CLSFI5:	MOVE	T,FOSPTR+S$ADR	;GET FILE'S NEW DEFINED S.T. ADR
	SUB	T,USYMP+S$LEN	;BACK UP BY NEW UNDEF S.T. LENGTH
	MOVEM	T,FOUPTR+S$ADR	;STORE FILE'S NEW UNDEF S.T. ADR

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;COPY THE UNDEFINED TABLE INTO THE FILE.

OUCPY:	SKIPN	W2,USYMP+S$LEN	;ANY UNDEF SYMS LEFT?
	JRST	OUCPY4		;NOTHING TO COPY, JUST GO UPDATE POINTER
	MOVE	R,FOUPTR+S$ADR	;WHERE IN FILE TO PUT THE DATA
	MOVE	W1,USYMP+S$ADR	;POINTER TO FILDDT'S COPY
OUCPY1:	MOVE	T,(W1)		;NEXT SYMBOL OR VALUE
	PUSHJ	P,DEPMEM	;WRITE BACK TO FILE
	 JRST	SCPERR		;GIVE UP COPY IF CAN'T STORE
	AOS	R		;INCREMENT FILE VIRTUAL ADDRESS
	AOS	W1		;INCREMENT INTERNAL-TO-FILDDT ADDRESS
	SOJG	W2,OUCPY1	;LOOP FOR REST OF UNDEFINED SYMBOL TABLE

;NOW UPDATE UNDEFINED POINTER(S)

OUCPY4:	SKIPG	SYTLOC		;JOBDAT OR PDV BASIS?
	SKIPL	SYMP+S$SUF	;JOBDAT, IOWD OR VECTOR SUBTABLE?
	JRST	OUCPY6		;SYMBOL TABLE VECTOR SUBTABLE
	MOVEI	R,.JBUSY	;WHERE TO STORE IT
	HRL	R,SYTLOC	;AND IN WHAT SECTION
	JRST	OUCPY8		;GO DO IT

OUCPY6:	MOVE	R,USYMP+S$SUB	;GET SUBTABLE ADDRESS
IFN .STDAT,ADDI	R,.STDAT	;POINT TO TYPE/LENGTH WORD
	MOVE	T,USYMP+S$OLN	;GET NEW DATA
	PUSHJ	P,DEPMEM	;STORE IT
	 JRST	SCPERR		;FAILURE
	ADDI	R,.STPTR-.STDAT	;INCREMENT TO ADDRESS WORD
OUCPY8:	MOVE	T,USYMP+S$OPT	;GET UPDATED POINTER
	PUSHJ	P,DEPMEM	;DO THE STORE
	 JRST	SCPERR		;FAILED

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;COPY THE DEFINED TABLE INTO THE FILE

OSCPY:	SKIPN	W2,SYMP+S$LEN	;ANY SYMBOLS?
	JRST	OSCPY4		;NOTHING TO COPY, JUST GO UPDATE POINTER
	MOVE	R,FOSPTR+S$ADR	;WHERE IN FILE TO PUT THE DATA
	MOVE	W1,SYMP+S$ADR	;POINTER TO FILDDT'S COPY
OSCPY1:	MOVE	T,(W1)		;NEXT SYMBOL OR VALUE
	PUSHJ	P,DEPMEM	;WRITE BACK TO FILE
	 JRST	SCPERR		;ERROR
	AOS	R		;INCREMENT FILE VIRTUAL ADDRESS
	AOS	W1		;INCREMENT INTERNAL-TO-FILDDT ADDRESS
	SOJG	W2,OSCPY1	;LOOP FOR WHOLE SYMBOL TABLE

;NOW UPDATE THE DEFINED SYMBOL POINTER(S)

OSCPY4:	SKIPG	SYTLOC		;PDV OR JOBDAT BASIS?
	SKIPL	SYMP+S$SUF	;JOBDAT, IOWD OR VECTOR SUBTABLE?
	JRST	OSCPY6		;SYMBOL TABLE VECTOR SUBTABLE
	MOVEI	R,.JBSYM	;WHERE TO STORE IT
	HRL	R,SYTLOC	;AND IN WHAT SECTION
	JRST	OSCPY8		;GO DO IT

OSCPY6:	MOVE	R,SYMP+S$SUB	;GET SUBTABLE ADDRESS
IFN .STDAT,ADDI	R,.STDAT	;POINT TO TYPE/LENGTH WORD
	MOVE	T,SYMP+S$OLN	;GET NEW DATA
	PUSHJ	P,DEPMEM	;STORE IT
	 JRST	SCPERR		;FAILURE
	ADDI	R,.STPTR-.STDAT	;INCREMENT TO ADDRESS WORD
OSCPY8:	MOVE	T,SYMP+S$OPT	;GET UPDATED POINTER
	PUSHJ	P,DEPMEM	;STORE NEW POINTER
	 JRST	SCPERR		;COMPLAIN IF ERROR

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

OHCPY:	SKIPN	R,FOHPTR+S$ADR	;ANY HISEG SYMBOLS?
	POPJ	P,		;NONE, ALL DONE WITH COPY
	MOVE	W2,HSYMP+S$LEN	;GET SIZE OF HISEG TABLE
	MOVE	W1,HSYMP+S$ADR	;POINTER TO FILDDT'S COPY
OHCPY1:	MOVE	T,(W1)		;GET NEXT DATA WORD
	PUSHJ	P,DEPMEM	;STORE IN FILE
	 JRST	SCPERR		;ERROR?
	AOS	R		;BUMP PTR INTO FILE
	AOS	W1		;AND PTR INTO FILDDT
	SOJG	W2,OHCPY1	;LOOP OVER ALL OF FILDDT'S SYMBOLS
	POPJ	P,		;DONE UPDATING SYMBOLS
;ORGSYM -- CHECK IF ORIGINAL SYMBOL VECTOR SUBTABLE POINTERS ARE STILL THERE.
;CALL:
; W/	INTERNAL SYMBOL BLOCK ADDRESS
;	PUSHJ	P,ORGSYM
;RETURNS: +1/ FAILURE
;	+2/ SUCCESS, ORIGINAL POINTERS STILL THERE
;
;USES R,T

ORGSYM:	MOVE	R,S$SUB(W)	;GET SUBTABLE ADDRESS
IFN .STDAT,ADDI	R,.STDAT	;POINT TO LENGTH WORD
	PUSHJ	P,FETCH		;GET FROM FILE
	 SETCM	T,S$OLN(W)	;CAN'T, INSURE FAILS
	CAME	T,S$OLN(W)	;SAME AS WHEN SYMS WERE COPIED?
	POPJ	P,		;NO, GIVE ERROR
	ADDI	R,.STPTR-.STDAT	;NOW FOR ADDRESS WORD
	PUSHJ	P,FETCH		;FROM FILE
	 SETCM	T,S$OPT(W)	;CAN'T, INSURE FAILURE
	CAME	T,S$OPT(W)	;STILL THE SAME?
	POPJ	P,		;NO, ERROR
	JRST	CPOPJ1		;ALL UNCHANGED, RETURN GOOD


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

SCPERR:	TMSG	<
% Update of file's symbol table failed
>
	POPJ	P,		;RETURN FROM WRTSYM

  > ;END IFN FTFILE FROM PAGES AGO
;NOW FILDDT'S HANDLING

  IFN FTFILE,<

;FETCH FROM LOCAL SECTION

FETCHL:	SKIPL	SYTLOC		;ARE WE LOOKING AT A JOBDAT?
	POPJ	P,		;NO, RETURN BAD
;	PJRST	FETCHV		;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
	TXNN	TT,PG$EXI	;DOES PAGE EXIST?
	JRST [	SMERS	<PAGE DOES NOT EXIST>
		POPJ	P,]	;SET ERROR MSG AND RETURN
	TXNN	TT,PG$REA	;AND CAN WE READ IT?
	JRST [	SMERS	<NO READ ACCESS>
		POPJ	P,]	;SET ERROR MSG AND REUTRN
	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 [	SMERS	<ACTUAL REFERENCE FAILED>
		POPJ	P,]	;CAN'T GET THE DATA
  > ;END IFN FTDEC20
	JRST	CPOPJ1		;RETURN HAPPILY
;STILL IFN FTFILE

  IFN FTDEC10,<
MONPEK:	SKIPE	JOBING		;JOBPEK'ING?
	JRST	JOBPEC		;YES
	PUSHJ	P,CHKADR	;VERIFY ADDRESS
	TXNN	TT,PG$EXI	;DOES PAGE EXIST?
	JRST [	SMERS	<PAGE DOES NOT EXIST>
		POPJ	P,]	;SET ERROR MSG AND RETURN
	TXNN	TT,PG$REA	;AND CAN WE READ IT?
	JRST [	SMERS	<NO READ ACCESS>
		POPJ	P,]	;SET ERROR MSG AND REUTRN
	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?
	JRST [	SMERS	<ADDRESS BEYOND END OF PHYSICAL MEM>
		POPJ	P,]
	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?
	JRST [	SMERS	<CAN'T PEEK PHYSICAL>
		POPJ	P,]
	PUSHJ	P,SAVT4		;SAVE JSYS ACS
	MOVEM	R,XPKBLK+.XPMAD	;PUT MONITOR ADDRESS IN ARG BLOCK.
	MOVEI	T1,XPKBLK	;POINT TO ARG BLOCK.
	XPEEK%
	 ERJMP [MOVE	T1,XPKBLK+.XPMAD  ;FAILED, MAYBE OLD MONITOR
		TLNE	T1,-1		;PEEK% CAN ONLY HANDLE SECTION 0
		JRST	MONPKE		;CAN'T DO THE PEEK
		HRLI	T1,1		;WANT ONE WORD
		MOVE	T2,XPKBLK+.XPUAD  ;PUT IT HERE
		PEEK%			;GET THE WORD
		 ERJMP	MONPKE		;STILL CAN'T!
		JRST	CPOPJ1]		;WORKED THIS TIME
	JRST	CPOPJ1		;OK

MONPKE:	SMERS	<PEEK FAILED>	;GIVE ERROR
	POPJ	P,		;AND RETURN BAD
  > ;END OF IFN FTDEC20
;STILL IFN 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


;REGULAR USER VIRTUAL STORE (PHYSICAL SAME AS VIRTUAL)

STOREV:
STOREP:	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:
STORE3:	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 IFN 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 IFN 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 IFN 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	;SET MONITOR POKE ADDR.
	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


;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
;STILL IFN FTFILE

SUBTTL	MEMORY MANAGEMENT ROUTINES -- FILDDT I/O

;REDWIN  --  READ FILE PAGE INTO FILDDT MEMORY WINDOW
;WRTWIN  --  WRITE FILE PAGE FROM FILDDT MEMORY WINDOW
;CALL IS:
;
;	MOVX	TT1,<FPN>
;	MOVX	TT2,<WIN>
;	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 IFN FTFILE & IFN 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,WINTT1	;GET FILE PAGE
	LSH	TT2,PG2WRD	;MAKE IT AN ADDRESS
	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 IFN 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
	RPACS%			;NOW FIND FILE'S PAGE ACCESS
	MOVEM	T2,WINFAC(TT2)	;HANG ONTO IT FOR CHKADR
	JRST	FILIOS		;PAGE IS MAPPED
;STILL IFN FTFILE & IFN 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
	MOVE	TT2,TT1		;COPY PAGE NUMBER
	IMUL	TT2,PHYSPP	;CONVERT PAGE NUMBER TO SECTOR NUMBER
	DPB	TT2,TT		;PUT SECTOR NUMBER IN RIGHT FIELD IN T1
	LDB	TT,TT		;GET SECTOR NUMBER BACK FROM T1
	CAME	TT,TT2		;DID WHOLE THING GET STORED?
	JRST	FILTRF		;BLOCK # TOO BIG! DON'T WRAP AROUND
	LSH	TT1,PG2WRD	;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
	SKIPL	PHYSIO		;PHYSICAL UNIT WANTED?
	TXO	T2,DOP%NF	;YES, SET NEW FORMAT USED
	MOVE	T3,WINTT2	;GET INTERNAL PAGE NUMBER
	LSH	T3,PG2WRD	;CONVERT TO WORDS
	ADD	T3,WIND0	;ADD BUFFER BASE ADDRESS
	MOVE	T4,PHYARG	;GET STRUCTURE DESIGNATOR OR CKU NUMBERS
	MOVE	TT1,T1		;SAVE ARGUMENT IN CASE OF FAILURE
	DSKOP%			;DO THE I/O
	 ERJMP	FILTRO		;FAILED, GO TRY OLD METHOD
	JUMPE	T1,FILIOS	;IF NO I/O ERROR, GIVE SUCCESS RETURN

FILTRO:	TXC	T4,DOP%K2	;COMPLEMENT CONTROLLER NUMBER
	TXCN	T4,DOP%K2	;FIX BACK AND CHECK IF CONTROLLER WAS GIVEN
	SKIPGE	PHYSIO		;OR IF DOING STRUCTURES
	JRST	FILTRF		;YES, CAN'T TRY OLD FORMAT
	MOVE	T1,TT1		;RESTORE ORIGINAL ARGUMENT
	LOAD	TT1,DOP%C2,T4	;GET CHANNEL NUMBER FROM NEW FORMAT
	LOAD	TT2,DOP%U2,T4	;AND UNIT NUMBER
	CAIG	TT1,<.RTJST(-1,DOP%CN)>	;CHANNEL TOO LARGE FOR OLD FORMAT?
	CAILE	TT2,<.RTJST(-1,DOP%UN)>	;OR UNIT TOO LARGE?
	JRST	FILTRF		;YES, HAVE TO GIVE UP
	STOR	TT1,DOP%CN,T1	;STORE OLD FORMAT CHANNEL NUMBER
	STOR	TT2,DOP%UN,T1	;AND UNIT NUMBER
	TXZ	T2,DOP%NF	;CLEAR NEW FORMAT FLAG
	DSKOP%			;TRY THE OLD STYLE DSKOP NOW
	 ERJMP	FILTRF		;FAILED
	JUMPE	T1,FILIOS	;IF READ OK, GIVE SUCCESS RETURN

FILTRF:	TMSG	<
? I/O error
>				;TELL THE USER WHAT'S UP
	JRST	FILIOE		;AND GO COMPLAIN

  > ;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 IFN 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 IFN 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)
	RPACS%			;GET FILE'S PAGE ACCESS
	MOVEM	T2,WINFAC(TT2)	;SAVE FOR CHKADR
  > ;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
;STILL IFN 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 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!PG$SXI  ;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!PG$SXI ;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!PG$SXI  ;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
	SKIPE	EXEFMT		;EXE FILE?
	JRST	CHKAD1		;DON'T CHECK MAXSIZ
	CAML	R,MAXSIZ	;BEFORE END OF DISK OR FILE?
	JRST	CHKAD8		;NO
	SKIPN	FILING		;LOOKING AT A FILE?
	JRST [	MOVX	TT,PG$EXI!PG$SXI!PG$REA ;NO, MONITOR
		JRST	CHKAD8]		;PEEK CAN ONLY READ
	SKIPN	PHYSIO		;PHYSICAL I/O?
	JRST	CHKAD1		;NO, CHECK /D OR EXE FORMAT
	MOVX	TT,PG$EXI!PG$SXI!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$SXI!PG$REA!PG$ABZ  ;ALLOCATED BUT ZERO
	JRST	CHKAD5		;GO SEE IF WE CAN WRITE

CHKAD2:	PUSHJ	P,SRHWIN	;SEE IF THIS PAGE IS MAPPED IN
	 JRST	CHKAD3		;ISN'T, DO IT THE HARD WAY
	MOVE	TT,WINFAC(TT2)	;IS, ALREADY KNOW MONITOR'S ACCESS
	JRST	CHKAD5		;SEE WHAT IT REALLY SHOULD BE

CHKAD3:	PUSHJ	P,SAVR		;SAVE R OVER RPACS%
	MOVE	T1,TT1		;FILE PAGE NUMBER
	HRL	T1,FILJFN	;JFN FOR FILE
	RPACS%			;GET ACCESS BITS
	ERJMP [	SETZ	T2,
		JRST	.+1]	;CAN'T ACCESS PAGE IF SECTION NOT THERE
	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	STORAGE -- MISCELLANEOUS

	DDS(BEG.V,0)		;BEGINNING OF VARIABLES

	DD(NM1A,1,<<MOVEI W2,0>>)	
	DD(ACCCF,1)		;"-1,,A" IF "A,,B" CONSTRUCTION
	DD(SEAXCT,1)		;XCT'ED BY SEAR2 IN [NOT]WORD SEARCH
	DD(TOCS,1,<<MOVEI T,.-.>>);GET RIGHT HALF BACK
	DD(MEMERS,1)		;ADR OF ERROR MESSAGE STRING

;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)		;FANCY TTY HANDLING MASK
	DD(TTDEV,1)		;$Y'ED TERMINAL (IF ANY)
IFN FTEXEC,<
	DD(TTSUP,1)		;EXEC-MODE ^O SUPPRESSION FLAG
	DD(TTHLD,1)		;EXEC-MODE ^S/^Q HOLD OUTPUT FLAG
> ;END IFN FTEXEC

	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
> ;END IFN FTDEC20
	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
> ;END IFN FTDEC10!FTEXEC

	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(COMCOR,1)		;.NE. 0 IF COMMAND IS FROM MEMORY STRING
	DD(PTDFLG,1)		;EOF SEEN ON COMMAND FILE
	YFLLEN==.FOMAX+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
	YRFLEN==.FOFMX
	DD(YRFBLK,YRFLEN)	;RETURNED FILESPEC BLOCK
	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.NSTS,1)		;SECTION OF REFERENCE FOR I.NSTE
	DD(I.NSS2,1)		;SECTION OF REFERENCE FOR I.NEA2
	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.CJMP,1)		;-1 IF CONDITIONAL JUMP (E.G. AOJX)
	DD(I.XJRS,1)		;XJRST VALUE AFTER DOITX'S XCT
  IFN FTDEC20,<
	DD(I.NECJ,1)		;COPY OF ERCAL/ERJMP IF PRESENT
	DD(I.NERJ,1)		;ERCALX/ERJMPX CONVERTED TO ERJMPX
	DD(I.ECJA,1)		;ERCAL/ERJMP TARGET ADDRESS
  > ;END IFN FTDEC20
	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(I.PCREF,1)		;PC-REF 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)		;0 IF BEFORE, -1 IF AFTER
	DD(PTSYM,1)		;SYMBOL USED IN PATCHING
	DD(PTVAL,1)		;ORIGINAL SYMBOL VALUE
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,%%DDT)	;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$STR:!	DD(,1)			;.NE. 0 THEN ADDRESS OF COMMAND STRING
B$FLG:!	DD(,1)			;	BREAKPOINT FLAGS
	BP$PRO==1B0		;		AUTO-PROCEED
	BP$INS==1B1		;		BREAKPOINT INSTALLED
	BP$ERM==1B2		;		ERROR MESSAGE TYPED
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 SAVE/RESTORE/SWAP (HOLDS REGISTER T)
				;ALSO USED BY PHYIN (HOLDS INSTRUCTION)
	DD(SAVP,1)		;HOLDS P BETWEEN JSR SAVE/JSP T,RESTOR
	DD(SAVF,1)		;FLAGS GO HERE BETWEEN SAVE/RESTOR
	DD(XSWAP,1)		;30-BIT PC FLAGS FOR SWAP
	DD(SWAP,1)		
	DD(,1,<JRST SWAPG>)

> ;END IFE FTFILE

IFN FTDEC10,<			;-10 DEFAULTS $4M OFF
	DD(BPBLK,1,<0>)		;IN-SECTION ADDR OF BREAKPOINT BLOCK
> ;END IFN FTDEC10
IFN FTDEC20,<			;-20 DEFAULTS $4M ON
IFE FTMON!FTEX20,<
	DD(BPBLK,1,1000000-BPBMAX) ;IN-SECTION ADDRESS OF BREAKPOINT BLOCK
>
IFN FTEX20,<
	DD(BPBLK,1,EDDBLK)	;BPBLK FOR KDDT
	DD(FAKDDT,1)		;TOPS-20 JSR'S TO HERE
	DD(,1,<JRST FAKDDG>)	; WHEN MOVING DDT AROUND
>
IFN FTMON,<
	DD(BPBLK,1,MDDBLK)	;BPBLK FOR MDDT
	DD(CHKCNT,1,0)		;USE COUNT FOR MDDT CHECKPOINT
>
> ;END IFN FTDEC20

	DD(BYSS,1)		;BYTE SIZE FOR ASCII INPUT/OUTPUT
	DD(PBYSS,1)		;PERMANENT-MODE BYTE SIZE
	DD(SVBTS,1)		;BYTE MASK FOR $O TYPEOUT
	DD(PSVBTS,1)		;SAVE BLOCK FOR ABOVE ON $$O

	DD(BYTMSK,1)		;$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(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

	DD(ESTUT,2)		;ADDRESS/LENGTH PAIR, COPY OF USYMP
ESTUTL=ESTUT+1			;USED BY UNDEFINED SYM ASSEMBLER
	DD(FSV,1)		
	DD(FH,1)		

;INTERNAL SYMBOL VECTOR IN CASE WE ARE BUILT WITH LINK 5.1

  IFN FTUD20,<			;USER-20 ONLY
				;PROTOTYPE SYMBOL TABLE VECTOR
	DD(DDTSYV,7,<7,<FLD(.R50D,ST%TYP)>,<IFIW>,0,<FLD(.R50U,ST%TYP)>,<IFIW>,0>)
  > ;END IFN FTUD20
	DD(SYMP,0)		;DEFINED SYMBOL TABLE POINTER BLOCK

	.PHASE	0		;DEFINE TAGS RELATIVE TO ZERO

S$ADR:!	DD(,1)			;ADDRESS OF SYMBOL TABLE
S$LEN:!	DD(,1)			;LENGTH OF SYMBOL TABLE (MUST BE S$ADR+1)
S$SUB:!	DD(,1)			;PDV SUBTABLE ADDRESS OR IOWD ADDRESS
S$SUF:!	DD(,1)			;LH: IOWD OR VECTOR SUBTABLE FLAG
				;RH: RESERVED
  IFN FTFILE,<
S$OLN:!	DD(,1)			;ORIGINAL LENGTH WORD
S$OPT:!	DD(,1)			;ORIGINAL POINTER WORD
  > ;END IFN FTFILE

	S$SIZ==.-S$ADR		;LENGTH OF SYMBOL BLOCK

	.DEPHASE		;BACK TO NORMAL

	DD(USYMP,S$SIZ)		;UNDEFINED SYMBOL TABLE BLOCK
	DD(HSYMP,S$SIZ)		;HISEG SYMBOL TABLE BLOCK

	DD(SYTLOC,1)		;-1,,JOBDAT SECTION /OR/ PDVA
				; /OR/ SYMTAB VECTOR ADDR (-10 ONLY)

  IFE FTMON!FTFILE,<		;SOME DON'T NEED PDV STORAGE
    IFN FTDEC20,<
	DD(PDVARG,6,<6,.FHSLF>)	;PDVOP% ARG BLOCK - SIZE, FORK
    > ;END IFN FTDEC20
	DD(PDVA,1)		;DATA BLOCK FOR PDVOP%
  > ;END IFE FTMON!FTFILE
  IFN FTUD20,<			;USER-20 ONLY
	DD(DDTPDV,1)		;DDT'S OWN PDV ADDRESS
  > ;END IFN FTUD20
  IFN FTDEC10,<			;TOPS-10 ONLY
	DD(SEGOPB,.SGFSP,.SGINF) ;SEGOP. UUO .SGINF BLOCK
	DD(,1,<<IFIW SEGFIL>>)	;POINTER TO FILESPEC BLOCK FOR HISEG
	DD(SEGFIL,.SGFLN)	;HISEG ORIGIN FILESPEC BLOCK
  > ;END IFN FTDEC10
	DD(ENDSUB,1)		;END OF VECTOR PROCESSED BY PDVBLK

IFN FTEX10,<
	DD(HSBLK,1)		;0 IF SYMBOLS NOT HIDDEN, ELSE BLOCK ADDRESS
	DD(JOBEDV,1)		;ADDRESS OF THE EXEC DATA VECTOR
	DD(CPNDDT,1)		;WORD TO POKE WHEN HITTING A BREAKPOINT
	DD(CPNBIT,1)		;BIT TO SET IN CPNDDT ON A BREAKPOINT
> ;END IFN FTEX10

IFN FTDEC10&FTFILE,<
	DD(JOBEDV,1)		;NON-ZERO IFF CRASH FILE HAD A USEFUL EDV
	DD(EDVEPT,1)		;EPT PAGE NUMBER FROM EDV
	DD(EDVSPT,1)		;INCOMING SPT ADDRESS
	DD(EDVCST,1)		;INCOMING CST ADDRESS
> ;END IFN FTDEC10&FTFILE


;SYMBOL TABLE CACHE DATA:

  IFN FTSCSH,<			;ONLY IF USING SYMBOL TABLE CACHE

	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
  > ;END IFN FTSCSH
SUBTTL	STORAGE -- ADDRESSING DATA

	DD(SPSAV,1,<-1>)	;POINTER TO LAST SYMBOL TYPED
	DD(ABBSY1,1)		;LOWER LIMIT IN ABBREV SYMBOL RANGE
	DD(ABBSY2,1)		;UPPER LIMIT IN ABBREV SYMBOL RANGE
	DD(ABBSY3,1)		;FLAGS MASK FOR ABBREV MATCHING

				;ORDER OF LLIMIT/LLREGF/LLACCF IS IMPORTANT!
	DD(LLIMIT,1)		;LOWER LIMIT WORD (SEARCHES, ETC)
				; ALSO VALUE FOR DEFINING SYMBOL
	DD(LLREGF,1)		;REGISTER "F" AT "<" TIME
	DD(LLACCF,1)		;FLAG "ACCCF" AT "<" TIME

				;ORDER OF ULIMIT/ULREGF/ULACCF IS IMPORTANT
	DD(ULIMIT,1)		;UPPER LIMIT WORD (SEARCHES, ETC)
	DD(ULREGF,1)		;REGISTER "F" AT ">" TIME
	DD(ULACCF,1)		;FLAG "ACCCF" AT ">" TIME

	DD(LLOC,1)		;LAST LOCATION (E.G., LOCATION/, ETC.)
	DD(LLOCO,1)		;LAST LOCATION OPEN
	DD(LLOCS,1)		;DEFAULT SECTION
	DD(PDFSEC,1,-1)		;PERMANENT DEFAULT SECTION
	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(EAGLOB,1)		;EA LOCAL/GLOBAL FLAG

	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,<<FTUE10>>);-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
IFN FTDEC10,<
	DD(LASTAF,1)		;FULL PAGE ACCESS BITS FOR LASTPG
	DD(S0PLIM,1)		;MASK FOR INACCESSIBLE ADDRS FROM SEC. 0
> ;END IFN FTDEC10
	DD(NZSXJF,2)		;FOR XJRSTF INTO SECTION 1 ACS


;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+08) SPT BASE ADDRESS (VIRTUAL)
	 DDS(ENDPI,0)		;DEFINE END OF LEGAL $I RANGE FOR DDSYMC

;STATE VARIABLES SUCH AS EXEC-MODE FLAG AND CPU-TYPE

	DD(SECDDT,1)		;SECTION IN WHICH DDT IS RUNNING,,0
  IFN FTUD20,<			;STUB EXISTS ONLY IN USER-20
	DD(SECUDD,1,-1)		;<SECTION OF UDDT STUB,,0> OR -1
  > ;END IFN FTUD20
	DD(USRFLG,1)		;.LT. 0 IF IN USER MODE (EXEC DDT ONLY)

	DDS(BZ$FLG,0)		;START OF FLAGS TO BE CLEARED ON ENTRY
	DDS(BZ$CPF,0)		;START OF CPU FLAGS AREA
	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
	DDS(ZZ$CPF,0)		;END (+1) OF CPU FLAGS AREA
	DD(KIPAG,1,<0>)		;.NE. 0 IF KI-PAGING
	DD(KLPAG,1,<-1>)	;.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)		
	DD(FVTEM4,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 FTEXEC

IFN FTDEC20,<
	DD(SAVTT2,1)		;SAVED RFCOC% WORDS
	DD(SAVTT3,1)		
	DD(SAVTIW,1)		;SAVED TERMINAL INTERRUPT MASK
	DD(SAVSTS,1)		;SAVED PSI STATE
	DD(SAVNXP,1)		;PAGE-CREATE CHANNEL FLAG
> ;END IFN FTDEC20

	DD(MSK,1,-1)		;INITIAL SEARCH MASK

	DD(SYMVAL,1)		;NON-ZERO IF WE TRUST @USYMP ETC.
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)		; . . .

;STORAGE FOR $L COMMAND
	DD(OLDBTS,1)		;ACCESS OF LAST PAGE CHECKED
	DD(LOWPAG,1)		;FIRST PAGE OF CURRENT GROUP
	DD(HGHPAG,1)		;LAST PAGE OF CURRENT GROUP
  IFN FTUE10,<
	DD(OLDSPY,1)		;FLAG FOR PA.GPN VALIDITY
  > ;END IFN FTUE10
  IFN FTPAGM,<
	DD(MAPBTS,1)		;STORAGE FOR MAP ENTRY BITS FROM MAPADR
  > ;END IFN FTPAGM
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>)  ;RANGE FOR SYMBOL+OFFSET TYPEOUT

IFN FTEXEC,<
	DD(XNXTCH,1)		;PRESET INPUT CHAR AT XLISTE
	DD(XTYPAC,1)		;COUNT OF TYPEAHEAD CHARACTERS
	DD(XTYPAG,1)		;TYPEAHEAD BYTE GETTER
	DD(XTYPAP,1)		;TYPEAHEAD BYTE PUTTER
	DD(XTYPAX,1)		;TYPEAHEAD CHECK COUNTER (EVAL, LOOK)
	DD(XTYPAB,XTYPAW)	;TYPEAHEAD BYTE BUFFER
> ;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==.FOMAX+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
	RFSLEN==.FOFMX		;LENGTH OF RETURNED FILESPEC BLOCK
	DD(RFSBLK,RFSLEN)	;RETURNED FILESPEC BLOCK
	DSKLEN==.DCUSZ+1	;LENGTH OF DSKCHR BLOCK
	DD(DSKBLK,DSKLEN)	;DSKCHR BLOCK (FOR /U)
	DD(DSKCHA,1)		;DSKCHR AC (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
	DD(THAWSW,1)		;-1, IF THAWED FILE ACCESS; 0, IF FROZEN
> ;END OF IFN FTDEC20
;STILL IFN 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)		;"/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(NUMSEG,1)		;COUNT OF SEGMENTS IN THIS EXE FILE
	DD(LSTNPG,1)		;LAST XLATED PAGE IN CHKADR
	DD(EXEFMT,1)		;.NE. 0 IF FILE IS IN .EXE FORMAT
	DD(PDVNUM,1)		;# PDVS READ FROM EXE FILE
	DD(PDVTBL,1)		;POINTER(W2) TO PDV LIST
	DD(EVLEN,1)		;ENTRY VECTOR LENGTH FROM EXE FILE
	DD(EVADR,1)		;ENTRY VECTOR ADR FROM EXE FILE
;STILL IFN 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(PHYARG,1)		;DEV DESIGNATOR OF STRUCTURE OR CKU NUMBERS
	DD(PHYSPP,1)		;NUMBER OF SECTORS PER PAGE FOR DISK UNITS
	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
	DD(WINFAC,WINMAX)	;FILE PAGE ACC FOR THIS WINDOW (PARALLEL
				;	TO WINFPN)
> ;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

IFN FTDEC20,<
	DD(XPKBLK,.XPLEN,<.XPLEN,.XPPEK,1,Z,Z,T>)
				;XPEEK% ARGUMENT BLOCK
> ;END IFN FTDEC20

	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(FOSPTR,S$SIZ)	;SYMP ON FILDDT STARTUP
	DD(FOUPTR,S$SIZ)	;USYMP ON FILDDT STARTUP
	DD(FOHPTR,S$SIZ)	;HSYMP 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 FTPURE,<
	DDS(VAREND,0)		;END OF INITIALIZED VARIABLES AREA
IFN FTMON,<
	DD(SETRT1,1)		;SCRATCH FOR VARIABLE INITIALIZATION
> ;END IFN FTMON
> ;END IFN FTPURE

	DDS(END.V,0)		;END OF VARIABLES

IFE FTPURE,<
	LEN.V==END.V-BEG.V	;LENGTH OF VARIABLE AREA
> ;END IFE FTPURE

IFN FTPURE,<
	LEN.V==.-PHVAR		;AVOID E ERROR IN PRINTX
> ;END IFN FTPURE


IFN FTPURE&<^-FTMON>,<
  IFGE VARLOC,<
	.ENDPS			;BIND OFF {DDTCOD|.HIGH.}
	.PSECT	DDTVAR/RWRITE,VARLOC
	BLOCK	LEN.V		;ALLOCATE THE SPACE
>>


IFGE RUNLOC,<IFGE VARLOC,<IFL <VARLOC-RUNLOC>,<
;>>>	DDTEND:			;DDTEND GOES HERE UNLESS WE'RE SURE
				;THAT VARIABLES ARE BELOW CODE
DEFINE PRROOM(WORDN,AREAN),<
	IF2,<
	PRINTX	[WORDN words left in AREAN area]
	>
> ;END DEFINE PRROOM

DEFINE PRFULL(WORDN,AREAN),<
	IF2,<
	PRINTX	? The AREAN area has overflowed by WORDN words
	>
> ;END DEFINE PRFULL

	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>) >
    > ;END IFE FTMON
> ;END IFGE RUNLOC

	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.

IFE FTDEC20,<		;NEVER FOR TOPS20
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
> ;END DEFINE XP

;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>
> ;END IFE FTDBUG
;DEFINE I/O DEVICE MNEMONICS

IFN FTEXEC,<

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
> ;END IFN FTEXEC
;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 XJRST,XJRST

XP JOV,JOV
XP JFOV,JFOV
XP JCRY0,JCRY0
XP JCRY1,JCRY1
XP JCRY,JCRY
> ;END IFE FTFILE
> ;END IF2
> ;END IFE FTDEC20
;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 FTDSYM,<XPUNGE>		;PURGE LOCALS IF SO DESIRED

IFE FTDBUG,<
    IFN FTFILE!FTVMX,<
	END	DDT>		;FILDDT OR VMDDT START ADDRESS

    IFN FTUD20,<
	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 FTUD20,<
	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