1 /* pdp8_tt.c: PDP-8 console terminal simulator
3 Copyright (c) 1993-2007, 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,tto KL8E terminal input/output
28 18-Jun-07 RMS Added UNIT_IDLE flag to console input
29 18-Oct-06 RMS Synced keyboard to clock
30 30-Sep-06 RMS Fixed handling of non-printable characters in KSR mode
31 22-Nov-05 RMS Revised for new terminal processing routines
32 28-May-04 RMS Removed SET TTI CTRL-C
33 29-Dec-03 RMS Added console output backpressure support
34 25-Apr-03 RMS Revised for extended file support
35 02-Mar-02 RMS Added SET TTI CTRL-C
36 22-Dec-02 RMS Added break support
37 01-Nov-02 RMS Added 7B/8B support
38 04-Oct-02 RMS Added DIBs, device number support
39 30-May-02 RMS Widened POS to 32b
40 07-Sep-01 RMS Moved function prototypes
43 #include "pdp8_defs.h"
46 extern int32 int_req
, int_enable
, dev_done
, stop_inst
;
47 extern int32 tmxr_poll
;
49 int32
tti (int32 IR
, int32 AC
);
50 int32
tto (int32 IR
, int32 AC
);
51 t_stat
tti_svc (UNIT
*uptr
);
52 t_stat
tto_svc (UNIT
*uptr
);
53 t_stat
tti_reset (DEVICE
*dptr
);
54 t_stat
tto_reset (DEVICE
*dptr
);
55 t_stat
tty_set_mode (UNIT
*uptr
, int32 val
, char *cptr
, void *desc
);
57 /* TTI data structures
59 tti_dev TTI device descriptor
60 tti_unit TTI unit descriptor
61 tti_reg TTI register list
62 tti_mod TTI modifiers list
65 DIB tti_dib
= { DEV_TTI
, 1, { &tti
} };
67 UNIT tti_unit
= { UDATA (&tti_svc
, UNIT_IDLE
|TT_MODE_KSR
, 0), 0 };
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), PV_LEFT
},
80 { TT_MODE
, TT_MODE_KSR
, "KSR", "KSR", &tty_set_mode
},
81 { TT_MODE
, TT_MODE_7B
, "7b", "7B", &tty_set_mode
},
82 { TT_MODE
, TT_MODE_8B
, "8b", "8B", &tty_set_mode
},
83 { TT_MODE
, TT_MODE_7P
, "7b", NULL
, NULL
},
84 { MTAB_XTD
|MTAB_VDV
, 0, "DEVNO", NULL
, NULL
, &show_dev
, NULL
},
89 "TTI", &tti_unit
, tti_reg
, tti_mod
,
91 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 DIB tto_dib
= { DEV_TTO
, 1, { &tto
} };
105 UNIT tto_unit
= { UDATA (&tto_svc
, TT_MODE_KSR
, 0), SERIAL_OUT_WAIT
};
108 { ORDATA (BUF
, tto_unit
.buf
, 8) },
109 { FLDATA (DONE
, dev_done
, INT_V_TTO
) },
110 { FLDATA (ENABLE
, int_enable
, INT_V_TTO
) },
111 { FLDATA (INT
, int_req
, INT_V_TTO
) },
112 { DRDATA (POS
, tto_unit
.pos
, T_ADDR_W
), PV_LEFT
},
113 { DRDATA (TIME
, tto_unit
.wait
, 24), PV_LEFT
},
118 { TT_MODE
, TT_MODE_KSR
, "KSR", "KSR", &tty_set_mode
},
119 { TT_MODE
, TT_MODE_7B
, "7b", "7B", &tty_set_mode
},
120 { TT_MODE
, TT_MODE_8B
, "8b", "8B", &tty_set_mode
},
121 { TT_MODE
, TT_MODE_7P
, "7p", "7P", &tty_set_mode
},
122 { MTAB_XTD
|MTAB_VDV
, 0, "DEVNO", NULL
, NULL
, &show_dev
},
127 "TTO", &tto_unit
, tto_reg
, tto_mod
,
129 NULL
, NULL
, &tto_reset
,
134 /* Terminal input: IOT routine */
136 int32
tti (int32 IR
, int32 AC
)
138 switch (IR
& 07) { /* decode IR<9:11> */
140 dev_done
= dev_done
& ~INT_TTI
; /* clear flag */
141 int_req
= int_req
& ~INT_TTI
;
145 return (dev_done
& INT_TTI
)? IOT_SKP
+ AC
: AC
;
148 dev_done
= dev_done
& ~INT_TTI
; /* clear flag */
149 int_req
= int_req
& ~INT_TTI
;
150 return 0; /* clear AC */
153 return (AC
| tti_unit
.buf
); /* return buffer */
156 if (AC
& 1) int_enable
= int_enable
| (INT_TTI
+INT_TTO
);
157 else int_enable
= int_enable
& ~(INT_TTI
+INT_TTO
);
158 int_req
= INT_UPDATE
; /* update interrupts */
162 dev_done
= dev_done
& ~INT_TTI
; /* clear flag */
163 int_req
= int_req
& ~INT_TTI
;
164 return (tti_unit
.buf
); /* return buffer */
167 return (stop_inst
<< IOT_V_REASON
) + AC
;
173 t_stat
tti_svc (UNIT
*uptr
)
177 sim_activate (uptr
, KBD_WAIT (uptr
->wait
, tmxr_poll
)); /* continue poll */
178 if ((c
= sim_poll_kbd ()) < SCPE_KFLAG
) return c
; /* no char or error? */
179 if (c
& SCPE_BREAK
) uptr
->buf
= 0; /* break? */
180 else uptr
->buf
= sim_tt_inpcvt (c
, TT_GET_MODE (uptr
->flags
) | TTUF_KSR
);
181 uptr
->pos
= uptr
->pos
+ 1;
182 dev_done
= dev_done
| INT_TTI
; /* set done */
183 int_req
= INT_UPDATE
; /* update interrupts */
189 t_stat
tti_reset (DEVICE
*dptr
)
192 dev_done
= dev_done
& ~INT_TTI
; /* clear done, int */
193 int_req
= int_req
& ~INT_TTI
;
194 int_enable
= int_enable
| INT_TTI
; /* set enable */
195 sim_activate_abs (&tti_unit
, KBD_WAIT (tti_unit
.wait
, tmxr_poll
));
199 /* Terminal output: IOT routine */
201 int32
tto (int32 IR
, int32 AC
)
203 switch (IR
& 07) { /* decode IR<9:11> */
206 dev_done
= dev_done
| INT_TTO
; /* set flag */
207 int_req
= INT_UPDATE
; /* update interrupts */
211 return (dev_done
& INT_TTO
)? IOT_SKP
+ AC
: AC
;
214 dev_done
= dev_done
& ~INT_TTO
; /* clear flag */
215 int_req
= int_req
& ~INT_TTO
; /* clear int req */
219 return (int_req
& (INT_TTI
+INT_TTO
))? IOT_SKP
+ AC
: AC
;
222 dev_done
= dev_done
& ~INT_TTO
; /* clear flag */
223 int_req
= int_req
& ~INT_TTO
; /* clear int req */
225 sim_activate (&tto_unit
, tto_unit
.wait
); /* activate unit */
226 tto_unit
.buf
= AC
; /* load buffer */
230 return (stop_inst
<< IOT_V_REASON
) + AC
;
236 t_stat
tto_svc (UNIT
*uptr
)
241 c
= sim_tt_outcvt (uptr
->buf
, TT_GET_MODE (uptr
->flags
) | TTUF_KSR
);
243 if ((r
= sim_putchar_s (c
)) != SCPE_OK
) { /* output char; error? */
244 sim_activate (uptr
, uptr
->wait
); /* try again */
245 return ((r
== SCPE_STALL
)? SCPE_OK
: r
); /* if !stall, report */
248 dev_done
= dev_done
| INT_TTO
; /* set done */
249 int_req
= INT_UPDATE
; /* update interrupts */
250 uptr
->pos
= uptr
->pos
+ 1;
256 t_stat
tto_reset (DEVICE
*dptr
)
259 dev_done
= dev_done
& ~INT_TTO
; /* clear done, int */
260 int_req
= int_req
& ~INT_TTO
;
261 int_enable
= int_enable
| INT_TTO
; /* set enable */
262 sim_cancel (&tto_unit
); /* deactivate unit */
266 t_stat
tty_set_mode (UNIT
*uptr
, int32 val
, char *cptr
, void *desc
)
268 tti_unit
.flags
= (tti_unit
.flags
& ~TT_MODE
) | val
;
269 tto_unit
.flags
= (tto_unit
.flags
& ~TT_MODE
) | val
;