First Commit of my working state
[simh.git] / HP2100 / hp2100_baci.c
1 /* hp2100_baci.c: HP 12966A buffered asynchronous communications interface simulator
2
3 Copyright (c) 2007-2008, 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 BACI 12966A BACI card
27
28 13-Jun-08 JDB Cleaned up debug reporting for sim_activate calls
29 16-Apr-08 JDB Separated terminal I/O and Telnet poll for idle compatibility
30 07-Dec-07 JDB Created BACI device
31
32 References:
33 - HP 12966A Buffered Asynchronous Data Communications Interface Installation
34 and Reference Manual (12966-90001, Jul-1982)
35 - Western Digital Communications Products Handbook (Jun-1984)
36
37
38 The 12966A BACI card supplanted the 12531C Teletype and 12880A CRT interfaces
39 as the primary terminal connection for HP 1000 systems. The main advantage
40 of this card over the others was its 128-character FIFO memory. While this
41 allowed more efficient I/O than its interrupt-per-character predecessors, the
42 most significant advantage was that block input from the 264x-series of CRT
43 terminals was supported. The 264x were the first HP-supported terminals to
44 provide local editing and character storage, as well as mass storage via dual
45 DC-100 minicartridge drives. This support meant that input from the terminal
46 could come in bursts at the full baud rate, which would overrun the older
47 cards that needed a small intercharacter handling time. Also, the older
48 cards placed a substantial load on the CPU in high-baud-rate output
49 applications. Indeed, block output under RTE on a 1000 M-Series with a
50 12880A CRT card would saturate the CPU at about 5700 baud.
51
52 For a while, the BACI and the earlier cards were both supported as the system
53 console interface, and RTE primary systems were generated with drivers for
54 both cards. The boot-time I/O reconfigurator would detect the presence of
55 the BACI card and would dynamically select the correct driver (DVR05 vs.
56 DVR00). However, the 12880A card faded quickly as the 264x and later 262x
57 terminals gained in popularity, and support for the 12880A was dropped in
58 favor of the BACI. This meant that later RTE primary systems could only be
59 run on CPUs containing a BACI card.
60
61 The simulation supports terminal and diagnostic modes. The latter simulates
62 the installation of the 12966-60003 diagnostic loopback connector on the
63 card.
64
65 Fifteen programmable baud rates were supported by the BACI. We simulate
66 these "realistic" rates by scheduling I/O service based on the appropriate
67 number of 1000 E-Series instructions for the rate selected. We also provide
68 an "external rate" that is equivalent to 9600 baud, as most terminals were
69 set to their maximum speeds.
70
71 We support the 12966A connected to an HP terminal emulator via Telnet.
72 Internally, we model the BACI as a terminal multiplexer with one line. The
73 simulation is complicated by the half-duplex nature of the card (there is
74 only one FIFO, used selectively either for transmission or reception) and the
75 double-buffered UART (a Western Digital TR1863A), which has holding registers
76 as well as a shift registers for transmission and reception. We model both
77 sets of device registers.
78
79 During an output operation, the first character output to the card passes
80 through the FIFO and into the transmitter holding register. Subsequent
81 characters remain in the FIFO. If the FIFO is then turned around by a mode
82 switch from transmission to reception, the second character output becomes
83 the first character input to the CPU, as the first character output remains
84 in the THR. Also, the FIFO counter reflects the combined state of the FIFO
85 and the THR: it is incremented by a "shift in" to the FIFO and decremented by
86 the "transmit complete" signal from the UART. This has two implications:
87
88 1. If the FIFO is turned around before the character in the THR is
89 transmitted, the counter will not decrement when transmission is
90 complete, so the FIFO will show as "empty" when the counter reads "1".
91
92 2. The FIFO counter will indicate "half full" and "full" one character
93 before the FIFO itself reaches those stages.
94
95 The diagnostic hood connects the UART clock to a spare output register. This
96 allows the diagnostic to supply programmed clock pulses to the UART. The
97 serial transmit and receive lines from the UART are also available to the
98 diagnostic. Functional operation is checked by supplying or testing serial
99 data while clocking the UART sixteen times for each bit. This meant that we
100 had to model the UART shift registers for faithful hardware simulation.
101
102 The simulation provides both the "realistic timing" described above, as well
103 as an "optimized (fast) timing" option. Optimization makes three
104 improvements:
105
106 1. On output, characters in the FIFO are emptied into the Telnet buffer as a
107 block, rather than one character per service call, and on input, all of
108 the characters available in the Telnet buffer are loaded into the FIFO as
109 a block.
110
111 2. The ENQ/ACK handshake is done locally, without involving the Telnet
112 client.
113
114 3. Input occurring during an output operation is delayed until the second or
115 third consecutive ENQ/ACK handshake.
116
117 During development, it was noted that a comparatively long time elapsed
118 (approximately 30 milliseconds on a 3 GHz system) between the transmission of
119 an ENQ and the reception of the ACK. As the RTE BACI driver, DVR05, does
120 three ENQ/ACKs at the end of each line, plus an additional ENQ/ACK every 33
121 characters within a line, maximum throughput was about ten lines per second.
122 The source of this delay is not understood but apparently lies within the
123 terminal emulator, as it was observed with two emulators from two different
124 companies. Absorbing the ENQ and generating the ACK locally provided a
125 dramatic improvement in output speed.
126
127 However, as a result, RTE break-mode became effectively impossible, i.e.,
128 striking a key during output no longer produced the break-mode prompt. This
129 was traced to the RTE driver. DVR05 only checks for an input character
130 during ENQ/ACK processing, and then only during the second and third
131 end-of-line handshakes. When the ENQ/ACKs were eliminated, break-mode also
132 disappeared.
133
134 The workaround is to save a character received during output and supply it
135 during the second or third consecutive handshake. This ensures that
136 break-mode is recognized. Because the driver tries to "cheat" the card by
137 selecting receive mode before the ENQ has actually been transmitted (in order
138 to save an interrupt), the FIFO counter becomes "off by one" and is reset
139 with a master clear at the end of each handshake. This would normally clear
140 the UART receiving register, thereby losing the deferred character. We work
141 around this by skipping the register clear in "fast timing" mode.
142 */
143
144 #include <ctype.h>
145
146 #include "hp2100_defs.h"
147 #include "sim_sock.h"
148 #include "sim_tmxr.h"
149
150
151 /* Program limits */
152
153 #define FIFO_SIZE 128 /* read/write buffer size */
154
155
156 /* Character constants */
157
158 #define ENQ '\005'
159 #define ACK '\006'
160
161
162 /* Unit flags */
163
164 #define UNIT_V_DIAG (UNIT_V_UF + 0) /* diagnostic mode */
165 #define UNIT_V_FASTTIME (UNIT_V_UF + 1) /* fast timing mode */
166 #define UNIT_V_CAPSLOCK (UNIT_V_UF + 2) /* caps lock mode */
167
168 #define UNIT_DIAG (1 << UNIT_V_DIAG)
169 #define UNIT_FASTTIME (1 << UNIT_V_FASTTIME)
170 #define UNIT_CAPSLOCK (1 << UNIT_V_CAPSLOCK)
171
172
173 /* Debug flags */
174
175 #define DEB_CMDS (1 << 0) /* commands and status */
176 #define DEB_CPU (1 << 1) /* CPU I/O */
177 #define DEB_BUF (1 << 2) /* buffer gets and puts */
178 #define DEB_XFER (1 << 3) /* character reads and writes */
179
180
181 /* Bit flags */
182
183 #define OUT_MR 0100000 /* common master reset */
184
185 #define OUT_ENCM 0000040 /* ID1: enable character mode */
186 #define OUT_ENCB 0000020 /* ID1: enable CB */
187 #define OUT_ENCC 0000010 /* ID1: enable CC */
188 #define OUT_ENCE 0000004 /* ID1: enable CE */
189 #define OUT_ENCF 0000002 /* ID1: enable CF */
190 #define OUT_ENSXX 0000001 /* ID1: enable SBB/SCF */
191
192 #define OUT_DIAG 0000040 /* ID2: diagnostic output */
193 #define OUT_REFCB 0000020 /* ID2: reference CB */
194 #define OUT_REFCC 0000010 /* ID2: reference CC */
195 #define OUT_REFCE 0000004 /* ID2: reference CE */
196 #define OUT_REFCF 0000002 /* ID2: reference CF */
197 #define OUT_REFSXX 0000001 /* ID2: reference SBB/SCF */
198
199 #define OUT_STBITS 0000040 /* ID3: number of stop bits */
200 #define OUT_ECHO 0000020 /* ID3: enable echo */
201 #define OUT_PARITY 0000010 /* ID3: enable parity */
202 #define OUT_PAREVEN 0000004 /* ID3: even parity or odd */
203
204 #define OUT_XMIT 0000400 /* ID4: transmit or receive */
205 #define OUT_CA 0000200 /* ID4: CA on */
206 #define OUT_CD 0000100 /* ID4: CD on */
207 #define OUT_SXX 0000040 /* ID4: SBA/SCA on */
208 #define OUT_DCPC 0000020 /* ID4: DCPC on */
209
210 #define OUT_CSC 0000040 /* ID5: clear special char interrupt */
211 #define OUT_CBH 0000020 /* ID5: clear buffer half-full interrupt */
212 #define OUT_CBF 0000010 /* ID5: clear buffer full interrupt */
213 #define OUT_CBE 0000004 /* ID5: clear buffer empty interrupt */
214 #define OUT_CBRK 0000002 /* ID5: clear break interrupt */
215 #define OUT_COVR 0000001 /* ID5: clear overrun/parity interrupt */
216
217 #define OUT_SPFLAG 0000400 /* ID6: special character */
218
219 #define OUT_IRQCLR (OUT_CBH | OUT_CBF | OUT_CBE | OUT_CBRK | OUT_COVR)
220
221
222 #define IN_VALID 0100000 /* received data: character valid */
223 #define IN_SPFLAG 0040000 /* received data: is special character */
224
225 #define IN_DEVINT 0100000 /* status: device interrupt */
226 #define IN_SPCHAR 0040000 /* status: special char has been recd */
227 #define IN_SPARE 0010000 /* status: spare receiver state */
228 #define IN_TEST 0004000 /* status: unprocessed serial data line */
229 #define IN_BUFHALF 0001000 /* status: buffer is half full */
230 #define IN_BUFFULL 0000400 /* status: buffer is full */
231 #define IN_BUFEMPTY 0000200 /* status: buffer is empty */
232 #define IN_BREAK 0000100 /* status: break detected */
233 #define IN_OVRUNPE 0000040 /* status: overrun or parity error */
234 #define IN_CB 0000020 /* status: CB is on */
235 #define IN_CC 0000010 /* status: CC is on */
236 #define IN_CE 0000004 /* status: CE is on */
237 #define IN_CF 0000002 /* status: CF is on */
238 #define IN_SXX 0000001 /* status: SBB/SCF is on */
239
240 #define IN_MODEM (IN_CB | IN_CC | IN_CE | IN_CF | IN_SXX)
241 #define IN_LOOPBACK (IN_DEVINT | IN_SPARE | IN_TEST | IN_MODEM)
242 #define IN_STDIRQ (IN_DEVINT | IN_SPCHAR | IN_BREAK | IN_OVRUNPE)
243 #define IN_FIFOIRQ (IN_BUFEMPTY | IN_BUFHALF | IN_BUFFULL)
244
245
246 /* Packed starting bit numbers */
247
248 #define OUT_V_ID 12 /* common output word ID */
249 #define OUT_V_DATA 0 /* ID 0: output data character */
250 #define OUT_V_CHARSIZE 0 /* ID 3: character size */
251 #define OUT_V_BAUDRATE 0 /* ID 4: baud rate */
252 #define OUT_V_SPCHAR 0 /* ID 6: special character */
253
254 #define IN_V_CHARCNT 8 /* data: char count in buffer */
255 #define IN_V_DATA 0 /* data: input character */
256 #define IN_V_IRQCLR 5 /* status: interrupt status clear */
257
258
259 /* Packed bit widths */
260
261 #define OUT_W_ID 3
262 #define OUT_W_DATA 8
263 #define OUT_W_CHARSIZE 2
264 #define OUT_W_BAUDRATE 4
265 #define OUT_W_SPCHAR 8
266
267 #define IN_W_CHARCNT 6
268 #define IN_W_DATA 8
269
270 /* Packed bit masks */
271
272 #define OUT_M_ID ((1 << OUT_W_ID) - 1)
273 #define OUT_M_DATA ((1 << OUT_W_DATA) - 1)
274 #define OUT_M_CHARSIZE ((1 << OUT_W_CHARSIZE) - 1)
275 #define OUT_M_BAUDRATE ((1 << OUT_W_BAUDRATE) - 1)
276 #define OUT_M_SPCHAR ((1 << OUT_W_SPCHAR) - 1)
277
278 #define IN_M_CHARCNT ((1 << IN_W_CHARCNT) - 1)
279 #define IN_M_DATA ((1 << IN_W_DATA) - 1)
280
281 /* Packed field masks */
282
283 #define OUT_ID (OUT_M_ID << OUT_V_ID)
284 #define OUT_DATA (OUT_M_DATA << OUT_V_DATA)
285 #define OUT_CHARSIZE (OUT_M_CHARSIZE << OUT_V_CHARSIZE)
286 #define OUT_BAUDRATE (OUT_M_BAUDRATE << OUT_V_BAUDRATE)
287 #define OUT_SPCHAR (OUT_M_SPCHAR << OUT_V_SPCHAR)
288
289 #define IN_CHARCNT (IN_M_CHARCNT << IN_V_CHARCNT)
290 #define IN_DATA (IN_M_DATA << IN_V_DATA)
291
292
293 /* Command helpers */
294
295 #define TO_CHARCNT(c) (((c) << IN_V_CHARCNT) & IN_CHARCNT)
296
297 #define GET_ID(i) (((i) & OUT_ID) >> OUT_V_ID)
298 #define GET_BAUDRATE(b) (((b) & OUT_BAUDRATE) >> OUT_V_BAUDRATE)
299
300 #define IO_MODE (baci_icw & OUT_XMIT)
301 #define XMIT OUT_XMIT
302 #define RECV 0
303
304 #define CLEAR_HR 0 /* UART holding register clear value */
305 #define CLEAR_R -1 /* UART register clear value */
306
307
308 /* Unit references */
309
310 #define baci_term baci_unit[0] /* terminal I/O unit */
311 #define baci_poll baci_unit[1] /* Telnet polling unit */
312
313
314 /* External variables */
315
316 extern uint32 PC;
317 extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2], dev_srq[2];
318 extern FILE *sim_deb;
319
320
321 /* BACI state variables */
322
323 uint16 baci_ibuf = 0; /* status/data in */
324 uint16 baci_obuf = 0; /* command/data out */
325 uint16 baci_status = 0; /* current status */
326
327 uint16 baci_edsiw = 0; /* enable device status word */
328 uint16 baci_dsrw = 0; /* device status reference word */
329 uint16 baci_cfcw = 0; /* character frame control word */
330 uint16 baci_icw = 0; /* interface control word */
331 uint16 baci_isrw = 0; /* interrupt status reset word */
332
333 uint32 baci_fput = 0; /* FIFO buffer add index */
334 uint32 baci_fget = 0; /* FIFO buffer remove index */
335 uint32 baci_fcount = 0; /* FIFO buffer counter */
336 uint32 baci_bcount = 0; /* break counter */
337
338 uint8 baci_fifo [FIFO_SIZE]; /* read/write buffer FIFO */
339 uint8 baci_spchar [256]; /* special character RAM */
340
341 uint16 baci_uart_thr = CLEAR_HR; /* UART transmitter holding register */
342 uint16 baci_uart_rhr = CLEAR_HR; /* UART receiver holding register */
343 int32 baci_uart_tr = CLEAR_R; /* UART transmitter register */
344 int32 baci_uart_rr = CLEAR_R; /* UART receiver register */
345 uint32 baci_uart_clk = 0; /* UART transmit/receive clock */
346
347 t_bool baci_enq_seen = FALSE; /* ENQ seen flag */
348 uint32 baci_enq_cntr = 0; /* ENQ seen counter */
349
350
351 /* Terminal multiplexer library interface */
352
353 TMLN baci_ldsc = { 0 }; /* line descriptor */
354 TMXR baci_desc = { 1, 0, 0, &baci_ldsc }; /* device descriptor */
355
356
357 /* BACI local routines */
358
359 static int32 service_time (uint32 control_word);
360 static const char *fmt_char (uint8 ch);
361 static void update_status (void);
362 static void master_reset (uint32 selcode);
363
364 static uint32 fifo_get (void);
365 static void fifo_put (uint8 ch);
366 static void clock_uart (void);
367
368 /* BACI global routines */
369
370 int32 baci_io (int32 inst, int32 IR, int32 dat);
371 t_stat baci_term_svc (UNIT *uptr);
372 t_stat baci_poll_svc (UNIT *uptr);
373 t_stat baci_reset (DEVICE *dptr);
374 t_stat baci_attach (UNIT *uptr, char *cptr);
375 t_stat baci_detach (UNIT *uptr);
376 t_stat baci_show (FILE *st, UNIT *uptr, int32 val, void *desc);
377
378
379 /* BACI data structures
380
381 baci_dib BACI device information block
382 baci_dev BACI device descriptor
383 baci_unit BACI unit list
384 baci_reg BACI register list
385 baci_mod BACI modifier list
386 baci_deb BACI debug list
387
388 Two units are used: one to handle character I/O via the Telnet library, and
389 another to poll for connections and input. The character I/O service routine
390 runs only when there are characters to read or write. It operates at the
391 approximate baud rate of the terminal (in CPU instructions per second) in
392 order to be compatible with the OS drivers. The Telnet poll must run
393 continuously, but it can operate much more slowly, as the only requirement is
394 that it must not present a perceptible lag to human input. To be compatible
395 with CPU idling, it is co-scheduled with the master poll timer, which uses a
396 ten millisecond period.
397 */
398
399 DIB baci_dib = { BACI, 0, 0, 0, 0, 0, &baci_io };
400
401 DEVICE baci_dev;
402
403 UNIT baci_unit[] =
404 { { UDATA (&baci_term_svc, UNIT_ATTABLE | UNIT_FASTTIME, 0) }, /* terminal I/O unit */
405 { UDATA (&baci_poll_svc, UNIT_DIS, POLL_WAIT) } }; /* Telnet poll unit */
406
407 REG baci_reg[] = {
408 { ORDATA (IBUF, baci_ibuf, 16) },
409 { ORDATA (OBUF, baci_obuf, 16) },
410 { ORDATA (STATUS, baci_status, 16) },
411
412 { ORDATA (EDSIW, baci_edsiw, 16) },
413 { ORDATA (DSRW, baci_dsrw, 16) },
414 { ORDATA (CFCW, baci_cfcw, 16) },
415 { ORDATA (ICW, baci_icw, 16) },
416 { ORDATA (ISRW, baci_isrw, 16) },
417
418 { DRDATA (FIFOPUT, baci_fput, 8) },
419 { DRDATA (FIFOGET, baci_fget, 8) },
420 { DRDATA (FIFOCNTR, baci_fcount, 8) },
421 { DRDATA (BRKCNTR, baci_bcount, 16) },
422
423 { BRDATA (FIFO, baci_fifo, 8, 8, FIFO_SIZE) },
424 { BRDATA (SPCHAR, baci_spchar, 8, 1, 256) },
425
426 { ORDATA (UARTTHR, baci_uart_thr, 16) },
427 { ORDATA (UARTTR, baci_uart_tr, 16), REG_NZ },
428 { ORDATA (UARTRHR, baci_uart_rhr, 16) },
429 { ORDATA (UARTRR, baci_uart_rr, 16), REG_NZ },
430 { DRDATA (UARTCLK, baci_uart_clk, 16) },
431
432 { DRDATA (CTIME, baci_term.wait, 19), REG_RO },
433
434 { FLDATA (ENQFLAG, baci_enq_seen, 0), REG_HRO },
435 { DRDATA (ENQCNTR, baci_enq_cntr, 16), REG_HRO },
436
437 { FLDATA (LKO, baci_dib.cmd, 0) },
438 { FLDATA (CTL, baci_dib.ctl, 0) },
439 { FLDATA (FLG, baci_dib.flg, 0) },
440 { FLDATA (FBF, baci_dib.fbf, 0) },
441 { FLDATA (SRQ, baci_dib.srq, 0) },
442 { ORDATA (DEVNO, baci_dib.devno, 6), REG_HRO },
443 { NULL }
444 };
445
446 MTAB baci_mod[] = {
447 { UNIT_DIAG, UNIT_DIAG, "diagnostic mode", "DIAG", NULL, NULL, NULL },
448 { UNIT_DIAG, 0, "terminal mode", "TERMINAL", NULL, NULL, NULL },
449
450 { UNIT_FASTTIME, UNIT_FASTTIME, "fast timing", "FASTTIME", NULL, NULL, NULL },
451 { UNIT_FASTTIME, 0, "realistic timing", "REALTIME", NULL, NULL, NULL },
452
453 { UNIT_CAPSLOCK, UNIT_CAPSLOCK, "CAPS LOCK down", "CAPSLOCK", NULL, NULL, NULL },
454 { UNIT_CAPSLOCK, 0, "CAPS LOCK up", "NOCAPSLOCK", NULL, NULL, NULL },
455
456 { MTAB_XTD | MTAB_VDV | MTAB_NC, 0, "LOG", "LOG", &tmxr_set_log, &tmxr_show_log, &baci_desc },
457 { MTAB_XTD | MTAB_VDV | MTAB_NC, 0, NULL, "NOLOG", &tmxr_set_nolog, NULL, &baci_desc },
458
459 { MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTION", NULL, NULL, &baci_show, NULL },
460 { MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATISTICS", NULL, NULL, &baci_show, NULL },
461 { MTAB_XTD | MTAB_VDV, 0, NULL, "DISCONNECT", &tmxr_dscln, NULL, &baci_desc },
462
463 { MTAB_XTD | MTAB_VDV, 0, "DEVNO", "DEVNO", &hp_setdev, &hp_showdev, &baci_dev },
464 { 0 }
465 };
466
467 DEBTAB baci_deb[] = {
468 { "CMDS", DEB_CMDS },
469 { "CPU", DEB_CPU },
470 { "BUF", DEB_BUF },
471 { "XFER", DEB_XFER },
472 { NULL, 0 }
473 };
474
475 DEVICE baci_dev = {
476 "BACI", /* device name */
477 baci_unit, /* unit array */
478 baci_reg, /* register array */
479 baci_mod, /* modifier array */
480 2, /* number of units */
481 10, /* address radix */
482 31, /* address width */
483 1, /* address increment */
484 8, /* data radix */
485 8, /* data width */
486 &tmxr_ex, /* examine routine */
487 &tmxr_dep, /* deposit routine */
488 &baci_reset, /* reset routine */
489 NULL, /* boot routine */
490 &baci_attach, /* attach routine */
491 &baci_detach, /* detach routine */
492 &baci_dib, /* device information block */
493 DEV_NET | DEV_DEBUG | DEV_DISABLE, /* device flags */
494 0, /* debug control flags */
495 baci_deb, /* debug flag name table */
496 NULL, /* memory size change routine */
497 NULL }; /* logical device name */
498
499
500
501 /* I/O instruction processor.
502
503 The BACI processes seven types of output words and supplies two types of
504 input words. Output word type is identified by an ID code in bits 14-12.
505 Input word type is determined by the state of the control flip-flop.
506
507 The card has the usual control, flag buffer, flag, and SRQ flip-flops.
508 However, they have the following unusual characteristics:
509
510 - STC is not required to transfer a character.
511 - Flag is not set after character transfer completes.
512 - FLAG and SRQ are decoupled.
513
514 An interrupt lockout flip-flop is used to prevent the generation of multiple
515 interrupts until the cause of the first interrupt is identified and cleared.
516 CMD is used to model the lockout flip-flop.
517 */
518
519 int32 baci_io (int32 inst, int32 IR, int32 dat)
520 {
521 uint8 ch;
522 uint32 mask;
523 uint32 dev = IR & I_DEVMASK;
524
525 switch (inst) { /* dispatch by instruction */
526
527 case ioFLG: /* set or clear flag */
528 if ((IR & I_HC) == 0) { /* STF? */
529 setFSR (dev); /* set flag, flag buffer, and SRQ */
530 setCMD (dev); /* set lockout */
531
532 if (DEBUG_PRI (baci_dev, DEB_CMDS))
533 fputs (">>BACI cmds: [STF] Flag, SRQ, and lockout set\n", sim_deb);
534 }
535 break; /* CLF handled by H/C below */
536
537
538 case ioSFC: /* skip if flag clear */
539 if (FLG (dev) == 0) /* flag clear? */
540 PC = (PC + 1) & VAMASK; /* skip next instruction */
541 break;
542
543
544 case ioSFS: /* skip if flag set */
545 if (FLG (dev) != 0) /* flag set? */
546 PC = (PC + 1) & VAMASK; /* skip next instruction */
547 break;
548
549
550 case ioCRS: /* control reset */
551 master_reset (dev); /* issue master reset */
552
553 if (DEBUG_PRI (baci_dev, DEB_CMDS))
554 fputs (">>BACI cmds: [CRS] Master reset\n", sim_deb);
555 break;
556
557
558 case ioOTX: /* output word */
559 if (DEBUG_PRI (baci_dev, DEB_CPU))
560 fprintf (sim_deb, ">>BACI cpu: [OTx] Command = %06o\n", dat);
561
562 baci_obuf = dat;
563
564 if (baci_obuf & OUT_MR) { /* master reset? */
565 master_reset (dev); /* do before processing */
566
567 if (DEBUG_PRI (baci_dev, DEB_CMDS))
568 fputs (">>BACI cmds: [OTx] Master reset\n", sim_deb);
569 }
570
571 switch (GET_ID (baci_obuf)) { /* isolate ID code */
572
573 case 0: /* transmit data */
574 if (IO_MODE == XMIT) { /* transmitting? */
575 ch = baci_obuf & OUT_DATA; /* mask to character */
576 fifo_put (ch); /* queue character */
577
578 if (baci_term.flags & UNIT_ATT) { /* attached to network? */
579 if (DEBUG_PRI (baci_dev, DEB_CMDS) && /* debugging? */
580 (sim_is_active (&baci_term) == 0)) /* service stopped? */
581 fprintf (sim_deb, ">>BACI cmds: [OTx] Terminal service scheduled, "
582 "time = %d\n", baci_term.wait);
583
584 if (baci_fcount == 1) /* first char to xmit? */
585 sim_activate_abs (&baci_term, /* start service with full char time */
586 baci_term.wait);
587 else
588 sim_activate (&baci_term, /* start service if not running */
589 baci_term.wait);
590 }
591 }
592 break;
593
594 case 1: /* enable device status interrupt */
595 baci_edsiw = baci_obuf; /* load new enable word */
596 update_status (); /* may have enabled an interrupt */
597 break;
598
599 case 2: /* device status reference */
600 if ((baci_term.flags & UNIT_DIAG) && /* diagnostic mode? */
601 (baci_dsrw & OUT_DIAG) && /* and last DIAG was high? */
602 !(baci_obuf & OUT_DIAG) && /* and new DIAG is low? */
603 !(baci_icw & OUT_BAUDRATE)) /* and clock is external? */
604 clock_uart (); /* pulse UART clock */
605
606 baci_dsrw = baci_obuf; /* load new reference word */
607 update_status (); /* clocking UART may interrupt */
608 break;
609
610 case 3: /* character frame control */
611 baci_cfcw = baci_obuf; /* load new frame word */
612 break;
613
614 case 4: /* interface control */
615 if ((baci_icw ^ baci_obuf) & OUT_BAUDRATE) { /* baud rate change? */
616 baci_term.wait = service_time (baci_obuf); /* set service time to match rate */
617
618 if (baci_term.flags & UNIT_DIAG) /* diagnostic mode? */
619 if (baci_obuf & OUT_BAUDRATE) { /* internal baud rate requested? */
620 sim_activate (&baci_term, /* activate I/O service */
621 baci_term.wait);
622
623 if (DEBUG_PRI (baci_dev, DEB_CMDS))
624 fprintf (sim_deb, ">>BACI cmds: [OTx] Terminal service scheduled, "
625 "time = %d\n", baci_term.wait);
626 }
627
628 else { /* external rate */
629 sim_cancel (&baci_term); /* stop I/O service */
630
631 if (DEBUG_PRI (baci_dev, DEB_CMDS))
632 fputs (">>BACI cmds: [OTx] Terminal service stopped\n", sim_deb);
633 }
634 }
635
636 baci_icw = baci_obuf; /* load new reference word */
637 update_status (); /* loopback may change status */
638 break;
639
640 case 5: /* interrupt status reset */
641 baci_isrw = baci_obuf; /* load new reset word */
642
643 mask = (baci_isrw & OUT_IRQCLR) << /* form reset mask */
644 IN_V_IRQCLR; /* for common irqs */
645
646 if (baci_isrw & OUT_CSC) /* add special char mask bit */
647 mask = mask | IN_SPCHAR; /* if requested */
648
649 baci_status = baci_status & ~mask; /* clear specified status bits */
650 break;
651
652 case 6: /* special character */
653 baci_spchar [baci_obuf & OUT_SPCHAR] = /* set special character entry */
654 ((baci_obuf & OUT_SPFLAG) != 0);
655 break;
656 }
657
658 break;
659
660
661 case ioLIX: /* load word */
662 dat = 0;
663
664 case ioMIX: /* merge word */
665 if (CTL (dev)) { /* control set? */
666 baci_ibuf = TO_CHARCNT (baci_fcount); /* get FIFO count */
667
668 if (IO_MODE == RECV) /* receiving? */
669 baci_ibuf = baci_ibuf | fifo_get (); /* add char and validity flag */
670
671 dat = dat | baci_ibuf; /* return received data */
672
673 if (DEBUG_PRI (baci_dev, DEB_CPU))
674 fprintf (sim_deb, ">>BACI cpu: [LIx] Received data = %06o\n", dat);
675 }
676
677 else { /* control clear? */
678 dat = dat | baci_status; /* return status */
679
680 if (DEBUG_PRI (baci_dev, DEB_CPU))
681 fprintf (sim_deb, ">>BACI cpu: [LIx] Status = %06o\n", dat);
682 }
683 break;
684
685
686 case ioCTL: /* control set/clear */
687 if (IR & I_CTL) { /* CLC */
688 clrCTL (dev); /* clear control */
689
690 if (DEBUG_PRI (baci_dev, DEB_CMDS))
691 fputs (">>BACI cmds: [CLC] Control cleared\n", sim_deb);
692 }
693
694 else { /* STC */
695 setCTL (dev); /* set control */
696 clrCMD (dev); /* clear lockout */
697
698 if (DEBUG_PRI (baci_dev, DEB_CMDS))
699 fputs (">>BACI cmds: [STC] Control set and lockout cleared\n", sim_deb);
700
701 update_status (); /* clearing lockout might interrupt */
702 }
703 break;
704
705
706 default: /* all others */
707 break; /* do nothing */
708 }
709
710
711 if (IR & I_HC) { /* H/C option */
712 clrFSR (dev); /* clear flag and SRQ */
713
714 if (DEBUG_PRI (baci_dev, DEB_CMDS))
715 fprintf (sim_deb, ">>BACI cmds: [%s] Flag and SRQ cleared\n",
716 (inst == ioFLG ? "CLF" : "x,C"));
717
718 update_status (); /* FLG might set when SRQ clears */
719 }
720
721 return dat;
722 }
723
724
725 /* BACI terminal service.
726
727 The terminal service routine is used to transmit and receive characters.
728
729 In terminal mode, it is started when a character is ready for output or when
730 the Telnet poll routine determines that there are characters ready for input
731 and stopped when there are no more characters to output or input. When the
732 terminal is quiescent, this routine does not run.
733
734 In diagnostic mode, it is started whenever an internal baud rate is set and
735 stopped when the external clock is requested. In this mode, the routine will
736 be called without an attached socket, so character I/O will be skipped.
737
738 Because there is only one FIFO, the card is half-duplex and must be
739 configured for transmit or receive mode. The UART, though, is double-
740 buffered, so it may transmit and receive simultaneously. We implement both
741 the UART shift and holding registers for each mode.
742
743 If a character is received by the UART while the card is in transmit mode, it
744 will remain in the receiver holding register (RHR). When the mode is
745 reversed, the RHR contents will be unloaded into the FIFO. Conversely,
746 transmit mode enables the output of the FIFO to be unloaded into the
747 transmitter holding register (THR). Characters received or transmitted pass
748 through the receiver register (RR) or transmitter register (TR),
749 respectively. They are not strictly necessary in terminal (Telnet)
750 transactions but are critical to diagnostic operations.
751
752 The UART signals an overrun if a complete character is received while the RHR
753 still contains the previous character. The BACI does not use this signal,
754 though; an overrun is only indicated if the FIFO is full, and another
755 character is received.
756
757 In "fast timing" mode, we defer the recognition of a received character until
758 the card is put into receive mode for the second or third consecutive ENQ/ACK
759 handshake. This improves RTE break-mode recognition. "Realistic timing"
760 mode behaves as the hardware does: a character present in the RHR is unloaded
761 into the FIFO as soon as receive mode is set.
762
763 Fast timing mode also enables internal ENQ/ACK handshaking. We allow one
764 character time for the RTE driver to turn the card around, as otherwise the
765 ACK may not be seen by the driver. Also, the local ACK is supplied after any
766 received characters, as the driver detects operator attention only when the
767 first character after an ENQ is not an ACK.
768
769 Finally, fast timing enables buffer combining. For output, all characters
770 present in the FIFO are unloaded into the Telnet buffer before initiating a
771 packet send. For input, all characters present in the Telnet buffer are
772 loaded into the FIFO. This reduces network traffic and decreases simulator
773 overhead (there is only one service routine entry per block, rather than one
774 per character).
775
776 In fast output mode, it is imperative that not less than 1500 instructions
777 elapse between the first character load to the FIFO and the initiation of
778 transmission. The RTE driver must have enough time to output the maximum
779 number of contiguous characters (33) and reset the interrupt status flags
780 before the service routine is entered. Because all of the characters are
781 transmitted as a block, the FIFO empty flag will be set by the service
782 routine. If the driver has not yet exited at that time, the buffer-empty
783 interrupt will be cleared when the interrupt status reset is done. The
784 symptom will be a 3.8-second pause in output until the driver times out.
785
786 To avoid this, the OTx output character handler does an absolute schedule for
787 the first character to ensure that a full character time is used.
788 */
789
790 t_stat baci_term_svc (UNIT *uptr)
791 {
792 uint32 data_bits, data_mask;
793 const t_bool fast_timing = (baci_term.flags & UNIT_FASTTIME) != 0;
794 const t_bool is_attached = (baci_term.flags & UNIT_ATT) != 0;
795 t_stat status = SCPE_OK;
796 t_bool xmit_loop = TRUE;
797 t_bool recv_loop = TRUE;
798
799
800 /* Transmission */
801
802 while (xmit_loop && (baci_uart_thr & IN_VALID)) { /* valid character in UART? */
803 data_bits = 5 + (baci_cfcw & OUT_CHARSIZE); /* calculate number of data bits */
804 data_mask = (1 << data_bits) - 1; /* generate mask for data bits */
805 baci_uart_tr = baci_uart_thr & data_mask; /* mask data into transmitter register */
806
807 if ((baci_uart_tr == ENQ) && fast_timing) { /* char is ENQ and fast timing? */
808 baci_enq_seen = TRUE; /* set flag instead of transmitting */
809 baci_enq_cntr = baci_enq_cntr + 1; /* bump ENQ counter */
810 recv_loop = FALSE; /* skip recv to allow time before ACK */
811
812 if (DEBUG_PRI (baci_dev, DEB_XFER))
813 fprintf (sim_deb, ">>BACI xfer: Character ENQ absorbed internally, "
814 "ENQ count = %d\n", baci_enq_cntr);
815 }
816
817 else { /* character is not an ENQ */
818 baci_enq_cntr = 0; /* reset ENQ counter */
819
820 if (is_attached) { /* attached to network? */
821 status = tmxr_putc_ln (&baci_ldsc, /* transmit the character */
822 baci_uart_tr);
823
824 if ((status == SCPE_OK) && /* transmitted OK? */
825 DEBUG_PRI (baci_dev, DEB_XFER))
826 fprintf (sim_deb, ">>BACI xfer: Character %s "
827 "transmitted from UART\n", fmt_char (baci_uart_tr));
828 }
829 }
830
831 if (status == SCPE_OK) { /* transmitted OK? */
832 baci_uart_tr = CLEAR_R; /* clear transmitter register */
833
834 if (IO_MODE == XMIT) { /* transmit mode? */
835 baci_fcount = baci_fcount - 1; /* decrement occupancy counter */
836 baci_uart_thr = fifo_get (); /* get next char into UART */
837 update_status (); /* update FIFO status */
838 }
839
840 else /* receive mode */
841 baci_uart_thr = CLEAR_HR; /* clear holding register */
842
843 xmit_loop = fast_timing && !baci_enq_seen; /* loop if fast mode and char not ENQ */
844 }
845
846 else
847 xmit_loop = FALSE;
848 }
849
850
851 /* Deferred reception */
852
853 if (recv_loop && /* ok to process? */
854 baci_uart_rhr && (IO_MODE == RECV) && /* and deferred char in RHR in recv mode? */
855 (!baci_enq_seen || (baci_enq_cntr >= 2))) { /* and either no ENQ or at least 2nd ENQ? */
856
857 baci_uart_rhr = baci_uart_rhr & ~IN_VALID; /* clear valid bit */
858
859 if (DEBUG_PRI (baci_dev, DEB_XFER))
860 fprintf (sim_deb, ">>BACI xfer: Deferred character %s processed\n",
861 fmt_char ((uint8) baci_uart_rhr));
862
863 fifo_put ((uint8) baci_uart_rhr); /* move deferred character to FIFO */
864 baci_uart_rhr = CLEAR_HR; /* clear RHR */
865 update_status (); /* update FIFO status */
866 }
867
868
869 /* Reception */
870
871 while (recv_loop && /* OK to process? */
872 (baci_uart_rr = tmxr_getc_ln (&baci_ldsc))) { /* and new character available? */
873
874 if (baci_uart_rr & SCPE_BREAK) /* break detected? */
875 baci_status = baci_status | IN_BREAK; /* set break status */
876
877 data_bits = 5 + (baci_cfcw & OUT_CHARSIZE); /* calculate number of data bits */
878 data_mask = (1 << data_bits) - 1; /* generate mask for data bits */
879 baci_uart_rhr = baci_uart_rr & data_mask; /* mask data into holding register */
880 baci_uart_rr = CLEAR_R; /* clear receiver register */
881
882 if (DEBUG_PRI (baci_dev, DEB_XFER))
883 fprintf (sim_deb, ">>BACI xfer: Character %s received by UART\n",
884 fmt_char ((uint8) baci_uart_rhr));
885
886 if (baci_term.flags & UNIT_CAPSLOCK) /* caps lock mode? */
887 baci_uart_rhr = toupper (baci_uart_rhr); /* convert to upper case if lower */
888
889 if (baci_cfcw & OUT_ECHO) /* echo wanted? */
890 tmxr_putc_ln (&baci_ldsc, baci_uart_rhr); /* send it back */
891
892 if ((IO_MODE == RECV) && !baci_enq_seen) { /* receive mode and not ENQ/ACK? */
893 fifo_put ((uint8) baci_uart_rhr); /* put data in FIFO */
894 baci_uart_rhr = CLEAR_HR; /* clear RHR */
895 update_status (); /* update FIFO status (may set flag) */
896
897 recv_loop = fast_timing && !FLG (baci_dib.devno); /* loop if fast mode and no IRQ */
898 }
899
900 else { /* xmit or ENQ/ACK, leave char in RHR */
901 baci_uart_rhr = baci_uart_rhr | IN_VALID; /* set character valid bit */
902 recv_loop = FALSE; /* terminate loop */
903 }
904 }
905
906
907 /* Housekeeping */
908
909 if (recv_loop && baci_enq_seen) { /* OK to process and ENQ seen? */
910 baci_enq_seen = FALSE; /* reset flag */
911
912 if (DEBUG_PRI (baci_dev, DEB_XFER))
913 fputs (">>BACI xfer: Character ACK generated internally\n", sim_deb);
914
915 fifo_put (ACK); /* fake ACK from terminal */
916 update_status (); /* update FIFO status */
917 }
918
919 if (is_attached) /* attached to network? */
920 tmxr_poll_tx (&baci_desc); /* output any accumulated chars */
921
922 if ((baci_uart_thr & IN_VALID) || baci_enq_seen || /* more to transmit? */
923 tmxr_rqln (&baci_ldsc)) /* or more to receive? */
924 sim_activate (uptr, uptr->wait); /* reschedule service */
925 else
926 if (DEBUG_PRI (baci_dev, DEB_CMDS))
927 fputs (">>BACI cmds: Terminal service stopped\n", sim_deb);
928
929 return status;
930 }
931
932
933 /* BACI Telnet poll service.
934
935 This service routine is used to poll for Telnet connections and incoming
936 characters. If characters are available, the terminal I/O service routine is
937 scheduled. It starts when the socket is attached and stops when the socket
938 is detached.
939 */
940
941 t_stat baci_poll_svc (UNIT *uptr)
942 {
943 if (baci_term.flags & UNIT_ATT) { /* attached to network? */
944 if (tmxr_poll_conn (&baci_desc) >= 0) /* new connection established? */
945 baci_ldsc.rcve = 1; /* enable line to receive */
946
947 tmxr_poll_rx (&baci_desc); /* poll for input */
948
949 if (tmxr_rqln (&baci_ldsc)) /* chars available? */
950 sim_activate (&baci_term, baci_term.wait); /* activate I/O service */
951 }
952
953 uptr->wait = sync_poll (SERVICE); /* synchronize poll */
954 sim_activate (uptr, uptr->wait); /* continue polling */
955
956 return SCPE_OK;
957 }
958
959
960 /* Simulator reset routine */
961
962 t_stat baci_reset (DEVICE *dptr)
963 {
964 master_reset (0); /* do master reset */
965
966 baci_dib.ctl = 0; /* clear control */
967 baci_dib.flg = 1; /* set flag */
968 baci_dib.fbf = 1; /* set flag buffer */
969 baci_dib.srq = 1; /* set SRQ */
970 baci_dib.cmd = 1; /* set lockout */
971
972 baci_ibuf = 0; /* clear input buffer */
973 baci_obuf = 0; /* clear output buffer */
974
975 baci_enq_seen = FALSE; /* reset ENQ seen flag */
976 baci_enq_cntr = 0; /* clear ENQ counter */
977
978 baci_term.wait = service_time (baci_icw); /* set terminal I/O time */
979
980 if (baci_term.flags & UNIT_ATT) { /* device attached? */
981 baci_poll.wait = sync_poll (INITIAL); /* synchronize poll */
982 sim_activate (&baci_poll, baci_poll.wait); /* start Telnet poll */
983 }
984 else
985 sim_cancel (&baci_poll); /* else stop Telnet poll */
986
987 return SCPE_OK;
988 }
989
990
991 /* Attach controller */
992
993 t_stat baci_attach (UNIT *uptr, char *cptr)
994 {
995 t_stat status = SCPE_OK;
996
997 status = tmxr_attach (&baci_desc, uptr, cptr); /* attach to socket */
998
999 if (status == SCPE_OK) {
1000 baci_poll.wait = sync_poll (INITIAL); /* synchronize poll */
1001 sim_activate (&baci_poll, baci_poll.wait); /* start Telnet poll */
1002 }
1003 return status;
1004 }
1005
1006 /* Detach controller */
1007
1008 t_stat baci_detach (UNIT *uptr)
1009 {
1010 t_stat status;
1011
1012 status = tmxr_detach (&baci_desc, uptr); /* detach socket */
1013 baci_ldsc.rcve = 0; /* disable line reception */
1014 sim_cancel (&baci_poll); /* stop Telnet poll */
1015 return status;
1016 }
1017
1018 /* Show connection status and statistics */
1019
1020 t_stat baci_show (FILE *st, UNIT *uptr, int32 val, void *desc)
1021 {
1022 if (baci_ldsc.conn)
1023 if (val)
1024 tmxr_fconns (st, &baci_ldsc, -1);
1025 else
1026 tmxr_fstats (st, &baci_ldsc, -1);
1027 else
1028 fprintf (st, "terminal disconnected\n");
1029
1030 return SCPE_OK;
1031 }
1032
1033
1034 /* Local routines */
1035
1036
1037 /* Master reset.
1038
1039 This is the programmed card master reset, not the simulator reset routine.
1040 It is called from the simulator reset routine with "selcode" = 0; the latter
1041 routine will take care of setting the card flip-flops appropriately.
1042
1043 Master reset normally clears the UART registers. However, if we are in "fast
1044 timing" mode, the receiver holding register may hold a deferred character.
1045 In this case, we do not clear the RHR, unless we are called from the
1046 simulator reset routine.
1047
1048 The HP BACI manual states that master reset "Clears Service Request (SRQ)."
1049 An examination of the schematic, though, shows that it sets SRQ instead.
1050 */
1051
1052 static void master_reset (uint32 selcode)
1053 {
1054 baci_fput = baci_fget = 0; /* clear FIFO indexes */
1055 baci_fcount = 0; /* clear FIFO counter */
1056 memset (baci_fifo, 0, sizeof (baci_fifo)); /* clear FIFO data */
1057
1058 baci_uart_thr = CLEAR_HR; /* clear transmitter holding register */
1059
1060 if (!(baci_term.flags & UNIT_FASTTIME) || !selcode) /* real time mode or power-on init? */
1061 baci_uart_rhr = CLEAR_HR; /* clear receiver holding register */
1062
1063 baci_uart_tr = CLEAR_R; /* clear transmitter register */
1064 baci_uart_rr = CLEAR_R; /* clear receiver register */
1065
1066 baci_uart_clk = 0; /* clear UART clock */
1067 baci_bcount = 0; /* clear break counter */
1068
1069 if (selcode) {
1070 clrCTL (selcode); /* clear control */
1071 setFLG (selcode); /* set flag and flag buffer */
1072 setSRQ (selcode); /* set SRQ */
1073 setCMD (selcode); /* set lockout flip-flop */
1074 }
1075
1076 baci_edsiw = 0; /* clear interrupt enables */
1077 baci_dsrw = 0; /* clear status reference */
1078 baci_cfcw = baci_cfcw & ~OUT_ECHO; /* clear echo flag */
1079 baci_icw = baci_icw & OUT_BAUDRATE; /* clear interface control */
1080
1081 if (baci_term.flags & UNIT_DIAG) /* diagnostic mode? */
1082 baci_status = baci_status & ~IN_MODEM | IN_SPARE; /* clear loopback status, set BA */
1083
1084 return;
1085 }
1086
1087
1088 /* Update status.
1089
1090 In diagnostic mode, several of the modem output lines are looped back to the
1091 input lines. Also, CD is tied to BB (received data), which is presented on
1092 the TEST status bit via an inversion. Echo mode couples BB to BA
1093 (transmitted data), which is presented on the SPARE status bit.
1094
1095 If a modem line interrupt condition is present and enabled, the DEVINT status
1096 bit is set. Other potential "standard" interrupt sources are the special
1097 character, break detected, and overrun/parity error bits. If DCPC transfers
1098 are not selected, then the FIFO interrupts (buffer empty, half-full, and
1099 full) and the "data ready" condition (i.e., receive and character modes
1100 enabled and FIFO not empty) also produces an interrupt request.
1101
1102 An interrupt request will set the card flag unless either the lockout or SRQ
1103 flip-flops are set. SRQ will set if DCPC mode is enabled and there is room
1104 (transmit mode) or data (receive mode) in the FIFO.
1105 */
1106
1107 static void update_status (void)
1108 {
1109 if (baci_term.flags & UNIT_DIAG) { /* diagnostic mode? */
1110 baci_status = baci_status & ~IN_LOOPBACK; /* prepare loopback flags */
1111
1112 if (baci_icw & OUT_SXX) /* SCA to SCF and CF */
1113 baci_status = baci_status | IN_SXX | IN_CF;
1114 if ((baci_icw & OUT_CA) && (baci_fcount < 128)) /* CA to CC and CE */
1115 baci_status = baci_status | IN_CC | IN_CE;
1116 if (baci_icw & OUT_CD) /* CD to CB */
1117 baci_status = baci_status | IN_CB;
1118 else {
1119 baci_status = baci_status | IN_TEST; /* BB is inversion of CD */
1120 if (baci_cfcw & OUT_ECHO)
1121 baci_status = baci_status | IN_SPARE; /* BB couples to BA with echo */
1122 }
1123
1124 if (!(baci_cfcw & OUT_ECHO) && (baci_uart_tr & 1)) /* no echo and UART TR set? */
1125 baci_status = baci_status | IN_SPARE; /* BA to SPARE */
1126 }
1127
1128 if (baci_edsiw & (baci_status ^ baci_dsrw) & IN_MODEM) /* device interrupt? */
1129 baci_status = baci_status | IN_DEVINT; /* set flag */
1130
1131 if ((baci_status & IN_STDIRQ) || /* standard interrupt? */
1132 !(baci_icw & OUT_DCPC) && /* or under program control */
1133 (baci_status & IN_FIFOIRQ) || /* and FIFO interrupt? */
1134 (IO_MODE == RECV) && /* or receiving */
1135 (baci_edsiw & OUT_ENCM) && /* and char mode */
1136 (baci_fget != baci_fput)) { /* and FIFO not empty? */
1137
1138 if (CMD (baci_dib.devno)) { /* interrupt lockout? */
1139 if (DEBUG_PRI (baci_dev, DEB_CMDS))
1140 fputs (">>BACI cmds: Lockout prevents flag set", sim_deb);
1141 }
1142
1143 else if (SRQ (baci_dib.devno)) { /* SRQ? */
1144 if (DEBUG_PRI (baci_dev, DEB_CMDS))
1145 fputs (">>BACI cmds: SRQ prevents flag set", sim_deb);
1146 }
1147
1148 else {
1149 setFLG (baci_dib.devno); /* set device flag and flag buffer */
1150 setCMD (baci_dib.devno); /* set lockout */
1151
1152 if (DEBUG_PRI (baci_dev, DEB_CMDS))
1153 fputs (">>BACI cmds: Flag and lockout set", sim_deb);
1154 }
1155
1156 if (DEBUG_PRI (baci_dev, DEB_CMDS))
1157 fprintf (sim_deb, ", status = %06o\n", baci_status);
1158 }
1159
1160 if ((baci_icw & OUT_DCPC) && /* DCPC enabled? */
1161 ((IO_MODE == XMIT) && (baci_fcount < 128) || /* and xmit and room in FIFO */
1162 (IO_MODE == RECV) && (baci_fcount > 0))) { /* or recv and data in FIFO? */
1163
1164 if (CMD (baci_dib.devno)) { /* interrupt lockout? */
1165 if (DEBUG_PRI (baci_dev, DEB_CMDS))
1166 fputs (">>BACI cmds: Lockout prevents SRQ set", sim_deb);
1167 }
1168
1169 else {
1170 setSRQ (baci_dib.devno); /* set SRQ */
1171
1172 if (DEBUG_PRI (baci_dev, DEB_CMDS))
1173 fputs (">>BACI cmds: SRQ set", sim_deb);
1174 }
1175
1176 if (DEBUG_PRI (baci_dev, DEB_CMDS))
1177 fprintf (sim_deb, ", status = %06o\n", baci_status);
1178 }
1179
1180 return;
1181 }
1182
1183
1184 /* Calculate service time from baud rate.
1185
1186 Service times are based on 1580 instructions per second, which is the 1000
1187 E-Series execution speed. The "external clock" rate uses the 9600 baud rate,
1188 as most real terminals were set to their maximum rate.
1189
1190 Note that the RTE driver has a race condition that will trip if the service
1191 time is less than 1500 instructions. Therefore, these times cannot be
1192 shortened arbitrarily.
1193 */
1194
1195 static int32 service_time (uint32 control_word)
1196 {
1197 static const int32 ticks [] = { 1646, 316000, 210667, 143636, 117472, 105333, 52667, 26333,
1198 17556, 13667, 8778, 6583, 4389, 3292, 2194, 1646 };
1199
1200 return ticks [GET_BAUDRATE (control_word)]; /* return service time for indicated rate */
1201 }
1202
1203
1204 /* Format a character into a printable string.
1205
1206 Control characters are translated to readable strings. Printable characters
1207 retain their original form but are enclosed in single quotes. Characters
1208 outside of the ASCII range are represented as escaped octal values.
1209 */
1210
1211 static const char *fmt_char (uint8 ch)
1212 {
1213 static const char *const ctl[] = { "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
1214 "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI",
1215 "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
1216 "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US" };
1217 static char rep[5];
1218
1219 if (ch <= '\037') /* ASCII control character? */
1220 return ctl [ch]; /* return string representation */
1221
1222 else if (ch == '\177') /* ASCII delete? */
1223 return "DEL"; /* return string representation */
1224
1225 else if (ch > '\177') { /* beyond printable range? */
1226 sprintf (rep, "\\%03o", ch); /* format value */
1227 return rep; /* return escaped octal code */
1228 }
1229
1230 else { /* printable character */
1231 rep[0] = '\''; /* form string */
1232 rep[1] = ch; /* containing character */
1233 rep[2] = '\'';
1234 rep[3] = '\0';
1235 return rep; /* return quoted character */
1236 }
1237 }
1238
1239
1240 /* FIFO manipulation routines.
1241
1242 The BACI is a half-duplex device that has a single 128-byte FIFO that is used
1243 for both transmitting and receiving. Whether the FIFO is connected to the
1244 input or output of the UART is determined by the XMIT bit in word 4. A
1245 separate 8-bit FIFO up/down counter is used to track the number of bytes
1246 available. FIFO operations are complicated slightly by the UART, which is
1247 double-buffered.
1248
1249 The FIFO is modeled as a circular 128-byte array. Separate get and put
1250 indexes track the current data extent. A FIFO character counter is used to
1251 derive empty, half-full, and full status indications, and counts greater than
1252 128 are possible.
1253
1254 In the transmit mode, an OTA/B with word type 0 generates SI (shift in) to
1255 load the FIFO and increment the FIFO counter. When the UART is ready for a
1256 character, THRE (UART transmitter holding register empty) and OR (FIFO output
1257 ready) generate THRL (transmitter holding register load) and SO (FIFO shift
1258 out) to unload the FIFO into the UART. When transmission of the character
1259 over the serial line is complete, TRE (UART transmitter register empty)
1260 decrements the FIFO counter.
1261
1262 In the receive mode, the UART sets DR (data received) when has obtained a
1263 character, which generates SI (FIFO shift in) to load the FIFO and increment
1264 the FIFO counter. This also clocks PE (UART parity error) and IR (FIFO input
1265 ready) into the overrun/parity error flip-flop. An LIA/B with control set
1266 and with OR (FIFO output ready) set, indicating valid data is available,
1267 generates SO (FIFO shift out) to unload the FIFO and decrement the FIFO
1268 counter.
1269
1270 Presuming an empty FIFO and UART, double-buffering in the transmit mode means
1271 that the first byte deposited into the FIFO is removed and loaded into the
1272 UART transmitter holding register. Even though the FIFO is actually empty,
1273 the FIFO counter remains at 1, because FIFO decrement does not occur until
1274 the UART actually transmits the data byte. The intended mode of operation is
1275 to wait until the buffer-empty interrupt occurs, which will happen when the
1276 final character is transmitted from the UART, before switching the BACI into
1277 receive mode. The counter will match the FIFO contents properly, i.e., will
1278 be zero, when the UART transmission completes.
1279
1280 However, during diagnostic operation, FIFO testing will take this "extra"
1281 count into consideration. For example, after a master reset, if ten bytes
1282 are written to the FIFO in transmit mode, the first byte will pass through to
1283 the UART transmitter holding register, and the next nine bytes will fill the
1284 FIFO. The first byte read in receive mode will be byte 2, not byte 1; the
1285 latter remains in the UART. After the ninth byte is read, OR (FIFO output
1286 ready) will drop, resetting the valid data flip-flop and inhibiting any
1287 further FIFO counter decrement pulses. The counter will remain at 1 until
1288 another master reset is done.
1289
1290 The same situation occurs in the RTE driver during ENQ/ACK handshakes. The
1291 driver sets the card to transmit mode, sends an ENQ, waits for a short time
1292 for the character to "bubble through" the FIFO and into the UART transmitter
1293 holding register, and then switches the card to receive mode to await the
1294 interrupt from the reception of the ACK. This is done to avoid the overhead
1295 of the interrupt after the ENQ is transmitted. However, switching the card
1296 into receive mode before the ENQ is actually transmitted means that the FIFO
1297 counter will not decrement when that occurs, leaving the counter in an "off
1298 by one" configuration. To remedy this, the driver does a master reset after
1299 the ACK is received.
1300
1301 Therefore, for proper operation, we must simulate both the UART
1302 double-buffering and the decoupling of the FIFO and FIFO character counter.
1303 */
1304
1305
1306 /* Get a character from the FIFO.
1307
1308 In receive mode, getting a character from the FIFO decrements the character
1309 counter concurrently. In transmit mode, the counter must not be decremented
1310 until the character is actually sent; in this latter case, the caller is
1311 responsible for decrementing. Attempting to get a character when the FIFO is
1312 empty returns the last valid data and does not alter the FIFO indexes.
1313
1314 Because the FIFO counter may indicate more characters than are actually in
1315 the FIFO, the count is not an accurate indicator of FIFO fill status. We
1316 account for this by examining the get and put indexes. If these are equal,
1317 then the FIFO is either empty or exactly full. We differentiate by examining
1318 the FIFO counter and seeing if it is >= 128, indicating an (over)full
1319 condition. If it is < 128, then the FIFO is empty, even if the counter is
1320 not 0.
1321 */
1322
1323 static uint32 fifo_get (void)
1324 {
1325 uint32 data;
1326
1327 data = baci_fifo [baci_fget]; /* get character */
1328
1329 if ((baci_fget != baci_fput) || (baci_fcount >= 128)) { /* FIFO occupied? */
1330 if (IO_MODE == RECV) /* receive mode? */
1331 baci_fcount = baci_fcount - 1; /* decrement occupancy counter */
1332
1333 if (DEBUG_PRI (baci_dev, DEB_BUF))
1334 fprintf (sim_deb, ">>BACI buf: Character %s get from FIFO [%d], "
1335 "character counter = %d\n", fmt_char (data), baci_fget, baci_fcount);
1336
1337 baci_fget = (baci_fget + 1) % FIFO_SIZE; /* bump index modulo array size */
1338
1339 if (baci_spchar [data]) /* is it a special character? */
1340 data = data | IN_SPFLAG; /* set flag */
1341
1342 data = data | IN_VALID; /* set valid flag in return */
1343 }
1344
1345 else /* FIFO empty */
1346 if (DEBUG_PRI (baci_dev, DEB_BUF))
1347 fprintf (sim_deb, ">>BACI buf: Attempted get on empty FIFO, "
1348 "character count = %d\n", baci_fcount);
1349
1350 if (baci_fcount == 0) /* count now zero? */
1351 baci_status = baci_status | IN_BUFEMPTY; /* set buffer empty flag */
1352
1353 update_status (); /* update FIFO status */
1354
1355 return data; /* return character */
1356 }
1357
1358
1359 /* Put a character into the FIFO.
1360
1361 In transmit mode, available characters are unloaded from the FIFO into the
1362 UART transmitter holding register as soon as the THR is empty. That is,
1363 given an empty FIFO and THR, a stored character will pass through the FIFO
1364 and into the THR immediately. Otherwise, the character will remain in the
1365 FIFO. In either case, the FIFO character counter is incremented.
1366
1367 In receive mode, characters are only unloaded from the FIFO explicitly, so
1368 stores always load the FIFO and increment the counter.
1369 */
1370
1371 static void fifo_put (uint8 ch)
1372 {
1373 uint32 index = 0;
1374 t_bool pass_thru;
1375
1376 pass_thru = (IO_MODE == XMIT) && /* pass thru if XMIT and THR empty */
1377 !(baci_uart_thr & IN_VALID);
1378
1379 if (pass_thru) /* pass char thru to UART */
1380 baci_uart_thr = ch | IN_VALID; /* and set valid character flag */
1381
1382 else { /* RECV or THR occupied */
1383 index = baci_fput; /* save current index */
1384 baci_fifo [baci_fput] = ch; /* put char in FIFO */
1385 baci_fput = (baci_fput + 1) % FIFO_SIZE; /* bump index modulo array size */
1386 }
1387
1388 baci_fcount = baci_fcount + 1; /* increment occupancy counter */
1389
1390 if (DEBUG_PRI (baci_dev, DEB_BUF))
1391 if (pass_thru)
1392 fprintf (sim_deb, ">>BACI buf: Character %s put to UART transmitter holding register, "
1393 "character counter = 1\n", fmt_char (ch));
1394 else
1395 fprintf (sim_deb, ">>BACI buf: Character %s put to FIFO [%d], "
1396 "character counter = %d\n", fmt_char (ch), index, baci_fcount);
1397
1398 if ((IO_MODE == RECV) && (baci_spchar [ch])) /* receive mode and special character? */
1399 baci_status = baci_status | IN_SPCHAR; /* set special char seen flag */
1400
1401 if (baci_fcount == 64) /* FIFO half full? */
1402 baci_status = baci_status | IN_BUFHALF;
1403
1404 else if (baci_fcount == 128) /* FIFO completely full? */
1405 baci_status = baci_status | IN_BUFFULL;
1406
1407 else if (baci_fcount > 128) /* FIFO overrun? */
1408 baci_status = baci_status | IN_OVRUNPE;
1409
1410 update_status (); /* update FIFO status */
1411
1412 return;
1413 }
1414
1415
1416 /* Clock the UART.
1417
1418 In the diagnostic mode, the DIAG output is connected to the EXT CLK input.
1419 If the baud rate of the Interface Control Word is set to "external clock,"
1420 then raising and lowering the DIAG output will pulse the UART transmitter and
1421 receiver clock lines, initiating transmission or reception of serial data.
1422 Sixteen pulses are needed to shift one bit through the UART.
1423
1424 The diagnostic hood ties CD to BB (received data), so bits presented to CD
1425 via the Interface Control Word can be clocked into the UART receiver register
1426 (RR). Similarly, the UART transmitter register (TR) shifts data onto BA
1427 (transmitted data), and the hood ties BA to SPARE, so transmitted bits are
1428 presented to the SPARE bit in the status word.
1429
1430 "baci_uart_clk" contains the number of clock pulses remaining for the current
1431 character transfer. Calling this routine with "baci_uart_clk" = 0 initiates
1432 a transfer. The value will be a multiple of 16 and will account for the
1433 start bit, the data bits, the optional parity bit, and the stop bits. The
1434 transfer terminates when the count reaches zero (or eight, if 1.5 stop bits
1435 is selected during transmission).
1436
1437 Every sixteen pulses when the lower four bits of the clock count are zero,
1438 the transmitter or receiver register will be shifted to present or receive a
1439 new serial bit. The registers are initialized to all ones for proper
1440 handling of the stop bits.
1441
1442 A break counter is maintained and incremented whenever a space (0) condition
1443 is seen on the serial line. After 160 clock times (10 bits) of continuous
1444 zero data, the "break seen" status is set.
1445
1446 This routine is not used in terminal mode.
1447 */
1448
1449 static void clock_uart (void)
1450 {
1451 uint32 uart_bits, data_bits, data_mask, parity, bit_low, i;
1452
1453 if (baci_uart_clk > 0) { /* transfer in progress? */
1454 bit_low = (baci_icw & OUT_CD); /* get current receive bit */
1455
1456 if ((baci_uart_clk & 017) == 0) /* end of a bit? */
1457 if (IO_MODE == XMIT) /* transmit? */
1458 baci_uart_tr = baci_uart_tr >> 1; /* shift new bit onto line */
1459 else /* receive? */
1460 baci_uart_rr = (baci_uart_rr >> 1) & /* shift new bit in */
1461 (bit_low ? ~SIGN : -1); /* (inverted sense) */
1462
1463 if (bit_low) { /* another low bit? */
1464 baci_bcount = baci_bcount + 1; /* update break counter */
1465
1466 if (baci_bcount == 160) { /* break held long enough? */
1467 baci_status = baci_status | IN_BREAK; /* set break flag */
1468
1469 if (DEBUG_PRI (baci_dev, DEB_XFER))
1470 fputs (">>BACI xfer: Break detected\n", sim_deb);
1471 }
1472 }
1473
1474 else /* high bit? */
1475 baci_bcount = 0; /* reset break counter */
1476
1477 baci_uart_clk = baci_uart_clk - 1; /* decrement clocks remaining */
1478
1479 if ((IO_MODE == XMIT) && /* transmit mode? */
1480 ((baci_uart_clk == 0) || /* and end of character? */
1481 (baci_uart_clk == 8) && /* or last stop bit */
1482 (baci_cfcw & OUT_STBITS) && /* and extra stop bit requested */
1483 ((baci_cfcw & OUT_CHARSIZE) == 0))) { /* and 1.5 stop bits used? */
1484
1485 baci_uart_clk = 0; /* clear clock count */
1486
1487 baci_fcount = baci_fcount - 1; /* decrement occupancy counter */
1488 baci_uart_thr = fifo_get (); /* get next char into THR */
1489 update_status (); /* update FIFO status */
1490
1491 if (DEBUG_PRI (baci_dev, DEB_XFER))
1492 fprintf (sim_deb, ">>BACI xfer: UART transmitter empty, "
1493 "holding register = %06o\n", baci_uart_thr);
1494 }
1495
1496 else if ((IO_MODE == RECV) && /* receive mode? */
1497 (baci_uart_clk == 0)) { /* and end of character? */
1498
1499 data_bits = 5 + (baci_cfcw & OUT_CHARSIZE); /* calculate number of data bits */
1500 data_mask = (1 << data_bits) - 1; /* generate mask for data bits */
1501
1502 uart_bits = data_bits + /* calculate UART bits as data bits */
1503 ((baci_cfcw & OUT_PARITY) != 0) + /* plus parity bit if used */
1504 ((baci_cfcw & OUT_STBITS) != 0); /* plus extra stop bit if used */
1505
1506 baci_uart_rhr = baci_uart_rr >> (16 - uart_bits); /* position data to right align */
1507 baci_uart_rr = CLEAR_R; /* clear receiver register */
1508
1509 if (DEBUG_PRI (baci_dev, DEB_XFER))
1510 fprintf (sim_deb, ">>BACI xfer: UART receiver = %06o (%s)\n",
1511 baci_uart_rhr, fmt_char (baci_uart_rhr & data_mask));
1512
1513 fifo_put (baci_uart_rhr & data_mask); /* put data in FIFO */
1514 update_status (); /* update FIFO status */
1515
1516 if (baci_cfcw & OUT_PARITY) { /* parity present? */
1517 data_mask = data_mask << 1 | 1; /* widen mask to encompass parity */
1518 uart_bits = baci_uart_rhr & data_mask; /* get data plus parity */
1519
1520 parity = (baci_cfcw & OUT_PAREVEN) == 0; /* preset for even/odd parity */
1521
1522 for (i = 0; i < data_bits + 1; i++) { /* calc parity of data + parity bit */
1523 parity = parity ^ uart_bits; /* parity calculated in LSB */
1524 uart_bits = uart_bits >> 1;
1525 }
1526
1527 if (parity & 1) { /* parity error? */
1528 baci_status = baci_status | IN_OVRUNPE; /* report it */
1529
1530 if (DEBUG_PRI (baci_dev, DEB_XFER))
1531 fputs (">>BACI xfer: Parity error detected\n", sim_deb);
1532 }
1533 }
1534 }
1535 }
1536
1537 if ((baci_uart_clk == 0) && /* start of transfer? */
1538 ((IO_MODE == RECV) || /* and receive mode */
1539 (baci_uart_thr & IN_VALID))) { /* or character ready to transmit? */
1540
1541 data_bits = 5 + (baci_cfcw & OUT_CHARSIZE); /* calculate number of data bits */
1542
1543 uart_bits = data_bits + /* calculate UART bits as data bits */
1544 ((baci_cfcw & OUT_PARITY) != 0) + /* plus parity bit if used */
1545 2 + ((baci_cfcw & OUT_STBITS) != 0); /* plus start/stop and extra stop if used */
1546
1547 baci_uart_clk = 16 * uart_bits; /* calculate clocks pulses expected */
1548
1549 if (IO_MODE == XMIT) { /* transmit mode? */
1550 data_mask = (1 << data_bits) - 1; /* generate mask for data bits */
1551 baci_uart_tr = baci_uart_thr & data_mask; /* mask data into holding register */
1552
1553 if (baci_cfcw & OUT_PARITY) { /* add parity to this transmission? */
1554 uart_bits = baci_uart_tr; /* copy data bits */
1555 parity = (baci_cfcw & OUT_PAREVEN) == 0; /* preset for even/odd parity */
1556
1557 for (i = 0; i < data_bits; i++) { /* calculate parity of data */
1558 parity = parity ^ uart_bits; /* parity calculated in LSB */
1559 uart_bits = uart_bits >> 1;
1560 }
1561
1562 data_mask = data_mask << 1 | 1; /* extend mask for the parity bit */
1563 baci_uart_tr = baci_uart_tr | /* include parity in transmission register */
1564 (parity & 1) << data_bits; /* (mask to parity bit and position it) */
1565 }
1566
1567 baci_uart_tr = (~data_mask | baci_uart_tr) << 2 | 1; /* form serial data stream */
1568
1569 if (DEBUG_PRI (baci_dev, DEB_XFER))
1570 fprintf (sim_deb, ">>BACI xfer: UART transmitter = %06o (%s), "
1571 "clock count = %d\n", baci_uart_tr & DMASK,
1572 fmt_char (baci_uart_thr & data_mask), baci_uart_clk);
1573 }
1574
1575 else {
1576 baci_uart_rr = CLEAR_R; /* clear receiver register */
1577
1578 if (DEBUG_PRI (baci_dev, DEB_XFER))
1579 fprintf (sim_deb, ">>BACI xfer: UART receiver empty, "
1580 "clock count = %d\n", baci_uart_clk);
1581 }
1582 }
1583
1584 return;
1585 }