PDP-11 integer FP-11 floating 22-bit memory management, K=00/S=01/U=11 modes ODT 8K write-through cache Programmer-visible registers: General-purpose: R0-R5, R0'-R5', KSP, SSP, USP, PC System control: PSW, LTC, PIRQ, MAINT, CPU ERROR Memory system: CACHE CONTROL, MEM SYS ERR, HIT/MISS Floating point: FPS, FEC, FEA, 6 accumulators (64 bits each) Memory management: MMR0, MMR1, MMR2, MMR3, K/S/U page tables (8 each I and D space, PAR/PDR for each) bit 11 of PSW says whether R0-R5 or R0'-R5' are in use PSW bits 14-15 select KSP/SSP/USP for R6, except for M[TF]P[ID], for which bits 12-13 select: PSW 15,14 or 13,12 R6 is 00 KSP 01 SSP 10 illegal - USP used 11 USP PSW (address 17777776) 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ | Current |Previous |Reg | | |Susp| Priority | | | | | | | mode | mode | set| 0 | 0 |info| level | T | N | Z | V | C | +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ Current mode: 00=kernel 01=supervisor 10=illegal 11=user Previous mode: as current mode Reg set: Selects register set (0=R0-R5, 1=R0'-R5') Susp info: Reserved (?) Priority level: Current priority level, coded in 3-bit binary T: When set, trap through 14 occurs at the end of the current instruction Cannot be set by writing to PSW; must use RTI/RTT N/Z/V/C: Condition codes CPU ERROR (address 17777766; entire register is readonly) 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ | | | | | | | | |Ill |Addr|NXM |I/O |Yel |Red | | | | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |Halt|Err | Err|Timo| Stk| Stk| 0 | 0 | +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ Ill Halt: HALT instruction attempted in user or supervisor mode Addr Err: Word access to odd address, or instruction fetch from internal register NXM Err: Main memory reference timed out I/O Timo: I/O page reference timed out Yel Stk: Yellow stack overflow trap (kernel mode stack ref < 0400) Red Stk: Red stack trap (kernel stack push abort during interrupt/abort/trap) PIRQ (address 17777772) [Program Interrupt ReQuest] High byte is bitmask of interrupts requested (all read/write) (priority i's bit is 1<<(i+8), i in 1..7) Low byte is 0x22 times highest priority requested (all readonly) Cleared by power-up, console start, or RESET. LTC (address 17777546) [Line Time Clock] Is either 0x0000 or 0x0040. When bit is set, BEVNTL bus signal generates highest possible level 6 interrupt through 100. Cleared by power-up, console start, or RESET. MAINT (address 17777750; entire register is readonly) 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ | | | | |FPA | |HALT| Powerup | DC | | Boot address | 0 | 0 | 0 |Avl.| Module ID |Optn| option | OK | +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ Boot address: Contains boot address from jumpers: 15 = W1, 14 = W2, 13 = W4, 12 = W6. 1 indicates inserted, 0 indicates removed. FPA Avl.: 1 if FPA is installed, 0 otherwise. Module ID: 0001 indicating KDJ11-A HALT Optn: 1: W5 removed, HALT will do SP<-4, then trap through 4 (kernel data space), also sets Ill Halt in CPU ERROR 0: W5 installed, HALT will enter ODT Powerup option: Power-up option from jumpers: 2 = W3, 1 = W7 (0 = installed, 1 = removed): 2 1 Option 0 0 PC at 24, PS at 26 0 1 ODT, PS = 0 1 0 PC = 173000, PS = 340 1 1 User bootstrap (PC = boot address << 12, PS = 340) DC OK: Set when BPOK H is asserted, indicating DC power is OK. Asynch interrupts: Interrupt Int/Ext Vector Priority Notes Red stack trap Int 4 NM CPU ERROR bit 2 Address error Int 4 NM CPU ERROR bit 6 Memory mgt violation Int 250 NM MMR0 15..13 Timeout/NXM Int 4 NM CPU ERROR bits 5..4 Parity error Ext 114 NM Trace trap Int 14 NM PSW bit 4 Yellow stack trap Int 4 NM CPU ERROR bit 3 Power fail Ext 24 NM FP exception Ext 244 NM PIRQ bit 15 Int 240 7 IRQ 7 Ext User 7 PIRQ bit 14 Int 240 6 Book says priority 7?? BEVNT Ext 100 6 LTC bit 6 IRQ 6 Ext User 6 PIRQ bit 13 Int 240 5 IRQ 5 Ext User 5 PIRQ bit 12 Int 240 4 IRQ 4 Ext User 4 PIRQ bit 11 Int 240 3 PIRQ bit 10 Int 240 2 PIRQ bit 9 Int 240 1 Halt line Ext N/A N/A Enters console mode Synch interrupts: Interrupt Vector FP instruction exception 244 TRAP instruction 34 EMT instruction 30 IOT instruction 20 BPT instruction 14 CSM instruction 10 HALT instruction 4 (unless kernel mode and W5 installed: ->ODT) WAIT instruction N/A Memory management: 16 user mode memory pages 16 supervisor mode memory pages 16 kernel mode memory pages 8 pages in each mode for instructions 8 pages in each mode for data Page lengths from 64 to 8K bytes Memory management off: virtual 000000-157777 is physical 00000000-00157777 virtual 160000-177777 is physical 17760000-17777777 Not sure whether vectors are read from physical memory or kernel D space; book seems to contradict itself. Stack used for push of PC and PSW is stack in 15..14 of new PSW. PSW mode bits also determine new mapping register set. I space is used for instructions, index words, absolute addresses, and immediate data. D space is used for everything else. MMR3 can cause D space to use the I space tables instead. V->P mapping: PA = (VA & 017777) + (PAR[space-and-access-mode][VA>>13]<<6) MMR0 17777572 MMR1 17777574 MMR2 17777576 MMR3 17777516 User I PDR 0 17777600 ... User I PDR 7 17777616 User D PDR 0 17777620 ... User D PDR 7 17777636 User I PAR 0 17777640 ... User I PAR 7 17777656 User D PAR 0 17777660 ... User D PAR 7 17777676 Supervisor I PDR 0 17772200 ... Supervisor I PDR 7 17772216 Supervisor D PDR 0 17772220 ... Supervisor D PDR 7 17772236 Supervisor I PAR 0 17772240 ... Supervisor I PAR 7 17772256 Supervisor D PAR 0 17772260 ... Supervisor D PAR 7 17772276 Kernel I PDR 0 17772300 ... Kernel I PDR 7 17772316 Kernel D PDR 0 17772320 ... Kernel D PDR 7 17772336 Kernel I PAR 0 17772340 ... Kernel I PAR 7 17772356 Kernel D PAR 0 17772360 ... Kernel D PAR 7 17772376 PDR: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ | | | | | | | | | | | NC | Page Length | 0 | W | 0 | 0 | ED | Access | 0 | +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ NC: RW No Cache - always access memory; cache hits invalidate cache Page Length: RW Length violation if ED clear: (VA>>6)&0177 is greater than length ED set: (VA>>6)&0177 is less than length W: RO Cleared by write to PDR or corresponding PAR; set by hardware on write access ED: RW clear: expand upwards; set: expand downwards (affects only length check, as far as I can see) Access: RW Access control: 00 Nonresident - abort all accesses 01 Read only - abort write accesses 10 Not used - abort all accesses 11 Read/write - never abort MMR0 (address 17777572): 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ |Non |Len | RO | | | | | | | Access |Adrs| | MM | | res| err| err| 0 | 0 | 0 | 0 | 0 | 0 | mode | spc| Page number | Enb| +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ Non res: RW Set by use of page with access of 00 or 10, or attempt to use relocation with PSW 15..14 = 10 Len err: RW Set by length violation (see PDR 14..8) RO err: RW Set by attempt to write to page with access of 01 Access mode: RO Access mode of access attempt that caused abort Adrs spc: RO Indicates I/D space of access causing abort (I=0, D=1) Page number: RO Page number of page causing abort (ie, VA>>13) MM Enb: RW Memory management enable Setting any of MMR0 15..13 with an explicit write does not cause an abort. Whenever MMR0 15..13 are not all zero (regardless of how), MMR0 06..01, MMR1, and MMR2 are frozen. MMR1 (address 17777574): 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ | | | | | | Amount changed | Register # | Amount changed | Register # | +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ Records autoincrement or autodecrement during instruction processing, PC included. Low byte is used for source operands; destination operands may be in either byte, depending on mode and instruction. Register is cleared at the beginning of each instruction fetch. MMR2 (address 17777576): MMR2 is loaded with PC at the beginning of each instruction fetch. MMR3 (address 17777516): 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ | | | | | | | | | | |Unin| 22 |CSM | Mode | | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |terp| bit| enb| K S U | +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ Uninterp: Can be set or cleared, but is not used by hardware. 22 bit: Enables 22-bit mapping; default is 18-bit mapping. CSM enb: Enables recognition of the CSM instruction. Mode K: Enables mapping for kernel mode. Mode S: Enables mapping for supervisor mode. Mode U: Enables mapping for user mode. Upon memory parity error, abort through 114. Upon cache parity error, check CACHE CONTROL 7 and 0: 7 0 Action 0 0 Update cache, interrupt through 114 0 1 Update cache silently 1 X Update cache, abort through 114 (should be used only by diagnostics) CACHE CONTROL (address 17777746): 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ | | | | | |Tag | | | PE |Data| | Force |Diag|CPI | | 0 | 0 | 0 | 0 | 0 | WWP|Byp |Flsh| enb| WWP|Uninterp | miss |mode| dis| +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ Tag WWP: Causes all cache updates to write the wrong tag parity. Byp: All accesses go to real memory; read hits invalidate cache. Flsh: Write-only (reads as 0); when written as 1, flushes cache (clears all valid bits). PE enb: Enables parity error abort (see "Upon cache parity error"). Data WWP: Causes all cache updates to write the wrong data parity. Uninterp: Can be set or cleared, but are not used by hardware. Force miss: When either is set, cache is completely disabled. Diag mode: Causes all non-bypass non-forced-miss word writes to allocate cache, irrespective of NXM errors. In addition, NXM writes will not trap. CPI dis: Disable cache parity interrupt (see "Upon cache parity error"). HIT/MISS (address 17777752): Shift register containing 1 for hit and 0 for miss, updated on each memory reference. Bit 0 is most recent. MEM SYS ERR (address 17777744): (This register is read-only; it is cleared by any write reference.) 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ | PE | | | | | | | | PE | PE |Tag | | | | | | |abrt| 0 | 0 | 0 | 0 | 0 | 0 | 0 |high| low| PE | 0 | 0 | 0 | 0 | 0 | +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ PE abrt: Set when cacpe or memory parity error aborts an instruction. PE high: Set when parity error was caused by high data byte. PE low: Set when parity error was caused by low data byte. Tag PE: Set when parity error was caused by tag. Bits 7..5 are maintained when CACHE CONTROL 7 is set; when not, all three are set on any cache parity error. Floating point is VAX format. Given 4 or 8 bytes in memory: 8 1 7 EMMMMMMM SEEEEEEE MMMMMMMM MMMMMMMM [ MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM ] 1 7 16 23 8 15 32 39 24 31 48 55 40 47 (MSB has lowest number, for both E and M. Yes, the mantissa byte-sex is twisted.) Mantissa includes a hidden bit. Exponent is excess-128. For example: 1.5 is c0 40 00 00 [ 00 00 00 00 ] FPS: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ | | | | | | | | | | | | | | | | | |FER |FID | 0 | 0 |FIUV|FIU |FIV |FIC | FD | FL | FT | 0 | FN | FZ | FV | FC | +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ FER: Floating ERror, set upon any of - division by zero - illegal opcode - any of the other errors, when the corresponding interrupt is enabled FID: Floating Interrupt Disable. Normally clear; when set, all floating interrupts are disabled. Intended as a maintenance feature. Assumed clear in all other discussions. FIUV: Floating Interrupt on Undefined Variable. When set, reading a -0 from memory as operand of ADD, SUB, MUL, DIV, CMP, MOD, NEG, ABS, TST, or any LOAD, causes interrupt, which occurs before execution. When clear, -0 can be loaded and used. Interrupt occurs on loading of -0, not on presence of -0 in registers. The FPP will not store -0 without an interrupt. FIU: Floating Interrupt on Underflow. When set, floating underflow causes interrupt. Fractional part will be correct; exponent will be 0400 too large, except for 0, which is correct. (An exception is discussed under the LDEXP instruction.) When reset, underflow stores exact 0 and no interrupt occurs. FIV: Floating Interrupt on oVerflow. When set, floating overflow causes interrupt. Fractional part will be correct; exponent will be 0400 too small. Exceptions can occur for MOD and LDEXP instructions. When reset, overflow stores exact 0 and no interrupt occurs. FIC: Floating Interrupt on integer Conversion. When set, a failure when trying to convert to an integer will cause an interrupt. Regardless of whether the interrupt occurs, the destination is set to 0 and all other registers are untouched. FD: Floating Double-precision. When set, calculations are done in double; when clear, single. FL: Floating Long integer. When set, conversions between integers and floats assume 32-bit integers; when clear, 16. FT: Floating Truncate. When set, floating operations, truncate; when clear, they round. FN/FZ/FV/FC: Condition codes. FC can be set only by float-to-int or double-to-int conversion. FEC, FEA: One vector is used for all floating exceptions (244). The six possible errors are coded in the FEC: 2 Invalid opcode 4 Divide-by-zero 6 F-to-int or D-to-int conversion error 8 Overflow 10 Underflow 12 Undefined variable The address of the instruction producing the exception is in the FEA. FEC and FEA are updated when any of these happen: - Divide by zero - Invalid opcode - Any of the other four exceptions when the corresponding interrupt is enabled When the corresponding interrupt is disabled, the four exceptions do not update FEC and FEA. The FID bit does not inhibit the updating of FEC and FEA. Floating addressing modes: Same as main processor, except for mode 0, in which case the register is a floating accumulator instead of R0-R7. Autoincrement and autodecrement use 4 and 8 as the inc/dec amount. Attempts to use accumulator 6 or 7 will result in an illegal opcode trap. "In mode 0, users can [use] all six FPP accumulators [...]. In all other modes which involve transfer of data to or from memory or the general registers, users are restricted to the first four FPP accumulators (AC0-AC3)."; this is probably because only two bits are reserved to hold the accumulator number. A biased exponent of 0 indicates a value of 0 (unless FIUV is enabled and the operand is -0, which traps). For all arithmetic except as the divisor of DIV, a 0 value means the result is exact. Two guard bits guarantee correct chop/round behavior for ADD/SUB/MUL/DIV. Rounding simply adds 1/2 LSB and then chops; there is no even/odd nonsense or such. Powerup sequence: Turn off LED 1 Assert BINIT L Wait 10 uS Negate BINIT L Clear MMR0 Clear MMR3 Wait 90 uS Clear PIRQ Clear FPS do { Read jumpers Clear CPU ERROR } while BPOK H is negated Set CCR<8> to flush cache, and clear all other CCR bits Clear MSER Clear PS Set CPU ERROR to 0177766 Read CPU ERROR Clear CPU ERROR if (value read equals value written) turn off LED 3 Read memory location 0 if (no NXM abort) { Read memory location 0177700 if (NXM abort) { Turn off LED 2 } } Read memory location 177560 if (no NXM abort) turn off LED 4 switch (powerup option) { case 0: pc@24, ps@26, begin execution case 1: ps=0, enter ODT case 2: pc=173000, ps=340, begin execution case 3: pc=(user boot << 12), ps=340, begin execution } ODT G command: Turn off LED 4 Assert BINIT L Wait 10 uS Negate BINIT L Clear MMR0 Clear MMR3 Wait 90 uS Clear PIRQ Clear FPS do { Read jumpers Clear CPU ERROR } while BPOK H is negated Set CCR<8> Clear MSER Clear PS Begin execution Bus timeout while getting interrupt vector: interrupt is ignored. ODT entry: DATI from RBUF (017777562) and ignore the character. Print Print R7 in %06o Print Print @ Enter wait loop ODT input sequence: Busy-wait using DATI for RCSR (017777560) bit <7> to become 1 DATI from RBUF (017777562) and use low byte ODT output sequence: Busy-wait using DATI for XCSR (017777564) bit <7> to become 1 DATO to XBUF (017777566) with character in low byte; high byte is undefined If XCSR bit <6> (interrupt enable) is set, program will get interrupt when P command is used. If G is used, BINIT L is supposed to clear all interrupt conditions. ODT has 10 internal states. Each echoes unknown characters as ? and ignores them. ODT echoes parity bits faithfully but ignores them when processing. Generated characters have 0 parity. All commands are echoed except for . R6 is the stack pointer selected by the PS. The PS responds to bus address 17777776; R0-R7 are not accessible by bus addresses. MMU registers are accessible by their bus addresses. Bus timeout generates "?\r\n@". ODT commands: / Open a bus address or processor register. @R3/123456 open R3 @RS/123456 open PS @1000/123456 open location 01000 With no specifier, @/123456 re-opens just-modified location (if none, ie if just entered ODT, ? is given.) Close open location. If new data precedes the , thing is changed. Reponse: @ Close open location, open next location. (If PS is open, this is like .) Doing this when R7 is open gets to R0. Address rollover is modulo 32K; to cross a 32K boundary, the address must be re-entered. Is echoed unusually; response is @, then sequence to open next location. \0, \2, \12 are echoed as "?\r\n@". $ is alternative to R for register designation with / command. If more than one character follows R (or $), last one is used, unless last three are 077 or 477, in which case PS is used. The T-bit of the PS cannot be changed by ODT (misfeature?). G Go. Echoed, then \0\0 is printed to flush the G, then above sequence is executed. P Proceed. No programmer-visible state is altered. After the P is echoed, the machine is in instruction-fetch microstate. ^S Binary dump. After the echo, two 8-bit bytes are expected, high byte first; they are not echoed. These form a starting address in the first 64K of core. ODT responds by dumping 8 bytes from that address in raw binary, then @. H Reserved to DEC in the future. Treated as an invalid character. Bus use: there is DATO and DATOB and DATI, but no DATIB for some reason. Both DATIO and DATIOB do, however, exist. Addressing modes: sss sss (or) ddd ddd = mmm rrr mmm = mode; rrr = register 000 Rn 001 (Rn) 010 (Rn)+ #n 011 @(Rn)+ @#n 100 -(Rn) 101 @-(Rn) 110 X(Rn) n 111 @X(Rn) @n SP and PC autoincrement and autodecrement always add/subtract 2, even for byte data. When pushing bytes, the odd byte is left unmodified. Instructions: b in instructions is 0 for word, 1 for byte Single-operand group: c ccc ccc ccc ooo ooo clr(b) b 000 101 000 ddd ddd com(b) b 000 101 001 ddd ddd inc(b) b 000 101 010 ddd ddd dec(b) b 000 101 011 ddd ddd neg(b) b 000 101 100 ddd ddd adc(b) b 000 101 101 ddd ddd sbc(b) b 000 101 110 ddd ddd tst(b) b 000 101 111 ddd ddd ror(b) b 000 110 000 ddd ddd rol(b) b 000 110 001 ddd ddd asr(b) b 000 110 010 ddd ddd asl(b) b 000 110 011 ddd ddd jmp 0 000 000 001 ddd ddd swab 0 000 000 011 ddd ddd mfps 1 000 110 111 ddd ddd mtps 1 000 110 100 sss sss sxt 0 000 110 111 ddd ddd tstset 0 000 111 010 ddd ddd wrtlck 0 000 111 011 ddd ddd Double-operand group: c ccc sss sss ddd ddd bit(b) b 011 sss sss ddd ddd bic(b) b 100 sss sss ddd ddd bis(b) b 101 sss sss ddd ddd add 0 110 sss sss ddd ddd sub 1 110 sss sss ddd ddd mov(b) b 001 sss sss ddd ddd cmp(b) b 010 sss sss ddd ddd Operand-and-register group: c ccc ccc rrr sss sss ash 0 111 010 rrr sss sss ashc 0 111 011 rrr sss sss div 0 111 001 rrr sss sss mul 0 111 000 rrr sss sss xor 0 111 100 rrr ddd ddd Branch group: c ccc ccc coo ooo ooo br 0 000 000 1oo ooo ooo bne 0 000 001 0oo ooo ooo beq 0 000 001 1oo ooo ooo bpl 1 000 000 0oo ooo ooo bmi 1 000 000 1oo ooo ooo bvc 1 000 010 0oo ooo ooo bvs 1 000 010 1oo ooo ooo bcc 1 000 011 0oo ooo ooo bcs 1 000 011 1oo ooo ooo bge 0 000 010 0oo ooo ooo blt 0 000 010 1oo ooo ooo bgt 0 000 011 0oo ooo ooo ble 0 000 011 1oo ooo ooo bhi 1 000 001 0oo ooo ooo blos 1 000 001 1oo ooo ooo bhis 1 000 011 0oo ooo ooo blo 1 000 011 1oo ooo ooo jsr: 0 000 100 rrr ddd ddd rts: 0 000 000 010 000 rrr Trap group: c ccc ccc ccc ccc ccc iot 0 000 000 000 000 100 emt 1 000 100 0nn nnn nnn trap 1 000 100 1nn nnn nnn bpt 0 000 000 000 000 011 sob: 0 111 111 rrr ooo ooo mark: 0 000 110 100 nnn nnn csm: 0 000 111 000 ddd ddd spl: 0 000 000 010 011 nnn Operate group: c ccc ccc ccc ccc ccc halt 0 000 000 000 000 000 wait 0 000 000 000 000 001 rti 0 000 000 000 000 010 reset 0 000 000 000 000 101 rtt 0 000 000 000 000 110 nop 0 000 000 010 100 000 mfpt 0 000 000 000 000 111 Condition code group: 0 000 000 010 1xn zvc clc 0 000 000 010 100 001 clv 0 000 000 010 100 010 clz 0 000 000 010 100 100 cln 0 000 000 010 101 000 ccc 0 000 000 010 101 111 sec 0 000 000 010 110 001 sev 0 000 000 010 110 010 sez 0 000 000 010 110 100 sen 0 000 000 010 111 000 scc 0 000 000 010 111 111 Previous space group: c ccc ccc ccc ooo ooo mtpd 1 000 110 110 sss sss mtpi 0 000 110 110 sss sss mfpd 0 000 110 101 sss sss mfpi 1 000 110 101 sss sss This leaves the following ranges undefined: 0 000 000 000 001 000 .. 0 000 000 000 111 111 000010..000077 0 000 000 010 001 000 .. 0 000 000 010 010 111 000210..000227 0 000 000 010 110 000 (alone) 0 000 111 001 000 000 .. 0 000 111 001 111 111 007100..007177 0 000 111 100 000 000 .. 0 000 111 111 111 111 007400..007777 0 111 101 000 000 000 .. 0 111 110 111 111 111 075000..076777 1 000 111 000 000 000 .. 1 000 111 111 111 111 107000..107777 1 111 000 000 000 000 .. 1 111 111 111 111 111 170000..177777 17xxxx is used for floating point; see below. Instruction descriptions: * meaning: n gets high bit of result z set iff result is ==0 v set iff signed overflow occurred c set iff unsigned overflow occurred nzvc (0/1/-/*/@) clr(b) 0100 dst = 0 com(b) **01 dst = ~ dst inc(b) ***- dst ++ dec(b) ***- dst -- neg(b) ***@ dst = - dst C: cleared iff result is 0 tst(b) **00 compare dst with 0 wrtlck **0- Write r0 into dst using bus lock. Rn dst traps to 10. tstset **0@ Reads dst into r0; writes r0|1 into dst, all atomically. Rn dst traps to 10. C: gets low bit of value read asr(b) **@@ dst >>= 1, signed V: gets N^C C: gets bit shifted out of dst asl(b) **@@ dst <<= 1 V: gets N^C C: gets bit shifted out of dst ror(b) **@@ Rotate dst and C right one bit (circular shift through C) V: gets N^C C: per description rol(b) **@@ Rotate dst and C left one bit (circular shift through C) V: gets N^C C: per description swab @@00 Swap bytes in dst (dst must be word address; what happens if not is unspecified) N: set if resulting low byte is <0 Z: set if resulting low byte is 0 adc(b) **** dst += C sbc(b) **** dst -= C sxt -*0- dst = N ? ~0 : 0; mfps **0- dst = PS<7:0>, dst treated as byte; mode 0 sign-extends into high half mtps @@@@ PS<7:0> = dst, except as noted: T bit cannot be set this way priority can be changed only in kernel mode mov(b) **0- src = dst; mode 0 for dst of movb sign-extends into high half cmp(b) **** src - dst, result thrown away after setting ccodes (backwards from sub instr) add **** dst += src sub **** dst -= src ash **@@ reg signededly shifted src bits; src<0 is right, src>0 is left (only low six bits of src are used) V: set iff (doc says "if") high bit of register changed during shift C: last bit shifted out of reg (what if src==0?) ashc **@@ If reg is even, the 32-bit word whose high half is in reg and low half is in reg+1 is shifted as for ash (doc doesn't say whether src<0 is signed shift or not) If reg is odd, its 16-bit contents are rotated circularly right src bits. As with ash, only the low six bits of src are used. V: set if(f) high bit changes during shift C: loaded with last bit shifted out of 32-bit operand (what if src==0?) mul **0@ reg and src are multipled; the 32-bit product is stored in reg and reg|1 (which half where?); the low half is stored last, so if reg is odd, the high half is lost. C: set iff result is < -32768 or > 32767. div **@@ The 32-bit integer in reg and reg|1 is divided by src; quotient is left in reg. Remainder is same sign as dividend. reg "must be even", but what if not? V: set if src==0 or if quotient would exceed 15 bits C: set if src==0 bit(b) **0- src & dst; result thrown away after setting ccodes bic(b) **0- dst &= ~src bis(b) **0- dst |= src xor **0- dst ^= reg Offset is in words relative to pc, which points just after the branch instruction. branch when br 1 bne !Z beq Z bpl !N bmi N bvc !V bvs V bcc/bhis !C bcs/blo C bge N==V [N^V==0] blt N!=V [N^V==1] bgt (N==V)&&!Z [Z|(N^V)==0] ble (N!=V)||Z [Z|(N^V)==1] bhi !(C|Z) [C|Z==0] blos C|Z [C|Z==1] jmp if dst is mode 0, trap to 10 (can't execute out of registers, sigh) jsr tmp = dst; -(sp) = reg; reg = pc; pc = tmp; rts pc = reg; reg = (sp)+; sob if (--reg != 0) pc -= (2 * offset); ccodes not affected; offset is _not_ signed. emt trap through 30 trap trap through 34 bpt trap through 14 iot trap through 20 rti pc = (sp)+; ps = (sp)+; this instruction can set the T bit in the PS, cannot increase priority, cannot clear PS<11>. if the restored PS has T set, trace trap occurs before next instruction rtt pc = (sp)+; ps = (sp)+; if T is set in restored PS, trace trap is deferred one instruction; otherwise as rti. mark sp = pc + (2 * nn); pc = r5; r5 = (sp)+ spl ps<7:5> = nn; works only in kernel mode; in user/supervisor, is nop (*not* a trap). csm if (!MMR3<3> || not in kernel mode) trap through 10 in kernel mode else supervisor SP = kernel SP tmp<15:4> = PS<15:4> tmp<3:0> = 0 PS<13:12> = PS<15:14> PS<15:14> = 1 PS<4> = 0 -(SP) = tmp -(SP) = PC -(SP) = dst PC = (10) [in supervisor space] halt trap through 4 unless kernel mode, in which case per halt option. wait if not in kernel mode, nop; else, wait until an interrupt happens. (RTI will of course return to instruction after the wait, that being where pc points.) reset perform a bus reset, or something like it. mfpt r0 = 5, 5 being a magic number for kdj11-a. mtpd/mtpi pops a word off the current mode's stack and stores it into dst. dst's address is computed using the current mode and memory map, but the final store uses the previous mode's memory map. current mode is ps<15:14>; previous is ps<13:12>. ccodes affected **0-. mfpd/mfpi like mtpd/mtpi, but fetches from previous space and pushes on the stack. ccodes **0-. when current mode and previous mode are both user, mfpi turns into mfpd. se*/cl* modify ccodes per low five bits of instruction T-bit: A trace trap (trap through 14) occurs after the execution of any instruction which was fetched with T set in the PS. In particular, a trace trap occurs after an instruction which clears T, but started with T set. Floating point instructions: Single operand: 1 111 ccc ccc ooo ooo Double operand: 1 111 ccc caa ooo ooo c = opcode a = accumulator s = src d = dst S = fsrc D = fdst instr bits nzvc description abs[fd] 1 111 000 110 DDD DDD 0*00 dst = fabs(dst) add[fd] 1 111 010 0aa SSS SSS ***0 acc += src cfcc 1 111 000 000 000 000 ---- Copy fccodes into ccodes; fccodes remain unchanged clr[fd] 1 111 000 100 DDD DDD 0100 dst = 0 cmp[fd] 1 111 011 1aa SSS SSS **00 src - acc; result thrown away after setting fccodes, except that if both operands have biased exponent 0, acc will get an exact 0 stored in it. div[fd] 1 111 100 1aa SSS SSS ***0 ac /= src; if src == 0, FEC=4 and interrupt before execution. ldcdf/ldcfd 1 111 111 1aa SSS SSS ***- ac = src; if FD=0, src is double and is chopped (FT=1) or rounded (FT=0) to single and stored in acc; else FD=1, src is single and is extended (with 0s) to double and stored in acc. ldc[il][fd] 1 111 111 0aa sss sss **00 ac = src; convert from integer to floating. If FL, 32-bit int, else 16; if FD, to double, else single. If FL and src is Rn or #X, supplied 16 bits are the high 16 of the value to be converted (I think). ldexp 1 111 110 1aa sss sss ***0 Set acc's unbiased exponent to src (that is, set its biased exponent to src+0200). src>0177 is overflow; src<-0177 is underflow. No trap if -0 in AC, even if FIUV. ld[fd] 1 111 010 1aa SSS SSS **00 acc = src; ldfps 1 111 000 001 sss sss @@@@ Load FPS from src. Note that bits 4, 12, 13 are stuck 0. (fccodes are of course loaded as part of the operation.) mod[fd] 1 111 001 1aa SSS SSS **@0 Multiply acc by src giving prod (a conceptual temporary). Represent prod as N+g, for N integer and 0<=fabs(g)<1; both N and g have the same sign as prod. Store g in acc; if acc is even, store N in acc|1. prod is generated to only 59 bits. Five cases: let L be 24 or 56 for float or double resp. 1) prod overflows and FIV is set: acc|1=N chopped to L bits; acc=0. exp(N) is too small by 0400 and -0 may be stored in acc|1. if FIV is clear, acc|1=0, acc=0, and -0 will never be stored. 2) if 1<8. 4) if abs(prod) < 1, acc|1=0, acc=g; g may be rounded to 1. 5) prod underflows and FIU is set: acc|1=0 and acc=g. exp(g) is too large by 0400, except for 0, which is correct. interrupt will of course occur, and -0 may be stored in acc. V: set iff prod overflows other fcc bits are set based on acc, not acc|1. mul[fd] 1 111 001 0aa SSS SSS ***0 acc *= src neg[fd] 1 111 000 111 DDD DDD **00 dst = - dst; if FIUV is set, trap on -0 before execution setd 1 111 000 000 001 001 ---- FD = 1 (enter double mode) setf 1 111 000 000 000 001 ---- FD = 0 (enter float mode) seti 1 111 000 000 000 010 ---- FL = 0 (enter 16-bit integer mode) setl 1 111 000 000 001 010 ---- FL = 1 (enter 32-bit integer mode) stcfd/stcdf 1 111 110 0aa DDD DDD ***0 dst = acc; if FD=0, acc is single and is extended (with 0s) to double and stored in dst; FD=1, acc is double and is chopped (FT=1) or rounded (FT=0) to single and stored in dst. trap on -0 cannot occur because src is an acc. overflow can happen when FD=1 and FT=0; dst will get overflowed result (which will be +0 or -0). stc[fd][il] 1 111 101 1aa ddd ddd **0@ Convert acc to integer, where float and int sizes come from FD and FL. Result is stored in dst; if dst is Rn or #X and FL=1, only high 16 bits are stored. If converted value would be out of range, 0 is stored and C is set (C is cleared otherwise). "out of range" is oddly defined; the converted value (cval) is in range iff -JL-1 < cval < JL+1, where JL is either (1<<15)-1 or (1<<32)-1 depending on FL. (The book says 15 and 32; surely it should be either 16/32 or 15/31.) Conversion is done by chopping at the binary point, even if FT=0. NOTE: ccodes are set equal to fccodes at end of instruction! stexp 1 111 101 0aa ddd ddd **00 Convert acc's exponent from excess-0200 to 2's-complement and store in dst. No check for -0 is made. NOTE: ccodes are set equal to fccodes at end of instruction! st[fd] 1 111 100 0aa DDD DDD ---- dst = acc; these will store a -0 without interrupt. -0 can be present in acc two ways: underflow/overflow with corresponding interrupt bit set, or ldf/ldd instruction with FIUV cleared. stfps 1 111 000 010 ddd ddd ???? dst = FPS stst 1 111 000 011 ddd ddd ???? dst = FEC; dst+2 = FEA; if dst is Rn or #X, only FEC is saved. Note that FEC and FEA are not cleared for successful instructions. sub[fd] 1 111 011 0aa SSS SSS ***0 ac -= src tst[fd] 1 111 000 101 DDD DDD **00 Test dst. If -0 and FIUV, trap before execution.