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