First Commit of my working state
[simh.git] / GRI / gri_stddev.c
CommitLineData
196ba1fc
PH
1/* gri_stddev.c: GRI-909 standard devices\r
2\r
3 Copyright (c) 2001-2008, Robert M Supnik\r
4\r
5 Permission is hereby granted, free of charge, to any person obtaining a\r
6 copy of this software and associated documentation files (the "Software"),\r
7 to deal in the Software without restriction, including without limitation\r
8 the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
9 and/or sell copies of the Software, and to permit persons to whom the\r
10 Software is furnished to do so, subject to the following conditions:\r
11\r
12 The above copyright notice and this permission notice shall be included in\r
13 all copies or substantial portions of the Software.\r
14\r
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\r
18 ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
19 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
21\r
22 Except as contained in this notice, the name of Robert M Supnik shall not be\r
23 used in advertising or otherwise to promote the sale, use or other dealings\r
24 in this Software without prior written authorization from Robert M Supnik.\r
25\r
26 tti S42-001 terminal input\r
27 tto S42-002 terminal output\r
28 hsr S42-004 high speed reader\r
29 hsp S42-006 high speed punch\r
30 rtc real time clock\r
31\r
32 31-May-08 RMS Fixed declarations (found by Peter Schorn)\r
33 30-Sep-06 RMS Fixed handling of non-printable characters in KSR mode\r
34 22-Nov-05 RMS Revised for new terminal processing routines\r
35 29-Dec-03 RMS Added support for console backpressure\r
36 25-Apr-03 RMS Revised for extended file support\r
37 22-Dec-02 RMS Added break support\r
38 01-Nov-02 RMS Added 7b/8B support to terminal\r
39*/\r
40\r
41#include "gri_defs.h"\r
42#include <ctype.h>\r
43\r
44uint32 hsr_stopioe = 1, hsp_stopioe = 1;\r
45\r
46extern uint16 M[];\r
47extern uint32 dev_done, ISR;\r
48\r
49t_stat tti_svc (UNIT *uhsr);\r
50t_stat tto_svc (UNIT *uhsr);\r
51t_stat tti_reset (DEVICE *dhsr);\r
52t_stat tto_reset (DEVICE *dhsr);\r
53t_stat tty_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc);\r
54t_stat hsr_svc (UNIT *uhsr);\r
55t_stat hsp_svc (UNIT *uhsr);\r
56t_stat hsr_reset (DEVICE *dhsr);\r
57t_stat hsp_reset (DEVICE *dhsr);\r
58t_stat rtc_svc (UNIT *uhsr);\r
59t_stat rtc_reset (DEVICE *dhsr);\r
60int32 rtc_tps = 1000;\r
61\r
62/* TTI data structures\r
63\r
64 tti_dev TTI device descriptor\r
65 tti_unit TTI unit descriptor\r
66 tti_reg TTI register list\r
67 tti_mod TTI modifiers list\r
68*/\r
69\r
70UNIT tti_unit = { UDATA (&tti_svc, TT_MODE_KSR, 0), KBD_POLL_WAIT };\r
71\r
72REG tti_reg[] = {\r
73 { ORDATA (BUF, tti_unit.buf, 8) },\r
74 { FLDATA (IRDY, dev_done, INT_V_TTI) },\r
75 { FLDATA (IENB, ISR, INT_V_TTI) },\r
76 { DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT },\r
77 { DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },\r
78 { NULL }\r
79 };\r
80\r
81MTAB tti_mod[] = {\r
82 { TT_MODE, TT_MODE_KSR, "KSR", "KSR", &tty_set_mode },\r
83 { TT_MODE, TT_MODE_7B, "7b", "7B", &tty_set_mode },\r
84 { TT_MODE, TT_MODE_8B, "8b", "8B", &tty_set_mode },\r
85 { TT_MODE, TT_MODE_7P, "7b", NULL, NULL },\r
86 { 0 }\r
87 };\r
88\r
89DEVICE tti_dev = {\r
90 "TTI", &tti_unit, tti_reg, tti_mod,\r
91 1, 10, 31, 1, 8, 8,\r
92 NULL, NULL, &tti_reset,\r
93 NULL, NULL, NULL\r
94 };\r
95\r
96/* TTO data structures\r
97\r
98 tto_dev TTO device descriptor\r
99 tto_unit TTO unit descriptor\r
100 tto_reg TTO register list\r
101*/\r
102\r
103UNIT tto_unit = { UDATA (&tto_svc, TT_MODE_KSR, 0), SERIAL_OUT_WAIT };\r
104\r
105REG tto_reg[] = {\r
106 { ORDATA (BUF, tto_unit.buf, 8) },\r
107 { FLDATA (ORDY, dev_done, INT_V_TTO) },\r
108 { FLDATA (IENB, ISR, INT_V_TTO) },\r
109 { DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT },\r
110 { DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },\r
111 { NULL }\r
112 };\r
113\r
114MTAB tto_mod[] = {\r
115 { TT_MODE, TT_MODE_KSR, "KSR", "KSR", &tty_set_mode },\r
116 { TT_MODE, TT_MODE_7B, "7b", "7B", &tty_set_mode },\r
117 { TT_MODE, TT_MODE_8B, "8b", "8B", &tty_set_mode },\r
118 { TT_MODE, TT_MODE_7P, "7p", "7P", &tty_set_mode },\r
119 { 0 }\r
120 };\r
121\r
122DEVICE tto_dev = {\r
123 "TTO", &tto_unit, tto_reg, tto_mod,\r
124 1, 10, 31, 1, 8, 8,\r
125 NULL, NULL, &tto_reset, \r
126 NULL, NULL, NULL\r
127 };\r
128\r
129/* HSR data structures\r
130\r
131 hsr_dev HSR device descriptor\r
132 hsr_unit HSR unit descriptor\r
133 hsr_reg HSR register list\r
134 hsr_mod HSR modifiers list\r
135*/\r
136\r
137UNIT hsr_unit = {\r
138 UDATA (&hsr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0), SERIAL_IN_WAIT\r
139 };\r
140\r
141REG hsr_reg[] = {\r
142 { ORDATA (BUF, hsr_unit.buf, 8) },\r
143 { FLDATA (IRDY, dev_done, INT_V_HSR) },\r
144 { FLDATA (IENB, ISR, INT_V_HSR) },\r
145 { DRDATA (POS, hsr_unit.pos, T_ADDR_W), PV_LEFT },\r
146 { DRDATA (TIME, hsr_unit.wait, 24), REG_NZ + PV_LEFT },\r
147 { FLDATA (STOP_IOE, hsr_stopioe, 0) },\r
148 { NULL }\r
149 };\r
150\r
151DEVICE hsr_dev = {\r
152 "HSR", &hsr_unit, hsr_reg, NULL,\r
153 1, 10, 31, 1, 8, 8,\r
154 NULL, NULL, &hsr_reset,\r
155 NULL, NULL, NULL\r
156 };\r
157\r
158/* HSP data structures\r
159\r
160 hsp_dev HSP device descriptor\r
161 hsp_unit HSP unit descriptor\r
162 hsp_reg HSP register list\r
163*/\r
164\r
165UNIT hsp_unit = {\r
166 UDATA (&hsp_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT\r
167 };\r
168\r
169REG hsp_reg[] = {\r
170 { ORDATA (BUF, hsp_unit.buf, 8) },\r
171 { FLDATA (ORDY, dev_done, INT_V_HSP) },\r
172 { FLDATA (IENB, ISR, INT_V_HSP) },\r
173 { DRDATA (POS, hsp_unit.pos, T_ADDR_W), PV_LEFT },\r
174 { DRDATA (TIME, hsp_unit.wait, 24), PV_LEFT },\r
175 { FLDATA (STOP_IOE, hsp_stopioe, 0) },\r
176 { NULL }\r
177 };\r
178\r
179DEVICE hsp_dev = {\r
180 "HSP", &hsp_unit, hsp_reg, NULL,\r
181 1, 10, 31, 1, 8, 8,\r
182 NULL, NULL, &hsp_reset,\r
183 NULL, NULL, NULL\r
184 };\r
185\r
186/* RTC data structures\r
187\r
188 rtc_dev RTC device descriptor\r
189 rtc_unit RTC unit descriptor\r
190 rtc_reg RTC register list\r
191*/\r
192\r
193UNIT rtc_unit = { UDATA (&rtc_svc, 0, 0), 16000 };\r
194\r
195REG rtc_reg[] = {\r
196 { FLDATA (RDY, dev_done, INT_V_RTC) },\r
197 { FLDATA (IENB, ISR, INT_V_RTC) },\r
198 { DRDATA (TIME, rtc_unit.wait, 24), REG_NZ + PV_LEFT },\r
199 { DRDATA (TPS, rtc_tps, 8), REG_NZ + PV_LEFT + REG_HIDDEN },\r
200 { NULL }\r
201 };\r
202\r
203DEVICE rtc_dev = {\r
204 "RTC", &rtc_unit, rtc_reg, NULL,\r
205 1, 0, 0, 0, 0, 0,\r
206 NULL, NULL, &rtc_reset,\r
207 NULL, NULL, NULL\r
208 };\r
209\r
210/* Console terminal function processors */\r
211\r
212uint32 tty_rd (int32 src, int32 ea)\r
213{\r
214return tti_unit.buf; /* return data */\r
215}\r
216\r
217t_stat tty_wr (uint32 dst, uint32 val)\r
218{\r
219tto_unit.buf = val & 0377; /* save char */\r
220dev_done = dev_done & ~INT_TTO; /* clear ready */\r
221sim_activate (&tto_unit, tto_unit.wait); /* activate unit */\r
222return SCPE_OK;\r
223}\r
224\r
225t_stat tty_fo (uint32 op)\r
226{\r
227if (op & TTY_IRDY) dev_done = dev_done & ~INT_TTI;\r
228if (op & TTY_ORDY) dev_done = dev_done & ~INT_TTO;\r
229return SCPE_OK;\r
230}\r
231\r
232uint32 tty_sf (uint32 op)\r
233{\r
234if (((op & TTY_IRDY) && (dev_done & INT_TTI)) ||\r
235 ((op & TTY_ORDY) && (dev_done & INT_TTO))) return 1;\r
236return 0;\r
237}\r
238\r
239/* Service routines */\r
240\r
241t_stat tti_svc (UNIT *uptr)\r
242{\r
243int32 c;\r
244\r
245sim_activate (uptr, uptr->wait); /* continue poll */\r
246if ((c = sim_poll_kbd ()) < SCPE_KFLAG) return c; /* no char or error? */\r
247if (c & SCPE_BREAK) uptr->buf = 0; /* break? */\r
248else uptr->buf = sim_tt_inpcvt (c, TT_GET_MODE (uptr->flags) | TTUF_KSR);\r
249dev_done = dev_done | INT_TTI; /* set ready */\r
250uptr->pos = uptr->pos + 1;\r
251return SCPE_OK;\r
252}\r
253\r
254t_stat tto_svc (UNIT *uptr)\r
255{\r
256int32 c;\r
257t_stat r;\r
258\r
259c = sim_tt_outcvt (uptr->buf, TT_GET_MODE (uptr->flags) | TTUF_KSR);\r
260if (c >= 0) {\r
261 if ((r = sim_putchar_s (c)) != SCPE_OK) { /* output; error? */\r
262 sim_activate (uptr, uptr->wait); /* try again */\r
263 return ((r == SCPE_STALL)? SCPE_OK: r); /* !stall? report */\r
264 }\r
265 }\r
266dev_done = dev_done | INT_TTO; /* set ready */\r
267uptr->pos = uptr->pos + 1;\r
268return SCPE_OK;\r
269}\r
270\r
271/* Reset routines */\r
272\r
273t_stat tti_reset (DEVICE *dptr)\r
274{\r
275tti_unit.buf = 0; /* clear buffer */\r
276dev_done = dev_done & ~INT_TTI; /* clear ready */\r
277sim_activate (&tti_unit, tti_unit.wait); /* activate unit */\r
278return SCPE_OK;\r
279}\r
280\r
281t_stat tto_reset (DEVICE *dptr)\r
282{\r
283tto_unit.buf = 0; /* clear buffer */\r
284dev_done = dev_done | INT_TTO; /* set ready */\r
285sim_cancel (&tto_unit); /* deactivate unit */\r
286return SCPE_OK;\r
287}\r
288\r
289t_stat tty_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc)\r
290{\r
291tti_unit.flags = (tti_unit.flags & ~TT_MODE) | val;\r
292tto_unit.flags = (tto_unit.flags & ~TT_MODE) | val;\r
293return SCPE_OK;\r
294}\r
295\r
296/* High speed paper tape function processors */\r
297\r
298uint32 hsrp_rd (int32 src, int32 ea)\r
299{\r
300return hsr_unit.buf; /* return data */\r
301}\r
302\r
303t_stat hsrp_wr (uint32 dst, uint32 val)\r
304{\r
305hsp_unit.buf = val & 0377; /* save char */\r
306dev_done = dev_done & ~INT_HSP; /* clear ready */\r
307sim_activate (&hsp_unit, hsp_unit.wait); /* activate unit */\r
308return SCPE_OK;\r
309}\r
310\r
311t_stat hsrp_fo (uint32 op)\r
312{\r
313if (op & PT_IRDY) dev_done = dev_done & ~INT_HSR;\r
314if (op & PT_ORDY) dev_done = dev_done & ~INT_HSP;\r
315if (op & PT_STRT) sim_activate (&hsr_unit, hsr_unit.wait);\r
316return SCPE_OK;\r
317}\r
318\r
319uint32 hsrp_sf (uint32 op)\r
320{\r
321if (((op & PT_IRDY) && (dev_done & INT_HSR)) ||\r
322 ((op & PT_ORDY) && (dev_done & INT_HSP))) return 1;\r
323return 0;\r
324}\r
325\r
326t_stat hsr_svc (UNIT *uptr)\r
327{\r
328int32 temp;\r
329\r
330if ((hsr_unit.flags & UNIT_ATT) == 0) /* attached? */\r
331 return IORETURN (hsr_stopioe, SCPE_UNATT);\r
332if ((temp = getc (hsr_unit.fileref)) == EOF) { /* read char */\r
333 if (feof (hsr_unit.fileref)) { /* err or eof? */\r
334 if (hsr_stopioe) printf ("HSR end of file\n");\r
335 else return SCPE_OK;\r
336 }\r
337 else perror ("HSR I/O error");\r
338 clearerr (hsr_unit.fileref);\r
339 return SCPE_IOERR;\r
340 }\r
341dev_done = dev_done | INT_HSR; /* set ready */\r
342hsr_unit.buf = temp & 0377; /* save char */\r
343hsr_unit.pos = hsr_unit.pos + 1;\r
344return SCPE_OK;\r
345}\r
346\r
347t_stat hsp_svc (UNIT *uptr)\r
348{\r
349dev_done = dev_done | INT_HSP; /* set ready */\r
350if ((hsp_unit.flags & UNIT_ATT) == 0) /* attached? */\r
351 return IORETURN (hsp_stopioe, SCPE_UNATT);\r
352if (putc (hsp_unit.buf, hsp_unit.fileref) == EOF) { /* write char */\r
353 perror ("HSP I/O error"); /* error? */\r
354 clearerr (hsp_unit.fileref);\r
355 return SCPE_IOERR;\r
356 }\r
357hsp_unit.pos = hsp_unit.pos + 1;\r
358return SCPE_OK;\r
359}\r
360\r
361/* Reset routines */\r
362\r
363t_stat hsr_reset (DEVICE *dptr)\r
364{\r
365hsr_unit.buf = 0; /* clear buffer */\r
366dev_done = dev_done & ~INT_HSR; /* clear ready */\r
367sim_cancel (&hsr_unit); /* deactivate unit */\r
368return SCPE_OK;\r
369}\r
370\r
371t_stat hsp_reset (DEVICE *dptr)\r
372{\r
373hsp_unit.buf = 0; /* clear buffer */\r
374dev_done = dev_done | INT_HSP; /* set ready */\r
375sim_cancel (&hsp_unit); /* deactivate unit */\r
376return SCPE_OK;\r
377}\r
378\r
379/* Clock function processors */\r
380\r
381t_stat rtc_fo (int32 op)\r
382{\r
383if (op & RTC_OFF) sim_cancel (&rtc_unit); /* clock off? */\r
384if ((op & RTC_ON) && !sim_is_active (&rtc_unit)) /* clock on? */\r
385 sim_activate (&rtc_unit, sim_rtc_init (rtc_unit.wait));\r
386if (op & RTC_OV) dev_done = dev_done & ~INT_RTC; /* clr ovflo? */\r
387return SCPE_OK;\r
388}\r
389\r
390uint32 rtc_sf (int32 op)\r
391{\r
392if ((op & RTC_OV) && (dev_done & INT_RTC)) return 1;\r
393return 0;\r
394}\r
395\r
396t_stat rtc_svc (UNIT *uptr)\r
397{\r
398M[RTC_CTR] = (M[RTC_CTR] + 1) & DMASK; /* incr counter */\r
399if (M[RTC_CTR] == 0) dev_done = dev_done | INT_RTC; /* ovflo? set ready */\r
400sim_activate (&rtc_unit, sim_rtc_calb (rtc_tps)); /* reactivate */\r
401return SCPE_OK;\r
402}\r
403\r
404t_stat rtc_reset (DEVICE *dptr)\r
405{\r
406dev_done = dev_done & ~INT_RTC; /* clear ready */\r
407sim_cancel (&rtc_unit); /* stop clock */\r
408return SCPE_OK;\r
409}\r