1 /* ibm1130_ptrp.c: IBM 1130 paper tape reader/punch emulation
3 Based on the SIMH simulator package written by Robert M Supnik
10 * (C) Copyright 2004, Brian Knittel.
11 * You may freely use this program, but: it offered strictly on an AS-IS, AT YOUR OWN
12 * RISK basis, there is no warranty of fitness for any purpose, and the rest of the
13 * usual yada-yada. Please keep this notice and the copyright in any distributions
16 * This is not a supported product, but I welcome bug reports and fixes.
17 * Mail to simh@ibm1130.org
20 #include "ibm1130_defs.h"
22 /***************************************************************************************
23 * 1134 Paper Tape Reader device PTR
24 * 1055 Paper Tape Punch device PTP (shares DSW with PTR)
25 ***************************************************************************************/
27 #define PTR1134_DSW_READER_RESPONSE 0x4000
28 #define PTR1134_DSW_PUNCH_RESPONSE 0x1000
29 #define PTR1134_DSW_READER_BUSY 0x0800
30 #define PTR1134_DSW_READER_NOT_READY 0x0400
31 #define PTR1134_DSW_PUNCH_BUSY 0x0200
32 #define PTR1134_DSW_PUNCH_NOT_READY 0x0100
34 #define IS_ONLINE(u) (((u)->flags & (UNIT_ATT|UNIT_DIS)) == UNIT_ATT)
36 static t_stat
ptr_svc (UNIT
*uptr
);
37 static t_stat
ptr_reset (DEVICE
*dptr
);
38 static t_stat
ptr_attach (UNIT
*uptr
, char *cptr
);
39 static t_stat
ptr_detach (UNIT
*uptr
);
40 static t_stat
ptr_boot (int unitno
, DEVICE
*dptr
);
41 static t_stat
ptp_svc (UNIT
*uptr
);
42 static t_stat
ptp_reset (DEVICE
*dptr
);
43 static t_stat
ptp_attach (UNIT
*uptr
, char *cptr
);
44 static t_stat
ptp_detach (UNIT
*uptr
);
46 static int16 ptr_dsw
= 0; /* device status word */
47 static int32 ptr_wait
= 1000; /* character read wait */
48 static uint8 ptr_char
= 0; /* last character read */
49 static int32 ptp_wait
= 1000; /* character punch wait */
52 { UDATA (&ptr_svc
, UNIT_ATTABLE
, 0) },
56 { HRDATA (DSW
, ptr_dsw
, 16) }, /* device status word */
57 { DRDATA (WTIME
, ptr_wait
, 24), PV_LEFT
}, /* character read wait */
58 { DRDATA (LASTCHAR
, ptr_char
, 8), PV_LEFT
}, /* last character read */
62 "PTR", ptr_unit
, ptr_reg
, NULL
,
64 NULL
, NULL
, ptr_reset
,
65 ptr_boot
, ptr_attach
, ptr_detach
};
68 { UDATA (&ptp_svc
, UNIT_ATTABLE
, 0) },
72 { HRDATA (DSW
, ptr_dsw
, 16) }, /* device status word (this is the same as the reader's!) */
73 { DRDATA (WTIME
, ptp_wait
, 24), PV_LEFT
}, /* character punch wait */
77 "PTP", ptp_unit
, ptp_reg
, NULL
,
79 NULL
, NULL
, ptp_reset
,
80 NULL
, ptp_attach
, ptp_detach
};
82 /* xio_1134_papertape - XIO command interpreter for the 1134 paper tape reader and 1055 paper tape punch */
84 void xio_1134_papertape (int32 iocc_addr
, int32 iocc_func
, int32 iocc_mod
)
89 case XIO_READ
: /* read: return last character read */
90 M
[iocc_addr
& mem_mask
] = (uint16
) (ptr_char
<< 8);
93 case XIO_WRITE
: /* write: initiate punch operation */
94 if ((ptr_dsw
& PTR1134_DSW_PUNCH_NOT_READY
) == 0 && IS_ONLINE(ptp_unit
)) {
95 putc((M
[iocc_addr
& mem_mask
] >> 8) & 0xFF, ptp_unit
->fileref
);
98 sim_activate(ptp_unit
, ptp_wait
); /* schedule interrupt */
99 SETBIT(ptr_dsw
, PTR1134_DSW_PUNCH_NOT_READY
| PTR1134_DSW_PUNCH_BUSY
);
102 case XIO_SENSE_DEV
: /* sense device status */
104 if (iocc_mod
& 0x01) { /* reset interrupts */
105 CLRBIT(ptr_dsw
, PTR1134_DSW_READER_RESPONSE
| PTR1134_DSW_PUNCH_RESPONSE
);
106 CLRBIT(ILSW
[4], ILSW_4_1134_TAPE
);
110 case XIO_CONTROL
: /* control: initiate character read */
111 sim_activate(ptr_unit
, ptr_wait
); /* schedule interrupt */
112 SETBIT(ptr_dsw
, PTR1134_DSW_READER_BUSY
| PTR1134_DSW_READER_NOT_READY
);
116 sprintf(msg
, "Invalid 1134 reader/1055 punch XIO function %x", iocc_func
);
121 /* ptr_svc - emulated timeout - 1134 read operation complete */
123 static t_stat
ptr_svc (UNIT
*uptr
)
125 CLRBIT(ptr_dsw
, PTR1134_DSW_READER_BUSY
); /* clear reader busy flag */
126 SETBIT(ptr_dsw
, PTR1134_DSW_READER_NOT_READY
); /* assume at end of file */
128 if (IS_ONLINE(uptr
)) { /* fetch character from file */
129 ptr_char
= getc(uptr
->fileref
);
132 if (! feof(uptr
->fileref
)) /* there's more left */
133 CLRBIT(ptr_dsw
, PTR1134_DSW_READER_NOT_READY
);
136 SETBIT(ptr_dsw
, PTR1134_DSW_READER_RESPONSE
); /* indicate read complete */
138 SETBIT(ILSW
[4], ILSW_4_1134_TAPE
); /* initiate interrupt */
144 /* ptp_svc - emulated timeout -- 1055 punch operation complete */
146 static t_stat
ptp_svc (UNIT
*uptr
)
148 CLRBIT(ptr_dsw
, PTR1134_DSW_PUNCH_BUSY
); /* clear punch busy flag */
150 if (IS_ONLINE(uptr
)) /* update punch ready status */
151 CLRBIT(ptr_dsw
, PTR1134_DSW_PUNCH_NOT_READY
);
153 SETBIT(ptr_dsw
, PTR1134_DSW_PUNCH_NOT_READY
);
155 SETBIT(ptr_dsw
, PTR1134_DSW_PUNCH_RESPONSE
); /* indicate punch complete */
157 SETBIT(ILSW
[4], ILSW_4_1134_TAPE
); /* initiate interrupt */
163 /* ptr_reset - reset emulated paper tape reader */
165 static t_stat
ptr_reset (DEVICE
*dptr
)
167 sim_cancel(ptr_unit
);
169 CLRBIT(ptr_dsw
, PTR1134_DSW_READER_BUSY
| PTR1134_DSW_READER_RESPONSE
);
170 SETBIT(ptr_dsw
, PTR1134_DSW_READER_NOT_READY
);
172 if (IS_ONLINE(ptr_unit
) && ! feof(ptr_unit
->fileref
))
173 CLRBIT(ptr_dsw
, PTR1134_DSW_READER_NOT_READY
);
175 if ((ptr_dsw
& PTR1134_DSW_PUNCH_RESPONSE
) == 0) { /* punch isn't interrupting either */
176 CLRBIT(ILSW
[4], ILSW_4_1134_TAPE
);
183 /* ptp_reset - reset emulated paper tape punch */
185 static t_stat
ptp_reset (DEVICE
*dptr
)
187 sim_cancel(ptp_unit
);
189 CLRBIT(ptr_dsw
, PTR1134_DSW_PUNCH_BUSY
| PTR1134_DSW_PUNCH_RESPONSE
);
190 SETBIT(ptr_dsw
, PTR1134_DSW_PUNCH_NOT_READY
);
192 if (IS_ONLINE(ptp_unit
))
193 CLRBIT(ptr_dsw
, PTR1134_DSW_PUNCH_NOT_READY
);
195 if ((ptr_dsw
& PTR1134_DSW_READER_RESPONSE
) == 0) { /* reader isn't interrupting either */
196 CLRBIT(ILSW
[4], ILSW_4_1134_TAPE
);
203 /* ptr_attach - attach file to simulated paper tape reader */
205 static t_stat
ptr_attach (UNIT
*uptr
, char *cptr
)
209 SETBIT(ptr_dsw
, PTR1134_DSW_READER_NOT_READY
); /* assume failure */
211 if ((rval
= attach_unit(uptr
, cptr
)) != SCPE_OK
) /* use standard attach */
214 if ((ptr_dsw
& PTR1134_DSW_READER_BUSY
) == 0 && ! feof(uptr
->fileref
))
215 CLRBIT(ptr_dsw
, PTR1134_DSW_READER_NOT_READY
); /* we're in business */
220 /* ptr_attach - detach file from simulated paper tape reader */
222 static t_stat
ptr_detach (UNIT
*uptr
)
224 SETBIT(ptr_dsw
, PTR1134_DSW_READER_NOT_READY
);
226 return detach_unit(uptr
);
229 /* ptr_attach - perform paper tape initial program load */
231 static t_stat
ptr_boot (int unitno
, DEVICE
*dptr
)
233 int ch
, nch
, val
, addr
;
234 t_bool leader
= TRUE
, start
= FALSE
;
242 if ((ch
= getc(ptr_unit
->fileref
)) == EOF
) {
243 printf("EOF on paper tape without finding Channel 5 end-of-load mark\n");
248 if ((ch
& 0x7F) == 0x7F) /* ignore leading rubouts or "delete" characters */
251 leader
= FALSE
; /* after first nonrubout, any punch in channel 5 terminates load */
254 /* this is untested -- not sure of actual byte ordering */
256 val
= (val
<< 4) | (ch
& 0x0F); /* get next nybble */
258 if (++nch
== 4) { /* if we now have four nybbles, store the word */
259 M
[addr
& mem_mask
] = (uint16
) val
;
261 addr
++; /* prepare for next word */
266 if (ch
& 0x10) { /* channel 5 punch terminates load */
272 if (! start
) /* if we didn't get a valid load, report EOF error */
275 if ((rval
= reset_all(0)) != SCPE_OK
) /* force a reset */
278 IAR
= 0; /* start running at address 0 */
282 /* ptp_attach - attach file to simulated paper tape punch */
284 static t_stat
ptp_attach (UNIT
*uptr
, char *cptr
)
288 SETBIT(ptr_dsw
, PTR1134_DSW_PUNCH_NOT_READY
); /* assume failure */
290 if ((rval
= attach_unit(uptr
, cptr
)) != SCPE_OK
) /* use standard attach */
293 fseek(uptr
->fileref
, 0, SEEK_END
); /* if we opened an existing file, append to it */
294 uptr
->pos
= ftell(uptr
->fileref
);
296 if ((ptr_dsw
& PTR1134_DSW_PUNCH_BUSY
) == 0)
297 CLRBIT(ptr_dsw
, PTR1134_DSW_PUNCH_NOT_READY
); /* we're in business */
302 /* ptp_detach - detach file from simulated paper tape punch */
304 static t_stat
ptp_detach (UNIT
*uptr
)
306 SETBIT(ptr_dsw
, PTR1134_DSW_PUNCH_NOT_READY
);
308 return detach_unit(uptr
);