1 /* pdp11_pt.c: PC11 paper tape reader/punch simulator
3 Copyright (c) 1993-2005, 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.
29 07-Jul-05 RMS Removed extraneous externs
30 19-May-03 RMS Revised for new conditional compilation scheme
31 25-Apr-03 RMS Revised for extended file support
32 12-Sep-02 RMS Split off from pdp11_stddev.c
35 #if defined (VM_PDP10) /* PDP10 version */
36 #include "pdp10_defs.h"
37 #define PT_DIS DEV_DIS
40 #elif defined (VM_VAX) /* VAX version */
42 #define PT_DIS DEV_DIS
43 extern int32 int_req
[IPL_HLVL
];
45 #else /* PDP-11 version */
46 #include "pdp11_defs.h"
48 extern int32 int_req
[IPL_HLVL
];
51 #define PTRCSR_IMP (CSR_ERR+CSR_BUSY+CSR_DONE+CSR_IE) /* paper tape reader */
52 #define PTRCSR_RW (CSR_IE)
53 #define PTPCSR_IMP (CSR_ERR + CSR_DONE + CSR_IE) /* paper tape punch */
54 #define PTPCSR_RW (CSR_IE)
56 int32 ptr_csr
= 0; /* control/status */
57 int32 ptr_stopioe
= 0; /* stop on error */
58 int32 ptp_csr
= 0; /* control/status */
59 int32 ptp_stopioe
= 0; /* stop on error */
61 DEVICE ptr_dev
, ptp_dev
;
62 t_stat
ptr_rd (int32
*data
, int32 PA
, int32 access
);
63 t_stat
ptr_wr (int32 data
, int32 PA
, int32 access
);
64 t_stat
ptr_svc (UNIT
*uptr
);
65 t_stat
ptr_reset (DEVICE
*dptr
);
66 t_stat
ptr_attach (UNIT
*uptr
, char *ptr
);
67 t_stat
ptr_detach (UNIT
*uptr
);
68 t_stat
ptp_rd (int32
*data
, int32 PA
, int32 access
);
69 t_stat
ptp_wr (int32 data
, int32 PA
, int32 access
);
70 t_stat
ptp_svc (UNIT
*uptr
);
71 t_stat
ptp_reset (DEVICE
*dptr
);
72 t_stat
ptp_attach (UNIT
*uptr
, char *ptr
);
73 t_stat
ptp_detach (UNIT
*uptr
);
75 /* PTR data structures
77 ptr_dev PTR device descriptor
78 ptr_unit PTR unit descriptor
79 ptr_reg PTR register list
83 IOBA_PTR
, IOLN_PTR
, &ptr_rd
, &ptr_wr
,
84 1, IVCL (PTR
), VEC_PTR
, { NULL
}
88 UDATA (&ptr_svc
, UNIT_SEQ
+UNIT_ATTABLE
+UNIT_ROABLE
, 0),
93 { GRDATA (BUF
, ptr_unit
.buf
, DEV_RDX
, 8, 0) },
94 { GRDATA (CSR
, ptr_csr
, DEV_RDX
, 16, 0) },
95 { FLDATA (INT
, int_req
, INT_V_PTR
) },
96 { FLDATA (ERR
, ptr_csr
, CSR_V_ERR
) },
97 { FLDATA (BUSY
, ptr_csr
, CSR_V_BUSY
) },
98 { FLDATA (DONE
, ptr_csr
, CSR_V_DONE
) },
99 { FLDATA (IE
, ptr_csr
, CSR_V_IE
) },
100 { DRDATA (POS
, ptr_unit
.pos
, T_ADDR_W
), PV_LEFT
},
101 { DRDATA (TIME
, ptr_unit
.wait
, 24), PV_LEFT
},
102 { FLDATA (STOP_IOE
, ptr_stopioe
, 0) },
103 { FLDATA (DEVDIS
, ptr_dev
.flags
, DEV_V_DIS
), REG_HRO
},
108 { MTAB_XTD
|MTAB_VDV
, 0, "ADDRESS", NULL
,
109 NULL
, &show_addr
, NULL
},
110 { MTAB_XTD
|MTAB_VDV
, 0, "VECTOR", NULL
,
111 NULL
, &show_vec
, NULL
},
116 "PTR", &ptr_unit
, ptr_reg
, ptr_mod
,
117 1, 10, 31, 1, DEV_RDX
, 8,
118 NULL
, NULL
, &ptr_reset
,
119 NULL
, &ptr_attach
, &ptr_detach
,
120 &ptr_dib
, DEV_DISABLE
| PT_DIS
| DEV_UBUS
| DEV_QBUS
123 /* PTP data structures
125 ptp_dev PTP device descriptor
126 ptp_unit PTP unit descriptor
127 ptp_reg PTP register list
131 IOBA_PTP
, IOLN_PTP
, &ptp_rd
, &ptp_wr
,
132 1, IVCL (PTP
), VEC_PTP
, { NULL
}
136 UDATA (&ptp_svc
, UNIT_SEQ
+UNIT_ATTABLE
, 0), SERIAL_OUT_WAIT
140 { GRDATA (BUF
, ptp_unit
.buf
, DEV_RDX
, 8, 0) },
141 { GRDATA (CSR
, ptp_csr
, DEV_RDX
, 16, 0) },
142 { FLDATA (INT
, int_req
, INT_V_PTP
) },
143 { FLDATA (ERR
, ptp_csr
, CSR_V_ERR
) },
144 { FLDATA (DONE
, ptp_csr
, CSR_V_DONE
) },
145 { FLDATA (IE
, ptp_csr
, CSR_V_IE
) },
146 { DRDATA (POS
, ptp_unit
.pos
, T_ADDR_W
), PV_LEFT
},
147 { DRDATA (TIME
, ptp_unit
.wait
, 24), PV_LEFT
},
148 { FLDATA (STOP_IOE
, ptp_stopioe
, 0) },
153 { MTAB_XTD
|MTAB_VDV
, 0, "ADDRESS", NULL
,
154 NULL
, &show_addr
, NULL
},
155 { MTAB_XTD
|MTAB_VDV
, 0, "VECTOR", NULL
,
156 NULL
, &show_vec
, NULL
},
161 "PTP", &ptp_unit
, ptp_reg
, ptp_mod
,
162 1, 10, 31, 1, DEV_RDX
, 8,
163 NULL
, NULL
, &ptp_reset
,
164 NULL
, &ptp_attach
, &ptp_detach
,
165 &ptp_dib
, DEV_DISABLE
| PT_DIS
| DEV_UBUS
| DEV_QBUS
168 /* Paper tape reader I/O address routines */
170 t_stat
ptr_rd (int32
*data
, int32 PA
, int32 access
)
172 switch ((PA
>> 1) & 01) { /* decode PA<1> */
174 case 0: /* ptr csr */
175 *data
= ptr_csr
& PTRCSR_IMP
;
178 case 1: /* ptr buf */
179 ptr_csr
= ptr_csr
& ~CSR_DONE
;
181 *data
= ptr_unit
.buf
& 0377;
185 return SCPE_NXM
; /* can't get here */
188 t_stat
ptr_wr (int32 data
, int32 PA
, int32 access
)
190 switch ((PA
>> 1) & 01) { /* decode PA<1> */
192 case 0: /* ptr csr */
193 if (PA
& 1) return SCPE_OK
;
194 if ((data
& CSR_IE
) == 0) CLR_INT (PTR
);
195 else if (((ptr_csr
& CSR_IE
) == 0) && (ptr_csr
& (CSR_ERR
| CSR_DONE
)))
198 ptr_csr
= (ptr_csr
& ~CSR_DONE
) | CSR_BUSY
;
200 if (ptr_unit
.flags
& UNIT_ATT
) /* data to read? */
201 sim_activate (&ptr_unit
, ptr_unit
.wait
);
202 else sim_activate (&ptr_unit
, 0); /* error if not */
204 ptr_csr
= (ptr_csr
& ~PTRCSR_RW
) | (data
& PTRCSR_RW
);
207 case 1: /* ptr buf */
209 } /* end switch PA */
211 return SCPE_NXM
; /* can't get here */
214 /* Paper tape reader service */
216 t_stat
ptr_svc (UNIT
*uptr
)
220 ptr_csr
= (ptr_csr
| CSR_ERR
) & ~CSR_BUSY
;
221 if (ptr_csr
& CSR_IE
) SET_INT (PTR
);
222 if ((ptr_unit
.flags
& UNIT_ATT
) == 0)
223 return IORETURN (ptr_stopioe
, SCPE_UNATT
);
224 if ((temp
= getc (ptr_unit
.fileref
)) == EOF
) {
225 if (feof (ptr_unit
.fileref
)) {
226 if (ptr_stopioe
) printf ("PTR end of file\n");
229 else perror ("PTR I/O error");
230 clearerr (ptr_unit
.fileref
);
233 ptr_csr
= (ptr_csr
| CSR_DONE
) & ~CSR_ERR
;
234 ptr_unit
.buf
= temp
& 0377;
235 ptr_unit
.pos
= ptr_unit
.pos
+ 1;
239 /* Paper tape reader support routines */
241 t_stat
ptr_reset (DEVICE
*dptr
)
245 if ((ptr_unit
.flags
& UNIT_ATT
) == 0) ptr_csr
= ptr_csr
| CSR_ERR
;
247 sim_cancel (&ptr_unit
);
251 t_stat
ptr_attach (UNIT
*uptr
, char *cptr
)
255 reason
= attach_unit (uptr
, cptr
);
256 if ((ptr_unit
.flags
& UNIT_ATT
) == 0) ptr_csr
= ptr_csr
| CSR_ERR
;
257 else ptr_csr
= ptr_csr
& ~CSR_ERR
;
261 t_stat
ptr_detach (UNIT
*uptr
)
263 ptr_csr
= ptr_csr
| CSR_ERR
;
264 return detach_unit (uptr
);
267 /* Paper tape punch I/O address routines */
269 t_stat
ptp_rd (int32
*data
, int32 PA
, int32 access
)
271 switch ((PA
>> 1) & 01) { /* decode PA<1> */
273 case 0: /* ptp csr */
274 *data
= ptp_csr
& PTPCSR_IMP
;
277 case 1: /* ptp buf */
278 *data
= ptp_unit
.buf
;
282 return SCPE_NXM
; /* can't get here */
285 t_stat
ptp_wr (int32 data
, int32 PA
, int32 access
)
287 switch ((PA
>> 1) & 01) { /* decode PA<1> */
289 case 0: /* ptp csr */
290 if (PA
& 1) return SCPE_OK
;
291 if ((data
& CSR_IE
) == 0) CLR_INT (PTP
);
292 else if (((ptp_csr
& CSR_IE
) == 0) && (ptp_csr
& (CSR_ERR
| CSR_DONE
)))
294 ptp_csr
= (ptp_csr
& ~PTPCSR_RW
) | (data
& PTPCSR_RW
);
297 case 1: /* ptp buf */
298 if ((PA
& 1) == 0) ptp_unit
.buf
= data
& 0377;
299 ptp_csr
= ptp_csr
& ~CSR_DONE
;
301 if (ptp_unit
.flags
& UNIT_ATT
) /* file to write? */
302 sim_activate (&ptp_unit
, ptp_unit
.wait
);
303 else sim_activate (&ptp_unit
, 0); /* error if not */
305 } /* end switch PA */
307 return SCPE_NXM
; /* can't get here */
310 /* Paper tape punch service */
312 t_stat
ptp_svc (UNIT
*uptr
)
314 ptp_csr
= ptp_csr
| CSR_ERR
| CSR_DONE
;
315 if (ptp_csr
& CSR_IE
) SET_INT (PTP
);
316 if ((ptp_unit
.flags
& UNIT_ATT
) == 0)
317 return IORETURN (ptp_stopioe
, SCPE_UNATT
);
318 if (putc (ptp_unit
.buf
, ptp_unit
.fileref
) == EOF
) {
319 perror ("PTP I/O error");
320 clearerr (ptp_unit
.fileref
);
323 ptp_csr
= ptp_csr
& ~CSR_ERR
;
324 ptp_unit
.pos
= ptp_unit
.pos
+ 1;
328 /* Paper tape punch support routines */
330 t_stat
ptp_reset (DEVICE
*dptr
)
334 if ((ptp_unit
.flags
& UNIT_ATT
) == 0) ptp_csr
= ptp_csr
| CSR_ERR
;
336 sim_cancel (&ptp_unit
); /* deactivate unit */
340 t_stat
ptp_attach (UNIT
*uptr
, char *cptr
)
344 reason
= attach_unit (uptr
, cptr
);
345 if ((ptp_unit
.flags
& UNIT_ATT
) == 0) ptp_csr
= ptp_csr
| CSR_ERR
;
346 else ptp_csr
= ptp_csr
& ~CSR_ERR
;
350 t_stat
ptp_detach (UNIT
*uptr
)
352 ptp_csr
= ptp_csr
| CSR_ERR
;
353 return detach_unit (uptr
);