Google
 

Trailing-Edge - PDP-10 Archives - bb-m403a-bk - ddt11.mac
There are 17 other files named ddt11.mac in the archive. Click here to see a list.
	TITLE	DDT11 %5(53) PDP-10 RESIDENT PDP-11 [FIL]DDT
	SUBTTL	DMCC et al

;THIS VERSION OF DDT11 WILL
; RUN ON A KS10 STANDALONE AND CONTROL ALL I/O
; RUN UNDER TOPS-10, TALKING TO DN8x, DN6x, DC7x, DN9x, and RSX20F
;	AND READING DUMPS FROM RSX20F, DTELDR, NETLDR, AND BOOT11
;	READING THE OUTPUT OF MACDLX, PAL10, AND RSXFMT (RSX20F.MAP)
; RUN UNDER TOPS-20, TALKING TO RSX20F
;	AND READING DUMPS FROM RSX20F, DN6x
;	READING THE OUTPUT FROM MACDLX, AND RSXFMT (RSX20F.MAP)
				
	SEARCH	JOBDAT,MACTEN,UUOSYM

	SALL			;GET NICE LISTINGS FOR A CHANGE
	.HWFRMT			;AND SKIP THE FANCY BITS
	.DIRECTIVE LITLST,FLBLST

;DDT11 VERSION NUMBER

VWHO==	0
VDDT11==5
VMINOR==0
VEDIT==	53

%%DDT11==:<BYTE	(3)VWHO(9)VDDT11(6)VMINOR(18)VEDIT>

	LOC	.JBVER
	%%DDT11
	RELOC	0
EXMAX==	140		;MAXIMUM NUMBER OF BYTES TO EXAMINE AT ONCE

IFNDEF	MASKSZ,<MASKSZ==10>	;NUMBER OF WORDS IN MASK
IFNDEF	CMDSIZ,<CMDSIZ==300>	;LARGEST COMMAND
IFNDEF	NUMBUF,<NUMBUF==1>	;NUMBER OF BUFFERS FOR READING DUMPS, ETC.
				; SETTING LARGER THAN 1 MAY CAUSE %GOTO TO FAIL

	SEARCH	MONSYM,MACSYM

IO.RLB==1000
IO.WLB==400

;TTYBIT FLAGS
TF.RUB==1B1			;DO RUBOUTS WITH BACKSPACE-SPACE-BACKSPACE
;REGISTER USAGE

AC1=	1
AC2=	AC1+1
AC3=	AC2+1
AC4=	AC3+1
SYM=	5			;POINTER TO SYMBOL BLOCK
STATE=	6
DOT=	7			;CURRENT LOCATION
				; IF LH IS NONZERO IS A REGISTER ADR
FLG=	10
T1=	11
T2=	T1+1
T3=	T2+1
T4=	T3+1
T5=	T4+1
P=	17
	.XCREF	AC1,AC2,AC3,AC4,SYM,STATE,DOT,FLG,T1,T2,T3,T4,T5,P
F.FLIP==1B35			;LOCAL FLAG
				; USED BY $V TO FLAG 1ST PASS
				; USED BY $N TO DISTINGUISH FROM $W
				; USED BY OPNFIL TO DEMAND PROMPT
				; USED BY $D TO REMEMBER DOING COMMAND LOGGING
				; USED WHEN READING BINARY FILE
F.FLOP==1B34			;LOCAL FLAG
				; SET IF USER SAYES /BINARY IN INITIAL COMMAND
				; SET IF READING A PACKED FILE
F..FOO==1B33			;LOCAL FLAG WHEN SET MEANS
				; DUMP IS DISASSEMBLY
				; READING A DTELDR DUMP
F.LOPN==1B32			;CURRENT LOCATION IS OPEN
F.MOPN==1B31			;MASK OPEN
F.MASK==1B30			;ESCAPE M TYPED
F.TEXT==1B29			;ASSEMBLING TEXT
F.IOCT==1B28			;ASSEMBLING AN OCTAL NUMBER
F.IDEC==1B27			;ASSEMBLING A DECIMAL NUMBER
F.IHEX==1B26			;ASSEMBLING A HEX NUMBER
F.SYMB==1B25			;ASSEMBLING A SYMBOL
F.CACH==1B24			;USE CACHE IF POSSIBLE
F.WRIT==1B23			;WE ARE OPENING FILE FOR OUTPUT
F.APND==1B22			;APPEND TO TO FILE IF ALREADY EXISTS
F.LOCK==1B21			;PROGRAM IS LOCKED
F.WENB==1B20			;PATCHING WAS ENABLED WITH /PATCH
F..ESC==1B19			;TYPED ESCAPE TWICE
F.PACK==1B18			;BINARY FILE IS PACKED
F.LBKT==1B17			;LOCATION OPENED WITH A LEFT BRACKET
F.HASH==1B16			;OPCODE PRECEEDED BY A # SIGN
F.PERC==1B15			;OPCODE PRECEEDED BY A % SIGN
F.LPAR==1B14			;OPCODE PRECEEDED BY A ( SIGN
F.SYML==1B13			;SYM HAS BEEN LOADED . SET BY GETEXP
F.GEXP==1B12			;GOT AN EXPRESSION . SET BY GETEXP
F.TOPN==1B11			;DID OPEN ON TTY(TO CONTROL ECHO)
F.SVIO==1B10			;HIT A STACK VIOLATION
F.SREG==1B9			;SYMBOLIC TYPEIN WAS A REGISTER NAME
F..SIM==1B8			;AM RUNNING SIMULATION
F.EXEC==1B7			;RUNNING IN EXEC MODE
F.RUNF==1B6			;RUN FLOP FOR SIMULATION
F.CERR==1B5			;HIT AN ERROR IN COMMAND FILE
F.FELE==1B4			;HAVE DONE FIRST ELEMENT OF EXPRESSION
F.HALT==1B3			;JUST DID A HALT


;FLAGS FOR TYPE OF OPERATING SYSTEM

T.OTHER==1B0			;THIS IS OTHER

T.TOP10==1B1			;THIS IS TOPS-10
T.ITS==1B2			;THIS IS ITS
T.TENEX==1B3			;THIS IS TENEX
T.TOP20==1B4			;THIS IS TOPS-20
T.EXEC==1B5			;THIS IS EXEC MODE
;SOME MACROS ETC

	OPDEF	CALL	[PUSHJ P,]
	OPDEF	NOP	[CAI]
	OPDEF	RET	[POPJ P,]

	DEFINE	TYPE (X) <
	MOVEI	T1,[ASCIZ \X\]
	CALL	TYPSTR
>;DEFINE TYPE
;DEFINE THE TYPES OF EXAMINES WE CAN DO

EX.MEM==	0		;MEMORY
EX.PORT==	1		;CALL11 UUO
EX.NODE==	2		;NODE UUO
EX.FE0==	3		;RSX20F EXAMINE
EX.D61==	4		;DN60 ON TOPS-10
EX.D62==	5		;DN60 ON TOPS-20
EX.MCB==	6		;DN20 DECNET 20 EXAMINE
EX.FE1==	7		;RSX20F/TOPS-10
	FE.MAX==40		;Max data bytes 20F allows for ME msg

	OPDEF	APRID	[700000,,0] ;READ MICROCODE VERSION AND CPU SERIAL NU
	OPDEF	WRAPR	[700200,,0] ;WRITE APR
			;1B19	;IO RESET
			;1B20	;ENABLE SELECTED CONDITIONS
			;1B21	;DISABLE SELECTED CONDITIONS
			;1B22	;CLEAR SELECTED CONDITIONS
			;1B23	;SET SELECTED CONDITIONS
			;1B25	;INTERRUPT 8080
			;1B26	;POWER FAIL
			;1B27	;NXM
			;1B28	;BAD MOS DATA
			;1B29	;CORRECTED MOS DATA
			;1B30	;TIMER
			;1B31	;8080 INTERRUPT
			;1B32	;GENERATE APR INTERRUPT
			;7B35	;APR LEVEL
	OPDEF	RDAPR	[700240,,0] ;READ APR
	OPDEF	WRPI	[700600,,0] ;WRITE PI
	OPDEF	PIOFF	[700600,,400]
	OPDEF	PION	[700600,,200]
	OPDEF	RDPI	[700640,,0] ;READ PI
	OPDEF	WRUBR	[701140,,0] ;WRITE USER BASE REGISTER
	OPDEF	CLRPT	[701100,,0] ;CLEAR PAGE TABLE
	OPDEF	RDUBR	[701040,,0] ;READ USER BASE REGISTER
	OPDEF	WREBR	[701200,,0] ;WRITE
	OPDEF	RDEBR	[701240,,0] ;READ
	OPDEF	TIOE	[710000,,0] ;TEST UNIBUS, SKIP EQUAL
	OPDEF	TIOEB	[720000,,0] ;TEST UNIBUS, SKIP EQUAL
	OPDEF	TION	[711000,,0] ;TEST UNIBUS, SKIP NOT EQUAL
	OPDEF	TIONB	[721000,,0] ;TEST UNIBUS, SKIP NOT EQUAL
	OPDEF	RDIO	[712000,,0] ;READ UNIBUS
	OPDEF	RDIOB	[722000,,0] ;READ UNIBUS BYTE
	OPDEF	WRIO	[713000,,0] ;WRITE UNIBUS
	OPDEF	WRIOB	[723000,,0] ;WRITE UNIBUS BYTE
	OPDEF	BSIO	[714000,,0] ;BIT SET TO UNIBUS
	OPDEF	BSIOB	[724000,,0] ;BIT SET TO UNIBUS BYTE
	OPDEF	BCIO	[715000,,0] ;BIT CLEAR TO UNIBUS
	OPDEF	BCIOB	[725000,,0] ;BIT CLEAR TO UNIBUS BYTE
	OPDEF	WRSPB	[702400,,0] ;WRITE SPT BASE REGISTER
	OPDEF	RDSPB	[702000,,0] ;READ SPT BASE REGISTER
	OPDEF	WRCSB	[702440,,0] ;WRITE CORE STATUS TABLE BASE REGISTER
	OPDEF	RDCSB	[702040,,0] ;READ CORE STATUS TABLE BASE REGISTER
	OPDEF	WRPUR	[702500,,0] ;WRITE PROCESS USE REGISTER
	OPDEF	RDPUR	[702100,,0] ;READ PROCESS USE REGISTER
	OPDEF	WRCSTM	[702540,,0] ;WRITE CST MASK REGISTER
	OPDEF	RDCSTM	[702140,,0] ;READ CST MASK REGISTER
	OPDEF	WRTIME	[702600,,0] ;WRITE TIME BASE
	OPDEF	RDTIME	[702200,,0] ;READ TIME BASE
	OPDEF	WRINT	[702640,,0] ;WRITE INTERVAL TIMER
	OPDEF	RDINT	[702240,,0] ;READ THE INTERVAL REGISTER
	OPDEF	UMOVE	[704000,,0] ;MOVE FROM PREVIOUS CONTEXT
	OPDEF	UMOVEM	[705000,,0] ;MOVE TO PREVIOUS CONTEXT
;EPT - EXECUTIVE PROCESS TABLE
			;0-37 CHANNEL LOGOUT AREA
			;40-41
EPTINT==42		;42-57 INTERRUPT LOCATIONS
			;60-77 (KL10 - DTE AREA)
EPTVEC==100		;100 128 WORD TABLE OF VECTORS
			;101-177 RESERVERED FOR FUTURE USE
			;200-377 EXEC PAGE 400-777
			;400-420
EPTAOV==421		;421 EXEC ARITH OVERFLOW TRAP INS
EPTPDO==422		;422 EXEC PUSHDOWN OVFL INS
EPTTP3==423		;423 EXEC TRAP-3 INS
			;424-427 HALT STATUS AREA
			;430-437
			;460-507
			;510 TIME BASE HIGH-ORDER WORD
			;511 TIME BASE LOW-ORDER WORD
			;512 PERF ANA COUNTER HIGH-ORDER WORD
			;513 " LOW-ORDER WORD
			;514 INTERVAL TIMER VEC INT LOC
			;515-577 RES FOR USE BY HDW
EPTSTP==540		;540-557 SECTION TABLE POINTER FOR SECTION 0-17
EPM000==600		;600-757 EXEC PAGE 0-337
			;760-777 RESERVED
;UPT - USER PAGE TABLE
			;0-377 USER PAGE 0-777
			;400-417 EXEC PAGE 340-377
			;420 FREE
			;421 USER ARTIH OVFLW TRAP INST
			;422 USER PUSHDOWN OVFLW TRAP INS
			;423 USER TRAP-3 INS
.UPMUO==1424		;424 USERS FLAGS,,MUUO OPCODE
.UPMUP==1425		;425 PC WORD OF MUUO STORED HERE
			;426 MUUO EFFECTIVE ADDR
			;427 PROCESSOR CONTEXT
			;430 KERNEL NO TRAP MUUO NEW PC WORD
			;431 KERNEL TRAP MUUO NEW PC WORD
			;432 SUPERVISOR TRAP MUUO NEW PC WORD
			;433 SUPERVISOR NO TRAP MUUO NEW PC WORD
			;434 CONCEALED TRAP MUUO NEW PC WORD
			;435 CONCEALED NO TRAP MUUO NEW PC WORD
			;436 PUBLIC TRAP MUUO NEW PC WORD
			;437 PUBLIC NO TRAP MUUO NEW PC WORD
			;440-477 FREE
UPTPFW==1500		;500 EXEC OR USER PAGE FAILWORD STORED HERE
			;B0 USER MODE
			;B1 IO = ADAPTER
UPTPFL==1501		;501 PAGE FAIL OLD FLAGS WORD
UPTPFO==1502		;502 PAGE FAIL OLD PC WORD
UPTPFN==1503		;503 PAGE FAIL NEW PC WORD
			;504 EBOX CLOCK TICKMETER HIGH ORDER WORD
			;505 EBOX CLOCK TICKMETER LOW-ORDER WORD
			;506 MBOX CYCLEMETER HIGH ORDER WORD
			;507 MBOX CYCLEMETER LOW-ORDER WORD
			;510-577 RESERVED FOR HDW
			;600-777 FREE

; PAGE TABLE WORDS
			;400000 ACCESS ALLOWED
			;200000 PUBLIC
			;100000 WRITABLE
			;040000 SOFTWARE
			;020000 CACHE ENABLED
			;017777 PHYSICAL PAGE ADR BITS 14-26
;UNIBUS ADAPTER
UBAMAP=	763000		;MAPPING REGISTERS
UB.RPW==400000		;MAINTENANCE PAUSE FOR EVEN AND ODD MEMORY WRITE
UB.16B==200000		;DISABLE UPPER TWO BITS ON TRANSFER
UB.FST==100000		;FAST XFER
UB.VLD==040000		;VALID
		;003777	;PAGE NUMBER
UBA.SR=	763100		;STATUS REGISTER
		;400000	;TIMEOUT
		;200000	;BAD MEMORY ON NPR TRANSFER
		;100000	;SM10 BACKPANEL BUS ERROR
		;040000	;CPU ADDRESSED NONEXISTENT DEVICE
		;004000	;BR6 OR BR7
		;002000	;BR5 OR BR4
		;001000	;AC OR DC LOW
		;000200	;DISABLE TRANSFER ON UNCORRECTABLE DATA
		;000100	;UBA INITIALIZE
UBA.B7==1B28+BR7LVL*10
UBA.B5==1B28+BR5LVL
UBALVL==1B28+BR7LVL*10+BR5LVL	;PI LVL ASSIGNMENTS
UBA.IR=	763200		;VECTOR REGISTER
UBA.MR=	763101		;MAINTENANCE REGISTER
		;000001	;CHANGE NPR REQUEST
		;000002	;ENABLE NPR WRAP AROUND
;DZ11
DZ.CSR==0		;CONTROL AND STATUS REGISTER
DZ.RBF==2		;READER BUFFER
DZ.LPR==2		;LINE PARAMETER REGISTER
DZ.TCR==4		;TRANSMIT CONTROL REGISTER
DZ.MSR==6		;MODEM STATUS REGISTER
DZ.TDR==6		;TRANSMIT DATA REGISTER
;RJP04
RPCS1==	776700
RPWC==	776702
RPBA==	776704
RPDA==	776706
RPCS2==	776710
RPDS==	776712
RPER1==	776714
RPAS==	776716
RPLA==	776720
RPDB==	776722
RPMR==	776724
RPDT==	776726
RPSN==	776730
RPOF==	776732
RPDC==	776734
RPCC==	776736
RPER2==	776740
RPER3==	776742
RPEC1==	776744
RPEC2==	776746
;INTERPROCESSOR COMMUNICATIONS AREA
;WORD 31 - KEEP ALIVE AND STATUS WORD
FEWSTS=	31
;WORD 32 - KS-10 INPUT WORD
FEWINP=	32
		;BITS 20-27 = 0 NO ACTION
		;BITS 20-27 = 1 CTY CHAR
		;BITS 28-35 = CHAR
;WORD 33 - KS-10 OUTPUT WORD
FEWOUT=	33
		;BITS 20-27 = 0 NO ACTION
		;BITS 20-27 = 1 CTY CHAR
		;BITS 28-35 = CHAR
;WORD 34 - KS-10 KLINIK LINE INPUT WORD
;WORD 35 - KS-10 KLINIK LINE OUTPUT WORD

;FORMAT OF PDP-11 BINARY TAPES
;
;	FRAME	-1	001
;		-2	000
;		-3	BYTE COUNT - LOWER ORDER
;		-4	BYTE COUNT - HIGHER ORDER
;		-5	LOAD ADDRESS - LOWER ORDER
;		-6	LOAD ADDRESS - HIGHER ORDER
;				DATA
;			CHKSUM
;
;	THE BYTE COUNT COUNTS FRAME-1 THROUGH ALL DATA
;	IF THE BYTE COUNT IS EQUAL TO 6 THE LOAD ADDRESS IS THE START ADDRESS
;	UNLESS ODD.
;	IF THE BYTE COUNT IS > 6, DATA WILL BE LOADED INTO MEMORY
;	WHEN CHKSUM IS ADDED TO SUM OF PREVIOUS FRAMES RESULT IS 0
;PDP11 ADDRESSING MODES
;
;	0	Rn	REGISTER
;	1	@Rn	REGISTER DEFERRED
;	2	(Rn)+	AUTO-INCREMENT
;	3	@(Rn)+	AUTO-INCREMENT DEFERRED
;	4	-(Rn)	AUTO-DECREMENT
;	5	@-(Rn)	AUTO-DECREMENT DEFERRED
;	6	X(Rn)	INDEX
;	7	@X(Rn)	INDEX DEFERRED
;
;	27	#X	IMMEDIATE
;	37	@#X	ABSOLUTE
;	67	X	RELATIVE
;	77	@X	RELATIVE DEFERRED
;MACRO TO DEFINE SYMBOLS FOR INSTRUCTIONS
; 1ST ARGUMENT IS VALUE OF INSTRUCTION
; 2ND ARG IS MASK FOR VALUE
; 3RD ARG IS MNEMONIC
; 4TH ARG IS FLAG BITS
; 5TH ARG IS SIMULATION

	DEFINE	INSTRU <
	XLIST
	X	000000,007000,AND,<SMF.IN!SMF.P8>
	X	000000,177777,HALT,<SMF.IN!SMF.11>
	X	000000,177777,R0,<SMF.RG!SMF.11>
	X	000001,177777,R1,<SMF.RG!SMF.11>
	X	000001,177777,WAIT,<SMF.IN!SMF.11>
	X	000002,177777,R2,<SMF.RG!SMF.11>
	X	000002,177777,RTI,<SMF.IN!SMF.11>
	X	000003,177777,BPT,<SMF.IN!SMF.11>
	X	000003,177777,R3,<SMF.RG!SMF.11>
	X	000004,177777,IOT,<SMF.IN!SMF.11>
	X	000004,177777,R4,<SMF.RG!SMF.11>
	X	000005,177777,R5,<SMF.RG!SMF.11>
	X	000005,177777,RESET,<SMF.IN!SMF.11>
	X	000006,177777,RTT,<SMF.IN!SMF.11>
	X	000006,177777,SP,<SMF.RG!SMF.11>
	X	000007,177777,PC,<SMF.RG!SMF.11>
	X	000100,177700,JMP,<SMF.IN!SMF.DD!SMF.11>
	X	000200,177770,RTS,<SMF.IN!SMF.RT!SMF.11>
	X	000230,177770,SPL,<SMF.IN!SMF.PL!SMF.11>
	X	000240,177777,NOP,<SMF.IN!SMF.11>
	X	000241,177777,CLC,<SMF.IN!SMF.11>
	X	000242,177777,CLV,<SMF.IN!SMF.11>
	X	000244,177777,CLZ,<SMF.IN!SMF.11>
	X	000250,177777,CLN,<SMF.IN!SMF.11>
	X	000257,177777,CCC,<SMF.IN!SMF.11>
	X	000261,177777,SEC,<SMF.IN!SMF.11>
	X	000262,177777,SEV,<SMF.IN!SMF.11>
	X	000264,177777,SEZ,<SMF.IN!SMF.11>
	X	000270,177777,SEN,<SMF.IN!SMF.11>
	X	000277,177777,SCC,<SMF.IN!SMF.11>
	X	000300,177700,SWAB,<SMF.IN!SMF.DD!SMF.11>
	X	000400,177400,BR,<SMF.IN!SMF.BR!SMF.11>
	X	001000,177400,BNE,<SMF.IN!SMF.BR!SMF.11>
	X	001000,007000,TAD,<SMF.IN!SMF.P8>
	X	001400,177400,BEQ,<SMF.IN!SMF.BR!SMF.11>
	X	002000,177400,BGE,<SMF.IN!SMF.BR!SMF.11>
	X	002000,007000,ISZ,<SMF.IN!SMF.P8>
	X	002400,177400,BLT,<SMF.IN!SMF.BR!SMF.11>
	X	003000,177400,BGT,<SMF.IN!SMF.BR!SMF.11>
	X	003000,007000,DCA,<SMF.IN!SMF.P8>
	X	003400,177400,BLE,<SMF.IN!SMF.BR!SMF.11>
	X	004000,177000,JSR,<SMF.IN!SMF.DD!SMF.JS!SMF.11>
	X	004000,007000,JMS,<SMF.IN!SMF.P8>
	X	005000,177700,CLR,<SMF.IN!SMF.DD!SMF.11>
	X	005000,007000,JMP,<SMF.IN!SMF.P8>
	X	005100,177700,COM,<SMF.IN!SMF.DD!SMF.11>
	X	005200,177700,INC,<SMF.IN!SMF.DD!SMF.11>
	X	005300,177700,DEC,<SMF.IN!SMF.DD!SMF.11>
	X	005400,177700,NEG,<SMF.IN!SMF.DD!SMF.11>
	X	005500,177700,ADC,<SMF.IN!SMF.DD!SMF.11>
	X	005600,177700,SBC,<SMF.IN!SMF.DD!SMF.11>
	X	005700,177700,TST,<SMF.IN!SMF.DD!SMF.11>
	X	006000,177700,ROR,<SMF.IN!SMF.DD!SMF.11>
	X	006000,007000,IOT,<SMF.IN!SMF.P8>
	X	006100,177700,ROL,<SMF.IN!SMF.DD!SMF.11>
	X	006200,177700,ASR,<SMF.IN!SMF.DD!SMF.11>
	X	006300,177700,ASL,<SMF.IN!SMF.DD!SMF.11>
	X	006400,177700,MARK,<SMF.IN!SMF.MK!SMF.11>
	X	006700,177700,SXT,<SMF.IN!SMF.DD!SMF.11>
	X	007000,007777,NOP,<SMF.IN!SMF.P8>
	X	007001,007401,IAC,<SMF.IN!SMF.P8>
	X	007002,007416,BSW,<SMF.IN!SMF.P8>
	X	007004,007406,RAL,<SMF.IN!SMF.P8>
	X	007006,007406,RTL,<SMF.IN!SMF.P8>
	X	007010,007412,RAR,<SMF.IN!SMF.P8>
	X	007012,007412,RTR,<SMF.IN!SMF.P8>
	X	007020,007420,CML,<SMF.IN!SMF.P8>
	X	007040,007440,CMA,<SMF.IN!SMF.P8>
	X	007100,007500,CLL,<SMF.IN!SMF.P8>
	X	007200,007600,CLA,<SMF.IN!SMF.P8>
	X	007400,007777,NOP,<SMF.IN!SMF.P8>
	X	007401,007777,NOP,<SMF.IN!SMF.P8>
	X	007402,007403,HLT,<SMF.IN!SMF.P8>
	X	007404,007405,OSR,<SMF.IN!SMF.P8>
	X	007410,007571,SKP,<SMF.IN!SMF.P8>
	X	007420,007431,SNL,<SMF.IN!SMF.P8>
	X	007421,007521,MQL,<SMF.IN!SMF.P8>
	X	007430,007431,SZL,<SMF.IN!SMF.P8>
	X	007440,007451,SZA,<SMF.IN!SMF.P8>
	X	007450,007451,SNA,<SMF.IN!SMF.P8>
	X	007500,007511,SMA,<SMF.IN!SMF.P8>
	X	007501,007521,MQA,<SMF.IN!SMF.P8>
	X	007510,007511,SPA,<SMF.IN!SMF.P8>
	X	007521,007521,SWP,<SMF.IN!SMF.P8>
	X	007600,007601,CLA,<SMF.IN!SMF.P8>
	X	007601,007601,CLA,<SMF.IN!SMF.P8>
	X	010000,170000,MOV,<SMF.IN!SMF.SS!SMF.11>
	X	020000,170000,CMP,<SMF.IN!SMF.SS!SMF.11>
	X	030000,170000,BIT,<SMF.IN!SMF.SS!SMF.11>
	X	040000,170000,BIC,<SMF.IN!SMF.SS!SMF.11>
	X	050000,170000,BIS,<SMF.IN!SMF.SS!SMF.11>
	X	060000,170000,ADD,<SMF.IN!SMF.SS!SMF.11>
	X	070000,177000,MUL,<SMF.IN!SMF.EI!SMF.11>
	X	071000,177000,DIV,<SMF.IN!SMF.EI!SMF.11>
	X	072000,177000,ASH,<SMF.IN!SMF.EI!SMF.11>
	X	073000,177000,ASHC,<SMF.IN!SMF.EI!SMF.11>
	X	074000,177000,XOR,<SMF.IN!SMF.JS!SMF.DD!SMF.11>
	X	075000,177770,FADD,<SMF.IN!SMF.RT!SMF.11>
	X	075010,177770,FSUB,<SMF.IN!SMF.RT!SMF.11>
	X	075020,177770,FMUL,<SMF.IN!SMF.RT!SMF.11>
	X	075030,177770,FDIV,<SMF.IN!SMF.RT!SMF.11>
	X	077000,177000,SOB,<SMF.IN!SMF.SB!SMF.11>
	X	100000,177400,BPL,<SMF.IN!SMF.BR!SMF.11>
	X	100400,177400,BMI,<SMF.IN!SMF.BR!SMF.11>
	X	101000,177400,BHI,<SMF.IN!SMF.BR!SMF.11>
	X	101400,177400,BLOS,<SMF.IN!SMF.BR!SMF.11>
	X	102000,177400,BVC,<SMF.IN!SMF.BR!SMF.11>
	X	102400,177400,BVS,<SMF.IN!SMF.BR!SMF.11>
	X	103000,177400,BCC,<SMF.IN!SMF.BR!SMF.11>
	X	103000,177400,BHIS,<SMF.IN!SMF.BR!SMF.11>
	X	103400,177400,BCS,<SMF.IN!SMF.BR!SMF.11>
	X	103400,177400,BLO,<SMF.IN!SMF.BR!SMF.11>
	X	104000,177400,EMT,<SMF.IN!SMF.EM!SMF.11>
	X	104400,177400,TRAP,<SMF.IN!SMF.EM!SMF.11>
	X	105000,177700,CLRB,<SMF.IN!SMF.DD!SMF.BY!SMF.11>
	X	105100,177700,COMB,<SMF.IN!SMF.DD!SMF.BY!SMF.11>
	X	105200,177700,INCB,<SMF.IN!SMF.DD!SMF.BY!SMF.11>
	X	105300,177700,DECB,<SMF.IN!SMF.DD!SMF.BY!SMF.11>
	X	105400,177700,NEGB,<SMF.IN!SMF.DD!SMF.BY!SMF.11>
	X	105500,177700,ADCB,<SMF.IN!SMF.DD!SMF.BY!SMF.11>
	X	105600,177700,SBCB,<SMF.IN!SMF.DD!SMF.BY!SMF.11>
	X	105700,177700,TSTB,<SMF.IN!SMF.DD!SMF.BY!SMF.11>
	X	106000,177700,RORB,<SMF.IN!SMF.DD!SMF.BY!SMF.11>
	X	106100,177700,ROLB,<SMF.IN!SMF.DD!SMF.BY!SMF.11>
	X	106200,177700,ASRB,<SMF.IN!SMF.DD!SMF.BY!SMF.11>
	X	106300,177700,ASLB,<SMF.IN!SMF.DD!SMF.BY!SMF.11>
	X	110000,170000,MOVB,<SMF.IN!SMF.SS!SMF.BY!SMF.11>
	X	120000,170000,CMPB,<SMF.IN!SMF.SS!SMF.BY!SMF.11>
	X	130000,170000,BITB,<SMF.IN!SMF.SS!SMF.BY!SMF.11>
	X	140000,170000,BICB,<SMF.IN!SMF.SS!SMF.BY!SMF.11>
	X	150000,170000,BISB,<SMF.IN!SMF.SS!SMF.BY!SMF.11>
	X	160000,170000,SUB,<SMF.IN!SMF.SS!SMF.11>
	X	163000,177777,UBAMAP,<SMF.11>
	X	163100,177777,UBA.SR,<SMF.11>
	;X	163200,177777,UBA.VC,<SMF.11>
	X	163300,177777,UBA.MR,<SMF.11>
	X	177570,177777,SW,<SMF.11>
	X	177776,177777,PS,<SMF.11>
	LIST	;TURN LISTINGS BACK ON
>;DEFINE INSTRU
	SUBTTL	INITIALIZATION

DDT11:	NOP
	JSR	INIALL		;GET PROCESSOR FLAGS, AND RESET WORLD
	CALL	IDTYPE		;IDENTIFY OURSELF
	CALL	CRLTYP		;END WITH A FLOURISH

	MOVE	T1,[0,,0]	;DEFAULT OUTPUT MODE IS SYMBOLIC
	MOVEM	T1,O.MODE
	SETZM	CACHEL		;HIGHEST ADDR IN CACHE
	SETZM	NODE		;HAVEN'T SPECIFIED NODE YET
	SETZM	CMDCON		;NO COMAND CONFLICTS YET
	SETZM	LINE		;OR LINE ON NODE
	JRST	INI.03
INI.00:	TYPE	<
Respond with file spec and/or switches>
	CLRBFI			;FLUSH TYPEAHEAD
INI.03:	TYPE	<
Input:	>
	SETZ	T1,		;NO DEFAULT FILE NAME
	MOVE	T2,[SIXBIT /LSDBIN/] ;DEFAULT EXTENSION
	MOVE	T3,[SW.DSP,,SW.LST]
	MOVE	T4,[400000,,RDDUMP] ;DEFAULT LAST SWITCH
	CALL	OPNFL0
	JRST	INI.00		;TELL HIM THATS NOT NICE
	JRST	INI.03
INIALL:	Z
	SETZ	0		;ZERO 1ST AC
	MOVEI	17,1		;MAKE BLT POINTER
	BLT	17,17		;CLEAR ALL AC'S
	MOVE	P,[IOWD PDLEN,PDL]
	PUSH	P,INIALL
	SETZM	OHD
	SETZM	CMDFIL
	MOVE	FLG,FLGSAV	;SETUP FLAGS
	TXZ	FLG,F.EXEC!F.TOPN!F.LOCK!F..SIM!F.WENB
	SETZM	MRGFLG
	HRROI	DOT,0
	MOVE	T1,INIALL
	TLNN	T1,010000	;CHECK USER MODE FLAG
	TXO	FLG,F.EXEC	;WE ARE IN EXEC MODE
	CALL	MAPCOR		;SETUP EPT AND UNIBUS MAPPING
	SETZM	UPTIME		;HAVEN'T STARTED THE CLOCK YET
	SETZ T2,
	TXNE FLG,F.EXEC		;IF NOT IN EXEC MODE
	JRST INIAL1
	MOVE T1,[XWD 112,11]	;GET THE MONITOR TYPE
	CALLI T1,41		;A GETTAB IN HIDING
	SETZ T1,		;ALWAYS A 0 IF IT FAILS
	LSH T1,-^D12		;MOVE THE TYPE OVER
	ANDI T1,17		;MASK ANY UNWANTED BITS
	MOVE T2,[T.OTHER	;FREE INDEX
		T.TOP10		;TOPS-10
		T.ITS		;ITS
		T.TENEX		;TENEX
		T.TOP20		;TOPS-20
		T.OTHER
		T.OTHER
		T.OTHER
		T.OTHER
		T.OTHER
		T.OTHER
		T.OTHER
		T.OTHER
		T.OTHER
		T.OTHER
		T.OTHER](T1)	;GET THE TYPE
INIAL1:	TXNE FLG,F.EXEC
	TXO T2,T.EXEC
	MOVEM T2,OSTYPE		;AND SAVE FOR LATER USE
	RESET
	SETZM	INSRUN		;HAVEN'T DONE ANY INSTRCUTIONS YET
	SETZM	WAITIM		;AND HAVEN'T WAITED YET
	GETPPN	T2,		; SEE WHO WE ARE
	JFCL			; BLOODY JACCT BIT
	MOVEM	T2,MYPPN	; SAVE FOR PPN DEFAULTING
	RET
;HERE BECAUSE FILE TO BE READ IS BINARY TAPE
SETBIN:	TXO	FLG,F.FLOP
	MOVEI T1,EX.MEM
	MOVEM T1,ETYPE
	RETSKP


;HERE FOR CORE ARGUMENT
SETCOR:	CALL	DECINP		;GET THE CORE SIZE
	RET
	CAIE	T5,"K"		;UPPERCASE K
	CAIN	T5,"K"+40	;LOWERCASE K ?
	JRST	[IMULI	T1,2000	;CONVERT TO NUMBER OF WORDS
		MOVEI	T5,40	;FAKE BREAK CHAR
		JRST	.+1 ]
	HRRZM	T1,CORARG
	MOVEI T1,EX.MEM
	MOVEM T1,ETYPE
	RETSKP


;HERE TO EFFECT THE /CORE:#
STCOR1:	SKIPN	PDP8F
	SKIPN	T2,CORARG	;WAS THERE A CORE ARGUMENT ?
	RETSKP			;NO SO WER'E DONE
	LSH	T2,1		;CONVERT BYTES TO WORDS
	ADDI	T2,017777	;ROUND TO NEXT 4K WORD BOUNDRY
	ANDI	T2,160000	;MASK TO RIGHT SIZE
	SOS	T2		;NEW MEMLIM IS ONE LESS
	MOVEM	T2,CORARG
	SKIPN	MEMORY		;ANY CORE ASSIGNED YET ?
	JRST	STCOR2		;NONE YET SO GET IT
	CAMG	T2,MEMLIM	;DO WE HAVE ENOUGH YET ?
	JRST	STCOR3		;WE HAVE ENOUGH
STCOR2:	SETZ	T1,
	CALL	PUTFOO		;MAKE SURE WE HAVE THAT LOCATION
STCOR3:	MOVE	T1,CORARG	;GET CORE ARGUMENT
	EXCH	T1,MEMLIM	;WHICH IS NEW MEMLIM
	SUB	T1,MEMLIM	;HOW MANY BYTES TO DELETE
	JUMPE	T1,STCOR9	;IF NONE WER'E DONE
	LSH	T1,-2		;NUMBER OF WORDS TO SHIFT SYMBOL TABLE
	HRL	T2,SYMBEG	;GET BEGINING OF SYMBOL TABLE
	HRR	T2,SYMBEG	;BUILD BLT POINTER
	SUB	T2,T1
	HRRM	T2,SYMBEG
	MOVE	T3,SYMEND
	SUB	T3,T1		;NEW END OF SYMBOL TABLE
	MOVEM	T3,SYMEND
	BLT	T2,(T3)
	HRRZM	T3,.JBFF##
	HRLM	T3,.JBSA##
STCOR9:	SETZM	CORARG		;DONE WITH ARGUMENT
	RETSKP


;HERE BECAUSE FILE TO BE READ IS NETLDR (OR EQUIVALENT) DUMP
SETDMP:	TXZ FLG,F..FOO
	MOVEI T1,EX.MEM
	MOVEM T1,ETYPE
	RETSKP


;HERE TO SET F..FOO FOR /DISASSEMBLY OR /DTELDR
SETFOO:	TXO FLG,F..FOO
	MOVEI T1,EX.MEM
	MOVEM T1,ETYPE
	RETSKP


;HERE IF USERS TYPES /FE:
SET.FE:	MOVE T1,OSTYPE		;GET SYSTEM TYPE
	TXNN T1,T.TOP20!T.TOP10	;SEE IF IT IS ALLOWED
	JRST [	TYPE <
?Illegal FE device when not on TOPS-10/20>
		RET]
	CALL	DECINP		;GET THE FRONTEND #
	JRST [	TYPE <
?Front End number required for the /FE switch>
		RET]
	MOVE	T2,OSTYPE	;GET OPS TYPE
	TXNE	T2,T.TOP10	;IF TOPS-10, DO DIFFERENTLY (BETTER)
	 JRST	[JUMPL	T1,R	;DISALLOW JUNK
		 IDIVI	T1,^D10	;SPLIT CPU/DTE
		 CAIG	T1,5	;IF CPU TOO BIG
		  CAILE	T2,3	;OR DTE TOO BIG
		 RET		;DON'T EVEN TRY
		 HRLI	T2,(T1)	;CPU,,DTE
		 MOVEM	T2,FE.CPU ;SAVE FOR DTE. UUOS
		 SETZM	FE.FED	;START WITH FED # 0
		 SETOM	FENAME	;CONFUSE TOPS-20
		 MOVE	T1,[400K,,OPNF10] ;THIS IS AN ACTION SWITCH
		 MOVEM	T1,LASTSW
		 MOVEI	T1,EX.FE1 ;TOPS-10 20F
		 MOVEM	T1,ETYPE  ;SAVE FOR EXAMINE CODE
		 RETSKP]
	CAIG	T1,^D9		;BE SURE NOT TOO LARGE
	CAIGE	T1,0		;BE SURE POSITIVE
	JRST [	TYPE <
?Number typed for /FE: not in range of 0-9>
		RET]
	SKIPA	T2,[EX.FE0]
SETD62:	MOVX	T2,EX.D62	; set DN62 type FE

SETFET:	MOVEM	T2,ETYPE	; T1/FE number, T2/fe type
	LSH	T1,17
	IOR	T1,[ASCII \FE0:\]
	MOVEM	T1,FENAME	;REMEMBER WE'RE DOING FRONT END STUFF
	MOVE	T1,[400000,,OPENFE]
	MOVEM	T1,LASTSW
	RETSKP

OPENFE:	MOVX	AC1,GJ%SHT!GJ%OLD
	HRROI	AC2,FENAME	;NAME OF  FRONT END
	GTJFN			;GET A JFN FOR THE FRONT END
	ERJMP [	TYPE <
?GTJFN for the FE device failed because:>
		JRST OPNFE9]
	MOVEM	AC1,FE.JFN	;SAVE JFN
	MOVE	AC2,ETYPE	;check which type of FE
	CAIE	AC2,EX.D62
	SKIPA	AC2,[200000,,OF%WR!OF%RD]
	MOVE	AC2,[100000,,OF%WR!OF%RD]	;DN62 uses 8 bit bytes
	OPENF
	ERJMP [	TYPE <
?OPENF for the FE device failed because:>
		JRST OPNFE9]
	MOVEI	AC2,.MODTE	;OPEN DTE
	SETZ	AC3,
	MTOPR
OPNFE8:	SETZM	MEMORY		;NOT USING MEMORY
	JRST	LEVL.0

OPNFE9:	MOVEI	AC1,.PRIOU	;OUTPUT ON TTY
	HRLOI	AC2,.FHSLF	;FOR OURSELVES
	SETZ	AC3,
	ERSTR
	SETZM	FENAME
	JRST	DDT11		;TRY AGAIN


	;HERE TO GET A FE DEVICE ON TOPS-10

OPNF10:	MOVE	T1,[.DTEGF,,FE.CPU] ;TRY TO GET A FED
	DTE.	T1,		;PLEASE...
	 JRST	[CAIN	T1,DTENF% ;DOESN'T EXIST?
		  JRST	[TYPE	<
? No FE devices available>
			 JRST	DDT11]
		 CAIE	T1,DTEFB% ;THIS ONE BUSY?
		  JRST	DTEERR	;NO, CONFUSED
		 AOS	FE.FED	;TRY NEXT
		 JRST	OPNF10]
	SETOM	FE.JFN		;CONFUSE THE TOPS-20 CODE
	JRST	OPNFE8		;AND GO FINISH UP

;HERE IF USER TYPES /GO
SETGO:	MOVE	T1,[400000,,LEVL.0]
	MOVEM	T1,LASTSW
	MOVEI T1,EX.MEM
	MOVEM T1,ETYPE
	RETSKP


;HERE FOR A /MERGE
SETMRG:	SETOM	MRGFLG#		;WANT TO MERGE OTHER FILES
	MOVEI T1,EX.MEM
	MOVEM T1,ETYPE
	RETSKP


;HERE FOR /PATCH
SETWEN:	TXO	FLG,F.WENB	;ENABLE PATCHING
	RETSKP


;HERE FOR /LINE IN COMMAND LINE
SETLIN:	MOVE T1,OSTYPE
	TXNN T1,T.TOP10
	JRST [	TYPE <
?Illegal /LINE switch when not on TOPS-10>
		RET]
	CALL	SIXIN		;GET LINE ARGUMENT
	JRST [	TYPE <
?Illegal argument for /LINE switch>
		RET]
	CALL	SIXOCT		;CONVERT TO NUMBER
	JRST [	TYPE <
?Illegal value for the /LINE switch>
		RET]
	AOS	T1
	MOVEM	T1,LINE
	MOVEI T1,EX.NOD
	MOVEM T1,ETYPE
	RETSKP


;HERE BECAUSE USER TYPED /PDP11 OR /11
SETP11:	SETZM	PDP8F		;CLEAR PDP8 FLAG
	RETSKP


;HERE BECAUSE USER TYPED /PDP8 OR /8
SETPD8:	SETOM PDP8F
	RETSKP


;HERE BECAUSE USER TYPED /FESYM WITH /SYMBOL
SETFES:	MOVE T1,[SIXBIT /MAPSYM/] ;DEFAULT EXTENSIONS
	MOVEM T1,DEFEXT
	MOVE T1,[400000,,RDSYMA] ;FLAG TO READ IN FE FORMAT
	MOVEM T1,LASTSW
	RETSKP


;HERE FOR A /LA36 IN COMMAND LINE
SETLA3:	SETZM TTYBIT
	RETSKP


;HERE ON A /RELOCATION:VAL SWITCH
SETREL:	CALL SIXIN		;READ VALUE
	JRST [	TYPE <
?Illegal argument for /RELOCATE switch>
		RET]
	PUSH P,T1		;SAVE IF WE NEED IT LATER
	CALL SIXOCT		;CONVERT IT TO AN OCTAL NUMBER
	JRST [	POP P,T1	;GET TYPIN BACK
		CALL SYMFND	;FIND IF WE HAVE A SYMBOL TO MATCH IT
		JRST [	TYPE <
?Unknown symbol as argument to /RELOCATE switch>
			RET]
		HRRZ T1,1(SYM)	;GET THE VALUE FIELD
		MOVEM T1,RELOFF	;SAVE FOR THE READ CODE
		RETSKP]		;RETURN
	MOVEM T1,RELOFF		;SAVE THE NEW OFFSET
	JRST TPOPJ1		;CLEAN STACK, SKIP RETURN


;HERE FOR /NODE IN COMMAND LINE
SETNOD:	MOVE T1,OSTYPE
	TXNN T1,T.TOP10
	JRST [	TYPE <
?Illegal /NODE: when not on TOPS-10>
		RET]
	CALL SIXIN		;GET NODE ARGUMENT
	JRST [	TYPE <
?Illegal argument for the /NODE switch>
		RET]
	CALL SIXOCT		;CONVERT TO NUMBER
	JRST [	TYPE <
?Illegal value for the /NODE switch>
		RET]
	MOVEM T1,NODE		;SAVE NODE NAME
	SETZM FE.JFN		;NOT DOING /FE STUFF
	CALL CLRMEM		;FORGET ANYTHING ALREADY READ
	MOVE T1,[400000,,LEVL.0]
	MOVEM T1,LASTSW
	MOVEI T1,EX.NOD
	MOVEM T1,ETYPE
	RETSKP


;HERE FOR /LOCK
SETLOK:	MOVE T1,OSTYPE
	TXNN T1,T.TOP10
	JRST [	TYPE <
?Illegal /LOCK when not on TOPS-10>
		RET]
	MOVEI T1,LK.LLS!LK.LNE;CODE TO LOCK
	LOCK T1,
	JRST LOCKER		;REPORT ERROR
	TXO FLG,F.LOCK		;REMEMBER WE DID
	RETSKP


;HERE FOR /PORT
SETPRT:	CALL	SIXIN		;GET SIXBIT ARGUMENT
	JRST [	TYPE <
?Illegal argument for the /PORT switch>
		RET]
	CALL	SIXOCT		;CONVERT TO OCTAL
	JRST [	TYPE <
?Illegal value for the /PORT switch>
		RET]
	ANDI	T1,17		;ALLOW FOR 8 DL10 PORTS PLUS 8 DN6X
	HRROM	T1,PORT		;SAVE PORT NUMBER
	MOVE	T2,OSTYPE	; check monitor type
	TXNE	T2,T.TOP20	; if TOPS-20 then have to do FE type io
	JRST	[CALL	CPUTYP	; determine cpu type to dsitinguish DN20,DN22
		 CALL	QUED60	; set up enqueue string
		 ANDI	T1,7	; remove dte offset to get FE number
		 JRST	SETD62]	; now go set type DN62
	MOVE	T1,[400000,,LEVL.0]
	MOVEM	T1,LASTSW
	MOVEI T1,EX.PORT
	MOVEM T1,ETYPE
	RETSKP

CLRMEM:	SKIPN	T1,MEMORY	;DID WE READ INTO MEMORY BEFORE ?
	RETSKP
	HRL	T1,SYMBEG	;BUILD BLT POINTER
	HRRZ	T2,SYMEND
	ADDI	T2,(T1)
	SUB	T2,SYMBEG
	HRRZM	T1,SYMBEG	;NEW BEGINNING OF SYMBOL TABLE
	BLT	T1,(T2)
	MOVE	T1,.JBFF##
	CAMN	T1,SYMEND
	MOVE	T1,T2		;THIS IS NEW .JBFF##
	MOVEM	T2,SYMEND
	HRRZM	T1,.JBFF##
	HRLM	T1,.JBSA##
	CORE	T1,
	JRST	CORERR
	SETZM	MEMORY
	SETOM	MEMLIM
	RETSKP


;HERE FOR A /SYMBOL
SETSYM:	MOVE	T1,[400000,,RDSYMB]
	MOVEM	T1,LASTSW
	MOVE	T1,[SIXBIT \LSTCRF\] ;RESET DEFAULT EXTENSION
	MOVEM	T1,DEFEXT
	SETZM	USETIT		;ALWAYS START AT 0
	CAIE	T5,":"		;GIVEN A BLOCK TO START ON ?
	RETSKP			;NO, ITS OK
	CALL	DECINP		;GET BLOCK TO START READING AT
	JRST [	TYPE <
?Illegal value for the /SYMBOL switch>
		RET]
	HRRZM	T1,USETIT	;REMEMBER WHERE TO START READING
	RETSKP


;HERE FOR A /UBA COMMAND LINE
SETUBA:	TXNN FLG,F.EXEC
	JRST [	TYPE <
?Illegal /UBA switch when not in EXEC mode>
		RET]
	CAIN T5,":"		;WAS BREAK A COLON ?
	CALL DECINP		;GET ADAPTER NUMBER TO USE
	JRST [	TYPE <
?Illegal argument for the /UBA switch>
		RET]
	HRLZ MA,T1		;COPY NEW UBA NUMBER
	TXNE FLG,F.EXEC	;RUNNING EXEC MODE ?
	RDIO T1,UBA.SR(MA)	;SEE IT THERE IS SUCH A UBA
	JRST [	MOVEM	MA,UBACTL ;SAVE IT
		RETSKP]
	TYPE	<
?Illegal value for the /UBA switch>
	RET


;HERE FOR A /VT52 IN COMMAND LINE
SETVTX:	MOVX	T1,TF.RUB	;BIT TO GET RIGHT KIND OF RUBOUTS
	MOVEM	T1,TTYBIT
	RETSKP


;HERE FOR A /READSTB IN THE COMMAND LINE
SETRST:	RETSKP


;HERE FOR A /WRITESTB IN THE COMMAND LINE
SETWST:	RETSKP
	SUBTTL	MAJOR LOOP

;HERE ON A REENTER
RSTART:	NOP
	JSR	INIALL		;DO RESET, ETC.

;HERE AFTER INITIAL DIALOGUE
LEVL.0:	MOVE	P,[IOWD PDLEN,PDL]
	CALL	STCOR1		;HANDLE /CORE:#
	CALL	MAPCOR		;UPDATE MEMORY MAP
	SETZM	OHD
	SETZM	CMDFIL		;NO MORE COMMAND FILE
	CALL	CRLTYP
	SETZM	CMDTKR

LEVEL0:	TXZ	FLG,F.LOPN!F.MASK!F.MOPN!F.CACH!F.WRIT!F.LBKT
	MOVEM	FLG,FLGSAV	;SAVE IN CASE OF REENTER
	HLRS	ORADIX		;RESET OUTPUT RADIX
	HLRS	O.MODE		;RESET CURRENT OUTPUT MODE FROM PERMANENT
	HLRS	BYTCNT		;RESET REPETITION COUNT
LEVEL1:
LEVEL2:	MOVE	P,[IOWD PDLEN,PDL]
	TXZ	FLG,F.SYMB!F.TEXT!F.IOCT!F.IDEC!F.IHEX
	MOVE	T1,[POINT 7,CMDLIN]
	MOVEM	T1,CMDPTR	;SAVE NEW COMMAND PUTTER
	MOVE	STATE,[T2,,STATE0] ;DISPATCH TABLE WHEN IDLE
	MOVE	T1,[POINT 8,DATA]
	SKIPE	PDP8F
	MOVE	T1,[POINT 12,DATA]
	MOVEM	T1,DAT		;POINTER TO DATA AREA
	SETZM	DTFINP
	MOVE	T1,[BYTCNT,,ESCSAV] ;SPECIAL CARE OF THINGS SET
	BLT	T1,ESCSAV+2	; WITH ESCAPE COMMANDS
	SETZM	LFTSAV		;NO PARTIAL X<Y>
LEVEL3:	CALL	GETEXP		;GET AN EXPRESSION
	JRST	COMAND		;CHECK FOR COMMAND FILE
	LDB	T1,CMDPTR	;GET LAST CHARACTER
	CAIE	T1,40		;WAS IT A SPACE ?
	JRST	LEVEL8
	SKIPE	PDP8F		;DOING PDP8 INSTRUCTIONS ?
	JRST	LEVEL6
	TXNE	FLG,F.SYML	;DID WE HAVE A SYMBOL ?
	TLNN	SYM,SMF.IN	;WAS IT AN INSTRUCTION ?
	JRST	LEVEL8
	MOVE	T1,EXPRESS	;GET EXPRESSION
	IDPB	T1,DAT		;SAVE IT
	PUSH	P,DAT		;SAVE POINTER TO OPCODE
	ROT	T1,-^D8
	IDPB	T1,DAT
	CALL	NDTFIN		;SET NEXT DTFINP
	PUSH	P,SYM		;SAVE SYMBOL POINTER
	TLNE	SYM,SMF.EI	;WAS THIS AN EIS INSTRUCTION ?
	JRST	[SETZ	T1,	;ARG FOR LEVEL5
		CALL	LEVEL5
		LDB	T1,CMDPTR ;GET BREAK CHARACTER
		CAIE	T1,","
		JRST	LEVEL7
		MOVE	SYM,(P)	;RESTORE SYMBOL POINTER
		JRST	.+1 ]
	TLNE SYM,SMF.JS!SMF.SB!SMF.EI ;WAS THIS A JSR OR SOB OR EIS ?
	JRST [	CALL GETREG	;GET REGISTER NAME ARGUMENT
		MOVE T3,-1(P)	;GET POINTER TO OPCODE
		LDB T2,T3	;GET LOW ORDER BITS
		ILDB T3,T3	;GET HIGH ORDER BITS
		DPB T3,[POINT 8,T2,27]
		DPB T1,[POINT 3,T2,29]
		MOVE T3,-1(P)	;GET POINTER TO OPCODE AGAIN
		DPB T2,T3	;RESTORE LOW ORDER BITS
		LSH T2,-^D8
		IDPB T2,T3
		MOVE SYM,(P)	;RESTORE SYM POINTER
		TLNE SYM,SMF.EI ;IF EIS DON'T CHECK ","
		JRST .+1
		LDB T1,CMDPTR
		CAIE T1,","	;PROPER BREAK ?
		JRST LEVEL7
		JRST .+1]
	MOVEI	T1,^D6		;ARG FOR LEVEL5
	TLNE	SYM,SMF.SS
	JRST	[CALL	LEVEL5
		LDB	T1,CMDPTR;GET BREAK CHARACTER
		CAIE	T1,","
		JRST	LEVEL7
		MOVE	SYM,(P)	;RELOAD POINTER TO SYMBOL
		JRST	.+1]
	SETZ	T1,		;ARG FOR LEVEL5
	TLNE	SYM,SMF.DD!SMF.SS
	CALL	LEVEL5
	MOVE	SYM,(P)		;GET FLAGS AGAIN
	TLNE	SYM,SMF.BR	;WAS THIS A BRANCH TYPE INSTRUCTION ?
	JRST	[CALL	GETEXP	;GET BRANCH ADR
		JRST	ILLCHR
		MOVE	T1,EXPRESS;GET DESTINATION ADR
		HRROM	T1,LSTIAD;SAVE LAST ADR TYPED IN
		SUB	T1,DTFINP
		ASH	T1,-1
		SOS	T1
		ANDI	T1,177777
		CAIL	T1,200
		CAIL	T1,177600
		TRZA	T1,777400
		JRST	ILLCHR
		DPB	T1,-1(P)
		JRST	LEVEL7 ]
	TLNE	SYM,SMF.MK	;WAS THIS A MARK ?
	JRST	[CALL	GETEXP		;GET ARGUMENT
		JRST	ILLCHR
		MOVE	T1,EXPRESS
		LDB	T2,-1(P)	;GET LOW ORDER BITS OF OPCODE
		DPB	T1,[POINT 6,T2,35]
		DPB	T2,-1(P)	;PUT OPCODE BACK IN DATA
		JRST	LEVEL7 ]
	TLNE	SYM,SMF.EM	;EMT TYPE INSTRUCTION ?
	JRST	[CALL	GETEXP		;GET OPERAND
		JRST	ILLCHR
		MOVE	T1,EXPRESS	;GET OPERAND
		DPB	T1,-1(P)	;PUT OPERAND IN INSTRUCTION
		JRST	LEVEL7 ]
	TLNE	SYM,SMF.RT	;RTS TYPE INSTRUCTION ?
	JRST	[CALL	GETREG		;GET REGISTER NAME
		LDB	T2,-1(P)	;GET LOW ORDER BITS OF OPCODE
		DPB	T1,[POINT 3,T2,35]
		DPB	T2,-1(P)
		JRST	LEVEL7 ]
	TLNE	SYM,SMF.PL	;WAS THIS A SPL TYPE ?
	JRST	[CALL	GETEXP		;GET ARGUMENT
		JRST	ILLCHR
		MOVE	T1,EXPRESS
		LDB	T2,-1(P)	;GET LOWORDER BITS OF OPCODE
		DPB	T1,[POINT 3,T2,35]
		DPB	T2,-1(P)
		JRST	LEVEL7 ]
	TLNE	SYM,SMF.SB	;WAS THIS A SOB ?
	JRST	[CALL	GETEXP		;GET ADDRESS
		JRST	ILLCHR
		MOVE	T1,EXPRESS
		HRROM	T1,LSTIAD	;IN CASE ENDS WITH A TAB
		HRRZ	T2,DTFINP
		SUBI	T2,-2(T1)
		ANDI	T2,177777
		LSH	T2,-1
		CAIL	T2,100
		JRST	ILLCHR		;OUT OF RANGE
		LDB	T1,-1(P)	;GET LOW ORDER BITS OF OPCODE
		DPB	T2,[POINT 6,T1,35]
		DPB	T1,-1(P)	;RESTORE
		JRST	LEVEL7 ]
LEVEL7:	POP	P,SYM
	POP	P,T1
	JRST	LEVEL9
LEVEL6:	JRST	LEVEL9

LEVEL8:	TXNN	FLG,F.GEXP	;DID WE GET ANYTHING ?
	JRST	LEVEL9		;NO
	MOVE	T1,EXPRESS
	HRLI	T1,400000	;ASSUME REGISTER
	TXNE	FLG,F.SYML	;WAS THERE A SYMBOL IN EXPRESSION ?
	TLNN	SYM,SMF.RG	;WAS THAT A REGISTER NAME ?
	HRROS	T1		;MEMORY ADR
	MOVEM	T1,LSTIAD	;SAVE LAST ADR TYPED IN
	IDPB	T1,DAT
	LSH	T1,-^D8
	IDPB	T1,DAT
	CALL	NDTFIN		;ADVANCE DTFINP
LEVEL9:	MOVE	T4,[POINT 8,DATA]	;POINTER TO DATA
	SKIPE	PDP8F
	HRLI	T4,(POINT 12)
	LDB	T1,CMDPTR	;GET BREAK CHARACTER
	ROT	T1,-1
	TLNE	T1,400000
	SKIPA	T2,STATEB(T1)
	HLRZ	T2,STATEB(T1)
	JRST	(T2)		;DISPATCH ON BREAK CHARACTER
;HERE IF FIRST GETEXP GIVES ERROR RETURN

COMAND:	LDB	T1,[POINT 6,SYMBOL,5]	;GET FIRST CHAR OF SYMBOL
	CAIE	T1,'  %'
	JRST	LEVEL2		;PUNT
	;SKIPN	CMDFIL
	;  JRST	ILLCHR
	MOVE	T1,SYMBOL	;GET SYMBOL
	CAMN	T1,[SIXBIT \%GOTO\]
	JRST	%GOTO
	CAMN	T1,[SIXBIT \%IF\]
	JRST	%IF
	JRST	ILLCHR

;HERE IF DOING "%GOTO"
%GOTO:	CALL	SIXIN		;FIND WHERE TO GO
	JRST	ILLCHR
%GOTO3:	MOVEM	T1,SYMBOL	;REMEMBER WHERE TO GO
	CALL	SYMFND		;SEE IF WE KNOW IT
	JRST	[CALL	FNDTAG
		JRST	ILLCHR
		JRST	.+1 ]
	SKIPE	CSECHO		;ECHOING COMMAND FILE ?
	JRST	%GOTO5		;NO
	CALL	CRLTYP		;BEGIN WITH A FLOURISH
	MOVE	T1,(SYM)	;GET TAG NAME
	CALL	SIXTYP
	CALL	COLTYP		;END WITH A ":"
%GOTO5:	MOVE	T1,1(SYM)	;GET VALUE
	MOVEM	T1,CMDCNT	;WHERE WE WILL BE
	CALL	FILPOS		;POSITION FILE
	JRST	ILLCHR
	JRST	LEVEL2
;HERE TO SEARCH THROUGH REST OF FILE TO FIND TAG

FNDTAG:	HRROS	CSECHO		;SUPPRESS ECHO WHILE SEARCHING
	CALL	SIXIN		;GET NEXT SIXBIT WORD
	JRST	FNDTG8
	CAIE	T5,":"		;WAS THAT A TAG DEFINITION ?
	JRST	FNDTG8		;NO
	LDB	T2,[POINT 6,T1,5]	;DID IT START WITH A % ?
	CAIE	T2,'  %'
	JRST	FNDTG8
	MOVE	T2,CMDCNT	;VALUE OF TAG
	MOVSI	T3,SMF.SU	;SUPPRESSED
	SETZM	T4		;MISC
	CALL	ADDSYM		;ADD IT TO OUR TABLE
	MOVE	T1,(SYM)	;GET SYMBOL
	CAME	T1,SYMBOL	;WAS THIS WHAT WE WANTED ?
	JRST	FNDTG8		;NO SO KEEP LOOKING
	HRRZS	CSECHO		;TURN ECHOING BACK ON
	RETSKP

FNDTG8:	SKIPE	CMDFIL		;DID WE HIT END OF FILE ?
	JRST	FNDTAG		;NO SO KEEP LOOKING
	HRRZS	CSECHO		;TURN ECHO BACK ON
	RET
;HERE IF DOING A %IF COMMAND
%IF:	CALL	SIXIN		;GET CONDITION
	JRST	ILLCHR		;LOSE
	SETZ	T3,
%IF..3:	SKIPN	%IFLST(T3)
	JRST	ILLCHR		;LOSE CAUSE CAN'T FIND THAT TYPE
	CAME	T1,%IFLST(T3)	;FIND IT ?
	AOJA	T3,%IF..3
	JRST	@%IFDSP(T3)	;DISPATCH ON TYPE OF CONDITION

;HERE FOR "%IF DEF" OR "IF DF"
%IFDEF:	CALL	SIXIN		;GET WHAT MIGHT BE DEFINED
	JRST	ILLCHR		;LOSE CAUSE END OF FILE
	CALL	SYMFND		;GO SEE IF WE CAN FIND IT
	JRST	%IFNOT		;NOT DEFINE SO DON'T DO IT
	JRST	%IFTRUE		;FOUND IT

;HERE FOR "%IF ERR"
%IFERR:	TXZN	FLG,F.CERR
	JRST	%IFNOT		;DON'T DO IT
	JRST	%IFTRU		;DO IT

;HERE FOR "%IF NDF"
%IFNDF:	CALL	SIXIN		;GET SYMBOL TO CHECK
	JRST	ILLCHR		;LOSE
	CALL	SYMFND		;SEE IF WE CAN FIND IT
	JRST	%IFTRUE		;WHAT HE WAS LOOKING FOR
	JRST	%IFNOT
;HERE FOR "IF EQ"
%IF.EQ:	MOVE	T1,[SKIPE T1]
	JRST	%IFEXP

;HERE FOR "%IF G" OR "%IF GT"
%IF.GT:	MOVE	T1,[SKIPG T1]
	JRST	%IFEXP

;HERE FOR "%IF GE"
%IF.GE:	MOVE	T1,[SKIPGE T1]
	JRST	%IFEXP

;HERE FOR "%IF NE" OR "%IF N"
%IF.NE:	MOVE	T1,[SKIPN T1]
	JRST	%IFEXP

;HERE FOR "%IF L" OR "%IF LT"
%IF.LT:	MOVE	T1,[SKIPL T1]
	JRST	%IFEXP

;HERE FOR "%IF LE"
%IF.LE:	MOVE	T1,[SKIPLE T1]
	JRST	%IFEXP
%IFEXP:	PUSH	P,T1		;SAVE TEST
	CALL	GETEXP		;GET EXPRESSION TO EVALUATE
	JRST	ILLCHR		;LOSE CAUSE EPRESSION NOT HERE
	TRNE	T1,100000	;IS THIS NEGATIVE ?
	ORCMI	T1,077777	;EXTEND SIGN
	POP	P,T2		;GET TEST
	XCT	T2
	JRST	%IFNOT		;NOT TRUE
%IFTRU:	CALL	SIXIN
	JRST	ILLCHR		;MUST BE END OF FILE
	SETZ	T2,
	ROTC	T1,6
	CAIE	T2,'  %'
	ROTC	T1,-6
	MOVEI	T2,'  %'
	ROTC	T1,-6
	JRST	%GOTO3		;BRANCH TO THAT TAG

;HERE BECAUSE CONDITION NOT TRUE
%IFNOT:	CALL	SIXIN
	JRST	ILLCHR
	JRST	LEVEL2		;ON TO OTHER THINGS
DEFINE	NAMES <
	X	DEF,%IFDEF
	X	DF,%IFDEF
	X	E,%IF.EQ
	X	EQ,%IF.EQ
	X	ERR,%IFERR
	X	G,%IF.GT
	X	GE,%IF.GE
	X	GT,%IF.GT
	X	N,%IF.NE
	X	NDF,%IFNDF
	X	NE,%IF.NE
	X	L,%IF.LT
	X	LE,%IF.LE
	X	LT,%IF.LT
>
	DEFINE	X (A,B),< SIXBIT \A\ >
%IFLST:	NAMES
	Z
	DEFINE	X (A,B),< EXP B >
%IFDSP:	NAMES
;HERE TO DO SS OR DD FIELD
LEVEL5:	PUSH	P,T1
	CALL	GETOPR		;GET OPERAND
	JRST	[POP	P,T1		;CLEAN OFF STACK
		POP	P,T1		;POP OFF RETURN
		JRST	LEVEL2 ]
	LDB	T3,[POINT 6,T1,17]	;GET MODE
	CAIE	T3,27		;IMMEDIATE ?
	CAIN	T3,37		;OR ABSOLUTE ?
	JRST	LEVEL4
	CAIL	T3,60
LEVEL4:	JRST	[IDPB	T1,DAT
		LSH	T1,-^D8
		IDPB	T1,DAT
		MOVEI	T1,2
		ADDM	T1,DTFINP
		JRST	.+1 ]
	POP	P,T1		;GET POSITION
	LSH	T3,(T1)
	MOVE	T2,-2(P)	;GET POINTER TO OPCODE
	LDB	T1,T2		;GET LOW ORDER BITS
	ILDB	T2,T2		;GET HIGH ORDER BITS
	DPB	T2,[POINT 8,T1,27]
	TRO	T1,(T3)		;SET SS OR DD MODE
	MOVE	T2,-2(P)	;GET POINTER TO OPCODE
	DPB	T1,T2		;SAVE LOW ORDER BITS
	LSH	T1,-^D8
	IDPB	T1,T2		;SAVE HIGH ORDER BITS
	RET
;HERE TO GET AN OPERAND
; CALL	CALL GETOPR
;	LOSE RETURN
;	WIN	WITH T1/ MODE,,ADR
GETOPR:	TXZ	FLG,F.HASH!F.PERC!F.LPAR
	MOVSI	AC1,400000		;BUILD MODE HERE
GETOP0:	CALL	GETEXP
	RET
	LDB	T1,CMDPTR		;GET BREAK CHAR
	CAIN T1,"@"
	JRST [	TLON AC1,10		;BIT FOR INDIRECT
		TXNE FLG,F.GEXP
		JRST ILLCHR
		JRST GETOP0]
	CAIN T1,"#"
	JRST [	TXON FLG,F.HASH
		TXNE FLG,F.GEXP
		JRST ILLCHR
		JRST GETOP0]
	CAIN	T1,"-"			;IS THIS AUTO DECREMENT ?
	JRST	[TLON	AC1,40		;FLAG AUTO DECREMENT
		TXNE	FLG,F.GEXP	;WAS THERE ANY DATA ?
		JRST	ILLCHR
		CALL	GETCHR		;GET THE (
		IDPB	T1,CMDPTR
		CAIE	T1,"("
		JRST	ILLCHR
		JRST	GETOP5 ]
	CAIN	T1,"("
	JRST	[TXOE	FLG,F.LPAR
		JRST	ILLCHR
		HRR	AC1,EXPRESS	;IN CASE INDEXED
		TLNN	AC1,10		;HAVE A @ ALSO ?
		TXNE	FLG,F.GEXP	;WAS IT INDEXED ?
		TLO	AC1,60		;REMEMBER WAS INDEXED
		JRST	GETOP5 ]
	TXNN	FLG,F.GEXP	;DID WE GET SOMETHING ?
	JRST	ILLCHR
	HRR	AC1,EXPRESS	;GET EXPRESSION
	TXNE	FLG,F.SREG
	JRST	[DPB	AC1,[POINT 3,AC1,17]
		JRST	GETOP8 ]
	TXNE	FLG,F.HASH	;WAS THAT IMMEDIATE ?
	JRST	[TLO	AC1,27		;SET IMMEDIATE OR ABSOLUTE
		JRST	GETOP8 ]
	TLO	AC1,67
	HRRZI	T1,-4(AC1)
	SUB	T1,DTFINP
	ANDI	T1,177777
	HRROM	AC1,LSTIAD	;IN CASE ENDS WITH AN HT
	HRR	AC1,T1
	JRST	GETOP9
;HERE TO GET THE REGISTER NAME IN OPERAND SPECIFICATION
GETOP5:	CALL	GETREG		;GET REGISTER NAME
	DPB	T1,[POINT 3,AC1,17]	;PUT REGISTER NAME IN MODE
	LDB	T1,CMDPTR	;GET BREAK CHARACTER
	CAIE	T1,")"
	JRST	ILLCHR
GETOP6:	CALL	GETCHR		;GET NEXT CHARACTER
	IDPB	T1,CMDPTR
	CAIN	T1,"+"		;WAS THAT AUTO INCREMENT ?
	JRST	[TLON	AC1,20		;ALREADY SEEN "+"
		TLNE	AC1,40
		JRST	ILLCHR
		JRST	GETOP6 ]
	TLNN	AC1,70
	TLO	AC1,10
GETOP8:	MOVEM	T1,LSTIAD	;LAST ADDRESS INPUT
GETOP9:	MOVE	T1,AC1		;PUT RESULT IN RIGHT REG
	RETSKP

;HERE TO GET A REGISTER ARGUMENT
GETREG:	CALL	GETEXP		;GET REGISTER NAME
	JRST	ILLCHR
	TXNN	FLG,F.SREG
	JRST	ILLCHR
	MOVE	T1,EXPRESS
	HRLI	T1,400000
	MOVEM	T1,LSTIAD	;LAST ADDRESS INPUT
	RET
;HERE TO GET AN EXPRESSION
; CALL	CALL	GETEXP
;	LOSE RETURN
;	WIN RETURN	EXPRESSION IN T1, AND FLAGS SET
GETEXP:	SETZM	EXPRES		;ACCUMULATED EXPRESSION
GTEXP1:	TXZ	FLG,F..ESC!F..SIM!F.GEXP!F.SYML!F.SYMB!F.TEXT!F.IOCT!F.IDEC!F.IHEX!F.SREG!F.FELE
	SETZM	INPOPR		;CLEAR INPUT OPERATOR
	SETZM	REMAIN		;REMAINDER OF LAST DIVISION
	SETZM	OCTIN#
	SETZM	DECIN#
	SETZM	HEXIN#
	SETZM	SYMBOL
	MOVE	T1,[POINT 6,SYMBOL]
	MOVEM	T1,SYMPTR
GTEXP2:	CALL	GETCHR		;GET FIRST CHARACTER
	CAIN	T1," "		;WAS IT A BLANK ?
	JRST	GTEXP2		;YES SO FLUSH IT
	CAIA

LOOP:	CALL	GETCHR		;GET A COMMAND CHAR
	IDPB	T1,CMDPTR	;REMEMBER CHAR IN CASE NEED TO RESCAN
LOOP1:	HRRZ	T2,T1
	LSH	T2,-1
	TRNE	T1,1
	SKIPA	T2,@STATE
	HLRZ	T2,@STATE
	JRST	(T2)		;DISPATCH ON CHARACTER
;HERE WHEN ASSEMBLING NUMBER AND FIND A PERIOD
ASSPER:	TXNN	FLG,F.IDEC!F.IOCT
	JRST	ASSYMB
	TXO	FLG,F.IDEC
	TXZ	FLG,F.IOCT!F.IHEX
	JRST	ASYMB2
;HERE WHEN NUMBER MUST BE DECIMAL
ASSDEC:	TXO	FLG,F.IDEC
	TXZ	FLG,F.IOCT

;HERE WHEN ASSEMBLING A OCTAL, DECIMAL OR HEX NUMBER
ASSNUM:	TXNN	FLG,F.IDEC!F.IHEX
	TXO	FLG,F.IOCT
	MOVE	T2,OCTIN
	LSH	T2,3
	ADDI	T2,-60(T1)
	MOVEM	T2,OCTIN
	MOVE	T2,DECIN
	IMULI	T2,^D10
	ADDI	T2,-60(T1)
	MOVEM	T2,DECIN
	MOVE	T2,HEXIN
	LSH	T2,4
	ADDI	T2,-60(T1)
	MOVEM	T2,HEXIN
	JRST	ASYMB2

;HERE WHEN ENCOUNTER A PERCENT SIGN - POSSIBLE TAG OR REG NAME
ASSPRC:	TXNN	FLG,F.FELE	;HAVE WE DONE FIRST ELEMENT OF EXPRESSION ?
	MOVE	T2,SYMPTR	;GET POINTER TO SYMBOL
	CAME	T2,[POINT 6,SYMBOL]	;STARTED SYMBOL YET ?
	JRST	ACCUM		;CAN'T HAVE THIS IN MIDDLE !

;HERE WHEN ASSEMBLING A SYMBOL
ASSYMB:	TXO	FLG,F.SYMB
	TXZ	FLG,F.IDEC!F.IOCT!F.IHEX

ASYMB2:	TXO	FLG,F.GEXP	;GOT SOMETHING
	CAIL	T1,40+"A"	;CHECK FOR LOWER CASE
	CAILE	T1,40+"Z"
	SUBI	T1,40		;CONVERT CHAR TO SIXBIT
	MOVE	T2,SYMPTR	;GET POINTER TO SYMBOL
	CAME	T2,[POINT 6,SYMBOL,35]
	IDPB	T1,SYMPTR	;ADD CHAR TO SYMBOL
	JRST	LOOP
;HERE IF END EXPRESSION WITH A SPACE
EXPSPC:	TXNN	FLG,F.FELE	;IS THIS FIRST ELEMENT OF EXPRESSION ?
	TXNN	FLG,F.SYMB	;EVALUATING A SYMBOL ?
	JRST	EXPLUS		;AFTER FIRST SUBEXPRESSION SAME AS PLUS
	CALL	EVLSYM		;FIND WHAT SYMBOL IS
	RET
	TLNN	SYM,SMF.IN	;WAS THAT AN INSTRUCTION
	JRST	EXPLUS		;NO SO SAME AS PLUS
	MOVE	T1,1(SYM)	;GET VALUE
	HRRZM	T1,EXPRESS
	RETSKP

;HERE IF END EXPRESSION WITH A PLUS
EXPLUS:	TDZA	T1,T1		;CODE FOR NEXT TIME IS 0

EXPMIN:	MOVEI	T1,1
	JRST	EXP.DO

EXPMUL:	MOVEI	T1,2
	JRST	EXP.DO

EXPDIV:	MOVEI	T1,3
	JRST	EXP.DO

EXPIOR:	MOVEI	T1,4
	JRST	EXP.DO

EXPAND:	MOVEI	T1,5
	JRST	EXP.DO

EXPXOR:	MOVEI	T1,6
EXP.DO:	TXO	FLG,F.FELE	;HAVE SEEN FIRST ELEMENT
	MOVE	T2,PRECED(T1)	;GET PRECEDENCE OF NEW OPERATOR
	MOVE	T3,INPOPR	;PREVIOUS OPERATOR
	MOVE	T3,PRECED(T3)	;GET PRECEDENCE OF OLD OPERATOR
	CAMG	T2,T3
	JRST	EXPDO5
	PUSH	P,EXPRESS	;SAVE PARTIAL EXPRESSION SO FAR
	PUSH	P,INPOPR	;AND PREVIOUS OPERATOR
	SETZM	EXPRESS		;INITIALIZE EXPRESSION
	SETZM	INPOPR
	PUSHJ	P,EXPDO5	;DO NEXT PART OF EXPRESSION
	SOS	-2(P)		;UNSKIP RETURN FROM ACCUM3
	POP	P,INPOPR	;PREVIOUS OPERATION
	MOVE	T2,EXPRESS	;LATEST ACCUMULATION
	POP	P,EXPRESS	;PREVIOUS ACCUMULATION
	JRST	ACCUM3
EXPDO5:	PUSH	P,T1		;SAVE CODE FOR NEXT TIME
	CALL	ACCUM		;ACCUMULATE EXPRESSION
	JRST	TPOPJ		;CLEAN OFF STACK THEN RETURN
	POP	P,INPOPR	;NEXT INPUT OPERATION
	JRST	LOOP		;THEN DONE
;HERE WHEN USER TYPES A <CONTROL F> - FILL FIELD

CNTRLF:	SKIPN	T1,SYMBOL	;ARE WE BUILDING A SYMBOL ?
	JRST	ILLCHR		;DING HIM
	MOVEI	T1,[BYTE (7)10,40,10,10,40,10,0]	;BACKUP OVER ^F
	MOVE	T2,TTYBIT	;GET TTY BITS
	TXNE	T2,TF.RUB	;VIDEO TERMINAL ?
	CALL	TYPSTR		;YES SO CLEAN SCREEN
	PUSH	P,T4
	PUSH	P,T5
	SETOM	T5		;ESTABLISH COUNTER
	SETZM	T4		;ESTABLISH MATCH
	CALL	MATCH		;TRY TO FIND PARTIAL MATCH
	JUMPE	SYM,CNTLF5
	AOSN	T5
	MOVE	T4,(SYM)	;GET MATCH
	MOVE	T1,(SYM)	;GET NEW MATCH
	SKIPA	T2,[EXP -1]	;BUILD MASK
CNTLF3:	LSH	T2,6		;SHRINK MASK
	AND	T1,T2		;MASK NEW MATCH
	AND	T4,T2		;MASK PREVIOUS MATCH
	CAME	T1,T4		;MATCH LAST MATCH ?
	JRST	CNTLF3
	RET
CNTLF5:	JUMPE	T4,CNTLF8	;CHECK FOR NO MATCHES
	XOR	T4,SYMBOL	;LEAVE ONLY NEW CHARS
	JUMPE	T4,CNTLF7
CNTLF2:	LSH	T4,6
	TLNN	T4,770000	;SHIFTED FAR ENOUGH ?
	JRST	CNTLF2
CNTLF6:	SETZ	T3,
	LSHC	T3,6
	MOVEI	T1,40(T3)
	IDPB	T1,CMDPTR
	CALL	TYPCHR
	JUMPN	T4,CNTLF6
CNTLF7:	JUMPE	T5,CNTLF9	;NO BELL IF ONLY ONE MATCH
CNTLF8:	MOVEI	T1,7
	CALL	TYPCHR
CNTLF9:	POP	P,T5
	POP	P,T4
	MOVE	T1,[POINT 7,CMDLIN]
	MOVEM	T1,CMDTKR	;RESCAN THE LINE
	MOVE	T1,CMDPTR
	MOVEM	T1,CMDLIM
	JRST	LEVEL1
;ROUTINE TO COMBINE ELEMENTS OF EXPRESSION
; MAY BE USED AS A SUBROUTINE OR AS EXIT FROM GETEXP

ACCUM:	LDB	T1,CMDPTR	;THE BREAK CHAR WHICH GOT US HERE
	CAIE	T1,"("		;WE ARE LOOKING FOR -(
	JRST	ACCUM2		;DEFINATELY NOT
	CALL	RSCAN		;GET POINTER TO PREVIOUS CHAR
	LDB	T1,T2		;GET PREVIOUS CHAR
	CAIE	T1,"-"		;WAS THIS AUTO DECREMENT ?
	JRST	ACCUM2		;NO
	MOVE	T1,CMDPTR	;LIMIT
	SKIPN	CMDTKR		;ALREADY DOING A RESCAN ?
	MOVEM	T1,CMDLIM	;DOING ONE NOW
	MOVEM	T2,CMDTKR
	MOVEM	T2,CMDPTR
	JRST	ACCUM8
ACCUM2:	SETZ	T2,		;IN CASE FOLLOWING DOESN'T SET UP T2
	TXZE	FLG,F.SYMB
	JRST	[CALL	EVLSYM
		RET
		MOVEM	T1,T2		;PUT IN RIGHT REG
		JRST	ACCUM3 ]
	TXZE	FLG,F.IOCT
	MOVE	T2,OCTIN
	TXZE	FLG,F.IDEC
	MOVE	T2,DECIN
	TXZE	FLG,F.IHEX
	MOVE	T2,HEXIN
ACCUM3:	MOVE	T1,EXPRES	;GET EXPRESSION SO FAR
	MOVE	T3,INPOPR	;GET INPUT OPERATOR
	XCT	[	ADD	T1,T2
			SUB	T1,T2
			IMUL	T1,T2
			IDIV	T1,T2
			IOR	T1,T2
			AND	T1,T2
			XOR	T1,T2 ](T3)
	CAIE	T3,3		;DID WE JUST DO A DIVISION ?
	SETZ	T2,		;NO SO NO REMAINDER
	MOVEM	T1,EXPRESS	;SAVE ACCUMULATED EXPRESSION
	MOVEM	T2,REMAIN	;SAVE NEW REMAINDER
ACCUM8:	MOVEI	T1,177777	;MASK FOR 16 BITS
	ANDB	T1,EXPRESS	;MASK OFF HIGH BITS
	SETZM	OCTIN
	SETZM	DECIN
	SETZM	HEXIN
	SETZM	SYMBOL
	MOVE	T2,[POINT 6,SYMBOL]
	MOVEM	T2,SYMPTR
	RETSKP
;HERE BECAUSE USER FINISHED SYMBOL WITH ":"
DEFSYM:	TXNE	FLG,F.SYMB
	SKIPN	T1,SYMBOL	;SYMBOL HE DEFINED
	JRST	ILLCHR
	SKIPE	T2,LFTSAV	;WAS THIS X<TAG: ?
	JRST	[ANDI	T2,177777	;STRIP EXTRA BITS
		JRST	DFSYM3 ]	;YES
	TLNN	DOT,400000
	TLO	DOT,777777
	HRRZ	T2,DOT		;CURRENT ADR
	SETZB	T3,T4		;NO FLAGS OR MISC
	TLNN	DOT,200000
	TLO	T3,SMF.RG
	LDB	T1,[POINT 6,SYMBOL,5]	;GET FIRST CHAR IN SYMBOL
	CAIN	T1,'  %'
	JRST	[SKIPN	CMDFIL		;DOING COMMAND FILE ?
		JRST	ILLCHR		;NO SO THIS IS TRASH
		MOVE	T2,CMDCNT	;VALUE IS CHAR IN FILE
		MOVSI	T3,SMF.SU	;SUPPRESS VALUE
		JRST	.+1 ]
DFSYM3:	MOVE	T1,SYMBOL	;GET SYMBOL AGAIN
	MOVE T4,[SIXBIT /TYPEIN/];SAY THAT THE USER DEFINED IT
	CALL	ADDSYM		
	CALL	TABTYP
	JRST	LEVEL1

;HERE TO EVALUATE A SYMBOL
; CALL	WITH SYMBOL SETUP
;	LOSE RETURN
;	WIN RETURN WITH SYM SETUP, VALUE IN T1, FLAGS IN T2
EVLSYM:	LDB	T1,[POINT 6,SYMBOL,5]	;GET FIRST CHAR OF SYMBOL
	CAIN	T1,'  %'
	RET
	MOVE	T1,SYMBOL	;GET CURRENT SYMBOL
	CAMN	T1,[SIXBIT \ Q\]	;CHECK FOR <ALT>Q
	JRST	[HRRZ	T1,ESC.Q.
		RETSKP]
	CAMN	T1,[SIXBIT \.\]	;CHECK FOR SPECIAL CASE
	JRST	[HRRZ	T1,DOT
		MOVSI	SYM,SMF.RG
		TLNN	DOT,400000
		TLO	DOT,777777
		TLNN	DOT,200000
		TXO	FLG,F.SYML
		RETSKP]
	TXO	FLG,F.SYML	;ASSUME WE'LL LOAD SYM
	CALL	SYMFND		;TRY TO FIND SYMBOL
	JRST	SYMERR
	HRRZ	T1,1(SYM)	;GET VALUE OF SYMBOL
	TLNE	SYM,SMF.RG	;IS THIS A REGISTER NAME ?
	TXO	FLG,F.SREG	;YES
	RETSKP

SYMERR:	MOVEI	T1,[ASCIZ \U   \]
	JRST	ILLCH0		;REST LIKE ILLEGAL CHARACTER
;HERE IF USER TYPES A CONTROL R
CNTRLR:	CALL	RSCAN
	MOVEM	T2,CMDPTR	;SAVE PUTTER WITHOUT CONTROL R
	CALL	CNTLR3
	JRST	LOOP

;HERE TO RETYPE COMMAND
CNTLR3:	CALL	CRLTYP		;TYPE A <CR><LF> TO BEGIN
	MOVE	T2,[POINT 7,CMDLIN]	;GET POINTER TO COMMAND LINE
	CAMN	T2,CMDPTR	;IS LINE EMPTY ?
	JRST	CRLTYP		;EXTRA FLOURISH TO END
CNTLR4:	ILDB	T1,T2		;GET NEXT CHAR TO ECHO
	CAIN	T1,33		;IS CHAR AN ALTOMODE ?
	MOVEI	T1,"$"		;YES SO SPECIAL ECHO
	CALL	TYPCHR		;ECHO THE CHAR
	CAME	T2,CMDPTR	;TYPED ENOUGH YET ?
	JRST	CNTLR4		;LOOP BACK FOR REST OF CHARS
	RET

;HERE TO BACKUP COMMAND POINTER
; CALL	CALL	RSCAN
;	RETURN	WITH T2 CONTAINING POINTER TO PREVIOUS CHAR
;		T1 CONTAINS POINTER TO PREVIOUS-2 CHAR
RSCAN:	SETZB	T1,T2
	MOVE	T3,[POINT 7,CMDLIN]
RSCAN2:	CAMN	T3,CMDPTR	;HIT END YET ?
	JRST	R
	MOVE	T1,T2
	MOVE	T2,T3
	IBP	T3
	JRST	RSCAN2
;HERE WHEN USER TYPES A RUBOUT
COMRUB:	CALL	RSCAN		;BACK UP POINTER
	JUMPE	T1,CNTRLU	;IF NOTHING IS SAME AS ^U
	MOVEM	T1,CMDLIM
	MOVEM	T1,CMDPTR	;IN CASE CALL CNTLR3
	MOVE	T1,[POINT 7,CMDLIN]
	MOVEM	T1,CMDTKR	;RESCAN THE COMMAND
	MOVE	T1,TTYBIT	;GET TTY DESCRIPTION WORD
	TXNN	T1,TF.RUB	;IS THIS A VIDEO TERMINAL ?
	JRST	CMRUB3		;GO DO "\X" TYPE ECHO
	LDB	T1,T2		;GET CHAR JUST RUBBED OUT
	CAIN	T1,33		;IS IT AN ALTMODE ?
	MOVEI	T1,"$"
	CAIGE	T1," "		;BE SURE USUAL PRINTING CHAR
	JRST	[	CALL	CNTLR3		;ECHO COMMAND
			JRST	CMRUB8 ]
	MOVEI	T1,[BYTE (7)10,40,10,0]
	CALL	TYPSTR
	JRST	CMRUB8

CMRUB3:	MOVEI	T1,"\"
	CALL	TYPCHR
	LDB	T1,T2
	CAIN	T1,33		;WAS THIS AN ALTMODE ?
	MOVEI	T1,"$"
	CALL	TYPCHR		;ECHO CHAR JUST RUBBED OUT
CMRUB8:
CMRUB9:	MOVE	T1,[ESCSAV,,BYTCNT]	;RESTORE THINGS SET WITH
	BLT	T1,BYTCNT+2	; ESCAPE COMMANDS
	JRST	LEVEL1

;HERE WHEN USER TYPES A CONTROL U
CNTRLU:	MOVEI	T1,[BYTE (7)7,"x","x","x",11,0]
	CALL	TYPSTR
	JRST	CMRUB9
;HERE WHEN USER TYPES A CONTROL W - DELETE FIELD FROM TYPEIN

CNTRLW:	CALL	RSCAN		;BACKUP POINTER
	JUMPE	T1,CNTRLU	;IF NOTHING SAME AS ^U
	SKIPA	T2,T1
CNTLW1:	CALL	RSCAN
	MOVEM	T2,CMDLIM
	MOVEM	T2,CMDPTR
	MOVE	T1,[POINT 7,CMDLIN]
	MOVEM	T1,CMDTKR
	JUMPE	T1,CNTRLU	;IF NOTHING IS SAME AS ^U
	LDB	T2,CMDPTR	;GET LAST CHAR
	CAIN	T2,"."
	JRST	CNTLW1		;KEEP BACKING UP
	CAIL	T2,"0"
	CAILE	T2,"Z"+40
	JRST	CNTLW9
	CAILE	T2,"9"
	CAIL	T2,"A"+40
	JRST	CNTLW1		;KEEP BACKING
	CAIL	T2,"A"
	CAILE	T2,"Z"
	JRST	CNTLW9
	JRST	CNTLW1
CNTLW9:	CALL	CNTLR3		;RETYPE THE LINE
	JRST	LEVEL1		;THEN REDO IT
	SUBTTL	COMMAND CHARACTERS

;HERE WHEN COMMAND STARTS WITH A QUOTE
QUOTE:	TXNE	FLG,F.GEXP	;DID ANYTHING PRECEDE THE " ?
	JRST	ILLCHR		;BOUNCE REQUEST
	HRR	STATE,.JBFF##	;GET WHERE WE WILL PUT STATE TABLE
	MOVEI	T1,100		;NEED 64 WORDS FOR TABLE
	CALL	GETCOR		;ALLOCATE CORE
	HRRM	STATE,.JBFF##	;SO WE DON'T FORGET LATER
	MOVEI	T2,QUOTEB	;NEXT CHAR IS THE BREAK CHAR
	CALL	QUOTET		;SET UP TABLE
	JRST	LOOP

;HERE WHEN GET BREAK CHARACTER AFTER QUOTE
QUOTEB:	TXO	FLG,F.TEXT	;NOW DOING TEXT
	MOVEI	T2,QUOTEC	;MOST CHARACTERS NOW ARE TEXT
	CALL	QUOTET		;SETUP DISPATCH TABLE
	ROT	T1,-1		;DIVIDE BREAK CHAR BY 2
	ADDI	T1,(STATE)	;POINT TO STATE TABLE
	MOVEI	T2,QUOTEE	;WHEN GET ANOTHER BREAK ARE DONE
	HRRM	T2,(T1)
	SKIPL	T1		;WAS CHAR EVEN ?
	MOVSS	@T1		;YES SO DISPATCH FROM LEFT OF WORD
	JRST	LOOP

;HERE WHEN GET ANOTHER TEXT CHAR
QUOTEC:	ANDI	T1,177		;STRIP PARITY
	IDPB	T1,DAT		;PUT INTO DATA AREA
	SKIPL	T1,DTFINP	;ALREADY SETUP DTFINP ?
	SKIPA	T1,DOT		;NO SO USE DOT
	AOS	T1		;ADVANCE IT
	MOVEM	T1,DTFINP
	JRST	LOOP		;GO GET NEXT CHAR

;HERE WHEN GET TERMINAL BREAK
QUOTEE:	TXZ	FLG,F.TEXT	;NO LONGER DOING TEXT
	HRRI	STATE,STATE0
	JRST	LEVEL3
;HERE TO SETUP DISPATCH TABLE

QUOTET:	HRLI	T2,(T2)
	MOVEM	T2,(STATE)
	HRLI	T2,(STATE)	;BUILD BLT POINTER
	HRRI	T2,1(STATE)	;FINISH POINTER
	BLT	T2,77(STATE)
	MOVEI	T2,CNTRLR	;DISPATCH FOR CONTROL R
	HRLM	T2,11(STATE)
	MOVEI	T2,CNTRLU	;DISPATCH FOR CONTROL U
	HRRM	T2,12(STATE)
	MOVEI	T2,CNTRLW	;DISPATCH FOR CONTROL W
	HRRM	T2,13(STATE)
	MOVEI	T2,CNTRLZ	;DISPATCH FOR CONTROL Z
	HRLM	T2,15(STATE)
	MOVEI	T2,COMRUB	;DISPATCH FOR RUBOUT
	HRRM	T2,77(STATE)
	RET
;HERE WHEN USER TYPES A CR COMMAND
COM.CR:	CALL	STEFIN		;DO DEPOSIT MAYBE
	TXZN	FLG,F..ESC	;WAS THIS AN <ESCAPE><CR> ?
	JRST	LEVEL0		;NO SO CLEAN UP THEN GET MORE CHARS
	CALL	DOTSWP		;LOAD ALTERNATE DOT
	CALL	COMLF1		;DISPLAY NEW DOT
	JRST	LEVEL0

;HERE WHEN USER TYPES A BACK SLASH
BKSLSH:	CALL	STEFIN
	CALL	B3.TYP
	PUSH	P,DOT
	PUSH	P,DOTFOO
	MOVE	DOT,LSTADR
	CALL	DATYPE
	POP	P,DOTFOO
	POP	P,DOT
	JRST	LEVEL1

;HERE WHEN USER TYPES IN AN ILLEGAL CHARACTER
ILLCHR:	MOVEI	T1,[BYTE (7)7,"?",7,11,7,0]
ILLCH0:	CALL	TYPSTR
	;CLRBFI			;CLEAR TYPEAHEAD
	TXO	FLG,F.CERR	;IN CASE THIS IS A COMMAND FILE
	MOVE	T1,[ESCSAV,,BYTCNT]	;RESTORE THINGS SET BY ESCAPE
	BLT	T1,BYTCNT+2	; COMMANDS
	JRST	LEVEL1

;HERE WHEN THE USER TYPES A TAB COMMAND
COM.HT:	CALL	STEFIN		;DO DEPOSIT MAYBE
	CALL	CRLTYP		;TYPE A CR/LF
	CALL	DOTSAV		;SAVE CURRENT DOT, DOTFOO, FOR LATER
	MOVE	DOT,LSTADR	;LAST ADDRESS TYPED IN OR OUT
	CALL	COMLF1
	JRST	LEVEL1
;HERE TO SAVE CURRENT DOT, DOTFOO FOR LATER $/ ETC.
DOTSAV:	MOVEM	DOT,DOTOLD	;SAVE DOT
	MOVE	T1,DOTFOO	;GET DOTFOO
	MOVEM	T1,DTFOLD	;SAVE IT ALSO
	RET

;HERE TO SET DOTFOO TO NEXT VALUE
NDTFOO:	MOVE	T1,DOTFOO	;CURRENT DOTFOO
	CALL	DOTINC
	MOVEM	T1,DOTFOO
	RET

;HERE TO SET DTFINP TO NEXT VALUE
NDTFIN:	MOVE	T1,DTFINP	;GET CURRENT DTFINP
	CALL	DOTINC		;INCREMENT IT
	MOVEM	T1,DTFINP	;RESTORE NEW DTFINP
	RET

;HERE TO GET THE NEXT VALUE FOR DOT
NXTDOT:	MOVE	T1,DOT
	CALL	DOTINC
	MOVEM	T1,DOT
	RET

;GET NEXT VALUE FOR LOCATION POINTER
; CALL	MOVE T1,<CURRENT VALUE>
;	CALL	DOTINC
DOTINC:	SKIPL	T1		;DID IT GET LOADED ?
	JRST	[SKIPL	T1,DOT		;START WITH DOT
		HRLI	T1,777777
		RET	]
	SKIPE	PDP8F		;OR A PDP8 ?
	AOJA	T1,[TRZ T1,700000	;15 BIT ADR
		RET	]
	TLNN	T1,200000	;WAS THIS A REGISTER ADDRESS ?
	JRST	[AOS	T1		;INCREMENT BY 1 FOR REGISTERS
		TRZ	T1,777770	;STRIP EXTRA BITS
		RET	]
	ADDI	T1,2
	TRZ	T1,600001
	RET
;HERE IF END EXPRESSION WITH AN LEFT ANGLE BRACKET

LFTANG:	CALL	ACCUM		;FINISH EXPRESSION
	RET			;LOSE
	HRROM	T1,LFTSAV	;SAVE IT
	JRST	GETEXP
;HERE WHEN THE USER TYPES A LINE FEED COMMAND
COM.LF:	CALL	STEFIN		;DO DEPOSIT MAYBE
	TXZE	FLG,F..ESC	;WAS <LF> PRECEDED BY AN <ESCAPE> ?
	CALL	DOTSWP		;YES SO SPECIAL HANDLING
	MOVEI	T1,15		;CARRIAGE RETURN
	CALL	TYPCHR
	MOVE	T1,DOTFOO
	SETZM	DOTFOO		;DONE WITH IT NOW
	CALL	DOTINC
	MOVEM	T1,DOT
	CALL	COMLF1
	JRST	LEVEL1

COMLF1:	TXO	FLG,F.LOPN	;FLAG LOCATION IS OPEN
COMLF2:	MOVE	T1,DOT
	CALL	ADRTYP		;TYPE ADDRESS
	MOVEI	T1,"/"
	TXNE	FLG,F.LBKT	;FOLLOWING A LEFT BRACKET ?
	MOVEI	T1,"["		;YES SO DECLARE IT
	CALL	TYPCHR
COMLF3:	HRRZ	T1,DOT
	CAMGE	T1,CACHEL	;IS THIS ALREADY IN CACHE ?
	SETZM	CACHEL		;YES SO FLUSH CACHE
COMLF4:	CALL	B3.TYP		;TYPE 3 SPACES
	TXO	FLG,F.CACH	;USE CACHE AFTER 1ST WORD
	TXNN	FLG,F.LBKT	;DOING LFT BRACKET STUFF ?
	PJRST	DATYPE
	MOVEI	T1,2		;NUMERIC STYLE
	MOVEI	T5,1		;ONE WORD
	PJRST	RETYPE
;HERE WHEN USER TYPES A BACK ARROW
BARROW:	CAMN	T4,DAT		;FOLLOWING TYPEIN ?
	JRST	BARRW5		;NO
BARRW3:	ILDB	T1,T4		;GET LOW ORDER BYTE
	SETZ	T2,		;IN CASE ODD NUMBER OF BYTES
	CAME	T4,DAT
	ILDB	T2,T4		;GET HIGH ORDER BYTE
	DPB	T2,[POINT 8,T1,27]
	CALL	ADRTYP		;DISPLAY AS AN ADDRESS
	CAME	T4,DAT		;DONE ALL YET ?
	JRST	[CALL	COMTYP
		JRST	BARRW3 ]	;LOOP BACK FOR REST
	CALL	B3.TYP
	JRST	LEVEL1
BARRW5:	TXNN	FLG,F.LOPN	;IS LOCATION OPEN ?
	JRST	ILLCHR		;NO SO BOUNCE COMMAND
	MOVEI	T1,0		;OUTPUT AS INSTRUCTION
	MOVEI	T5,2		;WANT ONLY 1 WORD
	CALL	RETYPE		;NO RETYPE STUFF
	JRST	LEVEL1

;HERE WHEN USER TYPES A SEMICOLON
SEMICL:	CAMN	T4,DAT		;FOLLOWING TYPEIN ?
	JRST	SMICL5		;NO
	JRST	LEVEL1
SMICL5:	TXNN	FLG,F.LOPN	;IS LOCATION OPEN ?
	JRST	ILLCHR		;IF NOT CAN'T HANDLE
	HRRZ	T1,O.MODE	;SET RIGHT MODE
	HRRZ	T5,BYTCNT
	CALL	RETYPE
	JRST	LEVEL1

RETYPE:	PUSH	P,O.MODE	;SAVE OUTPUT MODE
	HRRM	T1,O.MODE
	PUSH	P,BYTCNT
	HRRM	T5,BYTCNT
	;PUSH	P,DOTFOO
	SETZM	DOTFOO
	TXO	FLG,F.CACH	;USE CACHE IF POSSIBLE
	CALL	DATYPE		;TYPE DATA
	;POP	P,DOTFOO
	POP	P,BYTCNT
	POP	P,O.MODE	;RESTORE OUTPUT MODE
	RET
;HERE WHEN USER TYPES =
EQUALS:	CAMN	T4,DAT		;FOLLOWING TYPEIN ?
	JRST	EQUAL5		;NO
	TXNE	FLG,F.SYML	;DID TYPEIN INCLUDE A SYMBOL ?
	TLNN	SYM,SMF.RG	;WAS THAT A REGISTER NAME ?
	CAIA
	CALL	PCNTYP		;TYPE A %
EQUAL2:	ILDB	T1,T4
	SETZ	T2,
	CAME	T4,DAT
	ILDB	T2,T4
	DPB	T2,[POINT 8,T1,27]
	MOVEM	T1,LSTADR	;LAST OUTPUT ADDRESS
	MOVEM	T1,ESC.Q.	;IN CASE OF <ESCAPE>Q
	CALL	RADTYP
	CAMN	T4,DAT
	JRST	[CALL	B3.TYP		;TYPE 3 SPACES
		JRST	LEVEL1 ]
	CALL	COMTYP
	JRST	EQUAL2

;HERE TO RETYPE PREVIOUSLY OUTPUT DATA IN CURRENT RADIX
EQUAL5:	TXNN	FLG,F.LOPN	;IS LOCATION OPEN ?
	JRST	ILLCHR		;NO SO ILLEGAL
	MOVEI	T1,2		;OUTPUT AS NUMERIC
	SKIPN	T5,DOTFOO
	HRRZ	T5,DOT
	SUBI	T5,-2(DOT)
	ANDI	T5,777777	;HALF WORD ONLY
	LSH	T5,-1
	CALL	RETYPE
	JRST	LEVEL1
;HERE WHEN USER TYPES [ AT END OF A NUMBER
OPLBKT:	TXOA	FLG,F.LBKT	;REMEMBER HOW WE OPENED
;HERE WHEN USER TYPES / AT END OF A NUMBER
OPNLOC:	TXZ	FLG,F.LBKT
	TXZN	FLG,F.MASK	;ASKING ABOUT THE MASK ?
	JRST	OPNLC4		;LOOKING AT 11
	TXO	FLG,F.MOPN	;MASK NOW OPEN
	CALL	B3.TYP		;TYPE 3 SPACES
	MOVEI	T3,S.MASK-1	;MAKE A POINTER TO THE MASK
	SKIPN	T2,ESCOCT	;DID WE GET A NUMBER WITH THE COMMAND ?
	MOVEI	T2,1		;DEFAULTS TO 1
	CAIL	T2,MASKSZ	;ASKING FOR TOO MUCH ?
	MOVEI	T2,MASKSZ	;YES SO GIVE LIMIT
	CAIA
OPNLC2:	CALL	BLANKT
	AOS	T3
	MOVE	T1,(T3)
	MOVEM	T1,LSTADR	;IN CASE OF HT COMMAND
	MOVEM	T1,ESC.Q.	;IN CASE USES <ESCAPE>Q
	CALL	RADTYP		;DISPLAY IT
	SOJG	T2,OPNLC2
	CALL	TABTYP
	JRST	LEVEL1
;HERE BECAUSE REALLY OPENING A LOCATION
OPNLC4:	CALL	DOTSAV		;SAVE DOT FOR AN ESCAPE LF COMMAND
	HRRO	DOT,EXPRESS
	TXNE	FLG,F.SYML	;WAS SYM LOADED ?
	TLNN	SYM,SMF.RG
	CAIA
	TLZ	DOT,377777
	SETZM	DOTFOO
	TXO	FLG,F.LOPN	;FLAG LOCATION IS OPEN
	CALL	COMLF3
	JRST	LEVEL2
;HERE WHEN USER TYPES AN UP ARROW
UARROW:	CALL	STEFIN
	TXZE	FLG,F..ESC	;WAS <LF> PRECEDED BY AN <ESCAPE> ?
	CALL	DOTSWP		;YES SO SPECIAL HANDLING
	CALL	CRLTYP
	SETZM	DOTFOO
	TLNN	DOT,400000	;WAS ADR SET ?
	TLO	DOT,777777
	MOVEI	T1,-1		;IN CASE REGISTER MODE
	TLNN	DOT,200000	;REG OR MEM ?
	JRST	COMAR0		;REG - GO DO IT
	MOVNI	T1,2		;IN CASE "[" MODE
	TXNE	FLG,F.LBKT	;IS IT
	JRST	COMAR0		;YES
	MOVN	T1,BYTCNT	;NUMBER OF BYTES
	SKIPE	PDP8F
	JRST	COMAR0
	HRRZ	T2,O.MODE	;GET OUTPUT MODE
	JUMPE	T2,COMAR2	;SYMBOLIC ?
	CAIN	T2,1		; OR ADDRESS ?
	ASH	T1,1		;CONVERT WORD COUNT TO BYTES
	CAIN	T2,2		;OR NUMERIC
	ASH	T1,1		;CONVERT WORD COUNT TO BYTES
COMAR0:	ADD	T1,DOT
	TLNN	DOT,200000	;WAS THIS A REGISTER ?
	ANDI	T1,7		;IN CASE WRAPPED AROUND
	SKIPE	PDP8F		;IS THIS A PDP8 ADDRESS ?
	TRZA	T1,700000
	ANDI	T1,177777
	HRRM	T1,DOT
	CALL	COMLF1		;REST LIKE A LINE FEED COMMAND
	JRST	LEVEL2
;HERE IF DID UP ARROW WHEN IN SYMBOLIC MODE
; TRY TO MAKE A GUESS HOW FAR BACK TO GO
COMAR2:	TRZ	DOT,600001	;INSTRUCTIONS BEGIN ON WORD BOUNDRY
	TXZ	FLG,F.CACH	;DON'T USE CACHE
	MOVEI	T4,1		;TRY ONE WORD INSTRUCTION FIRST

;HERE TO COUNT WORDS IN INSTRUCTION
COMAR3:	MOVE	T2,T4		;NUMBER OF WORDS TO LOOK FOR
	ASH	T2,1		;TIMES 2 FOR BYTES
	MOVEI	T1,(DOT)	;CURRENT ADR
	SUBI	T1,(T2)		;BACK UP CURRENT ADR
	CALL	CNINWD		;COUNT WORDS IN INSTRUCTION AT ADR
	JRST	COMAR8		;NOT AN INSTRUCTION
	CAIE	T4,(T1)		;IS THAT WHAT WE WANTED ?
	JRST	COMAR8		;NO
	SUBI	DOT,(T4)
	SUBI	DOT,(T4)
	CALL	COMLF1		;PRINT INSTRUCTION
	JRST	LEVEL2

COMAR8:	AOS	T4		;TRY FOR LARGER INSTRUCTION
	CAIE	T4,4		;IS THAT TOO LARGE ?
	JRST	COMAR3		;NO
	SUBI	DOT,2		;JUST BACK UP ONE WORD
	CALL	COMLF1
	JRST	LEVEL2
;HERE TO COUNT WORDS IN AN INSTRUCTION
; CALL	MOVE	T1,<ADR>
;	CALL	CNINWD
;	ERROR RETURN
;	WIN RETURN	NUMBER OF WDS IN T1
CNINWD:	MOVEI	T2,2		;TRY FOR 2 BYTES
	SKIPE	PDP8F		;UNLESS PDP8
	MOVEI	T2,1		;IS PDP8 SO ONLY ONE WORD
	MOVEI	T2,2		;NUMBER OF BYTES TO TRY FOR
	CALL	GETWRD		;TRY TO GET THE DATA
	RET			;LOSES
	CALL	INVLFN		;SEE IT THERE IS ANY SUCH INSTRUCTION
	RET			;NO = LOSE
	MOVEI	T2,1		;ONE FOR INSTRUCTION
	LDB	T3,[POINT 6,T1,29]	;GET SS FIELD
	TLNE	SYM,SMF.SS	;IS THIS SSDD FORMAT ?
	CALL	CNIWD3		;YES SOADJUST NUMBER OF WDS IN INSTRUCTION
	LDB	T3,[POINT 6,T1,35]	;GET DD FIELD
	TLNE	SYM,SMF.DD!SMF.SS	;IS DD PRESENT ?
	CALL	CNIWD3		;YES SO ADJ WORD COUNT
	HRRZ	T1,T2		;NUMBER OF WORDS
	RETSKP

CNIWD3:	CAIE	T3,27		;IS THIS IMMEDIATE (#FOO)
	CAIN	T3,37		;OR ABSOLUTE
	AOS	T2		;YES SO ANOTHER WORD IN INSTRUCTION
	LDB	T3,[POINT 3,T3,32]
	CAIE	T3,6		;IS THIS RELATIVE
	CAIN	T3,7		;OR RELATIVE DEFERRED ?
	AOS	T2		;YES SO ANOTHER WORD
	RET
;HERE WHEN THE USER TYPE A ^Z
CNTRLZ:	MONRT.			;BACK TO THE MONITOR WE GO
	JRST	LEVEL0		;USER TYPED .CONTINUE


;HERE IF USER ENDS AN EXPRESSION WITH A ">"
SUPLIM:	SKIPE	T1,LFTSAV
	MOVEM	T1,SBEGIN	;SET LOWER LIMIT FOR SEARCH
	MOVE	T1,EXPRESS	;GET EXPRESSION
	HRRZM	T1,S..END	;SET UPPER LIMIT FOR SEARCH
	JRST	LEVEL2
;HERE IF USER ENDS SYMBOL WITH A "?"

QUEST.:	SKIPN	T1,SYMBOL	;WERE WE BUILDING A SYMBOL ?
	JRST	ILLCHR		;NO SO DING HIM
	PUSH	P,T5
	SETO	T5,		;COUNT MATCHES
	CALL	MATCH		;TRY TO FIND A PARTIAL MATCH
	JUMPE	SYM,QUEST5	;IN CASE CAN'T FIND ANY MATCHES
	CALL	CRLTYP		;BEGIN WITH <CR><LF>
	MOVEI	T1,[ASCIZ \following are partial matches
\]
	AOSN	T5
	CALL	TYPSTR
	CALL	TABTYP		;AND ADD A <HT>
	MOVE	T1,(SYM)	;GET SYMBOL NAME
	CALL	SIXTYP
	MOVEI	T1,[ASCIZ \ = \]
	CALL	TYPSTR
	TLNE	SYM,SMF.RG	;IS THIS A REGISTER DEFINITION ?
	CALL	PCNTYP		;TYPE A "%"
	HRRZ	T1,1(SYM)	;GET VALUE OF SYMBOL
	CALL	RADTYP		;TYPE VALUE IN CURRENT RADIX
	MOVEI	T1,[ASCIZ \ spd\]
	TLNE	SYM,SMF.SU	;IS SYMBOL SUPPRESSED ?
	CALL	TYPSTR		;YES
	MOVEI	T1,[ASCIZ \ opcode\]
	TLNE	SYM,SMF.IN	;IS THIS AN OPCODE ?
	CALL	TYPSTR		;YES
	SKIPN	3(SYM)		;WAS THERE A SOURCE ?
	JRST	QUEST4		;NO
	TYPE	< defined in >
	MOVE	T1,3(SYM)	;GET SOURCE
	CALL	SIXTYP
QUEST4:	RET

QUEST5:	MOVEI	T1,[ASCIZ \ no partial matches for symbol\]
	AOSN	T5		;FIND ANY MATCHES ?
	CALL	TYPSTR
	POP	P,T5
	CALL	CNTLR3		;RETYPE THE COMMAND
	JRST	LOOP
;HERE TO TRY TO FIND A PARTIAL MATCH FOR A SYMBOL
; CALL	SKIPN T1,SYMBOL	;WERE WE BUILDING A SYMBOL ?
;	JRST	ILLCHR	;DON'T CALL MATCH
;	CALL	MATCH
;	RETURN WITH SYM SETUP WITH PARTIAL MATCH
;		WITH (SYM) = 0 WHEN FOUND ALL MATCHES
MATCH:	CALL	RSCAN
	MOVEM	T2,CMDPTR	;DELETE THE "?" OR <CONTROL F>
	SKIPA	T3,[770000,,0]	;BUILD MASK TO TEST UNDER
MATCH0:	ASH	T3,-6		;ENLARGE THE MASK
	MOVE	T1,T3		;COPY SUGGESTED MASK
	AND	T1,SYMBOL
	CAME	T1,SYMBOL	;IS MASK LARGE ENOUGH ?
	JRST	MATCH0		;NO SO INCREASE SIZE
	MOVE	SYM,SYMBEG	;POINT TO THE FIRST SYMBOL
MATCH2:	MOVE	T1,(SYM)	;GET SYMBOL NAME
	AND	T1,T3		;MASK OFF
	CAME	T1,SYMBOL	;DOES THIS MATCH ?
	JRST	MATCH4		;NO
	HLL	SYM,2(SYM)	;GET FLAGS FOR THE SYMBOL
	SKIPE	PDP8F		;DOING PDP8 SYMBOLS ?
	TLC	SYM,SMF.P8
	TLNE	SYM,SMF.P8
	JRST	MATCH4
	HLL	SYM,2(SYM)	;SO SMF.P8 RIGHT
	CALL	@(P)
MATCH4:	MOVEI	SYM,4(SYM)
	CAME	SYM,SYMEND	;HIT END ?
	JRST	MATCH2
	SETZ	SYM,		;FLAG ALL DONE
	POPJ	P,
;HERE TO DO DEPOSIT MAYBE AFTER CR OR LF OR UP ARROW
STEFIN:	MOVE	T1,[POINT 8,DATA]	;VIRGIN DATA POINTER
	SKIPE	PDP8F		;WAS THIS A PDP8 LOOK ?
	HRLI	T1,(POINT 12)
	CAMN	T1,DAT		;DID USER TYPE ANYTHING ?
	RET			;NO SO DONE
	TXZE	FLG,F.MOPN	;IS MASK OPEN ?
	JRST	SETMSK		;SET MASK
	TXZN	FLG,F.LOPN	;IS LOCATION OPEN ?
	RET			;NO SO JUST RETURN
	TXNN	FLG,F.WENB	;WAS PATCHING ENABLED ?
	JRST	WRTLCK		;IS WRITE LOCKED
	SKIPL	T1,LSTIAD	;LAST ADDRESS GIVE BY USER
	MOVE	T1,LSTADR
	MOVEM	T1,LSTADR	;SAVE IT
	MOVEM	T1,ESC.Q.	;ALSO USE FOR <ESCAPE>Q
	SETZM	LSTIAD
	MOVE	T1,DTFINP	;GET NEW DOTFOO
	MOVEM	T1,DOTFOO	;AND SAVE IT
	SETZM	DTFINP
	MOVEI	T1,(DOT)	;WHERE TO PUT DATA
	TLNE	DOT,200000	;IS THIS MEMORY OR REGISTER
	JRST	STEFN5		;MUST BE MEMORY
	SETZM	DOTFOO		;SO FIRST CALL WORKS
	MOVE	T3,[POINT 8,DATA]	;POINTER TO DATA
STEFN3:	CALL	NDTFOO		;GET NEXT DOTFOO
	SETZ	T2,		;IN CASE ODD NUMBER OF BYTES
	ILDB	T1,T3		;GET LOW ORDER BYTE
	CAME	T3,DAT		;DONE ALL BYTES ?
	ILDB	T2,T3		;GET HIGH ORDER BITS
	DPB	T2,[POINT 8,T1,27]	;PUT HIGH ORDER WITH LOW ORDER
	HRRZ	T2,DOTFOO	;GET ADDRESS
	CAIN	T2,7		;IS THIS THE PC ?
	ANDI	T1,177776	;BE SURE IS EVEN
	MOVEM	T1,SIMREG(T2)	;STORE DATA
	CAME	T3,DAT		;WAS THAT END OF DATA ?
	JRST	STEFN3		;LOOP BACK FOR REST
	RET

STEFN5:	CALL	PUTBYT		;PUT DATA INTO 11
	NOP
	RET

WRTLCK:	TYPE	<?patching was not enabled by /PATCH
>
	JRST	LEVEL0

;HERE TO SET MASK
SETMSK:	SETZ	T4,		;INDEX FOR MASK
STMSK1:	ILDB	T2,T1		;GET NEXT BYTE
	SETZ	T3,		;IN CASE DONE
	CAME	T1,DAT		;DONE EVERYTHING YET ?
	ILDB	T3,T1
	DPB	T3,[POINT 8,T2,27]
	HRROM	T2,LSTADR	;SAVE IN CASE OF HT
	MOVEM	T2,ESC.Q.	;SAVE IN CASE <ESCAPE>Q
	HRRM	T2,S.MASK(T4)	;SET MASK
	CAME	T1,DAT		;ALL DONE YET ?
	AOJA	T4,STMSK1	;NOT YET - GO SET REST
	RET
	SUBTTL	ESCAPE COMMANDS

;HERE IF USER TYPES ESCAPE
ESCAPE:	CALL	ACCUM		;IN CASE ANYTHING ALREADY IN PROGRESS
	RET
	HRRI	STATE,STATSC	;SET ESCAPE FLAG
	SETZM	ESCOCT		;INITIAL OCTAL ARGUMENT
	SETZM	ESCDEC		;INITIAL DECIMAL ARGUMENT
	JRST	LOOP

ESCESC:	TXO	FLG,F..ESC
	JRST	LOOP

;HERE TO ACCUMULATE NUMBER AFTER ESCAPE
ESC...:	TXO	FLG,F.IDEC	;NUMBER IS DECIMAL
	MOVE	T1,ESCDEC	;GET DECIMAL VERSION
	MOVEM	T1,ESCOCT	;AND FORCE IT DECIMAL
	JRST	LOOP
ESC..8:	TXO	FLG,F.IDEC	;NUMBER IS DECIMAL
ESC..0:	MOVE	T2,ESCOCT
	IMULI	T2,^D8
	ADDI	T2,-60(T1)	;ACCUMULATE NUMBER
	MOVEM	T2,ESCOCT	;SAVE UPDATED NUMBER
	MOVE	T2,ESCDEC
	IMULI	T2,^D10
	ADDI	T2,-60(T1)	;ACCUMULATE NUMBER
	MOVEM	T2,ESCDEC	;SAVE UPDATED NUMBER
	TXNE	FLG,F.IDEC	;WANT DECIMAL ARGUMENT ?
	MOVEM	T2,ESCOCT	;YES SO FORCE IT
	JRST	LOOP

;HERE WHEN USER TYPES "(" AFTER AN ESCAPE
ESCPAR:	SKIPE	ESCOCT		;DID USER ALSO TYPE A # ?
	JRST	ILLCHR		;YES CONFUSED
	PUSH	P,EXPRES	;SAVE EXPRESSION SO FAR
	HRRI	STATE,STATE0	;PLAIN EXPRESSION EVALUATION
	CALL	GETEXP		;GET EXPRESSION
	JRST	TPOPJ		;ABORT
	HRRM	T1,ESCOCT	;THAT WAS NUMERIC ARGUMENT
	POP	P,EXPRESS	;GET OLD EXPRESSION BACK
	LDB	T1,CMDPTR	;GET BREAK CHARACTER
	CAIE	T1,")"
	JRST	ILLCHR
	HRRI	STATE,STATSC
	JRST	GTEXP1		;FINISH PARTIAL EXPRESSION
;HERE WHEN USER TYPES ESCAPE LF
ESC.LF:

;HERE WHEN USER TYPES ESCAPE CR
ESC.CR:

;HERE WHEN USER TYPES ESCAPE UPARROW
ESC.UP:	HRRI	STATE,STATE0	;FIX DISPATCH TABLE POINTER
	TXO	FLG,F..ESC	;REMEMBER WE SAW <ESCAPE>
	JRST	LOOP1		;THEN EXIT GETEXP

;HERE TO EXCHANGE OLD DOT, DOTFOO, & DOTFLG
DOTSWP:	EXCH	DOT,DOTOLD	;EXCHANGE NEW AND OLD DOT
	MOVE	T1,DOTFOO	;GET DOTFOO
	EXCH	T1,DTFOLD	;EXCHANGE WITH OLD ONE
	MOVEM	T1,DOTFOO	;AND SET NEW DOTFOO
	RET

;HERE FOR <ESCAPE>M - REFERS TO THE MASK
ESC..M:	TXO	FLG,F.MASK	;MASK REFERENCED
	JRST	ESCMD8		;FINISH COMMAND
ESC..A:	MOVEI	T1,1		;SETTING ADDRESS MODE
	JRST	ESCMOD

ESC..B:	MOVEI	T1,3		;SETTING BYTE MODE
	JRST	ESCMD0

ESC..C:	MOVEI	T1,2		;SETTING NUMERIC MODE
	JRST	ESCMOD

ESC..K:	JUMPE	SYM,ILLCHR	;DID A SYMBOL PRECEDE $K ?
	CALL	B3.TYP		;TYPE 3 SPACES		;TYPE TAB SO HE KNOWS HE WON
	MOVSI	T1,SMF.SU	;FLAG TO SUPRESS OUTPUT
	IORM	T1,2(SYM)	;SUPRESS SYMBOL
	MOVE	T1,(SYM)	;GET SYMBOL
	TXZE	FLG,F..ESC	;DID HE WANT TO FLUSH SYMBOL ?
	CALL	DELSYM		;YES SO FORGET IT
	JRST	LEVEL1

ESC..R:	TXNN	FLG,F.IDEC	;WAS ARGUEMNT DECIMAL
	SKIPA	T1,ESCOCT	;NO SO USE OCTAL
	MOVE	T1,ESCDEC
	CAIG	T1,^D16
	CAIG	T1,1		;IS RADIX REASONABLE ?
	JRST	ILLCHR		;NO SO FLUSH REQUEST
	HRRM	T1,ORADIX	;YES SET NEW RADIX
	TXZN	FLG,F..ESC	;SETTING PERMANENT MODE ?
	JRST	ESCMD8		;NOT PERMANENT MODE
	HRLM	T1,ORADIX	;YES
	JRST	ESCMD7		;EXIT

ESC..S:	MOVEI	T1,0		;SETTING INSTRUCTION MODE
	JRST	ESCMOD

ESC..I:	SKIPA	T1,[EXP 5]	;SETTING EBCDIC OUTPUT
ESC..T:	MOVEI	T1,4		;SETTING ASCII OUTPUT
ESCMD0:	MOVE	T2,ESCOCT	;GET ARGUMENT
	SKIPN	T2
	MOVEI	T2,2		;DEFAULT IS 2 BYTES
	JRST	ESCMD2
ESCMOD:	MOVE	T2,ESCOCT	;GET ARGUMENT
	SKIPN	T2
	MOVEI	T2,1		;DEFAULT IS 1
ESCMD2:	HRRM	T2,BYTCNT
	HRRM	T1,O.MODE	;SET CURRENT MODE
	TXZ	FLG,F.LBKT
	TXZN	FLG,F..ESC
	JRST	ESCMD8		;NOT PERMANENT
	HRLS	BYTCNT		;LOCAL COUNT IS PERMANT COUNT
	HRLM	T1,O.MODE	;SET PERMANT MODE
ESCMD7:	CALL	B3.TYP		;TYPE 3 SPACES
	JRST	LEVEL1
ESCMD8:	HRRI	STATE,STATE0	;RESTORE STATE POINTER
	JRST	LOOP		;FINISH COMMAND
;HERE IF USER TYPES <ESCAPE>Q

ESC..Q:	MOVE	T2,SYMPTR	;GET SYMBOL POINTER
	CAME	T2,[POINT 6,SYMBOL]	;DID THIS HAPPEN AT A REASONABLE TIME ?
	JRST	ILLCHR		;NO SO DING HIM
	TXO	FLG,F.SYMB!F.GEXP	;GOT SOMETHING
	TXZ	FLG,F.IDEC!F.IOCT!F.IHEX
	IBP	SYMPTR		;SKIP FIRST CHAR
	MOVEI	T1,'  Q'
	IDPB	T1,SYMPTR	;PUT Q IN SYMBOL
	HRRI	STATE,STATE0	;RESTORE STATE
	JRST	LOOP		;AND PROCEDE
ESC..G:	SKIPN	T1,EXPRESS	;GET ADDRESS HE TYPED
	MOVE	T1,GOTO		;OLD VALUE FOR STARTING ADDRESS
	ANDI	T1,177776	;ONLY 16 BITS PLEASE
	MOVEM	T1,GOTO		;REMEMBER IT FOR LATER
	SKIPE	MEMORY		;ARE DIDDLING DUMP OR BIN FILE ?
	JRST	ESC.G1		;START THE SIMULATION
	SKIPN	NODE		;ARE WE DOING STUFF WITH A NODE ?
	JRST	ILLCHR		;NO SO THIS IS IMPOSSIBLE
	TXNN	FLG,F.WENB	;WAS PATCHING ENABLED ?
	JRST	WRTLCK		;CAN'T DO IT
	MOVE	T1,EXPRESS	;GET ADDRESS HE TYPED
	CALL	SETUPN		;SETUP NODE UUO
	EXP	3		;CODE FOR GOTO IS 3
	CALL	NODSET		;GO DO NODE UUO
	JRST	CALER0		;FAILED ?!
TABDNE:	CALL	TABTYP
	JRST	LEVEL1		;WE DID IT

ESC.G1:	TXNE	FLG,F..ESC	;WAS THIS AN $$G ?
	JRST	TABDNE		;THAT JUST SETS STARTING ADDRESS
	CALL	SETUPC		;SETUP THE PC FOR EXECUTION
	TXO	FLG,F.RUNF	;SET RUN FLOP
	MOVEI	T1,[ASCIZ \

   beginning execution @pc = \]
	CALL	TYPSTR
	MOVE	T1,SIMREG+PC	;GET PC WE'LL START AT
	CALL	ADRTYP
	CALL	CRLTYP
	MOVE	AC4,INSRUN
	SUB	AC4,WAITIM
	SETZ	AC3,		;WANT OUR RUNTIME
	RUNTIM	AC3,		;GET RUNTIME SO FAR
	CALL	SIMXCT		;RUN THE SIMULATED MACHINE FOR A WHILE
	SETZ	T1,		;WANT OUR RUNTIME
	RUNTIM	T1,		;GET NEW RUNTIME
	SUBM	T1,AC3		;LEAVES HOW LONG WE RAN
	MOVEI	T1,[ASCIZ \
	PDP-11 halted @pc = \]
	CALL	TYPSTR
	MOVE	T1,SIMREG+PC
	CALL	ADRTYP
	TYPE	< ps = >
	HRRZ	T1,PS
	CALL	OCTYPE
	TYPE	<
	after >
	MOVE	T1,INSRUN
	SUB	T1,WAITIM
	SUB	T1,AC4
	MOVE	AC4,T1		;REMEMBER NUMBER OF INSTRUCTIONS EXECUTED
	CALL	PDECTY		;TYPE AS DECIMAL WITH COMMAS
	TYPE	< instructions >
	MOVE	T1,AC3		;COPY NUMBER OF MSEC'S EXECUTED
	MULI	T1,^D10000	;MAKES NUMBER OF uSEC*10
	DIV	T1,AC4		;MAKES NUMBER OF 10*USEC'S / INSTRUCTIONS
	IDIVI	T1,^D10
	CAIL	T1,^D100	;LESS THAN 100 ?
	JRST	ESC.G8
	PUSH	P,T2
	CALL	DECTYP
	CALL	PERTYP		;DO A DECIMAL POINT
	POP	P,T1
ESC.G8:	CALL	DECTYP		;TELL SPEED
	CALL	BLANKT		;TYPE A SPACE
	MOVE	T1,AC3		;GET RUNTIME IN MSEC'S
	CALL	TIMTY1		;TYPE RUN TIME
	CALL	CRLTYP
	JRST	LEVEL1
;ESCAPE V - WATCH A LOCATION FOR VARIANCE
ESC..V:	SKIPE	MEMORY
	JRST	ILLCHR
	TXNN	FLG,F.LOPN	;IS LOCATION OPEN ?
	JRST	ILLCHR		;GIVE USER "?"
	SETZM	CACHE		;SWEEP THE CACHE
	TXO	FLG,F.FLIP
ESC.V0:	MOVEI	T1,0		;MINIMUM SLEEP
	SLEEP	T1,
	HRRZ	T1,DOT		;GET ADDRESS TO WATCH
	HRRZ	T2,BYTCNT	;NUMBER OF BYTES TO DISPLAY
	HRRZ	T3,O.MODE	;OUTPUT MODE
	CAIG	T3,2
	ASH	T2,1		;WORD MODE SO TIMES 2 BYTES
	TXZ	FLG,F.CACH
	CALL	GETWRD		;GET DATA
	JRST	[CALL	CALER0
		JRST	LEVEL1 ]
	MOVE	T2,T1		;COPY DATA
	XOR	T2,DATA		;COMPARE TO LAST TIME
	AND	T2,S.MASK	;MASK OFF IRREVELANT BITS
	TXZN	FLG,F.FLIP
	JUMPE	T2,ESC.V9	;BRANCH IF SAME AS BEFORE
	PUSH	P,T1		;SAVE NEW DATA
	MOVEM	T1,DATA		;SAVE NEW DATA
	CALL	CRLTYP
	HRRZ	T1,DOT		;GET ADDRESS
	CALL	ADRTYP
	MOVEI	T1,"/"
	TXNE	FLG,F.LBKT
	MOVEI	T1,"["
	CALL	TYPCHR
	CALL	COMLF4
	POP	P,DATA		;IN CASE DATYPE CHANGED IT
ESC.V9:	SKPINC			;HAS USER TYPED A CHARACTER ?
	JRST	ESC.V0		;NO SO KEEP WATCHING
	TYPE	<
<done watching>
>
	JRST	LEVEL2		;GO PROCESS NEXT COMMAND
;HERE BECAUSE TYPED $X - EXECUTE AN INSTRUCTION
; REGISTER USAGE
;	AC1 ON RETURN FROM SIMXCT WILL CONTAIN PC WE JUST EXECUTED
;	AC3 CONTAINS # FROM $#X
;	AC4 FOR $$X WILL BE SET UP WITH PC TO STOP ON

ESC..X:	SKIPN	MEMORY		;DO WE HAVE A PROGRAM TO EXECUTE ?
	JRST	ILLCHR		;NO SO DING HIM
	HRLZ	AC3,ESCOCT	;COPY REPETITION COUNT
	MOVNS	AC3		;MAKE AN AOBJN POINTER
	CALL	SETUPC		;SETUP THE PC
	MOVE	AC4,SIMREG+PC	;GET STARTING PC
	MOVE	T1,AC4		;GET STARTING ADDRESS
	CALL	CNINWD		;COUNT WORDS IN INSTRUCTION
	MOVEI	T1,1		;CALL IT A ONE WORD INSTRUCTION
	ADD	AC4,T1		;PLUS NUMBER OF WORDS
	ADD	AC4,T1		;TWICE TO MAKE BYTE ADR
	TXZ	FLG,F.RUNF!F.FLIP	;NOT REALLY RUNNING
	CALL	CRLTYP		;ACKNOWLEDGE WE ARE DOING IT
	MOVE	T1,[SIMREG,,BEGREG]
	BLT	T1,BEGREG+7	;COPY INITIAL REGISTERS
	MOVEM	PS,BEG.PS	;SAVE INITIAL PS
	SETZM	CACHEL		;FLUSH CACHE
ESC.X1:	CALL	SIMXCT		;EXECUTE THE NEXT INSTRUCTION
	TXNE	FLG,F.HALT	;DID THE PDP11 HALT ?
	JRST	ESCX73		;YES
	TXNN	FLG,F..ESC	;DOING $$X ?
	JRST	ESC.X7		;NO
	MOVE	T1,SIMREG+PC	;GET CURRENT PC
	CAIL	T1,(AC4)	;RETURN FROM SUBROUTINE ?
	CAILE	T1,30(AC4)	;IN CASE OF ARGUMENT LIST
	CAIA
	JRST	ESC.X9
	SKPINC			;OPERATOR IMPATIENT ?
	JRST	ESC.X1		;DO ANOTHER INSTRUCTION
	JRST	ESC.X9
;HERE AFTER DOING INSTRUCTION FOR $X
ESC.X7:	AOBJN	AC3,ESC.X1	;IF WANT MORE DO'EM
	CAMN	PS,BEG.PS	;DID THE PS CHANGE ?
	JRST	ESCX73
	TXO	FLG,F.FLIP	;HAVE TYPED A REGISTER
	MOVEI	T1,[ASCIZ \PS/   \]
	CALL	TYPSTR
	HRRZ	T1,PS
	CALL	RADTYP
	CALL	B3.TYP		;TYPE A FEW SPACES

;HERE TO DISPLAY REGISTERS WHICH CHANGED
ESCX73:	MOVSI	AC4,-7
ESCX74:	MOVE	T1,SIMREG(AC4)
	CAME	T1,BEGREG(AC4)
	CALL	[TXO	FLG,F.FLIP	;HAVE TYPED A REGISTER
		HRRZ	DOT,AC4		;COPY REG ADR
		HRLI	DOT,400000
		JRST	COMLF1 ]
	AOBJN	AC4,ESCX74
	CAME	AC3,[1,,1]	;DID WE EXECUTE ONE INSTRUCTION
	JRST	ESC.X8		;MORE THAN ONE SO DON'T TRY TO TYPE OPERANDS

;HERE TO DISPLAY OPERANDS AFTER LAST INSTRUCTION
	MOVE	T1,AC1		;GET PC WE EXECUTED
	HRRO	DOT,AC1		;CURRENT LOCATION
	SETZM	DOTFOO
	MOVEI	T2,2		;WANT TWO BYTES
	CALL	GETWRD		;TRY TO GET THE INSTRUCTION
	JRST	ESC.X8		;CAN'T GET = DONE
	AOS	BEGREG+PC
	AOS	BEGREG+PC
	MOVEM	T1,DATA		;SAVE FOR FUTUTR REFERENCE
	CALL	INVLFN		;TRY TO FIND SYMBOL
	JRST	ESC.X8		;CAN'T FIND = DONE
	LDB	T1,[POINT 6,DATA,29]
	HLL	SYM,2(SYM)	;GET FLAGS FOR INSTRUCTION
	TLNE	SYM,SMF.SS
	CALL	[CAIE	T1,27		;IMMEDIATE ?
		JRST	ESC.X3		;PRINT DATA FOR FIRST OPERAND
		MOVEI	T1,2
		ADDM	T1,BEGREG+PC	;ADJUST OLD PC FOR THIS
		RET	]
	LDB	T1,[POINT 6,DATA,35]
	TLNE	SYM,SMF.DD!SMF.SS
	CALL	ESC.X3
ESC.X8:	TXZE	FLG,F.FLIP	;DID WE TYPE ANY REGISTERS ?
	CALL	CRLTYP		;YES SO FINISH OLD STUFF WITH A FLOURISH

;HERE WHEN $X OR $$X IS FINISHED TO TYPE NEXT INSTRUCTION
ESC.X9:	CALL	B3.TYP
	HRRO	DOT,SIMREG+PC	;SET UP DOT TO CALL DATYPE
	PUSH	P,O.MODE	;SAVE OLD OUTPUT MODE
	PUSH	P,BYTCNT	;SAVE OLD BYTE COUNT
	SETZM	O.MODE		;SET INSTRUCTION MODE
	MOVEI	T1,1
	HRRM	T1,BYTCNT
	CALL	COMLF1		;TYPE OUT INSTRUCTION
	POP	P,BYTCNT
	POP	P,O.MODE
	JRST	LEVEL1
ESC.X3:	TRNN	T1,70		;IS THIS REGISTER MODE ?
	RET			;ALREADY GAVE CHANGE
	LSHC	T1,-3		;LEAVE ONLY MODE IN T1
	LSH	T2,-^D33	;RIGHT JUSTIFY REG NUMBER
	HRR	DOT,BEGREG(T2)
	CAIN	T1,1		;WAS THIS REGISTER DEFERRED
	JRST	ESCX35		;YES SO WE HAVE ADR NOW
	CAIG	T1,3		;IS THIS AUTO INCREMENT ?
	JRST	[AOS	BEGREG(T2)
		TLNE	SYM,SMF.BY
		CAIL	T2,6
		AOS	BEGREG(T2)
		JRST	ESCX33 ]
	CAIG	T1,5		;IS THIS AUTO DECREMENT ?
	JRST	[SOS	BEGREG(T2)
		TLNE	SYM,SMF.BY
		CAIL	T2,6
		SOS	BEGREG(T2)
		HRR	DOT,BEGREG(T2)
		JRST	ESCX33]
	PUSH	P,T1
	PUSH	P,T2
	MOVE	T1,BEGREG+PC
	MOVEI	T2,2		;WANT TWO BYTES
	CALL	GETWRD
	SETZ	T1,
	HRRZ	DOT,T1
	POP	P,T2
	POP	P,T1
	AOS	BEGREG+PC
	AOS	BEGREG+PC
	ADD	DOT,BEGREG(T2)
ESCX33:	ANDI	DOT,177777	;STRIP EXTRA BITS
	TRNN	T1,1		;IS THIS DEFERRED MODE ?
	JRST	ESCX35
	MOVE	T1,DOT		;COPY ADDRESS
	MOVEI	T2,2
	CALL	GETWRD
	RET
	HRRZ	DOT,T1
ESCX35:	TXO	FLG,F.FLIP	;REMEMBER WE TYPED DATA
	ANDI	DOT,177777	;STRIP EXTRA BITS
	HRROS	DOT		;FLAG IS MEMORY LOCATION
	PUSH	P,DATA
	PUSH	P,SYM		;SAVE POINTER TO SYMBOL FOR INSTRUCTION
	PUSH	P,O.MODE	;SAVE OUTPUT MODE
	PUSH	P,BYTCNT	;AND SAVE OUTPUT COUNT
	HRRZ	T1,O.MODE	;GET OUTPUT MODE
	SKIPN	T1
	MOVEI	T1,1		;USE ADDRESS INSTEAD OF INSTRUCTION
	MOVEI	T2,2		;ASSUME TWO BYTES OF OUTPUT
	CAIG	T1,2		;WORD MODE OUTPUT ?
	MOVEI	T2,1		;ONLY ONE WORD
	TLNE	SYM,SMF.BY	;BYTE MODE INSTRUCTION ?
	JRST	[CAIG	T1,2		;ALREADY BYTE MODE OUTPUT ?
		MOVEI	T1,3		;SET BYTE MODE OUTPUT
		MOVEI	T2,1		;ONLY ONE BYTE OF OUTPUT
		JRST	.+1 ]
	MOVEM	T1,O.MODE	;SET NEW OUTPUT MODE
	HRRM	T2,BYTCNT	;AND BYTE COUNT
	CALL	COMLF2		;TYPE ADR AND DATA
	POP	P,BYTCNT
	POP	P,O.MODE
	POP	P,SYM		;GET SYMBOL POINTER BACK
	POP	P,DATA
	RET
;HERE BECAUSE USER TYPED $Y - INVOKES A COMMAND FILE
ESC..Y:	TYPE	<
	Log responses where: >
	CALL	ESC.D0		;SET UP TO CALL OPNFIL
	SETZ	T1,		;NO DEFAULT FILE NAME
	CALL	OPNFL0
	NOP			;NO LOG FILE SO JUST GO TO TTY
	TXZ	FLG,F.WRIT!F.APND	;REMEMBER WE ARE READING
	MOVE	T1,[SIXBIT \DDT11\]
	MOVE	T2,[SIXBIT \DDTCMD\]	;DEFAULT EXTENSIONS
	MOVE	T3,[CMDDSP,,CMDSWL]
	MOVEI	T4,RSKP
	PUSH	P,OHD		;IN CASE LOGGING
	SETZM	OHD
	CALL	OPNFIL
	JRST	LEVEL0
	POP	P,OHD
	CALL	ESC.D3		;PUT TITLE LINE ON DUMP
	TXZ	FLG,F.CERR	;NO COMMAND ERRORS YET
	SETZM	CSECHO		;NOT SUPPRESSING ECHO YET
	SETOM	CMDFIL
	SETZM	CMDCNT		;AT FIRST CHAR
	SETZM	CMDFAK
	JRST	LEVEL0
;HERE TO GET A CHAR FROM A COMMAND FILE
CMDCH1:	SETZM	CMDFAK
CMDCHR:	SKIPE	T1,CMDFAK	;PREVIOUS "^ATEXT^A" TO HANDLE ?
	JRST	[CAMN	T1,[POINT 6,CMDFAK+1,35]
		JRST	CMDCH1
		ILDB	T1,CMDFAK	;GET NEXT CHAR
		JUMPE	T1,CMDCH1	;IF BLANK HIT END
		MOVEI	T1,40(T1)	;CONVERT TO ASCII
		JRST	CMDCH8 ]
	CALL	FILCHR
	JRST	CMDONE		;DONE WITH COMMAND FILE
	AOS	CMDCNT		;COUNT CHARACTERS INTO FILE
	CAIN	T1,177		;IS THIS A RUBOUT ?
	JRST	CMDCHR		;IGNORE IT
	CAIN	T1,1		;IS THIS A "^A"
	JRST	CMDSUB		;SPECIAL SUBSTITUTION
	SKIPGE	CSECHO		;SEARCHING FOR A TAG ?
	JRST	CMDCH8		;YES SO XON, XOF STUFF
	CAIN	T1,37&"S"	;IS THIS AN XOF ?
	JRST	[HLLOS	CSECHO		;YES SHUT OFF ECHOING
		JRST	CMDCHR ]	;ON TO NEXT CHAR
	CAIN	T1,37&"Q"	;IS THIS AN XON ?
	JRST	[HLLZS	CSECHO		;YES SO TURN ECHOING BACK ON
		JRST	CMDCHR ]	;ON TO NEXT CHARACTER
CMDCH8:	SKIPE	CSECHO		;DOING AN ECHO ?
	JRST	RSKP
	PUSH	P,T1		;SAVE CHARACTER
	CAIN	T1,33		;IS THIS AN ALTMODE ?
	MOVEI	T1,"$"		;YES SO ECHO RIGHT
	CALL	TYPCHR
	JRST TPOPJ1		;GET CHAR BACK, AND SKIP RETURN

CMDSUB:	CALL	SAVE24
	MOVE	T4,[POINT 6,CMDFAK+1]
	SETZM	CMDFAK+1
CMDCH2:	CALL	FILCHR		;GET NEXT CHAR
	JRST	CMDCH7
	AOS	CMDCNT		;COUNT THIS CHAR
	CAIN	T1,1		;IS THIS THE TRAILING "^A" ?
	JRST	CMDCH4		;GO EVALUATE WHAT WE HAVE
	CAIL	T1,"A"+40	;CHECK FOR LC
	CAILE	T1,"Z"+40
	TRC	T1,40		;CONVERT TO SIXBIT
	CAME	T4,[POINT 6,CMDFAK+1,35]
	IDPB	T1,T4
	JRST	CMDCH2
CMDCH4:	MOVE	T1,CMDFAK+1	;GET SYMBOL WE BUILT
	CALL	SYMFND		;SEE IF THERE IS A SYMBOL FOR THIS
CMDCH7:	JRST	[MOVEI	T1,1		;THIS IS HIS "^A"
		JRST	CMDCH8 ]
	PUSH	P,[EXP CMDCHR]
	MOVE	T1,1(SYM)	;GET VALUE
	MOVE	T3,[POINT 6,CMDFAK+1]
	MOVEM	T3,CMDFAK
	SETZM	CMDFAK+1
	MOVE	T4,ORADIX
CMDCH6:	IDIVI	T1,(T4)
	HRLM	T2,(P)
	SKIPE	T1
	PUSHJ	P,CMDCH6
	HLRZ	T1,(P)
	IORI	T1,20		;CONVERT TO SIXBIT
	IDPB	T1,T3
	RET
;HERE WHEN DONE WITH A COMMAND FILE
CMDONE:	SKIPE	SYM,SYMBEG	;POINTER TO BEGINING OF SYMBOL TABLE
CMDDN1:	CAMN	SYM,SYMEND	;HIT END YET ?
	JRST	CMDDN7		;DONE
	LDB	T1,[POINT 6,(SYM),5]
	CAIN	T1,'  %'
	JRST	[MOVE	T1,(SYM)	;GET SYMBOL
		CALL	DELSYM		;FLUSH SYMBOL
		JRST	CMDONE ]	;GO GET REST
	MOVEI	SYM,4(SYM)	;POINT TO NEXT SYMBOL
	JRST	CMDDN1		;CHECK IT
CMDDN7:	SETZM	CMDFIL		;DONE WITH FILE NOW
	CALL	DONE.W		;IN CASE LOGGING COMMANDS
	TYPE	<
	Finished command file

>
	RET

CSECHO:	Z			;IF NONZERO SUPPRESS ECHOING COMMAND CHARACTERS
			; LH SET -1 IF SEARCHING FOR A TAG
			; RH SET -1 IF ENCOUNTER XOF, CLEARED WITH XON
CMDFIL:	Z
CMDCNT:	Z			;COUNT OF CURRENT COMMAND CHARACTER
CMDDSP:
CMDSWL:	Z
	Z
CMDFAK:	Z			;POINTER TO FOLLOWING WORD
	Z
;HERE FOR (ALTMODE)N WHICH IS NOT WORD SEARCH
ESC..N:	TROA	FLG,F.FLIP	;FLAG WE ARE DOING NOT SEARCH

;HERE FOR (ALTMODE)W WHICH IS WORD SEARCH
ESC..W:	TXZ	FLG,F.FLIP	;FLAG WE WANT MATCHES
	MOVE	T1,EXPRESS	;GET WHAT TO SEARCH FOR
	AND	T1,S.MASK
	MOVEM	T1,S.WORD
	MOVE	DOT,SBEGIN
	SETZM	CACHEL		;NOTHING IN CACHE SO FAR
	TXO	FLG,F.CACH	;USE CACHE IF WE CAN
ESC.W2:	HRROS	T1,DOT		;COPY ADR (FLAG MEMORY ADR)
	HRRZ	T2,S..END
	ADDI	T2,2
	SUB	T2,T1		;NUMBER OF WORDS TO GET TO FINSIH SEARCH
	CAILE	T2,EXMAX
	MOVEI	T2,EXMAX	;MAXIMUM NUMBER OF WORDS FOR THIS REQUEST
	CALL	GETWRD
	JRST	ESCW.9
	MOVEM	T1,DATA		;SAVE DATA
	AND	T1,S.MASK	;MASK SOME OF THE BITS
	TXNE	FLG,F.FLIP	;ARE WE LOOKING FOR MATCH ?
	JRST	[	CAMN	T1,S.WORD	;DON'T WANT MATCH
			JRST	ESCW.8
			JRST	ESCW.6 ]
	CAME	T1,S.WORD
	JRST	ESCW.8
ESCW.6:	CALL	CRLTYP
	MOVE	T1,DOT		;GET ADDRESS
	CALL	ADRTYP
	TYPE	</	>
	CALL	DATYPE
	SKPINC			;ANY TYPEAHEAD ?
	JRST	ESCW.8
	JRST	ESCW.9		;YES SO STOP
ESCW.8:	CALL	NXTDOT		;GET NEXT DOT
	HRRZ	T1,DOT
	CAMLE	T1,S..END
	JRST	ESCW.9
	TRNN	DOT,377		;DON'T DO TOO MANY UUO'S
	SKPINC			;TYPING AHEAD ?
	JRST	ESC.W2		;NO
ESCW.9:	TYPE	<
<search done>
>
	JRST	LEVEL1
	SUBTTL	ROUTINES TO HANDLE PDP11 MEMORY

;ROUTINE TO GET A WORD FROM THE PDP-11
; CALL	CALL	GETWRD		;WITH ADR IN T1, NUMBER OF BYTES IN T2
;	ERROR RETURN	ERROR CODE IN T1
;	SUCCES	DATA IN T1
GETWRD:	CALL	SAVE35		;SAVE T3, T4, & T5
	ANDI	T1,177777
	SKIPE	PDP8F
	ANDI	T1,077777	;STRIP EXTRA BITS
	SKIPN	T2
	HALT
	SKIPE	CACHEL		;IS THERE DATA IN CACHE ?
	TXNN	FLG,F.CACH	;AND MAY WE USE CACHE ?
	JRST	GETWD1		;NO CACHE OR CAN'T USE IT
	CAMGE	T1,CACHEL	;IS REQUEST TOO LARGE ?
	CAMGE	T1,CACHEA	;OR TOO SMALL
	JRST	GETWD1		;NO
GETWD0:	MOVE	T4,[POINT 8,CACHE]	;POINTER TO CACHE
	SKIPE	PDP8F
	MOVE	T4,[POINT 12,CACHE]
	MOVE	T3,T1		;COPY ADDRESS OF BYTE TO GET
	SUB	T3,CACHEA	;MAKE RELATIVE
	CAIA
	IBP	T4		;SKIP NEXT BYTE
	SOJGE	T3,.-1
	ILDB	T1,T4		;GET LOW ORDER BYTE OF REQUESTED WORD
	SKIPE	PDP8F
	JRST	GETWD3
	ILDB	T2,T4		;GET HIGH ORDER BYTE OF REQUESTED WORD
	DPB	T2,[POINT 8,T1,27]
GETWD3:	ANDI	T1,-1		;STRIP EXTRA BITS
	AOS	(P)		;SKIP RETURN
	RET

GETWD1:	MOVE T4,ETYPE
	JRST	@[GETMEM		;MEMORY
		  GET.C1		;CALL-11
		  GETNOD		;NODE. UUO
		  GET.FE		;FE0 ON TOPS-20
		  GET.C1		;DN60 ON TOPS-10
		  GETD62		;DN60 ON TOPS-20, BOTH DN20 AND DN22
		  GETNYI		;MCB
		  GT.F10](T4)		;FE0 ON TOPS-10

GETNYI:	TYPE <No code for reading from that type of device.
>
	JRST LEVEL2

;HERE TO DO CALL11 UUO TO GET DATA
GET.C1:	SETZ T4,
	HRRZM T1,T3
GETWDR:	MOVEI T2,1		;FUNCTION 1
	MOVE T1,[3,,T2]
	HRL T2,PORT		;ADD PORT NUMBER
	CAL78. T1,
	SKIPA T1,[3,,T2]
	JRST GETWD2
	CAL11. T1,
	JRST [	CAIE T1,4	;ERROR 4, ?ALREADY IN USE?
		JRST R		;NO, ERROR RETURN
		MOVE T1,^D100	;WAIT A WHILE
		HIBER T1,	;SEE HOW LONG IT TAKES
		 JRST R
		JRST GETWDR]	;AND TRY AGAIN
GETWD2:	HRRZ	T2,T3		;GET ADDRESS WE WERE GETTING

GTWD2A:	CALL	PUTBCH		;PUT BYTE INTO THE CACHE
	LSH	T1,-^D8		;ADJUST DATA
	AOS	T2
	CALL	PUTBCH		;ALSO HIGH ORDER BYTE
	MOVE	T1,T3		;GET ADDRESS AGAIN
	MOVEI	T2,2		;NUMBER OF BYTES TO GET
	JRST	GETWD0		;GET DATA FROM THE CACHE

GETD62:	CALL	D62EXM			;examine DN60/TOPS20 FE
	SKIPA	T1,AC1			;move error code to the right place
	SKIPA	T3,T2			;suc'd - move address for GETWD2
	RET
	JRST	GTWD2A
;HERE TO GET A WORD FROM CORE IN 10 MEMORY
GETMEM:	MOVE T4,MEMORY
	CAMLE	T1,MEMLIM	;IS IT IN RANGE ?
	JRST	[HRRZ	MA,T1		;ADR WE WANT
		CALL	IOLOAD-1
		JRST	R		;ERROR RETURN
		JRST	GETWD3 ]	;WON
	SKIPE	PDP8F
	JRST	GTMEM8		;GET WORD OF 8 MEMORY
	IDIVI	T1,4		;WE KEEP 4 BYTES IN 36BIT WORD
	ADD	T1,MEMORY	;ADD RELOCATION
	TRNE	T2,2
	SKIPA	T1,(T1)
	HLR	T1,(T1)
	TRNE	T2,1		;DID HE ASK FOR LH BYTE ?
	LSH	T1,-^D8		;YES
	JRST	GETWD3

;HERE TO GET A PDP8 WORD FROM CORE IN 10 MEMORY
GTMEM8:	IDIVI	T1,2
	ADD	T1,MEMORY	;RELOCATE
	LDB	T1,[POINT 18,(T1),17
		    POINT 18,(T1),35 ](T2)
	ANDI	T1,007777
	JRST	GETWD3
;HERE TO EXAMINE MEMORY FROM ANOTHER NETWORK NODE
GETNOD:	CALL	SETUPN		;BEGIN BUILDING MSG<LINE><CODE><ADR>
	EXP	1		;CODE FOR EXAMINE REQUESTS IS 1
	MOVEM	T1,T3		;SAVE ADDRESS
	ADDI	T1,(T2)		;MAKE LIMIT ADDRESS
	CALL	PUTADR		;PUT LIMIT ADDRESS INTO THE MESSAGE
	CALL	NODSET		;DO NODE UUO
	JRST	R		;ERROR RETURN
	CAIE	T1,12		;CODE FOR EXAMINE DATA IS 12
	JRST	STCERR
	PUSH	P,T3		;SAVE ADDRESS WE WENT FOR
	HLRZ	T3,NODARG+3	;GET BYTE COUNT FROM MSG
	SUBI	T3,4		;SUBTRACT BYTES WE ALREADY READ
	ILDB	T2,T4		;GET LOW ORDER 8 BITS OF ADDRESS
	ILDB	T1,T4		;GET HIGH ORDER 8 BITS
	DPB	T1,[POINT 8,T2,27]
	SKIPE	PDP8F
	JRST	GTNOD3
	SOS	T3		;COUNT BYTE
	ILDB	T1,T4
	DPB	T1,[POINT 8,T2,19]
GTNOD3:	ILDB	T1,T4		;GET NEXT BYTE OF DATA
	SKIPN	PDP8F
	JRST	GTNOD4
	PUSH	P,T1		;SAVE LOW ORDER BITS
	ILDB	T1,T4		;GET HIGH ORDER BITS
	DPB	T1,[POINT 6,(P),29]
	POP	P,T1
	SOS	T3		;KEEP COUNT HONEST
GTNOD4:	CALL	PUTBCH		;PUT BYTE INTO THE CACHE
	AOS	T2		;ADVANCE ADDRESS
	SOJG	T3,GTNOD3
	POP	P,T1		;GET ADDRESS WE WENT FOR
	JRST	GETWD0
;HERE TO GET DATA FROM A /FE DEVICE
GET.FE:	MOVE T3,[BYTE (16)IO.RLB(8)"E","M"]
	MOVEM T3,FE.MSG
	SETZM FE.MSG+1
	SETZM FE.MSG+2
	PUSH P,T1		;SAVE THE ADDR
	LSH T1,24
	HRRI T1,2*20
	MOVEM T1,FE.MSG+2	;BYTE(16)ADR,2
	MOVE AC1,FE.JFN		;GET JFN FOR FE DEVICE
	MOVE AC2,[442000,,FE.MSG]
	MOVNI AC3,6
	SOUT
	ERJMP TPOPJ
	MOVEI AC2,.MOEOF
	SETO AC3,
	MTOPR
	ERJMP TPOPJ
	CALL GETFEM		;GET RESPONSE
	JRST TPOPJ		;ERROR RETURN
	LDB T1,[POINT ^D16,FE.MSG+3,15]
	POP P,T3		;GET ADR OFF STACK
	JRST GETWD3		;ERROR RETURN

GETFEM:	MOVE	AC2,[POINT 16,FE.MSG]	;POINTER TO FRONT END MESSAGE
	MOVNI	AC3,6
	SIN			;GET IT
	ERJMP	R
	LDB	AC3,[POINT 16,FE.MSG+2,31]
	JUMPLE	AC3,GTFEM3	;NO MORE
	LSH AC3,-1		;CONVERT TO WORDS
	MOVN	AC3,AC3
	SIN
	ERJMP	R
GTFEM3:	LDB	T1,[POINT 8,FE.MSG+1,31]
	MOVN	T1,T1		;RETURN STATUS
	ANDI	T1,377
	TRNE	T1,200
	RETSKP
	RET


	;HERE TO DO THE WORK UNDER TOPS-10

GT.F10:	HRLI	T1,IO.RLB		;SET UP HEADER FOR READ FCN
	PUSHJ	P,ME.SET		;...
	MOVE	T1,[.DTEOF,,FE.CPU]	;DO OUTPUT
	DTE.	T1,			;TO ME: (PLEASE)
	 JRST	[DTEERR: TRO	T1,400	;Make DTE. error codes distinct
		 RET]
	PUSHJ	P,FE.RPY		;READ THE REPLY
	 POPJ	P,			;ERROR
	CAILE	T1,FE.MAX		;TOO MUCH DATA?
	 JRST	[FE$BLT:TYPE	<
?Bad PDP-11 Message>
		 JRST	DDT11]		;YES, WE LOSE SYNC
	ASH	T1,-1			;BYTES TO WORDS
	HRLI	T1,FE.MSG+3		;WHERE TO PUT DATA
	MOVSM	T1,FE.BUF
	MOVE	T1,[.DTEIF,,FE.CPU]	;READ IT
	DTE.	T1,			;...
	 JRST	DTEERR
	LDB	T1,[POINT 16,FE.MSG+3,17] ;DATA
	JRST	GETWD3

	;SUBROUTINE TO SET UP A MESSAGE HEADER FOR THE ME: DEVICE
	;CALL WITH T1/ IO.xLB,,ADDRESS

ME.SET:	HLLZM	T1,FE.MSG+0		;SET IO FUNCTION
	HRLI	T1,2			;DATA BYTES TO BE TRANSFERED
	MOVSM	T1,FE.MSG+2		;(PARAM-2,,BYTE-CNT)
	SETZM	FE.MSG+1		;(UNIT,,PARAM-1)
	MOVEI	T1,(<BYTE (2)0(8)"E","M">) ;SET DEVICE NAME
	HRRM	T1,FE.MSG+0		;IN HEADER
	MOVE	T1,[<14/2>,,FE.MSG]	;WORD COUNT TO SEND,,ADDRESS
	MOVEM	T1,FE.BUF		;FOR FEDSER
	POPJ	P,			;ALL SET

	;SUBROUTINE TO READ ME: REPLY HEADER
	;NON-SKIP T1 IS ERROR CODE, SKIP T1 IS # DATA BYTES TO FOLLOW

FE.RPY:	MOVE	T1,[<14/2>,,FE.MSG]	;READ HEADER ONLY
	MOVEM	T1,FE.BUF		;SET UP FOR UUO
	MOVE	T1,[.DTEIF,,FE.CPU]	;READ DATA FUNCTION
	DTE.	T1,			;...
	 JRST	DTEERR			;OOPS!
	LDB	T1,[POINT 8,FE.MSG+1,35] ;GET $DSW
	MOVNS	T1			;MAKE ERRORS POSITIVE
	ANDI	T1,377			;...
	TRNN	T1,200			;ERROR?
	 POPJ	P,			;YES, RETURN IT
	LDB	T1,[POINT 16,FE.MSG+2,35] ;HOW MUCH DATA FOLLOWS?
	RETSKP
;HERE TO BEGIN A NODE UUO MSG <LINE><CODE><ADDRESS>
; CALL	MOVE	T1,<ADR>
;	CALL	SETUPN
;	EXP	<CODE>
SETUPN:	PUSH	P,T1		;SAVE ADDRESS
	MOVE	T4,[POINT 8,STCMSG]	;POINTER TO STATION CONTROL MSG
	MOVE	T1,LINE		;0 = SELF, 1-N IS LINE NUMBER
	IDPB	T1,T4		;MSG IS FOR NODE
	MOVE	T1,@-1(P)	;GET CODE
	IDPB	T1,T4
	POP	P,T1		;GET ADDRESS BACK
	CALL	PUTADR		;PUT ADDRESS INTO THE MESSAGE
	RETSKP

;HERE TO PUT AN ADDRESS IN A NODE UUO STRING
PUTADR:	PUSH	P,T1
	SKIPE	PDP8F
	ANDI	T1,077777	;STRIP EXTRA BITS
	IDPB	T1,T4		;PUT LOW ORDER BYTE OF ADR INTO MSG
	ROT	T1,-^D8
	IDPB	T1,T4
	ROT	T1,-^D8
	SKIPE	PDP8F
	JRST	TPOPJ
	IDPB	T1,T4
TPOPJ:	POP	P,T1
	RET
;HERE TO DO A NODE UUO
; CALL	CALL	NODSET
;	ERROR RETURN	CODE IN T1
;	RETURNS WITH T4 POINTING TO INPUT MSG AND CODE IN T1
NODSET:	PUSH	P,[POINT 8,STCMSG]
	MOVEI	T1,1		;INITIALIZE LENGTH COUNTER
NODSE1:	IBP	(P)		;ADVANCE DUMMY POINTER
	CAME	T4,(P)
	AOJA	T1,NODSE1
	HRLI	T1,STCMSG
	MOVSM	T1,NODARG+2
	POP	P,T1		;CLEAN OFF STACK
	MOVEI	T1,4		;NUMBER OF WORDS IN ARGUMENT
	MOVEM	T1,NODARG
	MOVE	T1,NODE		;NODE NAME
	MOVEM	T1,NODARG+1
	MOVE	T1,[400,,STCIMS]	;INPUT MSG SLOT
	MOVEM	T1,NODARG+3
	MOVE	T1,[3,,NODARG]	;FUNCTION IS SEND STC MSG
	NODE.	T1,
	RET			;ERROR RETURN
	MOVE	T4,[POINT 8,STCIMS]	;POINTER TO INPUT MESSAGE
	ILDB	T1,T4		;GET FIRST BYTE (= LINE# OR SELF)
	CAME	T1,LINE
	JRST	CALER0		;DESCRIBE FAULT
	ILDB	T1,T4		;GET MESSAGE SUBTYPE
	RETSKP

STCERR:	TYPE	<STC error - msg =>
	HLRZ	T4,NODARG+3
	SKIPA	T5,[POINT 8,STCIMS]
STCER3:	CALL	COMTYP		;TYPE A COMMA
	MOVEI	T1,"<"
	CALL	TYPCHR
	ILDB	T1,T5
	CALL	OCTYPE
	MOVEI	T1,">"
	CALL	TYPCHR
	SOJG	T4,STCER3
	SETO T1,		;SAY WE PRINTED THE ERROR
	RET
;HERE TO PUT A BYTE INTO THE CACHE
; CALL	MOVE	T1,<BYTE>
;	MOVE	T2,<ADR>
;	CALL	PUTBCH
;	RETURN
PUTBCH:	PUSH	P,T1
	PUSH	P,T2
	PUSH	P,T3
	PUSH	P,T4
	SKIPE	T3,CACHEL	;IS CACHE EMPTY ?
	CAMG	T2,CACHEA	;IS NEW BYTE BELOW CACHE ADDRESS ?
	JRST	PTBCH2		;FLUSH CACHE
	SUB	T3,CACHEA	;HOW MANY BYTES ALREADY IN THE CACHE ?
	CAIGE	T3,CACHSZ	;SMALL ENOUGH ?
	JRST	PTBCH1		;YES
	MOVEI	T3,4		;REDUCE CONTENTS BY 4 BYTES = ON 10 WORD
	SKIPE	PDP8F
	MOVEI	T3,3		;REDUCE CONTENTS BY 3 WORDS = ONE 10 WORD
	ADDM	T3,CACHEA
	MOVE	T3,[CACHE+1,,CACHE]	;BLT POINTER
	BLT	T3,CACHE+<CACHSZ/4>-1	;SHUFFLE CACHE
PTBCH1:	CAMN	T2,CACHEL	;ARE TRYING TO ADD ONE BYTE TO CACHE ?
	JRST	PTBCH4		;YES
PTBCH2:	MOVEM	T2,CACHEA	;BEGIN CACHE HERE
PTBCH4:	MOVEM	T2,CACHEL	;THIS IS THE NEW CACHE LIMIT
	AOS	CACHEL		;MAKE ONE PLUS
	SUB	T2,CACHEA	;HOW MANY BYTES TO NEW BYTE ?
	MOVE	T3,[POINT 8,CACHE]
	SKIPE	PDP8F
	MOVE	T3,[POINT 12,CACHE]
	CAIA
	IBP	T3
	SOJGE	T2,.-1
	IDPB	T1,T3		;PUT BYTE INTO THE CACHE
	POP	P,T4
	POP	P,T3
	POP	P,T2
	JRST TPOPJ
;ROUTINE TO DEPOSIT BYTES IN PDP-11 MEMORY
; CALL	MOVE	T1,<ADR TO DEPOSIT TO>
;				;DATA STARTS AT DATA - DAT POINTS TO LAST BYTE
;	CALL	PUTBYT		;WITH ADR IN T1
;	LOSE RETURN <CODE IN T1>
;	WIN RETURN

PUTBYT:	CALL	SAVE35		;SAVE T3, T4, & T5
	MOVE	T5,DAT		;SAVE POINTER TO LAST DATA BYTE
	SKIPE	PDP8F
	SKIPA	T2,[POINT 12,DATA]
	MOVE	T2,[POINT 8,DATA]
	MOVEM	T2,DAT
	MOVE T4,ETYPE
	JRST	@[PUTMEM		;MEMORY
		  PUT.C1		;CALL-11
		  PUTNOD		;NODE. UUO
		  PUT.FE		;FE0 ON TOPS-20
		  PUT.C1		;DN60 ON TOPS-10
		  PUTD62		;DN60 ON TOPS-20, BOTH DN20 AND DN22
		  PUTNYI		;MCB
		  PUT.FE](T4)		;20F/TOPS-10

PUTNYI:	TYPE <No code for a write to this type of device.
>
	JRST LEVEL2
;HERE WHEN PUTTING BYTES WITH CAL11. OR CAL78. UUO'S
PUT.C1:	MOVEM	T1,T3		;SAVE ADR TO DEPOSIT INTO
PUTP.2:	ILDB	T4,DAT		;GET LOW ORDER BYTE
	TRNN	T3,1
	CAMN	T5,DAT
	JRST	PUTP.4
	ILDB	T1,DAT		;GET HIGH ORDER BYTE
	DPB	T1,[POINT 8,T4,27]
PUTP.4:	MOVEI	T2,0		;FUNCTION 0
	MOVE	T1,[3,,T2]
	HRL	T2,PORT		;ADD PORT NUMBER
	CAL78.	T1,
	SKIPA	T1,[3,,T2]
	JRST	PUTP.8		;WIN RETURN
	CAL11.	T1,
	JRST [	CAIE T1,4	;ALREADY IN USE?
		JRST R		;NO, ERROR RETURN
		MOVEI T1,^D100	;WAIT A WHILE
		HIBER T1,	;AND SEE 
		 JRST R		;HIBER FAILED, GIVE IT UP.
		JRST PUTP.4]	;TRY AGAIN
PUTP.8:	HRRZI	T3,2(T3)
	TRZ	T3,1
	CAME	T5,DAT
	JRST	PUTP.2
	JRST	GETWD3		;WIN RETURN


; PUTD62 - stuff words into a TOPS20 DN60 FE
;	shamelessy(and probably foolishly) plagerized from PUT.C1

PUTD62:	MOVEM	T1,T3		;SAVE ADR TO DEPOSIT INTO
PT6.2:	ILDB	T2,DAT		;GET LOW ORDER BYTE
	TRNN	T3,1
	CAMN	T5,DAT
	JRST	PT6.4
	ILDB	T4,DAT		;GET HIGH ORDER BYTE
	DPB	T4,[POINT 8,T2,27]
PT6.4:	MOVE	T1,T3		;get the place to crammit
	CALL	D62DEP		; so deposit it
	SKIPA	T1,AC1		; loser
	JRST	PT6.8
	RET

PT6.8:	HRRZI	T3,2(T3)
	TRZ	T3,1
	CAME	T5,DAT
	JRST	PT6.2
	JRST	GETWD3		;WIN RETURN

;HERE WHEN PUTTING BYTES WITH NODE. UUO
PUTNOD:	CALL	SETUPN		;BEGIN NODE. MSG <LINE><CODE><ADR>
	EXP	2		;CODE FOR DEPOSIT IS 2
PUTND2:	ILDB	T1,DAT		;GET NEXT BYTE
	IDPB	T1,T4		;PUT NEXT BYTE INTO MESSAGE
	CAME	T5,DAT		;DONE ENOUGH YET ?
	JRST	PUTND2		;NOT YET
	CALL	NODSET		;SEND MSG
	JRST	R		;ERROR RETURN
	CAIE	T1,11		;DID WE GET AN ACCEPT ?
	JRST	STCERR
	JRST	GETWD3


	;DEAL WITH RSX20F/TOPS-10 DEPOSITS HERE
	;T1/<STARTING ADDRESS> T5/<BP TO LAST BYTE> DAT/<BP TO FIRST BYTE>


PUT.FE:	HRLI	T1,IO.WLB	;SET WRITE FCN
	PUSHJ	P,ME.SET	;SET UP HEADER
	MOVNI	T3,FE.MAX	;SET LIMIT ON DEPOSIT
	MOVE	T4,[POINT 18,FE.MSG+3] ;POINT TO DATA MESSAGE
PT.F1A:	ILDB	T1,DAT		;GET A BYTE
	TRNN	T3,1		;EVEN?
	IDPB	T1,T4		;COPY TO FE BUFFER
	TRNE	T3,1		;ODD?
	 JRST	[PUSH	P,T5	;SAVE END
		 MOVE	T5,T4	;AND GET LAST WORD DEPOSITED
		 ADD	T5,[100000,,0] ;POINT TO HIGH BYTE
		 TLC	T5,003200 ;AND CHANGE BYTE SIZE
		 DPB	T1,T5	;INSERT IT
		 POP	P,T5	;RESTORE END
		 JRST	.+1]	;...
	CAME	T5,DAT		;GOT LAST?
	 AOJL	T3,PT.F1A	;NO, DO NEXT
	JUMPGE	T3,[TYPE	<
? Deposit size exceeds 20F max>
		    RET]	;ERROR CODE RANDOM
	ADDI	T3,FE.MAX+1	;NUMBER OF BYTES ACTUALLY MOVED
	HRRM	T3,FE.MSG+2	;STUFF IN HEADER
	AOJ	T3,		;ROUND BYTES TO WORDS
	ASH	T3,-1		;AND CONVERT
	MOVSS	T3
	ADDM	T3,FE.BUF	;ADD TO AMT XFERED BY UUO
	MOVE	T1,OSTYPE	;GET OS TYPE
	TXNN	T1,T.TOP10	;TOPS-10?
	 JRST	PT.F20		;YES, DO THAT
	MOVE	T1,[.DTEOF,,FE.CPU] ;ZAP MSG OUT
	DTE.	T1,
	 JRST	DTEERR		;...
	PUSHJ	P,FE.RPY	;READ REPLY
	 RET			;ERROR, RETURN CODE
	SKIPE	T1		;IF ASSOCIATED
	 JRST	FE$BLT		;BLAT...DATA WITH WRITE REPLY IS BAD
	JRST	GETWD3		;OK, DONE

	;TOPS-20 DEPOSIT

PT.F20:	MOVE	AC1,FE.JFN	;GET THE JFN OF FE:
	MOVE	AC2,[POINT 18,FE.MSG] ;POINT TO MESSAGE
	HLRZ	AC3,FE.BUF	;GET WC FROM TOPS-10
	MOVNS	AC3		; - WC
	SOUT			;SLITHER
	 ERJMP	R		;BLAT
	MOVEI	AC2,.MOEOF	;FORCE BUFFER OUT
	SETO	AC3,		;BUT DON'T SEND EOF
	MTOPR			;FLOP
	 ERJMP	R
	CALL	GETFEM		;GET REPLY
	 RET
	SKIPE	AC3		;DATA WITH WRITE REPLY?
	 JRST	FE$BLT		;BLAT?
	JRST	GETWD3		;OK, DONE
;HERE WHEN PUTTING BYTES IN 11 MEMORY
PUTMEM:	MOVE T4,MEMORY		;GET THE START OF OUR MEMORY
	MOVEM	T1,T2		;PUT ADR IN OTHER REG
PTMEM2:	CAML	T2,MEMLIM	;IS ADR IN RANGE ?
	JRST	PTMEM4		;NO
	ILDB	T1,DAT		;GET NEXT BYTE OF DATA
	CALL	PUTFOO		;PUT LOW ORDER BYTE INTO MEMORY
	CAME	T5,DAT		;DONE ALL OF IT ?
	AOJA	T2,PTMEM2	;NO SO LOOP BACK FOR NEXT BYTE
	JRST	GETWD3

;HERE TO DEPOSIT IN SIMULATED DEVICES
PTMEM4:	MOVEM	T2,MA		;PUT ADDRESS IN CORRECT REG
	PUSH	P,T5		;SAVE LIMIT
PTMEM5:	ILDB	T1,DAT		;GET NEXT BYTE OF DATA
	MOVE	T2,(P)		;GET LIMIT
	CAME	T2,DAT		;IS THIS LAST BYTE TO DEPOSIT ?
	TRNE	MA,1		;IS THIS AN ODD BYTE ?
	JRST	PTMEM6		;MUST USE BYTE STORE
	ILDB	T2,DAT		;GET LH OF WORD
	DPB	T2,[POINT 8,T1,27]
	CALL	IOSTOR		;STORE THE WORD
	JRST	PTMEM7
PTMEM6:	CALL	IOBSTO		;TRY TO WRITE BYTE IN THE IO AREA
PTMEM7:	MOVE	T1,(P)		;GET LIMIT
	CAME	T1,DAT		;DONE ALL OF IT
	AOJA	MA,PTMEM5
	POP	P,T1		;CLEAN OFF STACK
	JRST	GETWD3		;WIN RETURN
;HERE TO PUT A BYTE INTO A CORE DUMP
; CALL	CALL	PUTFOO	WITH DATA IN T1, ADR IN T2
PUTFOO:	CALL	SAVE4
	PUSH	P,T1
	ANDI	T2,177777	;STRIP EXTRA BITS (& LH)
	PUSH	P,T2
	SKIPE	MEMORY		;DO WE HAVE A BASE ADDRESS FOR DUMPS ?
	JRST	PUTBY1
	CALL	POSYMT		;BE SURE SYMBOL TABLE IS WHERE IT BELONGS
	MOVE	T1,SYMBEG	;WHERE WE WILL PUT DATA
	HRRZM	T1,MEMORY	;POINT TO WHERE MEMORY WILL BE
	SETOM	MEMLIM
	HRLI	T1,T1		;MAKE MEMUSE POINTER
	MOVEM	T1,MEMUSE	;SAVE POINTER TO MEMORY USAGE TABLE
PUTBY1:	HRRZ	T2,(P)		;GET ADDRESS WE WANT OFF STACK
	CAMG	T2,MEMLIM	;IS ADDRESS LARGER THAN PREVIOUS LIMIT ?
	JRST	PUTBY4		;NO
	MOVEI	T1,4000		;GET ANOTHER 2K PDP10 WORDS
PUTBY2:	MOVE	T2,T1		;NUMBER OF PDP-10 WORDS TO ADD
	LSH	T2,2		;MAKES NUMBER OF PDP11 BYTES
	SKIPE	PDP8F
	LSH	T2,-1		;MAKES NUMBER OF PDP8 WORDS
	ADDM	T2,MEMLIM
	CALL	MOVSMT		;MOVE THE SYMBOL TABLE UP AGAIN
	MOVE	T1,MEMLIM	;GET SIMULATED MEMORY SIZE
	IDIVI	T1,^D36		;NEW SIZE FOR MEMUSE
	AOS	T1		;JUST IN CASE
	ADDI	T1,777		;ROUND TO NEXT PAGE
	ANDI	T1,777000	;ROUND TO NEXT PAGE
	SUB	T1,MEMORY
	ADD	T1,MEMUSE	;MAKES HOW MANY MORE WORDS WE NEED
	ANDI	T1,-1
	CALL	MOVMEM		;MOVE MEMORY TO ADJUST FOR THIS
	CALL	MAPCOR		;UPDATE MEMORY MAP
	JRST	PUTBY1		;BACK TO BE SURE THAT WAS ENOUGH
PUTBY4:	HRRZ	T1,(P)		;GET ADR OFF STACK
	IDIVI	T1,^D36		;CONVERT BYTE ADDRESS TO BIT ADDRESS
	MOVSI	T3,400000
	MOVNS	T2
	LSH	T3,(T2)		;POSITION BIT
	IORM	T3,@MEMUSE
	POP	P,T2
	POP	P,T1
	SKIPE	PDP8F
	JRST	PUTBY7
	IDIVI	T2,^D4
	ADD	T2,MEMORY	;RELOCATE
	DPB	T1,[	POINT 8,(T2),17
			POINT	8,(T2),9
			POINT	8,(T2),35
			POINT	8,(T2),27 ](T3)
	RET

;HERE TO PUT A PDP8 WORD IN MEMORY
PUTBY7:	IORI	T1,10000	;FLAG WORD IS HERE
	IDIVI	T2,2		;PUT 2 8 WORDS IN A PDP10 WORD
	ADD	T2,MEMORY	;RELOCATE
	DPB	T1,[	POINT 18,(T2),17
			POINT	18,(T2),35 ](T3)
	RET
;HERE TO MOVE MEMORY UP IN CORE
; CALL	MOVEI	T1,<AMOUNT TO MOVE IT UP>
;	CALL MOVEM
MOVMEM:	PUSH	P,T1		;SAVE ARGUMENT
	CALL	MOVSMT		;FIRST MOVE UP THE SYMBOL TABLE
	POP	P,T1		;NUMBER OF WORDS TO MOVE
	SKIPN	T2,MEMORY	;ADR OF 1ST WORD IN MEMORY
	RET
	ADDM	T1,MEMORY	;UPDATE MEMORY POINTER
	MOVE	T3,SYMBEG	;GET NEW SYMBOL TABLE POINTER
	SOS	T3		;IS NEW LAST WORD IN MEMORY
	CALL	MOVTAB		;MOVE IT
	JRST	SIMREL		;ADJUST SIMULATION TO NOTICE NEW LOCATIONS

;HERE TO MOVE MEMORY USE TABLE UP IN CORE
; CALL	MOVEI	T1,<AMOUNT TO MOVE IT UP>
;	CALL	MOVMUS
MOVMUS:	PUSH	P,T1		;SAVE ARGUMENT
	CALL	MOVSMT		;FIRST MOVE UP THE SYMBOL TABLE
	POP	P,T1		;NUMBER OF WORDS TO MOVE
	HRRZ	T2,MEMUSE	;ADR OF FIRST WORD IN MEMORY USE TABLE
	JUMPE	T2,R		;IF NO MEMORY WE'RE DONE
	ADDM	T1,MEMUSE	;UPDATE MEMORY USE TABLE ADR
	ADDM	T1,MEMORY	;AND MEMORY POINTER
	MOVE	T3,SYMBEG	;NEW SYMBOL TABLE ADR
	SOS	T3		;MAKES NEW LAST WORD IN MEMORY
	CALL	MOVTAB		;MOVE IT
	JRST	SIMREL		;ADJUST SIMULATION TO NOTICE NEW ADDRESSES

;HERE TO MOVE A TABLE UP IN CORE (BACKWARDS BLT)
; CALL	MOVE	T1,<# OR WORDS TO MOVE)
;	MOVE	T2,ADR OF 1ST WORD IN CORE TO BE MOVED
;	MOVE	T3,<ADR OF NEW LAST WORD IN BLOCK>
;	CALL	MOVTAB
MOVTAB:	MOVE	T4,T3		;COPY ADR OF LAST WORD IN BLOCK
	SUB	T3,T1		;MAKES LAST ADR IN OLD TABLE
MOVTB2:	MOVE	T1,(T3)		;GET NEXT WORD TO COPY
	MOVEM	T1,(T4)		;COPY IT
	SOS	T4
	CAME	T3,T2		;COPIED LAST WORD YET ?
	SOJA	T3,MOVTB2	;LOOP FOR MORE WORDS
	SETZM	(T2)		;CLEAR FIRST WORD IN TABLE
	HRLI	T2,(T2)		;BUILD BLT POINTER
	AOS	T2		;FINISH BUILDING POINTER
	BLT	T2,(T4)		;CLEAR OLD TABLE
	RET
SAVE13:
SAVE4:	PUSH	P,T1
	PUSH	P,T2
	PUSH	P,T3
	PUSH	P,T4
	CALL	@-4(P)
	CAIA
	AOS	-5(P)
	POP	P,T4
	POP	P,T3
	POP	P,T2
	POP	P,T1
	POP	P,(P)
	RET

SAVE2:	EXCH	T2,(P)
	CALL	(T2)
	CAIA
	AOS	-1(P)
	POP	P,T2
	RET

SAVE24:	EXCH	T2,(P)
	PUSH	P,T3
	PUSH	P,T4
	CALL	(T2)
	CAIA
	AOS	-3(P)
	POP	P,T4
	POP	P,T3
	POP	P,T2
	RET

SAVE34:
SAVE35:	EXCH	T3,(P)
	PUSH	P,T4
	PUSH	P,T5
	CALL	(T3)
	CAIA
	AOS	-3(P)
	POP	P,T5
	POP	P,T4
	POP	P,T3
	RET
NODARG:	BLOCK	5
STCMSG:	BLOCK	20
STCIMS:	BLOCK	110
	SUBTTL	TOPS-20 DN60 CRUFT

D6.EXM==11				; DN60 examine memory function code
D6.DEP==12				; DN60 deposit memory function code


; D62EXM - examine a TOPS-20 DN60 front end
;	T1/address to examine
; RETURNS:
;	false - AC1/error code
;	true  - T1/data
;		T2/address examined

D62EXW:	MOVEI	AC1,^D50
	DISMS

D62EXM:	CALL	FESUP			; get the port
	JRST	D62EXW			; can't have it yet
	SETZM	@D10DT			; set up the DN60 request header
	MOVEI	T2,D6.EXM
	DPB	T2,D10FN		; the appropriate function
	DPB	T1,D10AD		; and where
	CALL	PUTHDR			; Output the header to say read data
	RET
	CALL	GETHDR			; Get the response header
	RET
	LDB	T1,D11DT		; get the data
	LDB	T2,D11AD		; get the address back
	RETSKP				; and suc


; D62DEP - deposit word in TOPS-20 DN60 front end
;	T2/data to deposit
;	T1/address to stuff it
; RETURNS:
;	false - AC1/error code
;	true  - original args

D62DEW:	MOVEI	AC1,^D50
	DISMS

D62DEP:	CALL	FESUP			; get the port
	JRST	D62DEW			; all booked for now
	DPB	T2,D10DT		; set up the  DN60 request header
	DPB	T1,D10AD
	MOVEI	AC1,D6.DEP
	DPB	AC1,D10FN
	CALL	PUTHDR			; Output the transmit header
	RET
	JRST	GETHDR			; have to read the response to complete the transaction

; PUTHDR - create a transmit header for read/write function that contains
;	the number of bytes to read/write in it. This routine is invoked before
;	each read/write is done if more data is needed to be read/written.
;	This routines also transmits the header and makes sure that it has gone
;	out.

PUTHDR:	MOVE	AC1,FE.JFN		; Get the JFN for the FE
	MOVE	AC2,[POINT 8,XMTHDR]	; Point to the transmit header
	MOVNI	AC3,6			; Get the string byte count
	SKIPGE	PTYPE			; Check for 2020 style I/O
	JRST	WR2020			;  and output the header 2020 style
	SOUT				; Output the header to the device
	ERJMP	R			;  Can't talk to FE
	JRST	IOBRK			; Make sure the header gets output.

; GETHDR - To read a receive header from the port that we are currently
;	talking to.

GETHDR: MOVE	AC1,FE.JFN		; Get the JFN of the FE
	MOVE	AC2,[POINT 8,RCVHDR]	; Point to the receive header string
	MOVNI	AC3,6			; 6 bytes in the header
	SKIPGE	PTYPE			; Check for 2020 style I/O
	JRST	RD2020			; Read header 2020 style
	SIN				; Read the header from the FE
	ERJMP	R			;  Can't talk to FE

; IOBRK - To create a break in the I/O stream and force the current buffers
;	to be flushed or finished reading in.


IOBRK:	MOVE	AC1,FE.JFN		; Get the JFN of the FE device
	MOVX	AC2,.MOEOF		; Get the EOF function
	MOVX	AC3,1			; Clear FE buffers w/o doing real EOF
	MTOPR				; Force I/O completion
	ERJMP	R			;  Can't talk to FE
	RETSKP				; The I/O was completed succesfully.

; WR2020 - This routine is used to simulate the SOUT to a front end
;	     device. It actually ships the data over a synchronous link
;	     using DDCMP to a DN200
;
; Parameters -
;
;	AC1/	Ignored JFN
;	AC2/	Byte pointer to string
;	AC3/	Negative byte count

WR2020: MOVMM	AC3,.BTLEN+BTARG 	; Set the byte count to transfer
	MOVEM	AC2,.BTMSG+BTARG 	; Set pointer to 8 bit byte area
	MOVE	AC1,PORT		; Get synchronous line number
	MOVEM	AC1,.BTDTE+BTARG 	; Set it as the DTE/line in BOOT block
	MOVEI	AC2,BTARG		; Get location of BOOT arg block
	MOVX	AC1,.BTSDD		; Send DDCMP message to DN200
	BOOT
	ERJMP	R			; JSYS failed
	MOVE	AC2,.BTMSG+BTARG 	; Get update byte pointer
	SETZ	AC3,			; Say that all the bytes where output
	RETSKP				; Sucess in sending data

 
; RD2020 - To read a string from a DN200 that is connected by a DDCMP
;	     synchronous link. This routine simulates the SIN JSYS that
;	     is normally used with a front end device.
;
; Parameters -
;
;	AC1/	Ignored JFN
;	AC2/	Byte pointer to input buffer
;	AC3/	Negative byte count to input

RD2020: DMOVEM	AC2,RDSAVE		; Save the read arguments
	MOVE	AC1,PORT		; Get synchronous line number
	MOVEM	AC1,.BTDTE+BTARG 	; Set it as the DTE/line in BOOT block

RD20ST: MOVMM	AC3,.BTLEN+BTARG 	; Set the byte count to transfer
	MOVEM	AC2,.BTMSG+BTARG 	; Set pointer to data buffer
	MOVEI	AC2,BTARG		; Get location of BOOT arg block
	MOVX	AC1,.BTRDD		; Read DDCMP message function
	BOOT				; Do the read
	ERJMP	R			;  BOOT JSYS failed
	MOVE	AC1,.BTLEN+BTARG 	; Get transfered length/error code
	TXNN	AC1,BT%CTL		; Check for control message flag
	JRST	R20OK			;  No .. so message was read ok
	CAXE	AC1,BT%CTL+.BTCMP	; Transmission complete?
	JRST	R			;  No .. so front end not running
					;  with time
R20AGN: DMOVE	AC2,RDSAVE		; Get the arguments back again
	JRST	RD20ST			; Go try to read it again

R20OK:	MOVE	AC3,AC1			; Get the count of bytes transfered
	ADD	AC3,RDSLEN		; Make it minus the number yet to get
	MOVE	AC2,.BTMSG+BTARG 	; Get updated byte pointer
	RETSKP				; Success

; FESUP - set up port for private use
;	RESTRICTION: must be called from the caller's top level

FESUP:					; set up port for molesting in private
	SKIPGE	PTYPE			; Check for KS10 style I/O
	JRST	FESUP1
	CALL	SELDTE			;  Make the link to the correct DTE
	RET				;  If didn't work give error return
FESUP1:					; Enqueue the port for SIN/SOUT I/O
					; fall into  enq function

;ENQD60 - To ENQ a DN60 front end to block others from using it while

ENQD60:	MOVEI	AC2,ENQBLK		; this must be called from the caller's top level
	MOVX	AC1,.ENQBL		; Get the enqueue function number
	ENQ				;  and try to do it.
	RET				;  False return if we can't ENQ
	POP	P,AC1
	CALL	1(AC1)			; call the true return so the caller
					; will return here for dequeing the port
	JRST	[PUSH	P,AC1		; error return - deque the port
		 CALL	DEQD60		; the original error is returned
		 NOP			; ignore addtional failures
		 POP	P,AC1
		 RET]
					; this returns sucs - just fall into DEQD60

;DEQD60 - To dequeue a DN60 on a port so that others can use it again.

DEQD60: MOVEI	AC2,ENQBLK
	MOVX	AC1,.DEQDR		; Get the DEQ function code
	DEQ
	RET				; error on the way out
	RETSKP				; it suc'd

; QUED60 -  make up the argument block needed to ENQ/DEQ a specific port.

;	T1/ port number

QUED60:	PUSH	P,T1
	SKIPGE	PTYPE
	ANDI	T1,7			; for DN22, use line no.
	DPB	T1,QPRT0		; just cram two octal segments in string
	LSH	T1,-3
	DPB	T1,QPRT1
	POP	P,T1
	RET


; SELDTE - To select which DTE is currently attached to the FEn: device
;	that was previously opened.
;
;	PORT/	DTE # to be selected
; RETURN:
;	True	was successful
;	False	MTOPR Jsys failed and the error code is in AC1

SELDTE:	MOVE	AC1,PORT		;get the dte #
	MOVX	AC2,.MODTE		; Select the appropriate DTE
	HRROI	AC3,-10(AC1)		; Get the port number
	CAMN	AC3,LSTDTE		; Was it the same as the last one used?
	RETSKP				;  Yes so assume he is still set up.
	HRRZ	AC3,AC3			; Make it only the DTE number
	MOVE	AC1,FE.JFN		; Use the FE JFN already opened
	MTOPR				; Do the select
	ERJMP	DSLERR			;  Didn't work, bad DTE
	HRROM	AC3,LSTDTE		; Save the last DTE to be selected
	RETSKP				; It is now selected on the DTE

DSLERR: SETZM	LSTDTE			; Clear the last DTE selected (none)
	MOVX	AC1,.FHSLF		; Get the last error that occurred
	GETER				;  in this process
	HRRZ	AC1,AC2			; Set the error value
	RET				;  and return flaging failure.

; CPUTYP - cleverly determine what processor we are on

CPUTYP:	JFCL	.+1			; CLEAR THE FLAGS
	JRST	.+1			; SEE IF WE CHANGE THE PC FLAG
	JFCL	AC1,PDP6		; YES,IT WAS A PDP-6
	SETO	AC1,			; SET AC TO -1
	AOBJN	AC1,.+1			; SEE HOW IT ADDS 1,,1 TO -1
	JUMPN	AC1,KA10		; ON A KA, IT IS TWO FULL ADDS
	BLT	AC1,0			; NOOP BLT
	JUMPE	AC1,KI10		; KI WONT UPDATE THE WORD
	DMOVE	AC1,[EXP 1,0]		; 1, AND NO STRING POINTER
	MOVEI	AC3,1			; OFFSET OF 1
	EXTEND	AC1,[CVTDBO]		; CONVERT DECIMAL TO BINARY WITH OFFSET
	TLNE	AC3,200000		; LOOK FOR KL MICROCODE BUG
KL10:	SKIPA	AC1,[P.KL10]		; set KL10 type
KS10:	MOVX	AC1,P.KS10		; set KS10 type
SETCPU:	MOVEM	AC1,PTYPE		; set the cpu type
	RET
KA10:	SKIPA	AC1,[P.KA10]		; set KA10 type
KI10:	MOVX	AC1,P.KI10		; set KI10 type
	JRST	SETCPU
PDP6:	MOVX	AC1,P.PDP6		; set PDP-6 type
	JRST	SETCPU

PTYPE:	0				; processor type
 P.KS10==1B0				; KS10 - deliberately the sign bit
 P.KL10==1B1				; KL10
 P.KI10==1B2				; KI10
 P.KA10==1B3				; KA10
 P.PDP6==1B4				; PDP-6

ENQBLK: XWD	1,5			; 1 lock,,length of block is 5
	XWD	0,0			; PSI chn 0,, ID
	EXP	EN%BLN+EN%LTL+<0,,-3>	; long term data base,, Operator only
	POINT	7,QD60BF		; Pointer to string of resource name
	XWD	0,0			; 1 resource,, number of accesses

QPRT0:	POINT	3,QD60BF+1,20		; Low order digit of port number
QPRT1:	POINT	3,QD60BF+1,13		; High order digit of port number
QD60BF: ASCIZ	\DN60-P00\		; Same name as used by D60SPD and

D10FN:	POINT	16,XMTHDR,15		; fcn code to 11
D10AD:	POINT	16,XMTHDR,31		; examine/deposit address
D10DT:	POINT	16,XMTHDR+1,15		; deposit data

D11RS:	POINT	8,RCVHDR,7		; result code from FE
D11FN:	POINT	8,RCVHDR,15		; function performed
D11AD:	POINT	16,RCVHDR,31		; examine/deposti address
D11DT:	POINT	16,RCVHDR+1,15		; examine data

LSTDTE: BLOCK	1			; Last DTE that was selected
RCVHDR:: BLOCK	2			; Receive header
XMTHDR:: BLOCK	2			; Transmit header

XMSG:	BLOCK	^o274/4+1		; DDCMP Q flush buffer
RETRY:	BLOCK	1			; BOOT retry counter
BTARG:	BLOCK	5			; BOOT JSYS argument block
RDSAVE: BLOCK	1			; Save area for RD2020 arguments
RDSLEN: BLOCK	1			;  including the length

	SUBTTL	ERROR ROUTINE

;CALL	MOVE T1,<ERROR CODE>
;	MOVE T2,ERROR LIST
;	CALL CALLERR
CALER0:	SETZ	T2,
CALERR:	JUMPL T1,R		;EXIT IF WE ALREADY GAVE THE ERROR
	PUSH	P,T1		;SAVE CODE
	JUMPN	T2,CALER1	;ERROR LIST GIVEN ?
	SKIPE	NODE		;WERE WE DOING /NODE STUFF ?
	MOVEI	T2,NERLST	;NODE. ERROR
	SKIPE	PORT		;WAS A /PORT GIVEN ?
	MOVEI	T2,C11LST	;YES SO IS CALL11 ERROR CODE
CALER1:	PUSH	P,T2		;SAVE LIST
	CALL	QESTYP		;TYPE A QUESTION MARK
	HRRZ	T1,(P)		;GET TYPE OF ERROR
	SKIPE	T1
	CALL [	HRRZ	T1,(T1)	;GET ERROR DESCRIPTION
		JRST	TYPSTR]	;DISPLAY IT
	TYPE	< error code = >
	MOVE	T1,-1(P)	;GET OCTAL CODE
	CALL	OCTYPE
	CALL	BLANKT		;TYPE A SPACE
	POP	P,T2		;GET ERROR LIST
	POP	P,T1		;GET ERROR CODE
	JUMPLE	T1,CALER9
	JUMPE	T2,CALER9
	HLRZ	T3,(T2)		;GET MAX ERROR WE KNOW
	CAILE	T1,(T3)		;IS IT IN RANGE ?
	JRST	CALER9		;NOT IN RANGE SO CAN'T HELP FURTHER
	ADDI	T1,(T2)
	MOVE	T1,(T1)
	CALL	TYPSTR
CALER9:	CALL	QESTYP
	CALL	TABTYP
	SETO T1,		;SAY WE PRINTED THE ERROR
	RET

;HERE FOR A LOCK ERROR
LOCKER:	MOVEI	T2,LERLST	;DESCRIPTIONS FOR LOCK ERRORS
	CALL	CALERR
	EXIT
	JRST LOCKER
C11LST:	XWD	7,[ASCIZ \CAL11\]
	Z	[ASCIZ	\not privileged\]
	Z	[ASCIZ	\unknown function\]
	Z	[ASCIZ	\not a DC76\]
	Z	[ASCIZ	\function already in use\]
	Z	[ASCIZ	\no answer to query\]
	Z	[ASCIZ	\queue entry too short\]
	Z	[ASCIZ	\not enough arguments\]
LERLST:	XWD	6,[ASCIZ \LOCK\]
	Z	[ASCIZ	\not privileged\]
	Z	[ASCIZ	\other job too large\]
	Z	[ASCIZ	\maximum too large\]
	Z	[ASCIZ	\EVM exhausted\]
	Z	[ASCIZ	\illegal subfunction\]
	Z	[ASCIZ	\page unavailable\]
NERLST:	XWD	6,[ASCIZ \NODE.\]
	Z	[ASCIZ	\ill arg list\]
	Z	[ASCIZ	\ill node name or number\]
	Z	[ASCIZ	\not privileged job\]
	Z	[ASCIZ	\remote node control not available\]
	Z	[ASCIZ	\job not locked\]
	Z	[ASCIZ	\timeout\]
	SUBTTL	SYMBOL TABLE ROUTINES

;SYMBOLS ARE KEPT IN FOUR WORD BLOCKS
;	SYMBEG POINTS TO FIRST BLOCK
;	SYMEND POINTS TO LAST BLOCK
; 1ST WORD IN BLOCK IS SIXBIT SYMBOL
; 2ND WORD IS VALUE
; 3RD WORD IS HALF WORD FLAGS,,MASK FOR MATCH
SMF.SU==000001		;SYMBOL IS SUPPRESSED(DEFINED WITH =)
SMF.RG==000002		;SYMBOL IS A REGISTER VALUE
SMF.IN==000004		;SYMBOL IS AN INSTRUCTION
SMF.EI==000010		;EIS INSTRUCTION FORMAT
SMF.DD==000020		;LOW ORDER SIX BITS ARE DESTINATION
SMF.SS==000040		;LOW ORDER 12 BITS ARE SSDD
SMF.BR==000100		;LOW ORDER 8 BITS ARE XXX(I.E. BR)
SMF.SB==000200		;SOB TYPE ADDRESS
SMF.RT==000400		;RTS TYPE REGISTER USAGE
SMF.JS==001000		;JSR TYPE REGISTER USAGE
SMF.EM==002000		;EMT TYPE ARGUMENT
SMF.MK==010000		;MARK
SMF.PL==020000		;SET PROCESSOR LEVEL
SMF.P8==040000		;PDP8 SYMBOL
SMF.11==100000		;PDP11 SYMBOL
SMF.BY==200000		;BYTE INSTRUCTION
; 4TH WORD IS SYMBOL SOURCE

;HERE TO FIND A MATCH FOR A SYMBOL
; CALL	MOVE	T1,[SIXBIT \SYMBOL\]
;	CALL	SYMFND
;	ERROR RETURN
;	SUCCESS RETURN	SYM POINTS TO SYMBOL
SYMFND:	SKIPN	SYM,SYMBEG	;GET ADR OF BEGINNING OF SYMBOL TABLE
	RET			;CAN'T FIND SYMBOL
SYMFN1:	CAMN	SYM,SYMEND	;HIT END OF TABLE YET ?
	RET			;YES SO CAN'T FIND SYMBOL
	CAMN	T1,(SYM)	;IS THIS SYMBOL ?
	CALL	SYMFN7		;CHECK PDP8/PDP11 RIGHT
	MOVEI	SYM,4(SYM)	;POINT TO NEXT SYMBOL TABLE BLOCK
	JRST	SYMFN1

;HERE TO SEE IF PDP8/PDP11 FLAG RIGHT FOR THIS SYMBOL
SYMFN7:	HLL	SYM,2(SYM)	;GET FLAGS FOR SYMBOL
	TLNN	SYM,SMF.IN	;IS THIS AN INSTRUCTION ?
	JRST	SYMFN9		;NO SO OK TO USE SYMBOL
	TLNE	SYM,SMF.P8	;IS THIS A PDP8 SYMBOL ?
	JRST	SYMFN8
	SKIPE	PDP8F
	RET			;REJECT SYMBOL
	JRST	SYMFN9
SYMFN8:	SKIPN	PDP8F
	RET
SYMFN9:	MOVEM	T1,(P)
TPOPJ1:	POP	P,T1
RSKP:	AOS	(P)		;FOR SKIP RETURN
R:	RET
;HERE TO SEE IF WE CAN FIND A MATCH FOR AN INSTRUCTION
; CALL	MOVEI	T1,<VALUE>
;	CALL	INVLFN
;	LOSE RETURN
;	WIN RETURN WITH SYM SET UP
INVLFN:	SKIPN	SYM,SYMBEG	;ADDRESS OF FIRST SYMBOL BLOCK
	RET			;NO SYMBOL TABLE
INVLF1:	MOVE	T2,2(SYM)	;GET FLAGS & MASK
	TLNN	T2,SMF.SU	;IS THIS SUPPRESSED >?
	TLNN	T2,SMF.IN	;IS THIS AN INSTRUCTION ?
	JRST	INVLF8
	ANDI	T2,(T1)		;MASK ARGUMENT
	CAMN	T2,1(SYM)	;IS THIS A MATCH ?
	CALL	SYMFN7		;OK IF PDP8/PDP11 FLAG RIGHT
INVLF8:	MOVEI	SYM,4(SYM)	;GET ADR OF NEXT SYMBOL BLOCK
	CAME	SYM,SYMEND	;HIT END OF SYMBOLS ?
	JRST	INVLF1		;NO SO SEE IF THIS ONE OK
	RET
;HERE TO FIND A NAME FOR A REGISTER
; CALL:	MOVEI	T1,#	;REGISTER NUMBER
;	CALL	RGFNDN
;	LOSE
;	BINGO	(WITH SYM SETUP - OTHER REGS PRESERVED)
RGFNDN:	CALL	SAVE24		;SAVE REGISTERS
	CALL	VLFND0		;FIND A SYMBOL FOR VALUE
	CAIA
RGFND8:	MOVEI	SYM,-4(SYM)	;MAKE ADDRESS OF PREVIOUS SYMBOL
	CAMN	T1,1(SYM)	;RIGHT VALUE ?
	CAMGE	SYM,SYMBEG	;BACKED UP TOO FAR ?
	RET			;LOSE
	HLL	SYM,2(SYM)	;GET FLAGS
	TLNN	SYM,SMF.SU	;IS THIS A SUPPRESSED SYMBOL ?
	TLNN	SYM,SMF.RG	;IS THIS A REGISTER ?
	JRST	RGFND8		;NO GOOD
	RETSKP
;HERE TO ADD A SYMBOL TO TABLE
; CALL	PUT SYMBOL IN T1, PUT VALUE IN T2, FLAGS IN T3, MISC IN T4
;	RETURNS WITH SYM POINTING TO NEW SYMBOL
ADDSYM:	PUSH	P,T4		;SAVE MISC ON STACK
	SKIPE	PDP8F		;IS THIS A PDP8 SYMBOL ?
	TLO	T3,SMF.P8	;YES IS A PDP8
	PUSH	P,T3		;SAVE FLAGS ON STACK
	PUSH	P,T1		;SAVE SYMBOL ON STACK
	PUSH	P,T2		;SAVE VALUE ON STACK
	CALL	DELSYM		;FIRST DELETE ANY OLD VALUE
	CALL	POSYMT		;POSITION SYMBOL TABLE AT END OF CORE
	MOVEI	T1,4		;GET 4 WORDS FOR A SYMBOL BLOCK
	CALL	GETCOR		;GET NEW CORE
	POP	P,T1		;GET VALUE FOR SYMBOL
	CALL	VLFND0		;FIND WHERE TO BULGE SYMBOL TABLE
	MOVEI	T2,4
	ADDM	T2,SYMEND	;AND POINTER TO END OF  SYMBOL TABLE
	CAML	T1,1(SYM)
	ADDI	SYM,4
	MOVE	T2,T1		;COPY SYMBOL VALUE
	POP	P,T1		;GET SYMBOL
	POP	P,T3		;GET FLAGS
	POP	P,T4		;GET MISC
	PUSH	P,SYM		;SAVE SYMBOL POINTER
ADSYM7:	EXCH	T1,(SYM)
	EXCH	T2,1(SYM)
	EXCH	T3,2(SYM)
	EXCH	T4,3(SYM)
	MOVEI	SYM,4(SYM)	;POINT TO NEXT SYMBOL TABLE BLOCK
	CAME	SYM,SYMEND	;HIT END OF TABLE YET ?
	JRST	ADSYM7		;NO SO KEEP GOING
	POP	P,SYM		;GET POINTER TO NEW SYMBOL
	RET
;HERE TO DELETE A SYMBOL FROM A SYMBOL TABEL
; CALL	MOVE	T1,[SIXBIT \SYMBOL\]
;	CALL	DELSYM
;	RETURN
DELSYM:	CALL	SYMFND		;TRY TO FIND SYMBOL IN CURRENT SYMBOL TABLE
	RET
	HRLI	T1,4(SYM)	;BUILD BLT POINTER
	HRR	T1,SYM
	HRRZ	T2,SYMEND	;END OF SYMBOL TABLE
	BLT	T1,-4(T2)
	MOVNI	T1,4
	CAMN	T2,.JBFF##	;SYMBOL TABLE AT END OF CORE ?
	ADDM	T1,.JBFF##	;YES SO ADJUST END POINTER
	ADDM	T1,SYMEND	;AND ADJUST POINTER TO END OF SYMBOL TABLE
	RET
;HERE TO BE SURE SYMBOL TABLE IS LAST THING IN CORE AND MOVE IT IF NOT
; CALL:	CALL	POSYMT
POSYMT:	MOVE	T1,SYMEND
	CAMN	T1,.JBFF##	;IS SYMBOL TABLE AT END OF CORE ?
	RET
	PUSH	P,.JBFF##	;SAVE OLD FREE CORE POINTER
	MOVE	T1,SYMEND
	SUB	T1,SYMBEG
	CALL	GETCOR
	POP	P,T1		;GET OLD FREE CORE POINTER
	HRL	T1,SYMBEG
	HRRZM	T1,SYMBEG	;NEW BEGINNING OF SYMBOL TABLE
	HRRZ	T2,.JBFF
	BLT	T1,-1(T2)
	MOVEM	T2,SYMEND	;NEW END OFF SYMBOL TABLE
	RET

;HERE TO MOVE THE SYMBOL TABLE UP IN CORE
; CALL:	MOVEI	T1,<AMOUNT TO MOVE IT UP>
;	CALL	MOVSMT
MOVSMT:	CALL	SAVE24		;SAVE REGISTERS
	PUSH	P,T1		;SAVE ARGUMENT
	CALL	GETCOR		;GET ADDITIONAL CORE
	POP	P,T1		;GET NUMBER OF WORDS TO MOVE
	MOVE	T2,SYMBEG	;FIRST WORD IN CURRENT SYMBOL TABLE
	ADDM	T1,SYMBEG	;NEW SYMBOL TABLE ADR
	HRRZ	T3,.JBFF##	;ADR OF NEW LAST WORD IN SYMBOL TABLE
	HRRM	T3,SYMEND	;NEW END OF SYMBOL TABLE
	SOJA	T3,MOVTAB	;MAKE NEW LAST WORD IN SYMBOL TABLE
				; AND MOVE THE TABLE
;HERE TO FIND A NEAR MATCH FOR A VALUE
; CALL	MOVEI	T1,VALUE TO MATCH
;	CALL	VALFND
;	ERROR RETURN	;WITH SYM CLEARED
;	RETURN WITH SYM SET UP
VALFND:	CALL	VLFND0
	JRST	VLFND4
VLFND3:	MOVEI	SYM,-4(SYM)	;BACK UP SYMBOL POINTER
	CAMGE	SYM,SYMBEG	;BACKED UP TOO FAR ?
	JRST	VLFND7		;YES
VLFND4:	HLL	SYM,2(SYM)	;GET FLAGS FOR SYMBOL
	TLNE	SYM,SMF.SU!SMF.IN!SMF.RG	;IS SYMBOL SUPPRESSED OR REG OR INSTRUCTION ?
	JRST	VLFND3		;YES SO REJECT IT
	MOVE	T2,1(SYM)	;GET SYMBOL VALUE
	CAIGE	T1,400(T2)
	AOSA	(P)
VLFND7:	SETZM	SYM
	RET

VLFND0:	MOVE	SYM,SYMBEG	;POINT TO FIRST SYMBOL BLOCK
	MOVE	T3,SYMEND
VLFND2:	MOVE	T2,T3		;COPY HIGH LIMIT POINTER
	SUB	T2,SYM		;MAKE DIFFERENCE BETWEEN HIGH AND LOW
	LSH	T2,-1
	ANDI	T2,777774
	JUMPE	T2,R		;HAVE CARRIED THIS AS FAR AS WE CAN
	ADD	T2,SYM
	CAMGE	T1,1(T2)
	SKIPA	T3,T2
	MOVE	SYM,T2
	JRST	VLFND2
;HERE TO GET MORE CORE
; CALL	MOVEI	T1,<#WORDS OF CORE WANTED>
;	CALL	GETCOR
GETCOR:	HRRZS	T1		;CLEAR LEFT HALF
	ADDB	T1,.JBFF##	;MAKE NEW END OF CORE
	HRRZS	T1		;CLEAR LEFT HALF
	HRLM	T1,.JBSA##	;IN CASE WE GET SAVED LATER
	TXNN	FLG,F.EXEC	;RUNNING IN EXEC MODE
	CAMG	T1,.JBREL##
	JRST	GTCOR9
	TXNE	FLG,F.LOCK
	JRST	[	MOVEI	T1,1		;CODE FOR LOW SEG
			UNLOK.	T1,	;CAN'T BE LOCKED WHEN WE DO THIS
			JRST	LOCKER		;OLD MONITOR PERHAPS ?
			HRRZ	T1,.JBFF##	;GET CORE ARG BACK
			CORE	T1,
			JRST	CORERR		;CAN'T HAVE MORE ?
			MOVEI	T1,1		;CODE TO LOCK LOW SEG
			LOCK	T1,
			JRST	LOCKER
			JRST	GTCOR6 ]
	CORE	T1,
	JRST	CORERR
GTCOR6:	MOVEI	T1,"["
	CALL	TYPCHR
	HRRZ	T1,.JBREL##
	AOS	T1
	LSH	T1,-^D9
	CALL	DECTYP
	TYPE	<p core]
>
GTCOR9:	RET

;HERE IF CAN'T GET CORE WE WANT
CORERR:	TYPE	< CORE UUO failed>
	EXIT
;HERE TO READ A SYMBOL TABLE FROM A LISTING

RDSYMB:	SKIPE	T1,USETIT	;WANT TO SKIP PART OF FILE ?
	USETI	1,(T1)		;POSITION FILE
	MOVE	T1,[FILDEV,,SYMDEV]
	BLT	T1,SYMDEV+$FBLEN-1	;COPY FILDEV, FILNAM, FILEXT, FILTIM
	SETZ	T5,		;COUNT OF SYMBOLS
GETSC1:	CALL	GETSCH
	CAIE	T1,12		;IS THIS A LINE FEED ?
	JRST	GETSC1		;LOOK FOR ONE
	SETZB	T3,SYMBOL	;BUILD SYMBOL HERE
	MOVE	T2,[POINT 6,SYMBOL]
	CALL	GETSCH		;GET FIRST CHAR FOR SYMBOL
	CAIL	T1,"0"		;CHECK TO SEE IF NUMERIC
	CAILE	T1,"9"
	CAIA			;NOT NUMERIC
	JRST	GETSC1		;NUMERIC SO FLUSH LINE
	CAIA
GETSC3:	CALL	GETSCH
	CAIG	T1,40
	JRST	GETSC4		;IF SO HAVE FINISHED SYMBOL
	CAIN	T1,"="		;DID SYMBOL END WITH "=" ?
	JRST	GETSC5
	SUBI	T1,40		;CONVERT TO SIXBIT
	CAME	T2,[POINT 6,SYMBOL,35]	;FILLED WORD YET ?
	IDPB	T1,T2		;NO SO KEEP FILLING
	JRST	GETSC3
GETSC4:	CAIE	T1,40		;SYMBOLS END WITH A SPACE
	JRST	GETSC1		;NOT SYMBOL - FLUSH LINE
GETSC5:	SKIPN	SYMBOL		;IS THERE A SYMBOL ?
	JRST	GETSC1		;NO SYMBOL FLUSH LINE
	TDZA	T4,T4		;CLEAR FLAGS
GETSC6:	CALL	GETSCH
	CAIN	T1,40
	JRST	GETSC6
	CAIN	T1,"="
	JRST	[	TRO	T4,SMF.SU	;SUPPRESSED SYMBOL
			JRST	GETSC6	]
	CAIN	T1,"%"
	JRST	[	TRO	T4,SMF.RG	;REGISTER NAME
			TRZ	T4,SMF.SU	;DON'T SUPPRESS REG NAMES
			JRST	GETSC6	]
	CAIL	T1,60
	CAILE	T1,67
	JRST	GETSC1		;FLUSH REST OF LINE
GETSC7:	IMULI	T3,^D8
	ADDI	T3,-60(T1)
	CALL	GETSCH
	CAIL	T1,60
	CAILE	T1,67
	CAIA
	JRST	GETSC7

	CAIE	T1,"8"
	CAIN	T1,"9"
	JRST	GETSC1		;FLUSH REST OD LINE
	CAIN	T1,"-"
	JRST	GETSC1		;FLUSH REST OF LINE
	MOVE	T1,SYMBOL	;COPY SYMBOL
	HRRZ	T2,T3		;VALUE
	HRLZ	T3,T4		;FLAGS
	MOVE	T4,SYMNAM	;FILE NAME
	PUSH	P,SYMEND
	CALL	ADDSYM
	POP	P,T1		;GET OLD SYMEND
	CAME	T1,SYMEND
	AOS	T5		;COUNT SYMBOL
	JRST	GETSC1		;FLUSH REST OF LINE
GETSCH:	CALL	FILCHR		;GET NEXT CHAR FROM FILE
	CAIA
	RET
	TYPE	< loaded >
	MOVE	T1,T5
	CALL	DECTYP
	TYPE	< symbols
>
	JRST TPOPJ1

SYMDEV:	BLOCK	1		;DEVICE NAME FOR SYMBOL FILE
SYMBLK:	BLOCK	1		; START OF LOOKUP/ENTER BLOCK
SYMDIR:	BLOCK	1		; ADDRESS OF PATH BLOCK
SYMNAM:	BLOCK	1		; FILE NAME
SYMEXT:	BLOCK	1		; FILE EXTENSION
SYMTIM:	BLOCK	1		; TIME/DATE AND PROTECTION
SYMPTH:	BLOCK	2		; FILE PATH
SYMPPN:	BLOCK	1		; FILE PPN
SYMSFD:	BLOCK	6		;  AND SUBSEQUENT SFD'S
	BLOCK	1		; SWITCHES
;HERE TO READ A FE SYMBOL FILE

RDSYMA:	MOVE T1,[FILDEV,,SYMDEV] ; COPY OF FILE, DEVICE, EXT, TIME
	BLT T1,SYMDEV+$FBLEN-1	;MOVE IT
	SETZ T5,		;COUNT OF SYMBOLS WE HAVE READ
RDSYM1:	CALL GETSCH		;GET NEXT BYTE
	CAIE T1,12		;LINE FEED?
	JRST RDSYM1		;NO, KEEP LOOKING FOR IT.
RDSYM2:	SETZB T3,SYMBOL		;BUILD SYMBOL HERE
	MOVE T2,[POINT 6,SYMBOL];POINTER FOR SYMBOL NAME
RDSYM3:	CALL GETSCH		;GET NEXT SYMBOL NAME BYTE
	CAIE T1,40		;SPACE?
	CAIN T1,11		;TAB?
	JRST RDSYM3		;YES, IGNORE IT AT START OF LINE
	CAIA
RDSYM4:	CALL GETSCH		;GET NEXT BYTE, PLEASE
	CAIG T1,40		;IF SO, WE HAVE FINISHED SYMBOL
	JRST RDSYM5		;YES, WE ARE DONE WITH THAT PART
	CAIE T1,11		;IS IT A TAB?
	CAIN T1,75		;IS IT AN "="?
	JRST RDSYM5		;YES, TOO, SO GET NEXT PART
	SUBI T1,40		;CONVERT TO SIXBIT
	CAME T2,[POINT 6,SYMBOL,35];AT THE END YET?
	IDPB T1,T2		;NO, POU BYTE INTO SYMBOL
	JRST RDSYM4		;LOOP FOR MORE OF SYMBOL

RDSYM5:	CAIN T1,75		;END OF SYMBOL, WAS IT A "="?
	JRST [	SKIPN SYMBOL
		JRST RDSYM1	;NO SYMBOL, FLUSH THE LINE, TRY AGAIN
		SETZ T4,	;CLEAR THE FLAGS
		JRST RDSYM6]	;AND GET THE VALUE 
	CAIE T1,11		;TAB
	CAIN T1,40		;SPACE?
	CAIA
	JRST RDSYM1		;NOT A SYMBOL AGAIN, FLUSH LINE
	SKIPN SYMBOL
	JRST RDSYM1		;NOT A SYMBOL, YET
	SETZ T4,
RDSYM7:	CALL GETSCH
	CAIN T1,40
	JRST RDSYM7		;EAT UP EXTRA SPACES
RDSYM6:	CAIN T1,75		;OK?
	JRST [	TRO T4,SMF.SU	;SUPPRESSED
		JRST RDSYM7]	;BACK FOR MORE
	CAIN T1,45		;"%"
	JRST [	TRO T4,SMF.RG	;REGISTER NAME
		TRZ T4,SMF.SU	;DONT KEEP THEM DOWN
		JRST RDSYM7]	;BACK AGAIN
	CAIL T1,60		;IS IT IN THE RANGE OF 0-7
	CAILE T1,67
	JRST RDSYM1		;NO, FLUSH LINE
RDSYM8:	IMULI T3,10		;MAKE ROOM FOR NEW VALUE
	ADDI T3,-60(T1)		;CONVERT AND ADD IT IN
RDSYM9:	CALL GETSCH		;NEXT BYTE
	CAIL T1,60
	CAILE T1,67
	CAIA
	JRST RDSYM8		;ADD IN NEXT VALUE
	CAIN T1,55		;WAS IT A "-"
	JRST RDSYM9		;YES, IGNORE IT
	CAIN T1,122		;IS IT A "R"
	ADD T3,RELOFF		;YES, ADD RELOCATION , AND KEEP GOING
	MOVE T1,SYMBOL		;GET SYMBOL NAME
	HRRZ T2,T3		;GET VALUE
	HRLZ T3,T4		;GET FLAGS
	MOVE T4,SYMNAM		;GET FILE MANE
	PUSH P,SYMEND		;SAVE END OF SYMBOL TABLE
	CALL ADDSYM		;ADD NEW SYMBOL
	POP P,T1		;GET OLD END
	CAME T1,SYMEND		;DID IT GROW?
	AOS T5			;YES, COUNT AS NEW SYMBOL (CROCK)
	JRST RDSYM2		;YES, GET NEXT SYMBOL FROM LINE
	SUBTTL	GENERAL FILE ROUTINES

;HERE TO OPEN A FILE TO READ(F.WRIT=0) OR WRITE(F.WRIT=1)
; CALL	MOVE	T1,[SIXBIT \FILE\]	;DEFAULT FILE NAME
;	MOVE	T2,[SIXBIT \EXTEXT\]	;DEFAULT EXTENSIONS
;	MOVE	T3,[SWDSP,,SWLST]	;SWITCH POINTER
;	MOVE	T4,[400000,,ADR]	;DEFAULT LAST SWITCH
;	CALL	OPNFIL
;	LOSE RETURN
;	WIN RETURN
OPNFIL:	TROA	FLG,F.FLIP	;FLAG WE SHOULD PROMPT
OPNFL0:	TXZ	FLG,F.FLIP	;NO PROMPT PLEASE
	MOVEM	T2,DEFEXT	;SAVE DEFAULT EXTENSIONS
	SETZM	FILDEV		;INITIALIZE START OF FILE BLOCK
	MOVE	T2,[FILDEV,,FILDEV+1]  ;BLT POINTER TO
	BLT	T2,FILDEV+$FBLEN-1  ; INITIALIZE REST OF FILE BLOCK
	MOVEM	T1,FILNAM	;SAVE DEFAULT FILE NAME
	MOVEM	T3,FIL.SW	;SAVE POINTER TO SWITCHES
	MOVEM	T4,LASTSW	;LAST SWITCH WE GET
OPFIL1:	MOVEI	T1,[ASCIZ \
FILE:	\]
	TXOE	FLG,F.FLIP	;WANT PROMPT ?
	CALL	TYPSTR
	CALL	SIXIN		;GET FILE NAME
	JRST	OPFIL1
	JUMPE	T1,OPFIL4	;JUST SWITCHES
	MOVSI	T2,'DSK'	;DEFAULT DEVICE NAME
	MOVEM	T2,FILDEV
	CAIE	T5,":"		;WAS THIS A DEVICE SPECIFICATION ?
	JRST	OPFIL2
	MOVEM	T1,FILDEV	;YES SO WAS A DEVICE
	CALL	SIXIN		;GET FILE NAME
	JRST	OPFIL1
OPFIL2:	SKIPE	T1		;WAS THERE A FILE NAME ?
	MOVEM	T1,FILNAM	;SAVE FILE NAME
	CAIE	T5,"."		;GIVING AN EXTENSION ?
	JRST	OPFIL3		;NO
	CALL	SIXIN		;GET EXTENSION
	JRST	OPFIL1
	HLLZM	T1,FILEXT
OPFIL3:	CAIE	T5,"["		;GIVING A PPN ?
	JRST	OPFIL4

;HERE TO READ IN A PATH SPEC
	CALL	SIXIN
	JRST	OPFIL4
	CAIE	T5,","
	JRST	OPFIL4
	CALL	SIXOCT
	JRST	OPFIL4
	CAIN	T1,0		;USER TYPE IN EXPLICIT PROJECT?
	HLRZ	T1,MYPPN	;NO, USE HIS THEN
	HRLM	T1,FILPPN	; SET IN FILE PATH BLOCK
	CALL	SIXIN
	JRST	OPFIL1
	CALL	SIXOCT
	JRST	OPFIL1
	CAIN	T1,0		;USER TYPE IN EXPLICIT PROGRAMMER?
	HRRZ	T1,MYPPN	;NO, USE HIS THEN
	HRRM	T1,FILPPN	; SET IN FILE PATH BLOCK
	MOVEI	T4,FILSFD-1	; START OF SFD'S
OPFL30:	MOVE	T1,T5
	CAIE	T1,","		;WERE SFD'S SPECIFIED ?
	JRST	OPFL39
	CALL	SIXIN		;GET SFD NAME
	JRST	OPFL39
	CAIN	T4,FILSFD+4	; ALREADY FILLED ALL ?
	JRST	[TYPE	<
?D11SFD SFD depth greater than 5>
		RET	]
	PUSH	T4,T1
	JRST	OPFL30
OPFL39:	CAIN	T1,"]"
	CALL	RDCHAR
OPFL40:	MOVEM	T1,T5
OPFIL4:	CAIN	T5,40		;WAS BREAK CHAR A SPACE ?
	JRST	[CALL	RDCHAR	;GET NEXT CHAR
		JRST	OPFL40 ]
	CAIE	T5,"/"		;TIME FOR SWITCHES ?
	JRST	OPFIL7
	CALL	SIXIN		;GET SWITCH NAME
	JRST	OPFIL7
	MOVSI	T2,770000	;MAKE A MASK
OPFL41:	MOVE	T3,T1		;COPY ARGUMENT
	AND	T3,T2		;MASK IT
	CAMN	T1,T3		;WAS THAT RIGHT MASK ?
	JRST	OPFL42
	ASH	T2,-6		;MAKE MASK BIGGER
	JRST	OPFL41
OPFL42:	HRRZ	T4,FIL.SW
OPFL43:	SKIPN	T3,(T4)		;GET NEXT ENTRY IN LIST
	JRST	OPFIL5		;NO MATCH FOR SWITCH
	CAMN T1,T3		;EXACT ENTRY?
	JRST OPFIL6		;YES, IGNORE PARTIAL MATCHES
	AND	T3,T2		;MASK OFF ENTRY
	CAME	T1,T3		;DID WE FIND MATCH ?
	AOJA	T4,OPFL43	;TRY NEXT ENTRY
	MOVE	T3,1(T4)	;GET NEXT ENTRY FROM LIST
	AND	T3,T2		;MASK IT
	CAME	T1,T3
	JRST	OPFIL6
OPFIL5:	PUSH	P,T1		;SAVE SWITCH
	TYPE	<
undefined or ambiguous switch />
	POP	P,T1
	CALL	SIXTYP
OPFL52:	TYPE	<
	Legal switches are:>
	HRRZ	T4,FIL.SW	;POINT TO LIST OF SWITCHES
OPFL55:	SKIPN	(T4)
	JRST	CRLTYP		;END WITH A FLURISH
	TYPE	< />
	MOVE	T1,(T4)		;GET SWITCH NAME
	CALL	SIXTYP
	AOJA	T4,OPFL55

OPFIL6:	SUB	T4,FIL.SW
	HLRZ	T1,FIL.SW
	ADDI	T1,(T4)
	SKIPGE	T1,(T1)
	JRST	[	MOVEM	T1,LASTSW
			JRST	OPFIL4 ]
	CALL	(T1)
	NOP
	JRST	OPFIL4
OPFIL7:	SETZ	T1,
	SKIPN	T2,FILDEV	;DID USER TYPE A FILE NAME ?
	JRST	OPNFL5		;NO - PROBABLY A /PORT
	MOVEI	T3,IHD
	TXNE	FLG,F.WRIT
	SKIPA	T3,[OHD,,0]
	SKIPA	T4,[OPEN 1,T1]	;READ ON CHNL 1
	MOVE	T4,[OPEN 0,T1]
	XCT	T4
	JRST	FILER0
	PUSH	P,.JBFF##
	MOVEI	T2,OBUFER
	MOVE	T1,[INBUF 1,NUMBUF]
	TXNE	FLG,F.WRIT
	SKIPA	T1,[OUTBUF 1]
	MOVEI	T2,IBUFER
	MOVEM	T2,.JBFF##
	XCT	T1
	NOP
	POP	P,.JBFF##
	SKIPE	FILEXT		; USER TYPE ANY EXTENSION?
	SETZM	DEFEXT		; YES, CLEAR DEFAULTS THEN
OPNFL2:	MOVE	T1,[LOOKUP 1,FILBLK]
	MOVEI	T2,LKELEN	; LENGTH OF EXTENDED LOOKUP/ENTER BLOCK
	MOVEM	T2,FILBLK	; SET IN LOOKUP/ENTER BLOCK
	SKIPN	FILPPN		; USER TYPE IN EXPLICIT PATH?
	TDZA	T2,T2		; NO, USE DEFAULT PATH
	MOVEI	T2,FILPTH	; YES, USE IT AS TYPED
	MOVEM	T2,FILDIR	; SET PATH BLOCK IN LOOKUP/ENTER BLOCK
	TXZE	FLG,F.APND	;IF APPENDING DO LOOKUP FIRST
	JRST	[TLZ	T1,000740	;CLEAR CHNL SPEC
		XCT	T1		;DO LOOKUP
		JRST	OPNFL2		;LOST BUT DON'T CARE
		TXO	FLG,F.APND	;NEED TO DO USETI
		LDB	T2,[POINTR 17,T1]  ;CHANNEL NUMBER
		MOVEM	T2,FILPTH	;SET IN PATH BLOCK
		MOVE	T2,[PTHLEN,,FILPTH]  ;ARG POINTER TO
		PATH.	T2,		;READ FILE TRUE PATH
		SETZ	T2,		;FAILED??
		JRST	.+1 ]
	TXNE	FLG,F.WRIT
	HRLI	T1,(ENTER)
	XCT	T1
	CAIA			;LOOKUP OR ENTER LOST
	JRST	OPNFL5		;WE HAVE A FILE READY FOR I/O
	TXNE	FLG,F.WRIT	;WRITING ?
	JRST	FILER0		;HE LOSES
	SKIPN	T2,DEFEXT	; ANY DEFAULTS LEFT?
	JRST	FILER0		;NO, ERROR
	HLLZM	T2,FILEXT	;YES, TRY NEXT DEFAULT
	LSH	T2,^D18		;TOSS IT OUT
	MOVEM	T2,DEFEXT	;AND SAVE ANYTHING LEFT FOR NEXT TIME
	JRST	OPNFL2
OPNFL5:	LDB	T2,[POINTR 17,T1]  ;CHANNEL NUMBER
	MOVEM	T2,FILPTH	;SET IN PATH. BLOCK
	MOVE	T2,[PTHLEN,,FILPTH]  ;ARG POINTER TO
	PATH.	T2,		;READ TRUE FILE PATH
	JFCL			;???
	TXNE	FLG,F.APND
	USETI	-1		;IN CASE SUPERCEEDING
	MOVE	T1,[FILDEV,,OFLDEV]	;BLT POINTER
	TXNN	FLG,F.WRIT	;ARE WE READING OR WRITING ?
	HRRI	T1,IFLDEV	;READING
	MOVEI	T2,$FBLEN-1(T1)	; LAST WORD TO TRANSFER
	BLT	T1,(T2)		;COPY FILE SPEC
	SKIPE	T1,LASTSW
	JRST	(T1)
	RETSKP
FILER0:	TXNE	FLG,F.WRIT
	SETZM	OHD
	TYPE	<? Can't LOOKUP/ENTER file >
FILERR:	TXNE	FLG,F.WRIT
	SETZM	OHD
	MOVEI	T1,FILDEV
	CALL	FILTYP
	CALL	CRLTYP
	TXNN	FLG,F.WRIT
	SETZM	IHD
	RET
FILTYP:	HRL	T2,T1		;BUILD BLT POINTER
	HRRI	T2,FILDEV
	BLT	T2,FILDEV+$FBLEN-1	; COPY FILE SPEC
	MOVE	T1,FILDEV	;GET DEVICE NAME
	CALL	SIXTYP
	CALL	COLTYP		;TYPE A COLON
	MOVE	T1,FILNAM	;GET FILE NAME
	CALL	SIXTYP
	CALL	PERTYP		;TYPE A "."
	HLLZ	T1,FILEXT	;GET EXTENSION
	CALL	SIXTYP
	SKIPN	FILPPN		; WAS THERE A PPN ?
	JRST	FILTY6
	MOVEI	T1,"["
	CALL	TYPCHR
	HLRZ	T1,FILPPN
	CALL	OCTYPE
	CALL	COMTYP		;TYPE A COMMA
	HRRZ	T1,FILPPN	; GET RH OF PPN
	ANDI	T1,-1
	CALL	OCTYPE
	MOVEI	T3,FILSFD	; START OF SFD'S
FILTY4:	CAIE	T3,FILSFD+5	; TYPED ALL SFD LEVELS ?
	SKIPN	T1,(T3)		;GET NEXT SFD NAME
	JRST	FILTY5
	CALL	COMTYP		;TYPE A COMMA
	CALL	SIXTYP
	AOJA	T3,FILTY4
FILTY5:	MOVEI	T1,"]"
	CALL	TYPCHR
FILTY6:	CALL	BLANKT
	LDB	T1,[POINT 11,FILTIM,23]
	JUMPE	T1,FILTY3
	CALL	TIMTY3
	CALL	BLANKT
FILTY3:	LDB	T1,[POINT 3,FILEXT,20]	;HIGH ORDER CREATION DATE
	LDB	T2,[POINT 12,FILTIM,35]	;LOWER ORDER CREATION DATE
	LSH	T2,^D24		;APPEND THE TWO TIMES INTO
	LSHC	T1,^D12		;ONE 15-BIT CREATION DATE
	CALL	DATET0		;TYPE DATE
	RET

;HERE TO CLOSE OUTPUT FILE
DONE.W:	SKIPN	OHD
	RET
	OUT
	CLOSE
	RELEASE
	SETZM	OHD
	TYPE	<File >
	MOVEI	T1,OFLDEV
	CALL	FILTYP
	TYPE	< written

>
	RET

DEFEXT:	BLOCK	1		; DEFAULT EXTENSIONS

FILDEV:	SIXBIT	\DSK\
FILBLK:	BLOCK	1		; START OF LOOKUP/ENTER BLOCK
FILDIR:	BLOCK	1		; POINTER TO FILE DIRECTORY
FILNAM:	BLOCK	1
FILEXT:	BLOCK	1
FILTIM:	BLOCK	1		; FILE PROTECTION AND DATES
	LKELEN==.-FILBLK-1	; SIZE OF LOOKUP/ENTER BLOCK
FILPTH:	BLOCK	2		; PATH BLOCK HEADER
FILPPN:	BLOCK	1		; FILE PPN
FILSFD:	BLOCK	5		;  AND SUBSEQUENT SFD'S
	BLOCK	1		; TERMINATING 0 WORD
	PTHLEN==.-FILPTH	; LENGTH OF PATH BLOCK
FIL.SW:	BLOCK	1
	$FBLEN==.-FILDEV	; LENGTH OF "FILE BLOCK"

IHD:	BLOCK	3		;HEADER FOR INPUT FILE
IBUFER:	BLOCK	<203*NUMBUF>
IFLDEV:	BLOCK	$FBLEN		; INPUT FILE SPEC

OHD:	BLOCK	3		;HEADER FOR OUTPUT FILE
OBUFER:	BLOCK	203
OFLDEV:	BLOCK	$FBLEN		; OUTPUT FILE SPEC
;HERE TO GET NEXT CHAR FROM A FILE
; CALL	CALL	FILCHR
;	ERROR RETURN
;	NORMAL RETURN WITH CHAR IN T1
FILCHR:	CALL	FILBYT		;GET NEXT BYTE FROM FILE
	RET			;LOST
	JUMPE	T1,FILCHR	;FLUSH NULLS
	AOS	(P)
	RET

;HERE TO GET THE NEXT BYTE FROM INPUT FILE
FILBYT:	SOSGE	T1,IHD+2	;IS THERE MORE STUFF IN BUFFER ?
	JRST	FLCHR5		;NO
	ILDB	T1,IHD+1	;GET NEXT CHAR
	AOS	(P)		;SKIP RETURN
	RET

FLCHR5:	IN	1,		;GET NEXT BUFFER
	JRST	FILBYT		;TRY AGAIN
	GETSTS	1,T1		;GET FILE STATUS
	TXNE	T1,IO.IMP!IO.DER!IO.DTE!IO.BKT	;ANY ERRORS
	PUSHJ P,IFILER		;REPORT ERROR
	RELEASE 1,		;GONE WITH CHANNEL
	RET			;AND RETURN

IFILER:	TYPE	<
?D11ERF error reading file >
	MOVEI	T1,IFLDEV	;ADR OF NAME OF FILE
	CALL	FILTYP
	TYPE	< status = >
	GETSTS 1,T1		;GET BACK STATUS
	CALL	OCTYPE
	JRST	CRLTYP 

;HERE TO POSITION FILE FOR INPUT
; CALL	MOVE	T1,BYTE # IN FILE
;	CALL	FILPOS
;	RETURN
FILPOS:	IDIVI	T1,200*5	;FIND BLOCK TO READ
	USETI	1,1(T1)
	IN	1,		;GET NEXT BUFFER
	CAIA
	RET
FILPS4:	SOJL	T2,RSKP
	CALL	FILBYT
	RET
	JRST	FILPS4
;HERE TO INPUT AN OCTAL NUMBER
; CALL:	CALL	INPOCT
;	ERROR RETURN
;	RETURN WITH OCTAL NUMBER IN T1, BREAK CHAR IN T2
INPOCT:	CALL	SAVE34
	SETZB	T3,T4
INPRD2:	CALL	FILCHR		;GET NEXT INPUT CHAR
	JRST	INPRD9		;NO MORE IN FILE
	JUMPE	T1,INPRD2
	CAIE	T1," "		;LEADING SPACE ?
	CAIN	T1,"	"		;OR TAB ?
	JRST	INPRD2		;YES
INPRD5:	CAIL	T1,"0"
	CAILE	T1,"7"
	JRST	INPRD7
	IMULI	T3,^D8
	ADDI	T3,-60(T1)
	CALL	FILCHR
	CAIA			;EOF
	JRST	INPRD5
INPRD7:	MOVE	T2,T1
	MOVE	T1,T3
	AOS	(P)		;SKIP RETURN
INPRD9:	RET
;HERE TO GET A SIXBIT WORD FROM TTY
; CALL:	CALL	SIXIN
;	LOSE RETURN
;	WIN RETURN WITH SIXBIT WORD IN T1 & BREAK CHAR IN T5
SIXIN:	PUSH	P,T4		;SAVE REG
SIXIN0:	CALL	RDCHAR		;GET THE FIRST CHAR
	CAIE	T1," "		;IS IT A BLANK
	CAIN	T1,"	"		;OR A TAB ?
	JRST	SIXIN0		;YES SO SKIP IT
	MOVE	T4,[POINT 6,T5]
	SETZ	T5,		;CLEAR ACCUMULATED SYMBOL
	CAIN	T1,"%"
	JRST	SIXIN7
	JRST	SIXIN3
SIXIN2:	CALL	RDCHAR		;GET A CHAR FROM TTY
SIXIN3:	CAIN	T1,177
	JRST	[	TYPE	<xxx>
			POP	P,T4
			RET	]
	CAIL	T1,"0"
	CAILE	T1,"Z"+40
	JRST	SIXIN9		;RETURN
	CAILE	T1,"9"
	CAIL	T1,"A"+40
	JRST	SIXIN7
	CAIL	T1,"A"
	CAILE	T1,"Z"
	JRST	SIXIN9		;RETURN
SIXIN7:	CAIGE	T1,40+"A"	;CHECK FOR LOWER CASE
	SUBI	T1,40
	CAME	T4,[POINT 6,T5,35]	;HAVE WE ALREADY FILLED WORD ?
	IDPB	T1,T4		;NOT YET
	JRST	SIXIN2
SIXIN9:	EXCH	T1,T5
	POP	P,T4
	RETSKP

;HERE TO CONVERT SIXBIT TO OCTAL
SIXOCT:	MOVE	T4,[POINT 6,T1]
	SETZ	T2,
SIXOC1:	ILDB	T3,T4
	JUMPE	T3,SIXOC9
	CAIL	T3,20
	CAILE	T3,27
	RET			;CAN'T CONVERT
	IMULI	T2,^D8
	ADDI	T2,-20(T3)
	CAME	T4,[POINT 6,T1,35]	;DONE ALL OF WORD ?
	JRST	SIXOC1
SIXOC9:	EXCH	T1,T2
	RETSKP
;HERE TO GET A DECIMAL ARGUMENT FROM THE TTY
; CALL	CALL	DECINP
;	LOSE RETURN
;	WIN RETURN	WITH # IN T1, BREAK CHAR IN T5
DECINP:	MOVEI	T1,^D10		;RADIX
RADINP:	CALL	SAVE2		;SAVE SOME REGISTERS
	SETZ	T5,		;BUILD NUMBER HERE
	MOVE	T2,T1		;COPY RADIX
RADIN0:	CALL	RDCHAR		;GET NEXT CHAR FROM THE TTY
	CAIE	T1," "		;IS THIS A LEADING SPACE ?
	CAIN	T1,"	"		;OR TAB ?
	JRST	RADIN0		;YES SO FLUSH IT
	CAIL	T1,"0"		;IS FIRST CHARACTER NUMERIC ?
	CAIL	T1,"0"(T2)
	JRST	RADIN9		;ERROR RETURN
	AOS	(P)		;WIN
RADIN2:	CAIL	T1,"0"		;IS CHARACTER NUMERIC
	CAIL	T1,"0"(T2)	;IS IT IN RANGE ?
	JRST	RADIN9		;ALL DONE
	IMULI	T5,(T2)		;SHIFT CURRENT ACCUMULATION
	ADDI	T5,-60(T1)	;ADD NEXT DIGIT
	CALL	RDCHAR		;GET NEXT CHAR FROM THE TTY
	JRST	RADIN2
RADIN9:	EXCH	T1,T5
	RET
	SUBTTL	TTY ROUTINES

;HERE TO DISPLAY CONTENTS OF T1 AS AN ADDRESS
ADRTYP:	TLNN	T1,400000
	TLO	T1,777777
	TLNN	T1,200000
	JRST	DATIN9		;TYPE REGISTER NAME
	ANDI	T1,177777	;SIXTEEN BITS ONLY PLEASE
	HRROM	T1,LSTADR	;SAVE LAST ADDRESS DISPLAYED
	CALL	VALFND		;SEE IF WE CAN FIND A SYMBOL
	JRST	RADTYP		;TYPE ADDR IN CURRENT RADIX
	SKIPN	1(SYM)		;DON'T USE IF SYMBOL=0
	JRST	RADTYP
	PUSH	P,T1		;SAVE VALUE
	MOVE	T1,(SYM)	;GET SYMBOL NAME
	CALL	SIXTYP		;TYPE SYMBOL
	POP	P,T1		;GET VALUE AGAIN
	SUB	T1,1(SYM)	;GET DISPLACEMENT
	ANDI	T1,177777	;STRIP EXTRA BITS
	JUMPE	T1,R		;IF EXACT WE ARE DONE
	PUSH	P,T1		;SAVE REMAINDER
	CALL	PLUTYP		;TYPE A "+"
	POP	P,T1
	JRST	RADTYP		;TYPE REST IN CURRENT RADIX
	SUBTTL	DISPLAY ROUTINES

;HERE TO TYPE CONTENTS OF CURRENT LOCATION
; CALL	WITH DOT SETUP TO POINT TO STARTING POINT OF DISPLAY
;	WITH BYTCNT AND O.MODE SETUP TO INDICATE TYPE OF DISPLAY
;	WITH BYTCNT AND O.MODE SETUP TO INDICATE TYPE OF DISPLAY
;	CALL	DATYPE

DATYPE:	HRRZ	T2,BYTCNT	;BYTE COUNT
	HRRZ	T3,O.MODE	;OUTPUT MODE
	MOVE	T1,DOT
	MOVEM	T1,DOTFOO
	SKIPE	PDP8F
	JRST	DATYP1
	TLNN	DOT,200000
	JRST	REGTYP		;WANT REGISTER DISPLAYED
	CAIG	T3,2		;IS THIS A WORD MODE
	ASH	T2,1		;YES SO BYTE=WORDS*2
DATYP1:	CALL	GETWRD
	JRST	[CALL	CALER0		;DESCRIBE PROBLEM
		RET	]		;THEN EXIT
	MOVEM	T1,ESC.Q.	;IN CASE OF <ESCAPE>Q LATER
	MOVEM	T1,DATA
	HRRZ	T5,BYTCNT	;REPETITION COUNT
	MOVE	T1,DATA		;GET DATA TO TYPE
	HRRZ	T2,O.MODE	;GET OUTPUT MODE
	JRST	@[EXP	DATINS,DATADR,DATNUM,DATBYT,DATASC,DATEBC](T2)
;HERE TO TYPE THE CONTENTS OF A REGISTER

REGTYP:	ANDI	T1,177777	;STRIP EXTRA BITS
	CAILE	T1,7		;SMALL ENOUGH ?
	JRST	QESTYP
	MOVE	T1,SIMREG(T1)	;GET REGISTER TO DISPLAY
	MOVEM	T1,ESC.Q.	;IN CASE OF $Q LATER
	CALL	@[EXP ADRTYP,ADRTYP,RADTYP,RGTBYT,RGTASC,RGTEBC](T3)
	JRST	B3.TYP		;END WITH A FEW SPACES

;HERE TO TYPE CONTENTS OF REGISTER AS BYTES
RGTBYT:	MOVEI	T2,RADTYP	;ROUTINE TO DISPLAY BYTES (NUMERIC)
	JRST	RGTYPX

;HERE TO TYPE CONTENTS OF REGISTER AS ASCII
RGTASC:	MOVEI	T2,DATAS3	;ROUTINE TO DISPLAY ASCII BYTES
	JRST	RGTYPX

;HERE TO TYPE CONTENTS OF REGISTER AS EBCDIC
RGTEBC:	MOVEI	T2,DATEB3	;ROUTINE TO DISPLAY EBCDIC BYTES

RGTYPX:	PUSH	P,T1		;SAVE DATA
	ANDI	T1,377		;FIRST BYTE IS RH
	PUSH	P,T2		;SAVE ADR OF DISPLAY ROUTINE
	CALL	(T2)		;DISPLAY THE FIRST BYTE
	POP	P,T2		;GET ADR OF DISPLAY ROUTINE BACK
	CAIN	T2,RADTYP	;WAS THIS BYTES ?
	CALL	COMTYP		;YES SO WANT A COMMA IN BETWEEN
	POP	P,T1		;GET DATA BACK
	LDB	T1,[POINT 8,T1,27]	;WANT LH BYTE NOW
	JRST	(T2)		;DISPLAY LAST BYTE
;HERE TO TYPE CONTENTS OF CURRENT LOCATION AS A NUMERIC
DATNUM:	HRROM	T1,LSTADR	;IN CASE TYPES A TAB LATER
	CALL	RADTYP		;TYPE AS NUMERIC
	SOJLE	T5,B3.TYP
	CALL	BLANKT
	CALL	NXTDWD		;GET NEXT DATA WORD
	JRST	DATNUM

NXTDWD:	CALL	NXTWRD		;GET NEXT WORD
	JRST	B3.TYP		;CAN'T READ NEXT WORD !
	MOVEM	T1,DATA
	RET

;HERE TO GET THE NEXT WORD FOR TYPEOUT
NXTWRD:	CALL	NDTFOO		;GET NEXT DOT FOO
	MOVE	T1,DOTFOO
	MOVEI	T2,2		;WANT 2 BYTES
	SKIPE	PDP8F
	MOVEI	T2,1
	CALL	GETWRD		;FIND WHAT NEXT WORD IS
	RET			;LOST
	MOVEM	T1,ESC.Q.	;IN CASE OF <ESCAPE>Q LATER
	RETSKP
;HERE TO TYPE DATA AS AN ADDRESS
DATADR:	CALL	ADRTYP
	SOJLE	T5,B3.TYP	;HAVE WE DONE ENOUGH ?
	CALL	BLANKT		;TYPE A SPACE TO SEPERATE FIELDS
	CALL	NXTDWD		;GET NEXT DATA WORD
	JRST	DATADR		;AND TYPE NEXT WORD


;HERE TO TYPE DATA AS INSTRUCTIONS
DATINS:
	SKIPE	PDP8F
	JRST	TYP8IN		;TYPE PDP8 INSTRUCTION
	CALL	INVLFN		;SEE IF WE CAN FIND AN INSTRUCTION TO MATCH
	JRST	DATNUM
	MOVE	T1,(SYM)	;GET INSTRUCTION NAME
	CALL	SIXTYP
	MOVE	T5,2(SYM)	;GET FLAGS AGAIN
	CALL	BLANKT		;TYPE A BLANK
	TLNE	T5,SMF.EI	;EIS TYPE INSTRUCTION ?
	JRST	[LDB	T4,[POINT 6,DATA,35]	;GET SOURCE CODE
		CALL	DATIN8		;DISPLAY IT
		CALL	COMTYP
		LDB	T1,[POINT 3,DATA,29]	;GET REGISTER
		CALL	DATIN9		;TYPE REG NAME
		JRST	B3.TYP]
	TLNE	T5,SMF.PL	;SPL TYPE INSTRUCTION ?
	JRST	[LDB	T1,[POINT 3,DATA,35]	;GET ARGUMENT
		CALL	OCTYPE
		JRST	B3.TYP]
	TLNE	T5,SMF.MK	;MARK TYPE ARGUMENTS ?
	JRST	[LDB	T1,[POINT 6,DATA,35]	;GET ARGUMENT
		CALL	RADTYP		;TYPE ARGUMENT AS NUMBER
		JRST	B3.TYP]
	TLNE	T5,SMF.EM	;EMT TYPE ARGUMENTS ?
	JRST	[LDB	T1,[POINT 8,DATA,35]	;GET ARGUMENT
		HRROM	T1,LSTADR	;IN CASE OF TAB
		CALL	RADTYP		;TYPE ARGUMENT AS NUMBER
		JRST	B3.TYP]
	TLNE	T5,SMF.RT	;RTS TYPE ?
	JRST	[LDB	T1,[POINT 3,DATA,35]	;GET REG ADR
		CALL	DATIN9		;TYPE REG NAME
		JRST	B3.TYP]
	TLNE	T5,SMF.JS	;JSR TYPE ?
	JRST	[LDB	T1,[POINT 3,DATA,29]
		CALL	DATIN9		;TYPE REG NAME
		CALL	COMTYP
		JRST	.+1]
	TLNE	T5,SMF.SB	;SOB TYPE ?
	JRST	[LDB	T1,[POINT 3,DATA,29]	;GET REGISTER
		CALL	DATIN9		;TYPE REG NAME
		CALL	COMTYP
		LDB	T1,[POINT 6,DATA,35]	;GET OFFSET
		IMULI	T1,-2
		ADDI	T1,2(DOT)
		ANDI	T1,177777
		CALL	ADRTYP
		JRST	B3.TYP]
	TLNN	T5,SMF.SS	;12BIT SSDD FORMAT ?
	JRST	DATIN2		;NO
	LDB	T4,[POINT 6,DATA,29]	;GET SS CODE
	CALL	DATIN8
	CALL	COMTYP
DATIN2:	TLNN	T5,SMF.SS!SMF.DD	;IS THERE A 6 BIT DESTINATION CODE ?
	JRST	DATIN4		;NO
	LDB	T4,[POINT 6,DATA,35]	;GET DD CODE
	CALL	DATIN8
DATIN4:	TLNN	T5,SMF.BR	;IS THIS BR TYPE ADDRESSING ?
	JRST	B3.TYP		;NO
	LDB	T1,[POINT 8,DATA,35]	;GET OFFSET
	TRNE	T1,200		;CHECK FOR NEGATIVE OFFSET
	IORI	T1,177400
	AOS	T1
	LSH	T1,1		;MAKE WORD ADDRESS
	ADD	T1,DOT
	ANDI	T1,177777	;16 BITS ONLY
	CALL	ADRTYP		;TYPE ADDRESS
	JRST	B3.TYP
DATIN8:	CAIN	T4,27		;CHECK FOR IMMEDIATE MODE
	JRST	[CALL	HSHTYP		;TYPE A #
		CALL	NXTWRD		;GET NEXT WORD
		RET
		JRST	ADRTYP]
	CAIN	T4,37		;CHECK FOR ABSOLUTE MODE
	JRST	[CALL	NXTWRD		;GET NEXT WORD
		RET
		JRST	ADRTYP]
	TRNE	T4,10		;CHECK FOR DEFERRED MODE
	CALL	[MOVEI	T1,"@"
		PJRST	TYPCHR]
	CAIE	T4,77		;CHECK FOR RELATIVE DEFERRED MODE
	CAIN	T4,67		;CHECK FOR RELATIVE MODE
	JRST	[CALL	NXTWRD		;GET NEXT WORD
		RET
		ADD	T1,DOTFOO	;MAKE RELATIVE
		ADDI	T1,2
		JRST	ADRTYP]
	LDB	T1,[POINT 3,T4,32]	;GET MODE
	CAIE	T1,4
	CAIN	T1,5
	CALL	MINTYP
	CAIL	T1,6		;CHECK FOR INDEX OR INDEX DEFERRED
	JRST	[CALL	NXTWRD		;GET NEXT WORD
		RET
		CALL	ADRTYP
		JRST	DATIN1]
	TRNE	T1,6
DATIN1:	CALL	[MOVEI	T1,"("
		PJRST	TYPCHR]
	LDB	T1,[POINT 3,T4,35]	;GET REGISTER VALUE
	CALL	DATIN9		;TYPE REGISTER NAME
	TRNN	T4,60
	RET			;PLAIN REGISTER MODE
	MOVEI	T1,")"
	CALL	TYPCHR
	LDB	T1,[POINT 3,T4,32]
	CAIE	T1,2
	CAIN	T1,3
	CALL	PLUTYP
	RET
DATIN9:	ANDI	T1,7		;STRIP EXTRA BITS
	HRLI	T1,400000	;FLAG IS A REGISTER
	MOVEM	T1,LSTADR	;IN CASE DOES A TAB
	HRRZS	T1
	CALL	RGFNDN		;FIND REGISTERS NAME
	JRST	[CALL	PCNTYP		;TYPE A %
		CALL	OCTYPE
		RET]
	MOVE	T1,(SYM)	;GET REGISTERS NAME
	JRST	SIXTYP
;HERE TO TYPE A PDP8 INSTRUCTION
TYP8IN:	LDB	T1,[POINT 3,DATA,26]	;PICK UP OP CODE
	CAIN	T1,7		;IS THIS AN OPERATE INSTRUCTION ?
	JRST	OPRTYP		;YES SO SPECIAL HANDLING
	MOVE	T1,[SIXBIT \AND\
		SIXBIT	\TAD\
		SIXBIT	\ISZ\
		SIXBIT	\DCA\
		SIXBIT	\JMS\
		SIXBIT	\JMP\
		SIXBIT	\IOT\](T1)
	CALL	SIXTYP
	CALL	BLANKT
	LDB	T1,[POINT 3,DATA,26]	;GET OP CODE AGAIN
	CAIL	T1,6
	JRST	[LDB	T1,[POINT 9,DATA,35]
		CALL	RADTYP
		JRST	B3.TYP]
	MOVE	T2,DATA		;GET INSTRUCTION
	MOVEI	T1,[BYTE (7)"@",0]
	TRNE	T2,400		;IS INDIRECT BIT ON ?
	CALL	TYPSTR
	MOVE	T2,DOT
	ANDI	T2,7600
	LDB	T1,[POINT 8,DATA,35]
	TRZE	T1,200
	ADDI	T1,(T2)
	PUSH	P,T1		;SAVE ADR
	CALL	ADRTYP		;TYPE ADR
	POP	P,T1		;GET ADR BACK
	MOVE	T2,DATA		;GET DATA AGAIN
	TRNN	T2,400		;WAS THIS AN INDIRECT CASE ?
	JRST	B3.TYP		;NOT INDIRECT SO DONE
	LDB	T2,[POINT 3,T2,26]	;GET OP CODE
	CAIN	T2,6		;IOTS DON'T USE ADDRESSES
	JRST	B3.TYP
	PUSH	P,T1		;SAVE ADR AGAIN
	MOVEI	T1,"\"
	CALL	TYPCHR
	POP	P,T1		;GET ADR AGAIN
	MOVEI	T2,1		;ONLY NEED ONE WORD
	CALL	GETWRD		;GET THAT WORD
	JRST	[CALL	CALER0
		JRST	LEVEL0 ]
	CALL	ADRTYP
	JRST	B3.TYP
;HERE TO TYPE AN OPERATE INSTRUCTION
OPRTYP:	SETZ	T5,		;ACCUMULATE BITS MATCHED HERE
	SKIPN	SYM,SYMBEG	;GET STARTING ADDR FOR SYMBOL TABLE
	EXIT			;OH GOOD GRIEF !!
OPRTY1:	MOVE	T1,2(SYM)	;GET FLAGS FOR SYMBOL & MASK
	TLNE	T1,SMF.P8	;IS THIS A PDP8 SYMBOL ?
	TLNN	T1,SMF.IN	;AND IS THIS AN INSTRUCTION ?
	JRST	OPRTY5		;REJECT THIS SYMBOL
	AND	T1,DATA		;GET VALUE UNDER MASK
	CAME	T1,1(SYM)	;HIT RIGHT ONE ?
	JRST	OPRTY5		;NO
	SKIPE	T5		;FOUND ANY OTHERS YET ?
	CALL	BLANKT		;YES SO TYPE A SPACE
	MOVE	T1,(SYM)	;GET SYMBOL NAME
	CALL	SIXTYP		;TYPE SYMBOL
	IOR	T5,1(SYM)	;REMBER BITS WE EXPLAINED
OPRTY5:	MOVEI	SYM,4(SYM)	;POINT TO NEXT SYMBOL BLOCK
	CAME	SYM,SYMEND	;HIT END OF TABLE ?
	JRST	OPRTY1		;LOOP BACK FOR REST
	ANDI	T5,7777		;STRIP EXTRA BITS
	CAME	T5,DATA		;DID WE MATCH ALL BITS ?
	CALL	QESTYP		;NO SO ADD QUESTION MARK
	JRST	B3.TYP		;CLEAN UP
;HERE TO TYPE DATA AS ASCII TEXT
DATASC:	SKIPE	PDP8F		;WAS THIS A PDP8 WORD ?
	JRST	DATAS2		;YES SO ONLY ONE CHAR/WORD
	ANDI	T1,377		;ONLY 8 BITS PLEASE
	CALL	DATAS3
	SOJLE	T5,B3.TYP
	LDB	T1,[POINT 8,DATA,27]
DATAS2:	CALL	DATAS3
	SOJLE	T5,B3.TYP
	CALL	NXTDWD		;GET NEXT DATA WORD
	JRST	DATASC

;HERE TO TYPE CONTENTS OF T1 AS AN ASCII CHAR IF PRINTABLE, ELSE TYPE <#>
DATAS3:	MOVEM	T1,T3		;SAVE IN CASE NOT ASCII
	ANDI	T1,177		;STRIP PARITY BIT
	CAIL	T1,40
	CAILE	T1,176
	CAIA			;SPECIAL HANDLING
	JRST	TYPCHR		;JUST TYPE CHARACTER
	PUSH	P,T3		;SAVE WEIRD CHARACTER
	MOVEI	T1,"<"
	CALL	TYPCHR
	POP	P,T1		;GET CHAR
	CALL	RADTYP
	MOVEI	T1,">"
	PJRST	TYPCHR
;HERE TO TYPE DATA AS EBCDIC TEXT

DATEBC:	SKIPE	PDP8F		;IS THIS PDP8 STUFF ?
	JRST	DATEB2		;YES SO ONLY ONE CHAR/WORD
	CALL	DATEB3
	SOJLE	T5,B3.TYP
	LDB	T1,[POINT 8,DATA,27]
DATEB2:	CALL	DATEB3
	SOJLE	T5,B3.TYP
	CALL	NXTDWD		;GET NEXT DATA WORD
	JRST	DATEBC
DATEB3:	ANDI	T1,377
	SETZ	T2,
	LSHC	T1,-2
	ROT	T2,2
	LDB T1,[POINT	8,EB.TRN(T1),7
		POINT	8,EB.TRN(T1),15
		POINT	8,EB.TRN(T1),23
		POINT	8,EB.TRN(T1),31 ](T2)
	PJRST	DATAS3
;HERE TO TYPE DATA AS BYTES

DATBYT:	ANDI	T1,377
	SKIPE	PDP8F
	ANDI	T1,77		;SIX BIT BYTES FOR PDP8
	CALL	RADTYP
	SOJLE	T5,B3.TYP
	CALL	COMTYP		;TYPE A COMMA
	LDB	T1,[POINT 8,DATA,27]
	SKIPE	PDP8F
	LDB	T1,[POINT 6,DATA,29]
	CALL	RADTYP		;TYPE IN CURRENT RADIX
	SOJLE	T5,B3.TYP
	CALL	COMTYP		;TYPE A COMMA
	CALL	NXTDWD		;GET NEXT DATA WORD
	JRST	DATBYT
	PJRST	B3.TYP		;TYPE 3 SPACES
; TO TYPE A NUMBER IN THE CURRENT RADIX
; CALL	MOVE	T1,<NUM TO TYPE>
;	CALL	RADTYP	;CLOBBERS T1
;	RETURN		;OTHER REGS PRESERVED
RADTYP:	CALL	SAVE24
	HRRZ	T3,ORADIX
	CALL	RADTY2
	CAIN	T3,^D10
	CALL	PERTYP		;TYPE A "."
	RET

;HERE TO TYPE DECIMAL NUMBER
; CALL	MOVE	T1,<NUM TO TYPE>
;	CALL	DECTYP	;CLOBBERS T1
;	RETURN		;OTHER REGS PRESERVED
DECTYP:	CALL	SAVE24
	MOVEI	T3,^D10
	JRST	RADTY2

;HERE TO TYPE AN OCTAL NUMBER AS SIX DIGITS
; CALL	MOVE	T1,<NUM TO TYPE>
;	CALL	OCTYPE	;CLOBBERS T1
;	RETURN		;OTHER REGS PRESERVED
OCTYP6:	CALL	SAVE24
	MOVEI	T3,^D8
	MOVEI	T4,6
	JRST	RADTY3

;HERE TO TYPE AN OCTAL NUMBER
; CALL	MOVE	T1,<NUM TO TYPE>
;	CALL	OCTYPE	;CLOBBERS T1
;	RETURN		;OTHER REGS PRESERVED
OCTYPE:	CALL	SAVE24
	MOVEI	T3,^D8
	;JRST	RADTY2

RADTY2:	SETZ	T4,
RADTY3:	JUMPGE	T1,RADTY5
	MOVMS	T1
	CALL	MINTYP

RADTY5:	IDIVI	T1,(T3)
	HRLM	T2,(P)
	SOSG	T4
	SKIPE	T1
	CALL	RADTY5
RADTY7:	HLRE	T1,(P)
	ADDI	T1,"0"
	CAILE	T1,"9"
	ADDI	T1,7		;DOING HEX
	PJRST	TYPCHR
;HERE TO TYPE A DECIMAL NUMBER WITH COMMAS
PDECTY:	CALL	SAVE24
	MOVEI	T3,^D10
	JUMPGE	T1,PRADT5
	MOVMS	T1
	CALL	MINTYP
PRADT5:	IDIVI	T1,(T3)
	HRLM	T2,(P)
	JUMPE	T1,RADTY7
	PUSH	P,[EXP RADTY7]
	IDIVI	T1,(T3)
	HRLM	T2,(P)
	JUMPE	T1,RADTY7
	PUSH	P,[EXP RADTY7]
	IDIVI	T1,(T3)
	HRLM	T2,(P)
	JUMPE	T1,RADTY7
	PUSH	P,[54-60,,RADTY7]
	PUSH	P,[EXP RADTY7]
	JRST	PRADT5

SIXTYP:	MOVEM	T1,T2
SXTYP1:	SETZ	T1,
	LSHC	T1,6
	ADDI	T1,40
	CALL	TYPCHR
	JUMPN	T2,SXTYP1
	RET
COLTYP:	PUSH	P,T1
	MOVEI	T1,":"
	PJRST	TYPEIT

QESTYP:	PUSH	P,T1
	MOVEI	T1,"?"
	PJRST	TYPEIT

TABTYP:	PUSH	P,T1
	MOVEI	T1,"	"
TYPEIT:	CALL	TYPCHR
	JRST TPOPJ

CRLTYP:	PUSH	P,T1
	MOVEI	T1,15		;CARRIAGE RETURN
	CALL	TYPCHR
	MOVEI	T1,12		;LINEFEED
	PJRST	TYPEIT

B3.TYP:	CALL	BLANKT
	CALL	BLANKT
	;JRST	BLANKT
BLANKT:	PUSH	P,T1
	MOVEI	T1," "
	PJRST	TYPEIT

COMTYP:	PUSH	P,T1
	MOVEI	T1,","
	PJRST	TYPEIT

PERTYP:	PUSH	P,T1
	MOVEI	T1,"."
	PJRST	TYPEIT

PCNTYP:	PUSH	P,T1
	MOVEI	T1,"%"
	PJRST	TYPEIT

HSHTYP:	PUSH	P,T1
	MOVEI	T1,"#"
	PJRST	TYPEIT

MINTYP:	PUSH	P,T1
	MOVEI	T1,"-"
	PJRST	TYPEIT

PLUTYP:	PUSH	P,T1
	MOVEI	T1,"+"
	PJRST	TYPEIT
;HERE TO TYPE OR PRINT A STRING OF CHARACTERS
; CALL	MOVEI	T1,<ADR OF ASCIZ STRING>
;	CALL	TYPSTR
TYPSTR:	PUSH	P,T2
	MOVE	T2,[POINT 7,0]
	ADDI	T2,(T1)		;COPY STRING POINTER
TYPST3:	ILDB	T1,T2		;GET NEXT CHAR
	JUMPE	T1,TYPST5
	CALL	TYPCHR		;TYPE THE CHARACTER
	JRST	TYPST3
TYPST5:	POP	P,T2		;RESTORE REGISTER
	RET

;HERE TO TYPE OR PRINT A SINGLE CHARACTER
TYPCHR:	SKIPE	OHD		;DOING A DUMP ?
	JRST	TYPCH3		;YES
	OUTCHR	T1
	RET

TYPCH3:	SOSGE	OHD+2		;ROOM IN BUFFER
	JRST	TYPCH4		;NO
	IDPB	T1,OHD+1
	RET
TYPCH4:	OUT
	JRST	TYPCH3
	HALT
;HERE TO TYPE PROGRAM NAME
IDTYPE:	TYPE	<DDT11 >
	LDB	T1,[POINT 9,.JBVER,11]
	CALL	OCTYPE
	LDB	T1,[POINT 6,.JBVER,17]
	MOVEI	T1,100(T1)
	CAIE	T1,100
	CALL	TYPCHR
	MOVEI	T1,"("
	CALL	TYPCHR
	HRRZ	T1,.JBVER
	CALL	OCTYPE
	MOVEI	T1,")"
	CALL	TYPCHR
	LDB	T1,[POINT 3,.JBVER,2]
	MOVNS	T1
	SKIPE	T1
	CALL	OCTYPE
	HRROI	T1,3		;CODE FOR PROGRAM NAME
	GETTAB	T1,
	JRST	IDTYP2
	CAMN	T1,[SIXBIT \DDT11\]
	JRST	IDTYP2
	PUSH	P,T1
	TYPE	< = >
	POP	P,T1
	CALL	SIXTYP
IDTYP2:	SKIPN	SYMDEV
	JRST	IDTYP3
	TYPE	< /SYMBOLS=>
	MOVEI	T1,SYMDEV
	CALL	FILTYP
IDTYP3:	CALL	BLANKT		;TYPE A BLANK
	RET
;HERE TO TYPE THE DATE
DATETY:	DATE	T1,
DATET0:	IDIVI	T1,^D31*^D12	;LEAVE YEAR-64 IN T1
	ADDI	T1,^D64
	PUSH	P,T1		;SAVE YEAR
	IDIVI	T2,^D31
	ADDI	T2,MONTAB	;GET NAME OF MONTH
	PUSH	P,T2		;SAVE ADR OF MONTH NAME
	AOS	T1,T3		;GET DAY
	CALL	DECTYP
	CALL	MINTYP		;TYPE A "-"
	POP	P,T1		;GET MONTH
	CALL	TYPSTR		;TYPE MONTH NAME
	CALL	MINTYP		;TYPE A "-"
	POP	P,T1		;GET YEAR
	CALL	DECTYP
	RET
MONTAB:	ASCIZ	\Jan\
	ASCIZ	\Feb\
	ASCIZ	\Mar\
	ASCIZ	\Aprl\
	ASCIZ	\May\
	ASCIZ	\June\
	ASCIZ	\July\
	ASCIZ	\Aug\
	ASCIZ	\Sept\
	ASCIZ	\Oct\
	ASCIZ	\Nov\
	ASCIZ	\Dec\
;HERE TO TYPE THE TIME OF DAY
TIMTYP:	CALL	SAVE13
	MSTIME	T1,		;GET TIME OF DAY IN MS
TIMTY1:	PUSH	P,T1		;SAVE TIME
	IDIVI	T1,^D1000	;GET RID OF MS
	IDIVI	T1,^D60		;LEAVES SECONDS IN T2
	PUSH	P,T2
	CALL	TIMTY3		;TYPE HH:MM
	CALL	COLTYP		;TYPE A COLON
	POP	P,T1
	CALL	DC2TYP		;TYPE 2 DIGIT DECIMAL NUMBER
	POP	P,T1		;TIME ORIGINAL TIME AGAIN
	CAIL	T1,^D60*^D1000	;LESS THAN A MINUTE ?
	RET			;NO SO DONE
	CALL	PERTYP		;TYPE A "."
	IDIVI	T1,^D1000	;GET MS FROM ORIGINAL TIME
	EXCH	T1,T2
	CAIL	T2,^D10
	JRST	[IDIVI	T1,^D100	;LEAVE TENTHS
		JRST	DECTYP ]	;TYPE TENTH'S
	IDIVI	T1,^D10
	JRST	DC2TYP		;TYPE HUNDRETHS
TIMTY3:	IDIVI	T1,^D60		;LEAVES MIN IN T2
	PUSH	P,T2
	CALL	DECTYP
	CALL	COLTYP		;TYPE A COLON
	POP	P,T1
	JRST	DC2TYP		;TYPE 2 DIGIT DECIMAL NUMBER

DC2TYP:	CAIL	T1,^D10
	JRST	DECTYP
	PUSH	P,T1
	MOVEI	T1,"0"
	CALL	TYPCHR
	POP	P,T1
	JRST	DECTYP
	SUBTTL	DUMP TO FILE

ESC..D:	TXO	FLG,F.FLIP	;ASSUME DOING COMMAND LOGGING
	TXZ	FLG,F..FOO	;ASSUME NOT DOING A DISASSEMBLY
	CALL	ESC.D0		;SET UP TO CALL OPNFIL
	SKIPE	CMDFIL		;PROCESSING A COMMAND FILE ?
	JRST	DUMP0		;DON'T OPEN A NEW DUMP
	CALL	OPNFIL
	JRST	DUMP9
	TXZ	FLG,F.FLIP	;NOT DOING COMMAND LOGGING
	CALL	ESC.D3		;PUT TITLE LINE ON DUMP
DUMP0:	SETZM	CACHEL		;SWEEP CACHE
	TXO	FLG,F.CACH	;PUT USE IT AFTER IT IS SET UP
	HRRO	DOT,SBEGIN	;WHERE TO BEGIN DUMP
	TXNN	FLG,F..FOO	;DOING A DIASSSEMBLY ?
	JRST	DUMP2		;GO DO USUAL DUMP
	PUSH	P,O.MODE	;SAVE OUTPUT MODE
	PUSH	P,BYTCNT	;AND REPETITION COUNT
DISA10:	CALL	CRLTYP		;TYPE A <CR><LF>
	CALL	TABTYP		;TYPE A <HT>
	CALL	DUMP6		;FIND IF LOCATION IS REAL
	JRST	DUMP8		;NOT REAL SO DONE
	HRRZ	T1,DOT		;GET CURRENT LOCATION
	CALL	OCTYP6		;TYPE SIX DIGIT OCTAL NUMBER
	CALL	TABTYP
	HRRZ	T1,DOT		;CURRENT LOCATION
	SETZM	O.MODE		;ASSUME DUMPING AS AN INSTRUCTION
	CALL	CNINWD		;FIND HOW MANY WORDS IN INSTRUCTION
	JRST	[	MOVEI	T1,1		;CODE FOR ADR TYPEOUT
			MOVEM	T1,O.MODE
			JRST	.+1 ]
	MOVEI	T5,(T1)		;NUMBER OF WORDS
	MOVEI	T1,(DOT)	;CURRENT ADR
	CALL	DISA40
	MOVEI	T1,2(DOT)
	CALL	DISA40
	MOVEI	T1,4(DOT)
	CALL	DISA40
	HRRZ	T1,DOT		;GET ADR TO TYPE TAG
	CALL	VALFND		;TRY TO FIND TAG FOR THIS LOCATION
	JRST	DISA20		;NO TAG HERE
	HRRZ	T1,DOT
	CAME	T1,1(SYM)	;EXACT MATCH ?
	JRST	DISA20		;NO IS SAME AS NOT CLOSE
	MOVE	T1,(SYM)	;GET SYMBOL NAME
	CALL	SIXTYP
	CALL	COLTYP		;PUT COLON AFTER SYMBOL
DISA20:	CALL	TABTYP
	CALL	DATYPE
	MOVE	T1,DOTFOO
	SETZM	DOTFOO
	CALL	DOTINC
	MOVEM	T1,DOT
	HRRZS	T1
	CAMG	T1,S..END
	JRST	DISA10
DISA90:	POP	P,BYTCNT	;RESTORE REPETITION COUNT
	POP	P,O.MODE	;AND OUTPUT MODE
	JRST	DUMP8

DISA40:	SOJL	T5,TABTYP
	MOVEI	T2,2
	CALL	GETWRD
	JRST	DISA90		;CAN'T GET = DONE
	CALL	OCTYP6
	JRST	TABTYP
DUMP1:	HRRZ	T1,DUMPA	;LAST ADDRESS WE TYPED
	ADDI	T1,20
	CAILE	T1,(DOT)	;TIME TO TYPE ADR AGAIN ?
	JRST	DUMP4
DUMP2:	CALL	CRLTYP
	CALL	CRLTYP
	HRRZ	T1,DOT
	CALL	ADRTYP
	JUMPE	SYM,DUMP3	;IF THERE WAS NO SYMBOL DON'T REPEAT
	CALL	BLANKT
	MOVEI	T1,"="
	CALL	TYPCHR
	CALL	BLANKT
	HRRZ	T1,DOT
	CALL	OCTYPE
DUMP3:	CALL	COLTYP		;TYPE A COLON
	HRRZ	T1,DOT
	ANDI	T1,177760	;IN CASE WAS HIGH
	MOVEM	T1,DUMPA	;REMEMBER LAST ADR WE TYPED
	CAIA			;SO WE DO AN EXTRA TAB
DUMP4:	TRNN	DOT,7
	CALL	TABTYP

	CALL	DUMP6		;GET NEXT WORD TO DUMP
	JRST	DUMP8		;ALL DONE
	CALL	DATYPE		;DUMP LOCATION
	MOVE	T1,DOTFOO
	SETZM	DOTFOO
	CALL	DOTINC
	MOVEM	T1,DOT
	HRRZS	T1
	CAMG	T1,S..END
	JRST	DUMP1

DUMP8:	CALL	CRLTYP
	CALL	CRLTYP
DUMP85:	TXNN	FLG,F.FLIP	;DON'T FLUSH IF LOGGING COMMANDS
	CALL	DONE.W
	CALL	CRLTYP
	CALL	CRLTYP
	JRST	LEVEL0

DUMP9:	SETZM	OHD
	TYPE	<error writing >
	CALL	FILERR
	JRST	LEVEL0

;HERE TO USE DOT TO GET THE NEXT WORD FROM PDP11 (AND LOAD CACHE)
; CALL	CALL	DUMP6
;	LOSE RETURN
;	WIN RETURN DATA IN T1
DUMP6:	HRRZ	T1,DOT		;GET ADDRESS TO EXAMINE
	MOVE	T2,S..END
	SUB	T2,T1
	CAIL	T2,EXMAX
	SKIPA	T2,[EXP EXMAX]
	ADDI	T2,^D2
	CALL	GETWRD
	RET
	MOVEM	T1,DATA
	RETSKP

DUMPA:	BLOCK	1		;LAST ADDRESS TYPED OUT
DEFINE	NAMES <
	X	DISASS,SETFOO	;/DISASSEMBLY
>;DEFINE NAMES
	DEFINE	X (A,B) <	0,,B	>
DMPDSP:	NAMES

DEFINE	X (A,B) <	SIXBIT	\A\ >
DMPSWL:	NAMES
	EXP	0
;HERE TO SETUP FOR CALL TO OPNFIL
ESC.D0:	TXO	FLG,F.WRIT!F.APND	;REMEMBER WE ARE WRITING
	HRROI	T1,3
	GETTAB	T1,		;GET NAME OF JOB
	MOVE	T1,[SIXBIT \DDT11\]
	MOVSI	T2,'LSD'
	MOVE	T3,[DMPDSP,,DMPSWL]
	MOVEI	T4,RSKP
	RET

;HERE TO PUT A TITLE LINE ON A DUMP
ESC.D3:	MOVEI	T1,[BYTE (7)15,12,14,0]
	CALL	TYPSTR
	TYPE	<dump made >
	CALL	TIMTYP		;TYPE TIME
	CALL	BLANKT
	CALL	DATETY		;TYPE DATE
	TYPE	< of />
	MOVE	T1,[SIXBIT \PORT:\]
	SKIPE	MEMORY
	MOVE	T1,[SIXBIT \FILE:\]
	SKIPE	NODE
	MOVE	T1,[SIXBIT \NODE:\]
	CALL	SIXTYP
	SKIPE	MEMORY
	JRST	[	MOVEI	T1,DMPDEV
			CALL	FILTYP		;TYPE FILE ID
			JRST	ESC.D4 ]
	SKIPN	T1,NODE
	HRRZ	T1,PORT
	MOVEI	T2,OCTYPE
	TLNE	T1,-1
	MOVEI	T2,SIXTYP
	CALL	(T2)
ESC.D4:	TYPE	<
	by >
	CALL	IDTYPE
	CALL	CRLTYP
	CALL	CRLTYP
	RET
	SUBTTL	DUMP TO A BINARY FILE

ESC..P:	TXO	FLG,F.WRIT!F.PACK	;REMEMBER WE ARE WRITING
	TXZ	FLG,F.APND
	MOVE	T1,[SIXBIT /KRUFT/]	;DEFAULT FILE NAME
	MOVSI	T2,'BIN'	;DEFAULT EXTENSION
	MOVE	T3,[PUNDSP,,PUNSWL]

	SETZ	T4,
	SETZM	PROM.F#
	CALL	OPNFIL		;OPEN FILE
	JRST	LEVEL0
	SKIPE	T1,PROM.F#
	JRST	PROM
	MOVEI	T1,^D18		;ASSUME HALFWORD WRITES
	TXNN	FLG,F.PACK	;UNLESS DOING PAPER TAPE
	MOVEI	T1,^D36		;IN WHICH CASE DO FULL WORDS
	DPB	T1,[POINT 6,OHD+1,11]
	MOVE	DOT,SBEGIN
	SETZM	CACHEL		;SWEEP THE CACHE
	TXO	FLG,F.CACH	;CAN USE THE CACHE FROM NOW ON
ESCP00:	SETZ	T4,		;NUMBER OF BYTES FOR CURRENT SEGMENT
	HRRZ	T3,DOT		;NEXT ADR TO GET
ESCP02:	MOVE	T1,T3		;NEXT ADR TO EXAMINE
	IDIVI	T1,^D36
	PUSH	P,T1		;SAVE RELATIVE PDP10 WORD ADR
	MOVN	T1,T2
	MOVSI	T2,400000	;MAKE BIT FOR WORD
	LSH	T2,(T1)		; MAKE IT RIGHT BIT
	POP	P,T1		;GET RELATIVE WORD ADR AGAIN
	TDNN	T2,@MEMUSE
	JRST	ESCP10		;WORD NOT IN USE
	MOVE	T1,T3		;NEXT ADR TO EXAMINE
	MOVEI	T2,1		;ONLY WANT ONE BYTE
	CALL	GETWRD		;TRY TO GET THE WORD
	JRST	ESCP10
	AOS	T4		;ANOTHER WORD TO DUMP
	CAML	T3,S..END
	JRST	ESCP10		;DONE
	CAIGE	T4,^D256
	AOJA	T3,ESCP02
ESCP10:	JUMPN	T4,ESCP11	;ANY BYTES
	AOJA	DOT,ESCP20	;NO SO ADVANCE WHERE TO DUMP FROM
ESCP11:	SETZ	T5,		;INITIALIZE THE CHECKSUM
	MOVEI	T1,1
	CALL	WRTWRD		;WRITE BINARY WORD
	MOVE	T1,T4		;COUNT FOR SEGMENT
	ADDI	T1,6
	CALL	WRTWRD
	HRRZ	T1,DOT
	CALL	WRTWRD
ESCP12:	HRRZ	T1,DOT
	AOS	DOT
	MOVEI	T2,1
	CALL	GETWRD
	EXIT
	SOJLE	T4,ESCP16
	PUSH	P,T1		;SAVE DATA
	HRRZ	T1,DOT
	AOS	DOT
	MOVEI	T2,1
	CALL	GETWRD
	EXIT
	DPB	T1,[POINT 8,(P),27]
	POP	P,T1
	CALL	WRTWRD
	SOJG	T4,ESCP12
	MOVE	T1,T5		;GET CHECKSUM
	ANDI	T1,377		;STRIP EXTRA BITS
	CALL	WRTWRD
	JRST	ESCP19
ESCP16:	SUB	T5,T1		;INCLUDE LAST CHAR IN CHECKSUM
	DPB	T5,[POINT 8,T1,27]
	CALL	WRTWRD

ESCP19:	SETZ	T1,		;ADD PAD BETWEEN SEQMENTS
	CALL	WRTWRD
	CALL	WRTWRD
	CALL	WRTWRD
ESCP20:	HRRZ	T1,DOT
	CAMGE	T1,S..END
	JRST	ESCP00
	SETZ	T5,		;INITIALIZE THE CHECKSUM
	MOVEI	T1,1
	CALL	WRTWRD
	MOVEI	T1,6
	CALL	WRTWRD
	SKIPN	T1,GOTO		;STARTING ADDRESS
	MOVEI	T1,1
	CALL	WRTWRD
	MOVE	T1,T5
	ANDI	T1,377
	CALL	WRTWRD
	CALL	DONE.W		;CLOSE OUTPUT FILE
	JRST	LEVEL2

WRTWRD:	SUB	T5,T1
	ROT	T1,-^D8
	SUB	T5,T1
	ROT	T1,^D8
	TXNN	FLG,F.PACK	;PUNCHING TAPE ?
	JRST	WRTBN4
	SOSGE	OHD+2		;IS THERE ROOM IN BUFFER ?
	CALL	WRTBN9		;NO ROOM
	ANDI	T1,177777	;STRIP EXTRA BITS
	IDPB	T1,OHD+1	;PUT WORD INTO BUFFER
	RET
WRTBN4:	SOSGE	OHD+2		;ROOM FOR LOW ORDER BITS ?
	CALL	WRTBN9
	PUSH	P,T1
	ANDI	T1,377		;ONLY 8 BITS
	IDPB	T1,OHD+1
	POP	P,T1
	LDB	T1,[POINT 8,T1,27]
	SOSGE	OHD+2
	CALL	WRTBN9
	IDPB	T1,OHD+1
	RET
WRTBN9:	SOS	(P)
	SOS	(P)
	OUT
	RET
	JRST	FILERR		;COMPLAIN
	DEFINE	NAMES <
	X	BM873,PUNBM8
	X	IMAGE,PUNIMG
	X	M9301,PUNM93
	X	PACKED,PUNPAK
>
	DEFINE	X (Q,QQ) < EXP QQ >
PUNDSP:	NAMES
	DEFINE	X (Q,QQ) < SIXBIT \Q\ >
PUNSWL:	NAMES
	EXP	0

PUNIMG:	TXZA	FLG,F.PACK
PUNPAK:	TXO	FLG,F.PACK
	RET

PUNBM8:	SETO	T1,
	CAIA
PUNM93:	MOVEI	T1,1
	MOVEM	T1,PROM.F#
	RET
PROM:	CALL	PROM.2
	NOP
	CALL	PROM.2
	LSH	T1,-^D4
	SKIPG	PROM.F		;SKIP IF M9301
	JRST	DUMP85
	CALL	PROM.2
	LSH	T1,-^D8
	CALL	PROM.2
	LSH	T1,-^D12
	JRST	DUMP85
PROM.2:	MOVEI	T1,377
	CALL	TYPCHR
	MOVE	DOT,SBEGIN
	MOVEI	T4,^D128	;FOR BM873
	SKIPL	PROM.F
	MOVEI	T4,^D256	;FOR M9301
PROM.4:	HRRZ	T1,DOT
	MOVEI	T2,2		;REQUEST 2 BYTES
	CALL	GETWRD
	SETZ	T1,
	TRC	T1,777001
	XCT	@(P)
	SKIPGE	PROM.F#
	PUSH	P,T1
	ANDI	T1,17
	CALL	TYPCHR
	SKIPL	PROM.F
	JRST	PROM.6
	POP	P,T1
	LSH	T1,-^D8
	ANDI	T1,17
	CALL	TYPCHR
PROM.6:	ADDI	DOT,2
	SOJG	T4,PROM.4
	SKIPGE	PROM.F
	JRST	PROM.9		;DON'T NEED FOR BM873

	HRRO	DOT,S..END
	MOVEI	T4,^D256
PROM.8:	HRRZ	T1,DOT
	MOVEI	T2,2
	CALL	GETWRD
	SETZ	T1,
	TRC	T1,777001
	XCT	@(P)
	ANDI	T1,17
	CALL	TYPCHR
	ADDI	DOT,2
	SOJG	T4,PROM.8

PROM.9:	MOVEI	T4,^D256
	SETZ	T1,
	CALL	TYPCHR
	SOJGE	T4,.-1
	AOS	(P)
	RET
;HERE TO GET A CHARACTER IN LINE MODE
RDCHAR:	SKIPE	CMDFIL		;ARE WE DOING COMMAND FILE STUFF ?
	CALL	CMDCHR		;GET A COMMAND FILE CHAR
	INCHWL	T1		;GET THE NEXT CHAR
	CAIN	T1,32		;IS THIS A CONTROL Z ?
	EXIT
	CALL	GETCH8
	JRST	RDCHAR
	RET

;HERE TO GET A CHARACTER FROM THE TTY
GETCHR:	SKIPE	T1,CMDTKR	;ARE WE RETYPING COMMAND LINE ?
	JRST	GETCH3		;YES SO DO IT THAT WAY
	SKIPE	CMDFIL		;ARE WE DOING COMMAND FILE STUFF ?
	CALL	CMDCHR		;GET A COMMAND FILE CHAR
	INCHRW	T1		;GET THE NEXT CHAR
GETCH1:	CALL	GETCH8
	JRST	GETCHR
	RET

GETCH3:	CAME	T1,CMDLIM	;RETYPED ENOUGH YET ?
	JRST	GETCH4		;NOT YET
	SETZM	CMDTKR		;DONE WITH TAKER
	JRST	GETCHR
GETCH4:	ILDB	T1,CMDTKR
	JRST	GETCH1

GETCH8:	JUMPE	T1,R		;FLUSH NULLS
	TXNN	FLG,F.TEXT	;DOING TEXT MODE STUFF ?
	CAIE	T1,15		;IS THIS A CARRIAGE RETURN ?
	JRST	GETCH9
	CALL	GETCHR		;GET LF
	CAIN	T1,15		;WAS THIS A 2ND CR ?
	JRST	GETCH8		;YES SO FLUSH IT ALSO
	MOVEI	T1,15		;CONVERT LF TO CR
GETCH9:	RETSKP
	SUBTTL	/FILE: HANDLING

;HERE BECAUSE FOUND /FILE IN RESPONSE INITIAL DIAGLOGUE
; READ EITHER A BOOT11 OR NETLDR DUMP OR A BINARY FILE

RDDUMP:	SETZB	T1,T2		;IN CASE CORE NOT SETUP YET
	SKIPG	MEMLIM		;ANYTHING PUT IN MEMORY YET ?
	CALL	PUTFOO		;NO SO MAKE SOME CORE
	SETZ	AC1,		;HIGHEST LOCATION SO FAR
	MOVE	T1,[SIXBIT \PDPXI0\]	;DEFAULT FILE NAME
	MOVE	T2,[SIXBIT \LSDBIN\]	;DEFAULT EXTENSION
	TXNE	FLG,F.FLOP	;READING BINARY FILE ?
	MOVSI	T2,'BIN'	;DEFAULT EXTENSION FOR BIN FILES
	MOVE	T1,[FILDEV,,DMPDEV]
	BLT	T1,DMPDEV+$FBLEN-1	;COPY FILDEV, FILNAM, FILEXT, FILPPN, FILTIM
	MOVE T1,[SIXBIT /DTED00/];IF FILE STARTS WITH DTED, ASSUME BIN
	XOR T1,FILNAM
	TDNN T1,[XWD -1,770000]	;MASK DOR "DTED"
	JRST [	TXNN FLG,F.FLOP	;IF NOT "/BINARY"
		TXO FLG,F..FOO	;SAY /DTE FOR HIM
		JRST .+1]
	TXNE FLG,F..FOO		;IS IT /DTE?
	JRST RDTDMP		;YES, READ THE DUMP
	HLRZ	T1,FILEXT	;GET FILE EXTENSION
	CAIE	T1,'BIC'	;OTHER WAY TO SPELL BIN
	CAIN	T1,'BIN'	;DID WE READ A BINARY FILE ?
	TXO	FLG,F.FLOP	;YES SO READING BINARY FILE
	SETZB	T5,T4		;ACCUMULATE CHECKSUM HERE
	TXNE	FLG,F..FOO	;DID WE GET A /DTELDR
	JRST	RDTDMP		;YES SO GO READ IT
	TXZN	FLG,F.FLOP	;READING A BINARY FILE ?
	JRST	RDUMP0		;NO READING A DUMP

	MOVEI	T1,^D36		;WANT 36BIT HEADERS
	CALL	SETIHD		;SO SET EM

;HERE TO LOOK FOR INITIAL 1
RDBN10:	CALL	RDBN70		;GET NEXT CHAR
	JRST	RDUMP9		;ALL DONE
	JUMPE	T1,RDBN10	;LOOP ON HEADER
	CAIE	T1,1		;IS THIS LEADING 1 ?
	JRST	RDBNER		;ERROR IN FORMAT
	CALL	RDBN70		;GET NEXT WORD = 0
	JRST	RDBNER		;ERROR IN FORMAT
	JUMPN	T1,RDBNER
	CALL	RDBN60		;GET 16BIT WORD = COUNT
	MOVEI	T3,-6(T1)	;MAKE BYTE COUNT
	CALL	RDBN60		;GET 16BIT WORD = ADR
	MOVE	T2,T1		;COPY ADDRESS
	TXZ	FLG,F.FLIP	;NO DATA MAYBE
	JUMPE	T3,RDBN30
RDBN20:	TXO	FLG,F.FLIP	;THIS SEGMENT HAD DATA
	CALL	RDBN70		;GET NEXT BYTE TO STUFF
	JRST	RDBNER
	CAMLE	T2,AC1
	HRRZ	AC1,T2		;NEW HIGHEST LOCATION LOADED
	CALL	PUTFOO		;PUT BYTE INTO MEMORY
	AOS	T2		;ADVANCE LOCATION COUNTER
	SOJG	T3,RDBN20
RDBN30:	CALL	RDBN60		;INCLUDE CHECKSUM IN CALC
	TRNE	T5,377		;TEST CHECKSUM
	JRST	[	TYPE	<CHECKSUM ERROR>
			EXIT	]
	TXNE	FLG,F.FLIP
	JRST	RDBN10		;PROBABLY MORE DATA
	ANDI	T2,177776	;ONLY 16 BITS & EVEN
	MOVEM	T2,GOTO		;SAVE STARTING ADDRESS
	MOVEM T2,SIMREG+PC	;SET INITIAL PC
	JRST	RDUMP9
;HERE TO READ A DTELDR DUMP
;TO DO THIS PROPERLY, THE LENGTH OF THE FILE SHOULD BE READ
; VERIFIED TO BE 34000 WORDS.  THE FIRST WORD SHOULD ALSO HAVE
; THE SIGN BIT ON.
;DTELDR DUMPS ARE (BY BLIND LUCK) IN THE SAME FORMAT AS DDT11'S
; INTERNAL MEMORY REPRESENTATION.
RDTDMP:	CALL	POSYMT		;MAKE SURE THE SYMTAB IS WHER EIT OUGHT
	PUSH	P,SYMBEG	;SAVE WHAT WILL BE THE START OF MEMUSE
	MOVEI	T1,<160000/4>+<160043/44> ;SIZE OF MEMUSE + MEMORY
	CALL	MOVSMT		;GET THE ROOM.

	POP	P,T1		;FIRST FREE LOC BACK
	HRLI	T1,T1		;GET THE INCESTUOUS POINTER
	MOVEM	T1,MEMUSE	; AND SAVE POINTER TO MEMUSE TABLE
	ADDI	T1,160043/44	;RELOCATE BY THE SIZE OF MEMUSE
	HRRZM	T1,MEMORY	; AND SAVE POINTER TO START OF MEMORY

	HRRZ	T1,MEMUSE	;GET BACK ADDRESS OF USE TABLE
	HRL	T2,T1		;MAKE A BLT POINTER TO
	HRRI	T2,1(T1)	; TO THE USE TABLE
	SETOM	(T1)		;BLT ALL BUT THE LAST WORD
	BLT	T2,<160000/44>-1(T1) ;TO "IN USE"
	MOVE	T2,[EXP -1_<44-<160000-<160000/44>*44>>] ;GET AND
	MOVEM	T2,160043/44-1(T1) ; STORE MASK FOR LAST WORD

	MOVSI	T1,-<160000/4>	;NOW AN IOWD TO THE
	HRR	T1,MEMORY	; MEMORY
	SOS	T1		; FOR A QUICK "IN"
	SETZ	T2,		;TERMINATE THE COMMAND LIST
	SETSTS	1,.IODMP	;SET DUMP MODE IO
	USETI	1,1		;GO TO THE FIRST BLOCK
	IN	1,T1		;READ THE FILE
	 CAIA			; OK
	  PUSHJ	P,IFILER	;REPORT THE ERROR
	RELEAS	1,		;DONE WITH THE FILE
	MOVEI	AC1,157777	;SET HIGHEST ADDRESS LOADED
	MOVEM	AC1,DOT		;REMEMBER WHERE WE ARE AS WELL
	MOVEM	AC1,MEMLIM	;SET THE TOP OF MEMORY
	JRST	RDUMP9		;DONE
;HERE TO SET BYTE SIZE FOR INPUT HEADER
; CALL	MOVEI	T1,<BYTE SIZE>
;	CALL	SETIHD
SETIHD:	LDB	T3,[POINT 6,IHD+1,11]	;GET S FIELD FROM INPUT POINTER
	DPB	T1,[POINT 6,IHD+1,11]	;SET NEW S FIELD
	MOVEI	T2,^D36
	IDIVI	T2,(T3)		;FIND NUMBER OF BITS/BYTE CURRENT
	MOVEM	T1,T3		;SAVE NEW SIZE
	MOVE	T1,IHD+2	;NUMBER OF BYTES IN CURRENT BUFFER
	IDIVI	T1,(T2)		;MAKE NUMBER OF WORDS IN CURRENT BUFFER
	MOVEI	T2,^D36
	IDIVI	T2,(T3)		;GET NUMBER OF BYTES/WORD IN NEW SIZE
	IMULI	T1,(T2)		;NUMBER OF BYTES OF NEW SIZE
	MOVEM	T1,IHD+2	;SAVE IT
	RET
;HERE TO GET SIXTEEN BITS
RDBN60:	CALL	RDBN70		;GET LOW ORDER BITS
	JRST	RDBNER
	PUSH	P,T2
	LSHC	T1,-^D8		;SHOVE EM INTO T2
	CALL	RDBN70		;GET HIGH ORDER BITS
	JRST	RDBNER
	ROTC	T1,^D8		;ADD LOW ORDER BITS
	POP	P,T2
	RET			;RETURN TO CALLER

;HERE TO GET NEXT BYTE FROM BINARY FILE
RDBN70:	JUMPE	T4,RDBN74	;HALF OF PREVIOUS WORD LEFT ?
	LDB	T1,[POINT 8,T4,27]	;LOW ORDER BITS FROM PREV HLF WRD
	SETZ	T4,		;DONE WITH HALF WORD
	JRST	RDBN79
RDBN74:	SOSGE	IHD+2		;MORE DATA IN BUFFER ?
	JRST	RDBN80		;NO SO READ MORE
	ILDB	T1,IHD+1
	TXNN	FLG,F.FLOP	;IS THIS PACKED FILE ?
	JRST	RDBN79		;NO
	HRRO	T4,T1		;COPY HALF WORD
	LDB	T1,[POINT 8,T4,35]	;GET HIGH ORDER BITS
RDBN79:	ANDI	T1,377		;STRIP EXTRA BITS
	ADDI	T5,(T1)		;INCLUDE IN CHECKSUM
	RETSKP

RDBN80:	IN	1,		;GET NEXT BUFFER
	JRST	RDBN85		;GOT NEXT BUFFER
	RET
RDBN85:	HRRZ	T1,IHD		;GET ADDRES OF CURRENT BUFFER
	HLRE	T1,2(T1)	;GET FIRST WORD IN BUFFER
	JUMPE	T1,RDBN70	;PROCEED
	TXO	FLG,F.FLOP	;IS PACKED FILE
	LDB	T1,[POINT 6,IHD+1,11]	;GET S FIELD FROM INPUT POINTER
	CAIN	T1,^D18		;HALF WORD POINTER
	JRST	RDBN70		;YES
	MOVEI	T1,^D18
	DPB	T1,[POINT 6,IHD+1,11]	;CHANGE POINTER
	MOVE	T1,IHD+2	;GET WORD COUNT
	LSH	T1,1		;MULTIPLY BY 2
	MOVEM	T1,IHD+2
	JRST	RDBN70

RDBNER:	TYPE	<improper format in input tape>
	EXIT

DMPDEV:	EXP	0		;DEVICE FOR DUMP FILE
	EXP	0		; LENGTH OF LOOKUP/ENTER BLOCK
DMPDIR:	EXP	0		; ADDRESS OF PATH BLOCK
	EXP	0		; FILE NAME
	EXP	0		; FILE EXTENSION
DMPTIM:	BLOCK	1		; TIME/DATE AND PROTECTION
DMPPTH:	BLOCK	2+5+1		; FILE DIRECTORY
	BLOCK	1		; SWITCHES WORD
	BLOCK	$FBLEN-<.-DMPDEV>
;ROUTINES TO READ BOOT11 OR NETLDR DUMPS

;HERE TO FLUSH REST OF INPUT LINE
RDUMP0:	CALL	FILCHR		;GET NEXT CHAR FROM DUMP
	JRST	RDUMP9		;END OF DUMP
	MOVE	T2,T1		;COPY CHAR
RDUMP1:	CAIE	T2,12		;WE ARE LOOKING FOR A LINE FEED
	CAIN	T2,15		;OR A CARRIAGE RETURN
	JRST	RDUMP2
	CAIE	T2,14		;BUT A FORM FEED WILL DO
	JRST	RDUMP0		;AND DIDN'T FIND ONE
RDUMP2:	CALL	INPOCT		;GET ADR
	JRST	RDUMP9
	CAIE	T2,":"		;FINISHED READING ADDRESS ?
	JRST	RDUMP1		;FLUSH LINE
	HRROM	T1,DOT		;SAVE ADDRESS
RDUMP5:	CALL	INPOCT		;GET DATA FOR LINE
	JRST	RDUMP9		;END OF DUMP
	CAIN	T2,40		;CHECK FOR SPACE
	JRST	RDUMP6		;THAT WAS DATA
	CAIE	T2,15		;CHECK FOR CR
	CAIN	T2,11		;CHECK FOR HT
	JRST	RDUMP6		;THAT WAS DATA
	JRST	RDUMP1		;FLUSH LINE
RDUMP6:	HRRZ	T2,DOT		;GET ADDRESS
	CAMLE	T2,AC1
	HRRZ	AC1,T2		;NEW HIGHEST LOCATION LOADED
	CALL	PUTFOO
	SKIPE	PDP8F
	AOJA	DOT,RDUMP5	;YES SO BACK FOR MORE DATA
	LSH	T1,-^D8
	AOS	T2,DOT
	CAMLE	T2,AC1
	HRRZ	AC1,T2		;NEW HIGHEST LOCATION LOADED
	CALL	PUTFOO
	AOJA	DOT,RDUMP5	;BACK FOR MORE DATA

RDUMP9:	MOVE	T1,MEMLIM	;HIGHEST ADDRESS READ
	MOVEM	T1,S..END	;END OF SEARCH
	TYPE	< highest location is >
	MOVE	T1,AC1		;HIGHEST LOCATION LOADED
	CALL	ADRTYP		;DISPLAY ADDRESS
	CALL	CRLTYP		;TYPE A CR/LF
	MOVEI	T1,RSTART
	MOVEM	T1,.JBREN##
	TXO	FLG,F.WENB	;SET WRITE ENABLE CAUSE SHOULDN'T HURT
	SKIPN	MRGFLG		;WANTED TO MERGE ?
	JRST	LEVL.0		;NO SO START
	RETSKP
;PDP11 WORDS ARE STORED IN PDP10 MEMORY AS FOLLOWS
;
;                      1             1 1 1 2             2 2             3
;  0 1 2             9 0             7 8 9 0             7 8             5
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; ! ! !    byte 1     !    byte 0     ! ! !    byte 3     !    byte 2     !
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;
;THE SPARE BITS ARE USED AS A FLAG TO SAY BYTE HAS BEEN USED
; I.E. BYTE WAS READ INTO FROM DUMP OR BINARY FILE OR WRITTEN BY USER
; E.G. IF BYTE 0 IS SET THEN BIT 1 IS SET AS A FLAG

MEMORY:	EXP	0		;ADDRESS OF DUMP MEMORY
MEMLIM:	EXP	-1		;HIGHEST LOCATION IN DUMP
				; BIT ON IFF BYTE READ OR DEPOSITED
MEMUSE:	EXP	0		;T1,,POINTER TO MEMORY USE TABLE
				; FOR EACH BYTE IN SIMULATED MEMORY, BIT WILL
				; BE SET IF BYTE SET BY LOAD OR USER
	SUBTTL	SIMULATION

;REGISTER USAGE

;WHEN SIMULATING REGS 0-7 ARE USED FOR CORRESPONDING PDP11 REG'S
; REGISTERS ALWAYS CLEAR EXCEPT FOR BITS 20-35
SP=	6		;SIMULATED STACK POINTER
PC=	7		;SIMULATED PC
		; PC MUST ALWAYS BE EVEN
MA=	T3		;CONTAINS LAST ADR SETUP UP BY CALLS THROUGH RFETCH
		; SO RSTORE USES SAME LOC.   WORD ADDRESSES ARE LOADED THEN
		; ROTATED RIGHT 2 POSITIONS.   BYTE ADDRESS ARE DIVIDED BY 4.
		; REMAINDER OF DIVISION IS KEPT IN MA+1
MA..UN==040000		;ADDRESS IS A UNIBUS DEVICE
MA..RG==020000		;LOCATION IS REGISTER
MA..IO==010000		;LOCATION IS IN PERIPHERAL AREA (I.E. 170000-177777)
IR=	T5		;CONTAINS INSTRUCTION WHEN SIMULATING
PS=	16		;SIMULATED PS
PS...T==000020		;TRAP BIT
PS...N==000010		;RESULT WAS NEGATIVE
PS...Z==000004		;RESULT WAS ZERO
PS...V==000002		;RESULT WAS ARITH OVERFLOW
PS...C==000001		;RESULT WAS A CARRY

P.PLVL:	POINT	3,PS,30		;BYTE POINTER TO GET PROCESSOR LEVEL
;MACRO TO REMEMBER REFERENCES TO SIMULATED CORE
RLMSIZ=	0
	DEFINE	MEMREL (QQ) <
	IF2	<
Q=	.
	RELOC	RLMTAB+RLMSIZ
	QQ,,Q
	RELOC	Q
>;IF2
RLMSIZ=	RLMSIZ+1
>;DEFINE MEMREL
;MACRO TO GET A WORD FROM MEMORY
; FIRST ARG IS REGISTER TO USE AS AN INDEX
; 2ND ARG IS DESTINATION
	DEFINE	LOAD (Q,QQ) <
	XLIST
IFN	<Q-PC> <
	TRNE	Q,1
	JRST	NXM...		;DO ODD ADDRESS TRAP
>;IFN <Q-PC>
IFN	<MA-Q>,< HRRZ	MA,Q >	;COPY REG SO WE CAN ROT IT
		MEMREL	MEMLIM
	CAIL	MA,0
IFE	<QQ-T1> <
	CALL	IOLOAD
LODRET==4		;NUMBER OF INSTRUCTIONS TO SKIP
>;IFE <QQ-T1>
IFN	<QQ-T1> <
	JRST	[MOVEM	T1,IOLT1S#	;SAVE T1
		CALL	IOLOAD+2
		HRRZ	QQ,T1
		MOVE	T1,IOLT1S#	;RESTORE T1
		JRST	.+LODRET+1]
>;IFN <QQ-T1>
	ROT	MA,-2
	SKIPGE	MA
		MEMREL	MEMORY
	SKIPA	QQ,0(MA)
		MEMREL	MEMORY
	HLRZ	QQ,0(MA)
	ANDI	QQ,177777	;STRIP EXTRA BITS
IFE	<QQ-PC> <
	TRNE	PC,1
	JRST	NXM...		;DO ODD ADDRESS TRAP
>;IFE <QQ-PC>
>;DEFINE LOAD (Q,QQ)
;MACRO TO GET A BYTE FROM MEMORY
; FIRST ARG IS REGISTER TO USE AS AN INDEX
; 2ND ARG IS DESTINATION
	DEFINE	BLOAD (Q,QQ) <
	XLIST
IFN	<MA-Q>,< HRRZ	MA,Q >	;COPY REG SO WE CAN DIVIDE IT
		MEMREL	MEMLIM
	CAIL	MA,0
	CALL	IOBLOD
BLDRET==7		;NUMBER OF INSTRUCTIONS TO SKIP
	LSHC	MA,-2		;IDIVI	MA,4
	LSH	MA+1,-^D34
	TRNE	MA+1,2
	 MEMREL	MEMORY
	SKIPA	QQ,0(MA)	;GET RH OF WORD
	 MEMREL	MEMORY
	HLRZ	QQ,0(MA)	;GET LH OF WORD
	TRNE	MA+1,1		;WANT ODD BYTE ?
	LSH	QQ,-^D8		;YES
	ANDI	QQ,377		;STRIP EXTRA BITS
>;DEFINE BLOAD (Q,QQ)
;MACRO TO STORE WORD OR BYTE IN MEMORY AFTER DOING LOAD FROM SAME LOCATION
; ADDRESS IS IN MA, DATA IS FOUND IN T1 (LH MAY BE NONZERO E.G. SBC)

	DEFINE	RSTORE (FLAG,TYPE) <
	XLIST
IFE	<<FLAG>&SMF.BY> <	;FOLLOWING FOR WORD MODE
	TLNE	MA,MA..RG	;WAS LOCATION A REGISTER ?
	JRST	[HRRM	T1,(MA)		;DEPOSIT APPROPRIATE REG
		TRNN	PC,1		;IN CASE SET PC
		JRST	SIM11		;PC WAS GARBAGED
		JRST	NXM...	]	;TAKE A TRAP
	TLNE	MA,MA..IO	;WAS LOCATION AN IO REGISTER ?
	JRST	[PUSH	P,[EXP SIM11]	;PUSH RETURN ON STACK
		JRST	IOR.'TYPE ]	;RESTORE WORD TO MEMORY
	SKIPGE	MA
	JRST	.+3
	MEMREL	MEMORY
	HRLM	T1,0(MA)
	JRST	SIM11
	MEMREL	MEMORY
	HRRM T1,0(MA)
>;IFE <<FLAG>&SMF.BY>

IFN	<<FLAG>&SMF.BY> <	;FOLLOWING FOR BYTE RESTORE
	TLNN MA,MA..RG	;WAS LOCATION A REGISTER ?
	JRST .+5		;NOT A REGISTER
	DPB T1,[POINT 8,(MA),35]	;THIS IS SLOW BUT PROB BEST WAY
	TRNN PC,1		;CHECK PC NOT POLLUTED
	JRST SIM11
	JRST NXM...		;TAKE A BUS TRAP

	TLNE MA,MA..IO	;WAS LOCATION AN IO REGISTER ?
	JRST [PUSH	P,[EXP SIM11]	;PUSH RETURN ON STACK
		JRST	IOBR.'TYPE ]	;RESTORE BYTE TO MEMORY
	DPB T1,SIMPTR(MA+1)	;PUT BYTE BACK INTO MEMORY
>;IFN <<FLAG>&SMF.BY>
>;DEFINE RSTORE
;MACRO TO STORE A WORD IN MEMORY
; FIRST ARG IS REGISTER TO USE AS AN INDEX
; 2ND ARG IS DESTINATION
	DEFINE	STORE (Q,QQ) <
	XLIST
IFN	<Q-PC> <
	TRNE	Q,1
	JRST	NXM...		;TAKE A BUS TRAP
>;IFE <Q-PC>
IFN	<MA-Q>,< HRRZ	MA,Q >
	MEMREL	MEMLIM
	CAIL	MA,0		;BE SURE IN CORE
	JRST	[IFN	<T1-QQ>,< HRRZ T1,QQ>
Z=	7
		IFE	<Q-6> <Z=Z+2>
		PUSH	P,[EXP .+Z]
		JRST	IOSTOR ]
IFE	<Q-6>,<
	CAIGE	MA,400		;IS THIS A STACK VIOLATION ?
	JSR	STCKVP		;RECORD VIOLATION (& RESTORE PS)
>;IFE <Q-6>
	ROT	MA,-2
	SKIPGE	MA
	JRST	.+3
	MEMREL	MEMORY
	HRLM	QQ,0(MA)
	JRST	.+2
	MEMREL	MEMORY
	HRRM	QQ,0(MA)
>;DEFINE STORE (Q,QQ)
;MACRO TO STORE A BYTE IN MEMORY
; FIRST ARG IS REGISTER TO USE AS AN INDEX
; 2ND ARG IS DESTINATION
	DEFINE	BSTORE (Q,QQ) <
	XLIST
	 IFN	<MA-Q>,< HRRZ	MA,Q >
		MEMREL	MEMLIM
	CAIL	MA,0		;BE SURE IN CORE
	JRST	[IFN	<T1-QQ>,< HRRZ T1,QQ>
Z=	4
		IFE	<Q-6>,<Z=Z+2>
		PUSH	P,[EXP .+Z]
		JRST	IOBSTO ]
	 IFE	<Q-6>,<
	CAIGE	MA,400		;IS THIS A STACK VIOLATION ?
	JSR	STCKVP		;RECORD VIOLATION (& RESTORE PS)
    >;IFE <Q-6>
	LSHC	MA,-2		;IDIVI	MA,4
	LSH	MA+1,-^D34
	DPB	QQ,SIMPTR(MA+1)	;STORE BYTE IN MEMORY
>;DEFINE BSTORE (Q,QQ)
;MACRO TO PUT PC AND PS ON STACK
	DEFINE	INTSAV (VEC) <
	XLIST
	CAIG	SP,177774
	CAIG	SP,400-40
	JRST	RSTACK		;RED STACK VIOLATION
	MOVEI	SP,-4(SP)
	HRRZI	MA,2(SP)
	STORE	MA,PS		;SAVE PS ON STACK
	STORE	SP,PC		;SAVE PC ON STACK
	MOVEI	MA,VEC
	LOAD	MA,T2		;GET NEW PC IN TEMP REG
	MOVEI	MA,2+VEC
	LOAD	MA,T1		;GET NEW PS
	ANDI	T1,377		;ONLY HAVE A RH
	EXCH	PS,T1		;SET NEW PS (AND PRESERVE OLD ONE)
	MOVE	PC,T2		;LOAD NEW PC
	CALL	PS.CHK		;ADJUST FOR NEW PS LEVEL
	TRNE	PC,1		;BE SURE OK
	JRST	NXM...		;TAKE A BUS TRAP
>;DEFINE INTSAV
	DEFINE	ADC. (FLAG) <
	JSR	@RFETCH(IR)	;GET OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V
	TRZE	PS,PS...C
	JRST	.+6
	TRNE	T1,100000
	TRO	PS,PS...N
	JUMPN	T1,SIM11
	TRO	PS,PS...Z
	JRST	SIM11
	AOS	T1
	TRNE	T1,100000
	TRO	PS,PS...N
	TRZE	T1,200000	;OVERFLOW IFF WENT TO ZERO
	TRO	PS,PS...Z!PS...C
	CAIN	T1,100000
	TRO	PS,PS...V
	RSTORE	FLAG
	>
	DEFINE	ADCB. (FLAG) <
	JSR	@BRFTCH(IR)	;GET OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V
	TRZE	PS,PS...C
	JRST	.+6
	TRNE	T1,000200
	TRO	PS,PS...N
	JUMPN	T1,SIM11
	TRO	PS,PS...Z
	JRST	SIM11
	AOS	T1
	TRNE	T1,000200
	TRO	PS,PS...N
	TRZE	T1,000400	;OVERFLOW IFF WENT TO ZERO
	TRO	PS,PS...Z!PS...C
	CAIN	T1,000200
	TRO	PS,PS...V
	RSTORE	FLAG
	>
	DEFINE	ADD. (FLAG) <
	MOVE	T2,T1		;SAVE SRC
	JSR	@RFETCH(IR)	;GET DST
	MOVE	IR,T1		;SAVE COPY OF DST FOR PS...V CALC
	ADD	T1,T2		;MAKES RESULT
	TRZ	PS,PS...N!PS...Z!PS...V!PS...C
	TRNE	T1,100000	;CHECK FOR NEGATIVE
	TRO	PS,PS...N
	TRZE	T1,600000	;CHECK FOR OVERFLOW
	TRO	PS,PS...C
	SKIPN	T1
	TRO	PS,PS...Z
	EQV	IR,T2		;SRC EQV DST
	XOR	T2,T1		;RESULT XOR SRC
	AND	T2,IR
	TRNE	T2,100000
	TRO	PS,PS...V
	RSTORE	FLAG
	>
	DEFINE	ASH. (FLAG) <
	ANDI	T2,7		;LEAVE ONLY REG FIELD
	JSR	@FETCH(IR)	;GET NN
	TRZ	PS,PS...N!PS...Z!PS...V!PS...C
	MOVE	MA,(T2)		;GET REGISTER TO SHIFT
	TRNE	MA,100000	;WAS REGISTER NEGATIVE ?
	IOR	MA,[-1,,700000]	;EXTEND SIGN
	TRNE	T1,40		;RIGHT OR LEFT SHIFT ?
	JRST	[IORI	T1,777740	;SHIFT RIGHT
		ASHC	MA,(T1)		;SHIFT IT
		TLNE	MA+1,200000	;WAS LAST BIT OUT A 1 ?
		TRO	PS,PS...C	;REMEMBER LAST BIT OUT
		JRST	.+13 ]
	ANDI	T1,37		;SHIFT LEFT
	;JUMPE	T1, ????		*****
	;	*****				*****
	;	*****	WHAT IF SHIFT 0 ???	*****
	;	*****				*****
	JOV	.+1		;CLEAR FLAG
	ASH	MA,(T1)		;SHIFT IT
	TRNE	MA,200000	;WAS LAST BIT OUT SET ?
	TRO	PS,PS...C	;LAST BIT OUT WAS SET
	JOV	.+4		;LOSE ANY BITS ?
	SKIPGE	T1,MA		;NEGATIVE ?
	XOR	T1,[-1,,700000]
	TDNE	T1,[-1,,700000]
	TRO	PS,PS...V
	ANDI	MA,177777	;STRIP EXTRA BITS
	TRNE	MA,100000	;IS RESULT NEGATIVE ?
	TRO	PS,PS...N	;WAS NEGATIVE RESULT
	SKIPN	MA		;WAS RESULT ZERO ?
	TRO	PS,PS...Z	;YES
	MOVEM	MA,(T2)		;UPDATE ORIGINAL REGISTER
	TRNE	PC,1		;DID THAT POLLUTE THE PC ?
	JRST	NXM...		;GIVE A BUS TRAP
	>
	DEFINE	ASHC. (FLAG) <
	; *****				*****
	; *****	WHAT IF REG IS ODD ??	*****
	; *****				*****
	ANDI	T2,7		;LEAVE ONLY REG FIELD
	JSR	@FETCH(IR)	;GET NN
	TRZ	PS,PS...N!PS...Z!PS...V!PS...C
	MOVE	MA,(T2)		;GET HIGH ORDER BITS
	LSH	MA,^D16		;POSITION
	MOVE	IR,T2		;COPY REGISTER ADR
	IORI	IR,1		;MAKE LOW ORDER BITS ADR
	IOR	MA,(IR)		;GET LOW ORDER BITS
	TLNE	MA,020000	;WAS REG NEGATIVE ?
	TLO	MA,740000	;EXTEND SIGN
	TRNE	T1,40		;RIGHT OR LEFT SHIFT ?
	JRST	[IORI	T1,777740	;SHIFT RIGHT
		ASHC	MA,(T1)		;SHIFT IT
		TLNE	MA+1,200000;WAS LAST BIT OUT A 1 ?
		TRO	PS,PS...C
		JRST	.+13 ]
	ANDI	T1,37		;SHIFT LEFT
	;JUMPE	T1, ????		*****
	;	*****				*****
	;	*****	WHAT IF SHIFT 0 ???	*****
	;	*****				*****
	JOV	.+1		;CLEAR FLAG
	ASH	MA,(T1)		;SHIFT IT
	TLNE	MA,040000	;WIN A CARRY BIT ?
	TRO	PS,PS...C	;WON A CARRY
	JOV	.+4
	SKIPGE	T1,MA		;WAS THAT NEGATIVE ?
	TLC	T1,760000	;CL7AR EXTENDED SIGN
	TLNE	T1,760000	;DID WE LOSE BITS ?
	TRO	PS,PS...V	;LOST BITS
	TLNE	MA,020000	;IS RESULT NEGATIVE ?
	TRO	PS,PS...N	;WAS NEGATIVE RESULT
	TLZ	MA,740000	;STRIP EXTRA BITS
	SKIPN	MA		;WAS RESULT ZERO ?
	TRO	PS,PS...Z	;YES
	MOVE	T1,MA		;COPY RESULT
	ANDI	T1,177777	;STRIP EXTRA BITS
	MOVEM	T1,(IR)		;RESTORE LOW ORDER BITS
	LSH	MA,-^D16	;POSITION HIGH ORDER BITS
	MOVEM	MA,(T2)		;RESTORE NEW HIGH ORDER BITS
	TRNE	PC,1		;DID THAT POLLUTE THE PC ?
	JRST	NXM...		;GIVE A BUS TRAP
	>
	DEFINE	ASL. (FLAG) <
	JSR	@RFETCH(IR)	;GET OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V!PS...C
	TRNN	T1,040000	;CHECK NEW N BIT
	JRST	.+5		;NO NEW N BIT
	TRZE	T1,100000	;CHECK NEW C BIT
	TROA	PS,PS...N!PS...C
	TRO	PS,PS...N!PS...V
	JRST	.+3
	TRZE	T1,100000	;CHECK NEW C BIT
	TRO	PS,PS...C!PS...V
	LSH	T1,1
	SKIPN	T1
	TRO	PS,PS...Z
	RSTORE	FLAG
	>
	DEFINE	ASLB. (FLAG) <
	JSR	@BRFTCH(IR)	;GET OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V!PS...C
	TRNN	T1,000100	;CHECK NEW N BIT
	JRST	.+5		;NO NEW N BIT
	TRZE	T1,000200	;CHECK NEW C BIT
	TROA	PS,PS...N!PS...C
	TRO	PS,PS...N!PS...V
	JRST	.+3
	TRZE	T1,000200	;CHECK NEW C BIT
	TRO	PS,PS...C!PS...V
	LSH	T1,1
	SKIPN	T1
	TRO	PS,PS...Z
	RSTORE	FLAG
	>
	DEFINE	ASR. (FLAG) <
	JSR	@RFETCH(IR)	;GET OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V!PS...C
	TRNN	T1,100000	;CHECK NEW N BIT
	JRST	.+6		;NO NEW N BIT
	TRO	T1,200000	;SET NEW SIGN BIT
	TRZE	T1,1		;CHECK NEW C BIT
	TROA	PS,PS...N!PS...C
	TRO	PS,PS...N!PS...V
	JRST	.+3
	TRZE	T1,1		;CHECK NEW C BIT
	TRO	PS,PS...C!PS...V
	LSH	T1,-1
	SKIPN	T1
	TRO	PS,PS...Z
	RSTORE	FLAG
	>
	DEFINE	ASRB. (FLAG) <
	JSR	@BRFTCH(IR)	;GET OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V!PS...C
	TRNN	T1,000200	;CHECK NEW N BIT
	JRST	.+6		;NO NEW N BIT
	TRO	T1,000400	;SET NEW SIGN BIT
	TRZE	T1,1		;CHECK NEW C BIT
	TROA	PS,PS...N!PS...C
	TRO	PS,PS...N!PS...V
	JRST	.+3
	TRZE	T1,1		;CHECK NEW C BIT
	TRO	PS,PS...C!PS...V
	LSH	T1,-1
	SKIPN	T1
	TRO	PS,PS...Z
	RSTORE	FLAG
	>
	DEFINE	BCC. (FLAG) <
	TRNE	PS,PS...C
	JRST	SIM11		;NO BRANCH
	>
	DEFINE	BCS. (FLAG) <
	TRNN	PS,PS...C
	JRST	SIM11		;NO BRANCH
	>
	DEFINE	BEQ. (FLAG) <
	TRNN	PS,PS...Z
	JRST	SIM11
	>
	DEFINE	BGE. (FLAG) <
	TRNN	PS,PS...N
	JRST	[TRNE	PS,PS...V
		JRST	SIM11		;NO BRANCH
		JRST	.+3 ]
	TRNN	PS,PS...V
	JRST	SIM11		;NO BRANCH
	>
	DEFINE	BGT. (FLAG) <
	TRNE	PS,PS...Z
	JRST	SIM11		;NO BRANCH
	TRNN	PS,PS...N
	JRST	[TRNE	PS,PS...V
		JRST	SIM11		;NO BRANCH
		JRST	.+3 ]
	TRNN	PS,PS...V
	JRST	SIM11		;NO BRANCH
	>
	DEFINE	BHI. (FLAG) <
	TRNE	PS,PS...Z!PS...C
	JRST	SIM11		;NO BRANCH
	>
	DEFINE	BHIS. (FLAG) <
	TRNE	PS,PS...C
	JRST	SIM11		;NO BRANCH
	>
	DEFINE	BIC. (FLAG) <
	MOVE	T2,T1		;COPY SRC
	JSR	@RFETCH(IR)	;GET DST
	ANDCM	T1,T2		;CLEAR SOME BITS
	TRZ	PS,PS...N!PS...Z!PS...V
	TRNE	T1,100000
	TRO	PS,PS...N
	SKIPN	T1
	TRO	PS,PS...Z
	RSTORE	FLAG,C
	>
	DEFINE	BICB. (FLAG) <
	MOVE	T2,T1		;COPY SRC
	JSR	@BRFTCH(IR)	;GET DST
	ANDCM	T1,T2		;CLEAR SOME BITS
	TRZ	PS,PS...N!PS...Z!PS...V
	TRNE	T1,000200
	TRO	PS,PS...N
	SKIPN	T1
	TRO	PS,PS...Z
	RSTORE	FLAG,C
	>
	DEFINE	BIS. (FLAG) <
	MOVE	T2,T1		;COPY SRC
	JSR	@RFETCH(IR)	;GET DST
	IOR	T1,T2		;SET NEW BITS
	TRZ	PS,PS...N!PS...Z!PS...V
	TRNE	T1,100000
	TRO	PS,PS...N
	SKIPN	T1
	TRO	PS,PS...Z
	RSTORE	FLAG,S
	>
	DEFINE	BISB. (FLAG) <
	MOVE	T2,T1		;COPY SRC
	JSR	@BRFTCH(IR)	;GET DST
	IOR	T1,T2		;SET NEW BITS
	TRZ	PS,PS...N!PS...Z!PS...V
	TRNE	T1,000200
	TRO	PS,PS...N
	SKIPN	T1
	TRO	PS,PS...Z
	RSTORE	FLAG,S
	>
	DEFINE	BIT. (FLAG) <
	MOVE	T2,T1		;COPY FIRST OPERAND
	JSR	@FETCH(IR)	;GET 2ND OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V
	AND	T1,T2		;MASK THE BITS
	SKIPN	T1
	TRO	PS,PS...Z
	TRNE	T1,100000
	TRO	PS,PS...N
	>
	DEFINE	BITB. (FLAG) <
	MOVE	T2,T1		;COPY FIRST OPERAND
	JSR	@BFETCH(IR)	;GET 2ND OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V
	AND	T1,T2		;MASK THE BITS
	SKIPN	T1
	TRO	PS,PS...Z
	TRNE	T1,000200
	TRO	PS,PS...N
	>
	DEFINE	BLE. (FLAG) <
	TRNE	PS,PS...Z
	JRST	.+5		;BRANCH
	TRNE	PS,PS...N
	JRST	[TRNE	PS,PS...V
		JRST	SIM11		;NO BRANCH
		JRST	.+3 ]
	TRNN	PS,PS...V
	JRST	SIM11		;NO BRANCH
	>
	DEFINE	BLO. (FLAG) <
	TRNN	PS,PS...C
	JRST	SIM11		;NO BRANCH
	>
	DEFINE	BLOS. (FLAG) <
	TRNN	PS,PS...Z!PS...C
	JRST	SIM11		;NO BRANCH
	>
	DEFINE	BLT. (FLAG) <
	TRNE	PS,PS...N
	JRST	[TRNE	PS,PS...V
		JRST	SIM11		;NO BRANCH
		JRST	.+3 ]
	TRNN	PS,PS...V
	JRST	SIM11		;NO BRANCH
	>
	DEFINE	BMI. (FLAG) <
	TRNN	PS,PS...N
	JRST	SIM11		;NO BRANCH
	>
	DEFINE	BNE. (FLAG) <
	TRNE	PS,PS...Z
	JRST	SIM11
	>
	DEFINE	BPL. (FLAG) <
	TRNE	PS,PS...N
	JRST	SIM11		;NO BRANCH
	>
	DEFINE	BPT. (FLAG) <
	INTSAV	14
	>
	DEFINE	BR. (FLAG) <
	>
	DEFINE	BVC. (FLAG) <
	TRNE	PS,PS...V
	JRST	SIM11		;NO BRANCH
	>
	DEFINE	BVS. (FLAG) <
	TRNN	PS,PS...V
	JRST	SIM11		;NO BRANCH
	>
;DEFINE CCC. (FLAG) <>	;HANDLED BY .CCCLR
;DEFINE CLC. (FLAG) <>	;HANDLED BY .CCCLR
;DEFINE CLN. (FLAG) <>	;HANDLED BY .CCCLR
	DEFINE	CLR. (FLAG) <
	HRRM PS,PS.REG+1	;IN CASE OF BUS TRAP
	SETZ	T1,
	TRZ	PS,PS...N!PS...V!PS...C
	TRO	PS,PS...Z
	JRST	@STUFF(IR)
ZZRET==	-1
	>
	DEFINE	CLRB. (FLAG) <
	HRRM PS,PS.REG+1	;IN CASE OF BUS TRAP
	SETZ	T1,
	TRZ	PS,PS...N!PS...V!PS...C
	TRO	PS,PS...Z
	JRST	@BSTUFF(IR)
ZZRET==	-1
	>
;DEFINE CLV. (FLAG) <>	;HANDLED BY .CCCLR
;DEFINE CLZ. (FLAG) <>	;HANDLED BY .CCCLR
	DEFINE	CMP. (FLAG) <
	MOVE	T2,T1		;COPY FIRST OPERAND
	JSR	@FETCH(IR)	;GET 2ND OPERAND
	MOVE	IR,T2		;ANOTHER COPY OF SRC FOR PS...V CALC
	TRZ	PS,PS...N!PS...Z!PS...V!PS...C
	SUB	T2,T1
	TRNE	T2,100000
	TRO	PS,PS...N
	TRNN	T2,177777
	TRO	PS,PS...Z
	TRNE	T2,200000
	TRO	PS,PS...C
	XOR	IR,T1		;SRC XOR DST
	EQV	T1,T2		;CHECK RESULT AND DST
	AND	T1,IR
	TRNE	T1,100000
	TRO	PS,PS...V	;SAME SIGN SO OVERFLOW
	>
	DEFINE	CMPB. (FLAG) <
	MOVE	T2,T1		;COPY FIRST OPERAND
	JSR	@BFETCH(IR)	;GET 2ND OPERAND
	MOVE	IR,T2		;ANOTHER COPY OF SRC FOR PS...V CALC
	TRZ	PS,PS...N!PS...Z!PS...V!PS...C
	SUB	T2,T1
	TRNE	T2,000200
	TRO	PS,PS...N
	TRNN	T2,000377
	TRO	PS,PS...Z
	TRNE	T2,000400
	TRO	PS,PS...C
	XOR	IR,T1		;SRC XOR DST
	EQV	T1,T2		;CHECK RESULT AND DST
	AND	T1,IR
	TRNE	T1,000200
	TRO	PS,PS...V	;SAME SIGN SO OVERFLOW
	>
	DEFINE	COM. (FLAG) <
	JSR	@RFETCH(IR)	;GET OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V
	TRO	PS,PS...C
	TRCE	T1,177777	;PERFORM COMPLEMENT AND CHECK FOR -1 RESULT
	TRNE	T1,100000
	TRO	PS,PS...N
	SKIPN	T1
	TRO	PS,PS...Z
	RSTORE	FLAG
	>
	DEFINE	COMB. (FLAG) <
	JSR	@BRFTCH(IR)	;GET OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V
	TRO	PS,PS...C
	TRCE	T1,000377	;PERFORM COMPLEMENT AND CHECK FOR -1 RESULT
	TRNE	T1,000200
	TRO	PS,PS...N
	SKIPN	T1
	TRO	PS,PS...Z
	RSTORE	FLAG
	>
	DEFINE	DEC. (FLAG) <
	JSR	@RFETCH(IR)	;GET OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V
	SOSN	T1
	TRO	PS,PS...Z
	ANDI	T1,177777
	TRNE	T1,100000
	TRO	PS,PS...N
	CAIN	T1,077777
	TRO	PS,PS...V
	RSTORE	FLAG
	>
	DEFINE	DECB. (FLAG) <
	JSR	@BRFTCH(IR)	;GET OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V
	SOSN	T1
	TRO	PS,PS...Z
	ANDI	T1,000377
	TRNE	T1,000200
	TRO	PS,PS...N
	CAIN	T1,000177
	TRO	PS,PS...V
	RSTORE	FLAG
	>
	DEFINE	DIV. (FLAG) <
	ANDI	T2,7		;LEAVE REGISTER FIELD
	JSR	@FETCH(IR)	;GET DIVISOR
	TRZ	PS,PS...N!PS...Z!PS...V!PS...C
	JUMPE	T1,[TRO PS,PS...C!PS...V	;SET FLAGS
		JRST	SIM11 ]
	TRNE	T1,100000	;NEGATIVE DIVSOR ?
	IOR	T1,[-1,,700000]	;EXTEND SIGN
	MOVE	MA,(T2)		;GET HIGH ORDER BITS OF DIVIDEND
	LSH	MA,^D16		;POSITION
	TLNE	MA,020000	;NEGATIVE ?
	TLO	MA,760000	;EXTEND SIGN
	MOVE	IR,T2		;COPY REG ADR
	IORI	IR,1
	IOR	MA,(IR)		;GET LOW ORDER BITS
	IDIV	MA,T1		;DO THE DIVISION
	ANDI	MA,177777	;STRIP EXTRA BITS
	MOVEM	MA,(T2)
	TRO	T1,1		;OTHER REGISTER
	ANDI	MA+1,177777	;STRIP OTHER BITS
	MOVEM	MA+1,(T2)	;AND SAVE THESE AS WELL
	TRNE	MA,100000	;NEGATIVE RESULT ?
	TRO	PS,PS...N	;REMEMBER NEGATIVE
	ANDI	MA,177777	;STRIP EXTRA BITS
	SKIPN	MA
	TRO	PS,PS...Z	;REMEMBER ZERO RESULT
	TRNE	PC,1		;DID THAT POLLUTE THE PC ?
	JRST	NXM...		;GIVE A BUS TRAP
	>
	DEFINE	EMT. (FLAG) <
	INTSAV	30
	>
	DEFINE	FADD. (FLAG) <
	JRST	ILLINS
ZZRET==	-1
	>
	DEFINE	FDIV. (FLAG) <
	JRST	ILLINS
ZZRET==	-1
	>
	DEFINE	FMUL. (FLAG) <
	JRST	ILLINS
ZZRET==	-1
	>
	DEFINE	FSUB. (FLAG) <
	JRST	ILLINS
ZZRET==	-1
	>
	DEFINE	HALT. (FLAG) <
	TXZ	FLG,F.RUNF
	TXO	FLG,F.HALT	;FLAG WE DID A HALT
	HRROS	INTDLY		;SO WE NOTICE RUN FLOP
	>
	DEFINE	INC. (FLAG) <
	JSR	@RFETCH(IR)	;GET OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V
	AOS	T1
	TRNE	T1,100000
	TRO	PS,PS...N
	TRZE	T1,200000	;HAPPENS IIF
	TRO	PS,PS...Z	; OPERAND NOW ZERO
	CAIN	T1,100000
	TRO	PS,PS...V
	RSTORE	FLAG
	>
	DEFINE	INCB. (FLAG) <
	JSR	@BRFTCH(IR)	;GET OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V
	AOS	T1
	TRNE	T1,000200
	TRO	PS,PS...N
	TRZE	T1,000400	;HAPPENS IFF
	TRO	PS,PS...Z	; OPERAND NOW ZERO
	CAIN	T1,000200
	TRO	PS,PS...V
	RSTORE	FLAG
	>
	DEFINE	IOT. (FLAG) <
	INTSAV	20
	>
	DEFINE	JMP. (FLAG) <
	JSR	@JMPCLC(IR)	;CALCULATE ADDR
	MOVE	PC,T1		;SET NEW PC
	TRNE	PC,1		;BE SURE KOSHER PC
	JRST	NXM...
	>
	DEFINE	JSR. (FLAG) <
	JSR	@JMPCLC(IR)	;GET ADR OF JSR
	TRZ	T2,777770	;REG IN JSR REG,FOO
	HRLM	T1,T2		;SAVE SUBROUTINE ADR
	MOVE	T1,(T2)		;GET CURRENT REG CONTENTS
	MOVEI	SP,-2(SP)	;START PUSHING OLD REG ON STACK
	ANDI	SP,177777	;BE SURE DIDN'T PUSH TO FAR
	HRRZM	PC,(T2)		;PUT PC IN REG
	HLRZ	PC,T2		;GET SUBROUTINE ADR BACK
	HRRM PS,PS.REG+1	;SAVE PS IN CASE OF STACK VIOLATION
	STORE	SP,T1		;FINISH PUSHING REG ON STACK
	TRNE	PC,1		;BE SURE NEW PC KOSHER
	JRST	NXM...		;DIE
	>
	DEFINE	MARK. (FLAG) <
	ANDI	IR,77		;LEAVES N
	LSH	IR,1		;MAKES N*2
	HRRZ	SP,IR
	ADDI	SP,(PC)		;SP FROM PC + 2*NN
	HRRZ	PC,5		;PC FROM R5
	LOAD	SP,5
	MOVEI	SP,2(SP)
	ANDI	SP,177777
	TRNE	PC,1		;IS NEW PC OK
	JRST	NXM...		;TAKE A BUS TRAP
	>
	DEFINE	MFPS. (FLAG) <
	HRRM PS,PS.REG+1	;IN CASE OF BUS TRAP
	HRRZ	T1,PS		;GET DATA TO STORE
	TRZ	PS,PS...N!PS...Z!PS...V
	TRNE	T1,200
	TRO	PS,PS...N
	TRNN	T1,377
	TRO	PS,PS...Z
	JRST	@BSTUFF(IR)	;NOW STORE THE DATA
ZZRET==	-1
	>
	DEFINE	MOV. (FLAG) <
	HRRM PS,PS.REG+1	;SAVE PS IN CASE OF STACK VIOLATION
	TRZ	PS,PS...N!PS...Z!PS...V
	TRNE	T1,100000	;DO WE WANT N BIT
	TRO	PS,PS...N	;SET N BIT
	SKIPN	T1
	TRO	PS,PS...Z	;SET Z BIT
	JRST	@STUFF(IR)
ZZRET==	-1
	>
	DEFINE	MOVB. (FLAG) <
	HRRM PS,PS.REG+1	;SAVE PS IN CASE OF STACK VIOLATION
	TRZ	PS,PS...N!PS...Z!PS...V
	TRNE	T1,000200	;DO WE WANT N BIT
	TRO	PS,PS...N	;SET N BIT
	SKIPN	T1
	TRO	PS,PS...Z	;SET Z BIT
	TRNE	IR,70		;CHECK FOR REGISTER DST
	JRST	@BSTUFF(IR)
	TRNE	T1,200		;WANT TO EXTEND SIGN ?
	TRO	T1,177600	;EXTEND SIGN
	HRRM	T1,(IR)
	>
	DEFINE	MTPS. (FLAG) <
	JSR	@BFETCH(IR)	;GET WHAT TO SET PS TO
	HRRM	PS,PS.REG+1	;SAVE ORIGINAL PS
	HRRZ	PS,T1		;SET NEW PS
	CALL	PS.CHK		;TAKE AN INTERRUPT MAYBE
	>
	DEFINE	MUL. (FLAG) <
	ANDI	T2,7		;LEAVE ONLY REGISTER FIELD
	JSR	@FETCH(IR)	;GET THE SOURCE OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V!PS...C
	TRNE	T1,100000	;NEGATIVE VALUE ?
	IOR	T1,[-1,,700000]	;EXTEND SIGN
	MOVE	MA,(T2)		;GET REGISTER ARGUMENT
	TRNE	MA,100000	;NEGATIVE ARGUMENT ?
	IOR	MA,[-1,,700000]	;EXTEND SIGN
	IMULB	T1,MA		;DO THE MULTIPLICATION
	SKIPN	T1		;WAS RESULT ZERO
	TRO	PS,PS...Z	;REMEMBER IT WAS ZERO
	TLNE	T1,020000	;IS RESULT NEGATIVE ?
	TRO	PS,PS...N	;REMEMBER IT WAS NEGATIVE
	CAML	T1,[-1,,700000]
	CAILE	T1,077777
	TRO	PS,PS...C	;NEED MORE THAN 16 BITS
	ANDI	MA,177777	;LEAVES LOW ORDER PORTION
	LSH	T1,-^D16	;LEAVES HIGH ORDER PORTION
	ANDI	T1,177777	;STRIP EXTRA IF ANY
	MOVEM	T1,(T2)		;STORE HIGH ORDER PORTION
	IORI	T2,1		;OTHER REG ADDRESS
	MOVEM	MA,(T2)
	TRNE	PC,1		;DID THAT CORRUPT THE PC ?
	JRST	NXM...		;YES SO TAKE A BUS TRAP
	>
	DEFINE	NEG. (FLAG) <
	JSR	@RFETCH(IR)	;GET OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V!PS...C
	MOVNS	T1
	ANDI	T1,177777
	TRNE	T1,100000
	TRO	PS,PS...N
	SKIPN	T1
	TROA	PS,PS...Z
	TRO	PS,PS...C
	CAIN	T1,100000
	TRO	PS,PS...V
	RSTORE	FLAG
	>
	DEFINE	NEGB. (FLAG) <
	JSR	@BRFTCH(IR)	;GET OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V!PS...C
	MOVNS	T1
	ANDI	T1,000377
	TRNE	T1,000200
	TRO	PS,PS...N
	SKIPN	T1
	TROA	PS,PS...Z
	TRO	PS,PS...C
	CAIN	T1,000200
	TRO	PS,PS...V
	RSTORE	FLAG
	>
;DEFINE NOP. (FLAG) <>	;HANDLED BY .CCCLR
	DEFINE	RESET. (FLAG) <
	CALL	R.SET		;DO COMMON STUFF
	>
	DEFINE	ROL. (FLAG) <
	JSR	@RFETCH(IR)	;GET OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V
	TRZE	PS,PS...C
	TLO	T1,400000	;CARRY BIT GOES TO SIGN BIT
	TRZE	T1,100000	;CHECK NEW CARRY
	TRO	PS,PS...C!PS...V	;NEW CARRY AND OVERFLOW (MAYBE)
	ROT	T1,1
	TRNE	T1,100000	;GET A NEGATIVE RESULT ?
	TRC	PS,PS...N!PS...V	;WIN NEGATIVE AND COMPLEMENT OVERFLOW
	SKIPN	T1
	TRO	PS,PS...Z
	RSTORE	FLAG
	>
	DEFINE	ROLB. (FLAG) <
	JSR	@BRFTCH(IR)	;GET OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V
	TRZE	PS,PS...C
	TLO	T1,400000	;CARRY BIT GOES TO SIGN BIT
	TRZE	T1,000200	;CHECK NEW CARRY
	TRO	PS,PS...C!PS...V	;NEW CARRY AND OVERFLOW (MAYBE)
	ROT	T1,1
	TRNE	T1,000200	;GET A NEGATIVE RESULT ?
	TRC	PS,PS...N!PS...V	;WIN NEGATIVE AND COMPLEMENT OVERFLOW
	SKIPN	T1
	TRO	PS,PS...Z
	RSTORE	FLAG
	>
	DEFINE	ROR. (FLAG) <
	JSR	@RFETCH(IR)	;GET OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V
	TRZE	PS,PS...C
	JRST	.+4
	TRZE	T1,1		;DO WE GET A NEW CARRY ?
	TRO	PS,PS...C!PS...V
	JRST	.+5
	TRO	T1,200000	;CARRY BIT GOES TO SIGN BIT
	TRZE	T1,1		;CHECK NEW CARRY
	TROA	PS,PS...C!PS...N	;NEW CARRY AND NEGATIVE
	TRO	PS,PS...V!PS...N	;OVERFLOW AND NEGATIVE
	LSH	T1,-1
	SKIPN	T1
	TRO	PS,PS...Z
	RSTORE	FLAG
	>
	DEFINE	RORB. (FLAG) <
	JSR	@BRFTCH(IR)	;GET OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V
	TRZE	PS,PS...C
	JRST	.+4
	TRZE	T1,1		;DO WE GET A NEW CARRY ?
	TRO	PS,PS...C!PS...V
	JRST	.+5
	TRO	T1,000400	;CARRY BIT GOES TO SIGN BIT
	TRZE	T1,1		;CHECK NEW CARRY
	TROA	PS,PS...C!PS...N	;NEW CARRY AND NEGATIVE
	TRO	PS,PS...V!PS...N	;OVERFLOW AND NEGATIVE
	LSH	T1,-1
	SKIPN	T1
	TRO	PS,PS...Z
	RSTORE	FLAG
	>
	DEFINE	RTI. (FLAG) <
	LOAD	SP,T1		;PUT RESTORED PC IN TEMP REG
	MOVEI	SP,2(SP)
	ANDI	SP,177776
	LOAD	SP,T2		;GET NEW PS
	ANDI	T2,377		;WE DON'T HAVE A LH
	HRRM	PS,PS.REG+1	;SAVE OLD PS
	MOVE	PS,T2		;LOAD NEW PS
	MOVEI	SP,2(SP)
	ANDI	SP,177776
	MOVE	PC,T1		;LOAD NEW PC
	TRNE	PC,1		;CHECK PC OK
	JRST	NXM...		;TAKE A BUS TRAP
	CALL	PS.CHK		;SEE IF THERE ARE INTERRUPTS TO TAKE
	>
	DEFINE	RTS. (FLAG) <
	ANDI	IR,7
	MOVE	PC,(IR)
	LOAD	SP,T1		;GET OLD REG FROM STACK
	MOVEM	T1,(IR)		;LOAD REG FROM STACK
	MOVEI	SP,2(SP)	;FINISH POP
	ANDI	SP,177777	;IN CASE OVERFLOWED
	TRNE	PC,1		;BE SURE NEW PC OK
	JRST	NXM...		;TAKE A BUS TRAP
	>
	DEFINE	RTT. (FLAG) <
	LOAD	SP,T1
	MOVEI	SP,2(SP)
	ANDI	SP,177776
	LOAD	SP,T2		;GET NEW PS
	ANDI	T2,377		;WE DON'T HAVE A LH
	HRRM	PS,PS.REG+1	;SAVE OLD PS
	MOVE	PS,T2		;LOAD NEW PS
	MOVEI	SP,2(SP)
	ANDI	SP,177776
	HRRZ	PC,T1		;LOAD NEW PC
	TRNE	PC,1		;CHECK NEW PC OK
	JRST	NXM...		;TAKE A BUS TRAP
	CALL	PS.CHK		;SEE IF THERE ARE INTERRUPTS TO TAKE
	JRST	SIM11A		;INHIBIT TRACE TRAP
ZZRET==	-1
	>
	DEFINE	SBC. (FLAG) <
	JSR	@RFETCH(IR)	;GET OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V
	TRZE	PS,PS...C
	JRST	.+8
	TRNE	T1,100000
	TRO	PS,PS...N
	CAIN	T1,100000
	TRO	PS,PS...V
	JUMPN	T1,SIM11
	TRO	PS,PS...Z
	JRST	SIM11
	SOSN	T1
	TRO	PS,PS...Z
	TRNE	T1,100000
	TRO	PS,PS...N
	CAIN	T1,100000-1
	TRO	PS,PS...V
	TRZE	T1,600000
	TRO	PS,PS...C
	RSTORE	FLAG
	>
	DEFINE	SBCB. (FLAG) <
	JSR	@BRFTCH(IR)	;GET OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V
	TRZE	PS,PS...C
	JRST	.+8
	TRNE	T1,000200
	TRO	PS,PS...N
	CAIN	T1,000200
	TRO	PS,PS...V
	JUMPN	T1,SIM11
	TRO	PS,PS...Z
	JRST	SIM11
	SOSN	T1
	TRO	PS,PS...Z
	TRNE	T1,000200
	TRO	PS,PS...N
	CAIN	T1,000200-1
	TRO	PS,PS...V
	TRZE	T1,777400
	TRO	PS,PS...C
	RSTORE	FLAG
	>
;DEFINE SCC. (FLAG) <>	;HANDLED BY .CCSET
;DEFINE SEC. (FLAG) <>	;HANDLED BY .CCSET
;DEFINE SEN. (FLAG) <>	;HANDLED BY .CCSET
;DEFINE SEV. (FLAG) <>	;HANDLED BY .CCSET
;DEFINE SEZ. (FLAG) <>	;HANDLED BY .CCSET
	DEFINE	SOB. (FLAG) <
	ANDI	T2,7		;GET REGISTER DESIGNATION
	SOSN	T1,(T2)
	JRST	SIM11		;DON'T TAKE BRANCH
	ANDI	T1,177777	;IN CASE OF OVERFLOW
	MOVEM	T1,(T2)
	ANDI	IR,77
	LSH	IR,1
	SUBI	PC,(IR)
	ANDI	PC,177777	;ONLY NEEDED IF PC .LT. 200 !
	>
	DEFINE	SPL. (FLAG) <
	ANDI	IR,7		;LEAVE ONLY NEW PRIORITY
	DPB	IR,P.PLVL
	CALL	PS.CHK
	>
	DEFINE	SUB. (FLAG) <
	MOVE	T2,T1		;SAVE SRC
	JSR	@RFETCH(IR)	;GET DST
	MOVE	IR,T1		;SAVE COPY OF DST FOR PS...V CALC
	SUB	T1,T2		;MAKES RESULT
	TRZ	PS,PS...N!PS...Z!PS...V!PS...C
	TRNE	T1,100000	;CHECK FOR NEGATIVE
	TRO	PS,PS...N
	TRZE	T1,600000	;CHECK FOR OVERFLOW
	TRO	PS,PS...C
	SKIPN	T1
	TRO	PS,PS...Z
	XOR	IR,T2		;DST XOR SRC
	EQV	T2,T1		;SRC EQV RESULT
	AND	T2,IR
	TRNE	T2,100000
	TRO	PS,PS...V
	RSTORE	FLAG
	>
	DEFINE	SWAB. (FLAG) <
	JSR	@RFETCH(IR)	;GET ARGUMENT
	DPB	T1,[POINT 8,T1,19]
	LSH	T1,-10
	TRZ PS,PS...N!PS...Z!PS...V!PS...C
	TRNE	T1,000200
	TRO	PS,PS...N
	TRNN	T1,377
	TRO	PS,PS...Z
	RSTORE	FLAG
	>
	DEFINE	SXT. (FLAG) <
	HRRM PS,PS.REG+1	;IN CASE OF BUS TRAP
	TRZ	PS,PS...V	;ALWAYS CLEARED
	TRNN	PS,PS...N
	TROA	PS,PS...Z	;WIN A Z BIT
	TRZA	PS,PS...Z	;LOST THE Z BIT
	TDZA	T1,T1
	MOVEI	T1,177777
	JRST	@STUFF(IR)
ZZRET==	-1
	>
	DEFINE	TRAP. (FLAG) <
	INTSAV	34
	>
	DEFINE	TST. (FLAG) <
	JSR	@FETCH(IR)	;GET OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V!PS...C
	TRNE	T1,100000
	TRO	PS,PS...N
	SKIPN	T1
	TRO	PS,PS...Z
	>
	DEFINE	TSTB. (FLAG) <
	JSR	@BFETCH(IR)	;GET OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V!PS...C
	TRNE	T1,000200
	TRO	PS,PS...N
	SKIPN	T1
	TRO	PS,PS...Z
	>
	DEFINE	WAIT. (FLAG) <
	TADJUS
WAIT0:
	TXNN	FLG,F.EXEC	;RUNNING IN EXEC MODE ?
	JRST	WAIT1		;NO
	SKIPN	BR7PND		;CHECK FOR INTERUPTS HAPPENED
	SKIPE	BR5PND		;CHECK OTHER FLAVOUR
	JRST	SIM11		;GO TAKE INTERRUPT
	SOSLE	T1,INTDLY
	JRST	WAIT0		;NOT YET
	TADJUS
	HRRZ	T1,CTISPD
	MOVEM	T1,INTDLY
	MOVEM	T1,INTDLY+1
	CALL	TIMCHK
	JRST	WAIT0
	JRST	SIM11

WAIT1:	HRRE	T1,INTDLY+1
	ADDM	T1,INSRUN	;ACCUMULATE NUMBER OF INSTRUCTIONS EXECUTED
	ADDM	T1,WAITIM	;ACCUMULATE WAIT TIME
	MOVE	T1,CTISPD
	HRRM	T1,INTDLY
	HRRM	T1,INTDLY+1
	CALL	TIMCHK
	JRST	WAIT0
	>
	DEFINE	XOR. (FLAG) <
	MOVE	T2,-740(T2)	;GET REGISTER
	JSR	@RFETCH(IR)	;GET OPERAND
	TRZ	PS,PS...N!PS...Z!PS...V
	XOR	T1,T2
	TRNE	T1,100000
	TRO	PS,PS...N
	SKIPN	T1
	TRO	PS,PS...Z
	RSTORE	FLAG
	>
;HERE TO EXECUTE THE NEXT INSTRUCTION
; CALL	WITH F.RUNF CLEAR TO SINGLE INSTRUCTION
;	WITH F.RUNF SET TO RUN
;	CALL	SIMXCT
;	RETURN			;WHEN MACHINE HALTED
;				; AC1 WILL CONTAIN THE STARTING PC
SIMXCT:	TXZ	FLG,F.SVIO!F.HALT
	TXNN	PS,20		;IS T BIT SET ?
	SETZM	INTDLY
	SETZM	INTDLY+1
	TXON	FLG,F.TOPN	;HAS CTY BEEN OPENED ?
	CALL	SIMOPN		;DO OPEN FOR TTY
	PUSHJ	P,SIMSAC	;SETUP THE AC'S
	SETSTS	17,200		;SET NO ECHO
	TRNN	PC,1		;GET A BUM PC ?
	JRST	SIMCYC		;EXECUTE AN INSTRUCTION
	JRST	NXM...		;TAKE A BUS TRAP

SIMSAC:	EXCH	0,SIMREG
	EXCH	1,SIMREG+1
	EXCH	2,SIMREG+2
	EXCH	3,SIMREG+3
	EXCH	4,SIMREG+4
	EXCH	5,SIMREG+5
	EXCH	6,SIMREG+6
	EXCH	7,SIMREG+7
	TXC	FLG,F..SIM
	RET

;FOLLOWING ARE SIMULATOR REGISTERS WHEN NOT SIMULATING
SIMREG:	EXP	0		;R0
	EXP	0		;R1
	EXP	0		;R2
	EXP	0		;R3
	EXP	0		;R4
	EXP	0		;R5
	EXP	0		;R6
	EXP	0		;R7
BEGREG:	EXP	0		;R0
	EXP	0		;R1
	EXP	0		;R2
	EXP	0		;R3
	EXP	0		;R4
	EXP	0		;R5
	EXP	0		;R6
	EXP	0		;R7
BEG.PS:	EXP	0		;BEGINNING PS
;HERE TO SETUP THE PC TO EXECUTE
SETUPC:	SKIPN	AC1,EXPRESS	;DID USER GIVE A PC ?
	SKIPE	AC1,SIMREG+PC	;OR DID WE ALREADY HAVE A PC ?
	JRST	SETPC2
	SKIPE	INSRUN		;HAVE WE RUN YET ?
	JRST	SETPC2		;YES SO MUST BE WE MEANT 0 PC
	SKIPN	AC1,GOTO	;TAKE STARTING ADDRESS FOR PROGRAM
	HRRZ	AC1,DOT		;OH WELL USE CURRENT LOCATION
SETPC2:	HRRZM	AC1,SIMREG+PC
	RET

;HERE TO OPEN THE TTY FOR THE SIMULATOR
SIMOPN:	CALL	SIMREL		;RELOCATE STUFF
SIMOP1:	INIT	17,200		;SUPRESS ECHO
	SIXBIT	\TTY\
	Z
	EXIT
	CALL	R.SET		;RESET THE WORLD
	CALL	PS.CHK		;BE SURE LEVELS SET UP RIGHT
	RET
SIM.U1:
;MAIN LOOP FOR SIMULATION

SIM11:	TRNE	PS,PS...T	;CHECK T BIT
	JRST	TB.INT
SIM11A:
	SOSG	T1,INTDLY	;TIME TO CHECK FOR INTERRUPTS ?
	JRST	INTCHK		;CHECK TO SEE IF THERE IS AN INTERRUPT PENDING

SIMCYC:	HRRZ	MA,PC		;COPY PC
		MEMREL	MEMLIM
	CAIL	MA,0
	JRST	[CALL	IOLOAD+2	;GET INFORMATION
		MOVE	IR,T1		;PUT INSTRUCTION IN RIGHT REGISTER
		JRST	SIMCY1]
	ROT	MA,-2
	SKIPGE	MA
		MEMREL	MEMORY
	SKIPA	IR,(MA)
		MEMREL	MEMORY
	MOVS	IR,(MA)
SIMCY1:	ADDI	PC,2		;ADVANCE PC
	HRRZ	T2,IR		;COPY INSTRUCTION
	LSH	T2,-6		;POSITION FOR DISPATCH
	JRST	@OPDSP0(T2)	;DISPATCH ON OPCODE
;HERE IF OPCODE IN RANGE 000000 THRU 000077
OPDSPA:	JRST	@OPDSP1(IR)

;HERE IF OPCODE IN RANGE 000200 THRU 000277
OPDSPB:	JRST	@OPDSP2-200(IR)

;HERE FOR A TBIT TRAP
TB.INT:	INTSAV	14
	HRROS	INTDLY		;COME BACK THROUGH AGAIN
	JRST	SIM11A
;HERE BECAUSE TIMER WENT OFF - CHECK FOR INTERRUPTS ETC.

INTCHK:
	HRRE	T1,INTDLY	;CURRENT COUNT
	HRRE	T2,INTDLY+1	;ORIGINAL COUNT
	SUB	T2,T1
	ADDB	T2,INSRUN	;MAKE CURRENT NUMBER OF INSTRUCTIONS EXECUTED
	MOVE	T1,CTISPD	;PROBABLE MAXIMUM FOR INTDLY
	MOVEM	T1,INTDLY
	MOVEM	T1,INTDLY+1

;NOW SEE IF LAST INSTRUCTION HAD A STACK VIOLATION
INTCK0:	TXZN	FLG,F.SVIO	;HIT A STACK VIOLATION ?
	JRST	INTCK1		;NO
	INTSAV	4
	TXZ	FLG,F.SVIO

INTCK1:	TXNN	FLG,F.EXEC	;RUNNING IN EXEC MODE ?
	JRST	INTCK6		;NO SO DON'T TOUCH HDW
	SKIPE	T1,BR7PND	;ANY INTERRUPTS PENDING ON BR7 ?
	JRST	[SETZM	BR7PND		;FORGET OLD INTERRUPT
		JRST	INTCK3 ]	;GO TAKE THE INTERRUPT
	SKIPN	T1,BR5PND	;ANY BR5 INTERRUPTS PENDING ?
	JRST	INTCK6		;NO
	SETZM	BR5PND
INTCK3:	INTSAV	<(T1)>		;TAKE AN INTERRUPT
	HRROS	INTDLY		;CHECK FOR OTHER INTERRUPTS
	JRST	SIM11A		;IN CASE THAT LOWERED THE LEVEL

INTCK6:	CALL	TIMCHK		;CHECK FOR DEVICES THAT WANT TO INTERRUPT
	NOP

	TXNE	FLG,F.RUNF	;STILL RUNNING ?
	JRST	SIMCYC		;YES GO DO NEXT INSTRUCTION
	SETSTS	17,0		;PUT ECHO BACK ON
	JRST	SIMSAC		;SAVE SIMULATED REGS AND RET
;HERE TO CHECK FOR DEVICES WHICH MAY EXPIRED TIMERS

TIMCHK:	TXZ	FLG,F.FLOP

;HERE TO SEE IF ANY DEVICES WANT TIMER SERVICE

	HRRZ	T5,FIRDDB	;POINT TO FIRST DEVICE(LOWEST ADR)
TIMCK2:	SKIPN	DV.TIM+1(T5)	;IS THIS DEVICE TIMING ?
	JRST	TIMCK4		;NO SO DONE WITH IT
	MOVE	T2,INSRUN
	CAMGE	T2,DV.TIM+1(T5)	;HAS TIMER EXPIRED ?
	JRST	TIMCK3		;NOT TIME FOR AN INTERRUPT
	SETZM	DV.TIM+1(T5)
	CALL	@DV.TIM(T5)
TIMCK3:	SKIPN	T1,DV.TIM+1(T5)	;IS THERE A TIMER ?
	JRST	TIMCK4		;NO TIMER NOW
	SUB	T1,INSRUN	;MAKE RELATIVE TIME
	CAML	T1,INTDLY+1	;LOWER THAN OTHERS ?
	JRST	TIMCK4		;NO
	MOVEM	T1,INTDLY	;RESET TIMER
	MOVEM	T1,INTDLY+1
TIMCK4:	HRRZ	T5,DV.LNK(T5)	;GET ADR OF NEXT DEVICE
	JUMPN	T5,TIMCK2
	TXNE	FLG,F.FLOP
	AOS	(P)
	RET
INTDLY:	Z			;FLAG TO KEEP TRACK OF TIMING ETC.
		; TO REQUEST A CHECK FOR INTERRUPTS DO A HRROS INTDLY
	Z			;ORIGINAL COUNT IN INTDLY

INSRUN:	Z			;COUNTER TICKED ONCE PER INSTRUCTION
WAITIM:	Z			;TIME SPENT WAITING

	DEFINE	TADJUS <
	HRRE	T1,INTDLY	;CURRENT COUNT
	HRRE	T2,INTDLY+1	;ORIGINAL COUNT
	SUB	T2,T1		;COUNTS TAKEN SO FAR
	ADDM	T2,INSRUN	;UPDATE NUMBER OF INSTRUCTIONS EXECUTED
	MOVNS	T2
	ADDB	T2,INTDLY+1	;MAKES NEW INTERVAL
	HRRM	T2,INTDLY
>;DEFINE TADJUS
;HERE ON A RESET INSTRUCTION OR WHEN FIRST START
R.SET:
	HLLZ	MA,UBACTL	;GET UNIBUS CONTROLLER NUMBER
	TXNN	FLG,F.EXEC
	JRST	R.SET1		;DON'T RESET UNIBUS
	MOVEI	T1,1B29		;BIT TO DO UNIBUS RESET
	WRIO	T1,UBA.SR(MA)	;RESET THE UNIBUS
	CAIA
	HALT	R.SET		;IN CASE OF PAGE FAIL
	WRIO	T1,UBA.SR(MA)	;RESET THE UNIBUS
	CAIA
	HALT	R.SET		;IN CASE OF PAGE FAIL
	MOVEI	T1,1B18!1B19!1B20!1B21	;TO RESET TIMEOUT & MEMORY ERRORS
	WRIO	T1,UBA.SR(MA)
	CAIA
	HALT	R.SET
	RDIO	T1,UBA.SR(MA)
	TRNE	T1,740000	;ANY ERRORS LEFT ?
	HALT	R.SET
	MOVEI	T1,1B28		;STOP ON MEMORY ERRORS
	WRIO	T1,UBA.SR(MA)	;ASSIGN PI LVLS
	CAIA
	HALT	.+1		;IN CASE OF PAGE FAIL

;INITIALIZE THE CTY
	SETZM	COLUMN		;BACK TO THE LH MARGIN
R.SET1:	SETZM	BR7PND		;CLEAN OUT PENDING INTERRUPTS
	SETZM	BR5PND		; DITTO
	HRRZ	T5,FIRDDB	;POINT TO THE FIRST DEVICE
R.SET2:	SETZM	DV.TIM+1(T5)	;CLEAR TIMER FOR DEVICE
	CALL	@DV.RST(T5)	;RESET THIS DEVICE
	HRRZ	T5,DV.LNK(T5)	;GET NEXT DEVICE ADR
	JUMPN	T5,R.SET2	;LOOPBACK FOR REST OF DEVICES
	RET
;DISPATCH TABLE FOR INSTRUCTIONS

	DEFINE	X (VAL,MASK,NAME,FLAG) <
IFE	<<FLAG&<SMF.11!SMF.IN>>-<SMF.11!SMF.IN>> <
ZZ=<VAL/100>-Z
IFG	ZZ < REPEAT	ZZ,<
	EXP	ILLINS		;ILLEGAL INSTRUCTION DISPATCH
Z=Z+1	>>;IFG ZZ
ZZ=<VAL+<<-MASK>&177777>>/100-Z
IFG	ZZ < REPEAT	ZZ,<
	EXP	.'NAME		;DISPATCH FOR INSTRUCTION
Z=Z+1	>>;IFG ZZ
	>;IFE <<FLAG&<SMF.11!SMF.IN>>-<SMF.11!SMF.IN>>
>;DEFINE X

OPDSP0:	OPDSPA			;0000XX INSTRUCTIONS
	.JMP		;0001XX INSTRUCTIONS
	OPDSPB			;0002XX INSTRUCTIONS
Z=	3
	INSTRU
ZZ=	2000-Z
	
REPEAT	ZZ,<
	EXP	ILLINS
	XLIST
	>
	LIST
;DISPATCH TABLE FOR OPCODES 000000 THRU 000077

	DEFINE	X (VAL,MASK,NAME,FLAG) <
IFE	<<FLAG&<SMF.11!SMF.IN>>-<SMF.11!SMF.IN>> <
IFL	<VAL-100> <
ZZ=VAL-Z
IFG	ZZ <REPEAT ZZ,<
	EXP	ILLINS		;ILLEGAL INSTRUCTION DISPATCH
Z=Z+1
	>>;IFG ZZ
ZZ=VAL+<<-MASK>&177777>-Z
IFG	ZZ <REPEAT ZZ,<
	EXP	.'NAME		;DISPATCH FOR INSTRUCTION
Z=Z+1
	>>>>
>;DEFINE X (VAL,MASK,NAME,FLAG)

Z=0
OPDSP1:	INSTRU			;DO DISPATCHS FOR 000000-000077
REPEAT	<100-Z>,<
	EXP	ILLINS
	XLIST
	>
	LIST

;DISPATCH TABLE FOR OPCODES 000200 THRU 000277

	DEFINE	X (VAL,MASK,NAME,FLAG) <
IFE	<<FLAG&<SMF.11!SMF.IN>>-<SMF.11!SMF.IN>> <
IFL	<VAL-240> <
ZZ=VAL-Z
IFG ZZ <REPEAT	ZZ,<
	EXP	ILLINS		;ILLEGAL INSTRUCTION DISPATCH
Z=Z+1
	>>
ZZ=VAL+<<-MASK>&177777>-Z
IFG ZZ <REPEAT	ZZ,<
	EXP	.'NAME		;DISPATCH FOR INSTRUCTION
Z=Z+1
	>>>>
>;DEFINE X (VAL,MASK,NAME,FLAG)

Z=200
OPDSP2:	INSTRU			;DO DISPATCHS FOR 000200-000227
REPEAT	<240-Z>,<
	EXP	ILLINS
	XLIST
	>
	LIST
	EXP	SIM11		;THIS IS A NOP
REPEAT	17,<
	EXP	.CCCLR		;CLEAR CONDITION CODES
	XLIST
	>
	LIST
	EXP	SIM11		;THIS IS A NOP
REPEAT	17,<
	EXP	.CCSET		;SET CONDITION CODES
	XLIST
	>
	LIST
	SUBTTL	OPCODE SIMULATION

	DEFINE	X (VAL,MASK,NAME,FLAG) <
IFE	<<FLAG&<SMF.11!SMF.IN>>-<SMF.11!SMF.IN>> <
IFN	<<VAL&177740>-240> <
	.'NAME:		ZZRET==0
IFN	<FLAG&<SMF.SS!SMF.DD!SMF.EI>>,<ANDI IR,77>	;LEAVE ONLY DD
IFN	<FLAG&SMF.SS>,<
	ANDI	T2,77		;LEAVE ONLY SS
IFN	<FLAG&SMF.BY>,<JSR @SBFTCH(T2)>	;GET BYTE SOURCE OPERAND
IFE	<FLAG&SMF.BY>,<JSR @SFETCH(T2)>	;GET SOURCE OPERAND
	>
	NAME'.	FLAG		;MACRO FOR UNIQUE CODE
IFN	<FLAG&SMF.BR> <
	TRNE	IR,200		;POSITIVIE OR NEGATIVE OFFSET
	TROA	IR,177400	;NEGATIVE SO EXTEND SIGN
	TRZ	IR,177400	;POSITIVE SO EXTEND SIGN
	LSH	IR,1		;MAKE OFFSET * 2
	ADD	PC,IR
	ANDI	PC,177777	;IN CASE PC SPILLED OUT OF 16 BITS
	>
IFE	ZZRET,<JRST SIM11>
	>>
>;DEFINE X

	INSTRU
;HERE WHEN INSTRUCTION TRIES TO JMP TO REG
JMPREG:	Z			;CAME WITH A JSR
	JRST	NXM...		;DIE

;HERE IF @STUFF (OR @BSTUFF) GIVES BUS TRAP
STFNXM:	HRR PS,PS.REG+1		;RESTORE OLD PS
	JRST	NXM...

;HERE FOR ILLEGAL MEMORY REFERENCES
NXM...:	INTSAV	4
	JRST	SIM11

;HERE FOR ILLEGAL INSTRUCTION
ILLINS:	INTSAV	10
	JRST	SIM11

;HERE FOR A CONDITION CODE CLEAR
.CCCLR:	ANDI	IR,17		;STRIP EXTRA BITS
	TRZ	PS,(IR)		;CLEAR BITS
	JRST	SIM11

;HERE FOR A CONDITION CODE SET
.CCSET:	ANDI	IR,17		;STRIP EXTRA BITS
	TRO	PS,(IR)		;SET BITS
	JRST	SIM11

;HERE FOR A STACK VIOLATION & RESTORE PS IF RED STACK & PDP11/40
STCKVP:	Z			;HERE WITH A JSR
	TXO	FLG,F.SVIO	;REMEMBER WE HAD VIOLATION
	HRROS	INTDLY		;SO WE FIND IT QUICK
	CAIL	MA,400-40	;DO WE NEED TO FORCE A RED ?
	JRST	@STCKVP		;JUST YELLOW SO RETURN
	HRR	PS,PS.REG+1	;RESTORE PS
	JRST	RSTACK		;AND TAKE A RED STACK

;HERE FOR A STACK VIOLATION
STACKV:	Z			;HERE WITH A JSR
	TXO	FLG,F.SVIO	;REMEMBER WE HAD VIOLATION
	HRROS	INTDLY		;SO WE FIND IT QUICK
	CAIL	MA,400-40	;DO WE NEED TO FORCE A RED ?
	JRST	@STACKV		;JUST YELLOW SO RETURN

;HERE FOR A RED STACK VIOLATION
RSTACK:	TXZ	FLG,F.SVIO	;WE DID IT
	MOVEI	MA,2		;PUT PS AT 2
	STORE	MA,PS		;SAVE THE PS
	SETZB	SP,MA
	STORE	MA,PC		;SAVE THE PC IN 0
	MOVEI	MA,4		;ADR OF NEW PC
	LOAD	MA,T1		;GET THE NEW PC
	MOVEI	MA,6		;GET THE NEW PS
	LOAD	MA,T2		;GET THE NEW PS
	ANDI	T2,377		;STRIP EXTRA BITS
	MOVE	PC,T1		;SET THE NEW PC
	MOVE	PS,T2		;SET THE NEW PS
	TRNE	PC,1		;BAD PC ?
	TXZ	FLG,F.RUNF	;STOP THE MACHINE
	JRST	SIM11
	SUBTTL	ADDRESSING MODE CALCULATIONS

;MACROS TO BUILD DISPATCH TABLES
	DEFINE	XX (TAG) <
	XLIST
Q=0
REPEAT	10,<QQ=0
REPEAT	10,< X	TAG,\Q,\QQ
QQ=QQ+1
>
Q=Q+1
>
	LIST
>;DEFINE XX
	DEFINE	X (TAG,Q,QQ) <
	.XCREF TAG'Q'QQ
	EXP	TAG'Q'QQ
>

;DISPATCH TO FECTH SOURCE OPERAND (WORD MODE)
SFETCH:	XX SGET

;DISPATCH TO FETCH OPERAND (WORD MODE)
FETCH:	XX	GET

;DISPATCH TO FETCH OPERAND (WORD MODE) AND SET UP MA FOR RSTORE
RFETCH:	XX	RGET

;DISPATCH TO FETCH SOURCE OPERAND (BYTE MODE)
SBFTCH:	XX SBGT

;DISPATCH TO FETCH OPERAND (BYTE MODE)
BFETCH:	XX	BGET

;DISPATCH TO FETCH OPERAND (BYTE MODE) AND SET UP MA FOR RSTORE
BRFTCH:	XX	BRGT

;DISPATCH TO DO ADDRESS CALCULATION FOR JMP OR JSR
JMPCLC:	XX	JMP

;DISPATCH TO STORE OPERAND (WORD MODE)
; RH OF OPERAND MUST ALREADY BE MASKED TO 16 BITS (LH MAY BE NONZERO)
STUFF:	XX	PUT

;DISPATCH TO STORE OPERAND (BYTE MODE)
; RH OF OPERAND MUST ALREADY BE MASKED TO 8 BITS (LH MAY BE NONZERO)
BSTUFF:	XX	BPUT
;MACRO TO DEFINE GET, RGET, AND PUT
;	GET AND RGET RETURN DATA IN T1
;	RGET ALSO SETS UP MA
;	PUT STORES DATA IN T1

	DEFINE	X (Q) <
	XLIST

;MODE 0 - REGISTER MODE

	SGET0'Q:
	Z
	HRRZ	T1,(T2)		;GET REGISTER
	HRRZ	MA+1,IR		;COPY DEST MODE
	ANDI	MA+1,7		;LEAVE ONLY DEST REGISTER
	CAME	MA+1,T2		;SAME AS SRC REGISTER ?
	JRST	@SGET0'Q	;NO SO DONE
	CAIL	IR,20		;MAYBE DEST IS REG OR @REG ?
	CAILE	IR,57		;OR IS INDEXED OR @INDEXED ?
	JRST	@SGET0'Q	;ONE OF THOSE SO DONE
	CAIGE	IR,30
	ADDI	T1,4		;WAS AUTO INCREMENT MODE
	SUBI	T1,2
	ANDI	T1,177777	;STRIP EXTRA BITS
	JRST	@SGET0'Q

	GET0'Q:
	Z
	HRRZ	T1,Q
	JRST	@GET0'Q

	RGET0'Q:
	Z
	HRROI	MA,Q
	HRRZ	T1,Q
	JRST	@RGET0'Q

	SBGT0'Q:
	Z
	HRRZ	T1,(T2)		;GET REGISTER
	ANDI	T1,377		;STRIP EXTRA BITS
	HRRZ	MA+1,IR		;COPY DEST MODE
	ANDI	MA+1,7		;LEAVE ONLY DEST REGISTER
	CAME	MA+1,T2		;SAME AS SRC REGISTER ?
	JRST	@SBGT0'Q	;NO SO DONE
	CAIL	IR,20		;MAYBE DEST IS REG OR @REG ?
	CAILE	IR,57		;OR IS INDEXED OR @INDEXED ?
	JRST	@SBGT0'Q	;ONE OF THOSE SO DONE
	CAIGE	IR,30
	IFL	<Q-6>,<
	ADDI	T1,2
	SOS	T1
	>;IFL <Q-6>
	IFGE	<Q-6>,<
	ADDI	T1,4		;WAS AUTO INCREMENT MODE
	SUBI	T1,2
	>;IFGE <Q-6>
	ANDI	T1,377		;STRIP EXTRA BITS
	JRST	@SBGT0'Q

	BGET0'Q:
	Z
	HRRZ	T1,Q
	ANDI	T1,377
	JRST	@BGET0'Q

	BRGT0'Q:
	Z
	HRROI	MA,Q
	HRRZ	T1,Q
	ANDI	T1,000377
	JRST	@BRGT0'Q

	JMP0'Q==JMPREG		;REGISTER MODE ILLEGAL FOR JMP & JSR

	PUT0'Q:
	HRRZ	Q,T1		;LOAD REGISTER
	IFE	<Q-PC> <
	TRNE	PC,1		;BE SURE PC NOT CORRUPTED
	JRST	NXM...
	>;IFE <Q-PC>
	JRST	SIM11

	BPUT0'Q:
	TRZ	Q,377		;STRIP OLD BITS
	TRO	Q,(T1)		;SET NEW BITS
	IFE	<Q-PC> <
	TRNE	PC,1		;BE SURE PC NOT CORRUPTED
	JRST	NXM...		;TAKE A BUS TRAP
	>;IFE <Q-PC>
	JRST	SIM11
;MODE 1 - REGISTER DEFERRED

	RGET1'Q:
	IFE	<Q-6>,<
	Z
	HRRZ	MA,Q		;COPY CONTENTS OF REGISTER
	CAIGE	MA,400
	JSR	STACKV		;WE'RE GONNA VIOLATE STACK
	LOAD	MA,T1
	JRST	@RGET1'Q
	>;IFE <Q-6>

	SGET1'Q:
	GET1'Q:
	Z
	LOAD	Q,T1
	JRST	@GET1'Q

	BRGT1'Q:
	IFE	<Q-6>,<
	Z
	HRRZ	MA,Q		;COPY STACK POINTER
	CAIGE	MA,400
	JSR	STACKV		;WE'RE GONNA VIOLATE STACK
	BLOAD	MA,T1
	JRST	@BRGT1'Q
	>;IFE <Q-6>

	SBGT1'Q:
	BGET1'Q:
	Z
	BLOAD	Q,T1
	JRST	@BGET1'Q

	JMP1'Q:
	Z
	HRRZ	T1,Q
	JRST	@JMP1'Q

	PUT1'Q:
	STORE	Q,T1
	JRST	SIM11

	BPUT1'Q:
	BSTORE	Q,T1
	JRST	SIM11
;MODE 2 - AUTO-INCREMENT

	RGET2'Q:
	IFE	<Q-6>,<
	Z
	HRRZ	MA,Q		;COPY STACK POINTER
	ADDI	Q,2
	IFL	<Q-6>,<ANDI Q,177777>
	CAIGE	MA,400
	JSR	STACKV		;WE'RE GONNA VIOLATE STACK
	LOAD	MA,T1
	JRST	@RGET2'Q
	>;IFE <Q-6>

	SGET2'Q:
	GET2'Q:
	Z
	HRRZ	MA,Q		;COPY REGISTER
	ADDI	Q,2
	IFL	<Q-6>,<ANDI Q,177777>
	LOAD	MA,T1
	JRST	@GET2'Q

	BRGT2'Q:
	IFE	<Q-6>,<
	Z
	HRRZ	MA,Q		;COPY STACK POINTER
	IFGE	<Q-6>,< ADDI Q,2 >
	IFL	<Q-6>,< AOS	Q >
	IFL	<Q-6>,<ANDI Q,177777>
	CAIGE	MA,400
	JSR	STACKV		;WE'RE GONNA VIOLATE STACK
	BLOAD	MA,T1
	JRST	@BRGT2'Q
	>;IFE <Q-6>

	SBGT2'Q:
	BGET2'Q:
	Z
	HRRZ	MA,Q		;COPY REGISTER
	IFGE	<Q-6>,< ADDI Q,2 >
	IFL	<Q-6>,< AOS	Q >
	IFL	<Q-6>,<ANDI Q,177777>
	BLOAD	MA,T1
	JRST	@BGET2'Q

	JMP2'Q:
	Z
	HRRZ	T1,Q
	ADDI	Q,2
	IFL	<Q-6>,<ANDI Q,177777>
	JRST	@JMP2'Q

	PUT2'Q:
	HRRZ	MA,Q		;COPY REGISTER
	ADDI	Q,2
	IFL	<Q-6>,<ANDI Q,177777>
	STORE	MA,T1
	JRST	SIM11

	BPUT2'Q:
	HRRZ	MA,Q		;COPY REGISTER
	IFGE	<Q-6>,< ADDI Q,2 >
IFL	<Q-6>,<
	AOS	Q
	ANDI	Q,177777
>
	BSTORE	MA,T1
	JRST	SIM11
;MODE 3 - AUTO-INCREMENT DEFERRED

	SGET3'Q:
	GET3'Q:
	RGET3'Q:
	Z
	HRRZ	MA,Q		;COPY REGISTER
	ADDI	Q,2
	IFL	<Q-6>,<ANDI Q,177777>
	LOAD	MA,MA
	LOAD	MA,T1
	JRST	@GET3'Q

	SBGT3'Q:
	BGET3'Q:
	BRGT3'Q:
	Z
	HRRZ	MA,Q		;COPY REGISTER
	ADDI	Q,2		;;2 (NOT 1) BECAUSE DEFERRED
	IFL	<Q-6>,<ANDI Q,177777>
	LOAD	MA,MA
	BLOAD	MA,T1
	JRST	@BGET3'Q

	JMP3'Q:
	Z
	HRRZ	MA,Q		;COPY REGISTER
	ADDI	Q,2
	IFL	<Q-6>,<ANDI Q,177777>
	LOAD	MA,T1
	JRST	@JMP3'Q

	PUT3'Q:
	HRRZ	MA,Q		;COPY REGISTER
	ADDI	Q,2
	IFL	<Q-6>,<ANDI Q,177777>
	LOAD	MA,MA
	STORE	MA,T1
	JRST	SIM11

	BPUT3'Q:
	HRRZ	MA,Q		;COPY REGISTER
	ADDI	Q,2		;;2 (NOT 1) BECAUSE DEFERRED
	IFL	<Q-6>,<ANDI Q,177777>
	LOAD	MA,MA
	BSTORE	MA,T1
	JRST	SIM11
;MODE 4 - AUTO-DECREMENT

	RGET4'Q:
	IFE	<Q-6>,<
	Z
	SUBI	Q,2
	IFL	<Q-7>,<ANDI Q,177777>
	HRRZ	MA,Q		;COPY SP IN CASE OF STACK VIOLATION
	CAIGE	MA,400
	JSR	STACKV		;WE'RE GONNA VIOLATE STACK
	LOAD	MA,T1
	JRST	@RGET4'Q
	>;IFE <Q-6>

	SGET4'Q:
	GET4'Q:
	Z
	SUBI	Q,2
	IFL	<Q-7>,<ANDI Q,177777>
	LOAD	Q,T1
	JRST	@GET4'Q

	BRGT4'Q:
	IFE	<Q-6>,<
	Z
	IFGE	<Q-6>,< SUBI Q,2 >
	IFL	<Q-6>,< SOSGE Q >
	IFL	<Q-7>,<ANDI Q,177777>
	HRRZ	MA,Q
	CAIGE	MA,400
	JSR	STACKV		;WE'RE GONNA VIOLATE STACK
	BLOAD	MA,T1
	JRST	@BRGT4'Q
	>;IFE <Q-6>

	SBGT4'Q:
	BGET4'Q:
	Z
	IFGE	<Q-6>,< SUBI Q,2 >
	IFL	<Q-6>,< SOSGE Q >
	IFL	<Q-7>,<ANDI Q,177777>
	BLOAD	Q,T1
	JRST	@BGET4'Q

	JMP4'Q:
	Z
	IFL	<Q-7>,<ANDI Q,177777>
	HRRZ	T1,Q
	JRST	@JMP4'Q

	PUT4'Q:
	SUBI	Q,2
	IFL	<Q-7>,<ANDI Q,177777>
	STORE	Q,T1
	JRST	SIM11

	BPUT4'Q:
	IFGE	<Q-6>,< SUBI Q,2 >
	IFL	<Q-6>,< SOSGE Q >
	IFL	<Q-7>,<ANDI Q,177777>
	BSTORE	Q,T1
	JRST	SIM11
;MODE 5 - AUTO-DECREMENT DEFERRED

	SGET5'Q:
	GET5'Q:
	RGET5'Q:
	Z
	SUBI	Q,2
	IFL	<Q-7>,<ANDI Q,177777>
	LOAD	Q,MA
	LOAD	MA,T1
	JRST	@GET5'Q

	SBGT5'Q:
	BGET5'Q:
	BRGT5'Q:
	Z
	SUBI	Q,2		;2 (NOT 1) BECAUSE DEFERRED
	IFL	<Q-7>,<ANDI Q,177777>
	LOAD	Q,MA
	BLOAD	MA,T1
	JRST	@BGET5'Q

	JMP5'Q:
	Z
	SUBI	Q,2
	IFL	<Q-7>,<ANDI Q,177777>
	LOAD	Q,T1
	JRST	@JMP5'Q

	PUT5'Q:
	SUBI	Q,2
	IFL	<Q-7>,<ANDI Q,177777>
	LOAD	Q,MA
	STORE	MA,T1
	JRST	SIM11

	BPUT5'Q:
	SUBI	Q,2		;2 (NOT 1) BECAUSE DEFERRED
	IFL	<Q-7>,<ANDI Q,177777>
	LOAD	Q,MA
	BSTORE	MA,T1
	JRST	SIM11
;MODE 6 - INDEXED

	RGET6'Q:
	IFE	<Q-6>,<
	Z
	LOAD	PC,MA
	ADDI	PC,2
	ADD	MA,Q
	ANDI	MA,177777
	CAIGE	MA,400
	JSR	STACKV		;WE'RE GONNA VIOLATE STACK
	LOAD	MA,T1
	JRST	@RGET6'Q
	>;IFE <Q-6>

	SGET6'Q:
	GET6'Q:
	Z
	LOAD	PC,MA
	ADDI	PC,2
	ADD	MA,Q
	ANDI	MA,177777
	LOAD	MA,T1
	JRST	@GET6'Q

	BRGT6'Q:
	IFE	<Q-6>,<
	Z
	LOAD	PC,MA
	ADDI	PC,2
	ADD	MA,Q
	ANDI	MA,177777
	CAIGE	MA,400
	JSR	STACKV		;WE'RE GONNA VIOLATE STACK
	BLOAD	MA,T1
	JRST	@BRGT6'Q
	>;IFE <Q-6>

	SBGT6'Q:
	BGET6'Q:
	Z
	LOAD	PC,MA
	ADDI	PC,2
	ADD	MA,Q
	ANDI	MA,177777
	BLOAD	MA,T1
	JRST	@BGET6'Q

	JMP6'Q:
	Z
	LOAD	PC,T1
	ADDI	PC,2
	ADD	T1,Q
	ANDI	T1,177777
	JRST	@JMP6'Q

	PUT6'Q:
	LOAD	PC,MA
	ADDI	PC,2
	ADD	MA,Q
	ANDI	MA,177777
	IFE	<Q-6>,<
		CAIGE	MA,400
		JSR	STCKVP		;MADE STACK VIOLATION
	>;IFE <Q-6>
	STORE	MA,T1
	JRST	SIM11

	BPUT6'Q:
	LOAD	PC,MA
	ADDI	PC,2
	ADD	MA,Q
	ANDI	MA,177777
	IFE	<Q-6>,<
		CAIGE	MA,400
		JSR	STCKVP		;MADE STACK VIOLATION
	>;IFE <Q-6>
	BSTORE	MA,T1
	JRST	SIM11
;MODE 7 - INDEXED DEFERRED

	SGET7'Q:
	GET7'Q:
	RGET7'Q:
	Z
	LOAD	PC,MA
	ADDI	PC,2
	ADD	MA,Q
	ANDI	MA,177777
	LOAD	MA,MA
	LOAD	MA,T1
	JRST	@GET7'Q

	SBGT7'Q:
	BGET7'Q:
	BRGT7'Q:
	Z
	LOAD	PC,MA
	ADDI	PC,2
	ADD	MA,Q
	ANDI	MA,177777
	LOAD	MA,MA
	BLOAD	MA,T1
	JRST	@BGET7'Q

	JMP7'Q:
	Z
	LOAD	PC,MA
	ADDI	PC,2
	ADD	MA,Q
	ANDI	MA,177777
	LOAD	MA,T1
	JRST	@JMP7'Q

	PUT7'Q:
	LOAD	PC,MA
	ADDI	PC,2
	ADD	MA,Q
	ANDI	MA,177777
	LOAD	MA,MA
	STORE	MA,T1
	JRST	SIM11

	BPUT7'Q:
	LOAD	PC,MA
	ADDI	PC,2
	ADD	MA,Q
	ANDI	MA,177777
	LOAD	MA,MA
	BSTORE	MA,T1
	JRST	SIM11

	LIST
>;DEFINE X (Q)
;EXPAND MACRO FOR GET, RGET AND PUT

QQ=	0
	REPEAT	10,<
	X	\QQ
QQ=	QQ+1
	>;REPEAT 10
	SUBTTL	IO SIMULATION

;ROUTINE TO READ AND WRITE IN THE IO AREA
; NOTE THAT REFERENCES ARE NOT CHECKED TO BE SURE IN IO AREA (160000-177777)
; THIS DOESN'T MATTER BECAUSE THEY WILL REFERENCE 600000+MEMLIM TO 7600000
; WHICH SHOULD PAGE FAIL (UNLESS MEMORY IS ON UNIBUS)

	DEFINE	X (Q,QQ) <
	XLIST
	HRRZ	MA+1,FIRDDB
	CAMG	MA,1(MA+1)
	JRST	[CAMGE	MA,(MA+1)
		JRST	.+3
		TLO	MA,MA..IO	;REMEMBER IS AN IO DEVICE
		JRST	@DV.'Q(MA+1) ]
	HRRZ	MA+1,DV.LNK(MA+1)	;GET NEXT DEVICE ADR
	JUMPN	MA+1,.-3
	TXNN	FLG,F.EXEC
	JRST	QQ		;CAN'T HELP THIS GUY
	HLL	MA,UBACTL	;ADD UBA UNIT NUMBER
	LIST
>;DEFINE X (OFFSET)
;HERE TO DO A WORD LOAD FROM AN IO REGISTER
	SKIPA	T1,[EXP 1]	;SIMPLE SKIP RETURN FOR GETWRD
IOLOAD:	MOVEI	T1,LODRET	;SO RETURN GOES RIGHT
	ADDM	T1,(P)
	X	LOD,NXMRET
	TXNN FLG,F.EXEC
	JRST NXMRET
	RDIO	T1,600000(MA)	;GET DATA FROM UNIBUS
	JRST	IORET		;DONE

;HERE FOR A NXM (AFTER POPING RETURN OFF STACK)
NXMRET:	TXNN	FLG,F.EXEC	;RUNNING IN EXEC MODE ?
	JRST	NXMRT3		;NO
	MOVEI	T2,1B18+1B21+1B28
	LDB	T1,P.PLVL	;GET PROCESSOR LEVEL
	CAIGE	T1,7		;ALLOW BR7 ?
	MOVEI	T2,1B18+1B21!UBA.B7
	CAIGE	T1,5		;ALLOW BR7 ?
	MOVEI	T2,1B18+1B21!UBA.B5!UBA.B7
	HLLZ	T1,UBACTL	;POINT TO RIGHT UNIBUS
	WRIO	T2,UBA.SR(T1)	;CLEAR FLAG
NXMRT3:	TXNN	FLG,F..SIM	;ARE WE SIMULATING ?
	JRST	[SOS	(P)		;UNSKIP THE RETURN
		RET	]
	POP	P,T1		;CLEAN OFF STACK
	JRST	NXM...

IORET:	HRLI	MA,MA..UN!MA..IO	;MUST BE A UNIBUS DEVICE
	RET

;HERE TO DO A BYTE LOAD FROM AN IO REGISTER
	SKIPA	T1,[EXP 1]	;SIMPLE SKIP RETURN
IOBLOD:	MOVEI	T1,BLDRET	;NUMBER OF INSTRUCTIONS TO SKIP
	ADDM	T1,(P)		;SKIP RETURN
	X	BLD,NXMRET
	TXNN FLG,F.EXEC
	JRST NXMRET
	RDIOB	T1,600000(MA)	;GET DATA FROM UNIBUS
	JRST	IORET		;WILL SKIP IF FAILED
;HERE TO STORE A WORD IN THE IO AREA
IOSTOR:
	X	WRT,STONXM
	TXNN FLG,F.EXEC
	JRST STONX3
	WRIO	T1,600000(MA)	;GIVE DATA TO UNIBUS
	JRST	IORET
STONXM:	TXNN	FLG,F.EXEC	;RUNNING IN EXEC MODE ?
	JRST	STONX3		;NO
	MOVEI	T2,1B18+1B21+1B28
	LDB	T1,P.PLVL	;GET PROCESSOR LEVEL
	CAIGE	T1,7		;ALLOW BR7 ?
	MOVEI	T2,1B18+1B21!UBA.B7
	CAIGE	T1,5		;ALLOW BR7 ?
	MOVEI	T2,1B18+1B21!UBA.B5!UBA.B7
	HLLZ	T1,UBACTL	;POINT TO RIGHT UNIBUS
	WRIO	T2,UBA.SR(T1)	;CLEAR FLAG
STONX3:	TXNN	FLG,F..SIM	;ARE WE SIMULATING ?
	POPJ	P,		;NO SO SIMPLE ERROR
	POP	P,T1		;CLEAN OFF STACK
	JRST	STFNXM		;GIVE BUS TRAP

;HERE TO STORE A BYTE IN THE IO AREA
IOBSTO:
	X	BWR,STONXM
	TXNN FLG,F.EXEC
	JRST STONXM
	WRIOB	T1,600000(MA)	;GET DATA FROM UNIBUS
	JRST	IORET		;WON
	DEFINE	X (Q,QQ) <
	XLIST
	TLNN	MA,MA..UN	;IS THIS A UNIBUS DEVICE ?
	JRST	Q		;SAME AS PLAIN TYPE
	HLL	MA,UBACTL	;ADD UNIBUS UNIT
	QQ	T2,600000(MA)	;DO THE WRITE
	RET
	JRST	IORERR		;ERROR !?!
	LIST
>;DEFINE X

;HERE TO RESTORE (CLEARING BITS) A WORD TO THE IO AREA
IOR.C:	X	IOR.,BCIO

;HERE TO RESTORE (SETTING BITS) A WORD TO THE IO AREA
IOR.S:	X	IOR.,BSIO

;HERE TO RESTORE A WORD TO THE IO AREA
IOR.:	TLNE	MA,MA..UN	;IS THIS A UNIBUS DEVICE ?
	JRST	[HLL	MA,UBACTL	;ADD UNIBUS UNIT
		WRIO	T1,600000(MA)	;WRITE THE DATA
		RET
		JRST	IORERR ]	;ERROR !?!
	ANDI	MA,177777
	JRST	@DV.WRT(MA+1)	;STORE DATA

;HERE TO RESTORE (CLEARING BITS) A BYTE TO THE IO AREA
IOBR.C:	X	IOBR.,BCIOB

;HERE TO RESTORE (SETTING BITS) A BYTE TO THE IO AREA
IOBR.S:	X	IOBR.,BSIOB

;HERE TO RESTORE A BYTE TO THE IO AREA
IOBR.:	TLNE	MA,MA..UN	;IS THIS A UNIBUS DEVICE ?
	JRST	[HLL	MA,UBACTL	;ADD UNIBUS NUMBER
		WRIOB	T1,600000(MA)	;WRITE THE DATA
		RET
		JRST	IORERR ]	;ERROR !?!
	ANDI	MA,177777	;STRIP EXTRA BITS
	JRST	@DV.BWR(MA+1)	;STORE DATA

;HERE IF ERROR RESTORING DATA
IORERR:	HALT	.
;TRANSLATION OF IO ADDRESS SPACE

	DEFINE	DDBGEN (DEV,WRDS) <
	XLIST
	 IF2,<
	IFGE	<DEV'ADR-DDBADR> <PRINTX ERROR BUILDING IOMAP>
	IFNDEF	DEV'TIM,<DEV'TIM==R>	;DEFAULT TIMER ROUTINE
	IFNDEF	DEV'RST,<DEV'RST==R>	;DEFAULT RESET ROUTINE
	IFNDEF	DEV'LVL,<DEV'LVL==0	;DEFAULT INTERRUPT LEVEL
			DEV'INT==0>	;DEFAULT INTERRUPT ROUTINE
    >;IF2
	DEV'DDB: PHASE	0
	0,,DEV'ADR	;FIRST ADR IN DEVICE
	0,,DEV'ADR+WRDS+WRDS-1	;HIGHEST ADR IN DEVICE
DDBADR==DEV'ADR
DV.LNK:! DDBLNK,,DDBLNK		;LINK TO NEXT DEVICE BLOCK
DDBLNK==DEV'DDB
DV.LOD:! EXP	DEV'LOD		;DISPATCH FOR LOAD
DV.BLD:! EXP	DEV'BLD		;DISPATCH FOR BYTE LOAD
DV.WRT:! EXP	DEV'WRT		;DISPATCH FOR WRITING WORDS
DV.BWR:! EXP	DEV'BWR		;DISPATCH FOR WRITING BYTES
DV.TIM:! EXP	DEV'TIM		;DISPATCH WHEN TIMER GOES OFF
				; RETURNS WITH SKIP IF INTERRUPTED
	Z			;TIME TO TAKE TIMER DISPATCH
DV.RST:! EXP	DEV'RST		;DISPATCH FOR RESET
DV.LVL:! EXP	DEV'LVL		;CONTAINS DEVICE LEVEL
DV.INT:! EXP	DEV'INT		;DISPATCH IF WANT TO CHECK FOR INTERRUPTS
DV.SIZ:! 
	DEPHASE
	LIST
>;DEFINE DDBGEN

;FOLLOWING DDBGEN ARE SIMULATED DEVICES TO USE STANDARD READ, WRITE ROUTINES
;	0,,0	;LH IS WRITEABLE BY PROGRAM BITS,,RH IS REGISTER
;	0,,0	;LH IS WRITEABLE BY OPERATORE BITS,,RH IS OLD REGISTER

DDBADR==200000

DDBLNK==0
;HERE TO WRITE A SIMULATED DEVICE REGISTER
; CALL	MOVE	T1,<WANT TO WRITE>
;	CALL	DEVWRT
;	RETURN	WITH NEW REGISTER IN T1
DEVWRT:	ANDI	MA,177777	;STRIP EXTRA BITS
	HRRZ	T2,MA		;COPY DEVICE ADDRESS
	SUB	T2,(MA+1)	;MAKE RELATIVE ADR
	ADDI	T2,DV.SIZ(MA+1)	;POINT TO DEVICE REGISTERS
	PUSH	P,T1		;SAVE DATA TO WRITE
	MOVE	T1,(T2)		;GET ORIGINAL REGISTER
	HRRM	T1,1(T2)	;SAVE ORIGINAL REGISTER
	HLRZS	T1		;BITS PROGRAM CAN WRITE
	TXNN	FLG,F..SIM	;IS SIMULATION RUNNING
	HLRZ	T1,1(T2)	;NO SO HAVE DIFFERENT ENABLES
	ANDCAM	T1,(T2)		;CLEAR BITS IN SIMULATED REGISTER
	AND	T1,(P)		;BITS TO SET
	IORB	T1,(T2)		;SET NEW BITS
	POP	P,T2		;CLEAN UP STACK
	RET
	SUBTTL	IO SIMULATION - PS

;HERE FOR PDP11 REFERENCES TO THE PS

PS.ADR==177776

	DDBGEN	PS.,1

PS.REG:
	000357,,0	;PS REGISTER FOR DEVWRT, ETC.
	000377,,0	;LET OPERATOR SET ALL BITS

PS.LOD:	HRRZ	T1,PS		;JUST A LOAD
	RET

PS.BLD:	HRRZ	T1,PS		;LOAD THE PS
	TRNE	MA,1		;WANT LEFT HALF ?
	LSH	T1,-^D8
	ANDI	T1,377
	RET

PS.BWR:	TRNE	MA,1		;WRITING LH ?
	RET
PS.WRT:	HRRM	PS,PS.REG	;COPY CURRENT PS
	CALL	DEVWRT		;SET NEW PS
	HRRZ	PS,PS.REG	;SETUP NEW PS
;HERE TO SEE IF NEW PS IS LOWER PRIORITY THAN OLD PS AND IF SO CHECK FOR INTERRUPTS
PS.CHK:	LDB	T2,P.PLVL	;GET CURRENT PS LEVEL
	TXNN	FLG,F.EXEC	;RUNNING IN EXEC MODE ?
	JRST	PSCHK0		;NO SO DON'T CHANGE ANYTHING
	MOVEI	T1,1B28		;ASSUME CAN'T TAKE INTERRUPTS
	CAIGE	T2,7		;CAN WE TAKE BR7'S NOW ?
	HRRZI	T1,UBA.B7	;ENABLE CHANNEL FOR BR7
	CAIGE	T2,5		;CAN WE TAKE BR5'S NOW ?
	HRRZI	T1,UBA.B5!UBA.B7;ENABLE FOR BR5 & BR7
	HLLZ	T2,UBACTL	;POINT TO UNIBUS
	WRIO	T1,UBA.SR(T2)	;ENABLE TO TAKE INTERRUPTS
PSCHK0:	HRRZ	MA+1,FIRDDB
PSCHK1:	CAML	T2,DV.LVL(MA+1)
	JRST	PSCHK3
	TXZ	FLG,F.FLOP
	CALL	@DV.INT(MA+1)
	TXNE	FLG,F.FLOP	;DID THAT ONE TAKE AN INTERRUPT ?
	RET			;ALL DONE
	LDB	T2,P.PLVL	;GET CURRENT PS LEVEL
PSCHK3:	HRRZ	MA+1,DV.LNK(MA+1)
	JUMPN	MA+1,PSCHK1
	RET
	SUBTTL	IO SIMULATION - SWITCHES

;HERE FOR PDP11 REFERENCES TO THE SWITCH REGISTER

SW.ADR==177570

	DDBGEN	SW.,1

SW.REG:	0,,0		;THIS IS THE SWITCH REGISTER
	177777,,0	;LH IS WRITEABLE BY OPER BITS

SW.LOD:	MOVE	T1,SW.REG	;LOAD THE SWITCHES
	RET

SW.BLD:	MOVE	T1,SW.REG	;LOAD THE SWITCHES
	TRNE	T1,1		;WANT LH BYTE ?
	LSH	T1,-10		;WANT LH
	ANDI	T1,377		;ONLY 8 BITS
	RET

SW.WRT==DEVWRT		;PLAIN DEVICE WRITE

SW.BWR:	TXNE	FLG,F..SIM	;ARE WE SIMULATING ?
	RET			;YES SO DON'T WRITE IT
	TRNN	MA,1		;WRITING RH ?
	DPB	T1,[POINT 8,SW.REG,35]	;YES
	TRNE	MA,1		;WRITING LH ?
	DPB	T1,[POINT 8,SW.REG,27]
	RET
	SUBTTL	IO SIMULATION - CTY

;HERE TO READ OR WRITE THE SIMULATED CTY REGS

CTYADR==177560
CTYLVL==4

	DDBGEN	CTY,4

;SIMULATED DEVICE REGISTERS FOR CTY
; LH IS MASK FOR BITS WHICH USER CAN WRITE
; RH IS SIMULATED REGISTER
; 2ND WORD IS COPY BEFORE WRITE
CTISTS:	100,,200
	300,,0
CTIDAT:	377,,0
	377,,0
CTOSTS:	104,,200	;200=RDY,100=ENAB,4=MAINT
	304,,0
CTODAT:	377,,0
	377,,0
CTOFLG:	-1		;WHEN -1 CTY OUTPUT WANTS TO INTERRUPT
CTIFLG:	-1		;WHEN -1 CTY INPUT WANTS TO INTERRUPT

CTITIM:	Z			;TIME TO CHECK CTY FOR INPUT
CTISPD:	EXP	010000		;NUMBER OF INSTRUCTIONS BETWEEN INPUTTING CHARS
CTOTIM:	Z			;TIME FOR CTY OUTPUT TO BE DONE OR 0
CTOSPD:	EXP	001000		;NUMBER OF INSTRUCTIONS BETWEEN PRINTING CHARS
;HERE ON A RESET
CTYRST:	MOVE	T1,CTISPD	;START TIMING AGAIN
	ADD	T1,INSRUN	;MAKE ABSOLUTE
	MOVEM	T1,CTITIM	;TIME TO CHECK KEYBOARD AGAIN
	MOVEM	T1,DV.TIM+1+CTYDDB	;TIME TO CHECK KEYBOARD
	SETZM	CTOTIM		;DON'T NEED TIMER FOR PRINTER
	HLLZS	CTISTS		;CLEAR KEYBOARD REGISTER
				;CTIDAT UNAFFECTED
	SETZM	CTIFLG		;DON'T WANT TO INTERRUPT
	MOVEI	T1,200		;DONE FLAG
	HRRM	T1,CTOSTS	;FOR TELEPRINTER
	HLLZS	CTODAT		;CLEAR OUTPUT DATA REGISTER
	SETOM	CTOFLG		;WANT TO INTERRUPT
	RET

;HERE IF USER DOES A BYTE OPERATION TO READ A CTY REGISTER
CTYBLD:	SETZ	T1,
	TRNE	MA,1
	RET
	;FALL INTO WORD OPERATION

;HERE IF USER DOES A WORD OPERATION TO READ A CTY REGISTER
CTYLOD:	SETCMI	T1,200		;MASK FOR CTISTS
	TXNN	FLG,F..SIM	;ARE WE SIMULATING ?
	SETZ	T1,		;NO - DON'T ZERO ANYTHING
	CAMN	MA,[MA..IO,,CTYADR+2]	;READING DATA ?
	ANDM	T1,CTISTS	;CLEAR DONE FLOP
	HRRZ	T1,CTISTS-CTYADR(MA)	;GET REGISTER FOR HIM
	RET

;HERE IF USER DOES A BYTE WRITE TO A CTY REGISTER
CTYBWR:	TRNE	MA,1		;WRITING LH ?
	RET			;NO BITS THERE TO CHANGE
	;FALL INTO WORD OPERATION

;HERE IF USER DOES A WORD WRITE TO A CTY REGISTER
CTYWRT:	CALL	DEVWRT		;PERFORM THE WRITE
	JRST	@.+1-CTYADR(MA)
	CTIWRS			;WRITE CTY KEYBOARD STATUS REGISTER
	HALT	.
	R			;WRITE KEYBOARD DATA REGISTER
	HALT	.
	CTOWRS			;WRITE CTY PRINTER STATUS REGISTER
	HALT	.
	CTOWDT			;WRITE CTY PRINTER DATA
	HALT	.
	DEFINE	X (Q,VEC) <
	XLIST
	CT'Q'WRS:	TDZ	T1,CT'Q'STS+1	;CLEAR BITS WHICH WERE ALREADY SET
	TRNN	T1,100		;WAS ENABLE SET ?
	RET			;WAS ALREADY SET
	SETOM	CT'Q'FLG	;CAN INTERRUPT AGAIN
	JRST	CTYCHK		;CHECK FOR INTERRUPTS
	LIST
>;DEFINE X

;HERE BECAUSE WRITING CTY KEYBOARD STATUS REGISTER
	X	I,60

;HERE BECAUSE WRITING CTY PRINTER STATUS REGISTER
	X	O,64

;HERE BECAUSE WRITING CTY PRINTER DATA REGISTER
CTOWDT:	MOVEI	T1,200		;READY FLOP
	ANDCAM	T1,CTOSTS
	SETZM	CTOFLG		;DON'T WANT TO INTERRUPT
	TADJUS			;BE SURE INSRUN IS CURRENT
	MOVE	T1,CTOSPD	;TIME TILL ALL PRINTED
	CAML	T1,INTDLY+1	;BEFORE WE STOP TO CHECK ?
	JRST	CTOWD1		;YES
	HRRM	T1,INTDLY	;SET NEW TIME TO STOP
	HRRM	T1,INTDLY+1
CTOWD1:	ADD	T1,INSRUN	;ABSOLUTE TIME TO FINISH PRINT
	MOVEM	T1,CTOTIM	;REMEMBER WHEN DONE
	CAMGE	T1,DV.TIM+1+CTYDDB	;SOONER THAN KEYBOARD ?
	MOVEM	T1,DV.TIM+1+CTYDDB	;SOONER SO USE THIS VALUE
	RET
;HERE IF TIMER FOR CTY GOES OFF
CTYTIM:	MOVE	T1,INSRUN	;GET NUMBER OF INSTRUCTIONS EXECUTED SO FAR
	CAMGE	T1,CTITIM	;TIME TO CHECK FOR CTY INPUT ?
	JRST	CHKCTO
	ADD	T1,CTISPD
	MOVEM	T1,CTITIM	;RESET CTY TIMER
	INCHRS	T1		;HAS USER TYPED ?
	JRST	CHKCTO		;NOT YET
	ANDI	T1,177		;STRIP PARITY (SHOULDN'T HAVE BEEN SET)
	CAIN	T1,15		;WAS THAT A CARRIAGE RETURN ?
	JRST	[INCHRS	T2		;GET THE LF THAT FOLLOWES
		NOP			;FOOBAZ !!!!
		JRST	.+1 ]
	CAIN	T1,5		;WAS THAT A <^E>
	JRST	[TYPE	<
^E
>
		CALL	TYPSTR
		HRROS	INTDLY		;STOP THE SIMULATION
		TXZ	FLG,F.RUNF	;STOP THE SIMULATION
		JRST	CHKCTO ]
	CAIN	T1,24		;WAS THAT A ^T ?
	JRST	CNTRLT		;DISPLAY STATUS FOR CONTROL T
	HRRM	T1,CTIDAT	;SAVE CHAR FOR PROGRAM
	MOVEI	T1,200		;DONE FLAG
	IORB	T1,CTISTS	;SET FLAG
	SETOM	CTIFLG		;SO WE INTERRUPT
CHKCTO:	SKIPE	T1,CTOTIM	;ARE WE TIMING TRANSMITTER ?
	CAMLE	T1,INSRUN	;AND HAS ITS TIME COME ?
	JRST	CTTIM8		;NO
	HRRZ	T1,CTODAT	;GET CHARACTER TO PRINT
	CALL	TYPCHR		;TYPE THE CHARACTER
	SETZM	CTOTIM		;CLEAR TIMER
	MOVEI	T1,200		;DONE FLAG
	IORB	T1,CTOSTS	;FLAG ITS DONE
	SETOM	CTOFLG		;WANT TO INTERRUPT
CTTIM8:	SKIPE	T1,CTOTIM	;ARE WE TIMING TRANSMITTER ?
	CAMLE	T1,CTITIM	;WILL TRANSMITTER BE FIRST ?
	MOVE	T1,CTITIM	;USE KEYBOARD TIME
	MOVEM	T1,CTYDDB+DV.TIM+1	;SET TIMER
CTYCHK:	LDB	T1,P.PLVL	;GET PROCESSOR LEVEL
	CAML	T1,CTYDDB+DV.LVL	;CAN WE TAKE INTERRUPTS NOW ?
	RET			;NOT NOW
;HERE CAUSE PS WENT BELOW OUR LVL
CTYINT:	MOVE	T1,CTISTS	;GET RECEIVER STATUS
	TRNE	T1,200		;IN INTERRUPT FLAG UP
	TRNN	T1,100		;AND IS ENABLE SET ?
	JRST	CTOINT		;CHECK TRANSMITTER
	SKIPN	CTIFLG		;MAY WE INTERRUPT ?
	JRST	CTOINT		;NO SO CHECK TRANSMITTER
	SETZM	CTIFLG		;DON'T INTERRUPT AGAIN
	INTSAV	60		;TAKE INPUT INTERRUPT
	TXO	FLG,F.FLOP	;FLAG WE TOOK AN INTERRUPT
CTOINT:	MOVE	T1,CTOSTS	;GET TRANSMITTER STATUS
	TRNE	T1,200		;IS FLAG SET ?
	TRNN	T1,100		;AND IS ENABLE SET ?
	RET
	SKIPN	CTOFLG		;WANT TO INTERRUPT ?
	RET			;CAN'T INTERRUPT AGAIN
	SETZM	CTOFLG		;DON'T WANT ANOTHER
	INTSAV	64		;TAKE A TRANSMITTER INTERRUPT
	TXO	FLG,F.FLOP	;FLAG WE TOOK AN INTERRUPT
	RET
;HERE WHEN READ A CONTROL T FROM CTY WHILE SIMULATING

CNTRLT:	CALL	SIMSAC		;SAVE REG'S
	TYPE	< PC = >
	MOVE	T1,SIMREG+PC
	CALL	ADRTYP
	TYPE	< PS = >
	MOVE	T1,PS
	CALL	OCTYPE
	TYPE	< after >
	MOVE	T1,INSRUN
	CALL	PDECTY
	TYPE	< instructions >
	TXNN	FLG,F.LOPN	;WAS A LOCATION OPEN ?
	JRST	CNTLT6		;NO SO DON'T DISPLAY
	PUSH	P,T5		;SAVE DDB POINTER
	CALL	COMLF1		;DISPLAY LOCATION
	POP	P,T5		;RESTORE DDB POINTER
CNTLT6:	CALL	SIMSAC		;RESTORE AC'S
	CALL	CRLTYP
	JRST	CHKCTO
	SUBTTL	IO SIMULATION - KW11L CLOCK

;HERE FOR REFERENCES TO KW11 CLOCK

CLKADR==177546
CLKLVL==6

	DDBGEN	CLK,1

CLKSTS:	000300,,0	;SIMULATED CLOCK STATUS REGISTER
	000300,,0	; 200=INT,100=ENAB
CLKFLG:	Z			;WHEN NONZERO CLOCK CAN INTERRUPT
CLKSPD:	EXP	^D1000		;INSTRUCTIONS/CLOCK TICK
			; THIS IS SLOWER THAN REAL 11/40 BUT
			; FASTER THAN SIMULATED 11/40
CLKTCK:	Z			;COUNTED DOWN ONCE/MILASECOND

;HERE FOR THE KW11L ON A RESET
CLKRST:	MOVEI	T1,200
	HRRM	T1,CLKSTS
	SETOM	CLKFLG		;CAN TAKE AN INTERRUPT
	TXNN FLG,F.EXEC
	JRST CLKRS1
	MOVEI	T1,^D20		;NUMBER OF MILLASECONDS TILL NEXT TICK
	MOVEM	T1,CLKTCK
CLKRS1:	TADJUS			;MAKE TIMER CURRENT
	MOVE	T1,CLKSPD	;TIME TILL NEXT TICK
	CAML	T1,INTDLY+1	;LESS THAN ANY OTHER ?
	JRST	CLKRS2
	HRRM	T1,INTDLY+1
	HRRM	T1,INTDLY
CLKRS2:	ADD	T1,INSRUN	;TIME TILL NEXT TICK
	MOVEM	T1,CLKDDB+DV.TIM+1
	RET
;HERE TO READ THE CLOCK
CLKLOD:	HRRZ	T1,CLKSTS	;GET THE STATUS REGISTER
	RET			;RETURN

;HERE TO READ THE CLOCK WITH A BYTE INSTRUCTION
CLKBLD:	TRNE	MA,1		;WANT RH OR LH ?
	TDZA	T1,T1		;WANTED LEFT HALF
	HRRZ	T1,CLKSTS	;WANTED RH
	RET

;HERE FOR A BYTE WRITE TO THE KW11L
CLKBWR:	TRNE	MA,1		;WRITING RH OR LH ?
	RET			;DON'T WRITE LH

;HERE TO WRITE THE KW11L
CLKWRT:	CALL	DEVWRT		;PERFORM THE WRITE
	TDZ	T1,CLKSTS+1	;CLEAR BITS ALREADY SET
	TRNE	T1,100		;DID THAT SET ENABLE ?
	SETOM	CLKFLG		;CAN INTERRUPT AGAIN
	JRST	CLKWR3		;CHECK FOR POSSIBLE INTERRUPT

;HERE WHEN TIMER GOES OFF FOR THE CLOCK
CLKTIM:	TADJUS			;BE SURE TIMER CURRENT
	MOVE	T1,CLKSPD	;TIME TILL NEXT CLOCK TICK
	CAML	T1,INTDLY+1	;WILL THIS BE NEXT DEVICE TO TICK ?
	JRST	CLKTI1
	HRRM	T1,INTDLY
	HRRM	T1,INTDLY+1
CLKTI1:	ADD	T1,INSRUN	;MAKES TIME FOR NEXT TICK
	MOVEM	T1,CLKDDB+DV.TIM+1	;TIME FOR NEXT TICK
	MOVEI	T1,200		;DONE FLAG
	IORM	T1,CLKSTS
	SETOM	CLKFLG		;CAN INTERRUPT AGAIN
	TXNN FLG,F.EXEC
	JRST CLKWR3
	MOVEI	T1,^D20		;NUMBER OF MILLASECONDS TILL NEXT TICK
	MOVEM	T1,CLKTCK
CLKWR3:	LDB	T1,P.PLVL	;GET PROCESSOR LEVEL
	CAML	T1,CLKDDB+DV.LVL	;CAN WE INTERRUPT ?
	RET			;NOT NOW
;HERE TO SEE IF CLOCK WANTS TO INTERRUPT

CLKINT:	SKIPN	CLKFLG		;CAN WE INTERRUPT ?
	RET			;NO
	HRRZ	T1,CLKSTS	;GET THE STATUS REGISTER
	TRNE	T1,100		;IS ENABLE SET ?
	TRNN	T1,200		;IS FLAG SET ?
	RET			;DON'T WANT TO INTERRUPT NOW
	SETZM	CLKFLG		;HAVE TAKEN OUR INTERRUPT NOW
	INTSAV	100		;TAKE AN INTERRUPT
	TXO	FLG,F.FLOP	;FLAG WE TOOK AN INTERRUPT
	RET
	SUBTTL	IO SIMULATION - KG11

	REPEAT	0,<
;HERE FOR REFERENCES TO KG11

KG.ADR==170700

	DDBGEN	KG.,3

KG.STS:	000117,,0
	000777,,0
KG.BCC:	000000,,0	;BCC REGISTER - READ ONLY FOR PDP11
	177777,,0	; BUT OPERATOR CAN WRITE IT
KG.DAT:	177777,,0	;DATA REGISTER - WRITE ONLY
	177777,,0

KG.RST:
KG.LOD:
KG.BLD:

;HERE FOR WRITES TO KG11
KG.WRT:	CALL	DEVWRT		;WRITE THE REGISTER
	RET

KG.BWR:
KG.TIM:
>
	SUBTTL	IO SIMULATION - UBX

;HERE FOR REFERENCES TO UNIBUS ADAPTER

UBXADR==163000

	DDBGEN	UBX,41

	DEFINE	X (Q) <
	XLIST
	TXNE	FLG,F..SIM	;ARE WE SIMULATING ?
	JRST	Q		;LOSE
	TXNN	FLG,F.EXEC	;ARE WE IN EXEC MODE ?
	JRST	Q		;LOSE
	HLL	MA,UBACTL	;ADD UNIBUS NUMBER
	LIST
>;DEFINE X

;HERE TO DO A LOAD FROM A UBX REGISTER
UBXLOD:	X	NXMRET
	RDIO	T1,600000(MA)	;GET DATA FROM UNIBUS
	RET			;WILL SKIP IF FAILED
	JRST	NXMRET

;HERE TO DO A BYTE LOAD FROM A UBX REGISTER
UBXBLD:	X	NXMRET
	RDIOB	T1,600000(MA)	;GET BYTE FROM UNIBUS
	RET			;WILL SKIP IF FAILED
	JRST	NXMRET

;HERE TO DO A WRITE TO A UBX REGISTER
UBXWRT:	X	STONXM
	WRIO	T1,600000(MA)	;GIVE DATA TO UNIBUS
	RET
	JRST	STONXM

;HERE TO DO A BYTE WRITE TO THE UBX REGISTER
UBXBWR:	X	STONXM
	WRIOB	T1,600000(MA)	;GIVE DATA TO UNIBUS
	RET
	JRST	STONXM
;POINTER TO FIRST DDB
; RH LINK IS FOR USE WHILE RUNNING - DEVICES MAY BE REMOVED BY REMOVING LINKS
; LH LINK IS SO DELETED DEVICES CAN BE REINSTALLED
FIRDDB:	DDBLNK,,DDBLNK		;POINTER TO FIRST DDB

;BYTE POINTERS TO THE SIMULATED MEMORY
SIMPTR:	MEMREL	MEMORY
	POINT	8,0(MA),17
		MEMREL	MEMORY
	POINT	8,0(MA),9
		MEMREL	MEMORY
	POINT	8,0(MA),35
		MEMREL	MEMORY
	POINT	8,0(MA),27

;TABLE OF INSTRUCTIONS WHICH MUST BE RELOCATED
RLMTAB:	BLOCK	RLMSIZ
;HERE TO RELOCATE MEMORY REFERENCES

SIMREL:	MOVE	T3,[-RLMSIZ,,RLMTAB]
	SKIPN	T1,MEMORY	;GET ADDRESS OF SIMULATED MEMORY
	HALT
SIMRL2:	MOVE	T2,(T3)
	HLRZ	T1,T2		;GET WHAT TO RELOCATE WITH
	MOVE	T1,(T1)
	HRRM	T1,(T2)
	AOBJN	T3,SIMRL2

;RECONSTRUCT VIRGIN DEVICE CHAIN
	MOVEI	T1,FIRDDB-DV.LNK
	HLRS	T1,DV.LNK(T1)
	JUMPN	T1,.-1

;TO SPEED UP USER MODE RUNS REMOVE DDB FOR UNIBUS ADAPTER
	TXNE	FLG,F.EXEC	;RUNNING IN EXEC MODE ?
	RET			;NO, SKIP THIS
	PUSH	P,IR		;SAVE REGISTER
	MOVEI	IR,FIRDDB-DV.LNK
SIMRL4:	HRRZ	T1,DV.LNK(IR)	;POINT TO NEXT DEVICE
	CAIN	T1,UBXDDB
	HRRZ	T1,DV.LNK(T1)	;SKIP POINTER TO UBA
	HRRM	T1,DV.LNK(IR)
	SKIPE	IR,T1
	JRST	SIMRL4
	POP	P,IR
SIMRL5:	RET

;HERE TO SETUP EPT AND UNIBUS MAPPING
; EPTBLK POINTS TO THE START OF:
EPT...==0		;PAGE FOR EXEC PROCESS TABLE
UPT...==1000		;PAGE FOR USER PROCESS TABLE
STB...==2000		;PAGE FOR SECTION TABLE FOR SECTION 0
CST...==3000		;PAGE FOR CORE STATUS TABLE
VECTAB==4000		;3000 WORDS FOR VECTORED INTERRUPTS
DSKPAG==7000		;PAGE FOR DISK IO
EBLKSZ==10000		;SIZE OF BLOCK FOR EXEC USAGE

MAPCOR:	TXNN	FLG,F.EXEC	;RUNNING IN EXEC MODE ?
	RET			;NO SO DON'T DIDDLE ADAPTER MAPPING
	SKIPE	T4,EPTBLK	;HAVE WE CHOSEN A SLOT FOR AN EPT YET ?
	JRST	MAPCR3		;ALREADY HAVE AN EPT

;MOVE SYMBOL TABLE AND PDP11 MEMORY UP TO ALLOW FOR EPT
	CALL	POSYMT		;BE SURE SYMBOL TABLE IS AT END OF CORE
	SKIPN	T1,MEMUSE	;FIRST TABLE TO MOVE UP
	HRRZ	T1,SYMBEG	;IF NO MEMORY THAN JUST MOVING SYMBOL TABLE
	HRRZM	T1,T2		;SAVE FIRST ADR IN OLD TABLES
	ADDI	T1,777		;WE WILL ROUND TO NEXT PAGE
	ANDI	T1,777000	;MAKE PAGE ADR
	MOVEM	T1,EPTBLK	;SAVE ADR OF EPT
	ADDI	T1,EBLKSZ	;TO GET TO FIRST TABLE
	SUB	T1,T2		;HOW MUCH TO MOVE TABLE
	MOVE	T3,SYMEND	;LAST ADR IN SYMBOL TABLE
	ADDI	T3,-1(T1)	;NEW LAST ADR IN SYMBOL TABLE
	CALL	MOVMUS		;MOVE THE TABLES
MAPCR1:	MOVE	T4,EPTBLK	;GET EPT ADR AGAIN
	HRLI	T1,INTBLK	;COPY UUO AND INTERRUPT VECTORS
	HRRI	T1,EPTINT(T4)
	BLT	T1,EPTINT+15(T4)
	MOVEI	T1,VECTAB(T4)	;ADR OF VECTOR TABLE FOR UBA
	MOVEI	T2,EPTVEC(T4)	;WHERE VECTORS GO
	HRLI	T2,-10		;POSSIBLE NUMBER OF UBA'S
	MOVEM	T1,(T2)
	AOBJN	T2,.-1
	MOVSI	T1,(NOP)
	MOVEM	T1,EPTAOV(T4)	;IN CASE OF ARITHMITIC OVERFLOW
	MOVE	T1,[JSR EPDLOV]	;TELL USER ABOUT PROBLEM
	MOVEM	T1,EPTPDO	;IN CASE OF PUSHDOWN LIST OVERFLOW
	LDB	T1,[POINT 9,T4,26]	;PICK UP PAGE NUMBER OF EPT
	ADD	T1,[124000,,2]	;IMMEDIATE; KERNEL; WRITABLE; CACHE
				; ,, SECT 0 PAGE TABLE
	MOVEM	T1,EPTSTP(T4)	;POINTER TO SECTION 0 PAGE TABLE
	MOVEI	T1,UUO0		;WHERE TO GO ON A MUUO
	MOVEM	T1,1430(T4)
	HRLI	T1,1430(T4)
	HRRI	T1,1431(T4)
	BLT	T1,1437(T4)
	MOVEI	T1,PGFAIL	;WHERE TO GO ON A PAGE FAIL
	MOVEM	T1,UPTPFN(T4)
	MOVSI	T1,400000	;CST ENTRY
	MOVEM	T1,CST...(T4)	;FIRST ENTRY IN THE TABLE
	HRLI	T1,CST...(T4)	;BEGINING OF CST TABLE
	HRRI	T1,CST...+1(T4)
	BLT	T1,CST...+777(T4)	;FILL TABLE
;FILL UP VECTOR TABLE AND SPACE
	MOVEI	T3,VECTAB(T4)
MAPCR2:	MOVE	T1,T3
	SUBI	T1,VECTAB(T4)
	IMULI	T1,5
	ADDI	T1,VECTAB+400(T4)
	HRLI	T1,(JSR)
	MOVEM	T1,(T3)		;JSR VEC#
	SETZM	(T1)		;VEC#: 0
	HRLI	T1,(PUSH P,)
	MOVEM	T1,1(T1)	;PUSH P,VEC#
	MOVE	T2,[PUSH P,T1]
	MOVEM	T2,2(T1)	;PUSH P,T1
	MOVE	T2,T3
	SUBI	T2,VECTAB(T4)
	LSH	T2,2
	HRLI	T2,(MOVEI T1,)
	MOVEM	T2,3(T1)	;MOVEI T1,#
	MOVE	T2,[JRST VECXX]
	MOVEM	T2,4(T1)	;JRST VECXX
	CAIE	T3,VECTAB+377(T4)
	AOJA	T3,MAPCR2

;SETUP THE PAGE MAP FOR LOW CORE
MAPCR3:	MOVSI	T1,124000	;FIRST ENTRY FOR SECTION 0 PAGE TABLE
	MOVEI	T3,STB...(T4)	;ADR OF SECTION 0 PAGE TABLE
	HRLI	T3,-400		;ONLY FILL IN FIRST 256 PAGES
MAPCR4:	HRRZ	T2,T1
	LSH	T2,^D9
	CAML	T2,MEMORY	;CACHE ONLY UP TO PDP11 MEMORY
	TLZ	T1,004000	;UNCACHE PDP11 MEMORY
	MOVEM	T1,(T3)
	AOS	T1
	AOBJN	T3,MAPCR4
	MOVSI	T1,4000		;MASK FOR CACHE BIT
	ANDCAM	T1,STB...(T4)	;UNCACHE FIRST PAGE (8080 WORDS)
;SETUP THE UNIBUS MAPPING REGISTERS
	SETZM	T2
	MOVE	T1,MEMORY	;GET STARTING ADDRESS OF MEMORY
	LSH	T1,-^D9		;CONVERT TO PAGE NUMBER
	TXO	T1,UB.VLD!UB.16B!UB.RPW	;SET READ/PAUSE WRITE, 16BIT, & VALID
MAPCR5:	HLL	T2,UBACTL	;POINT TO RIGHT UNIBUS
	WRIO	T1,UBAMAP(T2)	;WRITE MAPPING REGISTER
	TLZA	T2,-1		;CLEAR UNIBUS NUMBER
	HALT	.+1		;IF GET PAGE FAIL
	AOS	T2
	LSH	T2,^D11
	CAML	T2,MEMLIM	;STILL IN RANGE ?
	TXZ	T1,UB.VLD	;CLEAR VALID BIT
	LSH	T2,-^D11
	CAIE	T2,^D64
	AOJA	T1,MAPCR5
	SETO	T1,
	WRCSTM	T1		;WRITE CST MASK REGISTER
	SETZ	T1,
	WRPUR	T1		;WRITE PROCESS USE REGISTER
	MOVEI	T1,CST...(T4)	;ADR OF CST
	WRCSB	T1		;WRITE CORE STATUS TABLE BASE REGISTER
	MOVE	T1,EPTBLK	;GET ADR OF EXECUTIVE PROCESS TABLE
	LSH	T1,-^D9
	IORI	T1,1B21!1B22	;TOPS-20 PAGING, ENABLE TRAP AND PAGING
	WREBR	(T1)		;SET UP EBR FOR EPT
	TRZ	T1,1B22
	ADD	T1,[1B0!1B2!1]	;LOAD AC BLOCK AND UBR
	WRUBR	T1		;SETUP UBR FOR UPT
	RET
	SUBTTL	MONITOR FOR EXEC MODE USE

INTBLK:	JSR	CH1
	HALT	42
	JSR	CH2
	HALT	44
	JSR	CH3
	HALT	46
	JSR	CH4
	HALT	50
	JSR	CH5
	HALT	52
	JSR	CH6
	HALT	54
	JSR	CH7
	HALT	56

CH1:	Z
	HALT	.+1
	JEN	@CH1

APRLVL==2
CH2:	Z
	PUSH	P,T1		;SAVE REGISTER
	PUSH	P,T2		;SAVE ANOTHER REGISTER
	RDAPR	T1		;GET PROCESSOR STATUS
	TRNE	T1,7B28		;SERIOUS PROBLEM ?
	CALL	[CALL	SAVE24		;SAVE REGISTER
		PUSH	P,T1
		PUSHJ	P,INLMES
		ASCIZ	\
	APR	error \
		POP	P,T1
		CALL	OCTYPE
		WRAPR	1B22!7B28!APRLVL	;CLEAR ERROR FLAG
		HALT	R ]
	TRNN	T1,1B30		;DID CLOCK GO OFF ?
	JRST	CH2CK5
	AOS	UPTIME		;WE HAVE BEEN UP FOR ANOTHER MILLASECOND
	WRAPR	1B22!1B30!APRLVL	;CLEAR THE CLOCK FLAG
	SOSG	CLKTCK		;TIME FOR KW11 TO TICK ?
	JRST	[MOVEI	T2,^D20		;NUMBER OF MILASECONDS TILL NEXT TICK
		MOVEM	T2,CLKTCK
		TXNN	FLG,F.RUNF	;ARE WE SIMULATING
		JRST	CH2CK5		;NO
		MOVEM	T2,CLKDDB+DV.TIM+1	;KW11 WANTS TIMER SERVICE NOW
		HRROS	INTDLY		;CHECK KW11 SOON
		JRST	CH2CK5]
CH2CK5:	TRNE	T1,1B31		;DID THE 8080 INTERRUPT
	JRST	[MOVE	T2,FEWINP	;GET DATA
		WRAPR	1B22!1B31!APRLVL	;CLEAR FLAG
		JUMPE	T1,CH2CK9	;IF NOTHING WE'RE DONE
		SETZM	FEWINP		;FLAG WE SAW IT
		HRRZ	T1,T2		;COPY DATA
		LSH	T1,-^D8		;LEAVE ONLY THE CODE
		CAIE	T1,1		;IS THIS A CTY CHAR ?
		JRST	CH2CK9		;NO
		CAIN	T2,17		;IS THIS A CONTROL O ?
		JRST	[SETCMM	CNTLOF		;COMPLEMENT CONTROL O FLAG
			JRST	CH2CK9]
		MOVE	T1,RCVPTR	;GET RECEIVE CHAR PUTTER
		IDPB	T2,T1		;PUT CHAR IN BUFFER
		CAMN	T1,[POINT 8,RCVBUF+7,31]
		MOVE	T1,[POINT 8,RCVBUF]	;WRAP BUFFER AROUND
		MOVEM	T1,RCVPTR
		JRST	CH2CK9 ]
CH2CK9:	POP	P,T2		;RESTORE REGISTER
	POP	P,T1		;RESTORE REGISTER
	JEN	@CH2

UPTIME:	Z			;COUNTED ONCE PER MILLASECOND

BR7LVL==3
BR7OFF==1B26!1B31
BR7ON==	1B25!1B31
BR7INT==1B23		;INTERRUPT IN PROGRESS FOR BR7
CH3:	Z
	HALT	.+1
	JEN	@CH3

BR5LVL==4
BR5OFF==1B26!1B32
BR5ON==	1B25!1B32
BR5INT==1B24		;INTERRUPT IN PROGRESS FOR BR5
CH4:	Z
	HALT	.+1
	JEN	@CH4

CH5:	Z
	HALT	.+1
	JEN	@CH5

CH6:	Z
	HALT	.+1
	JEN	@CH6

CH7:	Z
	HALT	.+1
	JEN	@CH7
;HERE AFTER AFTER TAKING A VECTORED INTERRUPT
; INTERRUPTED PC IS PUSHED ON STACK FOLLOWED BY T1
VECXX:	HRROS	INTDLY
	PUSH	P,T2		;SAVE ANOTHER REG
	RDPI	T2		;GET PI STATUS
	TRNE	T2,BR7INT	;WAS THIS A BR7(BR6) INTERRUPT ?
	JRST	VECX7
	TRNN	T2,BR5INT	;WAS THIS A BR5(BR4) INTERRUPT
	HALT	.+1
	MOVEM	T1,BR5PND#	;SAVE VECTOR FOR PENDING INTERRUPT
	MOVEI	T1,1B28
	HLLZ	T2,UBACTL	;GET UNIBUS NUMBER
	WRIO	T1,UBA.SR(T2)
	POP	P,T2
	POP	P,T1
	POP	P,BR5TRP#
	JEN	@BR5TRP#	;DISMISS THE INTERRUPT

VECX7:	MOVEM	T1,BR7PND#	;SAVE VECTOR FOR PENDING INTERRUPT
	MOVEI	T1,1B28
	HLLZ	T2,UBACTL	;GET UNIBUS NUMBER
	WRIO	T1,UBA.SR(T2)
	POP	P,T2
	POP	P,T1
	POP	P,BR7TRP#	;GET WHERE WE INTERRUPTED FROM
	JEN	@BR7TRP#
;HERE IN CASE OF PUSHDOWN LIST OVERFLOW

EPDLOV:	HALT	.
;HERE ON A PAGE FAIL

PGFAIL:	MOVEM	T4,PGFSAV#	;SAVE A REG
	MOVE	T4,EPTBLK	;POINT TO PAGE TABLES
	PUSH	P,UPTPFO(T4)	;SAVE ADR WE CAME FROM
	AOS	(P)		;ADVANCE OVER FAILING INSTRUCTION
	MOVE	T4,PGFSAV#	;RESTORE REG
	CALL	SAVE4		;SAVE T1-T4
	MOVE	T4,EPTBLK	;POINT TO PAGE TABLES
	LDB	T1,[POINT 6,UPTPFW(T4),5]	;GET PAGE FAIL CODE
	CAIN	T1,20		;IS THIS AN IO FAILURE ?
	JRST	RSKP		;RETURN MAKING FAILING INSTRUCTION SKIP
	PUSHJ	P,INLMES
	ASCIZ	\
	Page Fail @pc = \
	MOVE	T4,EPTBLK	;POINT TO PAGE TABLES AGAIN
	MOVE	T1,UPTPFO(T4)	;GET FAILING PC
	CALL	OCTYPE		;DISPLAY THE PC
	PUSHJ	P,INLMES
	ASCIZ	\ ... Page fail word \
	MOVE	T4,EPTBLK	;CUZ INLMES WIPES T4
	MOVE	T1,UPTPFW(T4)
	CALL	OCTYPE
	HALT	.+1
	RET
;HERE ON A UUO
UUO0:	MOVEM	16,UUOACS+16
	MOVEI	16,UUOACS
	BLT	16,UUOACS+15
	MOVE	AC1,EPTBLK	;ADDRESS OF EXECUTIVE PROCESS TABLE
	PUSH	P,.UPMUP(AC1)	;SAVE RETURN ADR ON STACK
	MOVE	AC2,.UPMUO+2(AC1)	;GET UUO EFFECTIVE ADR
	LDB	AC3,[POINT 4,.UPMUO(AC1),30]	;GET REG ARGUMENT
	LDB	T1,[POINT 9,.UPMUO(AC1),26]	;GET OP CODE
	CAIL	T1,40
	CAIL	T1,100
	PUSHJ	P,ILLUUO
	ROT	T1,-1
	TLNE	T1,400000
	SKIPA	T1,UUODSP-20(T1)
	HLRZ	T1,UUODSP-20(T1)
	PUSHJ	P,(T1)
UUORET:	CAIA
	AOS	(P)
	MOVSI	16,UUOACS
	BLT	16,16		;RESTORE ACS
	RET

UUOACS:	BLOCK	^D16		;COPY AC'S HERE WHILE DOING A UUO

UUODSP:	ILLUUO,,UUINIT	;CALL(40),,INIT(41)
	ILLUUO,,ILLUUO	;(42),,(43)
	ILLUUO,,ILLUUO	;(44),,(45)
	ILLUUO,,UCALLI	;(46),,CALLI(47)
	UUOPEN,,UTTCAL	;OPEN(50),,TTCALL(51)
	ILLUUO,,ILLUUO	;(52),,(53)
	ILLUUO,,ILLUUO	;(54),,RENAME(55)
	ILLUUO,,ILLUUO	;IN(56),,OUT(57)
	USTSTS,,ILLUUO	;SETSTS(60),,STATO(61)
	ILLUUO,,ILLUUO	;STATUS(62),,GETSTS(63)
	ILLUUO,,ILLUUO	;STATZ(64),,INBUF(65)
	ILLUUO,,ILLUUO	;INPUT(66),,OUTPUT(67)
	UCLOSE,,URLEAS	;CLOSE(70),,RELEAS(71)
	ILLUUO,,ILLUUO	;MTAPE(72),,UGETF(73)
	ILLUUO,,ILLUUO	;USETI(74),,USETO(75)
	ILLUUO,,ILLUUO	;LOOKUP(76),,ENTER(77)

ILLUUO:	CALL	INLMES
	ASCIZ	\
Illegal UUO \
	PUSH	P,.UPMUP(AC1)	;SAVE PC
	HRLZ	T1,.UPMUO(AC1)	;GET THE UUO
	HRR	T1,.UPMUO+2(AC1)	;PICKUP EFFECTIVE ADR
	CALL	OCTYPE		;DISPLAY OCTAL CODE
	CALL	INLMES
	ASCIZ	\ @PC=\
	POP	P,T1		;GET PC
	ANDI	T1,-1		;STRIP OFF THE FLAGS
	SOS	T1		;BACK UP TO UUO
	CALL	OCTYPE
	HALT	.+1
	POP	P,T1		;CLEAN OFF THE STACK
	JRST	UUORET		;THEN EXIT UUO
;HERE FOR A CALLI UUO
UCALLI:	MOVE	T1,UUOACS(AC3)	;GET ARGUMENT FROM REGISTER
	HRRZ	T2,AC2		;GET CALLI INDEX
	CAIL	T2,126
	JRST	ILLUUO
	ROT	T2,-1
	TLNE	T2,400000
	SKIPA	T2,CALDSP(T2)
	HLRZ	T2,CALDSP(T2)
	JRST	(T2)

CALDSP:	CALLI0,,ILLUUO	;RESET(0),,(1)
	ILLUUO,,ILLUUO	;SETDDT(2),,(3)
	ILLUUO,,ILLUUO	;DEVCHR(4),,(5)
	ILLUUO,,ILLUUO	;GETCHR(6),,(7)
	ILLUUO,,UCORE	;WAIT(10),,CORE(11)
	ILLUUO,,ILLUUO	;EXIT(12),,(13)
	ILLUUO,,ILLUUO	;DATE(14),,LOGIN(15)
	ILLUUO,,ILLUUO	;APRENB(16),,LOGOUT(17)
	ILLUUO,,ILLUUO	;SWITCH(20),,REASSIGN(21)
	ILLUUO,,ILLUUO	;TIMER(22),,MSTIME(23)
	ILLUUO,,ILLUUO	;GETPPN(24),,TRPSET(25)
	ILLUUO,,URUNTM	;(26),,RUNTIM(27)
	ILLUUO,,USLEEP	;PJOB(30),,SLEEP(31)
	ILLUUO,,ILLUUO	;(32),,PEEK(33)
	ILLUUO,,ILLUUO	;GETLIN(34),,RUN(35)
	ILLUUO,,ILLUUO	;SETUWP(36),,REMAP(37)
	ILLUUO,,UGTTAB	;GETSEG(40),,GETTAB(41)
	ILLUUO,,ILLUUO	;SPY(42),,SETNAM(43)
	ILLUUO,,ILLUUO	;TMPCOR(44),,DSKCHR(45)
	ILLUUO,,ILLUUO	;SYSSTR(46),,JOBSTR(47)
	ILLUUO,,ILLUUO	;STRUUO(50),,SYSPHY(51)
	ILLUUO,,ILLUUO	;(52),,DEVTYP(53)
	ILLUUO,,ILLUUO	;DEVSTS(54),,DEVPPN(55)
	ILLUUO,,ILLUUO	;SEEK(56),,RTTRP(57)
	RSKP,,ILLUUO	;LOCK(60),,JOBSTS(61)
	ILLUUO,,ILLUUO	;LOCATE(62),,WHERE(63)
	ILLUUO,,ILLUUO	;DEVNAM(64),,CTLJOB(65)
	ILLUUO,,ILLUUO	;GOBSTR(66),,(67)
	ILLUUO,,ILLUUO	;(70),,HPQ(71)
	ILLUUO,,ILLUUO	;HIBER(72),,WAKE(73)
	ILLUUO,,ILLUUO	;CHGPPN(74),,SETUUO(75)
	ILLUUO,,ILLUUO	;(76),,OTHUSR(77)
	ILLUUO,,ILLUUO	;CHKACC(100),,DEVSIZ(101)
	ILLUUO,,ILLUUO	;DAEMON(102),,JOBPEK(103)
	ILLUUO,,ILLUUO	;ATTACH(104),,DAEFIN(105)
	ILLUUO,,ILLUUO	;FRCUUO(106),,DEVLNM(107)
	ILLUUO,,ILLUUO	;PATH(110),,METER.(111)
	ILLUUO,,ILLUUO	;MTCHR.(112),,JBSET.(113)
	ILLUUO,,ILLUUO	;POKE.(114),,TRMNO.(115)
	ILLUUO,,ILLUUO	;TRMOP.(116),,RESDV.(117)
	RSKP,,ILLUUO	;UNLOK.(120),,DISK(121)
	ILLUUO,,ILLUUO	;DVRST.(122),,DVURS.(123)
	ILLUUO,,ILLUUO	;(124),,CAL11.(125)
;RESET
CALLI0:	WRAPR	1B19!1B22!37B30	;IO RESET
	CALL	R.SET		;DO A UNIBUS RESET
	WRPI	12377	;RESET PI SYSTEM & TURN IT ON
	MOVEI	T1,^D4096
	WRINT	T1		;SET INTERVAL FOR TIMER
	SETZM	FEWSTS		;CLEAR FRONT END STATUS WORD
	SETZM	FEWINP		;CLEAR INPUT WORD
	SETZM	FEWOUT		;CLEAR OUTPUT WORD
	MOVE	T1,[POINT 8,RCVBUF]
	MOVEM	T1,RCVPTR	;INITIALIZE RECEIVE CHAR PUTTER
	MOVEM	T1,RCVTKR	;INITIALIZE RECEIVE CHAR TAKER
	SETZM	CNTLOF		;CLEAR CONTROL O FLAG
	WRAPR	1B20!73B31!APRLVL	;ENABLE INTERRUPTS
	MOVSI	T1,400000
	LSH	T1,-1
	JUMPG	T1,R
	TYPE	<LSH extends sign>
	HALT	CALLI0

;CORE - CALLI 11
UCORE:	IORI	T1,777
	HRRM	T1,.JBREL	;SET NEW JOBREL
	MOVEI	T1,140
	MOVEM	T1,UUOACS(AC3)	;RESULT
	RETSKP

;HERE FOR A RUNTIM UUO
URUNTM:	MOVE	T1,UPTIME	;GET UPTIME (WE USE ALL THE TIME)
	MOVEM	T1,UUOACS(AC3)	;RESULT
	RET

;SLEEP - CALLI 31
USLEEP:	RET

;GETTAB - CALLI 41
UGTTAB:	RET
;HERE FOR A TTCALL UUO
UTTCAL:	CAIG	AC2,16
	ADDI	AC2,UUOACS	;POINT TO RIGHT ARGUMENT
	ROT	AC3,-1
	TLNE	AC3,400000
	SKIPA	T2,TTCDSP(AC3)
	HLRZ	T2,TTCDSP(AC3)
	JRST	(T2)
TTCDSP:	TTCLL0,,TTCLL1	;INCHRW(0),,OUTCHR(1)
	TTCLL2,,TTCLL3	;INCHRS(2),,OUTSTR(3)
	TTCLL4,,TTCLL5	;INCHWL(4),,INCHSL(5)
	TTCLL6,,TTCLL7	;GETLCH(6),,SETLCH(7)
	TTCL10,,TTCL11	;RESCAN(10),,CLRBFI(11)
	TTCL12,,TTCL13	;CLRBFO(12),,SKPINC(13)
	TTCL14,,TTCL15	;SKPINL(14),,IONEOU(15)
	ILLUUO,,ILLUUO	;(16),,(17)

;INCHRW
TTCLL0:	CALL	CHKCHR		;SEE IF THERE IS A CHARACTER READY
	JRST	TTCLL0		;TRY AGAIN
	MOVEM	T1,(AC2)	;GIVE USER THE DATA
	RET

;OUTCHR
TTCLL1:	MOVE	T1,(AC2)	;GET THE CHARACTER TO WRITE
	JRST	SCNTYP		;TYPE THE CHARACTER

;INCHRS
TTCLL2:	CALL	CHKCHR		;TRY TO GET A CHARACTER
	RET			;TRY LATER
	MOVEM	T1,(AC2)	;GIVE THE USER THE CHARACTER
	RETSKP

;OUTSTR
TTCLL3:	HRLI	AC2,(POINT 7,0)
TTCL31:	ILDB	T1,AC2
	JUMPE	T1,R		;IF NULL WE ARE DONE
	CALL	SCNTYP		;TYPE THE CHARACTER
	JRST	TTCL31

;INCHWL
TTCLL4:	JRST	TTCLL0

;INCHSL
TTCLL5:	JRST	TTCLL2

;GETLCH
TTCLL6:	SETZM	(AC2)
	RET

;SETLCH
TTCLL7:	RET

;RESCAN
TTCL10:	RET

;CLRBFI
TTCL11:	RET

;CLRBFO
TTCL12:	RET

;SKPINC
TTCL13:	CALL	CHKCHR		;IS ANYTHING READY ?
	RET			;NO
	MOVEM	T1,(AC2)	;GIVER USER CHARACTER
	RETSKP

;SKPINL
TTCL14:	JRST	TTCL13

;IONEOU
TTCL15:	MOVE	T1,(AC2)
	JRST	SCNTYP
;HERE TO TYPE AN INLINE MESSAGE
INLMES:	HRLI	T1,(POINT 7,0)
	HLLM	T1,(P)		;MAKE A BYTE POINTER
INLMS3:	ILDB	T1,(P)
	JUMPE	T1,RSKP		;SKIP NULL CHAR AND DONE
	PUSHJ	P,SCNTYP
	JRST	INLMS3		;FINISH REST OF MESSAGE
;HERE TO TYPE A CHARACTER
SCNTYP:	SKIPE	CNTLOF		;DID USER FLUSH OUTPUT ?
	RET
	ANDI	T1,177		;STRIP PARITY BIT
	CAIN	T1,15		;WAS THAT A CARRIAGE RETURN ?
	SETZM	COLUMN		;BACK TO LH MARGIN
	AOS	T2,COLUMN	;ADVANCE COLUMN POINTER
	CAIE	T1,177		;RUBOUTS DON'T PRINT
	CAIGE	T1,40		;IS THIS A PRINTING CHARACTER ?
	SOS	T2,COLUMN	;NOT PRINTING SO BACKUP SOLUMN COUNTER
	CAIN	T1,11		;WAS THAT A HT ?
	JRST	[ADDI	T2,^D8
		ANDI	T2,-10
		MOVEM	T2,COLUMN
		JRST	.+1 ]
	CAMLE	T2,WIDTH	;IS THAT IN RANGE ?
	JRST	[PUSH	P,T1		;SAVE CHAR TO TYPE
		CALL	INLMES
		BYTE	(7)15,12,0
		POP	P,T1
		JRST	SCNTYP ]
	CAIGE	T1,40		;SHOULD WE PAD THIS CHARACTER ?
	JRST	[PUSHJ	P,.+1		;PRINT THE CHARACTER THEN RETURN HERE
		MOVEI	T1,377		;PAD CHAR
		JRST	.+1 ]
	SKIPE	FEWOUT		;CAN WE TYPE NEXT CHAR ?
	JRST	.-1		;WAIT UNTIL WE CAN
	ANDI	T1,377		;STRIP EXTRA BITS
	IORI	T1,1B27		;FLAG THIS IS A CTY CHAR
	MOVEM	T1,FEWOUT	;PUT IT FOR 8080 TO FIND
	WRAPR	1B23!1B25!APRLVL	;INTERRUPT THE 8080
	RET
CNTLOF:	Z			;CONTROL O FLAG
RCVTKR:	Z			;TAKER FOR RECEIVE CHARACTERS
RCVPTR:	Z			;PUTTER FOR RECEIVE CHARACTERS
RCVBUF:	BLOCK	10		;BUFFER FOR RECEIVE CHARACTERS

COLUMN:	Z			;COLUMN WE ARE ON
WIDTH:	^D80		;MAXIMUM NUMBER OF COLUMNS FOR OUTPUT
;HERE TO TRY TO GET A CHARACTER FROM THE CTY
CHKCHR:	SETZM	CNTLOF		;CLEAR CONTROL O FLAG
	SETZ	T1,
	EXCH	T1,SAVCHR#	;GET SAVED CHAR
	JUMPN	T1,CKCHR5
	MOVE	T2,RCVTKR	;GET RECEIVE CHAR TAKER
	CAMN	T2,RCVPTR	;ANY CHARACTERS
	RET
	ILDB	T1,T2		;GET NEXT CHARACTER
	CAMN	T2,[POINT 8,RCVBUF+7,31]	;WAS THAT LAST IN BUFFER ?
	MOVE	T2,[POINT 8,RCVBUF]	;TIME TO WRAP BUFFER AROUND
	MOVEM	T2,RCVTKR
CKCHR5:	ANDI	T1,377		;STRIP EXTRA BITS
	MOVE	T2,T1		;COPY CHAR
	ANDI	T2,177		;STRIP PARITY BIT
	TXNN	FLG,F.RUNF	;RUNNING SIMULATION ?
	CAIE	T2,3		;WAS THAT A CONTROL C ?
	CAIA
	JRST	DDT11		;YES SO BEGIN AGAIN
	PUSH	P,T2		;SAVE CHARACTER FOR RETURN
	CAIN	T2,15		;WAS THAT A CR ?
	JRST	[MOVEI	T2,12		;LF
		MOVEM	T2,SAVCHR#
		JRST	.+1]
	CAIN	T2,33		;WAS THAT AN ALTMODE ?
	MOVEI	T1,"$"		;ECHO AS THIS
	TXNN	FLG,F.RUNF	;IF SIMULATING DON'T ECHO
	CALL	SCNTYP		;ECHO THE CHARACTER
	POP	P,T1		;GET CHAR OFF STACK
	RETSKP
;HERE ON AN INIT UUO
UUINIT:	HRRZ	AC2,-1(P)	;GET RETURN ADDRESS
	SOS	AC2
	MOVEI	T1,2
	ADDM	T1,-1(P)	;SO RETURN WORKS
	;JRST	UUOPEN
;HERE ON AN OPEN UUO
UUOPEN:	CAIG	AC2,16		;WAS ARGUMENT IN REGISTERS ?
	ADDI	AC2,UUOACS	;YES SO RELOCATE
	HRRZ	T1,AC3		;GET REGISTER ARGUMENT = CHNL
	LSH	T1,^D23		;POSITION IN LH
	TLO	T1,20		;FLAG DEVICE OPENED
	HRR	T1,(AC2)	;GET STATUS
	MOVS	T2,1(AC2)	;GET DEVICE NAME TO OPEN
	CAIN	T2,'TTY'
	JRST	OPNTTY
	MOVEM	T1,DSKDDB	;SAVE STATUS
	MOVSM	T2,DSKSTR	;SAVE NAME OF DISK STRUCTURE
	SETZM	RJUNIT		;LOOK AT FIRST UNIT FOR STRUCTURE NAME
	SETZM	RJBLCK		;BLOCK TO READ
DSKOP2:	CALL	RJREAD		;TRY TO READ THE BLOCK
	JRST	[AOS	T1,RJUNIT
		CAIE	T1,^D8		;TOO LARGE ?
		JRST	DSKOP2
		RET	]
	RET

OPNTTY:	MOVEM	T1,TTYDDB	;SAVE DEVICE STATUS
	RETSKP

;DEVICE BLOCKS
TTYDDB:	Z			;CHNL,,DEVICE STATUS SET BY USER
	EXP	DSKDDB

DSKDDB:	Z			;CHNL,,DEVICE STATUS SET BY USER
	Z
DSKSTR:	Z			;STRUCTURE
DSKFIL:	Z			;FILE NAME
DSKEXT:	Z			;FILE EXT
;HERE ON A SETSTS UUO
USTSTS:	CALL	UFNDDB
	RET
	HRRM	T1,0(AC4)
	RET

;HERE ON A CLOSE UUO
UCLOSE:	RET

;HERE ON A RELEASE UUO
URLEAS:	CALL	UFNDDB		;FIND WHICH DDB
	RET
	SETZM	0(AC4)
	RET

UFNDDB:	MOVEI	AC4,TTYDDB
UFNDD0:	SKIPN	T1,0(AC4)	;GET STATUS
	JRST	UFNDD7
	LDB	T1,[POINT 4,0(AC4),12]
	CAMN	T1,AC3
	JRST	RSKP
UFNDD7:	SKIPE	AC4,1(AC4)	;GET NEXT DDB ADR
	JRST	UFNDD0
	RET
;HERE TO HANDLE AN RJPO4

;HERE TO READ A BLOCK FROM AN RJP04
; CALL	SETUP RJUNIT WITH UNIT NUMBER
;	SETUP RJBLCK TO BE BLOCK NUMBER TO READ
;	CALL RJREAD
;	ERROR RETURN
;	WIN RETURN
RJREAD:	HLLZ	MA,UBACTL	;ADD UNIBUS UNIT
	RDIO	T1,UBAMAP+77(MA)	;GET CURRENT MAP FOR PAGE
	PUSH	P,T1		;SAVE STATUS
	HRRZ	T1,EPTBLK	;GET ADR OF EPT
	MOVEI	T1,DSKPAG(T1)	;MAKE ADR OF DISK PAGE
	LSH	T1,-^D9		;MAKE PAGE NUMBER
	TRO	T1,UB.VLD!UB.FST	;STATUS
	WRIO	T1,UBAMAP+77(MA)	;MAP THE DISK PAGE
	MOVEI	T1,000040	;RESET
	WRIO	T1,RPCS2(MA)	;CLEAR OUT THE CONTROLLER
	MOVE	T1,RJUNIT	;UNIT TO READ FROM
	WRIO	T1,RPCS2(MA)	;SELECT UNIT
	MOVEI	T1,21		;PRESELECT
	WRIO	T1,RPCS1(MA)	;SELECT OUR UNIT
	MOVEI	T1,174000	;ADR TO TRANSFER TO
	WRIO	T1,RPBA(MA)	;SET ADDRESS
	MOVEI	T1,-2000	;NUMBER OF PDP11 WORDS TO TRANSFER
	WRIO	T1,RPWC(MA)
	MOVEI	T1,471		;READ DATA AND MEMORY EXTENSION
	WRIO	T1,RPCS1(MA)	;START THE TRANSFER
	CALL	RJRDWT		;WAIT FOR TRANSFER TO COMPLETE
	JRST	RJRD.9
RJRD.9:	POP	P,T2		;GET OLD UBAMAP STATUS
	LDB	T1,[POINT 11,T2,26]	;GET PAGE NUMBER
	LDB	T2,[POINT 4,T2,8]	;GET STATUS BITS
	DPB	T2,[POINT 4,T1,21]	;PUT INTO WORD
	WRIO	T1,UBAMAP+77(MA)	;RESTORE MAP FOR THAT PAGE
	RET
;HERE TO WAIT FOR DISK OPERATION TO COMPLETE
RJRDWT:	MOVE	T4,UPTIME	;HOW LOG WE HAVE BEEN UP
	ADDI	T4,^D1000	;ADD A SECOND
RJRDW4:	CAMG	T4,UPTIME	;HAVE WE WAITED TOO LONG ?
	RET			;MUST BE DEAD
RJRD.5:	RDIO	T1,RPCS1(MA)	;GET DRIVE STATUS
	TRNN	T1,160200	;FLAG COME UP ?
	JRST	RJRDW4		;NOT YET
	TRNN	T1,060000	;ERROR FLAG UP ?
	AOS (P)			;NO, SKIP RETURN
	RET			;YES LOSE


RJUNIT:	Z			;UNIT TO READ
RJBLCK:	Z			;BLOCK TO READ

	SUBTTL	EBCDIC TO ASCII TRANSLATION TABLE

;TRANSLATION TABLE FROM EBCDIC TO ASCII

EB.TRN:	BYTE	(8)000,001,002,003,000,011,000,177	;000-007
	BYTE	(8)000,000,000,013,014,015,000,000	;010-017
	BYTE	(8)000,021,022,000,000,000,000,000	;020-027
	BYTE	(8)000,000,000,000,000,000,000,000	;030-037
	BYTE	(8)000,000,000,000,000,000,000,000	;040-047
	BYTE	(8)000,000,000,000,000,000,000,000	;050-057
	BYTE	(8)000,000,000,000,000,000,000,000	;060-067
	BYTE	(8)000,000,000,000,000,000,000,000	;070-077
	BYTE	(8)040,000,000,000,000,000,000,000	;100-107
	BYTE	(8)000,000,000,056,074,050,053,136	;110-117
	BYTE	(8)046,000,000,000,000,000,000,000	;120-127
	BYTE	(8)000,000,041,044,052,051,073,155	;130-137
	BYTE	(8)055,057,000,000,000,000,000,000	;140-147
	BYTE	(8)000,000,174,054,045,137,076,077	;150-157
	BYTE	(8)000,000,000,000,000,000,000,000	;160-167
	BYTE	(8)000,140,072,043,100,047,075,042	;170-177
	BYTE	(8)075,141,142,143,144,145,146,147	;200-207
	BYTE	(8)150,151,000,000,000,000,000,000	;210-217
	BYTE	(8)000,152,153,154,155,156,157,160	;220-227
	BYTE	(8)161,162,000,000,000,000,000,000	;230-237
	BYTE	(8)100,176,163,164,165,166,167,170	;240-247
	BYTE	(8)171,172,134,116,153,133,113,141	;250-257
	BYTE	(8)060,061,062,063,064,065,066,067	;260-267
	BYTE	(8)070,071,172,136,114,135,156,157	;270-277
	BYTE	(8)173,101,102,103,104,105,106,107	;300-307
	BYTE	(8)110,111,000,000,000,000,000,000	;310-317
	BYTE	(8)175,112,113,114,115,116,117,120	;320-327
	BYTE	(8)121,122,000,000,000,000,000,000	;330-337
	BYTE	(8)134,000,123,124,125,126,127,130	;340-347
	BYTE	(8)131,132,000,000,000,000,000,000	;350-357
	BYTE	(8)060,061,062,063,064,065,066,067	;360-367
	BYTE	(8)070,071,174,000,000,000,000,000	;370-377
	SUBTTL	STATE TABLES

;INITIAL STATE TABLE

STATE0:
BYTE (18)LOOP  ,ILLCHR,ILLCHR,DDT11 ,ILLCHR,ILLCHR,CNTRLF,ILLCHR;00-07
BYTE (18)ACCUM ,ACCUM ,ACCUM ,ILLCHR,ILLCHR,ACCUM ,ILLCHR,ILLCHR;10-17
BYTE (18)ILLCHR,ILLCHR,CNTRLR,ILLCHR,ILLCHR,CNTRLU,ILLCHR,CNTRLW;20-27
BYTE (18)EXPXOR,ILLCHR,CNTRLZ,ESCAPE,ILLCHR,ILLCHR,ILLCHR,ILLCHR;30-37
BYTE (18)EXPSPC,EXPIOR,ACCUM ,ACCUM ,ASSYMB,ASSPRC,EXPAND,EXPDIV;40-47
BYTE (18)ACCUM ,ACCUM ,EXPMUL,EXPLUS,ACCUM ,EXPMIN,ASSPER,ACCUM	;50-57
BYTE (18)ASSNUM,ASSNUM,ASSNUM,ASSNUM,ASSNUM,ASSNUM,ASSNUM,ASSNUM;60-67
BYTE (18)ASSDEC,ASSDEC,DEFSYM,ACCUM ,LFTANG,ACCUM ,ACCUM ,QUEST.;70-77
BYTE (18)ACCUM ,ASSYMB,ASSYMB,ASSYMB,ASSYMB,ASSYMB,ASSYMB,ASSYMB;100-107
BYTE (18)ASSYMB,ASSYMB,ASSYMB,ASSYMB,ASSYMB,ASSYMB,ASSYMB,ASSYMB;110-117
BYTE (18)ASSYMB,ASSYMB,ASSYMB,ASSYMB,ASSYMB,ASSYMB,ASSYMB,ASSYMB;120-127
BYTE (18)ASSYMB,ASSYMB,ASSYMB,ACCUM ,ACCUM ,ILLCHR,ACCUM ,ACCUM	;130-137
BYTE (18)ILLCHR,ASSYMB,ASSYMB,ASSYMB,ASSYMB,ASSYMB,ASSYMB,ASSYMB;140-147
BYTE (18)ASSYMB,ASSYMB,ASSYMB,ASSYMB,ASSYMB,ASSYMB,ASSYMB,ASSYMB;150-157
BYTE (18)ASSYMB,ASSYMB,ASSYMB,ASSYMB,ASSYMB,ASSYMB,ASSYMB,ASSYMB;160-167
BYTE (18)ASSYMB,ASSYMB,ASSYMB,ILLCHR,ILLCHR,ILLCHR,ILLCHR,COMRUB;170-177
;STATE TABLE WHEN USER TYPES ALTMODE

STATSC:
BYTE	(18)LOOP  ,ILLCHR,ILLCHR,DDT11 ,ILLCHR,ILLCHR,ILLCHR,ILLCHR;00-07
BYTE	(18)ESC.UP,ILLCHR,ESC.LF,ILLCHR,ILLCHR,ESC.CR,ILLCHR,ILLCHR;10-17
BYTE	(18)ILLCHR,ILLCHR,CNTRLR,ILLCHR,ILLCHR,CNTRLU,ILLCHR,CNTRLW;20-27
BYTE	(18)ILLCHR,ILLCHR,CNTRLZ,ESCESC,ILLCHR,ILLCHR,ILLCHR,ILLCHR;30-37
BYTE	(18)ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR;40-47
BYTE	(18)ESCPAR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ESC...,ILLCHR;50-57
BYTE	(18)ESC..0,ESC..0,ESC..0,ESC..0,ESC..0,ESC..0,ESC..0,ESC..0;60-67
BYTE	(18)ESC..8,ESC..8,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR;70-77
BYTE	(18)ILLCHR,ESC..A,ESC..B,ESC..C,ESC..D,ILLCHR,ILLCHR,ESC..G;100-107
BYTE	(18)ILLCHR,ESC..I,ILLCHR,ESC..K,ILLCHR,ESC..M,ESC..N,ILLCHR;110-117
BYTE	(18)ESC..P,ESC..Q,ESC..R,ESC..S,ESC..T,ILLCHR,ESC..V,ESC..W;120-127
BYTE	(18)ESC..X,ESC..Y,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ESC.UP,ILLCHR;130-137
BYTE	(18)ILLCHR,ESC..A,ESC..B,ESC..C,ESC..D,ILLCHR,ILLCHR,ESC..G;140-147
BYTE	(18)ILLCHR,ESC..I,ILLCHR,ESC..K,ILLCHR,ESC..M,ESC..N,ILLCHR;150-157
BYTE	(18)ESC..P,ESC..Q,ESC..R,ESC..S,ESC..T,ILLCHR,ESC..V,ESC..W;160-167
BYTE	(18)ESC..X,ESC..Y,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,COMRUB;170-177
;STATE TABLE TO END AN EXPRESSION

STATEB:	
BYTE	(18)ILLCHR,ILLCHR,ILLCHR,DDT11 ,ILLCHR,ILLCHR,ILLCHR,ILLCHR;00-07
BYTE	(18)UARROW,COM.HT,COM.LF,ILLCHR,ILLCHR,COM.CR,ILLCHR,ILLCHR;10-17
BYTE	(18)ILLCHR,ILLCHR,CNTRLR,ILLCHR,ILLCHR,CNTRLU,ILLCHR,CNTRLW;20-27
BYTE	(18)ILLCHR,ILLCHR,CNTRLZ,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR;30-37
BYTE	(18)ILLCHR,ILLCHR,QUOTE ,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR;40-47
BYTE	(18)ILLCHR,ILLCHR,ILLCHR,ILLCHR,LEVEL3,ILLCHR,ILLCHR,OPNLOC;50-57
BYTE	(18)ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR;60-67
BYTE	(18)ILLCHR,ILLCHR,ILLCHR,SEMICL,ILLCHR,EQUALS,SUPLIM,ILLCHR;70-77
BYTE	(18)ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR;100-107
BYTE	(18)ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR;110-117
BYTE	(18)ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR;120-127
BYTE	(18)ILLCHR,ILLCHR,ILLCHR,OPLBKT,BKSLSH,ILLCHR,UARROW,BARROW;130-137
BYTE	(18)ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR;140-147
BYTE	(18)ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR;150-157
BYTE	(18)ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR;160-167
BYTE	(18)ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,ILLCHR,COMRUB;170-177
	SUBTTL	DATA STORAGE
LASTSW:	Z		;ROUTINE TO EXECUTE AFTER PARSING OTHER SWITCHES
DAT:	Z		;POINTER TO DATA AREA
DOTFOO:	Z		;IN CASE 32 OR 48 BIT INSTRUCTION
			; LH = -1 MEANS MEMORY ADR
			; LH = 400000 + BITS 12-17 ARE MODE
DTFINP:	Z		;DOTFOO WHILE TYPEING IN STUFF
DOTOLD:	Z		;OLD VALUE FOR DOT IN CASE OF ESCAPE CR ETC.
DTFOLD:	Z		;KEEP DOTFOO HERE
EXPRES:	Z		;BUILD EXPRESSIONS HERE
REMAIN:	Z		;REMAINDER FROM LAST DIVISION
LFTSAV:	Z		;IF LH NONZERO RH PRECEDED <
ETYPE:	Z		;TYPE OF EXAMINE ANE DEPOSIT WE WILL DO
PDP8F:	Z		;NONZERO IF WE DOING PDP8 STYLE
GOTO:	EXP	2	;STARTING ADDRESS FOR PROGRAM, EVEN, SO 11'S WORK
FENAME:	Z		;THIS IS ASCIZ \FE#:\ IF USING TOPS20 FRONT END
FE.JFN:	Z		;JFN FOR THE FRONT END DEVICE
FE.MSG:	BLOCK	<<14+FE.MAX>+3>/4	;MESSAGE FOR FRONT END
;KEEP IN ORDER
FE.CPU:	BLOCK	1	;CPU,,DTE
FE.FED:	BLOCK	1	;FED #
FE.STS:
FE.BUF:	BLOCK	1	;ABOVE 3 WORDS ARE DTE. ARG BLK
;KEPT IN ORDER
RELOFF:	Z		;RELOCATION OFFSET IF READING AN FE- DUMP
PORT:	Z		;-1,,PORT NUMBER FOR CALL11 UUO'S
NODE:	Z		;NAME OR NODE NUMBER WE ARE WORKING WITH
LINE:	Z		;LINE NUMBER ON NODE WE ARE WORKING WITH
CORARG:	Z		;CORE SIZE USER REQUESTED
USETIT:	Z		;BLOCK NUMBER TO START READING FOR SYMBOLS
SYMPTR:	Z		;BYTE POINTER TO FILL SYMBOL
SYMBOL:	Z		;CURRENT SYMBOL WE ARE BUILDING
DATA:	BLOCK	^D20
SBEGIN:	XWD	-1,0	;FIRST ADDRESS FOR SEARCH
S..END:	EXP	0	;LAST ADDRESS FOR SEACRH
S.WORD:	EXP	0	;WORD TO SEARCH FOR
S.MASK:	EXP	177777	;MASK FOR WORD SEARCH
REPEAT	MASKSZ,<EXP 0>	;MASK FOR WORD SEARCH
INPOPR:	EXP	0	;INPUT OPERATION (0=+,1=-,2=*,3=',4=!,5=&,6=^X)
PRECED:	EXP	0	;PRECEDENCE OF INPOPR = 0
	EXP	0
	EXP	1
	EXP	1
	EXP	2
	EXP	2
	EXP	2
BYTCNT:	XWD	1,1	;REPETITION COUNTS FOR OUPUT BYTES ETC.
O.MODE:	EXP	0	;OUTPUT MODE LH = PERMANENT, RH = CURRENT
			; (0=SYMBOLIC, 1=ADDRESS, 2=NUMERIC, 3=BYTES,
			;  4=ASCII TEXT, 5=EBCDIC TEXT)
ORADIX:	^D8,,^D8	;OUTPUT RADIX
			; LH IS PERMANENT SETTING, RH IS CURRENT
ESCSAV:	BLOCK	3	;SAVE BYTCNT ETC HERE IN CASE OF RUBOUT ETC.
LSTADR:	-1,,Z		;LAST ADDRESS DISPLAYED
LSTIAD:	Z		;LAST ADDRESS INPUT
ESC.Q.:	Z		;USED IF GET AN <ALT>Q
ESCOCT:	Z		;USED TO ACCUMULATE OCTAL NUMBER FOR ESCAPE ARG
ESCDEC:	Z		;USED TO ACCUMULATE DECIMAL NUMBER FOR ESCAPE ARG

	DEFINE	NAMES <
	X	11,SETP11	;/11
	X	8,SETPD8	;/8
	X	BINARY,SETBIN	;/BINARY
	X	CORE,SETCOR	;/CORE
	X	DTELDR,SETFOO	;/DETLDR
	X	DUMP,SETDMP	;/DUMP
	X 	FE,SET.FE	;/FE
	X	FESYMB,SETFES	;/FESYMBOLS
	X	GO,SETGO	;/GO
	X	LA36,SETLA3	;/LA36
	X	LINE,SETLIN	;/LINE
	X	LOCK,SETLOK	;/LOCK
	X	LSD,SETDMP	;/LSD
	X	MERGE,SETMRG	;/MERGE
	X	NODE,SETNOD	;/NODE
	X	PATCH,SETWEN	;/PATCH
	X	PDP11,SETP11	;/PDP11
	X	PDP8,SETPD8	;/PDP8
	X	PORT,SETPRT	;/PORT
	X	READST,SETRST	;/READSTB
	X	RELOCA,SETREL	;/RELOCATION
	X	SYMBOL,SETSYM	;/SYMBOL
	X	UBA,SETUBA	;/UBA - SET UNIBUS TO USE
	X	VT52,SETVTX	;/VT52
	X	WRITES,SETWST	;/WRITESTB
>
	DEFINE	X (A,B) <	SIXBIT	\A\ >
SW.LST:	NAMES
	Z
	DEFINE	X (A,B) <	0,,B >
SW.DSP:	NAMES


;KEEP A COPY OF CURRENT COMMAND HERE TO RETYPE IT OR RUBOUT CHARS
CMDTKR:	Z			;USE TO REPROCESS LINE
CMDLIM:	Z			;LIMIT TO RESCAN
CMDPTR:	Z			;UES TO FILL COMMAND LINE
Q=	<CMDSIZ+4>/5
CMDLIN:	BLOCK	Q

TTYBIT:	EXP	TF.RUB		;FLAGS TO DEFINE TYPE OF TERMINAL
FLGSAV:	EXP	0		;SAVE FLAG REGISTER HERE IN CASE OF REENTER
CMDCON:	EXP	0		;COMMAND CONFLICT LOCATION
MYPPN:	BLOCK	1		; PPN OF USER

;THE CACHE IS SO WORK OVER SYNCHRONOUS LINE WILL BE FASTER
CACHEL:	0		;CACHE LIMIT, I.E. 1ST NONEXISTEN BYTE ADR IN CACHE
CACHEA:	0		;ADDRESS REPRESENTED BY FIRST ADR IN CACHE
CACHSZ==400		;NUMBER OF WORDS IN CACHE
CACHE:	BLOCK	<CACHSZ/4>
	IFNDEF	PDLEN,<PDLEN==40>
PDL:	BLOCK	PDLEN

;DDT11 HAS BECOME SO LARGE THIS IS DESIREABLE

	IFNDEF	PATLEN,<PATLEN==40>
PATCH:	BLOCK	PATLEN

OSTYPE:	Z		;THE FLAG FOR THE TYPE OF OS WE ARE RUNNING
EPTBLK:	Z		;ADR OF EXEC STORAGE
UBACTL:	1,,0		;UBA CONTROLLER NUMBER
	SUBTTL	SYMBOL TABLES

	DEFINE	X (VAL,MASK,NAME,FLAG) <
IFL	<VAL-Q>,<PRINTX	SYMBOL TABLE MESSED UP
QVAL=	Q
>
IFN	<<VAL&MASK>-VAL>,<PRINTX SYMBOL TABLE MASK>
Q=	VAL

Z=	<<FLAG>&SMF.P8>!<<FLAG>&SMF.11>
IFE	<<FLAG>&<SMF.P8!SMF.11>>,<Z=1>
IFN	Z,<
	SIXBIT	\NAME\
	EXP	VAL
	XWD	FLAG,MASK
	SIXBIT	\DDT11\
>
>;END OF DEFINE X
Q=	0
SYMBEG:	EXP	.+2
SYMEND:	EXP	SYMZZZ

;FOLLOWING IS DYNAMIC STORAGE
;	SPACE (IF EXEC MODE)
;	MEMORY FOR EXEC MODE USAGE (EPT, UPT, ETC.) POINTED TO BY EPTBLK
;	MEMORY USE TABLE (IF READ FILE INTO CORE)
;	MEMORY (IF READ FILE INTO CORE)
;	SYMBOL TABLE (AT END CAUSE MOST LIKELY TO CHANGE IN SIZE)

	INSTRU
SYMZZZ==.

	PURGE	Z,ZZ,ZZRET,Q,QQ,X,XX,DDBLNK,DDBADR

DDTEND:	END	DDT11