Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 1 | /* pdp11_cpu.c: PDP-11 CPU simulator
|
| 2 |
|
Mark Pizzolato | 71e745b | 2016-03-06 06:27:15 -0800 | [diff] [blame] | 3 | Copyright (c) 1993-2016, Robert M Supnik
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 4 |
|
| 5 | Permission is hereby granted, free of charge, to any person obtaining a
|
| 6 | copy of this software and associated documentation files (the "Software"),
|
| 7 | to deal in the Software without restriction, including without limitation
|
| 8 | the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
| 9 | and/or sell copies of the Software, and to permit persons to whom the
|
| 10 | Software is furnished to do so, subject to the following conditions:
|
| 11 |
|
| 12 | The above copyright notice and this permission notice shall be included in
|
| 13 | all copies or substantial portions of the Software.
|
| 14 |
|
| 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
| 18 | ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
| 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
| 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
| 21 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 22 | Except as contained in this notice, the name of Robert M Supnik shall not be
|
| 23 | used in advertising or otherwise to promote the sale, use or other dealings
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 24 | in this Software without prior written authorization from Robert M Supnik.
|
| 25 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 26 | cpu PDP-11 CPU
|
Bob Supnik | 4d6dfa4 | 2001-11-06 20:50:00 -0800 | [diff] [blame] | 27 |
|
Paul Koning | 998cf5c | 2017-02-04 12:19:41 -0800 | [diff] [blame] | 28 | 04-Dec-16 RMS Removed duplicate IDLE entries in MTAB
|
| 29 | 30-Aug-16 RMS Fixed overloading of -d in ex/mod
|
| 30 | 14-Mar-16 RMS Added UC15 support
|
Mark Pizzolato | 71e745b | 2016-03-06 06:27:15 -0800 | [diff] [blame] | 31 | 06-Mar-16 RMS Fixed bug in history virtual addressing
|
Mark Pizzolato | 59947e8 | 2015-12-30 12:01:58 -0800 | [diff] [blame] | 32 | 30-Dec-15 RMS Added NOBEVENT option for 11/03, 11/23
|
| 33 | 29-Dec-15 RMS Call build_dib_tab during reset (Mark Pizzolato)
|
Mark Pizzolato | 2daa41e | 2013-12-06 10:54:56 -0800 | [diff] [blame] | 34 | 05-Dec-13 RMS Fixed bug in CSM (John Dundas)
|
Mark Pizzolato | f0d41f1 | 2013-10-27 05:30:13 -0700 | [diff] [blame] | 35 | 23-Oct-13 RMS Fixed PS behavior on initialization and boot
|
Mark Pizzolato | 4064cc0 | 2013-06-02 06:52:32 -0700 | [diff] [blame] | 36 | 10-Apr-13 RMS MMR1 does not track PC changes (Johnny Billquist)
|
Mark Pizzolato | e35e6bc | 2012-05-02 07:06:11 -0700 | [diff] [blame] | 37 | 29-Apr-12 RMS Fixed compiler warning (Mark Pizzolato)
|
Mark Pizzolato | 6e813b8 | 2012-03-24 19:46:37 -0700 | [diff] [blame] | 38 | 19-Mar-12 RMS Fixed declaration of sim_switches (Mark Pizzolato)
|
| 39 | 29-Dec-08 RMS Fixed failure to clear cpu_bme on RESET (Walter Mueller)
|
| 40 | 22-Apr-08 RMS Fixed MMR0 treatment in RESET (Walter Mueller)
|
| 41 | 02-Feb-08 RMS Fixed DMA memory address limit test (John Dundas)
|
Bob Supnik | 6149cc7 | 2007-05-12 17:39:00 -0700 | [diff] [blame] | 42 | 28-Apr-07 RMS Removed clock initialization
|
Bob Supnik | 53d02f7 | 2007-02-03 14:59:00 -0800 | [diff] [blame] | 43 | 27-Oct-06 RMS Added idle support
|
| 44 | 18-Oct-06 RMS Fixed bug in ASH -32 C value
|
Bob Supnik | dc871fa | 2006-05-27 11:34:00 -0700 | [diff] [blame] | 45 | 24-May-06 RMS Added instruction history
|
| 46 | 03-May-06 RMS Fixed XOR operand fetch order for 11/70-style systems
|
Mark Pizzolato | 6e813b8 | 2012-03-24 19:46:37 -0700 | [diff] [blame] | 47 | 22-Sep-05 RMS Fixed declarations (Sterling Garwood)
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 48 | 16-Aug-05 RMS Fixed C++ declaration and cast problems
|
| 49 | 19-May-05 RMS Replaced WAIT clock queue check with API call
|
Mark Pizzolato | 6e813b8 | 2012-03-24 19:46:37 -0700 | [diff] [blame] | 50 | 19-Jan-05 RMS Fixed bug(s) in RESET for 11/70 (Tim Chapman)
|
| 51 | 22-Dec-04 RMS Fixed WAIT to work in all modes (John Dundas)
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 52 | 02-Oct-04 RMS Added model emulation
|
| 53 | 25-Jan-04 RMS Removed local debug logging support
|
| 54 | 29-Dec-03 RMS Formalized 18b Qbus support
|
| 55 | 21-Dec-03 RMS Added autoconfiguration controls
|
| 56 | 05-Jun-03 RMS Fixed bugs in memory size table
|
| 57 | 12-Mar-03 RMS Added logical name support
|
| 58 | 01-Feb-03 RMS Changed R display to follow PSW<rs>, added SP display
|
| 59 | 19-Jan-03 RMS Changed mode definitions for Apple Dev Kit conflict
|
| 60 | 05-Jan-03 RMS Added memory size restore support
|
Mark Pizzolato | 6e813b8 | 2012-03-24 19:46:37 -0700 | [diff] [blame] | 61 | 17-Oct-02 RMS Fixed bug in examine/deposit (Hans Pufal)
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 62 | 08-Oct-02 RMS Revised to build dib_tab dynamically
|
| 63 | Added SHOW IOSPACE
|
| 64 | 09-Sep-02 RMS Added KW11P support
|
| 65 | 14-Jul-02 RMS Fixed bug in MMR0 error status load
|
| 66 | 03-Jun-02 RMS Fixed relocation add overflow, added PS<15:12> = 1111
|
| 67 | special case logic to MFPI and removed it from MTPI
|
Mark Pizzolato | 6e813b8 | 2012-03-24 19:46:37 -0700 | [diff] [blame] | 68 | (John Dundas)
|
| 69 | 29-Apr-02 RMS More fixes to DIV and ASH/ASHC (John Dundas)
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 70 | 28-Apr-02 RMS Fixed bugs in illegal instruction 000010 and in
|
Mark Pizzolato | 6e813b8 | 2012-03-24 19:46:37 -0700 | [diff] [blame] | 71 | write-only memory pages (Wolfgang Helbig)
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 72 | 21-Apr-02 RMS Fixed bugs in DIV by zero, DIV overflow, TSTSET, RTS,
|
Mark Pizzolato | 6e813b8 | 2012-03-24 19:46:37 -0700 | [diff] [blame] | 73 | ASHC -32, and red zone trap (John Dundas)
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 74 | 04-Mar-02 RMS Changed double operand evaluation order for M+
|
| 75 | 23-Feb-02 RMS Fixed bug in MAINT, CPUERR, MEMERR read
|
| 76 | 28-Jan-02 RMS Revised for multiple timers; fixed calc_MMR1 macros
|
| 77 | 06-Jan-02 RMS Revised enable/disable support
|
| 78 | 30-Dec-01 RMS Added old PC queue
|
| 79 | 25-Dec-01 RMS Cleaned up sim_inst declarations
|
| 80 | 11-Dec-01 RMS Moved interrupt debug code
|
| 81 | 07-Dec-01 RMS Revised to use new breakpoint package
|
| 82 | 08-Nov-01 RMS Moved I/O to external module
|
| 83 | 26-Oct-01 RMS Revised to use symbolic definitions for IO page
|
| 84 | 15-Oct-01 RMS Added debug logging
|
| 85 | 08-Oct-01 RMS Fixed bug in revised interrupt logic
|
| 86 | 07-Sep-01 RMS Revised device disable and interrupt mechanisms
|
| 87 | 26-Aug-01 RMS Added DZ11 support
|
| 88 | 10-Aug-01 RMS Removed register from declarations
|
| 89 | 17-Jul-01 RMS Fixed warning from VC++ 6.0
|
| 90 | 01-Jun-01 RMS Added DZ11 interrupts
|
| 91 | 23-Apr-01 RMS Added RK611 support
|
| 92 | 05-Apr-01 RMS Added TS11/TSV05 support
|
| 93 | 05-Mar-01 RMS Added clock calibration support
|
| 94 | 11-Feb-01 RMS Added DECtape support
|
Mark Pizzolato | 6e813b8 | 2012-03-24 19:46:37 -0700 | [diff] [blame] | 95 | 25-Jan-01 RMS Fixed 4M memory definition (Eric Smith)
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 96 | 14-Apr-99 RMS Changed t_addr to unsigned
|
| 97 | 18-Aug-98 RMS Added CIS support
|
| 98 | 09-May-98 RMS Fixed bug in DIV overflow test
|
| 99 | 19-Jan-97 RMS Added RP/RM support
|
| 100 | 06-Apr-96 RMS Added dynamic memory sizing
|
| 101 | 29-Feb-96 RMS Added TM11 support
|
| 102 | 17-Jul-94 RMS Corrected updating of MMR1 if MMR0 locked
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 103 |
|
| 104 | The register state for the PDP-11 is:
|
| 105 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 106 | REGFILE[0:5][0] general register set
|
| 107 | REGFILE[0:5][1] alternate general register set
|
| 108 | STACKFILE[4] stack pointers for kernel, supervisor, unused, user
|
| 109 | PC program counter
|
| 110 | PSW processor status word
|
| 111 | <15:14> = CM current processor mode
|
| 112 | <13:12> = PM previous processor mode
|
| 113 | <11> = RS register set select
|
| 114 | <8> = FPD first part done (CIS)
|
| 115 | <7:5> = IPL interrupt priority level
|
| 116 | <4> = TBIT trace trap enable
|
| 117 | <3:0> = NZVC condition codes
|
| 118 | FR[0:5] floating point accumulators
|
| 119 | FPS floating point status register
|
| 120 | FEC floating exception code
|
| 121 | FEA floating exception address
|
| 122 | MMR0,1,2,3 memory management control registers
|
| 123 | APRFILE[0:63] memory management relocation registers for
|
| 124 | kernel, supervisor, unused, user
|
| 125 | <31:16> = PAR processor address registers
|
| 126 | <15:0> = PDR processor data registers
|
| 127 | PIRQ processor interrupt request register
|
| 128 | CPUERR CPU error register
|
| 129 | MEMERR memory system error register
|
| 130 | CCR cache control register
|
| 131 | MAINT maintenance register
|
| 132 | HITMISS cache status register
|
| 133 | SR switch register
|
| 134 | DR display register
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 135 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 136 | The PDP-11 has many instruction formats:
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 137 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 138 | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ double operand
|
| 139 | | opcode | source spec | dest spec | 010000:067777
|
| 140 | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 110000:167777
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 141 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 142 | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ register + operand
|
| 143 | | opcode | src reg| dest spec | 004000:004777
|
| 144 | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 070000:077777
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 145 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 146 | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ single operand
|
| 147 | | opcode | dest spec | 000100:000177
|
| 148 | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 000300:000377
|
| 149 | 005000:007777
|
| 150 | 105000:107777
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 151 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 152 | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ single register
|
| 153 | | opcode |dest reg| 000200:000207
|
| 154 | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 000230:000237
|
| 155 |
|
| 156 | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ no operand
|
| 157 | | opcode | 000000:000007
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 158 | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
| 159 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 160 | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ branch
|
| 161 | | opcode | branch displacement | 000400:003477
|
| 162 | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 100000:103477
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 163 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 164 | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ EMT/TRAP
|
| 165 | | opcode | trap code | 104000:104777
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 166 | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
| 167 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 168 | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ cond code operator
|
| 169 | | opcode | immediate | 000240:000277
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 170 | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
| 171 |
|
| 172 | An operand specifier consists of an addressing mode and a register.
|
| 173 | The addressing modes are:
|
| 174 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 175 | 0 register direct R op = R
|
| 176 | 1 register deferred (R) op = M[R]
|
| 177 | 2 autoincrement (R)+ op = M[R]; R = R + length
|
| 178 | 3 autoincrement deferred @(R)+ op = M[M[R]]; R = R + 2
|
| 179 | 4 autodecrement -(R) R = R - length; op = M[R]
|
| 180 | 5 autodecrement deferred @-(R) R = R - 2; op = M[M[R]]
|
| 181 | 6 displacement d(R) op = M[R + disp]
|
| 182 | 7 displacement deferred @d(R) op = M[M[R + disp]]
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 183 |
|
| 184 | There are eight general registers, R0-R7. R6 is the stack pointer,
|
| 185 | R7 the PC. The combination of addressing modes with R7 yields:
|
| 186 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 187 | 27 immediate #n op = M[PC]; PC = PC + 2
|
| 188 | 37 absolute @#n op = M[M[PC]]; PC = PC + 2
|
| 189 | 67 relative d(PC) op = M[PC + disp]
|
| 190 | 77 relative deferred @d(PC) op = M[M[PC + disp]]
|
| 191 |
|
| 192 | This routine is the instruction decode routine for the PDP-11. It
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 193 | is called from the simulator control program to execute instructions
|
| 194 | in simulated memory, starting at the simulated PC. It runs until an
|
| 195 | enabled exception is encountered.
|
| 196 |
|
| 197 | General notes:
|
| 198 |
|
| 199 | 1. Virtual address format. PDP-11 memory management uses the 16b
|
| 200 | virtual address, the type of reference (instruction or data), and
|
| 201 | the current mode, to construct the 22b physical address. To
|
| 202 | package this conveniently, the simulator uses a 19b pseudo virtual
|
| 203 | address, consisting of the 16b virtual address prefixed with the
|
| 204 | current mode and ispace/dspace indicator. These are precalculated
|
| 205 | as isenable and dsenable for ispace and dspace, respectively, and
|
| 206 | must be recalculated whenever MMR0, MMR3, or PSW<cm> changes.
|
| 207 |
|
| 208 | 2. Traps and interrupts. Variable trap_req bit-encodes all possible
|
| 209 | traps. In addition, an interrupt pending bit is encoded as the
|
| 210 | lowest priority trap. Traps are processed by trap_vec and trap_clear,
|
| 211 | which provide the vector and subordinate traps to clear, respectively.
|
| 212 |
|
Bob Supnik | 654937f | 2001-11-06 21:02:00 -0800 | [diff] [blame] | 213 | Array int_req[0:7] bit encodes all possible interrupts. It is masked
|
| 214 | under the interrupt priority level, ipl. If any interrupt request
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 215 | is not masked, the interrupt bit is set in trap_req. While most
|
| 216 | interrupts are handled centrally, a device can supply an interrupt
|
| 217 | acknowledge routine.
|
| 218 |
|
| 219 | 3. PSW handling. The PSW is kept as components, for easier access.
|
| 220 | Because the PSW can be explicitly written as address 17777776,
|
| 221 | all instructions must update PSW before executing their last write.
|
| 222 |
|
Bob Supnik | 2c2dd5e | 2002-11-17 15:54:00 -0800 | [diff] [blame] | 223 | 4. Adding I/O devices. These modules must be modified:
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 224 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 225 | pdp11_defs.h add device address and interrupt definitions
|
| 226 | pdp11_sys.c add to sim_devices table entry
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 227 | */
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 228 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 229 | /* Definitions */
|
| 230 |
|
| 231 | #include "pdp11_defs.h"
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 232 | #include "pdp11_cpumod.h"
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 233 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 234 | #define PCQ_SIZE 64 /* must be 2**n */
|
| 235 | #define PCQ_MASK (PCQ_SIZE - 1)
|
| 236 | #define PCQ_ENTRY pcq[pcq_p = (pcq_p - 1) & PCQ_MASK] = PC
|
| 237 | #define calc_is(md) ((md) << VA_V_MODE)
|
| 238 | #define calc_ds(md) (calc_is((md)) | ((MMR3 & dsmask[(md)])? VA_DS: 0))
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 239 | /* Register change tracking actually goes into variable reg_mods; from there
|
| 240 | it is copied into MMR1 if that register is not currently locked. */
|
| 241 | #define calc_MMR1(val) ((reg_mods)? (((val) << 8) | reg_mods): (val))
|
Bob Supnik | 53d02f7 | 2007-02-03 14:59:00 -0800 | [diff] [blame] | 242 | #define GET_SIGN_W(v) (((v) >> 15) & 1)
|
| 243 | #define GET_SIGN_B(v) (((v) >> 7) & 1)
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 244 | #define GET_Z(v) ((v) == 0)
|
| 245 | #define JMP_PC(x) PCQ_ENTRY; PC = (x)
|
| 246 | #define BRANCH_F(x) PCQ_ENTRY; PC = (PC + (((x) + (x)) & 0377)) & 0177777
|
| 247 | #define BRANCH_B(x) PCQ_ENTRY; PC = (PC + (((x) + (x)) | 0177400)) & 0177777
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 248 | #define UNIT_V_MSIZE (UNIT_V_UF + 0) /* dummy */
|
| 249 | #define UNIT_MSIZE (1u << UNIT_V_MSIZE)
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 250 |
|
Bob Supnik | dc871fa | 2006-05-27 11:34:00 -0700 | [diff] [blame] | 251 | #define HIST_MIN 64
|
| 252 | #define HIST_MAX (1u << 18)
|
| 253 | #define HIST_VLD 1 /* make PC odd */
|
| 254 | #define HIST_ILNT 4 /* max inst length */
|
| 255 |
|
| 256 | typedef struct {
|
| 257 | uint16 pc;
|
| 258 | uint16 psw;
|
| 259 | uint16 src;
|
| 260 | uint16 dst;
|
| 261 | uint16 inst[HIST_ILNT];
|
| 262 | } InstHistory;
|
| 263 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 264 | /* Global state */
|
| 265 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 266 | uint16 *M = NULL; /* memory */
|
Mark Pizzolato | c71e0c3 | 2012-12-13 15:21:07 -0800 | [diff] [blame] | 267 | int32 REGFILE[6][2] = { {0} }; /* R0-R5, two sets */
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 268 | int32 STACKFILE[4] = { 0 }; /* SP, four modes */
|
| 269 | int32 saved_PC = 0; /* program counter */
|
| 270 | int32 R[8] = { 0 }; /* working registers */
|
| 271 | int32 PSW = 0; /* PSW */
|
| 272 | int32 cm = 0; /* current mode */
|
| 273 | int32 pm = 0; /* previous mode */
|
| 274 | int32 rs = 0; /* register set */
|
| 275 | int32 fpd = 0; /* first part done */
|
| 276 | int32 ipl = 0; /* int pri level */
|
| 277 | int32 tbit = 0; /* trace flag */
|
| 278 | int32 N = 0, Z = 0, V = 0, C = 0; /* condition codes */
|
| 279 | int32 wait_state = 0; /* wait state */
|
| 280 | int32 trap_req = 0; /* trap requests */
|
| 281 | int32 int_req[IPL_HLVL] = { 0 }; /* interrupt requests */
|
| 282 | int32 PIRQ = 0; /* programmed int req */
|
| 283 | int32 STKLIM = 0; /* stack limit */
|
Mark Pizzolato | c71e0c3 | 2012-12-13 15:21:07 -0800 | [diff] [blame] | 284 | fpac_t FR[6] = { {0} }; /* fp accumulators */
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 285 | int32 FPS = 0; /* fp status */
|
| 286 | int32 FEC = 0; /* fp exception code */
|
| 287 | int32 FEA = 0; /* fp exception addr */
|
| 288 | int32 APRFILE[64] = { 0 }; /* PARs/PDRs */
|
| 289 | int32 MMR0 = 0; /* MMR0 - status */
|
| 290 | int32 MMR1 = 0; /* MMR1 - R+/-R */
|
| 291 | int32 MMR2 = 0; /* MMR2 - saved PC */
|
| 292 | int32 MMR3 = 0; /* MMR3 - 22b status */
|
| 293 | int32 cpu_bme = 0; /* bus map enable */
|
| 294 | int32 cpu_astop = 0; /* address stop */
|
| 295 | int32 isenable = 0, dsenable = 0; /* i, d space flags */
|
| 296 | int32 stop_trap = 1; /* stop on trap */
|
| 297 | int32 stop_vecabort = 1; /* stop on vec abort */
|
| 298 | int32 stop_spabort = 1; /* stop on SP abort */
|
| 299 | int32 wait_enable = 0; /* wait state enable */
|
| 300 | int32 autcon_enb = 1; /* autoconfig enable */
|
Paul Koning | 998cf5c | 2017-02-04 12:19:41 -0800 | [diff] [blame] | 301 | uint32 cpu_model = INIMODEL; /* CPU model */
|
| 302 | uint32 cpu_type = 1u << INIMODEL; /* model as bit mask */
|
| 303 | uint32 cpu_opt = INIOPTNS; /* CPU options */
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 304 | uint16 pcq[PCQ_SIZE] = { 0 }; /* PC queue */
|
| 305 | int32 pcq_p = 0; /* PC queue ptr */
|
| 306 | REG *pcq_r = NULL; /* PC queue reg ptr */
|
| 307 | jmp_buf save_env; /* abort handler */
|
Bob Supnik | dc871fa | 2006-05-27 11:34:00 -0700 | [diff] [blame] | 308 | int32 hst_p = 0; /* history pointer */
|
| 309 | int32 hst_lnt = 0; /* history length */
|
| 310 | InstHistory *hst = NULL; /* instruction history */
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 311 | int32 dsmask[4] = { MMR3_KDS, MMR3_SDS, 0, MMR3_UDS }; /* dspace enables */
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 312 | int16 inst_pc; /* PC of current instr */
|
| 313 | int32 inst_psw; /* PSW at instr. start */
|
| 314 | int16 reg_mods; /* reg deltas */
|
| 315 | int32 last_pa; /* pa from ReadMW/ReadMB */
|
| 316 | int32 saved_sim_interval; /* saved at inst start */
|
| 317 | t_stat reason; /* stop reason */
|
Bob Supnik | 654937f | 2001-11-06 21:02:00 -0800 | [diff] [blame] | 318 |
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 319 | extern int32 CPUERR, MAINT;
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 320 | extern CPUTAB cpu_tab[];
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 321 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 322 | /* Function declarations */
|
| 323 |
|
| 324 | t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
|
| 325 | t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);
|
| 326 | t_stat cpu_reset (DEVICE *dptr);
|
Mark Pizzolato | e7a9349 | 2014-04-17 13:07:37 -0700 | [diff] [blame] | 327 | t_bool cpu_is_pc_a_subroutine_call (t_addr **ret_addrs);
|
Mark Pizzolato | 5531ccb | 2016-05-15 15:25:33 -0700 | [diff] [blame] | 328 | t_stat cpu_set_hist (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
| 329 | t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
| 330 | t_stat cpu_show_virt (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 331 | int32 GeteaB (int32 spec);
|
| 332 | int32 GeteaW (int32 spec);
|
| 333 | int32 relocR (int32 addr);
|
| 334 | int32 relocW (int32 addr);
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 335 | void relocR_test (int32 va, int32 apridx);
|
| 336 | void relocW_test (int32 va, int32 apridx);
|
| 337 | t_bool PLF_test (int32 va, int32 apr);
|
| 338 | void reloc_abort (int32 err, int32 apridx);
|
| 339 | int32 ReadE (int32 addr);
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 340 | int32 ReadW (int32 addr);
|
| 341 | int32 ReadB (int32 addr);
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 342 | int32 ReadCW (int32 addr);
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 343 | int32 ReadMW (int32 addr);
|
| 344 | int32 ReadMB (int32 addr);
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 345 | int32 PReadW (int32 addr);
|
| 346 | int32 PReadB (int32 addr);
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 347 | void WriteW (int32 data, int32 addr);
|
| 348 | void WriteB (int32 data, int32 addr);
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 349 | void WriteCW (int32 data, int32 addr);
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 350 | void PWriteW (int32 data, int32 addr);
|
| 351 | void PWriteB (int32 data, int32 addr);
|
Bob Supnik | f20f5c6 | 2003-02-07 21:28:00 -0800 | [diff] [blame] | 352 | void set_r_display (int32 rs, int32 cm);
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 353 | t_stat CPU_wr (int32 data, int32 addr, int32 access);
|
| 354 | void set_stack_trap (int32 adr);
|
| 355 | int32 get_PSW (void);
|
| 356 | void put_PSW (int32 val, t_bool prot);
|
| 357 | void put_PIRQ (int32 val);
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 358 |
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 359 | extern void fp11 (int32 IR);
|
Bob Supnik | 15919a2 | 2006-07-20 13:36:00 -0700 | [diff] [blame] | 360 | extern t_stat cis11 (int32 IR);
|
Bob Supnik | 1e704bf | 2005-10-15 15:38:00 -0700 | [diff] [blame] | 361 | extern t_stat fis11 (int32 IR);
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 362 | extern t_stat build_dib_tab (void);
|
Mark Pizzolato | 5531ccb | 2016-05-15 15:25:33 -0700 | [diff] [blame] | 363 | extern t_stat show_iospace (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
| 364 | extern t_stat set_autocon (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
| 365 | extern t_stat show_autocon (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
Bob Supnik | df64751 | 2002-07-14 15:20:00 -0700 | [diff] [blame] | 366 | extern t_stat iopageR (int32 *data, uint32 addr, int32 access);
|
| 367 | extern t_stat iopageW (int32 data, uint32 addr, int32 access);
|
Bob Supnik | 701f0fe | 2001-12-26 09:38:00 -0800 | [diff] [blame] | 368 | extern int32 calc_ints (int32 nipl, int32 trq);
|
| 369 | extern int32 get_vector (int32 nipl);
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 370 |
|
Bob Supnik | 701f0fe | 2001-12-26 09:38:00 -0800 | [diff] [blame] | 371 | /* Trap data structures */
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 372 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 373 | int32 trap_vec[TRAP_V_MAX] = { /* trap req to vector */
|
| 374 | VEC_RED, VEC_ODD, VEC_MME, VEC_NXM,
|
| 375 | VEC_PAR, VEC_PRV, VEC_ILL, VEC_BPT,
|
| 376 | VEC_IOT, VEC_EMT, VEC_TRAP, VEC_TRC,
|
| 377 | VEC_YEL, VEC_PWRFL, VEC_FPE
|
| 378 | };
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 379 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 380 | int32 trap_clear[TRAP_V_MAX] = { /* trap clears */
|
| 381 | TRAP_RED+TRAP_PAR+TRAP_YEL+TRAP_TRC+TRAP_ODD+TRAP_NXM,
|
| 382 | TRAP_ODD+TRAP_PAR+TRAP_YEL+TRAP_TRC,
|
| 383 | TRAP_MME+TRAP_PAR+TRAP_YEL+TRAP_TRC,
|
| 384 | TRAP_NXM+TRAP_PAR+TRAP_YEL+TRAP_TRC,
|
| 385 | TRAP_PAR+TRAP_TRC, TRAP_PRV+TRAP_TRC,
|
| 386 | TRAP_ILL+TRAP_TRC, TRAP_BPT+TRAP_TRC,
|
| 387 | TRAP_IOT+TRAP_TRC, TRAP_EMT+TRAP_TRC,
|
| 388 | TRAP_TRAP+TRAP_TRC, TRAP_TRC,
|
| 389 | TRAP_YEL, TRAP_PWRFL, TRAP_FPE
|
| 390 | };
|
| 391 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 392 | /* CPU data structures
|
| 393 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 394 | cpu_dev CPU device descriptor
|
| 395 | cpu_unit CPU unit descriptor
|
| 396 | cpu_reg CPU register list
|
| 397 | cpu_mod CPU modifier list
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 398 | */
|
| 399 |
|
Bob Supnik | 53d02f7 | 2007-02-03 14:59:00 -0800 | [diff] [blame] | 400 | UNIT cpu_unit = { UDATA (NULL, UNIT_FIX|UNIT_BINK, INIMEMSIZE) };
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 401 |
|
Mark Pizzolato | e054a78 | 2016-01-18 07:02:06 -0800 | [diff] [blame] | 402 | const char *psw_modes[] = {"K", "E", "S", "U"};
|
| 403 |
|
| 404 |
|
| 405 | BITFIELD psw_bits[] = {
|
| 406 | BIT(C), /* Carry */
|
| 407 | BIT(V), /* Overflow */
|
| 408 | BIT(Z), /* Zero */
|
| 409 | BIT(N), /* Negative */
|
| 410 | BIT(TBIT), /* trace trap */
|
| 411 | BITFFMT(IPL,3,%d), /* IPL */
|
| 412 | BIT(FPD), /* First Part Done */
|
| 413 | BITNCF(2), /* MBZ */
|
| 414 | BIT(RS), /* Register Set */
|
| 415 | BITFNAM(PM,2,psw_modes), /* Previous Access Mode */
|
| 416 | BITFNAM(CM,2,psw_modes), /* Current Access Mode */
|
| 417 | ENDBITS
|
| 418 | };
|
| 419 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 420 | REG cpu_reg[] = {
|
Mark Pizzolato | e054a78 | 2016-01-18 07:02:06 -0800 | [diff] [blame] | 421 | { ORDATAD (PC, saved_PC, 16, "Program Counter") },
|
| 422 | { ORDATAD (R0, REGFILE[0][0], 16, "General Purpose R0") },
|
| 423 | { ORDATAD (R1, REGFILE[1][0], 16, "General Purpose R1") },
|
| 424 | { ORDATAD (R2, REGFILE[2][0], 16, "General Purpose R2") },
|
| 425 | { ORDATAD (R3, REGFILE[3][0], 16, "General Purpose R3") },
|
| 426 | { ORDATAD (R4, REGFILE[4][0], 16, "General Purpose R4") },
|
| 427 | { ORDATAD (R5, REGFILE[5][0], 16, "General Purpose R5") },
|
| 428 | { ORDATAD (SP, STACKFILE[MD_KER], 16, "Stack Pointer"), },
|
| 429 | { ORDATAD (R00, REGFILE[0][0], 16, "Register File R00") },
|
| 430 | { ORDATAD (R01, REGFILE[1][0], 16, "Register File R01") },
|
| 431 | { ORDATAD (R02, REGFILE[2][0], 16, "Register File R02") },
|
| 432 | { ORDATAD (R03, REGFILE[3][0], 16, "Register File R03") },
|
| 433 | { ORDATAD (R04, REGFILE[4][0], 16, "Register File R04") },
|
| 434 | { ORDATAD (R05, REGFILE[5][0], 16, "Register File R05") },
|
| 435 | { ORDATAD (R10, REGFILE[0][1], 16, "Register File R10") },
|
| 436 | { ORDATAD (R11, REGFILE[1][1], 16, "Register File R11") },
|
| 437 | { ORDATAD (R12, REGFILE[2][1], 16, "Register File R12") },
|
| 438 | { ORDATAD (R13, REGFILE[3][1], 16, "Register File R13") },
|
| 439 | { ORDATAD (R14, REGFILE[4][1], 16, "Register File R14") },
|
| 440 | { ORDATAD (R15, REGFILE[5][1], 16, "Register File R15") },
|
| 441 | { ORDATAD (KSP, STACKFILE[MD_KER], 16, "Kernel Stack Pointer" ) },
|
| 442 | { ORDATAD (SSP, STACKFILE[MD_SUP], 16, "Supervisor Stack Pointer" ) },
|
| 443 | { ORDATAD (USP, STACKFILE[MD_USR], 16, "User Stack Pointer" ) },
|
| 444 | { ORDATADF(PSW, PSW, 16, "Processor Status Word", psw_bits) },
|
| 445 | { GRDATAD (CM, PSW, 8, 2, PSW_V_CM, "Current Mode") },
|
| 446 | { GRDATAD (PM, PSW, 8, 2, PSW_V_PM, "Previous Mode") },
|
| 447 | { FLDATAD (RS, PSW, PSW_V_RS, "Register Set") },
|
| 448 | { FLDATAD (FPD, PSW, PSW_V_FPD, "First Part Done") },
|
| 449 | { GRDATAD (IPL, PSW, 8, 3, PSW_V_IPL, "Interrupt Priority Level") },
|
| 450 | { FLDATAD (T, PSW, PSW_V_TBIT, "Trace Trap") },
|
| 451 | { FLDATAD (N, PSW, PSW_V_N, "Condition Code: Negative") },
|
| 452 | { FLDATAD (Z, PSW, PSW_V_Z, "Condition Code: Zero") },
|
| 453 | { FLDATAD (V, PSW, PSW_V_V, "Condition Code: Overflow") },
|
| 454 | { FLDATAD (C, PSW, PSW_V_C, "Condition Code: Carry") },
|
| 455 | { ORDATAD (PIRQ, PIRQ, 16, "Programmed Interrupt Request") },
|
| 456 | { ORDATAD (STKLIM, STKLIM, 16, "Stack Limit") },
|
| 457 | { ORDATAD (FAC0H, FR[0].h, 32, "Floating Point: R0 High") },
|
| 458 | { ORDATAD (FAC0L, FR[0].l, 32, "Floating Point: R0 Low") },
|
| 459 | { ORDATAD (FAC1H, FR[1].h, 32, "Floating Point: R1 High") },
|
| 460 | { ORDATAD (FAC1L, FR[1].l, 32, "Floating Point: R1 Low") },
|
| 461 | { ORDATAD (FAC2H, FR[2].h, 32, "Floating Point: R2 High") },
|
| 462 | { ORDATAD (FAC2L, FR[2].l, 32, "Floating Point: R2 Low") },
|
| 463 | { ORDATAD (FAC3H, FR[3].h, 32, "Floating Point: R3 High") },
|
| 464 | { ORDATAD (FAC3L, FR[3].l, 32, "Floating Point: R3 Low") },
|
| 465 | { ORDATAD (FAC4H, FR[4].h, 32, "Floating Point: R4 High") },
|
| 466 | { ORDATAD (FAC4L, FR[4].l, 32, "Floating Point: R4 Low") },
|
| 467 | { ORDATAD (FAC5H, FR[5].h, 32, "Floating Point: R5 High") },
|
| 468 | { ORDATAD (FAC5L, FR[5].l, 32, "Floating Point: R5 Low") },
|
| 469 | { ORDATAD (FPS, FPS, 16, "FP Status") },
|
| 470 | { ORDATAD (FEA, FEA, 16, "FP Exception Code") },
|
| 471 | { ORDATAD (FEC, FEC, 4, "FP Exception Address") },
|
| 472 | { ORDATAD (MMR0, MMR0, 16, "MMR0 - Status") },
|
| 473 | { ORDATAD (MMR1, MMR1, 16, "MMR1 - R+/-R") },
|
| 474 | { ORDATAD (MMR2, MMR2, 16, "MMR2 - saved PC") },
|
| 475 | { ORDATAD (MMR3, MMR3, 16, "MMR3 - 22b status") },
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 476 | { GRDATA (KIPAR0, APRFILE[000], 8, 16, 16) },
|
| 477 | { GRDATA (KIPDR0, APRFILE[000], 8, 16, 0) },
|
| 478 | { GRDATA (KIPAR1, APRFILE[001], 8, 16, 16) },
|
| 479 | { GRDATA (KIPDR1, APRFILE[001], 8, 16, 0) },
|
| 480 | { GRDATA (KIPAR2, APRFILE[002], 8, 16, 16) },
|
| 481 | { GRDATA (KIPDR2, APRFILE[002], 8, 16, 0) },
|
| 482 | { GRDATA (KIPAR3, APRFILE[003], 8, 16, 16) },
|
| 483 | { GRDATA (KIPDR3, APRFILE[003], 8, 16, 0) },
|
| 484 | { GRDATA (KIPAR4, APRFILE[004], 8, 16, 16) },
|
| 485 | { GRDATA (KIPDR4, APRFILE[004], 8, 16, 0) },
|
| 486 | { GRDATA (KIPAR5, APRFILE[005], 8, 16, 16) },
|
| 487 | { GRDATA (KIPDR5, APRFILE[005], 8, 16, 0) },
|
| 488 | { GRDATA (KIPAR6, APRFILE[006], 8, 16, 16) },
|
| 489 | { GRDATA (KIPDR6, APRFILE[006], 8, 16, 0) },
|
| 490 | { GRDATA (KIPAR7, APRFILE[007], 8, 16, 16) },
|
| 491 | { GRDATA (KIPDR7, APRFILE[007], 8, 16, 0) },
|
| 492 | { GRDATA (KDPAR0, APRFILE[010], 8, 16, 16) },
|
| 493 | { GRDATA (KDPDR0, APRFILE[010], 8, 16, 0) },
|
| 494 | { GRDATA (KDPAR1, APRFILE[011], 8, 16, 16) },
|
| 495 | { GRDATA (KDPDR1, APRFILE[011], 8, 16, 0) },
|
| 496 | { GRDATA (KDPAR2, APRFILE[012], 8, 16, 16) },
|
| 497 | { GRDATA (KDPDR2, APRFILE[012], 8, 16, 0) },
|
| 498 | { GRDATA (KDPAR3, APRFILE[013], 8, 16, 16) },
|
| 499 | { GRDATA (KDPDR3, APRFILE[013], 8, 16, 0) },
|
| 500 | { GRDATA (KDPAR4, APRFILE[014], 8, 16, 16) },
|
| 501 | { GRDATA (KDPDR4, APRFILE[014], 8, 16, 0) },
|
| 502 | { GRDATA (KDPAR5, APRFILE[015], 8, 16, 16) },
|
| 503 | { GRDATA (KDPDR5, APRFILE[015], 8, 16, 0) },
|
| 504 | { GRDATA (KDPAR6, APRFILE[016], 8, 16, 16) },
|
| 505 | { GRDATA (KDPDR6, APRFILE[016], 8, 16, 0) },
|
| 506 | { GRDATA (KDPAR7, APRFILE[017], 8, 16, 16) },
|
| 507 | { GRDATA (KDPDR7, APRFILE[017], 8, 16, 0) },
|
| 508 | { GRDATA (SIPAR0, APRFILE[020], 8, 16, 16) },
|
| 509 | { GRDATA (SIPDR0, APRFILE[020], 8, 16, 0) },
|
| 510 | { GRDATA (SIPAR1, APRFILE[021], 8, 16, 16) },
|
| 511 | { GRDATA (SIPDR1, APRFILE[021], 8, 16, 0) },
|
| 512 | { GRDATA (SIPAR2, APRFILE[022], 8, 16, 16) },
|
| 513 | { GRDATA (SIPDR2, APRFILE[022], 8, 16, 0) },
|
| 514 | { GRDATA (SIPAR3, APRFILE[023], 8, 16, 16) },
|
| 515 | { GRDATA (SIPDR3, APRFILE[023], 8, 16, 0) },
|
| 516 | { GRDATA (SIPAR4, APRFILE[024], 8, 16, 16) },
|
| 517 | { GRDATA (SIPDR4, APRFILE[024], 8, 16, 0) },
|
| 518 | { GRDATA (SIPAR5, APRFILE[025], 8, 16, 16) },
|
| 519 | { GRDATA (SIPDR5, APRFILE[025], 8, 16, 0) },
|
| 520 | { GRDATA (SIPAR6, APRFILE[026], 8, 16, 16) },
|
| 521 | { GRDATA (SIPDR6, APRFILE[026], 8, 16, 0) },
|
| 522 | { GRDATA (SIPAR7, APRFILE[027], 8, 16, 16) },
|
| 523 | { GRDATA (SIPDR7, APRFILE[027], 8, 16, 0) },
|
| 524 | { GRDATA (SDPAR0, APRFILE[030], 8, 16, 16) },
|
| 525 | { GRDATA (SDPDR0, APRFILE[030], 8, 16, 0) },
|
| 526 | { GRDATA (SDPAR1, APRFILE[031], 8, 16, 16) },
|
| 527 | { GRDATA (SDPDR1, APRFILE[031], 8, 16, 0) },
|
| 528 | { GRDATA (SDPAR2, APRFILE[032], 8, 16, 16) },
|
| 529 | { GRDATA (SDPDR2, APRFILE[032], 8, 16, 0) },
|
| 530 | { GRDATA (SDPAR3, APRFILE[033], 8, 16, 16) },
|
| 531 | { GRDATA (SDPDR3, APRFILE[033], 8, 16, 0) },
|
| 532 | { GRDATA (SDPAR4, APRFILE[034], 8, 16, 16) },
|
| 533 | { GRDATA (SDPDR4, APRFILE[034], 8, 16, 0) },
|
| 534 | { GRDATA (SDPAR5, APRFILE[035], 8, 16, 16) },
|
| 535 | { GRDATA (SDPDR5, APRFILE[035], 8, 16, 0) },
|
| 536 | { GRDATA (SDPAR6, APRFILE[036], 8, 16, 16) },
|
| 537 | { GRDATA (SDPDR6, APRFILE[036], 8, 16, 0) },
|
| 538 | { GRDATA (SDPAR7, APRFILE[037], 8, 16, 16) },
|
| 539 | { GRDATA (SDPDR7, APRFILE[037], 8, 16, 0) },
|
| 540 | { GRDATA (UIPAR0, APRFILE[060], 8, 16, 16) },
|
| 541 | { GRDATA (UIPDR0, APRFILE[060], 8, 16, 0) },
|
| 542 | { GRDATA (UIPAR1, APRFILE[061], 8, 16, 16) },
|
| 543 | { GRDATA (UIPDR1, APRFILE[061], 8, 16, 0) },
|
| 544 | { GRDATA (UIPAR2, APRFILE[062], 8, 16, 16) },
|
| 545 | { GRDATA (UIPDR2, APRFILE[062], 8, 16, 0) },
|
| 546 | { GRDATA (UIPAR3, APRFILE[063], 8, 16, 16) },
|
| 547 | { GRDATA (UIPDR3, APRFILE[063], 8, 16, 0) },
|
| 548 | { GRDATA (UIPAR4, APRFILE[064], 8, 16, 16) },
|
| 549 | { GRDATA (UIPDR4, APRFILE[064], 8, 16, 0) },
|
| 550 | { GRDATA (UIPAR5, APRFILE[065], 8, 16, 16) },
|
| 551 | { GRDATA (UIPDR5, APRFILE[065], 8, 16, 0) },
|
| 552 | { GRDATA (UIPAR6, APRFILE[066], 8, 16, 16) },
|
| 553 | { GRDATA (UIPDR6, APRFILE[066], 8, 16, 0) },
|
| 554 | { GRDATA (UIPAR7, APRFILE[067], 8, 16, 16) },
|
| 555 | { GRDATA (UIPDR7, APRFILE[067], 8, 16, 0) },
|
| 556 | { GRDATA (UDPAR0, APRFILE[070], 8, 16, 16) },
|
| 557 | { GRDATA (UDPDR0, APRFILE[070], 8, 16, 0) },
|
| 558 | { GRDATA (UDPAR1, APRFILE[071], 8, 16, 16) },
|
| 559 | { GRDATA (UDPDR1, APRFILE[071], 8, 16, 0) },
|
| 560 | { GRDATA (UDPAR2, APRFILE[072], 8, 16, 16) },
|
| 561 | { GRDATA (UDPDR2, APRFILE[072], 8, 16, 0) },
|
| 562 | { GRDATA (UDPAR3, APRFILE[073], 8, 16, 16) },
|
| 563 | { GRDATA (UDPDR3, APRFILE[073], 8, 16, 0) },
|
| 564 | { GRDATA (UDPAR4, APRFILE[074], 8, 16, 16) },
|
| 565 | { GRDATA (UDPDR4, APRFILE[074], 8, 16, 0) },
|
| 566 | { GRDATA (UDPAR5, APRFILE[075], 8, 16, 16) },
|
| 567 | { GRDATA (UDPDR5, APRFILE[075], 8, 16, 0) },
|
| 568 | { GRDATA (UDPAR6, APRFILE[076], 8, 16, 16) },
|
| 569 | { GRDATA (UDPDR6, APRFILE[076], 8, 16, 0) },
|
| 570 | { GRDATA (UDPAR7, APRFILE[077], 8, 16, 16) },
|
| 571 | { GRDATA (UDPDR7, APRFILE[077], 8, 16, 0) },
|
Mark Pizzolato | e054a78 | 2016-01-18 07:02:06 -0800 | [diff] [blame] | 572 | { BRDATAD (IREQ, int_req, 8, 32, IPL_HLVL, "Interrupt Requests"), REG_RO },
|
| 573 | { ORDATAD (TRAPS, trap_req, TRAP_V_MAX, "Trap Requests") },
|
| 574 | { FLDATAD (WAIT, wait_state, 0, "Wait State") },
|
Bob Supnik | 53d02f7 | 2007-02-03 14:59:00 -0800 | [diff] [blame] | 575 | { FLDATA (WAIT_ENABLE, wait_enable, 0), REG_HIDDEN },
|
Mark Pizzolato | e054a78 | 2016-01-18 07:02:06 -0800 | [diff] [blame] | 576 | { ORDATAD (STOP_TRAPS, stop_trap, TRAP_V_MAX, "Stop on Trap") },
|
| 577 | { FLDATAD (STOP_VECA, stop_vecabort, 0, "Stop on Vec Abort") },
|
| 578 | { FLDATAD (STOP_SPA, stop_spabort, 0, "Stop on SP Abort") },
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 579 | { FLDATA (AUTOCON, autcon_enb, 0), REG_HRO },
|
| 580 | { BRDATA (PCQ, pcq, 8, 16, PCQ_SIZE), REG_RO+REG_CIRC },
|
| 581 | { ORDATA (PCQP, pcq_p, 6), REG_HRO },
|
| 582 | { ORDATA (WRU, sim_int_char, 8) },
|
| 583 | { ORDATA (MODEL, cpu_model, 16), REG_HRO },
|
| 584 | { ORDATA (OPTIONS, cpu_opt, 32), REG_HRO },
|
| 585 | { NULL}
|
| 586 | };
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 587 |
|
| 588 | MTAB cpu_mod[] = {
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 589 | { MTAB_XTD|MTAB_VDV, 0, "TYPE", NULL,
|
| 590 | NULL, &cpu_show_model },
|
Paul Koning | 998cf5c | 2017-02-04 12:19:41 -0800 | [diff] [blame] | 591 | #if !defined (UC15)
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 592 | { MTAB_XTD|MTAB_VDV, MOD_1103, NULL, "11/03", &cpu_set_model },
|
| 593 | { MTAB_XTD|MTAB_VDV, MOD_1104, NULL, "11/04", &cpu_set_model },
|
| 594 | { MTAB_XTD|MTAB_VDV, MOD_1105, NULL, "11/05", &cpu_set_model },
|
| 595 | { MTAB_XTD|MTAB_VDV, MOD_1120, NULL, "11/20", &cpu_set_model },
|
| 596 | { MTAB_XTD|MTAB_VDV, MOD_1123, NULL, "11/23", &cpu_set_model },
|
| 597 | { MTAB_XTD|MTAB_VDV, MOD_1123P, NULL, "11/23+", &cpu_set_model },
|
| 598 | { MTAB_XTD|MTAB_VDV, MOD_1124, NULL, "11/24", &cpu_set_model },
|
| 599 | { MTAB_XTD|MTAB_VDV, MOD_1134, NULL, "11/34", &cpu_set_model },
|
| 600 | { MTAB_XTD|MTAB_VDV, MOD_1140, NULL, "11/40", &cpu_set_model },
|
| 601 | { MTAB_XTD|MTAB_VDV, MOD_1144, NULL, "11/44", &cpu_set_model },
|
| 602 | { MTAB_XTD|MTAB_VDV, MOD_1145, NULL, "11/45", &cpu_set_model },
|
| 603 | { MTAB_XTD|MTAB_VDV, MOD_1153, NULL, "11/53", &cpu_set_model },
|
| 604 | { MTAB_XTD|MTAB_VDV, MOD_1160, NULL, "11/60", &cpu_set_model },
|
| 605 | { MTAB_XTD|MTAB_VDV, MOD_1170, NULL, "11/70", &cpu_set_model },
|
| 606 | { MTAB_XTD|MTAB_VDV, MOD_1173, NULL, "11/73", &cpu_set_model },
|
| 607 | { MTAB_XTD|MTAB_VDV, MOD_1173B, NULL, "11/73B", &cpu_set_model },
|
| 608 | { MTAB_XTD|MTAB_VDV, MOD_1183, NULL, "11/83", &cpu_set_model },
|
| 609 | { MTAB_XTD|MTAB_VDV, MOD_1184, NULL, "11/84", &cpu_set_model },
|
| 610 | { MTAB_XTD|MTAB_VDV, MOD_1193, NULL, "11/93", &cpu_set_model },
|
| 611 | { MTAB_XTD|MTAB_VDV, MOD_1194, NULL, "11/94", &cpu_set_model },
|
| 612 | { MTAB_XTD|MTAB_VDV, MOD_1173, NULL, "Q22", &cpu_set_model },
|
| 613 | { MTAB_XTD|MTAB_VDV, MOD_1184, NULL, "URH11", &cpu_set_model },
|
| 614 | { MTAB_XTD|MTAB_VDV, MOD_1170, NULL, "URH70", &cpu_set_model },
|
| 615 | { MTAB_XTD|MTAB_VDV, MOD_1145, NULL, "U18", &cpu_set_model },
|
| 616 | { MTAB_XTD|MTAB_VDV, OPT_EIS, NULL, "EIS", &cpu_set_opt },
|
| 617 | { MTAB_XTD|MTAB_VDV, OPT_EIS, NULL, "NOEIS", &cpu_clr_opt },
|
| 618 | { MTAB_XTD|MTAB_VDV, OPT_FIS, NULL, "FIS", &cpu_set_opt },
|
| 619 | { MTAB_XTD|MTAB_VDV, OPT_FIS, NULL, "NOFIS", &cpu_clr_opt },
|
| 620 | { MTAB_XTD|MTAB_VDV, OPT_FPP, NULL, "FPP", &cpu_set_opt },
|
| 621 | { MTAB_XTD|MTAB_VDV, OPT_FPP, NULL, "NOFPP", &cpu_clr_opt },
|
| 622 | { MTAB_XTD|MTAB_VDV, OPT_CIS, NULL, "CIS", &cpu_set_opt },
|
| 623 | { MTAB_XTD|MTAB_VDV, OPT_CIS, NULL, "NOCIS", &cpu_clr_opt },
|
| 624 | { MTAB_XTD|MTAB_VDV, OPT_MMU, NULL, "MMU", &cpu_set_opt },
|
| 625 | { MTAB_XTD|MTAB_VDV, OPT_MMU, NULL, "NOMMU", &cpu_clr_opt },
|
Mark Pizzolato | 59947e8 | 2015-12-30 12:01:58 -0800 | [diff] [blame] | 626 | { MTAB_XTD|MTAB_VDV, OPT_BVT, NULL, "BEVENT", &cpu_set_opt, NULL, NULL, "Enable BEVENT line (11/03, 11/23 only)" },
|
| 627 | { MTAB_XTD|MTAB_VDV, OPT_BVT, NULL, "NOBEVENT", &cpu_clr_opt, NULL, NULL, "Disable BEVENT line (11/03, 11/23 only)" },
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 628 | { UNIT_MSIZE, 16384, NULL, "16K", &cpu_set_size},
|
| 629 | { UNIT_MSIZE, 32768, NULL, "32K", &cpu_set_size},
|
| 630 | { UNIT_MSIZE, 49152, NULL, "48K", &cpu_set_size},
|
| 631 | { UNIT_MSIZE, 65536, NULL, "64K", &cpu_set_size},
|
| 632 | { UNIT_MSIZE, 98304, NULL, "96K", &cpu_set_size},
|
| 633 | { UNIT_MSIZE, 131072, NULL, "128K", &cpu_set_size},
|
| 634 | { UNIT_MSIZE, 196608, NULL, "192K", &cpu_set_size},
|
| 635 | { UNIT_MSIZE, 262144, NULL, "256K", &cpu_set_size},
|
| 636 | { UNIT_MSIZE, 393216, NULL, "384K", &cpu_set_size},
|
| 637 | { UNIT_MSIZE, 524288, NULL, "512K", &cpu_set_size},
|
| 638 | { UNIT_MSIZE, 786432, NULL, "768K", &cpu_set_size},
|
| 639 | { UNIT_MSIZE, 1048576, NULL, "1024K", &cpu_set_size},
|
Mark Pizzolato | 7c9cebf | 2013-01-01 10:29:36 -0800 | [diff] [blame] | 640 | { UNIT_MSIZE, 1572864, NULL, "1536K", &cpu_set_size},
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 641 | { UNIT_MSIZE, 2097152, NULL, "2048K", &cpu_set_size},
|
| 642 | { UNIT_MSIZE, 3145728, NULL, "3072K", &cpu_set_size},
|
| 643 | { UNIT_MSIZE, 4186112, NULL, "4096K", &cpu_set_size},
|
| 644 | { UNIT_MSIZE, 1048576, NULL, "1M", &cpu_set_size},
|
| 645 | { UNIT_MSIZE, 2097152, NULL, "2M", &cpu_set_size},
|
| 646 | { UNIT_MSIZE, 3145728, NULL, "3M", &cpu_set_size},
|
| 647 | { UNIT_MSIZE, 4186112, NULL, "4M", &cpu_set_size},
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 648 | { MTAB_XTD|MTAB_VDV, 1, "AUTOCONFIG", "AUTOCONFIG",
|
| 649 | &set_autocon, &show_autocon },
|
| 650 | { MTAB_XTD|MTAB_VDV, 0, NULL, "NOAUTOCONFIG",
|
| 651 | &set_autocon, NULL },
|
Paul Koning | 998cf5c | 2017-02-04 12:19:41 -0800 | [diff] [blame] | 652 | #else
|
| 653 | { MTAB_XTD|MTAB_VDV, MOD_1104, NULL, "11/04", &cpu_set_model },
|
| 654 | { MTAB_XTD|MTAB_VDV, MOD_1105, NULL, "11/05", &cpu_set_model },
|
| 655 | { MTAB_XTD|MTAB_VDV, MOD_1120, NULL, "11/20", &cpu_set_model },
|
| 656 | { UNIT_MSIZE, 16384, NULL, "16K", &cpu_set_size},
|
| 657 | { UNIT_MSIZE, 24576, NULL, "24K", &cpu_set_size},
|
| 658 | { UNIT_MSIZE, 32768, NULL, "32K", &cpu_set_size},
|
| 659 | #endif
|
| 660 | { MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "IOSPACE", NULL,
|
| 661 | NULL, &show_iospace },
|
| 662 | { MTAB_XTD|MTAB_VDV, 0, "IDLE", "IDLE", &sim_set_idle, &sim_show_idle },
|
| 663 | { MTAB_XTD|MTAB_VDV, 0, NULL, "NOIDLE", &sim_clr_idle, NULL },
|
Bob Supnik | dc871fa | 2006-05-27 11:34:00 -0700 | [diff] [blame] | 664 | { MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "HISTORY", "HISTORY",
|
| 665 | &cpu_set_hist, &cpu_show_hist },
|
| 666 | { MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "VIRTUAL", NULL,
|
| 667 | NULL, &cpu_show_virt },
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 668 | { 0 }
|
| 669 | };
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 670 |
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 671 | BRKTYPTAB cpu_breakpoints [] = {
|
| 672 | BRKTYPE('E',"Execute Instruction at Virtual Address"),
|
| 673 | BRKTYPE('P',"Execute Instruction at Physical Address"),
|
| 674 | BRKTYPE('R',"Read from Virtual Address"),
|
| 675 | BRKTYPE('S',"Read from Physical Address"),
|
| 676 | BRKTYPE('W',"Write to Virtual Address"),
|
| 677 | BRKTYPE('X',"Write to Physical Address"),
|
| 678 | { 0 }
|
| 679 | };
|
| 680 |
|
Mark Pizzolato | cf1e7b9 | 2016-10-06 13:25:54 -0700 | [diff] [blame] | 681 | DEVICE cpu_dev = {
|
| 682 | "CPU", &cpu_unit, cpu_reg, cpu_mod,
|
| 683 | 1, 8, 22, 2, 8, 16,
|
| 684 | &cpu_ex, &cpu_dep, &cpu_reset,
|
| 685 | NULL, NULL, NULL,
|
| 686 | NULL, DEV_DYNM, 0,
|
| 687 | NULL, &cpu_set_size, NULL,
|
| 688 | NULL, NULL, NULL, NULL,
|
| 689 | cpu_breakpoints
|
| 690 | };
|
| 691 |
|
Mark Pizzolato | 3519c6c | 2013-11-17 08:55:29 -0800 | [diff] [blame] | 692 | t_value pdp11_pc_value (void)
|
| 693 | {
|
| 694 | return (t_value)PC;
|
| 695 | }
|
| 696 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 697 | t_stat sim_instr (void)
|
| 698 | {
|
Bob Supnik | 701f0fe | 2001-12-26 09:38:00 -0800 | [diff] [blame] | 699 | int abortval, i;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 700 | volatile int32 trapea; /* used by setjmp */
|
Mark Pizzolato | 0352e0f | 2016-08-25 14:27:02 -0700 | [diff] [blame] | 701 | InstHistory *hst_ent = NULL;
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 702 |
|
Mark Pizzolato | 3519c6c | 2013-11-17 08:55:29 -0800 | [diff] [blame] | 703 | sim_vm_pc_value = &pdp11_pc_value;
|
| 704 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 705 | /* Restore register state
|
| 706 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 707 | 1. PSW components
|
| 708 | 2. Active register file based on PSW<rs>
|
| 709 | 3. Active stack pointer based on PSW<cm>
|
| 710 | 4. Memory management control flags
|
| 711 | 5. Interrupt system
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 712 | */
|
| 713 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 714 | reason = build_dib_tab (); /* build, chk dib_tab */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 715 | if (reason != SCPE_OK)
|
| 716 | return reason;
|
Paul Koning | 998cf5c | 2017-02-04 12:19:41 -0800 | [diff] [blame] | 717 | if (MEMSIZE >= (cpu_tab[cpu_model].maxm - IOPAGESIZE)) /* mem size >= max - io page? */
|
| 718 | MEMSIZE = cpu_tab[cpu_model].maxm - IOPAGESIZE; /* max - io page */
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 719 | cpu_type = 1u << cpu_model; /* reset type mask */
|
| 720 | cpu_bme = (MMR3 & MMR3_BME) && (cpu_opt & OPT_UBM); /* map enabled? */
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 721 | PC = saved_PC;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 722 | put_PSW (PSW, 0); /* set PSW, call calc_xs */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 723 | for (i = 0; i < 6; i++)
|
| 724 | R[i] = REGFILE[i][rs];
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 725 | SP = STACKFILE[cm];
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 726 | isenable = calc_is (cm);
|
| 727 | dsenable = calc_ds (cm);
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 728 | put_PIRQ (PIRQ); /* rewrite PIRQ */
|
| 729 | STKLIM = STKLIM & STKLIM_RW; /* clean up STKLIM */
|
| 730 | MMR0 = MMR0 | MMR0_IC; /* usually on */
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 731 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 732 | trap_req = calc_ints (ipl, trap_req); /* upd int req */
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 733 | trapea = 0;
|
| 734 | reason = 0;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 735 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 736 | /* Abort handling
|
| 737 |
|
| 738 | If an abort occurs in memory management or memory access, the lower
|
| 739 | level routine executes a longjmp to this area OUTSIDE the main
|
| 740 | simulation loop. The longjmp specifies a trap mask which is OR'd
|
| 741 | into the trap_req register. Simulation then resumes at the fetch
|
| 742 | phase, and the trap is sprung.
|
| 743 |
|
| 744 | Aborts which occur within a trap sequence (trapea != 0) require
|
| 745 | special handling. If the abort occured on the stack pushes, and
|
| 746 | the mode (encoded in trapea) is kernel, an "emergency" kernel
|
| 747 | stack is created at 4, and a red zone stack trap taken.
|
Bob Supnik | df64751 | 2002-07-14 15:20:00 -0700 | [diff] [blame] | 748 |
|
| 749 | All variables used in setjmp processing, or assumed to be valid
|
| 750 | after setjmp, must be volatile or global.
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 751 | */
|
| 752 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 753 | abortval = setjmp (save_env); /* set abort hdlr */
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 754 | if (abortval == ABRT_BKPT) {
|
| 755 | /* Breakpoint encountered. */
|
| 756 | reason = STOP_IBKPT;
|
| 757 | /* Print a message reporting the type and address if it is not a
|
| 758 | plain virtual PC (instruction execution) breakpoint. */
|
| 759 | if (sim_brk_match_type != BPT_PCVIR)
|
| 760 | sim_messagef (reason, "\r\n%s", sim_brk_message());
|
| 761 | /* Restore the PC and sim_interval. */
|
| 762 | PC = inst_pc;
|
| 763 | sim_interval = saved_sim_interval;
|
| 764 | /* Restore PSW and the broken-out condition code values, provided
|
| 765 | FPD is not currently set. If it is, that means the instruction
|
| 766 | is interruptible and breakpoints are treated as continuation
|
| 767 | rather than replay. */
|
| 768 | if (!fpd) {
|
| 769 | PSW = inst_psw;
|
| 770 | put_PSW (inst_psw, 0);
|
| 771 | }
|
| 772 | /* Undo register changes. */
|
| 773 | while (reg_mods) {
|
| 774 | int rnum = reg_mods & 7;
|
| 775 | int delta = (reg_mods >> 3) & 037;
|
| 776 | reg_mods >>= 8;
|
| 777 | if (delta & 020) /* negative delta */
|
| 778 | delta = -(-delta & 037); /* get signed value */
|
| 779 | if (rnum != 7)
|
| 780 | R[rnum] -= delta;
|
| 781 | }
|
| 782 | }
|
| 783 | else {
|
| 784 | if (abortval != 0) {
|
| 785 | trap_req = trap_req | abortval; /* or in trap flag */
|
| 786 | if ((trapea > 0) && stop_vecabort)
|
| 787 | reason = STOP_VECABORT;
|
| 788 | if ((trapea < 0) && /* stack push abort? */
|
| 789 | (CPUT (STOP_STKA) || stop_spabort))
|
| 790 | reason = STOP_SPABORT;
|
| 791 | if (trapea == ~MD_KER) { /* kernel stk abort? */
|
| 792 | setTRAP (TRAP_RED);
|
| 793 | setCPUERR (CPUE_RED);
|
| 794 | STACKFILE[MD_KER] = 4;
|
| 795 | if (cm == MD_KER)
|
| 796 | SP = 4;
|
| 797 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 798 | }
|
| 799 | }
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 800 |
|
| 801 | /* Main instruction fetch/decode loop
|
| 802 |
|
| 803 | Check for traps or interrupts. If trap, locate the vector and check
|
| 804 | for stop condition. If interrupt, locate the vector.
|
| 805 | */
|
| 806 |
|
| 807 | while (reason == 0) {
|
Bob Supnik | 701f0fe | 2001-12-26 09:38:00 -0800 | [diff] [blame] | 808 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 809 | int32 IR, srcspec, srcreg, dstspec, dstreg;
|
| 810 | int32 src, src2, dst, ea;
|
| 811 | int32 i, t, sign, oldrs, trapnum;
|
Bob Supnik | df64751 | 2002-07-14 15:20:00 -0700 | [diff] [blame] | 812 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 813 | if (cpu_astop) {
|
| 814 | cpu_astop = 0;
|
| 815 | reason = SCPE_STOP;
|
| 816 | break;
|
Mark Pizzolato | 4064cc0 | 2013-06-02 06:52:32 -0700 | [diff] [blame] | 817 | }
|
Bob Supnik | 701f0fe | 2001-12-26 09:38:00 -0800 | [diff] [blame] | 818 |
|
Mark Pizzolato | 97de4db | 2013-01-29 04:35:30 -0800 | [diff] [blame] | 819 | AIO_CHECK_EVENT;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 820 | if (sim_interval <= 0) { /* intv cnt expired? */
|
Mark Pizzolato | 611a7e9 | 2014-10-26 15:15:31 -0700 | [diff] [blame] | 821 | /* Make sure all intermediate state is visible in simh registers */
|
| 822 | PSW = get_PSW ();
|
| 823 | for (i = 0; i < 6; i++)
|
| 824 | REGFILE[i][rs] = R[i];
|
| 825 | STACKFILE[cm] = SP;
|
| 826 | saved_PC = PC & 0177777;
|
| 827 | pcq_r->qptr = pcq_p; /* update pc q ptr */
|
| 828 | set_r_display (rs, cm);
|
Mark Pizzolato | 235ce92 | 2014-10-28 10:19:39 -0700 | [diff] [blame] | 829 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 830 | reason = sim_process_event (); /* process events */
|
Mark Pizzolato | 235ce92 | 2014-10-28 10:19:39 -0700 | [diff] [blame] | 831 |
|
| 832 | /* restore simh register contents into running variables */
|
| 833 | PC = saved_PC;
|
| 834 | put_PSW (PSW, 0); /* set PSW, call calc_xs */
|
| 835 | for (i = 0; i < 6; i++)
|
| 836 | R[i] = REGFILE[i][rs];
|
| 837 | SP = STACKFILE[cm];
|
| 838 | isenable = calc_is (cm);
|
| 839 | dsenable = calc_ds (cm);
|
| 840 | put_PIRQ (PIRQ); /* rewrite PIRQ */
|
| 841 | STKLIM = STKLIM & STKLIM_RW; /* clean up STKLIM */
|
| 842 | MMR0 = MMR0 | MMR0_IC; /* usually on */
|
| 843 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 844 | trap_req = calc_ints (ipl, trap_req); /* recalc int req */
|
| 845 | continue;
|
| 846 | } /* end if sim_interval */
|
Bob Supnik | 701f0fe | 2001-12-26 09:38:00 -0800 | [diff] [blame] | 847 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 848 | if (trap_req) { /* check traps, ints */
|
| 849 | trapea = 0; /* assume srch fails */
|
Mark Pizzolato | 0f8e6cf | 2012-04-29 11:59:44 -0700 | [diff] [blame] | 850 | if ((t = trap_req & TRAP_ALL)) { /* if a trap */
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 851 | for (trapnum = 0; trapnum < TRAP_V_MAX; trapnum++) {
|
| 852 | if ((t >> trapnum) & 1) { /* trap set? */
|
| 853 | trapea = trap_vec[trapnum]; /* get vec, clr */
|
| 854 | trap_req = trap_req & ~trap_clear[trapnum];
|
| 855 | if ((stop_trap >> trapnum) & 1) /* stop on trap? */
|
| 856 | reason = trapnum + 1;
|
| 857 | break;
|
| 858 | } /* end if t & 1 */
|
| 859 | } /* end for */
|
| 860 | } /* end if t */
|
| 861 | else {
|
| 862 | trapea = get_vector (ipl); /* get int vector */
|
| 863 | trapnum = TRAP_V_MAX; /* defang stk trap */
|
| 864 | } /* end else t */
|
| 865 | if (trapea == 0) { /* nothing to do? */
|
| 866 | trap_req = calc_ints (ipl, 0); /* recalculate */
|
| 867 | continue; /* back to fetch */
|
| 868 | } /* end if trapea */
|
| 869 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 870 | /* Process a trap or interrupt
|
| 871 |
|
| 872 | 1. Exit wait state
|
| 873 | 2. Save the current SP and PSW
|
| 874 | 3. Read the new PC, new PSW from trapea, kernel data space
|
| 875 | 4. Get the mode and stack selected by the new PSW
|
| 876 | 5. Push the old PC and PSW on the new stack
|
| 877 | 6. Update SP, PSW, and PC
|
| 878 | 7. If not stack overflow, check for stack overflow
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 879 |
|
| 880 | If the reads in step 3, or the writes in step 5, match a data breakpoint,
|
| 881 | the breakpoint status will be set but the interrupt actions will continue.
|
| 882 | The breakpoint stop will occur at the beginning of the next instruction
|
| 883 | cycle.
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 884 | */
|
| 885 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 886 | wait_state = 0; /* exit wait state */
|
| 887 | STACKFILE[cm] = SP;
|
| 888 | PSW = get_PSW (); /* assemble PSW */
|
| 889 | oldrs = rs;
|
| 890 | if (CPUT (HAS_MMTR)) { /* 45,70? */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 891 | if (update_MM) /* save vector */
|
| 892 | MMR2 = trapea;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 893 | MMR0 = MMR0 & ~MMR0_IC; /* clear IC */
|
| 894 | }
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 895 | src = ReadCW (trapea | calc_ds (MD_KER)); /* new PC */
|
| 896 | src2 = ReadCW ((trapea + 2) | calc_ds (MD_KER)); /* new PSW */
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 897 | t = (src2 >> PSW_V_CM) & 03; /* new cm */
|
| 898 | trapea = ~t; /* flag pushes */
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 899 | WriteCW (PSW, ((STACKFILE[t] - 2) & 0177777) | calc_ds (t));
|
| 900 | WriteCW (PC, ((STACKFILE[t] - 4) & 0177777) | calc_ds (t));
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 901 | trapea = 0; /* clear trap flag */
|
| 902 | src2 = (src2 & ~PSW_PM) | (cm << PSW_V_PM); /* insert prv mode */
|
| 903 | put_PSW (src2, 0); /* call calc_is,ds */
|
| 904 | if (rs != oldrs) { /* if rs chg, swap */
|
| 905 | for (i = 0; i < 6; i++) {
|
| 906 | REGFILE[i][oldrs] = R[i];
|
| 907 | R[i] = REGFILE[i][rs];
|
| 908 | }
|
| 909 | }
|
| 910 | SP = (STACKFILE[cm] - 4) & 0177777; /* update SP, PC */
|
| 911 | isenable = calc_is (cm);
|
| 912 | dsenable = calc_ds (cm);
|
| 913 | trap_req = calc_ints (ipl, trap_req);
|
| 914 | JMP_PC (src);
|
| 915 | if ((cm == MD_KER) && (SP < (STKLIM + STKL_Y)) &&
|
| 916 | (trapnum != TRAP_V_RED) && (trapnum != TRAP_V_YEL))
|
| 917 | set_stack_trap (SP);
|
| 918 | MMR0 = MMR0 | MMR0_IC; /* back to instr */
|
| 919 | continue; /* end if traps */
|
| 920 | }
|
| 921 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 922 | /* Fetch and decode next instruction */
|
| 923 |
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 924 | if (tbit)
|
| 925 | setTRAP (TRAP_TRC);
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 926 | if (wait_state) { /* wait state? */
|
Mark Pizzolato | 7256e09 | 2014-12-19 08:45:47 -0800 | [diff] [blame] | 927 | sim_idle (TMR_CLK, TRUE);
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 928 | continue;
|
| 929 | }
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 930 |
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 931 | reg_mods = 0;
|
| 932 | inst_pc = PC;
|
| 933 | /* Save PSW also because condition codes need to be preserved.
|
| 934 | We just save the whole PSW because that is sufficient (that
|
| 935 | representation is up to date at this point). If restoring is
|
| 936 | needed, both the PSW and the components that need to be restored
|
| 937 | are handled explicitly. */
|
| 938 | inst_psw = PSW;
|
| 939 | saved_sim_interval = sim_interval;
|
| 940 | if (BPT_SUMM_PC) { /* possible breakpoint */
|
| 941 | t_addr pa = relocR (PC | isenable); /* relocate PC */
|
| 942 | if (sim_brk_test (PC, BPT_PCVIR) || /* Normal PC breakpoint? */
|
| 943 | sim_brk_test (pa, BPT_PCPHY)) /* Physical Address breakpoint? */
|
| 944 | ABORT (ABRT_BKPT); /* stop simulation */
|
Mark Pizzolato | 4064cc0 | 2013-06-02 06:52:32 -0700 | [diff] [blame] | 945 | }
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 946 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 947 | if (update_MM) { /* if mm not frozen */
|
| 948 | MMR1 = 0;
|
| 949 | MMR2 = PC;
|
| 950 | }
|
| 951 | IR = ReadE (PC | isenable); /* fetch instruction */
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 952 | sim_interval = sim_interval - 1;
|
| 953 | srcspec = (IR >> 6) & 077; /* src, dst specs */
|
| 954 | dstspec = IR & 077;
|
| 955 | srcreg = (srcspec <= 07); /* src, dst = rmode? */
|
| 956 | dstreg = (dstspec <= 07);
|
Bob Supnik | dc871fa | 2006-05-27 11:34:00 -0700 | [diff] [blame] | 957 | if (hst_lnt) { /* record history? */
|
| 958 | t_value val;
|
| 959 | uint32 i;
|
Mark Pizzolato | 71e745b | 2016-03-06 06:27:15 -0800 | [diff] [blame] | 960 | static int32 swmap[4] = {
|
| 961 | SWMASK ('K') | SWMASK ('V'), SWMASK ('S') | SWMASK ('V'),
|
| 962 | SWMASK ('U') | SWMASK ('V'), SWMASK ('U') | SWMASK ('V')
|
| 963 | };
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 964 | hst_ent = &hst[hst_p];
|
| 965 | hst_ent->pc = PC | HIST_VLD;
|
| 966 | hst_ent->psw = get_PSW ();
|
| 967 | hst_ent->src = 0;
|
| 968 | hst_ent->dst = 0;
|
| 969 | hst_ent->inst[0] = IR;
|
Bob Supnik | dc871fa | 2006-05-27 11:34:00 -0700 | [diff] [blame] | 970 | for (i = 1; i < HIST_ILNT; i++) {
|
Mark Pizzolato | 71e745b | 2016-03-06 06:27:15 -0800 | [diff] [blame] | 971 | if (cpu_ex (&val, (PC + (i << 1)) & 0177777, &cpu_unit, swmap[cm & 03]))
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 972 | hst_ent->inst[i] = 0;
|
| 973 | else hst_ent->inst[i] = (uint16) val;
|
Bob Supnik | dc871fa | 2006-05-27 11:34:00 -0700 | [diff] [blame] | 974 | }
|
| 975 | hst_p = (hst_p + 1);
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 976 | if (hst_p >= hst_lnt)
|
| 977 | hst_p = 0;
|
Bob Supnik | dc871fa | 2006-05-27 11:34:00 -0700 | [diff] [blame] | 978 | }
|
| 979 | PC = (PC + 2) & 0177777; /* incr PC, mod 65k */
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 980 | switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
| 981 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 982 | /* Opcode 0: no operands, specials, branches, JSR, SOPs */
|
| 983 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 984 | case 000:
|
| 985 | switch ((IR >> 6) & 077) { /* decode IR<11:6> */
|
| 986 | case 000: /* no operand */
|
| 987 | if (IR >= 000010) { /* 000010 - 000077 */
|
| 988 | setTRAP (TRAP_ILL); /* illegal */
|
| 989 | break;
|
| 990 | }
|
| 991 | switch (IR) { /* decode IR<2:0> */
|
| 992 | case 0: /* HALT */
|
| 993 | if ((cm == MD_KER) &&
|
| 994 | (!CPUT (CPUT_J) || ((MAINT & MAINT_HTRAP) == 0)))
|
| 995 | reason = STOP_HALT;
|
| 996 | else if (CPUT (HAS_HALT4)) { /* priv trap? */
|
| 997 | setTRAP (TRAP_PRV);
|
| 998 | setCPUERR (CPUE_HALT);
|
| 999 | }
|
| 1000 | else setTRAP (TRAP_ILL); /* no, ill inst */
|
| 1001 | break;
|
| 1002 | case 1: /* WAIT */
|
Bob Supnik | 53d02f7 | 2007-02-03 14:59:00 -0800 | [diff] [blame] | 1003 | wait_state = 1;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1004 | break;
|
| 1005 | case 3: /* BPT */
|
| 1006 | setTRAP (TRAP_BPT);
|
| 1007 | break;
|
| 1008 | case 4: /* IOT */
|
| 1009 | setTRAP (TRAP_IOT);
|
| 1010 | break;
|
| 1011 | case 5: /* RESET */
|
| 1012 | if (cm == MD_KER) {
|
| 1013 | reset_all (2); /* skip CPU, sys reg */
|
Bob Supnik | 59aa4a7 | 2008-06-24 14:21:00 -0700 | [diff] [blame] | 1014 | PIRQ = 0; /* clear PIRQ */
|
| 1015 | STKLIM = 0; /* clear STKLIM */
|
| 1016 | MMR0 = 0; /* clear MMR0 */
|
| 1017 | MMR3 = 0; /* clear MMR3 */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1018 | cpu_bme = 0; /* (also clear bme) */
|
| 1019 | for (i = 0; i < IPL_HLVL; i++)
|
| 1020 | int_req[i] = 0;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1021 | trap_req = trap_req & ~TRAP_INT;
|
| 1022 | dsenable = calc_ds (cm);
|
| 1023 | }
|
| 1024 | break;
|
| 1025 | case 6: /* RTT */
|
| 1026 | if (!CPUT (HAS_RTT)) {
|
| 1027 | setTRAP (TRAP_ILL);
|
| 1028 | break;
|
| 1029 | }
|
| 1030 | case 2: /* RTI */
|
| 1031 | src = ReadW (SP | dsenable);
|
| 1032 | src2 = ReadW (((SP + 2) & 0177777) | dsenable);
|
| 1033 | STACKFILE[cm] = SP = (SP + 4) & 0177777;
|
| 1034 | oldrs = rs;
|
| 1035 | put_PSW (src2, (cm != MD_KER)); /* store PSW, prot */
|
| 1036 | if (rs != oldrs) {
|
| 1037 | for (i = 0; i < 6; i++) {
|
| 1038 | REGFILE[i][oldrs] = R[i];
|
| 1039 | R[i] = REGFILE[i][rs];
|
| 1040 | }
|
| 1041 | }
|
| 1042 | SP = STACKFILE[cm];
|
| 1043 | isenable = calc_is (cm);
|
| 1044 | dsenable = calc_ds (cm);
|
| 1045 | trap_req = calc_ints (ipl, trap_req);
|
| 1046 | JMP_PC (src);
|
| 1047 | if (CPUT (HAS_RTT) && tbit && /* RTT impl? */
|
Mark Pizzolato | 4064cc0 | 2013-06-02 06:52:32 -0700 | [diff] [blame] | 1048 | (IR == 000002))
|
| 1049 | setTRAP (TRAP_TRC); /* RTI immed trap */
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1050 | break;
|
| 1051 | case 7: /* MFPT */
|
| 1052 | if (CPUT (HAS_MFPT)) /* implemented? */
|
| 1053 | R[0] = cpu_tab[cpu_model].mfpt; /* get type */
|
| 1054 | else setTRAP (TRAP_ILL);
|
| 1055 | break;
|
| 1056 | } /* end switch no ops */
|
| 1057 | break; /* end case no ops */
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 1058 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1059 | case 001: /* JMP */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1060 | if (dstreg)
|
| 1061 | setTRAP (CPUT (HAS_JREG4)? TRAP_PRV: TRAP_ILL);
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1062 | else {
|
| 1063 | dst = GeteaW (dstspec) & 0177777; /* get eff addr */
|
| 1064 | if (CPUT (CPUT_05|CPUT_20) && /* 11/05, 11/20 */
|
| 1065 | ((dstspec & 070) == 020)) /* JMP (R)+? */
|
| 1066 | dst = R[dstspec & 07]; /* use post incr */
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1067 | if (hst_ent)
|
| 1068 | hst_ent->dst = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1069 | JMP_PC (dst);
|
| 1070 | }
|
| 1071 | break; /* end JMP */
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 1072 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1073 | case 002: /* RTS et al*/
|
| 1074 | if (IR < 000210) { /* RTS */
|
| 1075 | dstspec = dstspec & 07;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1076 | if (hst_ent)
|
| 1077 | hst_ent->dst = R[dstspec];
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1078 | JMP_PC (R[dstspec]);
|
| 1079 | R[dstspec] = ReadW (SP | dsenable);
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1080 | if (dstspec != 6)
|
| 1081 | SP = (SP + 2) & 0177777;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1082 | break;
|
| 1083 | } /* end if RTS */
|
| 1084 | if (IR < 000230) {
|
| 1085 | setTRAP (TRAP_ILL);
|
| 1086 | break;
|
| 1087 | }
|
| 1088 | if (IR < 000240) { /* SPL */
|
| 1089 | if (CPUT (HAS_SPL)) {
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1090 | if (cm == MD_KER)
|
| 1091 | ipl = IR & 07;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1092 | trap_req = calc_ints (ipl, trap_req);
|
| 1093 | }
|
| 1094 | else setTRAP (TRAP_ILL);
|
| 1095 | break;
|
| 1096 | } /* end if SPL */
|
| 1097 | if (IR < 000260) { /* clear CC */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1098 | if (IR & 010)
|
| 1099 | N = 0;
|
| 1100 | if (IR & 004)
|
| 1101 | Z = 0;
|
| 1102 | if (IR & 002)
|
| 1103 | V = 0;
|
| 1104 | if (IR & 001)
|
| 1105 | C = 0;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1106 | break;
|
| 1107 | } /* end if clear CCs */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1108 | if (IR & 010) /* set CC */
|
| 1109 | N = 1;
|
| 1110 | if (IR & 004)
|
| 1111 | Z = 1;
|
| 1112 | if (IR & 002)
|
| 1113 | V = 1;
|
| 1114 | if (IR & 001)
|
| 1115 | C = 1;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1116 | break; /* end case RTS et al */
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 1117 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1118 | case 003: /* SWAB */
|
| 1119 | dst = dstreg? R[dstspec]: ReadMW (GeteaW (dstspec));
|
| 1120 | dst = ((dst & 0377) << 8) | ((dst >> 8) & 0377);
|
| 1121 | N = GET_SIGN_B (dst & 0377);
|
| 1122 | Z = GET_Z (dst & 0377);
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1123 | if (!CPUT (CPUT_20))
|
| 1124 | V = 0;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1125 | C = 0;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1126 | if (hst_ent)
|
| 1127 | hst_ent->dst = dst;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1128 | if (dstreg)
|
| 1129 | R[dstspec] = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1130 | else PWriteW (dst, last_pa);
|
| 1131 | break; /* end SWAB */
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 1132 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1133 | case 004: case 005: /* BR */
|
| 1134 | BRANCH_F (IR);
|
| 1135 | break;
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 1136 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1137 | case 006: case 007: /* BR */
|
| 1138 | BRANCH_B (IR);
|
| 1139 | break;
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 1140 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1141 | case 010: case 011: /* BNE */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1142 | if (Z == 0) {
|
| 1143 | BRANCH_F (IR);
|
| 1144 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1145 | break;
|
| 1146 |
|
| 1147 | case 012: case 013: /* BNE */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1148 | if (Z == 0) {
|
| 1149 | BRANCH_B (IR);
|
| 1150 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1151 | break;
|
| 1152 |
|
| 1153 | case 014: case 015: /* BEQ */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1154 | if (Z) {
|
| 1155 | BRANCH_F (IR);
|
| 1156 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1157 | break;
|
| 1158 |
|
| 1159 | case 016: case 017: /* BEQ */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1160 | if (Z) {
|
| 1161 | BRANCH_B (IR);
|
| 1162 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1163 | break;
|
| 1164 |
|
| 1165 | case 020: case 021: /* BGE */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1166 | if ((N ^ V) == 0) {
|
| 1167 | BRANCH_F (IR);
|
| 1168 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1169 | break;
|
| 1170 |
|
| 1171 | case 022: case 023: /* BGE */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1172 | if ((N ^ V) == 0) {
|
| 1173 | BRANCH_B (IR);
|
| 1174 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1175 | break;
|
| 1176 |
|
| 1177 | case 024: case 025: /* BLT */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1178 | if (N ^ V) {
|
| 1179 | BRANCH_F (IR);
|
| 1180 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1181 | break;
|
| 1182 |
|
| 1183 | case 026: case 027: /* BLT */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1184 | if (N ^ V) {
|
| 1185 | BRANCH_B (IR);
|
| 1186 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1187 | break;
|
| 1188 |
|
| 1189 | case 030: case 031: /* BGT */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1190 | if ((Z | (N ^ V)) == 0) {
|
| 1191 | BRANCH_F (IR);
|
| 1192 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1193 | break;
|
| 1194 |
|
| 1195 | case 032: case 033: /* BGT */
|
| 1196 | if ((Z | (N ^ V)) == 0) { BRANCH_B (IR); }
|
| 1197 | break;
|
| 1198 |
|
| 1199 | case 034: case 035: /* BLE */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1200 | if (Z | (N ^ V)) {
|
| 1201 | BRANCH_F (IR);
|
| 1202 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1203 | break;
|
| 1204 |
|
| 1205 | case 036: case 037: /* BLE */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1206 | if (Z | (N ^ V)) {
|
| 1207 | BRANCH_B (IR);
|
| 1208 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1209 | break;
|
| 1210 |
|
| 1211 | case 040: case 041: case 042: case 043: /* JSR */
|
| 1212 | case 044: case 045: case 046: case 047:
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1213 | if (dstreg)
|
| 1214 | setTRAP (CPUT (HAS_JREG4)? TRAP_PRV: TRAP_ILL);
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1215 | else {
|
| 1216 | srcspec = srcspec & 07;
|
| 1217 | dst = GeteaW (dstspec);
|
| 1218 | if (CPUT (CPUT_05|CPUT_20) && /* 11/05, 11/20 */
|
| 1219 | ((dstspec & 070) == 020)) /* JSR (R)+? */
|
| 1220 | dst = R[dstspec & 07]; /* use post incr */
|
| 1221 | SP = (SP - 2) & 0177777;
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 1222 | reg_mods = calc_MMR1 (0366);
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1223 | if (update_MM)
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 1224 | MMR1 = reg_mods;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1225 | WriteW (R[srcspec], SP | dsenable);
|
| 1226 | if ((cm == MD_KER) && (SP < (STKLIM + STKL_Y)))
|
| 1227 | set_stack_trap (SP);
|
| 1228 | R[srcspec] = PC;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1229 | if (hst_ent)
|
| 1230 | hst_ent->dst = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1231 | JMP_PC (dst & 0177777);
|
| 1232 | }
|
| 1233 | break; /* end JSR */
|
| 1234 |
|
| 1235 | case 050: /* CLR */
|
| 1236 | N = V = C = 0;
|
| 1237 | Z = 1;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1238 | if (hst_ent)
|
| 1239 | hst_ent->dst = 0;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1240 | if (dstreg)
|
| 1241 | R[dstspec] = 0;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1242 | else WriteW (0, GeteaW (dstspec));
|
| 1243 | break;
|
| 1244 |
|
| 1245 | case 051: /* COM */
|
| 1246 | dst = dstreg? R[dstspec]: ReadMW (GeteaW (dstspec));
|
| 1247 | dst = dst ^ 0177777;
|
| 1248 | N = GET_SIGN_W (dst);
|
| 1249 | Z = GET_Z (dst);
|
| 1250 | V = 0;
|
| 1251 | C = 1;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1252 | if (hst_ent)
|
| 1253 | hst_ent->dst = dst;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1254 | if (dstreg)
|
| 1255 | R[dstspec] = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1256 | else PWriteW (dst, last_pa);
|
| 1257 | break;
|
| 1258 |
|
| 1259 | case 052: /* INC */
|
| 1260 | dst = dstreg? R[dstspec]: ReadMW (GeteaW (dstspec));
|
| 1261 | dst = (dst + 1) & 0177777;
|
| 1262 | N = GET_SIGN_W (dst);
|
| 1263 | Z = GET_Z (dst);
|
| 1264 | V = (dst == 0100000);
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1265 | if (hst_ent)
|
| 1266 | hst_ent->dst = dst;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1267 | if (dstreg)
|
| 1268 | R[dstspec] = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1269 | else PWriteW (dst, last_pa);
|
| 1270 | break;
|
| 1271 |
|
| 1272 | case 053: /* DEC */
|
| 1273 | dst = dstreg? R[dstspec]: ReadMW (GeteaW (dstspec));
|
| 1274 | dst = (dst - 1) & 0177777;
|
| 1275 | N = GET_SIGN_W (dst);
|
| 1276 | Z = GET_Z (dst);
|
| 1277 | V = (dst == 077777);
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1278 | if (hst_ent)
|
| 1279 | hst_ent->dst = dst;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1280 | if (dstreg)
|
| 1281 | R[dstspec] = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1282 | else PWriteW (dst, last_pa);
|
| 1283 | break;
|
| 1284 |
|
| 1285 | case 054: /* NEG */
|
| 1286 | dst = dstreg? R[dstspec]: ReadMW (GeteaW (dstspec));
|
| 1287 | dst = (-dst) & 0177777;
|
| 1288 | N = GET_SIGN_W (dst);
|
| 1289 | Z = GET_Z (dst);
|
| 1290 | V = (dst == 0100000);
|
| 1291 | C = Z ^ 1;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1292 | if (hst_ent)
|
| 1293 | hst_ent->dst = dst;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1294 | if (dstreg)
|
| 1295 | R[dstspec] = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1296 | else PWriteW (dst, last_pa);
|
| 1297 | break;
|
| 1298 |
|
| 1299 | case 055: /* ADC */
|
| 1300 | dst = dstreg? R[dstspec]: ReadMW (GeteaW (dstspec));
|
| 1301 | dst = (dst + C) & 0177777;
|
| 1302 | N = GET_SIGN_W (dst);
|
| 1303 | Z = GET_Z (dst);
|
| 1304 | V = (C && (dst == 0100000));
|
| 1305 | C = C & Z;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1306 | if (hst_ent)
|
| 1307 | hst_ent->dst = dst;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1308 | if (dstreg)
|
| 1309 | R[dstspec] = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1310 | else PWriteW (dst, last_pa);
|
| 1311 | break;
|
| 1312 |
|
| 1313 | case 056: /* SBC */
|
| 1314 | dst = dstreg? R[dstspec]: ReadMW (GeteaW (dstspec));
|
| 1315 | dst = (dst - C) & 0177777;
|
| 1316 | N = GET_SIGN_W (dst);
|
| 1317 | Z = GET_Z (dst);
|
| 1318 | V = (C && (dst == 077777));
|
| 1319 | C = (C && (dst == 0177777));
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1320 | if (hst_ent)
|
| 1321 | hst_ent->dst = dst;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1322 | if (dstreg)
|
| 1323 | R[dstspec] = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1324 | else PWriteW (dst, last_pa);
|
| 1325 | break;
|
| 1326 |
|
| 1327 | case 057: /* TST */
|
| 1328 | dst = dstreg? R[dstspec]: ReadW (GeteaW (dstspec));
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1329 | if (hst_ent)
|
| 1330 | hst_ent->dst = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1331 | N = GET_SIGN_W (dst);
|
| 1332 | Z = GET_Z (dst);
|
| 1333 | V = C = 0;
|
| 1334 | break;
|
| 1335 |
|
| 1336 | case 060: /* ROR */
|
| 1337 | src = dstreg? R[dstspec]: ReadMW (GeteaW (dstspec));
|
| 1338 | dst = (src >> 1) | (C << 15);
|
| 1339 | N = GET_SIGN_W (dst);
|
| 1340 | Z = GET_Z (dst);
|
| 1341 | C = (src & 1);
|
| 1342 | V = N ^ C;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1343 | if (hst_ent)
|
| 1344 | hst_ent->dst = dst;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1345 | if (dstreg)
|
| 1346 | R[dstspec] = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1347 | else PWriteW (dst, last_pa);
|
| 1348 | break;
|
| 1349 |
|
| 1350 | case 061: /* ROL */
|
| 1351 | src = dstreg? R[dstspec]: ReadMW (GeteaW (dstspec));
|
| 1352 | dst = ((src << 1) | C) & 0177777;
|
| 1353 | N = GET_SIGN_W (dst);
|
| 1354 | Z = GET_Z (dst);
|
| 1355 | C = GET_SIGN_W (src);
|
| 1356 | V = N ^ C;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1357 | if (hst_ent)
|
| 1358 | hst_ent->dst = dst;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1359 | if (dstreg)
|
| 1360 | R[dstspec] = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1361 | else PWriteW (dst, last_pa);
|
| 1362 | break;
|
| 1363 |
|
| 1364 | case 062: /* ASR */
|
| 1365 | src = dstreg? R[dstspec]: ReadMW (GeteaW (dstspec));
|
| 1366 | dst = (src >> 1) | (src & 0100000);
|
| 1367 | N = GET_SIGN_W (dst);
|
| 1368 | Z = GET_Z (dst);
|
| 1369 | C = (src & 1);
|
| 1370 | V = N ^ C;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1371 | if (hst_ent)
|
| 1372 | hst_ent->dst = dst;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1373 | if (dstreg)
|
| 1374 | R[dstspec] = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1375 | else PWriteW (dst, last_pa);
|
| 1376 | break;
|
| 1377 |
|
| 1378 | case 063: /* ASL */
|
| 1379 | src = dstreg? R[dstspec]: ReadMW (GeteaW (dstspec));
|
| 1380 | dst = (src << 1) & 0177777;
|
| 1381 | N = GET_SIGN_W (dst);
|
| 1382 | Z = GET_Z (dst);
|
| 1383 | C = GET_SIGN_W (src);
|
| 1384 | V = N ^ C;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1385 | if (hst_ent)
|
| 1386 | hst_ent->dst = dst;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1387 | if (dstreg)
|
| 1388 | R[dstspec] = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1389 | else PWriteW (dst, last_pa);
|
| 1390 | break;
|
| 1391 |
|
| 1392 | /* Notes:
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 1393 | - MxPI must mask GeteaW returned address to force ispace
|
| 1394 | - MxPI must set MMR1 for SP recovery in case of fault
|
| 1395 | */
|
| 1396 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1397 | case 064: /* MARK */
|
| 1398 | if (CPUT (HAS_MARK)) {
|
| 1399 | i = (PC + dstspec + dstspec) & 0177777;
|
| 1400 | JMP_PC (R[5]);
|
| 1401 | R[5] = ReadW (i | dsenable);
|
| 1402 | SP = (i + 2) & 0177777;
|
| 1403 | }
|
| 1404 | else setTRAP (TRAP_ILL);
|
| 1405 | break;
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 1406 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1407 | case 065: /* MFPI */
|
| 1408 | if (CPUT (HAS_MXPY)) {
|
| 1409 | if (dstreg) {
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1410 | if ((dstspec == 6) && (cm != pm))
|
| 1411 | dst = STACKFILE[pm];
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1412 | else dst = R[dstspec];
|
| 1413 | }
|
| 1414 | else {
|
Mark Pizzolato | c71e0c3 | 2012-12-13 15:21:07 -0800 | [diff] [blame] | 1415 | i = ((cm == pm) && (cm == MD_USR))? (int32)calc_ds (pm): (int32)calc_is (pm);
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1416 | dst = ReadW ((GeteaW (dstspec) & 0177777) | i);
|
| 1417 | }
|
| 1418 | N = GET_SIGN_W (dst);
|
| 1419 | Z = GET_Z (dst);
|
| 1420 | V = 0;
|
| 1421 | SP = (SP - 2) & 0177777;
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 1422 | reg_mods = calc_MMR1 (0366);
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1423 | if (update_MM)
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 1424 | MMR1 = reg_mods;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1425 | if (hst_ent)
|
| 1426 | hst_ent->dst = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1427 | WriteW (dst, SP | dsenable);
|
| 1428 | if ((cm == MD_KER) && (SP < (STKLIM + STKL_Y)))
|
| 1429 | set_stack_trap (SP);
|
| 1430 | }
|
| 1431 | else setTRAP (TRAP_ILL);
|
| 1432 | break;
|
| 1433 |
|
| 1434 | case 066: /* MTPI */
|
| 1435 | if (CPUT (HAS_MXPY)) {
|
| 1436 | dst = ReadW (SP | dsenable);
|
| 1437 | N = GET_SIGN_W (dst);
|
| 1438 | Z = GET_Z (dst);
|
| 1439 | V = 0;
|
| 1440 | SP = (SP + 2) & 0177777;
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 1441 | reg_mods = 026;
|
| 1442 | if (update_MM) MMR1 = reg_mods;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1443 | if (hst_ent)
|
| 1444 | hst_ent->dst = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1445 | if (dstreg) {
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1446 | if ((dstspec == 6) && (cm != pm))
|
| 1447 | STACKFILE[pm] = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1448 | else R[dstspec] = dst;
|
| 1449 | }
|
| 1450 | else WriteW (dst, (GeteaW (dstspec) & 0177777) | calc_is (pm));
|
| 1451 | }
|
| 1452 | else setTRAP (TRAP_ILL);
|
| 1453 | break;
|
| 1454 |
|
| 1455 | case 067: /* SXT */
|
| 1456 | if (CPUT (HAS_SXS)) {
|
| 1457 | dst = N? 0177777: 0;
|
| 1458 | Z = N ^ 1;
|
| 1459 | V = 0;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1460 | if (hst_ent)
|
| 1461 | hst_ent->dst = dst;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1462 | if (dstreg)
|
| 1463 | R[dstspec] = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1464 | else WriteW (dst, GeteaW (dstspec));
|
| 1465 | }
|
| 1466 | else setTRAP (TRAP_ILL);
|
| 1467 | break;
|
| 1468 |
|
| 1469 | case 070: /* CSM */
|
Mark Pizzolato | 2daa41e | 2013-12-06 10:54:56 -0800 | [diff] [blame] | 1470 | if (CPUT (HAS_CSM) && (MMR3 & MMR3_CSM) && (cm != MD_KER)) {
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1471 | dst = dstreg? R[dstspec]: ReadW (GeteaW (dstspec));
|
| 1472 | PSW = get_PSW () & ~PSW_CC; /* PSW, cc = 0 */
|
| 1473 | STACKFILE[cm] = SP;
|
| 1474 | WriteW (PSW, ((SP - 2) & 0177777) | calc_ds (MD_SUP));
|
| 1475 | WriteW (PC, ((SP - 4) & 0177777) | calc_ds (MD_SUP));
|
| 1476 | WriteW (dst, ((SP - 6) & 0177777) | calc_ds (MD_SUP));
|
| 1477 | SP = (SP - 6) & 0177777;
|
| 1478 | pm = cm;
|
| 1479 | cm = MD_SUP;
|
| 1480 | tbit = 0;
|
| 1481 | isenable = calc_is (cm);
|
| 1482 | dsenable = calc_ds (cm);
|
| 1483 | PC = ReadW (010 | isenable);
|
| 1484 | }
|
| 1485 | else setTRAP (TRAP_ILL);
|
| 1486 | break;
|
| 1487 |
|
| 1488 | case 072: /* TSTSET */
|
| 1489 | if (CPUT (HAS_TSWLK) && !dstreg) {
|
| 1490 | dst = ReadMW (GeteaW (dstspec));
|
| 1491 | N = GET_SIGN_W (dst);
|
| 1492 | Z = GET_Z (dst);
|
| 1493 | V = 0;
|
| 1494 | C = (dst & 1);
|
| 1495 | R[0] = dst; /* R[0] <- dst */
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1496 | if (hst_ent)
|
| 1497 | hst_ent->dst = dst | 1;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1498 | PWriteW (R[0] | 1, last_pa); /* dst <- R[0] | 1 */
|
| 1499 | }
|
| 1500 | else setTRAP (TRAP_ILL);
|
| 1501 | break;
|
| 1502 |
|
| 1503 | case 073: /* WRTLCK */
|
| 1504 | if (CPUT (HAS_TSWLK) && !dstreg) {
|
| 1505 | N = GET_SIGN_W (R[0]);
|
| 1506 | Z = GET_Z (R[0]);
|
| 1507 | V = 0;
|
| 1508 | WriteW (R[0], GeteaW (dstspec));
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1509 | if (hst_ent)
|
| 1510 | hst_ent->dst = R[0];
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1511 | }
|
| 1512 | else setTRAP (TRAP_ILL);
|
| 1513 | break;
|
| 1514 |
|
| 1515 | default:
|
| 1516 | setTRAP (TRAP_ILL);
|
| 1517 | break;
|
| 1518 | } /* end switch SOPs */
|
| 1519 | break; /* end case 000 */
|
| 1520 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 1521 | /* Opcodes 01 - 06: double operand word instructions
|
| 1522 |
|
Bob Supnik | df64751 | 2002-07-14 15:20:00 -0700 | [diff] [blame] | 1523 | J-11 (and F-11) optimize away register source operand decoding.
|
| 1524 | As a result, dop R,+/-(R) use the modified version of R as source.
|
| 1525 | Most (but not all) other PDP-11's fetch the source operand before
|
| 1526 | any destination operand decoding.
|
| 1527 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 1528 | Add: v = [sign (src) = sign (src2)] and [sign (src) != sign (result)]
|
| 1529 | Cmp: v = [sign (src) != sign (src2)] and [sign (src2) = sign (result)]
|
| 1530 | */
|
| 1531 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1532 | case 001: /* MOV */
|
| 1533 | if (CPUT (IS_SDSD) && srcreg && !dstreg) { /* R,not R */
|
| 1534 | ea = GeteaW (dstspec);
|
| 1535 | dst = R[srcspec];
|
| 1536 | }
|
| 1537 | else {
|
| 1538 | dst = srcreg? R[srcspec]: ReadW (GeteaW (srcspec));
|
Mark Pizzolato | 4064cc0 | 2013-06-02 06:52:32 -0700 | [diff] [blame] | 1539 | if (!dstreg)
|
| 1540 | ea = GeteaW (dstspec);
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1541 | }
|
| 1542 | N = GET_SIGN_W (dst);
|
| 1543 | Z = GET_Z (dst);
|
| 1544 | V = 0;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1545 | if (hst_ent) {
|
| 1546 | hst_ent->src = dst;
|
| 1547 | hst_ent->dst = dst;
|
| 1548 | }
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1549 | if (dstreg)
|
| 1550 | R[dstspec] = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1551 | else WriteW (dst, ea);
|
| 1552 | break;
|
| 1553 |
|
| 1554 | case 002: /* CMP */
|
| 1555 | if (CPUT (IS_SDSD) && srcreg && !dstreg) { /* R,not R */
|
| 1556 | src2 = ReadW (GeteaW (dstspec));
|
| 1557 | src = R[srcspec];
|
| 1558 | }
|
| 1559 | else {
|
| 1560 | src = srcreg? R[srcspec]: ReadW (GeteaW (srcspec));
|
| 1561 | src2 = dstreg? R[dstspec]: ReadW (GeteaW (dstspec));
|
| 1562 | }
|
| 1563 | dst = (src - src2) & 0177777;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1564 | if (hst_ent) {
|
| 1565 | hst_ent->src = src;
|
| 1566 | hst_ent->dst = src2;
|
| 1567 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1568 | N = GET_SIGN_W (dst);
|
| 1569 | Z = GET_Z (dst);
|
| 1570 | V = GET_SIGN_W ((src ^ src2) & (~src2 ^ dst));
|
| 1571 | C = (src < src2);
|
| 1572 | break;
|
| 1573 |
|
| 1574 | case 003: /* BIT */
|
| 1575 | if (CPUT (IS_SDSD) && srcreg && !dstreg) { /* R,not R */
|
| 1576 | src2 = ReadW (GeteaW (dstspec));
|
| 1577 | src = R[srcspec];
|
| 1578 | }
|
| 1579 | else {
|
| 1580 | src = srcreg? R[srcspec]: ReadW (GeteaW (srcspec));
|
| 1581 | src2 = dstreg? R[dstspec]: ReadW (GeteaW (dstspec));
|
| 1582 | }
|
| 1583 | dst = src2 & src;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1584 | if (hst_ent) {
|
| 1585 | hst_ent->src = src;
|
| 1586 | hst_ent->dst = dst;
|
| 1587 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1588 | N = GET_SIGN_W (dst);
|
| 1589 | Z = GET_Z (dst);
|
| 1590 | V = 0;
|
| 1591 | break;
|
| 1592 |
|
| 1593 | case 004: /* BIC */
|
| 1594 | if (CPUT (IS_SDSD) && srcreg && !dstreg) { /* R,not R */
|
| 1595 | src2 = ReadMW (GeteaW (dstspec));
|
| 1596 | src = R[srcspec];
|
| 1597 | }
|
| 1598 | else {
|
| 1599 | src = srcreg? R[srcspec]: ReadW (GeteaW (srcspec));
|
| 1600 | src2 = dstreg? R[dstspec]: ReadMW (GeteaW (dstspec));
|
| 1601 | }
|
| 1602 | dst = src2 & ~src;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1603 | if (hst_ent) {
|
| 1604 | hst_ent->src = src;
|
| 1605 | hst_ent->dst = dst;
|
| 1606 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1607 | N = GET_SIGN_W (dst);
|
| 1608 | Z = GET_Z (dst);
|
| 1609 | V = 0;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1610 | if (dstreg)
|
| 1611 | R[dstspec] = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1612 | else PWriteW (dst, last_pa);
|
| 1613 | break;
|
| 1614 |
|
| 1615 | case 005: /* BIS */
|
| 1616 | if (CPUT (IS_SDSD) && srcreg && !dstreg) { /* R,not R */
|
| 1617 | src2 = ReadMW (GeteaW (dstspec));
|
| 1618 | src = R[srcspec];
|
| 1619 | }
|
| 1620 | else {
|
| 1621 | src = srcreg? R[srcspec]: ReadW (GeteaW (srcspec));
|
| 1622 | src2 = dstreg? R[dstspec]: ReadMW (GeteaW (dstspec));
|
| 1623 | }
|
| 1624 | dst = src2 | src;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1625 | if (hst_ent) {
|
| 1626 | hst_ent->src = src;
|
| 1627 | hst_ent->dst = dst;
|
| 1628 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1629 | N = GET_SIGN_W (dst);
|
| 1630 | Z = GET_Z (dst);
|
| 1631 | V = 0;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1632 | if (dstreg)
|
| 1633 | R[dstspec] = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1634 | else PWriteW (dst, last_pa);
|
| 1635 | break;
|
| 1636 |
|
| 1637 | case 006: /* ADD */
|
| 1638 | if (CPUT (IS_SDSD) && srcreg && !dstreg) { /* R,not R */
|
| 1639 | src2 = ReadMW (GeteaW (dstspec));
|
| 1640 | src = R[srcspec];
|
| 1641 | }
|
| 1642 | else {
|
| 1643 | src = srcreg? R[srcspec]: ReadW (GeteaW (srcspec));
|
| 1644 | src2 = dstreg? R[dstspec]: ReadMW (GeteaW (dstspec));
|
| 1645 | }
|
| 1646 | dst = (src2 + src) & 0177777;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1647 | if (hst_ent) {
|
| 1648 | hst_ent->src = src;
|
| 1649 | hst_ent->dst = dst;
|
| 1650 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1651 | N = GET_SIGN_W (dst);
|
| 1652 | Z = GET_Z (dst);
|
| 1653 | V = GET_SIGN_W ((~src ^ src2) & (src ^ dst));
|
| 1654 | C = (dst < src);
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1655 | if (dstreg)
|
| 1656 | R[dstspec] = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1657 | else PWriteW (dst, last_pa);
|
| 1658 | break;
|
| 1659 |
|
Bob Supnik | 53d02f7 | 2007-02-03 14:59:00 -0800 | [diff] [blame] | 1660 | /* Opcode 07: EIS, FIS, CIS
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 1661 |
|
| 1662 | Notes:
|
| 1663 | - The code assumes that the host int length is at least 32 bits.
|
| 1664 | - MUL carry: C is set if the (signed) result doesn't fit in 16 bits.
|
| 1665 | - Divide has three error cases:
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1666 | 1. Divide by zero.
|
| 1667 | 2. Divide largest negative number by -1.
|
| 1668 | 3. (Signed) quotient doesn't fit in 16 bits.
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 1669 | Cases 1 and 2 must be tested in advance, to avoid C runtime errors.
|
| 1670 | - ASHx left: overflow if the bits shifted out do not equal the sign
|
| 1671 | of the result (convert shift out to 1/0, xor against sign).
|
| 1672 | - ASHx right: if right shift sign extends, then the shift and
|
| 1673 | conditional or of shifted -1 is redundant. If right shift zero
|
| 1674 | extends, then the shift and conditional or does sign extension.
|
| 1675 | */
|
| 1676 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1677 | case 007:
|
| 1678 | srcspec = srcspec & 07;
|
| 1679 | switch ((IR >> 9) & 07) { /* decode IR<11:9> */
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 1680 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1681 | case 0: /* MUL */
|
| 1682 | if (!CPUO (OPT_EIS)) {
|
| 1683 | setTRAP (TRAP_ILL);
|
| 1684 | break;
|
| 1685 | }
|
| 1686 | src2 = dstreg? R[dstspec]: ReadW (GeteaW (dstspec));
|
| 1687 | src = R[srcspec];
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1688 | if (GET_SIGN_W (src2))
|
| 1689 | src2 = src2 | ~077777;
|
| 1690 | if (GET_SIGN_W (src))
|
| 1691 | src = src | ~077777;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1692 | dst = src * src2;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1693 | if (hst_ent) {
|
| 1694 | hst_ent->src = src;
|
| 1695 | hst_ent->dst = dst;
|
| 1696 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1697 | R[srcspec] = (dst >> 16) & 0177777;
|
| 1698 | R[srcspec | 1] = dst & 0177777;
|
| 1699 | N = (dst < 0);
|
| 1700 | Z = GET_Z (dst);
|
| 1701 | V = 0;
|
| 1702 | C = ((dst > 077777) || (dst < -0100000));
|
| 1703 | break;
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 1704 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1705 | case 1: /* DIV */
|
| 1706 | if (!CPUO (OPT_EIS)) {
|
| 1707 | setTRAP (TRAP_ILL);
|
| 1708 | break;
|
| 1709 | }
|
| 1710 | src2 = dstreg? R[dstspec]: ReadW (GeteaW (dstspec));
|
| 1711 | src = (((uint32) R[srcspec]) << 16) | R[srcspec | 1];
|
| 1712 | if (src2 == 0) {
|
| 1713 | N = 0; /* J11,11/70 compat */
|
| 1714 | Z = V = C = 1; /* N = 0, Z = 1 */
|
| 1715 | break;
|
| 1716 | }
|
Mark Pizzolato | c548b34 | 2014-10-27 17:14:28 -0700 | [diff] [blame] | 1717 | if ((((uint32)src) == 020000000000) && (src2 == 0177777)) {
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1718 | V = 1; /* J11,11/70 compat */
|
| 1719 | N = Z = C = 0; /* N = Z = 0 */
|
| 1720 | break;
|
| 1721 | }
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1722 | if (GET_SIGN_W (src2))
|
| 1723 | src2 = src2 | ~077777;
|
| 1724 | if (GET_SIGN_W (R[srcspec]))
|
| 1725 | src = src | ~017777777777;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1726 | dst = src / src2;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1727 | if (hst_ent) {
|
| 1728 | hst_ent->src = src;
|
| 1729 | hst_ent->dst = dst;
|
| 1730 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1731 | N = (dst < 0); /* N set on 32b result */
|
| 1732 | if ((dst > 077777) || (dst < -0100000)) {
|
| 1733 | V = 1; /* J11,11/70 compat */
|
| 1734 | Z = C = 0; /* Z = C = 0 */
|
| 1735 | break;
|
| 1736 | }
|
| 1737 | R[srcspec] = dst & 0177777;
|
| 1738 | R[srcspec | 1] = (src - (src2 * dst)) & 0177777;
|
| 1739 | Z = GET_Z (dst);
|
| 1740 | V = C = 0;
|
| 1741 | break;
|
| 1742 |
|
| 1743 | case 2: /* ASH */
|
| 1744 | if (!CPUO (OPT_EIS)) {
|
| 1745 | setTRAP (TRAP_ILL);
|
| 1746 | break;
|
| 1747 | }
|
| 1748 | src2 = dstreg? R[dstspec]: ReadW (GeteaW (dstspec));
|
| 1749 | src2 = src2 & 077;
|
| 1750 | sign = GET_SIGN_W (R[srcspec]);
|
| 1751 | src = sign? R[srcspec] | ~077777: R[srcspec];
|
| 1752 | if (src2 == 0) { /* [0] */
|
| 1753 | dst = src;
|
| 1754 | V = C = 0;
|
| 1755 | }
|
| 1756 | else if (src2 <= 15) { /* [1,15] */
|
| 1757 | dst = src << src2;
|
| 1758 | i = (src >> (16 - src2)) & 0177777;
|
| 1759 | V = (i != ((dst & 0100000)? 0177777: 0));
|
| 1760 | C = (i & 1);
|
| 1761 | }
|
| 1762 | else if (src2 <= 31) { /* [16,31] */
|
| 1763 | dst = 0;
|
| 1764 | V = (src != 0);
|
| 1765 | C = (src << (src2 - 16)) & 1;
|
| 1766 | }
|
| 1767 | else if (src2 == 32) { /* [32] = -32 */
|
| 1768 | dst = -sign;
|
Bob Supnik | 53d02f7 | 2007-02-03 14:59:00 -0800 | [diff] [blame] | 1769 | V = 0;
|
| 1770 | C = sign;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1771 | }
|
| 1772 | else { /* [33,63] = -31,-1 */
|
| 1773 | dst = (src >> (64 - src2)) | (-sign << (src2 - 32));
|
| 1774 | V = 0;
|
| 1775 | C = ((src >> (63 - src2)) & 1);
|
| 1776 | }
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1777 | if (hst_ent) {
|
| 1778 | hst_ent->src = src;
|
| 1779 | hst_ent->dst = dst;
|
| 1780 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1781 | dst = R[srcspec] = dst & 0177777;
|
| 1782 | N = GET_SIGN_W (dst);
|
| 1783 | Z = GET_Z (dst);
|
| 1784 | break;
|
| 1785 |
|
| 1786 | case 3: /* ASHC */
|
| 1787 | if (!CPUO (OPT_EIS)) {
|
| 1788 | setTRAP (TRAP_ILL);
|
| 1789 | break;
|
| 1790 | }
|
| 1791 | src2 = dstreg? R[dstspec]: ReadW (GeteaW (dstspec));
|
| 1792 | src2 = src2 & 077;
|
| 1793 | sign = GET_SIGN_W (R[srcspec]);
|
| 1794 | src = (((uint32) R[srcspec]) << 16) | R[srcspec | 1];
|
| 1795 | if (src2 == 0) { /* [0] */
|
| 1796 | dst = src;
|
| 1797 | V = C = 0;
|
| 1798 | }
|
| 1799 | else if (src2 <= 31) { /* [1,31] */
|
| 1800 | dst = ((uint32) src) << src2;
|
| 1801 | i = (src >> (32 - src2)) | (-sign << src2);
|
| 1802 | V = (i != ((dst & 020000000000)? -1: 0));
|
| 1803 | C = (i & 1);
|
| 1804 | }
|
| 1805 | else if (src2 == 32) { /* [32] = -32 */
|
| 1806 | dst = -sign;
|
| 1807 | V = 0;
|
Bob Supnik | 53d02f7 | 2007-02-03 14:59:00 -0800 | [diff] [blame] | 1808 | C = sign;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1809 | }
|
| 1810 | else { /* [33,63] = -31,-1 */
|
| 1811 | dst = (src >> (64 - src2)) | (-sign << (src2 - 32));
|
| 1812 | V = 0;
|
| 1813 | C = ((src >> (63 - src2)) & 1);
|
| 1814 | }
|
| 1815 | i = R[srcspec] = (dst >> 16) & 0177777;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1816 | if (hst_ent) {
|
| 1817 | hst_ent->src = src;
|
| 1818 | hst_ent->dst = dst;
|
| 1819 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1820 | dst = R[srcspec | 1] = dst & 0177777;
|
| 1821 | N = GET_SIGN_W (i);
|
| 1822 | Z = GET_Z (dst | i);
|
| 1823 | break;
|
| 1824 |
|
| 1825 | case 4: /* XOR */
|
| 1826 | if (CPUT (HAS_SXS)) {
|
Bob Supnik | dc871fa | 2006-05-27 11:34:00 -0700 | [diff] [blame] | 1827 | if (CPUT (IS_SDSD) && !dstreg) { /* R,not R */
|
| 1828 | src2 = ReadMW (GeteaW (dstspec));
|
| 1829 | src = R[srcspec];
|
| 1830 | }
|
| 1831 | else {
|
| 1832 | src = R[srcspec];
|
| 1833 | src2 = dstreg? R[dstspec]: ReadMW (GeteaW (dstspec));
|
| 1834 | }
|
| 1835 | dst = src ^ src2;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1836 | if (hst_ent) {
|
| 1837 | hst_ent->src = src;
|
| 1838 | hst_ent->dst = dst;
|
| 1839 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1840 | N = GET_SIGN_W (dst);
|
| 1841 | Z = GET_Z (dst);
|
| 1842 | V = 0;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1843 | if (dstreg)
|
| 1844 | R[dstspec] = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1845 | else PWriteW (dst, last_pa);
|
| 1846 | }
|
| 1847 | else setTRAP (TRAP_ILL);
|
| 1848 | break;
|
| 1849 |
|
| 1850 | case 5: /* FIS */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1851 | if (CPUO (OPT_FIS))
|
| 1852 | fis11 (IR);
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1853 | else setTRAP (TRAP_ILL);
|
| 1854 | break;
|
| 1855 |
|
| 1856 | case 6: /* CIS */
|
| 1857 | if (CPUT (CPUT_60) && (cm == MD_KER) && /* 11/60 MED? */
|
| 1858 | (IR == 076600)) {
|
| 1859 | ReadE (PC | isenable); /* read immediate */
|
| 1860 | PC = (PC + 2) & 0177777;
|
| 1861 | }
|
Bob Supnik | 15919a2 | 2006-07-20 13:36:00 -0700 | [diff] [blame] | 1862 | else if (CPUO (OPT_CIS)) /* CIS option? */
|
| 1863 | reason = cis11 (IR);
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1864 | else setTRAP (TRAP_ILL);
|
| 1865 | break;
|
| 1866 |
|
| 1867 | case 7: /* SOB */
|
| 1868 | if (CPUT (HAS_SXS)) {
|
| 1869 | R[srcspec] = (R[srcspec] - 1) & 0177777;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1870 | if (hst_ent)
|
| 1871 | hst_ent->dst = R[srcspec];
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1872 | if (R[srcspec]) {
|
| 1873 | JMP_PC ((PC - dstspec - dstspec) & 0177777);
|
| 1874 | }
|
| 1875 | }
|
| 1876 | else setTRAP (TRAP_ILL);
|
| 1877 | break;
|
| 1878 | } /* end switch EIS */
|
| 1879 | break; /* end case 007 */
|
| 1880 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 1881 | /* Opcode 10: branches, traps, SOPs */
|
| 1882 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1883 | case 010:
|
| 1884 | switch ((IR >> 6) & 077) { /* decode IR<11:6> */
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 1885 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1886 | case 000: case 001: /* BPL */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1887 | if (N == 0) {
|
| 1888 | BRANCH_F (IR);
|
| 1889 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1890 | break;
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 1891 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1892 | case 002: case 003: /* BPL */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1893 | if (N == 0) {
|
| 1894 | BRANCH_B (IR);
|
| 1895 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1896 | break;
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 1897 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1898 | case 004: case 005: /* BMI */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1899 | if (N) {
|
| 1900 | BRANCH_F (IR);
|
| 1901 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1902 | break;
|
| 1903 |
|
| 1904 | case 006: case 007: /* BMI */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1905 | if (N) {
|
| 1906 | BRANCH_B (IR);
|
| 1907 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1908 | break;
|
| 1909 |
|
| 1910 | case 010: case 011: /* BHI */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1911 | if ((C | Z) == 0) {
|
| 1912 | BRANCH_F (IR);
|
| 1913 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1914 | break;
|
| 1915 |
|
| 1916 | case 012: case 013: /* BHI */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1917 | if ((C | Z) == 0) {
|
| 1918 | BRANCH_B (IR);
|
| 1919 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1920 | break;
|
| 1921 |
|
| 1922 | case 014: case 015: /* BLOS */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1923 | if (C | Z) {
|
| 1924 | BRANCH_F (IR);
|
| 1925 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1926 | break;
|
| 1927 |
|
| 1928 | case 016: case 017: /* BLOS */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1929 | if (C | Z) {
|
| 1930 | BRANCH_B (IR);
|
| 1931 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1932 | break;
|
| 1933 |
|
| 1934 | case 020: case 021: /* BVC */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1935 | if (V == 0) {
|
| 1936 | BRANCH_F (IR);
|
| 1937 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1938 | break;
|
| 1939 |
|
| 1940 | case 022: case 023: /* BVC */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1941 | if (V == 0) {
|
| 1942 | BRANCH_B (IR);
|
| 1943 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1944 | break;
|
| 1945 |
|
| 1946 | case 024: case 025: /* BVS */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1947 | if (V) {
|
| 1948 | BRANCH_F (IR);
|
| 1949 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1950 | break;
|
| 1951 |
|
| 1952 | case 026: case 027: /* BVS */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1953 | if (V) {
|
| 1954 | BRANCH_B (IR);
|
| 1955 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1956 | break;
|
| 1957 |
|
| 1958 | case 030: case 031: /* BCC */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1959 | if (C == 0) {
|
| 1960 | BRANCH_F (IR);
|
| 1961 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1962 | break;
|
| 1963 |
|
| 1964 | case 032: case 033: /* BCC */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1965 | if (C == 0) {
|
| 1966 | BRANCH_B (IR);
|
| 1967 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1968 | break;
|
| 1969 |
|
| 1970 | case 034: case 035: /* BCS */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1971 | if (C) {
|
| 1972 | BRANCH_F (IR);
|
| 1973 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1974 | break;
|
| 1975 |
|
| 1976 | case 036: case 037: /* BCS */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1977 | if (C) {
|
| 1978 | BRANCH_B (IR);
|
| 1979 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1980 | break;
|
| 1981 |
|
| 1982 | case 040: case 041: case 042: case 043: /* EMT */
|
| 1983 | setTRAP (TRAP_EMT);
|
| 1984 | break;
|
| 1985 |
|
| 1986 | case 044: case 045: case 046: case 047: /* TRAP */
|
| 1987 | setTRAP (TRAP_TRAP);
|
| 1988 | break;
|
| 1989 |
|
| 1990 | case 050: /* CLRB */
|
| 1991 | N = V = C = 0;
|
| 1992 | Z = 1;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 1993 | if (dstreg)
|
| 1994 | R[dstspec] = R[dstspec] & 0177400;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 1995 | else WriteB (0, GeteaB (dstspec));
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 1996 | if (hst_ent) {
|
| 1997 | if (dstreg)
|
| 1998 | hst_ent->dst = R[dstspec];
|
| 1999 | else hst_ent->dst = 0;
|
| 2000 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2001 | break;
|
| 2002 |
|
| 2003 | case 051: /* COMB */
|
| 2004 | dst = dstreg? R[dstspec]: ReadMB (GeteaB (dstspec));
|
| 2005 | dst = (dst ^ 0377) & 0377;
|
| 2006 | N = GET_SIGN_B (dst);
|
| 2007 | Z = GET_Z (dst);
|
| 2008 | V = 0;
|
| 2009 | C = 1;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2010 | if (dstreg)
|
| 2011 | R[dstspec] = (R[dstspec] & 0177400) | dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2012 | else PWriteB (dst, last_pa);
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 2013 | if (hst_ent) {
|
| 2014 | if (dstreg)
|
| 2015 | hst_ent->dst = R[dstspec];
|
| 2016 | else hst_ent->dst = dst;
|
| 2017 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2018 | break;
|
| 2019 |
|
| 2020 | case 052: /* INCB */
|
| 2021 | dst = dstreg? R[dstspec]: ReadMB (GeteaB (dstspec));
|
| 2022 | dst = (dst + 1) & 0377;
|
| 2023 | N = GET_SIGN_B (dst);
|
| 2024 | Z = GET_Z (dst);
|
| 2025 | V = (dst == 0200);
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2026 | if (dstreg)
|
| 2027 | R[dstspec] = (R[dstspec] & 0177400) | dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2028 | else PWriteB (dst, last_pa);
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 2029 | if (hst_ent) {
|
| 2030 | if (dstreg)
|
| 2031 | hst_ent->dst = R[dstspec];
|
| 2032 | else hst_ent->dst = dst;
|
| 2033 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2034 | break;
|
| 2035 |
|
| 2036 | case 053: /* DECB */
|
| 2037 | dst = dstreg? R[dstspec]: ReadMB (GeteaB (dstspec));
|
| 2038 | dst = (dst - 1) & 0377;
|
| 2039 | N = GET_SIGN_B (dst);
|
| 2040 | Z = GET_Z (dst);
|
| 2041 | V = (dst == 0177);
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2042 | if (dstreg)
|
| 2043 | R[dstspec] = (R[dstspec] & 0177400) | dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2044 | else PWriteB (dst, last_pa);
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 2045 | if (hst_ent) {
|
| 2046 | if (dstreg)
|
| 2047 | hst_ent->dst = R[dstspec];
|
| 2048 | else hst_ent->dst = dst;
|
| 2049 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2050 | break;
|
| 2051 |
|
| 2052 | case 054: /* NEGB */
|
| 2053 | dst = dstreg? R[dstspec]: ReadMB (GeteaB (dstspec));
|
| 2054 | dst = (-dst) & 0377;
|
| 2055 | N = GET_SIGN_B (dst);
|
| 2056 | Z = GET_Z (dst);
|
| 2057 | V = (dst == 0200);
|
| 2058 | C = (Z ^ 1);
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2059 | if (dstreg)
|
| 2060 | R[dstspec] = (R[dstspec] & 0177400) | dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2061 | else PWriteB (dst, last_pa);
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 2062 | if (hst_ent) {
|
| 2063 | if (dstreg)
|
| 2064 | hst_ent->dst = R[dstspec];
|
| 2065 | else hst_ent->dst = dst;
|
| 2066 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2067 | break;
|
| 2068 |
|
| 2069 | case 055: /* ADCB */
|
| 2070 | dst = dstreg? R[dstspec]: ReadMB (GeteaB (dstspec));
|
| 2071 | dst = (dst + C) & 0377;
|
| 2072 | N = GET_SIGN_B (dst);
|
| 2073 | Z = GET_Z (dst);
|
| 2074 | V = (C && (dst == 0200));
|
| 2075 | C = C & Z;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2076 | if (dstreg)
|
| 2077 | R[dstspec] = (R[dstspec] & 0177400) | dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2078 | else PWriteB (dst, last_pa);
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 2079 | if (hst_ent) {
|
| 2080 | if (dstreg)
|
| 2081 | hst_ent->dst = R[dstspec];
|
| 2082 | else hst_ent->dst = dst;
|
| 2083 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2084 | break;
|
| 2085 |
|
| 2086 | case 056: /* SBCB */
|
| 2087 | dst = dstreg? R[dstspec]: ReadMB (GeteaB (dstspec));
|
| 2088 | dst = (dst - C) & 0377;
|
| 2089 | N = GET_SIGN_B (dst);
|
| 2090 | Z = GET_Z (dst);
|
| 2091 | V = (C && (dst == 0177));
|
| 2092 | C = (C && (dst == 0377));
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2093 | if (dstreg)
|
| 2094 | R[dstspec] = (R[dstspec] & 0177400) | dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2095 | else PWriteB (dst, last_pa);
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 2096 | if (hst_ent) {
|
| 2097 | if (dstreg)
|
| 2098 | hst_ent->dst = R[dstspec];
|
| 2099 | else hst_ent->dst = dst;
|
| 2100 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2101 | break;
|
| 2102 |
|
| 2103 | case 057: /* TSTB */
|
| 2104 | dst = dstreg? R[dstspec] & 0377: ReadB (GeteaB (dstspec));
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 2105 | if (hst_ent)
|
| 2106 | hst_ent->dst = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2107 | N = GET_SIGN_B (dst);
|
| 2108 | Z = GET_Z (dst);
|
| 2109 | V = C = 0;
|
| 2110 | break;
|
| 2111 |
|
| 2112 | case 060: /* RORB */
|
| 2113 | src = dstreg? R[dstspec]: ReadMB (GeteaB (dstspec));
|
| 2114 | dst = ((src & 0377) >> 1) | (C << 7);
|
| 2115 | N = GET_SIGN_B (dst);
|
| 2116 | Z = GET_Z (dst);
|
| 2117 | C = (src & 1);
|
| 2118 | V = N ^ C;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2119 | if (dstreg)
|
| 2120 | R[dstspec] = (R[dstspec] & 0177400) | dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2121 | else PWriteB (dst, last_pa);
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 2122 | if (hst_ent) {
|
| 2123 | if (dstreg)
|
| 2124 | hst_ent->dst = R[dstspec];
|
| 2125 | else hst_ent->dst = dst;
|
| 2126 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2127 | break;
|
| 2128 |
|
| 2129 | case 061: /* ROLB */
|
| 2130 | src = dstreg? R[dstspec]: ReadMB (GeteaB (dstspec));
|
| 2131 | dst = ((src << 1) | C) & 0377;
|
| 2132 | N = GET_SIGN_B (dst);
|
| 2133 | Z = GET_Z (dst);
|
| 2134 | C = GET_SIGN_B (src & 0377);
|
| 2135 | V = N ^ C;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2136 | if (dstreg)
|
| 2137 | R[dstspec] = (R[dstspec] & 0177400) | dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2138 | else PWriteB (dst, last_pa);
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 2139 | if (hst_ent) {
|
| 2140 | if (dstreg)
|
| 2141 | hst_ent->dst = R[dstspec];
|
| 2142 | else hst_ent->dst = dst;
|
| 2143 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2144 | break;
|
| 2145 |
|
| 2146 | case 062: /* ASRB */
|
| 2147 | src = dstreg? R[dstspec]: ReadMB (GeteaB (dstspec));
|
| 2148 | dst = ((src & 0377) >> 1) | (src & 0200);
|
| 2149 | N = GET_SIGN_B (dst);
|
| 2150 | Z = GET_Z (dst);
|
| 2151 | C = (src & 1);
|
| 2152 | V = N ^ C;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2153 | if (dstreg)
|
| 2154 | R[dstspec] = (R[dstspec] & 0177400) | dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2155 | else PWriteB (dst, last_pa);
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 2156 | if (hst_ent) {
|
| 2157 | if (dstreg)
|
| 2158 | hst_ent->dst = R[dstspec];
|
| 2159 | else hst_ent->dst = dst;
|
| 2160 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2161 | break;
|
| 2162 |
|
| 2163 | case 063: /* ASLB */
|
| 2164 | src = dstreg? R[dstspec]: ReadMB (GeteaB (dstspec));
|
| 2165 | dst = (src << 1) & 0377;
|
| 2166 | N = GET_SIGN_B (dst);
|
| 2167 | Z = GET_Z (dst);
|
| 2168 | C = GET_SIGN_B (src & 0377);
|
| 2169 | V = N ^ C;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2170 | if (dstreg)
|
| 2171 | R[dstspec] = (R[dstspec] & 0177400) | dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2172 | else PWriteB (dst, last_pa);
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 2173 | if (hst_ent) {
|
| 2174 | if (dstreg)
|
| 2175 | hst_ent->dst = R[dstspec];
|
| 2176 | else hst_ent->dst = dst;
|
| 2177 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2178 | break;
|
Mark Pizzolato | 4064cc0 | 2013-06-02 06:52:32 -0700 | [diff] [blame] | 2179 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2180 | /* Notes:
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2181 | - MTPS cannot alter the T bit
|
| 2182 | - MxPD must mask GeteaW returned address, dspace is from cm not pm
|
| 2183 | - MxPD must set MMR1 for SP recovery in case of fault
|
| 2184 | */
|
| 2185 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2186 | case 064: /* MTPS */
|
| 2187 | if (CPUT (HAS_MXPS)) {
|
| 2188 | dst = dstreg? R[dstspec]: ReadB (GeteaB (dstspec));
|
| 2189 | if (cm == MD_KER) {
|
| 2190 | ipl = (dst >> PSW_V_IPL) & 07;
|
| 2191 | trap_req = calc_ints (ipl, trap_req);
|
| 2192 | }
|
| 2193 | N = (dst >> PSW_V_N) & 01;
|
| 2194 | Z = (dst >> PSW_V_Z) & 01;
|
| 2195 | V = (dst >> PSW_V_V) & 01;
|
| 2196 | C = (dst >> PSW_V_C) & 01;
|
| 2197 | }
|
| 2198 | else setTRAP (TRAP_ILL);
|
| 2199 | break;
|
| 2200 |
|
| 2201 | case 065: /* MFPD */
|
| 2202 | if (CPUT (HAS_MXPY)) {
|
| 2203 | if (dstreg) {
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2204 | if ((dstspec == 6) && (cm != pm))
|
| 2205 | dst = STACKFILE[pm];
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2206 | else dst = R[dstspec];
|
| 2207 | }
|
| 2208 | else dst = ReadW ((GeteaW (dstspec) & 0177777) | calc_ds (pm));
|
| 2209 | N = GET_SIGN_W (dst);
|
| 2210 | Z = GET_Z (dst);
|
| 2211 | V = 0;
|
| 2212 | SP = (SP - 2) & 0177777;
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2213 | reg_mods = calc_MMR1 (0366);
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2214 | if (update_MM)
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2215 | MMR1 = reg_mods;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 2216 | if (hst_ent)
|
| 2217 | hst_ent->dst = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2218 | WriteW (dst, SP | dsenable);
|
| 2219 | if ((cm == MD_KER) && (SP < (STKLIM + STKL_Y)))
|
| 2220 | set_stack_trap (SP);
|
| 2221 | }
|
| 2222 | else setTRAP (TRAP_ILL);
|
| 2223 | break;
|
| 2224 |
|
| 2225 | case 066: /* MTPD */
|
| 2226 | if (CPUT (HAS_MXPY)) {
|
| 2227 | dst = ReadW (SP | dsenable);
|
| 2228 | N = GET_SIGN_W (dst);
|
| 2229 | Z = GET_Z (dst);
|
| 2230 | V = 0;
|
| 2231 | SP = (SP + 2) & 0177777;
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2232 | reg_mods = 026;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2233 | if (update_MM)
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2234 | MMR1 = reg_mods;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 2235 | if (hst_ent)
|
| 2236 | hst_ent->dst = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2237 | if (dstreg) {
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2238 | if ((dstspec == 6) && (cm != pm))
|
| 2239 | STACKFILE[pm] = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2240 | else R[dstspec] = dst;
|
| 2241 | }
|
| 2242 | else WriteW (dst, (GeteaW (dstspec) & 0177777) | calc_ds (pm));
|
| 2243 | }
|
| 2244 | else setTRAP (TRAP_ILL);
|
| 2245 | break;
|
| 2246 |
|
| 2247 | case 067: /* MFPS */
|
| 2248 | if (CPUT (HAS_MXPS)) {
|
| 2249 | dst = get_PSW () & 0377;
|
| 2250 | N = GET_SIGN_B (dst);
|
| 2251 | Z = GET_Z (dst);
|
| 2252 | V = 0;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2253 | if (dstreg)
|
| 2254 | R[dstspec] = (dst & 0200)? 0177400 | dst: dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2255 | else WriteB (dst, GeteaB (dstspec));
|
| 2256 | }
|
| 2257 | else setTRAP (TRAP_ILL);
|
| 2258 | break;
|
| 2259 |
|
| 2260 | default:
|
| 2261 | setTRAP (TRAP_ILL);
|
| 2262 | break;
|
| 2263 | } /* end switch SOPs */
|
| 2264 | break; /* end case 010 */
|
| 2265 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2266 | /* Opcodes 11 - 16: double operand byte instructions
|
| 2267 |
|
| 2268 | Cmp: v = [sign (src) != sign (src2)] and [sign (src2) = sign (result)]
|
| 2269 | Sub: v = [sign (src) != sign (src2)] and [sign (src) = sign (result)]
|
| 2270 | */
|
| 2271 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2272 | case 011: /* MOVB */
|
| 2273 | if (CPUT (IS_SDSD) && srcreg && !dstreg) { /* R,not R */
|
| 2274 | ea = GeteaB (dstspec);
|
| 2275 | dst = R[srcspec] & 0377;
|
| 2276 | }
|
| 2277 | else {
|
| 2278 | dst = srcreg? R[srcspec] & 0377: ReadB (GeteaB (srcspec));
|
Mark Pizzolato | 4064cc0 | 2013-06-02 06:52:32 -0700 | [diff] [blame] | 2279 | if (!dstreg)
|
| 2280 | ea = GeteaB (dstspec);
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2281 | }
|
| 2282 | N = GET_SIGN_B (dst);
|
| 2283 | Z = GET_Z (dst);
|
| 2284 | V = 0;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2285 | if (dstreg)
|
| 2286 | R[dstspec] = (dst & 0200)? 0177400 | dst: dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2287 | else WriteB (dst, ea);
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 2288 | if (hst_ent) {
|
| 2289 | hst_ent->src = srcreg? R[srcspec]: dst;
|
| 2290 | hst_ent->dst = dstreg? R[dstspec]: dst;
|
| 2291 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2292 | break;
|
| 2293 |
|
| 2294 | case 012: /* CMPB */
|
| 2295 | if (CPUT (IS_SDSD) && srcreg && !dstreg) { /* R,not R */
|
| 2296 | src2 = ReadB (GeteaB (dstspec));
|
| 2297 | src = R[srcspec] & 0377;
|
| 2298 | }
|
| 2299 | else {
|
| 2300 | src = srcreg? R[srcspec] & 0377: ReadB (GeteaB (srcspec));
|
| 2301 | src2 = dstreg? R[dstspec] & 0377: ReadB (GeteaB (dstspec));
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 2302 | }
|
| 2303 | if (hst_ent) {
|
| 2304 | hst_ent->src = src;
|
| 2305 | hst_ent->dst = src2;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2306 | }
|
| 2307 | dst = (src - src2) & 0377;
|
| 2308 | N = GET_SIGN_B (dst);
|
| 2309 | Z = GET_Z (dst);
|
| 2310 | V = GET_SIGN_B ((src ^ src2) & (~src2 ^ dst));
|
| 2311 | C = (src < src2);
|
| 2312 | break;
|
| 2313 |
|
| 2314 | case 013: /* BITB */
|
| 2315 | if (CPUT (IS_SDSD) && srcreg && !dstreg) { /* R,not R */
|
| 2316 | src2 = ReadB (GeteaB (dstspec));
|
| 2317 | src = R[srcspec] & 0377;
|
| 2318 | }
|
| 2319 | else {
|
| 2320 | src = srcreg? R[srcspec] & 0377: ReadB (GeteaB (srcspec));
|
| 2321 | src2 = dstreg? R[dstspec] & 0377: ReadB (GeteaB (dstspec));
|
| 2322 | }
|
| 2323 | dst = (src2 & src) & 0377;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 2324 | if (hst_ent) {
|
| 2325 | hst_ent->src = src;
|
| 2326 | hst_ent->dst = dst;
|
| 2327 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2328 | N = GET_SIGN_B (dst);
|
| 2329 | Z = GET_Z (dst);
|
| 2330 | V = 0;
|
| 2331 | break;
|
| 2332 |
|
| 2333 | case 014: /* BICB */
|
| 2334 | if (CPUT (IS_SDSD) && srcreg && !dstreg) { /* R,not R */
|
| 2335 | src2 = ReadMB (GeteaB (dstspec));
|
| 2336 | src = R[srcspec];
|
| 2337 | }
|
| 2338 | else {
|
| 2339 | src = srcreg? R[srcspec]: ReadB (GeteaB (srcspec));
|
| 2340 | src2 = dstreg? R[dstspec]: ReadMB (GeteaB (dstspec));
|
| 2341 | }
|
| 2342 | dst = (src2 & ~src) & 0377;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 2343 | if (hst_ent) {
|
| 2344 | hst_ent->src = src;
|
| 2345 | hst_ent->dst = dst;
|
| 2346 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2347 | N = GET_SIGN_B (dst);
|
| 2348 | Z = GET_Z (dst);
|
| 2349 | V = 0;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2350 | if (dstreg)
|
| 2351 | R[dstspec] = (R[dstspec] & 0177400) | dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2352 | else PWriteB (dst, last_pa);
|
| 2353 | break;
|
| 2354 |
|
| 2355 | case 015: /* BISB */
|
| 2356 | if (CPUT (IS_SDSD) && srcreg && !dstreg) { /* R,not R */
|
| 2357 | src2 = ReadMB (GeteaB (dstspec));
|
| 2358 | src = R[srcspec];
|
| 2359 | }
|
| 2360 | else {
|
| 2361 | src = srcreg? R[srcspec]: ReadB (GeteaB (srcspec));
|
| 2362 | src2 = dstreg? R[dstspec]: ReadMB (GeteaB (dstspec));
|
| 2363 | }
|
| 2364 | dst = (src2 | src) & 0377;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 2365 | if (hst_ent) {
|
| 2366 | hst_ent->src = src;
|
| 2367 | hst_ent->dst = dst;
|
| 2368 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2369 | N = GET_SIGN_B (dst);
|
| 2370 | Z = GET_Z (dst);
|
| 2371 | V = 0;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2372 | if (dstreg)
|
| 2373 | R[dstspec] = (R[dstspec] & 0177400) | dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2374 | else PWriteB (dst, last_pa);
|
| 2375 | break;
|
| 2376 |
|
| 2377 | case 016: /* SUB */
|
| 2378 | if (CPUT (IS_SDSD) && srcreg && !dstreg) { /* R,not R */
|
| 2379 | src2 = ReadMW (GeteaW (dstspec));
|
| 2380 | src = R[srcspec];
|
| 2381 | }
|
| 2382 | else {
|
| 2383 | src = srcreg? R[srcspec]: ReadW (GeteaW (srcspec));
|
| 2384 | src2 = dstreg? R[dstspec]: ReadMW (GeteaW (dstspec));
|
| 2385 | }
|
| 2386 | dst = (src2 - src) & 0177777;
|
Paul Koning | 66fb70b | 2016-04-07 15:21:59 -0400 | [diff] [blame] | 2387 | if (hst_ent) {
|
| 2388 | hst_ent->src = src;
|
| 2389 | hst_ent->dst = dst;
|
| 2390 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2391 | N = GET_SIGN_W (dst);
|
| 2392 | Z = GET_Z (dst);
|
| 2393 | V = GET_SIGN_W ((src ^ src2) & (~src ^ dst));
|
| 2394 | C = (src2 < src);
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2395 | if (dstreg)
|
| 2396 | R[dstspec] = dst;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2397 | else PWriteW (dst, last_pa);
|
| 2398 | break;
|
| 2399 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2400 | /* Opcode 17: floating point */
|
| 2401 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2402 | case 017:
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2403 | if (CPUO (OPT_FPP))
|
| 2404 | fp11 (IR); /* call fpp */
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2405 | else setTRAP (TRAP_ILL);
|
| 2406 | break; /* end case 017 */
|
| 2407 | } /* end switch op */
|
| 2408 | } /* end main loop */
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2409 |
|
| 2410 | /* Simulation halted */
|
| 2411 |
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 2412 | PSW = get_PSW ();
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2413 | for (i = 0; i < 6; i++)
|
| 2414 | REGFILE[i][rs] = R[i];
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2415 | STACKFILE[cm] = SP;
|
| 2416 | saved_PC = PC & 0177777;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2417 | pcq_r->qptr = pcq_p; /* update pc q ptr */
|
Bob Supnik | f20f5c6 | 2003-02-07 21:28:00 -0800 | [diff] [blame] | 2418 | set_r_display (rs, cm);
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2419 | return reason;
|
| 2420 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2421 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2422 | /* Effective address calculations
|
| 2423 |
|
| 2424 | Inputs:
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2425 | spec = specifier <5:0>
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2426 | Outputs:
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2427 | ea = effective address
|
| 2428 | <15:0> = virtual address
|
| 2429 | <16> = instruction/data data space
|
| 2430 | <18:17> = mode
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2431 |
|
| 2432 | Data space calculation: the PDP-11 features both instruction and data
|
| 2433 | spaces. Instruction space contains the instruction and any sequential
|
| 2434 | add ons (eg, immediates, absolute addresses). Data space contains all
|
| 2435 | data operands and indirect addresses. If data space is enabled, then
|
| 2436 | memory references are directed according to these rules:
|
| 2437 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2438 | Mode Index ref Indirect ref Direct ref
|
| 2439 | 10..16 na na data
|
| 2440 | 17 na na instruction
|
| 2441 | 20..26 na na data
|
| 2442 | 27 na na instruction
|
| 2443 | 30..36 na data data
|
| 2444 | 37 na instruction (absolute) data
|
| 2445 | 40..46 na na data
|
| 2446 | 47 na na instruction
|
| 2447 | 50..56 na data data
|
| 2448 | 57 na instruction data
|
| 2449 | 60..67 instruction na data
|
| 2450 | 70..77 instruction data data
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2451 |
|
| 2452 | According to the PDP-11 Architecture Handbook, MMR1 records all
|
| 2453 | autoincrement and autodecrement operations, including those which
|
| 2454 | explicitly reference the PC. For the J-11, this is only true for
|
| 2455 | autodecrement operands, autodecrement deferred operands, and
|
| 2456 | autoincrement destination operands that involve a write to memory.
|
| 2457 | The simulator follows the Handbook, for simplicity.
|
| 2458 |
|
| 2459 | Notes:
|
| 2460 |
|
| 2461 | - dsenable will direct a reference to data space if data space is enabled
|
| 2462 | - ds will direct a reference to data space if data space is enabled AND if
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2463 | the specifier register is not PC; this is used for 17, 27, 37, 47, 57
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2464 | - Modes 2x, 3x, 4x, and 5x must update MMR1 if updating enabled
|
| 2465 | - Modes 46 and 56 must check for stack overflow if kernel mode
|
| 2466 | */
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2467 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2468 | /* Effective address calculation for words */
|
| 2469 |
|
| 2470 | int32 GeteaW (int32 spec)
|
| 2471 | {
|
| 2472 | int32 adr, reg, ds;
|
| 2473 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2474 | reg = spec & 07; /* register number */
|
| 2475 | ds = (reg == 7)? isenable: dsenable; /* dspace if not PC */
|
| 2476 | switch (spec >> 3) { /* decode spec<5:3> */
|
| 2477 |
|
| 2478 | default: /* can't get here */
|
| 2479 | case 1: /* (R) */
|
| 2480 | return (R[reg] | ds);
|
| 2481 |
|
| 2482 | case 2: /* (R)+ */
|
| 2483 | R[reg] = ((adr = R[reg]) + 2) & 0177777;
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2484 | reg_mods = calc_MMR1 (020 | reg);
|
Mark Pizzolato | 4064cc0 | 2013-06-02 06:52:32 -0700 | [diff] [blame] | 2485 | if (update_MM && (reg != 7))
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2486 | MMR1 = reg_mods;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2487 | return (adr | ds);
|
| 2488 |
|
| 2489 | case 3: /* @(R)+ */
|
| 2490 | R[reg] = ((adr = R[reg]) + 2) & 0177777;
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2491 | reg_mods = calc_MMR1 (020 | reg);
|
Mark Pizzolato | 4064cc0 | 2013-06-02 06:52:32 -0700 | [diff] [blame] | 2492 | if (update_MM && (reg != 7))
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2493 | MMR1 = reg_mods;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2494 | adr = ReadW (adr | ds);
|
| 2495 | return (adr | dsenable);
|
| 2496 |
|
| 2497 | case 4: /* -(R) */
|
| 2498 | adr = R[reg] = (R[reg] - 2) & 0177777;
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2499 | reg_mods = calc_MMR1 (0360 | reg);
|
Mark Pizzolato | 4064cc0 | 2013-06-02 06:52:32 -0700 | [diff] [blame] | 2500 | if (update_MM && (reg != 7))
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2501 | MMR1 = reg_mods;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2502 | if ((reg == 6) && (cm == MD_KER) && (adr < (STKLIM + STKL_Y)))
|
| 2503 | set_stack_trap (adr);
|
| 2504 | return (adr | ds);
|
| 2505 |
|
| 2506 | case 5: /* @-(R) */
|
| 2507 | adr = R[reg] = (R[reg] - 2) & 0177777;
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2508 | reg_mods = calc_MMR1 (0360 | reg);
|
Mark Pizzolato | 4064cc0 | 2013-06-02 06:52:32 -0700 | [diff] [blame] | 2509 | if (update_MM && (reg != 7))
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2510 | MMR1 = reg_mods;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2511 | if ((reg == 6) && (cm == MD_KER) && (adr < (STKLIM + STKL_Y)))
|
| 2512 | set_stack_trap (adr);
|
| 2513 | adr = ReadW (adr | ds);
|
| 2514 | return (adr | dsenable);
|
| 2515 |
|
| 2516 | case 6: /* d(r) */
|
| 2517 | adr = ReadW (PC | isenable);
|
| 2518 | PC = (PC + 2) & 0177777;
|
| 2519 | return (((R[reg] + adr) & 0177777) | dsenable);
|
| 2520 |
|
| 2521 | case 7: /* @d(R) */
|
| 2522 | adr = ReadW (PC | isenable);
|
| 2523 | PC = (PC + 2) & 0177777;
|
| 2524 | adr = ReadW (((R[reg] + adr) & 0177777) | dsenable);
|
| 2525 | return (adr | dsenable);
|
| 2526 | } /* end switch */
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2527 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2528 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2529 | /* Effective address calculation for bytes */
|
| 2530 |
|
| 2531 | int32 GeteaB (int32 spec)
|
| 2532 | {
|
| 2533 | int32 adr, reg, ds, delta;
|
| 2534 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2535 | reg = spec & 07; /* reg number */
|
| 2536 | ds = (reg == 7)? isenable: dsenable; /* dspace if not PC */
|
| 2537 | switch (spec >> 3) { /* decode spec<5:3> */
|
| 2538 |
|
| 2539 | default: /* can't get here */
|
| 2540 | case 1: /* (R) */
|
| 2541 | return (R[reg] | ds);
|
| 2542 |
|
| 2543 | case 2: /* (R)+ */
|
| 2544 | delta = 1 + (reg >= 6); /* 2 if R6, PC */
|
| 2545 | R[reg] = ((adr = R[reg]) + delta) & 0177777;
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2546 | reg_mods = calc_MMR1 ((delta << 3) | reg);
|
Mark Pizzolato | 4064cc0 | 2013-06-02 06:52:32 -0700 | [diff] [blame] | 2547 | if (update_MM && (reg != 7))
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2548 | MMR1 = reg_mods;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2549 | return (adr | ds);
|
| 2550 |
|
| 2551 | case 3: /* @(R)+ */
|
| 2552 | R[reg] = ((adr = R[reg]) + 2) & 0177777;
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2553 | reg_mods = calc_MMR1 (020 | reg);
|
Mark Pizzolato | 4064cc0 | 2013-06-02 06:52:32 -0700 | [diff] [blame] | 2554 | if (update_MM && (reg != 7))
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2555 | MMR1 = reg_mods;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2556 | adr = ReadW (adr | ds);
|
| 2557 | return (adr | dsenable);
|
| 2558 |
|
| 2559 | case 4: /* -(R) */
|
| 2560 | delta = 1 + (reg >= 6); /* 2 if R6, PC */
|
| 2561 | adr = R[reg] = (R[reg] - delta) & 0177777;
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2562 | reg_mods = calc_MMR1 ((((-delta) & 037) << 3) | reg);
|
Mark Pizzolato | 4064cc0 | 2013-06-02 06:52:32 -0700 | [diff] [blame] | 2563 | if (update_MM && (reg != 7))
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2564 | MMR1 = reg_mods;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2565 | if ((reg == 6) && (cm == MD_KER) && (adr < (STKLIM + STKL_Y)))
|
| 2566 | set_stack_trap (adr);
|
| 2567 | return (adr | ds);
|
| 2568 |
|
| 2569 | case 5: /* @-(R) */
|
| 2570 | adr = R[reg] = (R[reg] - 2) & 0177777;
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2571 | reg_mods = calc_MMR1 (0360 | reg);
|
Mark Pizzolato | 4064cc0 | 2013-06-02 06:52:32 -0700 | [diff] [blame] | 2572 | if (update_MM && (reg != 7))
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2573 | MMR1 = reg_mods;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2574 | if ((reg == 6) && (cm == MD_KER) && (adr < (STKLIM + STKL_Y)))
|
| 2575 | set_stack_trap (adr);
|
| 2576 | adr = ReadW (adr | ds);
|
| 2577 | return (adr | dsenable);
|
| 2578 |
|
| 2579 | case 6: /* d(r) */
|
| 2580 | adr = ReadW (PC | isenable);
|
| 2581 | PC = (PC + 2) & 0177777;
|
| 2582 | return (((R[reg] + adr) & 0177777) | dsenable);
|
| 2583 |
|
| 2584 | case 7: /* @d(R) */
|
| 2585 | adr = ReadW (PC | isenable);
|
| 2586 | PC = (PC + 2) & 0177777;
|
| 2587 | adr = ReadW (((R[reg] + adr) & 0177777) | dsenable);
|
| 2588 | return (adr | dsenable);
|
| 2589 | } /* end switch */
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2590 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2591 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2592 | /* Read byte and word routines, read only and read-modify-write versions
|
| 2593 |
|
| 2594 | Inputs:
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2595 | va = virtual address, <18:16> = mode, I/D space
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2596 | Outputs:
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2597 | data = data read from memory or I/O space
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2598 | */
|
| 2599 |
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 2600 | int32 ReadE (int32 va)
|
| 2601 | {
|
| 2602 | int32 pa, data;
|
| 2603 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2604 | if ((va & 1) && CPUT (HAS_ODD)) { /* odd address? */
|
| 2605 | setCPUERR (CPUE_ODD);
|
| 2606 | ABORT (TRAP_ODD);
|
| 2607 | }
|
| 2608 | pa = relocR (va); /* relocate */
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2609 | if (BPT_SUMM_RD &&
|
| 2610 | (sim_brk_test (va & 0177777, BPT_RDVIR) ||
|
| 2611 | sim_brk_test (pa, BPT_RDPHY))) /* read breakpoint? */
|
| 2612 | ABORT (ABRT_BKPT); /* stop simulation */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2613 | if (ADDR_IS_MEM (pa)) /* memory address? */
|
Paul Koning | 998cf5c | 2017-02-04 12:19:41 -0800 | [diff] [blame] | 2614 | return RdMemW (pa);
|
Bob Supnik | 53d02f7 | 2007-02-03 14:59:00 -0800 | [diff] [blame] | 2615 | if ((pa < IOPAGEBASE) || /* not I/O address */
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2616 | (CPUT (CPUT_J) && (pa >= IOBA_CPU))) { /* or J11 int reg? */
|
| 2617 | setCPUERR (CPUE_NXM);
|
| 2618 | ABORT (TRAP_NXM);
|
| 2619 | }
|
| 2620 | if (iopageR (&data, pa, READ) != SCPE_OK) { /* invalid I/O addr? */
|
| 2621 | setCPUERR (CPUE_TMO);
|
| 2622 | ABORT (TRAP_NXM);
|
| 2623 | }
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 2624 | return data;
|
| 2625 | }
|
| 2626 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2627 | int32 ReadW (int32 va)
|
| 2628 | {
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2629 | int32 pa;
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2630 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2631 | if ((va & 1) && CPUT (HAS_ODD)) { /* odd address? */
|
| 2632 | setCPUERR (CPUE_ODD);
|
| 2633 | ABORT (TRAP_ODD);
|
| 2634 | }
|
| 2635 | pa = relocR (va); /* relocate */
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2636 | if (BPT_SUMM_RD &&
|
| 2637 | (sim_brk_test (va & 0177777, BPT_RDVIR) ||
|
| 2638 | sim_brk_test (pa, BPT_RDPHY))) /* read breakpoint? */
|
| 2639 | ABORT (ABRT_BKPT); /* stop simulation */
|
| 2640 | return PReadW (pa);
|
| 2641 | }
|
| 2642 |
|
| 2643 | int32 ReadB (int32 va)
|
| 2644 | {
|
| 2645 | int32 pa;
|
| 2646 |
|
| 2647 | pa = relocR (va); /* relocate */
|
| 2648 | if (BPT_SUMM_RD &&
|
| 2649 | (sim_brk_test (va & 0177777, BPT_RDVIR) ||
|
| 2650 | sim_brk_test (pa, BPT_RDPHY))) /* read breakpoint? */
|
| 2651 | ABORT (ABRT_BKPT); /* stop simulation */
|
| 2652 | return PReadB (pa);
|
| 2653 | }
|
| 2654 |
|
| 2655 | /* Read word with breakpoint check: if a data breakpoint is encountered,
|
| 2656 | set reason accordingly but don't do an ABORT. This is used when we want
|
| 2657 | to break after doing the operation, used for interrupt processing. */
|
| 2658 | int32 ReadCW (int32 va)
|
| 2659 | {
|
| 2660 | int32 pa;
|
| 2661 |
|
| 2662 | if ((va & 1) && CPUT (HAS_ODD)) { /* odd address? */
|
| 2663 | setCPUERR (CPUE_ODD);
|
| 2664 | ABORT (TRAP_ODD);
|
| 2665 | }
|
| 2666 | pa = relocR (va); /* relocate */
|
| 2667 | if (BPT_SUMM_RD &&
|
| 2668 | (sim_brk_test (va & 0177777, BPT_RDVIR) ||
|
| 2669 | sim_brk_test (pa, BPT_RDPHY))) /* read breakpoint? */
|
| 2670 | reason = STOP_IBKPT; /* report that */
|
| 2671 | return PReadW (pa);
|
| 2672 | }
|
| 2673 |
|
| 2674 | int32 ReadMW (int32 va)
|
| 2675 | {
|
| 2676 | if ((va & 1) && CPUT (HAS_ODD)) { /* odd address? */
|
| 2677 | setCPUERR (CPUE_ODD);
|
| 2678 | ABORT (TRAP_ODD);
|
| 2679 | }
|
| 2680 | last_pa = relocW (va); /* reloc, wrt chk */
|
| 2681 | if (BPT_SUMM_RW &&
|
| 2682 | (sim_brk_test (va & 0177777, BPT_RWVIR) ||
|
| 2683 | sim_brk_test (last_pa, BPT_RWPHY))) /* read or write breakpoint? */
|
| 2684 | ABORT (ABRT_BKPT); /* stop simulation */
|
| 2685 | return PReadW (last_pa);
|
| 2686 | }
|
| 2687 |
|
| 2688 | int32 ReadMB (int32 va)
|
| 2689 | {
|
| 2690 | last_pa = relocW (va); /* reloc, wrt chk */
|
| 2691 | if (BPT_SUMM_RW &&
|
| 2692 | (sim_brk_test (va & 0177777, BPT_RWVIR) ||
|
| 2693 | sim_brk_test (last_pa, BPT_RWPHY))) /* read or write breakpoint? */
|
| 2694 | ABORT (ABRT_BKPT); /* stop simulation */
|
| 2695 | return PReadB (last_pa);
|
| 2696 | }
|
| 2697 |
|
| 2698 | int32 PReadW (int32 pa)
|
| 2699 | {
|
| 2700 | int32 data;
|
| 2701 |
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2702 | if (ADDR_IS_MEM (pa)) /* memory address? */
|
Paul Koning | 998cf5c | 2017-02-04 12:19:41 -0800 | [diff] [blame] | 2703 | return RdMemW (pa);
|
Bob Supnik | 53d02f7 | 2007-02-03 14:59:00 -0800 | [diff] [blame] | 2704 | if (pa < IOPAGEBASE) { /* not I/O address? */
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2705 | setCPUERR (CPUE_NXM);
|
| 2706 | ABORT (TRAP_NXM);
|
| 2707 | }
|
| 2708 | if (iopageR (&data, pa, READ) != SCPE_OK) { /* invalid I/O addr? */
|
| 2709 | setCPUERR (CPUE_TMO);
|
| 2710 | ABORT (TRAP_NXM);
|
| 2711 | }
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2712 | return data;
|
| 2713 | }
|
| 2714 |
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2715 | int32 PReadB (int32 pa)
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2716 | {
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2717 | int32 data;
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2718 |
|
Paul Koning | 998cf5c | 2017-02-04 12:19:41 -0800 | [diff] [blame] | 2719 | if (ADDR_IS_MEM (pa)) /* memory address? */
|
| 2720 | return RdMemB (pa);
|
Bob Supnik | 53d02f7 | 2007-02-03 14:59:00 -0800 | [diff] [blame] | 2721 | if (pa < IOPAGEBASE) { /* not I/O address? */
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2722 | setCPUERR (CPUE_NXM);
|
| 2723 | ABORT (TRAP_NXM);
|
| 2724 | }
|
| 2725 | if (iopageR (&data, pa, READ) != SCPE_OK) { /* invalid I/O addr? */
|
| 2726 | setCPUERR (CPUE_TMO);
|
| 2727 | ABORT (TRAP_NXM);
|
| 2728 | }
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2729 | return ((pa & 1)? data >> 8: data) & 0377;
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2730 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2731 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2732 | /* Write byte and word routines
|
| 2733 |
|
| 2734 | Inputs:
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2735 | data = data to be written
|
| 2736 | va = virtual address, <18:16> = mode, I/D space, or
|
| 2737 | pa = physical address
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2738 | Outputs: none
|
| 2739 | */
|
| 2740 |
|
| 2741 | void WriteW (int32 data, int32 va)
|
| 2742 | {
|
| 2743 | int32 pa;
|
| 2744 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2745 | if ((va & 1) && CPUT (HAS_ODD)) { /* odd address? */
|
| 2746 | setCPUERR (CPUE_ODD);
|
| 2747 | ABORT (TRAP_ODD);
|
| 2748 | }
|
| 2749 | pa = relocW (va); /* relocate */
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2750 | if (BPT_SUMM_WR &&
|
| 2751 | (sim_brk_test (va & 0177777, BPT_WRVIR) ||
|
| 2752 | sim_brk_test (pa, BPT_WRPHY))) /* write breakpoint? */
|
| 2753 | ABORT (ABRT_BKPT); /* stop simulation */
|
| 2754 | PWriteW (data, pa);
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2755 | }
|
| 2756 |
|
| 2757 | void WriteB (int32 data, int32 va)
|
| 2758 | {
|
| 2759 | int32 pa;
|
| 2760 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2761 | pa = relocW (va); /* relocate */
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2762 | if (BPT_SUMM_WR &&
|
| 2763 | (sim_brk_test (va & 0177777, BPT_WRVIR) ||
|
| 2764 | sim_brk_test (pa, BPT_WRPHY))) /* write breakpoint? */
|
| 2765 | ABORT (ABRT_BKPT); /* stop simulation */
|
| 2766 | PWriteB (data, pa);
|
| 2767 | }
|
| 2768 |
|
| 2769 | /* Write word with breakpoint check: if a data breakpoint is encountered,
|
| 2770 | set reason accordingly but don't do an ABORT. This is used when we want
|
| 2771 | to break after doing the operation, used for interrupt processing. */
|
| 2772 | void WriteCW (int32 data, int32 va)
|
| 2773 | {
|
| 2774 | int32 pa;
|
| 2775 |
|
| 2776 | if ((va & 1) && CPUT (HAS_ODD)) { /* odd address? */
|
| 2777 | setCPUERR (CPUE_ODD);
|
| 2778 | ABORT (TRAP_ODD);
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2779 | }
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 2780 | pa = relocW (va); /* relocate */
|
| 2781 | if (BPT_SUMM_WR &&
|
| 2782 | (sim_brk_test (va & 0177777, BPT_WRVIR) ||
|
| 2783 | sim_brk_test (pa, BPT_WRPHY))) /* write breakpoint? */
|
| 2784 | reason = STOP_IBKPT; /* report that */
|
| 2785 | PWriteW (data, pa);
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2786 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2787 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2788 | void PWriteW (int32 data, int32 pa)
|
| 2789 | {
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2790 | if (ADDR_IS_MEM (pa)) { /* memory address? */
|
Paul Koning | 998cf5c | 2017-02-04 12:19:41 -0800 | [diff] [blame] | 2791 | WrMemW (pa, data);
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2792 | return;
|
| 2793 | }
|
Bob Supnik | 53d02f7 | 2007-02-03 14:59:00 -0800 | [diff] [blame] | 2794 | if (pa < IOPAGEBASE) { /* not I/O address? */
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2795 | setCPUERR (CPUE_NXM);
|
| 2796 | ABORT (TRAP_NXM);
|
| 2797 | }
|
| 2798 | if (iopageW (data, pa, WRITE) != SCPE_OK) { /* invalid I/O addr? */
|
| 2799 | setCPUERR (CPUE_TMO);
|
| 2800 | ABORT (TRAP_NXM);
|
| 2801 | }
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2802 | return;
|
| 2803 | }
|
| 2804 |
|
| 2805 | void PWriteB (int32 data, int32 pa)
|
| 2806 | {
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2807 | if (ADDR_IS_MEM (pa)) { /* memory address? */
|
Paul Koning | 998cf5c | 2017-02-04 12:19:41 -0800 | [diff] [blame] | 2808 | WrMemB (pa, data);
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2809 | return;
|
| 2810 | }
|
Bob Supnik | 53d02f7 | 2007-02-03 14:59:00 -0800 | [diff] [blame] | 2811 | if (pa < IOPAGEBASE) { /* not I/O address? */
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2812 | setCPUERR (CPUE_NXM);
|
| 2813 | ABORT (TRAP_NXM);
|
| 2814 | }
|
| 2815 | if (iopageW (data, pa, WRITEB) != SCPE_OK) { /* invalid I/O addr? */
|
| 2816 | setCPUERR (CPUE_TMO);
|
| 2817 | ABORT (TRAP_NXM);
|
| 2818 | }
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2819 | return;
|
| 2820 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2821 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2822 | /* Relocate virtual address, read access
|
| 2823 |
|
| 2824 | Inputs:
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2825 | va = virtual address, <18:16> = mode, I/D space
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2826 | Outputs:
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2827 | pa = physical address
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2828 | On aborts, this routine aborts back to the top level simulator
|
| 2829 | with an appropriate trap code.
|
| 2830 |
|
| 2831 | Notes:
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 2832 | - The 'normal' read codes (010, 110) are done in-line; all
|
| 2833 | others in a subroutine
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2834 | - APRFILE[UNUSED] is all zeroes, forcing non-resident abort
|
| 2835 | - Aborts must update MMR0<15:13,6:1> if updating is enabled
|
| 2836 | */
|
| 2837 |
|
| 2838 | int32 relocR (int32 va)
|
| 2839 | {
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 2840 | int32 apridx, apr, pa;
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2841 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2842 | if (MMR0 & MMR0_MME) { /* if mmgt */
|
| 2843 | apridx = (va >> VA_V_APF) & 077; /* index into APR */
|
| 2844 | apr = APRFILE[apridx]; /* with va<18:13> */
|
| 2845 | if ((apr & PDR_PRD) != 2) /* not 2, 6? */
|
| 2846 | relocR_test (va, apridx); /* long test */
|
| 2847 | if (PLF_test (va, apr)) /* pg lnt error? */
|
| 2848 | reloc_abort (MMR0_PL, apridx);
|
| 2849 | pa = ((va & VA_DF) + ((apr >> 10) & 017777700)) & PAMASK;
|
| 2850 | if ((MMR3 & MMR3_M22E) == 0) {
|
| 2851 | pa = pa & 0777777;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2852 | if (pa >= 0760000)
|
| 2853 | pa = 017000000 | pa;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2854 | }
|
| 2855 | }
|
| 2856 | else {
|
| 2857 | pa = va & 0177777; /* mmgt off */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2858 | if (pa >= 0160000)
|
| 2859 | pa = 017600000 | pa;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2860 | }
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2861 | return pa;
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 2862 | }
|
| 2863 |
|
| 2864 | /* Read relocation, access control field != read only or read/write
|
| 2865 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2866 | ACF value 11/45,11/70 all others
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 2867 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2868 | 0 abort NR abort NR
|
| 2869 | 1 trap -
|
| 2870 | 2 ok ok
|
| 2871 | 3 abort NR -
|
| 2872 | 4 trap abort NR
|
| 2873 | 5 ok -
|
| 2874 | 6 ok ok
|
| 2875 | 7 abort NR -
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 2876 | */
|
| 2877 |
|
| 2878 | void relocR_test (int32 va, int32 apridx)
|
| 2879 | {
|
| 2880 | int32 apr, err;
|
| 2881 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2882 | err = 0; /* init status */
|
| 2883 | apr = APRFILE[apridx]; /* get APR */
|
| 2884 | switch (apr & PDR_ACF) { /* case on ACF */
|
| 2885 |
|
| 2886 | case 1: case 4: /* trap read */
|
| 2887 | if (CPUT (HAS_MMTR)) { /* traps implemented? */
|
| 2888 | APRFILE[apridx] = APRFILE[apridx] | PDR_A; /* set A */
|
| 2889 | if (MMR0 & MMR0_TENB) { /* traps enabled? */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2890 | if (update_MM) /* update MMR0 */
|
| 2891 | MMR0 = (MMR0 & ~MMR0_PAGE) | (apridx << MMR0_V_PAGE);
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2892 | MMR0 = MMR0 | MMR0_TRAP; /* set trap flag */
|
| 2893 | setTRAP (TRAP_MME); /* set trap */
|
| 2894 | }
|
| 2895 | return; /* continue op */
|
| 2896 | } /* not impl, abort NR */
|
| 2897 | case 0: case 3: case 7: /* non-resident */
|
| 2898 | err = MMR0_NR; /* set MMR0 */
|
| 2899 | break; /* go test PLF, abort */
|
| 2900 |
|
| 2901 | case 2: case 5: case 6: /* readable */
|
| 2902 | return; /* continue */
|
| 2903 | } /* end switch */
|
| 2904 |
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2905 | if (PLF_test (va, apr)) /* pg lnt error? */
|
| 2906 | err = err | MMR0_PL;
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 2907 | reloc_abort (err, apridx);
|
| 2908 | return;
|
| 2909 | }
|
| 2910 |
|
| 2911 | t_bool PLF_test (int32 va, int32 apr)
|
| 2912 | {
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2913 | int32 dbn = va & VA_BN; /* extr block num */
|
| 2914 | int32 plf = (apr & PDR_PLF) >> 2; /* extr page length */
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 2915 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2916 | return ((apr & PDR_ED)? (dbn < plf): (dbn > plf)); /* pg lnt error? */
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 2917 | }
|
| 2918 |
|
| 2919 | void reloc_abort (int32 err, int32 apridx)
|
| 2920 | {
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2921 | if (update_MM) MMR0 = /* update MMR0 */
|
| 2922 | (MMR0 & ~MMR0_PAGE) | (apridx << MMR0_V_PAGE);
|
| 2923 | APRFILE[apridx] = APRFILE[apridx] | PDR_A; /* set A */
|
| 2924 | MMR0 = MMR0 | err; /* set aborts */
|
| 2925 | ABORT (TRAP_MME); /* abort ref */
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 2926 | return;
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2927 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2928 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2929 | /* Relocate virtual address, write access
|
| 2930 |
|
| 2931 | Inputs:
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2932 | va = virtual address, <18:16> = mode, I/D space
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2933 | Outputs:
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2934 | pa = physical address
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2935 | On aborts, this routine aborts back to the top level simulator
|
| 2936 | with an appropriate trap code.
|
| 2937 |
|
| 2938 | Notes:
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 2939 | - The 'normal' write code (110) is done in-line; all others
|
| 2940 | in a subroutine
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2941 | - APRFILE[UNUSED] is all zeroes, forcing non-resident abort
|
| 2942 | - Aborts must update MMR0<15:13,6:1> if updating is enabled
|
| 2943 | */
|
| 2944 |
|
| 2945 | int32 relocW (int32 va)
|
| 2946 | {
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 2947 | int32 apridx, apr, pa;
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2948 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2949 | if (MMR0 & MMR0_MME) { /* if mmgt */
|
| 2950 | apridx = (va >> VA_V_APF) & 077; /* index into APR */
|
| 2951 | apr = APRFILE[apridx]; /* with va<18:13> */
|
| 2952 | if ((apr & PDR_ACF) != 6) /* not writeable? */
|
| 2953 | relocW_test (va, apridx); /* long test */
|
| 2954 | if (PLF_test (va, apr)) /* pg lnt error? */
|
| 2955 | reloc_abort (MMR0_PL, apridx);
|
| 2956 | APRFILE[apridx] = apr | PDR_W; /* set W */
|
| 2957 | pa = ((va & VA_DF) + ((apr >> 10) & 017777700)) & PAMASK;
|
| 2958 | if ((MMR3 & MMR3_M22E) == 0) {
|
| 2959 | pa = pa & 0777777;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2960 | if (pa >= 0760000)
|
| 2961 | pa = 017000000 | pa;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2962 | }
|
| 2963 | }
|
| 2964 | else {
|
| 2965 | pa = va & 0177777; /* mmgt off */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2966 | if (pa >= 0160000)
|
| 2967 | pa = 017600000 | pa;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2968 | }
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 2969 | return pa;
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 2970 | }
|
| 2971 |
|
| 2972 | /* Write relocation, access control field != read/write
|
| 2973 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2974 | ACF value 11/45,11/70 all others
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 2975 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2976 | 0 abort NR abort NR
|
| 2977 | 1 abort RO -
|
| 2978 | 2 abort RO abort RO
|
| 2979 | 3 abort NR -
|
| 2980 | 4 trap abort NR
|
| 2981 | 5 trap -
|
| 2982 | 6 ok ok
|
| 2983 | 7 abort NR -
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 2984 | */
|
| 2985 |
|
| 2986 | void relocW_test (int32 va, int32 apridx)
|
| 2987 | {
|
| 2988 | int32 apr, err;
|
| 2989 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 2990 | err = 0; /* init status */
|
| 2991 | apr = APRFILE[apridx]; /* get APR */
|
| 2992 | switch (apr & PDR_ACF) { /* case on ACF */
|
| 2993 |
|
| 2994 | case 4: case 5: /* trap write */
|
| 2995 | if (CPUT (HAS_MMTR)) { /* traps implemented? */
|
| 2996 | APRFILE[apridx] = APRFILE[apridx] | PDR_A; /* set A */
|
| 2997 | if (MMR0 & MMR0_TENB) { /* traps enabled? */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 2998 | if (update_MM) /* update MMR0 */
|
| 2999 | MMR0 = (MMR0 & ~MMR0_PAGE) | (apridx << MMR0_V_PAGE);
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3000 | MMR0 = MMR0 | MMR0_TRAP; /* set trap flag */
|
| 3001 | setTRAP (TRAP_MME); /* set trap */
|
| 3002 | }
|
| 3003 | return; /* continue op */
|
| 3004 | } /* not impl, abort NR */
|
| 3005 | case 0: case 3: case 7: /* non-resident */
|
| 3006 | err = MMR0_NR; /* MMR0 status */
|
| 3007 | break; /* go test PLF, abort */
|
| 3008 |
|
| 3009 | case 1: case 2: /* read only */
|
| 3010 | err = MMR0_RO; /* MMR0 status */
|
| 3011 | break;
|
| 3012 |
|
| 3013 | case 6: /* read/write */
|
| 3014 | return; /* continue */
|
| 3015 | } /* end switch */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3016 | if (PLF_test (va, apr)) /* pg lnt error? */
|
| 3017 | err = err | MMR0_PL;
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3018 | reloc_abort (err, apridx);
|
| 3019 | return;
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3020 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3021 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3022 | /* Relocate virtual address, console access
|
| 3023 |
|
| 3024 | Inputs:
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3025 | va = virtual address
|
| 3026 | sw = switches
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3027 | Outputs:
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3028 | pa = physical address
|
Bob Supnik | 2c2dd5e | 2002-11-17 15:54:00 -0800 | [diff] [blame] | 3029 | On aborts, this routine returns MAXMEMSIZE
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3030 | */
|
| 3031 |
|
| 3032 | int32 relocC (int32 va, int32 sw)
|
| 3033 | {
|
| 3034 | int32 mode, dbn, plf, apridx, apr, pa;
|
| 3035 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3036 | if (MMR0 & MMR0_MME) { /* if mmgt */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3037 | if (sw & SWMASK ('K'))
|
| 3038 | mode = MD_KER;
|
| 3039 | else if (sw & SWMASK ('S'))
|
| 3040 | mode = MD_SUP;
|
| 3041 | else if (sw & SWMASK ('U'))
|
| 3042 | mode = MD_USR;
|
| 3043 | else if (sw & SWMASK ('P'))
|
| 3044 | mode = (PSW >> PSW_V_PM) & 03;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3045 | else mode = (PSW >> PSW_V_CM) & 03;
|
Mark Pizzolato | 8eb3672 | 2016-08-30 13:10:56 -0700 | [diff] [blame] | 3046 | va = va | ((sw & SWMASK ('T'))? calc_ds (mode): calc_is (mode));
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3047 | apridx = (va >> VA_V_APF) & 077; /* index into APR */
|
| 3048 | apr = APRFILE[apridx]; /* with va<18:13> */
|
| 3049 | dbn = va & VA_BN; /* extr block num */
|
| 3050 | plf = (apr & PDR_PLF) >> 2; /* extr page length */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3051 | if ((apr & PDR_PRD) == 0) /* not readable? */
|
| 3052 | return MAXMEMSIZE;
|
| 3053 | if ((apr & PDR_ED)? dbn < plf: dbn > plf)
|
| 3054 | return MAXMEMSIZE;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3055 | pa = ((va & VA_DF) + ((apr >> 10) & 017777700)) & PAMASK;
|
| 3056 | if ((MMR3 & MMR3_M22E) == 0) {
|
| 3057 | pa = pa & 0777777;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3058 | if (pa >= 0760000)
|
| 3059 | pa = 017000000 | pa;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3060 | }
|
| 3061 | }
|
| 3062 | else {
|
| 3063 | pa = va & 0177777; /* mmgt off */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3064 | if (pa >= 0160000)
|
| 3065 | pa = 017600000 | pa;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3066 | }
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3067 | return pa;
|
| 3068 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3069 |
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3070 | /* Memory management registers
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3071 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3072 | MMR0 17777572 read/write, certain bits unimplemented or read only
|
| 3073 | MMR1 17777574 read only
|
| 3074 | MMR2 17777576 read only
|
| 3075 | MMR3 17777516 read/write, certain bits unimplemented
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3076 | */
|
| 3077 |
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3078 | t_stat MMR012_rd (int32 *data, int32 pa, int32 access)
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3079 | {
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3080 | switch ((pa >> 1) & 3) { /* decode pa<2:1> */
|
| 3081 |
|
| 3082 | case 0: /* SR */
|
| 3083 | return SCPE_NXM;
|
| 3084 |
|
| 3085 | case 1: /* MMR0 */
|
| 3086 | *data = MMR0 & cpu_tab[cpu_model].mm0;
|
| 3087 | break;
|
| 3088 |
|
| 3089 | case 2: /* MMR1 */
|
| 3090 | *data = MMR1;
|
| 3091 | break;
|
| 3092 |
|
| 3093 | case 3: /* MMR2 */
|
| 3094 | *data = MMR2;
|
| 3095 | break;
|
Bob Supnik | 53d02f7 | 2007-02-03 14:59:00 -0800 | [diff] [blame] | 3096 | } /* end switch pa */
|
| 3097 |
|
Bob Supnik | 89bcd02 | 2001-11-06 20:58:00 -0800 | [diff] [blame] | 3098 | return SCPE_OK;
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3099 | }
|
| 3100 |
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3101 | t_stat MMR012_wr (int32 data, int32 pa, int32 access)
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3102 | {
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3103 | switch ((pa >> 1) & 3) { /* decode pa<2:1> */
|
| 3104 |
|
| 3105 | case 0: /* DR */
|
| 3106 | return SCPE_NXM;
|
| 3107 |
|
| 3108 | case 1: /* MMR0 */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3109 | if (access == WRITEB)
|
| 3110 | data = (pa & 1)? (MMR0 & 0377) | (data << 8): (MMR0 & ~0377) | data;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3111 | data = data & cpu_tab[cpu_model].mm0;
|
| 3112 | MMR0 = (MMR0 & ~MMR0_WR) | (data & MMR0_WR);
|
| 3113 | return SCPE_OK;
|
| 3114 |
|
| 3115 | default: /* MMR1, MMR2 */
|
| 3116 | return SCPE_OK;
|
| 3117 | } /* end switch pa */
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3118 | }
|
| 3119 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3120 | t_stat MMR3_rd (int32 *data, int32 pa, int32 access) /* MMR3 */
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3121 | {
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3122 | *data = MMR3 & cpu_tab[cpu_model].mm3;
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3123 | return SCPE_OK;
|
| 3124 | }
|
| 3125 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3126 | t_stat MMR3_wr (int32 data, int32 pa, int32 access) /* MMR3 */
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3127 | {
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3128 | if (pa & 1)
|
| 3129 | return SCPE_OK;
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3130 | MMR3 = data & cpu_tab[cpu_model].mm3;
|
| 3131 | cpu_bme = (MMR3 & MMR3_BME) && (cpu_opt & OPT_UBM);
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3132 | dsenable = calc_ds (cm);
|
| 3133 | return SCPE_OK;
|
| 3134 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3135 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3136 | /* PARs and PDRs. These are grouped in I/O space as follows:
|
| 3137 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3138 | 17772200 - 17772276 supervisor block
|
| 3139 | 17772300 - 17772376 kernel block
|
| 3140 | 17777600 - 17777676 user block
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3141 |
|
| 3142 | Within each block, the subblocks are I PDR's, D PDR's, I PAR's, D PAR's
|
| 3143 |
|
| 3144 | Thus, the algorithm for converting between I/O space addresses and
|
| 3145 | APRFILE indices is as follows:
|
| 3146 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3147 | idx<3:0> = dspace'page = pa<4:1>
|
| 3148 | par = PDR vs PAR = pa<5>
|
| 3149 | idx<5:4> = ker/sup/user = pa<8>'~pa<6>
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3150 |
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3151 | Note: the A,W bits are read only; they are cleared by any write to an APR
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3152 | */
|
| 3153 |
|
| 3154 | t_stat APR_rd (int32 *data, int32 pa, int32 access)
|
| 3155 | {
|
| 3156 | t_stat left, idx;
|
| 3157 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3158 | idx = (pa >> 1) & 017; /* dspace'page */
|
| 3159 | left = (pa >> 5) & 1; /* PDR vs PAR */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3160 | if ((pa & 0100) == 0) /* 1 for super, user */
|
| 3161 | idx = idx | 020;
|
| 3162 | if (pa & 0400) /* 1 for user only */
|
| 3163 | idx = idx | 040;
|
| 3164 | if (left)
|
| 3165 | *data = (APRFILE[idx] >> 16) & cpu_tab[cpu_model].par;
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3166 | else *data = APRFILE[idx] & cpu_tab[cpu_model].pdr;
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3167 | return SCPE_OK;
|
| 3168 | }
|
| 3169 |
|
| 3170 | t_stat APR_wr (int32 data, int32 pa, int32 access)
|
| 3171 | {
|
| 3172 | int32 left, idx, curr;
|
| 3173 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3174 | idx = (pa >> 1) & 017; /* dspace'page */
|
| 3175 | left = (pa >> 5) & 1; /* PDR vs PAR */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3176 | if ((pa & 0100) == 0) /* 1 for super, user */
|
| 3177 | idx = idx | 020;
|
| 3178 | if (pa & 0400) /* 1 for user only */
|
| 3179 | idx = idx | 040;
|
| 3180 | if (left)
|
| 3181 | curr = (APRFILE[idx] >> 16) & cpu_tab[cpu_model].par;
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3182 | else curr = APRFILE[idx] & cpu_tab[cpu_model].pdr;
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3183 | if (access == WRITEB)
|
| 3184 | data = (pa & 1)? (curr & 0377) | (data << 8): (curr & ~0377) | data;
|
| 3185 | if (left)
|
| 3186 | APRFILE[idx] = ((APRFILE[idx] & 0177777) |
|
| 3187 | (((uint32) (data & cpu_tab[cpu_model].par)) << 16)) & ~(PDR_A|PDR_W);
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3188 | else APRFILE[idx] = ((APRFILE[idx] & ~0177777) |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3189 | (data & cpu_tab[cpu_model].pdr)) & ~(PDR_A|PDR_W);
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3190 | return SCPE_OK;
|
| 3191 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3192 |
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3193 | /* Explicit PSW read */
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3194 |
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3195 | t_stat PSW_rd (int32 *data, int32 pa, int32 access)
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3196 | {
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3197 | if (access == READC)
|
| 3198 | *data = PSW;
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3199 | else *data = get_PSW ();
|
| 3200 | return SCPE_OK;
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3201 | }
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3202 |
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3203 | /* Assemble PSW from pieces */
|
| 3204 |
|
| 3205 | int32 get_PSW (void)
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3206 | {
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3207 | return (cm << PSW_V_CM) | (pm << PSW_V_PM) |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3208 | (rs << PSW_V_RS) | (fpd << PSW_V_FPD) |
|
| 3209 | (ipl << PSW_V_IPL) | (tbit << PSW_V_TBIT) |
|
| 3210 | (N << PSW_V_N) | (Z << PSW_V_Z) |
|
| 3211 | (V << PSW_V_V) | (C << PSW_V_C);
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3212 | }
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3213 |
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3214 | /* Explicit PSW write - T-bit may be protected */
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3215 |
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3216 | t_stat PSW_wr (int32 data, int32 pa, int32 access)
|
| 3217 | {
|
| 3218 | int32 i, curr, oldrs;
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3219 |
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3220 | if (access == WRITEC) { /* console access? */
|
| 3221 | PSW = data & cpu_tab[cpu_model].psw;
|
| 3222 | return SCPE_OK;
|
| 3223 | }
|
| 3224 | curr = get_PSW (); /* get current */
|
| 3225 | oldrs = rs; /* save reg set */
|
| 3226 | STACKFILE[cm] = SP; /* save curr SP */
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3227 | if (access == WRITEB) data = (pa & 1)?
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3228 | (curr & 0377) | (data << 8): (curr & ~0377) | data;
|
| 3229 | if (!CPUT (HAS_EXPT)) /* expl T writes? */
|
| 3230 | data = (data & ~PSW_TBIT) | (curr & PSW_TBIT); /* no, use old T */
|
| 3231 | put_PSW (data, 0); /* call calc_is,ds */
|
| 3232 | if (rs != oldrs) { /* switch reg set */
|
| 3233 | for (i = 0; i < 6; i++) {
|
| 3234 | REGFILE[i][oldrs] = R[i];
|
| 3235 | R[i] = REGFILE[i][rs];
|
| 3236 | }
|
| 3237 | }
|
| 3238 | SP = STACKFILE[cm]; /* switch SP */
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3239 | isenable = calc_is (cm);
|
| 3240 | dsenable = calc_ds (cm);
|
| 3241 | return SCPE_OK;
|
| 3242 | }
|
| 3243 |
|
| 3244 | /* Store pieces of new PSW - implements RTI/RTT protection */
|
| 3245 |
|
| 3246 | void put_PSW (int32 val, t_bool prot)
|
| 3247 | {
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3248 | val = val & cpu_tab[cpu_model].psw; /* mask off invalid bits */
|
| 3249 | if (prot) { /* protected? */
|
| 3250 | cm = cm | ((val >> PSW_V_CM) & 03); /* or to cm,pm,rs */
|
| 3251 | pm = pm | ((val >> PSW_V_PM) & 03); /* can't change ipl */
|
| 3252 | rs = rs | ((val >> PSW_V_RS) & 01);
|
| 3253 | }
|
| 3254 | else {
|
| 3255 | cm = (val >> PSW_V_CM) & 03; /* write cm,pm,rs,ipl */
|
| 3256 | pm = (val >> PSW_V_PM) & 03;
|
| 3257 | rs = (val >> PSW_V_RS) & 01;
|
| 3258 | ipl = (val >> PSW_V_IPL) & 07;
|
| 3259 | }
|
| 3260 | fpd = (val >> PSW_V_FPD) & 01; /* always writeable */
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3261 | tbit = (val >> PSW_V_TBIT) & 01;
|
| 3262 | N = (val >> PSW_V_N) & 01;
|
| 3263 | Z = (val >> PSW_V_Z) & 01;
|
| 3264 | V = (val >> PSW_V_V) & 01;
|
| 3265 | C = (val >> PSW_V_C) & 01;
|
| 3266 | return;
|
| 3267 | }
|
| 3268 |
|
| 3269 | /* PIRQ write routine */
|
| 3270 |
|
| 3271 | void put_PIRQ (int32 val)
|
| 3272 | {
|
| 3273 | int32 pl;
|
| 3274 |
|
| 3275 | PIRQ = val & PIRQ_RW;
|
| 3276 | pl = 0;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3277 | if (PIRQ & PIRQ_PIR1) {
|
| 3278 | SET_INT (PIR1);
|
| 3279 | pl = 0042;
|
| 3280 | }
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3281 | else CLR_INT (PIR1);
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3282 | if (PIRQ & PIRQ_PIR2) {
|
| 3283 | SET_INT (PIR2);
|
| 3284 | pl = 0104;
|
| 3285 | }
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3286 | else CLR_INT (PIR2);
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3287 | if (PIRQ & PIRQ_PIR3) {
|
| 3288 | SET_INT (PIR3);
|
| 3289 | pl = 0146;
|
| 3290 | }
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3291 | else CLR_INT (PIR3);
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3292 | if (PIRQ & PIRQ_PIR4) {
|
| 3293 | SET_INT (PIR4);
|
| 3294 | pl = 0210;
|
| 3295 | }
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3296 | else CLR_INT (PIR4);
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3297 | if (PIRQ & PIRQ_PIR5) {
|
| 3298 | SET_INT (PIR5);
|
| 3299 | pl = 0252;
|
| 3300 | }
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3301 | else CLR_INT (PIR5);
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3302 | if (PIRQ & PIRQ_PIR6) {
|
| 3303 | SET_INT (PIR6);
|
| 3304 | pl = 0314;
|
| 3305 | }
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3306 | else CLR_INT (PIR6);
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3307 | if (PIRQ & PIRQ_PIR7) {
|
| 3308 | SET_INT (PIR7);
|
| 3309 | pl = 0356;
|
| 3310 | }
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3311 | else CLR_INT (PIR7);
|
| 3312 | PIRQ = PIRQ | pl;
|
| 3313 | return;
|
| 3314 | }
|
| 3315 |
|
| 3316 | /* Stack trap routine */
|
| 3317 |
|
| 3318 | void set_stack_trap (int32 adr)
|
| 3319 | {
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3320 | if (CPUT (HAS_STKLF)) { /* fixed stack? */
|
| 3321 | setTRAP (TRAP_YEL); /* always yellow trap */
|
| 3322 | setCPUERR (CPUE_YEL);
|
| 3323 | }
|
| 3324 | else if (CPUT (HAS_STKLR)) { /* register limit? */
|
| 3325 | if (adr >= (STKLIM + STKL_R)) { /* yellow zone? */
|
| 3326 | setTRAP (TRAP_YEL); /* still yellow trap */
|
| 3327 | setCPUERR (CPUE_YEL);
|
| 3328 | }
|
| 3329 | else { /* red zone abort */
|
| 3330 | setCPUERR (CPUE_RED);
|
| 3331 | STACKFILE[MD_KER] = 4;
|
| 3332 | SP = 4;
|
| 3333 | ABORT (TRAP_RED);
|
| 3334 | }
|
| 3335 | }
|
| 3336 | return; /* no stack limit */
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3337 | }
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3338 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3339 | /* Reset routine */
|
| 3340 |
|
| 3341 | t_stat cpu_reset (DEVICE *dptr)
|
| 3342 | {
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3343 | PIRQ = 0;
|
| 3344 | STKLIM = 0;
|
Mark Pizzolato | f0d41f1 | 2013-10-27 05:30:13 -0700 | [diff] [blame] | 3345 | if (CPUT (CPUT_T)) /* T11? */
|
| 3346 | PSW = 000340; /* start at IPL 7 */
|
Mark Pizzolato | ac837e5 | 2015-12-29 10:11:39 -0800 | [diff] [blame] | 3347 | else
|
| 3348 | PSW = 0; /* else at IPL 0 */
|
Bob Supnik | b6393b3 | 2004-11-23 15:49:00 -0800 | [diff] [blame] | 3349 | MMR0 = 0;
|
| 3350 | MMR1 = 0;
|
| 3351 | MMR2 = 0;
|
| 3352 | MMR3 = 0;
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3353 | trap_req = 0;
|
| 3354 | wait_state = 0;
|
Mark Pizzolato | ac837e5 | 2015-12-29 10:11:39 -0800 | [diff] [blame] | 3355 | if (M == NULL) { /* First time init */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3356 | M = (uint16 *) calloc (MEMSIZE >> 1, sizeof (uint16));
|
Mark Pizzolato | ac837e5 | 2015-12-29 10:11:39 -0800 | [diff] [blame] | 3357 | if (M == NULL)
|
| 3358 | return SCPE_MEM;
|
Mark Pizzolato | 6582aee | 2016-01-02 05:07:18 -0800 | [diff] [blame] | 3359 | sim_set_pchar (0, "01000023640"); /* ESC, CR, LF, TAB, BS, BEL, ENQ */
|
Mark Pizzolato | e2a8f0f | 2016-08-24 21:19:09 -0700 | [diff] [blame] | 3360 | sim_brk_dflt = SWMASK ('E');
|
Paul Koning | 89ffed4 | 2016-09-13 15:22:35 -0400 | [diff] [blame] | 3361 | sim_brk_types = sim_brk_dflt|SWMASK ('P')|
|
| 3362 | SWMASK ('R')|SWMASK ('S')|
|
| 3363 | SWMASK ('W')|SWMASK ('X');
|
| 3364 | sim_brk_type_desc = cpu_breakpoints;
|
Mark Pizzolato | ac837e5 | 2015-12-29 10:11:39 -0800 | [diff] [blame] | 3365 | sim_vm_is_subroutine_call = &cpu_is_pc_a_subroutine_call;
|
| 3366 | auto_config(NULL, 0); /* do an initial auto configure */
|
| 3367 | }
|
Bob Supnik | df64751 | 2002-07-14 15:20:00 -0700 | [diff] [blame] | 3368 | pcq_r = find_reg ("PCQ", NULL, dptr);
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3369 | if (pcq_r)
|
| 3370 | pcq_r->qptr = 0;
|
Mark Pizzolato | ac837e5 | 2015-12-29 10:11:39 -0800 | [diff] [blame] | 3371 | else
|
| 3372 | return SCPE_IERR;
|
Bob Supnik | f20f5c6 | 2003-02-07 21:28:00 -0800 | [diff] [blame] | 3373 | set_r_display (0, MD_KER);
|
Mark Pizzolato | 59947e8 | 2015-12-30 12:01:58 -0800 | [diff] [blame] | 3374 | return build_dib_tab (); /* build, chk dib_tab */
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3375 | }
|
| 3376 |
|
Mark Pizzolato | 3946eb7 | 2014-04-19 05:45:29 -0700 | [diff] [blame] | 3377 | static const char *cpu_next_caveats =
|
| 3378 | "The NEXT command in the PDP11 simulator currently will enable stepping\n"
|
| 3379 | "across subroutine calls which are initiated by the JSR instruction.\n"
|
| 3380 | "This stepping works by dynamically establishing breakpoints at the\n"
|
| 3381 | "10 memory addresses immediately following the instruction which initiated\n"
|
| 3382 | "the subroutine call. These dynamic breakpoints are automatically\n"
|
| 3383 | "removed once the simulator returns to the sim> prompt for any reason.\n"
|
| 3384 | "If the called routine returns somewhere other than one of these\n"
|
| 3385 | "locations due to a trap, stack unwind or any other reason, instruction\n"
|
| 3386 | "execution will continue until some other reason causes execution to stop.\n";
|
| 3387 |
|
Mark Pizzolato | e7a9349 | 2014-04-17 13:07:37 -0700 | [diff] [blame] | 3388 | t_bool cpu_is_pc_a_subroutine_call (t_addr **ret_addrs)
|
| 3389 | {
|
| 3390 | #define MAX_SUB_RETURN_SKIP 10
|
| 3391 | static t_addr returns[MAX_SUB_RETURN_SKIP + 1] = {0};
|
Mark Pizzolato | 3946eb7 | 2014-04-19 05:45:29 -0700 | [diff] [blame] | 3392 | static t_bool caveats_displayed = FALSE;
|
Mark Pizzolato | e2a8f0f | 2016-08-24 21:19:09 -0700 | [diff] [blame] | 3393 | static int32 swmap[4] = {
|
| 3394 | SWMASK ('K') | SWMASK ('V'), SWMASK ('S') | SWMASK ('V'),
|
| 3395 | SWMASK ('U') | SWMASK ('V'), SWMASK ('U') | SWMASK ('V')
|
| 3396 | };
|
| 3397 | int32 cm = ((PSW >> PSW_V_CM) & 03);
|
Mark Pizzolato | e7a9349 | 2014-04-17 13:07:37 -0700 | [diff] [blame] | 3398 |
|
Mark Pizzolato | 3946eb7 | 2014-04-19 05:45:29 -0700 | [diff] [blame] | 3399 | if (!caveats_displayed) {
|
| 3400 | caveats_displayed = TRUE;
|
Mark Pizzolato | 3256c10 | 2014-10-22 17:12:14 -0700 | [diff] [blame] | 3401 | sim_printf ("%s", cpu_next_caveats);
|
Mark Pizzolato | 3946eb7 | 2014-04-19 05:45:29 -0700 | [diff] [blame] | 3402 | }
|
Mark Pizzolato | e2a8f0f | 2016-08-24 21:19:09 -0700 | [diff] [blame] | 3403 | if (SCPE_OK != get_aval (relocC(PC, swmap[cm]), &cpu_dev, &cpu_unit))/* get data */
|
Mark Pizzolato | e7a9349 | 2014-04-17 13:07:37 -0700 | [diff] [blame] | 3404 | return FALSE;
|
| 3405 | if ((sim_eval[0] & 0177000) == 0004000) { /* JSR */
|
| 3406 | int32 dst, dstspec;
|
| 3407 | t_addr i, max_returns = MAX_SUB_RETURN_SKIP;
|
| 3408 | int32 save_Regs[8];
|
| 3409 |
|
| 3410 | memcpy (save_Regs, R, sizeof(R)); /* save register state */
|
| 3411 | PC = PC + 2; /* account for instruction fetch */
|
| 3412 | dstspec = sim_eval[0] & 077;
|
| 3413 | dst = GeteaW (dstspec);
|
| 3414 | if (CPUT (CPUT_05|CPUT_20) && /* 11/05, 11/20 */
|
| 3415 | ((dstspec & 070) == 020)) /* JSR (R)+? */
|
| 3416 | dst = R[dstspec & 07]; /* use post incr */
|
| 3417 | memcpy (R, save_Regs, sizeof(R)); /* restore register state */
|
| 3418 | returns[0] = PC + (1 - fprint_sym (stdnul, PC, sim_eval, &cpu_unit, SWMASK ('M')));
|
| 3419 | if (((t_addr)dst > returns[0]) && ((dst - returns[0]) < max_returns*2))
|
| 3420 | max_returns = (dst - returns[0])/2;
|
| 3421 | for (i=1; i<max_returns; i++)
|
| 3422 | returns[i] = returns[i-1] + 2; /* Possible skip return */
|
| 3423 | returns[i] = 0; /* Make sure the address list ends with a zero */
|
| 3424 | *ret_addrs = returns;
|
| 3425 | return TRUE;
|
| 3426 | }
|
| 3427 | return FALSE;
|
| 3428 | }
|
| 3429 |
|
Mark Pizzolato | f0d41f1 | 2013-10-27 05:30:13 -0700 | [diff] [blame] | 3430 | /* Boot setup routine */
|
| 3431 |
|
| 3432 | void cpu_set_boot (int32 pc)
|
| 3433 | {
|
Mark Pizzolato | 235ce92 | 2014-10-28 10:19:39 -0700 | [diff] [blame] | 3434 | saved_PC = pc;
|
Mark Pizzolato | f0d41f1 | 2013-10-27 05:30:13 -0700 | [diff] [blame] | 3435 | PSW = 000340;
|
| 3436 | return;
|
| 3437 | }
|
| 3438 |
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3439 | /* Memory examine */
|
| 3440 |
|
| 3441 | t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw)
|
| 3442 | {
|
| 3443 | int32 iodata;
|
| 3444 | t_stat stat;
|
| 3445 |
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3446 | if (vptr == NULL)
|
| 3447 | return SCPE_ARG;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3448 | if (sw & SWMASK ('V')) { /* -v */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3449 | if (addr >= VASIZE)
|
| 3450 | return SCPE_NXM;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3451 | addr = relocC (addr, sw); /* relocate */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3452 | if (addr >= MAXMEMSIZE)
|
| 3453 | return SCPE_REL;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3454 | }
|
Paul Koning | 998cf5c | 2017-02-04 12:19:41 -0800 | [diff] [blame] | 3455 | if (ADDR_IS_MEM (addr)) {
|
| 3456 | *vptr = RdMemW (addr) & 0177777;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3457 | return SCPE_OK;
|
| 3458 | }
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3459 | if (addr < IOPAGEBASE)
|
| 3460 | return SCPE_NXM;
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3461 | stat = iopageR (&iodata, addr, READC);
|
| 3462 | *vptr = iodata;
|
| 3463 | return stat;
|
| 3464 | }
|
| 3465 |
|
| 3466 | /* Memory deposit */
|
| 3467 |
|
| 3468 | t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw)
|
| 3469 | {
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3470 | if (sw & SWMASK ('V')) { /* -v */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3471 | if (addr >= VASIZE)
|
| 3472 | return SCPE_NXM;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3473 | addr = relocC (addr, sw); /* relocate */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3474 | if (addr >= MAXMEMSIZE)
|
| 3475 | return SCPE_REL;
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3476 | }
|
Paul Koning | 998cf5c | 2017-02-04 12:19:41 -0800 | [diff] [blame] | 3477 | if (ADDR_IS_MEM (addr)) {
|
| 3478 | WrMemW (addr, val & 0177777);
|
Bob Supnik | b7c1eae | 2005-09-09 18:09:00 -0700 | [diff] [blame] | 3479 | return SCPE_OK;
|
| 3480 | }
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3481 | if (addr < IOPAGEBASE)
|
| 3482 | return SCPE_NXM;
|
Bob Supnik | 9af6fd2 | 2001-11-06 20:44:00 -0800 | [diff] [blame] | 3483 | return iopageW ((int32) val, addr, WRITEC);
|
Bob Supnik | 2c2dd5e | 2002-11-17 15:54:00 -0800 | [diff] [blame] | 3484 | }
|
| 3485 |
|
Bob Supnik | f20f5c6 | 2003-02-07 21:28:00 -0800 | [diff] [blame] | 3486 | /* Set R, SP register display addresses */
|
| 3487 |
|
| 3488 | void set_r_display (int32 rs, int32 cm)
|
| 3489 | {
|
Bob Supnik | f20f5c6 | 2003-02-07 21:28:00 -0800 | [diff] [blame] | 3490 | REG *rptr;
|
| 3491 | int32 i;
|
| 3492 |
|
| 3493 | rptr = find_reg ("R0", NULL, &cpu_dev);
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3494 | if (rptr == NULL)
|
| 3495 | return;
|
| 3496 | for (i = 0; i < 6; i++, rptr++)
|
| 3497 | rptr->loc = (void *) ®FILE[i][rs];
|
Bob Supnik | f20f5c6 | 2003-02-07 21:28:00 -0800 | [diff] [blame] | 3498 | rptr->loc = (void *) &STACKFILE[cm];
|
| 3499 | return;
|
| 3500 | }
|
Bob Supnik | dc871fa | 2006-05-27 11:34:00 -0700 | [diff] [blame] | 3501 |
|
| 3502 | /* Set history */
|
| 3503 |
|
Mark Pizzolato | 5531ccb | 2016-05-15 15:25:33 -0700 | [diff] [blame] | 3504 | t_stat cpu_set_hist (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
|
Bob Supnik | dc871fa | 2006-05-27 11:34:00 -0700 | [diff] [blame] | 3505 | {
|
| 3506 | int32 i, lnt;
|
| 3507 | t_stat r;
|
| 3508 |
|
| 3509 | if (cptr == NULL) {
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3510 | for (i = 0; i < hst_lnt; i++)
|
| 3511 | hst[i].pc = 0;
|
Bob Supnik | dc871fa | 2006-05-27 11:34:00 -0700 | [diff] [blame] | 3512 | hst_p = 0;
|
| 3513 | return SCPE_OK;
|
| 3514 | }
|
| 3515 | lnt = (int32) get_uint (cptr, 10, HIST_MAX, &r);
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3516 | if ((r != SCPE_OK) || (lnt && (lnt < HIST_MIN)))
|
| 3517 | return SCPE_ARG;
|
Bob Supnik | dc871fa | 2006-05-27 11:34:00 -0700 | [diff] [blame] | 3518 | hst_p = 0;
|
| 3519 | if (hst_lnt) {
|
| 3520 | free (hst);
|
| 3521 | hst_lnt = 0;
|
| 3522 | hst = NULL;
|
| 3523 | }
|
| 3524 | if (lnt) {
|
| 3525 | hst = (InstHistory *) calloc (lnt, sizeof (InstHistory));
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3526 | if (hst == NULL)
|
| 3527 | return SCPE_MEM;
|
Bob Supnik | dc871fa | 2006-05-27 11:34:00 -0700 | [diff] [blame] | 3528 | hst_lnt = lnt;
|
| 3529 | }
|
| 3530 | return SCPE_OK;
|
| 3531 | }
|
| 3532 |
|
| 3533 | /* Show history */
|
| 3534 |
|
Mark Pizzolato | 5531ccb | 2016-05-15 15:25:33 -0700 | [diff] [blame] | 3535 | t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
|
Bob Supnik | dc871fa | 2006-05-27 11:34:00 -0700 | [diff] [blame] | 3536 | {
|
| 3537 | int32 j, k, di, lnt, ir;
|
Mark Pizzolato | 5531ccb | 2016-05-15 15:25:33 -0700 | [diff] [blame] | 3538 | const char *cptr = (const char *) desc;
|
Bob Supnik | dc871fa | 2006-05-27 11:34:00 -0700 | [diff] [blame] | 3539 | t_value sim_eval[HIST_ILNT];
|
| 3540 | t_stat r;
|
| 3541 | InstHistory *h;
|
Bob Supnik | dc871fa | 2006-05-27 11:34:00 -0700 | [diff] [blame] | 3542 |
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3543 | if (hst_lnt == 0) /* enabled? */
|
| 3544 | return SCPE_NOFNC;
|
Bob Supnik | dc871fa | 2006-05-27 11:34:00 -0700 | [diff] [blame] | 3545 | if (cptr) {
|
| 3546 | lnt = (int32) get_uint (cptr, 10, hst_lnt, &r);
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3547 | if ((r != SCPE_OK) || (lnt == 0))
|
| 3548 | return SCPE_ARG;
|
Bob Supnik | dc871fa | 2006-05-27 11:34:00 -0700 | [diff] [blame] | 3549 | }
|
| 3550 | else lnt = hst_lnt;
|
| 3551 | di = hst_p - lnt; /* work forward */
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3552 | if (di < 0)
|
| 3553 | di = di + hst_lnt;
|
Bob Supnik | dc871fa | 2006-05-27 11:34:00 -0700 | [diff] [blame] | 3554 | fprintf (st, "PC PSW src dst IR\n\n");
|
| 3555 | for (k = 0; k < lnt; k++) { /* print specified */
|
| 3556 | h = &hst[(di++) % hst_lnt]; /* entry pointer */
|
| 3557 | if (h->pc & HIST_VLD) { /* instruction? */
|
| 3558 | ir = h->inst[0];
|
| 3559 | fprintf (st, "%06o %06o|", h->pc & ~HIST_VLD, h->psw);
|
| 3560 | if (((ir & 0070000) != 0) || /* dops, eis, fpp */
|
| 3561 | ((ir & 0177000) == 0004000)) /* jsr */
|
| 3562 | fprintf (st, "%06o %06o ", h->src, h->dst);
|
| 3563 | else if ((ir >= 0000100) && /* not no opnd */
|
| 3564 | (((ir & 0007700) < 0000300) || /* not branch */
|
| 3565 | ((ir & 0007700) >= 0004000)))
|
| 3566 | fprintf (st, " %06o ", h->dst);
|
| 3567 | else fprintf (st, " ");
|
Bob Supnik | 9c4779c | 2009-02-08 09:06:00 -0800 | [diff] [blame] | 3568 | for (j = 0; j < HIST_ILNT; j++)
|
| 3569 | sim_eval[j] = h->inst[j];
|
Bob Supnik | dc871fa | 2006-05-27 11:34:00 -0700 | [diff] [blame] | 3570 | if ((fprint_sym (st, h->pc & ~HIST_VLD, sim_eval, &cpu_unit, SWMASK ('M'))) > 0)
|
| 3571 | fprintf (st, "(undefined) %06o", h->inst[0]);
|
| 3572 | fputc ('\n', st); /* end line */
|
| 3573 | } /* end else instruction */
|
| 3574 | } /* end for */
|
| 3575 | return SCPE_OK;
|
| 3576 | }
|
| 3577 |
|
| 3578 | /* Virtual address translation */
|
| 3579 |
|
Mark Pizzolato | 5531ccb | 2016-05-15 15:25:33 -0700 | [diff] [blame] | 3580 | t_stat cpu_show_virt (FILE *of, UNIT *uptr, int32 val, CONST void *desc)
|
Bob Supnik | dc871fa | 2006-05-27 11:34:00 -0700 | [diff] [blame] | 3581 | {
|
| 3582 | t_stat r;
|
Mark Pizzolato | 5531ccb | 2016-05-15 15:25:33 -0700 | [diff] [blame] | 3583 | const char *cptr = (const char *) desc;
|
Bob Supnik | dc871fa | 2006-05-27 11:34:00 -0700 | [diff] [blame] | 3584 | uint32 va, pa;
|
| 3585 |
|
| 3586 | if (cptr) {
|
| 3587 | va = (uint32) get_uint (cptr, 8, VAMASK, &r);
|
| 3588 | if (r == SCPE_OK) {
|
| 3589 | pa = relocC (va, sim_switches); /* relocate */
|
| 3590 | if (pa < MAXMEMSIZE)
|
| 3591 | fprintf (of, "Virtual %-o = physical %-o\n", va, pa);
|
| 3592 | else fprintf (of, "Virtual %-o is not valid\n", va);
|
| 3593 | return SCPE_OK;
|
| 3594 | }
|
| 3595 | }
|
| 3596 | fprintf (of, "Invalid argument\n");
|
| 3597 | return SCPE_OK;
|
| 3598 | }
|