f0b22632a8ca641aea5b958242bb0a9ede231c9c
1 /* vax_stddev.c: VAX 3900 standard I/O devices
3 Copyright (c) 1998-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 clk 100Hz and TODR clock
30 18-Jun-07 RMS Added UNIT_IDLE flag to console input, clock
31 17-Oct-06 RMS Synced keyboard poll to real-time clock for idling
32 22-Nov-05 RMS Revised for new terminal processing routines
33 09-Sep-04 RMS Integrated powerup into RESET (with -p)
34 28-May-04 RMS Removed SET TTI CTRL-C
35 29-Dec-03 RMS Added console backpressure support
36 25-Apr-03 RMS Revised for extended file support
37 02-Mar-02 RMS Added SET TTI CTRL-C
38 22-Dec-02 RMS Added console halt capability
39 01-Nov-02 RMS Added 7B/8B capability to terminal
40 12-Sep-02 RMS Removed paper tape, added variable vector support
41 30-May-02 RMS Widened POS to 32b
42 30-Apr-02 RMS Automatically set TODR to VMS-correct value during boot
48 #define TTICSR_IMP (CSR_DONE + CSR_IE) /* terminal input */
49 #define TTICSR_RW (CSR_IE)
50 #define TTIBUF_ERR 0x8000 /* error */
51 #define TTIBUF_OVR 0x4000 /* overrun */
52 #define TTIBUF_FRM 0x2000 /* framing error */
53 #define TTIBUF_RBR 0x0400 /* receive break */
54 #define TTOCSR_IMP (CSR_DONE + CSR_IE) /* terminal output */
55 #define TTOCSR_RW (CSR_IE)
56 #define CLKCSR_IMP (CSR_IE) /* real-time clock */
57 #define CLKCSR_RW (CSR_IE)
58 #define CLK_DELAY 5000 /* 100 Hz */
59 #define TMXR_MULT 1 /* 100 Hz */
61 extern int32 int_req
[IPL_HLVL
];
63 extern int32 sim_switches
;
65 int32 tti_csr
= 0; /* control/status */
66 int32 tto_csr
= 0; /* control/status */
67 int32 clk_csr
= 0; /* control/status */
68 int32 clk_tps
= 100; /* ticks/second */
69 int32 todr_reg
= 0; /* TODR register */
70 int32 todr_blow
= 1; /* TODR battery low */
71 int32 tmxr_poll
= CLK_DELAY
* TMXR_MULT
; /* term mux poll */
72 int32 tmr_poll
= CLK_DELAY
; /* pgm timer poll */
74 t_stat
tti_svc (UNIT
*uptr
);
75 t_stat
tto_svc (UNIT
*uptr
);
76 t_stat
clk_svc (UNIT
*uptr
);
77 t_stat
tti_reset (DEVICE
*dptr
);
78 t_stat
tto_reset (DEVICE
*dptr
);
79 t_stat
clk_reset (DEVICE
*dptr
);
81 extern int32
sysd_hlt_enb (void);
83 /* TTI data structures
85 tti_dev TTI device descriptor
86 tti_unit TTI unit descriptor
87 tti_reg TTI register list
90 DIB tti_dib
= { 0, 0, NULL
, NULL
, 1, IVCL (TTI
), SCB_TTI
, { NULL
} };
92 UNIT tti_unit
= { UDATA (&tti_svc
, UNIT_IDLE
|TT_MODE_8B
, 0), 0 };
95 { HRDATA (BUF
, tti_unit
.buf
, 16) },
96 { HRDATA (CSR
, tti_csr
, 16) },
97 { FLDATA (INT
, int_req
[IPL_TTI
], INT_V_TTI
) },
98 { FLDATA (DONE
, tti_csr
, CSR_V_DONE
) },
99 { FLDATA (IE
, tti_csr
, CSR_V_IE
) },
100 { DRDATA (POS
, tti_unit
.pos
, T_ADDR_W
), PV_LEFT
},
101 { DRDATA (TIME
, tti_unit
.wait
, 24), PV_LEFT
},
106 { TT_MODE
, TT_MODE_7B
, "7b", "7B", NULL
},
107 { TT_MODE
, TT_MODE_8B
, "8b", "8B", NULL
},
108 { MTAB_XTD
|MTAB_VDV
, 0, "VECTOR", NULL
,
109 NULL
, &show_vec
, NULL
},
114 "TTI", &tti_unit
, tti_reg
, tti_mod
,
116 NULL
, NULL
, &tti_reset
,
121 /* TTO data structures
123 tto_dev TTO device descriptor
124 tto_unit TTO unit descriptor
125 tto_reg TTO register list
128 DIB tto_dib
= { 0, 0, NULL
, NULL
, 1, IVCL (TTO
), SCB_TTO
, { NULL
} };
130 UNIT tto_unit
= { UDATA (&tto_svc
, TT_MODE_8B
, 0), SERIAL_OUT_WAIT
};
133 { HRDATA (BUF
, tto_unit
.buf
, 8) },
134 { HRDATA (CSR
, tto_csr
, 16) },
135 { FLDATA (INT
, int_req
[IPL_TTO
], INT_V_TTO
) },
136 { FLDATA (DONE
, tto_csr
, CSR_V_DONE
) },
137 { FLDATA (IE
, tto_csr
, CSR_V_IE
) },
138 { DRDATA (POS
, tto_unit
.pos
, T_ADDR_W
), PV_LEFT
},
139 { DRDATA (TIME
, tto_unit
.wait
, 24), PV_LEFT
},
144 { TT_MODE
, TT_MODE_7B
, "7b", "7B", NULL
},
145 { TT_MODE
, TT_MODE_8B
, "8b", "8B", NULL
},
146 { TT_MODE
, TT_MODE_7P
, "7p", "7P", NULL
},
147 { MTAB_XTD
|MTAB_VDV
, 0, "VECTOR", NULL
, NULL
, &show_vec
},
152 "TTO", &tto_unit
, tto_reg
, tto_mod
,
154 NULL
, NULL
, &tto_reset
,
159 /* CLK data structures
161 clk_dev CLK device descriptor
162 clk_unit CLK unit descriptor
163 clk_reg CLK register list
166 DIB clk_dib
= { 0, 0, NULL
, NULL
, 1, IVCL (CLK
), SCB_INTTIM
, { NULL
} };
168 UNIT clk_unit
= { UDATA (&clk_svc
, UNIT_IDLE
, 0), CLK_DELAY
};
171 { HRDATA (CSR
, clk_csr
, 16) },
172 { FLDATA (INT
, int_req
[IPL_CLK
], INT_V_CLK
) },
173 { FLDATA (IE
, clk_csr
, CSR_V_IE
) },
174 { DRDATA (TODR
, todr_reg
, 32), PV_LEFT
},
175 { FLDATA (BLOW
, todr_blow
, 0) },
176 { DRDATA (TIME
, clk_unit
.wait
, 24), REG_NZ
+ PV_LEFT
},
177 { DRDATA (POLL
, tmr_poll
, 24), REG_NZ
+ PV_LEFT
+ REG_HRO
},
178 { DRDATA (TPS
, clk_tps
, 8), REG_NZ
+ PV_LEFT
},
183 { MTAB_XTD
|MTAB_VDV
, 0, "VECTOR", NULL
, NULL
, &show_vec
},
188 "CLK", &clk_unit
, clk_reg
, clk_mod
,
190 NULL
, NULL
, &clk_reset
,
195 /* Clock and terminal MxPR routines
197 iccs_rd/wr interval timer
198 todr_rd/wr time of year clock
199 rxcs_rd/wr input control/status
201 txcs_rd/wr output control/status
202 txdb_wr output buffer
207 return (clk_csr
& CLKCSR_IMP
);
217 return (tti_csr
& TTICSR_IMP
);
222 int32 t
= tti_unit
.buf
; /* char + error */
224 tti_csr
= tti_csr
& ~CSR_DONE
; /* clr done */
225 tti_unit
.buf
= tti_unit
.buf
& 0377; /* clr errors */
232 return (tto_csr
& TTOCSR_IMP
);
235 void iccs_wr (int32 data
)
237 if ((data
& CSR_IE
) == 0) CLR_INT (CLK
);
238 clk_csr
= (clk_csr
& ~CLKCSR_RW
) | (data
& CLKCSR_RW
);
242 void todr_wr (int32 data
)
245 if (data
) todr_blow
= 0;
249 void rxcs_wr (int32 data
)
251 if ((data
& CSR_IE
) == 0) CLR_INT (TTI
);
252 else if ((tti_csr
& (CSR_DONE
+ CSR_IE
)) == CSR_DONE
)
254 tti_csr
= (tti_csr
& ~TTICSR_RW
) | (data
& TTICSR_RW
);
258 void txcs_wr (int32 data
)
260 if ((data
& CSR_IE
) == 0) CLR_INT (TTO
);
261 else if ((tto_csr
& (CSR_DONE
+ CSR_IE
)) == CSR_DONE
)
263 tto_csr
= (tto_csr
& ~TTOCSR_RW
) | (data
& TTOCSR_RW
);
267 void txdb_wr (int32 data
)
269 tto_unit
.buf
= data
& 0377;
270 tto_csr
= tto_csr
& ~CSR_DONE
;
272 sim_activate (&tto_unit
, tto_unit
.wait
);
276 /* Terminal input routines
278 tti_svc process event (character ready)
279 tti_reset process reset
282 t_stat
tti_svc (UNIT
*uptr
)
286 sim_activate (uptr
, KBD_WAIT (uptr
->wait
, tmr_poll
)); /* continue poll */
287 if ((c
= sim_poll_kbd ()) < SCPE_KFLAG
) return c
; /* no char or error? */
288 if (c
& SCPE_BREAK
) { /* break? */
289 if (sysd_hlt_enb ()) hlt_pin
= 1; /* if enabled, halt */
290 tti_unit
.buf
= TTIBUF_ERR
| TTIBUF_FRM
| TTIBUF_RBR
;
292 else tti_unit
.buf
= sim_tt_inpcvt (c
, TT_GET_MODE (uptr
->flags
));
293 uptr
->pos
= uptr
->pos
+ 1;
294 tti_csr
= tti_csr
| CSR_DONE
;
295 if (tti_csr
& CSR_IE
) SET_INT (TTI
);
299 t_stat
tti_reset (DEVICE
*dptr
)
304 sim_activate_abs (&tti_unit
, KBD_WAIT (tti_unit
.wait
, tmr_poll
));
308 /* Terminal output routines
310 tto_svc process event (character typed)
311 tto_reset process reset
314 t_stat
tto_svc (UNIT
*uptr
)
319 c
= sim_tt_outcvt (tto_unit
.buf
, TT_GET_MODE (uptr
->flags
));
321 if ((r
= sim_putchar_s (c
)) != SCPE_OK
) { /* output; error? */
322 sim_activate (uptr
, uptr
->wait
); /* retry */
323 return ((r
== SCPE_STALL
)? SCPE_OK
: r
); /* !stall? report */
326 tto_csr
= tto_csr
| CSR_DONE
;
327 if (tto_csr
& CSR_IE
) SET_INT (TTO
);
328 uptr
->pos
= uptr
->pos
+ 1;
332 t_stat
tto_reset (DEVICE
*dptr
)
337 sim_cancel (&tto_unit
); /* deactivate unit */
343 clk_svc process event (clock tick)
344 clk_reset process reset
345 todr_powerup powerup for TODR (get date from system)
348 t_stat
clk_svc (UNIT
*uptr
)
352 if (clk_csr
& CSR_IE
) SET_INT (CLK
);
353 t
= sim_rtcn_calb (clk_tps
, TMR_CLK
); /* calibrate clock */
354 sim_activate (&clk_unit
, t
); /* reactivate unit */
355 tmr_poll
= t
; /* set tmr poll */
356 tmxr_poll
= t
* TMXR_MULT
; /* set mux poll */
357 if (!todr_blow
) todr_reg
= todr_reg
+ 1; /* incr TODR */
361 /* Clock coscheduling routine */
363 int32
clk_cosched (int32 wait
)
367 t
= sim_is_active (&clk_unit
);
368 return (t
? t
- 1: wait
);
371 /* Powerup routine */
373 t_stat
todr_powerup (void)
379 curr
= time (NULL
); /* get curr time */
380 if (curr
== (time_t) -1) return SCPE_NOFNC
; /* error? */
381 ctm
= localtime (&curr
); /* decompose */
382 if (ctm
== NULL
) return SCPE_NOFNC
; /* error? */
383 base
= (((((ctm
->tm_yday
* 24) + /* sec since 1-Jan */
384 ctm
->tm_hour
) * 60) +
387 todr_reg
= (base
* 100) + 0x10000000; /* cvt to VAX form */
394 t_stat
clk_reset (DEVICE
*dptr
)
398 if (sim_switches
& SWMASK ('P')) todr_powerup (); /* powerup? */
401 t
= sim_rtcn_init (clk_unit
.wait
, TMR_CLK
); /* init timer */
402 sim_activate_abs (&clk_unit
, t
); /* activate unit */
403 tmr_poll
= t
; /* set tmr poll */
404 tmxr_poll
= t
* TMXR_MULT
; /* set mux poll */