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