First Commit of my working state
[simh.git] / PDP11 / pdp11_pt.c
CommitLineData
196ba1fc
PH
1/* pdp11_pt.c: PC11 paper tape reader/punch simulator\r
2\r
3 Copyright (c) 1993-2005, Robert M Supnik\r
4\r
5 Permission is hereby granted, free of charge, to any person obtaining a\r
6 copy of this software and associated documentation files (the "Software"),\r
7 to deal in the Software without restriction, including without limitation\r
8 the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
9 and/or sell copies of the Software, and to permit persons to whom the\r
10 Software is furnished to do so, subject to the following conditions:\r
11\r
12 The above copyright notice and this permission notice shall be included in\r
13 all copies or substantial portions of the Software.\r
14\r
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\r
18 ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
19 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
21\r
22 Except as contained in this notice, the name of Robert M Supnik shall not be\r
23 used in advertising or otherwise to promote the sale, use or other dealings\r
24 in this Software without prior written authorization from Robert M Supnik.\r
25\r
26 ptr paper tape reader\r
27 ptp paper tape punch\r
28\r
29 07-Jul-05 RMS Removed extraneous externs\r
30 19-May-03 RMS Revised for new conditional compilation scheme\r
31 25-Apr-03 RMS Revised for extended file support\r
32 12-Sep-02 RMS Split off from pdp11_stddev.c\r
33*/\r
34\r
35#if defined (VM_PDP10) /* PDP10 version */\r
36#include "pdp10_defs.h"\r
37#define PT_DIS DEV_DIS\r
38extern int32 int_req;\r
39\r
40#elif defined (VM_VAX) /* VAX version */\r
41#include "vax_defs.h"\r
42#define PT_DIS DEV_DIS\r
43extern int32 int_req[IPL_HLVL];\r
44\r
45#else /* PDP-11 version */\r
46#include "pdp11_defs.h"\r
47#define PT_DIS 0\r
48extern int32 int_req[IPL_HLVL];\r
49#endif\r
50\r
51#define PTRCSR_IMP (CSR_ERR+CSR_BUSY+CSR_DONE+CSR_IE) /* paper tape reader */\r
52#define PTRCSR_RW (CSR_IE)\r
53#define PTPCSR_IMP (CSR_ERR + CSR_DONE + CSR_IE) /* paper tape punch */\r
54#define PTPCSR_RW (CSR_IE)\r
55\r
56int32 ptr_csr = 0; /* control/status */\r
57int32 ptr_stopioe = 0; /* stop on error */\r
58int32 ptp_csr = 0; /* control/status */\r
59int32 ptp_stopioe = 0; /* stop on error */\r
60\r
61DEVICE ptr_dev, ptp_dev;\r
62t_stat ptr_rd (int32 *data, int32 PA, int32 access);\r
63t_stat ptr_wr (int32 data, int32 PA, int32 access);\r
64t_stat ptr_svc (UNIT *uptr);\r
65t_stat ptr_reset (DEVICE *dptr);\r
66t_stat ptr_attach (UNIT *uptr, char *ptr);\r
67t_stat ptr_detach (UNIT *uptr);\r
68t_stat ptp_rd (int32 *data, int32 PA, int32 access);\r
69t_stat ptp_wr (int32 data, int32 PA, int32 access);\r
70t_stat ptp_svc (UNIT *uptr);\r
71t_stat ptp_reset (DEVICE *dptr);\r
72t_stat ptp_attach (UNIT *uptr, char *ptr);\r
73t_stat ptp_detach (UNIT *uptr);\r
74\r
75/* PTR data structures\r
76\r
77 ptr_dev PTR device descriptor\r
78 ptr_unit PTR unit descriptor\r
79 ptr_reg PTR register list\r
80*/\r
81\r
82DIB ptr_dib = {\r
83 IOBA_PTR, IOLN_PTR, &ptr_rd, &ptr_wr,\r
84 1, IVCL (PTR), VEC_PTR, { NULL }\r
85 };\r
86\r
87UNIT ptr_unit = {\r
88 UDATA (&ptr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0),\r
89 SERIAL_IN_WAIT\r
90 };\r
91\r
92REG ptr_reg[] = {\r
93 { GRDATA (BUF, ptr_unit.buf, DEV_RDX, 8, 0) },\r
94 { GRDATA (CSR, ptr_csr, DEV_RDX, 16, 0) },\r
95 { FLDATA (INT, int_req, INT_V_PTR) },\r
96 { FLDATA (ERR, ptr_csr, CSR_V_ERR) },\r
97 { FLDATA (BUSY, ptr_csr, CSR_V_BUSY) },\r
98 { FLDATA (DONE, ptr_csr, CSR_V_DONE) },\r
99 { FLDATA (IE, ptr_csr, CSR_V_IE) },\r
100 { DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT },\r
101 { DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT },\r
102 { FLDATA (STOP_IOE, ptr_stopioe, 0) },\r
103 { FLDATA (DEVDIS, ptr_dev.flags, DEV_V_DIS), REG_HRO },\r
104 { NULL }\r
105 };\r
106\r
107MTAB ptr_mod[] = {\r
108 { MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL,\r
109 NULL, &show_addr, NULL },\r
110 { MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL,\r
111 NULL, &show_vec, NULL },\r
112 { 0 }\r
113 };\r
114\r
115DEVICE ptr_dev = {\r
116 "PTR", &ptr_unit, ptr_reg, ptr_mod,\r
117 1, 10, 31, 1, DEV_RDX, 8,\r
118 NULL, NULL, &ptr_reset,\r
119 NULL, &ptr_attach, &ptr_detach,\r
120 &ptr_dib, DEV_DISABLE | PT_DIS | DEV_UBUS | DEV_QBUS\r
121 };\r
122\r
123/* PTP data structures\r
124\r
125 ptp_dev PTP device descriptor\r
126 ptp_unit PTP unit descriptor\r
127 ptp_reg PTP register list\r
128*/\r
129\r
130DIB ptp_dib = {\r
131 IOBA_PTP, IOLN_PTP, &ptp_rd, &ptp_wr,\r
132 1, IVCL (PTP), VEC_PTP, { NULL }\r
133 };\r
134\r
135UNIT ptp_unit = {\r
136 UDATA (&ptp_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT\r
137 };\r
138\r
139REG ptp_reg[] = {\r
140 { GRDATA (BUF, ptp_unit.buf, DEV_RDX, 8, 0) },\r
141 { GRDATA (CSR, ptp_csr, DEV_RDX, 16, 0) },\r
142 { FLDATA (INT, int_req, INT_V_PTP) },\r
143 { FLDATA (ERR, ptp_csr, CSR_V_ERR) },\r
144 { FLDATA (DONE, ptp_csr, CSR_V_DONE) },\r
145 { FLDATA (IE, ptp_csr, CSR_V_IE) },\r
146 { DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT },\r
147 { DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT },\r
148 { FLDATA (STOP_IOE, ptp_stopioe, 0) },\r
149 { NULL }\r
150 };\r
151\r
152MTAB ptp_mod[] = {\r
153 { MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL,\r
154 NULL, &show_addr, NULL },\r
155 { MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL,\r
156 NULL, &show_vec, NULL },\r
157 { 0 }\r
158 };\r
159\r
160DEVICE ptp_dev = {\r
161 "PTP", &ptp_unit, ptp_reg, ptp_mod,\r
162 1, 10, 31, 1, DEV_RDX, 8,\r
163 NULL, NULL, &ptp_reset,\r
164 NULL, &ptp_attach, &ptp_detach,\r
165 &ptp_dib, DEV_DISABLE | PT_DIS | DEV_UBUS | DEV_QBUS\r
166 };\r
167\r
168/* Paper tape reader I/O address routines */\r
169\r
170t_stat ptr_rd (int32 *data, int32 PA, int32 access)\r
171{\r
172switch ((PA >> 1) & 01) { /* decode PA<1> */\r
173\r
174 case 0: /* ptr csr */\r
175 *data = ptr_csr & PTRCSR_IMP;\r
176 return SCPE_OK;\r
177\r
178 case 1: /* ptr buf */\r
179 ptr_csr = ptr_csr & ~CSR_DONE;\r
180 CLR_INT (PTR);\r
181 *data = ptr_unit.buf & 0377;\r
182 return SCPE_OK;\r
183 }\r
184\r
185return SCPE_NXM; /* can't get here */\r
186}\r
187\r
188t_stat ptr_wr (int32 data, int32 PA, int32 access)\r
189{\r
190switch ((PA >> 1) & 01) { /* decode PA<1> */\r
191\r
192 case 0: /* ptr csr */\r
193 if (PA & 1) return SCPE_OK;\r
194 if ((data & CSR_IE) == 0) CLR_INT (PTR);\r
195 else if (((ptr_csr & CSR_IE) == 0) && (ptr_csr & (CSR_ERR | CSR_DONE)))\r
196 SET_INT (PTR);\r
197 if (data & CSR_GO) {\r
198 ptr_csr = (ptr_csr & ~CSR_DONE) | CSR_BUSY;\r
199 CLR_INT (PTR);\r
200 if (ptr_unit.flags & UNIT_ATT) /* data to read? */\r
201 sim_activate (&ptr_unit, ptr_unit.wait); \r
202 else sim_activate (&ptr_unit, 0); /* error if not */\r
203 }\r
204 ptr_csr = (ptr_csr & ~PTRCSR_RW) | (data & PTRCSR_RW);\r
205 return SCPE_OK;\r
206\r
207 case 1: /* ptr buf */\r
208 return SCPE_OK;\r
209 } /* end switch PA */\r
210\r
211return SCPE_NXM; /* can't get here */\r
212}\r
213\r
214/* Paper tape reader service */\r
215\r
216t_stat ptr_svc (UNIT *uptr)\r
217{\r
218int32 temp;\r
219\r
220ptr_csr = (ptr_csr | CSR_ERR) & ~CSR_BUSY;\r
221if (ptr_csr & CSR_IE) SET_INT (PTR);\r
222if ((ptr_unit.flags & UNIT_ATT) == 0)\r
223 return IORETURN (ptr_stopioe, SCPE_UNATT);\r
224if ((temp = getc (ptr_unit.fileref)) == EOF) {\r
225 if (feof (ptr_unit.fileref)) {\r
226 if (ptr_stopioe) printf ("PTR end of file\n");\r
227 else return SCPE_OK;\r
228 }\r
229 else perror ("PTR I/O error");\r
230 clearerr (ptr_unit.fileref);\r
231 return SCPE_IOERR;\r
232 }\r
233ptr_csr = (ptr_csr | CSR_DONE) & ~CSR_ERR;\r
234ptr_unit.buf = temp & 0377;\r
235ptr_unit.pos = ptr_unit.pos + 1;\r
236return SCPE_OK;\r
237}\r
238\r
239/* Paper tape reader support routines */\r
240\r
241t_stat ptr_reset (DEVICE *dptr)\r
242{\r
243ptr_unit.buf = 0;\r
244ptr_csr = 0;\r
245if ((ptr_unit.flags & UNIT_ATT) == 0) ptr_csr = ptr_csr | CSR_ERR;\r
246CLR_INT (PTR);\r
247sim_cancel (&ptr_unit);\r
248return SCPE_OK;\r
249}\r
250\r
251t_stat ptr_attach (UNIT *uptr, char *cptr)\r
252{\r
253t_stat reason;\r
254\r
255reason = attach_unit (uptr, cptr);\r
256if ((ptr_unit.flags & UNIT_ATT) == 0) ptr_csr = ptr_csr | CSR_ERR;\r
257else ptr_csr = ptr_csr & ~CSR_ERR;\r
258return reason;\r
259}\r
260\r
261t_stat ptr_detach (UNIT *uptr)\r
262{\r
263ptr_csr = ptr_csr | CSR_ERR;\r
264return detach_unit (uptr);\r
265}\r
266\r
267/* Paper tape punch I/O address routines */\r
268\r
269t_stat ptp_rd (int32 *data, int32 PA, int32 access)\r
270{\r
271switch ((PA >> 1) & 01) { /* decode PA<1> */\r
272\r
273 case 0: /* ptp csr */\r
274 *data = ptp_csr & PTPCSR_IMP;\r
275 return SCPE_OK;\r
276\r
277 case 1: /* ptp buf */\r
278 *data = ptp_unit.buf;\r
279 return SCPE_OK;\r
280 }\r
281\r
282return SCPE_NXM; /* can't get here */\r
283}\r
284\r
285t_stat ptp_wr (int32 data, int32 PA, int32 access)\r
286{\r
287switch ((PA >> 1) & 01) { /* decode PA<1> */\r
288\r
289 case 0: /* ptp csr */\r
290 if (PA & 1) return SCPE_OK;\r
291 if ((data & CSR_IE) == 0) CLR_INT (PTP);\r
292 else if (((ptp_csr & CSR_IE) == 0) && (ptp_csr & (CSR_ERR | CSR_DONE)))\r
293 SET_INT (PTP);\r
294 ptp_csr = (ptp_csr & ~PTPCSR_RW) | (data & PTPCSR_RW);\r
295 return SCPE_OK;\r
296\r
297 case 1: /* ptp buf */\r
298 if ((PA & 1) == 0) ptp_unit.buf = data & 0377;\r
299 ptp_csr = ptp_csr & ~CSR_DONE;\r
300 CLR_INT (PTP);\r
301 if (ptp_unit.flags & UNIT_ATT) /* file to write? */\r
302 sim_activate (&ptp_unit, ptp_unit.wait);\r
303 else sim_activate (&ptp_unit, 0); /* error if not */\r
304 return SCPE_OK;\r
305 } /* end switch PA */\r
306\r
307return SCPE_NXM; /* can't get here */\r
308}\r
309\r
310/* Paper tape punch service */\r
311\r
312t_stat ptp_svc (UNIT *uptr)\r
313{\r
314ptp_csr = ptp_csr | CSR_ERR | CSR_DONE;\r
315if (ptp_csr & CSR_IE) SET_INT (PTP);\r
316if ((ptp_unit.flags & UNIT_ATT) == 0)\r
317 return IORETURN (ptp_stopioe, SCPE_UNATT);\r
318if (putc (ptp_unit.buf, ptp_unit.fileref) == EOF) {\r
319 perror ("PTP I/O error");\r
320 clearerr (ptp_unit.fileref);\r
321 return SCPE_IOERR;\r
322 }\r
323ptp_csr = ptp_csr & ~CSR_ERR;\r
324ptp_unit.pos = ptp_unit.pos + 1;\r
325return SCPE_OK;\r
326}\r
327\r
328/* Paper tape punch support routines */\r
329\r
330t_stat ptp_reset (DEVICE *dptr)\r
331{\r
332ptp_unit.buf = 0;\r
333ptp_csr = CSR_DONE;\r
334if ((ptp_unit.flags & UNIT_ATT) == 0) ptp_csr = ptp_csr | CSR_ERR;\r
335CLR_INT (PTP);\r
336sim_cancel (&ptp_unit); /* deactivate unit */\r
337return SCPE_OK;\r
338}\r
339\r
340t_stat ptp_attach (UNIT *uptr, char *cptr)\r
341{\r
342t_stat reason;\r
343\r
344reason = attach_unit (uptr, cptr);\r
345if ((ptp_unit.flags & UNIT_ATT) == 0) ptp_csr = ptp_csr | CSR_ERR;\r
346else ptp_csr = ptp_csr & ~CSR_ERR;\r
347return reason;\r
348}\r
349\r
350t_stat ptp_detach (UNIT *uptr)\r
351{\r
352ptp_csr = ptp_csr | CSR_ERR;\r
353return detach_unit (uptr);\r
354}\r