~ubuntu-branches/ubuntu/raring/simh/raring

« back to all changes in this revision

Viewing changes to PDP1/pdp1_dcs.c

  • Committer: Bazaar Package Importer
  • Author(s): Vince Mulhollon
  • Date: 2007-04-13 20:16:15 UTC
  • mfrom: (1.1.7 upstream) (2.1.3 lenny)
  • Revision ID: james.westby@ubuntu.com-20070413201615-jiar46bgkrs0dw2h
Tags: 3.7.0-1
* New upstream released 03-Feb-2007
* i7094 added which emulates the IBM 7090/7094
* Upstream has converted almost entirely to pdf format for docs
* All manpages updated
* All docs are registered with the doc-base system

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* pdp1_dcs.c: PDP-1D terminal multiplexor simulator
 
2
 
 
3
   Copyright (c) 2006, Robert M Supnik
 
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
   ROBERT M SUPNIK 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 Robert M Supnik 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 Robert M Supnik.
 
25
 
 
26
   dcs          Type 630 data communications subsystem
 
27
 
 
28
   This module implements up to 32 individual serial interfaces.
 
29
*/
 
30
 
 
31
#include "pdp1_defs.h"
 
32
#include "sim_sock.h"
 
33
#include "sim_tmxr.h"
 
34
 
 
35
#define DCS_LINES       32                              /* lines */
 
36
#define DCS_LINE_MASK   (DCS_LINES - 1)
 
37
#define DCSL_WAIT       1000                            /* output wait */
 
38
#define DCS_NUMLIN      dcs_desc.lines
 
39
 
 
40
int32 dcs_sbs = 0;                                      /* SBS level */
 
41
uint32 dcs_send = 0;                                    /* line for send */
 
42
uint32 dcs_scan = 0;                                    /* line for scanner */
 
43
uint8 dcs_flg[DCS_LINES];                               /* line flags */
 
44
uint8 dcs_buf[DCS_LINES];                               /* line bufffers */
 
45
 
 
46
extern int32 iosta, stop_inst;
 
47
extern int32 tmxr_poll;
 
48
 
 
49
TMLN dcs_ldsc[DCS_LINES] = { 0 };                       /* line descriptors */
 
50
TMXR dcs_desc = { DCS_LINES, 0, 0, dcs_ldsc };          /* mux descriptor */
 
51
 
 
52
t_stat dcsi_svc (UNIT *uptr);
 
53
t_stat dcso_svc (UNIT *uptr);
 
54
t_stat dcs_reset (DEVICE *dptr);
 
55
t_stat dcs_attach (UNIT *uptr, char *cptr);
 
56
t_stat dcs_detach (UNIT *uptr);
 
57
t_stat dcs_summ (FILE *st, UNIT *uptr, int32 val, void *desc);
 
58
t_stat dcs_show (FILE *st, UNIT *uptr, int32 val, void *desc);
 
59
t_stat dcs_vlines (UNIT *uptr, int32 val, char *cptr, void *desc);
 
60
void dcs_reset_ln (int32 ln);
 
61
void dcs_scan_next (t_bool unlk);
 
62
 
 
63
/* DCS data structures
 
64
 
 
65
   dcs_dev      DCS device descriptor
 
66
   dcs_unit     DCS unit descriptor
 
67
   dcs_reg      DCS register list
 
68
   dcs_mod      DCS modifiers list
 
69
*/
 
70
 
 
71
REG dcs_nlreg = { DRDATA (NLINES, DCS_NUMLIN, 6), PV_LEFT };
 
72
 
 
73
UNIT dcs_unit = { UDATA (&dcsi_svc, UNIT_ATTABLE, 0) };
 
74
 
 
75
REG dcs_reg[] = {
 
76
    { BRDATA (BUF, dcs_buf, 8, 8, DCS_LINES) },
 
77
    { BRDATA (FLAGS, dcs_flg, 8, 1, DCS_LINES) },
 
78
    { FLDATA (SCNF, iosta, IOS_V_DCS) },
 
79
    { ORDATA (SCAN, dcs_scan, 5) },
 
80
    { ORDATA (SEND, dcs_send, 5) },
 
81
    { DRDATA (SBSLVL, dcs_sbs, 4), REG_HRO },
 
82
    { NULL }
 
83
    };
 
84
 
 
85
MTAB dcs_mod[] = {
 
86
    { MTAB_XTD|MTAB_VDV, 0, "SBSLVL", "SBSLVL",
 
87
      &dev_set_sbs, &dev_show_sbs, (void *) &dcs_sbs },
 
88
    { MTAB_XTD | MTAB_VDV | MTAB_VAL, 0, "lines", "LINES",
 
89
      &dcs_vlines, NULL, &dcs_nlreg },
 
90
    { MTAB_XTD | MTAB_VDV, 1, NULL, "DISCONNECT",
 
91
      &tmxr_dscln, NULL, &dcs_desc },
 
92
    { UNIT_ATT, UNIT_ATT, "connections", NULL, NULL, &dcs_summ },
 
93
    { MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", NULL,
 
94
      NULL, &dcs_show, NULL },
 
95
    { MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATISTICS", NULL,
 
96
      NULL, &dcs_show, NULL },
 
97
    { 0 }
 
98
    };
 
99
 
 
100
DEVICE dcs_dev = {
 
101
    "DCS", &dcs_unit, dcs_reg, dcs_mod,
 
102
    1, 10, 31, 1, 8, 8,
 
103
    &tmxr_ex, &tmxr_dep, &dcs_reset,
 
104
    NULL, &dcs_attach, &dcs_detach,
 
105
    NULL, DEV_NET | DEV_DISABLE | DEV_DIS
 
106
    };
 
107
 
 
108
/* DCSL data structures
 
109
 
 
110
   dcsl_dev     DCSL device descriptor
 
111
   dcsl_unit    DCSL unit descriptor
 
112
   dcsl_reg     DCSL register list
 
113
   dcsl_mod     DCSL modifiers list
 
114
*/
 
115
 
 
116
UNIT dcsl_unit[] = {
 
117
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
118
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
119
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
120
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
121
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
122
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
123
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
124
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
125
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
126
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
127
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
128
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
129
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
130
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
131
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
132
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
133
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
134
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
135
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
136
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
137
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
138
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
139
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
140
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
141
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
142
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
143
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
144
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
145
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
146
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
147
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT },
 
148
    { UDATA (&dcso_svc, TT_MODE_UC, 0), DCSL_WAIT }
 
149
    };
 
150
 
 
151
MTAB dcsl_mod[] = {
 
152
    { TT_MODE, TT_MODE_UC, "UC", "UC", NULL },
 
153
    { TT_MODE, TT_MODE_7B, "7b", "7B", NULL },
 
154
    { TT_MODE, TT_MODE_8B, "8b", "8B", NULL },
 
155
    { TT_MODE, TT_MODE_7P, "7p", "7P", NULL },
 
156
    { MTAB_XTD|MTAB_VUN, 0, NULL, "DISCONNECT",
 
157
      &tmxr_dscln, NULL, &dcs_desc },
 
158
    { MTAB_XTD|MTAB_VUN|MTAB_NC, 0, "LOG", "LOG",
 
159
      &tmxr_set_log, &tmxr_show_log, &dcs_desc },
 
160
    { MTAB_XTD|MTAB_VUN|MTAB_NC, 0, NULL, "NOLOG",
 
161
      &tmxr_set_nolog, NULL, &dcs_desc },
 
162
    { 0 }
 
163
    };
 
164
 
 
165
REG dcsl_reg[] = {
 
166
    { URDATA (TIME, dcsl_unit[0].wait, 10, 24, 0,
 
167
              DCS_LINES, REG_NZ + PV_LEFT) },
 
168
    { NULL }
 
169
    };
 
170
 
 
171
DEVICE dcsl_dev = {
 
172
    "DCSL", dcsl_unit, dcsl_reg, dcsl_mod,
 
173
    DCS_LINES, 10, 31, 1, 8, 8,
 
174
    NULL, NULL, &dcs_reset,
 
175
    NULL, NULL, NULL,
 
176
    NULL, DEV_DIS
 
177
    };
 
178
 
 
179
/* DCS IOT routine */
 
180
 
 
181
int32 dcs (int32 inst, int32 dev, int32 dat)
 
182
{
 
183
int32 pls = (inst >> 6) & 077;
 
184
 
 
185
if (dcs_dev.flags & DEV_DIS)                            /* disabled? */
 
186
    return (stop_inst << IOT_V_REASON) | dat;           /* illegal inst */
 
187
if (pls & 020) dat = 0;                                 /* pulse 20? clr IO */
 
188
 
 
189
switch (pls & 057) {                                    /* case IR<6,8:11> */
 
190
 
 
191
    case 000:                                           /* RCH */
 
192
        dat |= dcs_buf[dcs_scan];                       /* return line buf */
 
193
        dcs_flg[dcs_scan] = 0;                          /* clr line flag */
 
194
        break;
 
195
 
 
196
    case 001:                                           /* RRC */
 
197
        dat |= dcs_scan;                                /* return line num */
 
198
        break;
 
199
 
 
200
    case 010:                                           /* RCC */
 
201
        dat |= dcs_buf[dcs_scan];                       /* return line buf */
 
202
        dcs_flg[dcs_scan] = 0;                          /* clr line flag */
 
203
                                                        /* fall through */
 
204
    case 011:                                           /* RSC */
 
205
        dcs_scan_next (TRUE);                           /* unlock scanner */
 
206
        break;
 
207
 
 
208
    case 040:                                           /* TCB */
 
209
        dcs_buf[dcs_send] = dat & 0377;                 /* load buffer */
 
210
        dcs_flg[dcs_send] = 0;                          /* clr line flag */
 
211
        sim_activate (&dcsl_unit[dcs_send], dcsl_unit[dcs_send].wait);
 
212
        break;
 
213
 
 
214
    case 041:                                           /* SSB */
 
215
        dcs_send = dat & DCS_LINE_MASK;                 /* load line num */
 
216
        break;
 
217
 
 
218
    case 050:                                           /* TCC */
 
219
        dcs_buf[dcs_scan] = dat & 0377;                 /* load buffer */
 
220
        dcs_flg[dcs_scan] = 0;                          /* clr line flag */
 
221
        sim_activate (&dcsl_unit[dcs_scan], dcsl_unit[dcs_scan].wait);
 
222
        dcs_scan_next (TRUE);                           /* unlock scanner */
 
223
        break;
 
224
 
 
225
    default:
 
226
        return (stop_inst << IOT_V_REASON) | dat;       /* illegal inst */
 
227
        }                                               /* end case */
 
228
 
 
229
return dat;
 
230
}
 
231
 
 
232
/* Unit service - receive side
 
233
 
 
234
   Poll all active lines for input
 
235
   Poll for new connections
 
236
*/
 
237
 
 
238
t_stat dcsi_svc (UNIT *uptr)
 
239
{
 
240
int32 ln, c, out;
 
241
 
 
242
if ((uptr->flags & UNIT_ATT) == 0) return SCPE_OK;      /* attached? */
 
243
if (dcs_dev.flags & DEV_DIS) return SCPE_OK;
 
244
sim_activate (uptr, tmxr_poll);                         /* continue poll */
 
245
ln = tmxr_poll_conn (&dcs_desc);                        /* look for connect */
 
246
if (ln >= 0) {                                          /* got one? */
 
247
    dcs_ldsc[ln].rcve = 1;                              /* set rcv enable */
 
248
    }
 
249
tmxr_poll_rx (&dcs_desc);                               /* poll for input */
 
250
for (ln = 0; ln < DCS_NUMLIN; ln++) {                   /* loop thru lines */
 
251
    if (dcs_ldsc[ln].conn) {                            /* connected? */
 
252
        if (c = tmxr_getc_ln (&dcs_ldsc[ln])) {         /* get char */
 
253
            if (c & SCPE_BREAK) c = 0;                  /* break? */
 
254
            else c = sim_tt_inpcvt (c, TT_GET_MODE (dcsl_unit[ln].flags)|TTUF_KSR);
 
255
            dcs_buf[ln] = c;                            /* save char */
 
256
            dcs_flg[ln] = 1;                            /* set line flag */
 
257
            dcs_scan_next (FALSE);                      /* kick scanner */
 
258
            out = sim_tt_outcvt (c & 0177, TT_GET_MODE (dcsl_unit[ln].flags));
 
259
            if (out >= 0) {
 
260
                tmxr_putc_ln (&dcs_ldsc[ln], out);      /* echo char */
 
261
                tmxr_poll_tx (&dcs_desc);               /* poll xmt */
 
262
                }
 
263
            }
 
264
        }
 
265
    else dcs_ldsc[ln].rcve = 0;                         /* disconnected */
 
266
    }                                                   /* end for */
 
267
return SCPE_OK;
 
268
}
 
269
 
 
270
/* Unit service - transmit side */
 
271
 
 
272
t_stat dcso_svc (UNIT *uptr)
 
273
{
 
274
int32 c;
 
275
uint32 ln = uptr - dcsl_unit;                           /* line # */
 
276
 
 
277
if (dcs_dev.flags & DEV_DIS) return SCPE_OK;
 
278
if (dcs_ldsc[ln].conn) {                                /* connected? */
 
279
    if (dcs_ldsc[ln].xmte) {                            /* xmt enabled? */
 
280
        c = sim_tt_outcvt (dcs_buf[ln] & 0177, TT_GET_MODE (uptr->flags));
 
281
        if (c >= 0) tmxr_putc_ln (&dcs_ldsc[ln], c);    /* output char */
 
282
        tmxr_poll_tx (&dcs_desc);                       /* poll xmt */
 
283
        }
 
284
    else {                                              /* buf full */
 
285
        tmxr_poll_tx (&dcs_desc);                       /* poll xmt */
 
286
        sim_activate (uptr, uptr->wait);                /* reschedule */
 
287
        return SCPE_OK;
 
288
        }
 
289
    }
 
290
dcs_flg[ln] = 1;                                        /* set line flag */
 
291
dcs_scan_next (FALSE);                                  /* kick scanner */
 
292
return SCPE_OK;
 
293
}
 
294
 
 
295
/* Kick scanner */
 
296
 
 
297
void dcs_scan_next (t_bool unlk)
 
298
{
 
299
int32 i;
 
300
 
 
301
if (unlk) iosta &= ~IOS_DCS;                            /* unlock? */
 
302
else if (iosta & IOS_DCS) return;                       /* no, locked? */
 
303
for (i = 0; i < DCS_LINES; i++) {                       /* scan flags */
 
304
    dcs_scan = (dcs_scan + 1) & DCS_LINE_MASK;          /* next flag */
 
305
    if (dcs_flg[dcs_scan] != 0) {                       /* flag set? */
 
306
        iosta |= IOS_DCS;                               /* lock scanner */
 
307
        dev_req_int (dcs_sbs);                          /* request intr */
 
308
        return;
 
309
        }
 
310
    }
 
311
return;
 
312
}
 
313
 
 
314
/* Reset routine */
 
315
 
 
316
t_stat dcs_reset (DEVICE *dptr)
 
317
{
 
318
int32 i;
 
319
 
 
320
if (dcs_dev.flags & DEV_DIS)                            /* master disabled? */
 
321
    dcsl_dev.flags = dcsl_dev.flags | DEV_DIS;          /* disable lines */
 
322
else dcsl_dev.flags = dcsl_dev.flags & ~DEV_DIS;
 
323
if (dcs_unit.flags & UNIT_ATT)                          /* master att? */
 
324
    sim_activate_abs (&dcs_unit, tmxr_poll);            /* activate */
 
325
else sim_cancel (&dcs_unit);                            /* else stop */
 
326
for (i = 0; i < DCS_LINES; i++) dcs_reset_ln (i);       /* reset lines */
 
327
dcs_send = 0;
 
328
dcs_scan = 0;
 
329
iosta &= ~IOS_DCS;                                      /* clr intr req */
 
330
return SCPE_OK;
 
331
}
 
332
 
 
333
/* Attach master unit */
 
334
 
 
335
t_stat dcs_attach (UNIT *uptr, char *cptr)
 
336
{
 
337
t_stat r;
 
338
 
 
339
r = tmxr_attach (&dcs_desc, uptr, cptr);                /* attach */
 
340
if (r != SCPE_OK) return r;                             /* error */
 
341
sim_activate_abs (uptr, tmxr_poll);                     /* start poll */
 
342
return SCPE_OK;
 
343
}
 
344
 
 
345
/* Detach master unit */
 
346
 
 
347
t_stat dcs_detach (UNIT *uptr)
 
348
{
 
349
int32 i;
 
350
t_stat r;
 
351
 
 
352
r = tmxr_detach (&dcs_desc, uptr);                      /* detach */
 
353
for (i = 0; i < DCS_LINES; i++) dcs_ldsc[i].rcve = 0;   /* disable rcv */
 
354
sim_cancel (uptr);                                      /* stop poll */
 
355
return r;
 
356
}
 
357
 
 
358
/* Show summary processor */
 
359
 
 
360
t_stat dcs_summ (FILE *st, UNIT *uptr, int32 val, void *desc)
 
361
{
 
362
int32 i, t;
 
363
 
 
364
for (i = t = 0; i < DCS_LINES; i++) t = t + (dcs_ldsc[i].conn != 0);
 
365
if (t == 1) fprintf (st, "1 connection");
 
366
else fprintf (st, "%d connections", t);
 
367
return SCPE_OK;
 
368
}
 
369
 
 
370
/* SHOW CONN/STAT processor */
 
371
 
 
372
t_stat dcs_show (FILE *st, UNIT *uptr, int32 val, void *desc)
 
373
{
 
374
int32 i, t;
 
375
 
 
376
for (i = t = 0; i < DCS_LINES; i++) t = t + (dcs_ldsc[i].conn != 0);
 
377
if (t) {
 
378
    for (i = 0; i < DCS_LINES; i++) {
 
379
        if (dcs_ldsc[i].conn) {
 
380
            if (val) tmxr_fconns (st, &dcs_ldsc[i], i);
 
381
            else tmxr_fstats (st, &dcs_ldsc[i], i);
 
382
            }
 
383
        }
 
384
    }
 
385
else fprintf (st, "all disconnected\n");
 
386
return SCPE_OK;
 
387
}
 
388
 
 
389
/* Change number of lines */
 
390
 
 
391
t_stat dcs_vlines (UNIT *uptr, int32 val, char *cptr, void *desc)
 
392
{
 
393
int32 newln, i, t;
 
394
t_stat r;
 
395
 
 
396
if (cptr == NULL) return SCPE_ARG;
 
397
newln = get_uint (cptr, 10, DCS_LINES, &r);
 
398
if ((r != SCPE_OK) || (newln == DCS_NUMLIN)) return r;
 
399
if (newln == 0) return SCPE_ARG;
 
400
if (newln < DCS_LINES) {
 
401
    for (i = newln, t = 0; i < DCS_NUMLIN; i++) t = t | dcs_ldsc[i].conn;
 
402
    if (t && !get_yn ("This will disconnect users; proceed [N]?", FALSE))
 
403
            return SCPE_OK;
 
404
    for (i = newln; i < DCS_NUMLIN; i++) {
 
405
        if (dcs_ldsc[i].conn) {
 
406
            tmxr_linemsg (&dcs_ldsc[i], "\r\nOperator disconnected line\r\n");
 
407
            tmxr_reset_ln (&dcs_ldsc[i]);               /* reset line */
 
408
            }
 
409
        dcsl_unit[i].flags = dcsl_unit[i].flags | UNIT_DIS;
 
410
        dcs_reset_ln (i);
 
411
        }
 
412
    }
 
413
else {
 
414
    for (i = DCS_NUMLIN; i < newln; i++) {
 
415
        dcsl_unit[i].flags = dcsl_unit[i].flags & ~UNIT_DIS;
 
416
        dcs_reset_ln (i);
 
417
        }
 
418
    }
 
419
DCS_NUMLIN = newln;
 
420
return SCPE_OK;
 
421
}
 
422
 
 
423
/* Reset an individual line */
 
424
 
 
425
void dcs_reset_ln (int32 ln)
 
426
{
 
427
sim_cancel (&dcsl_unit[ln]);
 
428
dcs_buf[ln] = 0;
 
429
dcs_flg[ln] = 0;
 
430
return;
 
431
}