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