First Commit of my working state
[simh.git] / I1620 / i1620_pt.c
CommitLineData
196ba1fc
PH
1/* i1620_pt.c: IBM 1621/1624 paper tape reader/punch simulator\r
2\r
3 Copyright (c) 2002-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 1621 paper tape reader\r
27 ptp 1624 paper tape punch\r
28\r
29 21-Sep-05 RMS Revised translation tables for 7094/1401 compatibility\r
30 25-Apr-03 RMS Revised for extended file support\r
31*/\r
32\r
33#include "i1620_defs.h"\r
34\r
35#define PT_EL 0x80 /* end record */\r
36#define PT_X 0x40 /* X */\r
37#define PT_O 0x20 /* O */\r
38#define PT_C 0x10 /* C */\r
39#define PT_FD 0x7F /* deleted */\r
40\r
41extern uint8 M[MAXMEMSIZE];\r
42extern uint8 ind[NUM_IND];\r
43extern UNIT cpu_unit;\r
44extern uint32 io_stop;\r
45\r
46t_stat ptr_reset (DEVICE *dptr);\r
47t_stat ptr_boot (int32 unitno, DEVICE *dptr);\r
48t_stat ptr_read (uint8 *c, t_bool ignfeed);\r
49t_stat ptp_reset (DEVICE *dptr);\r
50t_stat ptp_write (uint32 c);\r
51t_stat ptp_num (uint32 pa, uint32 len);\r
52\r
53/* PTR data structures\r
54\r
55 ptr_dev PTR device descriptor\r
56 ptr_unit PTR unit descriptor\r
57 ptr_reg PTR register list\r
58*/\r
59\r
60UNIT ptr_unit = {\r
61 UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0)\r
62 };\r
63\r
64REG ptr_reg[] = {\r
65 { DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT },\r
66 { NULL }\r
67 };\r
68\r
69DEVICE ptr_dev = {\r
70 "PTR", &ptr_unit, ptr_reg, NULL,\r
71 1, 10, 31, 1, 8, 8,\r
72 NULL, NULL, &ptr_reset,\r
73 &ptr_boot, NULL, NULL\r
74 };\r
75\r
76/* PTP data structures\r
77\r
78 ptp_dev PTP device descriptor\r
79 ptp_unit PTP unit descriptor\r
80 ptp_reg PTP register list\r
81*/\r
82\r
83UNIT ptp_unit = {\r
84 UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0)\r
85 };\r
86\r
87REG ptp_reg[] = {\r
88 { DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT },\r
89 { NULL }\r
90 };\r
91\r
92DEVICE ptp_dev = {\r
93 "PTP", &ptp_unit, ptp_reg, NULL,\r
94 1, 10, 31, 1, 8, 8,\r
95 NULL, NULL, &ptp_reset,\r
96 NULL, NULL, NULL\r
97 };\r
98\r
99/* Data tables */\r
100\r
101/* Paper tape reader odd parity chart: 1 = bad, 0 = ok */\r
102\r
103const int8 bad_par[128] = {\r
104 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 00 */\r
105 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 10 */\r
106 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 20 */\r
107 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 30 */\r
108 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 40 */\r
109 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 50 */\r
110 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 60 */\r
111 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 /* 70 */\r
112 };\r
113\r
114/* Paper tape read (7b) to numeric (one digit) */\r
115\r
116const int8 ptr_to_num[128] = {\r
117 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* - */\r
118 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x00, 0x0E, 0x0F,\r
119 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* C */\r
120 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x00, 0x0E, 0x0F,\r
121 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* O */\r
122 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x00, 0x0E, 0x0F,\r
123 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* OC */\r
124 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x00, 0x0E, 0x0F,\r
125 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* X */\r
126 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x10, 0x1E, 0x1F,\r
127 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* XC */\r
128 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x10, 0x1E, 0x1F,\r
129 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* XO */\r
130 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x00, 0x0E, 0x0F,\r
131 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* XOC */\r
132 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x00, 0x0E, 0x0F\r
133 };\r
134\r
135/* Paper tape read (7b) to alphameric (two digits)\r
136 Codes XO82, 82, XO842, 842 do not have consistent translations\r
137*/\r
138\r
139const int8 ptr_to_alp[128] = {\r
140 0x00, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* - */\r
141 0x78, 0x79, -1, 0x33, 0x34, 0x70, -1, 0x0F,\r
142 0x00, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* C */\r
143 0x78, 0x79, -1, 0x33, 0x34, 0x70, -1, 0x0F,\r
144 0x70, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* O */\r
145 0x68, 0x69, 0x0A, 0x23, 0x24, 0x60, 0x0E, 0x0F,\r
146 0x70, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* OC */\r
147 0x68, 0x69, 0x0A, 0x23, 0x24, 0x60, 0x0E, 0x0F,\r
148 0x20, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* X */\r
149 0x58, 0x59, 0x5A, 0x13, 0x14, 0x50, 0x5E, 0x5F,\r
150 0x20, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* XC */\r
151 0x58, 0x59, 0x5A, 0x13, 0x14, 0x50, 0x5E, 0x5F,\r
152 0x10, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* XO */\r
153 0x48, 0x49, -1, 0x03, 0x04, 0x40, -1, 0x7F,\r
154 0x10, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* XOC */\r
155 0x48, 0x49, -1, 0x03, 0x04, 0x40, -1, 0x7F\r
156 };\r
157\r
158/* Numeric (flag + digit) to paper tape punch */\r
159\r
160const int8 num_to_ptp[32] = {\r
161 0x20, 0x01, 0x02, 0x13, 0x04, 0x15, 0x16, 0x07, /* 0 */\r
162 0x08, 0x19, 0x2A, 0x3B, 0x1C, 0x0D, 0x3E, 0x3F,\r
163 0x40, 0x51, 0x52, 0x43, 0x54, 0x45, 0x46, 0x57, /* F + 0 */\r
164 0x58, 0x49, 0x4A, 0x5B, 0x4C, 0x5D, 0x5E, 0x4F\r
165 };\r
166\r
167/* Alphameric (two digits) to paper tape punch */\r
168\r
169const int8 alp_to_ptp[256] = {\r
170 0x10, -1, 0x7A, 0x6B, 0x7C, -1, -1, 0x7F, /* 00 */\r
171 -1, -1, 0x2A, -1, -1, -1, -1, 0x1F,\r
172 0x70, -1, 0x4A, 0x5B, 0x4C, -1, -1, -1, /* 10 */\r
173 -1, -1, -1, -1, -1, -1, -1, -1,\r
174 0x40, 0x31, 0x2A, 0x3B, 0x2C, -1, -1, -1, /* 20 */ \r
175 -1, -1, -1, -1, -1, -1, -1, -1,\r
176 -1, -1, 0x1A, 0x0B, 0x1C, 0x0D, 0x0E, -1, /* 30 */\r
177 -1, -1, -1, -1, -1, -1, -1, -1,\r
178 -1, 0x61, 0x62, 0x73, 0x64, 0x75, 0x76, 0x67, /* 40 */\r
179 0x68, 0x79, -1, -1, -1, -1, -1, -1,\r
180 0x40, 0x51, 0x52, 0x43, 0x54, 0x45, 0x46, 0x57, /* 50 */\r
181 0x58, 0x49, 0x4A, -1, -1, -1, -1, 0x4F,\r
182 -1, 0x31, 0x32, 0x23, 0x34, 0x25, 0x26, 0x37, /* 60 */\r
183 0x38, 0x29, -1, -1, -1, -1, -1, -1,\r
184 0x20, 0x01, 0x02, 0x13, 0x04, 0x15, 0x16, 0x07, /* 70 */\r
185 0x08, 0x19, 0x7A, -1, -1, -1, -1, 0x7F,\r
186 -1, -1, -1, -1, -1, -1, -1, -1, /* 80 */\r
187 -1, -1, -1, -1, -1, -1, -1, -1,\r
188 -1, -1, -1, -1, -1, -1, -1, -1, /* 90 */\r
189 -1, -1, -1, -1, -1, -1, -1, -1,\r
190 -1, -1, -1, -1, -1, -1, -1, -1, /* A0 */\r
191 -1, -1, -1, -1, -1, -1, -1, -1,\r
192 -1, -1, -1, -1, -1, -1, -1, -1, /* B0 */\r
193 -1, -1, -1, -1, -1, -1, -1, -1,\r
194 -1, -1, -1, -1, -1, -1, -1, -1, /* C0 */\r
195 -1, -1, -1, -1, -1, -1, -1, -1,\r
196 -1, -1, -1, -1, -1, -1, -1, -1, /* D0 */\r
197 -1, -1, -1, -1, -1, -1, -1, -1,\r
198 -1, -1, -1, -1, -1, -1, -1, -1, /* E0 */\r
199 -1, -1, -1, -1, -1, -1, -1, -1,\r
200 -1, -1, -1, -1, -1, -1, -1, -1, /* F0 */\r
201 -1, -1, -1, -1, -1, -1, -1, -1\r
202 }; \r
203\r
204/* Paper tape reader IO routine\r
205\r
206 - Hard errors halt the operation and the system.\r
207 - Parity errors place an invalid character in memory and set\r
208 RDCHK, but the read continues until end of record. If IO\r
209 stop is set, the system then halts.\r
210*/\r
211\r
212t_stat ptr (uint32 op, uint32 pa, uint32 f0, uint32 f1)\r
213{\r
214uint32 i;\r
215int8 mc;\r
216uint8 ptc;\r
217t_stat r, sta;\r
218\r
219sta = SCPE_OK;\r
220switch (op) { /* case on op */\r
221\r
222 case OP_RN: /* read numeric */\r
223 for (i = 0; i < MEMSIZE; i++) { /* (stop runaway) */\r
224 r = ptr_read (&ptc, TRUE); /* read frame */\r
225 if (r != SCPE_OK) return r; /* error? */\r
226 if (ptc & PT_EL) { /* end record? */\r
227 M[pa] = REC_MARK; /* store rec mark */\r
228 return sta; /* done */\r
229 }\r
230 if (bad_par[ptc]) { /* bad parity? */\r
231 ind[IN_RDCHK] = 1; /* set read check */\r
232 if (io_stop) sta = STOP_INVCHR; /* set return status */\r
233 M[pa] = 0; /* store zero */\r
234 }\r
235 else M[pa] = ptr_to_num[ptc]; /* translate, store */\r
236 PP (pa); /* incr mem addr */\r
237 }\r
238 break;\r
239\r
240 case OP_RA: /* read alphameric */\r
241 for (i = 0; i < MEMSIZE; i = i + 2) { /* (stop runaway) */\r
242 r = ptr_read (&ptc, TRUE); /* read frame */\r
243 if (r != SCPE_OK) return r; /* error? */\r
244 if (ptc & PT_EL) { /* end record? */\r
245 M[pa] = REC_MARK; /* store rec mark */\r
246 M[pa - 1] = 0;\r
247 return sta; /* done */\r
248 }\r
249 mc = ptr_to_alp[ptc]; /* translate */\r
250 if (bad_par[ptc] || (mc < 0)) { /* bad par or char? */\r
251 ind[IN_RDCHK] = 1; /* set read check */\r
252 if (io_stop) sta = STOP_INVCHR; /* set return status */\r
253 mc = 0; /* store blank */\r
254 }\r
255 M[pa] = (M[pa] & FLAG) | (mc & DIGIT); /* store 2 digits */\r
256 M[pa - 1] = (M[pa - 1] & FLAG) | ((mc >> 4) & DIGIT);\r
257 pa = ADDR_A (pa, 2); /* incr mem addr */\r
258 }\r
259 break; \r
260\r
261 default: /* invalid function */\r
262 return STOP_INVFNC;\r
263 }\r
264\r
265return STOP_RWRAP;\r
266}\r
267\r
268/* Binary paper tape reader IO routine - see above for error handling */\r
269\r
270t_stat btr (uint32 op, uint32 pa, uint32 f0, uint32 f1)\r
271{\r
272uint32 i;\r
273uint8 ptc;\r
274t_stat r, sta;\r
275\r
276if ((cpu_unit.flags & IF_BIN) == 0) return STOP_INVIO;\r
277\r
278sta = SCPE_OK;\r
279switch (op) { /* case on op */\r
280\r
281 case OP_RA: /* read alphameric */\r
282 for (i = 0; i < MEMSIZE; i = i + 2) { /* (stop runaway) */\r
283 r = ptr_read (&ptc, FALSE); /* read frame */\r
284 if (r != SCPE_OK) return r; /* error? */\r
285 if (ptc & PT_EL) { /* end record? */\r
286 M[pa] = REC_MARK; /* store rec mark */\r
287 M[pa - 1] = 0;\r
288 return sta; /* done */\r
289 }\r
290 if (bad_par[ptc]) { /* bad parity? */\r
291 ind[IN_RDCHK] = 1; /* set read check */\r
292 if (io_stop) sta = STOP_INVCHR; /* set return status */\r
293 }\r
294 M[pa] = (M[pa] & FLAG) | (ptc & 07); /* store 2 digits */\r
295 M[pa - 1] = (M[pa - 1] & FLAG) |\r
296 (((ptc >> 5) & 06) | ((ptc >> 3) & 1));\r
297 pa = ADDR_A (pa, 2); /* incr mem addr */\r
298 }\r
299 break; \r
300\r
301 default: /* invalid function */\r
302 return STOP_INVFNC;\r
303 }\r
304\r
305return STOP_RWRAP;\r
306}\r
307\r
308/* Read ptr frame - all errors are 'hard' errors and halt the system */\r
309\r
310t_stat ptr_read (uint8 *c, t_bool ignfeed)\r
311{\r
312int32 temp;\r
313\r
314if ((ptr_unit.flags & UNIT_ATT) == 0) { /* attached? */\r
315 ind[IN_RDCHK] = 1; /* no, error */\r
316 return SCPE_UNATT;\r
317 }\r
318\r
319do {\r
320 if ((temp = getc (ptr_unit.fileref)) == EOF) { /* read char */\r
321 ind[IN_RDCHK] = 1; /* err, rd chk */\r
322 if (feof (ptr_unit.fileref))\r
323 printf ("PTR end of file\n");\r
324 else perror ("PTR I/O error");\r
325 clearerr (ptr_unit.fileref);\r
326 return SCPE_IOERR;\r
327 }\r
328 *c = temp & 0377; /* save char */\r
329 ptr_unit.pos = ptr_unit.pos + 1; /* incr file addr */\r
330 } while (ignfeed && (*c == PT_FD)); /* until not feed */\r
331return SCPE_OK;\r
332}\r
333\r
334/* Reset routine */\r
335\r
336t_stat ptr_reset (DEVICE *dptr)\r
337{\r
338return SCPE_OK;\r
339}\r
340\r
341/* Bootstrap routine */\r
342\r
343const static uint8 boot_rom[] = {\r
344 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* NOP */\r
345 3, 6, 0, 0, 0, 3, 1, 0, 0, 3, 0, 0, /* RNPT 31 */\r
346 2, 5, 0, 0, 0, 7, 1, 0, 0, 0, 0, 0, /* TD 71,loc */\r
347 3, 6, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, /* RNPT loc1 */\r
348 2, 6, 0, 0, 0, 6, 6, 0, 0, 0, 3, 5, /* TF 66,35 */\r
349 1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* TDM loc2,loc3 */\r
350 4, 9, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0 /* BR 12 */\r
351 };\r
352\r
353#define BOOT_START 0\r
354#define BOOT_LEN (sizeof (boot_rom) / sizeof (uint8))\r
355\r
356t_stat ptr_boot (int32 unitno, DEVICE *dptr)\r
357{\r
358int32 i;\r
359extern int32 saved_PC;\r
360\r
361for (i = 0; i < BOOT_LEN; i++) M[BOOT_START + i] = boot_rom[i];\r
362saved_PC = BOOT_START;\r
363return SCPE_OK;\r
364}\r
365\r
366/* Paper tape punch IO routine\r
367\r
368 - Hard errors halt the operation and the system.\r
369 - Parity errors stop the operation and set WRCHK.\r
370 If IO stop is set, the system then halts.\r
371*/\r
372\r
373t_stat ptp (uint32 op, uint32 pa, uint32 f0, uint32 f1)\r
374{\r
375uint32 i;\r
376int8 ptc;\r
377uint8 z, d;\r
378t_stat r;\r
379\r
380switch (op) { /* decode op */\r
381\r
382 case OP_DN:\r
383 return ptp_num (pa, 20000 - (pa % 20000)); /* dump numeric */\r
384\r
385 case OP_WN:\r
386 return ptp_num (pa, 0); /* punch numeric */\r
387\r
388 case OP_WA:\r
389 for (i = 0; i < MEMSIZE; i = i + 2) { /* stop runaway */\r
390 d = M[pa] & DIGIT; /* get digit */\r
391 z = M[pa - 1] & DIGIT; /* get zone */\r
392 if ((d & REC_MARK) == REC_MARK) /* 8-2 char? */\r
393 return ptp_write (PT_EL); /* end record */\r
394 ptc = alp_to_ptp[(z << 4) | d]; /* translate pair */\r
395 if (ptc < 0) { /* bad char? */\r
396 ind[IN_WRCHK] = 1; /* write check */\r
397 CRETIOE (io_stop, STOP_INVCHR);\r
398 }\r
399 r = ptp_write (ptc); /* write char */\r
400 if (r != SCPE_OK) return r; /* error? */\r
401 pa = ADDR_A (pa, 2); /* incr mem addr */\r
402 }\r
403 break; \r
404\r
405 default: /* invalid function */\r
406 return STOP_INVFNC;\r
407 }\r
408\r
409return STOP_RWRAP;\r
410}\r
411\r
412/* Binary paper tape punch IO routine - see above for error handling */\r
413\r
414t_stat btp (uint32 op, uint32 pa, uint32 f0, uint32 f1)\r
415{\r
416uint32 i;\r
417uint8 ptc, z, d;\r
418t_stat r;\r
419\r
420if ((cpu_unit.flags & IF_BIN) == 0) return STOP_INVIO;\r
421\r
422switch (op) { /* decode op */\r
423\r
424 case OP_WA:\r
425 for (i = 0; i < MEMSIZE; i = i + 2) { /* stop runaway */\r
426 d = M[pa] & DIGIT; /* get digit */\r
427 z = M[pa - 1] & DIGIT; /* get zone */\r
428 if ((d & REC_MARK) == REC_MARK) /* 8-2 char? */\r
429 return ptp_write (PT_EL); /* end record */\r
430 ptc = ((z & 06) << 5) | ((z & 01) << 3) | (d & 07);\r
431 if (bad_par[ptc]) ptc = ptc | PT_C; /* set parity */\r
432 r = ptp_write (ptc); /* write char */\r
433 if (r != SCPE_OK) return r; /* error? */\r
434 pa = ADDR_A (pa, 2); /* incr mem addr */\r
435 }\r
436 break; \r
437\r
438 default: /* invalid function */\r
439 return STOP_INVFNC;\r
440 }\r
441\r
442return STOP_RWRAP;\r
443}\r
444\r
445/* Punch tape numeric - cannot generate parity errors */\r
446\r
447t_stat ptp_num (uint32 pa, uint32 len)\r
448{\r
449t_stat r;\r
450uint8 d;\r
451uint32 i, end;\r
452\r
453end = pa + len;\r
454for (i = 0; i < MEMSIZE; i++) { /* stop runaway */\r
455 d = M[pa] & (FLAG | DIGIT); /* get char */\r
456 if (len? (pa >= end): /* dump: end reached? */\r
457 ((d & REC_MARK) == REC_MARK)) /* write: rec mark? */\r
458 return ptp_write (PT_EL); /* end record */\r
459 r = ptp_write (num_to_ptp[d]); /* write */\r
460 if (r != SCPE_OK) return r; /* error? */\r
461 PP (pa); /* incr mem addr */\r
462 }\r
463return STOP_RWRAP;\r
464}\r
465\r
466/* Write ptp frame - all errors are hard errors */\r
467\r
468t_stat ptp_write (uint32 c)\r
469{\r
470if ((ptp_unit.flags & UNIT_ATT) == 0) { /* attached? */\r
471 ind[IN_WRCHK] = 1; /* no, error */\r
472 return SCPE_UNATT;\r
473 }\r
474if (putc (c, ptp_unit.fileref) == EOF) { /* write char */\r
475 ind[IN_WRCHK] = 1; /* error? */\r
476 perror ("PTP I/O error");\r
477 clearerr (ptp_unit.fileref);\r
478 return SCPE_IOERR;\r
479 }\r
480ptp_unit.pos = ptp_unit.pos + 1; /* count char */\r
481return SCPE_OK;\r
482}\r
483\r
484/* Reset routine */\r
485\r
486t_stat ptp_reset (DEVICE *dptr)\r
487{\r
488return SCPE_OK;\r
489}\r