~ubuntu-branches/ubuntu/utopic/simh/utopic

« back to all changes in this revision

Viewing changes to PDP8/pdp8_tt.c

  • Committer: Bazaar Package Importer
  • Author(s): Vince Mulhollon
  • Date: 2004-04-20 20:01:26 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040420200126-ehsuleda8xcgi51h
Tags: 3.2.0-1
New upstream 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* pdp8_tt.c: PDP-8 console terminal simulator
 
2
 
 
3
   Copyright (c) 1993-2004, 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
 
23
   be 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
   tti,tto      KL8E terminal input/output
 
27
 
 
28
   29-Dec-03    RMS     Added console output backpressure support
 
29
   25-Apr-03    RMS     Revised for extended file support
 
30
   02-Mar-02    RMS     Added SET TTI CTRL-C
 
31
   22-Dec-02    RMS     Added break support
 
32
   01-Nov-02    RMS     Added 7B/8B support
 
33
   04-Oct-02    RMS     Added DIBs, device number support
 
34
   30-May-02    RMS     Widened POS to 32b
 
35
   07-Sep-01    RMS     Moved function prototypes
 
36
*/
 
37
 
 
38
#include "pdp8_defs.h"
 
39
#include <ctype.h>
 
40
 
 
41
#define UNIT_V_8B       (UNIT_V_UF + 0)                 /* 8B */
 
42
#define UNIT_V_KSR      (UNIT_V_UF + 1)                 /* KSR33 */
 
43
#define UNIT_8B         (1 << UNIT_V_8B)
 
44
#define UNIT_KSR        (1 << UNIT_V_KSR)
 
45
 
 
46
extern int32 int_req, int_enable, dev_done, stop_inst;
 
47
 
 
48
int32 tti (int32 IR, int32 AC);
 
49
int32 tto (int32 IR, int32 AC);
 
50
t_stat tti_svc (UNIT *uptr);
 
51
t_stat tto_svc (UNIT *uptr);
 
52
t_stat tti_reset (DEVICE *dptr);
 
53
t_stat tto_reset (DEVICE *dptr);
 
54
t_stat tti_set_ctrlc (UNIT *uptr, int32 val, char *cptr, void *desc);
 
55
t_stat tty_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc);
 
56
 
 
57
/* TTI data structures
 
58
 
 
59
   tti_dev      TTI device descriptor
 
60
   tti_unit     TTI unit descriptor
 
61
   tti_reg      TTI register list
 
62
   tti_mod      TTI modifiers list
 
63
*/
 
64
 
 
65
DIB tti_dib = { DEV_TTI, 1, { &tti } };
 
66
 
 
67
UNIT tti_unit = { UDATA (&tti_svc, UNIT_KSR, 0), KBD_POLL_WAIT };
 
68
 
 
69
REG tti_reg[] = {
 
70
        { ORDATA (BUF, tti_unit.buf, 8) },
 
71
        { FLDATA (DONE, dev_done, INT_V_TTI) },
 
72
        { FLDATA (ENABLE, int_enable, INT_V_TTI) },
 
73
        { FLDATA (INT, int_req, INT_V_TTI) },
 
74
        { DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT },
 
75
        { DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
 
76
        { FLDATA (UC, tti_unit.flags, UNIT_V_KSR), REG_HRO },
 
77
        { NULL }  };
 
78
 
 
79
MTAB tti_mod[] = {
 
80
        { UNIT_KSR+UNIT_8B, UNIT_KSR, "KSR", "KSR", &tty_set_mode },
 
81
        { UNIT_KSR+UNIT_8B, 0       , "7b" , "7B" , &tty_set_mode },
 
82
        { UNIT_KSR+UNIT_8B, UNIT_8B , "8b" , "8B" , &tty_set_mode },
 
83
        { MTAB_XTD|MTAB_VDV|MTAB_VUN, 0, NULL, "CTRL-C", &tti_set_ctrlc, NULL, NULL },
 
84
        { MTAB_XTD|MTAB_VDV, 0, "DEVNO", NULL, NULL, &show_dev, NULL },
 
85
        { 0 }  };
 
86
 
 
87
DEVICE tti_dev = {
 
88
        "TTI", &tti_unit, tti_reg, tti_mod,
 
89
        1, 10, 31, 1, 8, 8,
 
90
        NULL, NULL, &tti_reset,
 
91
        NULL, NULL, NULL,
 
92
        &tti_dib, 0 };
 
93
 
 
94
/* TTO data structures
 
95
 
 
96
   tto_dev      TTO device descriptor
 
97
   tto_unit     TTO unit descriptor
 
98
   tto_reg      TTO register list
 
99
*/
 
100
 
 
101
DIB tto_dib = { DEV_TTO, 1, { &tto } };
 
102
 
 
103
UNIT tto_unit = { UDATA (&tto_svc, UNIT_KSR, 0), SERIAL_OUT_WAIT };
 
104
 
 
105
REG tto_reg[] = {
 
106
        { ORDATA (BUF, tto_unit.buf, 8) },
 
107
        { FLDATA (DONE, dev_done, INT_V_TTO) },
 
108
        { FLDATA (ENABLE, int_enable, INT_V_TTO) },
 
109
        { FLDATA (INT, int_req, INT_V_TTO) },
 
110
        { DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT },
 
111
        { DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
 
112
        { NULL }  };
 
113
 
 
114
MTAB tto_mod[] = {
 
115
        { UNIT_KSR+UNIT_8B, UNIT_KSR, "KSR", "KSR", &tty_set_mode },
 
116
        { UNIT_KSR+UNIT_8B, 0       , "7b" , "7B" , &tty_set_mode },
 
117
        { UNIT_KSR+UNIT_8B, UNIT_8B , "8b" , "8B" , &tty_set_mode },
 
118
        { MTAB_XTD|MTAB_VDV, 0, "DEVNO", NULL, NULL, &show_dev },
 
119
        { 0 }  };
 
120
 
 
121
DEVICE tto_dev = {
 
122
        "TTO", &tto_unit, tto_reg, tto_mod,
 
123
        1, 10, 31, 1, 8, 8,
 
124
        NULL, NULL, &tto_reset, 
 
125
        NULL, NULL, NULL,
 
126
        &tto_dib, 0 };
 
127
 
 
128
/* Terminal input: IOT routine */
 
129
 
 
130
int32 tti (int32 IR, int32 AC)
 
131
{
 
132
switch (IR & 07) {                                      /* decode IR<9:11> */
 
133
case 0:                                                 /* KCF */
 
134
        dev_done = dev_done & ~INT_TTI;                 /* clear flag */
 
135
        int_req = int_req & ~INT_TTI;
 
136
        return AC;
 
137
case 1:                                                 /* KSF */
 
138
        return (dev_done & INT_TTI)? IOT_SKP + AC: AC;
 
139
case 2:                                                 /* KCC */
 
140
        dev_done = dev_done & ~INT_TTI;                 /* clear flag */
 
141
        int_req = int_req & ~INT_TTI;
 
142
        return 0;                                       /* clear AC */
 
143
case 4:                                                 /* KRS */
 
144
        return (AC | tti_unit.buf);                     /* return buffer */
 
145
case 5:                                                 /* KIE */
 
146
        if (AC & 1) int_enable = int_enable | (INT_TTI+INT_TTO);
 
147
        else int_enable = int_enable & ~(INT_TTI+INT_TTO);
 
148
        int_req = INT_UPDATE;                           /* update interrupts */
 
149
        return AC;
 
150
case 6:                                                 /* KRB */
 
151
        dev_done = dev_done & ~INT_TTI;                 /* clear flag */
 
152
        int_req = int_req & ~INT_TTI;
 
153
        return (tti_unit.buf);                          /* return buffer */
 
154
default:
 
155
        return (stop_inst << IOT_V_REASON) + AC;  }     /* end switch */
 
156
}
 
157
 
 
158
/* Unit service */
 
159
 
 
160
t_stat tti_svc (UNIT *uptr)
 
161
{
 
162
int32 c;
 
163
 
 
164
sim_activate (&tti_unit, tti_unit.wait);                /* continue poll */
 
165
if ((c = sim_poll_kbd ()) < SCPE_KFLAG) return c;       /* no char or error? */
 
166
if (c & SCPE_BREAK) tti_unit.buf = 0;                   /* break? */
 
167
else if (tti_unit.flags & UNIT_KSR) {                   /* KSR? */
 
168
        c = c & 0177;
 
169
        if (islower (c)) c = toupper (c);
 
170
        tti_unit.buf = c | 0200;  }                     /* add TTY bit */
 
171
else tti_unit.buf = c & ((tti_unit.flags & UNIT_8B)? 0377: 0177);
 
172
tti_unit.pos = tti_unit.pos + 1;
 
173
dev_done = dev_done | INT_TTI;                          /* set done */
 
174
int_req = INT_UPDATE;                                   /* update interrupts */
 
175
return SCPE_OK;
 
176
}
 
177
 
 
178
/* Reset routine */
 
179
 
 
180
t_stat tti_reset (DEVICE *dptr)
 
181
{
 
182
tti_unit.buf = 0;
 
183
dev_done = dev_done & ~INT_TTI;                         /* clear done, int */
 
184
int_req = int_req & ~INT_TTI;
 
185
int_enable = int_enable | INT_TTI;                      /* set enable */
 
186
sim_activate (&tti_unit, tti_unit.wait);                /* activate unit */
 
187
return SCPE_OK;
 
188
}
 
189
 
 
190
/* Set control-C */
 
191
 
 
192
t_stat tti_set_ctrlc (UNIT *uptr, int32 val, char *cptr, void *desc)
 
193
{
 
194
if (cptr) return SCPE_ARG;
 
195
uptr->buf = (uptr->flags & UNIT_KSR)? 0203: 0003;
 
196
uptr->pos = uptr->pos + 1;
 
197
dev_done = dev_done | INT_TTI;                          /* set done */
 
198
int_req = INT_UPDATE;                                   /* update interrupts */
 
199
return SCPE_OK;
 
200
}
 
201
 
 
202
/* Terminal output: IOT routine */
 
203
 
 
204
int32 tto (int32 IR, int32 AC)
 
205
{
 
206
switch (IR & 07) {                                      /* decode IR<9:11> */
 
207
case 0:                                                 /* TLF */
 
208
        dev_done = dev_done | INT_TTO;                  /* set flag */
 
209
        int_req = INT_UPDATE;                           /* update interrupts */
 
210
        return AC;
 
211
case 1:                                                 /* TSF */
 
212
        return (dev_done & INT_TTO)? IOT_SKP + AC: AC;
 
213
case 2:                                                 /* TCF */
 
214
        dev_done = dev_done & ~INT_TTO;                 /* clear flag */
 
215
        int_req = int_req & ~INT_TTO;                   /* clear int req */
 
216
        return AC;
 
217
case 5:                                                 /* SPI */
 
218
        return (int_req & (INT_TTI+INT_TTO))? IOT_SKP + AC: AC;
 
219
case 6:                                                 /* TLS */
 
220
        dev_done = dev_done & ~INT_TTO;                 /* clear flag */
 
221
        int_req = int_req & ~INT_TTO;                   /* clear int req */
 
222
case 4:                                                 /* TPC */
 
223
        sim_activate (&tto_unit, tto_unit.wait);        /* activate unit */
 
224
        tto_unit.buf = AC;                              /* load buffer */
 
225
        return AC;
 
226
default:
 
227
        return (stop_inst << IOT_V_REASON) + AC;  }     /* end switch */
 
228
}
 
229
 
 
230
/* Unit service */
 
231
 
 
232
t_stat tto_svc (UNIT *uptr)
 
233
{
 
234
int32 c;
 
235
t_stat r;
 
236
 
 
237
if (tto_unit.flags & UNIT_KSR) {                        /* UC only? */
 
238
        c = tto_unit.buf & 0177;
 
239
        if (islower (c)) c = toupper (c);  }
 
240
else c = tto_unit.buf & ((tto_unit.flags & UNIT_8B)? 0377: 0177);
 
241
if ((r = sim_putchar_s (c)) != SCPE_OK) {               /* output char; error? */
 
242
        sim_activate (uptr, uptr->wait);                /* try again */
 
243
        return ((r == SCPE_STALL)? SCPE_OK: r);  }      /* if !stall, report */
 
244
dev_done = dev_done | INT_TTO;                          /* set done */
 
245
int_req = INT_UPDATE;                                   /* update interrupts */
 
246
tto_unit.pos = tto_unit.pos + 1;
 
247
return SCPE_OK;
 
248
}
 
249
 
 
250
/* Reset routine */
 
251
 
 
252
t_stat tto_reset (DEVICE *dptr)
 
253
{
 
254
tto_unit.buf = 0;
 
255
dev_done = dev_done & ~INT_TTO;                         /* clear done, int */
 
256
int_req = int_req & ~INT_TTO;
 
257
int_enable = int_enable | INT_TTO;                      /* set enable */
 
258
sim_cancel (&tto_unit);                                 /* deactivate unit */
 
259
return SCPE_OK;
 
260
}
 
261
 
 
262
t_stat tty_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc)
 
263
{
 
264
tti_unit.flags = (tti_unit.flags & ~(UNIT_KSR | UNIT_8B)) | val;
 
265
tto_unit.flags = (tto_unit.flags & ~(UNIT_KSR | UNIT_8B)) | val;
 
266
return SCPE_OK;
 
267
}