1 /* pdp11_lp.c: PDP-11 line printer simulator
3 Copyright (c) 1993-2007, 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.
28 19-Jan-07 RMS Added UNIT_TEXT flag
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 29-Sep-02 RMS Added vector change/display support
34 30-May-02 RMS Widened POS to 32b
35 06-Jan-02 RMS Added enable/disable support
36 09-Nov-01 RMS Added VAX support
37 07-Sep-01 RMS Revised interrupt mechanism
38 30-Oct-00 RMS Standardized register naming
41 #if defined (VM_PDP10) /* PDP10 version */
42 #error "LP11 is not supported on the PDP-10!"
44 #elif defined (VM_VAX) /* VAX version */
47 #else /* PDP-11 version */
48 #include "pdp11_defs.h"
51 #define LPTCSR_IMP (CSR_ERR + CSR_DONE + CSR_IE) /* implemented */
52 #define LPTCSR_RW (CSR_IE) /* read/write */
54 extern int32 int_req
[IPL_HLVL
];
56 int32 lpt_csr
= 0; /* control/status */
57 int32 lpt_stopioe
= 0; /* stop on error */
60 t_stat
lpt_rd (int32
*data
, int32 PA
, int32 access
);
61 t_stat
lpt_wr (int32 data
, int32 PA
, int32 access
);
62 t_stat
lpt_svc (UNIT
*uptr
);
63 t_stat
lpt_reset (DEVICE
*dptr
);
64 t_stat
lpt_attach (UNIT
*uptr
, char *ptr
);
65 t_stat
lpt_detach (UNIT
*uptr
);
67 /* LPT data structures
69 lpt_dev LPT device descriptor
70 lpt_unit LPT unit descriptor
71 lpt_reg LPT register list
75 IOBA_LPT
, IOLN_LPT
, &lpt_rd
, &lpt_wr
,
76 1, IVCL (LPT
), VEC_LPT
, { NULL
}
80 UDATA (&lpt_svc
, UNIT_SEQ
+UNIT_ATTABLE
+UNIT_TEXT
, 0), SERIAL_OUT_WAIT
84 { GRDATA (BUF
, lpt_unit
.buf
, DEV_RDX
, 8, 0) },
85 { GRDATA (CSR
, lpt_csr
, DEV_RDX
, 16, 0) },
86 { FLDATA (INT
, IREQ (LPT
), INT_V_LPT
) },
87 { FLDATA (ERR
, lpt_csr
, CSR_V_ERR
) },
88 { FLDATA (DONE
, lpt_csr
, CSR_V_DONE
) },
89 { FLDATA (IE
, lpt_csr
, CSR_V_IE
) },
90 { DRDATA (POS
, lpt_unit
.pos
, T_ADDR_W
), PV_LEFT
},
91 { DRDATA (TIME
, lpt_unit
.wait
, 24), PV_LEFT
},
92 { FLDATA (STOP_IOE
, lpt_stopioe
, 0) },
93 { GRDATA (DEVADDR
, lpt_dib
.ba
, DEV_RDX
, 32, 0), REG_HRO
},
94 { GRDATA (DEVVEC
, lpt_dib
.vec
, DEV_RDX
, 16, 0), REG_HRO
},
99 { MTAB_XTD
|MTAB_VDV
, 004, "ADDRESS", "ADDRESS",
100 &set_addr
, &show_addr
, NULL
},
101 { MTAB_XTD
|MTAB_VDV
, 0, "VECTOR", "VECTOR",
102 &set_vec
, &show_vec
, NULL
},
107 "LPT", &lpt_unit
, lpt_reg
, lpt_mod
,
108 1, 10, 31, 1, DEV_RDX
, 8,
109 NULL
, NULL
, &lpt_reset
,
110 NULL
, &lpt_attach
, &lpt_detach
,
111 &lpt_dib
, DEV_DISABLE
| DEV_UBUS
| DEV_QBUS
114 /* Line printer routines
117 lpt_wr I/O page write
118 lpt_svc process event (printer ready)
119 lpt_reset process reset
120 lpt_attach process attach
121 lpt_detach process detach
124 t_stat
lpt_rd (int32
*data
, int32 PA
, int32 access
)
126 if ((PA
& 02) == 0) *data
= lpt_csr
& LPTCSR_IMP
; /* csr */
127 else *data
= lpt_unit
.buf
; /* buffer */
131 t_stat
lpt_wr (int32 data
, int32 PA
, int32 access
)
133 if ((PA
& 02) == 0) { /* csr */
134 if (PA
& 1) return SCPE_OK
;
135 if ((data
& CSR_IE
) == 0) CLR_INT (LPT
);
136 else if ((lpt_csr
& (CSR_DONE
+ CSR_IE
)) == CSR_DONE
)
138 lpt_csr
= (lpt_csr
& ~LPTCSR_RW
) | (data
& LPTCSR_RW
);
141 if ((PA
& 1) == 0) lpt_unit
.buf
= data
& 0177; /* buffer */
142 lpt_csr
= lpt_csr
& ~CSR_DONE
;
144 if ((lpt_unit
.buf
== 015) || (lpt_unit
.buf
== 014) ||
145 (lpt_unit
.buf
== 012)) sim_activate (&lpt_unit
, lpt_unit
.wait
);
146 else sim_activate (&lpt_unit
, 0);
151 t_stat
lpt_svc (UNIT
*uptr
)
153 lpt_csr
= lpt_csr
| CSR_ERR
| CSR_DONE
;
154 if (lpt_csr
& CSR_IE
) SET_INT (LPT
);
155 if ((uptr
->flags
& UNIT_ATT
) == 0)
156 return IORETURN (lpt_stopioe
, SCPE_UNATT
);
157 fputc (uptr
->buf
& 0177, uptr
->fileref
);
158 uptr
->pos
= ftell (uptr
->fileref
);
159 if (ferror (uptr
->fileref
)) {
160 perror ("LPT I/O error");
161 clearerr (uptr
->fileref
);
164 lpt_csr
= lpt_csr
& ~CSR_ERR
;
168 t_stat
lpt_reset (DEVICE
*dptr
)
172 if ((lpt_unit
.flags
& UNIT_ATT
) == 0) lpt_csr
= lpt_csr
| CSR_ERR
;
174 sim_cancel (&lpt_unit
); /* deactivate unit */
178 t_stat
lpt_attach (UNIT
*uptr
, char *cptr
)
182 lpt_csr
= lpt_csr
& ~CSR_ERR
;
183 reason
= attach_unit (uptr
, cptr
);
184 if ((lpt_unit
.flags
& UNIT_ATT
) == 0) lpt_csr
= lpt_csr
| CSR_ERR
;
188 t_stat
lpt_detach (UNIT
*uptr
)
190 lpt_csr
= lpt_csr
| CSR_ERR
;
191 return detach_unit (uptr
);