1 /* pdp8_pt.c: PDP-8 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.
26 ptr,ptp PC8E paper tape reader/punch
28 25-Apr-03 RMS Revised for extended file support
29 04-Oct-02 RMS Added DIBs
30 30-May-02 RMS Widened POS to 32b
31 30-Nov-01 RMS Added read only unit support
32 30-Mar-98 RMS Added RIM loader as PTR bootstrap
35 #include "pdp8_defs.h"
37 extern int32 int_req
, int_enable
, dev_done
, stop_inst
;
39 int32 ptr_stopioe
= 0, ptp_stopioe
= 0; /* stop on error */
41 int32
ptr (int32 IR
, int32 AC
);
42 int32
ptp (int32 IR
, int32 AC
);
43 t_stat
ptr_svc (UNIT
*uptr
);
44 t_stat
ptp_svc (UNIT
*uptr
);
45 t_stat
ptr_reset (DEVICE
*dptr
);
46 t_stat
ptp_reset (DEVICE
*dptr
);
47 t_stat
ptr_boot (int32 unitno
, DEVICE
*dptr
);
49 /* PTR data structures
51 ptr_dev PTR device descriptor
52 ptr_unit PTR unit descriptor
53 ptr_reg PTR register list
56 DIB ptr_dib
= { DEV_PTR
, 1, { &ptr
} };
59 UDATA (&ptr_svc
, UNIT_SEQ
+UNIT_ATTABLE
+UNIT_ROABLE
, 0),
64 { ORDATA (BUF
, ptr_unit
.buf
, 8) },
65 { FLDATA (DONE
, dev_done
, INT_V_PTR
) },
66 { FLDATA (ENABLE
, int_enable
, INT_V_PTR
) },
67 { FLDATA (INT
, int_req
, INT_V_PTR
) },
68 { DRDATA (POS
, ptr_unit
.pos
, T_ADDR_W
), PV_LEFT
},
69 { DRDATA (TIME
, ptr_unit
.wait
, 24), PV_LEFT
},
70 { FLDATA (STOP_IOE
, ptr_stopioe
, 0) },
75 { MTAB_XTD
|MTAB_VDV
, 0, "DEVNO", NULL
, NULL
, &show_dev
},
80 "PTR", &ptr_unit
, ptr_reg
, ptr_mod
,
82 NULL
, NULL
, &ptr_reset
,
83 &ptr_boot
, NULL
, NULL
,
86 /* PTP data structures
88 ptp_dev PTP device descriptor
89 ptp_unit PTP unit descriptor
90 ptp_reg PTP register list
93 DIB ptp_dib
= { DEV_PTP
, 1, { &ptp
} };
96 UDATA (&ptp_svc
, UNIT_SEQ
+UNIT_ATTABLE
, 0), SERIAL_OUT_WAIT
100 { ORDATA (BUF
, ptp_unit
.buf
, 8) },
101 { FLDATA (DONE
, dev_done
, INT_V_PTP
) },
102 { FLDATA (ENABLE
, int_enable
, INT_V_PTP
) },
103 { FLDATA (INT
, int_req
, INT_V_PTP
) },
104 { DRDATA (POS
, ptp_unit
.pos
, T_ADDR_W
), PV_LEFT
},
105 { DRDATA (TIME
, ptp_unit
.wait
, 24), PV_LEFT
},
106 { FLDATA (STOP_IOE
, ptp_stopioe
, 0) },
111 { MTAB_XTD
|MTAB_VDV
, 0, "DEVNO", NULL
, NULL
, &show_dev
},
116 "PTP", &ptp_unit
, ptp_reg
, ptp_mod
,
118 NULL
, NULL
, &ptp_reset
,
123 /* Paper tape reader: IOT routine */
125 int32
ptr (int32 IR
, int32 AC
)
127 switch (IR
& 07) { /* decode IR<9:11> */
130 int_enable
= int_enable
| (INT_PTR
+INT_PTP
); /* set enable */
131 int_req
= INT_UPDATE
; /* update interrupts */
135 return (dev_done
& INT_PTR
)? IOT_SKP
+ AC
: AC
;
137 case 6: /* RFC!RRB */
138 sim_activate (&ptr_unit
, ptr_unit
.wait
);
140 dev_done
= dev_done
& ~INT_PTR
; /* clear flag */
141 int_req
= int_req
& ~INT_PTR
; /* clear int req */
142 return (AC
| ptr_unit
.buf
); /* or data to AC */
145 sim_activate (&ptr_unit
, ptr_unit
.wait
);
146 dev_done
= dev_done
& ~INT_PTR
; /* clear flag */
147 int_req
= int_req
& ~INT_PTR
; /* clear int req */
151 return (stop_inst
<< IOT_V_REASON
) + AC
;
157 t_stat
ptr_svc (UNIT
*uptr
)
161 if ((ptr_unit
.flags
& UNIT_ATT
) == 0) /* attached? */
162 return IORETURN (ptr_stopioe
, SCPE_UNATT
);
163 if ((temp
= getc (ptr_unit
.fileref
)) == EOF
) {
164 if (feof (ptr_unit
.fileref
)) {
165 if (ptr_stopioe
) printf ("PTR end of file\n");
168 else perror ("PTR I/O error");
169 clearerr (ptr_unit
.fileref
);
172 dev_done
= dev_done
| INT_PTR
; /* set done */
173 int_req
= INT_UPDATE
; /* update interrupts */
174 ptr_unit
.buf
= temp
& 0377;
175 ptr_unit
.pos
= ptr_unit
.pos
+ 1;
181 t_stat
ptr_reset (DEVICE
*dptr
)
184 dev_done
= dev_done
& ~INT_PTR
; /* clear done, int */
185 int_req
= int_req
& ~INT_PTR
;
186 int_enable
= int_enable
| INT_PTR
; /* set enable */
187 sim_cancel (&ptr_unit
); /* deactivate unit */
191 /* Paper tape punch: IOT routine */
193 int32
ptp (int32 IR
, int32 AC
)
195 switch (IR
& 07) { /* decode IR<9:11> */
198 int_enable
= int_enable
& ~(INT_PTR
+INT_PTP
); /* clear enables */
199 int_req
= INT_UPDATE
; /* update interrupts */
203 return (dev_done
& INT_PTP
)? IOT_SKP
+ AC
: AC
;
206 dev_done
= dev_done
& ~INT_PTP
; /* clear flag */
207 int_req
= int_req
& ~INT_PTP
; /* clear int req */
211 dev_done
= dev_done
& ~INT_PTP
; /* clear flag */
212 int_req
= int_req
& ~INT_PTP
; /* clear int req */
214 ptp_unit
.buf
= AC
& 0377; /* load punch buf */
215 sim_activate (&ptp_unit
, ptp_unit
.wait
); /* activate unit */
219 return (stop_inst
<< IOT_V_REASON
) + AC
;
225 t_stat
ptp_svc (UNIT
*uptr
)
227 dev_done
= dev_done
| INT_PTP
; /* set done */
228 int_req
= INT_UPDATE
; /* update interrupts */
229 if ((ptp_unit
.flags
& UNIT_ATT
) == 0) /* attached? */
230 return IORETURN (ptp_stopioe
, SCPE_UNATT
);
231 if (putc (ptp_unit
.buf
, ptp_unit
.fileref
) == EOF
) {
232 perror ("PTP I/O error");
233 clearerr (ptp_unit
.fileref
);
236 ptp_unit
.pos
= ptp_unit
.pos
+ 1;
242 t_stat
ptp_reset (DEVICE
*dptr
)
245 dev_done
= dev_done
& ~INT_PTP
; /* clear done, int */
246 int_req
= int_req
& ~INT_PTP
;
247 int_enable
= int_enable
| INT_PTP
; /* set enable */
248 sim_cancel (&ptp_unit
); /* deactivate unit */
252 /* Bootstrap routine */
254 #define BOOT_START 07756
255 #define BOOT_LEN (sizeof (boot_rom) / sizeof (int16))
257 static const uint16 boot_rom
[] = {
258 06014, /* 7756, RFC */
259 06011, /* 7757, LOOP, RSF */
265 05374, /* JMP 7774 */
271 03776, /* DCA I 7776 */
272 03376, /* 7774, DCA 7776 */
273 05357, /* JMP 7757 */
275 05301 /* 7777, JMP 7701 */
278 t_stat
ptr_boot (int32 unitno
, DEVICE
*dptr
)
281 extern int32 saved_PC
;
284 if (ptr_dib
.dev
!= DEV_PTR
) return STOP_NOTSTD
; /* only std devno */
285 for (i
= 0; i
< BOOT_LEN
; i
++) M
[BOOT_START
+ i
] = boot_rom
[i
];
286 saved_PC
= BOOT_START
;