0d7731604a940832bbcabac8ff4a67649bd79a08
1 /* gri_stddev.c: GRI-909 standard devices
3 Copyright (c) 2001-2008, Robert M Supnik
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:
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
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.
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.
26 tti S42-001 terminal input
27 tto S42-002 terminal output
28 hsr S42-004 high speed reader
29 hsp S42-006 high speed punch
32 31-May-08 RMS Fixed declarations (found by Peter Schorn)
33 30-Sep-06 RMS Fixed handling of non-printable characters in KSR mode
34 22-Nov-05 RMS Revised for new terminal processing routines
35 29-Dec-03 RMS Added support for console backpressure
36 25-Apr-03 RMS Revised for extended file support
37 22-Dec-02 RMS Added break support
38 01-Nov-02 RMS Added 7b/8B support to terminal
44 uint32 hsr_stopioe
= 1, hsp_stopioe
= 1;
47 extern uint32 dev_done
, ISR
;
49 t_stat
tti_svc (UNIT
*uhsr
);
50 t_stat
tto_svc (UNIT
*uhsr
);
51 t_stat
tti_reset (DEVICE
*dhsr
);
52 t_stat
tto_reset (DEVICE
*dhsr
);
53 t_stat
tty_set_mode (UNIT
*uptr
, int32 val
, char *cptr
, void *desc
);
54 t_stat
hsr_svc (UNIT
*uhsr
);
55 t_stat
hsp_svc (UNIT
*uhsr
);
56 t_stat
hsr_reset (DEVICE
*dhsr
);
57 t_stat
hsp_reset (DEVICE
*dhsr
);
58 t_stat
rtc_svc (UNIT
*uhsr
);
59 t_stat
rtc_reset (DEVICE
*dhsr
);
62 /* TTI data structures
64 tti_dev TTI device descriptor
65 tti_unit TTI unit descriptor
66 tti_reg TTI register list
67 tti_mod TTI modifiers list
70 UNIT tti_unit
= { UDATA (&tti_svc
, TT_MODE_KSR
, 0), KBD_POLL_WAIT
};
73 { ORDATA (BUF
, tti_unit
.buf
, 8) },
74 { FLDATA (IRDY
, dev_done
, INT_V_TTI
) },
75 { FLDATA (IENB
, ISR
, INT_V_TTI
) },
76 { DRDATA (POS
, tti_unit
.pos
, T_ADDR_W
), PV_LEFT
},
77 { DRDATA (TIME
, tti_unit
.wait
, 24), REG_NZ
+ PV_LEFT
},
82 { TT_MODE
, TT_MODE_KSR
, "KSR", "KSR", &tty_set_mode
},
83 { TT_MODE
, TT_MODE_7B
, "7b", "7B", &tty_set_mode
},
84 { TT_MODE
, TT_MODE_8B
, "8b", "8B", &tty_set_mode
},
85 { TT_MODE
, TT_MODE_7P
, "7b", NULL
, NULL
},
90 "TTI", &tti_unit
, tti_reg
, tti_mod
,
92 NULL
, NULL
, &tti_reset
,
96 /* TTO data structures
98 tto_dev TTO device descriptor
99 tto_unit TTO unit descriptor
100 tto_reg TTO register list
103 UNIT tto_unit
= { UDATA (&tto_svc
, TT_MODE_KSR
, 0), SERIAL_OUT_WAIT
};
106 { ORDATA (BUF
, tto_unit
.buf
, 8) },
107 { FLDATA (ORDY
, dev_done
, INT_V_TTO
) },
108 { FLDATA (IENB
, ISR
, INT_V_TTO
) },
109 { DRDATA (POS
, tto_unit
.pos
, T_ADDR_W
), PV_LEFT
},
110 { DRDATA (TIME
, tto_unit
.wait
, 24), PV_LEFT
},
115 { TT_MODE
, TT_MODE_KSR
, "KSR", "KSR", &tty_set_mode
},
116 { TT_MODE
, TT_MODE_7B
, "7b", "7B", &tty_set_mode
},
117 { TT_MODE
, TT_MODE_8B
, "8b", "8B", &tty_set_mode
},
118 { TT_MODE
, TT_MODE_7P
, "7p", "7P", &tty_set_mode
},
123 "TTO", &tto_unit
, tto_reg
, tto_mod
,
125 NULL
, NULL
, &tto_reset
,
129 /* HSR data structures
131 hsr_dev HSR device descriptor
132 hsr_unit HSR unit descriptor
133 hsr_reg HSR register list
134 hsr_mod HSR modifiers list
138 UDATA (&hsr_svc
, UNIT_SEQ
+UNIT_ATTABLE
+UNIT_ROABLE
, 0), SERIAL_IN_WAIT
142 { ORDATA (BUF
, hsr_unit
.buf
, 8) },
143 { FLDATA (IRDY
, dev_done
, INT_V_HSR
) },
144 { FLDATA (IENB
, ISR
, INT_V_HSR
) },
145 { DRDATA (POS
, hsr_unit
.pos
, T_ADDR_W
), PV_LEFT
},
146 { DRDATA (TIME
, hsr_unit
.wait
, 24), REG_NZ
+ PV_LEFT
},
147 { FLDATA (STOP_IOE
, hsr_stopioe
, 0) },
152 "HSR", &hsr_unit
, hsr_reg
, NULL
,
154 NULL
, NULL
, &hsr_reset
,
158 /* HSP data structures
160 hsp_dev HSP device descriptor
161 hsp_unit HSP unit descriptor
162 hsp_reg HSP register list
166 UDATA (&hsp_svc
, UNIT_SEQ
+UNIT_ATTABLE
, 0), SERIAL_OUT_WAIT
170 { ORDATA (BUF
, hsp_unit
.buf
, 8) },
171 { FLDATA (ORDY
, dev_done
, INT_V_HSP
) },
172 { FLDATA (IENB
, ISR
, INT_V_HSP
) },
173 { DRDATA (POS
, hsp_unit
.pos
, T_ADDR_W
), PV_LEFT
},
174 { DRDATA (TIME
, hsp_unit
.wait
, 24), PV_LEFT
},
175 { FLDATA (STOP_IOE
, hsp_stopioe
, 0) },
180 "HSP", &hsp_unit
, hsp_reg
, NULL
,
182 NULL
, NULL
, &hsp_reset
,
186 /* RTC data structures
188 rtc_dev RTC device descriptor
189 rtc_unit RTC unit descriptor
190 rtc_reg RTC register list
193 UNIT rtc_unit
= { UDATA (&rtc_svc
, 0, 0), 16000 };
196 { FLDATA (RDY
, dev_done
, INT_V_RTC
) },
197 { FLDATA (IENB
, ISR
, INT_V_RTC
) },
198 { DRDATA (TIME
, rtc_unit
.wait
, 24), REG_NZ
+ PV_LEFT
},
199 { DRDATA (TPS
, rtc_tps
, 8), REG_NZ
+ PV_LEFT
+ REG_HIDDEN
},
204 "RTC", &rtc_unit
, rtc_reg
, NULL
,
206 NULL
, NULL
, &rtc_reset
,
210 /* Console terminal function processors */
212 uint32
tty_rd (int32 src
, int32 ea
)
214 return tti_unit
.buf
; /* return data */
217 t_stat
tty_wr (uint32 dst
, uint32 val
)
219 tto_unit
.buf
= val
& 0377; /* save char */
220 dev_done
= dev_done
& ~INT_TTO
; /* clear ready */
221 sim_activate (&tto_unit
, tto_unit
.wait
); /* activate unit */
225 t_stat
tty_fo (uint32 op
)
227 if (op
& TTY_IRDY
) dev_done
= dev_done
& ~INT_TTI
;
228 if (op
& TTY_ORDY
) dev_done
= dev_done
& ~INT_TTO
;
232 uint32
tty_sf (uint32 op
)
234 if (((op
& TTY_IRDY
) && (dev_done
& INT_TTI
)) ||
235 ((op
& TTY_ORDY
) && (dev_done
& INT_TTO
))) return 1;
239 /* Service routines */
241 t_stat
tti_svc (UNIT
*uptr
)
245 sim_activate (uptr
, uptr
->wait
); /* continue poll */
246 if ((c
= sim_poll_kbd ()) < SCPE_KFLAG
) return c
; /* no char or error? */
247 if (c
& SCPE_BREAK
) uptr
->buf
= 0; /* break? */
248 else uptr
->buf
= sim_tt_inpcvt (c
, TT_GET_MODE (uptr
->flags
) | TTUF_KSR
);
249 dev_done
= dev_done
| INT_TTI
; /* set ready */
250 uptr
->pos
= uptr
->pos
+ 1;
254 t_stat
tto_svc (UNIT
*uptr
)
259 c
= sim_tt_outcvt (uptr
->buf
, TT_GET_MODE (uptr
->flags
) | TTUF_KSR
);
261 if ((r
= sim_putchar_s (c
)) != SCPE_OK
) { /* output; error? */
262 sim_activate (uptr
, uptr
->wait
); /* try again */
263 return ((r
== SCPE_STALL
)? SCPE_OK
: r
); /* !stall? report */
266 dev_done
= dev_done
| INT_TTO
; /* set ready */
267 uptr
->pos
= uptr
->pos
+ 1;
273 t_stat
tti_reset (DEVICE
*dptr
)
275 tti_unit
.buf
= 0; /* clear buffer */
276 dev_done
= dev_done
& ~INT_TTI
; /* clear ready */
277 sim_activate (&tti_unit
, tti_unit
.wait
); /* activate unit */
281 t_stat
tto_reset (DEVICE
*dptr
)
283 tto_unit
.buf
= 0; /* clear buffer */
284 dev_done
= dev_done
| INT_TTO
; /* set ready */
285 sim_cancel (&tto_unit
); /* deactivate unit */
289 t_stat
tty_set_mode (UNIT
*uptr
, int32 val
, char *cptr
, void *desc
)
291 tti_unit
.flags
= (tti_unit
.flags
& ~TT_MODE
) | val
;
292 tto_unit
.flags
= (tto_unit
.flags
& ~TT_MODE
) | val
;
296 /* High speed paper tape function processors */
298 uint32
hsrp_rd (int32 src
, int32 ea
)
300 return hsr_unit
.buf
; /* return data */
303 t_stat
hsrp_wr (uint32 dst
, uint32 val
)
305 hsp_unit
.buf
= val
& 0377; /* save char */
306 dev_done
= dev_done
& ~INT_HSP
; /* clear ready */
307 sim_activate (&hsp_unit
, hsp_unit
.wait
); /* activate unit */
311 t_stat
hsrp_fo (uint32 op
)
313 if (op
& PT_IRDY
) dev_done
= dev_done
& ~INT_HSR
;
314 if (op
& PT_ORDY
) dev_done
= dev_done
& ~INT_HSP
;
315 if (op
& PT_STRT
) sim_activate (&hsr_unit
, hsr_unit
.wait
);
319 uint32
hsrp_sf (uint32 op
)
321 if (((op
& PT_IRDY
) && (dev_done
& INT_HSR
)) ||
322 ((op
& PT_ORDY
) && (dev_done
& INT_HSP
))) return 1;
326 t_stat
hsr_svc (UNIT
*uptr
)
330 if ((hsr_unit
.flags
& UNIT_ATT
) == 0) /* attached? */
331 return IORETURN (hsr_stopioe
, SCPE_UNATT
);
332 if ((temp
= getc (hsr_unit
.fileref
)) == EOF
) { /* read char */
333 if (feof (hsr_unit
.fileref
)) { /* err or eof? */
334 if (hsr_stopioe
) printf ("HSR end of file\n");
337 else perror ("HSR I/O error");
338 clearerr (hsr_unit
.fileref
);
341 dev_done
= dev_done
| INT_HSR
; /* set ready */
342 hsr_unit
.buf
= temp
& 0377; /* save char */
343 hsr_unit
.pos
= hsr_unit
.pos
+ 1;
347 t_stat
hsp_svc (UNIT
*uptr
)
349 dev_done
= dev_done
| INT_HSP
; /* set ready */
350 if ((hsp_unit
.flags
& UNIT_ATT
) == 0) /* attached? */
351 return IORETURN (hsp_stopioe
, SCPE_UNATT
);
352 if (putc (hsp_unit
.buf
, hsp_unit
.fileref
) == EOF
) { /* write char */
353 perror ("HSP I/O error"); /* error? */
354 clearerr (hsp_unit
.fileref
);
357 hsp_unit
.pos
= hsp_unit
.pos
+ 1;
363 t_stat
hsr_reset (DEVICE
*dptr
)
365 hsr_unit
.buf
= 0; /* clear buffer */
366 dev_done
= dev_done
& ~INT_HSR
; /* clear ready */
367 sim_cancel (&hsr_unit
); /* deactivate unit */
371 t_stat
hsp_reset (DEVICE
*dptr
)
373 hsp_unit
.buf
= 0; /* clear buffer */
374 dev_done
= dev_done
| INT_HSP
; /* set ready */
375 sim_cancel (&hsp_unit
); /* deactivate unit */
379 /* Clock function processors */
381 t_stat
rtc_fo (int32 op
)
383 if (op
& RTC_OFF
) sim_cancel (&rtc_unit
); /* clock off? */
384 if ((op
& RTC_ON
) && !sim_is_active (&rtc_unit
)) /* clock on? */
385 sim_activate (&rtc_unit
, sim_rtc_init (rtc_unit
.wait
));
386 if (op
& RTC_OV
) dev_done
= dev_done
& ~INT_RTC
; /* clr ovflo? */
390 uint32
rtc_sf (int32 op
)
392 if ((op
& RTC_OV
) && (dev_done
& INT_RTC
)) return 1;
396 t_stat
rtc_svc (UNIT
*uptr
)
398 M
[RTC_CTR
] = (M
[RTC_CTR
] + 1) & DMASK
; /* incr counter */
399 if (M
[RTC_CTR
] == 0) dev_done
= dev_done
| INT_RTC
; /* ovflo? set ready */
400 sim_activate (&rtc_unit
, sim_rtc_calb (rtc_tps
)); /* reactivate */
404 t_stat
rtc_reset (DEVICE
*dptr
)
406 dev_done
= dev_done
& ~INT_RTC
; /* clear ready */
407 sim_cancel (&rtc_unit
); /* stop clock */