1 /* hp2100_cpu.h: HP 2100 CPU declarations 2 3 Copyright (c) 2005-2016, Robert M. Supnik 4 Copyright (c) 2017-2019, J. David Bryan 5 6 Permission is hereby granted, free of charge, to any person obtaining a copy 7 of this software and associated documentation files (the "Software"), to deal 8 in the Software without restriction, including without limitation the rights 9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 copies of the Software, and to permit persons to whom the Software is 11 furnished to do so, subject to the following conditions: 12 13 The above copyright notice and this permission notice shall be included in 14 all copies or substantial portions of the Software. 15 16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 23 Except as contained in this notice, the names of the authors shall not be 24 used in advertising or otherwise to promote the sale, use or other dealings 25 in this Software without prior written authorization from the authors. 26 27 23-Jan-19 JDB Removed fmt_ab global declaration; now local to hp2100_cpu5.c 28 removed cpu_user_20 global declaration 29 02-Aug-18 JDB Removed cpu_ema_* helper routine global declarations 30 20-Jul-18 JDB Incorporated declarations and changelog from hp2100_cpu1.h 31 10-Jul-18 JDB Moved IBL info to hp2100_io.h 32 14-Jun-18 JDB Renamed MST_PRO to MST_PROT 33 05-Jun-18 JDB Revised I/O model 34 22-Feb-18 JDB Reworked "cpu_ibl" into "cpu_copy_loader" 35 Cleaned up IBL definitions, added loader structure 36 22-Jul-17 JDB Renamed "intaddr" to CIR; added IR 37 14-Jul-17 JDB Removed calc_defer() prototype 38 11-Jul-17 JDB Moved "ibl_copy" and renamed to "cpu_ibl" 39 10-Jul-17 JDB Renamed the global routine "iogrp" to "cpu_iog" 40 07-Jul-17 JDB Changed "iotrap" from uint32 to t_bool 41 07-Jun-17 JDB Added maximum instruction length for sim_emax definition 42 06-Jun-17 JDB Added instruction group decoding macros 43 04-Apr-17 JDB Added "cpu_configuration" for symbolic ex/dep validation 44 08-Mar-17 JDB Added "cpu_speed" for TBG service access 45 15-Feb-17 JDB Deleted unneeded guard macro definition 46 26-Jan-17 JDB Removed debug parameters from cpu_ema_* routines 47 17-Jan-17 JDB Removed register print encoding constants (now redundant) 48 05-Aug-16 JDB Renamed the P register from "PC" to "PR" 49 24-Dec-14 JDB Added casts for explicit downward conversions 50 18-Mar-13 JDB Added declarations for the MP abort handler and CPU registers 51 Added externs for microcode helper functions 52 14-Mar-13 MP Changed guard macro name to avoid reserved namespace 53 03-Jan-10 RMS Changed declarations of mp_control, mp_mefvv, for VMS compiler 54 11-Sep-08 JDB Moved microcode function prototypes here 55 15-Jul-08 JDB Rearranged declarations with hp2100_cpu.c and hp2100_defs.h 56 26-Jun-08 JDB Added mp_control to CPU state externals 57 30-Apr-08 JDB Corrected OP_AFF to OP_AAFF for SIGNAL/1000 58 Removed unused operand patterns 59 24-Apr-08 JDB Added calc_defer() prototype 60 20-Apr-08 JDB Added DEB_VIS and DEB_SIG debug flags 61 23-Feb-08 HV Added more OP_* for SIGNAL/1000 and VIS 62 28-Nov-07 JDB Added fprint_ops, fprint_regs for debug printouts 63 26-Nov-07 JDB Added extern sim_deb, cpu_dev, DEB flags for debug printouts 64 05-Nov-07 JDB Added extern intaddr, mp_viol, mp_mevff, calc_int, dev_ctl, 65 ReadIO, WriteIO for RTE-6/VM microcode support 66 19-Oct-07 JDB Revised OP_KKKAKK operand profile to OP_CCCACC for $LOC 67 16-Dec-06 JDB Added UNIT_2115 and UNIT_2114 68 16-Oct-06 JDB Moved ReadF to hp2100_cpu1.c 69 Generalized operands for F-Series FP types 70 26-Sep-06 JDB Added CPU externs for microcode simulators 71 Split from hp2100_cpu1.c 72 16-Aug-06 JDB Added UNIT_EMA for future RTE-4 EMA microcode 73 Added UNIT_VMA for future RTE-6 VMA and OS microcode 74 Added UNIT_1000_F for future F-Series support 75 09-Aug-06 JDB Added UNIT_DBI for double integer microcode 76 21-Jan-05 JDB Reorganized CPU option flags 77 14-Jan-05 RMS Cloned from hp2100_cpu.c 78 79 CPU models are broken down into family, type, and series to facilitate option 80 validation. Bit 3 encodes the family, bit 2 encodes the type, and bits 1:0 81 encode the series within the type. 82 */ 83 84 85 86 /* Memory access macros. 87 88 These macros provide simplified function call sequences for memory reads and 89 writes by the CPU. They supply the correct access classification. The 90 following macro routines are provided: 91 92 Name Action 93 ------- ------------------------------------------------------------ 94 ReadF Read an instruction word using the current map 95 ReadW Read a data word using the current map 96 ReadWA Read a data word using the alternate map 97 ReadS Read a data word using the system map 98 ReadU Read a data word using the user map 99 100 ReadB Read a data byte using the current map 101 ReadBA Read a data byte using the alternate map 102 103 WriteW Write a data word using the current map 104 WriteWA Write a data word using the alternate map 105 WriteS Write a data word using the system map 106 WriteU Write a data word using the user map 107 108 WriteB Write a data byte using the current map 109 WriteBA Write a data byte using the alternate map 110 */ 111 112 #define ReadF(a) mem_read (&cpu_dev, Fetch, a) 113 #define ReadW(a) mem_read (&cpu_dev, Data, a) 114 #define ReadWA(a) mem_read (&cpu_dev, Data_Alternate, a) 115 #define ReadS(a) mem_read (&cpu_dev, Data_System, a) 116 #define ReadU(a) mem_read (&cpu_dev, Data_User, a) 117 118 #define ReadB(a) mem_read_byte (&cpu_dev, Data, a) 119 #define ReadBA(a) mem_read_byte (&cpu_dev, Data_Alternate, a) 120 121 #define WriteW(a,v) mem_write (&cpu_dev, Data, a, v) 122 #define WriteWA(a,v) mem_write (&cpu_dev, Data_Alternate, a, v) 123 #define WriteS(a,v) mem_write (&cpu_dev, Data_System, a, v) 124 #define WriteU(a,v) mem_write (&cpu_dev, Data_User, a, v) 125 126 #define WriteB(a,v) mem_write_byte (&cpu_dev, Data, a, v) 127 #define WriteBA(a,v) mem_write_byte (&cpu_dev, Data_Alternate, a, v) 128 129 130 /* CPU private tracing flags. 131 132 Private flags are allocated in descending order to avoid conflicts 133 with global flags that are allocated in ascending order. 134 */ 135 136 #define DEBUG_NOOS (1u << 31) /* configure RTE-6/VM not to use OS firmware */ 137 138 #define TRACE_INSTR (1u << 30) /* trace instruction executions */ 139 #define TRACE_DATA (1u << 29) /* trace memory data accesses */ 140 #define TRACE_FETCH (1u << 28) /* trace memory instruction fetches */ 141 #define TRACE_REG (1u << 27) /* trace register values */ 142 #define TRACE_OPND (1u << 26) /* trace instruction operands */ 143 #define TRACE_EXEC (1u << 25) /* trace matching instruction execution states */ 144 #define TRACE_SR (1u << 24) /* trace DMA service requests received */ 145 146 #define TRACE_ALL ~DEBUG_NOOS /* trace everything */ 147 148 #define REGA_FORMAT "%c **** %05o %06o " /* protection | fence | S register format for working registers */ 149 #define REGB_FORMAT "%c **** ***** ****** " /* protection format for MP/MEM registers */ 150 #define OPND_FORMAT "* **** %05o %06o " /* address | data format for operands */ 151 #define EXEC_FORMAT "******************** " /* null format for EXEC separation */ 152 #define DMS_FORMAT "%c %04o %05o %06o " /* map | physical page | logical address | value format */ 153 154 155 /* CPU stop flags */ 156 157 #define SS_INHIBIT (t_stat) (~0u) /* inhibit stops for the first instruction executed */ 158 159 #define STOP(s) ((s) & ~cpu_ss_inhibit) /* stop if the condition is enabled and not inhibited */ 160 161 162 /* Supported breakpoint switches */ 163 164 #define BP_EXEC (SWMASK ('E')) /* an execution breakpoint */ 165 #define BP_ENONE (SWMASK ('N')) /* an execution breakpoint when mapping is off */ 166 #define BP_ESYS (SWMASK ('S')) /* an execution breakpoint in the system map */ 167 #define BP_EUSER (SWMASK ('U')) /* an execution breakpoint in the user map */ 168 169 #define BP_SUPPORTED (BP_EXEC | BP_ENONE | BP_ESYS | BP_EUSER) 170 171 172 /* PC queue */ 173 174 #define PCQ_SIZE 64 /* must be 2 ** n */ 175 #define PCQ_MASK (PCQ_SIZE - 1) 176 #define PCQ_ENTRY pcq [pcq_p = (pcq_p - 1) & PCQ_MASK] = (uint16) err_PR 177 178 179 /* Maximum instruction length. 180 181 This value is the length in words of the longest machine instruction. It is 182 used to set "sim_emax", which, in turn, is used to allocate the "sim_eval" 183 array. This array holds the words of a machine instruction to be formatted 184 and printed or to be parsed and stored. 185 186 The longest instruction in the 21xx/1000 family is the [D]VPIV (vector pivot) 187 instruction in the Vector Instruction Set. 188 */ 189 190 #define MAX_INSTR_LENGTH 10 191 192 193 /* Instruction group decoding. 194 195 The HP 21xx/1000 instruction set consists of five groups: the Memory 196 Reference Group (MRG), the Shift-Rotate Group (SRG), the Alter-Skip Group 197 (ASG), the I/O Group (IOG), and the Macro Group (MAC). Group membership is 198 determined by a multi-level decoding of bits 15-10, as follows: 199 200 Bits 201 15-10 Group 202 ------ ----- 203 xnnnx MRG 204 00000 SRG 205 00001 ASG 206 10001 IOG 207 10000 MAC 208 209 Where: 210 211 x = 0 or 1 212 n = any collective value other than 0 213 214 The MAC group is subdivided into the Extended Arithmetic Group (EAG), the 215 first User Instruction Group (UIG-0), and the second User Instruction Group 216 (UIG-1). Decoding is by bits 11-8, as follows (note that bit 10 = 0 for the 217 MAC group): 218 219 Bits 220 11-8 Group 221 ---- ----- 222 0000 EAG 223 0001 EAG 224 0010 EAG 225 0011 UIG-1 226 1000 EAG 227 1001 EAG 228 1010 UIG-0 229 1011 UIG-1 230 231 Bits 7-4 further decode the UIG instruction feature group. 232 */ 233 234 #define GROUP_MASK 0172000u /* instruction group mask */ 235 236 #define MRG 0070000u /* Memory Reference Group indicator */ 237 #define SRG 0000000u /* Shift-Rotate Group indicator */ 238 #define ASG 0002000u /* Alter-Skip Group indicator */ 239 #define IOG 0102000u /* I/O Group indicator */ 240 241 #define MRGOP(v) (((v) & MRG) != 0) /* MRG membership test */ 242 #define SRGOP(v) (((v) & GROUP_MASK) == SRG) /* SRG membership test */ 243 #define ASGOP(v) (((v) & GROUP_MASK) == ASG) /* ASG membership test */ 244 #define IOGOP(v) (((v) & GROUP_MASK) == IOG) /* IOG membership test */ 245 246 #define SRG_CLE 0000040u /* SRG CLE opcode */ 247 #define SRG_SLx 0000010u /* SRG SLA/SLB opcode */ 248 #define SRG_NOP 0000000u /* SRG no-operation opcode */ 249 250 #define SRG1_DE_MASK 0001000u /* SRG disable/enable first micro-op field bit */ 251 #define SRG1_MASK 0001700u 252 #define SRG1_SHIFT 6 253 254 #define SRG2_DE_MASK 0000020u /* SRG disable/enable second micro-op field bit */ 255 #define SRG2_MASK 0000027u 256 #define SRG2_SHIFT 0 257 258 #define SRG1(u) (((u) & SRG1_MASK) >> SRG1_SHIFT) 259 #define SRG2(u) (((u) & SRG2_MASK) >> SRG2_SHIFT) 260 261 #define IOG_MASK 0001700u 262 #define IOG_SHIFT 6 263 #define IOG_OP(v) ((IO_GROUP_OP) (((v) & IOG_MASK) >> IOG_SHIFT)) 264 265 #define UIG_MASK 0000360u /* UIG feature group mask */ 266 #define UIG_SHIFT 4 /* UIG feature group alignment shift */ 267 268 #define UIG(i) (((i) & UIG_MASK) >> UIG_SHIFT) 269 270 #define UIG_0_MASK 0177400u /* UIG-0 opcode mask */ 271 #define UIG_0_RANGE 0105000u /* UIG-0 opcode range */ 272 273 #define UIG_1_MASK 0173400u /* UIG-1 opcode mask */ 274 #define UIG_1_RANGE 0101400u /* UIG-1 opcode range */ 275 276 #define UIG_0_OP(i) (((i) & UIG_0_MASK) == UIG_0_RANGE) /* UIG-0 membership test */ 277 #define UIG_1_OP(i) (((i) & UIG_1_MASK) == UIG_1_RANGE) /* UIG-1 membership test */ 278 279 #define RTE_IRQ_RANGE 0105354u /* RTE-6/VM interrupt request instructions range */ 280 281 282 /* Memory Reference Group instruction register fields */ 283 284 #define IR_IND 0100000u /* indirect address bit */ 285 #define IR_CP 0002000u /* current page bit */ 286 #define IR_OFFSET 0001777u /* page offset */ 287 288 #define MR_PAGE 0076000u /* page number bits within a memory address */ 289 290 291 /* I/O Group instruction register fields */ 292 293 #define IR_HCF 0001000u /* hold/clear flag bit */ 294 295 296 /* General instruction register fields */ 297 298 #define AB_MASK 0004000u /* A or B register select bit */ 299 #define AB_SHIFT 11 300 301 #define AB_SELECT(i) (((i) & AB_MASK) >> AB_SHIFT) 302 303 304 /* Instruction operand processing encoding */ 305 306 /* Base operand types. Note that all address encodings must be grouped together 307 after OP_ADR. 308 */ 309 310 #define OP_NUL 0 /* no operand */ 311 #define OP_IAR 1 /* 1-word int in A reg */ 312 #define OP_JAB 2 /* 2-word int in A/B regs */ 313 #define OP_FAB 3 /* 2-word FP const in A/B regs */ 314 #define OP_CON 4 /* inline 1-word constant */ 315 #define OP_VAR 5 /* inline 1-word variable */ 316 317 #define OP_ADR 6 /* inline address */ 318 #define OP_ADK 7 /* addr of 1-word int const */ 319 #define OP_ADD 8 /* addr of 2-word int const */ 320 #define OP_ADF 9 /* addr of 2-word FP const */ 321 #define OP_ADX 10 /* addr of 3-word FP const */ 322 #define OP_ADT 11 /* addr of 4-word FP const */ 323 #define OP_ADE 12 /* addr of 5-word FP const */ 324 325 #define OP_N_FLAGS 4 /* number of bits needed for flags */ 326 #define OP_M_FLAGS ((1 << OP_N_FLAGS) - 1) /* mask for flag bits */ 327 328 #define OP_N_F (8 * sizeof (uint32) / OP_N_FLAGS) /* max number of op fields */ 329 330 #define OP_V_F1 (0 * OP_N_FLAGS) /* 1st operand field */ 331 #define OP_V_F2 (1 * OP_N_FLAGS) /* 2nd operand field */ 332 #define OP_V_F3 (2 * OP_N_FLAGS) /* 3rd operand field */ 333 #define OP_V_F4 (3 * OP_N_FLAGS) /* 4th operand field */ 334 #define OP_V_F5 (4 * OP_N_FLAGS) /* 5th operand field */ 335 #define OP_V_F6 (5 * OP_N_FLAGS) /* 6th operand field */ 336 #define OP_V_F7 (6 * OP_N_FLAGS) /* 7th operand field */ 337 #define OP_V_F8 (7 * OP_N_FLAGS) /* 8th operand field */ 338 339 /* Operand processing patterns */ 340 341 #define OP_N (OP_NUL << OP_V_F1) 342 #define OP_I (OP_IAR << OP_V_F1) 343 #define OP_J (OP_JAB << OP_V_F1) 344 #define OP_R (OP_FAB << OP_V_F1) 345 #define OP_C (OP_CON << OP_V_F1) 346 #define OP_V (OP_VAR << OP_V_F1) 347 #define OP_A (OP_ADR << OP_V_F1) 348 #define OP_K (OP_ADK << OP_V_F1) 349 #define OP_D (OP_ADD << OP_V_F1) 350 #define OP_X (OP_ADX << OP_V_F1) 351 #define OP_T (OP_ADT << OP_V_F1) 352 #define OP_E (OP_ADE << OP_V_F1) 353 354 #define OP_IA ((OP_IAR << OP_V_F1) | (OP_ADR << OP_V_F2)) 355 #define OP_JA ((OP_JAB << OP_V_F1) | (OP_ADR << OP_V_F2)) 356 #define OP_JD ((OP_JAB << OP_V_F1) | (OP_ADD << OP_V_F2)) 357 #define OP_RC ((OP_FAB << OP_V_F1) | (OP_CON << OP_V_F2)) 358 #define OP_RK ((OP_FAB << OP_V_F1) | (OP_ADK << OP_V_F2)) 359 #define OP_RF ((OP_FAB << OP_V_F1) | (OP_ADF << OP_V_F2)) 360 #define OP_CV ((OP_CON << OP_V_F1) | (OP_VAR << OP_V_F2)) 361 #define OP_AC ((OP_ADR << OP_V_F1) | (OP_CON << OP_V_F2)) 362 #define OP_AA ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2)) 363 #define OP_AK ((OP_ADR << OP_V_F1) | (OP_ADK << OP_V_F2)) 364 #define OP_AX ((OP_ADR << OP_V_F1) | (OP_ADX << OP_V_F2)) 365 #define OP_AT ((OP_ADR << OP_V_F1) | (OP_ADT << OP_V_F2)) 366 #define OP_KV ((OP_ADK << OP_V_F1) | (OP_VAR << OP_V_F2)) 367 #define OP_KA ((OP_ADK << OP_V_F1) | (OP_ADR << OP_V_F2)) 368 #define OP_KK ((OP_ADK << OP_V_F1) | (OP_ADK << OP_V_F2)) 369 370 #define OP_IIF ((OP_IAR << OP_V_F1) | (OP_IAR << OP_V_F2) | \ 371 (OP_ADF << OP_V_F3)) 372 373 #define OP_IAT ((OP_IAR << OP_V_F1) | (OP_ADR << OP_V_F2) | \ 374 (OP_ADT << OP_V_F3)) 375 376 #define OP_CVA ((OP_CON << OP_V_F1) | (OP_VAR << OP_V_F2) | \ 377 (OP_ADR << OP_V_F3)) 378 379 #define OP_AAA ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \ 380 (OP_ADR << OP_V_F3)) 381 382 #define OP_AAF ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \ 383 (OP_ADF << OP_V_F3)) 384 385 #define OP_AAX ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \ 386 (OP_ADX << OP_V_F3)) 387 388 #define OP_AAT ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \ 389 (OP_ADT << OP_V_F3)) 390 391 #define OP_AKA ((OP_ADR << OP_V_F1) | (OP_ADK << OP_V_F2) | \ 392 (OP_ADR << OP_V_F3)) 393 394 #define OP_AKK ((OP_ADR << OP_V_F1) | (OP_ADK << OP_V_F2) | \ 395 (OP_ADK << OP_V_F3)) 396 397 #define OP_AXX ((OP_ADR << OP_V_F1) | (OP_ADX << OP_V_F2) | \ 398 (OP_ADX << OP_V_F3)) 399 400 #define OP_ATT ((OP_ADR << OP_V_F1) | (OP_ADT << OP_V_F2) | \ 401 (OP_ADT << OP_V_F3)) 402 403 #define OP_AEE ((OP_ADR << OP_V_F1) | (OP_ADE << OP_V_F2) | \ 404 (OP_ADE << OP_V_F3)) 405 406 #define OP_AAXX ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \ 407 (OP_ADX << OP_V_F3) | (OP_ADX << OP_V_F4)) 408 409 #define OP_AAFF ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \ 410 (OP_ADF << OP_V_F3) | (OP_ADF << OP_V_F4)) 411 412 #define OP_AAKK ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \ 413 (OP_ADK << OP_V_F3) | (OP_ADK << OP_V_F4)) 414 415 #define OP_KKKK ((OP_ADK << OP_V_F1) | (OP_ADK << OP_V_F2) | \ 416 (OP_ADK << OP_V_F3) | (OP_ADK << OP_V_F4)) 417 418 #define OP_AAAKK ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \ 419 (OP_ADR << OP_V_F3) | (OP_ADK << OP_V_F4) | \ 420 (OP_ADK << OP_V_F5)) 421 422 #define OP_AKAKK ((OP_ADR << OP_V_F1) | (OP_ADK << OP_V_F2) | \ 423 (OP_ADR << OP_V_F3) | (OP_ADK << OP_V_F4) | \ 424 (OP_ADK << OP_V_F5)) 425 426 #define OP_AAACCC ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \ 427 (OP_ADR << OP_V_F3) | (OP_CON << OP_V_F4) | \ 428 (OP_CON << OP_V_F5) | (OP_CON << OP_V_F6)) 429 430 #define OP_AAFFKK ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \ 431 (OP_ADF << OP_V_F3) | (OP_ADF << OP_V_F4) | \ 432 (OP_ADK << OP_V_F5) | (OP_ADK << OP_V_F6)) 433 434 #define OP_AAKAKK ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \ 435 (OP_ADK << OP_V_F3) | (OP_ADR << OP_V_F4) | \ 436 (OP_ADK << OP_V_F5) | (OP_ADK << OP_V_F6)) 437 438 #define OP_CATAKK ((OP_CON << OP_V_F1) | (OP_ADR << OP_V_F2) | \ 439 (OP_ADT << OP_V_F3) | (OP_ADR << OP_V_F4) | \ 440 (OP_ADK << OP_V_F5) | (OP_ADK << OP_V_F6)) 441 442 #define OP_CCCACC ((OP_CON << OP_V_F1) | (OP_CON << OP_V_F2) | \ 443 (OP_CON << OP_V_F3) | (OP_ADR << OP_V_F4) | \ 444 (OP_CON << OP_V_F5) | (OP_CON << OP_V_F6)) 445 446 #define OP_AAAFFKK ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \ 447 (OP_ADR << OP_V_F3) | (OP_ADF << OP_V_F4) | \ 448 (OP_ADF << OP_V_F5) | (OP_ADK << OP_V_F6) | \ 449 (OP_ADK << OP_V_F7)) 450 451 #define OP_AKAKAKK ((OP_ADR << OP_V_F1) | (OP_ADK << OP_V_F2) | \ 452 (OP_ADR << OP_V_F3) | (OP_ADK << OP_V_F4) | \ 453 (OP_ADR << OP_V_F5) | (OP_ADK << OP_V_F6) | \ 454 (OP_ADK << OP_V_F7)) 455 456 #define OP_AAKAKAKK ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \ 457 (OP_ADK << OP_V_F3) | (OP_ADR << OP_V_F4) | \ 458 (OP_ADK << OP_V_F5) | (OP_ADR << OP_V_F6) | \ 459 (OP_ADK << OP_V_F7) | (OP_ADK << OP_V_F8)) 460 461 #define OP_CCACACCA ((OP_CON << OP_V_F1) | (OP_CON << OP_V_F2) | \ 462 (OP_ADR << OP_V_F3) | (OP_CON << OP_V_F4) | \ 463 (OP_ADR << OP_V_F5) | (OP_CON << OP_V_F6) | \ 464 (OP_CON << OP_V_F7) | (OP_ADR << OP_V_F8)) 465 466 467 /* Operand precisions (compatible with F-Series FPP): 468 469 - S = 1-word integer 470 - D = 2-word integer 471 - F = 2-word single-precision floating-point 472 - X = 3-word extended-precision floating-point 473 - T = 4-word double-precision floating-point 474 - E = 5-word expanded-exponent floating-point 475 - A = null operand (operand is in the FPP accumulator) 476 477 5-word floating-point numbers are supported by the F-Series Floating-Point 478 Processor hardware, but the instruction codes are not documented. 479 480 481 Implementation notes: 482 483 1. The enumeration rdering is important, as we depend on the "fp" 484 type values to reflect the number of words needed (2-5). 485 */ 486 487 typedef enum { /* operand precision */ 488 in_s, /* 1-word integer */ 489 in_d, /* 2-word integer */ 490 fp_f, /* 2-word single-precision floating-point */ 491 fp_x, /* 3-word extended-precision floating-point */ 492 fp_t, /* 4-word double-precision floating-point */ 493 fp_e, /* 5-word expanded-exponent floating-point */ 494 fp_a /* null operand (operand is in FPP accumulator) */ 495 } OPSIZE; 496 497 498 /* Conversion from operand size to word count */ 499 500 #define TO_COUNT(s) ((s == fp_a) ? 0 : (uint32) (s + (s < fp_f))) 501 502 503 /* HP in-memory representation of a packed floating-point number. 504 Actual value will use two, three, four, or five words, as needed. 505 */ 506 507 typedef HP_WORD FPK [5]; 508 509 510 /* Operand processing types. 511 512 NOTE: Microsoft VC++ 6.0 does not support the C99 standard, so we cannot 513 initialize unions by arbitrary variant ("designated initializers"). 514 Therefore, we follow the C90 form of initializing via the first named 515 variant. The FPK variant must appear first in the OP structure, as we define 516 a number of FPK constants in other modules. 517 */ 518 519 typedef union { /* general operand */ 520 FPK fpk; /* floating-point value */ 521 HP_WORD word; /* 16-bit integer */ 522 uint32 dword; /* 32-bit integer */ 523 } OP; 524 525 typedef OP OPS[OP_N_F]; /* operand array */ 526 527 typedef uint32 OP_PAT; /* operand pattern */ 528 529 530 /* Microcode abort reasons */ 531 532 typedef enum { /* Abort reason passed via "longjmp" */ 533 Initialized = 0, 534 Memory_Protect, 535 Interrupt, 536 Indirect_Loop 537 } MICRO_ABORT; 538 539 540 /* CPU global register declarations */ 541 542 #define AR ABREG [0] /* A register = memory location 0 */ 543 #define BR ABREG [1] /* B register = memory location 1 */ 544 545 extern HP_WORD ABREG [2]; /* A and B registers (use AR/BR to reference) */ 546 extern HP_WORD PR; /* P register */ 547 extern HP_WORD SR; /* S register */ 548 extern HP_WORD MR; /* M register */ 549 extern HP_WORD TR; /* T register */ 550 extern HP_WORD XR; /* X register */ 551 extern HP_WORD YR; /* Y register */ 552 extern uint32 E; /* E register */ 553 extern uint32 O; /* O register */ 554 555 extern HP_WORD IR; /* Instruction Register */ 556 extern HP_WORD CIR; /* Central Interrupt Register */ 557 extern HP_WORD SPR; /* Stack Pointer Register (F-register for 2100) */ 558 559 560 /* CPU global state */ 561 562 extern DEVICE cpu_dev; /* CPU device structure */ 563 564 extern HP_WORD err_PR; /* P register error value */ 565 extern FLIP_FLOP cpu_interrupt_enable; /* interrupt enable flip-flop */ 566 extern uint16 pcq [PCQ_SIZE]; /* PC queue (must be 16-bits wide for REG array entry) */ 567 extern uint32 pcq_p; /* PC queue pointer */ 568 569 extern t_stat cpu_ss_unimpl; /* status return for unimplemented instruction execution */ 570 extern t_stat cpu_ss_undef; /* status return for undefined instruction execution */ 571 extern t_stat cpu_ss_unsc; /* status return for I/O to an unassigned select code */ 572 extern t_stat cpu_ss_indir; /* status return for indirect loop execution */ 573 extern t_stat cpu_ss_inhibit; /* simulation stop inhibition mask */ 574 extern t_stat cpu_ss_ioerr; /* status return for an unreported I/O error */ 575 extern UNIT *cpu_ioerr_uptr; /* pointer to a unit with an unreported I/O error */ 576 577 extern uint32 cpu_speed; /* the CPU speed, expressed as a multiplier of a real machine */ 578 extern uint32 cpu_pending_interrupt; /* the select code of a pending interrupt or zero if none */ 579 580 581 /* Microcode dispatcher functions (grouped by cpu module number) */ 582 583 extern t_stat cpu_uig_0 (uint32 intrq, t_bool int_ack); /* [0] UIG group 0 dispatcher */ 584 extern t_stat cpu_uig_1 (uint32 intrq); /* [0] UIG group 1 dispatcher */ 585 extern t_stat cpu_ds (void); /* [0] Distributed System stub */ 586 extern t_stat cpu_user (void); /* [0] User firmware dispatcher */ 587 588 extern t_stat cpu_eau (void); /* [1] EAU group simulator */ 589 extern t_stat cpu_iop (uint32 intrq); /* [1] 2000 I/O Processor */ 590 591 #if !defined (HAVE_INT64) /* int64 support unavailable */ 592 extern t_stat cpu_fp (void); /* [1] Firmware Floating Point */ 593 #endif 594 595 extern t_stat cpu_dms (uint32 intrq); /* [2] Dynamic mapping system */ 596 extern t_stat cpu_eig (HP_WORD IR, uint32 intrq); /* [2] Extended instruction group */ 597 598 extern t_stat cpu_ffp (uint32 intrq); /* [3] Fast FORTRAN Processor */ 599 extern t_stat cpu_dbi (HP_WORD IR); /* [3] Double-Integer instructions */ 600 601 #if defined (HAVE_INT64) /* int64 support available */ 602 extern t_stat cpu_fpp (HP_WORD IR); /* [4] Floating Point Processor */ 603 extern t_stat cpu_sis (HP_WORD IR); /* [4] Scientific Instruction Set */ 604 #endif 605 606 extern t_stat cpu_rte_ema (void); /* [5] RTE-IV EMA */ 607 extern t_stat cpu_signal (void); /* [5] SIGNAL/1000 Instructions */ 608 609 #if defined (HAVE_INT64) /* int64 support available */ 610 extern t_stat cpu_vis (void); /* [5] Vector Instruction Set */ 611 #endif 612 613 extern t_stat cpu_rte_os (t_bool int_ack); /* [6] RTE-6 OS */ 614 615 extern t_stat cpu_rte_vma (void); /* [7] RTE-6 VMA */ 616 617 618 /* Microcode helper functions */ 619 620 extern OP ReadOp (HP_WORD va, OPSIZE precision); /* generalized operand read */ 621 extern void WriteOp (HP_WORD va, OP operand, OPSIZE precision); /* generalized operand write */ 622 extern t_stat cpu_ops (OP_PAT pattern, OPS op); /* operand processor */ 623 624 625 /* CPU global SCP support routine declarations declared in scp.h 626 627 extern t_stat sim_instr (void); 628 */ 629 630 631 /* CPU global SCP support routine declarations */ 632 633 extern void cpu_post_cmd (t_bool from_scp); 634 635 636 /* CPU global utility routine declarations */ 637 638 extern t_stat cpu_iog (HP_WORD instruction); 639 extern t_stat cpu_resolve_indirects (t_bool is_interruptible); 640 extern void cpu_microcode_abort (MICRO_ABORT abort_reason); 641 642 643 /* I/O subsystem global utility routine declarations */ 644 645 extern uint32 io_poll_interrupts (FLIP_FLOP interrupt_system); 646