First Commit of my working state
[simh.git] / Ibm1130 / ibm1130_ptrp.c
CommitLineData
196ba1fc
PH
1/* ibm1130_ptrp.c: IBM 1130 paper tape reader/punch emulation\r
2\r
3 Based on the SIMH simulator package written by Robert M Supnik\r
4\r
5 Brian Knittel\r
6 Revision History\r
7\r
8 2004.10.22 - Written.\r
9\r
10 * (C) Copyright 2004, Brian Knittel.\r
11 * You may freely use this program, but: it offered strictly on an AS-IS, AT YOUR OWN\r
12 * RISK basis, there is no warranty of fitness for any purpose, and the rest of the\r
13 * usual yada-yada. Please keep this notice and the copyright in any distributions\r
14 * or modifications.\r
15 *\r
16 * This is not a supported product, but I welcome bug reports and fixes.\r
17 * Mail to simh@ibm1130.org\r
18 */\r
19\r
20#include "ibm1130_defs.h"\r
21\r
22/***************************************************************************************\r
23 * 1134 Paper Tape Reader device PTR\r
24 * 1055 Paper Tape Punch device PTP (shares DSW with PTR)\r
25 ***************************************************************************************/\r
26\r
27#define PTR1134_DSW_READER_RESPONSE 0x4000\r
28#define PTR1134_DSW_PUNCH_RESPONSE 0x1000\r
29#define PTR1134_DSW_READER_BUSY 0x0800\r
30#define PTR1134_DSW_READER_NOT_READY 0x0400\r
31#define PTR1134_DSW_PUNCH_BUSY 0x0200\r
32#define PTR1134_DSW_PUNCH_NOT_READY 0x0100\r
33\r
34#define IS_ONLINE(u) (((u)->flags & (UNIT_ATT|UNIT_DIS)) == UNIT_ATT)\r
35\r
36static t_stat ptr_svc (UNIT *uptr);\r
37static t_stat ptr_reset (DEVICE *dptr);\r
38static t_stat ptr_attach (UNIT *uptr, char *cptr);\r
39static t_stat ptr_detach (UNIT *uptr);\r
40static t_stat ptr_boot (int unitno, DEVICE *dptr);\r
41static t_stat ptp_svc (UNIT *uptr);\r
42static t_stat ptp_reset (DEVICE *dptr);\r
43static t_stat ptp_attach (UNIT *uptr, char *cptr);\r
44static t_stat ptp_detach (UNIT *uptr);\r
45\r
46static int16 ptr_dsw = 0; /* device status word */\r
47static int32 ptr_wait = 1000; /* character read wait */\r
48static uint8 ptr_char = 0; /* last character read */\r
49static int32 ptp_wait = 1000; /* character punch wait */\r
50\r
51UNIT ptr_unit[1] = {\r
52 { UDATA (&ptr_svc, UNIT_ATTABLE, 0) },\r
53};\r
54\r
55REG ptr_reg[] = {\r
56 { HRDATA (DSW, ptr_dsw, 16) }, /* device status word */\r
57 { DRDATA (WTIME, ptr_wait, 24), PV_LEFT }, /* character read wait */\r
58 { DRDATA (LASTCHAR, ptr_char, 8), PV_LEFT }, /* last character read */\r
59 { NULL } };\r
60\r
61DEVICE ptr_dev = {\r
62 "PTR", ptr_unit, ptr_reg, NULL,\r
63 1, 16, 16, 1, 16, 16,\r
64 NULL, NULL, ptr_reset,\r
65 ptr_boot, ptr_attach, ptr_detach};\r
66\r
67UNIT ptp_unit[1] = {\r
68 { UDATA (&ptp_svc, UNIT_ATTABLE, 0) },\r
69};\r
70\r
71REG ptp_reg[] = {\r
72 { HRDATA (DSW, ptr_dsw, 16) }, /* device status word (this is the same as the reader's!) */\r
73 { DRDATA (WTIME, ptp_wait, 24), PV_LEFT }, /* character punch wait */\r
74 { NULL } };\r
75\r
76DEVICE ptp_dev = {\r
77 "PTP", ptp_unit, ptp_reg, NULL,\r
78 1, 16, 16, 1, 16, 16,\r
79 NULL, NULL, ptp_reset,\r
80 NULL, ptp_attach, ptp_detach};\r
81\r
82/* xio_1134_papertape - XIO command interpreter for the 1134 paper tape reader and 1055 paper tape punch */\r
83\r
84void xio_1134_papertape (int32 iocc_addr, int32 iocc_func, int32 iocc_mod)\r
85{\r
86 char msg[80];\r
87\r
88 switch (iocc_func) {\r
89 case XIO_READ: /* read: return last character read */\r
90 M[iocc_addr & mem_mask] = (uint16) (ptr_char << 8);\r
91 break;\r
92\r
93 case XIO_WRITE: /* write: initiate punch operation */\r
94 if ((ptr_dsw & PTR1134_DSW_PUNCH_NOT_READY) == 0 && IS_ONLINE(ptp_unit)) {\r
95 putc((M[iocc_addr & mem_mask] >> 8) & 0xFF, ptp_unit->fileref);\r
96 ptp_unit->pos++;\r
97 }\r
98 sim_activate(ptp_unit, ptp_wait); /* schedule interrupt */\r
99 SETBIT(ptr_dsw, PTR1134_DSW_PUNCH_NOT_READY | PTR1134_DSW_PUNCH_BUSY);\r
100 break;\r
101\r
102 case XIO_SENSE_DEV: /* sense device status */\r
103 ACC = ptr_dsw;\r
104 if (iocc_mod & 0x01) { /* reset interrupts */\r
105 CLRBIT(ptr_dsw, PTR1134_DSW_READER_RESPONSE | PTR1134_DSW_PUNCH_RESPONSE);\r
106 CLRBIT(ILSW[4], ILSW_4_1134_TAPE);\r
107 }\r
108 break;\r
109\r
110 case XIO_CONTROL: /* control: initiate character read */\r
111 sim_activate(ptr_unit, ptr_wait); /* schedule interrupt */\r
112 SETBIT(ptr_dsw, PTR1134_DSW_READER_BUSY | PTR1134_DSW_READER_NOT_READY);\r
113 break;\r
114\r
115 default:\r
116 sprintf(msg, "Invalid 1134 reader/1055 punch XIO function %x", iocc_func);\r
117 xio_error(msg);\r
118 }\r
119}\r
120\r
121/* ptr_svc - emulated timeout - 1134 read operation complete */\r
122\r
123static t_stat ptr_svc (UNIT *uptr)\r
124{\r
125 CLRBIT(ptr_dsw, PTR1134_DSW_READER_BUSY); /* clear reader busy flag */\r
126 SETBIT(ptr_dsw, PTR1134_DSW_READER_NOT_READY); /* assume at end of file */\r
127\r
128 if (IS_ONLINE(uptr)) { /* fetch character from file */\r
129 ptr_char = getc(uptr->fileref);\r
130 uptr->pos++;\r
131\r
132 if (! feof(uptr->fileref)) /* there's more left */\r
133 CLRBIT(ptr_dsw, PTR1134_DSW_READER_NOT_READY);\r
134 }\r
135\r
136 SETBIT(ptr_dsw, PTR1134_DSW_READER_RESPONSE); /* indicate read complete */\r
137\r
138 SETBIT(ILSW[4], ILSW_4_1134_TAPE); /* initiate interrupt */\r
139 calc_ints();\r
140\r
141 return SCPE_OK;\r
142}\r
143\r
144/* ptp_svc - emulated timeout -- 1055 punch operation complete */\r
145\r
146static t_stat ptp_svc (UNIT *uptr)\r
147{\r
148 CLRBIT(ptr_dsw, PTR1134_DSW_PUNCH_BUSY); /* clear punch busy flag */\r
149\r
150 if (IS_ONLINE(uptr)) /* update punch ready status */\r
151 CLRBIT(ptr_dsw, PTR1134_DSW_PUNCH_NOT_READY);\r
152 else\r
153 SETBIT(ptr_dsw, PTR1134_DSW_PUNCH_NOT_READY);\r
154 \r
155 SETBIT(ptr_dsw, PTR1134_DSW_PUNCH_RESPONSE); /* indicate punch complete */\r
156\r
157 SETBIT(ILSW[4], ILSW_4_1134_TAPE); /* initiate interrupt */\r
158 calc_ints();\r
159\r
160 return SCPE_OK;\r
161}\r
162\r
163/* ptr_reset - reset emulated paper tape reader */\r
164\r
165static t_stat ptr_reset (DEVICE *dptr)\r
166{\r
167 sim_cancel(ptr_unit);\r
168\r
169 CLRBIT(ptr_dsw, PTR1134_DSW_READER_BUSY | PTR1134_DSW_READER_RESPONSE);\r
170 SETBIT(ptr_dsw, PTR1134_DSW_READER_NOT_READY);\r
171\r
172 if (IS_ONLINE(ptr_unit) && ! feof(ptr_unit->fileref))\r
173 CLRBIT(ptr_dsw, PTR1134_DSW_READER_NOT_READY);\r
174\r
175 if ((ptr_dsw & PTR1134_DSW_PUNCH_RESPONSE) == 0) { /* punch isn't interrupting either */\r
176 CLRBIT(ILSW[4], ILSW_4_1134_TAPE);\r
177 calc_ints();\r
178 }\r
179\r
180 return SCPE_OK;\r
181}\r
182\r
183/* ptp_reset - reset emulated paper tape punch */\r
184\r
185static t_stat ptp_reset (DEVICE *dptr)\r
186{\r
187 sim_cancel(ptp_unit);\r
188\r
189 CLRBIT(ptr_dsw, PTR1134_DSW_PUNCH_BUSY | PTR1134_DSW_PUNCH_RESPONSE);\r
190 SETBIT(ptr_dsw, PTR1134_DSW_PUNCH_NOT_READY);\r
191\r
192 if (IS_ONLINE(ptp_unit))\r
193 CLRBIT(ptr_dsw, PTR1134_DSW_PUNCH_NOT_READY);\r
194\r
195 if ((ptr_dsw & PTR1134_DSW_READER_RESPONSE) == 0) { /* reader isn't interrupting either */\r
196 CLRBIT(ILSW[4], ILSW_4_1134_TAPE);\r
197 calc_ints();\r
198 }\r
199\r
200 return SCPE_OK;\r
201}\r
202\r
203/* ptr_attach - attach file to simulated paper tape reader */\r
204\r
205static t_stat ptr_attach (UNIT *uptr, char *cptr)\r
206{\r
207 t_stat rval;\r
208\r
209 SETBIT(ptr_dsw, PTR1134_DSW_READER_NOT_READY); /* assume failure */\r
210\r
211 if ((rval = attach_unit(uptr, cptr)) != SCPE_OK) /* use standard attach */\r
212 return rval;\r
213\r
214 if ((ptr_dsw & PTR1134_DSW_READER_BUSY) == 0 && ! feof(uptr->fileref))\r
215 CLRBIT(ptr_dsw, PTR1134_DSW_READER_NOT_READY); /* we're in business */\r
216\r
217 return SCPE_OK;\r
218}\r
219\r
220/* ptr_attach - detach file from simulated paper tape reader */\r
221\r
222static t_stat ptr_detach (UNIT *uptr)\r
223{\r
224 SETBIT(ptr_dsw, PTR1134_DSW_READER_NOT_READY);\r
225\r
226 return detach_unit(uptr);\r
227}\r
228\r
229/* ptr_attach - perform paper tape initial program load */\r
230\r
231static t_stat ptr_boot (int unitno, DEVICE *dptr)\r
232{\r
233 int ch, nch, val, addr;\r
234 t_bool leader = TRUE, start = FALSE;\r
235 t_stat rval;\r
236\r
237 addr = 0;\r
238 nch = 0;\r
239 val = 0;\r
240\r
241 for (;;) {\r
242 if ((ch = getc(ptr_unit->fileref)) == EOF) {\r
243 printf("EOF on paper tape without finding Channel 5 end-of-load mark\n");\r
244 break;\r
245 }\r
246\r
247 if (leader) {\r
248 if ((ch & 0x7F) == 0x7F) /* ignore leading rubouts or "delete" characters */\r
249 continue;\r
250\r
251 leader = FALSE; /* after first nonrubout, any punch in channel 5 terminates load */\r
252 }\r
253\r
254 /* this is untested -- not sure of actual byte ordering */\r
255\r
256 val = (val << 4) | (ch & 0x0F); /* get next nybble */\r
257\r
258 if (++nch == 4) { /* if we now have four nybbles, store the word */\r
259 M[addr & mem_mask] = (uint16) val;\r
260\r
261 addr++; /* prepare for next word */\r
262 nch = 0;\r
263 val = 0;\r
264 }\r
265\r
266 if (ch & 0x10) { /* channel 5 punch terminates load */\r
267 start = TRUE;\r
268 break;\r
269 }\r
270 }\r
271\r
272 if (! start) /* if we didn't get a valid load, report EOF error */\r
273 return SCPE_EOF;\r
274\r
275 if ((rval = reset_all(0)) != SCPE_OK) /* force a reset */\r
276 return rval;\r
277\r
278 IAR = 0; /* start running at address 0 */\r
279 return SCPE_OK;\r
280}\r
281\r
282/* ptp_attach - attach file to simulated paper tape punch */\r
283\r
284static t_stat ptp_attach (UNIT *uptr, char *cptr)\r
285{\r
286 t_stat rval;\r
287\r
288 SETBIT(ptr_dsw, PTR1134_DSW_PUNCH_NOT_READY); /* assume failure */\r
289\r
290 if ((rval = attach_unit(uptr, cptr)) != SCPE_OK) /* use standard attach */\r
291 return rval;\r
292\r
293 fseek(uptr->fileref, 0, SEEK_END); /* if we opened an existing file, append to it */\r
294 uptr->pos = ftell(uptr->fileref);\r
295\r
296 if ((ptr_dsw & PTR1134_DSW_PUNCH_BUSY) == 0)\r
297 CLRBIT(ptr_dsw, PTR1134_DSW_PUNCH_NOT_READY); /* we're in business */\r
298\r
299 return SCPE_OK;\r
300}\r
301\r
302/* ptp_detach - detach file from simulated paper tape punch */\r
303\r
304static t_stat ptp_detach (UNIT *uptr)\r
305{\r
306 SETBIT(ptr_dsw, PTR1134_DSW_PUNCH_NOT_READY);\r
307\r
308 return detach_unit(uptr);\r
309}\r