First Commit of my working state
[simh.git] / Ibm1130 / ibm1130_sca.c
1 /* ibm1130_sca.c: IBM 1130 synchronous communications adapter emulation
2
3 Based on the SIMH simulator package written by Robert M Supnik
4
5 Brian Knittel
6 Revision History
7
8 2005.03.08 - Started
9
10 * (C) Copyright 2005, Brian Knittel.
11 * You may freely use this program, but: it offered strictly on an AS-IS, AT YOUR OWN
12 * RISK basis, there is no warranty of fitness for any purpose, and the rest of the
13 * usual yada-yada. Please keep this notice and the copyright in any distributions
14 * or modifications.
15 *
16 * This is not a supported product, but I welcome bug reports and fixes.
17 * Mail to simh@ibm1130.org
18 */
19
20 /******************************************************************************************************************
21 * NOTES:
22 * This module sends raw bisync data over a standard TCP port. It's meant to be
23 * used with the emulated 2703 device in Hercules.
24 *
25 * Attach command:
26 *
27 * to establish an outgoing connection:
28 *
29 * attach sca host connect to named host on default port (initial default port is 2703); or
30 * attach sca host:### connect to named host on port ###. ### is also set as new default port number.
31 * >> The simulator waits until the connection is established
32 *
33 * or to set up for incoming connections:
34 *
35 * attach sca -l dummy listen for a connection on default port (initially 2703); Nonnumeric "dummy" argument is ignored; or
36 * attach sca -l ### listen for a connection on the port ###. ### is also set as the new default port
37 * >> The simulator proceeds. When another simulator connects, the READY bit is set in the DSW.
38 *
39 * If the SCA's autoanswer-enable bit has been set, an incoming connection causes an interrupt (untested)
40 * Configuration commands:
41 *
42 * set sca bsc set bisync mode (default)
43 * set sca str set synchronous transmit/recieve mode (NOT IMPLEMENTED)
44 *
45 * set sca ### set simulated baud rate to ###, where ### is 600, 1200, 2000, 2400 or 4800 (4800 is default)
46 *
47 * set sca half set simulated half-duplex mode
48 * set sca full set simulated full-duplex mode (note: 1130's SCA can't actually send and receive at the same time!)
49 *
50 * deposit sca keepalive ### send SYN packets every ### msec when suppressing SYN's, default is 0 (no keepalives)
51 *
52 * STR/BSC mode is selected by a toggle switch on the 1130, with the SET SCA BSC or SET SET STR command here.
53 * Testable with in_bsc_mode() or in_str_mode() in this module. If necessary, the SET command can be configured
54 * to call a routine when the mode is changed; or, we can just required the user to reboot the simulated 1130
55 * when switching modes.
56 *
57 * STR MODE IS NOT IMPLEMENTED!
58 *
59 * The SCA adapter appears to know nothing of the protocols used by STR and BSC. It does handle the sync/idle
60 * character specially, and between BSC and STR mode the timers are used differently. Also in STR mode it
61 * can be set to a sychronization mode where it sends SYN's without program intervention.
62 *
63 * See definition of SCA_STATE for defintion of simulator states.
64 *
65 * Rather than trying to simulate the actual baud rates, we try to keep the character service interrupts
66 * coming at about the same number of instruction intervals -- thus existing 1130 code should work correctly
67 * but the effective data transfer rate will be much higher. The "timers" however are written to run on real wall clock
68 * time, This may or may not work. If necessary they could be set to time out based on the number of calls to sca_svc
69 * which occurs once per character send/receive time; For example, at 4800 baud and an 8 bit frame, we get
70 * 600 characters/second, so the 3 second timer would expire in 1800 sca_svc calls. Well, that's something to
71 * think about.
72 *
73 * To void blowing zillions of SYN characters across the network when the system is running but idle, we suppress
74 * them. If 100 consecutive SYN's are sent, we flush the output buffer and stop sending SYN's
75 * until some other character is sent, OR the line is turned around (e.g. INITR, INITW or an end-operation
76 * CONTROL is issued), or the number of msec set by DEPOSIT SCS KEEPALIVE has passed, if a value has
77 * been set. By default no keepalives are sent.
78 *
79 * Timer operations are not debugged. First, do timers automatically reset and re-interrupt if
80 * left alone after they timeout the first time? Does XIO_SENSE_DEV really restart all running timers?
81 * Does it touch the timer trigger (program timer?) How do 3 and 1.25 second timers really work
82 * in BSC mode? Hard to tell from the FC manual.
83 ******************************************************************************************************************/
84
85 #include "ibm1130_defs.h"
86 #include "sim_sock.h" /* include path must include main simh directory */
87 #include <ctype.h>
88 #ifndef INADDR_NONE
89 #define INADDR_NONE ((unsigned long)-1)
90 #endif
91
92 #define DEBUG_SCA_FLUSH 0x0001 /* debugging options */
93 #define DEBUG_SCA_TRANSMIT 0x0002
94 #define DEBUG_SCA_CHECK_INDATA 0x0004
95 #define DEBUG_SCA_RECEIVE_SYNC 0x0008
96 #define DEBUG_SCA_RECEIVE_DATA 0x0010
97 #define DEBUG_SCA_XIO_READ 0x0020
98 #define DEBUG_SCA_XIO_WRITE 0x0040
99 #define DEBUG_SCA_XIO_CONTROL 0x0080
100 #define DEBUG_SCA_XIO_INITW 0x0100
101 #define DEBUG_SCA_XIO_INITR 0x0200
102 #define DEBUG_SCA_XIO_SENSE_DEV 0x0400
103 #define DEBUG_SCA_TIMERS 0x0800
104 #define DEBUG_SCA_ALL 0xFFFF
105
106 /* #define DEBUG_SCA (DEBUG_SCA_TIMERS|DEBUG_SCA_FLUSH|DEBUG_SCA_TRANSMIT|DEBUG_SCA_CHECK_INDATA|DEBUG_SCA_RECEIVE_SYNC|DEBUG_SCA_RECEIVE_DATA|DEBUG_SCA_XIO_INITR|DEBUG_SCA_XIO_INITW) */
107 #define DEBUG_SCA (DEBUG_SCA_TIMERS|DEBUG_SCA_FLUSH|DEBUG_SCA_CHECK_INDATA|DEBUG_SCA_XIO_INITR|DEBUG_SCA_XIO_INITW)
108
109 #define SCA_DEFAULT_PORT 2703 /* default socket, This is the number of the IBM 360's BSC device */
110
111 #define MAX_SYNS 100 /* number of consecutive syn's after which we stop buffering them */
112
113 /***************************************************************************************
114 * SCA
115 ***************************************************************************************/
116
117 #define SCA_DSW_READ_RESPONSE 0x8000 /* receive buffer full interrupt */
118 #define SCA_DSW_WRITE_RESPONSE 0x4000 /* transmitter buffer empty interrupt */
119 #define SCA_DSW_CHECK 0x2000 /* data overrun or character gap error */
120 #define SCA_DSW_TIMEOUT 0x1000 /* timer interrupt, mode specific */
121 #define SCA_DSW_AUTOANSWER_REQUEST 0x0800 /* dataset is ringing and autoanswer is enabled */
122 #define SCA_DSW_BUSY 0x0400 /* adapter is in either receive or transmit mode */
123 #define SCA_DSW_AUTOANSWER_ENABLED 0x0200 /* 1 when autoanswer mode has been enabled */
124 #define SCA_DSW_READY 0x0100 /* Carrier detect? Connected and ready to rcv, xmit or sync */
125 #define SCA_DSW_RECEIVE_RUN 0x0080 /* used in two-wire half-duplex STR mode only. "Slave" mode (?) */
126
127 #define IS_ONLINE(u) (((u)->flags & (UNIT_ATT|UNIT_DIS)) == UNIT_ATT)
128
129 typedef enum { /* ms m = mode (0 = idle, 1 = send, 2 = receive), s = substate */
130 SCA_STATE_IDLE = 0x00, /* nothing happening */
131 SCA_STATE_TURN_SEND = 0x10, /* line turning around to the send state */
132 SCA_STATE_SEND_SYNC = 0x11, /* sca is sending syncs */
133 SCA_STATE_SEND1 = 0x12, /* have issued write response, waiting for write command */
134 SCA_STATE_SEND2 = 0x13, /* write command issued, "sending" byte */
135 SCA_STATE_TURN_RECEIVE = 0x20, /* line turnaround to the receive state */
136 SCA_STATE_RECEIVE_SYNC = 0x21, /* sca is receiving syncs */
137 SCA_STATE_RECEIVE_SYNC2 = 0x22, /* bsc mode, waiting for 2nd SYN */
138 SCA_STATE_RECEIVE_SYNC3 = 0x23, /* bsc mode, waiting for 1st non-SYN */
139 SCA_STATE_RECEIVE1 = 0x24, /* "receiving" a byte */
140 SCA_STATE_RECEIVE2 = 0x25, /* read response issued, "receiving" next byte */
141 } SCA_STATE;
142
143 #define in_send_state() (sca_state & 0x10)
144 #define in_receive_state() (sca_state & 0x20)
145
146 static t_stat sca_svc (UNIT *uptr); /* prototypes */
147 static t_stat sca_reset (DEVICE *dptr);
148 static t_stat sca_attach (UNIT *uptr, char *cptr);
149 static t_stat sca_detach (UNIT *uptr);
150 static void sca_start_timer (int n, int msec_now);
151 static void sca_halt_timer (int n);
152 static void sca_toggle_timer (int n, int msec_now);
153 /* timer states, chosen so any_timer_running can be calculated by oring states of all 3 timers */
154 typedef enum {SCA_TIMER_INACTIVE = 0, SCA_TIMER_RUNNING = 1, SCA_TIMER_INHIBITED = 2, SCA_TIMER_TIMEDOUT = 4} SCA_TIMER_STATE;
155
156 #define TIMER_3S 0 /* 3 second timer index into sca_timer_xxx arrays */
157 #define TIMER_125S 1 /* 1.25 second timer */
158 #define TIMER_035S 2 /* 0.35 second timer */
159
160 static uint16 sca_dsw = 0; /* device status word */
161 static uint32 sca_cwait = 275; /* inter-character wait */
162 static uint32 sca_iwait = 2750; /* idle wait */
163 static uint32 sca_state = SCA_STATE_IDLE;
164 static uint8 sichar = 0; /* sync/idle character */
165 static uint8 rcvd_char = 0; /* most recently received character */
166 static uint8 sca_frame = 8;
167 static uint16 sca_port = SCA_DEFAULT_PORT; /* listening port number */
168 static int32 sca_keepalive = 0; /* keepalive SYN packet period in msec, default = 0 (disabled) */
169 static SCA_TIMER_STATE sca_timer_state[3]; /* current timer state */
170 static int sca_timer_endtime[3]; /* clocktime when timeout is to occur if state is RUNNING */
171 static int sca_timer_timeleft[3]; /* time left in msec if state is INHIBITED */
172 static t_bool any_timer_running = FALSE; /* TRUE if at least one timer is running */
173 static int sca_timer_msec[3] = {3000, 1250, 350}; /* timebase in msec for the three timers: 3 sec, 1.25 sec, 0.35 sec */
174 static t_bool sca_timer_trigger; /* if TRUE, the "timer trigger" is set, the 0.35s timer is running and the 3 sec and 1.25 sec timers are inhibited */
175 static int sca_nsyns = 0; /* number of consecutively sent SYN's */
176 static int idles_since_last_write = 0; /* used to detect when software has ceased sending data */
177 static SOCKET sca_lsock = INVALID_SOCKET;
178 static SOCKET sca_sock = INVALID_SOCKET;
179
180 #define SCA_SENDBUF_SIZE 145 /* maximum number of bytes to buffer for transmission */
181 #define SCA_RCVBUF_SIZE 256 /* max number of bytes to read from socket at a time */
182 #define SCA_SEND_THRESHHOLD 140 /* number of bytes to buffer before initiating packet send */
183 #define SCA_IDLE_THRESHHOLD 3 /* maximum number of unintentional idles to buffer before initiating send */
184
185 static uint8 sca_sendbuf[SCA_SENDBUF_SIZE]; /* bytes pending to write to socket */
186 static uint8 sca_rcvbuf[SCA_RCVBUF_SIZE]; /* bytes received from socket, to be given to SCA */
187 static int sca_n2send = 0; /* number of bytes queued for transmission */
188 static int sca_nrcvd = 0; /* number of received bytes in buffer */
189 static int sca_rcvptr = 0; /* index of next byte to take from rcvbuf */
190
191 #define UNIT_V_BISYNC (UNIT_V_UF + 0) /* BSC (bisync) mode */
192 #define UNIT_V_BAUD (UNIT_V_UF + 1) /* 3 bits for baud rate encoding */
193 #define UNIT_V_FULLDUPLEX (UNIT_V_UF + 4)
194 #define UNIT_V_AUTOANSWER (UNIT_V_UF + 5)
195 #define UNIT_V_LISTEN (UNIT_V_UF + 6) /* listen socket mode */
196
197 #define UNIT_BISYNC (1u << UNIT_V_BISYNC)
198 #define UNIT_BAUDMASK (7u << UNIT_V_BAUD)
199 #define UNIT_BAUD600 (0u << UNIT_V_BAUD)
200 #define UNIT_BAUD1200 (1u << UNIT_V_BAUD)
201 #define UNIT_BAUD2000 (2u << UNIT_V_BAUD)
202 #define UNIT_BAUD2400 (3u << UNIT_V_BAUD)
203 #define UNIT_BAUD4800 (4u << UNIT_V_BAUD)
204 #define UNIT_FULLDUPLEX (1u << UNIT_V_FULLDUPLEX)
205 #define UNIT_AUTOANSWER (1u << UNIT_V_AUTOANSWER)
206 #define UNIT_LISTEN (1u << UNIT_V_LISTEN)
207
208 extern int sim_switches; /* variable that gets bits set for -x switches on command lines */
209
210 t_stat sca_set_baud (UNIT *uptr, int32 value, char *cptr, void *desc);
211
212 UNIT sca_unit = { /* default settings */
213 UDATA (sca_svc, UNIT_ATTABLE|UNIT_BISYNC|UNIT_BAUD4800|UNIT_FULLDUPLEX, 0),
214 };
215
216 REG sca_reg[] = { /* DEVICE STATE/SETTABLE PARAMETERS: */
217 { HRDATA (SCADSW, sca_dsw, 16) }, /* device status word */
218 { DRDATA (SICHAR, sichar, 8), PV_LEFT }, /* sync/idle character */
219 { DRDATA (RCVDCHAR, rcvd_char, 8), PV_LEFT }, /* most recently received character */
220 { DRDATA (FRAME, sca_frame, 8), PV_LEFT }, /* frame bits (6, 7 or 8)
221 { DRDATA (SCASTATE, sca_state, 32), PV_LEFT }, /* current state */
222 { DRDATA (CTIME, sca_cwait, 32), PV_LEFT }, /* inter-character wait */
223 { DRDATA (ITIME, sca_iwait, 32), PV_LEFT }, /* idle wait (polling interval for socket connects) */
224 { DRDATA (SCASOCKET, sca_port, 16), PV_LEFT }, /* listening port number */
225 { DRDATA (KEEPALIVE, sca_keepalive, 32), PV_LEFT }, /* keepalive packet period in msec */
226 { NULL } };
227
228 MTAB sca_mod[] = { /* DEVICE OPTIONS */
229 { UNIT_BISYNC, 0, "STR", "STR", NULL }, /* mode option */
230 { UNIT_BISYNC, UNIT_BISYNC, "BSC", "BSC", NULL },
231 { UNIT_BAUDMASK, UNIT_BAUD600, "600", "600", sca_set_baud }, /* data rate option */
232 { UNIT_BAUDMASK, UNIT_BAUD1200, "1200", "1200", sca_set_baud },
233 { UNIT_BAUDMASK, UNIT_BAUD2000, "2000", "2000", sca_set_baud },
234 { UNIT_BAUDMASK, UNIT_BAUD2400, "2400", "2400", sca_set_baud },
235 { UNIT_BAUDMASK, UNIT_BAUD4800, "4800", "4800", sca_set_baud },
236 { UNIT_FULLDUPLEX, 0, "HALF", "HALF", NULL }, /* duplex option (does this matter?) */
237 { UNIT_FULLDUPLEX, UNIT_FULLDUPLEX, "FULL", "FULL", NULL },
238 { 0 } };
239
240 DEVICE sca_dev = {
241 "SCA", &sca_unit, sca_reg, sca_mod,
242 1, 16, 16, 1, 16, 16,
243 NULL, NULL, sca_reset,
244 NULL, sca_attach, sca_detach
245 };
246
247 /*********************************************************************************************
248 * sca_set_baud - set baud rate handler (SET SCA.BAUD nnn)
249 *********************************************************************************************/
250
251 t_stat sca_set_baud (UNIT *uptr, int32 value, char *cptr, void *desc)
252 {
253 uint32 newbits;
254
255 switch (value) {
256 case 600: newbits = UNIT_BAUD600; break;
257 case 1200: newbits = UNIT_BAUD1200; break;
258 case 2000: newbits = UNIT_BAUD2000; break;
259 case 2400: newbits = UNIT_BAUD2400; break;
260 case 4800: newbits = UNIT_BAUD4800; break;
261 default: return SCPE_ARG;
262 }
263
264 CLRBIT(sca_unit.flags, UNIT_BAUDMASK);
265 SETBIT(sca_unit.flags, newbits);
266
267 sca_cwait = 1320000 / value; /* intercharacter wait time in instructions (roughly) */
268
269 return SCPE_OK;
270 }
271
272 /*********************************************************************************************
273 * HANDY MACROS
274 *********************************************************************************************/
275
276 #define in_bsc_mode() (sca_unit.flags & UNIT_BISYNC) /* TRUE if user selected BSC mode */
277 #define in_str_mode() ((sca_unit.flags & UNIT_BISYNC) == 0) /* TRUE if user selected STR mode */
278
279 /*********************************************************************************************
280 * mstring - allocate a copy of a string
281 *********************************************************************************************/
282
283 char *mstring (char *str)
284 {
285 int len;
286 char *m;
287
288 len = strlen(str)+1;
289 if ((m = malloc(len)) == NULL) {
290 printf("Out of memory!");
291 return "?"; /* this will of course cause trouble if it's subsequently freed */
292 }
293 strcpy(m, str);
294 return m;
295 }
296
297 /*********************************************************************************************
298 * sca_socket_error - call when there is an error reading from or writing to socket
299 *********************************************************************************************/
300
301 static void sca_socket_error (void)
302 {
303 char name[100];
304
305 /* print diagnostic? */
306 printf("SCA socket error, closing connection\n");
307
308 /* tell 1130 that connection was lost */
309 CLRBIT(sca_dsw, SCA_DSW_READY);
310
311 if (sca_sock != INVALID_SOCKET) {
312 /* close socket, prepare to listen again if in listen mode. It's a "master" socket if it was an outgoing connection */
313 sim_close_sock(sca_sock, (sca_unit.flags & UNIT_LISTEN) == 0);
314 sca_sock = INVALID_SOCKET;
315
316 if (sca_unit.filename != NULL) /* reset filename string in unit record */
317 free(sca_unit.filename);
318
319 if (sca_unit.flags & UNIT_LISTEN) {
320 sprintf(name, "(Listening on port %d)", sca_port);
321 sca_unit.filename = mstring(name);
322 printf("%s\n", name);
323 }
324 else
325 sca_unit.filename = mstring("(connection failed)");
326 }
327
328 /* clear buffers */
329 sca_nrcvd = sca_rcvptr = sca_n2send = sca_nsyns = 0;
330 }
331
332 /*********************************************************************************************
333 * sca_transmit_byte, sca_flush - send data buffering mechanism
334 *********************************************************************************************/
335
336 static void sca_flush (void)
337 {
338 int nbytes;
339
340 if (sca_n2send > 0) {
341 #if (DEBUG_SCA & DEBUG_SCA_FLUSH)
342 printf("* SCA_FLUSH %d byte%s\n", sca_n2send, (sca_n2send == 1) ? "" : "s");
343 #endif
344
345 if (sca_sock != INVALID_SOCKET) {
346 nbytes = sim_write_sock(sca_sock, sca_sendbuf, sca_n2send);
347
348 if (nbytes == SOCKET_ERROR)
349 sca_socket_error();
350 else if (nbytes != sca_n2send)
351 printf("SOCKET BLOCKED -- NEED TO REWRITE IBM1130_SCA.C");
352
353 /* I'm going to assume that SCA communications on the 1130 will consist entirely */
354 /* of back and forth exchanges of short records, and so we should never stuff the pipe so full that */
355 /* it blocks. If it does ever block, we'll have to come up with an asychronous buffering mechanism. */
356 }
357
358 sca_n2send = 0; /* mark buffer cleared */
359 }
360 }
361
362 /*********************************************************************************************
363 * sca_transmit_byte - buffer a byte to be send to the socket
364 *********************************************************************************************/
365
366 static void sca_transmit_byte (uint8 b)
367 {
368 uint32 curtime;
369 static uint32 last_syn_time, next_syn_time;
370
371 #if (DEBUG_SCA & DEBUG_SCA_TRANSMIT)
372 printf("* SCA_TRANSMIT: %02x\n", b);
373 #endif
374
375 /* write a byte to the socket. Let's assume an 8 bit frame in all cases.
376 * We buffer them up, then send the packet when (a) it fills up to a certain point
377 * and/or (b) some time has passed? We handle (b) by:
378 * checking in sva_svc if several sca_svc calls are made w/o any XIO_WRITES, and
379 * flushing send buffer on line turnaround, timeouts, or any other significant state change
380 */
381
382 /* on socket error, call sca_socket_error(); */
383
384 if (b == sichar) {
385 if (sca_nsyns >= MAX_SYNS) { /* we're suppressing SYN's */
386 if (sca_keepalive > 0) { /* we're sending keepalives, though... check to see if it's time */
387 curtime = sim_os_msec();
388 if (curtime >= next_syn_time || curtime < last_syn_time) { /* check for < last_syn_time because sim_os_msec() can wrap when OS has been running a long time */
389 sca_sendbuf[sca_n2send++] = b;
390 sca_sendbuf[sca_n2send++] = b; /* send 2 of them */
391 sca_flush();
392 last_syn_time = curtime;
393 next_syn_time = last_syn_time + sca_keepalive;
394 }
395 }
396 return;
397 }
398
399 if (++sca_nsyns == MAX_SYNS) { /* we've sent a bunch of SYN's, time to stop sending them */
400 sca_sendbuf[sca_n2send] = b; /* send last one */
401 sca_flush();
402 last_syn_time = sim_os_msec(); /* remember time, and note time to send next one */
403 next_syn_time = last_syn_time + sca_keepalive;
404 return;
405 }
406 }
407 else
408 sca_nsyns = 0;
409
410 sca_sendbuf[sca_n2send] = b; /* store character */
411
412 if (++sca_n2send >= SCA_SEND_THRESHHOLD)
413 sca_flush(); /* buffer is full, send it immediately */
414 }
415
416 /*********************************************************************************************
417 * sca_interrupt (utility routine) - set a bit in the device status word and initiate an interrupt
418 *********************************************************************************************/
419
420 static void sca_interrupt (int bit)
421 {
422 sca_dsw |= bit; /* set device status word bit(s) */
423 SETBIT(ILSW[1], ILSW_1_SCA); /* set interrupt level status word bit */
424
425 calc_ints(); /* udpate simulator interrupt status (not really needed if within xio handler, since ibm1130_cpu calls it after xio handler) */
426 }
427
428 /*********************************************************************************************
429 * sca_reset - reset the SCA device
430 *********************************************************************************************/
431
432 static t_stat sca_reset (DEVICE *dptr)
433 {
434 /* flush any pending data */
435 sca_flush();
436 sca_nrcvd = sca_rcvptr = sca_n2send = sca_nsyns = 0;
437
438 /* reset sca activity */
439 sca_state = SCA_STATE_IDLE;
440 CLRBIT(sca_dsw, SCA_DSW_BUSY | SCA_DSW_AUTOANSWER_ENABLED | SCA_DSW_RECEIVE_RUN | SCA_DSW_READ_RESPONSE | SCA_DSW_WRITE_RESPONSE | SCA_DSW_CHECK | SCA_DSW_TIMEOUT | SCA_DSW_AUTOANSWER_REQUEST);
441 sca_timer_state[0] = sca_timer_state[1] = sca_timer_state[2] = SCA_TIMER_INACTIVE;
442 any_timer_running = FALSE;
443 sca_timer_trigger = FALSE;
444
445 if (sca_unit.flags & UNIT_ATT) /* if unit is attached (or listening) */
446 sim_activate(&sca_unit, sca_iwait); /* poll for service. Must do this here as BOOT clears activity queue before resetting all devices */
447
448 return SCPE_OK;
449 }
450
451 /*********************************************************************************************
452 * sca_attach - attach the SCA device
453 *********************************************************************************************/
454
455 static t_stat sca_attach (UNIT *uptr, char *cptr)
456 {
457 t_bool do_listen;
458 char *colon;
459 uint32 ipaddr;
460 int32 port;
461 struct hostent *he;
462 char name[256];
463 static SOCKET sdummy = INVALID_SOCKET;
464 fd_set wr_set, err_set;
465
466 do_listen = sim_switches & SWMASK('L'); /* -l means listen mode */
467
468 if (sca_unit.flags & UNIT_ATT) /* if already attached, detach */
469 detach_unit(&sca_unit);
470
471 if (do_listen) { /* if listen mode, string specifies socket number (only; otherwise it's a dummy argument) */
472 if (isdigit(*cptr)) { /* if digits specified, extract port number */
473 port = atoi(cptr);
474 if (port <= 0 || port > 65535)
475 return SCPE_ARG;
476 else
477 sca_port = port;
478 }
479 /* else if nondigits specified, ignore... but the command has to have something there otherwise the core scp */
480 /* attach_cmd() routine complains "too few arguments". */
481
482 if ((sca_lsock = sim_master_sock(sca_port)) == INVALID_SOCKET)
483 return SCPE_OPENERR;
484
485 SETBIT(sca_unit.flags, UNIT_LISTEN); /* note that we are listening, not yet connected */
486
487 sprintf(name, "(Listening on port %d)", sca_port);
488 sca_unit.filename = mstring(name);
489 printf("%s\n", name);
490
491 }
492 else {
493 while (*cptr && *cptr <= ' ')
494 cptr++;
495
496 if (! *cptr)
497 return SCPE_2FARG;
498
499 if ((colon = strchr(cptr, ':')) != NULL) {
500 *colon++ = '\0'; /* clip hostname at colon */
501
502 port = atoi(colon); /* extract port number that follows it */
503 if (port <= 0 || port > 65535)
504 return SCPE_ARG;
505 else
506 sca_port = port;
507 }
508
509 if (sdummy == INVALID_SOCKET)
510 if ((sdummy = sim_create_sock()) == INVALID_SOCKET) /* create and keep a socket, to force initialization */
511 return SCPE_IERR; /* of socket library (e.g on Win32 call WSAStartup), else gethostbyname fails */
512
513 if (get_ipaddr(cptr, &ipaddr, NULL) != SCPE_OK) { /* try to parse hostname as dotted decimal nnn.nnn.nnn.nnn */
514 if ((he = gethostbyname(cptr)) == NULL) /* if not decimal, look up name through DNS */
515 return SCPE_OPENERR;
516
517 if ((ipaddr = * (unsigned long *) he->h_addr_list[0]) == INADDR_NONE)
518 return SCPE_OPENERR;
519
520 ipaddr = ntohl(ipaddr); /* convert to host byte order; gethostbyname() gives us network order */
521 }
522
523 if ((sca_sock = sim_connect_sock(ipaddr, sca_port)) == INVALID_SOCKET)
524 return SCPE_OPENERR;
525
526 /* sim_connect_sock() sets socket to nonblocking before initiating the connect, so
527 * the connect is pending when it returns. For outgoing connections, the attach command should wait
528 * until the connection succeeds or fails. We use "accept" to wait and find out which way it goes...
529 */
530
531 FD_ZERO(&wr_set); /* we are only interested in info for sca_sock */
532 FD_ZERO(&err_set);
533 FD_SET(sca_sock, &wr_set);
534 FD_SET(sca_sock, &err_set);
535
536 select(3, NULL, &wr_set, &err_set, NULL); /* wait for connection to complete or fail */
537
538 if (FD_ISSET(sca_sock, &wr_set)) { /* sca_sock appears in "writable" set -- connect completed */
539 sprintf(name, "%s:%d", cptr, sca_port);
540 sca_unit.filename = mstring(name);
541 SETBIT(sca_dsw, SCA_DSW_READY);
542 }
543 else if (FD_ISSET(sca_sock, &err_set)) { /* sca_sock appears in "error" set -- connect failed */
544 sim_close_sock(sca_sock, TRUE);
545 sca_sock = INVALID_SOCKET;
546 return SCPE_OPENERR;
547 }
548 else { /* if we get here my assumption about how select works is wrong */
549 printf("SCA_SOCK NOT FOUND IN WR_SET -OR- ERR_SET, CODING IN IBM1130_SCA IS WRONG\n");
550 sim_close_sock(sca_sock, TRUE);
551 sca_sock = INVALID_SOCKET;
552 return SCPE_OPENERR;
553 }
554 }
555
556 /* set up socket connect or listen. on success, set UNIT_ATT.
557 * If listen mode, set UNIT_LISTEN. sca_svc will poll for connection
558 * If connect mode, set dsw SCA_DSW_READY to indicate connection is up
559 */
560
561 SETBIT(sca_unit.flags, UNIT_ATT); /* record successful socket binding */
562
563 sca_state = SCA_STATE_IDLE;
564 sim_activate(&sca_unit, sca_iwait); /* start polling for service */
565
566 sca_n2send = 0; /* clear buffers */
567 sca_nrcvd = 0;
568 sca_rcvptr = 0;
569 sca_nsyns = 0;
570
571 return SCPE_OK;
572 }
573
574 /*********************************************************************************************
575 * sca_detach - detach the SCA device
576 *********************************************************************************************/
577
578 static t_stat sca_detach (UNIT *uptr)
579 {
580 if ((sca_unit.flags & UNIT_ATT) == 0)
581 return SCPE_OK;
582
583 sca_flush();
584
585 sca_state = SCA_STATE_IDLE; /* stop processing during service calls */
586 sim_cancel(&sca_unit); /* stop polling for service */
587
588 CLRBIT(sca_dsw, SCA_DSW_READY); /* indicate offline */
589
590 if (sca_sock != INVALID_SOCKET) { /* close connected socket */
591 sim_close_sock(sca_sock, (sca_unit.flags & UNIT_LISTEN) == 0);
592 sca_sock = INVALID_SOCKET;
593 }
594 if (sca_lsock != INVALID_SOCKET) { /* close listening socket */
595 sim_close_sock(sca_lsock, TRUE);
596 sca_lsock = INVALID_SOCKET;
597 }
598
599 free(sca_unit.filename);
600 sca_unit.filename = NULL;
601
602 CLRBIT(sca_unit.flags, UNIT_ATT|UNIT_LISTEN);
603
604 return SCPE_OK;
605 }
606
607 /*********************************************************************************************
608 * sca_check_connect - see if an incoming socket connection has com
609 *********************************************************************************************/
610
611 static void sca_check_connect (void)
612 {
613 uint32 ipaddr;
614 char name[100];
615
616 if ((sca_sock = sim_accept_conn(sca_lsock, &ipaddr)) == INVALID_SOCKET)
617 return;
618
619 ipaddr = htonl(ipaddr); /* convert to network order so we can print it */
620
621 sprintf(name, "%d.%d.%d.%d", ipaddr & 0xFF, (ipaddr >> 8) & 0xFF, (ipaddr >> 16) & 0xFF, (ipaddr >> 24) & 0xFF);
622
623 printf("(SCA connection from %s)\n", name);
624
625 if (sca_unit.filename != NULL)
626 free(sca_unit.filename);
627
628 sca_unit.filename = mstring(name);
629
630 SETBIT(sca_dsw, SCA_DSW_READY); /* indicate active connection */
631
632 if (sca_dsw & SCA_DSW_AUTOANSWER_ENABLED) /* if autoanswer was enabled, I guess we should give them an interrupt. Untested. */
633 sca_interrupt(SCA_DSW_AUTOANSWER_REQUEST);
634 }
635
636 /*********************************************************************************************
637 * sca_check_indata - try to fill receive buffer from socket
638 *********************************************************************************************/
639
640 static void sca_check_indata (void)
641 {
642 int nbytes;
643
644 sca_rcvptr = 0; /* reset pointers and count */
645 sca_nrcvd = 0;
646
647 #ifdef FAKE_SCA
648
649 nbytes = 5; /* FAKE: receive SYN SYN SYN SYN DLE ACK0 */
650 sca_rcvbuf[0] = 0x32;
651 sca_rcvbuf[1] = 0x32;
652 sca_rcvbuf[2] = 0x32;
653 sca_rcvbuf[3] = 0x10;
654 sca_rcvbuf[4] = 0x70;
655
656 #else
657 /* read socket; 0 is returned if no data is available */
658 nbytes = sim_read_sock(sca_sock, sca_rcvbuf, SCA_RCVBUF_SIZE);
659
660 #endif
661
662 if (nbytes < 0)
663 sca_socket_error();
664 else /* zero or more */
665 sca_nrcvd = nbytes;
666
667 #if (DEBUG_SCA & DEBUG_SCA_CHECK_INDATA)
668 if (sca_nrcvd > 0)
669 printf("* SCA_CHECK_INDATA %d byte%s\n", sca_nrcvd, (sca_nrcvd == 1) ? "" : "s");
670 #endif
671 }
672
673 /*********************************************************************************************
674 * sca_svc - handled scheduled event. This will presumably be scheduled frequently, and can check
675 * for incoming data, reasonableness of initiating a write interrupt, timeouts etc.
676 *********************************************************************************************/
677
678 static t_stat sca_svc (UNIT *uptr)
679 {
680 t_bool timeout;
681 int msec_now;
682 int i;
683
684 /* if not connected, and if in wait-for-connection mode, check for connection attempt */
685 if ((sca_unit.flags & UNIT_LISTEN) && ! (sca_dsw & SCA_DSW_READY))
686 sca_check_connect();
687
688 if (any_timer_running) {
689 msec_now = sim_os_msec();
690
691 timeout = FALSE;
692 for (i = 0; i < 3; i++) {
693 if (sca_timer_state[i] == SCA_TIMER_RUNNING && msec_now >= sca_timer_endtime[i]) {
694 timeout = TRUE;
695 sca_timer_state[i] = SCA_TIMER_TIMEDOUT;
696 #if (DEBUG_SCA & DEBUG_SCA_TIMERS)
697 printf("+ SCA_TIMER %d timed out\n", i);
698 #endif
699
700 if (i == TIMER_035S && sca_timer_trigger) {
701 sca_timer_trigger = FALSE; /* uninhibit the other two timers */
702 sca_toggle_timer(TIMER_3S, msec_now);
703 sca_toggle_timer(TIMER_125S, msec_now);
704 }
705 }
706 }
707
708 if (timeout)
709 sca_interrupt(SCA_DSW_TIMEOUT);
710
711 any_timer_running = (sca_timer_state[0]| sca_timer_state[1] | sca_timer_state[2]) & SCA_TIMER_RUNNING;
712 }
713
714 if (sca_dsw & SCA_DSW_READY) { /* if connected */
715
716 /* if rcvd data buffer is empty, and if in one of the receive states, checÄk for arrival of received data */
717 if (in_receive_state() && sca_rcvptr >= sca_nrcvd)
718 sca_check_indata();
719
720 switch (sca_state) {
721 case SCA_STATE_IDLE:
722 break;
723
724 case SCA_STATE_TURN_SEND:
725 /* has enough time gone by yet? if so... */
726 sca_state = SCA_STATE_SEND1;
727 sca_interrupt(SCA_DSW_WRITE_RESPONSE);
728 break;
729
730 case SCA_STATE_SEND_SYNC:
731 sca_transmit_byte(sichar);
732 break;
733
734 case SCA_STATE_SEND1:
735 sca_transmit_byte(sichar); /* character interval has passed with no character written? character gap check */
736 sca_interrupt(SCA_DSW_CHECK); /* send an idle character (maybe? for socket IO maybe send nothing) and interrupt */
737
738 if (idles_since_last_write >= 0) {
739 if (++idles_since_last_write >= SCA_IDLE_THRESHHOLD) {
740 sca_flush();
741 idles_since_last_write = -1; /* don't send a short packet again until real data gets written again */
742 sca_nsyns = 0; /* resume sending syns if output starts up again */
743 }
744 }
745 break;
746
747 case SCA_STATE_SEND2:
748 sca_state = SCA_STATE_SEND1; /* character has been sent. Schedule another transmit */
749 sca_interrupt(SCA_DSW_WRITE_RESPONSE);
750 break;
751
752 case SCA_STATE_TURN_RECEIVE:
753 /* has enough time gone by yet? if so... */
754 sca_state = SCA_STATE_RECEIVE_SYNC; /* assume a character is coming in */
755 break;
756
757 case SCA_STATE_RECEIVE_SYNC:
758 if (sca_rcvptr < sca_nrcvd) {
759 rcvd_char = sca_rcvbuf[sca_rcvptr++];
760 #if (DEBUG_SCA & DEBUG_SCA_RECEIVE_SYNC)
761 printf("* SCA rcvd %02x %s\n", rcvd_char, (rcvd_char == sichar) ? "sync1" : "ignored");
762 #endif
763 if (in_bsc_mode()) {
764 if (rcvd_char == sichar) /* count the SYN but don't interrupt */
765 sca_state = SCA_STATE_RECEIVE_SYNC2;
766 }
767 }
768 break;
769
770 case SCA_STATE_RECEIVE_SYNC2:
771 if (sca_rcvptr < sca_nrcvd) {
772 rcvd_char = sca_rcvbuf[sca_rcvptr++];
773 #if (DEBUG_SCA & DEBUG_SCA_RECEIVE_SYNC)
774 printf("* SCA rcvd %02x %s\n", rcvd_char, (rcvd_char == sichar) ? "sync2" : "ignored");
775 #endif
776 if (in_bsc_mode()) {
777 if (rcvd_char == sichar) /* count the SYN but don't interrupt */
778 sca_state = SCA_STATE_RECEIVE_SYNC3;
779 }
780 }
781 break;
782
783 case SCA_STATE_RECEIVE_SYNC3:
784 case SCA_STATE_RECEIVE1:
785 if (sca_rcvptr < sca_nrcvd) {
786 rcvd_char = sca_rcvbuf[sca_rcvptr++];
787
788 if (sca_state == SCA_STATE_RECEIVE_SYNC3 && rcvd_char == sichar) {
789 /* we're ready for data, but we're still seeing SYNs */
790 #if (DEBUG_SCA & DEBUG_SCA_RECEIVE_SYNC)
791 printf("* SCA rcvd %02x extra sync\n", rcvd_char);
792 #endif
793 }
794 else {
795 #if (DEBUG_SCA & DEBUG_SCA_RECEIVE_DATA)
796 printf("* SCA rcvd %02x\n", rcvd_char);
797 #endif
798 sca_interrupt(SCA_DSW_READ_RESPONSE);
799 sca_state = SCA_STATE_RECEIVE2;
800 }
801 }
802 /* otherwise remain in state until data becomes available */
803 break;
804
805 case SCA_STATE_RECEIVE2: /* if we are still in this state when another service interval has passed */
806 if (sca_rcvptr < sca_nrcvd) {
807 rcvd_char = sca_rcvbuf[sca_rcvptr++];
808
809 sca_interrupt(SCA_DSW_CHECK); /* overrun error */
810 sca_state = SCA_STATE_RECEIVE1; /* another character will come soon */
811 }
812 break;
813
814 default:
815 printf("Simulator error: unknown state %d in sca_svc\n", sca_state);
816 sca_state = SCA_STATE_IDLE;
817 break;
818 }
819 }
820 /* schedule service again */
821 sim_activate(&sca_unit, (sca_state == SCA_STATE_IDLE) ? sca_iwait : sca_cwait);
822
823 return SCPE_OK;
824 }
825
826 /*********************************************************************************************
827 * sca_toggle_timer - toggle a given timer's running/inhibited state for XIO_CONTROL
828 *********************************************************************************************/
829
830 static void sca_toggle_timer (int n, int msec_now)
831 {
832 if (sca_timer_state[n] == SCA_TIMER_RUNNING && sca_timer_trigger) {
833 sca_timer_state[n] = SCA_TIMER_INHIBITED;
834 sca_timer_timeleft[n] = sca_timer_endtime[n] - msec_now; /* save time left */
835 #if (DEBUG_SCA & DEBUG_SCA_TIMERS)
836 printf("+ SCA_TIMER %d inhibited\n", n);
837 #endif
838 }
839 else if (sca_timer_state[n] == SCA_TIMER_INHIBITED && ! sca_timer_trigger) {
840 sca_timer_state[n] = SCA_TIMER_RUNNING;
841 sca_timer_endtime[n] = sca_timer_timeleft[n] + msec_now; /* compute new endtime */
842 #if (DEBUG_SCA & DEBUG_SCA_TIMERS)
843 printf("+ SCA_TIMER %d uninhibited\n", n);
844 #endif
845 }
846 }
847
848 static void sca_start_timer (int n, int msec_now)
849 {
850 sca_timer_state[n] = SCA_TIMER_RUNNING;
851 sca_timer_endtime[n] = sca_timer_msec[n] + msec_now;
852 any_timer_running = TRUE;
853 #if (DEBUG_SCA & DEBUG_SCA_TIMERS)
854 printf("+ SCA_TIMER %d started\n", n);
855 #endif
856 }
857
858 static void sca_halt_timer (int n)
859 {
860 #if (DEBUG_SCA & DEBUG_SCA_TIMERS)
861 if (sca_timer_state[n] != SCA_TIMER_INACTIVE)
862 printf("+ SCA_TIMER %d stopped\n", n);
863 #endif
864
865 sca_timer_state[n] = SCA_TIMER_INACTIVE;
866 }
867
868 /*********************************************************************************************
869 * sca_start_transmit - initiate transmit mode, from XIO_INITR or XIO_CONTROL (sync mode)
870 *********************************************************************************************/
871
872 void sca_start_transmit (int32 iocc_addr, int32 modify)
873 {
874 sca_flush();
875 sca_nsyns = 0; /* reset SYN suppression */
876
877 /* Address bits are used to reset DSW conditions. */
878
879 if (modify & 0x40) /* bit 9. If set, reset all conditions */
880 iocc_addr = 0xD800;
881
882 iocc_addr &= 0xD800; /* look at just bits 0, 1, 3 and 4 */
883 if (iocc_addr) { /* if set, these bits clear DSW conditions */
884 CLRBIT(sca_dsw, iocc_addr);
885 CLRBIT(ILSW[1], ILSW_1_SCA); /* and I assume clear the interrupt condition too? (Seems unlikely that INITW would */
886 } /* be used in an interrupt service routine before SENSE, but who knows?) */
887
888 if (! in_send_state()) {
889 sca_state = SCA_STATE_TURN_SEND; /* begin line turnaround */
890 }
891 else {
892 sca_state = SCA_STATE_SEND1; /* line is */
893 sca_interrupt(SCA_DSW_WRITE_RESPONSE);
894 }
895
896 SETBIT(sca_dsw, SCA_DSW_BUSY); /* SCA is now busy, in transmit mode */
897
898 sim_cancel(&sca_unit);
899 sim_activate(&sca_unit, sca_cwait); /* start polling frequently */
900 }
901
902 /*********************************************************************************************
903 * xio_sca - handle SCA XIO command
904 *********************************************************************************************/
905
906 void xio_sca (int32 iocc_addr, int32 func, int32 modify)
907 {
908 char msg[80];
909 int i, msec_now;
910
911 switch (func) {
912 case XIO_READ: /* ***** XIO_READ - store last-received character to memory */
913 #if (DEBUG_SCA & DEBUG_SCA_XIO_READ)
914 printf("SCA RD addr %04x mod %02x rcvd_char %02x\n", iocc_addr, modify, rcvd_char);
915 #endif
916 if (modify & 0x03) { /* bits 14 and 15 */
917 #if (DEBUG_SCA & DEBUG_SCA_XIO_READ)
918 printf("(rd diag)\n");
919 #endif
920 /* if either of low two modifier bits is set, reads diagnostic words. whatever that is */
921 }
922 else {
923 WriteW(iocc_addr, rcvd_char << 8); /* always return last received character */
924
925 /* note: in read mode, read w/o interrupt (or two reads after an interrupt) causes a check
926 * so here we have to check the current state and possibly cause an interrupt
927 * Failure to have read before another arrives (overrun) also causes a check.
928 */
929
930 if (sca_state == SCA_STATE_RECEIVE2)/* XIO_READ should only be done (and only once) after a character interrupt */
931 sca_state = SCA_STATE_RECEIVE1; /* assume another character is coming in -- wait for it */
932 else
933 sca_interrupt(SCA_DSW_CHECK);
934 }
935 break;
936
937 case XIO_WRITE: /* ***** XIO_WRITE - transfer character from memory to output shift register */
938 #if (DEBUG_SCA & DEBUG_SCA_XIO_WRITE)
939 printf("SCA WRT addr %04x (%04x) mod %02x\n", iocc_addr, M[iocc_addr & mem_mask], modify);
940 #endif
941 if (modify & 0x01) { /* bit 15 */
942 /* clear audible alarm trigger */
943 #if (DEBUG_SCA & DEBUG_SCA_XIO_WRITE)
944 printf("(clr audible alarm trigger)\n");
945 #endif
946 }
947 /* else? or can they all operate in parallel? */
948 if (modify & 0x02) { /* bit 14 */
949 /* set audible alarm trigger */
950 #if (DEBUG_SCA & DEBUG_SCA_XIO_WRITE)
951 printf("(set audible alarm trigger)\n");
952 #endif
953 }
954 /* else? */
955 if (modify & 0x04) { /* bit 13 */
956 #if (DEBUG_SCA & DEBUG_SCA_XIO_WRITE)
957 printf("(set SYN)\n");
958 #endif
959 /* set sync/idle character */
960 sichar = (uint8) (ReadW(iocc_addr) >> 8);
961 sca_nsyns = 0; /* reset SYN suppression */
962 }
963 /* else? does presence of mod bit preclude sending a character? */
964 if ((modify & 0x07) == 0) { /* no modifiers */
965 /* transmit character --
966 * note: in write mode, failure to write soon enough after a write response interrupt causes a check
967 * Also, writing w/o interrupt (or two writes after an interrupt) causes a check
968 * so again, here we have to check the state to be sure that a write is appropriate
969 *
970 * note that in this simulator, we transmit the character immediately on XIO_WRITE. Therefore,
971 * there is no need to delay an end-operation function (XIO_CONTROL bit 13) until after a character time
972 */
973
974 idles_since_last_write = 0;
975
976 switch (sca_state) {
977 case SCA_STATE_SEND_SYNC:
978 case SCA_STATE_SEND1:
979 sca_transmit_byte((uint8) (M[iocc_addr & mem_mask] >> 8));
980 sca_state = SCA_STATE_SEND2;
981 sim_cancel(&sca_unit);
982 sim_activate(&sca_unit, sca_cwait); /* schedule service after character write time */
983 break;
984
985 case SCA_STATE_SEND2:
986 sca_interrupt(SCA_DSW_CHECK); /* write issued while a character is in progress out? write overrun */
987 break;
988
989 case SCA_STATE_IDLE: /* wrong time to issue a write, incorrect sca state */
990 default:
991 sca_flush();
992 sca_interrupt(SCA_DSW_CHECK); /* ??? or does this just perform a line turnaround and start transmission? */
993 break;
994 }
995
996 }
997 break;
998
999 case XIO_CONTROL: /* ***** XIO_CONTROL - manipulate interface state */
1000 #if (DEBUG_SCA & DEBUG_SCA_XIO_CONTROL)
1001 printf("SCA CTL addr %04x mod %02x\n", iocc_addr, modify);
1002 #endif
1003 if (modify & 0x80) { /* bit 8 */
1004 /* enable auto answer */
1005 #if (DEBUG_SCA & DEBUG_SCA_XIO_CONTROL)
1006 printf("(enable autoanswer)\n");
1007 #endif
1008 SETBIT(sca_unit.flags, UNIT_AUTOANSWER);
1009 SETBIT(sca_dsw, SCA_DSW_AUTOANSWER_ENABLED);
1010 }
1011
1012 if (modify & 0x40) { /* bit 9 */
1013 /* disable auto answer */
1014 #if (DEBUG_SCA & DEBUG_SCA_XIO_CONTROL)
1015 printf("(disable autoanswer)\n");
1016 #endif
1017 CLRBIT(sca_unit.flags, UNIT_AUTOANSWER);
1018 CLRBIT(sca_dsw, SCA_DSW_AUTOANSWER_ENABLED);
1019 }
1020
1021 if (modify & 0x20) { /* bit 10 */
1022 /* toggle timers, inhibit->run or run->inhibit */
1023 #if (DEBUG_SCA & (DEBUG_SCA_XIO_CONTROL|DEBUG_SCA_TIMERS))
1024 printf("(toggle timers)\n");
1025 #endif
1026 msec_now = sim_os_msec();
1027
1028 if (in_bsc_mode())
1029 sca_timer_trigger = ! sca_timer_trigger; /* toggle the timer trigger */
1030 if (sca_timer_trigger) /* if we've just set it, we're stopping the other timers and */
1031 sca_start_timer(TIMER_035S, msec_now); /* starting the 0.35 sec timer */
1032 else
1033 sca_halt_timer(TIMER_035S);
1034
1035 sca_toggle_timer(TIMER_3S, msec_now); /* toggle the 3 sec and 1.35 sec timers accordingly */
1036 sca_toggle_timer(TIMER_125S, msec_now);
1037
1038 any_timer_running = (sca_timer_state[0]| sca_timer_state[1] | sca_timer_state[2]) & SCA_TIMER_RUNNING;
1039 }
1040
1041 if (modify & 0x10) { /* bit 11 */
1042 /* enable sync mode. See references to this in FC manual
1043 * In STR mode only, sends a constant stream of SYN's without any CPU intervention
1044 * In BSC mode, appears to start the 1.25 second timer and otherwise act like INITW?
1045 */
1046 #if (DEBUG_SCA & DEBUG_SCA_XIO_CONTROL)
1047 printf("(enable sync mode)\n");
1048 #endif
1049
1050 if (in_bsc_mode()) { /* in bsc mode start the 1.25 second timer. not sure what resets it?!? */
1051 if (! in_send_state()) /* also may cause a line turnaround */
1052 sca_start_transmit(iocc_addr, 0);
1053
1054 sca_start_timer(TIMER_125S, sim_os_msec());
1055 }
1056 }
1057
1058 if (modify & 0x08) { /* bit 12 */
1059 /* diagnostic mode. What does this do?!? */
1060 #if (DEBUG_SCA & DEBUG_SCA_XIO_CONTROL)
1061 printf("(diag mode)\n");
1062 #endif
1063 }
1064
1065 if (modify & 0x04) { /* bit 13 */
1066 /* end operation (reset adapter. See references to this in FC manual). In transmit mode the real adapter delays this
1067 * function until current character has been sent. We don't need to do that as the character got buffered for transmission
1068 * immediately on XIO_WRITE.
1069 */
1070
1071 #if (DEBUG_SCA & (DEBUG_SCA_XIO_CONTROL|DEBUG_SCA_XIO_INITR|DEBUG_SCA_XIO_INITW))
1072 printf("(end operation)\n");
1073 #endif
1074 sca_state = SCA_STATE_IDLE;
1075 sca_timer_state[0] = sca_timer_state[1] = sca_timer_state[2] = SCA_TIMER_INACTIVE;
1076 any_timer_running = FALSE;
1077 sca_timer_trigger = FALSE;
1078 sca_nsyns = 0; /* reset SYN suppression */
1079 CLRBIT(sca_dsw, SCA_DSW_BUSY);
1080 }
1081
1082 if (modify & 0x02) { /* bit 14 */
1083 #if (DEBUG_SCA & DEBUG_SCA_XIO_CONTROL)
1084 printf("(6 bit frame)\n");
1085 #endif
1086 /* set six bit character frame. This is reset to 8 bits at every line turnaround */
1087 sca_frame = 6;
1088 }
1089
1090 if (modify & 0x01) { /* bit 15 */
1091 #if (DEBUG_SCA & DEBUG_SCA_XIO_CONTROL)
1092 printf("(7 bit frame)\n");
1093 #endif
1094 /* set seven bit character frame. This is reset to 8 bits at every line turnaround */
1095 sca_frame = 7;
1096 }
1097
1098 sca_flush();
1099 break;
1100
1101 case XIO_INITW: /* ***** XIO_INITW - put SCA in transmit mode */
1102 #if (DEBUG_SCA & DEBUG_SCA_XIO_INITW)
1103 printf("SCA INITW addr %04x mod %02x\n", iocc_addr, modify);
1104 #endif
1105 /* enter transmit mode. Causes line turnaround. Resets frame to 8 bits. */
1106 /* (may cause syncing, may involve a fixed timeout?) */
1107 sca_frame = 8;
1108 sca_start_transmit(iocc_addr, modify); /* this code pulled out to a subroutine cuz transmit can be started from XIO_CONTROL too */
1109 break;
1110
1111 case XIO_INITR: /* ***** XIO_INITR - put SCA in receive mode */
1112 #if (DEBUG_SCA & DEBUG_SCA_XIO_INITR)
1113 printf("SCA INITR addr %04x mod %02x\n", iocc_addr, modify);
1114 #endif
1115 sca_flush();
1116
1117 sca_nrcvd = sca_rcvptr = 0; /* discard any data previously read! */
1118 sca_nsyns = 0; /* reset SYN suppression */
1119
1120 /* enter receive mode. Causes line turnaround (e.g. resets to 8 bit frame). Modifier bits are used here too */
1121 /* (may cause syncing, may involve a fixed timeout?) */
1122
1123 sca_frame = 8;
1124 if (! in_receive_state())
1125 sca_state = SCA_STATE_TURN_RECEIVE; /* begin line turnaround */
1126 else
1127 sca_state = SCA_STATE_RECEIVE_SYNC;
1128
1129 SETBIT(sca_dsw, SCA_DSW_BUSY); /* SCA is now busy, in receive mode */
1130
1131 if (in_bsc_mode()) /* in BSC mode, start the 3 second timer when we enter receive mode */
1132 sca_start_timer(TIMER_3S, sim_os_msec());
1133
1134 break;
1135
1136 case XIO_SENSE_DEV: /* ***** XIO_SENSE_DEV - read device status word */
1137 #if (DEBUG_SCA & DEBUG_SCA_XIO_SENSE_DEV)
1138 printf("SCA SNS mod %02x dsw %04x\n", modify, sca_dsw);
1139 #endif
1140 ACC = sca_dsw; /* return DSW in accumulator */
1141
1142 if (modify & 0x01) { /* bit 15: reset interrupts */
1143 #if (DEBUG_SCA & DEBUG_SCA_XIO_SENSE_DEV)
1144 printf("(reset interrupts)\n");
1145 #endif
1146 CLRBIT(sca_dsw, SCA_DSW_READ_RESPONSE | SCA_DSW_WRITE_RESPONSE | SCA_DSW_CHECK | SCA_DSW_TIMEOUT | SCA_DSW_AUTOANSWER_REQUEST);
1147 CLRBIT(ILSW[1], ILSW_1_SCA);
1148 }
1149
1150 if (modify & 0x02) { /* bit 14: restart running timers */
1151 #if (DEBUG_SCA & (DEBUG_SCA_XIO_SENSE_DEV|DEBUG_SCA_TIMERS))
1152 printf("(restart timers)\n");
1153 #endif
1154 msec_now = sim_os_msec(); /* restart "any running timer?" All three, really? */
1155 for (i = 0; i < 3; i++)
1156 if (sca_timer_state[i] == SCA_TIMER_RUNNING || sca_timer_state[i] == SCA_TIMER_TIMEDOUT)
1157 sca_start_timer(i, msec_now);
1158 }
1159 break;
1160
1161 default:
1162 sprintf(msg, "Invalid SCA XIO function %x", func);
1163 xio_error(msg);
1164 }
1165 }