1 /* hp2100_di.h: HP 12821A HP-IB Disc Interface simulator definitions
2 
3    Copyright (c) 2010-2012, 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    DI           12821A Disc Interface
27 
28    14-Feb-12    JDB     First release
29    16-Nov-10    JDB     Created DI common definitions file
30 
31 
32    This file defines the interface between HP-IB device simulators and the
33    12821A Disc Interface simulator.  It must be included by the device-specific
34    modules (hp2100_di_da.c, etc.).
35 
36 
37    Implementation notes:
38 
39     1. Three CARD_ID values are defined, corresponding to the Amigo disc (DA),
40        CS/80 disc (DC), and Amigo mag tape (MA) simulators.  At first release,
41        only the DA device is implemented.  However, as the 12821A diagnostic
42        requires two cards to test I/O fully, a dummy DC device is provided by
43        the DA simulator.  It is enabled only when the DA card is configured for
44        diagnostic mode.  This dummy device should be removed when either the DC
45        or MA device is implemented.
46 */
47 
48 
49 
50 /* Program constants */
51 
52 #define FIFO_SIZE       16                              /* FIFO depth */
53 
54 typedef enum {
55     da, dc, ma,                                         /* card IDs */
56     first_card = da,                                    /* first card ID */
57     last_card  = ma,                                    /* last card ID */
58     card_count                                          /* count of card IDs */
59     } CARD_ID;
60 
61 
62 /* Device flags and accessors (bits 7-0 are reserved for disc/tape flags) */
63 
64 #define DEV_V_BUSADR    (DEV_V_UF +  8)                 /* bits 10-8: interface HP-IB address */
65 #define DEV_V_DIAG      (DEV_V_UF + 11)                 /* bit 11: diagnostic mode */
66 #define DEV_V_W1        (DEV_V_UF + 12)                 /* bit 12: DCPC pacing jumper */
67 
68 #define DEV_M_BUSADR    07                              /* bus address mask */
69 
70 #define DEV_BUSADR      (DEV_M_BUSADR << DEV_V_BUSADR)
71 #define DEV_DIAG        (1 << DEV_V_DIAG)
72 #define DEV_W1          (1 << DEV_V_W1)
73 
74 #define GET_DIADR(f)    (((f) >> DEV_V_BUSADR) & DEV_M_BUSADR)
75 #define SET_DIADR(f)    (((f) & DEV_M_BUSADR) << DEV_V_BUSADR)
76 
77 
78 /* Unit flags and accessors (bits 7-0 are reserved for disc/tape flags) */
79 
80 #define UNIT_V_BUSADR   (UNIT_V_UF + 8)                 /* bits 10-8: unit HP-IB address */
81 
82 #define UNIT_M_BUSADR   07                              /* bus address mask */
83 
84 #define UNIT_BUSADR     (UNIT_M_BUSADR << UNIT_V_BUSADR)
85 
86 #define GET_BUSADR(f)   (((f) >> UNIT_V_BUSADR) & UNIT_M_BUSADR)
87 #define SET_BUSADR(f)   (((f) & UNIT_M_BUSADR) << UNIT_V_BUSADR)
88 
89 
90 /* Debug flags */
91 
92 #define DEB_CPU         (1 << 0)                        /* words received from and sent to the CPU */
93 #define DEB_CMDS        (1 << 1)                        /* interface commands received from the CPU */
94 #define DEB_BUF         (1 << 2)                        /* data read from and written to the card FIFO */
95 #define DEB_XFER        (1 << 3)                        /* data received and transmitted via HP-IB */
96 #define DEB_RWSC        (1 << 4)                        /* device read/write/status/control commands */
97 #define DEB_SERV        (1 << 5)                        /* unit service scheduling calls */
98 
99 
100 /* HP-IB control line state bit flags.
101 
102    NOTE that these flags align with the corresponding flags in the DI status
103    register, so don't change the numerical values!
104 */
105 
106 #define BUS_ATN         0001                            /* attention */
107 #define BUS_EOI         0002                            /* end or identify */
108 #define BUS_DAV         0004                            /* data available */
109 #define BUS_NRFD        0010                            /* not ready for data */
110 #define BUS_NDAC        0020                            /* not data accepted */
111 #define BUS_REN         0040                            /* remote enable */
112 #define BUS_IFC         0100                            /* interface clear */
113 #define BUS_SRQ         0200                            /* service request */
114 
115 #define BUS_PPOLL       (BUS_ATN | BUS_EOI)             /* parallel poll */
116 
117 /* HP-IB data */
118 
119 #define BUS_ADDRESS     0037                            /* bus address mask */
120 #define BUS_GROUP       0140                            /* bus group mask */
121 #define BUS_COMMAND     0160                            /* bus command type mask */
122 #define BUS_DATA        0177                            /* bus data mask */
123 #define BUS_PARITY      0200                            /* bus parity mask */
124 
125 #define BUS_PCG         0000                            /* primary command group */
126 #define BUS_LAG         0040                            /* listen address group */
127 #define BUS_TAG         0100                            /* talk address group */
128 #define BUS_SCG         0140                            /* secondary command group */
129 
130 #define BUS_UCG         0020                            /* universal command group */
131 #define BUS_ACG         0000                            /* addressed command group */
132 
133 #define BUS_UNADDRESS   0037                            /* unlisten and untalk addresses */
134 
135 #define PPR(a)          (uint8) (1 << (7 - (a)))        /* parallel poll response */
136 
137 
138 /* Byte accessors */
139 
140 #define BYTE_SHIFT      8                               /* byte shift count */
141 #define UPPER_BYTE      0177400                         /* high-order byte mask */
142 #define LOWER_BYTE      0000377                         /* low-order byte mask */
143 
144 #define GET_UPPER(w)    (uint8) (((w) & UPPER_BYTE) >> BYTE_SHIFT)
145 #define GET_LOWER(w)    (uint8) ((w) & LOWER_BYTE)
146 
147 #define SET_UPPER(b)    ((b) << BYTE_SHIFT)
148 #define SET_LOWER(b)    (b)
149 #define SET_BOTH(b)     (SET_UPPER (b) | SET_LOWER (b))
150 
151 typedef enum {
152     upper,                                              /* upper byte selected */
153     lower                                               /* lower byte selected */
154     } SELECTOR;
155 
156 
157 /* Per-card state variables */
158 
159 typedef struct {
160     FLIP_FLOP control;                                  /* control flip-flop */
161     FLIP_FLOP flag;                                     /* flag flip-flop */
162     FLIP_FLOP flagbuf;                                  /* flag buffer flip-flop */
163     FLIP_FLOP srq;                                      /* SRQ flip-flop */
164     FLIP_FLOP edt;                                      /* EDT flip-flop */
165     FLIP_FLOP eor;                                      /* EOR flip-flop */
166     SELECTOR  ibp;                                      /* input byte pointer selector */
167     SELECTOR  obp;                                      /* output byte pointer selector */
168 
169     uint16    cntl_register;                            /* control word register */
170     uint16    status_register;                          /* status word register */
171     uint16    input_data_register;                      /* input data register */
172 
173     uint32    fifo [FIFO_SIZE];                         /* FIFO buffer */
174     uint32    fifo_count;                               /* FIFO occupancy counter */
175     REG      *fifo_reg;                                 /* FIFO register pointer */
176 
177     uint32    acceptors;                                /* unit bitmap of the bus acceptors */
178     uint32    listeners;                                /* unit bitmap of the bus listeners */
179     uint32    talker;                                   /* unit bitmap of the bus talker */
180 
181     uint8     bus_cntl;                                 /* HP-IB bus control state (ATN, EOI, etc.) */
182     uint8     poll_response;                            /* address bitmap of parallel poll responses */
183 
184     double    ifc_timer;                                /* 100 microsecond IFC timer */
185     } DI_STATE;
186 
187 
188 /* Disc interface VM global register definitions.
189 
190    These definitions should be included before any device-specific registers.
191 
192 
193    Implementation notes:
194 
195     1. The TMR register is included to ensure that the IFC timer is saved by a
196        SAVE command.  It is declared as a hidden, read-only byte array of a size
197        compatible with a double-precision floating-point value, as there is no
198        appropriate macro for the double type.
199 */
200 
201 #define DI_REGS(dev)    \
202     { ORDATA (CWR, di [dev].cntl_register,       16), REG_FIT },                   \
203     { ORDATA (SWR, di [dev].status_register,     16), REG_FIT },                   \
204     { ORDATA (IDR, di [dev].input_data_register, 16), REG_FIT },                   \
205                                                                                    \
206     { DRDATA (FCNT, di [dev].fifo_count, 5) },                                     \
207     { BRDATA (FIFO, di [dev].fifo, 8, 20, FIFO_SIZE), REG_CIRC },                  \
208                                                                                    \
209     { GRDATA (ACPT,   di [dev].acceptors,     2, 4, 0) },                          \
210     { GRDATA (LSTN,   di [dev].listeners,     2, 4, 0) },                          \
211     { GRDATA (TALK,   di [dev].talker,        2, 4, 0) },                          \
212     { GRDATA (PPR,    di [dev].poll_response, 2, 8, 0), REG_FIT },                 \
213     { GRDATA (BUSCTL, di [dev].bus_cntl,      2, 8, 0), REG_FIT },                 \
214                                                                                    \
215     { FLDATA (CTL, di [dev].control, 0) },                                         \
216     { FLDATA (FLG, di [dev].flag,    0) },                                         \
217     { FLDATA (FBF, di [dev].flagbuf, 0) },                                         \
218     { FLDATA (SRQ, di [dev].srq,     0) },                                         \
219     { FLDATA (EDT, di [dev].edt,     0) },                                         \
220     { FLDATA (EOR, di [dev].eor,     0) },                                         \
221                                                                                    \
222     { BRDATA (TMR, &di [dev].ifc_timer, 10, CHAR_BIT, sizeof (double)), REG_HRO }, \
223                                                                                    \
224     { ORDATA (SC, dev##_dib.select_code, 6), REG_HRO }
225 
226 
227 /* Disc interface VM global modifier definitions.
228 
229    These definitions should be included before any device-specific modifiers.
230 */
231 
232 #define DI_MODS(dev)    \
233     { MTAB_XTD | MTAB_VDV,             1, "ADDRESS", "ADDRESS", &di_set_address, &di_show_address, &dev }, \
234                                                                                                            \
235     { MTAB_XTD | MTAB_VDV,             1, NULL,      "DIAG",    &di_set_cable,   NULL,             &dev }, \
236     { MTAB_XTD | MTAB_VDV,             0, NULL,      "HPIB",    &di_set_cable,   NULL,             &dev }, \
237     { MTAB_XTD | MTAB_VDV,             0, "CABLE",   NULL,      NULL,            &di_show_cable,   &dev }, \
238                                                                                                            \
239     { MTAB_XTD | MTAB_VDV,             0, "SC",      "SC",      &hp_setsc,       &hp_showsc,       &dev }, \
240     { MTAB_XTD | MTAB_VDV | MTAB_NMO,  0, "DEVNO",   "DEVNO",   &hp_setdev,      &hp_showdev,      &dev }, \
241                                                                                                            \
242     { MTAB_XTD | MTAB_VUN,             0, "BUS",     "BUS",     &di_set_address, &di_show_address, &dev }
243 
244 
245 /* Disc interface global bus routine definitions */
246 
247 typedef t_bool ACCEPTOR  (uint32  unit, uint8  data);
248 typedef void   RESPONDER (CARD_ID card, uint32 unit, uint8 new_cntl);
249 
250 
251 /* Disc interface global variables */
252 
253 extern DI_STATE di [];
254 extern DEBTAB   di_deb [];
255 
256 
257 /* Disc interface global VM routines */
258 
259 extern IOHANDLER di_io;
260 extern t_stat    di_reset (DEVICE *dptr);
261 
262 /* Disc interface global SCP routines */
263 
264 extern t_stat di_set_address  (UNIT *uptr, int32 value, char  *cptr, void *desc);
265 extern t_stat di_show_address (FILE *st,   UNIT  *uptr, int32 value, void *desc);
266 extern t_stat di_set_cable    (UNIT *uptr, int32 value, char  *cptr, void *desc);
267 extern t_stat di_show_cable   (FILE *st,   UNIT  *uptr, int32 value, void *desc);
268 
269 /* Disc interface global bus routines */
270 
271 extern t_bool di_bus_source    (CARD_ID card, uint8  data);
272 extern void   di_bus_control   (CARD_ID card, uint32 unit, uint8 assert, uint8 deny);
273 extern void   di_poll_response (CARD_ID card, uint32 unit, FLIP_FLOP response);
274 
275 
276 /* Amigo disc global VM routines */
277 
278 extern t_stat da_service (UNIT  *uptr);
279 extern t_stat da_boot    (int32 unitno, DEVICE *dptr);
280 
281 /* Amigo disc global bus routines */
282 
283 extern ACCEPTOR  da_bus_accept;
284 extern RESPONDER da_bus_respond;
285 
286 
287 /* Amigo mag tape global VM routines */
288 
289 extern t_stat ma_service (UNIT  *uptr);
290 extern t_stat ma_boot    (int32 unitno, DEVICE *dptr);
291 
292 /* Amigo mag tape global SCP routines */
293 
294 extern t_stat ma_set_timing  (UNIT *uptr, int32 val,   char  *cptr, void *desc);
295 extern t_stat ma_show_timing (FILE *st,   UNIT  *uptr, int32 val,   void *desc);
296 
297 /* Amigo mag tape global bus routines */
298 
299 extern ACCEPTOR  ma_bus_accept;
300 extern RESPONDER ma_bus_respond;
301