1 /* hp2100_di_da.c: HP 12821A HP-IB Disc Interface simulator for Amigo disc drives
2 
3    Copyright (c) 2011-2021, 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    DA           12821A Disc Interface with Amigo disc drives
27 
28    02-Apr-21    JDB     Changed u3-u6 synonyms to title case to avoid conflicts
29    07-Feb-21    JDB     Changed CNVARS register macro from BRDATA to SVDATA
30    02-Dec-20    JDB     RESET no longer presets the interface
31    11-Jul-18    JDB     Revised I/O model, changed global scope of variables to local
32    21-Feb-18    JDB     ATTACH -N now creates a full-size disc image
33    11-Jul-17    JDB     Renamed "ibl_copy" to "cpu_ibl"
34    15-Mar-17    JDB     Changed DEBUG_PRI calls to tprintfs
35    09-Mar-17    JDB     Deprecated LOCKED/WRITEENABLED for PROTECT/UNPROTECT
36    27-Feb-17    JDB     ibl_copy no longer returns a status code
37    17-Jan-17    JDB     Changed to use new byte accessors in hp2100_defs.h
38    13-May-16    JDB     Modified for revised SCP API function parameter types
39    04-Mar-16    JDB     Name changed to "hp2100_disclib" until HP 3000 integration
40    30-Dec-14    JDB     Added S-register parameters to ibl_copy
41    24-Dec-14    JDB     Use T_ADDR_FMT with t_addr values for 64-bit compatibility
42                         Removed redundant global declarations
43    24-Oct-12    JDB     Changed CNTLR_OPCODE to title case to avoid name clash
44    07-May-12    JDB     Cancel the intersector delay if an untalk is received
45    29-Mar-12    JDB     First release
46    04-Nov-11    JDB     Created DA device
47 
48    References:
49      - HP 13365 Integrated Controller Programming Guide
50          (13365-90901, February 1980)
51      - HP 7910 Disc Drive Service Manual
52          (07910-90903, April 1981)
53      - 12745D Disc Controller (13037) to HP-IB Adapter Kit Installation and Service Manual
54          (12745-90911, September 1983)
55      - HP's 5 1/4-Inch Winchester Disc Drive Service Documentation
56          (09134-90032, August 1983)
57      - HP 12992 Loader ROMs Installation Manual
58          (12992-90001, April 1986)
59      - RTE Driver DVA32 Source
60          (92084-18708, revision 2540)
61      - IEEE Standard Digital Interface for Programmable Instrumentation
62          (IEEE-488A-1980, September 1979)
63 
64 
65    The HP 7906H, 7920H, and 7925H Integrated Controller Disc (ICD) drives were
66    connected via an 12821A disc interface and provided 20MB, 50MB, and 120MB
67    capacities.  The drives were identical to the 7906M, 7920M, and 7925M
68    Multi-Access Controller (MAC) units but incorporated internal two-card
69    controllers in each drive and connected to the CPU interface via the
70    Hewlett-Packard Interface Bus (HP-IB), HP's implementation of IEEE-488.  Each
71    controller was dedicated to a single drive and operated similarly to the
72    12745 Disc Controller to HP-IB Adapter option for the 13037 Disc Controller
73    chassis.  The 7906H was introduced in 1980 (there was no 7905H version, as
74    the 7905 was obsolete by that time).  Up to four ICD drives could be
75    connected to a single 12821A card.  The limitation was imposed by the bus
76    loading and the target data transfer rate.
77 
78    The ICD command set essentially was the MAC command set modified for
79    single-unit operation.  The unit number and CPU hold bit fields in the opcode
80    words were unused in the ICD implementation.  The Load TIO Register, Wakeup,
81    and Request Syndrome commands were removed, as Load TIO was used with the HP
82    3000, Wakeup was used in a multi-CPU environment, and the simpler ICD
83    controller did not support ECC.  Controller status values 02B (Unit
84    Available) and 27B (Unit Unavailable) were dropped as the controller
85    supported only single units, 12B (I/O Program Error) was reused to indicate
86    HP-IB protocol errors, 13B (Sync Not Received) was added, and 17B (Possibly
87    Correctable Data Error) was removed as error correction was not supported.
88 
89    Some minor redefinitions also occurred.  For example, status 14B (End of
90    Cylinder) was expanded to include an auto-seek beyond the drive limits, and
91    37B (Drive Attention) was restricted just head unloads from head loads and
92    unloads.
93 
94    The command set was expanded to include several commands related to HP-IB
95    operation.  These were, in large part, adapted from the Amigo disc command
96    protocol outlined in the service manual for the HP 9133/34/35 series of
97    5-1/4" Winchester drives.  They include the Amigo Identify and Amigo Clear
98    sequences, Read and Write Loopback channel tests, and controller Self Test
99    commands.
100 
101    This simulator implements the Amigo disc protocol.  It calls the 12821A Disc
102    Interface (DI) simulator to send and receive bytes across the HP-IB to and
103    from the CPU, and it calls the HP Disc Library to implement the controller
104    functions related to disc unit operation (e.g., seek, read, write, etc.).
105    Four units are provided, and any combination of 7906H/20H/25H drives may be
106    defined.
107 
108    Unfortunately, the primary reference for the ICD controller (the HP 13365
109    Integrated Controller Programming Guide) does not indicate parallel poll
110    responses for these HP-IB commands.  Therefore, the responses have been
111    derived from the sequences in the 7910 and 12745 manuals, although they
112    sometimes conflict.
113 
114    The drives respond to the following commands; the secondary and opcode
115    numeric values are in hex, and the bus addressing state is indicated by U
116    [untalk], L [listen], and T [talk]:
117 
118      Bus  Sec  Op  Operation
119      ---  ---  --  --------------------------------
120       U   MSA  --  Amigo Identify
121 
122       L   00   --  Write Data
123       L   08   00  Cold Load Read
124       L   08   01  Recalibrate
125       L   08   02  Seek
126       L   08   03  Request Status
127       L   08   04  Request Sector Address
128       L   08   05  Read
129       L   08   06  Read Full Sector
130       L   08   07  Verify
131       L   08   08  Write
132       L   08   09  Write Full Sector
133       L   08   0A  Clear
134       L   08   0B  Initialize
135       L   08   0C  Address Record
136       L   08   0E  Read with Offset
137       L   08   0F  Set File Mask
138       L   08   12  Read without Verify
139       L   08   14  Request Logical Disc Address
140       L   08   15  End
141       L   09   --  Cyclic Redundancy Check
142       L   10   --  Amigo Clear
143       L   1E   --  Write Loopback
144       L   1F   ss  Initiate Self-Test <ss>
145 
146       T   00   --  Read Data
147       T   08   --  Read Status
148       T   09   --  Cyclic Redundancy Check
149       T   10   --  Device Specified Jump
150       T   1E   --  Read Loopback
151       T   1F   --  Return Self-Test Result
152 
153    In addition, the controller responds to the Selected Device Clear primary
154    (04).
155 
156 
157    HP-IB Transaction Sequences
158    ===========================
159 
160    Amigo Identify
161 
162        ATN  UNT     Untalk
163        ATN  MSA     My secondary address
164             DAB     ID data byte #1 = 00H
165        EOI  DAB     ID data byte #2 = 03H
166        ATN  OTA     Talk 30
167 
168 
169    Amigo Clear
170 
171        ATN  MLA     My listen address
172        ATN  SCG     Secondary command 10H
173             ppd     Parallel poll disabled
174        EOI  DAB     Unused data byte
175        ATN  SDC     Selected device clear
176        ATN  UNL     Unlisten
177             ...
178             ppe     Parallel poll enabled when clear completes
179 
180 
181    CRC
182 
183        ATN  MTA     My talk address
184        ATN  SCG     Secondary command 09H
185             ppd     Parallel poll disabled
186             DAB     Data byte #1
187             ...
188        EOI  DAB     Data byte #n
189             ppe     Parallel poll enabled
190        ATN  UNT     Untalk
191 
192    or
193 
194        ATN  MLA     My listen address
195        ATN  SCG     Secondary command 09H
196             ppd     Parallel poll disabled
197             DAB     Data byte #1
198             ...
199        EOI  DAB     Data byte #n
200             ppe     Parallel poll enabled
201        ATN  UNL     Unlisten
202 
203 
204    Device Specified Jump
205 
206        ATN  MTA     My talk address
207        ATN  SCG     Secondary command 10H
208             ppd     Parallel poll disabled
209        EOI  DAB     DSJ data byte
210        ATN  UNT     Untalk
211 
212 
213    Initiate Self-Test and Return Self-Test Result
214 
215        ATN  MLA     My listen address
216        ATN  SCG     Secondary command 1FH
217             ppd     Parallel poll disabled
218        EOI  DAB     Self-test number
219             ppe     Parallel poll enabled
220        ATN  UNL     Unlisten
221 
222        ATN  MTA     My talk address
223        ATN  SCG     Secondary command 1FH
224             ppd     Parallel poll disabled
225        EOI  DAB     Result data byte
226             ppe     Parallel poll enabled
227        ATN  UNT     Untalk
228 
229 
230    Write Loopback and Read Loopback
231 
232        ATN  MLA     My listen address
233        ATN  SCG     Secondary command 1EH
234             ppd     Parallel poll disabled
235             DAB     Loopback data byte #1
236             ...
237        EOI  DAB     Loopback data byte #256
238             ppe     Parallel poll enabled
239        ATN  UNL     Unlisten
240 
241        ATN  MTA     My talk address
242        ATN  SCG     Secondary command 1EH
243             ppd     Parallel poll disabled
244             DAB     Loopback data byte #1
245             ...
246        EOI  DAB     Loopback data byte #16
247             ppe     Parallel poll enabled
248        ATN  UNT     Untalk
249 
250 
251    Recalibrate and Seek
252 
253        ATN  MLA     My listen address
254        ATN  SCG     Secondary command 08H
255             ppd     Parallel poll disabled
256             DAB     Opcode 01H, 02H
257             ...     (one to five
258        EOI  DAB        parameter bytes)
259        ATN  UNL     Unlisten
260             ...
261             ppe     Parallel poll enabled when seek completes
262 
263 
264    Clear, Address Record, and Set File Mask
265 
266        ATN  MLA     My listen address
267        ATN  SCG     Secondary command 08H
268             ppd     Parallel poll disabled
269             DAB     Opcode 0AH, 0CH, 0FH
270             ...     (one to five
271        EOI  DAB        parameter bytes)
272             ppe     Parallel poll enabled
273        ATN  UNL     Unlisten
274 
275 
276    End
277 
278        ATN  MLA     My listen address
279        ATN  SCG     Secondary command 08H
280             ppd     Parallel poll disabled
281             DAB     Opcode 15H
282        EOI  DAB     Unused data byte
283        ATN  UNL     Unlisten
284 
285 
286    Request Status, Request Sector Address, and Request Logical Disc Address
287 
288        ATN  MLA     My listen address
289        ATN  SCG     Secondary command 08H
290             ppd     Parallel poll disabled
291             DAB     Opcode 03H, 04H, 14H
292        EOI  DAB     Unused data byte
293        ATN  UNL     Unlisten
294 
295        ATN  MTA     My talk address
296        ATN  SCG     Secondary command 08H
297             DAB     Status byte #1
298             ...     (two to four
299        EOI  DAB        status bytes)
300             ppe     Parallel poll enabled
301        ATN  UNT     Untalk
302 
303 
304    Cold Load Read, Read, Read Full Sector, Verify, Read with Offset, and Read
305    without Verify
306 
307        ATN  MLA     My listen address
308        ATN  SCG     Secondary command 08H
309             ppd     Parallel poll disabled
310             DAB     Opcode 00H, 05H, 06H, 07H, 0EH, 12H
311        EOI  DAB     Unused data byte
312        ATN  UNL     Unlisten
313 
314        ATN  MTA     My talk address
315        ATN  SCG     Secondary command 00H
316             DAB     Read data byte #1
317             ...
318             DAB     Read data byte #n
319        ATN  UNT     Untalk
320             ...
321             ppe     Parallel poll enabled when sector ends
322 
323 
324    Write, Write Full Sector, and Initialize
325 
326        ATN  MLA     My listen address
327        ATN  SCG     Secondary command 08H
328             ppd     Parallel poll disabled
329             DAB     Opcode 08H, 09H, 0BH
330        EOI  DAB     Unused data byte
331        ATN  UNL     Unlisten
332 
333        ATN  MLA     My listen address
334        ATN  SCG     Secondary command 00H
335             DAB     Write data byte #1
336             ...
337        EOI  DAB     Write data byte #n
338             ppe     Parallel poll enabled
339        ATN  UNL     Unlisten
340 
341 
342    Implementation notes:
343 
344     1. The 12745 does not alter the parallel poll response for the
345        Device-Specified Jump command.
346 
347     2. The 7910 does not perform a parallel poll response enable and disable
348        between the Initiate Self-Test and Return Self-Test Result commands.
349 
350     3. The 12745 does not disable the parallel poll response for the Read
351        Loopback command.
352 */
353 
354 
355 
356 #include "hp2100_defs.h"
357 #include "hp2100_io.h"
358 #include "hp2100_di.h"
359 #include "hp2100_disclib.h"
360 
361 
362 
363 /* Program constants */
364 
365 #define DA_UNITS        4                       /* number of addressable disc units */
366 
367 
368 /* Interface states */
369 
370 typedef enum {
371     idle = 0,                                   /* idle = default for reset */
372     opcode_wait,                                /* waiting for opcode reception */
373     parameter_wait,                             /* waiting for parameter reception */
374     read_wait,                                  /* waiting for send read data secondary */
375     write_wait,                                 /* waiting for receive write data secondary */
376     status_wait,                                /* waiting for send status secondary */
377     command_exec,                               /* executing an interface command */
378     command_wait,                               /* waiting for command completion */
379     read_xfer,                                  /* sending read data or status */
380     write_xfer,                                 /* receiving write data */
381     error_source,                               /* sending bytes for error recovery */
382     error_sink                                  /* receiving bytes for error recovery */
383     } IF_STATE;
384 
385 
386 /* Interface state names */
387 
388 static const char * const if_state_name [] = {
389     "idle",
390     "opcode wait",
391     "parameter wait",
392     "read wait",
393     "write wait",
394     "status wait",
395     "command execution",
396     "command wait",
397     "read transfer",
398     "write transfer",
399     "error source",
400     "error sink"
401     };
402 
403 
404 /* Next interface state after command recognition */
405 
406 static const IF_STATE next_state [] = {
407     read_wait,                                  /* cold load read */
408     command_exec,                               /* recalibrate */
409     command_exec,                               /* seek */
410     status_wait,                                /* request status */
411     status_wait,                                /* request sector address */
412     read_wait,                                  /* read */
413     read_wait,                                  /* read full sector */
414     command_exec,                               /* verify */
415     write_wait,                                 /* write */
416     write_wait,                                 /* write full sector */
417     command_exec,                               /* clear */
418     write_wait,                                 /* initialize */
419     command_exec,                               /* address record */
420     idle,                                       /* request syndrome */
421     read_wait,                                  /* read with offset */
422     command_exec,                               /* set file mask */
423     idle,                                       /* invalid */
424     idle,                                       /* invalid */
425     read_wait,                                  /* read without verify */
426     idle,                                       /* load TIO register */
427     status_wait,                                /* request disc address */
428     command_exec,                               /* end */
429     idle                                        /* wakeup */
430     };
431 
432 
433 /* Interface commands */
434 
435 typedef enum {
436     invalid = 0,                                /* invalid = default for reset */
437     disc_command,                               /* MLA 08 */
438     crc_listen,                                 /* MLA 09 */
439     amigo_clear,                                /* MLA 10 */
440     write_loopback,                             /* MLA 1E */
441     initiate_self_test,                         /* MLA 1F */
442     crc_talk,                                   /* MTA 09 */
443     device_specified_jump,                      /* MTA 10 */
444     read_loopback,                              /* MTA 1E */
445     return_self_test_result,                    /* MTA 1F */
446     amigo_identify                              /* UNT MSA */
447     } IF_COMMAND;
448 
449 /* Interface command names */
450 
451 static const char * const if_command_name [] = {
452     "invalid",
453     "disc command",
454     "CRC listen",
455     "Amigo clear",
456     "write loopback",
457     "initiate self-test",
458     "CRC talk",
459     "device specified jump",
460     "read loopback",
461     "return self-test result",
462     "Amigo identify"
463     };
464 
465 
466 
467 /* Amigo disc state variables */
468 
469 static uint16 buffer [DL_BUFSIZE];              /* command/status/sector buffer */
470 
471 static uint8      if_dsj     [DA_UNITS];        /* ICD controller DSJ values */
472 static IF_STATE   if_state   [DA_UNITS];        /* ICD controller state */
473 static IF_COMMAND if_command [DA_UNITS];        /* ICD controller command */
474 
475 static CNTLR_VARS icd_cntlr [DA_UNITS] =        /* ICD controllers: */
476     { { CNTLR_INIT (ICD, buffer, NULL) },       /*   unit 0 controller */
477       { CNTLR_INIT (ICD, buffer, NULL) },       /*   unit 1 controller */
478       { CNTLR_INIT (ICD, buffer, NULL) },       /*   unit 2 controller */
479       { CNTLR_INIT (ICD, buffer, NULL) } };     /*   unit 3 controller */
480 
481 
482 
483 /* Amigo disc local VM routines */
484 
485 static t_stat da_reset   (DEVICE *dptr);
486 static t_stat da_boot    (int32  unitno, DEVICE *dptr);
487 static t_stat da_attach  (UNIT   *uptr,  char *cptr);
488 static t_stat da_detach  (UNIT   *uptr);
489 
490 /* Amigo disc local SCP routines */
491 
492 static t_stat da_service     (UNIT *uptr);
493 static t_stat da_load_unload (UNIT *uptr, int32 value, char *cptr, void *desc);
494 
495 /* Amigo disc local utility routines */
496 
497 static t_bool start_command     (uint32 unit);
498 static void   abort_command     (uint32 unit, CNTLR_STATUS status, IF_STATE state);
499 static void   complete_read     (uint32 unit);
500 static void   complete_write    (uint32 unit);
501 static void   complete_abort    (uint32 unit);
502 static uint8  get_buffer_byte   (CVPTR  cvptr);
503 static void   put_buffer_byte   (CVPTR  cvptr, uint8 data);
504 static t_stat activate_unit     (UNIT   *uptr);
505 
506 
507 
508 /* Amigo disc VM global data structures.
509 
510    da_dib       DA device information block
511    da_unit      DA unit list
512    da_reg       DA register list
513    da_mod       DA modifier list
514    da_dev       DA device descriptor
515 
516 
517    Implementation notes:
518 
519     1. The IFSTAT and IFCMD registers are declared to accommodate the
520        corresponding arrays of enums.  Arrayed registers assume that elements
521        are allocated space only to the integral number of bytes implied by the
522        "width" field.  The storage size of an enum is implementation-defined, so
523        we must determine the number of bits for "width" at compile time.
524        PV_LEFT is used to avoid the large number of leading zeros that would be
525        displayed if an implementation stored enums in full words.
526 
527     2. The CNVARS register is included to ensure that the controller state
528        variables array is saved by a SAVE command.
529 
530        Ideally, each corresponding field of the four controller state variable
531        structures could appear as an arrayed register.  Unfortunately, access to
532        an array assumes that elements appear at memory offsets equal to the
533        element size, i.e., a 32-bit arrayed register has elements at four-byte
534        offsets.  While the UNIT_REG flag overrides this for UNIT arrays and
535        increases the access span to the size of the UNIT structure, there is no
536        generalization of this to other structures (e.g., there is no way to
537        specify an array of structure fields where a given 32-bit field appears
538        at, say, 92-byte offsets).  As there is no way to display the fields, we
539        include the controller array simply for SAVE/RESTORE.
540 */
541 
542 DEVICE da_dev;
543 
544 static DIB da_dib = {
545     &di_interface,                              /* the device's I/O interface function pointer */
546     NULL,                                       /* the power state function pointer */
547     DI_DA,                                      /* the device's select code (02-77) */
548     da,                                         /* the card index */
549     "12821A Disc Interface",                    /* the card description */
550     "12992H 7906H/7920H/7925H/9895 Disc Loader" /* the ROM description */
551     };
552 
553 #define UNIT_FLAGS  (UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE | UNIT_DISABLE | UNIT_UNLOAD)
554 
555 static UNIT da_unit [] = {
556     { UDATA (&da_service, UNIT_FLAGS | MODEL_7906 | SET_BUSADR (0), D7906_WORDS) }, /* drive unit 0 */
557     { UDATA (&da_service, UNIT_FLAGS | MODEL_7906 | SET_BUSADR (1), D7906_WORDS) }, /* drive unit 1 */
558     { UDATA (&da_service, UNIT_FLAGS | MODEL_7906 | SET_BUSADR (2), D7906_WORDS) }, /* drive unit 2 */
559     { UDATA (&da_service, UNIT_FLAGS | MODEL_7906 | SET_BUSADR (3), D7906_WORDS) }  /* drive unit 3 */
560     };
561 
562 static REG da_reg [] = {
563     DI_REGS (da),
564 
565     { BRDATA (BUFFER, buffer,      8, 16,       DL_BUFSIZE)                              },
566 
567     { BRDATA (DSJ,    if_dsj,     10,  2,                             DA_UNITS)          },
568     { BRDATA (ISTATE, if_state,   10, sizeof (IF_STATE) * CHAR_BIT,   DA_UNITS), PV_LEFT },
569     { BRDATA (ICMD,   if_command, 10, sizeof (IF_COMMAND) * CHAR_BIT, DA_UNITS), PV_LEFT },
570 
571     { SVDATA (CNVARS, icd_cntlr)                                                         },
572 
573     { NULL }
574     };
575 
576 static MTAB da_mod [] = {
577     DI_MODS (da_dev, da_dib),
578 
579 /*    Mask Value    Match Value   Print String       Match String     Validation        Display  Descriptor */
580 /*    ------------  ------------  -----------------  ---------------  ----------------  -------  ---------- */
581     { UNIT_UNLOAD,  UNIT_UNLOAD,  "heads unloaded",  "UNLOADED",      &da_load_unload,  NULL,    NULL       },
582     { UNIT_UNLOAD,  0,            "heads loaded",    "LOADED",        &da_load_unload,  NULL,    NULL       },
583 
584     { UNIT_WLK,     UNIT_WLK,     "protected",       "PROTECT",       NULL,             NULL,    NULL       },
585     { UNIT_WLK,     0,            "unprotected",     "UNPROTECT",     NULL,             NULL,    NULL       },
586 
587     { UNIT_WLK,     UNIT_WLK,     NULL,              "LOCKED",        NULL,             NULL,    NULL       },
588     { UNIT_WLK,     0,            NULL,              "WRITEENABLED",  NULL,             NULL,    NULL       },
589 
590     { UNIT_FMT,     UNIT_FMT,     "format enabled",  "FORMAT",        NULL,             NULL,    NULL       },
591     { UNIT_FMT,     0,            "format disabled", "NOFORMAT",      NULL,             NULL,    NULL       },
592 
593     { UNIT_MODEL,   MODEL_7906,   "7906H",           "7906H",         &dl_set_model,    NULL,    NULL       },
594     { UNIT_MODEL,   MODEL_7920,   "7920H",           "7920H",         &dl_set_model,    NULL,    NULL       },
595     { UNIT_MODEL,   MODEL_7925,   "7925H",           "7925H",         &dl_set_model,    NULL,    NULL       },
596 
597     { 0 }
598     };
599 
600 DEVICE da_dev = {
601     "DA",                                       /* device name */
602     da_unit,                                    /* unit array */
603     da_reg,                                     /* register array */
604     da_mod,                                     /* modifier array */
605     DA_UNITS,                                   /* number of units */
606     10,                                         /* address radix */
607     26,                                         /* address width */
608     1,                                          /* address increment */
609     8,                                          /* data radix */
610     16,                                         /* data width */
611     NULL,                                       /* examine routine */
612     NULL,                                       /* deposit routine */
613     &da_reset,                                  /* reset routine */
614     &da_boot,                                   /* boot routine */
615     &da_attach,                                 /* attach routine */
616     &da_detach,                                 /* detach routine */
617     &da_dib,                                    /* device information block */
618     DEV_DISABLE | DEV_DEBUG,                    /* device flags */
619     0,                                          /* debug control flags */
620     di_deb,                                     /* debug flag name table */
621     NULL,                                       /* memory size change routine */
622     NULL                                        /* logical device name */
623     };
624 
625 
626 
627 /* Amigo disc global VM routines */
628 
629 
630 /* Service an Amigo disc drive I/O event.
631 
632    The service routine is called to execute commands and control the transfer of
633    data to and from the HP-IB card.  The actions to be taken depend on the
634    current state of the ICD interface.  The possibilities are:
635 
636     1. A command is pending on the interface.  This occurs only when a command
637        is received while a Seek or Recalibrate command is in progress.
638 
639     2. A command is executing.
640 
641     3. Data is being sent or received over the HP-IB during command execution.
642 
643     4. Dummy bytes are being sent or received over the HP-IB due to a command
644        error.
645 
646    Entry to the the service routine in any other interface state or to process a
647    command not allowed in a valid state will return an Internal Error to cause a
648    simulator stop.  Exit from the routine will be either in one of the above
649    states, or in the idle state if the operation is complete.
650 
651    The specific actions taken for the various interface states are as follows:
652 
653    command_wait
654    ============
655 
656      We are entered in this state only if a unit that was busy (still seeking)
657      was addressed to listen or talk.  The card has been held off by asserting
658      NRFD after receiving MLA or MTA.  Upon entry, we complete the seek and then
659      release the interface by denying NRFD to allow the remainder of the command
660      sequence to be received from the card.
661 
662    command_exec
663    ============
664 
665      We are entered in this state to initiate, continue, or complete a command.
666      The command may be a disc command, such as Seek or Read, or an interface
667      command, such as Amigo Identify or Device-Specified Jump.
668 
669      Disc commands call the disc library service routine to perform all of the
670      common controller actions.  Any ICD-specific actions needed, such as
671      setting the DSJ value, are performed after the call.
672 
673      Certain disc commands require multiple execution phases.  For example, the
674      Read command has a start phase that reads data from the disc image file
675      into the sector buffer, a data phase that transfers bytes from the buffer
676      to the card, and an end phase that schedules the intersector gap time and
677      resets to the start phase.  Data phase transfers are performed in the
678      read_xfer or write_xfer interface states.
679 
680      The results of the disc library service are inferred by the controller
681      state.  If the controller is busy, then the command continues in a new
682      phase.  Otherwise, the command either has completed normally or has
683      terminated with an error.  If an error has occurred during a disc command
684      that transfers data, DSJ is set to 1, and the interface state is changed to
685      source or sink dummy bytes to complete the command sequence.
686 
687      Interface commands may either complete immediately (e.g., Amigo Clear) or
688      transfer data (e.g., DSJ).
689 
690    read_xfer
691    =========
692 
693      Commands that send data to the CPU enter the service routine to source a
694      byte to the bus.  Bytes are transferred only when ATN and NRFD are denied;
695      if they are not, we simply exit, as we will be rescheduled when the lines
696      are dropped.  Otherwise, we get a byte from the sector buffer and send it
697      to the card.  If the card has stopped listening, or the buffer is now
698      empty, then we terminate the transfer and move to the end phase of the
699      command.  Otherwise, we reschedule the next data phase byte transfer.
700 
701      Disc and interface commands are handled separately, as EOI is always
702      asserted on the last byte of an interface command transfer and never on a
703      (good) disc command transfer.
704 
705    write_xfer
706    ==========
707 
708      Commands that receive data from the CPU enter the service routine to
709      determine whether or not to continue the transfer.  Our bus accept routine
710      has already stored the received byte in the sector buffer and has asserted
711      NRFD to hold off the card.  If the buffer is now full, or the byte was
712      tagged with EOI, then we terminate the transfer and move to the end phase
713      of the command.  Otherwise, we deny NRFD and exit; we will be rescheduled
714      when the next byte arrives.
715 
716    error_source
717    ============
718 
719      If an error occurred during the data transfer phase of a read or status
720      command, a dummy byte tagged with EOI is sourced to the bus.  This allows
721      the OS driver for the card to terminate the command and request the
722      controller's status.
723 
724    error_sink
725    ==========
726 
727      If an error occurred during the data transfer phase of a write command,
728      dummy bytes are sunk from the bus until EOI is seen or the card is
729      unaddressed.  This allows the OS driver to complete the command as expected
730      and then determine the cause of the failure by requesting the controller's
731      status.
732 
733 
734    Implementation notes:
735 
736     1. The disc library sets the controller state to idle for a normal End,
737        Seek, or Recalibrate command and to wait for all other commands that end
738        normally.  So we determine command completion by checking if the
739        controller is not busy, rather than checking if the controller is idle.
740 
741        Drive Attention status is the normal result of the completion of a Seek
742        or Recalibrate command.  Normal Completion status is the normal result of
743        all other commands.
744 
745     2. The disc library returns the buffer length in words.  We double the
746        return value to count bytes.
747 
748     3. Some commands, such as DSJ, could be completed in the bus accept routine.
749        They are serviced here instead to avoid presenting a zero execution time
750        to the CPU.
751 
752     4. The Amigo command set does not provide the disc with the number of bytes
753        that will be read, and the unit expects to be untalked when the read is
754        to terminate.  The RTE ICD bootstrap extension does not do this.
755        Instead, it resets the card via CLC 0,C to terminate the Cold Load Read
756        that was started by the ICD boot loader ROM.
757 
758        In hardware, if the LSTN control bit is cleared, e.g., by CRS,
759        transmission stops because the card denies NDAC and NRFD (the HP-IB
760        handshake requires NDAC and NRFD to be asserted to start the handshake
761        sequence; TACS * SDYS * ~NDAC * ~NRFD is an error condition).  In
762        simulation, we handle this by terminating a read transfer if the card
763        stops accepting.  If we did not, then the disc would continue to source
764        bytes to the bus, overflowing the card FIFO (a FIFO full condition cannot
765        assert NRFD if the LSTN control bit is clear).
766 */
767 
da_service(UNIT * uptr)768 static t_stat da_service (UNIT *uptr)
769 {
770 uint8 data;
771 CNTLR_CLASS command_class;
772 const int32 unit = uptr - da_unit;                          /* get the disc unit number */
773 const CVPTR cvptr = &icd_cntlr [unit];                      /* get a pointer to the controller */
774 t_stat result = SCPE_OK;
775 t_bool release_interface = FALSE;
776 
777 switch (if_state [unit]) {                                  /* dispatch the interface state */
778 
779     case command_wait:                                      /* command is waiting */
780         release_interface = TRUE;                           /* release the interface at then end if it's idle */
781 
782     /* fall through into the command_exec handler to process the current command */
783 
784     case command_exec:                                      /* command is executing */
785         switch (if_command [unit]) {                        /* dispatch the interface command */
786 
787             case disc_command:                              /* execute a disc command */
788                 result = dl_service_drive (cvptr, uptr);    /* service the disc unit */
789 
790                 if (cvptr->opcode == Clear)                 /* is this a Clear command? */
791                     if_dsj [unit] = 2;                      /* indicate that the self test is complete */
792 
793                 if (cvptr->state != cntlr_busy) {           /* has the controller stopped? */
794                     if_state [unit] = idle;                 /* idle the interface */
795 
796                     if (cvptr->status == normal_completion ||   /* do we have normal completion */
797                         cvptr->status == drive_attention)       /*   or drive attention? */
798                         break;                                  /* we're done */
799 
800                     else {                                      /* if the status is abnormal */
801                         if_dsj [unit] = 1;                      /*   an error has occurred */
802 
803                         command_class = dl_classify (*cvptr);   /* classify the command */
804 
805                         if (command_class == class_write) {     /* did a write command fail? */
806                             if_state [unit] = error_sink;       /* sink the remaining bytes */
807                             uptr->wait = cvptr->cmd_time;       /* activate to complete processing */
808                             }
809 
810                         else if (command_class != class_control) {  /* did a read or status command fail? */
811                             if_state [unit] = error_source;         /* source an error byte */
812                             uptr->wait = cvptr->cmd_time;           /* activate to complete processing */
813                             }
814                         }
815                     }
816 
817                 else if (uptr->Phase == data_phase) {           /* are we starting the data phase? */
818                     cvptr->length = cvptr->length * 2;          /* convert the buffer length to bytes */
819 
820                     if (dl_classify (*cvptr) == class_write)    /* is this a write command? */
821                         if_state [unit] = write_xfer;           /* set for a write data transfer */
822                     else                                        /* it is a read or status command */
823                         if_state [unit] = read_xfer;            /* set for a read data transfer */
824                     }
825 
826                 break;
827 
828 
829             case amigo_identify:                            /* Amigo Identify */
830                 buffer [0] = 0x0003;                        /* store the response in the buffer */
831                 cvptr->length = 2;                          /* return two bytes */
832 
833                 if_state [unit] = read_xfer;                /* we are ready to transfer the data */
834                 uptr->wait = cvptr->cmd_time;               /* schedule the transfer */
835 
836                 tprintf (da_dev, DEB_RWSC, "Unit %d Amigo identify response %04XH\n",
837                          unit, buffer [0]);
838                 break;
839 
840 
841             case initiate_self_test:                        /* Initiate a self test */
842                 sim_cancel (&da_unit [unit]);               /* cancel any operation in progress */
843                 dl_clear_controller (cvptr,                 /* hard-clear the controller */
844                                      &da_unit [unit],
845                                      hard_clear);
846                 if_dsj [unit] = 2;                          /* set DSJ for self test completion */
847                 if_state [unit] = idle;                     /* the command is complete */
848                 di_poll_response (da, unit, SET);           /*   with PPR enabled */
849                 break;
850 
851 
852             case amigo_clear:                               /* Amigo clear */
853                 dl_idle_controller (cvptr);                 /* idle the controller */
854                 if_dsj [unit] = 0;                          /* clear the DSJ value */
855                 if_state [unit] = idle;                     /* the command is complete */
856                 di_poll_response (da, unit, SET);           /*   with PPR enabled */
857                 break;
858 
859 
860             default:                                        /* no other commands are executed */
861                 result = SCPE_IERR;                         /* signal an internal error */
862                 break;
863             }                                               /* end of command dispatch */
864         break;
865 
866 
867     case error_source:                                          /* send data after an error */
868         if (not (di [da].bus_cntl & (BUS_ATN | BUS_NRFD))) {    /* is the card ready for data? */
869             di [da].bus_cntl |= BUS_EOI;                        /* set EOI */
870             di_bus_source (da, 0);                              /*   and send a dummy byte to the card */
871             if_state [unit] = idle;                             /* the command is complete */
872             }
873         break;
874 
875 
876     case read_xfer:                                         /* send read data */
877         if (not (di [da].bus_cntl & (BUS_ATN | BUS_NRFD)))  /* is the card ready for data? */
878             switch (if_command [unit]) {                    /* dispatch the interface command */
879 
880                 case disc_command:                          /* disc read or status commands */
881                     data = get_buffer_byte (cvptr);         /* get the next byte from the buffer */
882 
883                     if (di_bus_source (da, data) == FALSE)  /* send the byte to the card; is it listening? */
884                         cvptr->eod = SET;                   /* no, so terminate the read */
885 
886                     if (cvptr->length == 0 || cvptr->eod == SET) {  /* is the data phase complete? */
887                         uptr->Phase = end_phase;                    /* set the end phase */
888 
889                         if (cvptr->opcode == Request_Status)    /* is it a Request Status command? */
890                             if_dsj [unit] = 0;                  /* clear the DSJ value */
891 
892                         if_state [unit] = command_exec;         /* set to execute the command */
893                         uptr->wait = cvptr->cmd_time;           /*   and reschedule the service */
894                         }
895 
896                     else                                    /* the data phase continues */
897                         uptr->wait = cvptr->data_time;      /* reschedule the next transfer */
898 
899                     break;
900 
901 
902                 case amigo_identify:
903                 case read_loopback:
904                 case return_self_test_result:
905                     data = get_buffer_byte (cvptr);         /* get the next byte from the buffer */
906 
907                     if (cvptr->length == 0)                 /* is the transfer complete? */
908                         di [da].bus_cntl |= BUS_EOI;        /* set EOI */
909 
910                     if (di_bus_source (da, data)            /* send the byte to the card; is it listening? */
911                       && cvptr->length > 0)                 /*   and is there more to transfer? */
912                         uptr->wait = cvptr->data_time;      /* reschedule the next transfer */
913 
914                     else {                                  /* the transfer is complete */
915                         if_state [unit] = idle;             /* the command is complete */
916                         di_poll_response (da, unit, SET);   /* enable the PPR */
917                         }
918                     break;
919 
920 
921                 case device_specified_jump:
922                     di [da].bus_cntl |= BUS_EOI;            /* set EOI */
923                     di_bus_source (da, if_dsj [unit]);      /* send the DSJ value to the card */
924                     if_state [unit] = idle;                 /* the command is complete */
925                     break;
926 
927 
928                 case crc_talk:
929                     di [da].bus_cntl |= BUS_EOI;            /* set EOI */
930                     di_bus_source (da, 0);                  /* send dummy bytes */
931                     break;                                  /*   until the card untalks */
932 
933 
934                 default:                                    /* no other commands send data */
935                     result = SCPE_IERR;                     /* signal an internal error */
936                     break;
937                 }                                           /* end of read data transfer dispatch */
938         break;
939 
940 
941     case error_sink:                                        /* absorb data after an error */
942         cvptr->index = 0;                                   /* absorb data until EOI asserts */
943 
944         if (cvptr->eod == SET)                              /* is the transfer complete? */
945             if_state [unit] = idle;                         /* the command is complete */
946 
947         di_bus_control (da, unit, 0, BUS_NRFD);             /* deny NRFD to allow the card to resume */
948         break;
949 
950 
951     case write_xfer:                                        /* receive write data */
952         switch (if_command [unit]) {                        /* dispatch the interface command */
953 
954             case disc_command:                                  /* disc write commands */
955                 if (cvptr->length == 0 || cvptr->eod == SET) {  /* is the data phase complete? */
956                     uptr->Phase = end_phase;                    /* set the end phase */
957 
958                     if_state [unit] = command_exec;         /* set to execute the command */
959                     uptr->wait = cvptr->cmd_time;           /*   and schedule the service */
960 
961                     if (cvptr->eod == CLEAR)                /* is the transfer continuing? */
962                         break;                              /* do not deny NRFD until next service! */
963                     }
964 
965                 di_bus_control (da, unit, 0, BUS_NRFD);     /* deny NRFD to allow the card to resume */
966                 break;
967 
968 
969             case write_loopback:
970                 if (cvptr->eod == SET) {                    /* is the transfer complete? */
971                     cvptr->length = 16 - cvptr->length;     /* set the count of bytes transferred */
972                     if_state [unit] = idle;                 /* the command is complete */
973                     }
974 
975                 di_bus_control (da, unit, 0, BUS_NRFD);     /* deny NRFD to allow the card to resume */
976                 break;
977 
978 
979             default:                                        /* no other commands receive data */
980                 result = SCPE_IERR;                         /* signal an internal error */
981                 break;
982             }                                               /* end of write data transfer dispatch */
983         break;
984 
985 
986     default:                                                /* no other states schedule service */
987         result = SCPE_IERR;                                 /* signal an internal error */
988         break;
989     }                                                       /* end of interface state dispatch */
990 
991 
992 if (uptr->wait)                                             /* is service requested? */
993     activate_unit (uptr);                                   /* schedule the next event */
994 
995 if (result == SCPE_IERR)                                    /* did an internal error occur? */
996     if (if_state [unit] == command_exec
997       && if_command [unit] == disc_command)
998         tprintf (da_dev, DEB_RWSC, "Unit %d %s command %s phase service not handled\n",
999                  unit,
1000                  dl_opcode_name (ICD, (CNTLR_OPCODE) uptr->Op),
1001                  dl_phase_name ((CNTLR_PHASE) uptr->Phase));
1002     else
1003         tprintf (da_dev, DEB_RWSC, "Unit %d %s state %s service not handled\n",
1004                  unit,
1005                  if_command_name [if_command [unit]],
1006                  if_state_name [if_state [unit]]);
1007 
1008 if (if_state [unit] == idle) {                              /* is the command now complete? */
1009     if (if_command [unit] == disc_command) {                /* did a disc command complete? */
1010         if (cvptr->opcode != End)                           /* yes; if the command was not End, */
1011             di_poll_response (da, unit, SET);               /*   then enable PPR */
1012 
1013         tprintf (da_dev, DEB_RWSC, "Unit %d %s disc command completed\n",
1014                  unit, dl_opcode_name (ICD, cvptr->opcode));
1015         }
1016 
1017     else                                                    /* an interface command completed */
1018         tprintf (da_dev, DEB_RWSC, "Unit %d %s command completed\n",
1019                  unit, if_command_name [if_command [unit]]);
1020 
1021     if (release_interface)                                  /* if the next command is already pending */
1022         di_bus_control (da, unit, 0, BUS_NRFD);             /*   deny NRFD to allow the card to resume */
1023     }
1024 
1025 return result;                                              /* return the result of the service */
1026 }
1027 
1028 
1029 /* Reset or preset the simulator.
1030 
1031    In hardware, a self-test is performed by the controller at power-on.  When
1032    the self-test completes, the controller sets DSJ = 2 and enables the parallel
1033    poll response.
1034 
1035    A front panel PRESET or programmed CRS has no direct effect on the controller
1036    or drive.  However, the card reacts to CRS by clearing its talker and
1037    listener states, so an in-progress read or status command will abort when the
1038    next byte sourced to the bus finds no acceptors.
1039 */
1040 
da_reset(DEVICE * dptr)1041 static t_stat da_reset (DEVICE *dptr)
1042 {
1043 uint32 unit;
1044 t_stat status;
1045 
1046 status = di_reset (dptr);                               /* reset the card */
1047 
1048 if (status == SCPE_OK && (sim_switches & SWMASK ('P'))) /* is the card OK and is this a power-on reset? */
1049     for (unit = 0; unit < dptr->numunits; unit++) {     /* loop through the units */
1050         sim_cancel (dptr->units + unit);                /* cancel any current activation */
1051         dptr->units [unit].Cyl = 0;                     /* reset the head position */
1052         dptr->units [unit].pos = 0;                     /*   to cylinder 0 */
1053 
1054         dl_clear_controller (&icd_cntlr [unit],         /* hard-clear the controller */
1055                              dptr->units + unit,
1056                              hard_clear);
1057 
1058         if_state [unit] = idle;                         /* reset the interface state */
1059         if_command [unit] = invalid;                    /* reset the interface command */
1060 
1061         if_dsj [unit] = 2;                              /* set the DSJ for power up complete */
1062         }
1063 
1064 return status;
1065 }
1066 
1067 
1068 /* Attach a unit to a disc image file.
1069 
1070    The simulator considers an attached unit to be connected to the bus and an
1071    unattached unit to be disconnected, so we set the card's acceptor bit for the
1072    selected unit if the attach is successful.  An attached unit is ready if the
1073    heads are loaded or not ready if not.
1074 
1075    This model is slightly different than the MAC (DS) simulation, where an
1076    unattached unit is considered "connected but not ready" -- the same
1077    indication returned by an attached unit whose heads are unloaded.  Therefore,
1078    the situation when the simulator is started is that all DS units are
1079    "connected to the controller but not ready," whereas all DA units are "not
1080    connected to the bus."  This eliminates the overhead of sending HP-IB
1081    messages to unused units.
1082 
1083    In tabular form, the simulator responses are:
1084 
1085       Enabled  Loaded  Attached    DS (MAC)      DA (ICD)
1086       -------  ------  --------  ------------  ------------
1087          N       N        N      disconnected  disconnected
1088          N       N        Y           --            --
1089          N       Y        N           --            --
1090          N       Y        Y           --            --
1091          Y       N        N        unloaded    disconnected
1092          Y       N        Y        unloaded      unloaded
1093          Y       Y        N           --            --
1094          Y       Y        Y         ready         ready
1095 
1096    The unspecified responses are illegal conditions; for example, the simulator
1097    does not allow an attached unit to be disabled.
1098 
1099    If a new file is specified, the file is initialized to its capacity by
1100    writing a zero to the last byte in the file.
1101 
1102 
1103    Implementation notes:
1104 
1105     1. To conform exactly to the MAC responses would have required intercepting
1106        the SET <unit> DISABLED/ENABLED commands in order to clear or set the unit
1107        accepting bits.  However, short of intercepting the all SET commands with
1108        a custom command table, there is no way to ensure that unit enables are
1109        observed.  Adding ENABLED and DISABLED to the modifiers table and
1110        specifying a validation routine works for the DISABLED case but not the
1111        ENABLED case -- set_unit_enbdis returns SCPE_UDIS before calling the
1112        validation routine.
1113 
1114     2. The C standard says, "A binary stream need not meaningfully support fseek
1115        calls with a whence value of SEEK_END," so instead we determine the
1116        offset from the start of the file to the last byte and seek there.
1117 */
1118 
da_attach(UNIT * uptr,char * cptr)1119 static t_stat da_attach (UNIT *uptr, char *cptr)
1120 {
1121 t_stat      result;
1122 t_addr      offset;
1123 const uint8 zero = 0;
1124 const int32 unit = uptr - da_unit;                      /* calculate the unit number */
1125 
1126 result = dl_attach (&icd_cntlr [unit], uptr, cptr);     /* attach the drive */
1127 
1128 if (result == SCPE_OK) {                                /* if the attach was successful */
1129     di [da].acceptors |= (1 << unit);                   /*   then set the unit's accepting bit */
1130 
1131     if (sim_switches & SWMASK ('N')) {                  /* if this is a new disc image */
1132         offset = (t_addr)                               /*   then determine the offset of */
1133           (uptr->capac * sizeof (int16) - sizeof zero); /*     the last byte in a full-sized file */
1134 
1135         if (sim_fseek (uptr->fileref, offset, SEEK_SET) != 0    /* seek to the last byte */
1136           || fwrite (&zero, sizeof zero, 1, uptr->fileref) == 0 /*   and write a zero to fill */
1137           || fflush (uptr->fileref) != 0)                       /*     the file to its capacity */
1138             clearerr (uptr->fileref);                           /* clear and ignore any errors */
1139         }
1140     }
1141 
1142 return result;                                          /* return the result of the attach */
1143 }
1144 
1145 
1146 /* Detach a disc image file from a unit.
1147 
1148    As explained above, detaching a unit is the hardware equivalent of
1149    disconnecting the drive from the bus, so we clear the unit's acceptor bit if
1150    the detach is successful.
1151 */
1152 
da_detach(UNIT * uptr)1153 static t_stat da_detach (UNIT *uptr)
1154 {
1155 t_stat result;
1156 const int32 unit = uptr - da_unit;                      /* calculate the unit number */
1157 
1158 result = dl_detach (&icd_cntlr [unit], uptr);           /* detach the drive */
1159 
1160 if (result == SCPE_OK) {                                /* was the detach successful? */
1161     di [da].acceptors &= ~(1 << unit);                  /* clear the unit's accepting bit */
1162     di_poll_response (da, unit, CLEAR);                 /*   and its PPR, as it's no longer present */
1163     }
1164 
1165 return result;
1166 }
1167 
1168 
1169 /* 7906H/20H/25H disc bootstrap loader (12992H).
1170 
1171    The HP 1000 uses the 12992H boot loader ROM to bootstrap the ICD discs.  Bit
1172    12 of the S register determines whether an RPL or manual boot is performed.
1173    Bits 1-0 specify the head number to use.
1174 
1175    The loader reads 256 words from cylinder 0 sector 0 of the specified head
1176    into memory starting at location 2011 octal.  Loader execution ends with one
1177    of the following instructions:
1178 
1179      * HLT 11     - the drive aborted the transfer due to an unrecoverable error
1180      * JSB 2055,I - the disc read succeeded
1181 
1182    The ICD drives are not supported on the 2100/14/15/16 CPUs, so no 21xx loader
1183    is provided.
1184 */
1185 
1186 static const LOADER_ARRAY da_loaders = {
1187     {                               /* HP 21xx Loader does not exist */
1188       IBL_NA,                       /*   loader starting index */
1189       IBL_NA,                       /*   DMA index */
1190       IBL_NA,                       /*   FWA index */
1191       { 0 } },
1192 
1193     {                               /* HP 1000 Loader ROM (12992H) */
1194       IBL_START,                    /*   loader starting index */
1195       IBL_DMA,                      /*   DMA index */
1196       IBL_FWA,                      /*   FWA index */
1197       { 0102501,                    /*   77700:  START LIA 1         GET SWITCH REGISTER SETTING */
1198         0100044,                    /*   77701:        LSL 4         SHIFT A LEFT 4 */
1199         0006111,                    /*   77702:        CLE,SLB,RSS   SR BIT 12 SET FOR MANUAL BOOT? */
1200         0100041,                    /*   77703:        LSL 1         NO, SHIFT HEAD # FOR RPL BOOT */
1201         0001424,                    /*   77704:        ALR,ALR       SHIFT HEAD 2, CLEAR SIGN */
1202         0033744,                    /*   77705:        IOR HDSEC     SET EOI BIT */
1203         0073744,                    /*   77706:        STA HDSEC     PLACE IN COMMAND BUFFER */
1204         0017756,                    /*   77707:        JSB BTCTL     SEND DUMMY,U-CLR,PP */
1205         0102510,                    /*   77710:        LIA IBI       READ INPUT REGISTER */
1206         0101027,                    /*   77711:        ASR 7         SHIFT DRIVE 0 RESPONSE TO LSB */
1207         0002011,                    /*   77712:        SLA,RSS       DID DRIVE 0 RESPOND? */
1208         0027710,                    /*   77713:        JMP *-3       NO, GO LOOK AGAIN */
1209         0107700,                    /*   77714:        CLC 0,C       */
1210         0017756,                    /*   77715:        JSB BTCTL     SEND TALK, CL-RD,BUS HOLDER */
1211         0002300,                    /*   77716:        CCE           */
1212         0017756,                    /*   77717:        JSB BTCTL     TELL CARD TO LISTEN */
1213         0063776,                    /*   77720:        LDA DMACW     LOAD DMA CONTROL WORD */
1214         0102606,                    /*   77721:        OTA 6         OUTPUT TO DCPC */
1215         0106702,                    /*   77722:        CLC 2         READY DCPC */
1216         0063735,                    /*   77723:        LDA ADDR1     LOAD DMA BUFFER ADDRESS */
1217         0102602,                    /*   77724:        OTA 2         OUTPUT TO DCPC */
1218         0063740,                    /*   77725:        LDA DMAWC     LOAD DMA WORD COUNT */
1219         0102702,                    /*   77726:        STC 2         READY DCPC */
1220         0102602,                    /*   77727:        OTA 2         OUTPUT TO DCPC */
1221         0103706,                    /*   77730:        STC 6,C       START DCPC */
1222         0102206,                    /*   77731:  TEST  SFC 6         SKIP IF DMA NOT DONE */
1223         0117750,                    /*   77732:        JSB ADDR2,I   SUCCESSFUL END OF TRANSFER */
1224         0102310,                    /*   77733:        SFS IBI       SKIP IF DISC ABORTED TRANSFER */
1225         0027731,                    /*   77734:        JMP TEST      RECHECK FOR TRANSFER END */
1226         0102011,                    /*   77735:  ADDR1 HLT 11B       ERROR HALT */
1227         0000677,                    /*   77736:  UNCLR OCT 677       UNLISTEN */
1228         0000737,                    /*   77737:        OCT 737       UNTALK */
1229         0176624,                    /*   77740:  DMAWC OCT 176624    UNIVERSAL CLEAR,LBO */
1230         0000440,                    /*   77741:  LIST  OCT 440       LISTEN BUS ADDRESS 0 */
1231         0000550,                    /*   77742:  CMSEC OCT 550       SECONDARY GET COMMAND */
1232         0000000,                    /*   77743:  BOOT  OCT 0         COLD LOAD READ COMMAND */
1233         0001000,                    /*   77744:  HDSEC OCT 1000      HEAD,SECTOR PLUS EOI */
1234         0000677,                    /*   77745:  UNLST OCT 677       ATN,PRIMARY UNLISTEN,PARITY */
1235         0000500,                    /*   77746:  TALK  OCT 500       SEND READ DATA */
1236         0100740,                    /*   77747:  RDSEC OCT 100740    SECONDARY READ DATA */
1237         0102055,                    /*   77750:  ADDR2 OCT 102055    BOOT EXTENSION STARTING ADDRESS */
1238         0004003,                    /*   77751:  CTLP  OCT 4003      INT=LBO,T,CIC */
1239         0000047,                    /*   77752:        OCT 47        PPE,L,T,CIC */
1240         0004003,                    /*   77753:        OCT 4003      INT=LBO,T,CIC */
1241         0000413,                    /*   77754:        OCT 413       ATN,P,L,CIC */
1242         0001015,                    /*   77755:        OCT 1015      INT=EOI,P,L,CIC */
1243         0000000,                    /*   77756:  BTCTL NOP           */
1244         0107710,                    /*   77757:        CLC IBI,C     RESET IBI */
1245         0063751,                    /*   77760:  BM    LDA CTLP      LOAD CONTROL WORD */
1246         0102610,                    /*   77761:        OTA IBI       OUTPUT TO CONTROL REGISTER */
1247         0102710,                    /*   77762:        STC IBI       RETURN IBI TO DATA MODE */
1248         0037760,                    /*   77763:        ISZ BM        INCREMENT CONTROL WORD POINTER */
1249         0002240,                    /*   77764:        SEZ,CME       */
1250         0127756,                    /*   77765:        JMP BTCTL,I   RETURN */
1251         0063736,                    /*   77766:  LABL  LDA UNCLR     LOAD DATA WORD */
1252         0037766,                    /*   77767:        ISZ LABL      INCREMENT WORD POINTER */
1253         0102610,                    /*   77770:        OTA IBI       OUTPUT TO HPIB */
1254         0002021,                    /*   77771:        SSA,RSS       SKIP IF LAST WORD */
1255         0027766,                    /*   77772:        JMP LABL      GO BACK FOR NEXT WORD */
1256         0102310,                    /*   77773:        SFS IBI       SKIP IF LAST WORD SENT TO BUS */
1257         0027773,                    /*   77774:        JMP *-1       RECHECK ACCEPTANCE */
1258         0027757,                    /*   77775:        JMP BTCTL+1   */
1259         0000010,                    /*   77776:  DMACW ABS IBI       */
1260         0170100 } }                 /*   77777:        ABS -START    */
1261     };
1262 
1263 /* Device boot routine.
1264 
1265    This routine is called directly by the BOOT DA and LOAD DA commands to copy
1266    the device bootstrap into the upper 64 words of the logical address space.
1267    It is also called indirectly by a BOOT CPU or LOAD CPU command when the
1268    specified HP 1000 loader ROM socket contains a 12992H ROM.
1269 
1270    When called in response to a BOOT DA or LOAD DA command, the "unitno"
1271    parameter indicates the unit number specified in the BOOT command or is zero
1272    for the LOAD command, and "dptr" points at the DA device structure.  The
1273    bootstrap supports loading only from the disc at bus address 0 only.  The
1274    12992F loader ROM will be copied into memory and configured for the DA select
1275    code.  The S register will be set as it would be by the front-panel
1276    microcode.
1277 
1278    When called for a BOOT/LOAD CPU command, the "unitno" parameter indicates the
1279    select code to be used for configuration, and "dptr" will be NULL.  As above,
1280    the 12992H loader ROM will be copied into memory and configured for the
1281    specified select code.  The S register is assumed to be set correctly on
1282    entry and is not modified.
1283 
1284    The loader expects the S register to be is set as follows:
1285 
1286       15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0
1287      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
1288      | ROM # | 0   1 |      select code      |   reserved    | head  |
1289      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
1290 
1291    Bit 12 must be 1 for a manual boot.  Bits 5-2 are nominally zero but are
1292    reserved for the target operating system.  For example, RTE uses bit 5 to
1293    indicate whether a standard (0) or reconfiguration (1) boot is desired.
1294 
1295    The boot routine sets bits 15-6 of the S register to appropriate values.
1296    Bits 5-3 and 1-0 retain their original values, so S should be set before
1297    booting.  These bits are typically set to 0, although bit 5 is set for an RTE
1298    reconfiguration boot, and bits 1-0 may be set if booting from a head other
1299    than 0 is desired.
1300 */
1301 
da_boot(int32 unitno,DEVICE * dptr)1302 static t_stat da_boot (int32 unitno, DEVICE *dptr)
1303 {
1304 static const HP_WORD da_preserved   = 0000073u;             /* S-register bits 5-3 and 1-0 are preserved */
1305 static const HP_WORD da_manual_boot = 0010000u;             /* S-register bit 12 set for a manual boot */
1306 uint32 status;
1307 
1308 if (dptr == NULL)                                           /* if we are being called for a BOOT/LOAD CPU */
1309     status = cpu_copy_loader (da_loaders, unitno,           /*   then copy the boot loader to memory */
1310                               IBL_S_NOCLEAR, IBL_S_NOSET);  /*     but do not alter the S register */
1311 
1312 else if (GET_BUSADR (da_unit [unitno].flags) != 0)          /* otherwise BOOT DA is supported on bus address 0 only */
1313     return SCPE_NOFNC;                                      /*   so reject other addresses as unsupported */
1314 
1315 else                                                            /* otherwise this is a BOOT/LOAD DA */
1316     status = cpu_copy_loader (da_loaders, da_dib.select_code,   /*   so copy the boot loader to memory */
1317                               da_preserved, da_manual_boot);    /*     and configure the S register if 1000 CPU */
1318 
1319 if (status == 0)                                        /* if the copy failed */
1320     return SCPE_NOFNC;                                  /*   then reject the command */
1321 else                                                    /* otherwise */
1322     return SCPE_OK;                                     /*   the boot loader was successfully copied */
1323 }
1324 
1325 
1326 
1327 /* Amigo disc global SCP routines */
1328 
1329 
1330 /* Load or unload a unit's heads.
1331 
1332    The heads are automatically loaded when a unit is attached and unloaded when
1333    a unit is detached.  While a unit is attached, the heads may be manually
1334    unloaded; this yields a "not ready" status if the unit is accessed.  An
1335    unloaded drive may be manually loaded, returning the unit to "ready" status.
1336 
1337    The ICD controller sets Drive Attention status when the heads unload and also
1338    asserts a parallel poll response if the heads unload while in idle state 2
1339    (i.e., after an End command).
1340 
1341 
1342    Implementation notes:
1343 
1344     1. The 13365 manual says on page 28 that Drive Attention status is
1345        "Generated whenever...the drive unloads and the controller is in Idle
1346        State 2 or 3."  However, the ICD diagnostic tests for Drive Attention
1347        status on head unload immediately after the Request Status command that
1348        completes the previous step, which leaves the controller in idle state 1.
1349 
1350        Moreover, the diagnostic does NOT check for Drive Attention status if the
1351        Amigo ID is 2 (MAC controller).  But the 12745 manual says on page 3-7
1352        that the status is returned if "...Drive becomes not ready (heads
1353        unload)" with no mention of controller state.
1354 
1355        It appears as though the diagnostic test is exactly backward.  However,
1356        we match the diagnostic expectation below.
1357 */
1358 
da_load_unload(UNIT * uptr,int32 value,char * cptr,void * desc)1359 static t_stat da_load_unload (UNIT *uptr, int32 value, char *cptr, void *desc)
1360 {
1361 const int32 unit = uptr - da_unit;                          /* calculate the unit number */
1362 const t_bool load = (value != UNIT_UNLOAD);                 /* true if the heads are loading */
1363 t_stat result;
1364 
1365 result = dl_load_unload (&icd_cntlr [unit], uptr, load);    /* load or unload the heads */
1366 
1367 if (result == SCPE_OK && not load) {                        /* was the unload successful? */
1368     icd_cntlr [unit].status = drive_attention;              /* set Drive Attention status */
1369 
1370     if (uptr->Op == End)                                    /* is the controller in idle state 2? */
1371         di_poll_response (da, unit, SET);                   /* enable PPR */
1372     }
1373 
1374 return result;
1375 }
1376 
1377 
1378 
1379 /* Amigo disc global bus routines */
1380 
1381 
1382 /* Accept a data byte from the bus.
1383 
1384    The indicated unit is offered a byte that has been sourced to the bus.  The
1385    routine returns TRUE or FALSE to indicate whether or not it accepted the
1386    byte.
1387 
1388    Commands from the bus may be universal (applying to all acceptors) or
1389    addressed (applying only to those acceptors that have been addressed to
1390    listen).  Data bytes are accepted only if the unit has been addressed to
1391    listen.  As we are called for a data transfer or an addressed command only if
1392    we are currently listening, the only bytes that we do not accept are primary
1393    talk or listen commands directed to another address, or secondary commands
1394    when we are not addressed to listen.
1395 
1396    This routine handles the HP-IB protocol.  The type of byte passed is
1397    determined by the state of the ATN signal and, if ATN is asserted, by the
1398    high-order bits of the value.  Most of the work involves decoding secondary
1399    commands and their associated data parameters.  The interface state is
1400    changed as needed to track the command protocol.  The states processed in
1401    this routine are:
1402 
1403    opcode_wait
1404    ===========
1405 
1406      A Receive Disc Command secondary has been received, and the interface is
1407      waiting for the opcode that should follow.
1408 
1409    parameter_wait
1410    ==============
1411 
1412      A disc opcode or interface command has been received, and the interface is
1413      waiting for a parameter byte that should follow.
1414 
1415    write_wait
1416    ==========
1417 
1418      A disc write command has been received, and the interface is waiting for
1419      the Receive Write Data secondary that should follow.
1420 
1421    read_wait
1422    =========
1423 
1424      A disc read command has been received, and the interface is waiting for the
1425      Send Read Data secondary that should follow.
1426 
1427    status_wait
1428    ===========
1429 
1430      A disc status command has been received, and the interface is waiting for
1431      the Send Disc Status secondary that should follow.
1432 
1433    write_xfer
1434    ==========
1435 
1436      A disc write is in progress, and the interface is waiting for a data byte
1437      that should follow.
1438 
1439    error_sink
1440    ==========
1441 
1442      A disc write has terminated with an error, and the interface is waiting to
1443      absorb all of the remaining data bytes of the transfer.
1444 
1445 
1446    Disc commands and parameters are assembled in the sector buffer before being
1447    passed to the disc library to start the command.  Once the command is
1448    started, the interface state is set either to execute the command or to wait
1449    for the receipt of a data transfer secondary before executing, depending on
1450    the command.
1451 
1452    Two disc command protocol errors are detected.  First, an Illegal Opcode is
1453    identified during the check for the expected number of disc command
1454    parameters.  This allows us to sink an arbitrary number of parameter bytes.
1455    Second, an I/O Program Error occurs if an unsupported secondary is received
1456    or the HP-IB sequence is incorrect.  The latter occurs if a command has the
1457    wrong number of parameters or a secondary data transfer sequence is invalid.
1458 
1459    Disc commands that require data transfers (e.g., Read, Write, Request Status)
1460    involve a pair of secondaries.  The first transmits the command, and the
1461    second transmits or receives the data.  If one occurs without the other, an
1462    I/O Program Error occurs.
1463 
1464    A secondary or command that generates an I/O Program Error is always ignored.
1465    Error recovery is as follows:
1466 
1467     - An unsupported talk secondary sends a single data byte tagged with EOI.
1468 
1469     - An unsupported listen secondary accepts and discards any accompanying data
1470       bytes until EOI is asserted or an Unlisten is received.
1471 
1472     - A supported command with too few parameter bytes or for which the last
1473       parameter byte is not tagged with EOI (before unlisten) does nothing.
1474 
1475     - A supported command with too many parameter bytes accepts and discards
1476       excess parameter bytes until EOI is asserted or an Unlisten is received.
1477 
1478     - A read or status command that is not followed by a Send Read Data or a
1479       Send Disc Status secondary does nothing.  The unexpected secondary is
1480       executed normally.
1481 
1482     - A write command that is not followed by a Receive Write Data secondary
1483       does nothing.  The unexpected secondary is executed normally.
1484 
1485     - A Send Read Data or a Send Disc Status secondary that is not preceded by a
1486       read or status command sends a single data byte tagged with EOI.
1487 
1488     - A Receive Write Data secondary that is not preceded by a write command
1489       accepts and discards data bytes until EOI is asserted or an Unlisten is
1490       received.
1491 
1492    The Amigo command sequence does not provide a byte count for disc read and
1493    write commands, so the controller continues to source or accept data bytes
1494    until the device is unaddressed.  Normally, this is done by an Unlisten or
1495    Untalk.  However, per IEEE-488, a listening device may be unaddressed by IFC,
1496    by an Unlisten, or by addressing the device to talk, and a talking device may
1497    be unaddressed by IFC, by addressing another device to talk (or no device via
1498    Untalk), or by addressing the device to listen.  Therefore, we must keep
1499    track of whether the unit stopped talking or listening, and if it has, we
1500    check for command termination.
1501 
1502    If the controller is unaddressed in the middle of a sector transfer, the read
1503    or write must be terminated cleanly to ensure that the disc image is
1504    coherent.  It is also permissible to untalk the controller before all of the
1505    requested status bytes are returned.
1506 
1507    In addition, the controller has no way to inform the host that an error has
1508    occurred that prevents the command from continuing.  For example, if a data
1509    error is encountered while reading or a protected track is encountered while
1510    writing, the controller must still source or sink data bytes until the
1511    command is terminated by the host.  The controller handles read errors by
1512    sourcing a single data byte tagged with EOI and write errors by sinking data
1513    bytes until EOI is seen or the unit is unaddressed.
1514 
1515    Therefore, if the unit is unaddressed while a read, write, or status command
1516    is transferring data, the unit service must be scheduled to end the current
1517    command.  Unaddressing while an error condition is present merely terminates
1518    the source or sink operation.
1519 
1520 
1521    Implementation notes:
1522 
1523     1. The 13365 manual does not indicate that the controller responds to
1524        Universal Clear, but the 12992H loader ROM issues this primary and
1525        expects the controller to initialize.
1526 
1527     2. It is not necessary to check for listening when processing addressed
1528        commands, as only listeners are called by the bus source.
1529 */
1530 
da_bus_accept(uint32 unit,uint8 data)1531 t_bool da_bus_accept (uint32 unit, uint8 data)
1532 {
1533 const uint8 message_address = data & BUS_ADDRESS;
1534 t_bool accepted = TRUE;
1535 t_bool initiated = FALSE;
1536 t_bool addressed = FALSE;
1537 t_bool stopped_listening = FALSE;
1538 t_bool stopped_talking = FALSE;
1539 char action [40] = "";
1540 uint32 my_address;
1541 
1542 if (di [da].bus_cntl & BUS_ATN) {                           /* is it a bus command (ATN asserted)? */
1543     switch (data & BUS_GROUP) {                             /* dispatch the bus group */
1544 
1545         case BUS_PCG:                                       /* primary command group */
1546             switch (message_address) {
1547 
1548                 case 0x04:                                  /* selected device clear */
1549                 case 0x05:                                  /* SDC with parity freeze */
1550                 case 0x14:                                  /* universal clear */
1551                     tprintf (da_dev, DEB_RWSC, "Unit %d device cleared\n", unit);
1552 
1553                     sim_cancel (&da_unit [unit]);           /* cancel any in-progress command */
1554                     dl_idle_controller (&icd_cntlr [unit]); /* idle the controller */
1555                     if_dsj [unit] = 0;                      /* clear DSJ */
1556                     if_state [unit] = idle;                 /* idle the interface */
1557                     di_poll_response (da, unit, SET);       /* enable PPR */
1558 
1559                     if (TRACING (da_dev, TRACE_XFER))
1560                         strcpy (action, "device clear");
1561                     break;
1562 
1563 
1564                 default:                                    /* unsupported universal command */
1565                     break;                                  /* universals are always accepted */
1566                 }
1567 
1568             break;
1569 
1570 
1571         case BUS_LAG:                                       /* listen address group */
1572             my_address = GET_BUSADR (da_unit [unit].flags); /* get my bus address */
1573 
1574             if (message_address == my_address) {            /* is it my listen address? */
1575                 di [da].listeners |= (1 << unit);           /* set my listener bit */
1576                 di [da].talker &= ~(1 << unit);             /* clear my talker bit */
1577 
1578                 addressed = TRUE;                           /* unit is now addressed */
1579                 stopped_talking = TRUE;                     /* MLA stops the unit from talking */
1580 
1581                 if (TRACING (da_dev, TRACE_XFER))
1582                     sprintf (action, "listen %d", message_address);
1583                 }
1584 
1585             else if (message_address == BUS_UNADDRESS) {    /* is it an Unlisten? */
1586                 di [da].listeners = 0;                      /* clear all of the listeners */
1587 
1588                 stopped_listening = TRUE;                   /* UNL stops the unit from listening */
1589 
1590                 if (TRACING (da_dev, TRACE_XFER))
1591                     strcpy (action, "unlisten");
1592                 }
1593 
1594             else                                            /* other listen addresses */
1595                 accepted = FALSE;                           /*   are not accepted */
1596 
1597             break;
1598 
1599 
1600         case BUS_TAG:                                       /* talk address group */
1601             my_address = GET_BUSADR (da_unit [unit].flags); /* get my bus address */
1602 
1603             if (message_address == my_address) {            /* is it my talk address? */
1604                 di [da].talker = (1 << unit);               /* set my talker bit and clear the others */
1605                 di [da].listeners &= ~(1 << unit);          /* clear my listener bit */
1606 
1607                 addressed = TRUE;                           /* the unit is now addressed */
1608                 stopped_listening = TRUE;                   /* MTA stops the unit from listening */
1609 
1610                 if (TRACING (da_dev, TRACE_XFER))
1611                     sprintf (action, "talk %d", message_address);
1612                 }
1613 
1614             else {                                          /* it is some other talker (or Untalk) */
1615                 di [da].talker &= ~(1 << unit);             /* clear my talker bit */
1616 
1617                 stopped_talking = TRUE;                     /* UNT or OTA stops the unit from talking */
1618 
1619                 if (message_address != BUS_UNADDRESS)       /* other talk addresses */
1620                     accepted = FALSE;                       /*   are not accepted */
1621 
1622                 else                                        /* it's an Untalk */
1623                     if (TRACING (da_dev, TRACE_XFER))
1624                         strcpy (action, "untalk");
1625                 }
1626 
1627             break;
1628 
1629 
1630         case BUS_SCG:                                       /* secondary command group */
1631             icd_cntlr [unit].index = 0;                     /* reset the buffer index */
1632 
1633             if (di [da].listeners & (1 << unit)) {          /* is it a listen secondary? */
1634                 if (if_state [unit] == write_wait           /* if we're waiting for a write data secondary */
1635                   && message_address != 0x00)               /*   but it's not there, */
1636                     abort_command (unit, io_program_error,  /*   then abort the pending command */
1637                                    idle);                   /*   and process the new command */
1638 
1639                 switch (message_address) {                  /* dispatch the listen secondary */
1640 
1641                     case 0x00:                                                  /* Receive Write Data */
1642                         if (if_state [unit] != write_wait)                      /* if we're not expecting it */
1643                             abort_command (unit, io_program_error,              /*   abort and sink any data */
1644                                            error_sink);
1645                         else {                                                  /* the sequence is correct */
1646                             if_state [unit] = command_exec;                     /* the command is ready to execute */
1647                             da_unit [unit].wait = icd_cntlr [unit].cmd_time;    /* schedule the unit */
1648                             di_bus_control (da, unit, BUS_NRFD, 0);             /* assert NRFD to hold off the card */
1649                             }
1650 
1651                         initiated = TRUE;                   /* log the command or abort initiation */
1652                         break;
1653 
1654                     case 0x08:                                  /* disc commands */
1655                         if_command [unit] = disc_command;       /* set the command and wait */
1656                         if_state [unit] = opcode_wait;          /*  for the opcode that must follow */
1657                         break;
1658 
1659                     case 0x09:                                  /* CRC (Listen) */
1660                         if_command [unit] = crc_listen;         /* set up the command */
1661                         if_state [unit] = error_sink;           /* sink any data that will be coming */
1662                         initiated = TRUE;                       /* log the command initiation */
1663                         break;
1664 
1665                     case 0x10:                                  /* Amigo Clear */
1666                         if_command [unit] = amigo_clear;        /* set up the command */
1667                         if_state [unit] = parameter_wait;       /* a parameter must follow */
1668                         icd_cntlr [unit].length = 1;            /* set to expect one (unused) byte */
1669                         break;
1670 
1671                     case 0x1E:                                  /* Write Loopback */
1672                         if_command [unit] = write_loopback;     /* set up the command */
1673                         if_state [unit] = write_xfer;           /* data will be coming */
1674                         icd_cntlr [unit].length = 16;           /* accept only the first 16 bytes */
1675                         initiated = TRUE;                       /* log the command initiation */
1676                         break;
1677 
1678                     case 0x1F:                                  /* Initiate Self-Test */
1679                         if_command [unit] = initiate_self_test; /* set up the command */
1680                         if_state [unit] = parameter_wait;       /* a parameter must follow */
1681                         icd_cntlr [unit].length = 1;            /* set to expect the test ID byte */
1682                         break;
1683 
1684                     default:                                    /* an unsupported listen secondary was received */
1685                         abort_command (unit, io_program_error,  /* abort and sink any data */
1686                                        error_sink);             /*   that might accompany the command */
1687                         initiated = TRUE;                       /* log the abort initiation */
1688                         break;
1689                     }
1690                 }
1691 
1692 
1693             else if (di [da].talker & (1 << unit)) {                /* is it a talk secondary? */
1694                 da_unit [unit].wait = icd_cntlr [unit].cmd_time;    /* these are always scheduled and */
1695                 initiated = TRUE;                                   /*   logged as initiated */
1696 
1697                 if (if_state [unit] == read_wait                    /* if we're waiting for a send data secondary */
1698                   && message_address != 0x00                        /*   but it's not there */
1699                   || if_state [unit] == status_wait                 /* or a send status secondary, */
1700                   && message_address != 0x08)                       /*   but it's not there */
1701                     abort_command (unit, io_program_error,          /*   then abort the pending command */
1702                                    idle);                           /*   and process the new command */
1703 
1704                 switch (message_address) {                          /* dispatch the talk secondary */
1705 
1706                     case 0x00:                                      /* Send Read Data */
1707                         if (if_state [unit] != read_wait)           /* if we're not expecting it */
1708                             abort_command (unit, io_program_error,  /*   abort and source a data byte */
1709                                            error_source);           /*     tagged with EOI */
1710                         else
1711                             if_state [unit] = command_exec;         /* the command is ready to execute */
1712                         break;
1713 
1714                     case 0x08:                                      /* Read Status */
1715                         if (if_state [unit] != status_wait)         /* if we're not expecting it, */
1716                             abort_command (unit, io_program_error,  /*   abort and source a data byte */
1717                                            error_source);           /*     tagged with EOI */
1718                         else                                        /* all status commands */
1719                             if_state [unit] = read_xfer;            /*   are ready to transfer data */
1720                         break;
1721 
1722                     case 0x09:                                      /* CRC (Talk) */
1723                         if_command [unit] = crc_talk;               /* set up the command */
1724                         if_state [unit] = read_xfer;                /* data will be going */
1725                         break;
1726 
1727                     case 0x10:                                      /* Device-Specified Jump */
1728                         if_command [unit] = device_specified_jump;  /* set up the command */
1729                         if_state [unit] = read_xfer;                /* data will be going */
1730                         break;
1731 
1732                     case 0x1E:                                      /* Read Loopback */
1733                         if_command [unit] = read_loopback;          /* set up the command */
1734                         if_state [unit] = read_xfer;                /* data will be going */
1735                         break;
1736 
1737                     case 0x1F:                                          /* Return Self-Test Result */
1738                         if_command [unit] = return_self_test_result;    /* set up the command */
1739                         if_state [unit] = read_xfer;                    /* data will be going */
1740                         icd_cntlr [unit].length = 1;                    /* return one byte that indicates */
1741                         buffer [0] = 0;                                 /*   that the self-test passed */
1742                         break;
1743 
1744                     default:                                        /* an unsupported talk secondary was received */
1745                         abort_command (unit, io_program_error,      /* abort and source a data byte */
1746                                        error_source);               /*   tagged with EOI */
1747                         break;
1748                     }
1749                 }
1750 
1751 
1752             else {                                                  /* the unit is not addressed */
1753                 my_address = GET_BUSADR (da_unit [unit].flags);     /* get my bus address */
1754 
1755                 if (di [da].talker == 0 && di [da].listeners == 0       /* if there are no talkers or listeners */
1756                   && message_address == my_address) {                   /*   and this is my secondary address, */
1757                     if_command [unit] = amigo_identify;                 /*     then this is an Amigo ID sequence */
1758                     if_state [unit] = command_exec;                     /* set up for execution */
1759                     da_unit [unit].wait = icd_cntlr [unit].cmd_time;    /* schedule the unit */
1760                     initiated = TRUE;                                   /* log the command initiation */
1761                     }
1762 
1763                 else                                                /* unaddressed secondaries */
1764                     accepted = FALSE;                               /*   are not accepted */
1765                 }
1766 
1767 
1768             if (accepted) {                                 /* was the command accepted? */
1769                 if (TRACING (da_dev, TRACE_XFER))
1770                     sprintf (action, "secondary %02XH", message_address);
1771 
1772                 if (if_command [unit] != amigo_identify)    /* disable PPR for all commands */
1773                     di_poll_response (da, unit, CLEAR);     /*   except Amigo ID */
1774                 }
1775 
1776             break;                                          /* end of secondary processing */
1777         }
1778 
1779 
1780     if (addressed && sim_is_active (&da_unit [unit])) {     /* is the unit being addressed while it is busy? */
1781         if_state [unit] = command_wait;                     /* change the interface state to wait */
1782         di_bus_control (da, unit, BUS_NRFD, 0);             /*   and assert NRFD to hold off the card */
1783 
1784         tprintf (da_dev, DEB_RWSC, "Unit %d addressed while controller is busy\n", unit);
1785         }
1786 
1787     if (stopped_listening) {                                /* was the unit Unlistened? */
1788         if (icd_cntlr [unit].state == cntlr_busy)           /* if the controller is busy, */
1789             complete_write (unit);                          /*   then check for write completion */
1790 
1791         else if (if_command [unit] == invalid)              /* if a command was aborting, */
1792             complete_abort (unit);                          /*   then complete it */
1793 
1794         else if (if_state [unit] == opcode_wait             /* if waiting for an opcode */
1795           || if_state [unit] == parameter_wait)             /*   or a parameter, */
1796             abort_command (unit, io_program_error, idle);   /*   then abort the pending command */
1797         }
1798 
1799     else if (stopped_talking) {                             /* was the unit Untalked? */
1800         if (icd_cntlr [unit].state == cntlr_busy)           /* if the controller is busy, */
1801             complete_read (unit);                           /*   then check for read completion */
1802 
1803         else if (if_command [unit] == invalid)              /* if a command was aborting, */
1804             complete_abort (unit);                          /*   then complete it */
1805         }
1806     }                                                       /* end of bus command processing */
1807 
1808 
1809 else {                                                      /* it is bus data (ATN is denied) */
1810     switch (if_state [unit]) {                              /* dispatch the interface state */
1811 
1812         case opcode_wait:                                   /* waiting for an opcode */
1813             if (TRACING (da_dev, TRACE_XFER))
1814                 sprintf (action, "opcode %02XH", data & DL_OPCODE_MASK);
1815 
1816             buffer [0] = TO_WORD (data, 0);                 /* set the opcode into the buffer */
1817 
1818             if (dl_prepare_command (&icd_cntlr [unit],      /* is the command valid? */
1819                                     da_unit, unit)) {
1820                 if_state [unit] = parameter_wait;           /* set up to get the pad byte */
1821                 icd_cntlr [unit].index = 0;                 /* reset the word index for the next byte */
1822                 icd_cntlr [unit].length =                   /* convert the parameter count to bytes */
1823                   icd_cntlr [unit].length * 2 + 1;          /*   and include the pad byte */
1824                 }
1825 
1826             else {                                          /* the disc command is invalid */
1827                 abort_command (unit, illegal_opcode,        /* abort the command */
1828                                error_sink);                 /*   and sink any parameter bytes */
1829                 initiated = TRUE;                           /* log the abort initiation */
1830                 }                                           /* (the unit cannot be busy) */
1831             break;
1832 
1833 
1834         case parameter_wait:                                /* waiting for a parameter */
1835             if (TRACING (da_dev, TRACE_XFER))
1836                 sprintf (action, "parameter %02XH", data);
1837 
1838             put_buffer_byte (&icd_cntlr [unit], data);      /* add the byte to the buffer */
1839 
1840             if (icd_cntlr [unit].length == 0)               /* is this the last parameter? */
1841                 if (di [da].bus_cntl & BUS_EOI)             /* does the host agree? */
1842                     initiated = start_command (unit);       /* start the command and log the initiation */
1843 
1844                 else {                                      /* the parameter count is wrong */
1845                     abort_command (unit, io_program_error,  /* abort the command and sink */
1846                                    error_sink);             /*   any additional parameter bytes */
1847                     initiated = TRUE;                       /* log the abort initiation */
1848                     }
1849             break;
1850 
1851 
1852         case write_xfer:                                    /* transferring write data */
1853             if (icd_cntlr [unit].length > 0)                /* if there is more to transfer */
1854                 put_buffer_byte (&icd_cntlr [unit], data);  /*   then add the byte to the buffer */
1855 
1856         /* fall through into the error_sink handler */
1857 
1858         case error_sink:                                        /* sinking data after an error */
1859             if (TRACING (da_dev, TRACE_XFER))
1860                 sprintf (action, "data %03o", data);
1861 
1862             if (di [da].bus_cntl & BUS_EOI)                     /* is this the last byte from the bus? */
1863                 icd_cntlr [unit].eod = SET;                     /* indicate EOD to the controller */
1864 
1865             di_bus_control (da, unit, BUS_NRFD, 0);             /* assert NRFD to hold off the card */
1866 
1867             da_unit [unit].wait = icd_cntlr [unit].data_time;   /* schedule the unit */
1868             break;
1869 
1870 
1871         default:                                            /* data was received in the wrong state */
1872             abort_command (unit, io_program_error,          /* report the error */
1873                            error_sink);                     /*   and sink any data that follows */
1874 
1875             if (TRACING (da_dev, TRACE_XFER))
1876                 sprintf (action, "unhandled data %03o", data);
1877             break;
1878         }
1879     }
1880 
1881 
1882 if (accepted)
1883     tprintf (da_dev, TRACE_XFER, "HP-IB address %d accepted %s\n",
1884              GET_BUSADR (da_unit [unit].flags), action);
1885 
1886 if (da_unit [unit].wait > 0)                            /* was service requested? */
1887     activate_unit (&da_unit [unit]);                    /* schedule the unit */
1888 
1889 if (initiated)
1890     if (if_command [unit] == disc_command)
1891         tprintf (da_dev, DEB_RWSC, "Unit %d position %" T_ADDR_FMT "d %s disc command initiated\n",
1892                  unit, da_unit [unit].pos, dl_opcode_name (ICD, icd_cntlr [unit].opcode));
1893     else
1894         tprintf (da_dev, DEB_RWSC, "Unit %d %s command initiated\n",
1895                  unit, if_command_name [if_command [unit]]);
1896 
1897 return accepted;                                        /* indicate the acceptance condition */
1898 }
1899 
1900 
1901 /* Respond to the bus control lines.
1902 
1903    The indicated unit is notified of the new control state on the bus.  There
1904    are two conditions to which we must respond:
1905 
1906     1. An Interface Clear is initiated.  IFC unaddresses all units, so any
1907        in-progress disc command must be terminated as if an Untalk and Unlisten
1908        were accepted from the data bus.
1909 
1910     2. Attention and Not Ready for Data are denied.  A device addressed to talk
1911        must wait for ATN to deny before data may be sent.  Also, a listener that
1912        has asserted NRFD must deny it before a talker may send data.  If the
1913        interface is sending data and both ATN and NRFD are denied, then we
1914        reschedule the service routine to send the next byte.
1915 */
1916 
da_bus_respond(CARD_ID card,uint32 unit,uint8 new_cntl)1917 void da_bus_respond (CARD_ID card, uint32 unit, uint8 new_cntl)
1918 {
1919 if (new_cntl & BUS_IFC) {                               /* is interface clear asserted? */
1920     di [da].listeners = 0;                              /* perform an Unlisten */
1921     di [da].talker = 0;                                 /*   and an Untalk */
1922 
1923     if (icd_cntlr [unit].state == cntlr_busy) {         /* is the controller busy? */
1924         complete_write (unit);                          /* check for write completion */
1925         complete_read (unit);                           /*   or read completion */
1926 
1927         if (da_unit [unit].wait > 0)                    /* is service needed? */
1928             activate_unit (&da_unit [unit]);            /* activate the unit */
1929         }
1930 
1931     else if (if_command [unit] == invalid)              /* if a command was aborting, */
1932         complete_abort (unit);                          /*   then complete it */
1933 
1934     else if (if_state [unit] == opcode_wait             /* if we're waiting for an opcode */
1935       || if_state [unit] == parameter_wait)             /*   or a parameter, */
1936         abort_command (unit, io_program_error, idle);   /*   then abort the pending command */
1937     }
1938 
1939 if (not (new_cntl & (BUS_ATN | BUS_NRFD))               /* is the card in data mode and ready for data? */
1940   && (if_state [unit] == read_xfer                      /* is the interface waiting to send data */
1941   || if_state [unit] == error_source))                  /*   or source error bytes? */
1942     da_service (&da_unit [unit]);                       /* start or resume the transfer */
1943 }
1944 
1945 
1946 
1947 /* Amigo disc local utility routines */
1948 
1949 
1950 /* Start a command with parameters.
1951 
1952    A command that has been waiting for all of its parameters to be received is
1953    now ready to start.  If this is a disc command, call the disc library to
1954    validate the parameters and, if they are OK, to start the command.  Status
1955    commands return the status values in the sector buffer and the number of
1956    words that were returned in the buffer length, which we convert to a byte
1957    count.
1958 
1959    If the disc command was accepted, the library returns a pointer to the unit
1960    to be scheduled.  For an ICD controller, the unit is always the one currently
1961    addressed, so we simply test if the return is not NULL.  If it isn't, then we
1962    set the next interface state as determined by the command that is executing.
1963    For example, a Read command sets the interface to read_wait status in order
1964    to wait until the accompanying Send Read Data secondary is received.
1965 
1966    If the return is NULL, then the command was rejected, so we set DSJ = 1 and
1967    leave the interface state in parameter_wait; the controller status will have
1968    been set to the reason for the rejection.
1969 
1970    If the next interface state is command_exec, then the disc command is ready
1971    for execution, and we return TRUE to schedule the unit service.  Otherwise,
1972    we return FALSE, and the appropriate action will be taken by the caller.
1973 
1974    For all other commands, execution begins as soon as the correct parameters
1975    are received, so we set command_exec state and return TRUE.  (Only Amigo
1976    Clear and Initiate Self Test require parameters, so they will be the only
1977    other commands that must be started here.)
1978 
1979 
1980    Implementation notes:
1981 
1982     1. As the ICD implementation does not need to differentiate between unit and
1983        controller commands, the return value from the dl_start_command routine
1984        is not used other than as an indication of success or failure.
1985 */
1986 
start_command(uint32 unit)1987 static t_bool start_command (uint32 unit)
1988 {
1989 if (if_command [unit] == disc_command) {                        /* are we starting a disc command? */
1990     if (dl_start_command (&icd_cntlr [unit], da_unit, unit)) {  /* start the command; was it successful? */
1991         icd_cntlr [unit].length = icd_cntlr [unit].length * 2;  /* convert the return length from words to bytes */
1992         if_state [unit] = next_state [icd_cntlr [unit].opcode]; /* set the next interface state */
1993         }
1994 
1995     else                                                        /* the command was rejected */
1996         if_dsj [unit] = 1;                                      /*   so indicate an error */
1997 
1998     if (if_state [unit] == command_exec)                        /* if the command is executing */
1999         return TRUE;                                            /*   activate the unit */
2000 
2001     else {                                                      /* if we must wait */
2002         da_unit [unit].wait = 0;                                /*   for another secondary, */
2003         return FALSE;                                           /*   then skip the activation */
2004         }
2005     }
2006 
2007 else {                                                          /* all other commands */
2008     if_state [unit] = command_exec;                             /*   execute as soon */
2009     da_unit [unit].wait = icd_cntlr [unit].cmd_time;            /*     as they */
2010     return TRUE;                                                /*       are received */
2011     }
2012 }
2013 
2014 
2015 /* Abort an in-process command.
2016 
2017    A command sequence partially received via the bus must be aborted.  The cause
2018    might be an unknown secondary, an illegal disc command opcode, an improper
2019    secondary sequence (e.g., a Read not followed by Send Read Data), an
2020    incorrect number of parameters, or unaddressing before the sequence was
2021    complete.  In any event, the controller and interface are set to an abort
2022    state, and the DSJ value is set to 1 to indicate an error.
2023 */
2024 
abort_command(uint32 unit,CNTLR_STATUS status,IF_STATE state)2025 static void abort_command (uint32 unit, CNTLR_STATUS status, IF_STATE state)
2026 {
2027 if_command [unit] = invalid;                            /* indicate an invalid command */
2028 if_state [unit] = state;                                /* set the interface state as directed */
2029 if_dsj [unit] = 1;                                      /* set DSJ to indicate an error condition */
2030 dl_end_command (&icd_cntlr [unit], status);             /* place the disc controller into the wait state */
2031 return;
2032 }
2033 
2034 
2035 /* Complete an in-process read command.
2036 
2037    An Untalk terminates a Read, Read Full Sector, Read Without Verify, Read With
2038    Offset, or Cold Load Read command, which must be tied off cleanly by setting
2039    the end-of-data condition and calling the service routine.  This is required
2040    only if the read has not already aborted (e.g., for an auto-seek error).
2041 
2042    If a read is in progress, the controller will be busy, and the interface
2043    state will be either command_exec (if between sectors) or read_xfer (if
2044    within a sector).  We set up the end phase for the command and schedule the
2045    disc service to tidy up.
2046 
2047    If a read has aborted, the controller will be waiting, and the interface
2048    state will be error_source.  In this latter case, we no nothing, as the
2049    controller has already set the required error status.
2050 
2051    We must be careful NOT to trigger on an Untalk that may follow the opcode and
2052    precede the Send Read Data sequence.  In this case, the controller will be
2053    busy, but the interface state will be either read_wait or status_wait.
2054 
2055 
2056    Implementation notes:
2057 
2058     1. The test for controller busy is made before calling this routine.  This
2059        saves the call overhead for the most common case, which is the card is
2060        being unaddressed after command completion.
2061 
2062     2. There is no need to test if we are processing a disc command, as the
2063        controller would not be busy otherwise.
2064 
2065     3. If an auto-seek will be needed to continue the read, but the seek will
2066        fail, then an extra delay is inserted before the service call to start
2067        the next sector.  Once an Untalk is received, this delay is no longer
2068        needed, so it is cancelled before rescheduling the service routine.
2069 */
2070 
complete_read(uint32 unit)2071 static void complete_read (uint32 unit)
2072 {
2073 if ((if_state [unit] == command_exec                        /* is a command executing */
2074   || if_state [unit] == read_xfer)                          /*   or is data transferring */
2075   && (dl_classify (icd_cntlr [unit]) == class_read          /* and the controller is executing */
2076   ||  dl_classify (icd_cntlr [unit]) == class_status)) {    /*    a read or status command? */
2077     icd_cntlr [unit].eod = SET;                             /* set the end of data flag */
2078 
2079     if_state [unit] = command_exec;                         /* set to execute */
2080     da_unit [unit].Phase = end_phase;                       /*   the completion phase */
2081 
2082     sim_cancel (&da_unit [unit]);                           /* cancel the EOT delay */
2083     da_unit [unit].wait = icd_cntlr [unit].data_time;       /* reschedule for completion */
2084     }
2085 
2086 return;
2087 }
2088 
2089 
2090 /* Complete an in-process write command.
2091 
2092    Normally, the host sends a byte tagged with EOI to end a Write, Write Full
2093    Sector, or Initialize command.  However, an Unlisten may terminate a write,
2094    which must be tied off cleanly by setting the end-of-data condition and
2095    calling the service routine.  This is required only if the write has not
2096    already aborted (e.g., for a write-protected disc).
2097 
2098    If a write is in progress, the controller will be busy, and the interface
2099    state will be either command_exec (if between sectors) or write_xfer (if
2100    within a sector).  We set up the end phase for the command and schedule the
2101    disc service to tidy up.
2102 
2103    If a write has aborted, the controller will be waiting, and the interface
2104    state will be error_sink.  In this latter case, we do nothing, as the
2105    controller has already set the required error status.
2106 
2107    We must be careful NOT to trigger on the Unlisten that may follow the opcode
2108    and precede the Receive Write Data sequence.  In this case, the controller
2109    will be busy, but the interface state will be write_wait.
2110 
2111 
2112    Implementation notes:
2113 
2114     1. The test for controller busy is made before calling this routine.  This
2115        saves the call overhead for the most common case, which is the card is
2116        being unaddressed after command completion.
2117 
2118     2. There is no need to test if we are processing a disc command, as the
2119        controller would not be busy otherwise.
2120 */
2121 
complete_write(uint32 unit)2122 static void complete_write (uint32 unit)
2123 {
2124 if ((if_state [unit] == command_exec                    /* is a command executing */
2125   || if_state [unit] == write_xfer)                     /*   or is data transferring */
2126   && dl_classify (icd_cntlr [unit]) == class_write) {   /* and the controller is executing a write? */
2127     icd_cntlr [unit].eod = SET;                         /* set the end of data flag */
2128 
2129     if_state [unit] = command_exec;                     /* set to execute */
2130     da_unit [unit].Phase = end_phase;                   /*   the completion phase */
2131     da_unit [unit].wait = icd_cntlr [unit].data_time;   /* ensure that the controller will finish */
2132     }
2133 
2134 return;
2135 }
2136 
2137 
2138 /* Complete an in-process command abort.
2139 
2140    Errors in the command protocol begin an abort sequence that may involve
2141    sourcing or sinking bytes to allow the sequence to complete as expected by
2142    the CPU.  Unaddressing the unit terminates the aborted command.
2143 
2144    If an abort is in progress, and the interface is not idle, the end-of-data
2145    indication is set, and the disc service routine is called directly to process
2146    the completion of the abort.  The service routine will terminate the
2147    error_source or error_sink state cleanly and then idle the interface.
2148 
2149 
2150    Implementation notes:
2151 
2152     1. The test for an abort-in-progress is made before calling this routine.
2153        This saves the call overhead for the most common case, which is the card
2154        is being unaddressed after normal command completion.
2155 */
2156 
complete_abort(uint32 unit)2157 static void complete_abort (uint32 unit)
2158 {
2159 if (if_state [unit] != idle) {                          /* is the interface busy? */
2160     icd_cntlr [unit].eod = SET;                         /* set the end of data flag */
2161     da_service (&da_unit [unit]);                       /*   and process the abort completion */
2162     }
2163 
2164 return;
2165 }
2166 
2167 
2168 /* Get a byte from the sector buffer.
2169 
2170    The next available byte in the sector buffer is returned to the caller.  The
2171    determination of which byte of the 16-bit buffer word to return is made by
2172    the polarity of the buffer byte count.  The count always begins with an even
2173    number, as it is set by doubling the word count returned from the disc
2174    library.  Therefore, because we decrement the count first, the upper byte is
2175    indicated by an odd count, and the lower byte is indicated by an even count.
2176    The buffer index is incremented only after the lower byte is returned.
2177 */
2178 
get_buffer_byte(CVPTR cvptr)2179 static uint8 get_buffer_byte (CVPTR cvptr)
2180 {
2181 cvptr->length = cvptr->length - 1;                      /* count the byte */
2182 
2183 if (cvptr->length & 1)                                  /* is the upper byte next? */
2184     return UPPER_BYTE (buffer [cvptr->index]);          /* return the byte */
2185 else                                                    /* the lower byte is next */
2186     return LOWER_BYTE (buffer [cvptr->index++]);        /* return the byte and bump the word index */
2187 }
2188 
2189 
2190 /* Put a byte into the sector buffer.
2191 
2192    The supplied byte is stored in the sector buffer.  The determination of which
2193    byte of the 16-bit buffer word to store is made by the polarity of the buffer
2194    byte count.  The count always begins with an even number, as it is set by
2195    doubling the word count returned from the disc library.  Therefore, because
2196    we decrement the count first, the upper byte is indicated by an odd count,
2197    and the lower byte is indicated by an even count.  The buffer index is
2198    incremented only after the lower byte is stored.
2199 */
2200 
put_buffer_byte(CVPTR cvptr,uint8 data)2201 static void put_buffer_byte (CVPTR cvptr, uint8 data)
2202 {
2203 cvptr->length = cvptr->length - 1;                      /* count the byte */
2204 
2205 if (cvptr->length & 1)                                  /* is the upper byte next? */
2206     buffer [cvptr->index] = TO_WORD (data, 0);          /* save the byte */
2207 else                                                    /* the lower byte is next */
2208     buffer [cvptr->index++] |= TO_WORD (0, data);       /* merge the byte and bump the word index */
2209 return;
2210 }
2211 
2212 
2213 /* Activate the unit.
2214 
2215    The specified unit is activated using the unit's "wait" time.  If debugging
2216    is enabled, the activation is logged to the debug file.
2217 */
2218 
activate_unit(UNIT * uptr)2219 static t_stat activate_unit (UNIT *uptr)
2220 {
2221 t_stat result;
2222 
2223 tprintf (da_dev, TRACE_SERV, "Unit %d state %s delay %d service scheduled\n",
2224          uptr - da_unit, if_state_name [if_state [uptr - da_unit]], uptr->wait);
2225 
2226 result = sim_activate (uptr, uptr->wait);               /* activate the unit */
2227 uptr->wait = 0;                                         /* reset the activation time */
2228 
2229 return result;                                          /* return the activation status */
2230 }
2231