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