1 /* hp2100_mc.c: HP 12566B Microcircuit Interface simulator
2 
3    Copyright (c) 2018-2020, J. David Bryan
4 
5    Permission is hereby granted, free of charge, to any person obtaining a
6    copy of this software and associated documentation files (the "Software"),
7    to deal in the Software without restriction, including without limitation
8    the rights to use, copy, modify, merge, publish, distribute, sublicense,
9    and/or sell copies of the Software, and to permit persons to whom the
10    Software is furnished to do so, subject to the following conditions:
11 
12    The above copyright notice and this permission notice shall be included in
13    all copies or substantial portions of the Software.
14 
15    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18    THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19    IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20    CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 
22    Except as contained in this notice, the name of the author shall not be
23    used in advertising or otherwise to promote the sale, use or other dealings
24    in this Software without prior written authorization from the author.
25 
26    MC           12566B Microcircuit Interface
27 
28    09-Dec-20    JDB     Replaced "io_assert" with "io_assert_ENF"
29    02-Dec-20    JDB     RESET no longer presets the interface
30    09-Jul-18    JDB     Created
31 
32    References:
33      - 12566B[-001/2/3] Microcircuit Interface Kits Operating and Service Manual
34          (12566-90015,  April 1976)
35 
36 
37    The 12566B Microcircuit Interface provides a general-purpose 16-bit
38    bidirectional data path between the CPU and an I/O device that supports both
39    programmed I/O and DMA transfers.  A simple, two-wire handshake provides the
40    control signals to coordinate data transfers.  All device signals are
41    TTL-compatible, and transfer rates up to one-half of the DMA bandwidth are
42    possible.
43 
44    The 12566B supplies 16 data bits and asserts a Device Command signal to the
45    device to indicate the start of a transfer.  The device returns 16 data bits
46    and asserts a Device Flag signal to indicate completion of the transfer.
47    Assertion of Device Flag causes the interface to set its Flag flip-flop and
48    assert an interupt request to the CPU and a service request to the DMA
49    controller.
50 
51    This simulation primarily provides a target interface for several diagnostic
52    programs.  In the DIAGNOSTIC mode, a loopback connector is installed in place
53    of the usual device cable, and the interface provides a general data source
54    and sink, as well as a source of interrupts and a break in the I/O priority
55    chain.  In the DEVICE mode, the simulation provides a model to illustrate the
56    required interface to the CPU's I/O backplane, as no peripheral device is
57    simulated.
58 
59    Befitting its general purpose, the hardware interface has nine jumpers,
60    labelled W1-W9, that may be positioned to configure the electrical polarity
61    and behavior of the Device Command and Device Flag signals.  The lettered
62    jumper positions and their effects are:
63 
64      Jumper  Pos  Action
65      ------  ---  ------------------------------------------------------------
66        W1     A   Device Command signal is ground true asserted with STC
67               B   Device Command signal is positive true asserted with STC
68               C   Device Command signal is ground true asserted for T6 and T2
69 
70        W2     A   Device Command flip-flop clears on positive edge of Device Flag
71               B   Device Command flip-flop clears on negative edge of Device Flag
72               C   Device Command flip-flop clears on ENF (T2)
73 
74        W3     A   Device Flag signal sets Flag Buffer and strobes data on positive edge
75               B   Device Flag signal sets Flag Buffer and strobes data on negative edge
76 
77        W4     A   Output Data Register is gated by the data flip-flop
78               B   Output Data Register is continuously available
79 
80        W5    IN   Input Data Register bits 0-3 are latched by Device Flag
81              OUT  Input Data Register bits 0-3 are transparent
82 
83        W6    IN   Input Data Register bits 4-7 are latched by Device Flag
84              OUT  Input Data Register bits 4-7 are transparent
85 
86        W7    IN   Input Data Register bits 8-11 are latched by Device Flag
87              OUT  Input Data Register bits 8-11 are transparent
88 
89        W8    IN   Input Data Register bits 12-15 are latched by Device Flag
90              OUT  Input Data Register bits 12-15 are transparent
91 
92        W9     A   Device Command flip-flop cleared by CLC, CRS, and Device Flag
93               B   Device Command flip-flop cleared by CRS and Device Flag
94 
95    The electrical characteristics of the device being interfaced dictates the
96    jumper settings used.  The jumper settings required for the standard HP
97    peripherals that use the microcircuit card are:
98 
99      W1  W2  W3  W4  W5  W6  W7  W8  W9  Device
100      --- --- --- --- --- --- --- --- --- ----------------------------------------
101       A   B   A   B  OUT IN  IN  IN   A  12566B-004 Line Printer Interface (9866)
102 
103       B   A   B   B  OUT IN  IN  OUT  A  12653A Line Printer Interface (2767)
104 
105       A   B   B   B  IN  IN  IN  OUT  B  12732A Flexible Disc Subsystem (Control)
106       A   A   B   B  IN  IN  IN  IN   B  12732A Flexible Disc Subsystem (Data)
107 
108       A   B   B   B  IN  IN  IN  IN   A  12875A Processor Interconnect Kit
109 
110    For diagnostic use, the required jumper settings are:
111 
112      W1  W2  W3  W4  W5  W6  W7  W8  W9   DSN    Diagnostic
113      --- --- --- --- --- --- --- --- --- ------  ---------------------------------
114       C   B   B   B  IN  IN  IN  IN   A  143300  General Purpose Register
115 
116       C   B   B   B  IN  IN  IN  IN   A  141203  I/O Instruction Group
117 
118       C   B   B   B  IN  IN  IN  IN   A  102103  Memory Expansion Unit
119 
120       C   B   B   B  IN  IN  IN  IN   A  101220  DMA/DCPC for 2100/1000
121 
122       B   A   A   B  IN  IN  IN  IN   A    --    DMA for 2100 (HP 24195)
123 
124       B   A   A   B  IN  IN  IN  IN   A  101105  DMA for 2114/2115/2116 (HP 24322)
125       B   C   A  A/B IN  IN  IN  IN   A  101105  DMA for 2114/2115/2116 (HP 24322)
126 
127       B   C   B   B  IN  IN  IN  IN   A    --    DMA for 2115/2116 (HP 24185)
128 
129       (not relevant; interrupt only)     101112  Extended Instruction Group
130 
131       (not relevant; interrupt only)     101213  M/E-Series Fast FORTRAN Package 1
132 
133       (not relevant; interrupt only)     101115  M/E-Series Fast FORTRAN Package 2
134 
135       (not relevant; interrupt only)     101121  F-Series FPP-SIS-FFP
136 
137       (not relevant; interrupt only)     102305  Memory Protect/Parity Error
138 
139    The diagnostics that specify jumper settings above test data writing and
140    reading and so require the installation of the HP 1251-0332 diagnostic test
141    (loopback) connector in place of the normal device cable connector.  This
142    test connector connects each data output bit with its corresponding data
143    input bit and connects the Device Command output signal to the Device Flag
144    input signal.
145 
146    The diagnostics that test the HP 12607B DMA card for the 2115 and 2116 CPUs
147    require an unusual jumper configuration.  The card provides hardware byte
148    packing and unpacking during DMA transfers.  The diagnostics test this
149    hardware by strapping the microcircuit interface so that the Device Flag
150    signal sets the Flag flip-flop for a CPU cycle but not for a DMA cycle.  This
151    allows the diagnostic to advance the DMA byte transfer hardware sequence
152    cycle-by-cycle under program control.
153 
154    In hardware, this works only because the 2115/2116 DMA cycle asserts the STC
155    and CLF signals for two staggered T-periods, with CLF remaining asserted for
156    one T-period after STC denies.  The 2115/2116 CPU cycle, as well as the CPU
157    and DMA cycles of all other 21xx/1000 machines, assert STC and CLF
158    coincidently for one T-period.
159 
160    Under simulation, this action cannot be derived by simulating the jumper
161    behaviors directly, because the I/O backplane signal timing relationships are
162    not simulated.  Instead, Device Flag assertion is omitted for 2115/2116 DMA
163    cycles when DIAGNOSTIC mode is selected.
164 
165    This module does not simulate the individual jumper settings, for two
166    reasons.  First, with no peripheral device connected to the interface, the
167    jumper settings are irrelevant.  Should this module be used as the basis for
168    a specific device interface, that device would dictate the jumper settings
169    required.  As the settings would be fixed, having a user-configurable set of
170    jumpers would serve no purpose.  Second, while user-configurable jumpers
171    would be useful to configure the card for diagnostics, the fact that the I/O
172    backplane signal timing is not simulated means that the interface behavior
173    cannot be derived from the jumper settings alone.  Therefore, entering the
174    DIAGNOSTIC mode simulates the proper jumper settings for the various
175    diagnostics listed above.
176 
177 
178    Implementation notes:
179 
180      1. Two identical interfaces are provided: MC1 and MC2.  Both interfaces are
181         used by the 12936A Privileged Interrupt Fence diagnostic.  They also
182         serve as an illustration of how to model multiple interfaces in the HP
183         2100 simulator.
184 
185      2. The microcircuit interfaces are disabled by default, as they are only
186         used during diagnostic execution.
187 */
188 
189 
190 
191 #include "hp2100_defs.h"
192 #include "hp2100_io.h"
193 
194 
195 
196 /* Program limits */
197 
198 #define CARD_COUNT          2                   /* count of cards supported */
199 
200 
201 /* Device property constant declarations */
202 
203 #define LOOPBACK_DELAY      (int32) uS (1)      /* diagnostic loopback flag assertion delay */
204 
205 
206 /* Unit flags */
207 
208 #define UNIT_V_DIAG         (UNIT_V_UF + 0)     /* diagnostic mode is selected */
209 
210 #define UNIT_DIAG           (1 << UNIT_V_DIAG)
211 
212 
213 /* Unit references */
214 
215 typedef enum {
216     mc1,                                        /* first microcircuit card index */
217     mc2                                         /* second microcircuit card index */
218     } CARD_INDEX;
219 
220 
221 /* Interface state */
222 
223 typedef struct {
224     HP_WORD      output_data;                   /* output data register */
225     HP_WORD      input_data;                    /* input data register */
226     FLIP_FLOP    command;                       /* command flip-flop */
227     FLIP_FLOP    control;                       /* control flip-flop */
228     FLIP_FLOP    flag;                          /* flag flip-flop */
229     FLIP_FLOP    flag_buffer;                   /* flag buffer flip-flop */
230     } CARD_STATE;
231 
232 static CARD_STATE mc [CARD_COUNT];              /* per-card state */
233 
234 
235 /* Interface local SCP support routines */
236 
237 static IO_INTERFACE mc_interface;
238 
239 
240 /* Interface local SCP support routines */
241 
242 static t_stat mc_service (UNIT *uptr);
243 static t_stat mc_reset   (DEVICE *dptr);
244 
245 
246 /* Interface SCP data structures */
247 
248 
249 /* Device information block */
250 
251 static DIB mc_dib [CARD_COUNT] = {
252     { &mc_interface,                            /* the device's I/O interface function pointer */
253       NULL,                                     /* the power state function pointer */
254       MC1,                                      /* the device's select code (02-77) */
255       0,                                        /* the card index */
256       "12566B Microcircuit Interface",          /* the card description */
257       NULL },                                   /* the ROM description */
258 
259     { &mc_interface,                            /* the device's I/O interface function pointer */
260       NULL,                                     /* the power state function pointer */
261       MC2,                                      /* the device's select code (02-77) */
262       1,                                        /* the card index */
263       "12566B Microcircuit Interface",          /* the card description */
264       NULL }                                    /* the ROM description */
265     };
266 
267 
268 /* Unit list */
269 
270 #define UNIT_FLAGS          (0)
271 
272 static UNIT mc_unit [CARD_COUNT] = {
273 /*           Event Routine  Unit Flags  Capacity  Delay */
274 /*           -------------  ----------  --------  ----- */
275     { UDATA (&mc_service,   UNIT_FLAGS,    0),      0   },
276     { UDATA (&mc_service,   UNIT_FLAGS,    0),      0   }
277     };
278 
279 
280 /* Register lists.
281 
282 
283    Implementation notes:
284 
285     1. The two REG arrays would be more conveniently declared as:
286 
287          static REG mc_reg [CARD_COUNT] [] = { { ... }, { ... } };
288 
289        Unfortunately, this is illegal in C ("a multidimensional array must have
290        bounds for all dimensions except the first").
291 */
292 
293 static REG mc1_reg [] = {
294 /*    Macro   Name    Location                    Width     Offset        Flags       */
295 /*    ------  ------  ------------------------  ----------  ------  ----------------- */
296     { ORDATA (IN,     mc [mc1].input_data,         16)                                },
297     { ORDATA (OUT,    mc [mc1].output_data,        16)                                },
298     { FLDATA (CTL,    mc [mc1].control,                       0)                      },
299     { FLDATA (FLG,    mc [mc1].flag,                          0)                      },
300     { FLDATA (FBF,    mc [mc1].flag_buffer,                   0)                      },
301     { FLDATA (CMD,    mc [mc1].command,                       0)                      },
302 
303       DIB_REGS (mc_dib [mc1]),
304 
305     { NULL }
306     };
307 
308 static REG mc2_reg [] = {
309 /*    Macro   Name    Location                    Width     Offset        Flags       */
310 /*    ------  ------  ------------------------  ----------  ------  ----------------- */
311     { ORDATA (IN,     mc [mc2].input_data,         16)                                },
312     { ORDATA (OUT,    mc [mc2].output_data,        16)                                },
313     { FLDATA (CTL,    mc [mc2].control,                       0)                      },
314     { FLDATA (FLG,    mc [mc2].flag,                          0)                      },
315     { FLDATA (FBF,    mc [mc2].flag_buffer,                   0)                      },
316     { FLDATA (CMD,    mc [mc2].command,                       0)                      },
317 
318       DIB_REGS (mc_dib [mc2]),
319 
320     { NULL }
321     };
322 
323 
324 /* Modifier lists */
325 
326 static MTAB mc1_mod [] = {
327 /*    Mask Value  Match Value  Print String       Match String  Validation   Display  Descriptor */
328 /*    ----------  -----------  -----------------  ------------  -----------  -------  ---------- */
329     { UNIT_DIAG,  UNIT_DIAG,   "diagnostic mode", "DIAGNOSTIC", NULL,        NULL,    NULL       },
330     { UNIT_DIAG,  0,           "device mode",     "DEVICE",     NULL,        NULL,    NULL       },
331 
332 /*    Entry Flags  Value  Print String  Match String  Validation    Display        Descriptor             */
333 /*    -----------  -----  ------------  ------------  ------------  -------------  ---------------------- */
334     { MTAB_XDV,     1u,   "SC",         "SC",         &hp_set_dib,  &hp_show_dib,  (void *) &mc_dib [mc1] },
335     { 0 }
336     };
337 
338 static MTAB mc2_mod [] = {
339 /*    Mask Value  Match Value  Print String       Match String  Validation   Display  Descriptor */
340 /*    ----------  -----------  -----------------  ------------  -----------  -------  ---------- */
341     { UNIT_DIAG,  UNIT_DIAG,   "diagnostic mode", "DIAGNOSTIC", NULL,        NULL,    NULL       },
342     { UNIT_DIAG,  0,           "device mode",     "DEVICE",     NULL,        NULL,    NULL       },
343 
344 /*    Entry Flags  Value  Print String  Match String  Validation    Display        Descriptor             */
345 /*    -----------  -----  ------------  ------------  ------------  -------------  ---------------------- */
346     { MTAB_XDV,     1u,   "SC",         "SC",         &hp_set_dib,  &hp_show_dib,  (void *) &mc_dib [mc2] },
347     { 0 }
348     };
349 
350 
351 /* Debugging trace list */
352 
353 static DEBTAB mc_deb [] = {
354     { "XFER",  TRACE_XFER  },                   /* trace data transmissions and receptions */
355     { "IOBUS", TRACE_IOBUS },                   /* trace I/O bus signals and data words received and returned */
356     { NULL,    0           }
357     };
358 
359 
360 /* Device descriptors */
361 
362 DEVICE mc1_dev = {
363     "MC1",                                      /* device name */
364     &mc_unit [mc1],                             /* unit array */
365     mc1_reg,                                    /* register array */
366     mc1_mod,                                    /* modifier array */
367     1,                                          /* number of units */
368     10,                                         /* address radix */
369     31,                                         /* address width */
370     1,                                          /* address increment */
371     8,                                          /* data radix */
372     16,                                         /* data width */
373     NULL,                                       /* examine routine */
374     NULL,                                       /* deposit routine */
375     &mc_reset,                                  /* reset routine */
376     NULL,                                       /* boot routine */
377     NULL,                                       /* attach routine */
378     NULL,                                       /* detach routine */
379     &mc_dib [mc1],                              /* device information block pointer */
380     DEV_DISABLE | DEV_DIS | DEV_DEBUG,          /* device flags */
381     0,                                          /* debug control flags */
382     mc_deb,                                     /* debug flag name array */
383     NULL,                                       /* memory size change routine */
384     NULL                                        /* logical device name */
385     };
386 
387 DEVICE mc2_dev = {
388     "MC2",                                      /* device name */
389     &mc_unit [mc2],                             /* unit array */
390     mc2_reg,                                    /* register array */
391     mc2_mod,                                    /* modifier array */
392     1,                                          /* number of units */
393     10,                                         /* address radix */
394     31,                                         /* address width */
395     1,                                          /* address increment */
396     8,                                          /* data radix */
397     16,                                         /* data width */
398     NULL,                                       /* examine routine */
399     NULL,                                       /* deposit routine */
400     &mc_reset,                                  /* reset routine */
401     NULL,                                       /* boot routine */
402     NULL,                                       /* attach routine */
403     NULL,                                       /* detach routine */
404     &mc_dib [mc2],                              /* device information block pointer */
405     DEV_DISABLE | DEV_DIS | DEV_DEBUG,          /* device flags */
406     0,                                          /* debug control flags */
407     mc_deb,                                     /* debug flag name array */
408     NULL,                                       /* memory size change routine */
409     NULL                                        /* logical device name */
410     };
411 
412 static DEVICE *dptrs [CARD_COUNT] = {           /* device pointer array, indexed by CARD_INDEX */
413     &mc1_dev,
414     &mc2_dev
415     };
416 
417 
418 
419 /* Microcircuit interface.
420 
421    The microcircuit interface is installed on the I/O bus and receives I/O
422    commands from the CPU and DMA/DCPC channels.  In simulation, the asserted
423    signals on the bus are represented as bits in the inbound_signals set.  Each
424    signal is processed sequentially in ascending numerical order.  The outbound
425    signals and optional data value are returned after inbound signal processing
426    is complete.
427 
428    In DIAGNOSTIC mode, the interface behaves as though a loopback connector
429    is installed.  In addition, for all accesses other than DMA cycles for a 2115 or
430    2116 CPU, it behaves as though jumpers W1-W3 are installed in locations
431    C-B-B, respectively.  In this case, the Flag flip-flop sets one I/O cycle
432    after STC signal assertion.  For 2115/2116 DMA cycles, it behaves as though
433    the jumpers are installed in locations B-C-A, which suppresses setting the
434    Flag flip-flop.
435 
436    Because there is no attached peripheral, the Flag flip-flop never sets in
437    DEVICE mode in response to a programmed STC instruction.
438 
439 
440    Implementation notes:
441 
442     1. The B-C-B jumper setting used by the HP 24185 DMA diagnostic causes the
443        Flag flip-flop to set two I/O cycles after STC assertion.  However, the
444        diagnostic executes an STC,C instruction at that point that clears the
445        Flag flip-flop explictly.  This has the same effect as if the Flag had
446        never set and so is functionally identical to the B-C-A jumper setting.
447 
448     2. The 12195 DMA diagnostic depends on the input data register being clocked
449        by an STC instruction.  W1 = B and W3 = A asserts Device Command positive
450        true and strobes the input register on the positive edge of Device Flag.
451        This is simulated by copying the output data register to the input data
452        register in the STC handler if DIAGNOSTIC mode is enabled.
453 */
454 
mc_interface(const DIB * dibptr,INBOUND_SET inbound_signals,HP_WORD inbound_value)455 static SIGNALS_VALUE mc_interface (const DIB *dibptr, INBOUND_SET inbound_signals, HP_WORD inbound_value)
456 {
457 const CARD_INDEX card = (CARD_INDEX) dibptr->card_index;    /* the card selector */
458 UNIT * const     uptr = &(mc_unit [card]);                  /* the associated unit pointer */
459 INBOUND_SIGNAL   signal;
460 INBOUND_SET      working_set = inbound_signals;
461 SIGNALS_VALUE    outbound    = { ioNONE, 0 };
462 t_bool           irq_enabled = FALSE;
463 
464 while (working_set) {                                   /* while signals remain */
465     signal = IONEXTSIG (working_set);                   /*   isolate the next signal */
466 
467     switch (signal) {                                   /* dispatch the I/O signal */
468 
469         case ioCLF:                                     /* Clear Flag flip-flop */
470             mc [card].flag_buffer = CLEAR;              /* clear the flag buffer */
471             mc [card].flag        = CLEAR;              /*   and flag flip-flops */
472             break;
473 
474 
475         case ioSTF:                                     /* Set Flag flip-flop */
476             mc [card].flag_buffer = SET;                /* set the flag buffer flip-flop */
477             break;
478 
479 
480         case ioENF:                                     /* Enable Flag */
481             if (mc [card].flag_buffer == SET)           /* if the flag buffer flip-flop is set */
482                 mc [card].flag = SET;                   /*   then set the flag flip-flop */
483             break;
484 
485 
486         case ioSFC:                                     /* Skip if Flag is Clear */
487             if (mc [card].flag == CLEAR)                /* if the flag flip-flop is clear */
488                 outbound.signals |= ioSKF;              /*   then assert the Skip on Flag signal */
489             break;
490 
491 
492         case ioSFS:                                     /* Skip if Flag is Set */
493             if (mc [card].flag == SET)                  /* if the flag flip-flop is set */
494                 outbound.signals |= ioSKF;              /*   then assert the Skip on Flag signal */
495             break;
496 
497 
498         case ioIOI:                                     /* I/O data input */
499             outbound.value = mc [card].input_data;      /* set the outbound data value from the input buffer */
500             break;
501 
502 
503         case ioIOO:                                     /* I/O data output */
504             mc [card].output_data = inbound_value;      /* store the inbound data value in the output buffer */
505             break;
506 
507 
508         case ioPOPIO:                                   /* Power-On Preset to I/O */
509             mc [card].flag_buffer = SET;                /* set the flag buffer flip-flop */
510             mc [card].output_data = 0;                  /*   and clear the output register */
511             break;
512 
513 
514         case ioCRS:                                     /* Control Reset */
515             mc [card].control = CLEAR;                  /* clear the control flip-flop */
516             mc [card].command = CLEAR;                  /*   and the command flip-flop */
517 
518             sim_cancel (uptr);                          /* cancel any operation in progress */
519             break;
520 
521 
522         case ioCLC:                                     /* Clear Control flip-flop */
523             mc [card].control = CLEAR;                  /* clear the control flip-flop */
524             mc [card].command = CLEAR;                  /*   and the command flip-flop */
525 
526             if (sim_activate_time (uptr) > LOOPBACK_DELAY)  /* if Device Flag assertion is still in the future */
527                 sim_cancel (uptr);                          /*   then cancel it */
528             break;
529 
530 
531         case ioSTC:                                     /* Set Control flip-flop */
532             mc [card].control = SET;                    /* set the control flip-flop */
533             mc [card].command = SET;                    /*   and the command flip-flop */
534 
535             if (uptr->flags & UNIT_DIAG                             /* if the card is in diagnostic mode */
536               && (cpu_configuration & ~(CPU_2116 | CPU_2115)        /*   and this is not a 2116 or 2115 CPU */
537               || (inbound_signals & (ioIOI | ioIOO)) == ioNONE)) {  /*     or not a DMA cycle */
538                 mc [card].input_data = mc [card].output_data;       /*       then loop the data back */
539 
540                 tpprintf (dptrs [card], TRACE_XFER, "Output data word %06o looped back to input\n",
541                           mc [card].output_data);
542 
543                 sim_activate_abs (uptr, LOOPBACK_DELAY);            /* schedule Device Flag assertion */
544                 }
545             break;
546 
547 
548         case ioSIR:                                     /* Set Interrupt Request */
549             if (mc [card].control & mc [card].flag)     /* if the control and flag flip-flops are set */
550                 outbound.signals |= cnVALID;            /*   then deny PRL */
551             else                                        /* otherwise */
552                 outbound.signals |= cnPRL | cnVALID;    /*   conditionally assert PRL */
553 
554             if (mc [card].control & mc [card].flag      /* if the control and flag */
555               & mc [card].flag_buffer)                  /*   and flag buffer flip-flops are set */
556                 outbound.signals |= cnIRQ;              /*     then conditionally assert IRQ */
557 
558             if (mc [card].flag == SET)                  /* if the flag flip-flop is set */
559                 outbound.signals |= ioSRQ;              /*   then assert SRQ */
560             break;
561 
562 
563         case ioIAK:                                     /* Interrupt Acknowledge */
564             mc [card].flag_buffer = CLEAR;              /* clear the flag buffer flip-flop */
565             break;
566 
567 
568         case ioIEN:                                     /* Interrupt Enable */
569             irq_enabled = TRUE;                         /* permit IRQ to be asserted */
570             break;
571 
572 
573         case ioPRH:                                         /* Priority High */
574             if (irq_enabled && outbound.signals & cnIRQ)    /* if IRQ is enabled and conditionally asserted */
575                 outbound.signals |= ioIRQ | ioFLG;          /*   then assert IRQ and FLG */
576 
577             if (not irq_enabled || outbound.signals & cnPRL)    /* if IRQ is disabled or PRL is conditionally asserted */
578                 outbound.signals |= ioPRL;                      /*   then assert it unconditionally */
579             break;
580 
581 
582         case ioEDT:                                     /* not used by this interface */
583         case ioPON:                                     /* not used by this interface */
584             break;
585         }
586 
587     IOCLEARSIG (working_set, signal);                   /* remove the current signal from the set */
588     }                                                   /*   and continue until all signals are processed */
589 
590 return outbound;                                        /* return the outbound signals and value */
591 }
592 
593 
594 /* Unit service */
595 
mc_service(UNIT * uptr)596 static t_stat mc_service (UNIT *uptr)
597 {
598 const CARD_INDEX card = (CARD_INDEX) (uptr - mc_unit);  /* the card selector */
599 
600 if (uptr->flags & UNIT_DIAG) {                          /* if the card is in diagnostic mode */
601     mc [card].command     = CLEAR;                      /*   then clear the command flip-flop */
602     mc [card].flag_buffer = SET;                        /*     and set the flag buffer */
603     io_assert_ENF (dptrs [card]->ctxt);                 /*       and flag flip-flops */
604     }
605 
606 return SCPE_OK;
607 }
608 
609 
610 /* Reset routine */
611 
mc_reset(DEVICE * dptr)612 static t_stat mc_reset (DEVICE *dptr)
613 {
614 UNIT * const uptr = dptr->units;                        /* a pointer to the device's unit */
615 
616 if (sim_switches & SWMASK ('P')) {                      /* if this is the power-on reset */
617     }                                                   /*   then perform any power-up processing */
618 
619 sim_cancel (uptr);                                      /* cancel any I/O in progress */
620 
621 return SCPE_OK;
622 }
623