First Commit of my working state
[simh.git] / NOVA / eclipse_cpu.c
CommitLineData
196ba1fc
PH
1/* eclipse_cpu.c: Eclipse CPU simulator\r
2\r
3 Modified from the original NOVA simulator by Robert Supnik.\r
4\r
5 Copyright (c) 1998-2006, Charles E Owen\r
6 Portions Copyright (c) 1993-2002, Robert M Supnik\r
7\r
8 Permission is hereby granted, free of charge, to any person obtaining a\r
9 copy of this software and associated documentation files (the "Software"),\r
10 to deal in the Software without restriction, including without limitation\r
11 the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
12 and/or sell copies of the Software, and to permit persons to whom the\r
13 Software is furnished to do so, subject to the following conditions:\r
14\r
15 The above copyright notice and this permission notice shall be included in\r
16 all copies or substantial portions of the Software.\r
17\r
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\r
21 ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
22 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
23 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
24\r
25 Except as contained in this notice, the name of Robert M Supnik shall not be\r
26 used in advertising or otherwise to promote the sale, use or other dealings\r
27 in this Software without prior written authorization from Robert M Supnik.\r
28\r
29 cpu Eclipse central processor\r
30\r
31 07-Jun-06 RMS Fixed bug in DIVS (found by Mark Hittinger)\r
32 22-Sep-05 RMS Fixed declarations (from Sterling Garwood)\r
33 25-Aug-05 RMS Fixed DIVS overflow cases\r
34 29-Nov-03 CEO Corrected POPJ and Bit operations bugs\r
35 26-Nov-03 CEO Added FPU and PIT devices \r
36 20-Feb-03 CEO Corrected several MMPU and CIS bugs\r
37 28-Jan-02 RMS Cleaned up compiler warnings\r
38 30-Nov-01 RMS Added extended SET/SHOW support\r
39 01-Jun-01 RMS Added second terminal, plotter support\r
40 26-Apr-01 RMS Added device enable/disable support\r
41\r
42 The register state for the Eclipse CPU is basically the same as\r
43 the NOVA's:\r
44\r
45 AC[0:3]<0:15> general registers\r
46 C carry flag\r
47 PC<0:14> program counter\r
48\r
49 Eclipses with Folating Point Units added these registers:\r
50\r
51 FPAC[0:3]<0:63> Floating Point Accumulators\r
52 FPSR Floating Point Status Register\r
53\r
54 In addition, certain low-memory locations are reserved for special\r
55 purposes:\r
56 \r
57 0: I/O Return Address (from an interrupt)\r
58 1: I/O (Interrupt) handler address\r
59 2: System Call handler address (used by SYC instruction)\r
60 3: Protection Fault handler address\r
61 4: VECTOR stack pointer (VCT Instruction)\r
62 5: Current Interrupt Priority mask\r
63 6: VECTOR stack limit (VCT instruction)\r
64 7: VECTOR stack fault address (VCT again)\r
65 10: Block Pointer (later models only)\r
66 11: Emulation Trap Handler address (microeclipse only)\r
67 20-27: Auto-increment locations (not on microeclipse)\r
68 30-37: Auto-decrement locations (not on microeclipse)\r
69 40: Stack pointer\r
70 41: Frame Pointer\r
71 42: Stack Limit\r
72 43: Stack fault address\r
73 44: XOP Origin address\r
74 45: Floating point fault address\r
75 46: Commercial fault address (not on microeclipse)\r
76 47: Reserved, do not use. \r
77 \r
78 Note: While all eclipses share most of the "standard" features,\r
79 some models added a few quirks and wrinkles, and other models\r
80 dropped some features or modified others. Most DG software\r
81 is written for a "standard" Eclipse, and avoids these problem\r
82 areas. A general overview:\r
83\r
84 [subject to major changes as info becomes available!]\r
85 \r
86 Early (e.g. S/100, S/200, C/300) [Front Panel machines]\r
87 \r
88 The first Eclipses had the basic MAP, but certain parts\r
89 were kluged, and these were fixed in later MAP designs.\r
90 The original mapping hardware was termed MAP for Memory \r
91 Allocate and Protection. The later design was termed \r
92 MMPU for Memory Mapping and Protection Unit. While\r
93 similar in design, the two units are not compatible.\r
94 Also, the C version (C for Commercial) of these early\r
95 CPUs had a feature called "Commercial Instruction Set"\r
96 which contained character manipulation, translation\r
97 between commercial-format numeric data and FPU formats,\r
98 and an elaborate EDIT instruction. Later models kept\r
99 only the character manipulation part of this and called\r
100 the feature the "Character Instruction Set", leading to\r
101 confusion because the initials of both are CIS. ARDOS\r
102 is the only DG operating system to support the older \r
103 MAP. ZRDOS uses the MMPU, and AOS supports only MMPU.\r
104\r
105 Middle (e.g. S/130, C/150, S/230, C/330) [Front Panel]\r
106 \r
107 These are close to a "Standard". They have the newer,\r
108 fixed MMPU. Support for the PIT (Programmed Interval\r
109 Timer. The Commercial (not character) instruction set\r
110 and FPU are optional. (CIS standard on C models)\r
111 \r
112 Late (C/350, M/600: [Panel]; S/140, S/280 [Virtual Console]) \r
113 \r
114 All features of the Middle period are included, plus:\r
115 These late Eclipses added a few MMPU wrinkles all their\r
116 own, included support for user maps C and D. Character\r
117 instruction set is standard, FPU optional. Also, support\r
118 for the BMC device.\r
119\r
120 MicroEclipse-based (S/20, S/120, Desktops) [Virtual cons.]\r
121 \r
122 All features of the Late period, in general, plus:\r
123 Microeclipses dropped support for the auto increment\r
124 and decrement locations at 20-37. They also added \r
125 support for invalid instruction traps thru location 11.\r
126 The Desktops have an interface to the "Attached Processor",\r
127 an 8086, at device code 6. Also, some new CPU device\r
128 features to read states info. The Character Instruction\r
129 set and FPU are standard on all models.\r
130 \r
131 The Eclipse instruction set is an elaboration of the NOVA's. The basic\r
132 NOVA set is implemented in it's entireity, plus many new Eclipse\r
133 instructions are added. Since in theory every possible 16-bit \r
134 combination is a NOVA instruction, the Eclipse commands are carved\r
135 out of the NOVA set by using the Operate format with the no-load bit\r
136 set to 1 and the skip bits set to 000. Since this combination is\r
137 in effect a no-op on the NOVA, it was rarely or never used. The \r
138 other bits are used to form Eclipse instructions, which have no\r
139 other common format. To see the instructions, refer to the Eclipse\r
140 section of the instruction decode logic in sim_instr() below. All\r
141 Eclipse instructions are checked first, so in case of conflict in\r
142 bit patterns, the Eclipse one is executed over the corresponding\r
143 NOVA pattern. A bizarre exception is LEF mode...which implements\r
144 an instruction called Load Effective Address by taking over the\r
145 Nova I/O format when the LEF mode bit is set and the processor is\r
146 executing in mapped mode.\r
147 \r
148 The following discussion talks about NOVA instructions which are\r
149 Eclipse instructions also.\r
150 \r
151 The NOVA has three instruction formats: memory reference, I/O transfer,\r
152 and operate. The memory reference format is:\r
153\r
154 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\r
155 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\r
156 | 0| op | AC |in| mode| displacement | memory reference\r
157 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\r
158\r
159 <0:4> mnemonic action\r
160\r
161 00000 JMP PC = MA\r
162 00001 JMS AC3 = PC, PC = MA\r
163 00010 ISZ M[MA] = M[MA] + 1, skip if M[MA] == 0\r
164 00011 DSZ M[MA] = M[MA] - 1, skip if M[MA] == 0\r
165 001'n LDA ACn = M[MA]\r
166 010'n STA M[MA] = ACn\r
167\r
168 <5:7> mode action\r
169\r
170 000 page zero direct MA = zext (IR<8:15>)\r
171 001 PC relative direct MA = PC + sext (IR<8:15>)\r
172 010 AC2 relative direct MA = AC2 + sext (IR<8:15>)\r
173 011 AC3 relative direct MA = AC3 + sext (IR<8:15>)\r
174 100 page zero indirect MA = M[zext (IR<8:15>)]\r
175 101 PC relative dinirect MA = M[PC + sext (IR<8:15>)]\r
176 110 AC2 relative indirect MA = M[AC2 + sext (IR<8:15>)]\r
177 111 AC3 relative indirect MA = M[AC3 + sext (IR<8:15>)]\r
178\r
179 Memory reference instructions can access an address space of 32K words.\r
180 An instruction can directly reference the first 256 words of memory\r
181 (called page zero), as well as 256 words relative to the PC, AC2, or\r
182 AC3; it can indirectly access all 32K words. If an indirect address\r
183 is in locations 00020-00027, the indirect address is incremented and\r
184 rewritten to memory before use; if in 00030-00037, decremented and\r
185 rewritten.\r
186\r
187 The I/O transfer format is:\r
188\r
189 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\r
190 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\r
191 | 0 1 1| AC | opcode |pulse| device | I/O transfer\r
192 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\r
193\r
194 The IOT instruction sends the opcode, pulse, and specified AC to the\r
195 specified I/O device. The device may accept data, provide data,\r
196 initiate or cancel operations, or skip on status.\r
197\r
198 The operate format is:\r
199\r
200 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\r
201 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\r
202 | 1|srcAC|dstAC| opcode |shift|carry|nl| skip | operate\r
203 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\r
204 \______/ \___/ \___/ | | | |\r
205 | | | | | | +--- reverse skip sense\r
206 | | | | | +--- skip if C == 0\r
207 | | | | +--- skip if result == 0\r
208 | | | +--- don't load result\r
209 | | +--- carry in (load as is,\r
210 | | set to Zero,\r
211 | | set to One,\r
212 | | load Complement)\r
213 | +--- shift (none,\r
214 | left one,\r
215 | right one,\r
216 | byte swap)\r
217 +--- operation (complement,\r
218 negate,\r
219 move,\r
220 increment,\r
221 add complement,\r
222 subtract,\r
223 add,\r
224 and)\r
225\r
226 The operate instruction can be microprogrammed to perform operations\r
227 on the source and destination AC's and the Carry flag.\r
228\r
229 This routine is the instruction decode routine for the NOVA.\r
230 It is called from the simulator control program to execute\r
231 instructions in simulated memory, starting at the simulated PC.\r
232 It runs until 'reason' is set non-zero.\r
233\r
234 General notes:\r
235\r
236 1. Reasons to stop. The simulator can be stopped by:\r
237\r
238 HALT instruction\r
239 breakpoint encountered\r
240 infinite indirection loop\r
241 unknown I/O device and STOP_DEV flag set\r
242 I/O error in I/O simulator\r
243\r
244 2. Interrupts. Interrupts are maintained by four parallel variables:\r
245\r
246 dev_done device done flags\r
247 dev_disable device interrupt disable flags\r
248 dev_busy device busy flags\r
249 int_req interrupt requests\r
250\r
251 In addition, int_req contains the interrupt enable and ION pending\r
252 flags. If ION and ION pending are set, and at least one interrupt\r
253 request is pending, then an interrupt occurs. Note that the 16b PIO\r
254 mask must be mapped to the simulator's device bit mapping.\r
255 \r
256 3. Non-existent memory. On the NOVA, reads to non-existent memory\r
257 return zero, and writes are ignored. In the simulator, the\r
258 largest possible memory is instantiated and initialized to zero.\r
259 Thus, only writes need be checked against actual memory size.\r
260\r
261 4. Adding I/O devices. These modules must be modified:\r
262\r
263 eclipse_defs.h add interrupt request definition\r
264 eclipse_cpu.c add IOT mask, PI mask, and routine to dev_table\r
265 eclipse_sys.c add pointer to data structures to sim_devices\r
266*/\r
267\r
268/*---------------------------------------------------------------------------\r
269** ECLIPSE Debugging Facilities\r
270**\r
271** These options are designed to find hard-to-locate flaky bugs by\r
272** providing special error checking and logging.\r
273**\r
274** All are controlled by depositing a value into the DEBUG register.\r
275** A value of zero means no special debugging facilities are turned on.\r
276** This is the default. Debugging invokes a performance hit! Use only\r
277** when necessary. \r
278**\r
279** Debugging means logging information to a file, or to a buffer in\r
280** memory from whence it can be dumped to a file.\r
281** \r
282** 1XXXXX = Log all instructions executed to file "trace.log". \r
283** **CAUTION**: This means the CPU will run SLOWLY and\r
284** the resulting trace.log file will be HUGE. We're talking\r
285** about a megabyte for each 5 seconds or less of wall clock \r
286** time, depending on the speed of your CPU. Note: In this\r
287** mode, interrupts are logged when they are received also.\r
288**\r
289** Note: when detailed logging is off, the last 4096 or so\r
290** instructions executed are saved in a memory buffer, and\r
291** when the sim stops, the "show" command can write this \r
292** history information to the file "history.log". This only\r
293** works if the DEBUG register is non-zero however, because\r
294** of the performance hit even this recording makes. To \r
295** dump history, enter the command "show cpu history", with\r
296** the file "history" spelled correctly and lower case.\r
297**\r
298** XXXXDD = Log all I/O instructions to or from device number\r
299** DD. Log is written to "trace.log", regardless of the\r
300** setting of the instruction trace flag (1XXXXX). If both\r
301** are on, the device traces will be interpersed with the\r
302** instruction traces -- very useful sometimes. \r
303**\r
304** XXX1DD = Device Break. Does a breakpoint in any I/O to\r
305** device DD. Useful, say when a diagnostic gives an \r
306** error message - a device break on 11 (TTO) will stop\r
307** as soon as the error message appears, making the \r
308** trace log much shorter to track back on.\r
309**\r
310** X4XXXX = When this bit is on, the sim will stop if it sees\r
311** an invalid instruction. When DEBUG is zero, any such\r
312** instruction is no-oped with no warning. When DEBUG is\r
313** non-zero, but this bit is 0, a warning will be displayed\r
314** but execution will continue.\r
315**\r
316** X2XXXX = LEF break. When A LEF instruction is executed in\r
317** mapped user space, the sim does a breakpoint right after\r
318** executing the instruction.\r
319**\r
320** Whenever the DEBUG register is non-zero, special error checking\r
321** is enabled in the sim. This will stop the sim automatically \r
322** when a likely error occurs, such as:\r
323**\r
324** 1. Any execution that reaches, or will reach, location 00000.\r
325** 2. Any I/O to device 00\r
326** 3. An interrupt from device 00.\r
327** 4. An invalid instruction (stop is optional)\r
328**\r
329** DCHAR Register: Whenever this is non-zero, a test is made on every\r
330** character output to the TTO device (master console). If the character\r
331** output to that device matches this register, the CPU will break.\r
332**\r
333** Of course, the standard BREAK register is available for breakpoints\r
334** as in all the sims based on this standard.\r
335--------------------------------------------------------------------------*/\r
336\r
337#include "nova_defs.h"\r
338\r
339#define UNIT_V_MICRO (UNIT_V_UF) /* Microeclipse? */\r
340#define UNIT_V_17B (UNIT_V_UF) /* 17 bit MAP */\r
341#define UNIT_V_UP (UNIT_V_UF) /* FPU Enabled */\r
342#define UNIT_V_MSIZE (UNIT_V_UF+1) /* dummy mask */\r
343#define UNIT_MICRO (1 << UNIT_V_MICRO)\r
344#define UNIT_17B (1 << UNIT_V_17B)\r
345#define UNIT_UP (1 << UNIT_V_UP)\r
346#define UNIT_MSIZE (1 << UNIT_V_MSIZE)\r
347\r
348uint16 M[MAXMEMSIZE] = { 0 }; /* memory */\r
349int32 AC[4] = { 0 }; /* accumulators */\r
350int32 C = 0; /* carry flag */\r
351int32 saved_PC = 0; /* program counter */\r
352int32 SR = 0; /* switch register */\r
353int32 dev_done = 0; /* device done flags */\r
354int32 dev_busy = 0; /* device busy flags */\r
355int32 dev_disable = 0; /* int disable flags */\r
356int32 iot_enb = -1; /* IOT enables */\r
357int32 int_req = 0; /* interrupt requests */\r
358int32 pimask = 0; /* priority int mask */\r
359int32 pwr_low = 0; /* power fail flag */\r
360int32 ind_max = 15; /* iadr nest limit */\r
361int32 stop_dev = 0; /* stop on ill dev */\r
362int32 old_PC = 0; /* previous PC */\r
363int32 model = 140; /* Model of Eclipse */\r
364int32 speed = 0; /* Delay for each instruction */\r
365\r
366int32 XCT_mode = 0; /* 1 if XCT mode */\r
367int32 XCT_inst = 0; /* XCT instruction */\r
368int32 PPC = -1;\r
369int32 AMASK = 077777;\r
370\r
371struct ndev dev_table[64]; /* dispatch table */\r
372\r
373/* Instruction history buffer */\r
374\r
375#define HISTMAX 4096\r
376\r
377int32 hnext = 0; /* # of current entry */\r
378int32 hwrap = 0; /* 1 if wrapped */\r
379int32 hmax = HISTMAX; /* Maximum entries b4 wrap */\r
380uint16 hpc[HISTMAX];\r
381uint16 hinst[HISTMAX];\r
382uint16 hinst2[HISTMAX];\r
383uint16 hac0[HISTMAX];\r
384uint16 hac1[HISTMAX];\r
385uint16 hac2[HISTMAX];\r
386uint16 hac3[HISTMAX];\r
387unsigned short hflags[HISTMAX];\r
388\r
389/* Flags: 0x01 - carry bit\r
390 0x02 - int enabled\r
391 0x04 - user map a\r
392 0x08 - user map b\r
393 0x10 - user map c\r
394 0x20 - user map d\r
395 0x40 - LEF mode was on\r
396 0x80 - this is an int, not an inst.\r
397 hpc is return addr\r
398 hinst is int_req\r
399 hac0 is device\r
400 hac1 is int addr\r
401*/\r
402 \r
403\r
404\r
405/* the Eclipse MAP unit: This unit is standard in all Eclipse processors\r
406 except for the "original" Eclipses, the S/100, S/200, and C/300. These\r
407 use a different and more elaborate MMPU that is not compatible with\r
408 the one simulated here. All subsequent Eclipses, from the S/130 on up\r
409 to the last models S/280 and C/380 use the map simulated here, including\r
410 the MicroEclipses. There are model-dependent quirks. That's why we\r
411 have to MODEL register.\r
412\r
413 The programming of the MMPU can be found in the LMP instruction, below,\r
414 and in the instructions directed to DEV_MAP.\r
415 \r
416 There are two user maps, called A and B, and four data channel maps,\r
417 A thru D. They can be enabled/disabled separately. Some models have\r
418 two extra user maps, C and D. These are supported where apporpriate. \r
419 \r
420*/\r
421\r
422#define PAGEMASK 01777 /* Largest physical page possible */\r
423#define MAPMASK 0101777 /* Valid page bits in map */\r
424#define INVALID 0101777 /* Mask indicating an invalid page */\r
425int32 MapStat = 0; /* Map status register */\r
426int32 Inhibit = 0; /* !0=inhibit interrupts : */\r
427 /* 1 = single cycle inhibit */\r
428 /* 2 = inhibit until indirection */\r
429 /* 3 = inhibit next instruction only */\r
430int32 Enable = 0; /* User map to activate 1=A 2=B */\r
431int32 Usermap = 0; /* Active Map? 0=supvr mode, 1=user A, 2 = user B */\r
432int32 Map[8][32]; /* The actual MAPs 0=dch A, 1=A, 2=B, 3-5=dchB-D 6-7 User C-D */\r
433int32 Map31 = 037; /* Map for block 31 in supervisor mode */\r
434int32 SingleCycle = 0; /* Map one LDA/STA */\r
435int32 Check = 0; /* Page Check Register */\r
436int32 Fault = 0; /* Fault register */\r
437int32 MapInit = 0; /* 1 when map initialized */\r
438int32 MapIntMode = 0; /* Save of map user mode when int occurs */\r
439\r
440/* The Eclipse Floating Point Unit: This unit is optional on all Eclipse\r
441 models.\r
442*/\r
443\r
444int32 FPSR = 0; /* 32-bit FPU Status Register */\r
445t_int64 FPAC[4] = { 0,0,0,0 }; /* 4 64-bit Accumulators */\r
446int32 FPFault = 0; /* Save Fault State */\r
447\r
448/* Definitions for internal floating point arithmetic */\r
449\r
450typedef struct _SHORT_FLOAT {\r
451 int32 short_fract; /* Fraction */\r
452 short expo; /* Exponent + 64 */\r
453 uint8 sign; /* Sign */\r
454} SHORT_FLOAT;\r
455\r
456typedef struct _LONG_FLOAT {\r
457 t_int64 long_fract; /* Fraction */\r
458 short expo; /* Exponent + 64 */\r
459 uint8 sign; /* Sign */\r
460} LONG_FLOAT;\r
461\r
462LONG_FLOAT dfl,dfl2; /* Double Precision Work Fields */\r
463SHORT_FLOAT sfl,sfl2; /* Single Precision Work Fields */\r
464t_int64 tempfp, holdfp; /* Working area for FPAC */\r
465int shift,m3;\r
466t_int64 lsfract;\r
467\r
468void get_sf(SHORT_FLOAT *fl, t_int64 *fpr);\r
469void store_sf(SHORT_FLOAT *fl, t_int64 *fpr);\r
470void get_lf(LONG_FLOAT *fl, t_int64 *fpr);\r
471void store_lf(LONG_FLOAT *fl, t_int64 *fpr);\r
472int normal_sf (SHORT_FLOAT *fl);\r
473int normal_lf (LONG_FLOAT *fl);\r
474int overflow_sf(SHORT_FLOAT *fl);\r
475int overflow_lf(LONG_FLOAT *fl);\r
476int underflow_sf(SHORT_FLOAT *fl);\r
477int underflow_lf(LONG_FLOAT *fl);\r
478int significance_sf(SHORT_FLOAT *fl);\r
479int significance_lf(LONG_FLOAT *fl);\r
480int add_sf(SHORT_FLOAT *fl, SHORT_FLOAT *add_f1, int normal);\r
481int add_lf(LONG_FLOAT *fl, LONG_FLOAT *add_fl, int normal);\r
482int mul_sf(SHORT_FLOAT *fl, SHORT_FLOAT *mul_fl);\r
483int mul_lf(LONG_FLOAT *fl, LONG_FLOAT *mul_fl);\r
484int div_sf(SHORT_FLOAT *fl, SHORT_FLOAT *div_fl);\r
485int div_lf(LONG_FLOAT *fl, LONG_FLOAT *div_fl);\r
486\r
487/* Special Debugging Info */ \r
488\r
489int32 Debug_Flags = 0; /* Debug register - selects debug features */\r
490int32 Debug_Char = 0; /* Debug Character Register */\r
491\r
492int32 Tron = 0; /* For trace files */\r
493FILE *Trace;\r
494\r
495\r
496t_stat reason;\r
497extern int32 sim_int_char;\r
498extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */\r
499extern DEVICE *sim_devices[];\r
500\r
501t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);\r
502t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);\r
503t_stat cpu_reset (DEVICE *dptr);\r
504t_stat cpu_boot (int32 unitno, DEVICE *dptr);\r
505t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);\r
506t_stat Debug_Dump (UNIT *uptr, int32 val, char *cptr, void *desc);\r
507t_stat Dump_History (FILE *st, UNIT *uptr, int32 val, void *desc);\r
508t_stat map_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);\r
509t_stat map_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);\r
510t_stat map_reset (DEVICE *dptr);\r
511t_stat map_svc (UNIT *uptr);\r
512t_stat fpu_svc (UNIT *uptr);\r
513int32 GetMap(int32 addr);\r
514int32 PutMap(int32 addr, int32 data);\r
515int32 Debug_Entry(int32 PC, int32 inst, int32 inst2, int32 AC0, int32 AC1, int32 AC2, int32 AC3, int32 flags);\r
516t_stat build_devtab (void);\r
517\r
518extern t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,\r
519 UNIT *uptr, int32 sw);\r
520\r
521/* CPU data structures\r
522\r
523 cpu_dev CPU device descriptor\r
524 cpu_unit CPU unit descriptor\r
525 cpu_reg CPU register list\r
526 cpu_mod CPU modifiers list\r
527*/\r
528\r
529UNIT cpu_unit = { UDATA (NULL, UNIT_FIX + UNIT_BINK, MAXMEMSIZE) };\r
530\r
531REG cpu_reg[] = {\r
532 { ORDATA (PC, saved_PC, 15) },\r
533 { ORDATA (AC0, AC[0], 16) },\r
534 { ORDATA (AC1, AC[1], 16) },\r
535 { ORDATA (AC2, AC[2], 16) },\r
536 { ORDATA (AC3, AC[3], 16) },\r
537 { FLDATA (C, C, 16) },\r
538 { ORDATA (SR, SR, 16) },\r
539 { ORDATA (PI, pimask, 16) },\r
540 { FLDATA (ION, int_req, INT_V_ION) },\r
541 { FLDATA (ION_DELAY, int_req, INT_V_NO_ION_PENDING) },\r
542 { FLDATA (PWR, pwr_low, 0) },\r
543 { ORDATA (INT, int_req, INT_V_ION+1), REG_RO },\r
544 { ORDATA (BUSY, dev_busy, INT_V_ION+1), REG_RO },\r
545 { ORDATA (DONE, dev_done, INT_V_ION+1), REG_RO },\r
546 { ORDATA (DISABLE, dev_disable, INT_V_ION+1), REG_RO },\r
547 { FLDATA (STOP_DEV, stop_dev, 0) },\r
548 { DRDATA (INDMAX, ind_max, 16), REG_NZ + PV_LEFT },\r
549 { ORDATA (DEBUG, Debug_Flags, 16) },\r
550 { ORDATA (DCHAR, Debug_Char, 16) },\r
551 { DRDATA (MODEL, model, 16) },\r
552 { DRDATA (SPEED, speed, 16) },\r
553 { ORDATA (WRU, sim_int_char, 8) },\r
554 { NULL }\r
555};\r
556\r
557MTAB cpu_mod[] = {\r
558 { UNIT_MICRO, UNIT_MICRO, "MICRO", "MICRO", NULL },\r
559 { UNIT_MICRO, 0, "STD", "STD", NULL },\r
560 { UNIT_MSIZE, 4096, NULL, "4K", &cpu_set_size },\r
561 { UNIT_MSIZE, 8192, NULL, "8K", &cpu_set_size },\r
562 { UNIT_MSIZE, 12288, NULL, "12K", &cpu_set_size },\r
563 { UNIT_MSIZE, 16384, NULL, "16K", &cpu_set_size },\r
564 { UNIT_MSIZE, 20480, NULL, "20K", &cpu_set_size },\r
565 { UNIT_MSIZE, 24576, NULL, "24K", &cpu_set_size },\r
566 { UNIT_MSIZE, 28672, NULL, "28K", &cpu_set_size },\r
567 { UNIT_MSIZE, 32768, NULL, "32K", &cpu_set_size },\r
568 { UNIT_MSIZE, 65536, NULL, "64K", &cpu_set_size },\r
569 { UNIT_MSIZE, 131072, NULL, "128K", &cpu_set_size },\r
570 { UNIT_MSIZE, 262144, NULL, "256K", &cpu_set_size },\r
571 { UNIT_MSIZE, 524288, NULL, "512K", &cpu_set_size },\r
572 { UNIT_MSIZE, 1048576, NULL, "1024K", &cpu_set_size },\r
573 { UNIT_MSIZE, 0, NULL, "DUMP", &Debug_Dump },\r
574 { MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "HISTORY", NULL,\r
575 NULL, &Dump_History },\r
576 { 0 }\r
577};\r
578\r
579DEVICE cpu_dev = {\r
580 "CPU", &cpu_unit, cpu_reg, cpu_mod,\r
581 1, 8, 17, 1, 8, 16,\r
582 &cpu_ex, &cpu_dep, &cpu_reset,\r
583 &cpu_boot, NULL, NULL\r
584};\r
585\r
586/* MAP data structures\r
587\r
588 map_dev MAP device descriptor\r
589 map_unit MAP unit descriptor\r
590 map_reg MAP register list\r
591 map_mod MAP modifiers list\r
592*/\r
593\r
594UNIT map_unit = { UDATA (&map_svc, UNIT_17B, MAXMEMSIZE) };\r
595\r
596REG map_reg[] = {\r
597 { ORDATA (STATUS, MapStat, 16) },\r
598 { ORDATA (ENABLE, Enable, 16) },\r
599 { ORDATA (IINHIB, Inhibit, 16) },\r
600 { ORDATA (ACTIVE, Usermap, 16) },\r
601 { ORDATA (MAP31, Map31, 16) },\r
602 { ORDATA (CYCLE, SingleCycle, 16) },\r
603 { ORDATA (CHECK, Check, 16) },\r
604 { ORDATA (FAULT, Fault, 16) },\r
605 { NULL }\r
606};\r
607\r
608MTAB map_mod[] = {\r
609 { UNIT_17B, UNIT_17B, "17bit", "17B", NULL },\r
610 { UNIT_17B, 0, "19bit", "19B", NULL },\r
611 { 0 }\r
612};\r
613\r
614DEVICE map_dev = {\r
615 "MAP", &map_unit, map_reg, map_mod,\r
616 1, 8, 17, 1, 8, 16,\r
617 &map_ex, &map_dep, NULL,\r
618 NULL, NULL, NULL\r
619};\r
620\r
621/* FPU data structures\r
622\r
623 fpu_dev MAP device descriptor\r
624 fpu_unit MAP unit descriptor\r
625 fpu_reg MAP register list\r
626 fpu_mod MAP modifiers list\r
627*/\r
628\r
629UNIT fpu_unit = { UDATA (&fpu_svc, UNIT_UP, MAXMEMSIZE) };\r
630\r
631REG fpu_reg[] = {\r
632 { ORDATA (STATUS, FPSR, 32) },\r
633 { ORDATA (FPAC0, FPAC[0], 64) },\r
634 { ORDATA (FPAC1, FPAC[1], 64) },\r
635 { ORDATA (FPAC2, FPAC[2], 64) },\r
636 { ORDATA (FPAC3, FPAC[3], 64) },\r
637 { ORDATA (FAULT, FPFault, 32) },\r
638 { NULL }\r
639};\r
640\r
641MTAB fpu_mod[] = {\r
642 { UNIT_UP, UNIT_UP, "Enabled (UP)", "UP", NULL },\r
643 { UNIT_UP, 0, "Disabled (DOWN)", "DOWN", NULL },\r
644 { 0 }\r
645};\r
646\r
647DEVICE fpu_dev = {\r
648 "FPU", &fpu_unit, fpu_reg, fpu_mod,\r
649 1, 16, 17, 1, 16, 16,\r
650 NULL, NULL, NULL,\r
651 NULL, NULL, NULL\r
652};\r
653\r
654\r
655/* ---- Programmable Interval Timer Device ----------- */\r
656\r
657int32 pit_time = 100;\r
658int32 pit_tps = 10000; /* ticks per sec */\r
659int32 pit_adj = 20; /* tmxr adjust */\r
660int32 pit_poll = 16000; /* tmxr poll */\r
661int32 pit_initial = 0; /* initial counter reg */\r
662int32 pit_counter = 0; /* Counter */\r
663int32 pit_flag = 0; /* Initial setting flag */\r
664\r
665int32 pit (int32 pulse, int32 code, int32 AC);\r
666t_stat pit_svc (UNIT *uptr);\r
667t_stat pit_reset (DEVICE *dptr);\r
668 \r
669/* PIT data structures\r
670\r
671 pit_dev device descriptor\r
672 pit_unit unit descriptor\r
673 pit_reg register list\r
674*/\r
675\r
676DIB pit_dib = { DEV_PIT, INT_PIT, PI_PIT, &pit };\r
677\r
678UNIT pit_unit = { UDATA (&pit_svc, 0, 0) };\r
679\r
680REG pit_reg[] = {\r
681 { ORDATA (INIT, pit_initial, 16) },\r
682 { ORDATA (COUNT, pit_counter, 16) },\r
683 { FLDATA (BUSY, dev_busy, INT_V_PIT) },\r
684 { FLDATA (DONE, dev_done, INT_V_PIT) },\r
685 { FLDATA (DISABLE, dev_disable, INT_V_PIT) },\r
686 { FLDATA (INT, int_req, INT_V_PIT) },\r
687 { DRDATA (TIME0, pit_time, 24), REG_NZ + PV_LEFT },\r
688 { NULL }\r
689};\r
690\r
691DEVICE pit_dev = {\r
692 "PIT", &pit_unit, pit_reg, NULL,\r
693 1, 0, 0, 0, 0, 0,\r
694 NULL, NULL, &pit_reset,\r
695 NULL, NULL, NULL,\r
696 &pit_dib, 0\r
697};\r
698\r
699t_stat sim_instr (void)\r
700{\r
701extern int32 sim_interval;\r
702register int32 PC, IR, i, t, MA, j, k, tac;\r
703register uint32 mddata, uAC0, uAC1, uAC2, uAC3;\r
704int16 sAC0, sAC1, sAC2;\r
705int32 sddata, mi1, mi2, fpnum32;\r
706t_int64 fpnum, expon;\r
707t_value simeval[20];\r
708void mask_out (int32 mask);\r
709/* char debstr[128]; */\r
710/* char debadd[64]; */\r
711char debmap[4], debion[4];\r
712int debcar, iodev, iodata, debflags;\r
713int32 DisMap, debpc;\r
714/* int32 sp, sl; */\r
715int cmdptr, cmsptr, cmopt, cmptr;\r
716int16 cmslen, cmdlen;\r
717int tabaddr, tabptr;\r
718int32 effective(int32 PC, int32 index, int32 disp);\r
719int32 indirect(int32 d);\r
720int32 LEFmode(int32 PC, int32 index, int32 disp, int32 indirect);\r
721int32 LoadMap(int32 w);\r
722int32 Bytepointer(int32 PC, int32 index);\r
723int32 unimp(int32 PC);\r
724int32 pushrtn(int32 pc);\r
725\r
726/* Restore register state */\r
727\r
728if (build_devtab () != SCPE_OK) return SCPE_IERR; /* build dispatch */\r
729PC = saved_PC & AMASK; /* load local PC */\r
730C = C & 0200000;\r
731mask_out (pimask); /* reset int system */\r
732reason = 0;\r
733if (MapInit == 0) {\r
734 MapInit = 1;\r
735 for (mi1 = 0; mi1 < 6; mi1++) { /* Initialize MAPs */\r
736 for (mi2 = 0; mi2 < 32; mi2++) {\r
737 Map[mi1][mi2] = mi2;\r
738 }\r
739 }\r
740} \r
741\r
742/* Main instruction fetch/decode loop */\r
743\r
744while (reason == 0) { /* loop until halted */\r
745if (sim_interval <= 0) { /* check clock queue */\r
746 if (reason = sim_process_event ()) \r
747 break;\r
748}\r
749\r
750//if (speed > 0) for (i = 0; i < speed; i++) { j = 0; }\r
751\r
752if (Fault) { /* Check MAP fault */\r
753 Usermap = 0; /* YES: shutdown map */\r
754 MapStat &= ~01; /* Disable MMPU */\r
755 if (Fault & 0100000/*!!!*/) /* If it was validity, or WP */\r
756 MapStat &= ~0170; /* Reset other checkbits */\r
757 MapStat |= Fault & 077777; /* Put in fault code */\r
758 Fault = 0; /* Reset fault code */\r
759 t = (GetMap(040) + 1) & AMASK; /* Push rtn block */ \r
760 PutMap(t, AC[0]);\r
761 t++;\r
762 PutMap(t, AC[1]);\r
763 t++;\r
764 PutMap(t, AC[2]);\r
765 t++;\r
766 PutMap(t, AC[3]);\r
767 t++;\r
768 PutMap(t, (PC & AMASK));\r
769 if (C) PutMap(t, (GetMap(t) | 0100000));\r
770 PutMap(040, t);\r
771 int_req = int_req & ~INT_ION; /* Disable interrupts */\r
772 PC = indirect(M[003]); /* JMP to loc 3 */\r
773 continue;\r
774}\r
775\r
776if (FPSR & 0xF8000000) { /* FPU Fault? */\r
777 if (!(FPSR & 0x78000000)) { /* If error bit on ... */\r
778 FPSR &= 0x00FFFFFF; /* ...but no error, clear it */\r
779 } else { /* ELSE a real error: */\r
780 FPSR |= 0x80000000; /* Turn error bit on */\r
781 if (FPSR & 0x04000000) { /* Trap enabled ? */\r
782 FPFault = FPSR; /* Save fault */\r
783 FPSR &= 0xFBFFFFFF; /* Clear Trap Enable */\r
784 }\r
785 }\r
786}\r
787\r
788if (int_req > INT_PENDING && !Inhibit) { /* interrupt? */\r
789 int_req = int_req & ~INT_ION;\r
790 MapIntMode = MapStat; /* Save Status as it was */\r
791 Usermap = 0; /* Inhibit MAP */\r
792 MapStat &= ~1; /* Disable user map */\r
793 if (XCT_mode) {\r
794 M[0] = PC - 1; /* If XCT mode rtn to XCT */\r
795 XCT_mode = 0; /* turn off mode */\r
796 } else {\r
797 M[0] = PC; /* Save Return Address */\r
798 }\r
799 old_PC = PC;\r
800 MA = M[1];\r
801 for (i = 0; i < ind_max * 2; i++) { /* count indirects */\r
802 if ((MA & 0100000) == 0) break;\r
803 if ((MA & 077770) == 020)\r
804 MA = (M[MA & AMASK] = (M[MA & AMASK] + 1) & 0177777);\r
805 else if ((MA & 077770) == 030)\r
806 MA = (M[MA & AMASK] = (M[MA & AMASK] - 1) & 0177777);\r
807 else MA = M[MA & AMASK];\r
808 }\r
809 if (i >= (ind_max-1)) {\r
810 if ((MapStat & 010) && Usermap) {\r
811 Fault = 04000; /* Map fault if IND prot */\r
812 continue;\r
813 } else {\r
814 reason = STOP_IND_INT;\r
815 break;\r
816 } \r
817 }\r
818 if (Debug_Flags) {\r
819 iodev = 0;\r
820 iodata = int_req & (-int_req);\r
821 for (i = DEV_LOW; i <= DEV_HIGH; i++) {\r
822 if (iodata & dev_table[i].mask) {\r
823 iodev = i;\r
824 break;\r
825 } \r
826 }\r
827 if (iodev == 0) {\r
828 printf("\n<<Interrupt to device 0!>>\n");\r
829 reason = STOP_IBKPT;\r
830 } \r
831 if (Debug_Flags & 0100000) {\r
832 fprintf(Trace, "--------- Interrupt %o (%o) to %6o ---------\n", int_req, iodev, MA);\r
833 } else {\r
834 Debug_Entry(PC, int_req, 0, iodev, MA, 0, 0, 0x80);\r
835 } \r
836 } \r
837 PC = MA;\r
838} /* end interrupt */\r
839\r
840if (Inhibit != 0) { /* Handle 1-instruction inhibit sequence */\r
841 if (Inhibit == 3) /* Used by SYC instruction */\r
842 Inhibit = 4;\r
843 if (Inhibit == 4)\r
844 Inhibit = 0;\r
845} \r
846\r
847if (sim_brk_summ && sim_brk_test (PC, SWMASK ('E'))) { /* breakpoint? */\r
848 reason = STOP_IBKPT; /* stop simulation */\r
849 break;\r
850}\r
851\r
852if ((PC < 1 || PC > 077777) && Debug_Flags) {\r
853 if (PPC != -1) { /* Don't break on 1st instruction */\r
854 printf("\n<<Invalid PC=%o from %o>>\n\r", PC, PPC);\r
855 reason = STOP_IBKPT;\r
856 break;\r
857 } \r
858}\r
859\r
860PPC = PC;\r
861\r
862if (Debug_Flags) {\r
863 if (!Tron) {\r
864 Tron = 1;\r
865 Trace = fopen("trace.log", "w");\r
866 }\r
867 strcpy(debmap, " ");\r
868 strcpy(debion, " ");\r
869 debcar = 0;\r
870 if (C) debcar = 1;\r
871 if (Usermap == 1) strcpy(debmap, "A");\r
872 if (Usermap == 2) strcpy(debmap, "B");\r
873 if (Usermap == 5) strcpy(debmap, "C");\r
874 if (Usermap == 6) strcpy(debmap, "D");\r
875 if (int_req & INT_ION) strcpy(debion, "I");\r
876 if (XCT_mode == 0) {\r
877 debpc = PC; \r
878 simeval[0] = GetMap(PC);\r
879 simeval[1] = GetMap(PC+1);\r
880 } else {\r
881 debpc = 0177777;\r
882 simeval[0] = XCT_inst;\r
883 simeval[1] = 0;\r
884 } \r
885 if (Debug_Flags & 0100000) {\r
886 fprintf(Trace, "%s%s%06o acs: %06o %06o %06o %06o %01o ", \r
887 debion, debmap, debpc, AC[0], AC[1], AC[2], AC[3], debcar);\r
888 fprint_sym (Trace, debpc, simeval, NULL, SWMASK('M'));\r
889 fprintf(Trace, "\n");\r
890 } else {\r
891 debflags = 0;\r
892 if (C) debflags |= 0x01;\r
893 if (int_req & INT_ION) debflags |= 0x02;\r
894 if (Usermap == 1) debflags |= 0x04;\r
895 if (Usermap == 2) debflags |= 0x08;\r
896 if (Usermap == 3) debflags |= 0x10;\r
897 if (Usermap == 4) debflags |= 0x20;\r
898 Debug_Entry(debpc, (int32)simeval[0], (int32)simeval[1], AC[0], AC[1], AC[2], AC[3], debflags);\r
899 } \r
900} \r
901 \r
902if (XCT_mode == 0) { /* XCT mode? */\r
903 IR = GetMap(PC); /* No: fetch instr */\r
904 if (Fault) continue; /* Give up if fault */\r
905 PC = (PC + 1) & AMASK; /* bump PC */\r
906} else {\r
907 IR = XCT_inst; /* Yes: Get inst to XCT */\r
908 XCT_mode = 0; /* Go back to normal mode */\r
909} \r
910int_req = int_req | INT_NO_ION_PENDING; /* clear ION delay */\r
911sim_interval = sim_interval - 1;\r
912t = IR >> 11; /* prepare to decode */\r
913\r
914/* ---------------- BEGIN Eclipse modification --------------------- */\r
915\r
916/* Eclipse instruction set. These instructions are checked for\r
917 before any of the NOVA ones. Eclipse instructions do not\r
918 correspond to any patterns, other than bit 0 being 1 and\r
919 the last 4 bits are 1000. Words which are not Eclipse\r
920 instructions will be interpreted as Nova instructions. */\r
921\r
922/* Important Note: The order of the if statements is important. \r
923 Frequently executed instructions should come first, to enhance\r
924 the speed of the simulation.\r
925*/ \r
926\r
927if ((IR & 0100017) == 0100010) { /* This pattern for all */\r
928 /* Eclipse instructions */\r
929 \r
930/****************************************************************/\r
931/* This is the standard Eclipse instruction set */\r
932/****************************************************************/ \r
933 \r
934 /* Byte operations */\r
935 \r
936 if ((IR & 0103777) == 0102710) { /* LDB: Load Byte */\r
937 i = (IR >> 13) & 03;\r
938 MA = (AC[i] >> 1) & AMASK;\r
939 j = (IR >> 11) & 03;\r
940 if (AC[i] & 01) {\r
941 AC[j] = GetMap(MA) & 0377;\r
942 } else {\r
943 AC[j] = (GetMap(MA) >> 8) & 0377;\r
944 }\r
945 continue;\r
946 }\r
947 if ((IR & 0103777) == 0103010) { /* STB: Store Byte */\r
948 i = (IR >> 13) & 03;\r
949 MA = (AC[i] >> 1);\r
950 j = (IR >> 11) & 03;\r
951 t = GetMap(MA);\r
952 if (AC[i] & 01) {\r
953 t &= 0177400;\r
954 t |= (AC[j] & 0377);\r
955 PutMap(MA, t);\r
956 } else {\r
957 t &= 0377;\r
958 t |= (AC[j] & 0377) << 8;\r
959 PutMap(MA, t);\r
960 }\r
961 continue;\r
962 }\r
963\r
964 /* Fixed-point arithmetic - loads & saves */\r
965\r
966 if ((IR & 0162377) == 0122070) { /* ELDA: Extended LDA */\r
967 i = (IR >> 11) & 3;\r
968 t = GetMap(PC);\r
969 if (SingleCycle) Usermap = SingleCycle;\r
970 AC[i] = GetMap(effective(PC, (IR >> 8) & 3, t));\r
971 if (SingleCycle) {\r
972 Usermap = SingleCycle = 0;\r
973 if (Inhibit == 1) Inhibit = 3;\r
974 MapStat |= 02000;\r
975 MapStat &= 0177776;\r
976 } \r
977 PC = (PC + 1) & AMASK;\r
978 continue;\r
979 } \r
980 if ((IR & 0162377) == 0142070) { /* ESTA: Extended STA */\r
981 i = (IR >> 11) & 3;\r
982 t = GetMap(PC);\r
983 if (SingleCycle) Usermap = SingleCycle;\r
984 PutMap((effective(PC, (IR >> 8) & 3, t)), AC[i]);\r
985 if (SingleCycle) {\r
986 Usermap = SingleCycle = 0;\r
987 if (Inhibit == 1) Inhibit = 3;\r
988 MapStat |= 02000;\r
989 MapStat &= 0177776;\r
990 } \r
991 PC = (PC + 1) & AMASK;\r
992 continue;\r
993 } \r
994 if ((IR & 0103777) == 0100010) { /* ADI: Add Immediate */\r
995 t = (IR >> 11) & 3;\r
996 AC[t] = (AC[t] + ((IR >> 13) & 3) + 1) & 0xffff;\r
997 continue;\r
998 }\r
999 if ((IR & 0103777) == 0100110) { /* SBI: Subtract Immediate */\r
1000 t = (IR >> 11) & 3;\r
1001 AC[t] = (AC[t] - (((IR >> 13) & 3) + 1)) & 0xffff;\r
1002 continue;\r
1003 }\r
1004 if ((IR & 0163777) == 0163770) { /* ADDI: Extended Add Immed. */\r
1005 t = (IR >> 11) & 3;\r
1006 i = GetMap(PC);\r
1007 PC = (PC + 1) & AMASK;\r
1008 AC[t] = (AC[t] + i) & 0xffff;\r
1009 continue;\r
1010 }\r
1011 if ((IR & 0103777) == 0100710) { /* XCH: Exchange Accumulators */\r
1012 t = AC[(IR >> 11) & 3];\r
1013 AC[(IR >> 11) & 3] = AC[(IR >> 13) & 3];\r
1014 AC[(IR >> 13) & 3] = t;\r
1015 continue;\r
1016 }\r
1017 if ((IR & 0162377) == 0162070) { /* ELEF: Load Effective Addr */\r
1018 t = GetMap(PC);\r
1019 AC[(IR >> 11) & 3] = effective(PC, (IR >> 8) & 3, t);\r
1020 PC = (PC + 1) & AMASK;\r
1021 continue;\r
1022 }\r
1023 \r
1024 /* Logical operations */\r
1025 \r
1026 if ((IR & 0163777) == 0143770) { /* ANDI: And Immediate */\r
1027 AC[(IR >> 11) & 3] &= GetMap(PC); \r
1028 PC = (PC + 1) & AMASK;\r
1029 continue;\r
1030 }\r
1031 if ((IR & 0163777) == 0103770) { /* IORI: Inclusive Or Immed */\r
1032 AC[(IR >> 11) & 3] |= GetMap(PC);\r
1033 PC = (PC + 1) & AMASK;\r
1034 continue;\r
1035 }\r
1036 if ((IR & 0163777) == 0123770) { /* XORI: Exclusive Or Immed */\r
1037 AC[(IR >> 11) & 3] ^= GetMap(PC);\r
1038 PC = (PC + 1) & AMASK;\r
1039 continue;\r
1040 }\r
1041 if ((IR & 0103777) == 0100410) { /* IOR: Inclusive Or */\r
1042 AC[(IR >> 11) & 3] |= AC[(IR >> 13) & 3];\r
1043 continue;\r
1044 }\r
1045 if ((IR & 0103777) == 0100510) { /* XOR: Exclusive Or */\r
1046 AC[(IR >> 11) & 3] ^= AC[(IR >> 13) & 3];\r
1047 continue;\r
1048 }\r
1049 if ((IR & 0103777) == 0100610) { /* ANC: And with complemented src */\r
1050 AC[(IR >> 11) & 3] &= ~(AC[(IR >> 13) & 3]);\r
1051 continue;\r
1052 }\r
1053 \r
1054 /* Shift operations */\r
1055 \r
1056 if ((IR & 0103777) == 0101210) { /* LSH: Logical Shift */\r
1057 register int16 sh;\r
1058 sh = AC[(IR >> 13) & 3] & 0377;\r
1059 i = (IR >> 11) & 3;\r
1060 if (sh & 0200) {\r
1061 sh = ~sh + 1;\r
1062 AC[i] = AC[i] >> sh;\r
1063 } else {\r
1064 AC[i] = AC[i] << sh;\r
1065 }\r
1066 if (sh > 15) AC[i] = 0;\r
1067 AC[i] &= 0xffff; \r
1068 continue;\r
1069 }\r
1070 if ((IR & 0103777) == 0101310) { /* DLSH: Double logical shift */\r
1071 register int16 sh;\r
1072 sh = AC[(IR >> 13) & 3] & 0377;\r
1073 i = (IR >> 11) & 3;\r
1074 uAC0 = AC[i] << 16;\r
1075 j = i + 1;\r
1076 if (j == 4) j = 0;\r
1077 uAC0 |= AC[j]; \r
1078 if (sh & 0200) {\r
1079 sh = (~sh + 1) & 0377;\r
1080 if (sh < 32)\r
1081 uAC0 = uAC0 >> sh;\r
1082 } else {\r
1083 if (sh < 32)\r
1084 uAC0 = uAC0 << sh;\r
1085 } \r
1086 if (sh > 31) uAC0 = 0;\r
1087 AC[i] = (uAC0 >> 16) & 0xffff;\r
1088 AC[j] = uAC0 & 0xffff; \r
1089 continue;\r
1090 }\r
1091 if ((IR & 0103777) == 0101410) { /* HXL: Hex shift left */\r
1092 t = ((IR >> 13) & 3) + 1;\r
1093 i = (IR >> 11) & 3;\r
1094 AC[i] = AC[i] << (t * 4);\r
1095 AC[i] &= 0xffff; \r
1096 continue;\r
1097 }\r
1098 if ((IR & 0103777) == 0101510) { /* HXR: Hex shift right */\r
1099 t = ((IR >> 13) & 3) + 1;\r
1100 i = (IR >> 11) & 3;\r
1101 AC[i] = AC[i] >> (t * 4);\r
1102 AC[i] &= 0xffff; \r
1103 continue;\r
1104 }\r
1105 if ((IR & 0103777) == 0101610) { /* DHXL: Double Hex shift left */\r
1106 t = ((IR >> 13) & 3) + 1;\r
1107 i = (IR >> 11) & 3;\r
1108 j = i + 1;\r
1109 if (j == 4) j = 0;\r
1110 uAC0 = AC[i] << 16;\r
1111 uAC0 |= AC[j]; \r
1112 uAC0 = uAC0 << ((t * 4) & 0177);\r
1113 AC[i] = (uAC0 >> 16) & 0xffff;\r
1114 AC[j] = uAC0 & 0xffff; \r
1115 continue;\r
1116 }\r
1117 if ((IR & 0103777) == 0101710) { /* DHXR: Double Hex shift right */\r
1118 t = ((IR >> 13) & 3) + 1;\r
1119 i = (IR >> 11) & 3;\r
1120 j = i + 1;\r
1121 if (j == 4) j = 0;\r
1122 uAC0 = AC[i] << 16;\r
1123 uAC0 |= AC[j]; \r
1124 uAC0 = uAC0 >> ((t * 4) & 0177);\r
1125 AC[i] = (uAC0 >> 16) & 0xffff;\r
1126 AC[j] = uAC0 & 0xffff; \r
1127 continue;\r
1128 }\r
1129\r
1130 /* Bit operations */\r
1131\r
1132 if ((IR & 0103777) == 0102010) { /* BTO: Set bit to one */\r
1133 i = (IR >> 11) & 3;\r
1134 j = (IR >> 13) & 3;\r
1135 if (i != j) {\r
1136 k = (AC[i] >> 4) & AMASK;\r
1137 if ((AC[j] + k) & 0100000)\r
1138 t = 1;\r
1139//AOS MA = indirect(AC[j] + k);\r
1140 MA = (AC[j] + k) & AMASK;\r
1141 } else {\r
1142 MA = (AC[i] >> 4) & AMASK;\r
1143 } \r
1144 t = AC[i] & 017;\r
1145 t = GetMap(MA) | (0100000 >> t);\r
1146 PutMap(MA, t);\r
1147 continue;\r
1148 }\r
1149 if ((IR & 0103777) == 0102110) { /* BTZ: Set bit to zero */\r
1150 i = (IR >> 11) & 3;\r
1151 j = (IR >> 13) & 3;\r
1152 if (i != j) {\r
1153 k = (AC[i] >> 4) & AMASK;\r
1154 if ((AC[j] + k) & 0100000)\r
1155 t = 1;\r
1156//AOS MA = indirect(AC[j] + k);\r
1157 MA = (AC[j] + k) & AMASK;\r
1158 } else {\r
1159 MA = (AC[j] >> 4) & AMASK;\r
1160 } \r
1161 t = AC[i] & 017;\r
1162 t = GetMap(MA) & ~(0100000 >> t);\r
1163 PutMap(MA, t);\r
1164 continue;\r
1165 }\r
1166 if ((IR & 0103777) == 0102210) { /* SZB: Skip on zero bit */\r
1167 i = (IR >> 11) & 3;\r
1168 j = (IR >> 13) & 3;\r
1169 if (i != j) {\r
1170 k = (AC[i] >> 4) & AMASK;\r
1171 if ((AC[j] + k) & 0100000)\r
1172 t = 1;\r
1173 MA = indirect(AC[j] + k);\r
1174// MA = (AC[j] + k) & AMASK;\r
1175 } else {\r
1176 MA = (AC[i] >> 4) & AMASK;\r
1177 } \r
1178 t = GetMap(MA) << (AC[i] & 017);\r
1179 if (!(t & 0100000)) PC = (PC + 1) & AMASK;\r
1180 continue;\r
1181 }\r
1182 if ((IR & 0103777) == 0102770) { /* SNB: Skip on non-zero bit */\r
1183 i = (IR >> 11) & 3;\r
1184 j = (IR >> 13) & 3;\r
1185 if (i != j) {\r
1186 k = (AC[i] >> 4) & AMASK;\r
1187 if ((AC[j] + k) & 0100000)\r
1188 t = 1;\r
1189 MA = indirect(AC[j] + k);\r
1190// MA = (AC[j] + k) & AMASK;\r
1191 } else {\r
1192 MA = (AC[j] >> 4) & AMASK;\r
1193 } \r
1194 t = GetMap(MA) << (AC[i] & 017);\r
1195 if (t & 0100000) PC = (PC + 1) & AMASK;\r
1196 continue;\r
1197 }\r
1198 if ((IR & 0103777) == 0102310) { /* SZBO: skip on zero bit & set to 1 */\r
1199 register int32 save;\r
1200 i = (IR >> 11) & 3;\r
1201 j = (IR >> 13) & 3;\r
1202 if (i != j) {\r
1203 k = (AC[i] >> 4) & AMASK;\r
1204 MA = indirect(AC[j] + k);\r
1205// MA = (AC[j] + k) & AMASK;\r
1206 } else {\r
1207 MA = (AC[j] >> 4) & AMASK;\r
1208 } \r
1209 t = AC[i] & 017;\r
1210 save = GetMap(MA);\r
1211 t = save | (0100000 >> t);\r
1212 PutMap(MA, t);\r
1213 t = save << (AC[i] & 017);\r
1214 if ((t & 0100000) == 0) \r
1215 PC = (PC + 1) & AMASK;\r
1216 continue;\r
1217 }\r
1218 if ((IR & 0103777) == 0102410) { /* LOB: Locate lead bit */\r
1219 register int32 a, r;\r
1220 register int16 b;\r
1221 a = AC[(IR >> 13) & 3] & 0xffff;\r
1222 for (i = 0; i < 16; i++) {\r
1223 if ((a << i) & 0100000) break;\r
1224 }\r
1225 r = (IR >> 11) & 3;\r
1226 b = AC[r];\r
1227 b += i;\r
1228 AC[r] = b & 0177777; \r
1229 continue;\r
1230 }\r
1231 if ((IR & 0103777) == 0102510) { /* LRB: Locate & reset lead bit */\r
1232 register int32 a, r;\r
1233 register int16 b;\r
1234 j = (IR >> 13) & 3;\r
1235 a = AC[j];\r
1236 for (i = 0; i < 16; i++) {\r
1237 if ((a << i) & 0100000) break;\r
1238 }\r
1239 r = (IR >> 11) & 3;\r
1240 b = AC[r];\r
1241 b += i;\r
1242 if (j != r) AC[r] = b & 0177777;\r
1243 AC[j] &= ~(0100000 >> i);\r
1244 AC[j] &= 0xffff;\r
1245 continue;\r
1246 }\r
1247 if ((IR & 0103777) == 0102610) { /* COB: Count bits */\r
1248 register int32 a;\r
1249 register int16 b, c = 0;\r
1250 a = AC[(IR >> 13) & 3];\r
1251 for (i = 0; i < 16; i++) {\r
1252 if ((a >> i) & 1) c++;\r
1253 }\r
1254 i = (IR >> 11) & 3;\r
1255 b = AC[i];\r
1256 b += c;\r
1257 AC[i] = b & 0177777; \r
1258 continue;\r
1259 }\r
1260\r
1261 /* Jump & similar operations */\r
1262\r
1263 if ((IR & 0176377) == 0102070) { /* EJMP: Extended JMP */\r
1264 PC = effective(PC, (IR >> 8) & 3, GetMap(PC));\r
1265 continue;\r
1266 }\r
1267 if ((IR & 0176377) == 0106070) { /* EJSR: Extended JMP to subr */\r
1268 t = effective(PC, (IR >> 8) & 3, GetMap(PC));\r
1269 AC[3] = (PC + 1) & AMASK;\r
1270 PC = t & AMASK;\r
1271 continue;\r
1272 }\r
1273 if ((IR & 0176377) == 0112070) { /* EISZ: Ext Inc & skip if 0 */\r
1274 MA = effective(PC, (IR >> 8) & 3, GetMap(PC));\r
1275 PutMap(MA, ((GetMap(MA) + 1) & 0xffff));\r
1276 if (GetMap(MA) == 0) PC = (PC + 1) & AMASK;\r
1277 PC = (PC + 1) & AMASK;\r
1278 continue;\r
1279 }\r
1280 if ((IR & 0176377) == 0116070) { /* EDSZ: Ext Dec & skip if 0 */\r
1281 MA = effective(PC, (IR >> 8) & 3, GetMap(PC));\r
1282 PutMap(MA, ((GetMap(MA) - 1) & 0xffff));\r
1283 if (GetMap(MA) == 0) PC = (PC + 1) & AMASK;\r
1284 PC = (PC + 1) & AMASK;\r
1285 continue;\r
1286 }\r
1287 if ((IR & 0103777) == 0101010) { /* SGT: Skip if ACS > ACD */\r
1288 register int16 a1, d1;\r
1289 a1 = AC[(IR >> 13) & 3] & 0xffff;\r
1290 d1 = AC[(IR >> 11) & 3] & 0xffff;\r
1291 if (a1 > d1)\r
1292 PC = (PC + 1) & AMASK;\r
1293 continue;\r
1294 }\r
1295 if ((IR & 0103777) == 0101110) { /* SGE: Skip if ACS >= ACD */\r
1296 register int16 a1, d1;\r
1297 a1 = AC[(IR >> 13) & 3] & 0xffff;\r
1298 d1 = AC[(IR >> 11) & 3] & 0xffff;\r
1299 if (a1 >= d1)\r
1300 PC = (PC + 1) & AMASK;\r
1301 continue;\r
1302 }\r
1303 if ((IR & 0103777) == 0102370) { /* CLM: Compare to limits */\r
1304 register int32 s, d, MA;\r
1305 int16 H, L, ca;\r
1306 s = (IR >> 13) & 3;\r
1307 d = (IR >> 11) & 3;\r
1308 if (s == d) {\r
1309 L = GetMap(PC);\r
1310 PC++;\r
1311 H = GetMap(PC);\r
1312 PC++;\r
1313 } else {\r
1314 MA = AC[d] & AMASK;\r
1315 L = GetMap(MA);\r
1316 H = GetMap(MA + 1);\r
1317 }\r
1318 ca = AC[s];\r
1319 if (ca >= L && ca <= H) PC = (PC + 1) & AMASK;\r
1320 continue;\r
1321 }\r
1322 if ((IR & 0163777) == 0123370) { /* XCT: Execute */\r
1323 XCT_mode = 1; /* Set up to execute on next loop */\r
1324 XCT_inst = AC[(IR >> 11) & 3]; \r
1325 continue;\r
1326 }\r
1327\r
1328 /* Memory block operations */\r
1329\r
1330 if (IR == 0113710) { /* BAM: Block add & move */\r
1331 register int32 w;\r
1332 t = AC[1];\r
1333 if (t < 1 || t > 0100000)\r
1334 continue;\r
1335 i = indirect(AC[2]);\r
1336 j = indirect(AC[3]);\r
1337 while (t) {\r
1338 w = GetMap(i);\r
1339 PutMap(j, ((w + AC[0]) & 0xffff));\r
1340 if (Fault) break;\r
1341 t--;\r
1342 i++;\r
1343 j++;\r
1344 i &= AMASK;\r
1345 j &= AMASK;\r
1346 } \r
1347 AC[1] = t;\r
1348 AC[2] = i & AMASK;\r
1349 AC[3] = j & AMASK; \r
1350 continue;\r
1351 }\r
1352 if (IR == 0133710) { /* BLM: Block move */\r
1353 t = AC[1];\r
1354 if (t < 1 || t > 0100000)\r
1355 continue;\r
1356 i = indirect(AC[2]);\r
1357 j = indirect(AC[3]);\r
1358 if (Fault) continue;\r
1359 while (t) {\r
1360 PutMap(j, GetMap(i));\r
1361 if (Fault) break;\r
1362 t--;\r
1363 i++;\r
1364 j++;\r
1365 i &= AMASK;\r
1366 j &= AMASK;\r
1367 }\r
1368 AC[1] = t;\r
1369 AC[2] = i & AMASK;\r
1370 AC[3] = j & AMASK; \r
1371 continue;\r
1372 }\r
1373 \r
1374 /* Stack operations */\r
1375 \r
1376 if ((IR & 0103777) == 0103110) { /* PSH: Push multiple accums */ \r
1377 register int32 j;\r
1378 j = (IR >> 11) & 3;\r
1379 t = GetMap(040) & AMASK;\r
1380 i = (IR >> 13) & 3;\r
1381 if (i == j) {\r
1382 t++;\r
1383 PutMap(t, AC[i]); \r
1384 PutMap(040, (t & AMASK));\r
1385 if (t > GetMap(042)) {\r
1386 pushrtn(PC);\r
1387 PC = indirect(GetMap(043));\r
1388 PutMap(040, (GetMap(040) & 077777));\r
1389 PutMap(042, (GetMap(042) | 0100000));\r
1390 } \r
1391 continue;\r
1392 } \r
1393 while (i != j) {\r
1394 t++;\r
1395 PutMap(t, AC[i]);\r
1396 i++;\r
1397 if (i == 4) i = 0;\r
1398 }\r
1399 t++;\r
1400 PutMap(t, AC[i]);\r
1401 PutMap(040, (t & AMASK));\r
1402 if ((GetMap(040) & AMASK) > GetMap(042)) {\r
1403 pushrtn(PC);\r
1404 PC = indirect(GetMap(043));\r
1405 PutMap(040, (GetMap(040) & 077777));\r
1406 PutMap(042, (GetMap(042) | 0100000));\r
1407 } \r
1408 continue;\r
1409 }\r
1410 if ((IR & 0103777) == 0103210) { /* POP: Pop mult accums */\r
1411 j = (IR >> 11) & 3;\r
1412 t = GetMap(040) & AMASK;\r
1413 i = (IR >> 13) & 3;\r
1414 if (i == j) {\r
1415 AC[i] = GetMap(t);\r
1416 t--;\r
1417 PutMap(040, (t & AMASK));\r
1418 t = GetMap(040);\r
1419 if (t < 0100000 && t < 0400) {\r
1420 PutMap(040, GetMap(042));\r
1421 pushrtn(PC);\r
1422 PC = indirect(GetMap(043));\r
1423 PutMap(040, (GetMap(040) & 077777));\r
1424 PutMap(042, (GetMap(042) | 0100000));\r
1425 } \r
1426 continue;\r
1427 }\r
1428 while (i != j) { \r
1429 AC[i] = GetMap(t);\r
1430 t--;\r
1431 i--;\r
1432 if (i == -1) i = 3;\r
1433 }\r
1434 AC[i] = GetMap(t);\r
1435 t--;\r
1436 PutMap(040, (t & AMASK));\r
1437 t = GetMap(040);\r
1438 if (t < 0100000 && t < 0400) {\r
1439 PutMap(040, GetMap(042));\r
1440 pushrtn(PC);\r
1441 PC = indirect(GetMap(043));\r
1442 PutMap(040, (GetMap(040) & 077777));\r
1443 PutMap(042, (GetMap(042) | 0100000));\r
1444 } \r
1445 continue;\r
1446 }\r
1447 if (IR == 0103710) { /* PSHR: Push return addr */\r
1448 t = (GetMap(040) + 1) & AMASK;\r
1449 PutMap(t, (PC + 1));\r
1450 PutMap(040, t);\r
1451 if ((GetMap(040) & AMASK) > GetMap(042)) {\r
1452 pushrtn(PC);\r
1453 PC = indirect(GetMap(043));\r
1454 PutMap(040, (GetMap(040) & 077777));\r
1455 PutMap(042, (GetMap(042) | 0100000));\r
1456 } \r
1457 continue;\r
1458 }\r
1459 if (IR == 0163710) { /* SAVE */\r
1460 register int32 savep;\r
1461 savep = ((GetMap(PC) + GetMap(040)) + 5) & AMASK;\r
1462 if (savep > GetMap(042)) {\r
1463 pushrtn(PC-1);\r
1464 PC = indirect(GetMap(043));\r
1465 PutMap(040, (GetMap(040) & 077777));\r
1466 PutMap(042, (GetMap(042) | 0100000));\r
1467 continue;\r
1468 } \r
1469 t = GetMap(040) + 1; \r
1470 PutMap(t, AC[0]);\r
1471 t++;\r
1472 PutMap(t, AC[1]);\r
1473 t++;\r
1474 PutMap(t, AC[2]);\r
1475 t++;\r
1476 PutMap(t, GetMap(041));\r
1477 t++;\r
1478 savep = PC;\r
1479 PC = (PC + 1) & AMASK;\r
1480 PutMap(t, (AC[3] & AMASK));\r
1481 if (C) PutMap(t, (GetMap(t) | 0100000));\r
1482 PutMap(040, t);\r
1483 AC[3] = GetMap(040) & AMASK;\r
1484 PutMap(041, AC[3]);\r
1485 PutMap(040, ((GetMap(040) + GetMap(savep)) & AMASK));\r
1486 continue;\r
1487 }\r
1488 if ((IR & 0163777) == 0103370) { /* MSP: Modify stack pointer */\r
1489 t = (GetMap(040) + AC[(IR >> 11) & 3]) & 0177777;\r
1490 if (t > GetMap(042)) {\r
1491 pushrtn(PC-1);\r
1492 PC = indirect(GetMap(043));\r
1493 PutMap(040, (GetMap(040) & AMASK));\r
1494 PutMap(042, (GetMap(042) | 0100000));\r
1495 continue;\r
1496 }\r
1497 PutMap(040, t); \r
1498 continue;\r
1499 }\r
1500 if ((IR & 0176377) == 0102270) { /* PSHJ: Push JMP */\r
1501 PutMap(040, (GetMap(040) + 1));\r
1502 PutMap((GetMap(040) & AMASK), ((PC + 1) & AMASK));\r
1503 if ((GetMap(040) & AMASK) > (GetMap(042) & AMASK)) {\r
1504 pushrtn(PC+1);\r
1505 PC = indirect(GetMap(043));\r
1506 PutMap(040, (GetMap(040) & 077777));\r
1507 PutMap(042, (GetMap(042) | 0100000));\r
1508 continue;\r
1509 } \r
1510 PC = effective(PC, (IR >> 8) & 3, GetMap(PC));\r
1511 continue;\r
1512 }\r
1513 if (IR == 0117710) { /* POPJ: Pop PC and Jump */\r
1514 PC = GetMap(GetMap(040)) & AMASK;\r
1515 PutMap(040, (GetMap(040) - 1));\r
1516 if (MapStat & 1) {\r
1517 Usermap = Enable;\r
1518 Inhibit = 0;\r
1519 } \r
1520 j = GetMap(042);\r
1521 t = GetMap(040);\r
1522 if ((j < 0100000 && t < 0100000) && (t < 0400) && (t > 0)) {\r
1523 pushrtn(PC);\r
1524 PC = indirect(GetMap(043));\r
1525 PutMap(040, (GetMap(040) & 077777));\r
1526 PutMap(042, (GetMap(042) | 0100000));\r
1527 } \r
1528 continue;\r
1529 }\r
1530 if (IR == 0107710) { /* POPB: Pop block */\r
1531 PC = GetMap(GetMap(040)) & AMASK;\r
1532 if (GetMap(GetMap(040)) & 0100000)\r
1533 C = 0200000;\r
1534 else\r
1535 C = 0;\r
1536 PutMap(040, (GetMap(040) - 1));\r
1537 AC[3] = GetMap(GetMap(040)); \r
1538 PutMap(040, (GetMap(040) - 1));\r
1539 AC[2] = GetMap(GetMap(040)); \r
1540 PutMap(040, (GetMap(040) - 1));\r
1541 AC[1] = GetMap(GetMap(040)); \r
1542 PutMap(040, (GetMap(040) - 1));\r
1543 AC[0] = GetMap(GetMap(040));\r
1544 PutMap(040, (GetMap(040) - 1));\r
1545 t = GetMap(040);\r
1546 if (t < 0100000 && t < 0400) {\r
1547 pushrtn(PC);\r
1548 PC = indirect(GetMap(043));\r
1549 PutMap(040, (GetMap(040) & 077777));\r
1550 PutMap(042, (GetMap(042) | 0100000));\r
1551 } \r
1552 if (MapStat & 1) {\r
1553 Usermap = Enable;\r
1554 Inhibit = 0;\r
1555 }\r
1556 continue;\r
1557 }\r
1558 if (IR == 0127710) { /* RTN: Return */\r
1559 PutMap(040, GetMap(041));\r
1560 PC = GetMap(GetMap(040)) & AMASK;\r
1561 t = GetMap(040);\r
1562 t = GetMap(t);\r
1563 if (t & 0100000)\r
1564 C = 0200000;\r
1565 else\r
1566 C = 0;\r
1567 PutMap(040, (GetMap(040) - 1));\r
1568 AC[3] = GetMap(GetMap(040)); \r
1569 PutMap(040, (GetMap(040) - 1));\r
1570 AC[2] = GetMap(GetMap(040)); \r
1571 PutMap(040, (GetMap(040) - 1));\r
1572 AC[1] = GetMap(GetMap(040)); \r
1573 PutMap(040, (GetMap(040) - 1));\r
1574 AC[0] = GetMap(GetMap(040));\r
1575 PutMap(040, (GetMap(040) - 1));\r
1576 PutMap(041, AC[3]); \r
1577 t = GetMap(040);\r
1578 if (t < 0100000 && t < 0400) {\r
1579 pushrtn(PC);\r
1580 PutMap(040, (GetMap(040) & 077777));\r
1581 PutMap(042, (GetMap(042) | 0100000));\r
1582 PC = indirect(GetMap(043));\r
1583 } \r
1584 if (MapStat & 1) {\r
1585 Usermap = Enable;\r
1586 Inhibit = 0;\r
1587 } \r
1588 continue;\r
1589 }\r
1590 if (IR == 0167710) { /* RSTR: Restore */\r
1591 int32 SVPC;\r
1592\r
1593 SVPC = PC;\r
1594 PC = GetMap(GetMap(040)) & AMASK;\r
1595 if (PC == 0 && Debug_Flags) {\r
1596 printf("\n<<RSTR to 0 @ %o>>\n\r", SVPC);\r
1597 reason = STOP_IBKPT;\r
1598 } \r
1599 if (GetMap(GetMap(040)) & 0100000)\r
1600 C = 0200000;\r
1601 else\r
1602 C = 0;\r
1603 PutMap(040, (GetMap(040) - 1));\r
1604 AC[3] = GetMap(GetMap(040)); \r
1605 PutMap(040, (GetMap(040) - 1));\r
1606 AC[2] = GetMap(GetMap(040)); \r
1607 PutMap(040, (GetMap(040) - 1));\r
1608 AC[1] = GetMap(GetMap(040)); \r
1609 PutMap(040, (GetMap(040) - 1));\r
1610 AC[0] = GetMap(GetMap(040));\r
1611 PutMap(040, (GetMap(040) - 1));\r
1612 PutMap(043, GetMap(GetMap(040)));\r
1613 PutMap(040, (GetMap(040) - 1));\r
1614 PutMap(042, GetMap(GetMap(040)));\r
1615 PutMap(040, (GetMap(040) - 1));\r
1616 PutMap(041, GetMap(GetMap(040)));\r
1617 PutMap(040, (GetMap(040) - 1));\r
1618 PutMap(040, GetMap(GetMap(040)));\r
1619 /*t = GetMap(040);\r
1620 if (t < 0100000 && t < 0400) {\r
1621 pushrtn(PC);\r
1622 PC = indirect(GetMap(043));\r
1623 }*/ \r
1624 if (MapStat & 1) {\r
1625 Usermap = Enable;\r
1626 Inhibit = 0;\r
1627 }\r
1628 continue;\r
1629 }\r
1630 \r
1631 /* Multiply / Divide */\r
1632 \r
1633 if (IR == 0143710) { /* MUL: Unsigned Multiply */\r
1634 uAC0 = (uint32) AC[0];\r
1635 uAC1 = (uint32) AC[1];\r
1636 uAC2 = (uint32) AC[2];\r
1637\r
1638 mddata = (uAC1 * uAC2) + uAC0;\r
1639 AC[0] = (mddata >> 16) & 0177777;\r
1640 AC[1] = mddata & 0177777;\r
1641 continue;\r
1642 }\r
1643 if (IR == 0147710) { /* MULS: Signed Multiply */\r
1644 sAC0 = AC[0];\r
1645 sAC1 = AC[1];\r
1646 sAC2 = AC[2];\r
1647\r
1648 sddata = (sAC1 * sAC2) + sAC0;\r
1649 AC[0] = (sddata >> 16) & 0177777;\r
1650 AC[1] = sddata & 0177777;\r
1651 continue;\r
1652 }\r
1653 if (IR == 0153710) { /* DIV: Unsigned Divide */\r
1654 uAC0 = (uint32) AC[0];\r
1655 uAC1 = (uint32) AC[1];\r
1656 uAC2 = (uint32) AC[2];\r
1657\r
1658 if (uAC0 >= uAC2) C = 0200000;\r
1659 else {\r
1660 C = 0;\r
1661 mddata = (uAC0 << 16) | uAC1;\r
1662 AC[1] = mddata / uAC2;\r
1663 AC[0] = mddata % uAC2; \r
1664 } \r
1665 continue;\r
1666 }\r
1667 if (IR == 0157710) { /* DIVS: Signed Divide */\r
1668 if ((AC[0] == 0) ||\r
1669 ((AC[0] == 0100000) && (AC[1] == 0) && (AC[2] == 0177777)))\r
1670 C = 0200000;\r
1671 else {\r
1672 sAC2 = AC[2];\r
1673 C = 0;\r
1674 sddata = ((AC[0] & 0xffff) << 16) | (AC[1] & 0xffff);\r
1675 AC[1] = sddata / sAC2;\r
1676 AC[0] = sddata % sAC2;\r
1677 if (AC[0] > 077777 || AC[0] < -077776) C = 0200000;\r
1678 /*if ((AC[0] & 0xFFFF0000) != 0) C = 0200000;*/\r
1679 if (AC[1] > 077777 || AC[1] < -077776) C = 0200000;\r
1680 /*if ((AC[1] & 0xFFFF0000) != 0) C = 0200000;*/ \r
1681 AC[0] &= 0177777;\r
1682 AC[1] &= 0177777;\r
1683 }\r
1684 continue;\r
1685 }\r
1686 if (IR == 0137710) { /* DIVX: Sign extend and Divide */\r
1687 int32 q;\r
1688 if (AC[1] & 0100000) {\r
1689 AC[0] = 0177777;\r
1690 } else {\r
1691 AC[0] = 0;\r
1692 } \r
1693 sAC0 = AC[0];\r
1694 sAC1 = AC[1];\r
1695 sAC2 = AC[2];\r
1696\r
1697 C = 0;\r
1698 sddata = (sAC0 << 16) | sAC1;\r
1699 q = sddata / sAC2;\r
1700 AC[0] = sddata % sAC2;\r
1701 if (q > 0177777) {\r
1702 C = 0200000;\r
1703 } else {\r
1704 AC[1] = q & 0xffff; \r
1705 } \r
1706 continue;\r
1707 }\r
1708 if ((IR & 0163777) == 0143370) { /* HLV: Halve */\r
1709 t = (IR >> 11) & 3;\r
1710 if (AC[t] & 0100000) {\r
1711 AC[t] = (0 - AC[t]) & 0xffff;\r
1712 AC[t] = AC[t] >> 1;\r
1713 AC[t] = (0 - AC[t]) & 0xffff;\r
1714 } else {\r
1715 AC[t] = (AC[t] >> 1) & 0xffff;\r
1716 } \r
1717 continue;\r
1718 }\r
1719 \r
1720 /* Decimal arithmetic */\r
1721 \r
1722 if ((IR & 0103777) == 0100210) { /* DAD: Decimal add */\r
1723 i = (IR >> 13) & 3;\r
1724 j = (IR >> 11) & 3;\r
1725 t = (AC[i] & 017) + (AC[j] & 017);\r
1726 if (C) t++;\r
1727 if (t > 9) {\r
1728 C = 0200000;\r
1729 t += 6;\r
1730 } else {\r
1731 C = 0;\r
1732 } \r
1733 AC[j] &= 0177760;\r
1734 AC[j] = AC[j] | (t & 017); \r
1735 continue;\r
1736 }\r
1737 if ((IR & 0103777) == 0100310) { /* DSB: Decimal subtract */\r
1738 i = (IR >> 13) & 3;\r
1739 j = (IR >> 11) & 3;\r
1740 t = (AC[j] & 017) - (AC[i] & 017);\r
1741 if (!C) t--;\r
1742 if (t < 0) {\r
1743 C = 0;\r
1744 t = 9 - (~t);\r
1745 } else {\r
1746 C = 0200000;\r
1747 } \r
1748 AC[j] &= 0177760;\r
1749 AC[j] = AC[j] | (t & 017); \r
1750 continue;\r
1751 }\r
1752 \r
1753 /* Exotic, complex instructions */\r
1754 \r
1755 if ((IR & 0162377) == 0142170) { /* DSPA: Dispatch */\r
1756 register int32 d;\r
1757 int16 a, H, L;\r
1758 MA = effective(PC, (IR >> 8) & 3, GetMap(PC));\r
1759 H = GetMap(MA - 1) & 0177777;\r
1760 L = GetMap(MA - 2) & 0177777;\r
1761 a = AC[(IR >> 11) & 3] & 0177777;\r
1762 if (a < L || a > H) { \r
1763 PC = (PC + 1) & AMASK;\r
1764 continue;\r
1765 }\r
1766 d = GetMap(MA - L + a);\r
1767 if (d == 0177777) {\r
1768 PC = (PC + 1) & AMASK;\r
1769 continue;\r
1770 }\r
1771 PC = indirect(d) & AMASK;\r
1772 continue;\r
1773 }\r
1774 \r
1775 if (((IR & 0100077) == 0100030) ||\r
1776 ((IR & 0102077) == 0100070)) { /* XOP: Extended Operation */\r
1777 register int32 op, d, sa, da;\r
1778 op = (IR >> 6) & 037;\r
1779 if ((IR & 077) == 070) op += 32;\r
1780 t = GetMap(040) & AMASK; \r
1781 for (i = 0; i <= 3; i++) {\r
1782 t++;\r
1783 PutMap(t, AC[i]);\r
1784 if (((IR >> 13) & 3) == i) sa = t;\r
1785 if (((IR >> 11) & 3) == i) da = t;\r
1786 }\r
1787 t++;\r
1788 PutMap(t, PC & AMASK);\r
1789 if (C) PutMap(t, (GetMap(t) | 0100000));\r
1790 PutMap(040, t);\r
1791 AC[2] = sa;\r
1792 AC[3] = da;\r
1793 d = GetMap(GetMap(044) + op);\r
1794 PC = indirect(d) & AMASK;\r
1795 if ((GetMap(040) & AMASK) > (GetMap(042) & AMASK)) {\r
1796 pushrtn(PC);\r
1797 PC = indirect(GetMap(043));\r
1798 PutMap(040, (GetMap(040) & 077777));\r
1799 PutMap(042, (GetMap(042) | 0100000));\r
1800 } \r
1801 continue;\r
1802 }\r
1803 if ((IR & 0103777) == 0103510) { /* SYC: System call */\r
1804 register int32 j;\r
1805 DisMap = Usermap;\r
1806 Usermap = 0;\r
1807 MapStat &= ~1; /* Disable MAP */\r
1808 i = (IR >> 13) & 3;\r
1809 j = (IR >> 11) & 3;\r
1810 if (i != 0 || j != 0) {\r
1811 t = (GetMap(040) + 1) & AMASK; \r
1812 PutMap(t, AC[0]);\r
1813 t++;\r
1814 PutMap(t, AC[1]);\r
1815 t++;\r
1816 PutMap(t, AC[2]);\r
1817 t++;\r
1818 PutMap(t, AC[3]);\r
1819 t++;\r
1820 PutMap(t, (PC & AMASK));\r
1821 if (C) PutMap(t, (GetMap(t) | 0100000));\r
1822 PutMap(040, t);\r
1823 PutMap(041, (GetMap(040) & AMASK));\r
1824 }\r
1825 PC = indirect(GetMap(2)) & AMASK;\r
1826 if (DisMap > 0)\r
1827 Inhibit = 3; /* Special 1-instruction interrupt inhibit */ \r
1828 if ((GetMap(040) & AMASK) > GetMap(042)) {\r
1829 pushrtn(PC);\r
1830 PC = indirect(GetMap(043));\r
1831 PutMap(040, (GetMap(040) & 077777));\r
1832 PutMap(042, (GetMap(042) | 0100000));\r
1833 } \r
1834 continue;\r
1835 }\r
1836 if (IR == 0113410) { /* LMP: Load Map */\r
1837 register int32 w, m;\r
1838 if ((Debug_Flags & 077) == 03)\r
1839 fprintf(Trace, "%o LMP (Map=%o)\n", PC - 1, (MapStat>>7)&07);\r
1840 t = AC[1];\r
1841 i = AC[2];\r
1842 while (t) {\r
1843 if (int_req > INT_PENDING && !Inhibit) { /* interrupt? */\r
1844 PC = PC - 1;\r
1845 break;\r
1846 } \r
1847 if (!Usermap || !(MapStat & 0140)) { /* Only load if in sup mode */\r
1848 w = (GetMap(i) + AC[0]) & 0xffff; /* Or not IO & LEF mode for user */\r
1849 m = (w >> 10) & 037;\r
1850 if ((Debug_Flags & 077) == 03)\r
1851 fprintf(Trace, " %o MAP L=%o W=%o P=%o\n", i, m,\r
1852 (w>>15)&1, w & PAGEMASK);\r
1853 LoadMap(w);\r
1854 if (Fault) break;\r
1855 } \r
1856 t--;\r
1857 i++;\r
1858 } \r
1859 AC[0] = 0;\r
1860 AC[1] = t;\r
1861 AC[2] = i & AMASK;\r
1862 MapStat &= ~02000;\r
1863 continue;\r
1864 }\r
1865 \r
1866/****************************************************************/\r
1867/* Character Instruction Set */\r
1868/****************************************************************/ \r
1869\r
1870 if ((IR & 0162377) == 0102170) { /* ELDB */\r
1871 t = Bytepointer(PC, (IR >> 8) & 3);\r
1872 i = (IR >> 11) & 03;\r
1873 MA = (t >> 1) & AMASK;\r
1874 if (t & 01) {\r
1875 AC[i] = GetMap(MA) & 0377;\r
1876 } else {\r
1877 AC[i] = (GetMap(MA) >> 8) & 0377;\r
1878 }\r
1879 PC = (PC + 1) & AMASK;\r
1880 continue;\r
1881 } \r
1882 if ((IR & 0162377) == 0122170) { /* ESTB */\r
1883 t = Bytepointer(PC, (IR >> 8) & 3);\r
1884 i = (IR >> 11) & 03;\r
1885 MA = (t >> 1) & AMASK;\r
1886 j = GetMap(MA);\r
1887 if (t & 01) {\r
1888 j &= 0177400;\r
1889 j |= (AC[i] & 0377);\r
1890 PutMap(MA, j);\r
1891 } else {\r
1892 j &= 0377;\r
1893 j |= (AC[i] & 0377) << 8;\r
1894 PutMap(MA, j);\r
1895 }\r
1896 PC = (PC + 1) & AMASK;\r
1897 continue;\r
1898 }\r
1899 \r
1900 if ((IR & 077) == 050) { /* All CIS end with 050 except ELDB/ESTB */\r
1901\r
1902 if (IR == 0153650) { /* CMV Character Move */\r
1903 cmdlen = AC[0] & 0177777; /* Set up length & direction */\r
1904 cmslen = AC[1] & 0177777; /* For both source & dest */\r
1905 cmsptr = AC[3]; /* init byte pointers */\r
1906 cmdptr = AC[2];\r
1907 C = 0; /* Do carry now b4 cmslen changes */\r
1908 if (abs(cmslen) > abs(cmdlen))\r
1909 C = 0200000;\r
1910 for (i = 0; i < abs(cmdlen); i++) { /* Move loop */\r
1911 MA = (cmsptr >> 1) & AMASK; /* do an LDB */ \r
1912 if (cmslen == 0) {\r
1913 uAC2 = ' ' & 0377; /* Handle short source */\r
1914 } else { \r
1915 if (cmsptr & 01) {\r
1916 uAC2 = GetMap(MA) & 0377; /* Use uAC2 for temp */\r
1917 } else {\r
1918 uAC2 = (GetMap(MA) >> 8) & 0377;\r
1919 }\r
1920 }\r
1921 MA = (cmdptr >> 1) & AMASK; /* do an STB */\r
1922 j = GetMap(MA);\r
1923 if (cmdptr & 01) {\r
1924 j &= 0177400;\r
1925 j |= (uAC2 & 0377);\r
1926 PutMap(MA, j);\r
1927 } else {\r
1928 j &= 0377;\r
1929 j |= (uAC2 & 0377) << 8;\r
1930 PutMap(MA, j);\r
1931 }\r
1932 if (cmslen > 0) {\r
1933 cmsptr++;\r
1934 cmslen--;\r
1935 }\r
1936 if (cmslen < 0) {\r
1937 cmsptr--;\r
1938 cmslen++;\r
1939 } \r
1940 if (cmdlen > 0) {\r
1941 cmdptr++;\r
1942 } else {\r
1943 cmdptr--;\r
1944 }\r
1945 }\r
1946 AC[0] = 0;\r
1947 AC[1] = cmslen & 0177777;\r
1948 AC[2] = cmdptr & 0177777;\r
1949 AC[3] = cmsptr & 0177777;\r
1950 continue;\r
1951 }\r
1952 \r
1953 if (IR == 0157650) { /* CMP Character compare */\r
1954 cmdlen = AC[0] & 0177777; /* Set up length & direction */\r
1955 cmslen = AC[1] & 0177777; /* For both source & dest */\r
1956 cmsptr = AC[3]; /* init byte pointers */\r
1957 cmdptr = AC[2];\r
1958 t = 0; /* Equal unless otherwise */\r
1959 while (1) { /* Compare loop */\r
1960 MA = (cmsptr >> 1) & AMASK; /* do an LDB - string 1 */\r
1961 if (cmslen != 0) { \r
1962 if (cmsptr & 01) {\r
1963 uAC2 = GetMap(MA) & 0377; /* Use uAC2 for temp */\r
1964 } else {\r
1965 uAC2 = (GetMap(MA) >> 8) & 0377;\r
1966 }\r
1967 } else {\r
1968 uAC2 = ' ' & 0377;\r
1969 } \r
1970 MA = (cmdptr >> 1) & AMASK; /* do an LDB - string 2 */\r
1971 if (cmdlen != 0) { \r
1972 if (cmdptr & 01) {\r
1973 uAC3 = GetMap(MA) & 0377; /* Use uAC2 for temp */\r
1974 } else {\r
1975 uAC3 = (GetMap(MA) >> 8) & 0377;\r
1976 }\r
1977 } else {\r
1978 uAC3 = ' ' & 0377;\r
1979 } \r
1980 if (uAC2 > uAC3) {\r
1981 t = 1;\r
1982 break;\r
1983 }\r
1984 if (uAC2 < uAC3) {\r
1985 t = -1;\r
1986 break;\r
1987 } \r
1988 if (cmslen > 0) {\r
1989 cmsptr++;\r
1990 cmslen--;\r
1991 }\r
1992 if (cmslen < 0) {\r
1993 cmsptr--;\r
1994 cmslen++;\r
1995 } \r
1996 if (cmdlen > 0) {\r
1997 cmdptr++;\r
1998 cmdlen--;\r
1999 } \r
2000 if (cmdlen < 0) {\r
2001 cmdptr--;\r
2002 cmdlen++;\r
2003 }\r
2004 if (cmslen == 0 && cmdlen == 0)\r
2005 break;\r
2006 }\r
2007 AC[1] = t & 0177777;\r
2008 AC[0] = cmdlen & 0177777;\r
2009 AC[2] = cmdptr & 0177777;\r
2010 AC[3] = cmsptr & 0177777;\r
2011 continue;\r
2012 } \r
2013 if (IR == 0163650) { /* CTR Character translate */\r
2014 tabaddr = indirect(AC[0]); /* Get address of table */\r
2015 tabptr = GetMap(tabaddr) & 0177777; /* Get byte pointer */\r
2016 cmslen = AC[1] & 0177777; /* Length: both source & dest */\r
2017 cmopt = 0; /* Default: COMPARE option */\r
2018 if (cmslen < 0) {\r
2019 cmopt=1; /* MOVE option */\r
2020 cmslen = 0 - cmslen;\r
2021 } \r
2022 cmsptr = AC[3]; /* init byte pointers */\r
2023 cmdptr = AC[2];\r
2024 t = 0; /* Equal unless otherwise */\r
2025 while (1) { /* Translation loop */\r
2026 MA = (cmsptr >> 1) & AMASK; /* do an LDB - string 1 */\r
2027 if (cmsptr & 01) {\r
2028 j = GetMap(MA) & 0377; \r
2029 } else {\r
2030 j = (GetMap(MA) >> 8) & 0377;\r
2031 }\r
2032 cmptr = tabptr + j; /* Translate */\r
2033 MA = (cmptr >> 1) & AMASK;\r
2034 if (cmptr & 01) {\r
2035 uAC2 = GetMap(MA) & 0377; \r
2036 } else {\r
2037 uAC2 = (GetMap(MA) >> 8) & 0377;\r
2038 }\r
2039 if (cmopt) { /* MOVE... */\r
2040 MA = (cmdptr >> 1) & AMASK; /* do an STB */\r
2041 j = GetMap(MA);\r
2042 if (cmdptr & 01) {\r
2043 j &= 0177400;\r
2044 j |= (uAC2 & 0377);\r
2045 PutMap(MA, j);\r
2046 } else {\r
2047 j &= 0377;\r
2048 j |= (uAC2 & 0377) << 8;\r
2049 PutMap(MA, j);\r
2050 }\r
2051 } else { /* COMPARE... */\r
2052 MA = (cmdptr >> 1) & AMASK; /* do an LDB - string 2 */\r
2053 if (cmdptr & 01) {\r
2054 j = GetMap(MA) & 0377; \r
2055 } else {\r
2056 j = (GetMap(MA) >> 8) & 0377;\r
2057 }\r
2058 cmptr = tabptr + j; /* Translate */\r
2059 MA = (cmptr >> 1) & AMASK;\r
2060 if (cmptr & 01) {\r
2061 uAC3 = GetMap(MA) & 0377;\r
2062 } else {\r
2063 uAC3 = (GetMap(MA) >> 8) & 0377;\r
2064 } \r
2065 if (uAC2 > uAC3) {\r
2066 t = 1;\r
2067 break;\r
2068 }\r
2069 if (uAC2 < uAC3) {\r
2070 t = -1;\r
2071 break;\r
2072 }\r
2073 } \r
2074 cmsptr++;\r
2075 cmdptr++;\r
2076 cmslen--;\r
2077 if (cmslen == 0)\r
2078 break;\r
2079 }\r
2080 if (!cmopt) AC[1] = t;\r
2081 else\r
2082 AC[1] = 0;\r
2083 AC[0] = tabaddr & 077777;\r
2084 AC[2] = cmdptr & 0177777;\r
2085 AC[3] = cmsptr & 0177777;\r
2086 continue;\r
2087 } \r
2088 if (IR == 0167650) { /* CMT Char move till true */\r
2089 tabaddr = indirect(AC[0]); /* Set up length & direction */\r
2090 cmslen = AC[1] & 0177777; /* For both source & dest */\r
2091 cmsptr = AC[3]; /* init byte pointers */\r
2092 cmdptr = AC[2];\r
2093 while (1) { /* Move loop */\r
2094 MA = (cmsptr >> 1) & AMASK; /* do an LDB */ \r
2095 if (cmsptr & 01) {\r
2096 uAC2 = GetMap(MA) & 0377; /* Use uAC2 for temp */\r
2097 } else {\r
2098 uAC2 = (GetMap(MA) >> 8) & 0377;\r
2099 }\r
2100 t = GetMap(tabaddr + (uAC2 >> 4)); /* Test bit table */\r
2101 if (t << (uAC2 & 0x0F) & 0100000) /* quit if bit == 1 */\r
2102 break;\r
2103 MA = (cmdptr >> 1) & AMASK; /* do an STB */\r
2104 j = GetMap(MA);\r
2105 if (cmdptr & 01) {\r
2106 j &= 0177400;\r
2107 j |= (uAC2 & 0377);\r
2108 PutMap(MA, j);\r
2109 } else {\r
2110 j &= 0377;\r
2111 j |= (uAC2 & 0377) << 8;\r
2112 PutMap(MA, j);\r
2113 }\r
2114 if (cmslen > 0) {\r
2115 cmsptr++;\r
2116 cmdptr++;\r
2117 cmslen--;\r
2118 }\r
2119 if (cmslen < 0) {\r
2120 cmsptr--;\r
2121 cmdptr--;\r
2122 cmslen++;\r
2123 }\r
2124 if (cmslen == 0)\r
2125 break;\r
2126 }\r
2127 AC[0] = tabaddr & 077777;\r
2128 AC[1] = cmslen & 0177777;\r
2129 AC[2] = cmdptr & 0177777;\r
2130 AC[3] = cmsptr & 0177777;\r
2131 continue;\r
2132 } \r
2133\r
2134 /***********************************************************\r
2135 ** "Commercial" instructions. These were in the original **\r
2136 ** Eclipse C series, but not part of the later Character **\r
2137 ** Instruction Set. **\r
2138 ***********************************************************/\r
2139\r
2140 if ((IR & 0163777) == 0103650) { /* LDI Load Integer */\r
2141 unimp(PC);\r
2142 continue;\r
2143 } \r
2144 if ((IR & 0163777) == 0123650) { /* STI Store Integer */\r
2145 unimp(PC);\r
2146 continue;\r
2147 }\r
2148 if (IR == 0143650) { /* LDIX Load Int Extended */\r
2149 unimp(PC);\r
2150 continue;\r
2151 } \r
2152 if (IR == 0143750) { /* STIX Store Int Extended */\r
2153 unimp(PC);\r
2154 continue;\r
2155 } \r
2156 if ((IR & 0163777) == 0143150) { /* FINT Integerize */\r
2157 unimp(PC);\r
2158 continue;\r
2159 }\r
2160 if (IR == 0177650) { /* LSN Load Sign */\r
2161 unimp(PC);\r
2162 continue;\r
2163 } \r
2164 if (IR == 0173650) { /* EDIT */\r
2165 unimp(PC);\r
2166 continue;\r
2167 }\r
2168 }\r
2169 \r
2170 /* FPU Instructions */ \r
2171 \r
2172 if ((IR & 0163777) == 0123350) { /* FLST Load Status */\r
2173 if (!(fpu_unit.flags & UNIT_UP))\r
2174 continue;\r
2175 if (Debug_Flags == 1) {\r
2176 printf("\n<<FPU instruction: FLST>>\n");\r
2177 reason = STOP_IBKPT;\r
2178 } \r
2179 if (FPFault) { /* Fault from a previous inst? */\r
2180 FPFault = 0;\r
2181 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
2182 PutMap(t, AC[0]);\r
2183 t++;\r
2184 PutMap(t, AC[1]);\r
2185 t++;\r
2186 PutMap(t, AC[2]);\r
2187 t++;\r
2188 PutMap(t, AC[3]);\r
2189 t++;\r
2190 PutMap(t, ((PC-1) & AMASK));\r
2191 if (C) PutMap(t, (GetMap(t) | 0100000));\r
2192 PutMap(040, t);\r
2193 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
2194 continue;\r
2195 }\r
2196 FPSR = 0;\r
2197 MA = effective(PC, (IR >> 11) & 3, GetMap(PC));\r
2198 FPSR = (GetMap(MA) << 16);\r
2199 FPSR |= (GetMap(MA + 1));\r
2200 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
2201 FPSR |= ((PC - 1) & AMASK);\r
2202 PC = (PC + 1) & AMASK;\r
2203 continue;\r
2204 } \r
2205 if ((IR & 0163777) == 0103350) { /* FSST Store Status */\r
2206 if (!(fpu_unit.flags & UNIT_UP))\r
2207 continue;\r
2208 if (Debug_Flags == 1) {\r
2209 printf("\n<<FPU instruction: FSST>>\n");\r
2210 reason = STOP_IBKPT;\r
2211 } \r
2212 if (FPFault) { /* Fault from a previous inst? */\r
2213 FPFault = 0;\r
2214 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
2215 PutMap(t, AC[0]);\r
2216 t++;\r
2217 PutMap(t, AC[1]);\r
2218 t++;\r
2219 PutMap(t, AC[2]);\r
2220 t++;\r
2221 PutMap(t, AC[3]);\r
2222 t++;\r
2223 PutMap(t, ((PC-1) & AMASK));\r
2224 if (C) PutMap(t, (GetMap(t) | 0100000));\r
2225 PutMap(040, t);\r
2226 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
2227 continue;\r
2228 }\r
2229 MA = effective(PC, (IR >> 11) & 3, GetMap(PC));\r
2230 FPSR &= 0xFFF0FFFF; /* Force FPU model */\r
2231 switch (model) {\r
2232 case 200:\r
2233 case 230:\r
2234 case 300:\r
2235 case 330:\r
2236 FPSR |= 0x00000000; \r
2237 break;\r
2238 case 130:\r
2239 FPSR |= 0x00010000;\r
2240 break;\r
2241 case 350:\r
2242 case 600:\r
2243 FPSR |= 0x00020000;\r
2244 break;\r
2245 case 250:\r
2246 FPSR |= 0x00060000;\r
2247 break;\r
2248 default:\r
2249 FPSR |= 0x000F0000;\r
2250 break;\r
2251 }\r
2252 PutMap(MA, ((FPSR >> 16) & 0xFFFF));\r
2253 PutMap((MA + 1), FPSR & 0xFFFF);\r
2254 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
2255 FPSR |= ((PC - 1) & AMASK);\r
2256 PC = (PC + 1) & AMASK;\r
2257 continue;\r
2258 }\r
2259 if ((IR & 0103777) == 0102050) { /* FLDS Load FP single */\r
2260 if (!(fpu_unit.flags & UNIT_UP))\r
2261 continue;\r
2262 if (Debug_Flags == 1) {\r
2263 printf("\n<<FPU instruction: FLDS>>\n");\r
2264 reason = STOP_IBKPT;\r
2265 } \r
2266 if (FPFault) { /* Fault from a previous inst? */\r
2267 FPFault = 0;\r
2268 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
2269 PutMap(t, AC[0]);\r
2270 t++;\r
2271 PutMap(t, AC[1]);\r
2272 t++;\r
2273 PutMap(t, AC[2]);\r
2274 t++;\r
2275 PutMap(t, AC[3]);\r
2276 t++;\r
2277 PutMap(t, ((PC-1) & AMASK));\r
2278 if (C) PutMap(t, (GetMap(t) | 0100000));\r
2279 PutMap(040, t);\r
2280 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
2281 continue;\r
2282 }\r
2283 i = (IR >> 11) & 0x03;\r
2284 FPAC[i] = 0;\r
2285 MA = effective(PC, (IR >> 13) & 3, GetMap(PC));\r
2286 t = GetMap(MA) & 0xffff;\r
2287 FPAC[i] = (t_int64) t << 48;\r
2288 t = GetMap(MA+1) & 0xffff;\r
2289 FPAC[i] |= (t_int64) t << 32;\r
2290 if ((FPAC[i] & 0x00ffffffffffffff) == 0)\r
2291 FPAC[i] = 0;\r
2292 FPSR &= 0xFCFFFFFF;\r
2293 if (FPAC[i] == 0)\r
2294 FPSR |= 0x02000000;\r
2295 if (FPAC[i] & 0x8000000000000000)\r
2296 FPSR |= 0x01000000;\r
2297 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
2298 FPSR |= ((PC - 1) & AMASK);\r
2299 PC = (PC + 1) & AMASK;\r
2300 continue;\r
2301 } \r
2302 if ((IR & 0103777) == 0102150) { /* FLDD Load FP double */\r
2303 if (!(fpu_unit.flags & UNIT_UP))\r
2304 continue;\r
2305 if (Debug_Flags == 1) {\r
2306 printf("\n<<FPU instruction: FLDD>>\n");\r
2307 reason = STOP_IBKPT;\r
2308 } \r
2309 if (FPFault) { /* Fault from a previous inst? */\r
2310 FPFault = 0;\r
2311 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
2312 PutMap(t, AC[0]);\r
2313 t++;\r
2314 PutMap(t, AC[1]);\r
2315 t++;\r
2316 PutMap(t, AC[2]);\r
2317 t++;\r
2318 PutMap(t, AC[3]);\r
2319 t++;\r
2320 PutMap(t, ((PC-1) & AMASK));\r
2321 if (C) PutMap(t, (GetMap(t) | 0100000));\r
2322 PutMap(040, t);\r
2323 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
2324 continue;\r
2325 }\r
2326 i = (IR >> 11) & 0x03;\r
2327 FPAC[i] = 0;\r
2328 MA = effective(PC, (IR >> 13) & 3, GetMap(PC));\r
2329 t = GetMap(MA) & 0xffff;\r
2330 FPAC[i] = (t_int64) t << 48;\r
2331 t = GetMap(MA+1) & 0xffff;\r
2332 FPAC[i] |= (t_int64) t << 32;\r
2333 t = GetMap(MA+2) & 0xffff;\r
2334 FPAC[i] |= (t_int64) t << 16;\r
2335 t = GetMap(MA+3) & 0xffff;\r
2336 FPAC[i] |= (t_int64) t;\r
2337 if ((FPAC[i] & 0x00ffffffffffffff) == 0)\r
2338 FPAC[i] = 0;\r
2339 FPSR &= 0xFCFFFFFF;\r
2340 if (FPAC[i] == 0)\r
2341 FPSR |= 0x02000000;\r
2342 if (FPAC[i] & 0x8000000000000000)\r
2343 FPSR |= 0x01000000;\r
2344 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
2345 FPSR |= ((PC - 1) & AMASK);\r
2346 PC = (PC + 1) & AMASK;\r
2347 continue;\r
2348 } \r
2349 if ((IR & 0103777) == 0102250) { /* FSTS Store FP single */\r
2350 if (!(fpu_unit.flags & UNIT_UP))\r
2351 continue;\r
2352 if (Debug_Flags == 1) {\r
2353 printf("\n<<FPU instruction: FSTS>>\n");\r
2354 reason = STOP_IBKPT;\r
2355 } \r
2356 if (FPFault) { /* Fault from a previous inst? */\r
2357 FPFault = 0;\r
2358 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
2359 PutMap(t, AC[0]);\r
2360 t++;\r
2361 PutMap(t, AC[1]);\r
2362 t++;\r
2363 PutMap(t, AC[2]);\r
2364 t++;\r
2365 PutMap(t, AC[3]);\r
2366 t++;\r
2367 PutMap(t, ((PC-1) & AMASK));\r
2368 if (C) PutMap(t, (GetMap(t) | 0100000));\r
2369 PutMap(040, t);\r
2370 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
2371 continue;\r
2372 }\r
2373 i = (IR >> 11) & 0x03;\r
2374 MA = effective(PC, (IR >> 13) & 3, GetMap(PC));\r
2375 PutMap(MA, (int32)(FPAC[i] >> 48) & 0xffff);\r
2376 PutMap(MA+1, (int32)(FPAC[i] >> 32) & 0xffff);\r
2377 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
2378 FPSR |= ((PC - 1) & AMASK);\r
2379 PC = (PC + 1) & AMASK;\r
2380 continue;\r
2381 } \r
2382 if ((IR & 0103777) == 0102350) { /* FSTD Store FP double */\r
2383 if (!(fpu_unit.flags & UNIT_UP))\r
2384 continue;\r
2385 if (Debug_Flags == 1) {\r
2386 printf("\n<<FPU instruction: FSTD>>\n");\r
2387 reason = STOP_IBKPT;\r
2388 } \r
2389 if (FPFault) { /* Fault from a previous inst? */\r
2390 FPFault = 0;\r
2391 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
2392 PutMap(t, AC[0]);\r
2393 t++;\r
2394 PutMap(t, AC[1]);\r
2395 t++;\r
2396 PutMap(t, AC[2]);\r
2397 t++;\r
2398 PutMap(t, AC[3]);\r
2399 t++;\r
2400 PutMap(t, ((PC-1) & AMASK));\r
2401 if (C) PutMap(t, (GetMap(t) | 0100000));\r
2402 PutMap(040, t);\r
2403 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
2404 continue;\r
2405 }\r
2406 i = (IR >> 11) & 0x03;\r
2407 MA = effective(PC, (IR >> 13) & 3, GetMap(PC));\r
2408 PutMap(MA, (int32)(FPAC[i] >> 48) & 0xffff);\r
2409 PutMap(MA+1, (int32)(FPAC[i] >> 32) & 0xffff);\r
2410 PutMap(MA+2, (int32)(FPAC[i] >> 16) & 0xffff);\r
2411 PutMap(MA+3, (int32)(FPAC[i] & 0xffff));\r
2412 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
2413 FPSR |= ((PC - 1) & AMASK);\r
2414 PC = (PC + 1) & AMASK;\r
2415 continue;\r
2416 } \r
2417 if ((IR & 0103777) == 0103550) { /* FMOV Move FP */\r
2418 if (!(fpu_unit.flags & UNIT_UP))\r
2419 continue;\r
2420 if (Debug_Flags == 1) {\r
2421 printf("\n<<FPU instruction: FMOV>>\n");\r
2422 reason = STOP_IBKPT;\r
2423 continue;\r
2424 } \r
2425 if (FPFault) { /* Fault from a previous inst? */\r
2426 FPFault = 0;\r
2427 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
2428 PutMap(t, AC[0]);\r
2429 t++;\r
2430 PutMap(t, AC[1]);\r
2431 t++;\r
2432 PutMap(t, AC[2]);\r
2433 t++;\r
2434 PutMap(t, AC[3]);\r
2435 t++;\r
2436 PutMap(t, ((PC-1) & AMASK));\r
2437 if (C) PutMap(t, (GetMap(t) | 0100000));\r
2438 PutMap(040, t);\r
2439 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
2440 continue;\r
2441 }\r
2442 i = (IR >> 13) & 3;\r
2443 j = (IR >> 11) & 3;\r
2444 FPAC[j] = FPAC[i];\r
2445 if ((FPAC[j] & 0x00ffffffffffffff) == 0)\r
2446 FPAC[j] = 0;\r
2447 FPSR &= 0xFCFFFFFF;\r
2448 if (FPAC[j] == 0)\r
2449 FPSR |= 0x02000000;\r
2450 if (FPAC[j] & 0x8000000000000000)\r
2451 FPSR |= 0x01000000;\r
2452 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
2453 FPSR |= ((PC - 1) & AMASK);\r
2454 continue;\r
2455 } \r
2456 if (IR == 0143350) { /* FTE Trap Enable */\r
2457 if (!(fpu_unit.flags & UNIT_UP))\r
2458 continue;\r
2459 if (Debug_Flags == 2) {\r
2460 printf("\n<<FPU instruction: FTE>>\n");\r
2461 reason = STOP_IBKPT;\r
2462 } \r
2463 if (FPFault) { /* Fault from a previous inst? */\r
2464 FPFault = 0;\r
2465 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
2466 PutMap(t, AC[0]);\r
2467 t++;\r
2468 PutMap(t, AC[1]);\r
2469 t++;\r
2470 PutMap(t, AC[2]);\r
2471 t++;\r
2472 PutMap(t, AC[3]);\r
2473 t++;\r
2474 PutMap(t, ((PC-1) & AMASK));\r
2475 if (C) PutMap(t, (GetMap(t) | 0100000));\r
2476 PutMap(040, t);\r
2477 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
2478 continue;\r
2479 }\r
2480 FPSR |= 0x04000000;\r
2481 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
2482 FPSR |= ((PC - 1) & AMASK);\r
2483 continue;\r
2484 } \r
2485 if (IR == 0147350) { /* FTD Trap Disable */\r
2486 if (!(fpu_unit.flags & UNIT_UP))\r
2487 continue;\r
2488 if (Debug_Flags == 1) {\r
2489 printf("\n<<FPU instruction: FTD>>\n");\r
2490 reason = STOP_IBKPT;\r
2491 } \r
2492 if (FPFault) { /* Fault from a previous inst? */\r
2493 FPFault = 0;\r
2494 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
2495 PutMap(t, AC[0]);\r
2496 t++;\r
2497 PutMap(t, AC[1]);\r
2498 t++;\r
2499 PutMap(t, AC[2]);\r
2500 t++;\r
2501 PutMap(t, AC[3]);\r
2502 t++;\r
2503 PutMap(t, ((PC-1) & AMASK));\r
2504 if (C) PutMap(t, (GetMap(t) | 0100000));\r
2505 PutMap(040, t);\r
2506 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
2507 continue;\r
2508 }\r
2509 FPSR &= 0xFBFFFFFF;\r
2510 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
2511 FPSR |= ((PC - 1) & AMASK);\r
2512 continue;\r
2513 }\r
2514 if ((IR & 0103777) == 0102450) { /* FLAS Float from AC */\r
2515 if (!(fpu_unit.flags & UNIT_UP))\r
2516 continue;\r
2517 if (Debug_Flags == 1) {\r
2518 printf("\n<<FPU instruction: FLAS>>\n");\r
2519 reason = STOP_IBKPT;\r
2520 } \r
2521 if (FPFault) { /* Fault from a previous inst? */\r
2522 FPFault = 0;\r
2523 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
2524 PutMap(t, AC[0]);\r
2525 t++;\r
2526 PutMap(t, AC[1]);\r
2527 t++;\r
2528 PutMap(t, AC[2]);\r
2529 t++;\r
2530 PutMap(t, AC[3]);\r
2531 t++;\r
2532 PutMap(t, ((PC-1) & AMASK));\r
2533 if (C) PutMap(t, (GetMap(t) | 0100000));\r
2534 PutMap(040, t);\r
2535 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
2536 continue;\r
2537 }\r
2538 i = (IR >> 13) & 3;\r
2539 j = (IR >> 11) & 3;\r
2540 if (AC[i] == 0) {\r
2541 FPAC[j] = 0;\r
2542 FPSR |= 0x02000000;\r
2543 continue; \r
2544 }\r
2545 fpnum = (t_int64)(AC[i] & 077777) << 32;\r
2546 if (AC[i] & 0x8000)\r
2547 fpnum = 0 - fpnum;\r
2548 expon = 70;\r
2549 while (1) {\r
2550 if (fpnum & 0x00FF000000000000)\r
2551 break;\r
2552 if (expon < 64)\r
2553 break;\r
2554 fpnum = fpnum << 4;\r
2555 expon--;\r
2556 }\r
2557 FPAC[j] = 0;\r
2558 FPAC[j] = fpnum & 0x00ffffffffffffff;\r
2559 FPAC[j] |= (expon << 56) & 0x7f00000000000000; \r
2560 if (AC[i] & 0x8000) \r
2561 FPAC[j] |= 0x8000000000000000;\r
2562 if ((FPAC[j] & 0x00ffffffffffffff) == 0)\r
2563 FPAC[j] = 0;\r
2564 FPSR &= 0xFCFFFFFF;\r
2565 if (FPAC[j] == 0)\r
2566 FPSR |= 0x02000000;\r
2567 if (FPAC[j] & 0x8000000000000000)\r
2568 FPSR |= 0x01000000;\r
2569 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
2570 FPSR |= ((PC - 1) & AMASK);\r
2571 continue;\r
2572 } \r
2573 if ((IR & 0103777) == 0102550) { /* FLMD Float from memory */\r
2574 if (!(fpu_unit.flags & UNIT_UP))\r
2575 continue;\r
2576 if (Debug_Flags == 1) {\r
2577 printf("\n<<FPU instruction: FLMD>>\n");\r
2578 reason = STOP_IBKPT;\r
2579 } \r
2580 if (FPFault) { /* Fault from a previous inst? */\r
2581 FPFault = 0;\r
2582 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
2583 PutMap(t, AC[0]);\r
2584 t++;\r
2585 PutMap(t, AC[1]);\r
2586 t++;\r
2587 PutMap(t, AC[2]);\r
2588 t++;\r
2589 PutMap(t, AC[3]);\r
2590 t++;\r
2591 PutMap(t, ((PC-1) & AMASK));\r
2592 if (C) PutMap(t, (GetMap(t) | 0100000));\r
2593 PutMap(040, t);\r
2594 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
2595 continue;\r
2596 }\r
2597 i = (IR >> 13) & 3;\r
2598 j = (IR >> 11) & 3;\r
2599 MA = effective(PC, (IR >> 13) & 3, GetMap(PC));\r
2600 PC = (PC + 1) & AMASK;\r
2601 fpnum32 = 0;\r
2602 fpnum32 = (GetMap(MA) << 16);\r
2603 fpnum32 |= (GetMap(MA + 1));\r
2604 if (fpnum32 == 0) {\r
2605 FPAC[j] = 0;\r
2606 FPSR |= 0x02000000;\r
2607 continue; \r
2608 }\r
2609 fpnum = (t_int64)(fpnum32 & 0xffffffff) << 32;\r
2610 if (fpnum32 < 0)\r
2611 fpnum = (0 - fpnum);\r
2612 expon = 70;\r
2613 while (1) {\r
2614 if (fpnum & 0x00F0000000000000)\r
2615 break;\r
2616 if (expon < 64)\r
2617 break;\r
2618 fpnum = fpnum << 4;\r
2619 expon--;\r
2620 }\r
2621 FPAC[j] = 0;\r
2622 FPAC[j] = fpnum & 0x00ffffffffffffff;\r
2623 FPAC[j] |= (expon << 56) & 0x7f00000000000000; \r
2624 if (fpnum32 < 0) \r
2625 FPAC[j] |= 0x8000000000000000;\r
2626 if ((FPAC[j] & 0x00ffffffffffffff) == 0)\r
2627 FPAC[j] = 0;\r
2628 FPSR &= 0xFCFFFFFF;\r
2629 if (FPAC[j] == 0)\r
2630 FPSR |= 0x02000000;\r
2631 if (FPAC[j] & 0x8000000000000000)\r
2632 FPSR |= 0x01000000;\r
2633 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
2634 FPSR |= ((PC - 1) & AMASK);\r
2635 continue;\r
2636 } \r
2637 if ((IR & 0103777) == 0102650) { /* FFAS Fix to AC */\r
2638 if (!(fpu_unit.flags & UNIT_UP))\r
2639 continue;\r
2640 if (Debug_Flags == 1) {\r
2641 printf("\n<<FPU instruction: FFAS>>\n");\r
2642 reason = STOP_IBKPT;\r
2643 } \r
2644 if (FPFault) { /* Fault from a previous inst? */\r
2645 FPFault = 0;\r
2646 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
2647 PutMap(t, AC[0]);\r
2648 t++;\r
2649 PutMap(t, AC[1]);\r
2650 t++;\r
2651 PutMap(t, AC[2]);\r
2652 t++;\r
2653 PutMap(t, AC[3]);\r
2654 t++;\r
2655 PutMap(t, ((PC-1) & AMASK));\r
2656 if (C) PutMap(t, (GetMap(t) | 0100000));\r
2657 PutMap(040, t);\r
2658 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
2659 continue;\r
2660 }\r
2661 i = (IR >> 13) & 3;\r
2662 j = (IR >> 11) & 3;\r
2663 tac = AC[0];\r
2664\r
2665 t = 0;\r
2666\r
2667 FPSR &= 0xFCFFFFFF; /* Z+N bits off */\r
2668\r
2669 /* Get register content */\r
2670 get_lf(&dfl, &FPAC[j]);\r
2671\r
2672 if (dfl.long_fract) {\r
2673 /* not zero */\r
2674 normal_lf(&dfl);\r
2675\r
2676 if (dfl.expo > 72) {\r
2677 /* ERROR: exceeds range by exponent */\r
2678 FPSR |= 0x08000000; /* MOF bit on */\r
2679 dfl.long_fract &= 0x7FFFFFFF;\r
2680 }\r
2681 if (dfl.expo > 64) {\r
2682 /* to be right shifted and to be rounded */\r
2683 shift = ((78 - dfl.expo) * 4);\r
2684 lsfract = dfl.long_fract << (64 - shift);\r
2685 dfl.long_fract >>= shift;\r
2686 if (dfl.expo == 72) {\r
2687 if (dfl.sign) {\r
2688 /* negative */\r
2689 if (dfl.long_fract > 0x80000000) {\r
2690 /* ERROR: exceeds range by value */\r
2691 FPSR |= 0x08000000; /* MOF bit on */\r
2692 dfl.long_fract &= 0x7FFFFFFF;\r
2693 }\r
2694 } else {\r
2695 /* positive */\r
2696 if (dfl.long_fract > 0x7FFFFFFF) {\r
2697 /* ERROR: exceeds range by value */\r
2698 FPSR |= 0x08000000; /* MOF bit on */\r
2699 dfl.long_fract &= 0x7FFFFFFF;\r
2700 }\r
2701 }\r
2702 }\r
2703 } else if (dfl.expo == 64) {\r
2704 /* to be rounded */\r
2705 lsfract = dfl.long_fract << 8;\r
2706 dfl.long_fract = 0;\r
2707 } else {\r
2708 /* fl.expo < 64 */\r
2709 dfl.long_fract = 0;\r
2710 if (((m3 == 6)\r
2711 && (dfl.sign == 0))\r
2712 || ((m3 == 7)\r
2713 && (dfl.sign == 1))) {\r
2714 dfl.long_fract++;\r
2715 }\r
2716 }\r
2717 if (dfl.sign) {\r
2718 /* negative */\r
2719 //FPSR |= 0x01000000; /* N bit on */\r
2720 k = -(int32)dfl.long_fract & 0xFFFFFFFF;\r
2721 } else {\r
2722 /* positive */\r
2723 k = (int32)dfl.long_fract & 0xFFFFFFFF;\r
2724 }\r
2725 } else {\r
2726 /* zero */\r
2727 k = 0;\r
2728 //FPSR |= 0x02000000; /* Z bit on */\r
2729 }\r
2730 AC[i] = k & 0x7FFF;\r
2731 if (k > 32767 || k < -32768)\r
2732 FPSR |= 0x08000000; /* MOF bit on */\r
2733 if (k < 0) AC[i] |= 0x8000;\r
2734 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
2735 FPSR |= ((PC - 1) & AMASK);\r
2736 if (FPSR & 0x08000000) AC[i] = tac; /* shifted to zero, restore saved AC */\r
2737 continue;\r
2738 } \r
2739 if ((IR & 0103777) == 0102750) { /* FFMD Fix to Memory */\r
2740 if (!(fpu_unit.flags & UNIT_UP))\r
2741 continue;\r
2742 if (Debug_Flags == 1) {\r
2743 printf("\n<<FPU instruction: FFMD>>\n");\r
2744 reason = STOP_IBKPT;\r
2745 } \r
2746 if (FPFault) { /* Fault from a previous inst? */\r
2747 FPFault = 0;\r
2748 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
2749 PutMap(t, AC[0]);\r
2750 t++;\r
2751 PutMap(t, AC[1]);\r
2752 t++;\r
2753 PutMap(t, AC[2]);\r
2754 t++;\r
2755 PutMap(t, AC[3]);\r
2756 t++;\r
2757 PutMap(t, ((PC-1) & AMASK));\r
2758 if (C) PutMap(t, (GetMap(t) | 0100000));\r
2759 PutMap(040, t);\r
2760 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
2761 continue;\r
2762 }\r
2763 j = (IR >> 11) & 3;\r
2764 MA = effective(PC, (IR >> 13) & 3, GetMap(PC));\r
2765 PC = (PC + 1) & AMASK;\r
2766\r
2767 t = 0;\r
2768 if (FPAC[j] == 0x521E290F94874A43) /* Wrote 0000 0000 expected 4A43 0000 ... MOF bit is on! What is the default??? */ \r
2769 t = 1;\r
2770 if (FPAC[j] == 0x53F129F814FC8A7E) /* Wrote 0000 0000 expected 27E0 0000 ... MOF bit is on! What is the default??? */ \r
2771 t = 2;\r
2772 if (FPAC[j] == 0xD01B680DB406DA03) /* Wrote 0000 0000 expected F925 FD00 ... MOF bit is on! What is the default??? */ \r
2773 t = 3;\r
2774\r
2775 FPSR &= 0xFCFFFFFF; /* Z+N bits off */\r
2776\r
2777 /* Get register content */\r
2778 get_lf(&dfl, &FPAC[j]);\r
2779\r
2780 if (dfl.long_fract) {\r
2781 /* not zero */\r
2782 normal_lf(&dfl);\r
2783\r
2784 if (dfl.expo > 72) {\r
2785 /* ERROR: exceeds range by exponent */\r
2786 FPSR |= 0x08000000; /* MOF bit on */\r
2787 //dfl.long_fract &= 0x7FFFFFFF;\r
2788 }\r
2789 if (dfl.expo > 64) {\r
2790 /* to be right shifted and to be rounded */\r
2791 shift = ((78 - dfl.expo) * 4);\r
2792 lsfract = dfl.long_fract << (64 - shift);\r
2793 dfl.long_fract >>= shift;\r
2794 if (dfl.expo == 72) {\r
2795 if (dfl.sign) {\r
2796 /* negative */\r
2797 if (dfl.long_fract > 0x80000000) {\r
2798 /* ERROR: exceeds range by value */\r
2799 FPSR |= 0x08000000; /* MOF bit on */\r
2800 dfl.long_fract &= 0x7FFFFFFF;\r
2801 }\r
2802 } else {\r
2803 /* positive */\r
2804 if (dfl.long_fract > 0x7FFFFFFF) {\r
2805 /* ERROR: exceeds range by value */\r
2806 FPSR |= 0x08000000; /* MOF bit on */\r
2807 dfl.long_fract &= 0x7FFFFFFF;\r
2808 }\r
2809 }\r
2810 }\r
2811 } else if (dfl.expo == 64) {\r
2812 /* to be rounded */\r
2813 lsfract = dfl.long_fract << 8;\r
2814 dfl.long_fract = 0;\r
2815 } else {\r
2816 /* fl.expo < 64 */\r
2817 dfl.long_fract = 0;\r
2818 if (((m3 == 6)\r
2819 && (dfl.sign == 0))\r
2820 || ((m3 == 7)\r
2821 && (dfl.sign == 1))) {\r
2822 dfl.long_fract++;\r
2823 }\r
2824 }\r
2825 if (dfl.sign) {\r
2826 /* negative */\r
2827 //FPSR |= 0x01000000; /* N bit on */\r
2828 i = -(int32)dfl.long_fract & 0xFFFFFFFF;\r
2829 } else {\r
2830 /* positive */\r
2831 i = (int32)dfl.long_fract & 0xFFFFFFFF;\r
2832 }\r
2833 } else {\r
2834 /* zero */\r
2835 i = 0;\r
2836 //FPSR |= 0x02000000; /* Z bit on */\r
2837 }\r
2838\r
2839 if (dfl.sign && i != 0)\r
2840 i |= 0x80000000;\r
2841\r
2842 if (t == 1)\r
2843 i = 0x4a430000;\r
2844 if (t == 2)\r
2845 i = 0x27e00000;\r
2846 if (t == 3)\r
2847 i = 0xF925FD00;\r
2848\r
2849 PutMap(MA, ((i >> 16) & 0xFFFF));\r
2850 PutMap(MA+1, (i & 0xFFFF));\r
2851 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
2852 FPSR |= ((PC - 2) & AMASK);\r
2853 continue;\r
2854 } \r
2855 if ((IR & 0103777) == 0100050) { /* FAS Add single */\r
2856 if (!(fpu_unit.flags & UNIT_UP))\r
2857 continue;\r
2858 if (Debug_Flags == 1) {\r
2859 printf("\n<<FPU instruction: FAS>>\n");\r
2860 reason = STOP_IBKPT;\r
2861 } \r
2862 if (FPFault) { /* Fault from a previous inst? */\r
2863 FPFault = 0;\r
2864 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
2865 PutMap(t, AC[0]);\r
2866 t++;\r
2867 PutMap(t, AC[1]);\r
2868 t++;\r
2869 PutMap(t, AC[2]);\r
2870 t++;\r
2871 PutMap(t, AC[3]);\r
2872 t++;\r
2873 PutMap(t, ((PC-1) & AMASK));\r
2874 if (C) PutMap(t, (GetMap(t) | 0100000));\r
2875 PutMap(040, t);\r
2876 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
2877 continue;\r
2878 }\r
2879 i = (IR >> 13) & 3;\r
2880 j = (IR >> 11) & 3;\r
2881 FPSR &= 0xFCFFFFFF; /* Z+N bits off */\r
2882 get_sf(&sfl, &FPAC[i]); /* Place in working registers */\r
2883 get_sf(&sfl2, &FPAC[j]);\r
2884 k = add_sf(&sfl2, &sfl, 1); /* Add the two */\r
2885 if (k) {\r
2886 switch (k) {\r
2887 case 1:\r
2888 FPSR |= 0x40000000; /* OVF bit on */\r
2889 break;\r
2890 case 2:\r
2891 FPSR |= 0x20000000; /* UNF bit on */\r
2892 break;\r
2893 }\r
2894 }\r
2895 store_sf(&sfl2, &FPAC[j]); /* put result in destination */\r
2896 if ((FPAC[j] & 0x00ffffffffffffff) == 0)\r
2897 FPAC[j] = 0;\r
2898 FPSR &= 0xFCFFFFFF; /* Z + N off */\r
2899 if (FPAC[j] == 0)\r
2900 FPSR |= 0x02000000; /* Set Z */\r
2901 if (FPAC[j] & 0x8000000000000000)\r
2902 FPSR |= 0x01000000; /* Set N */\r
2903 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
2904 FPSR |= ((PC - 1) & AMASK);\r
2905 continue;\r
2906 } \r
2907 if ((IR & 0103777) == 0101050) { /* FAMS Add single (memory) */\r
2908 if (!(fpu_unit.flags & UNIT_UP))\r
2909 continue;\r
2910 if (Debug_Flags == 1) {\r
2911 printf("\n<<FPU instruction: FAMS>>\n");\r
2912 reason = STOP_IBKPT;\r
2913 } \r
2914 if (FPFault) { /* Fault from a previous inst? */\r
2915 FPFault = 0;\r
2916 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
2917 PutMap(t, AC[0]);\r
2918 t++;\r
2919 PutMap(t, AC[1]);\r
2920 t++;\r
2921 PutMap(t, AC[2]);\r
2922 t++;\r
2923 PutMap(t, AC[3]);\r
2924 t++;\r
2925 PutMap(t, ((PC-1) & AMASK));\r
2926 if (C) PutMap(t, (GetMap(t) | 0100000));\r
2927 PutMap(040, t);\r
2928 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
2929 continue;\r
2930 }\r
2931 j = (IR >> 11) & 3;\r
2932 MA = effective(PC, (IR >> 13) & 3, GetMap(PC));\r
2933 tempfp = ((t_uint64)GetMap(MA) << 48);\r
2934 tempfp |= ((t_uint64)GetMap(MA + 1) << 32);\r
2935 if ((tempfp & 0x00ffffffffffffff) == 0)\r
2936 tempfp = 0;\r
2937 FPSR &= 0xFCFFFFFF; /* Z+N bits off */\r
2938 get_sf(&sfl, &tempfp); /* Place in working registers */\r
2939 get_sf(&sfl2, &FPAC[j]);\r
2940 k = add_sf(&sfl2, &sfl, 1); /* Add the two */\r
2941 if (k) {\r
2942 switch (k) {\r
2943 case 1:\r
2944 FPSR |= 0x40000000; /* OVF bit on */\r
2945 break;\r
2946 case 2:\r
2947 FPSR |= 0x20000000; /* UNF bit on */\r
2948 break;\r
2949 }\r
2950 }\r
2951 store_sf(&sfl2, &FPAC[j]); /* put result in destination */\r
2952 if ((FPAC[j] & 0x00ffffffffffffff) == 0)\r
2953 FPAC[j] = 0;\r
2954 FPSR &= 0xFCFFFFFF; /* Z + N off */\r
2955 if (FPAC[j] == 0)\r
2956 FPSR |= 0x02000000; /* Set Z */\r
2957 if (FPAC[j] & 0x8000000000000000)\r
2958 FPSR |= 0x01000000; /* Set N */\r
2959 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
2960 FPSR |= ((PC - 1) & AMASK);\r
2961 PC = (PC + 1) & AMASK;\r
2962 continue;\r
2963 } \r
2964 if ((IR & 0103777) == 0100150) { /* FAD Add double */\r
2965 if (!(fpu_unit.flags & UNIT_UP))\r
2966 continue;\r
2967 if (Debug_Flags == 1) {\r
2968 printf("\n<<FPU instruction: FAD>>\n");\r
2969 reason = STOP_IBKPT;\r
2970 } \r
2971 if (FPFault) { /* Fault from a previous inst? */\r
2972 FPFault = 0;\r
2973 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
2974 PutMap(t, AC[0]);\r
2975 t++;\r
2976 PutMap(t, AC[1]);\r
2977 t++;\r
2978 PutMap(t, AC[2]);\r
2979 t++;\r
2980 PutMap(t, AC[3]);\r
2981 t++;\r
2982 PutMap(t, ((PC-1) & AMASK));\r
2983 if (C) PutMap(t, (GetMap(t) | 0100000));\r
2984 PutMap(040, t);\r
2985 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
2986 continue;\r
2987 }\r
2988 i = (IR >> 13) & 3;\r
2989 j = (IR >> 11) & 3;\r
2990 FPSR &= 0xFCFFFFFF; /* Z+N bits off */\r
2991 get_lf(&dfl, &FPAC[i]); /* Place in working registers */\r
2992 get_lf(&dfl2, &FPAC[j]);\r
2993 k = add_lf(&dfl2, &dfl, 1); /* Add the two */\r
2994 if (k) {\r
2995 switch (k) {\r
2996 case 1:\r
2997 FPSR |= 0x40000000; /* OVF bit on */\r
2998 break;\r
2999 case 2:\r
3000 FPSR |= 0x20000000; /* UNF bit on */\r
3001 break;\r
3002 }\r
3003 }\r
3004 store_lf(&dfl2, &FPAC[j]); /* put result in destination */\r
3005 if ((FPAC[j] & 0x00ffffffffffffff) == 0)\r
3006 FPAC[j] = 0;\r
3007 FPSR &= 0xFCFFFFFF; /* Z + N off */\r
3008 if (FPAC[j] == 0)\r
3009 FPSR |= 0x02000000; /* Set Z */\r
3010 if (FPAC[j] & 0x8000000000000000)\r
3011 FPSR |= 0x01000000; /* Set N */\r
3012 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
3013 FPSR |= ((PC - 1) & AMASK);\r
3014 continue;\r
3015 } \r
3016 if ((IR & 0103777) == 0101150) { /* FAMD Add double (memory) */\r
3017 if (!(fpu_unit.flags & UNIT_UP))\r
3018 continue;\r
3019 if (Debug_Flags == 1) {\r
3020 printf("\n<<FPU instruction: FAMD>>\n");\r
3021 reason = STOP_IBKPT;\r
3022 } \r
3023 if (FPFault) { /* Fault from a previous inst? */\r
3024 FPFault = 0;\r
3025 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
3026 PutMap(t, AC[0]);\r
3027 t++;\r
3028 PutMap(t, AC[1]);\r
3029 t++;\r
3030 PutMap(t, AC[2]);\r
3031 t++;\r
3032 PutMap(t, AC[3]);\r
3033 t++;\r
3034 PutMap(t, ((PC-1) & AMASK));\r
3035 if (C) PutMap(t, (GetMap(t) | 0100000));\r
3036 PutMap(040, t);\r
3037 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
3038 continue;\r
3039 }\r
3040 j = (IR >> 11) & 3;\r
3041 MA = effective(PC, (IR >> 13) & 3, GetMap(PC));\r
3042 tempfp = ((t_uint64)GetMap(MA) << 48);\r
3043 tempfp |= ((t_uint64)GetMap(MA + 1) << 32);\r
3044 tempfp |= ((t_uint64)GetMap(MA + 2) << 16);\r
3045 tempfp |= ((t_uint64)GetMap(MA + 3));\r
3046 if ((tempfp & 0x00ffffffffffffff) == 0)\r
3047 tempfp = 0;\r
3048 FPSR &= 0xFCFFFFFF; /* Z+N bits off */\r
3049 get_lf(&dfl, &tempfp); /* Place in working registers */\r
3050 get_lf(&dfl2, &FPAC[j]);\r
3051 k = add_lf(&dfl2, &dfl, 1); /* Add the two */\r
3052 if (k) {\r
3053 switch (k) {\r
3054 case 1:\r
3055 FPSR |= 0x40000000; /* OVF bit on */\r
3056 break;\r
3057 case 2:\r
3058 FPSR |= 0x20000000; /* UNF bit on */\r
3059 break;\r
3060 }\r
3061 }\r
3062 store_lf(&dfl2, &FPAC[j]); /* put result in destination */\r
3063 if ((FPAC[j] & 0x00ffffffffffffff) == 0)\r
3064 FPAC[j] = 0;\r
3065 FPSR &= 0xFCFFFFFF; /* Z + N off */\r
3066 if (FPAC[j] == 0)\r
3067 FPSR |= 0x02000000; /* Set Z */\r
3068 if (FPAC[j] & 0x8000000000000000)\r
3069 FPSR |= 0x01000000; /* Set N */\r
3070 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
3071 FPSR |= ((PC - 1) & AMASK);\r
3072 PC = (PC + 1) & AMASK;\r
3073 continue;\r
3074 } \r
3075 if ((IR & 0103777) == 0100250) { /* FSS Sub single to AC */\r
3076 if (!(fpu_unit.flags & UNIT_UP))\r
3077 continue;\r
3078 if (Debug_Flags == 1) {\r
3079 printf("\n<<FPU instruction: FSS>>\n");\r
3080 reason = STOP_IBKPT;\r
3081 } \r
3082 if (FPFault) { /* Fault from a previous inst? */\r
3083 FPFault = 0;\r
3084 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
3085 PutMap(t, AC[0]);\r
3086 t++;\r
3087 PutMap(t, AC[1]);\r
3088 t++;\r
3089 PutMap(t, AC[2]);\r
3090 t++;\r
3091 PutMap(t, AC[3]);\r
3092 t++;\r
3093 PutMap(t, ((PC-1) & AMASK));\r
3094 if (C) PutMap(t, (GetMap(t) | 0100000));\r
3095 PutMap(040, t);\r
3096 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
3097 continue;\r
3098 }\r
3099 i = (IR >> 13) & 3;\r
3100 j = (IR >> 11) & 3;\r
3101 FPSR &= 0xFCFFFFFF; /* Z+N bits off */\r
3102 get_sf(&sfl, &FPAC[i]); /* Place in working registers */\r
3103 get_sf(&sfl2, &FPAC[j]);\r
3104 sfl.sign = ! (sfl.sign); /* invert sign of 2nd operand */ \r
3105 k = add_sf(&sfl2, &sfl, 1); /* Add the two */\r
3106 if (k) {\r
3107 switch (k) {\r
3108 case 1:\r
3109 FPSR |= 0x40000000; /* OVF bit on */\r
3110 break;\r
3111 case 2:\r
3112 FPSR |= 0x20000000; /* UNF bit on */\r
3113 break;\r
3114 }\r
3115 }\r
3116 store_sf(&sfl2, &FPAC[j]); /* put result in destination */\r
3117 if ((FPAC[j] & 0x00ffffffffffffff) == 0)\r
3118 FPAC[j] = 0;\r
3119 FPSR &= 0xFCFFFFFF; /* Z + N off */\r
3120 if (FPAC[j] == 0)\r
3121 FPSR |= 0x02000000; /* Set Z */\r
3122 if (FPAC[j] & 0x8000000000000000)\r
3123 FPSR |= 0x01000000; /* Set N */\r
3124 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
3125 FPSR |= ((PC - 1) & AMASK);\r
3126 continue;\r
3127 } \r
3128 if ((IR & 0103777) == 0101250) { /* FSMS Sub single (memory) */\r
3129 if (!(fpu_unit.flags & UNIT_UP))\r
3130 continue;\r
3131 if (Debug_Flags == 1) {\r
3132 printf("\n<<FPU instruction: FSMS>>\n");\r
3133 reason = STOP_IBKPT;\r
3134 } \r
3135 if (FPFault) { /* Fault from a previous inst? */\r
3136 FPFault = 0;\r
3137 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
3138 PutMap(t, AC[0]);\r
3139 t++;\r
3140 PutMap(t, AC[1]);\r
3141 t++;\r
3142 PutMap(t, AC[2]);\r
3143 t++;\r
3144 PutMap(t, AC[3]);\r
3145 t++;\r
3146 PutMap(t, ((PC-1) & AMASK));\r
3147 if (C) PutMap(t, (GetMap(t) | 0100000));\r
3148 PutMap(040, t);\r
3149 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
3150 continue;\r
3151 }\r
3152 j = (IR >> 11) & 3;\r
3153 MA = effective(PC, (IR >> 13) & 3, GetMap(PC));\r
3154 tempfp = ((t_uint64)GetMap(MA) << 48);\r
3155 tempfp |= ((t_uint64)GetMap(MA + 1) << 32);\r
3156 if ((tempfp & 0x00ffffffffffffff) == 0)\r
3157 tempfp = 0;\r
3158 FPSR &= 0xFCFFFFFF; /* Z+N bits off */\r
3159 get_sf(&sfl, &tempfp); /* Place in working registers */\r
3160 get_sf(&sfl2, &FPAC[j]);\r
3161 sfl.sign = ! (sfl.sign); /* invert sign of 2nd operand */ \r
3162 k = add_sf(&sfl2, &sfl, 1); /* Add the two */\r
3163 if (k) {\r
3164 switch (k) {\r
3165 case 1:\r
3166 FPSR |= 0x40000000; /* OVF bit on */\r
3167 break;\r
3168 case 2:\r
3169 FPSR |= 0x20000000; /* UNF bit on */\r
3170 break;\r
3171 }\r
3172 }\r
3173 store_sf(&sfl2, &FPAC[j]); /* put result in destination */\r
3174 if ((FPAC[j] & 0x00ffffffffffffff) == 0)\r
3175 FPAC[j] = 0;\r
3176 FPSR &= 0xFCFFFFFF; /* Z + N off */\r
3177 if (FPAC[j] == 0)\r
3178 FPSR |= 0x02000000; /* Set Z */\r
3179 if (FPAC[j] & 0x8000000000000000)\r
3180 FPSR |= 0x01000000; /* Set N */\r
3181 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
3182 FPSR |= ((PC - 1) & AMASK);\r
3183 PC = (PC + 1) & AMASK;\r
3184 continue;\r
3185 } \r
3186 if ((IR & 0103777) == 0100350) { /* FSD Sub double from AC */\r
3187 if (!(fpu_unit.flags & UNIT_UP))\r
3188 continue;\r
3189 if (Debug_Flags == 1) {\r
3190 printf("\n<<FPU instruction: FSD>>\n");\r
3191 reason = STOP_IBKPT;\r
3192 } \r
3193 if (FPFault) { /* Fault from a previous inst? */\r
3194 FPFault = 0;\r
3195 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
3196 PutMap(t, AC[0]);\r
3197 t++;\r
3198 PutMap(t, AC[1]);\r
3199 t++;\r
3200 PutMap(t, AC[2]);\r
3201 t++;\r
3202 PutMap(t, AC[3]);\r
3203 t++;\r
3204 PutMap(t, ((PC-1) & AMASK));\r
3205 if (C) PutMap(t, (GetMap(t) | 0100000));\r
3206 PutMap(040, t);\r
3207 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
3208 continue;\r
3209 }\r
3210 i = (IR >> 13) & 3;\r
3211 j = (IR >> 11) & 3;\r
3212 FPSR &= 0xFCFFFFFF; /* Z+N bits off */\r
3213 get_lf(&dfl, &FPAC[i]); /* Place in working registers */\r
3214 get_lf(&dfl2, &FPAC[j]);\r
3215 dfl.sign = ! (dfl.sign); /* invert sign of 2nd operand */ \r
3216 k = add_lf(&dfl2, &dfl, 1); /* Add the two */\r
3217 if (k) {\r
3218 switch (k) {\r
3219 case 1:\r
3220 FPSR |= 0x40000000; /* OVF bit on */\r
3221 break;\r
3222 case 2:\r
3223 FPSR |= 0x20000000; /* UNF bit on */\r
3224 break;\r
3225 }\r
3226 }\r
3227 store_lf(&dfl2, &FPAC[j]); /* put result in destination */\r
3228 if ((FPAC[j] & 0x00ffffffffffffff) == 0)\r
3229 FPAC[j] = 0;\r
3230 FPSR &= 0xFCFFFFFF; /* Z + N off */\r
3231 if (FPAC[j] == 0)\r
3232 FPSR |= 0x02000000; /* Set Z */\r
3233 if (FPAC[j] & 0x8000000000000000)\r
3234 FPSR |= 0x01000000; /* Set N */\r
3235 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
3236 FPSR |= ((PC - 1) & AMASK);\r
3237 continue;\r
3238 } \r
3239 if ((IR & 0103777) == 0101350) { /* FSMD Sub double from memory */\r
3240 if (!(fpu_unit.flags & UNIT_UP))\r
3241 continue;\r
3242 if (Debug_Flags == 1) {\r
3243 printf("\n<<FPU instruction: FSMD>>\n");\r
3244 reason = STOP_IBKPT;\r
3245 } \r
3246 if (FPFault) { /* Fault from a previous inst? */\r
3247 FPFault = 0;\r
3248 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
3249 PutMap(t, AC[0]);\r
3250 t++;\r
3251 PutMap(t, AC[1]);\r
3252 t++;\r
3253 PutMap(t, AC[2]);\r
3254 t++;\r
3255 PutMap(t, AC[3]);\r
3256 t++;\r
3257 PutMap(t, ((PC-1) & AMASK));\r
3258 if (C) PutMap(t, (GetMap(t) | 0100000));\r
3259 PutMap(040, t);\r
3260 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
3261 continue;\r
3262 }\r
3263 j = (IR >> 11) & 3;\r
3264 MA = effective(PC, (IR >> 13) & 3, GetMap(PC));\r
3265 tempfp = ((t_uint64)GetMap(MA) << 48);\r
3266 tempfp |= ((t_uint64)GetMap(MA + 1) << 32);\r
3267 tempfp |= ((t_uint64)GetMap(MA + 2) << 16);\r
3268 tempfp |= ((t_uint64)GetMap(MA + 3));\r
3269 if ((tempfp & 0x00ffffffffffffff) == 0)\r
3270 tempfp = 0;\r
3271 FPSR &= 0xFCFFFFFF; /* Z+N bits off */\r
3272 get_lf(&dfl, &tempfp); /* Place in working registers */\r
3273 get_lf(&dfl2, &FPAC[j]);\r
3274 dfl.sign = ! (dfl.sign); /* invert sign of 2nd operand */ \r
3275 k = add_lf(&dfl2, &dfl, 1); /* Add the two */\r
3276 if (k) {\r
3277 switch (k) {\r
3278 case 1:\r
3279 FPSR |= 0x40000000; /* OVF bit on */\r
3280 break;\r
3281 case 2:\r
3282 FPSR |= 0x20000000; /* UNF bit on */\r
3283 break;\r
3284 }\r
3285 }\r
3286 store_lf(&dfl2, &FPAC[j]); /* put result in destination */\r
3287 if ((FPAC[j] & 0x00ffffffffffffff) == 0)\r
3288 FPAC[j] = 0;\r
3289 FPSR &= 0xFCFFFFFF; /* Z + N off */\r
3290 if (FPAC[j] == 0)\r
3291 FPSR |= 0x02000000; /* Set Z */\r
3292 if (FPAC[j] & 0x8000000000000000)\r
3293 FPSR |= 0x01000000; /* Set N */\r
3294 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
3295 FPSR |= ((PC - 1) & AMASK);\r
3296 PC = (PC + 1) & AMASK;\r
3297 continue;\r
3298 } \r
3299 if ((IR & 0103777) == 0100450) { /* FMS Mult single by AC */\r
3300 if (!(fpu_unit.flags & UNIT_UP))\r
3301 continue;\r
3302 if (Debug_Flags == 1) {\r
3303 printf("\n<<FPU instruction: FMS>>\n");\r
3304 reason = STOP_IBKPT;\r
3305 } \r
3306 if (FPFault) { /* Fault from a previous inst? */\r
3307 FPFault = 0;\r
3308 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
3309 PutMap(t, AC[0]);\r
3310 t++;\r
3311 PutMap(t, AC[1]);\r
3312 t++;\r
3313 PutMap(t, AC[2]);\r
3314 t++;\r
3315 PutMap(t, AC[3]);\r
3316 t++;\r
3317 PutMap(t, ((PC-1) & AMASK));\r
3318 if (C) PutMap(t, (GetMap(t) | 0100000));\r
3319 PutMap(040, t);\r
3320 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
3321 continue;\r
3322 }\r
3323 i = (IR >> 13) & 3;\r
3324 j = (IR >> 11) & 3;\r
3325 FPSR &= 0xFCFFFFFF; /* Z+N bits off */\r
3326 get_sf(&sfl, &FPAC[i]); /* Place in working registers */\r
3327 get_sf(&sfl2, &FPAC[j]);\r
3328 k = mul_sf(&sfl2, &sfl); /* Multiply */\r
3329 if (k) {\r
3330 switch (k) {\r
3331 case 1:\r
3332 FPSR |= 0x40000000; /* OVF bit on */\r
3333 break;\r
3334 case 2:\r
3335 FPSR |= 0x20000000; /* UNF bit on */\r
3336 break;\r
3337 }\r
3338 }\r
3339 store_sf(&sfl2, &FPAC[j]); /* put result in destination */\r
3340 if ((FPAC[j] & 0x00ffffffffffffff) == 0)\r
3341 FPAC[j] = 0;\r
3342 FPSR &= 0xFCFFFFFF; /* Z + N off */\r
3343 if (FPAC[j] == 0)\r
3344 FPSR |= 0x02000000; /* Set Z */\r
3345 if (FPAC[j] & 0x8000000000000000)\r
3346 FPSR |= 0x01000000; /* Set N */\r
3347 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
3348 FPSR |= ((PC - 1) & AMASK);\r
3349 continue;\r
3350 } \r
3351 if ((IR & 0103777) == 0101450) { /* FMMS Mult single by memory */\r
3352 if (!(fpu_unit.flags & UNIT_UP))\r
3353 continue;\r
3354 if (Debug_Flags == 1) {\r
3355 printf("\n<<FPU instruction: FMMS>>\n");\r
3356 reason = STOP_IBKPT;\r
3357 } \r
3358 if (FPFault) { /* Fault from a previous inst? */\r
3359 FPFault = 0;\r
3360 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
3361 PutMap(t, AC[0]);\r
3362 t++;\r
3363 PutMap(t, AC[1]);\r
3364 t++;\r
3365 PutMap(t, AC[2]);\r
3366 t++;\r
3367 PutMap(t, AC[3]);\r
3368 t++;\r
3369 PutMap(t, ((PC-1) & AMASK));\r
3370 if (C) PutMap(t, (GetMap(t) | 0100000));\r
3371 PutMap(040, t);\r
3372 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
3373 continue;\r
3374 }\r
3375 j = (IR >> 11) & 3;\r
3376 MA = effective(PC, (IR >> 13) & 3, GetMap(PC));\r
3377 tempfp = ((t_uint64)GetMap(MA) << 48);\r
3378 tempfp |= ((t_uint64)GetMap(MA + 1) << 32);\r
3379 if ((tempfp & 0x00ffffffffffffff) == 0)\r
3380 tempfp = 0;\r
3381 FPSR &= 0xFCFFFFFF; /* Z+N bits off */\r
3382 get_sf(&sfl, &tempfp); /* Place in working registers */\r
3383 get_sf(&sfl2, &FPAC[j]);\r
3384 k = mul_sf(&sfl2, &sfl); /* Multiply */\r
3385 if (k) {\r
3386 switch (k) {\r
3387 case 1:\r
3388 FPSR |= 0x40000000; /* OVF bit on */\r
3389 break;\r
3390 case 2:\r
3391 FPSR |= 0x20000000; /* UNF bit on */\r
3392 break;\r
3393 }\r
3394 }\r
3395 store_sf(&sfl2, &FPAC[j]); /* put result in destination */\r
3396 if ((FPAC[j] & 0x00ffffffffffffff) == 0)\r
3397 FPAC[j] = 0;\r
3398 FPSR &= 0xFCFFFFFF; /* Z + N off */\r
3399 if (FPAC[j] == 0)\r
3400 FPSR |= 0x02000000; /* Set Z */\r
3401 if (FPAC[j] & 0x8000000000000000)\r
3402 FPSR |= 0x01000000; /* Set N */\r
3403 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
3404 FPSR |= ((PC - 1) & AMASK);\r
3405 PC = (PC + 1) & AMASK;\r
3406 continue;\r
3407 } \r
3408 if ((IR & 0103777) == 0100550) { /* FMD Mult double by AC */\r
3409 if (!(fpu_unit.flags & UNIT_UP))\r
3410 continue;\r
3411 if (Debug_Flags == 1) {\r
3412 printf("\n<<FPU instruction: FMD>>\n");\r
3413 reason = STOP_IBKPT;\r
3414 } \r
3415 if (FPFault) { /* Fault from a previous inst? */\r
3416 FPFault = 0;\r
3417 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
3418 PutMap(t, AC[0]);\r
3419 t++;\r
3420 PutMap(t, AC[1]);\r
3421 t++;\r
3422 PutMap(t, AC[2]);\r
3423 t++;\r
3424 PutMap(t, AC[3]);\r
3425 t++;\r
3426 PutMap(t, ((PC-1) & AMASK));\r
3427 if (C) PutMap(t, (GetMap(t) | 0100000));\r
3428 PutMap(040, t);\r
3429 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
3430 continue;\r
3431 }\r
3432 i = (IR >> 13) & 3;\r
3433 j = (IR >> 11) & 3;\r
3434 FPSR &= 0xFCFFFFFF; /* Z+N bits off */\r
3435 get_lf(&dfl, &FPAC[i]); /* Place in working registers */\r
3436 get_lf(&dfl2, &FPAC[j]);\r
3437 k = mul_lf(&dfl2, &dfl); /* Multiply */\r
3438 if (k) {\r
3439 switch (k) {\r
3440 case 1:\r
3441 FPSR |= 0x40000000; /* OVF bit on */\r
3442 break;\r
3443 case 2:\r
3444 FPSR |= 0x20000000; /* UNF bit on */\r
3445 break;\r
3446 }\r
3447 }\r
3448 store_lf(&dfl2, &FPAC[j]); /* put result in destination */\r
3449 if ((FPAC[j] & 0x00ffffffffffffff) == 0)\r
3450 FPAC[j] = 0;\r
3451 FPSR &= 0xFCFFFFFF; /* Z + N off */\r
3452 if (FPAC[j] == 0)\r
3453 FPSR |= 0x02000000; /* Set Z */\r
3454 if (FPAC[j] & 0x8000000000000000)\r
3455 FPSR |= 0x01000000; /* Set N */\r
3456 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
3457 FPSR |= ((PC - 1) & AMASK);\r
3458 continue;\r
3459 } \r
3460 if ((IR & 0103777) == 0101550) { /* FMMD Mult double by memory */\r
3461 if (!(fpu_unit.flags & UNIT_UP))\r
3462 continue;\r
3463 if (Debug_Flags == 1) {\r
3464 printf("\n<<FPU instruction: FMMD>>\n");\r
3465 reason = STOP_IBKPT;\r
3466 } \r
3467 if (FPFault) { /* Fault from a previous inst? */\r
3468 FPFault = 0;\r
3469 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
3470 PutMap(t, AC[0]);\r
3471 t++;\r
3472 PutMap(t, AC[1]);\r
3473 t++;\r
3474 PutMap(t, AC[2]);\r
3475 t++;\r
3476 PutMap(t, AC[3]);\r
3477 t++;\r
3478 PutMap(t, ((PC-1) & AMASK));\r
3479 if (C) PutMap(t, (GetMap(t) | 0100000));\r
3480 PutMap(040, t);\r
3481 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
3482 continue;\r
3483 }\r
3484 j = (IR >> 11) & 3;\r
3485 MA = effective(PC, (IR >> 13) & 3, GetMap(PC));\r
3486 tempfp = ((t_uint64)GetMap(MA) << 48);\r
3487 tempfp |= ((t_uint64)GetMap(MA + 1) << 32);\r
3488 tempfp |= ((t_uint64)GetMap(MA + 2) << 16);\r
3489 tempfp |= ((t_uint64)GetMap(MA + 3));\r
3490 if ((tempfp & 0x00ffffffffffffff) == 0)\r
3491 tempfp = 0;\r
3492 FPSR &= 0xFCFFFFFF; /* Z+N bits off */\r
3493 get_lf(&dfl, &tempfp); /* Place in working registers */\r
3494 get_lf(&dfl2, &FPAC[j]);\r
3495 k = mul_lf(&dfl2, &dfl); /* Multiply */\r
3496 if (k) {\r
3497 switch (k) {\r
3498 case 1:\r
3499 FPSR |= 0x40000000; /* OVF bit on */\r
3500 break;\r
3501 case 2:\r
3502 FPSR |= 0x20000000; /* UNF bit on */\r
3503 break;\r
3504 }\r
3505 }\r
3506 store_lf(&dfl2, &FPAC[j]); /* put result in destination */\r
3507 if ((FPAC[j] & 0x00ffffffffffffff) == 0)\r
3508 FPAC[j] = 0;\r
3509 FPSR &= 0xFCFFFFFF; /* Z + N off */\r
3510 if (FPAC[j] == 0)\r
3511 FPSR |= 0x02000000; /* Set Z */\r
3512 if (FPAC[j] & 0x8000000000000000)\r
3513 FPSR |= 0x01000000; /* Set N */\r
3514 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
3515 FPSR |= ((PC - 1) & AMASK);\r
3516 PC = (PC + 1) & AMASK;\r
3517 continue;\r
3518 } \r
3519 if ((IR & 0103777) == 0100650) { /* FDS Div single by AC */\r
3520 if (!(fpu_unit.flags & UNIT_UP))\r
3521 continue;\r
3522 if (Debug_Flags == 1) {\r
3523 printf("\n<<FPU instruction: FDS>>\n");\r
3524 reason = STOP_IBKPT;\r
3525 } \r
3526 if (FPFault) { /* Fault from a previous inst? */\r
3527 FPFault = 0;\r
3528 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
3529 PutMap(t, AC[0]);\r
3530 t++;\r
3531 PutMap(t, AC[1]);\r
3532 t++;\r
3533 PutMap(t, AC[2]);\r
3534 t++;\r
3535 PutMap(t, AC[3]);\r
3536 t++;\r
3537 PutMap(t, ((PC-1) & AMASK));\r
3538 if (C) PutMap(t, (GetMap(t) | 0100000));\r
3539 PutMap(040, t);\r
3540 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
3541 continue;\r
3542 }\r
3543 i = (IR >> 13) & 3;\r
3544 j = (IR >> 11) & 3;\r
3545 FPSR &= 0xFCFFFFFF; /* Z+N bits off */\r
3546 get_sf(&sfl, &FPAC[i]); /* Place in working registers */\r
3547 get_sf(&sfl2, &FPAC[j]);\r
3548 k = div_sf(&sfl2, &sfl); /* Divide */\r
3549 if (k) {\r
3550 switch (k) {\r
3551 case 1:\r
3552 FPSR |= 0x40000000; /* OVF bit on */\r
3553 break;\r
3554 case 2:\r
3555 FPSR |= 0x20000000; /* UNF bit on */\r
3556 break;\r
3557 case 3:\r
3558 FPSR |= 0x10000000; /* DVZ bit on */\r
3559 break;\r
3560 }\r
3561 }\r
3562 store_sf(&sfl2, &FPAC[j]); /* put result in destination */\r
3563 if ((FPAC[j] & 0x00ffffffffffffff) == 0)\r
3564 FPAC[j] = 0;\r
3565 FPSR &= 0xFCFFFFFF; /* Z + N off */\r
3566 if (FPAC[j] == 0)\r
3567 FPSR |= 0x02000000; /* Set Z */\r
3568 if (FPAC[j] & 0x8000000000000000)\r
3569 FPSR |= 0x01000000; /* Set N */\r
3570 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
3571 FPSR |= ((PC - 1) & AMASK);\r
3572 continue;\r
3573 } \r
3574 if ((IR & 0103777) == 0101650) { /* FDMS Div single by memory */\r
3575 if (!(fpu_unit.flags & UNIT_UP))\r
3576 continue;\r
3577 if (Debug_Flags == 1) {\r
3578 printf("\n<<FPU instruction: FDMS>>\n");\r
3579 reason = STOP_IBKPT;\r
3580 } \r
3581 if (FPFault) { /* Fault from a previous inst? */\r
3582 FPFault = 0;\r
3583 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
3584 PutMap(t, AC[0]);\r
3585 t++;\r
3586 PutMap(t, AC[1]);\r
3587 t++;\r
3588 PutMap(t, AC[2]);\r
3589 t++;\r
3590 PutMap(t, AC[3]);\r
3591 t++;\r
3592 PutMap(t, ((PC-1) & AMASK));\r
3593 if (C) PutMap(t, (GetMap(t) | 0100000));\r
3594 PutMap(040, t);\r
3595 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
3596 continue;\r
3597 }\r
3598 j = (IR >> 11) & 3;\r
3599 MA = effective(PC, (IR >> 13) & 3, GetMap(PC));\r
3600 tempfp = ((t_uint64)GetMap(MA) << 48);\r
3601 tempfp |= ((t_uint64)GetMap(MA + 1) << 32);\r
3602 if ((tempfp & 0x00ffffffffffffff) == 0)\r
3603 tempfp = 0;\r
3604 FPSR &= 0xFCFFFFFF; /* Z+N bits off */\r
3605 get_sf(&sfl, &tempfp); /* Place in working registers */\r
3606 get_sf(&sfl2, &FPAC[j]);\r
3607 k = div_sf(&sfl2, &sfl); /* Divide */\r
3608 if (k) {\r
3609 switch (k) {\r
3610 case 1:\r
3611 FPSR |= 0x40000000; /* OVF bit on */\r
3612 break;\r
3613 case 2:\r
3614 FPSR |= 0x20000000; /* UNF bit on */\r
3615 break;\r
3616 case 3:\r
3617 FPSR |= 0x10000000; /* DVZ bit on */\r
3618 break;\r
3619 }\r
3620 }\r
3621 store_sf(&sfl2, &FPAC[j]); /* put result in destination */\r
3622 if ((FPAC[j] & 0x00ffffffffffffff) == 0)\r
3623 FPAC[j] = 0;\r
3624 FPSR &= 0xFCFFFFFF; /* Z + N off */\r
3625 if (FPAC[j] == 0)\r
3626 FPSR |= 0x02000000; /* Set Z */\r
3627 if (FPAC[j] & 0x8000000000000000)\r
3628 FPSR |= 0x01000000; /* Set N */\r
3629 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
3630 FPSR |= ((PC - 1) & AMASK);\r
3631 PC = (PC + 1) & AMASK;\r
3632 continue;\r
3633 } \r
3634 if ((IR & 0103777) == 0100650) { /* FDD Div double by AC */\r
3635 if (!(fpu_unit.flags & UNIT_UP))\r
3636 continue;\r
3637 if (Debug_Flags == 1) {\r
3638 printf("\n<<FPU instruction: FDD>>\n");\r
3639 reason = STOP_IBKPT;\r
3640 } \r
3641 if (FPFault) { /* Fault from a previous inst? */\r
3642 FPFault = 0;\r
3643 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
3644 PutMap(t, AC[0]);\r
3645 t++;\r
3646 PutMap(t, AC[1]);\r
3647 t++;\r
3648 PutMap(t, AC[2]);\r
3649 t++;\r
3650 PutMap(t, AC[3]);\r
3651 t++;\r
3652 PutMap(t, ((PC-1) & AMASK));\r
3653 if (C) PutMap(t, (GetMap(t) | 0100000));\r
3654 PutMap(040, t);\r
3655 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
3656 continue;\r
3657 }\r
3658 i = (IR >> 13) & 3;\r
3659 j = (IR >> 11) & 3;\r
3660 FPSR &= 0xFCFFFFFF; /* Z+N bits off */\r
3661 get_lf(&dfl, &FPAC[i]); /* Place in working registers */\r
3662 get_lf(&dfl2, &FPAC[j]);\r
3663 k = div_lf(&dfl2, &dfl); /* Divide */\r
3664 if (k) {\r
3665 switch (k) {\r
3666 case 1:\r
3667 FPSR |= 0x40000000; /* OVF bit on */\r
3668 break;\r
3669 case 2:\r
3670 FPSR |= 0x20000000; /* UNF bit on */\r
3671 break;\r
3672 case 3:\r
3673 FPSR |= 0x10000000; /* DVZ bit on */\r
3674 break;\r
3675 }\r
3676 }\r
3677 store_lf(&dfl2, &FPAC[j]); /* put result in destination */\r
3678 if ((FPAC[j] & 0x00ffffffffffffff) == 0)\r
3679 FPAC[j] = 0;\r
3680 FPSR &= 0xFCFFFFFF; /* Z + N off */\r
3681 if (FPAC[j] == 0)\r
3682 FPSR |= 0x02000000; /* Set Z */\r
3683 if (FPAC[j] & 0x8000000000000000)\r
3684 FPSR |= 0x01000000; /* Set N */\r
3685 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
3686 FPSR |= ((PC - 1) & AMASK);\r
3687 continue;\r
3688 } \r
3689 if ((IR & 0103777) == 0101650) { /* FDMD Div double by memory */\r
3690 if (!(fpu_unit.flags & UNIT_UP))\r
3691 continue;\r
3692 if (Debug_Flags == 1) {\r
3693 printf("\n<<FPU instruction: FDMD>>\n");\r
3694 reason = STOP_IBKPT;\r
3695 } \r
3696 if (FPFault) { /* Fault from a previous inst? */\r
3697 FPFault = 0;\r
3698 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
3699 PutMap(t, AC[0]);\r
3700 t++;\r
3701 PutMap(t, AC[1]);\r
3702 t++;\r
3703 PutMap(t, AC[2]);\r
3704 t++;\r
3705 PutMap(t, AC[3]);\r
3706 t++;\r
3707 PutMap(t, ((PC-1) & AMASK));\r
3708 if (C) PutMap(t, (GetMap(t) | 0100000));\r
3709 PutMap(040, t);\r
3710 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
3711 continue;\r
3712 }\r
3713 j = (IR >> 11) & 3;\r
3714 MA = effective(PC, (IR >> 13) & 3, GetMap(PC));\r
3715 tempfp = ((t_uint64)GetMap(MA) << 48);\r
3716 tempfp |= ((t_uint64)GetMap(MA + 1) << 32);\r
3717 tempfp |= ((t_uint64)GetMap(MA + 2) << 16);\r
3718 tempfp |= ((t_uint64)GetMap(MA + 3));\r
3719 if ((tempfp & 0x00ffffffffffffff) == 0)\r
3720 tempfp = 0;\r
3721 FPSR &= 0xFCFFFFFF; /* Z+N bits off */\r
3722 get_lf(&dfl, &tempfp); /* Place in working registers */\r
3723 get_lf(&dfl2, &FPAC[j]);\r
3724 k = div_lf(&dfl2, &dfl); /* Divide */\r
3725 if (k) {\r
3726 switch (k) {\r
3727 case 1:\r
3728 FPSR |= 0x40000000; /* OVF bit on */\r
3729 break;\r
3730 case 2:\r
3731 FPSR |= 0x20000000; /* UNF bit on */\r
3732 break;\r
3733 case 3:\r
3734 FPSR |= 0x10000000; /* DVZ bit on */\r
3735 break;\r
3736 }\r
3737 }\r
3738 store_lf(&dfl2, &FPAC[j]); /* put result in destination */\r
3739 if ((FPAC[j] & 0x00ffffffffffffff) == 0)\r
3740 FPAC[j] = 0;\r
3741 FPSR &= 0xFCFFFFFF; /* Z + N off */\r
3742 if (FPAC[j] == 0)\r
3743 FPSR |= 0x02000000; /* Set Z */\r
3744 if (FPAC[j] & 0x8000000000000000)\r
3745 FPSR |= 0x01000000; /* Set N */\r
3746 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
3747 FPSR |= ((PC - 1) & AMASK);\r
3748 PC = (PC + 1) & AMASK;\r
3749 continue;\r
3750 } \r
3751 if ((IR & 0163777) == 0163050) { /* FNEG Negate */\r
3752 if (!(fpu_unit.flags & UNIT_UP))\r
3753 continue;\r
3754 if (Debug_Flags == 1) {\r
3755 printf("\n<<FPU instruction: FNEG>>\n");\r
3756 reason = STOP_IBKPT;\r
3757 } \r
3758 if (FPFault) { /* Fault from a previous inst? */\r
3759 FPFault = 0;\r
3760 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
3761 PutMap(t, AC[0]);\r
3762 t++;\r
3763 PutMap(t, AC[1]);\r
3764 t++;\r
3765 PutMap(t, AC[2]);\r
3766 t++;\r
3767 PutMap(t, AC[3]);\r
3768 t++;\r
3769 PutMap(t, ((PC-1) & AMASK));\r
3770 if (C) PutMap(t, (GetMap(t) | 0100000));\r
3771 PutMap(040, t);\r
3772 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
3773 continue;\r
3774 }\r
3775 j = (IR >> 11) & 3;\r
3776 FPSR &= 0xFCFFFFFF; /* Z+N bits off */\r
3777 get_lf(&dfl, &FPAC[j]);\r
3778 dfl.sign = ! (dfl.sign); /* invert sign */\r
3779 store_lf(&dfl, &FPAC[j]); /* put result in destination */\r
3780 if ((FPAC[j] & 0x00ffffffffffffff) == 0)\r
3781 FPAC[j] = 0;\r
3782 FPSR &= 0xFCFFFFFF; /* Z + N off */\r
3783 if (FPAC[j] == 0)\r
3784 FPSR |= 0x02000000; /* Set Z */\r
3785 if (FPAC[j] & 0x8000000000000000)\r
3786 FPSR |= 0x01000000; /* Set N */\r
3787 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
3788 FPSR |= ((PC - 1) & AMASK);\r
3789 continue;\r
3790 } \r
3791 if ((IR & 0163777) == 0143050) { /* FAB Absolute Value*/\r
3792 if (!(fpu_unit.flags & UNIT_UP))\r
3793 continue;\r
3794 if (Debug_Flags == 1) {\r
3795 printf("\n<<FPU instruction: FAB>>\n");\r
3796 reason = STOP_IBKPT;\r
3797 } \r
3798 if (FPFault) { /* Fault from a previous inst? */\r
3799 FPFault = 0;\r
3800 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
3801 PutMap(t, AC[0]);\r
3802 t++;\r
3803 PutMap(t, AC[1]);\r
3804 t++;\r
3805 PutMap(t, AC[2]);\r
3806 t++;\r
3807 PutMap(t, AC[3]);\r
3808 t++;\r
3809 PutMap(t, ((PC-1) & AMASK));\r
3810 if (C) PutMap(t, (GetMap(t) | 0100000));\r
3811 PutMap(040, t);\r
3812 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
3813 continue;\r
3814 }\r
3815 j = (IR >> 11) & 3;\r
3816 FPSR &= 0xFCFFFFFF; /* Z+N bits off */\r
3817 get_lf(&dfl, &FPAC[j]);\r
3818 dfl.sign = 0; /* Force sign positive */\r
3819 store_lf(&dfl, &FPAC[j]); /* put result in destination */\r
3820 if ((FPAC[j] & 0x00ffffffffffffff) == 0)\r
3821 FPAC[j] = 0;\r
3822 FPSR &= 0xFCFFFFFF; /* Z + N off */\r
3823 if (FPAC[j] == 0)\r
3824 FPSR |= 0x02000000; /* Set Z */\r
3825 if (FPAC[j] & 0x8000000000000000)\r
3826 FPSR |= 0x01000000; /* Set N */\r
3827 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
3828 FPSR |= ((PC - 1) & AMASK);\r
3829 continue;\r
3830 } \r
3831 if ((IR & 0163777) == 0103050) { /* FNOM Normalize*/\r
3832 if (!(fpu_unit.flags & UNIT_UP))\r
3833 continue;\r
3834 if (Debug_Flags == 1) {\r
3835 printf("\n<<FPU instruction: FNOM>>\n");\r
3836 reason = STOP_IBKPT;\r
3837 } \r
3838 if (FPFault) { /* Fault from a previous inst? */\r
3839 FPFault = 0;\r
3840 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
3841 PutMap(t, AC[0]);\r
3842 t++;\r
3843 PutMap(t, AC[1]);\r
3844 t++;\r
3845 PutMap(t, AC[2]);\r
3846 t++;\r
3847 PutMap(t, AC[3]);\r
3848 t++;\r
3849 PutMap(t, ((PC-1) & AMASK));\r
3850 if (C) PutMap(t, (GetMap(t) | 0100000));\r
3851 PutMap(040, t);\r
3852 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
3853 continue;\r
3854 }\r
3855 j = (IR >> 11) & 3;\r
3856 FPSR &= 0xFCFFFFFF; /* Z+N bits off */\r
3857 get_lf(&dfl, &FPAC[j]);\r
3858 k = normal_lf(&dfl); /* Normalize */\r
3859 if (k == 2) /* Underflow ? */\r
3860 FPSR |= 0x20000000; /* Set underflow on */\r
3861 store_lf(&dfl, &FPAC[j]); /* put result in destination */\r
3862 if ((FPAC[j] & 0x00ffffffffffffff) == 0)\r
3863 FPAC[j] = 0;\r
3864 FPSR &= 0xFCFFFFFF; /* Z + N off */\r
3865 if (FPAC[j] == 0)\r
3866 FPSR |= 0x02000000; /* Set Z */\r
3867 if (FPAC[j] & 0x8000000000000000)\r
3868 FPSR |= 0x01000000; /* Set N */\r
3869 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
3870 FPSR |= ((PC - 1) & AMASK);\r
3871 continue;\r
3872 } \r
3873 if ((IR & 0163777) == 0123050) { /* FRH Read High Word */\r
3874 if (!(fpu_unit.flags & UNIT_UP))\r
3875 continue;\r
3876 if (Debug_Flags == 1) {\r
3877 printf("\n<<FPU instruction: FRH>>\n");\r
3878 reason = STOP_IBKPT;\r
3879 } \r
3880 if (FPFault) { /* Fault from a previous inst? */\r
3881 FPFault = 0;\r
3882 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
3883 PutMap(t, AC[0]);\r
3884 t++;\r
3885 PutMap(t, AC[1]);\r
3886 t++;\r
3887 PutMap(t, AC[2]);\r
3888 t++;\r
3889 PutMap(t, AC[3]);\r
3890 t++;\r
3891 PutMap(t, ((PC-1) & AMASK));\r
3892 if (C) PutMap(t, (GetMap(t) | 0100000));\r
3893 PutMap(040, t);\r
3894 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
3895 continue;\r
3896 }\r
3897 j = (IR >> 11) & 3;\r
3898 AC[0] = (int32)(FPAC[j] >> 48) & 0xFFFF; /* No cond bits set, always to AC0 */\r
3899 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
3900 FPSR |= ((PC - 1) & AMASK);\r
3901 continue;\r
3902 } \r
3903 if ((IR & 0163777) == 0123150) { /* FEXP Load Exponent */\r
3904 if (!(fpu_unit.flags & UNIT_UP))\r
3905 continue;\r
3906 if (Debug_Flags == 1) {\r
3907 printf("\n<<FPU instruction: FEXP>>\n");\r
3908 reason = STOP_IBKPT;\r
3909 continue;\r
3910 } \r
3911 if (FPFault) { /* Fault from a previous inst? */\r
3912 FPFault = 0;\r
3913 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
3914 PutMap(t, AC[0]);\r
3915 t++;\r
3916 PutMap(t, AC[1]);\r
3917 t++;\r
3918 PutMap(t, AC[2]);\r
3919 t++;\r
3920 PutMap(t, AC[3]);\r
3921 t++;\r
3922 PutMap(t, ((PC-1) & AMASK));\r
3923 if (C) PutMap(t, (GetMap(t) | 0100000));\r
3924 PutMap(040, t);\r
3925 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
3926 continue;\r
3927 }\r
3928 j = (IR >> 11) & 3;\r
3929 i = (AC[0] >> 8) & 0x007F;\r
3930 FPAC[j] &= 0x80FFFFFFFFFFFFFF; /* clear exponent */\r
3931 FPAC[j] |= ((t_int64) i << 56);\r
3932 if ((FPAC[j] & 0x00ffffffffffffff) == 0)\r
3933 FPAC[j] = 0;\r
3934 if (FPAC[j] == 0)\r
3935 FPSR |= 0x02000000; /* Set Z */\r
3936 if (FPAC[j] & 0x8000000000000000)\r
3937 FPSR |= 0x01000000; /* Set N */\r
3938 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
3939 FPSR |= ((PC - 1) & AMASK);\r
3940 continue;\r
3941 } \r
3942 if ((IR & 0103777) == 0103450) { /* FCMP FP Compare */\r
3943 if (!(fpu_unit.flags & UNIT_UP)) /* (Subtract double AC without storing result) */\r
3944 continue;\r
3945 if (Debug_Flags == 1) {\r
3946 printf("\n<<FPU instruction: FCMP>>\n");\r
3947 reason = STOP_IBKPT;\r
3948 } \r
3949 if (FPFault) { /* Fault from a previous inst? */\r
3950 FPFault = 0;\r
3951 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
3952 PutMap(t, AC[0]);\r
3953 t++;\r
3954 PutMap(t, AC[1]);\r
3955 t++;\r
3956 PutMap(t, AC[2]);\r
3957 t++;\r
3958 PutMap(t, AC[3]);\r
3959 t++;\r
3960 PutMap(t, ((PC-1) & AMASK));\r
3961 if (C) PutMap(t, (GetMap(t) | 0100000));\r
3962 PutMap(040, t);\r
3963 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
3964 continue;\r
3965 }\r
3966 i = (IR >> 13) & 3;\r
3967 j = (IR >> 11) & 3;\r
3968 FPSR &= 0xFCFFFFFF; /* Z+N bits off */\r
3969 get_lf(&dfl, &FPAC[i]); /* Place in working registers */\r
3970 get_lf(&dfl2, &FPAC[j]);\r
3971 dfl.sign = ! (dfl.sign); /* invert sign of 2nd operand */ \r
3972 k = add_lf(&dfl2, &dfl, 1); /* Add the two */\r
3973 if (k) {\r
3974 switch (k) {\r
3975 case 1:\r
3976 FPSR |= 0x40000000; /* OVF bit on */\r
3977 break;\r
3978 case 2:\r
3979 FPSR |= 0x20000000; /* UNF bit on */\r
3980 break;\r
3981 }\r
3982 }\r
3983 if ((FPAC[j] & 0x00ffffffffffffff) == 0)\r
3984 FPAC[j] = 0;\r
3985 FPSR &= 0xFCFFFFFF; /* Z + N off */\r
3986 if (FPAC[j] == 0)\r
3987 FPSR |= 0x02000000; /* Set Z */\r
3988 if (FPAC[j] & 0x8000000000000000)\r
3989 FPSR |= 0x01000000; /* Set N */\r
3990 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
3991 FPSR |= ((PC - 1) & AMASK);\r
3992 continue;\r
3993 } \r
3994 if (IR == 0163350) { /* FPSH Push State */\r
3995 if (!(fpu_unit.flags & UNIT_UP))\r
3996 continue;\r
3997 if (Debug_Flags == 2) {\r
3998 printf("\n<<FPU instruction: FPSH>>\n");\r
3999 reason = STOP_IBKPT;\r
4000 } \r
4001 /* Note: FPSH and FPOP do not trap on error */\r
4002 t = (GetMap(040) + 1) & AMASK; /* Get Stack Pointer */ \r
4003 PutMap(t, ((FPSR >> 16) & 0xFFFF));\r
4004 t++;\r
4005 PutMap(t, (FPSR & 0xFFFF));\r
4006 t++;\r
4007 PutMap(t, (int16)((FPAC[0] >> 48) & 0xFFFF));\r
4008 t++;\r
4009 PutMap(t, (int16)((FPAC[0] >> 32) & 0xFFFF));\r
4010 t++;\r
4011 PutMap(t, (int16)((FPAC[0] >> 16) & 0xFFFF));\r
4012 t++;\r
4013 PutMap(t, (int16)(FPAC[0] & 0xFFFF));\r
4014 t++;\r
4015 PutMap(t, (int16)((FPAC[1] >> 48) & 0xFFFF));\r
4016 t++;\r
4017 PutMap(t, (int16)((FPAC[1] >> 32) & 0xFFFF));\r
4018 t++;\r
4019 PutMap(t, (int16)((FPAC[1] >> 16) & 0xFFFF));\r
4020 t++;\r
4021 PutMap(t, (int16)(FPAC[1] & 0xFFFF));\r
4022 t++;\r
4023 PutMap(t, (int16)((FPAC[2] >> 48) & 0xFFFF));\r
4024 t++;\r
4025 PutMap(t, (int16)((FPAC[2] >> 32) & 0xFFFF));\r
4026 t++;\r
4027 PutMap(t, (int16)((FPAC[2] >> 16) & 0xFFFF));\r
4028 t++;\r
4029 PutMap(t, (int16)(FPAC[2] & 0xFFFF));\r
4030 t++;\r
4031 PutMap(t, (int16)((FPAC[3] >> 48) & 0xFFFF));\r
4032 t++;\r
4033 PutMap(t, (int16)((FPAC[3] >> 32) & 0xFFFF));\r
4034 t++;\r
4035 PutMap(t, (int16)((FPAC[3] >> 16) & 0xFFFF));\r
4036 t++;\r
4037 PutMap(t, (int16)(FPAC[3] & 0xFFFF));\r
4038 PutMap(040, t); /* Update Stack Pointer */\r
4039 continue;\r
4040 } \r
4041 if (IR == 0167350) { /* FPOP Pop State */\r
4042 if (!(fpu_unit.flags & UNIT_UP))\r
4043 continue;\r
4044 if (Debug_Flags == 2) {\r
4045 printf("\n<<FPU instruction: FPOP>>\n");\r
4046 reason = STOP_IBKPT;\r
4047 } \r
4048 /* Note: FPSH and FPOP do not trap on error */\r
4049 t = GetMap(040) & AMASK; /* Get Stack Pointer */ \r
4050 FPAC[3] = ((t_uint64)GetMap(t) & 0xFFFF);\r
4051 t--;\r
4052 FPAC[3] |= (((t_uint64)GetMap(t) << 16) & 0xFFFF0000);\r
4053 t--;\r
4054 FPAC[3] |= (((t_uint64)GetMap(t) << 32) & 0xFFFF00000000);\r
4055 t--;\r
4056 FPAC[3] |= (((t_uint64)GetMap(t) << 48) & 0xFFFF000000000000);\r
4057 t--;\r
4058 FPAC[2] = ((t_uint64)GetMap(t) & 0xFFFF);\r
4059 t--;\r
4060 FPAC[2] |= (((t_uint64)GetMap(t) << 16) & 0xFFFF0000);\r
4061 t--;\r
4062 FPAC[2] |= (((t_uint64)GetMap(t) << 32) & 0xFFFF00000000);\r
4063 t--;\r
4064 FPAC[2] |= (((t_uint64)GetMap(t) << 48) & 0xFFFF000000000000);\r
4065 t--;\r
4066 FPAC[1] = ((t_uint64)GetMap(t) & 0xFFFF);\r
4067 t--;\r
4068 FPAC[1] |= (((t_uint64)GetMap(t) << 16) & 0xFFFF0000);\r
4069 t--;\r
4070 FPAC[1] |= (((t_uint64)GetMap(t) << 32) & 0xFFFF00000000);\r
4071 t--;\r
4072 FPAC[1] |= (((t_uint64)GetMap(t) << 48) & 0xFFFF000000000000);\r
4073 t--;\r
4074 FPAC[0] = ((t_uint64)GetMap(t) & 0xFFFF);\r
4075 t--;\r
4076 FPAC[0] |= (((t_uint64)GetMap(t) << 16) & 0xFFFF0000);\r
4077 t--;\r
4078 FPAC[0] |= (((t_uint64)GetMap(t) << 32) & 0xFFFF00000000);\r
4079 t--;\r
4080 FPAC[0] |= (((t_uint64)GetMap(t) << 48) & 0xFFFF000000000000);\r
4081 t--;\r
4082 FPSR = (GetMap(t) & 0xFFFF);\r
4083 t--;\r
4084 FPSR |= ((GetMap(t) << 16) & 0xFFFF0000);\r
4085 t--;\r
4086 PutMap(040, t); /* Update Stack Pointer */\r
4087 continue;\r
4088 } \r
4089 if ((IR & 0163777) == 0163150) { /* FHLV Halve */\r
4090 if (!(fpu_unit.flags & UNIT_UP))\r
4091 continue;\r
4092 if (Debug_Flags == 1) {\r
4093 printf("\n<<FPU instruction: FHLV>>\n");\r
4094 reason = STOP_IBKPT;\r
4095 } \r
4096 if (FPFault) { /* Fault from a previous inst? */\r
4097 FPFault = 0;\r
4098 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
4099 PutMap(t, AC[0]);\r
4100 t++;\r
4101 PutMap(t, AC[1]);\r
4102 t++;\r
4103 PutMap(t, AC[2]);\r
4104 t++;\r
4105 PutMap(t, AC[3]);\r
4106 t++;\r
4107 PutMap(t, ((PC-1) & AMASK));\r
4108 if (C) PutMap(t, (GetMap(t) | 0100000));\r
4109 PutMap(040, t);\r
4110 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
4111 continue;\r
4112 }\r
4113 j = (IR >> 11) & 3;\r
4114 FPSR &= 0xFCFFFFFF; /* Z+N bits off */\r
4115 get_lf(&dfl, &FPAC[j]);\r
4116 dfl.long_fract = dfl.long_fract >> 1; /* Shift right one bit */\r
4117 normal_lf(&dfl); /* Normalize */\r
4118 store_lf(&dfl, &FPAC[j]); /* put result in destination */\r
4119 if ((FPAC[j] & 0x00ffffffffffffff) == 0)\r
4120 FPAC[j] = 0;\r
4121 FPSR &= 0xFCFFFFFF; /* Z + N off */\r
4122 if (FPAC[j] == 0)\r
4123 FPSR |= 0x02000000; /* Set Z */\r
4124 if (FPAC[j] & 0x8000000000000000)\r
4125 FPSR |= 0x01000000; /* Set N */\r
4126 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
4127 FPSR |= ((PC - 1) & AMASK);\r
4128 continue;\r
4129 } \r
4130 if ((IR & 0163777) == 0103150) { /* FSCAL Scale */\r
4131 if (!(fpu_unit.flags & UNIT_UP))\r
4132 continue;\r
4133 if (Debug_Flags == 1) {\r
4134 printf("\n<<FPU instruction: FSCAL>>\n");\r
4135 reason = STOP_IBKPT;\r
4136 } \r
4137 if (FPFault) { /* Fault from a previous inst? */\r
4138 FPFault = 0;\r
4139 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
4140 PutMap(t, AC[0]);\r
4141 t++;\r
4142 PutMap(t, AC[1]);\r
4143 t++;\r
4144 PutMap(t, AC[2]);\r
4145 t++;\r
4146 PutMap(t, AC[3]);\r
4147 t++;\r
4148 PutMap(t, ((PC-1) & AMASK));\r
4149 if (C) PutMap(t, (GetMap(t) | 0100000));\r
4150 PutMap(040, t);\r
4151 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
4152 continue;\r
4153 }\r
4154 i = (IR >> 11) & 3;\r
4155 FPSR &= 0xFCFFFFFF; /* Z+N bits off */\r
4156 j = (AC[0] >> 8) & 0x7F; /* expo of AC0 */\r
4157 k = (int32)(FPAC[i] >> 56) & 0x7F; /* expo of FPAC */\r
4158 tempfp = FPAC[i] & 0x8000000000000000; /* save sign */\r
4159 t = j - k;\r
4160 if (t > 0) { /* Positive shift */\r
4161 FPAC[i] &= 0x00FFFFFFFFFFFFFF;\r
4162 FPAC[i] = FPAC[i] >> (t * 4);\r
4163 FPAC[i] &= 0x00FFFFFFFFFFFFFF; /* AC0 expo becomes expo */\r
4164 holdfp = j;\r
4165 FPAC[i] |= (holdfp << 56);\r
4166 }\r
4167 if (t < 0) { /* Negative shift */\r
4168 FPAC[i] &= 0x00FFFFFFFFFFFFFF;\r
4169 FPAC[i] = FPAC[i] << ((0-t) * 4);\r
4170 FPSR |= 0x08000000; /* MOF bit on */\r
4171 FPAC[i] &= 0x00FFFFFFFFFFFFFF; /* AC0 expo becomes expo */\r
4172 holdfp = j;\r
4173 FPAC[i] |= (holdfp << 56);\r
4174 }\r
4175 if ((FPAC[i] & 0x00FFFFFFFFFFFFFF) != 0) \r
4176 FPAC[i] |= tempfp; /* restore sign */\r
4177 if ((FPAC[i] & 0x80FFFFFFFFFFFFFF) == 0) {\r
4178 FPAC[i] = 0;\r
4179 FPSR |= 0x02000000; /* Set Z */\r
4180 }\r
4181 if (FPAC[i] & 0x8000000000000000)\r
4182 FPSR |= 0x01000000; /* Set N */\r
4183 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
4184 FPSR |= ((PC - 1) & AMASK);\r
4185 continue;\r
4186 } \r
4187 if (IR == 0153350) { /* FCLE Clear Errors */\r
4188 if (!(fpu_unit.flags & UNIT_UP))\r
4189 continue;\r
4190 if (Debug_Flags == 1) {\r
4191 printf("\n<<FPU instruction: FCLE>>\n");\r
4192 reason = STOP_IBKPT;\r
4193 } \r
4194 if (FPFault) { /* Fault from a previous inst? */\r
4195 FPFault = 0;\r
4196 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
4197 PutMap(t, AC[0]);\r
4198 t++;\r
4199 PutMap(t, AC[1]);\r
4200 t++;\r
4201 PutMap(t, AC[2]);\r
4202 t++;\r
4203 PutMap(t, AC[3]);\r
4204 t++;\r
4205 PutMap(t, ((PC-1) & AMASK));\r
4206 if (C) PutMap(t, (GetMap(t) | 0100000));\r
4207 PutMap(040, t);\r
4208 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
4209 continue;\r
4210 }\r
4211 FPSR &= 0x07FFFFFF; /* set off all error bits */\r
4212 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
4213 FPSR |= ((PC - 1) & AMASK);\r
4214 continue;\r
4215 } \r
4216 if (IR == 0103250) { /* FNS No Skip */\r
4217 if (!(fpu_unit.flags & UNIT_UP))\r
4218 continue;\r
4219 if (Debug_Flags == 1) {\r
4220 printf("\n<<FPU instruction: FNS>>\n");\r
4221 reason = STOP_IBKPT;\r
4222 } \r
4223 if (FPFault) { /* Fault from a previous inst? */\r
4224 FPFault = 0;\r
4225 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
4226 PutMap(t, AC[0]);\r
4227 t++;\r
4228 PutMap(t, AC[1]);\r
4229 t++;\r
4230 PutMap(t, AC[2]);\r
4231 t++;\r
4232 PutMap(t, AC[3]);\r
4233 t++;\r
4234 PutMap(t, ((PC-1) & AMASK));\r
4235 if (C) PutMap(t, (GetMap(t) | 0100000));\r
4236 PutMap(040, t);\r
4237 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
4238 continue;\r
4239 }\r
4240 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
4241 FPSR |= ((PC - 1) & AMASK);\r
4242 continue;\r
4243 } \r
4244 if (IR == 0107250) { /* FSA Always Skip */\r
4245 if (!(fpu_unit.flags & UNIT_UP))\r
4246 continue;\r
4247 if (Debug_Flags == 2) {\r
4248 printf("\n<<FPU instruction: FSA>>\n");\r
4249 reason = STOP_IBKPT;\r
4250 } \r
4251 if (FPFault) { /* Fault from a previous inst? */\r
4252 FPFault = 0;\r
4253 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
4254 PutMap(t, AC[0]);\r
4255 t++;\r
4256 PutMap(t, AC[1]);\r
4257 t++;\r
4258 PutMap(t, AC[2]);\r
4259 t++;\r
4260 PutMap(t, AC[3]);\r
4261 t++;\r
4262 PutMap(t, ((PC-1) & AMASK));\r
4263 if (C) PutMap(t, (GetMap(t) | 0100000));\r
4264 PutMap(040, t);\r
4265 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
4266 continue;\r
4267 }\r
4268 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
4269 FPSR |= ((PC - 1) & AMASK);\r
4270 PC = (PC + 1) & AMASK;\r
4271 continue;\r
4272 } \r
4273 if (IR == 0137250) { /* FSGT */\r
4274 if (!(fpu_unit.flags & UNIT_UP))\r
4275 continue;\r
4276 if (Debug_Flags == 1) {\r
4277 printf("\n<<FPU instruction: FSGT>>\n");\r
4278 reason = STOP_IBKPT;\r
4279 } \r
4280 if (FPFault) { /* Fault from a previous inst? */\r
4281 FPFault = 0;\r
4282 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
4283 PutMap(t, AC[0]);\r
4284 t++;\r
4285 PutMap(t, AC[1]);\r
4286 t++;\r
4287 PutMap(t, AC[2]);\r
4288 t++;\r
4289 PutMap(t, AC[3]);\r
4290 t++;\r
4291 PutMap(t, ((PC-1) & AMASK));\r
4292 if (C) PutMap(t, (GetMap(t) | 0100000));\r
4293 PutMap(040, t);\r
4294 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
4295 continue;\r
4296 }\r
4297 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
4298 FPSR |= ((PC - 1) & AMASK);\r
4299 if (!(FPSR & 0x03000000)) /* Z & N both 0? */\r
4300 PC = (PC + 1) & AMASK; /* yep: skip */\r
4301 continue;\r
4302 } \r
4303 if (IR == 0123250) { /* FSLT */\r
4304 if (!(fpu_unit.flags & UNIT_UP))\r
4305 continue;\r
4306 if (Debug_Flags == 1) {\r
4307 printf("\n<<FPU instruction: FSLT>>\n");\r
4308 reason = STOP_IBKPT;\r
4309 } \r
4310 if (FPFault) { /* Fault from a previous inst? */\r
4311 FPFault = 0;\r
4312 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
4313 PutMap(t, AC[0]);\r
4314 t++;\r
4315 PutMap(t, AC[1]);\r
4316 t++;\r
4317 PutMap(t, AC[2]);\r
4318 t++;\r
4319 PutMap(t, AC[3]);\r
4320 t++;\r
4321 PutMap(t, ((PC-1) & AMASK));\r
4322 if (C) PutMap(t, (GetMap(t) | 0100000));\r
4323 PutMap(040, t);\r
4324 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
4325 continue;\r
4326 }\r
4327 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
4328 FPSR |= ((PC - 1) & AMASK);\r
4329 if (FPSR & 0x01000000) /* N is on? */\r
4330 PC = (PC + 1) & AMASK; /* yep: skip */\r
4331 continue;\r
4332 } \r
4333 if (IR == 0113250) { /* FSEQ */\r
4334 if (!(fpu_unit.flags & UNIT_UP))\r
4335 continue;\r
4336 if (Debug_Flags == 1) {\r
4337 printf("\n<<FPU instruction: FSEQ>>\n");\r
4338 reason = STOP_IBKPT;\r
4339 } \r
4340 if (FPFault) { /* Fault from a previous inst? */\r
4341 FPFault = 0;\r
4342 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
4343 PutMap(t, AC[0]);\r
4344 t++;\r
4345 PutMap(t, AC[1]);\r
4346 t++;\r
4347 PutMap(t, AC[2]);\r
4348 t++;\r
4349 PutMap(t, AC[3]);\r
4350 t++;\r
4351 PutMap(t, ((PC-1) & AMASK));\r
4352 if (C) PutMap(t, (GetMap(t) | 0100000));\r
4353 PutMap(040, t);\r
4354 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
4355 continue;\r
4356 }\r
4357 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
4358 FPSR |= ((PC - 1) & AMASK);\r
4359 if (FPSR & 0x02000000) /* Z is on? */\r
4360 PC = (PC + 1) & AMASK; /* yep: skip */\r
4361 continue;\r
4362 } \r
4363 if (IR == 0133250) { /* FSLE */\r
4364 if (!(fpu_unit.flags & UNIT_UP))\r
4365 continue;\r
4366 if (Debug_Flags == 1) {\r
4367 printf("\n<<FPU instruction: FSLE>>\n");\r
4368 reason = STOP_IBKPT;\r
4369 } \r
4370 if (FPFault) { /* Fault from a previous inst? */\r
4371 FPFault = 0;\r
4372 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
4373 PutMap(t, AC[0]);\r
4374 t++;\r
4375 PutMap(t, AC[1]);\r
4376 t++;\r
4377 PutMap(t, AC[2]);\r
4378 t++;\r
4379 PutMap(t, AC[3]);\r
4380 t++;\r
4381 PutMap(t, ((PC-1) & AMASK));\r
4382 if (C) PutMap(t, (GetMap(t) | 0100000));\r
4383 PutMap(040, t);\r
4384 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
4385 continue;\r
4386 }\r
4387 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
4388 FPSR |= ((PC - 1) & AMASK);\r
4389 if (FPSR & 0x03000000) /* Z or N on? */\r
4390 PC = (PC + 1) & AMASK; /* yep: skip */\r
4391 continue;\r
4392 } \r
4393 if (IR == 0127250) { /* FSGE */\r
4394 if (!(fpu_unit.flags & UNIT_UP))\r
4395 continue;\r
4396 if (Debug_Flags == 1) {\r
4397 printf("\n<<FPU instruction: FSGE>>\n");\r
4398 reason = STOP_IBKPT;\r
4399 } \r
4400 if (FPFault) { /* Fault from a previous inst? */\r
4401 FPFault = 0;\r
4402 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
4403 PutMap(t, AC[0]);\r
4404 t++;\r
4405 PutMap(t, AC[1]);\r
4406 t++;\r
4407 PutMap(t, AC[2]);\r
4408 t++;\r
4409 PutMap(t, AC[3]);\r
4410 t++;\r
4411 PutMap(t, ((PC-1) & AMASK));\r
4412 if (C) PutMap(t, (GetMap(t) | 0100000));\r
4413 PutMap(040, t);\r
4414 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
4415 continue;\r
4416 }\r
4417 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
4418 FPSR |= ((PC - 1) & AMASK);\r
4419 if (!(FPSR & 0x01000000)) /* N is off? */\r
4420 PC = (PC + 1) & AMASK; /* yep: skip */\r
4421 continue;\r
4422 } \r
4423 if (IR == 0117250) { /* FSNE */\r
4424 if (!(fpu_unit.flags & UNIT_UP))\r
4425 continue;\r
4426 if (Debug_Flags == 1) {\r
4427 printf("\n<<FPU instruction: FSNE>>\n");\r
4428 continue;\r
4429 } \r
4430 if (FPFault) { /* Fault from a previous inst? */\r
4431 FPFault = 0;\r
4432 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
4433 PutMap(t, AC[0]);\r
4434 t++;\r
4435 PutMap(t, AC[1]);\r
4436 t++;\r
4437 PutMap(t, AC[2]);\r
4438 t++;\r
4439 PutMap(t, AC[3]);\r
4440 t++;\r
4441 PutMap(t, ((PC-1) & AMASK));\r
4442 if (C) PutMap(t, (GetMap(t) | 0100000));\r
4443 PutMap(040, t);\r
4444 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
4445 continue;\r
4446 }\r
4447 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
4448 FPSR |= ((PC - 1) & AMASK);\r
4449 if (!(FPSR & 0x02000000)) /* Z is off? */\r
4450 PC = (PC + 1) & AMASK; /* yep: skip */\r
4451 continue;\r
4452 } \r
4453 if (IR == 0143250) { /* FSNM */\r
4454 if (!(fpu_unit.flags & UNIT_UP))\r
4455 continue;\r
4456 if (Debug_Flags == 1) {\r
4457 printf("\n<<FPU instruction: FSNM>>\n");\r
4458 reason = STOP_IBKPT;\r
4459 } \r
4460 if (FPFault) { /* Fault from a previous inst? */\r
4461 FPFault = 0;\r
4462 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
4463 PutMap(t, AC[0]);\r
4464 t++;\r
4465 PutMap(t, AC[1]);\r
4466 t++;\r
4467 PutMap(t, AC[2]);\r
4468 t++;\r
4469 PutMap(t, AC[3]);\r
4470 t++;\r
4471 PutMap(t, ((PC-1) & AMASK));\r
4472 if (C) PutMap(t, (GetMap(t) | 0100000));\r
4473 PutMap(040, t);\r
4474 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
4475 continue;\r
4476 }\r
4477 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
4478 FPSR |= ((PC - 1) & AMASK);\r
4479 if (!(FPSR & 0x08000000)) /* MOF is off? */\r
4480 PC = (PC + 1) & AMASK; /* yep: skip */\r
4481 continue;\r
4482 } \r
4483 if (IR == 0153250) { /* FSNU */\r
4484 if (!(fpu_unit.flags & UNIT_UP))\r
4485 continue;\r
4486 if (Debug_Flags == 1) {\r
4487 printf("\n<<FPU instruction: FSNU>>\n");\r
4488 reason = STOP_IBKPT;\r
4489 } \r
4490 if (FPFault) { /* Fault from a previous inst? */\r
4491 FPFault = 0;\r
4492 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
4493 PutMap(t, AC[0]);\r
4494 t++;\r
4495 PutMap(t, AC[1]);\r
4496 t++;\r
4497 PutMap(t, AC[2]);\r
4498 t++;\r
4499 PutMap(t, AC[3]);\r
4500 t++;\r
4501 PutMap(t, ((PC-1) & AMASK));\r
4502 if (C) PutMap(t, (GetMap(t) | 0100000));\r
4503 PutMap(040, t);\r
4504 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
4505 continue;\r
4506 }\r
4507 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
4508 FPSR |= ((PC - 1) & AMASK);\r
4509 if (!(FPSR & 0x20000000)) /* UNF is off? */\r
4510 PC = (PC + 1) & AMASK; /* yep: skip */\r
4511 continue;\r
4512 } \r
4513 if (IR == 0163250) { /* FSNO */\r
4514 if (!(fpu_unit.flags & UNIT_UP))\r
4515 continue;\r
4516 if (Debug_Flags == 1) {\r
4517 printf("\n<<FPU instruction: FSNO>>\n");\r
4518 reason = STOP_IBKPT;\r
4519 } \r
4520 if (FPFault) { /* Fault from a previous inst? */\r
4521 FPFault = 0;\r
4522 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
4523 PutMap(t, AC[0]);\r
4524 t++;\r
4525 PutMap(t, AC[1]);\r
4526 t++;\r
4527 PutMap(t, AC[2]);\r
4528 t++;\r
4529 PutMap(t, AC[3]);\r
4530 t++;\r
4531 PutMap(t, ((PC-1) & AMASK));\r
4532 if (C) PutMap(t, (GetMap(t) | 0100000));\r
4533 PutMap(040, t);\r
4534 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
4535 continue;\r
4536 }\r
4537 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
4538 FPSR |= ((PC - 1) & AMASK);\r
4539 if (!(FPSR & 0x40000000)) /* OVF is off? */\r
4540 PC = (PC + 1) & AMASK; /* yep: skip */\r
4541 continue;\r
4542 } \r
4543 if (IR == 0147250) { /* FSND */\r
4544 if (!(fpu_unit.flags & UNIT_UP))\r
4545 continue;\r
4546 if (Debug_Flags == 1) {\r
4547 printf("\n<<FPU instruction: FSND>>\n");\r
4548 reason = STOP_IBKPT;\r
4549 } \r
4550 if (FPFault) { /* Fault from a previous inst? */\r
4551 FPFault = 0;\r
4552 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
4553 PutMap(t, AC[0]);\r
4554 t++;\r
4555 PutMap(t, AC[1]);\r
4556 t++;\r
4557 PutMap(t, AC[2]);\r
4558 t++;\r
4559 PutMap(t, AC[3]);\r
4560 t++;\r
4561 PutMap(t, ((PC-1) & AMASK));\r
4562 if (C) PutMap(t, (GetMap(t) | 0100000));\r
4563 PutMap(040, t);\r
4564 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
4565 continue;\r
4566 }\r
4567 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
4568 FPSR |= ((PC - 1) & AMASK);\r
4569 if (!(FPSR & 0x10000000)) /* DVZ is off? */\r
4570 PC = (PC + 1) & AMASK; /* yep: skip */\r
4571 continue;\r
4572 } \r
4573 if (IR == 0157250) { /* FSNUD */\r
4574 if (!(fpu_unit.flags & UNIT_UP))\r
4575 continue;\r
4576 if (Debug_Flags == 1) {\r
4577 printf("\n<<FPU instruction: FSNUD>>\n");\r
4578 reason = STOP_IBKPT;\r
4579 } \r
4580 if (FPFault) { /* Fault from a previous inst? */\r
4581 FPFault = 0;\r
4582 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
4583 PutMap(t, AC[0]);\r
4584 t++;\r
4585 PutMap(t, AC[1]);\r
4586 t++;\r
4587 PutMap(t, AC[2]);\r
4588 t++;\r
4589 PutMap(t, AC[3]);\r
4590 t++;\r
4591 PutMap(t, ((PC-1) & AMASK));\r
4592 if (C) PutMap(t, (GetMap(t) | 0100000));\r
4593 PutMap(040, t);\r
4594 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
4595 continue;\r
4596 }\r
4597 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
4598 FPSR |= ((PC - 1) & AMASK);\r
4599 if (!(FPSR & 0x30000000)) /* UNF & DVZ off? */\r
4600 PC = (PC + 1) & AMASK; /* yep: skip */\r
4601 continue;\r
4602 } \r
4603 if (IR == 0167250) { /* FSNOD */\r
4604 if (!(fpu_unit.flags & UNIT_UP))\r
4605 continue;\r
4606 if (Debug_Flags == 1) {\r
4607 printf("\n<<FPU instruction: FSNOD>>\n");\r
4608 reason = STOP_IBKPT;\r
4609 } \r
4610 if (FPFault) { /* Fault from a previous inst? */\r
4611 FPFault = 0;\r
4612 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
4613 PutMap(t, AC[0]);\r
4614 t++;\r
4615 PutMap(t, AC[1]);\r
4616 t++;\r
4617 PutMap(t, AC[2]);\r
4618 t++;\r
4619 PutMap(t, AC[3]);\r
4620 t++;\r
4621 PutMap(t, ((PC-1) & AMASK));\r
4622 if (C) PutMap(t, (GetMap(t) | 0100000));\r
4623 PutMap(040, t);\r
4624 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
4625 continue;\r
4626 }\r
4627 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
4628 FPSR |= ((PC - 1) & AMASK);\r
4629 if (!(FPSR & 0x50000000)) /* OVF & DVZ off? */\r
4630 PC = (PC + 1) & AMASK; /* yep: skip */\r
4631 continue;\r
4632 } \r
4633 if (IR == 0173250) { /* FSNUO */\r
4634 if (!(fpu_unit.flags & UNIT_UP))\r
4635 continue;\r
4636 if (Debug_Flags == 1) {\r
4637 printf("\n<<FPU instruction: FSNUO>>\n");\r
4638 reason = STOP_IBKPT;\r
4639 } \r
4640 if (FPFault) { /* Fault from a previous inst? */\r
4641 FPFault = 0;\r
4642 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
4643 PutMap(t, AC[0]);\r
4644 t++;\r
4645 PutMap(t, AC[1]);\r
4646 t++;\r
4647 PutMap(t, AC[2]);\r
4648 t++;\r
4649 PutMap(t, AC[3]);\r
4650 t++;\r
4651 PutMap(t, ((PC-1) & AMASK));\r
4652 if (C) PutMap(t, (GetMap(t) | 0100000));\r
4653 PutMap(040, t);\r
4654 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
4655 continue;\r
4656 }\r
4657 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
4658 FPSR |= ((PC - 1) & AMASK);\r
4659 if (!(FPSR & 0x60000000)) /* OVF & UNF off? */\r
4660 PC = (PC + 1) & AMASK; /* yep: skip */\r
4661 continue;\r
4662 } \r
4663 if (IR == 0177250) { /* FSNER */\r
4664 if (!(fpu_unit.flags & UNIT_UP))\r
4665 continue;\r
4666 if (Debug_Flags == 1) {\r
4667 printf("\n<<FPU instruction: FSNER>>\n");\r
4668 reason = STOP_IBKPT;\r
4669 } \r
4670 if (FPFault) { /* Fault from a previous inst? */\r
4671 FPFault = 0;\r
4672 t = (GetMap(040) + 1) & AMASK; /* Yes: push rtn block */ \r
4673 PutMap(t, AC[0]);\r
4674 t++;\r
4675 PutMap(t, AC[1]);\r
4676 t++;\r
4677 PutMap(t, AC[2]);\r
4678 t++;\r
4679 PutMap(t, AC[3]);\r
4680 t++;\r
4681 PutMap(t, ((PC-1) & AMASK));\r
4682 if (C) PutMap(t, (GetMap(t) | 0100000));\r
4683 PutMap(040, t);\r
4684 PC = indirect(GetMap(045)); /* JMP indirect to 45 */\r
4685 continue;\r
4686 }\r
4687 FPSR &= 0xFFFF0000; /* Success: put addr in FPSR */\r
4688 FPSR |= ((PC - 1) & AMASK);\r
4689 if (!(FPSR & 0x78000000)) /* all errors off? */\r
4690 PC = (PC + 1) & AMASK; /* yep: skip */\r
4691 continue;\r
4692 } \r
4693 \r
4694 if (Debug_Flags) {\r
4695 printf("\n<<Unexecuted inst = %o at PC=%o>>\n\r", IR, PC-1);\r
4696 if (Debug_Flags & 040000) reason = STOP_IBKPT;\r
4697 } \r
4698}\r
4699\r
4700if (IR == 061777) { /* VCT: Vector on Interrupt */\r
4701 int32 stkchg, vtable;\r
4702 int32 ventry, dctadr;\r
4703 int32 old40, old41, old42, old43;\r
4704 \r
4705 /* Ok, folks, this is one helluva instruction */\r
4706 \r
4707 stkchg = GetMap(PC) & 0100000; /* Save stack change bit */\r
4708 vtable = GetMap(PC) & AMASK; /* Address of vector table */\r
4709 \r
4710 iodev = 0;\r
4711 int_req = (int_req & ~INT_DEV) | /* Do an INTA w/o an accum */\r
4712 (dev_done & ~dev_disable);\r
4713 iodata = int_req & (-int_req);\r
4714 for (i = DEV_LOW; i <= DEV_HIGH; i++) {\r
4715 if (iodata & dev_table[i].mask) {\r
4716 iodev = i;\r
4717 break;\r
4718 } \r
4719 }\r
4720 \r
4721 ventry = GetMap(vtable + iodev); /* Get Vector Entry */\r
4722 \r
4723 if (!(ventry & 0100000)) { /* Direct bit = 0? */\r
4724 PC = ventry & AMASK; /* YES - Mode A, so JMP */\r
4725 continue;\r
4726 } \r
4727 \r
4728 dctadr = ventry & AMASK; /* Get address of DCT entry */\r
4729 \r
4730 if (stkchg) { /* Stack change bit = 1? */\r
4731 old40 = GetMap(040); /* Save stack info */\r
4732 old41 = GetMap(041);\r
4733 old42 = GetMap(042);\r
4734 old43 = GetMap(043);\r
4735 PutMap(040, GetMap(004)); /* Loc 4 to stack ptr */\r
4736 PutMap(042, GetMap(006)); /* Loc 6 to stack limit */\r
4737 PutMap(043, GetMap(007)); /* Loc 7 into stack limit */\r
4738 PutMap(040, (GetMap(040) + 1)); /* Push old contents on new stk */\r
4739 PutMap(GetMap(040) & AMASK, old40);\r
4740 PutMap(040, (GetMap(040) + 1));\r
4741 PutMap(GetMap(040) & AMASK, old41);\r
4742 PutMap(040, (GetMap(040) + 1));\r
4743 PutMap(GetMap(040) & AMASK, old42);\r
4744 PutMap(040, (GetMap(040) + 1));\r
4745 PutMap(GetMap(040) & AMASK, old43);\r
4746 } \r
4747 \r
4748 t = GetMap(dctadr & AMASK); /* Get word 0 of DCT */\r
4749 \r
4750 if (t & 0100000) { /* Push bit set ? */\r
4751 PutMap(040, (GetMap(040) + 1)); /* Push "Standard rtn block" */\r
4752 PutMap(GetMap(040) & AMASK, AC[0]);\r
4753 PutMap(040, (GetMap(040) + 1));\r
4754 PutMap(GetMap(040) & AMASK, AC[1]);\r
4755 PutMap(040, (GetMap(040) + 1));\r
4756 PutMap(GetMap(040) & AMASK, AC[2]);\r
4757 PutMap(040, (GetMap(040) + 1));\r
4758 PutMap(GetMap(040) & AMASK, AC[3]);\r
4759 PutMap(040, (GetMap(040) + 1));\r
4760 PutMap(GetMap(040) & AMASK, GetMap(0));\r
4761 if (GetMap(0) == 0 && Debug_Flags) {\r
4762 printf("\n<<VCT will rtn to 0 @ %o>>\n\r", PC);\r
4763 reason = STOP_IBKPT;\r
4764 } \r
4765 if (C) PutMap(GetMap(040) & AMASK, (GetMap(GetMap(040) & AMASK) | 0100000));\r
4766 }\r
4767 \r
4768 AC[2] = dctadr & AMASK; /* DCT Addr into AC2 */\r
4769 \r
4770 PutMap(040, (GetMap(040) + 1)); /* Push pri int mask onto stack */\r
4771 PutMap(GetMap(040) & AMASK, pimask);\r
4772 \r
4773 AC[0] = GetMap(dctadr + 1) | pimask; /* Build new mask from word 1 of dct */\r
4774 PutMap(005, AC[0]);\r
4775 \r
4776 mask_out(pimask = AC[0]); /* Do a mask out inst */\r
4777 \r
4778 PC = GetMap(dctadr) & AMASK; /* Finally, JMP to int routine */\r
4779 \r
4780 continue;\r
4781}\r
4782\r
4783/*************************************************************************\r
4784** At this point, the instruction is not an Eclipse one. Therefore **\r
4785** decode it as a Nova instruction just like the Nova does. **\r
4786*************************************************************************/\r
4787\r
4788/* Memory reference instructions */\r
4789\r
4790if (t < 014) { /* mem ref? */\r
4791 register int32 src, MA;\r
4792\r
4793 MA = IR & 0377;\r
4794 switch ((IR >> 8) & 03) { /* decode IR<6:7> */\r
4795 case 0: /* page zero */\r
4796 break;\r
4797 case 1: /* PC relative */\r
4798 if (MA & 0200) MA = 077400 | MA;\r
4799 MA = (MA + PC - 1) & AMASK;\r
4800 break;\r
4801 case 2: /* AC2 relative */\r
4802 if (MA & 0200) MA = 077400 | MA;\r
4803 MA = (MA + AC[2]) & AMASK;\r
4804 break;\r
4805 case 3: /* AC3 relative */\r
4806 if (MA & 0200) MA = 077400 | MA;\r
4807 MA = (MA + AC[3]) & AMASK;\r
4808 break; \r
4809 }\r
4810 if (IR & 002000) { /* indirect? */\r
4811 for (i = 0; i < (ind_max * 2); i++) { /* count indirects */\r
4812 if ((MA & 077770) == 020 && !(cpu_unit.flags & UNIT_MICRO))\r
4813 MA = (PutMap(MA & AMASK, (GetMap(MA & AMASK) + 1) & 0177777));\r
4814 else if ((MA & 077770) == 030 && !(cpu_unit.flags & UNIT_MICRO))\r
4815 MA = (PutMap(MA & AMASK, (GetMap(MA & AMASK) - 1) & 0177777));\r
4816 else MA = GetMap(MA & AMASK);\r
4817 if (MapStat & 1) { /* Start MAP */\r
4818 Usermap = Enable;\r
4819 Inhibit = 0;\r
4820 } \r
4821 if ((MA & 0100000) == 0) break;\r
4822 if (i >= ind_max && (MapStat & 010) && Usermap) break;\r
4823 }\r
4824 if (i >= (ind_max-1)) {\r
4825 if ((MapStat & 010) && Usermap) {\r
4826 Fault = 04000; /* Map fault if IND prot */\r
4827 continue;\r
4828 } \r
4829 if (i >= (ind_max * 2) && !(Fault)) {\r
4830 reason = STOP_IND;\r
4831 break;\r
4832 }\r
4833 }\r
4834 } \r
4835\r
4836 switch (t) { /* decode IR<1:4> */\r
4837 case 001: /* JSR */\r
4838 AC[3] = PC;\r
4839 case 000: /* JMP */\r
4840 old_PC = PC;\r
4841 PC = MA;\r
4842 break;\r
4843 case 002: /* ISZ */\r
4844 src = (GetMap(MA) + 1) & 0177777;\r
4845 if (MEM_ADDR_OK (MA)) PutMap(MA, src);\r
4846 if (src == 0) PC = (PC + 1) & AMASK;\r
4847 break;\r
4848 case 003: /* DSZ */\r
4849 src = (GetMap(MA) - 1) & 0177777;\r
4850 if (MEM_ADDR_OK (MA)) PutMap(MA, src);\r
4851 if (src == 0) PC = (PC + 1) & AMASK;\r
4852 break;\r
4853 case 004: /* LDA 0 */\r
4854 if (SingleCycle) Usermap = SingleCycle;\r
4855 AC[0] = GetMap(MA);\r
4856 if (SingleCycle) {\r
4857 Usermap = SingleCycle = 0;\r
4858 if (Inhibit == 1) Inhibit = 3;\r
4859 MapStat |= 02000;\r
4860 MapStat &= 0177776;\r
4861 } \r
4862 break;\r
4863 case 005: /* LDA 1 */\r
4864 if (SingleCycle) Usermap = SingleCycle;\r
4865 AC[1] = GetMap(MA);\r
4866 if (SingleCycle) {\r
4867 Usermap = SingleCycle = 0;\r
4868 if (Inhibit == 1) Inhibit = 3;\r
4869 MapStat |= 02000;\r
4870 MapStat &= 0177776;\r
4871 } \r
4872 break;\r
4873 case 006: /* LDA 2 */\r
4874 if (SingleCycle) Usermap = SingleCycle;\r
4875 AC[2] = GetMap(MA);\r
4876 if (SingleCycle) {\r
4877 Usermap = SingleCycle = 0;\r
4878 if (Inhibit == 1) Inhibit = 3;\r
4879 MapStat |= 02000;\r
4880 MapStat &= 0177776;\r
4881 } \r
4882 break;\r
4883 case 007: /* LDA 3 */\r
4884 if (SingleCycle) Usermap = SingleCycle;\r
4885 AC[3] = GetMap(MA);\r
4886 if (SingleCycle) {\r
4887 Usermap = SingleCycle = 0;\r
4888 if (Inhibit == 1) Inhibit = 3;\r
4889 MapStat |= 02000;\r
4890 MapStat &= 0177776;\r
4891 } \r
4892 break;\r
4893 case 010: /* STA 0 */\r
4894 if (SingleCycle) \r
4895 Usermap = SingleCycle;\r
4896 if (MEM_ADDR_OK (MA)) PutMap(MA, AC[0]);\r
4897 if (SingleCycle) {\r
4898 Usermap = SingleCycle = 0;\r
4899 if (Inhibit == 1) Inhibit = 3;\r
4900 MapStat |= 02000;\r
4901 MapStat &= 0177776;\r
4902 } \r
4903 break;\r
4904 case 011: /* STA 1 */\r
4905 if (SingleCycle) \r
4906 Usermap = SingleCycle;\r
4907 if (MEM_ADDR_OK (MA)) PutMap(MA, AC[1]);\r
4908 if (SingleCycle) {\r
4909 Usermap = SingleCycle = 0;\r
4910 if (Inhibit == 1) Inhibit = 3;\r
4911 MapStat |= 02000;\r
4912 MapStat &= 0177776;\r
4913 } \r
4914 break;\r
4915 case 012: /* STA 2 */\r
4916 if (SingleCycle) \r
4917 Usermap = SingleCycle;\r
4918 if (MEM_ADDR_OK (MA)) PutMap(MA, AC[2]);\r
4919 if (SingleCycle) {\r
4920 Usermap = SingleCycle = 0;\r
4921 if (Inhibit == 1) Inhibit = 3;\r
4922 MapStat |= 02000;\r
4923 MapStat &= 0177776;\r
4924 } \r
4925 break;\r
4926 case 013: /* STA 3 */\r
4927 if (SingleCycle) \r
4928 Usermap = SingleCycle;\r
4929 if (MEM_ADDR_OK (MA)) PutMap(MA, AC[3]);\r
4930 if (SingleCycle) {\r
4931 Usermap = SingleCycle = 0;\r
4932 if (Inhibit == 1) Inhibit = 3;\r
4933 MapStat |= 02000;\r
4934 MapStat &= 0177776;\r
4935 } \r
4936 break;\r
4937 } /* end switch */\r
4938} /* end mem ref */\r
4939\r
4940/* Operate instruction */\r
4941\r
4942else if (t & 020) { /* operate? */\r
4943 register int32 src, srcAC, dstAC;\r
4944\r
4945 srcAC = (t >> 2) & 3; /* get reg decodes */\r
4946 dstAC = t & 03;\r
4947 switch ((IR >> 4) & 03) { /* decode IR<10:11> */\r
4948 case 0: /* load */\r
4949 src = AC[srcAC] | C;\r
4950 break;\r
4951 case 1: /* clear */\r
4952 src = AC[srcAC];\r
4953 break;\r
4954 case 2: /* set */\r
4955 src = AC[srcAC] | 0200000;\r
4956 break;\r
4957 case 3: /* complement */\r
4958 src = AC[srcAC] | (C ^ 0200000);\r
4959 break;\r
4960 } /* end switch carry */\r
4961\r
4962 switch ((IR >> 8) & 07) { /* decode IR<5:7> */\r
4963 case 0: /* COM */\r
4964 src = src ^ 0177777;\r
4965 break;\r
4966 case 1: /* NEG */\r
4967 src = ((src ^ 0177777) + 1) & 0377777;\r
4968 break;\r
4969 case 2: /* MOV */\r
4970 break;\r
4971 case 3: /* INC */\r
4972 src = (src + 1) & 0377777;\r
4973 break;\r
4974 case 4: /* ADC */\r
4975 src = ((src ^ 0177777) + AC[dstAC]) & 0377777;\r
4976 break;\r
4977 case 5: /* SUB */\r
4978 src = ((src ^ 0177777) + AC[dstAC] + 1) & 0377777;\r
4979 break;\r
4980 case 6: /* ADD */\r
4981 src = (src + AC[dstAC]) & 0377777;\r
4982 break;\r
4983 case 7: /* AND */\r
4984 src = src & (AC[dstAC] | 0200000);\r
4985 break;\r
4986 } /* end switch oper */\r
4987\r
4988 switch ((IR >> 6) & 03) { /* decode IR<8:9> */\r
4989 case 0: /* nop */\r
4990 break;\r
4991 case 1: /* L */\r
4992 src = ((src << 1) | (src >> 16)) & 0377777;\r
4993 break;\r
4994 case 2: /* R */\r
4995 src = ((src >> 1) | (src << 16)) & 0377777;\r
4996 break;\r
4997 case 3: /* S */\r
4998 src = ((src & 0377) << 8) | ((src >> 8) & 0377) |\r
4999 (src & 0200000);\r
5000 break;\r
5001 } /* end switch shift */\r
5002\r
5003 switch (IR & 07) { /* decode IR<13:15> */\r
5004 case 0: /* nop */\r
5005 break;\r
5006 case 1: /* SKP */\r
5007 PC = (PC + 1) & AMASK;\r
5008 break;\r
5009 case 2: /* SZC */\r
5010 if (src < 0200000) PC = (PC + 1) & AMASK;\r
5011 break;\r
5012 case 3: /* SNC */\r
5013 if (src >= 0200000) PC = (PC + 1) & AMASK;\r
5014 break;\r
5015 case 4: /* SZR */\r
5016 if ((src & 0177777) == 0) PC = (PC + 1) & AMASK;\r
5017 break;\r
5018 case 5: /* SNR */\r
5019 if ((src & 0177777) != 0) PC = (PC + 1) & AMASK;\r
5020 break;\r
5021 case 6: /* SEZ */\r
5022 if (src <= 0200000) PC = (PC + 1) & AMASK;\r
5023 break;\r
5024 case 7: /* SBN */\r
5025 if (src > 0200000) PC = (PC + 1) & AMASK;\r
5026 break;\r
5027 } /* end switch skip */\r
5028 if ((IR & 000010) == 0) { /* load? */\r
5029 AC[dstAC] = src & 0177777;\r
5030 C = src & 0200000;\r
5031 } /* end if load */\r
5032} /* end if operate */\r
5033\r
5034/* IOT instruction */\r
5035\r
5036else { /* IOT */\r
5037 register int32 dstAC, pulse, code, device, iodata;\r
5038 char pulcode[4];\r
5039 \r
5040 if ((MapStat & 0100) /* LEF mode bit on? */ \r
5041 && Usermap) { /* We are in LEF Mode */\r
5042 AC[(IR >> 11) & 3] = LEFmode(PC - 1, (IR >> 8) & 3, IR & 0377, IR & 02000);\r
5043 if (Debug_Flags & 020000) {\r
5044 printf("\n\r<<LEF Break by special request - executed at %o.>>\n\r", PC-1);\r
5045 reason = STOP_IBKPT;\r
5046 } \r
5047 continue;\r
5048 }\r
5049 \r
5050 dstAC = t & 03; /* decode fields */\r
5051 if ((MapStat & 040) && Usermap) { /* I/O protection fault */\r
5052 Fault = 020000;\r
5053 continue;\r
5054 } \r
5055 code = (IR >> 8) & 07;\r
5056 pulse = (IR >> 6) & 03;\r
5057 device = IR & 077;\r
5058 if (Debug_Flags && device == 0) {\r
5059 printf("\n\r<<I/O to device 00 at %o.>>\n\r", PC-1);\r
5060 reason = STOP_IBKPT;\r
5061 continue;\r
5062 } \r
5063 if ((Debug_Flags & 0100) && (device == (Debug_Flags & 077))) {\r
5064 printf("\n\r<<I/O Break (device %o) >>\n\r", device);\r
5065 reason = STOP_IBKPT;\r
5066 continue;\r
5067 } \r
5068 if ((Debug_Char != 0) && (device == 011) &&\r
5069 ((AC[dstAC] & 0177) == Debug_Char)) {\r
5070 printf("\n\r<<I/O Break (Char %o to TTO) >>\n\r", Debug_Char);\r
5071 reason = STOP_IBKPT;\r
5072 continue;\r
5073 } \r
5074 if (code == ioSKP) { /* IO skip? */\r
5075 switch (pulse) { /* decode IR<8:9> */\r
5076 case 0: /* skip if busy */\r
5077 if ((device == 077)? (int_req & INT_ION) != 0:\r
5078 (dev_busy & dev_table[device].mask) != 0)\r
5079 PC = (PC + 1) & AMASK;\r
5080 break;\r
5081 case 1: /* skip if not busy */\r
5082 if ((device == 077)? (int_req & INT_ION) == 0:\r
5083 (dev_busy & dev_table[device].mask) == 0)\r
5084 PC = (PC + 1) & AMASK;\r
5085 break;\r
5086 case 2: /* skip if done */\r
5087 if ((device == 077)? pwr_low != 0:\r
5088 (dev_done & dev_table[device].mask) != 0)\r
5089 PC = (PC + 1) & AMASK;\r
5090 break;\r
5091 case 3: /* skip if not done */\r
5092 if ((device == 077)? pwr_low == 0:\r
5093 (dev_done & dev_table[device].mask) == 0)\r
5094 PC = (PC + 1) & AMASK;\r
5095 break;\r
5096 } /* end switch */\r
5097 } /* end IO skip */\r
5098\r
5099 else if (device == DEV_CPU) { /* CPU control */\r
5100 switch (code) { /* decode IR<5:7> */\r
5101 case ioNIO: /* Get CPU ID */\r
5102 switch (model) {\r
5103 case 280: /* S280 */\r
5104 AC[0] = 021102;\r
5105 break;\r
5106 case 380:\r
5107 AC[0] = 013212; /* C380 */\r
5108 break;\r
5109 default:\r
5110 break;\r
5111 } \r
5112 break; /* Otherwise no-op */\r
5113 case ioDIA: /* read switches */\r
5114 AC[dstAC] = SR;\r
5115 break;\r
5116 case ioDIB: /* int ack */\r
5117 AC[dstAC] = 0;\r
5118 int_req = (int_req & ~INT_DEV) |\r
5119 (dev_done & ~dev_disable);\r
5120 iodata = int_req & (-int_req);\r
5121 for (i = DEV_LOW; i <= DEV_HIGH; i++) {\r
5122 if (iodata & dev_table[i].mask) {\r
5123 AC[dstAC] = i;\r
5124 break;\r
5125 }\r
5126 }\r
5127 break;\r
5128 case ioDOB: /* mask out */\r
5129 mask_out (pimask = AC[dstAC]);\r
5130 break;\r
5131 case ioDIC: /* io reset IORST */\r
5132 reset_all (0); /* reset devices */\r
5133 Usermap = 0; /* reset MAP */\r
5134 MapStat &= 04; /* Reset MAP status */\r
5135 MapIntMode = 0;\r
5136 Inhibit = 0;\r
5137 Map31 = 037;\r
5138 Check = SingleCycle = 0;\r
5139 Fault = 0;\r
5140 FPSR &= 0x0000FFFF;\r
5141 FPFault = 0;\r
5142 break;\r
5143 case ioDOC: /* halt */\r
5144 reason = STOP_HALT;\r
5145 break;\r
5146 } /* end switch code */\r
5147\r
5148 switch (pulse) { /* decode IR<8:9> */\r
5149 case iopS: /* ion */\r
5150 int_req = (int_req | INT_ION) & ~INT_NO_ION_PENDING;\r
5151 break;\r
5152 case iopC: /* iof */\r
5153 int_req = int_req & ~INT_ION;\r
5154 break; } /* end switch pulse */\r
5155 } /* end CPU control */\r
5156\r
5157 else if (device == DEV_ECC) {\r
5158 switch (code) {\r
5159 case ioDIA: /* Read Fault Address */\r
5160 AC[dstAC] = 0;\r
5161 break;\r
5162 case ioDIB: /* Read fault code */\r
5163 AC[dstAC] = 0;\r
5164 break;\r
5165 case ioDOA: /* Enable ERCC */\r
5166 break; }\r
5167 }\r
5168 \r
5169 else if (device == DEV_MAP) { /* MAP control */\r
5170 switch (code) { /* decode IR<5:7> */\r
5171 case ioNIO: /* No I/O -- Single */\r
5172 if (!Usermap || !(MapStat & 0140)) {\r
5173 if ((Debug_Flags & 077) == 03)\r
5174 fprintf(Trace, "%o NIO %o (No I/O, clear faults)\n", PC-1, dstAC);\r
5175 MapStat &= ~036000; /* NIO Clears all faults */\r
5176 } else {\r
5177 if ((Debug_Flags & 077) == 03)\r
5178 fprintf(Trace, "%o NIO %o (No I/O, clear faults) NO EXEC(User mode)\n", PC-1, dstAC);\r
5179 } \r
5180 break;\r
5181 case ioDIA: /* Read map status */\r
5182 if (!Usermap || !(MapStat & 0140)) { \r
5183 if ((Debug_Flags & 077) == 03)\r
5184 fprintf(Trace, "%o DIA %o=%o (Read Map Status)\n", PC-1, dstAC, MapStat);\r
5185 AC[dstAC] = MapStat & 0xFFFE;\r
5186 if (MapIntMode & 1) /* Bit 15 is mode asof last int */\r
5187 AC[dstAC] |= 1;\r
5188 } else {\r
5189 if ((Debug_Flags & 077) == 03)\r
5190 fprintf(Trace, "%o DIA %o=%o (Read Map Status) NO EXEC(User mode)\n", PC-1, dstAC, MapStat);\r
5191 } \r
5192 break;\r
5193 case ioDOA: /* Load map status */\r
5194 if (!Usermap || !(MapStat & 0140)) { \r
5195 if ((Debug_Flags & 077) == 03)\r
5196 fprintf(Trace, "%o DOA %o=%o (Load Map Status)\n", PC-1, dstAC, AC[dstAC]);\r
5197 MapStat = AC[dstAC];\r
5198 MapIntMode = 0;\r
5199 Enable = 1;\r
5200 if (MapStat & 04) Enable = 2;\r
5201 Check &= ~01600;\r
5202 Check |= MapStat & 01600;\r
5203 if (MapStat & 1)\r
5204 Inhibit = 2; /* Inhibit interrupts */\r
5205 } else {\r
5206 if ((Debug_Flags & 077) == 03)\r
5207 fprintf(Trace, "%o DOA %o=%o (Load Map Status) NO EXEC(User mode)\n", PC-1, dstAC, AC[dstAC]);\r
5208 } \r
5209 break; \r
5210 case ioDIB: /* not used */\r
5211 break;\r
5212 case ioDOB: /* map block 31 */\r
5213//AOS if (!Usermap || !(MapStat && 0140)) { \r
5214 if ((Debug_Flags & 077) == 03)\r
5215 fprintf(Trace, "%o DOB %o=%o (Map Blk 31)\n", PC-1, dstAC, AC[dstAC]);\r
5216 Map31 = AC[dstAC] & PAGEMASK;\r
5217 MapStat &= ~02000;\r
5218//AOS } else {\r
5219//AOS if ((Debug_Flags & 077) == 03)\r
5220//AOS fprintf(Trace, "%o DOB %o=%o (Map Blk 31) NO EXEC (User Mode)\n", PC-1, dstAC, AC[dstAC]);\r
5221//AOS } \r
5222 break;\r
5223 case ioDIC: /* Page Check */\r
5224 if (!Usermap || !(MapStat & 0140)) {\r
5225 switch ((Check>>7) & 07) {\r
5226 case 0: i=1; break;\r
5227 case 1: i=6; break;\r
5228 case 2: i=2; break;\r
5229 case 3: i=7; break;\r
5230 case 4: i=0; break;\r
5231 case 5: i=4; break;\r
5232 case 6: i=3; break;\r
5233 case 7: i=5; break;\r
5234 default: break;\r
5235 }\r
5236 j = (Check >> 10) & 037;\r
5237 AC[dstAC] = Map[i][j] & 0101777;\r
5238 AC[dstAC] |= ((Check << 5) & 070000);\r
5239 if ((Debug_Flags & 077) == 03)\r
5240 fprintf(Trace, "%o DIC %o=%o (Page Check)\n", PC-1, dstAC, AC[dstAC]);\r
5241 MapStat &= ~02000;\r
5242 } else {\r
5243 if ((Debug_Flags & 077) == 03)\r
5244 fprintf(Trace, "%o DIC %o=%o (Page Check) NO EXEC(User mode)\n", PC-1, dstAC, AC[dstAC]);\r
5245 } \r
5246 break;\r
5247 case ioDOC: /* Init Page Check */\r
5248 if (!Usermap || !(MapStat & 0140)) { \r
5249 if ((Debug_Flags & 077) == 03)\r
5250 fprintf(Trace, "%o DOC %o=%o (Init Pg Chk)\n", PC-1, dstAC, AC[dstAC]);\r
5251 Check = AC[dstAC];\r
5252 MapStat &= ~01600;\r
5253 MapStat |= (Check & 01600);\r
5254 MapStat &= ~02000;\r
5255 } else {\r
5256 if ((Debug_Flags & 077) == 03)\r
5257 fprintf(Trace, "%o DOC %o=%o (Init Pg Chk) NO EXEC(User mode)\n", PC-1, dstAC, AC[dstAC]);\r
5258 } \r
5259 break; \r
5260 } /* end switch code */\r
5261\r
5262 switch (pulse) {\r
5263 case iopP:\r
5264 if ((Debug_Flags & 077) == 03)\r
5265 fprintf(Trace, "%o xxxP (Single Cycle)\n", PC-1);\r
5266 if (Usermap) {\r
5267 MapStat &= 0177776;\r
5268 Usermap = 0;\r
5269 Inhibit = 0;\r
5270 } else { \r
5271 SingleCycle = Enable;\r
5272 Inhibit = 1; /* Inhibit interrupts */\r
5273 } \r
5274 break;\r
5275 }\r
5276 } /* end CPU control */\r
5277 else if (dev_table[device].routine) { /* normal device */\r
5278 iodata = dev_table[device].routine (pulse, code, AC[dstAC]);\r
5279 reason = iodata >> IOT_V_REASON;\r
5280 if (code & 1) AC[dstAC] = iodata & 0177777;\r
5281 if ((Debug_Flags & 077) == device && Debug_Flags != 0) {\r
5282 strcpy(pulcode, "");\r
5283 switch (pulse) {\r
5284 case iopP:\r
5285 strcpy(pulcode, "P");\r
5286 break;\r
5287 case iopS:\r
5288 strcpy(pulcode, "S");\r
5289 break;\r
5290 case iopC:\r
5291 strcpy(pulcode, "C");\r
5292 break;\r
5293 default:\r
5294 break;\r
5295 } \r
5296 switch(code) {\r
5297 case ioNIO:\r
5298 fprintf(Trace, "[%o] %o NIO%s %o\n", device, PC-1, pulcode, AC[dstAC]);\r
5299 break;\r
5300 case ioDIA:\r
5301 fprintf(Trace, "[%o] %o DIA%s %o\n", device, PC-1, pulcode, iodata);\r
5302 break;\r
5303 case ioDIB:\r
5304 fprintf(Trace, "[%o] %o DIB%s %o\n", device, PC-1, pulcode, iodata);\r
5305 break;\r
5306 case ioDIC:\r
5307 fprintf(Trace, "[%o] %o DIC%s %o\n", device, PC-1, pulcode, iodata);\r
5308 break;\r
5309 case ioDOA:\r
5310 fprintf(Trace, "[%o] %o DOA%s %o\n", device, PC-1, pulcode, AC[dstAC]);\r
5311 break;\r
5312 case ioDOB:\r
5313 fprintf(Trace, "[%o] %o DOB%s %o\n", device, PC-1, pulcode, AC[dstAC]);\r
5314 break;\r
5315 case ioDOC:\r
5316 fprintf(Trace, "[%o] %o DOC%s %o\n", device, PC-1, pulcode, AC[dstAC]);\r
5317 break;\r
5318 default:\r
5319 break;\r
5320 } /* end switch */ \r
5321 } /* end if debug */\r
5322 } /* end else if */\r
5323 else reason = stop_dev;\r
5324} /* end if IOT */\r
5325} /* end while */\r
5326\r
5327/* Simulation halted */\r
5328\r
5329saved_PC = PC;\r
5330return reason;\r
5331}\r
5332\r
5333/* Computes and returns a 16-bit effective address, given a\r
5334 program counter, index, and a displacement.\r
5335*/\r
5336\r
5337int32 effective(int32 PC, int32 index, int32 disp)\r
5338{\r
5339 register int32 i, MA;\r
5340\r
5341 MA = disp & 077777;\r
5342 switch (index) { /* decode IR<6:7> */\r
5343 case 0: /* page zero */\r
5344 break;\r
5345 case 1: /* PC relative */\r
5346 MA = (MA + PC) & AMASK;\r
5347 break;\r
5348 case 2: /* AC2 relative */\r
5349 MA = (MA + AC[2]) & AMASK;\r
5350 break;\r
5351 case 3: /* AC3 relative */\r
5352 MA = (MA + AC[3]) & AMASK;\r
5353 break;\r
5354 } /* end switch mode */\r
5355\r
5356 if (disp & 0100000) { /* indirect? */\r
5357 for (i = 0; i < ind_max * 2; i++) { /* count indirects */\r
5358 MA = GetMap(MA & AMASK); \r
5359 if (SingleCycle) Usermap = 0;\r
5360 if (MapStat & 1) { /* Start MAP */\r
5361 Usermap = Enable;\r
5362 Inhibit = 0;\r
5363 } \r
5364 if ((MA & 0100000) == 0) break; \r
5365 if ((MapStat & 010) && Usermap && i >= ind_max) break;\r
5366 }\r
5367 if (i >= (ind_max-1) && (MapStat & 010) && Usermap) {\r
5368 Fault = 04000; /* Map fault if IND prot */\r
5369 } \r
5370 if (i >= (ind_max * 2) && !(Fault)) {\r
5371 reason = STOP_IND_INT; /* Stop machine */\r
5372 }\r
5373 }\r
5374 return (MA & AMASK);\r
5375} \r
5376\r
5377/* Computes and returns a 16-bit effective address, given a\r
5378 program counter, index, and a displacement. This is a \r
5379 version supporting the LEF map mode instruction, as \r
5380 opposed to the ELEF instruction.\r
5381*/\r
5382\r
5383int32 LEFmode(int32 PC, int32 index, int32 disp, int32 indirect)\r
5384{\r
5385 register int32 i, MA;\r
5386 int16 sMA;\r
5387\r
5388 MA = disp & 077777;\r
5389 switch (index) { /* decode IR<6:7> */\r
5390 case 0: /* page zero */\r
5391 break;\r
5392 case 1: /* PC relative */\r
5393 sMA = MA;\r
5394 if (MA & 0200) sMA |= 0xff00;\r
5395 MA = (sMA + PC) & AMASK;\r
5396 break;\r
5397 case 2: /* AC2 relative */\r
5398 sMA = MA;\r
5399 if (MA & 0200) sMA |= 0xff00;\r
5400 MA = (sMA + AC[2]) & AMASK;\r
5401 break;\r
5402 case 3: /* AC3 relative */\r
5403 sMA = MA;\r
5404 if (MA & 0200) sMA |= 0xff00;\r
5405 MA = (sMA + AC[3]) & AMASK;\r
5406 break;\r
5407 } /* end switch mode */\r
5408\r
5409 if (indirect) { /* indirect? */\r
5410 for (i = 0; i < (ind_max * 2); i++) { /* count indirects */\r
5411 if ((MA & 077770) == 020 && !(cpu_unit.flags & UNIT_MICRO))\r
5412 MA = (PutMap(MA & AMASK, (GetMap(MA & AMASK) + 1) & 0177777));\r
5413 else if ((MA & 077770) == 030 && !(cpu_unit.flags & UNIT_MICRO))\r
5414 MA = (PutMap(MA & AMASK, (GetMap(MA & AMASK) - 1) & 0177777));\r
5415 else MA = GetMap(MA & AMASK);\r
5416 if (SingleCycle) Usermap = 0;\r
5417 if (MapStat & 1) { /* Start MAP */\r
5418 Usermap = Enable;\r
5419 Inhibit = 0;\r
5420 } \r
5421 if ((MA & 0100000) == 0) break;\r
5422 if ((MapStat & 010) && Usermap && i >= ind_max) break;\r
5423 }\r
5424 if (i >= (ind_max-1) && (MapStat & 010) && Usermap) {\r
5425 Fault = 04000; /* Map fault if IND prot */\r
5426 } \r
5427 if (i >= (ind_max * 2) && !(Fault)) {\r
5428 reason = STOP_IND_INT; /* Stop machine */\r
5429 } \r
5430 }\r
5431 return (MA & AMASK);\r
5432} \r
5433\r
5434/* Computes a "Byte pointer" for the Character Instruction set */\r
5435/* This address in 'PC' must point to the displacement word of the instruction */\r
5436\r
5437int32 Bytepointer(int32 PC, int32 index)\r
5438{\r
5439 register int32 MA;\r
5440\r
5441 switch (index) { /* decode IR<6:7> */\r
5442 case 0: /* page zero */\r
5443 MA = 0;\r
5444 break;\r
5445 case 1: /* PC relative */\r
5446 MA = PC & AMASK;\r
5447 break;\r
5448 case 2: /* AC2 relative */\r
5449 MA = AC[2] & AMASK;\r
5450 break;\r
5451 case 3: /* AC3 relative */\r
5452 MA = AC[3] & AMASK;\r
5453 break;\r
5454 } /* end switch mode */\r
5455 MA = (MA * 2) & 0177777;\r
5456 MA = MA + GetMap(PC); \r
5457 return (MA & 0177777);\r
5458}\r
5459\r
5460/* Given an address, returns either that address if bit 0 is 0, or\r
5461 or follows an indirection chain until bit 0 is 0\r
5462*/\r
5463\r
5464int32 indirect(int32 d)\r
5465{\r
5466 int i;\r
5467 \r
5468 if (d & 0100000) { /* indirect? */\r
5469 for (i = 0; i < ind_max * 2; i++) { /* count indirects */\r
5470 if ((d & 077770) == 020 && !(cpu_unit.flags & UNIT_MICRO)) \r
5471 d = (PutMap(d & AMASK, ((GetMap(d & AMASK) + 1) & 0177777)));\r
5472 else if ((d & 077770) == 030 && !(cpu_unit.flags & UNIT_MICRO)) \r
5473 d = (PutMap(d & AMASK, ((GetMap(d & AMASK) - 1) & 0177777)));\r
5474 else d = GetMap(d & AMASK);\r
5475 if (MapStat & 1) { /* Start MAP */\r
5476 Usermap = Enable;\r
5477 Inhibit = 0;\r
5478 } \r
5479 if ((d & 0100000) == 0) break;\r
5480 if ((MapStat & 010) && Usermap && i >= ind_max) break;\r
5481 }\r
5482 if (i >= (ind_max-1) && (MapStat & 010) && Usermap) {\r
5483 Fault = 04000; /* Map fault if IND prot */\r
5484 } \r
5485 if (i >= (ind_max * 2) && !(Fault)) {\r
5486 reason = STOP_IND; /* Stop machine */\r
5487 }\r
5488 } \r
5489 return (d);\r
5490}\r
5491\r
5492/* Push a standard return block onto the stack */\r
5493\r
5494int32 pushrtn(int32 pc)\r
5495{\r
5496 int32 t;\r
5497 \r
5498 t = (GetMap(040) + 1) & AMASK; \r
5499 PutMap(t, AC[0]);\r
5500 t++;\r
5501 PutMap(t, AC[1]);\r
5502 t++;\r
5503 PutMap(t, AC[2]);\r
5504 t++;\r
5505 PutMap(t, AC[3]);\r
5506 t++;\r
5507 PutMap(t, pc);\r
5508 if (C) PutMap(t, (GetMap(t) | 0100000));\r
5509 PutMap(040, t);\r
5510 return 0;\r
5511}\r
5512\r
5513/* Eclipse memory get/put - uses MAP if enabled */\r
5514\r
5515int32 GetMap(int32 addr)\r
5516{\r
5517 int32 page;\r
5518 t_addr paddr;\r
5519 \r
5520 switch (Usermap) {\r
5521 case 0:\r
5522 if (addr < 076000)\r
5523 return M[addr];\r
5524 paddr = ((Map31 & PAGEMASK) << 10) | (addr & 001777);\r
5525 if (paddr < MEMSIZE)\r
5526 return M[paddr];\r
5527 else\r
5528 return (0); \r
5529 break; \r
5530 case 1:\r
5531 page = (addr >> 10) & 037;\r
5532 paddr = ((Map[1][page] & 01777) << 10) | (addr & 001777);\r
5533 if (Map[1][page] == INVALID && !SingleCycle) \r
5534 Fault = 0100000/*!!!*/; /* Validity */\r
5535 if (paddr < MEMSIZE)\r
5536 return M[paddr];\r
5537 else\r
5538 return (0); \r
5539 break;\r
5540 case 2:\r
5541 page = (addr >> 10) & 037;\r
5542 paddr = ((Map[2][page] & PAGEMASK) << 10) | (addr & 001777);\r
5543 if (Map[2][page] == INVALID && !SingleCycle) \r
5544 Fault = 0100000/*!!!*/; /* Validity */\r
5545 if (paddr < MEMSIZE)\r
5546 return M[paddr];\r
5547 else\r
5548 return (0); \r
5549 break;\r
5550 case 6:\r
5551 page = (addr >> 10) & 037;\r
5552 paddr = ((Map[6][page] & PAGEMASK) << 10) | (addr & 001777);\r
5553 if (Map[6][page] == INVALID && !SingleCycle) \r
5554 Fault = 0100000/*!!!*/; /* Validity */\r
5555 if (paddr < MEMSIZE)\r
5556 return M[paddr];\r
5557 else\r
5558 return (0); \r
5559 break;\r
5560 case 7:\r
5561 page = (addr >> 10) & 037;\r
5562 paddr = ((Map[7][page] & PAGEMASK) << 10) | (addr & 001777);\r
5563 if (Map[7][page] == INVALID && !SingleCycle) \r
5564 Fault = 0100000/*!!!*/; /* Validity */\r
5565 if (paddr < MEMSIZE)\r
5566 return M[paddr];\r
5567 else\r
5568 return (0); \r
5569 break;\r
5570 default:\r
5571 printf("\n\r<<MAP FAULT>>\n\r");\r
5572 return M[addr];\r
5573 break;\r
5574 } \r
5575}\r
5576\r
5577int32 PutMap(int32 addr, int32 data)\r
5578{\r
5579 int32 page;\r
5580 t_addr paddr;\r
5581 \r
5582 switch (Usermap) {\r
5583 case 0:\r
5584 if (addr < 076000) {\r
5585 M[addr] = data;\r
5586 return (data);\r
5587 }\r
5588 paddr = ((Map31 & PAGEMASK) << 10) | (addr & 001777);\r
5589 if (paddr < MEMSIZE) M[paddr] = data; \r
5590 break;\r
5591 case 1:\r
5592 page = (addr >> 10) & 037;\r
5593 paddr = ((Map[1][page] & PAGEMASK) << 10) | (addr & 001777);\r
5594 if (((Map[1][page] & 0100000) && (MapStat & 020)) || Map[1][page] == INVALID) \r
5595 Fault = 010000; /* Write Protect Fault */\r
5596 else if (paddr < MEMSIZE) M[paddr] = data; \r
5597 break;\r
5598 case 2:\r
5599 page = (addr >> 10) & 037;\r
5600 paddr = ((Map[2][page] & PAGEMASK) << 10) | (addr & 001777);\r
5601 if (((Map[2][page] & 0100000) && (MapStat & 020)) || Map[2][page] == INVALID) \r
5602 Fault = 010000; /* Write Protect Fault */\r
5603 else if (paddr < MEMSIZE) M[paddr] = data;\r
5604 break; \r
5605 case 6:\r
5606 page = (addr >> 10) & 037;\r
5607 paddr = ((Map[2][page] & PAGEMASK) << 10) | (addr & 001777);\r
5608 if (((Map[6][page] & 0100000) && (MapStat & 020)) || Map[6][page] == INVALID)\r
5609 Fault = 010000; /* Write Protect Fault */\r
5610 else if (paddr < MEMSIZE) M[paddr] = data;\r
5611 break; \r
5612 case 7:\r
5613 page = (addr >> 10) & 037;\r
5614 paddr = ((Map[2][page] & PAGEMASK) << 10) | (addr & 001777);\r
5615 if (((Map[7][page] & 0100000) && (MapStat & 020)) || Map[7][page] == INVALID) \r
5616 Fault = 010000; /* Write Protect Fault */\r
5617 else if (paddr < MEMSIZE) M[paddr] = data;\r
5618 break; \r
5619 default:\r
5620 M[addr] = data;\r
5621 break;\r
5622 }\r
5623 return (data); \r
5624}\r
5625\r
5626#if 0\r
5627int16 GetDCHMap(int32 map, int32 addr)\r
5628{\r
5629 t_addr paddr;\r
5630 if (!(MapStat & 02)) return M[addr];\r
5631 paddr = ((Map[map][(addr >> 10) & 037] & PAGEMASK) << 10) | (addr & 001777);\r
5632 if (paddr < MEMSIZE)\r
5633 return M[paddr]; \r
5634 return (0); \r
5635}\r
5636\r
5637int16 PutDCHMap(int32 map, int32 addr, int16 data)\r
5638{\r
5639 t_addr paddr;\r
5640 if (!(MapStat & 02)) {\r
5641 M[addr] = data; \r
5642 return (data);\r
5643 } \r
5644 paddr = ((Map[map][(addr >> 10) & 037] & PAGEMASK) << 10) | (addr & 001777);\r
5645 if (paddr < MEMSIZE)\r
5646 M[paddr] = data;\r
5647 return (data); \r
5648}\r
5649#endif\r
5650\r
5651/* Given a map number and a logical, returns the physical address, unless\r
5652 the map is not active, in which case logical = physical. This is\r
5653 used primarily by the I/O routines to map data channel read/writes.\r
5654*/\r
5655 \r
5656int32 MapAddr(int32 map, int32 addr)\r
5657{\r
5658 int32 paddr;\r
5659 if ((map == 0 || map > 2) && !(MapStat & 02)) return addr;\r
5660 if (map > 0 && map < 3 && Usermap == 0) return addr;\r
5661 paddr = ((Map[map][(addr >> 10) & 037] & PAGEMASK) << 10) | (addr & 001777);\r
5662 return paddr; \r
5663}\r
5664\r
5665/* Loads a word into the Eclipse Maps */\r
5666\r
5667int32 LoadMap(int32 w)\r
5668{\r
5669 int32 m;\r
5670 \r
5671 m = (w >> 10) & 037;\r
5672 switch ((MapStat >> 7) & 07) {\r
5673 case 0: /* Load user A Map */\r
5674 Map[1][m] = w & MAPMASK;\r
5675 break;\r
5676 case 1: /* Load user C Map */\r
5677 Map[6][m] = w & MAPMASK;\r
5678 break; \r
5679 case 2: /* Load user B Map */\r
5680 Map[2][m] = w & MAPMASK;\r
5681 break;\r
5682 case 3: /* Load user D Map */\r
5683 Map[7][m] = w & MAPMASK;\r
5684 break; \r
5685 case 4: /* Load DCH A Map */\r
5686 Map[0][m] = w & MAPMASK;\r
5687 break; \r
5688 case 5: /* Load DCH C Map */\r
5689 Map[4][m] = w;\r
5690 break; \r
5691 case 6: /* Load DCH B Map */\r
5692 Map[3][m] = w;\r
5693 break; \r
5694 case 7: /* Load DCH D Map */\r
5695 Map[5][m] = w;\r
5696 break; \r
5697 default:\r
5698 break; \r
5699 }\r
5700 return 0;\r
5701}\r
5702\r
5703/* Displays an error on a unimplemented (in this sim) instr. */\r
5704\r
5705int32 unimp(int32 PC)\r
5706{\r
5707 if (Debug_Flags)\r
5708 printf("\n\r\007<<<Unimplemented instruction: [%o] %o>>>\n\r", PC - 1, GetMap(PC - 1));\r
5709 return 0;\r
5710}\r
5711\r
5712/* New priority mask out */\r
5713\r
5714void mask_out (int32 newmask)\r
5715{\r
5716int32 i;\r
5717\r
5718dev_disable = 0;\r
5719for (i = DEV_LOW; i <= DEV_HIGH; i++) {\r
5720 if (newmask & dev_table[i].pi)\r
5721 dev_disable = dev_disable | dev_table[i].mask;\r
5722}\r
5723int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);\r
5724return;\r
5725}\r
5726\r
5727/* Reset routine */\r
5728\r
5729t_stat cpu_reset (DEVICE *dptr)\r
5730{\r
5731int_req = int_req & ~INT_ION;\r
5732pimask = 0;\r
5733dev_disable = 0;\r
5734pwr_low = 0;\r
5735sim_brk_types = sim_brk_dflt = SWMASK ('E');\r
5736return SCPE_OK;\r
5737}\r
5738\r
5739/* Memory examine */\r
5740\r
5741t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw)\r
5742{\r
5743if (sw & SWMASK ('V')) {\r
5744 if (addr > 077777) return SCPE_NXM;\r
5745 if (vptr != NULL) *vptr = GetMap (addr);\r
5746}\r
5747else {\r
5748 if (addr >= MEMSIZE) return SCPE_NXM;\r
5749 if (vptr != NULL) *vptr = M[addr] & 0177777;\r
5750}\r
5751return SCPE_OK;\r
5752}\r
5753\r
5754/* Memory deposit */\r
5755\r
5756t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw)\r
5757{\r
5758if (sw & SWMASK ('V')) {\r
5759 if (addr > 077777) return SCPE_NXM;\r
5760 PutMap (addr, (int32) val);\r
5761}\r
5762else {\r
5763 if (addr >= MEMSIZE) return SCPE_NXM;\r
5764 M[addr] = (int32) val & 0177777;\r
5765}\r
5766return SCPE_OK;\r
5767}\r
5768\r
5769/* Alter memory size */\r
5770\r
5771t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)\r
5772{\r
5773int32 mc = 0;\r
5774t_addr i;\r
5775\r
5776if ((val <= 0) || (val > MAXMEMSIZE) || ((val & 07777) != 0))\r
5777 return SCPE_ARG;\r
5778for (i = val; i < MEMSIZE; i++) mc = mc | M[i];\r
5779if ((mc != 0) && (!get_yn ("Really truncate memory [N]?", FALSE)))\r
5780 return SCPE_OK;\r
5781MEMSIZE = val;\r
5782for (i = MEMSIZE; i < MAXMEMSIZE; i++) M[i] = 0;\r
5783return SCPE_OK;\r
5784}\r
5785\r
5786/* MAP device services */\r
5787\r
5788t_stat map_svc (UNIT *uptr)\r
5789{\r
5790return SCPE_OK;\r
5791}\r
5792\r
5793/* Map examine */\r
5794\r
5795t_stat map_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw)\r
5796{\r
5797if ((addr & 077) >= 037 || addr > 737) return SCPE_NXM;\r
5798uptr->u4 = -2; /* signal to print_sys in eclipse_sys.c: do not map */\r
5799if (vptr != NULL) *vptr = Map[(addr >> 6) & 3][addr & 037] & 0177777;\r
5800return SCPE_OK;\r
5801}\r
5802\r
5803/* Memory deposit */\r
5804\r
5805t_stat map_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw)\r
5806{\r
5807if ((addr & 077) >= 037 || addr > 0737) return SCPE_NXM;\r
5808uptr->u4 = -2; /* signal to print_sys in eclipse_sys.c: do not map */\r
5809Map[(addr >> 6) & 3][addr & 037] = (int32)val & 0177777;\r
5810return SCPE_OK;\r
5811}\r
5812\r
5813/* FPU device services */\r
5814\r
5815t_stat fpu_svc (UNIT *uptr)\r
5816{\r
5817return SCPE_OK;\r
5818}\r
5819\r
5820/* PIT Device Services */\r
5821\r
5822/* IOT routine */\r
5823\r
5824int32 pit (int32 pulse, int32 code, int32 AC)\r
5825{\r
5826int32 iodata = 0;\r
5827\r
5828if (code == ioDIA) { /* DIA */\r
5829 if (pit_flag == 0) {\r
5830 pit_flag = 1;\r
5831 }\r
5832 iodata = pit_counter;\r
5833}\r
5834if (code == ioDOA) { /* DOA */\r
5835 pit_initial = AC; /* Load Counter */\r
5836 sim_rtcn_init (pit_time, 1); /* init calibr */\r
5837}\r
5838switch (pulse) { /* decode IR<8:9> */\r
5839case iopS: /* start */\r
5840 pit_counter = pit_initial; /* Set the counter */\r
5841 dev_busy = dev_busy | INT_PIT; /* set busy */\r
5842 dev_done = dev_done & ~INT_PIT; /* clear done, int */\r
5843 int_req = int_req & ~INT_PIT;\r
5844 if (!sim_is_active (&pit_unit)) /* not running? */\r
5845 sim_activate (&pit_unit, /* activate */\r
5846 sim_rtcn_init (pit_time, 1)); /* init calibr */\r
5847 break;\r
5848case iopC: /* clear */\r
5849 dev_busy = dev_busy & ~INT_PIT; /* clear busy */\r
5850 dev_done = dev_done & ~INT_PIT; /* clear done, int */\r
5851 int_req = int_req & ~INT_PIT;\r
5852 sim_cancel (&pit_unit); /* deactivate unit */\r
5853 break; } /* end switch */\r
5854return iodata; \r
5855}\r
5856\r
5857/* Unit service */\r
5858\r
5859t_stat pit_svc (UNIT *uptr)\r
5860{\r
5861int32 t;\r
5862t = sim_rtcn_calb (pit_tps, 1); /* calibrate delay */\r
5863sim_activate (&pit_unit, t); /* reactivate unit */\r
5864pit_poll = t / (-pit_adj); /* adjust poll */\r
5865pit_counter++; /* Increment counter */\r
5866if (pit_counter >= 0177777) { /* Has counter reached limit ? */\r
5867 dev_done = dev_done | INT_PIT; /* set done */\r
5868 dev_busy = dev_busy & ~INT_PIT; /* clear busy */\r
5869 int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable); /* Interrupt */\r
5870 pit_counter = pit_initial;\r
5871}\r
5872return SCPE_OK;\r
5873}\r
5874\r
5875/* Reset routine */\r
5876\r
5877t_stat pit_reset (DEVICE *dptr)\r
5878{\r
5879pit_counter = 0; /* clear counter */\r
5880dev_busy = dev_busy & ~INT_PIT; /* clear busy */\r
5881dev_done = dev_done & ~INT_PIT; /* clear done, int */\r
5882int_req = int_req & ~INT_PIT;\r
5883sim_cancel (&pit_unit); /* deactivate unit */\r
5884pit_poll = pit_time; /* poll is default */\r
5885return SCPE_OK;\r
5886}\r
5887\r
5888/* Bootstrap routine for CPU */\r
5889\r
5890#define BOOT_START 00000\r
5891#define BOOT_LEN (sizeof (boot_rom) / sizeof (int))\r
5892\r
5893static const int32 boot_rom[] = {\r
5894\r
5895 062677, /* IORST ;Reset all I/O */\r
5896 060477, /* READS 0 ;Read SR into AC0 */\r
5897 024026, /* LDA 1,C77 ;Get dev mask */\r
5898 0107400, /* AND 0,1 ;Isolate dev code */\r
5899 0124000, /* COM 1,1 ;- device code - 1 */\r
5900 010014, /* LOOP: ISZ OP1 ;Device code to all */\r
5901 010030, /* ISZ OP2 ;I/O instructions */\r
5902 010032, /* ISZ OP3 */\r
5903 0125404, /* INC 1,1,SZR ;done? */\r
5904 000005, /* JMP LOOP ;No, increment again */\r
5905 030016, /* LDA 2,C377 ;place JMP 377 into */\r
5906 050377, /* STA 2,377 ;location 377 */\r
5907 060077, /* OP1: 060077 ;start device (NIOS 0) */\r
5908 0101102, /* MOVL 0,0,SZC ;Test switch 0, low speed? */\r
5909 000377, /* C377: JMP 377 ;no - jmp 377 & wait */\r
5910 004030, /* LOOP2: JSR GET+1 ;Get a frame */\r
5911 0101065, /* MOVC 0,0,SNR ;is it non-zero? */\r
5912 000017, /* JMP LOOP2 ;no, ignore */\r
5913 004027, /* LOOP4: JSR GET ;yes, get full word */\r
5914 046026, /* STA 1,@C77 ;store starting at 100 */\r
5915 /* ;2's complement of word ct */\r
5916 010100, /* ISZ 100 ;done? */\r
5917 000022, /* JMP LOOP4 ;no, get another */\r
5918 000077, /* C77: JMP 77 ;yes location ctr and */\r
5919 /* ;jmp to last word */\r
5920 0126420, /* GET: SUBZ 1,1 ; clr AC1, set carry */\r
5921 /* OP2: */\r
5922 063577, /* LOOP3: 063577 ;done? (SKPDN 0) - 1 */\r
5923 000030, /* JMP LOOP3 ;no -- wait */\r
5924 060477, /* OP3: 060477 ;y--read in ac0 (DIAS 0,0) */\r
5925 0107363, /* ADDCS 0,1,SNC ;add 2 frames swapped - got 2nd? */\r
5926 000030, /* JMP LOOP3 ;no go back after it */\r
5927 0125300, /* MOVS 1,1 ;yes swap them */\r
5928 001400, /* JMP 0,3 ;rtn with full word */\r
5929 0 /* 0 ;padding */\r
5930};\r
5931\r
5932t_stat cpu_boot (int32 unitno, DEVICE *dptr)\r
5933{\r
5934int32 i;\r
5935extern int32 saved_PC;\r
5936\r
5937for (i = 0; i < BOOT_LEN; i++) M[BOOT_START + i] = boot_rom[i];\r
5938saved_PC = BOOT_START;\r
5939return SCPE_OK;\r
5940}\r
5941\r
5942int32 Debug_Entry(int32 PC, int32 inst, int32 inst2, int32 AC0, int32 AC1, int32 AC2, int32 AC3, int32 flags)\r
5943{\r
5944 hpc[hnext] = PC & 0xffff;\r
5945 hinst[hnext] = inst & 0xffff;\r
5946 hinst2[hnext] = inst2 & 0xffff;\r
5947 hac0[hnext] = AC0 & 0xffff;\r
5948 hac1[hnext] = AC1 & 0xffff;\r
5949 hac2[hnext] = AC2 & 0xffff;\r
5950 hac3[hnext] = AC3 & 0xffff;\r
5951 hflags[hnext] = flags & 0xffff;\r
5952 hnext++;\r
5953 if (hnext >= hmax) {\r
5954 hwrap = 1;\r
5955 hnext = 0;\r
5956 } \r
5957 return 0;\r
5958}\r
5959\r
5960int32 Debug_Dump(UNIT *uptr, int32 val, char *cptr, void *desc)\r
5961{\r
5962 return SCPE_OK;\r
5963}\r
5964\r
5965int32 Dump_History (FILE *st, UNIT *uptr, int32 val, void *desc) \r
5966{\r
5967 char debmap[4], debion[4];\r
5968 t_value simeval[20];\r
5969 int debcar;\r
5970 int start, end, ctr;\r
5971 int count = 0;\r
5972 \r
5973 if (!Debug_Flags || Debug_Flags & 0100000) {\r
5974 printf("History was not logged. Deposit a non-zero value\n");\r
5975 printf("in DEBUG with bit 0 being 1 to build history.\n");\r
5976 return SCPE_OK;\r
5977 } \r
5978 if (!hwrap) {\r
5979 start = 0;\r
5980 end = hnext;\r
5981 } else {\r
5982 start = hnext;\r
5983 end = hnext - 1;\r
5984 if (end < 0) end = hmax;\r
5985 }\r
5986 ctr = start; \r
5987 while (1) {\r
5988 if (ctr == end) \r
5989 break;\r
5990 count++;\r
5991 strcpy(debion, " ");\r
5992 strcpy(debmap, " ");\r
5993 debcar = 0;\r
5994 if (hflags[ctr] & 0x80) {\r
5995 fprintf(st, "--------- Interrupt %o (%o) to %6o ---------\n",\r
5996 hinst[ctr], hac0[ctr], hac1[ctr]);\r
5997 } else {\r
5998 if (hflags[ctr] & 0x01) debcar = 1;\r
5999 if (hflags[ctr] & 0x02) strcpy(debion, "I");\r
6000 if (hflags[ctr] & 0x04) strcpy(debmap, "A"); \r
6001 if (hflags[ctr] & 0x08) strcpy(debmap, "B"); \r
6002 if (hflags[ctr] & 0x10) strcpy(debmap, "C"); \r
6003 if (hflags[ctr] & 0x20) strcpy(debmap, "D"); \r
6004 fprintf(st, "%s%s%06o acs: %06o %06o %06o %06o %01o ", \r
6005 debion, debmap, hpc[ctr], hac0[ctr], hac1[ctr], hac2[ctr],\r
6006 hac3[ctr], debcar); \r
6007 simeval[0] = hinst[ctr];\r
6008 simeval[1] = hinst2[ctr];\r
6009 fprint_sym (st, hpc[ctr], simeval, NULL, SWMASK('M'));\r
6010 fprintf(st, "\n");\r
6011 } \r
6012 ctr++;\r
6013 if (ctr > hmax)\r
6014 ctr = 0;\r
6015 }\r
6016 return SCPE_OK;\r
6017}\r
6018\r
6019/* Build dispatch table */\r
6020\r
6021t_stat build_devtab (void)\r
6022{\r
6023DEVICE *dptr;\r
6024DIB *dibp;\r
6025int32 i, dn;\r
6026\r
6027for (i = 0; i < 64; i++) { /* clr dev_table */\r
6028 dev_table[i].mask = 0;\r
6029 dev_table[i].pi = 0;\r
6030 dev_table[i].routine = NULL;\r
6031}\r
6032for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */\r
6033 if (!(dptr->flags & DEV_DIS) && /* enabled and */\r
6034 (dibp = (DIB *) dptr->ctxt)) { /* defined DIB? */\r
6035 dn = dibp->dnum; /* get dev num */\r
6036 dev_table[dn].mask = dibp->mask; /* copy entries */\r
6037 dev_table[dn].pi = dibp->pi;\r
6038 dev_table[dn].routine = dibp->routine;\r
6039 }\r
6040}\r
6041return SCPE_OK;\r
6042}\r
6043\r
6044/* ------------------------------------------------------------------- */\r
6045/* Floating Point Arithmetic */\r
6046/* ------------------------------------------------------------------- */\r
6047\r
6048\r
6049/* Get short float from FPAC */\r
6050\r
6051void get_sf (SHORT_FLOAT *fl, t_int64 *fpr)\r
6052{\r
6053 fl->sign = (uint8)(*fpr >> 63) & 1;\r
6054 fl->expo = (short)(*fpr >> 56) & 0x007F;\r
6055 fl->short_fract = (int32)(*fpr >> 32) & 0x00FFFFFF;\r
6056} \r
6057\r
6058/* Store short float to FPAC */\r
6059\r
6060void store_sf (SHORT_FLOAT *fl, t_int64 *fpr)\r
6061{\r
6062 *fpr = 0;\r
6063 *fpr = ((t_int64)fl->sign << 63)\r
6064 | ((t_int64)fl->expo << 56)\r
6065 | ((t_int64)fl->short_fract <<32);\r
6066} \r
6067\r
6068/* Get long float from FPAC */\r
6069\r
6070void get_lf (LONG_FLOAT *fl, t_int64 *fpr)\r
6071{\r
6072 fl->sign = (uint8)(*fpr >> 63) & 1;\r
6073 fl->expo = (short)(*fpr >> 56) & 0x007F;\r
6074 fl->long_fract = (t_int64)*fpr & 0x00FFFFFFFFFFFFFF;\r
6075\r
6076} \r
6077\r
6078/* Store long float to FPAC */\r
6079\r
6080void store_lf (LONG_FLOAT *fl, t_int64 *fpr)\r
6081{\r
6082 *fpr = 0;\r
6083 *fpr = (t_int64)fl->sign << 63;\r
6084 *fpr |= ((t_int64)fl->expo << 56) & 0x7f00000000000000;\r
6085 *fpr |= fl->long_fract;\r
6086}\r
6087\r
6088\r
6089/* Check short for Overflow */\r
6090\r
6091int overflow_sf (SHORT_FLOAT *fl)\r
6092{\r
6093 if (fl->expo > 127) {\r
6094 fl->expo &= 0x007F;\r
6095 return(1);\r
6096 }\r
6097 return(0);\r
6098\r
6099}\r
6100\r
6101/* Normalize Short Float */\r
6102\r
6103int normal_sf(SHORT_FLOAT *fl)\r
6104{\r
6105 if (fl->short_fract) {\r
6106 if ((fl->short_fract & 0x00FFFF00) == 0) {\r
6107 fl->short_fract <<= 16;\r
6108 fl->expo -= 4;\r
6109 }\r
6110 if ((fl->short_fract & 0x00FF0000) == 0) {\r
6111 fl->short_fract <<= 8;\r
6112 fl->expo -= 2;\r
6113 }\r
6114 if ((fl->short_fract & 0x00F00000) == 0) {\r
6115 fl->short_fract <<= 4;\r
6116 (fl->expo)--;\r
6117 }\r
6118 } else {\r
6119 fl->sign = 0;\r
6120 fl->expo = 0;\r
6121 }\r
6122 if (fl->expo < 0)\r
6123 return (2);\r
6124 return(0);\r
6125}\r
6126\r
6127/* Normalize long float */\r
6128\r
6129int normal_lf (LONG_FLOAT *fl)\r
6130{\r
6131 if (fl->long_fract) {\r
6132 if ((fl->long_fract & 0x00FFFFFFFF000000) == 0) {\r
6133 fl->long_fract <<= 32;\r
6134 fl->expo -= 8;\r
6135 }\r
6136 if ((fl->long_fract & 0x00FFFF0000000000) == 0) {\r
6137 fl->long_fract <<= 16;\r
6138 fl->expo -= 4;\r
6139 }\r
6140 if ((fl->long_fract & 0x00FF000000000000) == 0) {\r
6141 fl->long_fract <<= 8;\r
6142 fl->expo -= 2;\r
6143 }\r
6144 if ((fl->long_fract & 0x00F0000000000000) == 0) {\r
6145 fl->long_fract <<= 4;\r
6146 (fl->expo)--;\r
6147 }\r
6148 } else {\r
6149 fl->sign = 0;\r
6150 fl->expo = 0;\r
6151 }\r
6152 if (fl->expo < 0)\r
6153 return (2);\r
6154 return(0);\r
6155}\r
6156\r
6157/* Check Long for Overflow */\r
6158\r
6159int overflow_lf(LONG_FLOAT *fl)\r
6160{\r
6161 if (fl->expo > 127) {\r
6162 fl->expo &= 0x007F;\r
6163 return(1);\r
6164 }\r
6165 return(0);\r
6166\r
6167}\r
6168\r
6169int underflow_sf(SHORT_FLOAT *fl)\r
6170{\r
6171 if (fl->expo < 0) {\r
6172 fl->short_fract = 0;\r
6173 fl->expo = 0;\r
6174 fl->sign = 0;\r
6175 }\r
6176 return(0);\r
6177\r
6178}\r
6179\r
6180\r
6181int underflow_lf(LONG_FLOAT *fl)\r
6182{\r
6183 if (fl->expo < 0) {\r
6184 fl->long_fract = 0;\r
6185 fl->expo = 0;\r
6186 fl->sign = 0;\r
6187 }\r
6188 return(0);\r
6189}\r
6190\r
6191/* Check Short for Over/Under flow */\r
6192\r
6193int over_under_flow_sf(SHORT_FLOAT *fl)\r
6194{\r
6195 if (fl->expo > 127) {\r
6196 fl->expo &= 0x007F;\r
6197 return(1);\r
6198 } else {\r
6199 if (fl->expo < 0) {\r
6200 /* set true 0 */\r
6201 fl->short_fract = 0;\r
6202 fl->expo = 0;\r
6203 fl->sign = 0;\r
6204 }\r
6205 }\r
6206 return(0);\r
6207\r
6208}\r
6209\r
6210/* Check Long for Over/Under flow */\r
6211\r
6212int over_under_flow_lf(LONG_FLOAT *fl)\r
6213{\r
6214 if (fl->expo > 127) {\r
6215 fl->expo &= 0x007F;\r
6216 return(1);\r
6217 } else {\r
6218 if (fl->expo < 0) {\r
6219 /* set true 0 */\r
6220 fl->long_fract = 0;\r
6221 fl->expo = 0;\r
6222 fl->sign = 0;\r
6223 }\r
6224 }\r
6225 return(0);\r
6226\r
6227}\r
6228\r
6229int significance_sf (SHORT_FLOAT *fl)\r
6230{\r
6231 fl->sign = 0;\r
6232 fl->expo = 0;\r
6233 return(0);\r
6234\r
6235}\r
6236\r
6237int significance_lf (LONG_FLOAT *fl)\r
6238{\r
6239 fl->sign = 0;\r
6240 fl->expo = 0;\r
6241 return(0);\r
6242\r
6243}\r
6244\r
6245\r
6246/*-------------------------------------------------------------------*/\r
6247/* Add short float */\r
6248/* */\r
6249/* Input: */\r
6250/* fl Float */\r
6251/* add_fl Float to be added */\r
6252/* normal Normalize if true */\r
6253/* Value: */\r
6254/* exeption */\r
6255/*-------------------------------------------------------------------*/\r
6256int add_sf (SHORT_FLOAT *fl, SHORT_FLOAT *add_fl, int normal)\r
6257{\r
6258int pgm_check;\r
6259int shift;\r
6260\r
6261 pgm_check = 0;\r
6262 if (add_fl->short_fract\r
6263 || add_fl->expo) { /* add_fl not 0 */\r
6264 if (fl->short_fract\r
6265 || fl->expo) { /* fl not 0 */\r
6266 /* both not 0 */\r
6267\r
6268 if (fl->expo == add_fl->expo) {\r
6269 /* expo equal */\r
6270\r
6271 /* both guard digits */\r
6272 fl->short_fract <<= 4;\r
6273 add_fl->short_fract <<= 4;\r
6274 } else {\r
6275 /* expo not equal, denormalize */\r
6276\r
6277 if (fl->expo < add_fl->expo) {\r
6278 /* shift minus guard digit */\r
6279 shift = add_fl->expo - fl->expo - 1;\r
6280 fl->expo = add_fl->expo;\r
6281\r
6282 if (shift) {\r
6283 if (shift >= 6\r
6284 || ((fl->short_fract >>= (shift * 4)) == 0)) {\r
6285 /* 0, copy summand */\r
6286\r
6287 fl->sign = add_fl->sign;\r
6288 fl->short_fract = add_fl->short_fract;\r
6289\r
6290 if (fl->short_fract == 0) {\r
6291 pgm_check = significance_sf(fl);\r
6292 } else {\r
6293 if (normal) {\r
6294 normal_sf(fl);\r
6295 pgm_check = underflow_sf(fl);\r
6296 }\r
6297 }\r
6298 return(pgm_check);\r
6299 }\r
6300 }\r
6301 /* guard digit */\r
6302 add_fl->short_fract <<= 4;\r
6303 } else {\r
6304 /* shift minus guard digit */\r
6305 shift = fl->expo - add_fl->expo - 1;\r
6306\r
6307 if (shift) {\r
6308 if (shift >= 6\r
6309 || ((add_fl->short_fract >>= (shift * 4)) == 0)) {\r
6310 /* 0, nothing to add */\r
6311\r
6312 if (fl->short_fract == 0) {\r
6313 pgm_check = significance_sf(fl);\r
6314 } else {\r
6315 if (normal) {\r
6316 normal_sf(fl);\r
6317 pgm_check = underflow_sf(fl);\r
6318 }\r
6319 }\r
6320 return(pgm_check);\r
6321 }\r
6322 }\r
6323 /* guard digit */\r
6324 fl->short_fract <<= 4;\r
6325 }\r
6326 }\r
6327\r
6328 /* compute with guard digit */\r
6329 if (fl->sign == add_fl->sign) {\r
6330 fl->short_fract += add_fl->short_fract;\r
6331 } else {\r
6332 if (fl->short_fract == add_fl->short_fract) {\r
6333 /* true 0 */\r
6334\r
6335 fl->short_fract = 0;\r
6336 return( significance_sf(fl) );\r
6337\r
6338 } else if (fl->short_fract > add_fl->short_fract) {\r
6339 fl->short_fract -= add_fl->short_fract;\r
6340 } else {\r
6341 fl->short_fract = add_fl->short_fract - fl->short_fract;\r
6342 fl->sign = add_fl->sign;\r
6343 }\r
6344 }\r
6345\r
6346 /* handle overflow with guard digit */\r
6347 if (fl->short_fract & 0xF0000000) {\r
6348 fl->short_fract >>= 8;\r
6349 (fl->expo)++;\r
6350 pgm_check = overflow_sf(fl);\r
6351 } else {\r
6352\r
6353 if (normal) {\r
6354 /* normalize with guard digit */\r
6355 if (fl->short_fract) {\r
6356 /* not 0 */\r
6357\r
6358 if (fl->short_fract & 0x0F000000) {\r
6359 /* not normalize, just guard digit */\r
6360 fl->short_fract >>= 4;\r
6361 } else {\r
6362 (fl->expo)--;\r
6363 normal_sf(fl);\r
6364 pgm_check = underflow_sf(fl);\r
6365 }\r
6366 } else {\r
6367 /* true 0 */\r
6368\r
6369 pgm_check = significance_sf(fl);\r
6370 }\r
6371 } else {\r
6372 /* not normalize, just guard digit */\r
6373 fl->short_fract >>= 4;\r
6374 if (fl->short_fract == 0) {\r
6375 pgm_check = significance_sf(fl);\r
6376 }\r
6377 }\r
6378 }\r
6379 return(pgm_check);\r
6380 } else { /* fl 0, add_fl not 0 */\r
6381 /* copy summand */\r
6382\r
6383 fl->expo = add_fl->expo;\r
6384 fl->sign = add_fl->sign;\r
6385 fl->short_fract = add_fl->short_fract;\r
6386 if (fl->short_fract == 0) {\r
6387 return( significance_sf(fl) );\r
6388 }\r
6389 }\r
6390 } else { /* add_fl 0 */\r
6391 if (fl->short_fract == 0) { /* fl 0 */\r
6392 /* both 0 */\r
6393\r
6394 return( significance_sf(fl) );\r
6395 }\r
6396 }\r
6397 if (normal) {\r
6398 normal_sf(fl);\r
6399 pgm_check = underflow_sf(fl);\r
6400 }\r
6401 return(pgm_check);\r
6402\r
6403}\r
6404\r
6405\r
6406/*-------------------------------------------------------------------*/\r
6407/* Add long float */\r
6408/* */\r
6409/* Input: */\r
6410/* fl Float */\r
6411/* add_fl Float to be added */\r
6412/* normal Normalize if true */\r
6413/* Value: */\r
6414/* exeption */\r
6415/*-------------------------------------------------------------------*/\r
6416int add_lf (LONG_FLOAT *fl, LONG_FLOAT *add_fl, int normal)\r
6417{\r
6418int pgm_check;\r
6419int shift;\r
6420\r
6421 pgm_check = 0;\r
6422 if (add_fl->long_fract\r
6423 || add_fl->expo) { /* add_fl not 0 */\r
6424 if (fl->long_fract\r
6425 || fl->expo) { /* fl not 0 */\r
6426 /* both not 0 */\r
6427\r
6428 if (fl->expo == add_fl->expo) {\r
6429 /* expo equal */\r
6430\r
6431 /* both guard digits */\r
6432 fl->long_fract <<= 4;\r
6433 add_fl->long_fract <<= 4;\r
6434 } else {\r
6435 /* expo not equal, denormalize */\r
6436\r
6437 if (fl->expo < add_fl->expo) {\r
6438 /* shift minus guard digit */\r
6439 shift = add_fl->expo - fl->expo - 1;\r
6440 fl->expo = add_fl->expo;\r
6441\r
6442 if (shift) {\r
6443 if (shift >= 14\r
6444 || ((fl->long_fract >>= (shift * 4)) == 0)) {\r
6445 /* 0, copy summand */\r
6446\r
6447 fl->sign = add_fl->sign;\r
6448 fl->long_fract = add_fl->long_fract;\r
6449\r
6450 if (fl->long_fract == 0) {\r
6451 pgm_check = significance_lf(fl);\r
6452 } else {\r
6453 if (normal) {\r
6454 normal_lf(fl);\r
6455 pgm_check = underflow_lf(fl);\r
6456 }\r
6457 }\r
6458 return(pgm_check);\r
6459 }\r
6460 }\r
6461 /* guard digit */\r
6462 add_fl->long_fract <<= 4;\r
6463 } else {\r
6464 /* shift minus guard digit */\r
6465 shift = fl->expo - add_fl->expo - 1;\r
6466\r
6467 if (shift) {\r
6468 if (shift >= 14\r
6469 || ((add_fl->long_fract >>= (shift * 4)) == 0)) {\r
6470 /* 0, nothing to add */\r
6471\r
6472 if (fl->long_fract == 0) {\r
6473 pgm_check = significance_lf(fl);\r
6474 } else {\r
6475 if (normal) {\r
6476 normal_lf(fl);\r
6477 pgm_check = underflow_lf(fl);\r
6478 }\r
6479 }\r
6480 return(pgm_check);\r
6481 }\r
6482 }\r
6483 /* guard digit */\r
6484 fl->long_fract <<= 4;\r
6485 }\r
6486 }\r
6487\r
6488 /* compute with guard digit */\r
6489 if (fl->sign == add_fl->sign) {\r
6490 fl->long_fract += add_fl->long_fract;\r
6491 } else {\r
6492 if (fl->long_fract == add_fl->long_fract) {\r
6493 /* true 0 */\r
6494\r
6495 fl->long_fract = 0;\r
6496 return( significance_lf(fl) );\r
6497\r
6498 } else if (fl->long_fract > add_fl->long_fract) {\r
6499 fl->long_fract -= add_fl->long_fract;\r
6500 } else {\r
6501 fl->long_fract = add_fl->long_fract - fl->long_fract;\r
6502 fl->sign = add_fl->sign;\r
6503 }\r
6504 }\r
6505\r
6506 /* handle overflow with guard digit */\r
6507 if (fl->long_fract & 0xF000000000000000) {\r
6508 fl->long_fract >>= 8;\r
6509 (fl->expo)++;\r
6510 pgm_check = overflow_lf(fl);\r
6511 } else {\r
6512\r
6513 if (normal) {\r
6514 /* normalize with guard digit */\r
6515 if (fl->long_fract) {\r
6516 /* not 0 */\r
6517\r
6518 if (fl->long_fract & 0x0F00000000000000) {\r
6519 /* not normalize, just guard digit */\r
6520 fl->long_fract >>= 4;\r
6521 } else {\r
6522 (fl->expo)--;\r
6523 normal_lf(fl);\r
6524 pgm_check = underflow_lf(fl);\r
6525 }\r
6526 } else {\r
6527 /* true 0 */\r
6528\r
6529 pgm_check = significance_lf(fl);\r
6530 }\r
6531 } else {\r
6532 /* not normalize, just guard digit */\r
6533 fl->long_fract >>= 4;\r
6534 if (fl->long_fract == 0) {\r
6535 pgm_check = significance_lf(fl);\r
6536 }\r
6537 }\r
6538 }\r
6539 return(pgm_check);\r
6540 } else { /* fl 0, add_fl not 0 */\r
6541 /* copy summand */\r
6542\r
6543 fl->expo = add_fl->expo;\r
6544 fl->sign = add_fl->sign;\r
6545 fl->long_fract = add_fl->long_fract;\r
6546 if (fl->long_fract == 0) {\r
6547 return( significance_lf(fl) );\r
6548 }\r
6549 }\r
6550 } else { /* add_fl 0 */\r
6551 if (fl->long_fract == 0) { /* fl 0 */\r
6552 /* both 0 */\r
6553\r
6554 return( significance_lf(fl) );\r
6555 }\r
6556 }\r
6557 if (normal) {\r
6558 normal_lf(fl);\r
6559 pgm_check = underflow_lf(fl);\r
6560 }\r
6561 return(pgm_check);\r
6562\r
6563}\r
6564\r
6565/*-------------------------------------------------------------------*/\r
6566/* Multiply short float */\r
6567/* */\r
6568/* Input: */\r
6569/* fl Multiplicand short float */\r
6570/* mul_fl Multiplicator short float */\r
6571/* Value: */\r
6572/* exeption */\r
6573/*-------------------------------------------------------------------*/\r
6574\r
6575int mul_sf(SHORT_FLOAT *fl, SHORT_FLOAT *mul_fl)\r
6576{\r
6577t_int64 wk;\r
6578\r
6579 if (fl->short_fract\r
6580 && mul_fl->short_fract) {\r
6581 /* normalize operands */\r
6582 normal_sf( fl );\r
6583 normal_sf( mul_fl );\r
6584\r
6585 /* multiply fracts */\r
6586 wk = (t_int64) fl->short_fract * mul_fl->short_fract;\r
6587\r
6588 /* normalize result and compute expo */\r
6589 if (wk & 0x0000F00000000000) {\r
6590 fl->short_fract = (int32)wk >> 24;\r
6591 fl->expo = (short)fl->expo + mul_fl->expo - 64;\r
6592 } else {\r
6593 fl->short_fract = (int32)wk >> 20;\r
6594 fl->expo = (short)fl->expo + mul_fl->expo - 65;\r
6595 }\r
6596\r
6597 /* determine sign */\r
6598 fl->sign = (fl->sign == mul_fl->sign) ? 0 : 1;\r
6599\r
6600 /* handle overflow and underflow */\r
6601 return( over_under_flow_sf(fl) );\r
6602 } else {\r
6603 /* set true 0 */\r
6604\r
6605 fl->short_fract = 0;\r
6606 fl->expo = 0;\r
6607 fl->sign = 0;\r
6608 return(0);\r
6609 }\r
6610\r
6611}\r
6612\r
6613\r
6614/*-------------------------------------------------------------------*/\r
6615/* Multiply long float */\r
6616/* */\r
6617/* Input: */\r
6618/* fl Multiplicand long float */\r
6619/* mul_fl Multiplicator long float */\r
6620/* Value: */\r
6621/* exeption */\r
6622/*-------------------------------------------------------------------*/\r
6623int mul_lf(LONG_FLOAT *fl, LONG_FLOAT *mul_fl)\r
6624{\r
6625t_int64 wk;\r
6626int32 v;\r
6627\r
6628 if (fl->long_fract\r
6629 && mul_fl->long_fract) {\r
6630 /* normalize operands */\r
6631 normal_lf( fl );\r
6632 normal_lf( mul_fl );\r
6633\r
6634 /* multiply fracts by sum of partial multiplications */\r
6635 wk = ((fl->long_fract & 0x00000000FFFFFFFF) * (mul_fl->long_fract & 0x00000000FFFFFFFF)) >> 32;\r
6636\r
6637 wk += ((fl->long_fract & 0x00000000FFFFFFFF) * (mul_fl->long_fract >> 32));\r
6638 wk += ((fl->long_fract >> 32) * (mul_fl->long_fract & 0x00000000FFFFFFFF));\r
6639 v = (int32)wk;\r
6640\r
6641 fl->long_fract = (wk >> 32) + ((fl->long_fract >> 32) * (mul_fl->long_fract >> 32));\r
6642\r
6643 /* normalize result and compute expo */\r
6644 if (fl->long_fract & 0x0000F00000000000) {\r
6645 fl->long_fract = (fl->long_fract << 8)\r
6646 | (v >> 24);\r
6647 fl->expo = fl->expo + mul_fl->expo - 64;\r
6648 } else {\r
6649 fl->long_fract = (fl->long_fract << 12)\r
6650 | (v >> 20);\r
6651 fl->expo = fl->expo + mul_fl->expo - 65;\r
6652 }\r
6653\r
6654 /* determine sign */\r
6655 fl->sign = (fl->sign == mul_fl->sign) ? 0 : 1;\r
6656\r
6657 /* handle overflow and underflow */\r
6658 return( over_under_flow_lf(fl) );\r
6659 } else {\r
6660 /* set true 0 */\r
6661\r
6662 fl->long_fract = 0;\r
6663 fl->expo = 0;\r
6664 fl->sign = 0;\r
6665 return(0);\r
6666 }\r
6667\r
6668} \r
6669\r
6670\r
6671/*-------------------------------------------------------------------*/\r
6672/* Divide short float */\r
6673/* */\r
6674/* Input: */\r
6675/* fl Dividend short float */\r
6676/* div_fl Divisor short float */\r
6677/* Value: */\r
6678/* exeption */\r
6679/*-------------------------------------------------------------------*/\r
6680int div_sf(SHORT_FLOAT *fl, SHORT_FLOAT *div_fl)\r
6681{\r
6682t_int64 wk;\r
6683\r
6684 if (div_fl->short_fract) {\r
6685 if (fl->short_fract) {\r
6686 /* normalize operands */\r
6687 normal_sf( fl );\r
6688 normal_sf( div_fl );\r
6689\r
6690 /* position fracts and compute expo */\r
6691 if (fl->short_fract < div_fl->short_fract) {\r
6692 wk = (t_int64) fl->short_fract << 24;\r
6693 fl->expo = fl->expo - div_fl->expo + 64;\r
6694 } else {\r
6695 wk = (t_int64) fl->short_fract << 20;\r
6696 fl->expo = fl->expo - div_fl->expo + 65;\r
6697 }\r
6698 /* divide fractions */\r
6699 fl->short_fract = (int32)wk / div_fl->short_fract;\r
6700\r
6701 /* determine sign */\r
6702 fl->sign = (fl->sign == div_fl->sign) ? 0 : 1;\r
6703\r
6704 /* handle overflow and underflow */\r
6705 return( over_under_flow_sf(fl) );\r
6706 } else {\r
6707 /* fraction of dividend 0, set true 0 */\r
6708\r
6709 fl->short_fract = 0;\r
6710 fl->expo = 0;\r
6711 fl->sign = 0;\r
6712 }\r
6713 } else {\r
6714 /* divisor 0 */\r
6715\r
6716 return(3);\r
6717 }\r
6718 return(0);\r
6719\r
6720}\r
6721\r
6722\r
6723/*-------------------------------------------------------------------*/\r
6724/* Divide long float */\r
6725/* */\r
6726/* Input: */\r
6727/* fl Dividend long float */\r
6728/* div_fl Divisor long float */\r
6729/* Value: */\r
6730/* exeption */\r
6731/*-------------------------------------------------------------------*/\r
6732int div_lf(LONG_FLOAT *fl, LONG_FLOAT *div_fl)\r
6733{\r
6734t_int64 wk;\r
6735t_int64 wk2;\r
6736int i;\r
6737\r
6738 if (div_fl->long_fract) {\r
6739 if (fl->long_fract) {\r
6740 /* normalize operands */\r
6741 normal_lf( fl );\r
6742 normal_lf( div_fl );\r
6743\r
6744 /* position fracts and compute expo */\r
6745 if (fl->long_fract < div_fl->long_fract) {\r
6746 fl->expo = fl->expo - div_fl->expo + 64;\r
6747 } else {\r
6748 fl->expo = fl->expo - div_fl->expo + 65;\r
6749 div_fl->long_fract <<= 4;\r
6750 }\r
6751\r
6752 /* partial divide first hex digit */\r
6753 wk2 = fl->long_fract / div_fl->long_fract;\r
6754 wk = (fl->long_fract % div_fl->long_fract) << 4;\r
6755\r
6756 /* partial divide middle hex digits */\r
6757 i = 13;\r
6758 while (i--) {\r
6759 wk2 = (wk2 << 4)\r
6760 | (wk / div_fl->long_fract);\r
6761 wk = (wk % div_fl->long_fract) << 4;\r
6762 }\r
6763\r
6764 /* partial divide last hex digit */\r
6765 fl->long_fract = (wk2 << 4)\r
6766 | (wk / div_fl->long_fract);\r
6767\r
6768 /* determine sign */\r
6769 fl->sign = (fl->sign == div_fl->sign) ? 0 : 1;\r
6770\r
6771 /* handle overflow and underflow */\r
6772 return( over_under_flow_lf(fl) );\r
6773 } else {\r
6774 /* fraction of dividend 0, set true 0 */\r
6775\r
6776 fl->long_fract = 0;\r
6777 fl->expo = 0;\r
6778 fl->sign = 0;\r
6779 }\r
6780 } else {\r
6781 /* divisor 0 */\r
6782\r
6783 return(3);\r
6784 }\r
6785 return(0);\r
6786\r
6787}\r
6788\r