First Commit of my working state
[simh.git] / NOVA / nova_plt.c
1 /* nova_plt.c: NOVA plotter simulator
2
3 Copyright (c) 2000-2008, Robert M. Supnik
4 Written by Bruce Ray and used with his gracious permission.
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23 Except as contained in this notice, the name of Robert M Supnik shall not be
24 used in advertising or otherwise to promote the sale, use or other dealings
25 in this Software without prior written authorization from Robert M Supnik.
26
27 plt plotter
28
29 04-Jul-07 BKR added 7B/8B support (default is 8B),
30 DEV_SET/CLR macros now used
31 25-Apr-03 RMS Revised for extended file support
32 03-Oct-02 RMS Added DIB
33 30-May-02 RMS Widened POS to 32b
34 06-Jan-02 RMS Revised enable/disable support
35 26-Apr-01 RMS Added device enable/disable support
36
37
38 Notes:
39 - data masked to 7- or 8- bits, based on 7B or 8B, default is 8-bits
40 - if register TIME is non-zero, then delay TIME events if <FF>, <CR> or <LF> seen
41 - register POS show the current file position
42 - register STOP_IOE determines return value issued if output to unattached PLT is attempted
43 */
44
45 #include "nova_defs.h"
46
47 extern int32 int_req, dev_busy, dev_done, dev_disable;
48
49 int32 plt_stopioe = 0; /* stop on error */
50
51 DEVICE plt_dev;
52 int32 plt (int32 pulse, int32 code, int32 AC);
53 t_stat plt_svc (UNIT *uptr);
54 t_stat plt_reset (DEVICE *dptr);
55
56
57 /* 7 or 8 bit data mask support for either device */
58
59 #define UNIT_V_8B (UNIT_V_UF + 0) /* 8b output */
60 #define UNIT_8B (1 << UNIT_V_8B)
61
62 /* PLT data structures
63
64 plt_dev PLT device descriptor
65 plt_unit PLT unit descriptor
66 plt_reg PLT register list
67 */
68
69 DIB plt_dib = { DEV_PLT, INT_PLT, PI_PLT, &plt };
70
71 UNIT plt_unit = { /* 2007-May-30, bkr */
72 UDATA (&plt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_8B, 0), SERIAL_OUT_WAIT
73 };
74
75 REG plt_reg[] = {
76 { ORDATA (BUF, plt_unit.buf, 8) },
77 { FLDATA (BUSY, dev_busy, INT_V_PLT) },
78 { FLDATA (DONE, dev_done, INT_V_PLT) },
79 { FLDATA (DISABLE, dev_disable, INT_V_PLT) },
80 { FLDATA (INT, int_req, INT_V_PLT) },
81 { DRDATA (POS, plt_unit.pos, T_ADDR_W), PV_LEFT },
82 { DRDATA (TIME, plt_unit.wait, 24), PV_LEFT },
83 { FLDATA (STOP_IOE, plt_stopioe, 0) },
84 { NULL }
85 };
86
87 MTAB plt_mod[] = /* 2007-May-30, bkr */
88 {
89 { UNIT_8B, 0, "7b", "7B", NULL },
90 { UNIT_8B, UNIT_8B, "8b", "8B", NULL },
91 { 0, 0, NULL, NULL, NULL }
92 } ;
93
94 DEVICE plt_dev = {
95 "PLT", &plt_unit, plt_reg, plt_mod,
96 1, 10, 31, 1, 8, 8,
97 NULL, NULL, &plt_reset,
98 NULL, NULL, NULL,
99 &plt_dib, DEV_DISABLE
100 };
101
102
103 /* plotter: IOT routine */
104
105 int32 plt (int32 pulse, int32 code, int32 AC)
106 {
107 if (code == ioDOA)
108 plt_unit.buf = AC & ((plt_unit.flags & UNIT_8B)?
109 0377
110 : 0177);
111 switch (pulse)
112 { /* decode IR<8:9> */
113 case iopS: /* start */
114 DEV_SET_BUSY( INT_PLT ) ;
115 DEV_CLR_DONE( INT_PLT ) ;
116 DEV_UPDATE_INTR ;
117 sim_activate (&plt_unit, plt_unit.wait); /* activate unit */
118 break;
119
120 case iopC: /* clear */
121 DEV_CLR_BUSY( INT_PLT ) ;
122 DEV_CLR_DONE( INT_PLT ) ;
123 DEV_UPDATE_INTR ;
124 sim_cancel (&plt_unit); /* deactivate unit */
125 break;
126 } /* end switch */
127
128 return 0;
129 }
130
131
132 /* Unit service */
133
134 t_stat plt_svc (UNIT *uptr)
135 {
136 DEV_CLR_BUSY( INT_PLT ) ;
137 DEV_SET_DONE( INT_PLT ) ;
138 DEV_UPDATE_INTR ;
139 if ((plt_unit.flags & UNIT_ATT) == 0) /* attached? */
140 return IORETURN (plt_stopioe, SCPE_UNATT);
141 if (putc (plt_unit.buf, plt_unit.fileref) == EOF) {
142 perror ("PLT I/O error");
143 clearerr (plt_unit.fileref);
144 return SCPE_IOERR;
145 }
146 ++(plt_unit.pos);
147 return SCPE_OK;
148 }
149
150
151 /* Reset routine */
152
153 t_stat plt_reset (DEVICE *dptr)
154 {
155 plt_unit.buf = 0; /* <not DG compatible> */
156 DEV_CLR_BUSY( INT_PLT ) ;
157 DEV_CLR_DONE( INT_PLT ) ;
158 DEV_UPDATE_INTR ;
159 sim_cancel (&plt_unit); /* deactivate unit */
160 return SCPE_OK;
161 }