24ed0d323ca6ce4ea7a154e26feca9c4a35e7f90
1 /* id_ttp.c: Interdata PASLA console interface
3 Copyright (c) 2000-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.
28 18-Jun-07 RMS Added UNIT_IDLE flag to console input
29 18-Oct-06 RMS Sync keyboard to LFC clock
30 22-Nov-05 RMS Revised for new terminal processing routines
31 29-Dec-03 RMS Added support for console backpressure
32 25-Apr-03 RMS Revised for extended file support
43 #define STA_OVR 0x80 /* overrun RO */
44 #define STA_PF 0x40 /* parity err RO */
45 #define STA_FR 0x20 /* framing err RO */
46 #define STA_RCV (STA_OVR|STA_PF|STA_FR)
47 #define SET_EX (STA_OVR|STA_PF|STA_FR)
48 #define STA_XMT (STA_BSY)
50 /* Command bytes 1,0 */
52 #define CMD_ECHO (0x10 << 8) /* echoplex */
53 #define CMD_WRT (0x02 << 8) /* write/read */
54 #define CMD_TYP 0x01 /* command type */
56 extern uint32 int_req
[INTSZ
], int_enb
[INTSZ
];
57 extern int32
pas_par (int32 cmd
, int32 c
);
58 extern int32 lfc_poll
;
60 uint32 ttp_sta
= 0; /* status */
61 uint32 ttp_cmd
= 0; /* command */
62 uint32 ttp_kchp
= 0; /* rcvr chr pend */
63 uint32 ttp_karm
= 0; /* rcvr int armed */
64 uint32 ttp_tarm
= 0; /* xmt int armed */
65 uint8 ttp_tplte
[] = { 0, 1, TPL_END
};
67 uint32
ttp (uint32 dev
, uint32 op
, uint32 dat
);
68 t_stat
ttpi_svc (UNIT
*uptr
);
69 t_stat
ttpo_svc (UNIT
*uptr
);
70 t_stat
ttp_reset (DEVICE
*dptr
);
71 t_stat
ttp_set_mode (UNIT
*uptr
, int32 val
, char *cptr
, void *desc
);
72 t_stat
ttp_set_break (UNIT
*uptr
, int32 val
, char *cptr
, void *desc
);
73 t_stat
ttp_set_enbdis (UNIT
*uptr
, int32 val
, char *cptr
, void *desc
);
75 /* TTP data structures */
77 DIB ttp_dib
= { d_TTP
, -1, v_TTP
, ttp_tplte
, &ttp
, NULL
};
80 { UDATA (&ttpi_svc
, UNIT_IDLE
, 0), 0 },
81 { UDATA (&ttpo_svc
, 0, 0), SERIAL_OUT_WAIT
}
85 { HRDATA (CMD
, ttp_cmd
, 16) },
86 { HRDATA (KBUF
, ttp_unit
[TTI
].buf
, 8) },
87 { DRDATA (KPOS
, ttp_unit
[TTI
].pos
, T_ADDR_W
), PV_LEFT
},
88 { DRDATA (KTIME
, ttp_unit
[TTI
].wait
, 24), REG_NZ
+ PV_LEFT
+ REG_HRO
},
89 { FLDATA (KIREQ
, int_req
[l_TTP
], i_TTP
) },
90 { FLDATA (KIENB
, int_enb
[l_TTP
], i_TTP
) },
91 { FLDATA (KARM
, ttp_karm
, 0) },
92 { FLDATA (CHP
, ttp_kchp
, 0) },
93 { HRDATA (TBUF
, ttp_unit
[TTO
].buf
, 8) },
94 { DRDATA (TPOS
, ttp_unit
[TTO
].pos
, T_ADDR_W
), PV_LEFT
},
95 { DRDATA (TTIME
, ttp_unit
[TTO
].wait
, 24), REG_NZ
+ PV_LEFT
},
96 { FLDATA (TIREQ
, int_req
[l_TTP
], i_TTP
+ 1) },
97 { FLDATA (TIENB
, int_enb
[l_TTP
], i_TTP
+ 1) },
98 { FLDATA (TARM
, ttp_tarm
, 0) },
99 { HRDATA (DEVNO
, ttp_dib
.dno
, 8), REG_HRO
},
104 { TT_MODE
, TT_MODE_UC
, "UC", "UC", &ttp_set_mode
},
105 { TT_MODE
, TT_MODE_7B
, "7b", "7B", &ttp_set_mode
},
106 { TT_MODE
, TT_MODE_8B
, "8b", "8B", &ttp_set_mode
},
107 { TT_MODE
, TT_MODE_7P
, "7p", "7P", &ttp_set_mode
},
108 { MTAB_XTD
|MTAB_VDV
|MTAB_NMO
, 0, NULL
, "ENABLED",
109 &ttp_set_enbdis
, NULL
, NULL
},
110 { MTAB_XTD
|MTAB_VDV
|MTAB_NMO
, DEV_DIS
, NULL
, "DISABLED",
111 &ttp_set_enbdis
, NULL
, NULL
},
112 { MTAB_XTD
|MTAB_VDV
|MTAB_NMO
, 0, NULL
, "BREAK",
113 &ttp_set_break
, NULL
, NULL
},
114 { MTAB_XTD
|MTAB_VDV
, 0, "DEVNO", "DEVNO",
115 &set_dev
, &show_dev
, NULL
},
120 "TTP", ttp_unit
, ttp_reg
, ttp_mod
,
122 NULL
, NULL
, &ttp_reset
,
127 /* Terminal: I/O routine */
129 uint32
ttp (uint32 dev
, uint32 op
, uint32 dat
)
134 switch (op
) { /* case IO op */
136 case IO_ADR
: /* select */
137 return BY
; /* byte only */
139 case IO_RD
: /* read */
140 ttp_kchp
= 0; /* clr chr pend */
141 ttp_sta
= ttp_sta
& ~STA_OVR
; /* clr overrun */
142 return ttp_unit
[TTI
].buf
; /* return buf */
144 case IO_WD
: /* write */
145 ttp_unit
[TTO
].buf
= dat
& 0xFF; /* store char */
146 ttp_sta
= ttp_sta
| STA_BSY
; /* set busy */
147 sim_activate (&ttp_unit
[TTO
], ttp_unit
[TTO
].wait
);
150 case IO_SS
: /* status */
151 if (xmt
) t
= ttp_sta
& STA_XMT
; /* xmt? just busy */
153 t
= ttp_sta
& STA_RCV
; /* get static */
154 if (!ttp_kchp
) t
= t
| STA_BSY
; /* no char? busy */
155 if (t
& SET_EX
) t
= t
| STA_EX
; /* test for ex */
159 case IO_OC
: /* command */
160 old_cmd
= ttp_cmd
; /* old cmd */
161 if (dat
& CMD_TYP
) { /* type 1? */
162 ttp_cmd
= (ttp_cmd
& 0xFF) | (dat
<< 8);
163 if (ttp_cmd
& CMD_WRT
) /* write? */
164 ttp_tarm
= int_chg (v_TTP
+ 1, dat
, ttp_tarm
);
165 else ttp_karm
= int_chg (v_TTP
, dat
, ttp_karm
);
167 else ttp_cmd
= (ttp_cmd
& ~0xFF) | dat
;
176 t_stat
ttpi_svc (UNIT
*uptr
)
180 sim_activate (uptr
, KBD_WAIT (uptr
->wait
, lfc_poll
)); /* continue poll */
181 ttp_sta
= ttp_sta
& ~STA_FR
; /* clear break */
182 if ((c
= sim_poll_kbd ()) < SCPE_KFLAG
) return c
; /* no char or error? */
183 ttp_sta
= ttp_sta
& ~STA_PF
; /* clear parity err */
184 if (ttp_kchp
) ttp_sta
= ttp_sta
| STA_OVR
; /* overrun? */
185 if (ttp_karm
) SET_INT (v_TTP
);
186 if (c
& SCPE_BREAK
) { /* break? */
187 ttp_sta
= ttp_sta
| STA_FR
; /* framing error */
188 uptr
->buf
= 0; /* no character */
191 out
= c
& 0x7F; /* echo is 7b */
192 c
= sim_tt_inpcvt (c
, TT_GET_MODE (uptr
->flags
));
193 if (TT_GET_MODE (uptr
->flags
) != TT_MODE_8B
) /* not 8b mode? */
194 c
= pas_par (ttp_cmd
, c
); /* apply parity */
195 uptr
->buf
= c
; /* save char */
196 uptr
->pos
= uptr
->pos
+ 1; /* incr count */
197 ttp_kchp
= 1; /* char pending */
198 if (ttp_cmd
& CMD_ECHO
) {
199 out
= sim_tt_outcvt (out
, TT_GET_MODE (uptr
->flags
));
200 if (c
>= 0) sim_putchar (out
);
201 ttp_unit
[TTO
].pos
= ttp_unit
[TTO
].pos
+ 1;
207 t_stat
ttpo_svc (UNIT
*uptr
)
212 if (TT_GET_MODE (uptr
->flags
) == TT_MODE_8B
) /* 8b? */
213 c
= pas_par (ttp_cmd
, uptr
->buf
); /* apply parity */
214 else c
= sim_tt_outcvt (uptr
->buf
, TT_GET_MODE (uptr
->flags
));
216 if ((r
= sim_putchar_s (c
)) != SCPE_OK
) { /* output; error? */
217 sim_activate (uptr
, uptr
->wait
); /* try again */
218 return ((r
== SCPE_STALL
)? SCPE_OK
: r
);
221 ttp_sta
= ttp_sta
& ~STA_BSY
; /* not busy */
222 if (ttp_tarm
) SET_INT (v_TTP
+ 1); /* set intr */
223 uptr
->pos
= uptr
->pos
+ 1; /* incr count */
229 t_stat
ttp_reset (DEVICE
*dptr
)
231 if (dptr
->flags
& DEV_DIS
) sim_cancel (&ttp_unit
[TTI
]);
232 else sim_activate_abs (&ttp_unit
[TTI
], KBD_WAIT (ttp_unit
[TTI
].wait
, lfc_poll
));
233 sim_cancel (&ttp_unit
[TTO
]);
234 CLR_INT (v_TTP
); /* clear int */
236 CLR_INT (v_TTP
+ 1); /* disable int */
238 ttp_karm
= ttp_tarm
= 0; /* disarm int */
245 /* Make mode flags uniform */
247 t_stat
ttp_set_mode (UNIT
*uptr
, int32 val
, char *cptr
, void *desc
)
249 ttp_unit
[TTO
].flags
= (ttp_unit
[TTO
].flags
& ~TT_MODE
) | val
;
250 if (val
== TT_MODE_7P
) val
= TT_MODE_7B
;
251 ttp_unit
[TTI
].flags
= (ttp_unit
[TTI
].flags
& ~TT_MODE
) | val
;
255 /* Set input break */
257 t_stat
ttp_set_break (UNIT
*uptr
, int32 val
, char *cptr
, void *desc
)
259 if (ttp_dev
.flags
& DEV_DIS
) return SCPE_NOFNC
;
260 ttp_sta
= ttp_sta
| STA_FR
;
261 if (ttp_karm
) SET_INT (v_TTP
); /* if armed, intr */
262 sim_cancel (&ttp_unit
[TTI
]); /* restart TT poll */
263 sim_activate (&ttp_unit
[TTI
], ttp_unit
[TTI
].wait
);
267 /* Set enabled/disabled */
269 t_stat
ttp_set_enbdis (UNIT
*uptr
, int32 val
, char *cptr
, void *desc
)
271 extern DEVICE tt_dev
;
272 extern t_stat
tt_reset (DEVICE
*dptr
);
274 ttp_dev
.flags
= (ttp_dev
.flags
& ~DEV_DIS
) | val
;
275 tt_dev
.flags
= (tt_dev
.flags
& ~DEV_DIS
) | (val
^ DEV_DIS
);
276 ttp_reset (&ttp_dev
);