forked from open-simh/simh
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkx10_cty.c
237 lines (204 loc) · 8.52 KB
/
kx10_cty.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
/* kx10_cty.c: PDP6, KA-10 and KI-10 front end (console terminal) simulator
Copyright (c) 2013-2020, Richard Cornwell
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
RICHARD CORNWELL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Richard Cornwell shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Richard Cornwell
*/
#include "kx10_defs.h"
#if PDP6 | KA | KI
#define UNIT_DUMMY (1 << UNIT_V_UF)
extern int32 tmxr_poll;
t_stat ctyi_svc (UNIT *uptr);
t_stat ctyo_svc (UNIT *uptr);
t_stat cty_reset (DEVICE *dptr);
t_stat cty_stop_os (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat tty_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat cty_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
const char *cty_description (DEVICE *dptr);
/* CTY data structures
cty_dev CTY device descriptor
cty_unit CTY unit descriptor
cty_reg CTY register list
*/
#define TEL_RDY 0010
#define TEL_BSY 0020
#define KEY_RDY 0040
#define KEY_BSY 0100
#define KEY_TST 04000
#define CTY_DEVNUM 0120
#define STATUS u3
#define DATA u4
#define PIA u5
t_stat cty_devio(uint32 dev, uint64 *data);
DIB cty_dib = { CTY_DEVNUM, 1, cty_devio, NULL};
UNIT cty_unit[] = {
{ UDATA (&ctyo_svc, TT_MODE_7B, 0), 10000 },
{ UDATA (&ctyi_svc, TT_MODE_7B|UNIT_IDLE, 0), 0 },
};
MTAB cty_mod[] = {
{ UNIT_DUMMY, 0, NULL, "STOP", &cty_stop_os },
{ TT_MODE, TT_MODE_UC, "UC", "UC", &tty_set_mode },
{ TT_MODE, TT_MODE_7B, "7b", "7B", &tty_set_mode },
{ TT_MODE, TT_MODE_8B, "8b", "8B", &tty_set_mode },
{ TT_MODE, TT_MODE_7P, "7p", "7P", &tty_set_mode },
{ 0 }
};
REG cty_reg[] = {
{ HRDATAD (WRU, sim_int_char, 8, "interrupt character") },
{ 0 }
};
DEVICE cty_dev = {
"CTY", cty_unit, cty_reg, cty_mod,
2, 10, 31, 1, 8, 8,
NULL, NULL, &cty_reset,
NULL, NULL, NULL, &cty_dib, DEV_DEBUG, 0, dev_debug,
NULL, NULL, &cty_help, NULL, NULL, &cty_description
};
t_stat cty_devio(uint32 dev, uint64 *data) {
uint64 res;
switch(dev & 3) {
case CONI:
res = cty_unit[0].PIA | (cty_unit[0].STATUS & (TEL_RDY | TEL_BSY));
res |= cty_unit[1].STATUS & (KEY_RDY | KEY_BSY);
res |= cty_unit[0].STATUS & KEY_TST;
*data = res;
sim_debug(DEBUG_CONI, &cty_dev, "CTY %03o CONI %06o\n", dev, (uint32)*data);
break;
case CONO:
res = *data;
cty_unit[0].PIA = res & 07;
cty_unit[1].PIA = res & 07;
cty_unit[0].PIA &= ~(KEY_TST);
cty_unit[0].STATUS &= ~((res >> 4) & (TEL_RDY | TEL_BSY));
cty_unit[0].STATUS |= (res & (TEL_RDY | TEL_BSY | KEY_TST));
cty_unit[1].STATUS &= ~((res >> 4) & (KEY_RDY | KEY_BSY));
cty_unit[1].STATUS |= (res & (KEY_RDY | KEY_BSY));
if ((cty_unit[0].STATUS & TEL_RDY) || (cty_unit[1].STATUS & KEY_RDY))
set_interrupt(dev, cty_unit[0].PIA);
else
clr_interrupt(dev);
sim_debug(DEBUG_CONO, &cty_dev, "CTY %03o CONO %06o\n", dev, (uint32)*data);
break;
case DATAI:
res = cty_unit[1].DATA & 0xff;
cty_unit[1].STATUS &= ~KEY_RDY;
if ((cty_unit[0].STATUS & TEL_RDY) == 0)
clr_interrupt(dev);
*data = res;
sim_debug(DEBUG_DATAIO, &cty_dev, "CTY %03o DATAI %06o\n", dev, (uint32)*data);
break;
case DATAO:
cty_unit[0].DATA = *data & 0x7f;
cty_unit[0].STATUS &= ~TEL_RDY;
cty_unit[0].STATUS |= TEL_BSY;
if ((cty_unit[1].STATUS & KEY_RDY) == 0)
clr_interrupt(dev);
sim_activate(&cty_unit[0], cty_unit[0].wait);
sim_debug(DEBUG_DATAIO, &cty_dev, "CTY %03o DATAO %06o\n", dev, (uint32)*data);
break;
}
return SCPE_OK;
}
t_stat ctyo_svc (UNIT *uptr)
{
t_stat r;
int32 ch;
if (uptr->DATA != 0) {
ch = sim_tt_outcvt ( uptr->DATA, TT_GET_MODE (uptr->flags)) ;
if ((r = sim_putchar_s (ch)) != SCPE_OK) { /* output; error? */
sim_activate (uptr, uptr->wait); /* try again */
return ((r == SCPE_STALL)? SCPE_OK: r); /* !stall? report */
}
}
uptr->STATUS &= ~TEL_BSY;
uptr->STATUS |= TEL_RDY;
set_interrupt(CTY_DEVNUM, uptr->PIA);
return SCPE_OK;
}
t_stat ctyi_svc (UNIT *uptr)
{
int32 ch;
sim_clock_coschedule (uptr, tmxr_poll);
/* continue poll */
if (uptr->STATUS & KEY_RDY)
return SCPE_OK;
if ((ch = sim_poll_kbd ()) < SCPE_KFLAG) /* no char or error? */
return ch;
if (ch & SCPE_BREAK) /* ignore break */
return SCPE_OK;
uptr->DATA = 0177 & sim_tt_inpcvt(ch, TT_GET_MODE (uptr->flags));
uptr->DATA = ch & 0177;
uptr->STATUS |= KEY_RDY;
set_interrupt(CTY_DEVNUM, uptr->PIA);
return SCPE_OK;
}
/* Reset */
t_stat cty_reset (DEVICE *dptr)
{
cty_unit[0].STATUS &= ~(TEL_RDY | TEL_BSY);
cty_unit[1].STATUS &= ~(KEY_RDY | KEY_BSY);
clr_interrupt(CTY_DEVNUM);
sim_clock_coschedule (&cty_unit[1], tmxr_poll);
return SCPE_OK;
}
/* Stop operating system */
t_stat cty_stop_os (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
#if ITS
if (cpu_unit[0].flags & UNIT_ITSPAGE)
M[037] = FMASK;
else
#endif
M[CTY_SWITCH] = 1; /* tell OS to stop */
return SCPE_OK;
}
t_stat tty_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
cty_unit[0].flags = (cty_unit[0].flags & ~TT_MODE) | val;
cty_unit[1].flags = (cty_unit[1].flags & ~TT_MODE) | val;
return SCPE_OK;
}
t_stat cty_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
{
fprintf (st, "To stop the cpu use the command:\n\n");
fprintf (st, " sim> SET CTY STOP\n\n");
#if ITS
fprintf (st, "If the CPU is in standard mode, this will write 1 to location\n\n");
fprintf (st, "%03o, causing TOPS10 to stop. If the CPU is in ITS mode, this\n\n", CTY_SWITCH);
fprintf (st, "will write -1 to location 037, causing ITS to stop.\n\n");
#else
fprintf (st, "This will write a 1 to location %03o, causing TOPS10 to stop\n\n", CTY_SWITCH);
#endif
fprintf (st, "The additional terminals can be set to one of four modes: UC, 7P, 7B, or 8B.\n\n");
fprintf (st, " mode input characters output characters\n\n");
fprintf (st, " UC lower case converted lower case converted to upper case,\n");
fprintf (st, " to upper case, high-order bit cleared,\n");
fprintf (st, " high-order bit cleared non-printing characters suppressed\n");
fprintf (st, " 7P high-order bit cleared high-order bit cleared,\n");
fprintf (st, " non-printing characters suppressed\n");
fprintf (st, " 7B high-order bit cleared high-order bit cleared\n");
fprintf (st, " 8B no changes no changes\n\n");
fprintf (st, "The default mode is 7P. In addition, each line can be configured to\n");
fprintf (st, "behave as though it was attached to a dataset, or hardwired to a terminal:\n\n");
fprint_reg_help (st, &cty_dev);
return SCPE_OK;
}
const char *cty_description (DEVICE *dptr)
{
return "Console TTY Line";
}
#endif