Google
 

Trailing-Edge - PDP-10 Archives - BB-P363B-SM_1985 - mcb/cex/ddt.mac
There are 55 other files named ddt.mac in the archive. Click here to see a list.
;                    COPYRIGHT (c) 1980, 1981, 1982
;                    DIGITAL EQUIPMENT CORPORATION
;                        Maynard, Massachusetts
;
;     This software is furnished under a license and may  be  used
;     and copied only in accordance with the terms of such license
;     and with the inclusion of the above copyright notice.   This
;     software  or any other copies thereof may not be provided or
;     otherwise made available to any other person.  No  title  to
;     and ownership of the software is hereby transferred.
;
;     The information  in  this  software  is  subject  to  change
;     without  notice  and should not be construed as a commitment
;     by DIGITAL EQUIPMENT CORPORATION.
;
;     DIGITAL assumes no responsibility for the use or reliability
;     of  its  software  on  equipment  which  is  not supplied by
;     DIGITAL.

	.TITLE	DDT	- DYNAMIC DEBUGGING TECHNIQUE FOR A PDP-11.
	.IDENT	/X03350/
	.ENABL	LC
D.FORM	=	'X		; DDT form
D.VER	=	3.		; DDT version
D.LVL	=	2.		; DDT level
D.EDIT	=	35.		; DDT edit

; IT RESEMBLES DDT FOR A PDP-10 IN AS MANY WAYS AS POSSIBLE
; AND FALLS SHORT ONLY SLIGHTLY DUE TO THE VARIETY OF PDP-11
; CONFIGURATIONS AVAILABLE.
;
; AUTHOR: STEVEN M. RUBIN (SR12) AT CARNEGIE-MELLON UNIVERSITY
;MUNGED BY RIC WERME FOR INHOUSE DEBUGGING OF THE DN87S
;AND REMUNGED BY SAME FOR USE ON RSX-11M!
;AND REMUNGED AGAIN BY SCOTT ROBINSON TO DO THINGS CORRECTLY FOR
;RSX11M.
;AND REMUNGED AGAIN BY ALAN PECKHAM FOR USE ON MCB!

; UN-COMMENT THE NEXT LINE IF DDT IS TO RUN ON AN LSI-11
;D.LSI	=	1		; DEFINED IF PROCESSOR IS AN LSI-11

; THE NEXT DEFINES DESCRIBE THE MAIN OUTPUT DEVICE THAT
; DDT WILL USE.  ONLY 1 MAY BE DEFINED AND THE REST MUST BE
; COMMENTED OUT.
;D.GDP	=	1 		; TTY IS GRAPHICS DISPLAY PROCESSOR
;D.KSR	=	1 		; TTY IS KSR-33
;D.GT40	=	1 		; TTY IS DEC GT40
;D.RSX	=	1		; TTY IS ON (BLETCH) RSX-11M
D.MCB	=	1		; TTY IS ON (YAY!!!) MCB

	.IF	DF,D.LSI
.PRINT	; *****DDT for an LSI-11*****
	.ENABLE NSF
	.OPDEF	MFPS,TST,106700
	.OPDEF	MTPS,TST,106400
	.ENDC
	D.OKTTY=-1
	.IF	DF,D.GDP
	D.OKTTY=D.OKTTY+1
	.TITLE	D.GDP
.PRINT	; *****DDT for a GDP*****
D.RDB	=	165202		; READER DATA BUFFER
D.RCSR	=	165200		; READER STATUS REGISTER
D.PRIO	=	0		; RUN AT PRIORITY ZERO
	.ENDC
	.IF	DF,D.GT40
	D.OKTTY=D.OKTTY+1
	.TITLE	D.GT40
.PRINT	; *****DDT for a GT40*****
D.RCSR	=	177560		; READER STATUS REGISTER
D.RDB	=	177562		; READER DATA BUFFER
D.PRIO	=	200		; RUN AT PRIORITY FOUR
	.ENDC
	.IF	DF,D.KSR
	D.OKTTY=D.OKTTY+1
	.TITLE	D.KSR
.PRINT	; *****DDT for a TTY*****
D.RCSR	=	177560		; READER STATUS REGISTER
D.RDB	=	177562		; READER DATA BUFFER
D.RCHR	=	25.		; Input type-ahead buffer length
D.TCSR	=	177564		; PRINTER STATUS REGISTER
D.TDB	=	177566		; PRINTER DATA BUFFER
D.TCOL	=	72.		; Number of printer columns
D.PRIO	=	340		; RUN AT PRIORITY SEVEN
	.ENDC
	.IF DF D.RSX
	D.OKTTY=D.OKTTY+1
	.TITLE	D.RSX
.PRINT	; *****DDT FOR RSX-11M*****
D.PRIO	=	0		;WE DON'T USE THIS
.MCALL	EXIT$S,QIOW$S,ALUN$S,SVDB$S
	.ENDC
	.IF	DF,D.MCB
	D.OKTTY=D.OKTTY+1
	.TITLE	MDT	- DDT for MCB
	.MCALL	CCBDF$,HDRDF$,SYNDF$,TCBDF$,DSP$B,PHD$B,CALL$C
	CCBDF$			; Define CCB symbols
	SYNDF$			; Define SYNCH block symbols
	TCBDF$			; Define TCB symbols
	HDRDF$			; Define Task Header symbols
D.RCSR	=	177560		; READER STATUS REGISTER
D.RDB	=	177562		; READER DATA BUFFER
D.RCHR	=	25.		; Input type-ahead buffer length
D.TCSR	=	177564		; PRINTER STATUS REGISTER
D.TDB	=	177566		; PRINTER DATA BUFFER
D.TCOL	=	72.		; Number of printer columns
D.PRIO	=	7*40		; RUN AT PRIORITY SEVEN
UISAR0	=	177640		; User mode APR registers.
	.ENDC

.IIF NE,D.OKTTY,.ERROR	; INVALID OUTPUT DEVICE FOR DDT
D.BKP	=	8.		; NUMBER OF BREAKPOINTS
D.BKS	=	0		; Number of single-step breakpoint
D.SYML	=	10.		; MAX NUMBER CHARS IN A SYMBOL
D.SYMU	=	20.		; Number of user symbol entries.
R0	=	%0
R1	=	%1
R2	=	%2
R3	=	%3
R4	=	%4
R5	=	%5
SP	=	%6
PC	=	%7
PS	=	177776		; PROCESSOR STATUS

.IF NDF D.LSI
	.MACRO	MFPS val
	.IF NB,<val>
	MOV	@#PS,val
	.IFF
	MOV	@#PS,-(SP)
	.ENDC
	.ENDM	MFPS
	.MACRO	MTPS val
	.IF NB,<val>
	MOV	val,@#PS
	.IFF
	MOV	(SP)+,@#PS
	.ENDC
	.ENDM	MTPS
.ENDC

	.MACRO	EXTEND
.IF DF D.MCB
	MAP$	D.DAR6
.ENDC
	.ENDM	EXTEND

.IF NE,0
	DDT/11 - Dynamic Debugging Technique on the PDP-11

Each  command in DDT/11  is identical to the  PDP-10 version whenever
possible.   In some cases,  DDT/10 commands have been  omitted in the
interest  of saving core and  making good sense.  The  following is a
list of the DDT/11 commands:
    n/	Open word n.  Type contents in current mode
     /	Open word pointed to by last typed value
    n\	Open byte n.  Type contents in current mode
     \	Open byte pointed to by last typed value
    n[	Open location n, type as a numeric
    n]	Open location n, type as instruction
    n!	Open location n, do not type value
 n<CR>	Modify currently open word to be n.  Close word.
 n<LF>	Modify, close, open next word
    n^	Modify, close, open previous word
 n<BS>	(same as ^)
n<TAB>	Modify, close, open word pointed to by last typed address
    $A	Addresses will be typed as absolute numbers ($$A for permanence)
    $R	Addresses will be typed relative to symbols ($$R for permanence)
   $nR	Same as above, but change offset limit to n.
    $C	Change current mode to numeric type out ($$C for permanence)
   $nC	Change current radix for $C to n (n is decimal, $$nC for permanence)
   $nO	Change current mode to n bit byte typeout ($$nO for permanence)
    $S	Change current mode to instruction type out ($$S for permanence)
    $T	Change current mode to ASCII text output ($$T for permanence)
   $5T	Change current mode to Radix-50 text output ($$5T for permanence)
     ;	Retype currently open word
     =	Retype currently open word as number
    n=	Type value of n as a number
     _	Retype currently open word as instruction
    $X	Execute next instruction
   i$X	Execute instruction i (don't execute branches)
   $$X	Execute instructions until PC = <next instruction after current>
   n$G	Start executing program at location n.
	Default is to start executing at address in JOBSA (start of program)
  v$nB	Set breakpoint n at address v (n from 1 to 8 or can be omitted)
a,v$nB	Same as above but open address a at breakpoint
	If two altmodes are used, automatic proceding is enabled.
	The breakpoint will cause the message to be typed and the program
	resumed.  If you type a character, the automatic proceding will stop.
  0$nB	Remove breakpoint n
    $B	Remove all breakpoints
    $P	Procede from breakpoint
   n$P	Procede from breakpoint "n" times (without halting)
	If two altmodes are used, the breakpoint will be proceded automatically
    a:	Make symbolic name "a" have value of current location
  v<a:	Make symbolic name "a" have value "v"
  a$$K	Delete symbolic name "a"
   a$K	Delete symbolic name "a" from typeout only
   $$K	Delete last symbol coloned (:)
    $K	Delete last symbol coloned (:) from typeout only
   n$M	Set mask for searches (below) to "n"
l<u>s$W	Search core from "l" to "u" for word "s"
l<u>s$E	Search core from "l" to "u" for effective address "s"
l<u>s$N	Search core from "l" to "u" for word not equal to "s"
l<u$$Z	Zero memory from "l" to "u"
   $nD	Synchronize to process with PIX "n"
  1$nD	Break on severity code "n"
 -1$nD	Continue on severity code "n"
  0$$D	Disable DDT
 -1$$D	Crash the system and cause a panic dump
<CALL>	Soft restart at address 1004 (Graphics DDT only)
 ctl-D	Interrupt execution (only good during program execution)

Note that numbers can be as any combination of the following:

	<Octal number>
	<Decimal number> .
	<Program symbol>
	" <Delimeter> <Two ASCII Characters> <Delimeter>
	"$ <Delimeter> <Three Radix-50 Characters> <Delimeter>
	<Instruction>

The operators +  (addition), - (subtraction), * (multiplication), and
' (division) are evaluated  from left to right unless parenthesis are
included.  The space is treated like a plus except after instructions
when  it is merely a  separator.   All input is  accepted in lower or
upper case and is folded (except for text.)

If you  are not  in DDT,  you can  re-enter with  a Meta-BREAK  on  a
graphics or  a restart  at DDT  (location typed  out initially).   In
addition to program symbols, the following are also defined for you:

 R0-R5	are the user registers.  R1/ would open register 1.
 SP	is the user's stack pointer
 PC	is the user's program counter
 PS	is the user status
 $M	is the mask for searches
 $Q	is the value at the current address
 $V	is the value at the current address with the bytes switched
 $nB	is the address of breakpoint n
 JOBSA	is the starting address of your program.
 .	represents the current location.
	Thus .$1B puts breakpoint 1 at the currently opened location.

When  your program is  executing, the following  unexpected traps may
occur:

   NXM! is caused when your program requests a non-existant memory or
        does a word operation on an odd address.
   ILG! is caused by an illegal instruction.
   BPT! is  caused  by  an  entry  to DDT  that  is  unexpected (i.e.
        executing the BPT instruction or setting the T-bit).
.ENDC
; INSTRUCTION DECODE/ENCODE TABLE

	.MACRO	INSTRS
; THE FIVE PARAMETERS TO THE CODE OP-CODE DESCRIBE AN INSTRUCTION:
; THE FIRST PARAMETER IS THE LOWER LIMIT OF VALUES THAT WILL FALL
;  INTO THAT OP-CODE (THE TABLE MUST BE SCANNED SEQUENTIALLY)
; THE SECOND PARAMETER IS THE OP-CODE TEXT
; THE THIRD PARAMETER TELLS THE MACHINE SUITABILITY
;  0 MEANS ANY MACHINE HAS THIS INSTRUCTION.  1 MEANS
;  11/40 AND UP ONLY, 2 MEANS 11/45 ONLY.
; THE FOURTH PARAMETER TELLS HOW TO DECODE THE PARAMETERS:
;   0 MEANS NO PARAMETERS
;   1 MEANS "NNNNNN" (16 BIT NUMBER)
;   2 MEANS DECODE CONDITION CODE BITS (NZVC)
;   3 MEANS "N" (3 BIT NUMBER)
;   4 MEANS "XXX" (8 BIT DISPLACEMENT)
;   5 MEANS "R,DD"
;   6 MEANS "NN" (6 BIT NUMBER)
;   7 MEANS "SS,DD" (OR "DD,SS")
;  10 MEANS "R"
;  11 MEANS "R,NN" (6 BIT DISPLACEMENT)
;  12 MEANS "NNN" (8 BIT NUMBER)
;  13 MEANS "DD" (OR "SS")
;  14 MEANS "SS,R"
; THE FIFTH PARAMETER IS 1 IF THIS INSTRUCTION IS LEGAL IN BYTE MODE
	CODE	0,HALT,0,0,0
	CODE	1,WAIT,0,0,0
	CODE	2,RTI,0,0,0
	CODE	3,BPT,0,0,0
	CODE	4,IOT,0,0,0
	CODE	5,RESET,0,0,0
	CODE	6,RTT,1,0,0
	CODE	7,,0,1,0
	CODE	100,JMP,0,13,0
	CODE	200,RTS,0,10,0
	CODE	210,,0,1,0
	CODE	230,SPL,2,3,0
	CODE	240,NOP,0,0,0
	CODE	241,CL,0,2,0
	CODE	257,CCC,0,0,0
	CODE	260,,0,1,0
	CODE	261,SE,0,2,0
	CODE	277,SCC,0,0,0
	CODE	300,SWAB,0,13,0
	CODE	400,BR,0,4,0
	CODE	1000,BNE,0,4,0
	CODE	1400,BEQ,0,4,0
	CODE	2000,BGE,0,4,0
	CODE	2400,BLT,0,4,0
	CODE	3000,BGT,0,4,0
	CODE	3400,BLE,0,4,0
	CODE	4000,JSR,0,5,0
	CODE	5000,CLR,0,13,1
	CODE	5100,COM,0,13,1
	CODE	5200,INC,0,13,1
	CODE	5300,DEC,0,13,1
	CODE	5400,NEG,0,13,1
	CODE	5500,ADC,0,13,1
	CODE	5600,SBC,0,13,1
	CODE	5700,TST,0,13,1
	CODE	6000,ROR,0,13,1
	CODE	6100,ROL,0,13,1
	CODE	6200,ASR,0,13,1
	CODE	6300,ASL,0,13,1
	CODE	6400,MARK,1,6,0
	CODE	6500,MFPI,1,13,0
	CODE	6600,MTPI,1,13,0
	CODE	6700,SXT,1,13,0
	CODE	7000,,0,1,0
	CODE	10000,MOV,0,7,1
	CODE	20000,CMP,0,7,1
	CODE	30000,BIT,0,7,1
	CODE	40000,BIC,0,7,1
	CODE	50000,BIS,0,7,1
	CODE	60000,ADD,0,7,0
	CODE	70000,MUL,1,14,0
	CODE	71000,DIV,1,14,0
	CODE	72000,ASH,1,14,0
	CODE	73000,ASHC,1,14,0
	CODE	74000,XOR,1,5,0
	CODE	75000,FADD,1,10,0
	CODE	75010,FSUB,1,10,0
	CODE	75020,FMUL,1,10,0
	CODE	75030,FDIV,1,10,0
	CODE	75040,,0,1,0
	CODE	77000,SOB,1,11,0
	CODE	100000,BPL,0,4,0
	CODE	100400,BMI,0,4,0
	CODE	101000,BHI,0,4,0
	CODE	101400,BLOS,0,4,0
	CODE	102000,BVC,0,4,0
	CODE	102400,BVS,0,4,0
	CODE	103000,BCC,0,4,0
	CODE	103000,BHIS,0,4,0
	CODE	103400,BCS,0,4,0
	CODE	103400,BLO,0,4,0
	CODE	104000,EMT,0,12,0
	CODE	104400,TRAP,0,12,0
	CODE	105000,,0,1,0
.IF DF D.LSI
	CODE	106400,MTPS,1,13,0
.IFTF
	CODE	106500,MFPD,2,13,0
	CODE	106600,MTPD,2,13,0
.IFT
	CODE	106700,MFPS,1,13,0
	CODE	107000,,0,1,0
.IFF
	CODE	106700,,0,1,0
.ENDC
	CODE	160000,SUB,0,7,0
	CODE	170000,,0,1,0
	CODE	177777,,0,1,0
	.ENDM
; WORD ALIGNED CONSTANTS

	.PSECT	$PLIT$,D
D.LGDR:				; COMMAND DISPATCH TABLE
	D.ERR			;  @  ERROR
	D.ERR			;  #  ERROR
	D.ERR			;  (  ERROR
	D.ADD			;  +   
	D.ADD			;  <SP>
	D.MULT			;  *  MULTIPLICATION
	D.DIV			;  '  DIVISION
	D.SUBT			;  -  SUBTS SIGN
	D.ERR			;  )  ERROR
	D.TEXT			;  "  MAKE ASCII
	D.LWAS			;  >
	D.FWAS			;  <  SET FIRST WORD OF SEARCH
	D.EQAL			;  =  
	D.ALTM			;  $  ALTMODE
	D.COLN			;  :  DEFINES SYMBOL
	D.SEMI			;  ;  RE-TYPE WORD
	D.WRD			;  /  OPEN WORD
	D.BYT			;  \  OPEN BYTE
	D.DCOM			;  ,  COMMA PARAMETER
	D.CRET			;  <CR>  CLOSE
	D.OPNX			;  <LF>  MODIFY, CLOSE, OPEN NEXT
	D.ORPC			;  _  TYPE WORD AS INSTRUCTION
	D.BACK			;  ^  OPEN PREVIOUS
	D.BACK			;  <BS>  OPEN PREVIOUS
.IF DF D.GDP
	D.SOFT			;  <CALL>  SOFT RESTART AT 1004
.ENDC
	D.ORAB			;  <TAB>  OPEN RELATED, ABSOLUTE
	D.OPBR			;  [  OPEN WORD AS NUMERIC
	D.CLBR			;  ]  OPEN WORD AS INSTRUCTION
	D.EXCL			;  !  OPEN WORD SILENTLY
	D.ERR			;  <SP> SECOND SPACE (ERROR)
	D.ABS			;  A  ABSOLUTE ADDRESSES
	D.BKPT			;  B  BREAKPOINTS
	D.INNM			;  C  IN NUMERICS
	M.DBG			;  D  Set debugging mode
	D.ESCH			;  E  SEARCH EFFECTIVE ADDRESS
	D.ERR			;  F  (undefined)
	D.GO			;  G  GO TO ADDRESS K
	D.ERR			;  H  (undefined)
	D.ERR			;  I  (undefined)
	D.ERR			;  J  (undefined)
	D.KILL			;  K  SYMBOL TABLE DELETION
	D.ERR			;  L  (undefined)
	D.MAST			;  M  SET MASK
	D.NSCH			;  N  NON-SEARCH
	D.BYTE			;  O  TYPEOUT IN BYTES
	D.PROC			;  P  PROCEED
	D.ALTQ			;  Q  CURRENT WORD
	D.INRD			;  R  SET RADIX
	D.INMD			;  S  IN INSTRUCTION MODE
	D.INTX			;  T  IN TEXT
	D.SNGL			;  U  SECOND SET OF ROUTINES
	D.ALTV			;  V  SWAB OF CURRENT WORD
	D.WSCH			;  W  SEARCH WORD
	D.EXEC			;  X  EXECUTE INSTRUCTION
	D.ERR			;  Y  (undefined)
	D.ZERO			;  Z  ZERO CORE

D.UADD:
.IF DF D.GDP
	D.GRAP			;  UG  RETURN USER DISPLAY
.ENDC

D.PARG:	D.NONE			; NO PARAMETERS
	D.NONE			; 16-BIT NUMBER NOT AN INSTRUCTION
	D.NONE			; CONDITION CODE ALREADY DECODED
	D.NONE			; 3 BIT OPERAND ADDED IN AUTOMATICALLY
	D.DISP			; GET 8-BIT DISPLACEMENT
	D.GRSS			; GET "R,SS"
	D.GNUM			; GET 6-BIT NUMBER (MARK OPERAND)
	D.GSD			; GET "SS,DD"
	D.GR			; GET "R"
	D.GRNN			; GET "R,NN"
	D.GNUM			; GET 8-BIT OPERAND
	D.GDD			; GET "DD" (OR "SS")
	D.GDDR			; GET "DD,R"

D.PARM:	D.RTS
	D.N16
	D.CZVN
	D.N3
	D.X8
	D.RDD
	D.N6
	D.SSDD
	D.R
	D.RN6
	D.N8
	D.DD
	D.DDR
.IF DF D.MCB
.PAGE
;
; Debug process header and LLC dispatch vector
;

	PHD$B	MDT
	PHD$D	MDTDSP
	PHD$E

	.PSECT	$PLIT$,D
MDTDSP:	DSP$B
	DSP$	FC.AST		; Asynchronous Notification
	DSP$	FC.XME		; Transmit
	DSP$	FC.RCE		; Receive
	DSP$	FC.KIL		; Kill
	DSP$	FC.CTL		; Control
	DSP$	FC.TIM,DDT	; Timeout
	DSP$	FC.XCP		; Transmit Complete
	DSP$	FC.RCP		; Receive Complete
	DSP$	FC.KCP		; Kill Complete
	DSP$	FC.CCP		; Control Complete
	DSP$E
.ENDC

.IF DF D.RSX
D.TRPV:	.WORD	4,250,14,20,10,30,34,244
.ENDC
	.PSECT	$PLIT$,D

	.MACRO	CODE	TOP,STR,LEG,PARM,BYT
	.WORD	TOP-1
	.ENDM

D.TOPS:	INSTRS
	.WORD	-1

	.MACRO	CODE	TOP,STR,LEG,PARM,BYT
	.BYTE	<BYT*200>+<PARM*4>+LEG
	.NCHR	D.LEN,STR
	OFFSET=OFFSET+D.LEN
	.BYTE	OFFSET
	.ENDM
	OFFSET=0

D.COUS:	.BYTE	OFFSET
D.LEGS:	INSTRS
D.ECNT=.-1

	.MACRO	CODE	TOP,STR,LEG,PARM,BYT
	.ASCII	"STR"
	.ENDM

D.STRS:	INSTRS
	.PSECT	$PLIT$,D
D.FIRS:	.ASCII	<0> "((@(-(@-(" <0> "@" <0> "))+)+))))??#@#??" <0> "@"
D.NZVC:	.ASCII	"CVZN"
D.OPCH:	.BYTE	0,1,2,3,5,7,12,13
D.CLOS:	.BYTE	14,15,16,20,22,23,24,25
D.MOD7:	.BYTE	26,27,30,31,33,34,35,36,37
.IF DF D.MCB
D.HELO:	.ASCII	"DDT "<D.FORM>
.RADIX 10.
.IRP ver,<\D.VER>
	.ASCII	"'ver'"
.ENDM
.IF NE,D.LVL
.IRP lvl,<\D.LVL>
	.ASCII	".'lvl'"
.ENDM
.ENDC
.IRP edt,<\D.EDIT>
	.ASCII	"('edt')"
.ENDM
.RADIX 8.
	.ASCIZ	" enabled"<15><12><12>
.IFF
D.GRET:	.ASCII	<15><12>"DDT EXECUTION"
.IF NDF D.GDP
	.ASCII	"; MANUAL RESTART = "
.ENDC
	.ASCIZ	""
D.BE:	.ASCIZ	";BPT!"
D.NM:	.ASCIZ	";NXM!"
D.IM:	.ASCIZ	";ILG!"
.ENDC
D.UTAB:
.IF DF D.GDP
	.BYTE	'G		;  G
.ENDC
D.ENUT	=.-D.UTAB
D.LGCH:				; FIRST CHARACTERS MUST BE "@#(+ *'-)"
	.BYTE	'@		;  @
D.HASH	=.-D.LGCH
	.BYTE	'#		;  #
D.OPAR	=.-D.LGCH
	.BYTE	'(		;  (
D.ADDS	=.-D.LGCH
	.BYTE	'+		;  +
D.SPAC	=.-D.LGCH
	.BYTE	' 		;  <SP>
	.BYTE	'*		;  *
	.BYTE	''		;  '
D.DASH	=.-D.LGCH
	.BYTE	'-		;  -
D.CPAR	=.-D.LGCH
	.BYTE	')		;  )
	.BYTE	'"		;  "
	.BYTE	'>		;  >
	.BYTE	'<		;  <
	.BYTE	'=		;  =
	.BYTE	33		;  <ALT>
D.COLO	=.-D.LGCH
	.BYTE	':		;  :
	.BYTE	';		;  ;
	.BYTE	'/		;  /
	.BYTE	'\		;  \
D.COMM	=.-D.LGCH
	.BYTE	',		;  ,
	.BYTE	15		;  <CR>
	.BYTE	12		;  <LF>
	.BYTE	'_		;  _
	.BYTE	'^		;  ^
	.BYTE	10		;  <BS>
.IF DF D.GDP
	.BYTE	3		;  <CALL>
.ENDC
	.BYTE	11		;  <TAB>
	.BYTE	'[		;  [
	.BYTE	']		;  ]
	.BYTE	'!		;  !
D.LETR	=.-D.LGCH
D.RDTB:	.ASCII	" ABCDEFGHIJKLMNOPQRSTUVWXYZ"
D.CLGT	=.-D.LGCH		; COMMAND TABLE END
	.ASCII	"$.*0123456789"
D.ENTB	=.-D.RDTB
; BYTE ALIGNED VARIABLES

	.PSECT	$OWN$,D
.IF DF D.KSR!D.MCB
D.CPOS:	.BYTE	0		; CHARACTER POSITION FOR TTY
D.BUFR:	.BLKB	D.RCHR		; 25 CHARACTER INPUT BUFFER
D.ENDB:
.ENDC
D.CDSP:	.BYTE	'/		; <LF> display character
D.TDSP:	.BYTE	' 		; <TAB> display character
D.USED:	.BYTE	0		; IF ZERO, USE OCTAL NUMBER
D.MACH:	.BYTE	1		; 0=11/15  1=11/40  2=11/45
D.LEVL:	.BYTE	0		; PARENTHESIS LEVEL
D.FWAF:	.BYTE	0		; MARKER OF < PARAMETER
D.INPA:	.BYTE	0		; NON-ZERO IF IN AN INSTRUCTION TYPE-IN
D.P:	.BYTE	-1		; PROCEED FLAG = <1-8>*2 IF NORMAL BREAK
				;		0 IF SINGLE STEP BREAK
				;		-1 IF NOT ENTERED BY BREAK
.IF DF D.MCB
D.PSVR:	.BYTE	0,0,0,0,0,0,0,0	; Severity proceede switches:
				;   0 = unspecified
				;  >0 = continue
				;  <0 = break
D.E:	.BYTE	0		; Exception type:
				;   0 = SIGNAL
				;  -1 = hardware exception
.ENDC
D.ALTF:	.BYTE	0		; ALTMODE FOUND
D.CR:	.ASCIZ	<15><12>
.IF DF D.MCB
M.BMES:	.ASCIZ	"$nB"
.IFF
D.BMES:	.ASCIZ	"$nB >> "
.ENDC
.PAGE
; WORD ALIGNED VARIABLES
	.EVEN

.IF DF D.KSR!D.MCB
D.INPU:	D.BUFR			; INPUT BUFFER POINTER
D.OUTP:	D.BUFR			; OUTPUT BUFFER POINTER
.ENDC
.IF DF D.RSX
D.STS:	.BLKW	2		;ERROR STATUS FROM TI0: INPUT STORED HERE
D.BUFR:	.WORD	0
D.SVDB:	.BLKW	10		;USED IN SVDB$S CALL
.ENDC
D.SYM:	.BLKB	D.SYML+1	; HOLDS SYMBOL TYPED
	.EVEN
D.SD.T:				; WORD ADDRESS OF D.S AND D.T
D.S:	.BYTE	0		; SINGLE STEP FLAG
D.T:	.BYTE	0		; T-BIT FLAG
D.BOTH:				; WORD ADDRESS OF D.NOTY AND D.FIND
D.NOTY:	.BYTE	0		; DON'T TYPE OUT IF EQUALS 1
D.FIND:	.BYTE	0		; ADDRESS FOUND (EFF SEARCH) IF EQUALS 1
D.TPC:	0			; PC OF LAST BPT WE PROCEEDED
D.LFIN:	0			; LINE FEED INCREMENT
; THE NEXT 4 WORDS FORM THE TEMPORARY MODE TABLE AND MUST BE IN ORDER********
D.CURM:	D.INST			; TYPEOUT MODE ADDRESS			*****
D.DVTB:	8.			; CURRENT RADIX				*****
D.BW:	2			; BYTE-WORD INDICATOR (1=BYTE, 2=WORD)	*****
D.IFMT:	0			; (1=ABSOLUTE, 0=RELATIVE)		*****
; END OF CRITICAL ORDERING***************************************************
; THE NEXT 4 WORDS FORM THE PERMANENT MODE TABLE AND MUST BE IN ORDER********
D.PERM:	D.INST			; PERMANENT TYPEOUT MODE		*****
D.PERN:	8.			; PERMANENT RADIX			*****
D.PEBW:	2			; PERMANENT BYTE-WORD INDICATOR		*****
D.PEFM:	0			; PERMANENT ADDRESS TYPEOUT INDICATOR	*****
; END OF CRITICAL ORDERING***************************************************
D.OMOD:	D.INST			; MODE TO OPEN WORDS IN
D.OPER:	0			; OPERATION
D.DECN:	0			; DECIMAL NUMBER
D.SVR2:	0			; SAVE FOR R2
; THE NEXT THREE LINES MUST BE IN THAT ORDER FOR $X INST.********************
D.SVR4:	0			; SAVE FOR R4				*****
D.PARS:	0,0			; PARAMETERS FOR INSTR. TYPE-IN		*****
.IF NDF D.MCB
	JMP	D.EXE2		; RETURN IN CASE INSTRUCTION FINISHES	*****
.ENDC
D.PATR:	0			;
D.PATI:	JMP	@(PC)+		; Patch instruction
D.PATA:	0
	NOP
D.PATS:	.BLKW	5		; Patched instruction
D.PATE:	D.PATS			; end of patched instruction
; END OF CRITICAL ORDERING***************************************************
.PAGE
D.SVR7:	0			; SAVE FOR PC DURING $X
D.PARO:	0,0			; RELOCATIOON FOR D.PARS
D.OFST:	0			; OFFSET FROM COMMA
D.RFNL:	127.			; RFND OFFSET
D.LASV:	0			; LAST TYPED NUMBER
D.LASW:	0			; LAST TYPED WORD
D.DOT:	0			; CURRENT LOCATION
D.CADC:	0			; COPY OF D.CAD FOR TYPE-IN
D.ERF:	0			; ADDRESS OF ERROR MESSAGE
D.CAD:	0			; CURRENT ADDRESS
D.NLWD:	0			;USED ONLY TO MARK CLOSED WORD
D.XXX:	0			; TEMPORARY STORAGE
D.COMA:	0			; ADDRESS BEFORE COMMA
D.SIZE:	0			; BYTE SIZE FOR "O" TYPEOUT
D.RAD1:	0			; FIRST WORD OF RAD50 SYMBOL
D.RAD2:	0			; SECOND WORD OF RAD50 SYMBOL
D.LASC:	0			; LAST COLONED WORD
D.FENC:	S.SMDT			; ADDRESS OF FENCE SYMBOL TABLE
D.POS:	D.SYM			; ADDRESS OF CHARACTER IN D.SYM
D.FWA:	0			; LOW LIMIT
D.LWA:	DDT-2			; HIGH LIMIT
D.MASK:	177777			; MASK

D.BKTB:	.REPT	1+D.BKP
	0			; ADDRESS OF BREAKPOINTS
	.ENDR
.IF DF D.MCB
D.ADDR:	.BLKW	1+D.BKP		; APR6 virtual address
D.BIAS:	.BLKW	1+D.BKP		; APR6 relocation bias
.ENDC
D.UIN:	.BLKW	1+D.BKP		; Saved instruction
D.CT:	.BLKW	1+D.BKP		; Proceede counter
D.OPEN:	.BLKW	1+D.BKP		; Breakpoint open location
;
; The following are for $$X execution -
; They specify the range of addresses to break on.
;
D.BKLO:	.WORD	0		; Break on PC between this 
D.BKHI:	.WORD	0		; and this address.
.PAGE
; THE DDT STACK, INCLUDING SOME VARIABLES AT ITS BASE (HIGH ADDRESSES)
; WHICH DESCRIBE THE USER'S PROGRAM STATE:

; THE FOLLOWING VARIABLES ARE CRITICALLY ORDERED FOR VARIOUS REASONS.********
.IF NDF D.MCB
	.BLKW	40.		; ACTIVE STACK AREA			*****
D.STK:				; BASE OF ACTIVE DDT STACK		*****
.IF DF D.KSR
	0			; SAVE CELL - R C/SR			*****
.ENDC
.IF NDF D.RSX
	0			; SAVE CELL - T C/SR			*****
.ENDC
	0,0,0,0			; USER LOCATION 12,10,6,4		*****
.IFTF
D.URG:
D.UR0:	0			; USER REGISTER 0			*****
D.UR1:	0			; USER REGISTER 1			*****
D.UR2:	0			; USER REGISTER 2			*****
D.UR3:	0			; USER REGISTER 3			*****
D.UR4:	0			; USER REGISTER 4			*****
D.UR5:	0			; USER REGISTER 5			*****
D.UR6:	0			; USER SP				*****
D.UR7:	0			; USER PC				*****
.IFT
JOBSA:	0			; USER START ADDRESS			*****
.ENDC
; END OF CRITICALLY ORDERED VARIABLES****************************************

D.UPS:	0			; USER STATUS
D.DAR6:	0			; DDT's APR6
D.DR6:	0			; DDT's stack
D.DPS:	D.PRIO			; DDT'S entry status
.IF DF D.MCB
MAPR:				; Kernel mapping register:
	0			;  APR0 mapping bias.
	0			;  APR1 mapping bias.
	0			;  APR2 mapping bias.
	0			;  APR3 mapping bias.
	0			;  APR4 mapping bias.
MAPR5:	0			;  APR5 mapping bias.
MAPR6:	0			;  APR6 mapping bias.
	0			;  APR7 mapping bias.

MMCHV:	0			; Mechanism vector.
MSIGV:	0			; Signal vector.
MTTBK:	0			; Keyboard interrupt block.
MSNBK:	0			; Process synchronization block.
NEWEXV:	0,0,0			; Our exception vector.
EXVPRI:	0,0,0			; Old primary exception vector.
EXVLST:	0,0,0			; Old last chance exception vector.
.ENDC
	.SBTTL	SYMBOL TABLES

	.PSECT	$SYM$,D		; Beginning of DDT symbol table.
S.SMDT:
	.IRPC	rg,<012345>
	.RAD50	/R'rg'    /
	177700+'rg
	.ENDM
	.RAD50	/SP    /
	177706
	.RAD50	/PC    /
	177707
	.RAD50	/PS    /
	177776

	.PSECT	$SYM.,D
	.REPT	D.SYMU		; For user defined symbols.
	0,0,-1
	.ENDR
	-1,-1			; End of DDT symbol table.
	.SBTTL	DDT	- DDT Initialization

	.PSECT	$ABS$,I
DDT:
.IF DF D.MCB
	MOV	@#KISAR5,D.DAR6
	ADD	#200,D.DAR6
	MAP$	@#KISAR5
	MOV	.CRPIX,NEWEXV+2
	MOV	#M.PRIM,NEWEXV+0
	CALL$C	#$EXVEN,<#0,#NEWEXV+20000,#EXVPRI+20000>
	MOV	#M.LAST,NEWEXV+0
	CALL$C	#$EXVEN,<#2,#NEWEXV+20000,#EXVLST+20000>
	MAP$	D.DAR6
	CALL	M.TTON
	TST	@#0
	BNE	10$
	MOV	#$NONSI,@#0
	PUSH$S	<(SP),@#14>
	MFPS	4(SP)
	MTPS	@#16
	MOV	MTTBK,R1
	INC	MT.INT(R1)
	BIS	#20,4(SP)
10$:	MOV	#D.HELO,R1
	JMP	D.STYP
.IFF
	BR	10$		; HARD ENTRY ADDRESS TO DDT
.IF DF D.RSX
	ALUN$S	#LUNTI,#"TI,#0	;TIRED OF TYPING THIS TO TKB
	CLR	D.UPS		;I DON'T THINK THIS IS NECESSARY.
.IFF
	MFPS	D.UPS		; GET USER'S STATUS
.IFTF
	POP$S	D.UR7		; SOFT ENTRY ASSUMES STACK HAS RETURN ADDRESS
	CALL	D.SAVE		; SAVE REGISTERS
	BR	D.DDT2		; FINISH INITIALIZATION
10$:
.IFF
.IF NDF D.LSI
	MFPS	D.UPS		; SAVE USER'S STATUS
.ENDC
.ENDC
.IF DF D.LSI
	HALT			; HALT TO ALLOW TYPEOUT
	MFPS	D.UPS		; GET USER'S STATUS
.ENDC
	CMP	#400,SP		;IS STACK REASONABLE?
	BLO	20$		;YES, SEE IF ITS ADDRESSABLE
	MOV	#D.STK,SP	;NOPE, USE OURS THEN
20$:	MOV	#D.NOSP,@#4	; SET FOR INVALID STACK INTERRUPT
	MOV	#340,@#6	; SET HIGH STATUS
	MOV	#D.ILGT,@#10	; SET FOR ILLEGAL INSTRUCTIONS
	MOV	#340,@#12	; SET HIGH STATUS
	MOV	SP,D.XXX	; SAVE HIS STACK
	MOV	#D.STK,SP	; USE OURS TEMPORARILY
	TST	@D.XXX		; DOES HIS STACK EXIST?
	MOV	D.XXX,SP	; GIVE HIM BACK HIS STACK
D.FIX:	MOV	#D.NXMT,@#4	; RESTORE FOR EXTERNAL NXMS
	MOV	JOBSA,D.UR7	; ASSUME HE CAME FROM STARTING ADDRESS
	CALL	D.SAVE		; SAVE REGISTERS
.IF DF D.GDP
	MOV	#DDT+2,R0	; ADDRESS OF RESTART FOR MONITOR
	TRAP	133		; DDTCAL
.ENDC
	CLRB	D.NOTY		; ALLOW TYPEOUT
	MOV	#D.GRET,R1	; TELL YOU ARE HERE
	CALL	D.STYP		; TYPE MESSAGE
.IF NDF D.GDP
	MOV	#DDT,R0		; ADDRESS OF RESTART
	CALL	D.TYPN		; TYPE RESTART ADDRESS
.ENDC
D.DDT2:	CALL	D.CRLF		; TYPE CARRIAGE RETURN-LINE FEED
	CLR	D.SD.T		; NOT IN SINGLE STEP OR TRACE
	MOVB	#-1,D.P		; DISALLOW PROCEDE
	BR	D.DCD		; GET INTO MAIN LOOP
D.NOSP:	MOV	#D.STK,SP	; SET OWN STACK PERMANENTLY FOR USER
	BR	D.FIX		; RETURN
.ENDC
	.SBTTL	D.DCD	- Decode User Command
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.COLN
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.DCD:	CLR	D.COMA		; NO , PARAMETER.  RETURN FROM <CR>HCTSAR>
	CLRB	D.FWAF		; NO < PARAMETER
.IF NDF D.RSX
	MTPS	#D.PRIO		; SET DDT STATUS
.ENDC
	MOV	#NOP,D.PARS	; FILL $X AREA WITH NOPS
	CLR	D.PARO		; NO OFFSET
	CLR	D.PARO+2	; NO OFFSET
D.DCD2:	CLR	D.SVR2		; RETURN FROM ,<
	CLR	D.SVR4		; D.SVR4 IS A SAVE REGISTER FOR R4
	CLR	D.OFST		; TALLY
	CLR	R2		; NUMBER TYPED FLAG
D.DCD3:	CLRB	D.ALTF		; RETURN FROM B"MVQI
D.DCD1:	CLRB	D.LEVL		; RETURN FROM $
	CLRB	D.INPA		; NOT IN INSTRUCTION TYPE-IN
	MOV	D.CAD,D.CADC	; KEEP A CURRENT COPY FOR INST TYPE-IN
	MOV	D.DR6,SP	; RESET STACK POINTER
	CALL	D.EXPR		; GET EXPRESSION (R2,R4,R1)
	TST	R2		; NEED OPERANDS FOR INSTRUCTION?
	BPL	50$		; BRANCH IF NOT
	CALL	D.GETI		; GET OPERANDS
50$:	TST	R2		; ANY VALUE TYPED?
	BEQ	60$		; BRANCH IF NOT
	MOV	R4,D.LASV	; STORE LAST TYPED VALUE
	MOV	R4,D.LASW	; STORE LAST TYPED WORD TOO
60$:	ASL	R1		; MULTIPLY BY TWO
	CALL	@D.LGDR(R1)	; GO TO PROPER ROUTINE
	CALL	D.TTAB		; TYPE TAB
	BR	D.DCD		; GET NEXT COMMAND

D.ERR:	MOV	#' ,R0		; TYPE A SPACE
	CALL	D.TYPE
	MOV	#'?,R0		; ? TO BE TYPED
	CALL	D.TYPE		; TYPE CHARACTER
	CALL	D.TTAB		; TYPE TAB
	BR	D.DCD
	.SBTTL	D.PRIM	- Get a Primary
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.PRIM
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.PRIM:	CLR	R4		; R4 CONTAINS THE CONVERTED OCTAL
	CLR	D.DECN		; CLEAR DECIMAL NUMBER
	CLRB	D.USED		; CLEAR USE-DECIMAL NUMBER INDICATOR
	CALL	D.CLSM		; CLEAR SYMBOL
10$:	CALL	D.GET		; GET A CHAR, RETURN IN R0
	CMP	#'0,R0		; COMPARE WITH ASCII 0
	BHI	30$		; CHECK LEGALITY IF NON-NUMERIC
	CMP	#'9,R0		; COMPARE WITH ASCII 9
	BLO	30$		; CHECK LEGALITY IF NOT OCTAL
	CMP	D.POS,#D.SYM	; IN THE MIDDLE OF A SYMBOL?
	BNE	50$		; YES, PUT DIGIT IN SYMBOL
	SUB	#'0,R0		; CONVERT TO BCD
.IF DF D.MCB
	ASH	#3,R4
.IFF
	ASL	R4		; MAKE ROOM
	ASL	R4		;  IN
	ASL	R4		;    R4
.IFTF
	ADD	R0,R4		; PACK THREE BITS IN R4
	MOV	D.DECN,R1	; GET DECIMAL NUMBER
.IFT
	MUL	#10.,R1		; MULTIPLY BY 10
.IFF
	ASL	R1		; MULTIPLY BY 2
	ADD	R1,R0		; ADD 2X
	ASL	R1		; MULTIPLY BY 4
	ASL	R1		; MULTIPLY BY 8
.ENDC
	ADD	R0,R1		; ADD IN NEW DIGIT
	MOV	R1,D.DECN	; STORE IN DECIMAL NUMBER
	INC	R2		; R2 HAS NUMERIC FLAG
	BR	10$		;   AND TRY AGAIN
20$:	MOV	#'U,R0		; UNDEFINED MESSAGE
	CALL	D.TYPE		; DISPLAY IT
	CALL	D.TTAB		; TYPE TAB
	BR	D.DCD		; PROCESS NEW COMMAND
30$:	CMPB	R0,#'.		; DOT FOUND?
	BEQ	60$		; BRANCH IF SO
	CLR	R1		; BASE OF CHARACTER TABLE
40$:	CMPB	D.LGCH(R1),R0	; MATCH?
	BEQ	70$		; YES
	INC	R1		; NEXT CHARACTER
	CMP	R1,#D.CLGT	; ANY MORE?
	BLT	40$		; LOOP IF SO
50$:	TST	R4		; NUMBER ALREADY?
	BNE	D.ERR		; ERROR TO START SYMBOL
	CALL	D.PTSM		; PUT SYMBOL IN D.SYM
	BR	10$		; DECODE MORE CHARACTERS
60$:	TST	R2		; NUMBER BEING TYPED?
	BEQ	50$		; BRANCH IF NOT
	INCB	D.USED		; IT IS, MAKE IT DECIMAL
	BR	10$		; CONTINUE SCANNING
70$:	TSTB	D.ALTF		; ALTMODE FOUND?
	BNE	80$		; YES, DO IT
	CMP	R1,#D.LETR	; IS IT A LETTER?
	BGE	50$		; YES
80$:	CMPB	#' ,D.SYM	; ANY SYMBOL?
	BEQ	110$		; NO, RETURN
	CMP	#". ,D.SYM	; IS SYMBOL A DOT?
	BNE	90$		; BRANCH IF NOT
	MOV	D.DOT,R4	; USE VALUE OF D.DOT
	INC	R2		; NOTE THAT IT IS A NUMBER
	BR	110$		; DO THE REST
90$:	MOV	#D.SYM,R0	; ADDRESS OF SYMBOL
	CALL	D.GTAD		; GET ADDRESS
	CMP	R1,#D.COLO	; COLON?
	BEQ	120$		; RETURN IF SO
	TST	R0		; CHECK SYMBOL ADDRESS
	BEQ	130$		; BRANCH IF NOT AN ADDRESS
	MOV	(R0),R4		; GET SYMBOL VALUE
100$:	INC	R2		; MARK R2 AS A NUMBER
110$:	TSTB	D.USED		; USE DECIMAL NUMBER?
	BEQ	120$		; BRANCH IF NOT
	MOV	D.DECN,R4	; USE DECIMAL NUMBER
120$:	RETURN			; RETURN
130$:	MOV	#D.COUS,R0	; ADDRESS OF OFFSET TABLE
140$:	CMP	R0,#D.ECNT	; END OF LIST?
	BHIS	20$		; YES, LOSE
	MOV	#D.SYM,R5	; SCAN THE SYMBOL
	MOV	(R0)+,R3	; GET OFFSET OF CHARACTERS
	BIC	#^C377,R3	; TURN OFF EXTRA CRUFT
	CMPB	R3,(R0)		; NULL STRING?
	BEQ	140$		; YES, IGNORE IT
150$:	CMPB	D.STRS(R3),(R5)+; IS IT A CHARACTER MATCH?
	BNE	140$		; BRANCH IF NOT
	INC	R3		; NEXT CHARACTER
	CMPB	R3,(R0)		; END OF STRING?
	BNE	150$		; BRANCH IF NOT
	MOV	D.TOPS-D.COUS-2(R0),R4	;GET THE INSTRUCTION-1
	MOVB	-1(R0),R3	; GET LEGALITY BYTE
	CMPB	R3,#10		; IS IT A CONDITION CODE SET/CLEAR?
	BEQ	200$		; MAY BE
	INC	R4		; FIX INSTRUCTION
160$:	CMPB	#' ,(R5)	; BLANK AT END OF SYMBOL?
	BNE	180$		; NO, HOW ABOUT "B"?
	BIC	#^C3,R3		; STRIP TO MACHINE TYPE
	CMPB	R3,D.MACH	; VALID ON THIS MACHINE?
	BGT	20$		; UNDEFINED SYMBOL
170$:	MOVB	-(R0),R3	; RE-FETCH LEGALITY BYTE
	CMP	R1,#D.SPAC	; IS INSTRUCTION TERMINATED WITH SPACE?
	BNE	100$		; DON'T GET OPERANDS IF NOT
	MOV	#-2,R2		; MARK INSTRUCTION
	BR	100$		; ALL DONE
180$:	CMPB	#'B,(R5)+	; BYTE INSTRUCTION MUST TERMINATE WITH "B"
	BNE	140$		; NOT AN INSTRUCTION
	TSTB	R3		; TEST LEGALITY BYTE
	BPL	140$		; NO
	ADD	#100000,R4	; ADD IN BYTE OFFSET
	BCC	160$		; AND CONTINUE, UNLESS THAT WAS A SECOND "B"
	BR	140$		; IN WHICH CASE WE LOSE

190$:	BITB	(SP),R4		; BIT ALREADY ON?
	BNE	220$		; YES, LOSE
	BISB	(SP),R4		; SET IT
	CMPB	(SP)+,(R5)+	; BUMP SP BY 2, R5 BY 1
	CMPB	#' ,(R5)	; SPACE YET?
	BEQ	170$		; YES, ALL DONE.
200$:	PUSH$S	#10		; SET UP MAGIC BIT
	MOV	#D.NZVC+4,R3	; CHARACTER POINTER
210$:	CMPB	(R5),-(R3)	; MATCH?
	BEQ	190$		; BRANCH IF SO
	ASRB	(SP)		; MOVE BIT
	BNE	210$		; AND LOOP
220$:	POP$S	,1
	BR	140$		; ELSE NOT THE RIGHT INSTRUCTION
; ROUTINE TO GET AN EXPRESSION (VALUE IN R4, FLAG IN R2, TERMINATOR IN R1)

D.CEXP:	INCB	D.INPA		; NOT IN INSTRUCTION
	CLR	D.OFST		; START OUT FRESH
D.EXPR:	MOV	#D.ADD,D.OPER	; INITIAL FUNCTION
10$:	CALL	D.PRIM		; GET PRIMARY EXPRESSION
	TST	R2		; INSTRUCTION?
	BMI	20$		; EXIT IF SO
	CMP	R1,#D.OPAR	; OPEN PARENTHESIS OR OPERATOR?
	BLT	20$		; BRANCH IF NEITHER
	BEQ	30$		; BRANCH IF OPEN PARENTHESIS
	CMP	R1,#D.CPAR	; CLOSE PARENTHESIS OR OPERATOR?
	BLT	60$		; BRANCH IF OPERATOR
	BEQ	40$		; BRANCH IF CLOSE PARENTHESIS
20$:	TSTB	D.LEVL		; TERMINATOR FOUND...AT UPPER LEVEL?
	BEQ	50$		; BRANCH IF SO
	JMP	D.ERR		; ERROR
30$:	TSTB	D.INPA		; IN AN INSTRUCTION TYPE-IN?
	BNE	50$		; BRANCH IF SO (INSTRUCTION FORMAT)
	INCB	D.LEVL		; GO DOWN TO NEXT PARENTHESIS LEVEL
	PUSH$S	<D.OFST,D.OPER>	; SAVE TALLY AND OPERATION
	CLR	D.OFST		; CLEAR TALLY
	CALL	D.EXPR		; RECURSION!
	POP$S	<D.OPER,D.OFST>	; RESTORE OPERATION and TALLY
	CALL	@D.OPER		; COMBINE THEM
	BR	D.EXPR		; LOOP
40$:	DECB	D.LEVL		; UP TO HIGHER PARENTHESIS LEVEL
	BMI	70$		; ERROR IF NONE HIGHER
50$:	CALL	@D.OPER		; DO OPERATION
	MOV	D.OFST,R4	; GET TALLY AS RETURN PARAMETER
	RETURN			; RETURN (POSSIBLY TO SELF)
60$:	CALL	@D.OPER		; DO OPERATION
	ASL	R1		; AND GET
	MOV	D.LGDR(R1),D.OPER ;   THE NEXT
	BR	10$		; LOOP
70$:	JMP	D.ERR		; ERROR

D.GTAD:	PUSH$S	R0		; SAVE CHARACTER ADDRESS
	CALL	D.RD50		; CONVERT FIRST 3 TO RAD50
	MOV	R0,D.RAD1	; SAVE VALUE
	POP$S	R0		; GET CHARACTER ADDRESS
	ADD	#3,R0		; POINT TO LAST 3 CHARACTERS
	CALL	D.RD50		; CONVERT TO RAD50
	MOV	R0,D.RAD2	; STORE IT AWAY
	JMP	D.GTAC
; ROUTINE TO HANDLE PARAMETERS FOR INSTRUCTION TYPE-IN

D.GETI:	ASR	R3		; PARAMETER CODE
	BIC	#^C<17*2>,R3	; MASK OUT OTHER BITS
	PUSH$S	R4		; SAVE OPERATION MASK
	CALL	@D.PARG(R3)	; GET PARAMETERS
	BIS	(SP)+,R4	; PUT OPERATION MASK INTO OPERANDS
	MOV	#1,R2		; MARK A GOOD NUMBER
	RETURN			; RETURN

D.NONE:	RETURN			; RETURN

D.DISP:	CALL	D.CEXP		; GET EXPRESSION
	SUB	D.DOT,R4	; COMPUTE OFFSET
	ASR	R4		; SHIFT
	DEC	R4		; POINTS TO PROPER WORD
	BIC	#^C377,R4	; CLEAR HIGH BITS
	RETURN			; RETURN

D.GRSS:	CALL	D.GR		; GET REGISTER
	CALL	D.PSAV		; SAVE PARAMETER
	CALL	D.GDD		; GET OTHER PARAMETER
	BIS	(SP)+,R4	; ADD IN REGISTER
	RETURN			; RETURN

D.GNUM:	JMP	D.PRIM		; GET NUMBER AND RETURN

D.GSD:	CALL	D.GDD		; GET 6-BIT OPERAND
	CALL	D.PSAV		; SAVE PARAMETER
	CALL	D.GDD		; GET OTHER PARAMETER
	BIS	(SP)+,R4	; ADD IN REGISTER
	RETURN			; RETURN

D.GR:	CALL	D.PRIM		; GET PRIMARY
	CALL	D.RCHK
	BCS	10$
	RETURN
10$:	JMP	D.ERR		; ERROR

D.GRNN:	CALL	D.GR		; GET REGISTER
	CALL	D.PSAV		; SAVE PARAMETERS
	CALL	D.DISP		; GET ADDRESS
	BIC	#^C77,R4	; REDUCE TO 6-BITS
	BIS	(SP)+,R4	; ADD IN REGISTER
	RETURN			; RETURN

D.GDD:	CLR	R2		; NO PARAMETERS YET
	CALL	D.CEXP		; GET EXPRESSION
	CMP	R1,#D.OPAR	; OPEN PARENTHESIS?
	BEQ	30$		; BRANCH IF SO
	CMP	R1,#D.HASH	; HASH MARK?
	BEQ	10$		; BRANCH IF SO
	BLO	60$		; BRANCH IF AT-SIGN
	CALL	D.RCHK
	BCS	D.NOTR
	RETURN

10$:	CALL	D.CEXP		; GET EXPRESSION
20$:	CALL	D.NEXP		; NEXT PARAMETER
	SUB	D.CAD,R0	; GET PARAMETER OFFSET
	CLR	D.PARO-4(R0)	; NO RELOCATION
	MOV	R4,D.PARS-4(R0)	; PUT VALUE IN
	MOV	#27,R4		; IMMEDIATE ADDRESSING
	RETURN			; RETURN
30$:	TST	R2		; "(" FOUND, ANY OFFSET?
	BNE	50$		; BRANCH IF SO (INDEX ADDRESSING)
	CMP	D.OPER,#D.SUBT	; "-(R)" ?
	BNE	40$		; BRANCH IF NOT
	CALL	D.GR		; GET REGISTER
	ADD	#40,R4		; ADD IN AUTO-DECR OFFSET
	BR	100$		; SKIP TO COMMAND AND RETURN
40$:	CALL	D.GR		; GET REGISTER..."(R)" OR "(R)+"
	CALL	100$		; SKIP TO NEXT PARAMETER
	CMP	R1,#D.ADDS	; PLUS SIGN?
	BNE	70$		; BRANCH IF NOT
	ADD	#20,R4		; ADD IN AUTO-INCR OFFSET
	BR	100$		; SKIP TO COMMAND AND RETURN
50$:	CALL	20$		; PUT PARAMETER IN
	CALL	D.GR		; GET REGISTER
	ADD	#60,R4		; ADD IN INDEX OFFSET
	BR	100$		; SKIP TO COMMAND AND RETURN
60$:	CLR	R2		; "@" FOUND, MARK NO NUMBER FOUND YET
	CALL	D.CEXP		; AN "@" WAS FOUND, LOOK TO NEXT
	CMP	R1,#D.HASH	; "@#" MEANS ABSOLUTE ADDRESSING
	BEQ	130$		; BRANCH IF SO
	CMP	R1,#D.OPAR	; COULD BE "@(" OR "@X("
	BEQ	90$		; BRANCH IF EITHER
	CALL	D.RCHK
	BCS	80$
70$:	ADD	#10,R4		; ADD IN REG-DEFERRED OFFSET
	RETURN			; THATS ALL...RETURN
80$:	CALL	D.NOTR		; PERFORM NORMAL RELOCATION
	MOV	#77,R4		; MARK RELATIVE DEFERRED ADDRESSING
	RETURN			; RETURN
90$:	TST	R2		; ANY NUMBER THERE?
	BEQ	110$		; BRANCH IF "@("
	CALL	20$		; GET OFFSET INTO PARAMETER
	CALL	D.GR		; NOW GET REGISTER
	ADD	#70,R4		; ADD IN INDEX DEFERRED OFFSET
100$:	PUSH$S	R4		; SAVE VALUE
	CALL	D.PRIM		; SKIP TO NEXT COMMAND
	POP$S	R4		; RESTORE VALUE
	RETURN			; RETURN
110$:	CMP	D.OPER,#D.SUBT	; "@-(" ?
	BNE	120$		; BRANCH IF NOT
	CALL	D.GR		; GET REGISTER
	ADD	#50,R4		; ADD IN AUTO-DECR DEFERRED OFFSET
	BR	100$		; SKIP TO COMMAND AND RETURN
120$:	CALL	D.GR		; GET REGISTER
	MOV	#'+,R0		; FORM IS "@(R)+"
	CALL	D.GGET		; GET THE PLUS
	ADD	#30,R4		; ADD IN AUTO-INCR DEFERRED OFFSET
	BR	100$		; SKIP TO COMMAND AND RETURN
130$:	CALL	10$		; GET ABSOLUTE ADDRESS
	MOV	#37,R4		; MARK ABSOLUTE MODE
	RETURN			; DONE

D.NOTR:	CALL	D.NEXP		; POINT TO NEXT PARAMETER
	PUSH$S	R0		; SAVE RELOCATION
	SUB	D.CAD,R0	; GET PARAMETER OFFSET
	POP$S	D.PARO-4(R0)	; PUT IN OFFSET
	MOV	R4,D.PARS-4(R0)	; PUT VALUE IN
	MOV	#67,R4		; RELATIVE PC ADDRESSING
	RETURN			; DONE

D.GDDR:	CALL	D.GDD		; GET 6-BIT-OPERAND
	PUSH$S	R4		; SAVE OPERAND
	CALL	D.GR		; GET REGISTER
	SWAB	R4		; SHIFT
	ASR	R4		;  INTO
	ASR	R4		;   HIGH PLACE
	BIS	(SP)+,R4	; ADD IN REGISTER
	RETURN			; RETURN

D.GGET:	PUSH$S	R0		; SAVE WHAT MUST BE READ
	CALL	D.GET		; GET LETTER
	CMP	R0,(SP)		; EQUAL?
	BNE	10$		; YES, RETURN
	POP$S	,1		; FIX STACK
	RETURN			; RETURN
10$:	JMP	D.ERR		; ERROR

D.PSAV:	PUSH$S	(SP)		; PUSH RETURN ADDRESS DOWN
	SWAB	R4		; MOVE
	ASR	R4		;  TO
	ASR	R4		;   HIGH POSITION
	MOV	R4,2(SP)	; PUT PARAMETERS IN
	CMP	R1,#D.COMM	; COMMA IN-BETWEEN?
	BNE	10$		; ERROR IF NOT
	RETURN			; RETURN
10$:	JMP	D.ERR		; ERROR

D.RCHK:	CMP	R4,#177700
	BLO	90$
	CMP	#177707,R4
	BLO	90$
	SUB	#177700,R4
	CLC
90$:	RETURN

D.NEXP:	MOV	D.CADC,R0	; GET CAD COPY
	ADD	#2,R0		; BUMP TO NEXT
	MOV	R0,D.CADC	; RESTORE NEW VALUE
	ADD	#2,R0		; INCREMENT AGAIN
	RETURN			; RETURN
; SYMBOL MANIPULATION SUBROUTINES

D.PTSM:	MOV	D.POS,R1	; GET POSITION ADDRESS
	CMP	R1,#D.SYM+D.SYML; NO MORE ROOM?
	BHIS	10$		; EXIT IF SO
	MOVB	R0,(R1)+	; PUT CHARACTER IN
	MOV	R1,D.POS	; RESTORE POINTER
10$:	RETURN			; RETURN

D.CLSM:	MOV	#D.SYM+D.SYML,R0
D.CLS3:	MOVB	#' ,-(R0)
	CMP	R0,#D.SYM
	BHI	D.CLS3
	MOV	R0,D.POS
	RETURN			; RETURN

; ADDITION, SUBTRACTION, MULTIPLICATION, DIVISION FOR DECODER

D.ADD:	ADD	R4,D.OFST	; ADD OPERANDS
	RETURN			; RETURN
D.SUBT:	SUB	R4,D.OFST	; SUBTRACT OPERANDS
	RETURN			; RETURN
D.MULT:
.IF DF D.MCB
	PUSH$S	R1
	MOV	D.OFST,R1
	MUL	R4,R1
	MOV	R1,D.OFST
	POP$S	R1
.IFF
	CLR	R0		; MULTIPLY THEM
	PUSH$S	#16.		; LOOPER
10$:	ASR	R4		; GET BOTTOM BIT
	BCC	20$		; SKIP IF OFF
	ADD	D.OFST,R0	; ADD IN OPERAND
20$:	ASL	D.OFST		; SHIFT OPERAND
	DEC	(SP)		; MORE TO LOOP?
	BGT	10$		; LOOP IF SO
	MOV	R0,D.OFST	; RESULT IN D.OFST
	POP$S	,1		; FIX STACK
.IFTF
	RETURN			; RETURN
D.DIV:	PUSH$S	R1		; SAVE R1
.IFT
	MOV	D.OFST,R1	; GET OPERAND
	SXT	R0
	DIV	R4,R0
.IFF
	MOV	D.OFST,R0	; GET OPERAND
	MOV	R4,R2		; GET OTHER OPERAND
	CALL	D.DIVD		; DIVIDE THEM
.ENDC
	MOV	R0,D.OFST	; GET RESULT
	POP$S	R1		; RESTORE R1
	RETURN			; RETURN
	.SBTTL	D.COLN	- Define symbol
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.COLN
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.COLN:	CMPB	D.SYM,#' 	; NULL SYMBOL?
	BEQ	40$		; ERROR IF SO
	MOV	D.DOT,R4	; ASSUME DOT ADDRESS
	TSTB	D.FWAF		; REAL VALUE GIVEN?
	BEQ	10$		; BRANCH IF NOT
	MOV	D.FWA,R4	; GET REAL VALUE
10$:	TST	R0		; IN SYMBOL TABLE?
	BNE	20$		; BRANCH IF SO
	PUSH$S	<D.RAD1,D.RAD2>	; SAVE RAD50 OF NAME
	CLR	D.RAD1		; ASSUME NULL RAD50 LABEL
	CLR	D.RAD2		; IN BOTH HALVES
	CALL	D.GTAC		; LOOK IT UP
	TST	R0		; FOUND?
	BEQ	40$		; ERROR IF NOT
	POP$S	<-(R0),-(R0)>	; FILL LABEL IN BY SETTING BOTH WORDS
	CMP	(R0)+,(R0)+	; NOW FIX POSITION
20$:	MOV	R4,(R0)		; AND SET VALUE
	MOV	R0,D.LASC	; SET LAST COLONED WORD
	MOV	D.FENC,R1	; GET FENCE
	CMP	R0,R1		; BEHIND FENCE?
	BHI	30$		; DONE IF NOT
	CALL	D.SWAP		; SWAP SYMBOLS
	MOV	R1,D.FENC	; STORE IN FENCE
30$:	RETURN			; RETURN
40$:	JMP	D.ERR		; ERROR
	.SBTTL	D.KILL	- Kill symbol
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.KILL
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.KILL:	MOV	D.LASC,R0	; Get last coloned symbol
	BEQ	10$		; (if there is one)
	EXTEND
	CMPB	#' ,D.SYM	; and if no symbol specified
	BEQ	12$		; then
10$:	CALL	D.GTAC		; GET ADDRESS OF SYMBOL
	TST	R0		; ANY SYMBOL?
	BNE	100$		; If not,
12$:	CMPB	D.ALTF,#1	; HOW MANY ALTMODES?
	BGT	20$		; BRANCH IF 2
	MOV	D.FENC,R1	; GET FENCE
	CMP	R0,R1		; SYMBOL BEHIND FENCE?
	BLO	90$		; BRANCH IF ALREADY KILLED
	ADD	#6,R1		; PUSH UP FENCE
	MOV	R1,D.FENC	; AND STORE IT
	JMP	D.SWAP		; SWAP SYMBOLS AND RETURN
20$:	CLR	(R0)		; CLEAR ADDRESS
	CLR	-(R0)		; PUT IN NULL SYMBOL
	CLR	-(R0)		; IN BOTH WORDS
90$:	RETURN			; RETURN

100$:	JMP	D.ERR		; ERROR
; ROUTINES TO HANDLE THE SYMBOL TABLE

D.GTAC:	EXTEND
	MOV	#S.SMDT,R0	; ADDRESS OF SYMBOL TABLE
	CALL	110$		; Check for symbol
	BCC	90$		; and if not found
	CLR	R0		; then return failure indication.
90$:	RETURN

100$:	CMP	#-1,(R0)+
	BEQ	120$
	TST	(R0)+
110$:	CMP	D.RAD1,(R0)+	; YES, HOW ABOUT THE FIRST THREE?
	BNE	100$		; NO, GO TO NEXT SYMBOL
	CMP	D.RAD2,(R0)	; DO SECOND THREE CHARACTERS MATCH?
	BNE	100$		; NO, GO TO NEXT SYMBOL
	TST	(R0)+
	RETURN
120$:	SEC
	RETURN

D.GTSM:	MOV	D.FENC,R2	; FIND CLOSEST SYMBOL <= R0
	MOV	D.RFNL,R1	; WHICH IS ALSO >= R0-D.RFNL
D.GTSS:	EXTEND
	PUSH$S	#0		; SPACE FOR TEMPORARIES
	BR	30$
10$:	TST	(R2)+		; Bypass symbol value
	BR	30$		; and go on to next.
20$:	SUB	(R2)+,R3	; OBTAIN DIFERENCE
	BLO	30$		; IF SYMBOL HIGHER THAN R0, NO GO
	SUB	R1,R3		; ARE WE CLOSER THAN BEFORE?
	BHI	30$		; NO, FURTHER
	MOV	R2,(SP)		; SAVE POINTER TO SYMBOL
	ADD	R3,R1		; SAVE DIFFERENCE
30$:	MOV	R0,R3		; SET A TEMPORARY
	CMP	(R2)+,(R2)+	; SKIP OVER THE NAME
	BNE	20$		; AND LOOK FOR ONE CLOSER
	TST	-4(R2)		; If an undefined symbol
	BEQ	10$		; then skip over.
	CMP	#-1,-4(R2)	; AT END OF TABLE?
	BNE	20$		; NO, KEEP GOING
	POP$S	R1		; GET SYMBOL PTR
	BEQ	90$		; BRANCH IF NOT FOUND.
	CMP	#400,-(R1)	; IGNORE SMALL SYMBOLS
	BLO	70$
	CMP	D.FENC,R1
	BLO	90$
70$:	SUB	(R1),R0		; RECOMPUTE DIFFERENCE
	PUSH$S	<R0,-(R1)>	; AND SAVE IT AND LAST THREE CHARACTERS
	MOV	-(R1),R0	; GET FIRST THREE
	MOV	#D.SYM,R1	; ADDRESS TO PUT CHARACTERS
	CALL	D.CHAR		; CONVERT TO ASCII
	POP$S	R0		; GET FIRST RAD50 WORD
	CALL	D.CHAR		; CONVERT TO ASCII
80$:	CMPB	#' ,-(R1)
	BEQ	80$
	CLRB	1(R1)
	MOV	#D.SYM,R1
	POP$S	R0		; RESTORE DIFFERENCE
	RETURN			; RETURN

90$:	CLR	R1		; NOT FOUND...MARK IT SO
	RETURN			; RETURN

; MANIPULATION OF THE SYMBOL TABLE
D.SWAP:	MOV	#3,R2		; COUNTER
10$:	PUSH$S	-(R1)		; GET WORD
	MOV	(R0),(R1)	; PUT OTHER WORD IN
	POP$S	(R0)		; AND FINISH SWAP
	TST	-(R0)		; MOVE WORD
	SOB	R2,10$		; LOOP IF MORE
	RETURN			; RETURN
	.SBTTL	D.ALTM	- Process altmode
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.ALTM
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.ALTM:	TSTB	D.ALTF		; ALREADY AN ALTMODE TYPED?
	BNE	10$		; BRANCH IF SO
	MOV	R2,D.SVR2	; AN ALTMODE HAS BEEN RECEIVED
	MOV	R4,D.SVR4	; NUMERIC FLAG TO D.SVR2, CONTENTS TO D.SVR4
10$:	CLR	R2		; NO ARGS TYPED YET
	CLR	D.OFST		; CLEAR OFFSET
	INCB	D.ALTF		; COUNT NUMBER OF ALTMODES
	JMP	D.DCD1		; RETURN
	.SBTTL	D.BYT	- Open byte
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.BYT
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.BYT:	CALL	D.SBYT		; Set for byte display.
	MOV	D.CURM,D.OMOD	; TEMP COPY OF ROUTINE ADDRESS
	BR	D.OPNW		; OPEN WORD
	.SBTTL	D.SBYT	- Set for Byte Display
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.SBYT
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.SBYT:	MOV	#1,D.BW		; Set byte mode
	MOVB	#'\,D.CDSP
	RETURN
	.SBTTL	D.WRD	- Open word
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.WRD
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.WRD:	CALL	D.SWRD		; Set for word display.
	MOV	D.CURM,D.OMOD	; TEMP COPY OF ROUTINE ADDRESS
	BR	D.OPNW		; OPEN WORD
	.SBTTL	D.SWRD	- Set for Word Display
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.SWRD
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.SWRD:	MOV	#2,D.BW		; Set fullword mode.
	MOVB	#'/,D.CDSP
	RETURN
	.SBTTL	D.OPNW	- Open word
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.OPNW
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.OPNW:	TST	R2		; NUMBER THERE?
	BEQ	10$		; IF NOT,
	MOV	R4,D.DOT	; SET DOT
	BR	20$
10$:	MOV	D.LASV,R4	; GET LAST ADDRESS
20$:	MOV	R4,D.CAD	; SET CURRENT ADDRESS
	JMP	@D.OMOD		; TYPE WORD AND RETURN
	.SBTTL	D.SEMI	- Retype word
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.SEMI
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.SEMI:	JMP	@D.OMOD		; TYPE WORD AND RETURN
	.SBTTL	D.ORAB	- Open indirect
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.ORAB
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.ORAB:	CALL	D.CLSE		; CLOSE WORD
	MOV	D.LASV,D.DOT	; INDIRECT REFERENCE
	BR	D.OP2		; OPEN IT AND RETURN
	.SBTTL	D.EXCL	- Open word silently
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.EXCL
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.EXCL:	MOV	#D.RTS,D.OMOD	; NULL ROUTINE FOR TYPING
	BR	D.OPNW		; OPEN WORD
	.SBTTL	D.OPNX	- Open next word
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.OPNX
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.OPNX:	CALL	D.CLSE		; CLOSE WORD
	CMP	D.DOT,#177700
	BLO	10$
	CMP	D.DOT,#177707
	BHI	10$
	INC	D.DOT
	BR	D.OP2
10$:	ADD	D.BW,D.DOT	; ADD IN BYTE/WORD INCREMENT
	ADD	D.LFIN,D.DOT	; ADD IN LINE-FEED INCREMENT
D.OP2:	CALL	D.CRLF		; TYPE CRLF
D.OP3:	MOV	D.DOT,R0	; GET WORD
	CALL	D.RFND		; TYPE ADDRESS
	MOVB	D.CDSP,R0	; SLASH
	CALL	D.TYPE		; TYPE IT
	MOV	D.DOT,D.CAD	; SET CURRENT ADDRESS
	JMP	@D.OMOD		; TYPE WORD AND RETURN
	.SBTTL	D.OPBR	- Open word as numeric
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.OPBR
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.OPBR:	CALL	D.SWRD		; Set word mode.
	MOV	#D.CADV,D.OMOD	; NUMBER ROUTINE
	BR	D.OPNW		; DO ROUTINE
	.SBTTL	D.CLBR	- Open word as instruction
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.CLBR
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.CLBR:	CALL	D.SWRD		; Set word display.
	MOV	#D.INST,D.OMOD	; INSTRUCTION ROUTINE
	BR	D.OPNW		; DO IT
	.SBTTL	D.BACK	- Open previous word
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.BACK
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.BACK:	CALL	D.CLSE		; CLOSE WORD
	CMP	D.DOT,#177700
	BLO	10$
	CMP	D.DOT,#177710
	BLOS	20$
10$:	SUB	D.BW,D.DOT	; SUBTRACT BYTE/WORD INCREMENT
	BR	D.OP2		; OPEN WORD
20$:	DEC	D.DOT		; Back up a register
	BR	D.OP2		; and open it.
	.SBTTL	D.ORPC	- Type word symbolically
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.ORPC
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.ORPC:	CLR	D.LFIN		; NO LINE-FEED INCREMENT
	TSTB	D.ALTF		; IS IT AN $_ ?
	BEQ	10$		; BRANCH IF NOT
	MOV	D.LASW,R0	; GET LAST TYPED WORD
	JMP	D.RFND		; TYPE SYMBOLICALLY AND RETURN
10$:	JMP	D.INST		; TYPE INSTRUCTION AND RETURN
	.SBTTL	D.EQAL	- Type word as number
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.EQAL
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.EQAL:	MOV	D.LASW,R0	; GET LAST TYPED WORD
	CLR	D.LFIN		; NO LINE-FEED INCREMENT
	JMP	D.TYPN		; TYPE AS A NUMBER
	.SBTTL	D.DCOM	- Comma parameter
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.DCOM
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.DCOM:	TST	R2		; ANY PARAMETER?
	BEQ	10$		; BRANCH IF NOT
	MOV	R4,D.COMA	; PUT IN PARAMETER AREA
10$:	JMP	D.DCD2		; RETURN
	.SBTTL	D.FWAS	- Store first word address for search
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.FWAS
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.FWAS:	TSTB	D.ALTF
	BNE	10$
	MOV	R4,D.FWA	; SET FIRST WORD
	INCB	D.FWAF		; MARK FIRST WORD FOUND
	JMP	D.DCD2		; RETURN
10$:	CMPB	D.ALTF,#2
	BHIS	100$
	CMP	D.CAD,#D.NLWD	; If word not open
	BEQ	100$		; then don't allow.
	CMP	D.BW,#1		; If in byte mode
	BEQ	100$		; then don't allow.
	TST	D.PATA		; If already patching
	BNE	100$		; then don't allow.
	CMP	D.LFIN,#4	; At least 2 words must be open
	BLO	100$		; or it will not work.
	TST	D.SVR2		; If patch address not given
	BNE	30$		; then
	MOV	#^RPAT,D.RAD1	; look for "PAT..".
	MOV	#^R..,D.RAD2
	CALL	D.GTAC
	TST	R0
	BEQ	100$		; No place to patch to
	MOV	(R0),D.SVR4	; or here is where we go.
30$:	MOV	D.DOT,D.PATA	; This is the address we are patching from
	MOV	D.SVR4,D.PATI+2	; and this is the patch area.
	MOV	D.PATI+2,D.DOT
	MOV	#D.PATS,D.PATE
	CMPB	D.ALTF,#1
	BNE	50$
40$:	MOV	D.CAD,R4	; Get the patched instruction(s).
	CALL	D.GETW
	ADD	#2,D.CAD
	MOV	R0,@D.PATE	; Save the word
	ADD	#2,D.PATE
	CMP	D.CADC,D.CAD
	BHIS	40$
	BR	60$
50$:	MOV	D.CAD,R4	; Get patched instruction(s).
	CALL	D.GETW
	ADD	#2,D.CAD
	MOV	D.DOT,R4
	CALL	D.STRW
	ADD	#2,D.DOT
	CMP	D.CADC,D.CAD
	BHIS	50$
60$:	MOV	D.PATE,R1	; Now insert
	MOV	(PC)+,(R1)+	; the instrution
	JMP	@(PC)+		; that jumps back
	MOV	R4,(R1)+	; to the main line code.
	MOV	R1,D.PATE
	MOV	#D.NLWD,D.CAD	; Close the words.
	JMP	D.OP2		; Open the patch area.

100$:	JMP	D.ERR
	.SBTTL	D.ZERO	- Zero core
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.ZERO
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.ZERO:	MOV	D.FWA,R4	; FIRST WORD
10$:	CMP	R4,D.SVR4	; AT LAST WORD?
	BHI	20$		; DONE IF SO
	CLR	R0		; Zero the word
	CALL	D.STRW
	ADD	#2,R4
	BR	10$		; LOOP
20$:	RETURN			; RETURN
	.SBTTL	D.SNGL	- Second set of instructions
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.SNGL
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.SNGL:	CALL	D.GET		; GET CHARACTER
	CLR	R5		; OFFSET
10$:	CMPB	D.UTAB(R5),R0	; MATCH?
	BNE	20$		; NO
	ASL	R5		; MULTIPLY BY 2
	JMP	@D.UADD(R5)	; DO THIS ROUTINE
20$:	INC	R5		; NEXT CHARACTER
	CMP	R5,#D.ENUT	; END OF LIST?
	BLT	10$		; LOOP IF NOT
	JMP	D.ERR		; RETURN
	.SBTTL	D.GRAP	- Return user display
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.GRAP
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--
.IF DF D.GDP

	.PSECT	$CODE$,I
D.GRAP:	TRAP	144
	MOV	#104544,D.SAV9	; UG! SELF MODIFYING-CODE
	RETURN	
.ENDC
	.SBTTL	D.ESCH	- Effective search
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.ESCH
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.ESCH:	MOV	#1,R1		; SET EFFECTIVE SEARCH
	BR	D.WDS		; DO SEARCH
	.SBTTL	D.NSCH	- No search
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.NSCH
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.NSCH:	MOV	#-1,R1		; SET NON-SEARCH
	BR	D.WDS		; DO SEARCH
	.SBTTL	D.WSCH	- Word search
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.WSCH
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.WSCH:	CLR	R1		; SET WORD SEARCH
	BR	D.WDS
	.SBTTL	D.WDS	- Do search
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.WDS
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.WDS:	TST	D.SVR2		; NUMBER TO SEARCH FOR?
	BEQ	80$		; ERROR IF NOT
	CALL	D.SWRD		; Set word mode
	PUSH$S	D.CAD		; THIS IS "MOST RECENT VALUE" OF D.CAD
	MOV	D.FWA,R2	; SET ORIGIN
10$:
.IF NDF D.RSX
.IF NDF D.KSR&D.MCB
	TSTB	@#D.RCSR	; CHARACTER TYPED?
	BMI	70$		; BRANCH IF SO
.ENDC
.ENDC
.IF DF D.KSR!D.MCB
	CALL	D.POLL		; CHECK FOR TYPED CHARACTER
	CMP	D.INPU,D.OUTP	; ANY CHARACTERS IN BUFFER?
	BNE	70$
.ENDC
	CMP	R2,D.LWA	; IS THE SEARCH ALL DONE?
	BHI	70$		;  YES
	MOV	D.SVR4,R5	; GET NUMBER TO SEARCH FOR
	MOV	D.MASK,R4	; GET MASK
	COM	R4		; COMPLEMENT IT
	PUSH$S	R4
	MOV	R2,R4		; OBJECT ADDRESS
	CALL	D.GETW		; pick it up
	POP$S	R4
	MOV	R2,D.CAD	; THIS IS CURRENT ADDRESS
	BIC	R4,R0		; TURN OFF BITS NOT BEING SEARCHED FOR
	BIC	R4,R5		; TURN OFF BITS NOT BEING SEARCHED FOR
	PUSH$S	R1		; STORE AND TEST
	BMI	60$		; BRANCH IF NON-SEARCH
	BGT	40$		; BRANCH IF EFFECTIVE SEARCH
	CMP	R0,R5		; EQUALITY?
	BNE	30$		; RE-LOOP IF NO MATCH
20$:	CALL	D.CRLF		; TYPE CRLF
	MOV	D.CAD,R0	; GET READY TO TYPE
	MOV	R0,2(SP)	; SET MOST RECENT VALUE OF D.CAD
	CALL	D.RFND		; RELOCATE
	MOVB	D.CDSP,R0	; SLASH TO R0
	CALL	D.TYPE		; TYPE IT
	CALL	@D.CURM		; TYPE CONTENTS
30$:	POP$S	R1		; RESTORE R1
	MOV	D.CAD,R2	; RESTORE R2
	ADD	#2,R2		; INCREMENT TO NEXT CELL AND
	BR	10$		;    RETURN
40$:	MOV	#1,D.BOTH	; MARK NOTHING FOUND AND DON'T TYPE INSTRUCTION
	CALL	D.INST		; "TYPE" THE INSTRUCTION
	DEC	D.BOTH		; ALLOW TYPEOUT AND TEST FOUND INDICATOR
50$:	BEQ	30$		; BRANCH IF NOT FOUND
	BR	20$		; BRANCH IF FOUND
60$:	CMP	R0,R5		; EQUALITY?
	BR	50$		; BRANCH TO DECIDE
70$:	POP$S	D.CAD		; RESTORE MOST RECENT VALUE OF D.CAD
	RETURN			; RETURN
80$:	JMP	D.ERR		; RETURN
	.SBTTL	D.INNM	- Set numeric typeout
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.INNM
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.INNM:	TST	R2		; If radix specified
	BEQ	20$		; then
	CMP	#D.DECN,#2	; check if in range.
	BGE	10$		; If not,
	JMP	D.ERR		; then tell him so;
10$:	MOV	D.DECN,D.DVTB	; otherwise set the decimal radix.
20$:	MOV	#D.CADV,D.CURM	; SET NUMERIC MODE
	MOV	D.CURM,D.OMOD	; SET LF AND ^ TYPEOUT MODE

D.PRM:	CMPB	D.ALTF,#2	; TWO ALTMODES TYPED?
	BLT	90$		; RETURN IF NOT
	MOV	#D.CURM,R0	; ADDRESS OF TEMPORARY TABLE
	MOV	#D.PERM,R1	; ADDRESS OF PERMANENT TABLE
	MOV	#4,R2		; SWAP MODES: WORD COUNTER IN R2
10$:	MOV	(R0)+,(R1)+	; MOVE A WORD
	SOB	R2,10$		; LOOP TILL DONE
	RETURN			; RETURN

90$:	JMP	D.DCD		; RETURN
	.SBTTL	D.INTX	- Text typeout
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.INTX
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.INTX:	MOV	#D.ASCI,D.CURM	; DEFAULT TO ASCII
	CMP	R4,#5		; RAD50?
	BNE	10$		; RETURN IF NOT
	MOV	#D.RADC,D.CURM	; RAD50
10$:	MOV	D.CURM,D.OMOD	; SET LF AND ^ TYPEOUT MODE
	BR	D.PRM		; RETURN
	.SBTTL	D.BYTE	- Byte typeout
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.BYTE
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.BYTE:	MOV	#D.PART,D.CURM	; IN BYTE TYPEOUT MODE
	MOV	#D.PART,D.OMOD	; SET LF AND ^ TYPEOUT MODE
	MOV	D.DECN,D.SIZE	; SET BYTE SIZE
	BR	D.PRM		; RETURN
	.SBTTL	D.INMD	- Instruction typeout
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.INMD
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.INMD:	MOV	#D.INST,D.CURM	; IN INSTRUCTION MODE
	MOV	D.CURM,D.OMOD	; SET LF AND ^ TYPEOUT MODE
	BR	D.PRM		; RETURN
	.SBTTL	D.ABS	- Absolute address typeout
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.ABS
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.ABS:	MOV	#1,D.IFMT	; SET ABSOLUTE ADDRESSING
	BR	D.PRM		; RETURN
	.SBTTL	D.INRD	- Set radix
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.INRD
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.INRD:	TST	R2		; If limit specified
	BEQ	10$		; then
	MOV	R4,D.RFNL	; set it in out data base.
10$:	CLR	D.IFMT		; Turn on relative addressing.
	BR	D.PRM
	.SBTTL	D.CRET	- Close word and reset permanent modes
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.CRET
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.CRET:	CALL	D.CLSE		; CLOSE LOCATION
	MOV	#D.PERM,R0	; ADDRESS OF PERMANENT TABLE
	MOV	#D.CURM,R1	; ADDRESS OF TEMPORARY TABLE
	MOV	#4,R2		; SWAP MODES: WORD COUNTER IN R2
10$:	MOV	(R0)+,(R1)+	; MOVE A WORD
	SOB	R2,10$		; LOOP TILL DONE
	MOV	D.CURM,D.OMOD	; SET LF AND ^ TYPEOUT MODE
	JMP	D.DCD		; RETURN
	.SBTTL	D.CLSE	- Close Word or Byte
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.CLSE
;
; INPUT PARAMETERS:
;	R2 =
;
; IMPLICIT INPUTS:
;	D.CAD =
;	D.NLWD =
;	D.BW =
;	D.CADC =
;	D.PARS =
;	D.PARO =
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	D.CAD =
;	D.LFIN =
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.CLSE:	TST	R2		; IF NO NUMBER WAS TYPED THERE IS
	BEQ	20$		; NOTHING TO CLOSE
	CMP	D.CAD,#D.NLWD	; ANY OPEN WORD?
	BEQ	20$		; BRANCH IF NOT
	CLR	D.LFIN		; NO LINE FEED INCREMENT
.IF DF D.MCB
	CMP	D.CAD,#177706	; If modifying the SP
	BEQ	30$		; then crash.
.ENDC
	MOV	R4,R0
	MOV	D.CAD,R4	; WORD ADDRESS
	CMP	#1,D.BW		; BYTE MODE?
	BEQ	10$		; JUMP IF BYTE MODE
	CALL	D.STRW
	CMP	D.CADC,R4	; SUBTRACT COPY
	BLOS	20$		; BRANCH IF NO MORE
	ADD	#2,R4
	ADD	#2,D.LFIN	; LINE FEED INCREMENT
	MOV	D.PARS,R0	; MOVE ANOTHER WORD (2 OR 3 WORD INST)
	SUB	D.PARO,R0	; RELOCATE WORD
	CALL	D.STRW
	CMP	D.CADC,R4	; THIRD PARAMETER?
	BLOS	20$		; BRANCH IF NOT
	ADD	#2,R4
	ADD	#2,D.LFIN	; LINE FEED INCREMENT
	MOV	D.PARS+2,R0	; PUT THIRD WORD IN
	SUB	D.PARO+2,R0	; RELOCATE WORD
	CALL	D.STRW
	BR	20$		; FINISH UP
10$:	CALL	D.STRB
20$:	MOV	#D.NLWD,D.CAD	; CLOSE WORD
	RETURN			; RETURN
30$:	JMP	D.ERR
	.SBTTL	D.LWAS	- Store last word address for search
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.LWAS
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.LWAS:	CMPB	D.ALTF,#1
	BGE	20$
	MOV	R4,D.LWA	; SET LAST WORD
	TST	R2		; ANY WORD THERE?
	BNE	10$		; BRANCH IF NOT
	MOV	#DDT-2,D.LWA	; SET HIGH LAST WORD
10$:	JMP	D.DCD		; RETURN
20$:	BNE	100$
	TST	D.PATA		; If not patching
	BNE	100$		; then don't allow.
	MOV	#D.PATS,R1
	MOV	D.PATE,R2
	MOV	D.DOT,R4
	CALL	30$
	MOV	#D.PATI,R1
	MOV	-(R2),R2
	MOV	D.PATA,R4
	SUB	R4,R2
	ADD	R1,R2
	CALL	30$
	JMP	D.OP2

30$:	MOV	(R1)+,R0
	CALL	D.STRW
	ADD	#2,R4
	CMP	R2,R1
	BNE	30$
	MOV	R4,D.DOT
	RETURN

100$:	JMP	D.ERR
	.SBTTL	D.BKPT	- Set and remove breakpoints
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.BKPT
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.BKPT:	TST	D.SVR2		; DID HE GIVE A FIRST ARG?
	BEQ	90$
	ASL	R4		; MULTIPLY NUMBER BY TWO
	MOV	D.SVR4,R5	; GET FIRST NUMBER
	BEQ	50$		; REMOVE BREAK IF FIRST ARG 0
	CALL	D.VLD		; Validate address.
	TST	R4		; SPECIFIC CELL REQUESTED?
	BNE	20$		; JUMP IF SO
	MOV	#2,R4
10$:	CALL	D.BKCK		; Check breakpoint
	BCS	30$		; It is free
	BEQ	30$		; or the same
	TST	(R4)+		; INCREMENT BY TWO
	CMP	R4,#D.BKP*2	; ARE WE AT THE END OF OUR ROPE?
	BLOS	10$		; NO, KEEP LOOKING
20$:	CMP	R4,#D.BKP*2	; REQUESTED NUMBER TOO LARGE?
	BHI	100$		; ERROR IF TOO LARGE
30$:	CALL	D.BKST		; SET BREAKPOINT
	MOV	D.COMA,D.OPEN(R4) ; SET WORD TO OPEN AT BREAKPOINT
	CLR	D.CT(R4)	; SET CONTINUE COUNT
	CMPB	D.ALTF,#1	; TWO ALTMODES?
	BGT	40$		; BRANCH IF NOT
	INC	D.CT(R4)	; DO NOT SET AUTOMATIC PROCEDE
40$:	RETURN			; RETURN
50$:	TST	R2		; IF NO NUMBER WAS TYPED...
	BEQ	62$		; GO REMOVE ALL
	CMP	R4,#D.BKP*2	; WAS THE TYPED NUMBER VALID?
	BHI	100$		; JUMP IF NOT
	CALL	D.BKST		; CLEAR BREAKPOINT
	RETURN			; RETURN
60$:	CLR	R5
62$:	MOV	#2,R4
64$:	CALL	D.BKST		; Clear breakpoint
	TST	(R4)+		; INCREMENT BY TWO
	CMP	R4,#D.BKP*2	; ARE WE AT THE END OF OUR ROPE?
	BLOS	64$		; NO, KEEP LOOKING
	RETURN			; RETURN
90$:	TST	R2		; If a number typed
	BEQ	60$		; then
	ASL	R4		; Validate the number.
	BEQ	100$
	CMP	#<D.BKP*2>,R4
	BLO	100$		; Jump if invalid.
	MOV	D.BKTB(R4),R4
	CALL	@D.OPER		; COMBINE VALUE WITH CURRENT EXPRESSION
	POP$S	,1
	INC	R2		; MARK A TYPED NUMBER
	JMP	D.DCD3		; CONTINUE SCANNING
100$:	JMP	D.ERR		; INTERMEDIATE HELP
	.SBTTL	D.BKCK	- Check Breakpoint Availability
;++
; FUNCTIONAL DESCRIPTION:
;	Compare given breakpoint against given address
;
; CALLING SEQUENCE:
;	CALL	D.BKCK
;
; INPUT PARAMETERS:
;	R5 = Address to compare
;	R4 = breakpoint index
;
; IMPLICIT INPUTS:
;	Process context or task context of given address
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	C-bit set = breakpoint undefined
;	N-bit set = breakpoint does not match address
;	N-bit clear = breakpoint matches address
;
; SIDE EFFECTS:
;	Register R0 is modified.
;--

	.PSECT	$CODE$,I
D.BKCK:	MOV	D.BKTB(R4),R0	; IS THIS CELL FREE?
	BEQ	80$		; JUMP IF YES
.IF DF D.MCB
	PUSH$S	R4
	MOV	R4,R0
	MOV	R5,R4
	CALL	D.CMPB		; Check APR6 address
	POP$S	R4
	MTPS	R0
.IFF
	CMP	R0,R5		; Check address
.IFTF
	CLC
	RETURN
80$:	COM	R0		; Set C-bit and N-bit
90$:	RETURN
.IFT
	.PSECT	$ABS$,I
D.CMPB:	JSR	R3,D.REL
	CMP	D.BIAS(R0),@#KISAR6
	BNE	10$
	CMP	D.ADDR(R0),R3
10$:	MFPS	R0
	RETURN
.ENDC
	.SBTTL	D.BKST	- Set Breakpoint
;++
; FUNCTIONAL DESCRIPTION:
;	Set given breakpoint as given address
;
; CALLING SEQUENCE:
;	CALL	D.BKST
;
; INPUT PARAMETERS:
;	R5 = Address to set
;	R4 = breakpoint index
;
; IMPLICIT INPUTS:
;	Process context or task context of given address
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	Register R0 is modified.
;--

	.PSECT	$CODE$,I
D.BKST:	MOV	R5,D.BKTB(R4)	; Set address
	BEQ	90$
.IF DF D.MCB
	PUSH$S	R4
	MOV	R4,R0
	MOV	R5,R4
	CALL	D.SETB		; Set APR6 address
	POP$S	R4
.IFTF
90$:	RETURN
.IFT
	.PSECT	$ABS$,I
D.SETB:	JSR	R3,D.REL
	MOV	@#KISAR6,D.BIAS(R0)
	MOV	R3,D.ADDR(R0)
	RETURN
.ENDC
	.SBTTL	D.MAST	- Type and set mask
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.MAST
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.MAST:	PUSH$S	#D.MASK		; GET MASK
	TST	D.SVR2		; NUMBER THERE?
	BNE	10$		; BRANCH IF SO
	POP$S	R4		; ADDRESS TO OPEN
	CALL	@D.OPER		; COMBINE VALUE WITH CURRENT EXPRESSION
	INC	R2		; MARK A TYPED NUMBER
	JMP	D.DCD3		; CONTINUE SCANNING
10$:	MOV	D.SVR4,@(SP)+	; SET MASK
	RETURN			; RETURN
	.SBTTL	D.ALTV	- Get contents of Dot byte-swapped.
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.ALTV
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.ALTV:	MOV	D.DOT,R4	; ADDRESS OF WORD
	CALL	D.GETW		; RELOCATE IT
	MOV	R0,R4		; FETCH THE WORD
	SWAB	R4		; SWAB IT
	CALL	@D.OPER		; COMBINE VALUE WITH CURRENT EXPRESSION
	INC	R2		; MARK A TYPED NUMBER
	JMP	D.DCD3		; CONTINUE SCANNING
	.SBTTL	D.ALTQ	- Get contents of Dot
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.ALTQ
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.ALTQ:	MOV	D.DOT,R4	; ADDRESS OF WORD
	CALL	D.GETW		; RELOCATE IT
	MOV	R0,R4
	CALL	@D.OPER		; COMBINE VALUE WITH CURRENT EXPRESSION
	INC	R2		; MARK A TYPED NUMBER
	JMP	D.DCD3		; CONTINUE SCANNING
	.SBTTL	D.TEXT	- Get Text
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.TEXT
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.TEXT:	CALL	D.GET		; GET NEXT CHARACTER
	CLR	R2		; RAD50/ASCII INDICATOR
	CMP	R0,#33		; ALTMODE?
	BNE	10$		; BRANCH IF NOT
	INC	R2		; SET INDICATOR
	CALL	D.GET		; GET NEXT CHARACTER
10$:	MOV	R1,R5		; DELIMETER (EXACT CHARACTER)
20$:	CALL	D.GET		; GET CHARACTER
	CMP	R1,R5		; DELEMETER?
	BEQ	30$		; BRANCH IF SO
	MOV	R1,R0		; PUT IN ARGUMENT PLACE
	CALL	D.PTSM		; PUT IN SYMBOL
	BR	20$		; LOOP
30$:	TST	R2		; ASCII?
	BNE	40$		; BRANCH IF NOT
	MOV	D.SYM,R4	; GET ASCII CHARACTERS
	BR	50$		; RETURN
40$:	MOV	#D.SYM,R0	; ADDRESS OF FIRST THREE CHARACTERS
	CALL	D.RD50		; CONVERT TO RAD50
	MOV	R0,R4		; NOW CURRENT VALUE
50$:	CALL	@D.OPER		; COMBINE VALUE WITH CURRENT EXPRESSION
	INC	R2		; MARK A TYPED NUMBER
	JMP	D.DCD3		; CONTINUE SCANNING
	.SBTTL	M.DBG	- Set debugging mode
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	M.DBG
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
M.DBG:
.IF DF D.MCB
	CMPB	D.ALTF,#2	; If two altmodes typed
	BGE	60$		; then dangerous function requested.
	TST	D.SVR2		; If operating switch
	BNE	20$		; then check what is requested.
	TST	R2		; If PIX specified
	BEQ	100$		; then
	CMP	.PDBNM,R4	; check its range
	BLO	10$		; and if so
	CALL	M.SNON		; request synchronization.
	BR	18$
10$:	INC	R4
	BNE	100$
	MOV	@#$TKTCB,R4	; Get current task
	TST	T.TCBL(R4)	; and if not null task
	BEQ	100$		; then
	CALL	M.USON		; set task to break.
18$:	CLR	R2
	CLR	D.SVR2
	JMP	D.PROC		; Simulate $$P function.
20$:	MOV	D.SVR4,R0	; Get switch number
	BEQ	100$		; and check range
	BPL	22$		; of
	NEG	R0		; absolute value.
22$:	CMP	#1,R0
	BNE	100$
	CMP	#7,R4		; If severity out of range
	BLO	100$		; then razz him.
	MOVB	D.SVR4,D.PSVR(R4)
	RETURN
60$:	TST	D.SVR2		; If argument specified
	BEQ	100$		; and
	TST	D.SVR4		; if zero
	BNE	70$		; then
	CALL	M.TTOF		; disable the TTY trap
	CALL	M.SNCK		; process synchronize
	JMP	EXVEN
70$:	INC	D.SVR4		; If minus one (-1)
	BNE	100$		; then
	CALL	D.REST		; restore the signal context
	CLR	R0		; and request re-signalling.
	RETURN
.IFTF
100$:	JMP	D.ERR		; Not defined
.IFT
	.PSECT	$ABS$,I
EXVEN:	MAP$	@#KISAR5
	CALL$C	#$EXVEN,<#0,#EXVPRI+20000,#0> ; and
	CALL$C	#$EXVEN,<#2,#EXVLST+20000,#0> ; DDT.
	MAP$	D.DAR6
	RETURN
.ENDC
	.SBTTL	D.SOFT	- Soft restart
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.SOFT
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--
.IF DF D.GDP

	.PSECT	$CODE$,I
D.SOFT:	MOV	#1004,R5	; ADDRESS OF SOFT RESTART
	BR	D.GO3		; GO THERE
.ENDC
	.SBTTL	D.EXEC	- Execute instruction
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.EXEC
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.EXEC:	TST	D.SVR2		; ANY INSTRUCTION?
	BEQ	30$		; ERROR IF NOT
.IF DF D.MCB
	JMP	D.ERR		; Unsupported
.IFF
	MOV	#D.SVR4,R5	; INSTRUCTION STARTING ADDRESS
	TST	D.PARO		; RELOCATE FIRST WORD?
	BEQ	10$		; BRANCH IF NOT
	SUB	#D.PARS+2,D.PARS; RELOCATE FIRST WORD
10$:	TST	D.PARO+2	; RELOCATE SECOOND WORD?
	BEQ	20$		; BRANCH IF NOT
	SUB	#D.PARS+4,D.PARS+2 ; RELOCATE SECOND WORD
20$:	MOV	D.UR7,D.SVR7	; SAVE PC
	BR	D.GO5		; EXECUTE INSTRUCTION
.IFT
30$:	MOV	D.UR7,R5	; GET PC
	CALL	D.VLD		; Validate address.
	MOV	D.COMA,D.OPEN+<D.BKS*2>
	MOVB	#1,D.S
	CMPB	D.ALTF,#1	; If to execute to next instruction
	BLE	32$		; then
	NEGB	D.S		; set multiple step mode
	MOV	R5,D.BKLO
	ADD	#1*2,D.BKLO	; and set
	MOV	R5,D.BKHI
	ADD	#3*2,D.BKHI	; break address range.
32$:	MOV	#1,R4
	MOV	R4,D.CT+<D.BKS*2>
	MOVB	D.P,R0		; DID WE ENTER VIA A BREAK?
	BLT	D.GO3		; NO, OKAY.
	BR	D.PRO6
.IFF

D.EXE2:
.IF NDF D.RSX
	MFPS	D.UPS		; GET PS
.ENDC
	MOV	D.SVR7,D.UR7	; RESTORE CORRECT PC
	CALL	D.SAVE		; SAVE ALL REGISTERS
	CALL	D.TTAB		; TYPE TAB
	JMP	D.DCD		; RETURN
.ENDC
	.SBTTL	D.PROC	- Proceede
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.PROC
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.PROC:	TST	R2		; CHECK FOR ILLEGAL COUNT
	BNE	D.PRO9		; JUMP IF ILLEGAL
	MOV	D.UR7,R5	; GET PC
	CALL	D.VLD		; Validate address.
	MOVB	D.P,R0		; DID WE ENTER VIA A BREAK?
	BLT	D.PRO3		; NO, RETURN TO CALLER
	MOV	D.SVR4,R4	; GET COUNT
	TST	D.SVR2		; WAS COUNT SPECIFIED?
	BNE	D.PRO1		; NO
	MOV	#1,R4		; SET COUNT OF 1
D.PRO1:	CMPB	D.ALTF,#1	; AUTOMATIC PROCEDE?
	BLE	D.PRO6		; BRANCH IF NOT
	NEG	R4		; SET TO AUTOMATIC
D.PRO6:	MOV	R4,D.CT(R0)	; PUT AWAY COUNT
D.PRO7:	CALL	D.CRLF		; CARRIAGE RETURN LINE FEED
D.PRO2:	INCB	D.T		; SET SPECIAL BIT TO 1
	MOV	R5,D.TPC	; SAVE PC FOR 11/40 KLUDGE
	BR	D.GO5
D.PRO3:	TST	D.SVR2		; COUNT SPECIFIED?
	BEQ	D.GO3		; NO, OK, RETURN TO CALLER OF DDT
D.PRO9:	JMP	D.ERR		; ELSE ERROR
	.SBTTL	D.GO	- Go
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.GO
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
	.ENABL	LSB
D.GO:
.IF DF D.MCB
	JMP	D.ERR		; no starting address available
.IFF
	MOV	D.SVR4,R5	; GET STARTING ADDRESS
	TST	D.SVR2		; STARTING ADDRESS SPECIFIED?
	BNE	D.GO3		; IF NOT,
	MOV	JOBSA,R5	; GET STARTING ADDRESS
.ENDC
D.GO3:	CALL	D.VLD		; Validate address.
	CALL	D.CRLF
D.GO5:	BIC	#20,D.UPS	; Assume T-bit off
	TST	D.SD.T		; and if it should be on
	BEQ	40$		; then
D.GO4:	BIS	#20,D.UPS	; set it.
40$:	MOV	R5,D.UR7
	CALL	D.REST		; Restore user context
.IF DF D.MCB
	MOV	#1,R0		; and request signal continuation.
	RETURN
.IFF
	PUSH$S	<D.UPS,D.UR7>	; Set status and PC
D.GO1:	RTI			; THIS IS "RTT" IF 11/40...
.ENDC
	.DSABL	LSB
	.SBTTL	M.LAST	- Last Chance Exceptional Condition Handler
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	M.LAST
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--
.IF DF D.MCB

	.PSECT	$CODE$,I
M.LAST:	MOV	6(SP),R0	; Get signal vector
	TST	(R0)+		; and if status specified
	BLE	20$		; and
	CMP	S.SDTE+4,(R0)	; it is a DTE "magic finger"
	BNE	20$		; then fall into panic dump.
	RETURN
20$:	CALL	D.SAVE		; Save the context.
	MOVB	#-1,D.P
	MOV	MSIGV,R0
	MOV	2(R0),R0
	CMP	S.SBPT+4,R0
	BNE	60$
	CALL	M.TTCK
	BCC	24$
	CALL	M.SNCK
	BCC	24$
	CALL	M.USCK
24$:	MOV	D.UR7,R5	; GET PC, IT POINTS TO THE INSTRUCTION
	TSTB	D.T		; WERE WE PROCEEDING AFTER A BREAK?
	BLE	28$		; YES, FIX IT UP
	TSTB	D.MACH		; 11/40,45?
	BEQ	26$		; NO, DON'T NEED TO KLUDGE
	CMP	R5,D.TPC	; DID WE NOT EXECUTE THE BROKEN INSTRUCTION?
	BEQ	D.GO4		; YES, TRY IT AGAIN
26$:	CLRB	D.T		; WE CAN CONTINUE NORMALLY
	TSTB	D.S		; UNLESS WE ARE SINGLE STEPPING
	BEQ	D.GO5
28$:	CALL	D.BCHK		; Check for a breakpoint
	BCS	34$
	MOVB	R4,D.P		; and if it is
	BLE	60$		; then
	TST	D.CT(R4)	; check the proceede count.
	BPL	32$		; BRANCH IF GETTING THERE
	INC	D.CT(R4)	; COUNT 'EM OFF
	BMI	34$		; PROCEDE IF STILL NEGATIVE
32$:	BEQ	60$		; BRANCH IF AUTOMATIC PROCEDE
	DEC	D.CT(R4)	; TEST REPEAT COUNT
	BEQ	36$		; BRANCH IF NO REPEAT
34$:	MOV	D.UR7,R5	; Get user PC
	JMP	D.PRO2		; and procede.
36$:	INC	D.CT(R4)	; RESET COUNT TO 1
60$:	CLRB	D.T		; TURN OFF BIT
	CALL	M.PROC
	MOVB	D.P,R4
	BEQ	80$
	MOVB	#':,R0
	CALL	D.TYPE
	MOVB	R4,R0
	BMI	70$
	ASR	R0
	ADD	#'0,R0
	MOV	#M.BMES,R1
	MOVB	R0,1(R1)
	CALL	D.STYP
	MOV	D.OPEN(R4),R0
	BEQ	80$
	MOV	R0,D.CAD
	CALL	D.TTAB
	CALL	@D.OMOD
	BR	80$
70$:	MOV	MSIGV,R1
	PUSH$S	<(R1)+,R1>
	MOV	(R1)+,R0
	CLR	R1
	MOV	#S.CSTS,R2
	CALL	D.GTSS
	TST	R1
	BEQ	74$
	CALL	D.STYP
	BR	76$
72$:	MOVB	#' ,R0
	CALL	D.TYPE
74$:	MOV	(SP),D.CAD
	CALL	D.CADV
76$:	ADD	#2,(SP)
	DEC	2(SP)
	BNE	72$
	POP$S	,2
80$:	CALL	D.CRLF		; Type <CR><LF>,
	MOVB	D.P,R4		; If it is a breakpoint
	BLE	84$		; then
	TST	D.CT(R4)	; AUTOMATIC PROCEDE?
	BNE	88$		; RETURN IF NOT
	TSTB	@#D.RCSR	; CHARACTER TYPED?
	BMI	88$		; EXIT IF SO
82$:	MOV	D.UR7,R5	; RESTORE R5
	JMP	D.PRO2		; CONTINUE BREAKPOINT
84$:	MOV	MSIGV,R0	; Pick up status code
	TST	(R0)+		; if there is one.
	BEQ	88$
	MOV	(R0),R0
	BIC	#^C7,R0		; Isolate the severity
	TSTB	D.PSVR(R0)	; and check on action:
	BMI	88$		;  <0	break
	BGT	86$		;  >0	continue
	ASR	R0		;  =0	continue on success.
	BCC	88$
86$:	CALL	D.REST
	MOV	#1,R0
	RETURN
88$:	MOV	D.UR7,D.DOT	; exception address
	MOV	#D.INST,D.OMOD	; with instruction typeout
	CALL	D.OP3		; (open it),
	CALL	D.TTAB		; and a <tab>.
	JMP	D.DCD
.ENDC
	.SBTTL	M.PRIM	- Primary Exception Condition Handler
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	M.PRIM
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	C-bit set = exception caused by DDT.
;	C-bit clear = exception not caused by DDT.
;
; SIDE EFFECTS:
;	None
;--
.IF DF D.MCB

	.PSECT	$CODE$,I
M.PRIM:	MOV	4(SP),R0	; Get mechanism vector address.
	CMP	M.AR5(R0),@#KISAR5 ; If a crash in us
	BNE	90$		; then
	MOV	6(SP),R0	; get signal vector
	CMP	S.SDTE+4,2(R0)	; and if not "DTE magic finger"
	BEQ	90$		; then
	ADD	(R0)+,R0	; bypass parameter count
	ADD	@6(SP),R0	; to get address of signal PC.
	CMP	#120000,(R0)	; If within the process
	BHI	90$		; then
	MOV	#D.ERR,(R0)	; set to return from handler.
	INC	R0
90$:	RETURN
.ENDC
	.SBTTL	D.NXMT	- Non-existent memory trap
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.NXMT
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--
.IF NDF D.MCB

	.PSECT	$CODE$,I
D.NXMT:	POP$S	<D.UR7,D.UPS>	; SAVE PC AND STATUS
	CALL	D.SAVE		; SAVE VARIOUS REGISTERS
	MOV	#D.NM,D.ERF	; NXM TRAP SERVICE
	BR	D.BRK		; HANDLE BREAKPOINT
.ENDC
	.SBTTL	D.ILGT	- Illegal instruction trap
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.ILGT
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--
.IF NDF D.MCB

	.PSECT	$CODE$,I
D.ILGT:	POP$S	<D.UR7,D.UPS>	; SAVE PC AND STATUS
	CALL	D.SAVE		; SAVE VARIOUS REGISTERS
	MOV	#D.IM,D.ERF	; ILLEGAL INSTRUCTION
	BR	D.BRK		; HANDLE BREAKPOINT
.ENDC
	.SBTTL	D.BRKT	- Breakpoint Handler
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.BRKT
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.BRKT:
.IF NDF D.MCB
	POP$S	<D.UR7,D.UPS>	; SAVE PC AND STATUS
	CALL	D.SAVE		; SAVE VARIOUS REGISTERS
	MOV	D.UR7,R5	; GET PC, IT POINTS TO THE INSTRUCTION
	TSTB	D.T		; WERE WE PROCEEDING AFTER A BREAK?
	BLE	40$		; YES, FIX IT UP
	TSTB	D.MACH		; 11/40,45?
	BEQ	34$		; NO, DON'T NEED TO KLUDGE
	CMP	R5,D.TPC	; DID WE NOT EXECUTE THE BROKEN INSTRUCTION?
	BEQ	D.GO4		; YES, TRY IT AGAIN
34$:	CLRB	D.T		; WE CAN CONTINUE NORMALLY
	TSTB	D.S		; UNLESS WE ARE SINGLE STEPPING
	BEQ	D.GO5
40$:	CALL	D.BCHK		; Check for a breakpoint
	BCS	54$
	MOVB	R4,D.P		; and set the breakpoint flag.
	BMI	90$
	TST	D.CT(R4)	; AUTOMATIC PROCEDE?
	BPL	52$		; BRANCH IF GETTING THERE
	INC	D.CT(R4)	; COUNT 'EM OFF
	BMI	54$		; PROCEDE IF STILL NEGATIVE
52$:	BEQ	62$		; BRANCH IF AUTOMATIC PROCEDE
	DEC	D.CT(R4)	; TEST REPEAT COUNT
	BEQ	60$		; BRANCH IF NO REPEAT
54$:	MOV	D.UR7,R5	; Get user PC
	JMP	D.PRO2		; and procede.
60$:	INC	D.CT(R4)	; RESET COUNT TO 1
62$:	PUSH$S	D.CT(R4)	; Save count.
	MOV	#D.BMES,R1	; Get breakpoint message
	ASR	R4		; and
	ADD	#'0,R4		; insert
	MOVB	R4,1(R1)	; breakpoint number.
	CALL	D.STYP		; Type it
	MOV	D.UR7,R0	; Get address of break
	CALL	D.RFND		; and relocate.
	MOV	D.OPEN(R4),R0	; a word is to be opened
	BEQ	68$		; then
	MOV	R0,D.DOT	; put in current word
	CALL	D.TTAB		; type a tab
	CALL	D.OP3		; and open it.
68$:	TST	(SP)+		; AUTOMATIC PROCEDE?
	BNE	D.BRK8		; RETURN IF NOT
.IF NDF D.RSX
	TSTB	@#D.RCSR	; CHARACTER TYPED?
	BMI	D.BRK8		; EXIT IF SO
.ENDC
	MOV	D.UR7,R5	; RESTORE R5
	JMP	D.PRO7		; CONTINUE BREAKPOINT
90$:	MOV	#D.BE,D.ERF	; ERROR: UNEXPECTED BREAK

D.BRK:	MOVB	#-1,D.P		; DISALLOW PROCEED
	CLRB	D.T		; TURN OFF BIT
	MOV	D.UR7,R0	; GET ADDRESS OF BREAK
	CALL	D.RFND		; RELOCATE
	MOV	D.ERF,R1	; GET CODE
	CALL	D.STYP		; TYPE MESSAGE
	CLR	D.ERF		; REMOVE TRACES OF THIS ENTRY

D.BRK8:	CALL	D.TTAB		; TYPE TAB
	JMP	D.DCD		; RETURN
.ENDC
	.SBTTL	D.BCHK	- Check for Valid Breakpoint
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.BCHK
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	R4 = proceede index
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	Carry set = proceede
;	Carry clear = break
;
; SIDE EFFECTS:
;	Registers R0, R4 and R5 are modified.
;--

	.PSECT	$CODE$,I
D.BCHK:	CLR	R4		; Assume single stepping.
	TSTB	D.S		; If single stepping
	BNE	70$		; then all is well.
	MOV	D.UR7,R5	; Get breakpoint
	SUB	#2,R5		; and back up over BPT.
	MOV	#D.BKP*2,R4	; GET A COUNTER
10$:	CALL	D.BKCK
	BEQ	60$		; BRANCH IF YES
18$:	SUB	#2,R4
	BNE	10$		; LOOP, UNLESS DONE
	DEC	R4
	BR	80$
60$:	MOV	R5,D.UR7	; Back up PC to our BPT.
	BR	80$
70$:	BPL	80$
	CMP	D.BKHI,R5
	BLO	90$
	CMP	R5,D.BKLO
	BLO	90$
80$:	CLRB	D.S
90$:	RETURN
	.SBTTL	D.SAVE	- Save the world
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.SAVE
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.SAVE:	POP$S	D.XXX		; PICK UP RETURN ADDRESS FROM STACK
.IF DF D.MCB
	MFPS	D.DPS		; Save DDT PS
	MOV	SP,D.DR6	; and stack pointer.
	MOV	4(SP),MMCHV	; Get mechanism
	MOV	6(SP),MSIGV	; and signal vector addresses.
	MOV	MMCHV,R0
	MOV	M.R0(R0),D.UR0 ; Get registers.
	.IRPC	rg,<12345>
	MOV	R'rg',D.UR'rg'
	.ENDM
	MOV	#172340,R1
	MOV	#MAPR,R2
	MOV	#8.,R3
10$:	MOV	(R1)+,(R2)+
	SOB	R3,10$
	MOV	M.AR5(R0),MAPR5
	SMAP$	MAPR6
	MOV	MSIGV,R0	; Get the signal vector
	MOV	R0,D.UR6	; to set default user stack pointer,
	MOV	-(R0),D.UR7	; user PC
	MOV	D.DPS,D.UPS	; and PS.
	CLRB	D.E		; Assume SIGNAL
	MOV	#S.SSTS,R2	; Check if it is an exception.
	CLR	R1
	MOV	2+2(R0),R0
	CALL	D.GTSS
	TST	R1
	BEQ	20$		; If so,
	COMB	D.E		; set hardware exception,
	MOV	MSIGV,R0	; get
	ADD	(R0)+,R0	; address
	ADD	@MSIGV,R0	; of
	MOV	(R0)+,D.UR7	; user PC,
	MOV	(R0)+,D.UPS	; user PS,
	MOV	R0,D.UR6	; user stack pointer.
	BIT	#140000,D.UPS
	BEQ	20$
	MFPI	SP
	POP$S	D.UR6
20$:
.IFF
	MOV	SP,D.UR6	; SAVE USER STACK ADDRESS
	MOV	#D.UR6,SP	; SET TO INTERNAL STACK
	PUSH$S	<R5,R4,R3,R2,R1,R0>
.IF DF D.GDP
	TRAP	72		; USECLR
D.SAV9:	NOP			; MAY HAVE USERET
	TRAP	107		; SCRUNB
.ENDC
.IFTF
	TST	D.SD.T		; TEST D.S AND D.T
	BNE	50$		; SKIP BREAKPOINTS IF SO
.IFT
	SMAP$S
.IFTF
	CLR	R1		; REMOVE ALL BREAKPOINTS
30$:	MOV	D.BKTB(R1),R4	; GET ADDRESS OF BREAKPOINT
	BEQ	38$		; BRANCH IF NOT FILLED
.IFT
	MAP$	D.BIAS(R1)
	MOV	D.UIN(R1),@D.ADDR(R1) ; RESTORE USER'S INSTRUCTION
.IFF
	MOV	D.UIN(R1),(R4)	; RESTORE USER'S INSTRUCTION
.IFTF
38$:	TST	(R1)+		; LOOP
	CMP	R1,#D.BKP*2	; AT END?
	BLE	30$		; RE-LOOP UNTIL DONE
.IFT
	MAP$S
.IFTF
50$:
.IFF
	MOV	#340,R1		; PS
	MOV	#4,R0		; START FILLING AT WORD 4
	PUSH$S	(R0)		; 4
	MOV	#D.SAV5,(R0)+	; INTERNAL NXMS
	PUSH$S	(R0)		; 6
	MOV	R1,(R0)+	; SET VECTOR PS
	PUSH$S	(R0)		; 10
	MOV	#D.SAV5,(R0)+	; INTERRUPT FOR ILLEGAL INSTRUCTION
	PUSH$S	(R0)		; 12
	MOV	R1,(R0)+	; SET VECTOR PS

	MOV	#D.BRKT,(R0)+	; BPT VECTOR
	MOV	R1,(R0)		; SET VECTOR PS
.IF NDF D.RSX
	PUSH$S	@#D.RCSR	; SAVE KEYBOARD STATUS
	CLR	@#D.RCSR	; TURN OFF ALL INTERRUPTS
.IF DF D.KSR!D.MCB
	PUSH$S	@#D.TCSR	; SAVE PRINTER STATUS
	CLR	@#D.TCSR	; REMOVE ALL ENABLES
.ENDC
.ENDC
	MOV	SP,D.DR6	; Set DDT stack pointer.
	MOVB	#2,D.MACH	; SET MACHINE TO 11/45
	SXT	R1		; 11/40,45 INSTRUCTION
	CMPB	D.MACH,#1	; 11/15?
	BEQ	70$		; BRANCH IF NOT
	MOV	#RTT,D.GO1	; USE RTT INSTRUCTION
70$:
.IF NDF D.RSX
	TST	@#177772	; WORD ONLY EXISTS ON 11/45
.ENDC
	MOV	#D.ERR,@#4	; RESET NXM ADDRESS
	MOV	#D.ILGT,@#10	; ILLEGAL INSTRUCTION
.IFTF
	MOV	#D.NLWD,D.CAD	; No word is open
	JMP	@D.XXX		; RETURN
.IFF

D.SAV5:	DECB	D.MACH		; IT FAILED, DIFFERENT MACHINE
	RTI			; RETURN
.ENDC
	.SBTTL	D.REST	- Restore the world
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.REST
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.REST:	POP$S	D.XXX		; GET RETURN ADDRESS FROM STACK
	TST	D.SD.T		; TEST D.S AND D.T
	BNE	30$		; SKIP BREAKPOINTS IF SO
.IF DF D.MCB
	SMAP$S
.IFTF
	MOV	#<D.BKP*2>,R1	; RESTORE ALL BREAKPOINTS
10$:	MOV	D.BKTB(R1),R4	; GET ADDRESS OF BREAKPOINT
	BEQ	18$		; BRANCH IF NO BREAKPOINT
.IFT
	MAP$	D.BIAS(R1)
	MOV	@D.ADDR(R1),D.UIN(R1) ; SAVE CONTENTS OF USER LOCATION
	MOV	#3,@D.ADDR(R1)	; and set BPT
.IFF
	MOV	(R4),D.UIN(R1)	; SAVE CONTENTS OF USER LOCATION
	MOV	#3,(R4)		; and set BPT
.IFTF
18$:	SUB	#2,R1		; DECREMENT
	BGE	10$		; RE-LOOP UNTIL DONE
.IFT
	MAP$S
.IFTF
30$:	MOV	D.DR6,SP	; Reset DDT stack.
.IFT
	TSTB	D.E		; If it is an exception
	BPL	50$		; then
	MOV	MSIGV,R0	; get
	ADD	(R0)+,R0	; address
	ADD	@MSIGV,R0	; of
	MOV	D.UR7,(R0)+	; and user PC.
	MOV	D.UPS,(R0)	; user PS,
	BR	60$
50$:	MOV	D.UPS,D.DPS
60$:	MOV	MMCHV,R0
	MOV	D.UR0,M.R0(R0)
	.IRPC	rg,<12345>
	MOV	D.UR'rg',R'rg'
	.ENDM
	MAP$	MAPR6
	MOV	MAPR5,M.AR5(R0)
	MTPS	D.DPS		; Reset DDT status.
.IFF
.IF NDF D.RSX
.IF DF D.KSR!D.MCB
	POP$S	@#D.TCSR	; PUT TELETYPE STATUS BACK
.ENDC
	POP$S	@#D.RCSR	; PUT KEYBOARD STATUS BACK
.ENDC
	MOV	#12,R0		; RESTORE HIS VECTORS
	POP$S	<(R0),-(R0),-(R0),-(R0)>
.IF DF D.RSX
	MOV	#D.SVDB,R0	;THIS IS THE WRONG WAY TO DO THIS, BUT TOO BAD!
	MOV	#D.TRPV,R1	;VECTOR OF TRAP VECTORS
	MOV	#10,R2		;LAST I COUNTED THERE WERE THIS MANY
40$:	MOV	@(R1)+,(R0)+	;MOVE ONE OF THEM
	SOB	R2,40$		;MOVE REST
	SVDB$S	#D.SVDB,#10
.ENDC
.IF DF D.GDP
	TRAP	144		; USERET
.ENDC
	POP$S	<R0,R1,R2,R3,R4,R5>
	MOV	(SP),SP		; RESTORE USER STACK
.ENDC
	JMP	@D.XXX		; AND RETURN
	.SBTTL	D.RFND	- Display Address
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.RFND
;
; INPUT PARAMETERS:
;	R0 = word to display.
;
; IMPLICIT INPUTS:
;	D.SVR4 =
;	D.FMT =
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	D.FIND =
;	D.LASW =
;	D.LASV =
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	Registers R0, R2 through R4 are modified.
;	Routines D.GTSM, D.TYPE and D.TYPN are called.
;--

	.PSECT	$CODE$,I
D.RFND:	PUSH$S	<R1,R0>		; SAVE R1 and ADDRESS FOR LATER
	CMP	R0,D.SVR4	; IS IT THE ADDRESS WE ARE LOOKING FOR?
	BNE	10$		; BRANCH IF NOT
	INCB	D.FIND		; MARK IT FOUND
10$:	TST	D.IFMT		; ABSOLUTE ADDRESSING?
	BNE	40$		; BRANCH IF SO
	CALL	D.GTSM		; GET SYMBOL (IF ANY)
	TST	R1		; ANY SYMBOL?
	BEQ	40$		; BRANCH IF NOT
	PUSH$S	R0
	CALL	D.STYP
	POP$S	R1		; GET OFFSET
	BEQ	50$		; BRANCH IF NONE
	MOV	#'+,R0		; MAKE A PLUS
	CALL	D.TYPE		; TYPE IT
	MOV	R1,R0		; GET OFFSET
40$:	CALL	D.TYPN		; TYPE THE NUMBER
50$:	MOV	(SP),D.LASW	; LAST TYPED WORD
	POP$S	<D.LASV,R1>	; LAST TYPED ADDRESS and R1
	RETURN			; RETURN
	.SBTTL	D.CADV	- Display Number at Current Address
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.CADV
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	D.BW =
;	D.CAD =
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	D.LFIN =
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	Registers R0 through R3 are modified.
;	Routines D.RFND and D.TYPN are called.
;--

	.PSECT	$CODE$,I
D.CADV:	CALL	D.FTCH		; Fetch the byte/word
	CMP	#1,D.BW		; BYTE MODE?
	BEQ	10$		; BRANCH IF SO
	CALL	D.RFND		; TYPE NUMBER
	BR	20$		; RETURN
10$:	CALL	D.TYPN		; TYPE IT
20$:	CLR	D.LFIN		; TURN OFF LINE-FEED SKIPPING
	RETURN			; RETURN
	.SBTTL	D.ASCI	- Display ASCII Bytes at Current Address
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.ASCI
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	D.CAD =
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	D.LASV =
;	D.LASW =
;	D.LFIN =
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	Registers R0 and R5 are modified.
;	Routine D.TYPE are called.
;--

	.PSECT	$CODE$,I
D.ASCI:	CALL	D.FTCH
	MOV	R0,D.LASV	; LAST TYPED DATA
	MOV	R0,D.LASW	; LAST TYPED WORD TOO
	CALL	D.TYPE		; TYPE IT
	CMP	#1,D.BW		; If in byte mode
	BEQ	10$		; then only one character.
	CLR	R0
	BISB	D.LASV+1,R0	; GET NEXT CHARACTER
	CALL	D.TYPE		; TYPE IT
10$:	CLR	D.LFIN		; TURN OFF LINE-FEED SKIPPING
D.RTS:	RETURN			; RETURN
	.SBTTL	D.PART	- Display Multi-byte Word at Current Address
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.PART
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	D.CAD =
;	D.SIZE =
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	D.LASV =
;	D.LASW =
;	D.LFIN =
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	Registers R0, R1, R2, R3 and R5 are modified.
;	Routines D.TYPN and D.TYPE are called.
;--

	.PSECT	$CODE$,I
D.PART:	CALL	D.FTCH		; Get byte/word.
	MOV	R0,D.LASV	; LAST TYPED DATA
	MOV	R0,D.LASW	; LAST TYPED WORD TOO
	MOV	R0,R5
	PUSH$S	#16.		; Assume 16 bits
	CMP	#1,D.BW		; and if byte
	BNE	10$		; then
	MOV	#8.,(SP)	; set as 8 bits.
10$:	MOV	R5,R0		; ACCUMULATOR FOR BYTE
	MOV	#177777,R3	; MASK FOR BYTE
	MOV	D.SIZE,R2	; BYTE SIZE
20$:	ASR	R5		; REMOVE ONE BIT
	ASL	R3		; ONE MORE BIT IN MASK
	DEC	(SP)		; ONE LESS BIT IN WORD
	BLE	30$		; EXIT IF DONE
	DEC	R2		; ONE LESS BIT IN BYTE
	BGT	20$		; LOOP IF NOT DONE
30$:	BIC	R3,R0		; MASK WORD
	CALL	D.TYPN		; TYPE BYTE
	TST	(SP)		; ALL DONE?
	BLE	40$		; BRANCH IF SO
	MOV	#',,R0		; COMMA
	CALL	D.TYPE		; TYPE IT
	BR	10$		; GET NEXT BYTE
40$:	POP$S	,1		; FIX STACK
	CLR	D.LFIN		; TURN OFF LINE-FEED SKIPPING
	RETURN			; RETURN
	.SBTTL	D.RADC	- Display Radix-50 Word at Current Address
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.RADC
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	D.CAD =
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	D.SYM =
;	D.LASV =
;	D.LASW =
;	D.LFIN =
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	Registers R0 through R4 are modified.
;	Routines , D.CHAR and D.STYP are called.
;--

	.PSECT	$CODE$,I
D.RADC:	CMP	#1,D.BW		; If in byte mode
	BEQ	90$		; then display as numeric.
	CALL	D.FTCH		; Fetch the word
	MOV	#D.SYM,R1	; ADDRESS FOR RESULT
	CALL	D.CHAR		; MAKE CHARACTERS OF IT
	CLRB	(R1)
	MOV	#D.SYM,R1	; ADDRESS OF FIRST CHARACTER
	CALL	D.STYP		; TYPE THEM
	MOV	D.CAD,R4
	CALL	D.GETW
	MOV	R0,D.LASV	; LAST TYPED DATA
	MOV	R0,D.LASW	; LAST TYPED WORD TOO
	CLR	D.LFIN		; TURN OFF LINE-FEED SKIPPING
	RETURN			; RETURN
90$:	JMP	D.CADV		; Display as numeric.
	.SBTTL	D.INST	- Display Instruction at Current Address
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.INST
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	D.CAD =
;	D.DOT =
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	D.LFIN =
;	D.LASW =
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	Registers R0 through R5 are modified.
;	Routines D.TTAB, D.DC49 and D.STYP are called.
;--
	.PSECT	$PLIT$,D
	.EVEN
D.REGT:	.IRP	rg,<R0,R1,R2,R3,R4,R5,SP,PC>
	.WORD	"rg
	.ENDM

	.PSECT	$CODE$,I
D.INST:	CMP	#1,D.BW		; If in byte mode
	BEQ	90$		; then just type value.
	MOV	D.CAD,R5	; PUT CURRENT ADDRESS INTO DECODE
.IF DF D.MCB
	CMP	#177700,R5	; and if in registers
	BLOS	90$		; then use numeric typeout.
.ENDC
	CALL	D.TTAB		; TYPE TAB
	CALL	D.DC49		; DECODE IT
	SUB	D.CAD,R5	; GET INSTRUCTION LENGTH
	TST	-(R5)		; DECREMENT TO BE OFFSET OF INSTR
	CMP	D.DOT,D.CAD	; ARE WE AT THE DOT?
	BNE	10$		; DON'T SET INCREMENT IF NOT
	MOV	R5,D.LFIN	; PUT IN LINE-FEED INCREMENT
10$:	CALL	D.FTCH
	MOV	R0,D.LASW	; LAST TYPED WORD
	RETURN			; RETURN
90$:	JMP	D.CADV		; Display as numeric.
.PAGE
; TYPE WORD(S) AT R5 IN INSTRUCTION FORMAT

	.ENABL	LSB
D.DC49:	PUSH$S	R4
	MOV	R5,R4
	CALL	D.GETW
	POP$S	R4
	ADD	#2,R5
	MOV	#D.TOPS+2,R1	; POINT TO ARRAY OF INSTRUCTION VALUES
	MOV	R0,R4		; SAVE INSTRUCTION
	CLR	R3		; DON'T TYPE A "B"
	BIC	#100000,R0	; START OUT LOOKING FOR INS. WITHOUT "B"
10$:	CMP	R0,(R1)+	; DOES INSTRUCTION FALL IN HERE?
	BHI	10$		; NO, LOOP
	CMP	R4,R0		; DID WE GET REAL INSTRUCTION MATCH?
	BEQ	20$		; YES
	MOV	R4,R0		; NO, BUT DO SO NEXT TIME
	TSTB	D.LEGS-D.TOPS-4(R1)	; BYTE INSTRUCTION?
	BPL	10$		; NO!
	DEC	R3		; PRINT A  "B"
20$:	MOVB	D.LEGS-D.TOPS-4(R1),R2	; GET LEGAL CONSIDERATION BYTE
	BIC	#^C3,R2		; CLEAR HIGH BITS
	CMPB	R2,D.MACH	; MACHINE TYPE RIGHT?
	BGT	D.N16		; TYPE NUMBER IF BAD
	ADD	#D.COUS-D.TOPS-4,R1	; ADD IN ADDRESS OF STRING
	MOV	(R1)+,R2	; GET OFFSET OF CHARACTERS
	BIC	#^C377,R2	; TURN OFF EXTRA CRUFT
30$:	CMPB	R2,(R1)		; AT END?
	BEQ	40$		; BRANCH IF SO
	MOVB	D.STRS(R2),R0	; GET A CHARACTER
	CALL	D.TYPE		; TYPE IT
	INC	R2		; NEXT CHARACTER
	BR	30$		; LOOP
40$:	TST	R3		; BYTE INSTRUCTION?
	BEQ	50$		; BRANCH IF NOT
	MOV	#'B,R0		; BYTE INSTRUCTION: TYPE "B"
	CALL	D.TYPE		; TYPE IT
50$:	MOVB	-(R1),R3	; RE-GET LEGALITY BYTE
	BIC	#^C<17*4>,R3	; GET LEGAL CONSIDERATION
	CMP	R3,#10		; TYPE A SPACE AFTER OP-CODE?
	BLE	60$		; BRANCH IF NOT
	MOV	#' ,R0		; SPACE
	CALL	D.TYPE		; TYPE IT
60$:	MOV	R4,R0		; GET INSTRUCTION BACK
	ASL	R4		; GET OPERAND THAT STARTS AT BIT 6
	ASL	R4		; WITH TWO SHIFTS AND...
	SWAB	R4		; A SWAB
	ASR	R3
	JMP	@D.PARM(R3)	; TYPE PARAMETERS
70$:	MOV	R0,R1		; GET R1 FOR D.DC5
	ADD	#D.MOD7,R1	; DISPLACEMENT OF OPENING CHARACTERS
	MOVB	(R1),R2		; GET OFFSET OF CHARACTERS
	CMPB	D.FIRS(R2),#'?	; IS IT LEGAL?
	BEQ	90$		; BRANCH IF NOT
	CALL	D.DC5		; TYPE THEM
	PUSH$S	<R0,R4>
	MOV	R5,R4
	CALL	D.GETW		; GET INSTRUCTION INTO R0
	POP$S	R4
	ADD	#2,R5
	CMP	(SP)+,#6	; RELATIVE ADDRESSING?
	BCS	D.N16		; BRANCH IF IMMEDIATE
80$:	ADD	R5,R0		; FUDGE FOR RELATIVE.
D.N16:	JMP	D.RFND		; TYPE IN CURRENT ADDRESSING MODE

D.SSDD:	PUSH$S	R0		; SAVE SECOND PARAMETER
	MOV	R4,R0		; GET FIRST ONE
	CALL	D.DD		; TYPE IT
	BR	D.SS		; DO THE REST
D.CZVN:	MOV	#D.NZVC,R1	; LOOP ON BITS OF CODE
	MOV	R0,R2		; SAVE OPERATION IN R2
	CALL	(PC)		; DO WHAT FOLLOWS TWICE
	CALL	(PC)		; NO, I MEAN 4 TIMES
	MOVB	(R1)+,R0	; GET CHARACTER
	ROR	R2		; TEST A BIT
	BCC	130$		; BRANCH IF NOT ON
	JMP	D.TYPE		; TYPE IT AND RETURN
D.N3:	BIC	#^C7,R0		; MASK OUT ALL BUT LOW 3 BITS
D.N6:	BIC	#^C77,R0	; MASK OUT ALL BUT LOW 6 BITS
D.N8:	BIC	#^C377,R0	; MASK OUT ALL BUT LOW 8 BITS
	JMP	D.TYPN		; TYPE THE NUMBER
D.RN6:	PUSH$S	R0		; SAVE R0
	MOV	R4,R0		; GET FIRST PARAMETER
	CALL	D.R		; TYPE AS REGISTER
	MOV	#',,R0		; INSERT COMMA BETWEEN PARAMETERS
	CALL	D.TYPE		; TYPE IT
	POP$S	R0		; GET SECOND PARAMETER
	BIS	#300,R0		; TURN ON HIGH TWO BITS IN LOW BYTE
D.X8:	MOVB	R0,R0		; SIGN EXTEND
	ASL	R0		; MULTIPLY BY 2
	BR	80$		; DO THE REST AND RETURN
D.RDD:	PUSH$S	R0		; SAVE SECOND PARAMETER
	MOV	R4,R0		; GET FIRST ONE
	CALL	D.R		; TYPE AS A REGISTER
D.SS:	MOV	#',,R0		; PUT COMMA...
	CALL	D.TYPE		; ... INBETWEEN PARAMETERS
	POP$S	R0		; GET SECOND PARAMETER

D.DD:				; THIS ROUTINE TYPES A MODE/REGISTER OPERAND IN R0
	MOV	R0,R3		; LOW 6 BITS OF R0 HAVE MODE/REG
	BIC	#^C7,R3		; R3 HAS REGISTER
	ASR	R0		; GET MODE
	ASR	R0		; BY SHIFTING
	ASR	R0		; INTO LOW BITS
	BIC	#^C7,R0		; R0 HAS MODE
	CMP	R3,#7		; PC ADDRESSING?
	BEQ	70$		; BRANCH IF SO
90$:	PUSH$S	R0		; MAKE THIS SAVED DATA
	MOV	R0,R1		; PUT IN R1 FOR D.DC5
	ADD	#D.OPCH,R1	; ADD IN DISPLACEMENT OF SPECIAL CHARACTERS
	CALL	D.DC5		; TYPE PRECEDING CHARACTERS
	PUSH$S	R3		; SAVE R3
	CMP	R0,#6		; IS THERE AN INDEX?
	BLT	100$		; BRANCH IF NOT
	PUSH$S	R4
	MOV	R5,R4
	CALL	D.GETW		; PUT ADDRESS IN R0
	POP$S	R4
	ADD	#2,R5
	CALL	D.RFND		; TYPE ADDRESS AND OFFSET
	MOV	#'(,R0		; PUT "(" IN OUTPUT
	CALL	D.TYPE		; TYPE IT
100$:	POP$S	R0		; GET REGISTER
	CALL	D.R		; TYPE REGISTER NUMBER
	POP$S	R1		; RESTORE MODE
	ADD	#D.CLOS,R1	; ADD IN CLOSING CHARACTERS

D.DC5:				; THIS ROUTINE TYPES A STRING INDEXED BY R1
	PUSH$S	R0		; SAVE R0
	MOVB	(R1)+,R2	; GET OFFSET OF CHARACTERS
110$:	MOVB	D.FIRS(R2),R0	; GET CHARACTER
	BEQ	120$		; SKIP IF NULL CHARACTER
	CALL	D.TYPE		; TYPE IT
120$:	INC	R2		; NEXT CHARACTER
	CMPB	R2,(R1)		; AT END?
	BLO	110$		; BRANCH IF NOT
	POP$S	R0		; RETURN R0
130$:	RETURN			; RETURN

D.DDR:	PUSH$S	R4		; SAVE FIRST PARAMETER
	CALL	D.DD		; TYPE SECOND PARAMETER
	MOV	#',,R0		; COMMA
	CALL	D.TYPE		; TYPE IT
	POP$S	R0		; RESTORE REGISTER

D.R:	BIC	#^C7,R0		; Isolate the reigster
	ASL	R0		; and index
	MOV	D.REGT(R0),R1	; into register name table.
	CALL	(PC)		; Do this twice:
	MOVB	R1,R0		; copy next character
	SWAB	R1		; switch them
	JMP	D.TYPE		; and type the character.
	.DSABL	LSB
	.SBTTL	M.PROC	- Display Current Process Name
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	M.PROC
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	Registers R0 through R3 are modified.
;	Routine D.TYPE is called.
;--
.IF DF D.MCB
	.PSECT	$PLIT$,D
INRSX:	.ASCIZ	"RSX-"
INMCB:	.ASCIZ	"MCB-"
INEXEC:	.ASCIZ	"executive"
ININTR:	.ASCIZ	"interrupt"
INNULL:	.ASCIZ	"null task"

	.PSECT	$CODE$,I
M.PROC:	TST	.CEXDP
	BPL	20$
	MOV	#INRSX,R1
	CALL	D.STYP
	CMP	$STKDP,#-1
	BLT	50$		; RSX-interrupt
	BEQ	40$		; RSX-executive
	TST	$HEADR
	BEQ	10$		; RSX-null task
	MOV	$TKTCB,R1	; RSX-task
	PUSH$S	T.NAM+2(R1)
	MOV	T.NAM(R1),R0
	MOV	#D.SYM,R1
	CALL	D.CHAR
	POP$S	R0
	CALL	D.CHAR
	BR	74$
10$:	MOV	#INNULL,R1
	BR	80$
20$:	MOV	#INMCB,R1
	CALL	D.STYP
	TST	.INTCB
	BNE	60$		; MCB-interrupt
	CMP	@.PDBVB,MAPR5
	BEQ	40$		; MCB-executive
	MAP$	@.CRPDB		; MCB process
	MOV	@#PHDNAM+20000,R0
	PUSH$S	R0
	MOV	#D.SYM,R1
	CALL	D.CHAR
22$:	CMPB	#' ,-(R1)
	BEQ	22$
	CLRB	1(R1)
	MOV	#D.SYM,R1
	MAP$	MAPR5
	CMP	@#PHDNAM+20000,(SP)+
	BEQ	80$
	CALL	D.STYP
	BR	70$
40$:	MOV	#INEXEC,R1
	BR	80$
50$:	MOV	#ININTR,R1
	BR	80$
60$:	MOV	#ININTR,R1
	CALL	D.STYP
	MAP$	MAPR5
70$:	MOVB	#'>,R0
	CALL	D.TYPE
	MOV	@#PHDNAM+20000,R0
	MOV	#D.SYM,R1
	CALL	D.CHAR
74$:	CMPB	#' ,-(R1)
	BEQ	74$
	CLRB	1(R1)
	MOV	#D.SYM,R1
80$:	JMP	D.STYP
.ENDC
	.SBTTL	D.TTAB	- Display a Tab Character
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.TTAB
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	D.NOTY = don't display if non-zero.
;	D.CPOS = current horizontal carriage position.
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	D.CPOS = current horizontal carriage position.
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	Register R0 is modified.
;	Routine D.TYPE is called.
;--

	.PSECT	$CODE$,I
D.TTAB:
.IF NDF D.KSR
	MOVB	D.TDSP,R0	; Tab display character.
	BNE	D.TYPE
.IFTF
10$:	TSTB	D.NOTY		; IN NON-TYPEOUT MODE?
	BNE	90$		; EXIT IF SO
	MOVB	#' ,R0		; SPACE
	CALL	D.TYPE		; TYPE IT
	BITB	#7,D.CPOS	; ON A MULTIPLE OF 8?
	BNE	10$		; LOOP ON SPACES IF NOT
90$:	RETURN			; RETURN
.ENDC
	.SBTTL	D.CRLF	- Display a CR/LF
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.CRLF
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	Registers R0 through R2 are modified.
;	Routine D.STYP is called.
;--

	.PSECT	$CODE$,I
D.CRLF:	MOV	#D.CR,R1	; FWA <CR,LF>
	BR	D.STYP
	.SBTTL	D.STYP	- Display a Local ASCII String
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.STYP
;
; INPUT PARAMETERS:
;	R1 = address of ASCIZ string.
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	Registers R0 and R1 are modified.
;	Routine D.TYPE is called.
;--

	.PSECT	$CODE$,I
D.STY1:	CALL	D.TYPE		; TYPE ONE CHARACTER
D.STYP:	MOVB	(R1)+,R0	; GET A CHARACTER
	BNE	D.STY1
	RETURN
	.SBTTL	D.TYPN	- Display a Number in the Current Radix
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.TYPN
;
; INPUT PARAMETERS:
;	R0 = number to be displayed.
;
; IMPLICIT INPUTS:
;	D.DVTB = radix to type number in.
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	D.LASV = last number to be typed.
;	D.LASW = last word to be typed.
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	Registers R0 through R3 are modified.
;	Routines D.DIVD and D.TYPE are called.
;--

	.PSECT	$CODE$,I
D.TYPN:	MOV	R0,D.LASV	; MARK LAST NUMBER TYPED
	MOV	R0,D.LASW	; LAST TYPED WORD TOO
	MOV	D.DVTB,R2	; GET RADIX
.IF DF D.MCB
	MOV	R0,R1
	CMP	#10.,R2
	BNE	60$
	TST	R1
	BPL	10$
	MOVB	#'-,R0
	CALL	D.TYPE
	NEG	R1
10$:	CALL	60$
	MOV	#'.,R0
	BR	68$

60$:	CLR	R0
62$:	DIV	R2,R0
	PUSH$S	R1
	MOV	R0,R1
	BEQ	64$
	CALL	60$
64$:	POP$S	R0
	CMP	#10.,R0
	BHI	66$
	ADD	#'A-'0-10.,R0
66$:	ADD	#'0,R0
68$:	JMP	D.TYPE
.IFF
	CMP	#10.,R2		; DECIMAL?
	BEQ	40$		; YES
10$:	CALL	D.DIVD		; DIVIDE IT.
	ADD	#60,R1		; CONVERT REMAINDER TO ASCII
	PUSH$S	R1		; AND SAVE IT.
	TST	R0		; DONE?
	BEQ	30$		; YES, TYPE THE DIGIT AND RETURN
20$:	CALL	10$		; CALL OURSELF RECURSIVELY
30$:	POP$S	R0		; RESTORE THE DIGIT
	BR	D.TYPE		; PRINT IT, AND RETURN

40$:	PUSH$S	#'.		; PUT A . AT THE END OF THE NUMBER
	MOV	R0,R3		; GET THE NUMBER
	BPL	20$		; AND TYPE IF POSITIVE
	MOV	#'-,R0		; ELSE PRINT A -
	CALL	D.TYPE
	MOV	R3,R0		; RESTORE NUMBER
	NEG	R0		; BUT TAKE ABSOLUTE VALUE
	BR	20$
.ENDC
	.SBTTL	D.TYPE	- Display a Character on the Controlling TTY
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.TYPE
;
; INPUT PARAMETERS:
;	R0 = character to display.
;
; IMPLICIT INPUTS:
;	D.NOTY = don't display if non-zero.
;	D.CPOS = current horizontal carriage position.
;	D.TCSR = address of transmit status register.
;	D.TDB = address of transmit data buffer.
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	D.CPOS = current horizontal carriage position.
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	Register R0 is modified.
;	Routine D.POLL is called.
;--

	.PSECT	$CODE$,I
D.TYPE:	TSTB	D.NOTY		; SHOULD WE TYPE?
	BNE	90$		; BRANCH IF NOT
.IF DF D.GDP
	TRAP	120		; SCRRTN
.ENDC
.IF DF D.GT40
	EMT	0
.ENDC
.IF DF D.KSR!D.MCB
	CALL	20$		; TYPE CHARACTER
	CMPB	#15,R0		; CARRIAGE RETURN?
	BEQ	10$		; ZERO POSITION COUNTER IF SO
	BITB	#140,R0		; CONTROL CHARACTER?
	BEQ	90$		; RETURN IF SO
	INCB	D.CPOS		; INCREMENT CHARACTER POSITION
	CMPB	#D.TCOL,D.CPOS
	BHI	90$		; RETURN IF NOT
	CALL	40$
10$:	CLRB	D.CPOS		; CLEAR CHARACTER POSITION
	RETURN			; RETURN
20$:	TSTB	@#D.TCSR	; PRINTER READY FOR CHARACTER?
	BPL	20$		; LOOP IF NOT
	MOVB	R0,@#D.TDB	; PUT OUT CHARACTER
	CALL	D.POLL		; CHECK FOR TYPED-IN CHARACTERS
.ENDC
.IF DF D.RSX
	MOV	R0,D.BUFR
	QIOW$S	#IO.WLB,#LUNTI,#52.,,,,<#D.BUFR,#1>
.ENDC
	RETURN			; RETURN
40$:	PUSH$S	R0		; SAVE CHARACTER
	MOV	#15,R0		; YES, GENERATE CARRIAGE RETURN
	CALL	20$		; TYPE IT
	MOV	#12,R0		; AND A LINE FEED
	CALL	20$		; TYPE IT
	POP$S	R0		; RESTORE CHARACTER
90$:	RETURN
	.SBTTL	D.GET	- Get a Character from the Controlling TTY
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.GET
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	D.RCSR = address of receive status register.
;	D.RDB = address of receive data buffer.
;	D.INPU = ring buffer pointer to insert next character.
;	D.OUTP = ring buffer pointer to extract next character.
;	D.BUFR = beginning of ring buffer.
;	D.ENDB = end of ring buffer.
;
; OUTPUT PARAMETERS:
;	R0 = received character.
;
; IMPLICIT OUTPUTS:
;	D.OUTP = ring buffer pointer to extract next character.
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	Routines D.POLL and D.TYPE are called.
;--

	.PSECT	$CODE$,I
D.GET:
.IF DF D.RSX
	QIOW$S	#IO.RLB!TF.RAL!TF.RNE,#LUNTI,#52.,,#D.STS,,<#D.BUFR,#1>
	BCC	20$		;CHECK FOR ERROR
10$:	EXIT$S			;CAN'T DO MUCH IF TTY DOESN'T WORK!

20$:	MOV	D.BUFR,R0	;GET IT
	BIC	#^C177,R0	;CLEAR PARITY BIT
	CMP	#3,R0		;JUST GOT A CTRL/C?
	BEQ	10$		;YES, EXIT
.IFF
.IF NDF D.KSR&D.MCB
	TSTB	@#D.RCSR	; CHARACTER TYPED?
	BPL	D.GET		; LOOP UNTIL FOUND
	MOVB	@#D.RDB,R0	; GET A CHARACTER
.ENDC
.ENDC
.IF DF D.KSR!D.MCB
	CALL	D.POLL		; CHECK FOR CHARACTERS IN I/O BUFFER
	CMP	D.INPU,D.OUTP	; ANY CHARACTERS TYPED?
	BEQ	D.GET		; LOOP IF BUFFER EMPTY
	MOVB	@D.OUTP,R0	; GET CHARACTER FROM BUFFER
	INC	D.OUTP		; POINT TO NEXT CHARACTER
	CMP	D.OUTP,#D.ENDB	; AT END OF BUFFER?
	BNE	30$		; BRANCH IF NOT
	MOV	#D.BUFR,D.OUTP	; WRAP-AROUND
30$:
.ENDC
.IF DF D.GDP
	TRAP	64		; KEYASC
.ENDC
	BIC	#^C177,R0	; CLEAR META, CNTL AND SHIFT STUFF
	MOV	R0,R1		; EXACT (UNFOLDED COPY IN R1)
	BEQ	D.GET		; IGNORE NULLS
	CMPB	#15,R0		; SEE IF A <CR>
	BNE	40$		; BRANCH IF NOT
	MOV	#12,R0		; LINE FEED
	CALL	D.TYPE		; TYPE IT
	MOV	#15,R0		; RESET TO CR
40$:	CMPB	#177,R0		; IS IT A BACKSPACE
	BEQ	70$		; GUARANTEED TO GET A ?
	CMP	#12,R0		; IS IT A LINE FEED?
	BEQ	50$		; IF SO, SAVE THE PAPER
	CMPB	#33,R0		; IS IT AN ESCAPE?
	BEQ	60$		; TYPE DOLLAR SIGN IF SO
.IF DF D.KSR!D.MCB
	CMPB	#175,R0		; IS IT AN ALTMODE?
	BLE	60$		; TYPE DOLLAR SIGN IF SO
.ENDC
	CALL	D.TYPE		; ECHO CHARACTER
	CMPB	#'a,R0		; FOLD TO UPPER CASE
	BGT	50$		; BRANCH IF NOT A LETTER
	CMPB	#'z,R0		; IS IT IN ALPHABET?
	BLT	50$		; BRANCH IF STILL NOT
	SUB	#'a-'A,R0	; FOLD DOWN
50$:	RETURN			; RETURN
60$:	MOV	#'$,R0		; DOLLAR SIGN
	CALL	D.TYPE		; TYPE IT
	MOV	#33,R0		; RESTORE R0
	RETURN			; RETURN
70$:	MOV	#'X,R0		; TYPE "XXX"
	CALL	D.TYPE		; TYPE FIRST
	CALL	D.TYPE		; TYPE SECOND
	CALL	D.TYPE		; TYPE THIRD
	CALL	D.TTAB		; TYPE TAB
	JMP	D.DCD		; AND PROCESS NEW COMMAND
	.SBTTL	D.POLL	- Poll for a Received Character from the TTY
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.POLL
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	D.RCSR = address of receive status register.
;	D.RDB = address of receive data buffer.
;	D.INPU = ring buffer pointer to insert next character.
;	D.BUFR = beginning of ring buffer.
;	D.ENDB = end of ring buffer.
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	D.INPU = ring buffer pointer to insert next character.
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--
.IF DF D.KSR!D.MCB

	.PSECT	$CODE$,I
D.POLL:	TSTB	@#D.RCSR	; ANY CHARACTER TYPED?
	BPL	10$		; BRANCH IF NOT
	MOVB	@#D.RDB,@D.INPU	; PUT CHARACTER IN BUFFER
	INC	D.INPU		; NEXT
	CMP	D.INPU,#D.ENDB	; AT END OF BUFFER?
	BNE	10$		; BRANCH IF NOT
	MOV	#D.BUFR,D.INPU	; WRAP-AROUND
10$:	RETURN			; RETURN
.ENDC
	.SBTTL	M.TTCK	- Check if TTY Requested Interrupt
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	M.TTCK
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	C-bit set = TTY interrupt not requested.
;	C-bit clear = TTY interrupt requested.
;
; SIDE EFFECTS:
;	None
;--
.IF DF D.MCB

	.PSECT	$CODE$,I
M.TTCK:	MOV	MTTBK,R0
	BEQ	80$
	TST	MT.INT(R0)
	BEQ	80$
	CLR	MT.INT(R0)
	BIC	#20,D.UPS
	MOVB	#1,D.S
	MOV	#1,D.CT+<D.BKS*2>
	TST	(PC)+
80$:	SEC
90$:	RETURN
.ENDC
	.SBTTL	M.TTIN	- TTY Interrupt Code
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	Through TTY interrupt vector.
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

.IF DF D.MCB
	.PSECT	$PLIT$,D
	.EVEN
M.TTIN:	CMP	@#KISAR5,(PC)+
MT.AR5	= .-M.TTIN
	.WORD	0
	BEQ	30$
	MOVB	@#D.RDB,-(SP)
	BIC	#^C177,(SP)
	CMPB	#'D-100,(SP)+
	BNE	30$
	INC	(PC)+
MT.INT	= .-M.TTIN
	.WORD	0
	BIT	#140000,2(SP)
	BNE	20$
10$:	BIS	#20,2(SP)
	RTI
20$:	MFPS
	JSR	PC,10$
	RTI
30$:	JMP	@(PC)+
MT.ADR	= .-M.TTIN
	.WORD	0
MT.TLN	= .-M.TTIN
	RTI
.ENDC
	.SBTTL	M.TTON	- Enable TTY Interrupts
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	M.TTON
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--
.IF DF D.MCB

	.PSECT	$CODE$,I
M.TTON:	TST	MTTBK
	BNE	60$
	MOV	#2+MT.TLN,R1
	CALL	$ALOCB
	BCS	90$
	MOV	R1,(R0)+
	MOV	R0,R3
	MOV	#M.TTIN,R2
	MOV	#MT.TLN/2,R1
10$:	MOV	(R2)+,(R0)+
	SOB	R1,10$
	MOV	@#KISAR5,MT.AR5(R3)
	MOV	@#60,-(R0)
	CMP	@#64,(R0)
	BNE	20$
	CLR	(R0)
	MOV	(R2),-(R0)
20$:	MOV	R3,MTTBK
	MOV	R3,@#60
60$:	TST	@#D.RDB
	BIS	#100,@#D.RCSR
90$:	RETURN
.ENDC
	.SBTTL	M.TTOF	- Disable TTY Interrupts
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	M.TTOF
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--
.IF DF D.MCB

	.PSECT	$CODE$,I
M.TTOF:	MOV	MTTBK,R0
	BEQ	90$
	CLR	MTTBK
	MOV	MT.ADR(R0),R1
	BNE	10$
	BIC	#100,@#D.RCSR
	MOV	@#64,R1
10$:	MOV	R1,@#60
	MOV	-(R0),R1
	CALL	$DEACB
90$:	RETURN
.ENDC
	.SBTTL	M.SNCK	- Check if Trap caused by DDT Synch
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	M.SNCK
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	C-bit set = SYNCH not effected.
;	C-bit clear = SYNCH sprung.
;
; SIDE EFFECTS:
;	None
;--
.IF DF D.MCB

	.PSECT	$CODE$,I
M.SNCK:	MOV	MSNBK,R0
	BEQ	80$
	TST	MS.INT(R0)
	BEQ	80$
	CLR	MSNBK
	MOVB	#1,D.S
	MOV	#1,D.CT+<D.BKS*2>
	TST	(PC)+
80$:	SEC
90$:	RETURN
.ENDC
	.SBTTL	M.SNIN	- Synchronization Code
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	Through $SYNCH dispatch
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

.IF DF D.MCB
	.PSECT	$PLIT$,D
	.EVEN
M.SBLK:	.WORD	0
MS.PDB	= .-M.SBLK
	.WORD	0
MS.ADR	= .-M.SBLK
	.WORD	M.SNIN-M.SBLK
M.SNIN:	PUSH$S	R4
	CALL	10$
	POP$S	R0
	MOV	-(R0),R1
	JMP	@#$DEACB
10$:	INC	(PC)+
MS.INT	= .-M.SBLK
	.WORD	0
	BPT
	RETURN
MS.NLN	= .-M.SBLK
.ENDC
	.SBTTL	M.SNOF	- Cancel a Process Synchronization
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	M.SNOF
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--
.IF DF D.MCB

	.PSECT	$CODE$,I
M.SNOF:	MOV	MSNBK,R0
	BEQ	90$
	CLR	MSNBK
	CMP	.SYNQH,R0
	BEQ	70$
	MOV	(R0),.SYNQH+0
	BNE	70$
	MOV	#.SYNQH,.SYNQH+2
70$:	MOV	-(R0),R1
	CALL	$DEACB
90$:	RETURN
.ENDC
	.SBTTL	M.SNON	- Set Up to Synchronize with Process
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	M.SNON
;
; INPUT PARAMETERS:
;	R4 = PIX of process to activate.
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	Register R4 is modified
;--
.IF DF D.MCB

	.PSECT	$CODE$,I
M.SNON:	MOV	MSNBK,R3
	BNE	80$
	MOV	#2+MS.NLN,R1
	CALL	$ALOCB
	BCS	90$
	MOV	R1,(R0)+
	MOV	R0,R3
	MOV	#M.SBLK,R2
	MOV	#MS.NLN/2,R1
10$:	MOV	(R2)+,(R0)+
	SOB	R1,10$
	ADD	R3,MS.ADR(R3)
	MOV	.SYNQH+0,(R3)
	BNE	70$
	MOV	R3,.SYNQH+2
70$:	MOV	R3,.SYNQH+0
	INC	.CEXRQ
	MOV	R3,MSNBK
80$:	ASL	R4
	MOV	.PDBVB(R4),MS.PDB(R3)
90$:	RETURN
.ENDC
	.SBTTL	M.USCK	- Check if Break in User Space Caused by MDT
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	M.USCK
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	Register R0 is modified
;--
.IF DF D.MCB

	.PSECT	$CODE$,I
M.USCK:	MOV	#140020,R0	; If user space
	BIC	D.UPS,R0	; and t-bit on
	BNE	80$		; and
	TSTB	D.T		; not proceeding after a break
	BGT	80$		; then
	BIC	#20,D.UPS	; turn off T-bit,
	MOV	@#$HEADR,R0	; get header
	BIC	#20,H.IPS(R0)	; to clear the T-bit in initial PS,
	MOVB	#1,D.S		; and simulate
	MOV	#1,D.CT+<D.BKS*2> ; a single step.
	TST	(PC)+
80$:	SEC
	RETURN
.ENDC
	.SBTTL	M.USON	- Set Up to Synchronize with Task
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	M.USON
;
; INPUT PARAMETERS:
;	R4 = TCB of task to break into.
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	Register R0 is modified
;--
.IF DF D.MCB

	.PSECT	$CODE$,I
M.USON:	CMP	@#$TKTCB,R4
	BNE	10$
	BIS	#20,$STACK-2	; Set the current task T-bit
	BR	90$
10$:	TST	T.STAT(R4)	; Check TS.EXE
	BMI	20$		; and if executing
	MOV	T.PCB(R4),R0	; then follow the PCB
	MOV	P.HDR(R0),R0	; to the header
	MOV	H.GARD(R0),R0	; to the guard word
	BIS	#20,-<8.*2>(R0)	; and set the T-bit in the PS.
	BR	90$		; Not executing:
20$:	MOV	T.PCB(R4),R0	; follow the PCB
	MOV	P.HDR(R0),R0	; to the header
	BIS	#20,H.IPS(R0)	; and set the T-bit in initial PS.
90$:	MOV	#240,$EX14+0	; Allow user breakpoints
	MOV	#240,$EX14+2
	MOV	#240,$EX14+4
	RETURN
.ENDC
	.SBTTL	D.RD50	- Convert three ASCII Characters to Radix-50 Word
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.RD50
;
; INPUT PARAMETERS:
;	R0 = address of character string.
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	R0 = Radix-50 word
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.RD50:	PUSH$S	<R2,R1,#-3>	; SAVE R2, R1 and character looper.
	CLR	R1		; NOW CLEAR IT
10$:	CLR	R2		; OFFSET OF CHARACTERS
20$:	CMPB	D.RDTB(R2),(R0)	; CHARACTER MATCH?
	BEQ	30$		; BRANCH IF SO
	INC	R2		; NEXT CHARACTER
	CMP	R2,#D.ENTB	; AT END OF TABLE
	BLT	20$		; BRANCH IF NOT
	JMP	D.ERR		; BAD CHARACTERS
30$:
.IF DF D.MCB
	MUL	#50,R1		; multiply by 50
.IFF
	ASL	R1		; MULTIPLY BY 2
	ASL	R1		; MULTIPLY BY 4
	ASL	R1		; MULTIPLY BY 8
	PUSH$S	R1		; STORE AWAY
	ASL	R1		; MULTIPLY BY 16
	ASL	R1		; MULTIPLY BY 32
	ADD	(SP)+,R1	; ADD 8X TO MAKE IT 40X
.ENDC
	ADD	R2,R1		; PUT IN NEW CHARACTER
	INC	R0		; POINT TO NEXT CHARACTER
	INC	(SP)		; INCREMENT LOOPER
	BMI	10$		; BRANCH IF MORE
	POP$S	,1		; RESET STACK
	MOV	R1,R0		; RESULT IN R0
	POP$S	<R1,R2>		; RESTORE R1 and R2
	RETURN			; RETURN
	.SBTTL	D.CHAR	- Convert Radix-50 Word to three ASCII Characters
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.CHAR
;
; INPUT PARAMETERS:
;	R1 = address of character buffer.
;	R0 = Radix-50 word.
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	R1 = adjusted to point past characters inserted in buffer.
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	Registers R0, R2 and R3 are modified.
;--

	.PSECT	$CODE$,I
D.CHAR:	MOV	R1,R3		; INDEX HERE SINCE D.DIVD WILL USE R1
.IF DF D.MCB
	MOV	R0,R1
	CLR	R0
	DIV	#50*50,R0
.IFF
	MOV	#50*50,R2	; OTHER OPERAND
	CALL	D.DIVD		; DIVIDE THEM
.IFTF
	MOVB	D.RDTB(R0),(R3)+ ; MOVE A CHARACTER IN
.IFT
	CLR	R0
	DIV	#50,R0
.IFF
	MOV	#50,R2		; OPERAND
	MOV	R1,R0		; GET NEW NUMERATOR
	CALL	D.DIVD		; DIVIDE THEM
.ENDC
	MOVB	D.RDTB(R0),(R3)+ ; MOVE ANOTHER CHARACTER IN
	MOVB	D.RDTB(R1),(R3)+ ; MOVE LAST CHARACTER IN
	MOV	R3,R1		; RESTORE FOR THE USER
	RETURN			; RETURN
	.SBTTL	D.DIVD	- Division Routine
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.DIVD
;
; INPUT PARAMETERS:
;	R0 = dividend.
;	R2 = divisor.
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	R0 = quotient.
;	R1 = remainder.
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--
.IF NDF D.MCB

	.PSECT	$CODE$,I
D.DIVD:	PUSH$S	#16.		; SHIFT COUNT
	CLR	R1		; ASSUME NO HIGH PART
10$:	ASL	R0		; DOUBLE PRECISON SHIFT
	ROL	R1
	CMP	R2,R1		; WILL DIVISOR GO IN?
	BHI	20$
	SUB	R2,R1
	INC	R0
20$:	DEC	(SP)
	BGT	10$		; SOB?
	POP$S	,1
	RETURN	
.ENDC
	.SBTTL	D.VLD	- Check for Valid Word Address
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.VLD
;
; INPUT PARAMETERS:
;	R5 = virtual address of word to be checked
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	None
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.VLD:	PUSH$S	<R4,R0>
	MOV	R5,R4
	CALL	D.GETW
	POP$S	<R0,R4>
	RETURN	
	.SBTTL	D.FTCH	- Fetch Word or Byte at Given Address
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.FTCH
;
; INPUT PARAMETERS:
;	None
;
; IMPLICIT INPUTS:
;	D.CAD = Address of byte/word to fetch
;	D.BW = 1/byte or 2/word
;
; OUTPUT PARAMETERS:
;	R0 = Value fetched
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$CODE$,I
D.FTCH:	PUSH$S	R4
	MOV	D.CAD,R4
	CMP	#1,D.BW
	BNE	20$
	CALL	D.GETB
	BR	80$
20$:	CALL	D.GETW
80$:	POP$S	R4
	RETURN	
	.SBTTL	D.REL	- Relocate Address for Fetch or Store
;++
; FUNCTIONAL DESCRIPTION:
;	None
;
; CALLING SEQUENCE:
;	CALL	D.REL
;
; INPUT PARAMETERS:
;	R4 = virtual address of byte/word to access.
;
; IMPLICIT INPUTS:
;	None
;
; OUTPUT PARAMETERS:
;	R4 = mapped address to access byte/word.
;	KISAR6 = mapped to specified address.
;
; IMPLICIT OUTPUTS:
;	None
;
; CONDITION CODES:
;	None
;
; SIDE EFFECTS:
;	None
;--

	.PSECT	$ABS$,I
D.GETB:	JSR	R3,D.REL
	CLR	R0
	BISB	(R3),R0
	RETURN
D.GETW:	JSR	R3,D.REL
	MOV	(R3),R0
	RETURN
D.STRB:	JSR	R3,D.REL
	MOVB	R0,(R3)
	RETURN
D.STRW:	JSR	R3,D.REL
	MOV	R0,(R3)
	RETURN

D.REL:	PUSH$S	R3
	MOV	R4,R3
	CMP	#177700,R4
	BHI	30$
	CMP	#177707,R4
	BHIS	20$
	CMP	#177776,R4
	BHI	30$
	SUB	#177776,R3	; Display saved PS
	ADD	#D.UPS,R3
	BR	70$
20$:	SUB	#177700,R3	; Display saved register
	ASL	R3
	ADD	#D.URG,R3
.IF DF D.MCB
	BR	70$
30$:	BIT	#140000,D.UPS
	BEQ	40$
	ASH	#-14,R3		; Display user mode virtual
	BIC	#^C<7*2>,R3
	MAP$	UISAR0(R3)
	BR	60$
40$:	CMP	#172340,R4
	BHI	50$
	CMP	#172400,R4
	BLOS	50$
	SUB	#172340,R3	; Display saved APR
	ADD	#MAPR,R3
	BR	70$
50$:	ASH	#-14,R3		; Display kernel mode virtual
	BIC	#^C<7*2>,R3
	MAP$	MAPR(R3)
60$:	MOV	R4,R3
	BIC	#160000,R3
	BIS	#140000,R3
.IFF
30$:
.ENDC
70$:	CALL	@(SP)+
	MAP$	D.DAR6
	POP$S	R3
	RETURN	

	.END	DDT