Documentation file for the PDP11 simulator, PDP11 and PDP45.


On the pdp-11 simulated:

The instructions:

	mov %0,-(%0)	,etc., store the original contents of the register,
		rather than the altered contents.
		this is correct for the 11/45 but not the 11/20.

the low speed reader is not implemented, since it's a lsr.

the run time ratio of simulated to real pdp11/20 is near 30.

simulated real time is maintained to precision of .1 microsec.
	(probably not quite 20% accurate).


Characters effective at interrupt level:

^G (bell) is a quit-character.
	if typed while simulating, causes DDT to be called.
		a ;p command will resume simulation.
	if typed while in ddt, causes an immediate return to ddt's main loop.
^G^G is identical in effect to ^G^S
^G^G^G causes ddt to be called immediately.
	it is useful when the simulator itself is hung.
^S is used to stop printout from the time it is typed
	to the time it is actually read by the simulated program.
^B turns on output to the lpt,
	^E turns it off.
^V turns on output to tty,
	^W turns it off.
^Q causes the next character typed not to have any special effects.
	thus, it can be used enter a ^G, ^S, ^B, ^E, ^V, ^W or ^Q .
^Q is also useful in ddt, to put one of the interrupt chars in an ascii value,
	to put ":, ";, ",, " , or ^M in a filename,
	and to put non-squoze chars and initial digits in symbols.
within ddt, if a char quoted by a ^Q is rubbed out,
	the ^Q that quoted it is also automatically rubbed out.

when ddt is entered, it prints:

loc/  insn
where loc is the address of the next instruction to be executed.
that location is not open for modification, however.
in the 1145 version, the permanent, temporary and 1-shot mapping
modes are all set to the i-space of the processor's current
mode (or to $a if paging is off).

normally, ddt is only called between instructions.
3 ^G's, however, will cause ddt to be called immediately,
  usually within an instruction. system variables might be only
  partially updated.
in that case, proceeding will just return from ddt,
  while ;g will start at the beginning of an instruction.

Expressions in the simulator's ddt:

Expressions are made up of terms separated by operators.

terms are either octal numbers,
	decimal numbers followed by ".",
	ascii values of the form 'a or "ab,
	defined symbols,
	unary + or - preceded by a term,
	or expressions in angle brackets.

operators defined are:
	level 0:	@(mapping)
	level 1:	*,!(divide)
	level 2:	+,-
	level 3:	&,\(or),#(xor)
	level 4:	space (addition)

(the syntax for the mapping operator "@" is:
<term>@<mode>  where <mode> is a mapping mode name
(one of "0","2","4","6","a","ki","kd","si","sd","ui","ud").
the term is mapped as if it were an address being opened,
and the absolute location that would have been opened
is the value of the operator. thus, foo@ki= types out what
foo in kernel i-space maps into.  registers are not allowed
as the first argument of an @).

some special symbols whose values are automatically set are:

	.		as in pdp-10 ddt.
	%.		location actually open.
	%		set to contents of pc at entry to ddt.
	%opc		address of last or current instruction
	%q		last qty. typed in or out.
	%p		within a multi-word expression,
			  holds value of previous word.
			  otherwise same as %q.
	%b		address of last breakpoint taken.
	%s		last explicit source address.
	%d		last explicit destination address.
			  also set by branches.
	%l		length of last qty in or out.
	%ol		length of what was last opened or stored.
	%il		length of next insn (printed at entry)
	%go		starting address for ;g with no arg.
	%core		number of bytes of core attached.
			  first nonexistent address.
	%swr		address of switch register.
	%csx		addr. of place where ;x puts its instruction.
	%ps		address of ps word (=-2).
	%jpc		sometimes set to addr. of last jump or trap.
	%0, etc.	register 0  - %1, ... %7 similar.

also, symbols are defined for various device registers.
	see device control commands.

a value can be either ordinary or a register number.
	an expression evaluates to a register number iff any term in it does.
	a term has a register value iff
	it is a register-valued expression in angle-brackets,
	or it is a register symbol.
	the only initially present register symbols are %0...%7

because the pdp-11 has multi-word insn,
	the ddt can handle multi-word values.
	they are the values if expressions with the following forms:

	<exp1,exp2,...,expn>
or:	op-code operand1,operand2	(maybe 0 or 1 operands).

	where exp1...expn are expressions,
	op-code's and operand's are as in pal-11.

if one multi-word expression occurs within another,
	only the first word of the inner one is used.

there is one incompatibility between ddt's instructions and pal-11's:

	for:	use:
	sec	sfl @c
	sev	sfl @v
	scc	sfl @znvc or sfl @vncz , etc.
	clz	cfl @z
	etc.	etc.

commands to open, close, etc.

arg represents any expression.

if 2 expressions are typed in a row, only the second is used.

arg/		open location arg in current mode, change . .
   /		similar, but location %q, and don't change . .
arg[		similar, but open in numeric mode.
   [		similar, but %q.
arg=		retype arg in numeric mode.
   =		similar, but %q.
arg]		similar, but current mode.
   ]		similar, but %q.
   _		reopen location now open, in current mode.
   ^I		close open loc, open location addressed by it.
   ^J		close open loc, if word open, open .+%ol
		  if byte open, open .+1 as a byte
		  the new location is opened in the
		  same mapping mode as the location last opened.
   ^		close open loc, if word open, open .-2
		  if byte open, open .-1 as byte
		  the new location is opened in the
		  same mapping mode as the location last opened.
   ^M		close open loc.
arg>sym		define symbol sym with value arg.
   >sym		same as %q>sym .
arg>sym^K	similar, but half-kills sym.
   >sym^K	same as %q>sym^K .
   ^K sym	complement half-kill switch for symbol sym.


in the 11-45 version of the simulator, several mapping modes are
available for opening addresses in various paged spaces. these
modes affect the actions of the commands that open locations.
in particular, they affect which copy of a register will be
examined.  see "mapping modes".

ddt attempts to remember the length of what is open.
this length is set from %l when the location is opened,
and is updated if an = or ] is given to retype it before any
value is typed in or the location is closed.
when something is deposited, %ol is set to its length.
linefeed uses %ol to determine the next location to open;
the patch commands, to determine what value to give to patch or %patr.

patching:

   :pat arg	closes the open location, storing in it a special
		  device code, and the value arg.
this special device causes a break when read or written by
  the simulated program.
if an instruction is fetched from it, it acts like a jmp arg  instruction.
opening the location in ddt causes :pat argx  to be typed,
  where argx will have the same value as arg, but may look
  different.
storing in it from ddt will cause the patch-device to be removed.
patch-devices will load and dump properly.
  :pat also does  %q+%ol>%patr  - ie. it saves the
  addr of the next instruction to facilitate patching back.

example:

!foo/  movb a20,%1    :pat xyz
!foo/  :pat zbc   =1074    xyz=1074

   ^\		like :pat patch, but opens location patch.

   ^]		like :pat %patr, but sets patch instead of %patr.
arg^]		like arg ^j ^]

example:
!foo/  inc r1    ^\
patch/  halt    dec r2^j
patch+2/  halt    inc r1^]
!
!foo/  :pat patloc    ^i
patloc/  dec r2    ^j
patloc+2/  inc r1    ^j
patloc+4/  :pat foo+2    ^j
patch/  halt

the value of patch is initially 1, so ^\ will fail.

typeout mode commands:

example of a series of typeout mode commands.

$b		set 1-shot byte mode.
$$b		set 1-shot and temporary byte mode.
$$$b		set 1-shot, temporary and permanent byte mode.
$-b		clear 1-shot byte mode.
$$-b		clear 1-shot and temporary byte mode.
$$$-b		clear 1-shot, temporary and permanent byte mode.

	locations opened while 1-shot byte mode is set are opened as bytes.

the 1-shot modes are the ones actually referred to when printing.
they are restored from the temporary modes after each command,
	except after typeout-mode commands.
the temporary modes are restored from the permanent modes
	whenever ddt prompts with "!".
each typeout mode is represented by 3 bits: 1 for the 1-shot
setting, 1 for the temporary setting, and 1 for the permanent.
if several conflicting 1-shot modes are set, one overrides the
others, according to the ordering described below.

other series of typeout-mode commands:

$i, etc.	instruction mode.
		when opening a location, print as instruction.
$r, etc.	register mode.
		print register quantities numerically.
$!, etc.	non-printing mode.
		when opening a location, don't print its contents.
		overrides all other modes. %s and %d aren't set, but %q is.
$", etc.	ascii mode.
		print quantities, except special addresses, as ascii values.
$', etc.	both ascii mode and byte mode.
$n, etc.	numeric mode.
		print quantities, except special addresses, numerically.
		overrides ascii mode.
$d, etc.	decimal mode.
		when printing a number, use base 10. .
		(otherwise, base 8. is used).

mapping modes: (1145 only)
a series of mapping mode commands is like a series of typeout
mode commands except that the minus sign may not be used.
the 11. mapping modes for a set of alternatives. thus, at any
time the 1-shot mapping mode is one of those 11., the temporary
mapping mode is a (perhaps) different one, and the permanent
mapping mode is also one of those 11.

$0, etc.	when opening a location, use the
		specified 18-bit address unmodified.
$2, etc.	add 200000 to the spec'd 18-bit address.
$4, etc.	add 400000 .
$6, etc.	add 600000 . good for io-device regs.
$a, etc.	map the low 16 bits as if paging were off
		that is, the bottom 28.k are unchanged, and the
		rest refer to io-device registers.
		this mode is also good for open device reg
		symbols such as %tkb.
$ki, etc.	map the spec'd address in kernel i-space, using
		the current contents of the kernel i-space sdrs
		and sars. it works to change the sdrs or sars in
		ddt and then map through them. a nonresident
		segment or segment length error will give
		an error message.
the $kd, $si, $sd, $ui, and $ud mapping modes all exist.
when %6 is opened, the copy of %6 referred to depends on the
mapping mode.  if it is $k..., $s..., or $u..., the %6 associated
with the mapping mode is opened.  otherwise, the r6 currently being
used by the processor is opened.  when %0 through %5 are opened,
you get the register set being used by the processor except in
$6 mode, when you get the register set not being used.

$!, $i, $b and mapping modes are consulted when opening a location.
$" and $n are consulted when printing a quantity.
	(also $r if it is a register value).
$d is consulted when printing a number.

special addresses are those of locations being opened (e.g. by ^i, ^j),
addresses of breakpoints, branches, patches.

expressione preceding typeout mode commands are treated as if they followed the commands.
	e.g.  10 $d=   is equivalent to $d10=     .

breakpoint commands:

arg;b		set type 7 bpt. (any processor access) at arg.
		arg is mapped using the 1-shot mapping mode
		just as if it were about to be opened. (this is
		true for all the breakpoint setting commands
		when they are given 1 prefix argument).
arg;u		remove any breakpoint at arg.
arg;f		set a fetch-only bkpt at arg (type 1).
arg;r		set processor-read breakpoint at arg.
arg;w		set processor-write breakpoint at arg.
   ;b		set breakpoints of type 7 everywhere.
   ;u		remove all breakpoints.
   ;f, ;r, ;w	analogous.
<arg0,arg1>;b	set breakpoints of type 7 everywhere from arg0 to arg1.
		arg0 and arg1 are treated as 18-bit absolute
		addresses; they are not mapped. the "@" operator
		may be used in them if mapping is desired.
<arg0,arg1>;u	remove all breakpoints in that range.
   ;f, ;r, ;w with such args act analogously.
arg;arg2b	set breakpoint of type arg2 at arg1.
		if arg2=0, remove breakpoint.
		arg is mapped.
   ;u, ;f, ;r, ;w with such args act identically to ;b .
;arg2b,;arg2u,<arg0,arg1>;arg2b,<arg0,arg1>;arg2u	--
		all analogous.

breakpoint types:
a breakpoint type is a 7 bit number. the bits are as follows:

1	break on insn fetches.
2	break on write references by cpu.
4	break on cpu read references (not insn fetches).
10	if set, don't call ddt - just print message.
20	break on write references by i-o devices (df, etc).
40	break on device read references.
100	autoflush breakpoint.

thus, a breakpoint of type 12 will break only on cpu writes,
   and won't stop - it will just print a message.

read and write breakpoints type out the old contents of location,
	and the breaking insn.

non-stop fetch breakpoints type out the insn, and the previous insn.

stopping fetch breakpoints are unique in stopping before the insn.

autoflush breakpoints break on fetch referrences, and always stop
	before executing the insn. in addition, they reset themselves
	(but not any other breakpoints that may be on the same word).
	their action is completely independent of the setting of the
	other breakpoint bits - in particular, they will call ddt
	even if bit 10 is set.
	they print "break(f)" instead of "break".


       :lbrks	prints $b commands that would
		 create the existing breakpoints.
<a1,a2>:lbrks	similar, for breakpoints between a1 and a2.

trap message control commands:

arg;arg2 t	sets the trap action code for trap thru arg to arg2.
   ;arg2 t	sets all trap action codes to arg2
arg;t		same as arg;0t
   ;t		same as ;0t

the trap action codes are:

0		continue simulation (of the trap).
1		set %jpc from %opc and continue.
2		print message and continue.
3		print message and stop at end of insn.



jump and branch printout commands:

  0;arg2 t	causes the pc change action code to be set to arg2.
  0;t		same as 0;0t

the pc change action code determines what
  will be done whenever the pc changes except by normal incrementing.
it is interpreted just as the trap action codes are.



buss error memory:

   :buss		print out the locations, times and causes of last 3 buss errors.


various printouts:

   :regs		prints contents of pdp11 accumulators.
   :lsyms		prints values of all symbols defined.

execution commands:

arg^N		execute arg instructions.
   ^N		execute 1 instruction.
   ;p		return from ddt, resume simlation.
   ^P		same as ;p .
arg;g		go to address arg, aborting current instruction.
   ;g		similar, but starts from location %go .
arg;a2 g	starts at arg, and executes a2 insns.
arg;0g		starts at arg and returns immediately to ddt.
   ;a2 g	like %go;a2 g .
   ;0g		like %go;0g .
   ;n		like $$^N in 10-ddt.

starting at an odd address will cause a bus error trap.



reinitialization:

   ;i		executes a reset instruction, zeros the ps,
		  and zeros the cumulative virtual time.
		  also forgets old buss errors and
		  aborts the instruction (if in superquit).



executing a particular instruction:

( ;x commands must be terminated by a cr (i.e. ^M )).

   ;x insn	executes the instruction insn.
   ;x		executes whatever insn was last ;x'd (usually).
arg;x insn	like ;x insn ,  but puts arg in %1 before execution,
		  and restores %1's old contents afterwards.
arg;x		similar, but uses same insn as last time.

if the instruction ;x'd causes a transfer of control, simulation will
   continue until control returns, or ddt is called for some other reason
   (e.g. a breakpoint).
the contents of %7 are restored when the insn finishes normally
(that is, when control reaches the word after the insn).

to execute an insn, ;x first stores it at location %csx.
normally, %csx is set to 177720. you can cause insns to be
  stored and executed at any other loc. by  the :s%csx command.
it is possible to put an insn at %csx normally, e.g.
   %csx/  halt     jsr pc,print
or	%csx: jsr pc,print	in the source file.
   future ;x's which do not specify an insn
   will use the one that was stored at %csx.

examples:    ;x inc xloc		adds 1 to the contents of xloc.
	1506;x jsr pc,print		calls the routine print
		    with 1506 in %1. ddt takes over on return from print,
		    and %1's old contents are restored.

i-o device control commands:
(must be terminated by a carriage return)

   ;a		prints names of available devices.
   ;d		same
arg;a dev info	attaches device dev. (how info is used
		depends on the device being attached).
arg;d dev info	detaches device dev.

note: different devices expect different kinds of info.
   some expect none.  only some devices use an arg.

the following options for   arg;a name info
  are available (blank arg or info column indicates that the
  arg or info shouldn't be present for that option)

name	arg	info	action

core	# k		add that many k virt. core.
dc		file	attach dc11 to file, both directions.
dcr		file	attach for receive only.
dct		file	attach for transmit only.
df		file	attach rf11 disk drive 0, using file (see rk device)
df	drive#	file	attach that drive, using spec'd file (see rk device)
dm			print dm11 line attach status.
dm	line #	file	attach line as file both rcv & trans.
dmr			print receive line attach status.
dmr	line #	file	attach line as file, receive only.
dmt			print transmit line attach status.
dmt	line #	file	attach line as file, transmit only.
eae			causes an eae to exist.
i45			causes some pdp11-45 insns to work.
lk	cps		attaches line freq clock, arg is freq.
lp		file	attaches lpt as file.
master			enter i.t.s. master mode.
ngdis	?	?	attaches knight display, i don't know args.
nuldis	?	?	attaches something that looks like a knight
			 display but doesn't display or need 340.
pk	?		attaches programmable clock.
pp			attaches virt. punch as real punch.
ppa		file	attaches virt. punch as file, ascii mode.
ppi		file	attaches virt punch as file, 1 byte per word.
pr			attaches virt. reader as real reader.
pra		file	attaches virt. reader as file, ascii mode.
			 good for reading i.t.s. ascii files.
pri		file	attaches virt. rdr as file, 1 byte per word.
			 suitable for absolute loader, etc.
rk			creates the registers for the rk-11 if they
			 don't exist. doesn't make any drives ready.
rk	drv #	file	as above if nec., and makes that drive exist
			 note that if no sname is spec'd, the sname
			 last used for this drive will be used, not
			 changing the current sname. (the current
			 sname will be used the 1st time)
			 if the file doesn't exist it will be created.
			 the rk must be detached to force data still
			 in core to be written into the file.
tk			causes a tty input dev. to exist.
tp			causes a tty output dev. to exist.

the following options for  arg;d name info	exist.

name	arg	info	action.
core	# k		remove that many k virt. core.
dc			detach dc11 both directions.
dcr			detach receive only.	(dc11 registers go away...
dct			detach trans. only.	...when neither direction attached).
df			detach all drivds of rf11. registers go away.
			detaces each drive individually.
df	drv #		detaches spec'd drive of rf11.
			any pages in core are written out into the file
			the drive was attached from.
dm			same as ;a dm   .
dm	line		detcach that line, both directions.
dmr			same as ;a dmr   .
dmr	line		detach that line, receive only.
dmt			same as ;a dmt
dmt	line		detach that line, trans. only.
eae			eae ceases to exist.
i45			pdp11-45 insns trap thru 10 again.
lk			detach line freq clock, registers become nxm.
lp			  "     lpt,		    "	    "	  " .
master			leave i.t.s. master mode.
ngdis			  "	knight display,	    "	    "	  "
   nuldis same as ngdis.
pk				programmable clock,
pp				punch,
   ppa,ppi same as pp.
pr				reader,
   pra,pri same as pr.
rk	drv #		writes out data for that drive and forgets
			 about it (it isn't ready, file still exists)
rk			does so for all drives, then destroys regs,
			 frees core used for buffers, etc.

tk			detach	teletype keyboard, regs become nxm.
tp				teletype printer,

initially, there are 8. k of core, the lk, tk, tp and eae are attached,
	and all other devices are detached.


   :reset dev	resets that dev - ie does what a reset
		instruction would do to that dev.
		for rk, writes out all data in core.

   :devtim dev	types that dev's "time constant" as
		xxxx.y where xxxx is in virt. microsec.
arg:devtim dev	sets the time constant, and prints it.
		arg should be a number of 10^-7 sec.
		the device rk has 3 time constants:
		  rk - sector rotation time,
		  rkc - seek time per cylinder,
		  rkx - basic seek time.

dumping and loading:
(these commands must be terminated by a carriage return)

	:load filspc	loads file specified.
	:lod filspc	same.
	:lodcor filspc	loads only core from file specified.
	:lodsym filspc	loads only symbols from file specified.
	:lodptr		loads from tape reader in 8-bit mode.
	;l filspc	zeros core and symbols, does a ;i, then loads file specified.

	:dmpcor filspc	dumps all core (but not device register contents).
<a1,a2>	:dmpcor filspc	dumps from a1 to a2.
	:dmpsym filspc	dumps all symbol defs.
	:dmptpv filspc	dumps the trap and pc change action codes set by ;t ("tpv").

	:dmp filspc	dumps all core, symbols and tpv.
	;y filspc	same.
<a1,a2>	:dmp filspc	dumps core from a1 to a2, all symbols and tpv.
<a1,a2>	;y filspc	same.
	:adump filspc	dumps core in absolute loader format, followed by symbols.
<a1,a2>	:adump filspc	similar but dumps specified range of core.

;l will load absolute loader format files.
  however, it will not load pdp11 type absolute loader tapes,
  since it uses block-mode i-o.
  paper tapes should be loaded with :lodptr instead.
;y dumps in a special, compressed format which
	;l can read, but the absolute loader can't.

a filspc contains filenames separated by" ", ";" and ":",
	and is terminated by a ^M or ",.
exception: the chars ":;, " can go into filenames if quoted by ^Q.

names followed by colons are device specifications;
names followed by semicolons, sname specifications;
other names are, in this order: fname1, fname2, dev, sname.

names not specified are left the same as they
	were in the last ;l or ;y command,
	except the sname, which, if unspecified, is the same as
	was specified in the last filspc in any command.

zeroing core:

   ;z		zeros all core.
arg;z		sets all words to arg.
<a1,a2>;z	zeros all core from a1 to a2.
<a1,a2,a3>;z	similar, but sets to a3.



timing commands:

	:time		prints the cumulative virtual run-time in decimal.
	:ztime		zeros   "      "         "     "   "   .

the ;i command also resets the time.



file i-o:

   :xfile filspc	executes the ddt commands in the file filspc,
			  printing them on the tty as it does so.

when reading from a file, linefeeds that follow carriage returns are ignored.

on starting pdp11, if a file  .pdp11 (init)  is found, it
   will be automatically :xfile'd.

   :wallp filspc	starts outputting to filspc as well as tty.
			  future uses of ^b will output to filspc,
			  instead of lpt: .


colon commands -- all terminated with carriage return:

   :lcoms	list all colon comands
   :lsyms	print definitions of all symbols except instructions.
   :flsyms	kills all user symbols.
arg:s%csx	sets up arg for use by ;x .
   :s%csx	sets up default addr. (177720) for ;x .
   :odmp filspc		open a permanent dump file.
   :cdmp		close one.
			ordinary dump commands between a :odmp
			and a :cdmp all dump into the file
			opened by the :odmp.
arg:core		either detaches or attaches core
			so there will be arg k.
   :core		prints the number of k of core.
   :altsem		switches the roles of "; and "$ in commands -
			mode setting commands use ";,
			special action commands use "$.
			prints "switched" if that is the case.
			if they were already switched,
			prints "normal" and restores them.



   ^L		clears the screen. otherwise ignored.
