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