+1 Paul's comments

some resources - cut and pasted from a message to a young
engineer/mentee/student I have at the moment ;-)

PDP11 Processor Handbook 1979
<http://bitsavers.trailing-edge.com/pdf/dec/pdp11/handbooks/PDP11_Handbook1979.pdf>

AA-5075A-TC PDP-11 MACRO-11 Language Reference Manual (RT-11)
<http://www.bitsavers.org/www.computer.museum.uq.edu.au/RT-11/AA-5075A-TC%20PDP-11%20MACRO-11%20Language%20Reference%20Manual.pdf>

$5 used on Amazon:  https://www.amazon.com/Introduction-Assembly-
Language-Prentice-Hall-software/dp/0134917049



ᐧ

On Fri, Feb 16, 2018 at 10:15 AM, Paul Koning <paulkon...@comcast.net>
wrote:

> Mike,
>
> You should get yourself a good intro to the PDP-11, for example one of the
> PDP-11 Processor Handbook copies you can find on Bitsavers.  It answers
> that question and many others.
>
> The key point is that you have to distinguish virtual addresses from
> physical ones.  The I/O device addresses are physical addresses.  The
> program uses virtual addresses.  Physical addresses can be 16, 18, or 22
> bits depending on the model; virtual addresses are always 16 bits.
>
> The power on default mapping is that physical addresses 0-157777 map to
> physical addresses with leading zeroes; virtual addresses 160000 and up map
> to physical adddresses with leading ones.  So, for example,
>
>         mov     #101, @#177566
>
> moves the value 0101 (decimal 65, the ASCII code for "A") to physical
> address 17 777 566 which should result in A appearing on the console output.
>
> On machines with an MMU (which is most of them) the mapping from virtual
> to physical can be changed, and for example the "I/O page" (top 4kW of
> physical memory) might not be accessible.  But by universal software
> convention, in kernel mode 160000 and up (MMU page 7) are always mapped to
> the physical I/O page address range.
>
>         paul
>
>
> > On Feb 16, 2018, at 10:05 AM, Mike Stramba <mikestra...@gmail.com>
> wrote:
> >
> > Greetings,
> >
> > I'm trying to figure out how console I/O works with the PD11.
> >
> > Or more generally I/O addressing
> >
> > E.g.
> > A  "sh TTO"  gives :
> >
> > TTO, address=17777564-17777567, vector=64, 7p
> >
> > And 17777564 (octal) is 4,194,164 dec, which is obviously out of range
> > of the 64K addressable by any MOV instruction.
> >
> > But various diagnostic routines, e.g. below, are using
> >     movb rX,@#177566       ; output to console
> >
> > https://www.ak6dn.com/PDP-11/M9312/23-248F1/23-248F1.mac
> >
> > Are I/O devices always at the "top 64k" of memory ?
> >
> > If so, why doesn't  SH DEV display :
> >
> > xxx xxx-177 777  ?
> >
> > Mike
> > _______________________________________________
> > Simh mailing list
> > Simh@trailing-edge.com
> > http://mailman.trailing-edge.com/mailman/listinfo/simh
>
> _______________________________________________
> Simh mailing list
> Simh@trailing-edge.com
> http://mailman.trailing-edge.com/mailman/listinfo/simh
>
PDP-11 Instruction Set

                We are to admit no more causes of natural things than such as
                are both true and sufficient to explain their appearances.
                              Isaac Newton, Principles: A System of the World

This paper describes the PDP-11/40 Instruction Set, including the
Extended Instruction Set (EIS) and the Memory Management Unit (MMU).
This particular configuration is similar to the machine John Lions used
during his studies of Unix Version 6 at the University of New South
Wales in 1976/1977. Features of the more powerful models PDP-11/45 and
PDP-11/70 are appended since on these machines Ken Thompson and Dennis
Ritchie developed Unix V6 and V7 in the 1970s.

Notation: The contents of registers, memory and addresses are
represented as nonnegative integers. Leading zero indicates octal and
leading "0x" indicates hexadecimal notation.  The (horizontal or
vertical) sequence of digits starts always with the most significant
one. "Low memory" are cells with low addresses. "K" equals 2^10.
Integer ranges "[i, k)" include i and exclude k if i < k and are empty
otherwise. The C language is employed for expressions.

0 Registers

All registers are 16-bit wide.

0.0 General Registers R0, R1, R2, R3, R4, R5 (FP), R6 (SP), R7 (PC)

The PDP-11 has eight general registers. They are addressed explicitly
by a 3-bit register number which is encoded in instruction words. In
addition to this, three registers are used implicitly, namely:

R7, the program counter (PC), points to the instruction to be executed
next.  After each fetch of a word addressed implicitly by the PC, the PC is
incremented by 2, before being used in address calculations.

R6, the stack pointer (SP), supports subroutine, trap and interrupt
linkage by employing a "last in/first out" memory allocation scheme. It
is used implicitly among others by jsr, rts, mark, sys and rtt. There
are two SPs, one active in user mode (USP), the other active in kernel
mode (KSP). "Push x" allocates memory and saves the value x, "pop y"
restores y and frees the memory allocated for y. The stack builds
toward low memory. If the SP was initalized to i, the stack occupies
the memory at [SP, i). Thus the SP addresses the item allocated last.

R5, the frame pointer (FP), is used implicitly solely by the mark
instruction to support subroutine linkage.

0.1 Processor Status Word PSW (at 0777776)

The bits of the PSW are assigned as:

name    width   meaning
CM      2       current operation mode, 00 is kernel mode, 11 user mode
PM      2       previous operation mode
****    4       not used
IPL     3       interrupt priority level
T       1       enable trace trap
NZVC    4       condition codes

A pending interrupt will be served if the hardwired bus request number
(BR) of the interrupting device is greater than the IPL.

If the T-bit is set, a trap at 14 is taken after execution of an
instruction. The T-bit enables debuggers to single-step a program.

Arithmetical and boolean instructions modify the condition codes (CCs)
to be sensed later by conditional branch instructions.

N indicates "result is negative"
Z indicates "result is zero"
V indicates "signed overflow"
C indicates the carry bit, i.e., unsigned additive overflow

0.2 Panel Registers (at 0777570)

There are two panel registers: a read only switch register (SR), which
mirrors the state of the panel switches, and a write only display
register (DR) to control the panel lights.

After power on, all but two registers are set to zero.  The IPL in the
PSW is set to 7 and the switch register is left as it is.

1 Addresses

16-bit (virtual) addresses are translated to 18-bit (physical) bus
addresses. The first 58K addresses are mapped to memory, the remaining
8K addressses are used to access device registers and are mapped to the
last 8K bus addresses. The last 8K block is called "I/O page".

This, this mapping is defined as:
        [0,   56K) --> [0,     56K),    x --> x
        [56K, 64K) --> [248K, 256K),    x --> x + 192K (== x | 0600000)

The memory management unit (MMU) can be enabled to set this mapping
under software control. The MMU handles two mappings (aka address
spaces)--one is active in user mode, the other in kernel mode. After
power on, the MMU is disabled.

2 Operands and Operations

Operands are stored in 8-bit bytes, 16-bit words and 32-bit longwords. The
multiplicative instructions multiply, divide, and "arithmetic shift
concatenated" (i.e., mul, div, ashc) are the only ones that operate on
longwords.

The instruction set provides signed integer arithmetic (byte, word and
longword), operations on boolean arrays of length 8 or 16, and additive
artithmetic on unsigned integers.

Most binary and unary operations are implemented for byte and word
sized operands.  Addition and subtraction operate on words only.

Words are stored in memory or registers, bytes in memory only. The
address of a word is even and equals the address of the word's low byte
("Little Endian"). If a register is the destination of a byte
operation, the signed value of the byte is stored in the register,
i.e., the sign bit is extended to the high byte of the register. A
register is truncated to its low byte if it is the source of a byte
operation.

A longword operand is stored in a pair of general registers RS, with
r, the number of R, being even and the number of S being r+1.  R holds
the high word ("Big Endian").

3 Instruction Formats and Address Modes

The parts of an instruction word are:

name    width   meaning 
w       1       operand width, 0 specifies word, 1 specifies byte
ss      6       source operand specification
dd      6       destination operand specification
a       3       address mode
r       3       register number
o       varying operation code
nn      8       signed word offset (in branches) ; system call number (in sys)
nn      6       unsigned number
m       4       mask to select condition flags NZVC in CC operations

The operand specifications ss and dd consist of the address mode
and the register number.

Notation: Instructions containing 4-bit or 8-bit parts are notated
hexadecimal, the others octal. If octal, the first character stands for
1 bit and the others for 3 bits each; if hexadecimal each character
stands for 4 bits. Hexadecimal notation is prefixed by "0x".

name                    format  example
double operand          wossdd  mov src,dst
register and operand    woordd  jsr r5,subr
register and operand    woorss  ash 2,r0
single operand          wooodd  inc a
single register         ooooor  rts r5
zero operand            oooooo  halt
branch                  0xoonn  br label
CC operation            0xooom  sec

The operand is specificied depending on the address mode:
a-mode  operand         name
0       R               register
1       m[R]            register indirect
2       m[R]; R=R+w     auto-increment          (pop)
3       m[m[R]]; R=R+2  auto-increment indirect (pop)
4       R=R-w; m[R]     auto-decrement          (push)
5       R=R-2; m[m[R]]  auto-decrement indirect (push)
6       m[m[PC]+R]      indexed
7       m[m[m[PC]+R]]   indexed indirect

Here R is the register selected in the operand specification, m the
memory, and w the operand width, i.e., w equals 1 for byte operands and
2 for word operands. If R is the SP, w == 2, even for byte operands.

4 Instructions

The instructions are sorted into four lists:
- Traps and other special instructions
- Arithmetic, boolean and data transfer
- Jump and subroutine linkage 
- Branches

Notation: Throughout the instruction lists, s and d denote source
respective destination operands. On the right side of an assignment
("=") d stands for the value before the operation is applied.

4.0 Traps and other Special Instructions

The memory at [0, 0400), the "yellow stack", is reserved for the
interrupt vector. An entry spans two words.  The first one holds an
address of a trap routine respective of an interrupt service routine
(ISR) and the second one the program status (PS), which is the low
byte of the PSW.

When a trap or interrupt is executed, the CPU switches to kernel mode,
pushes the previous PSW and the PC onto kernel stack, sets PM to the
previous operation mode, and executes the trap routine with the PS set
from the vector. This sequence is abbreviated by "trap at n" where n is
the address of the vector entry.

Return to interrupted/trapped program (rti, rtt) pops the PC and the PSW and
thus undoes the change of the state done by the trap or interrupt.  In
user mode, these instructions won't change CM, PM and IPL when they pop
the PSW from stack.

rtt differs from rti, in that it will not be trapped even if the T-bit
is set during execution. This enables debuggers to execute one
instruction of the debugged program.

Accessing word operands or instructions with an odd address, accessing
nonexisting memory, executing the halt instruction in user mode, or
pushing into the yellow stack while in kernel mode will trap at 4,
whereas executing an illegal (i.e., not implemented) instruction traps
at 10.

Execution of a trap might fail because a memory error occures while
saving PSW and PC. In that case, both words are saved in an emergency
stack at [0, 4) and a "red stack trap" is executed at 4.

In both the emulator and system trap instruction its low byte is
reserved for operating systems. In Unix it holds the system call
number.

ass     read            code    operation
----------------------------------------------------------------------
halt    halt            000000  stop the processor (privileged)
wait    wait            000001  wait for interrupt
rti     return to intr  000002  PC = SP++*; PSW = SP++*
bpt     breakpoint      000003  trap at 14 (for debugging)
iot     i/o trap        000004  trap at 20
reset   reset           000005  reset I/O devices (no-op in user mode)
rtt     return to trap  000006  PC = SP++*; PSW = SP++*
emt     emulator trap   0x88nn  trap at 30 (used by DEC)
sys     system trap     0x89nn  trap at 34 (used by Unix)

4.1 Arithmetic, Boolean and Data Transfer

Shift/rotate: ror, rot, asr, asl, ash, ashc
These instructions implement multiplicative operations with one
operand being a power of two. The C flag is set to the bit shifted out.

Integer Division: div, asr, ror, ash, ashc.
div truncates towards zero (notated by "/") whereas the right shifts
truncate to the smaller integer, notated by "//".

Access memory via previous address space: mfpi, mtpi
The mapping of the operand's virtual address is controlled by the
previous instead of the current mode's address space.  The previous
mode is determined from PM. If the operand is the SP, the previous
mode's SP is chosen.  Mfpi pushes and mtpi pops the operand using the
current stack.

CC operations: cln, clz, clv, clc, sen, sez, sev, sec
These instructions clear rsp. set condition codes. The CCs are selected
by the mask m in the instruction word. More then one flag can be
selected by oring instructions of either the set or the clear type.
When no flag is selected, the CC operations degenerate to no-ops.

The list is sorted by instruction code. The byte instructions (codes
[100000, 104000), [105000, 106400), [110000, 170000)) are left out.

ass     read            code    operation       Condition Codes affected
------------------------------------------------------------------------
cl?     clear CC        0x00Am                  NZVC = NZVC & ~m
se?     set CC          0x00Bm                  NZVC = NZVC | m
swab    swab bytes      0003dd  d.hi <-> d.lo   N, Z from low byte; V=C=0
clr(b)  clear (byte)    w050dd  d=0             N, Z, V, C
com(b)  complement      w051dd  d=~d            N, Z; V=0; C=1
inc(b)  increment       w052dd  d=d+1           N, Z, V
dec(b)  decrement       w053dd  d=d-1           N, Z, V
neg(b)  negate          w054dd  d=0-d           N, Z, V, C
adc(b)  add carry       w055dd  d=d+C           N, Z, V, C
sbc(b)  sub carry       w056dd  d=d-C           N, Z, V, C
tst(b)  test            w057dd                  N, Z; V=C=0
ror(b)  rotate right    w060dd  d=d//2 - C*2^15 N, Z, V; C=d%2
rol(b)  rotate left     w061dd  d=d*2 + C       N, Z, V, C
asr(b)  shift right     w062dd  d=d//2          N, Z, V; C=d%2
asl(b)  shift left      w063dd  d=d*2           N, Z, V, C
mfpi    mv fr prev i-sp 0065ss  --SP* = s       N, Z; V=0
mtpi    mv to prev i-sp 0066dd  d = SP++*       N, Z; V=0
sxt     sign extend     0067dd  d=-N            N, Z, V
mov(b)  move (byte)     w1ssdd  d=s             N, Z; V=0
cmp(b)  compare         w2ssdd                  N, Z, V, C as if d = s-d
bit(b)  bit test        w3ssdd                  N, Z as if d = s&d; V=0
bic(b)  bit clear       w4ssdd  d = d & ~s      N, Z; V=0
bis(b)  bit set         w5ssdd  d = d | s       N, Z; V=0
add     add             06ssdd  d = d + s       N, Z, V, C
sub     subtract        16ssdd  d = d - s       N, Z, V, C
mul     multiply, r evn 070rss  RS = s*R        N, Z, V (C see next line)
mul          "  , r odd 070rss  R = s*R         C="s*R does not fit in word"
div     divide          071rss  R=RS/s; S=RS%s  N, Z, V; C="/ by zero"
ash     arith shift     072rss  R=R*2^s         N, Z, V, C
ashc    " conct., r evn 073rss  RS=RS*2^s       N, Z, V, C (C=RS%2 if s > 0)
ashc    " conct., r odd 073rss  R=R*2^s         N, Z, V, C (C=R%2 if s > 0)
xor     exclusive or    074rdd  d = d ^ R       N, Z; V=0

4.2 Subroutine Linkage and Jump

Jump subroutine (jsr) pushes R, saves the return address (i.e., PC, the
address of the next instruction) in R, and jumps to the address of d.
It follows that if R is the PC, jsr simply pushes the PC and jumps.

The destination of jmp and jsr must not be a register, i.e., the
address mode must not equal zero. If it does, a trap at 10 occurs.

Return from subroutine (rts) restores the PC from R and pops R.
It follows that if R is the PC, rts just pops it.

With the mark instruction being the word last pushed, jmp (sp) means:
Free nn+1 (i.e. including mark) words from the stack, restore the
caller's FP and return; nn is a 6-bit unsigned integer.

Subtract one and branch (sob) decrements R and, if R != 0, jumps up
nn words, where nn is a 6-bit unsigned integer.

ass     read            code    operation
------------------------------------------------------------------------------
jmp     jump            0001dd  PC = &d (a-mode > 0)
rts     return fr subr  00020r  PC = R; R = *SP++
jsr     jump subroutine 004rdd  *--SP = R; R = PC; PC = &d (a-mode > 0)
mark    mark            0064nn  SP = PC + 2*nn; PC = FP; FP = *SP++
sob     subtract one    077rnn  R = R - 1; if R != 0: PC = PC - 2*nn 

4.3 Branches

If the condition holds, these instructions set PC = PC - 2*nn.  The
column labeled "s/u" indicates whether the tested condition is
appropiate for signed respective unsigned artithmetic.

ass     read            code    s/u     condition       cmp a, b        tst a
------------------------------------------------------------------------------
br      branch          0x01nn  s/u     always 
bne     not equal       0x02nn  s/u     !Z              a != b          a != 0
beq     equal           0x03nn  s/u     Z               a == b          a == 0
bge     greater equal   0x04nn  s       N == V          a >= b
blt     less than       0x05nn  s       N != V          a <  b
bgt     greater than    0x06nn  s       !Z && N == V    a >  b
ble     less equal      0x07nn  s       Z | N != V      a <= b
bpl     plus            0x80nn  s       !N                              a >= 0
bmi     minus           0x81nn  s       N                               a <  0
bhi     high            0x82nn  u       !C & !Z         a >  b
blos    lower or same   0x83nn  a       C | Z           a <= b
bvc     overflow clear  0x84nn  s       !V              no overflow
bvs     overflow set    0x85nn  s       V               overflow
bcc     carry clear     0x86nn  u       !C              a >= b
bhis    higher or same          another name for bcc    
bcs     carry set       0x87nn  u       C               a <  b
blo     lower                   another name for bcs

5 Memory Management Unit

5.0 The Mapping as Controlled by Paging Registers

The virtual address range [0, 64K) is partitioned into eight pages
        [0*8K, 1*8K), [1*8K, 2*8K), ... , [7*8K, 8*8K) .
Each page is assigned a page description register (PDR) and a page
address register (PAR).  The virtual address in a page are mapped
to a range of physical addresses which starts at p = PAR*64.

The meaning of the PDR bits are:
name    width   meaning
*       1       not used
S       7       with b=64*S, the lower part of page n is [n, n+b].
*       1       not used
C       1       set, when memory addressed by this page is changed
                cleared, when the PDR is changed
**      2       not used
U       1       upper part of the page is valid, i.e., mapped
W       1       write permission
R       1       read permission
*       1       not used

Let v be a virtual address contained in the page [n, n+8K).  This page
is divided into a lower part [n, n+b] and an upper part [n+b, n+8K].  U
controls which part of the page is mapped:

If U off:       [n,   n+b]  --> [p, p+b],    v  --> p + v - n
If U on:        [n+b, n+8K) --> [p, p+8K-b), v  --> p + v - (n+b)

A trap at 0250 is executed if one of the following conditions holds:
        R is off
        v is not mapped, i.e. not in the lower respective upper part
        W is off and the program tried to write to the memory

Physical addresses of the page registers:
kernel: PDR 0-7: [0772300, 0772320), PAR 0-7: [0772340, 0772360)
user:   PDR 0-7: [0777600, 0777620), PAR 0-7: [0777640, 0777660)

5.1 Control and status registers

MMR0 register (at 0777572) 
The MMU is enabled if the low bit is set. The other bits are set when
the MMU traps. They indicate the reason and identify the page that
caused the trap.

mask    width   meaning
010000  1       write access and !W
004000  1       address not mapped; not in valid part of the page
002000  1       read or write access, and page not readable
000140  2       operation mode to which the page belongs
000020  1       if set, page is from data space (PDP-11/45, /70 only)
000016  3       page number
000001  1       enable MMU 

MMR2 (at 0777576) is a status register that holds the address of an
instruction that caused an MMU trap.

6 PDP-11/45 and PDP-11/70

6.0 Extensions of the Instruction Set.

Instructions that are illegal on the PDP-11/40 might be implemented by
other PDP-11 models or by optional hardware extensions.

The  MMU in the PDP-11/45/70 supports two mappings per operation mode.
One is used for words addressed by the PC, i.e., instructions, the
other for the rest. This feature is called "separate I/D space".

Floating point instructions are offered either by the "Floating Point
Instruction Set" (FIS), a small extension, or by the "FP11", a full
blown floating point processor.

The mtps/mfps instructions are only needed by models that cannot
access the PSW, and therefore the PS, via the I/O page.

ass     read                     code           implemented in
--------------------------------------------------------------
mfpt    move from processor type 000007         other models
spl     set IPL to m             00023m         PDP-11/45, PDP-11/70
csm     call supervisor mode     0070dd         PDP-11/45, PDP-11/70
tstset  test & set               0072dd         multiprocessor machines
wrtlck  write locked             0073dd         multiprocessor machines
FIS     floating pt. instr. set  075000-075777  optional for PDP-11/40
CIS     commercial instr. set    076000-076777  optional for other models
mtps    move to PS               1064dd         other models
mfpd    move from prev d-space   1065dd         PDP-11/45, PDP-11/70
mtpd    move to prev d-space     1066dd         PDP-11/45, PDP-11/70
mfps    move from PS             1067dd         other models
FP11    floating pt. processor   170000-177777  PDP-11/70, optionial for /45

6.1 The MMU of the PDP-11/45 and PDP-11/70

The CPUs with separate I/D space need another four sets of paging
registers, namely PDRs and PARs for the kernel data space and for the
user data space.  Each of these sets is located in the I/O page below
the corresponding set of the instruction space. Since these PDP-11s
offer a third operation mode (supervisor mode), they also have another
two sets of paging registers for this mode. (at [772200, 772300))

MMR1 (at 777574) identifies the registers changed by the incrementing /
decrementing address modes in an instruction that caused an MMU trap.
The increment is in the range [-2, +2] and encoded as a 3-bit integer
which is negative in case of decrementing address modes.

The meanings of the bits are:
width   meaning
2       not used
3       increment from source a-mode
3       register from source a-mode
2       not used
3       increment from destination a-mode
3       register from destination a-mode

MMR3 (at 777516) is a control register used to enable separate I/D
space and the CSM instruction, i.e. the supervisor mode.

The bits are assigned as:
width   meaning
10      not used
1       enable 22bit I/O addresses (PDP-11/70 only)
1       enable 22bit physical addresses (PDP-11/70 only)
1       enable csm
1       enable seperate kernel data space
1       enable seperate supervisor data space
1       enable seperate user data space

7 Assignment of Instruction Codes
"Illegal" means illegal on Lions' PDP-11/40

000000-000006   traps; halt, reset ...
000007-000077   illegal; mfpt
000100-000207   jump, rts 
000210-000237   illegal; spl
000240-000377   arithmetic, boolean and data trnsfr; CC operations, swab bytes
000400-003777   branches
004000-004777   jsr
005000-006377   arithmetic, boolean and data transfer; single word operand
006400-006477   mark
006500-006777   arithmetic, boolean and data transfer; single word operand
007000-007777   illegal, csm, tstset, wrtlck
010000-067777   arithmetic, boolean and data transfer; two word operands
070000-073777   extended instruction set (EIS); mul, div, ash, ashc
074000-074777   boolean; XOR
075000-076777   illegal
077000-077777   sob
100000-103777   branches
104000-104777   traps; emt, sys
105000-106377   arithmetic, boolean and data transfer; single byte operand
106400-107777   illegal; mtps, mfpd, mtpd, mfps
110000-167777   arithmetic, boolean and data transfer; two byte operands
170000-177777   illegal; FP11
_______________________________________________
Simh mailing list
Simh@trailing-edge.com
http://mailman.trailing-edge.com/mailman/listinfo/simh

Reply via email to