1 /* hp2100_cpu1.h: HP 2100/1000 firmware dispatcher definitions
2 
3    Copyright (c) 2006-2008, J. David Bryan
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    THE AUTHOR 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 
22    Except as contained in this notice, the name of the author shall not
23    be used in advertising or otherwise to promote the sale, use or other dealings
24    in this Software without prior written authorization from the author.
25 
26    11-Sep-08    JDB     Moved microcode function prototypes here
27    30-Apr-08    JDB     Corrected OP_AFF to OP_AAFF for SIGNAL/1000
28                         Removed unused operand patterns
29    23-Feb-08    HV      Added more OP_* for SIGNAL/1000 and VIS
30    28-Nov-07    JDB     Added fprint_ops, fprint_regs for debug printouts
31    19-Oct-07    JDB     Revised OP_KKKAKK operand profile to OP_CCCACC for $LOC
32    16-Oct-06    JDB     Generalized operands for F-Series FP types
33    26-Sep-06    JDB     Split from hp2100_cpu1.c
34 */
35 
36 #ifndef _HP2100_CPU1_H_
37 #define _HP2100_CPU1_H_
38 
39 
40 /* Register print encoding */
41 
42 #define REG_COUNT       9                               /* count of print flags */
43 
44 #define REG_CIR         (1 << 0)                        /* print central interrupt register */
45 #define REG_A           (1 << 1)                        /* print A register */
46 #define REG_B           (1 << 2)                        /* print B register */
47 #define REG_E           (1 << 3)                        /* print E register */
48 #define REG_X           (1 << 4)                        /* print X register */
49 #define REG_Y           (1 << 5)                        /* print Y register */
50 #define REG_O           (1 << 6)                        /* print O register */
51 #define REG_P           (1 << 7)                        /* print P register */
52 #define REG_P_REL       (1 << 8)                        /* print P register as relative */
53 
54 
55 /* Operand processing encoding */
56 
57 /* Base operand types.  Note that all address encodings must be grouped together
58    after OP_ADR.
59 */
60 
61 #define OP_NUL          0                               /* no operand */
62 #define OP_IAR          1                               /* 1-word int in A reg */
63 #define OP_JAB          2                               /* 2-word int in A/B regs */
64 #define OP_FAB          3                               /* 2-word FP const in A/B regs */
65 #define OP_CON          4                               /* inline 1-word constant */
66 #define OP_VAR          5                               /* inline 1-word variable */
67 
68 #define OP_ADR          6                               /* inline address */
69 #define OP_ADK          7                               /* addr of 1-word int const */
70 #define OP_ADD          8                               /* addr of 2-word int const */
71 #define OP_ADF          9                               /* addr of 2-word FP const */
72 #define OP_ADX         10                               /* addr of 3-word FP const */
73 #define OP_ADT         11                               /* addr of 4-word FP const */
74 #define OP_ADE         12                               /* addr of 5-word FP const */
75 
76 #define OP_N_FLAGS      4                               /* number of bits needed for flags */
77 #define OP_M_FLAGS      ((1 << OP_N_FLAGS) - 1)         /* mask for flag bits */
78 
79 #define OP_N_F          (8 * sizeof (uint32) / OP_N_FLAGS)  /* max number of op fields */
80 
81 #define OP_V_F1         (0 * OP_N_FLAGS)                /* 1st operand field */
82 #define OP_V_F2         (1 * OP_N_FLAGS)                /* 2nd operand field */
83 #define OP_V_F3         (2 * OP_N_FLAGS)                /* 3rd operand field */
84 #define OP_V_F4         (3 * OP_N_FLAGS)                /* 4th operand field */
85 #define OP_V_F5         (4 * OP_N_FLAGS)                /* 5th operand field */
86 #define OP_V_F6         (5 * OP_N_FLAGS)                /* 6th operand field */
87 #define OP_V_F7         (6 * OP_N_FLAGS)                /* 7th operand field */
88 #define OP_V_F8         (7 * OP_N_FLAGS)                /* 8th operand field */
89 
90 /* Operand processing patterns */
91 
92 #define OP_N            (OP_NUL << OP_V_F1)
93 #define OP_I            (OP_IAR << OP_V_F1)
94 #define OP_J            (OP_JAB << OP_V_F1)
95 #define OP_R            (OP_FAB << OP_V_F1)
96 #define OP_C            (OP_CON << OP_V_F1)
97 #define OP_V            (OP_VAR << OP_V_F1)
98 #define OP_A            (OP_ADR << OP_V_F1)
99 #define OP_K            (OP_ADK << OP_V_F1)
100 #define OP_D            (OP_ADD << OP_V_F1)
101 #define OP_X            (OP_ADX << OP_V_F1)
102 #define OP_T            (OP_ADT << OP_V_F1)
103 #define OP_E            (OP_ADE << OP_V_F1)
104 
105 #define OP_IA           ((OP_IAR << OP_V_F1) | (OP_ADR << OP_V_F2))
106 #define OP_JA           ((OP_JAB << OP_V_F1) | (OP_ADR << OP_V_F2))
107 #define OP_JD           ((OP_JAB << OP_V_F1) | (OP_ADD << OP_V_F2))
108 #define OP_RC           ((OP_FAB << OP_V_F1) | (OP_CON << OP_V_F2))
109 #define OP_RK           ((OP_FAB << OP_V_F1) | (OP_ADK << OP_V_F2))
110 #define OP_RF           ((OP_FAB << OP_V_F1) | (OP_ADF << OP_V_F2))
111 #define OP_CV           ((OP_CON << OP_V_F1) | (OP_VAR << OP_V_F2))
112 #define OP_AC           ((OP_ADR << OP_V_F1) | (OP_CON << OP_V_F2))
113 #define OP_AA           ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2))
114 #define OP_AK           ((OP_ADR << OP_V_F1) | (OP_ADK << OP_V_F2))
115 #define OP_AX           ((OP_ADR << OP_V_F1) | (OP_ADX << OP_V_F2))
116 #define OP_AT           ((OP_ADR << OP_V_F1) | (OP_ADT << OP_V_F2))
117 #define OP_KV           ((OP_ADK << OP_V_F1) | (OP_VAR << OP_V_F2))
118 #define OP_KA           ((OP_ADK << OP_V_F1) | (OP_ADR << OP_V_F2))
119 #define OP_KK           ((OP_ADK << OP_V_F1) | (OP_ADK << OP_V_F2))
120 
121 #define OP_IIF          ((OP_IAR << OP_V_F1) | (OP_IAR << OP_V_F2) | \
122                          (OP_ADF << OP_V_F3))
123 
124 #define OP_IAT          ((OP_IAR << OP_V_F1) | (OP_ADR << OP_V_F2) | \
125                          (OP_ADT << OP_V_F3))
126 
127 #define OP_CVA          ((OP_CON << OP_V_F1) | (OP_VAR << OP_V_F2) | \
128                          (OP_ADR << OP_V_F3))
129 
130 #define OP_AAA          ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \
131                          (OP_ADR << OP_V_F3))
132 
133 #define OP_AAF          ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \
134                          (OP_ADF << OP_V_F3))
135 
136 #define OP_AAX          ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \
137                          (OP_ADX << OP_V_F3))
138 
139 #define OP_AAT          ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \
140                          (OP_ADT << OP_V_F3))
141 
142 #define OP_AKA          ((OP_ADR << OP_V_F1) | (OP_ADK << OP_V_F2) | \
143                          (OP_ADR << OP_V_F3))
144 
145 #define OP_AKK          ((OP_ADR << OP_V_F1) | (OP_ADK << OP_V_F2) | \
146                          (OP_ADK << OP_V_F3))
147 
148 #define OP_AXX          ((OP_ADR << OP_V_F1) | (OP_ADX << OP_V_F2) | \
149                          (OP_ADX << OP_V_F3))
150 
151 #define OP_ATT          ((OP_ADR << OP_V_F1) | (OP_ADT << OP_V_F2) | \
152                          (OP_ADT << OP_V_F3))
153 
154 #define OP_AEE          ((OP_ADR << OP_V_F1) | (OP_ADE << OP_V_F2) | \
155                          (OP_ADE << OP_V_F3))
156 
157 #define OP_AAXX         ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \
158                          (OP_ADX << OP_V_F3) | (OP_ADX << OP_V_F4))
159 
160 #define OP_AAFF         ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \
161                          (OP_ADF << OP_V_F3) | (OP_ADF << OP_V_F4))
162 
163 #define OP_AAKK         ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \
164                          (OP_ADK << OP_V_F3) | (OP_ADK << OP_V_F4))
165 
166 #define OP_KKKK         ((OP_ADK << OP_V_F1) | (OP_ADK << OP_V_F2) | \
167                          (OP_ADK << OP_V_F3) | (OP_ADK << OP_V_F4))
168 
169 #define OP_AAAKK        ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \
170                          (OP_ADR << OP_V_F3) | (OP_ADK << OP_V_F4) | \
171                          (OP_ADK << OP_V_F5))
172 
173 #define OP_AKAKK        ((OP_ADR << OP_V_F1) | (OP_ADK << OP_V_F2) | \
174                          (OP_ADR << OP_V_F3) | (OP_ADK << OP_V_F4) | \
175                          (OP_ADK << OP_V_F5))
176 
177 #define OP_AAACCC       ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \
178                          (OP_ADR << OP_V_F3) | (OP_CON << OP_V_F4) | \
179                          (OP_CON << OP_V_F5) | (OP_CON << OP_V_F6))
180 
181 #define OP_AAFFKK       ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \
182                          (OP_ADF << OP_V_F3) | (OP_ADF << OP_V_F4) | \
183                          (OP_ADK << OP_V_F5) | (OP_ADK << OP_V_F6))
184 
185 #define OP_AAKAKK       ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \
186                          (OP_ADK << OP_V_F3) | (OP_ADR << OP_V_F4) | \
187                          (OP_ADK << OP_V_F5) | (OP_ADK << OP_V_F6))
188 
189 #define OP_CATAKK       ((OP_CON << OP_V_F1) | (OP_ADR << OP_V_F2) | \
190                          (OP_ADT << OP_V_F3) | (OP_ADR << OP_V_F4) | \
191                          (OP_ADK << OP_V_F5) | (OP_ADK << OP_V_F6))
192 
193 #define OP_CCCACC       ((OP_CON << OP_V_F1) | (OP_CON << OP_V_F2) | \
194                          (OP_CON << OP_V_F3) | (OP_ADR << OP_V_F4) | \
195                          (OP_CON << OP_V_F5) | (OP_CON << OP_V_F6))
196 
197 #define OP_AAAFFKK      ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \
198                          (OP_ADR << OP_V_F3) | (OP_ADF << OP_V_F4) | \
199                          (OP_ADF << OP_V_F5) | (OP_ADK << OP_V_F6) | \
200                          (OP_ADK << OP_V_F7))
201 
202 #define OP_AKAKAKK      ((OP_ADR << OP_V_F1) | (OP_ADK << OP_V_F2) | \
203                          (OP_ADR << OP_V_F3) | (OP_ADK << OP_V_F4) | \
204                          (OP_ADR << OP_V_F5) | (OP_ADK << OP_V_F6) | \
205                          (OP_ADK << OP_V_F7))
206 
207 #define OP_AAKAKAKK     ((OP_ADR << OP_V_F1) | (OP_ADR << OP_V_F2) | \
208                          (OP_ADK << OP_V_F3) | (OP_ADR << OP_V_F4) | \
209                          (OP_ADK << OP_V_F5) | (OP_ADR << OP_V_F6) | \
210                          (OP_ADK << OP_V_F7) | (OP_ADK << OP_V_F8))
211 
212 #define OP_CCACACCA     ((OP_CON << OP_V_F1) | (OP_CON << OP_V_F2) | \
213                          (OP_ADR << OP_V_F3) | (OP_CON << OP_V_F4) | \
214                          (OP_ADR << OP_V_F5) | (OP_CON << OP_V_F6) | \
215                          (OP_CON << OP_V_F7) | (OP_ADR << OP_V_F8))
216 
217 
218 /* Operand precisions (compatible with F-Series FPP):
219 
220     - S = 1-word integer
221     - D = 2-word integer
222     - F = 2-word single-precision floating-point
223     - X = 3-word extended-precision floating-point
224     - T = 4-word double-precision floating-point
225     - E = 5-word expanded-exponent floating-point
226     - A = null operand (operand is in FPP accumulator)
227 
228    5-word floating-point numbers are supported by the F-Series Floating-Point
229    Processor hardware, but the instruction codes are not documented.
230 
231    Note that ordering is important, as we depend on the "fp" type codes to
232    reflect the number of words needed.
233 */
234 
235 typedef enum { in_s, in_d, fp_f, fp_x, fp_t, fp_e, fp_a } OPSIZE;
236 
237 
238 /* Conversion from operand size to word count */
239 
240 #define TO_COUNT(s)     ((s == fp_a) ? 0 : (uint32) (s + (s < fp_f)))
241 
242 
243 /* HP in-memory representation of a packed floating-point number.
244    Actual value will use two, three, four, or five words, as needed.
245 */
246 
247 typedef uint16 FPK[5];
248 
249 
250 /* Operand processing types.
251 
252    NOTE: Microsoft VC++ 6.0 does not support the C99 standard, so we cannot
253    initialize unions by arbitrary variant ("designated initializers").
254    Therefore, we follow the C90 form of initializing via the first named
255    variant.  The FPK variant must appear first in the OP structure, as we define
256    a number of FPK constants in other modules.
257 */
258 
259 typedef union {                                         /* general operand */
260     FPK fpk;                                            /* floating-point value */
261     uint16 word;                                        /* 16-bit integer */
262     uint32 dword;                                       /* 32-bit integer */
263     } OP;
264 
265 typedef OP OPS[OP_N_F];                                 /* operand array */
266 
267 typedef uint32 OP_PAT;                                  /* operand pattern */
268 
269 
270 /* Microcode dispatcher functions (grouped by cpu module number) */
271 
272 extern t_stat cpu_ds      (uint32 IR, uint32 intrq);                /* [0] Distributed System stub */
273 extern t_stat cpu_user    (uint32 IR, uint32 intrq);                /* [0] User firmware dispatcher */
274 extern t_stat cpu_user_20 (uint32 IR, uint32 intrq);                /* [0] Module 20 user microprograms stub */
275 
276 extern t_stat cpu_eau   (uint32 IR, uint32 intrq);                  /* [1] EAU group simulator */
277 extern t_stat cpu_uig_0 (uint32 IR, uint32 intrq, uint32 iotrap);   /* [1] UIG group 0 dispatcher */
278 extern t_stat cpu_uig_1 (uint32 IR, uint32 intrq, uint32 iotrap);   /* [1] UIG group 1 dispatcher */
279 
280 #if !defined (HAVE_INT64)                                           /* int64 support unavailable */
281 extern t_stat cpu_fp  (uint32 IR, uint32 intrq);                    /* [2] Firmware Floating Point */
282 #endif
283 extern t_stat cpu_dms (uint32 IR, uint32 intrq);                    /* [2] Dynamic mapping system */
284 extern t_stat cpu_eig (uint32 IR, uint32 intrq);                    /* [2] Extended instruction group */
285 extern t_stat cpu_iop (uint32 IR, uint32 intrq);                    /* [2] 2000 I/O Processor */
286 
287 extern t_stat cpu_ffp (uint32 IR, uint32 intrq);                    /* [3] Fast FORTRAN Processor */
288 extern t_stat cpu_dbi (uint32 IR, uint32 intrq);                    /* [3] Double-Integer instructions */
289 
290 #if defined (HAVE_INT64)                                            /* int64 support available */
291 extern t_stat cpu_fpp (uint32 IR, uint32 intrq);                    /* [4] Floating Point Processor */
292 extern t_stat cpu_sis (uint32 IR, uint32 intrq);                    /* [4] Scientific Instruction Set */
293 #endif
294 
295 extern t_stat cpu_rte_vma (uint32 IR, uint32 intrq);                /* [5] RTE-6 VMA */
296 extern t_stat cpu_rte_ema (uint32 IR, uint32 intrq);                /* [5] RTE-IV EMA */
297 
298 extern t_stat cpu_rte_os (uint32 IR, uint32 intrq, uint32 iotrap);  /* [6] RTE-6 OS */
299 
300 #if defined (HAVE_INT64)                                            /* int64 support available */
301 extern t_stat cpu_vis    (uint32 IR, uint32 intrq);                 /* [7] Vector Instruction Set */
302 extern t_stat cpu_signal (uint32 IR, uint32 intrq);                 /* [7] SIGNAL/1000 Instructions */
303 #endif
304 
305 
306 /* Microcode helper functions */
307 
308 OP     ReadOp  (uint32 va, OPSIZE precision);               /* generalized operand read */
309 void   WriteOp (uint32 va, OP operand, OPSIZE precision);   /* generalized operand write */
310 t_stat cpu_ops (OP_PAT pattern, OPS op, uint32 irq);        /* operand processor */
311 
312 void fprint_ops (OP_PAT pattern, OPS op);                   /* debug print operands */
313 void fprint_regs (char *caption, uint32 regs, uint32 base); /* debug print CPU registers */
314 
315 #endif
316