mirror of
https://github.com/simh/simh.git
synced 2026-04-30 21:38:32 +00:00
Notes For V3.5-0
The source set has been extensively overhauled. For correct viewing, set Visual C++ or Emacs to have tab stops every 4 characters. 1. New Features in 3.4-1 1.1 All Ethernet devices - Added Windows user-defined adapter names (from Timothe Litt) 1.2 Interdata, SDS, HP, PDP-8, PDP-18b terminal multiplexors - Added support for SET <unit>n DISCONNECT 1.3 VAX - Added latent QDSS support - Revised autoconfigure to handle QDSS 1.4 PDP-11 - Revised autoconfigure to handle more casees 2. Bugs Fixed in 3.4-1 2.1 SCP and libraries - Trim trailing spaces on all input (for example, attach file names) - Fixed sim_sock spurious SIGPIPE error in Unix/Linux - Fixed sim_tape misallocation of TPC map array for 64b simulators 2.2 1401 - Fixed bug, CPU reset was clearing SSB through SSG 2.3 PDP-11 - Fixed bug in VH vector display routine - Fixed XU runt packet processing (found by Tim Chapman) 2.4 Interdata - Fixed bug in SHOW PAS CONN/STATS - Fixed potential integer overflow exception in divide 2.5 SDS - Fixed bug in SHOW MUX CONN/STATS 2.6 HP - Fixed bug in SHOW MUX CONN/STATS 2.7 PDP-8 - Fixed bug in SHOW TTIX CONN/STATS - Fixed bug in SET/SHOW TTOXn LOG 2.8 PDP-18b - Fixed bug in SHOW TTIX CONN/STATS - Fixed bug in SET/SHOW TTOXn LOG 2.9 Nova, Eclipse - Fixed potential integer overflow exception in divide
This commit is contained in:
committed by
Mark Pizzolato
parent
ec60bbf329
commit
b7c1eae41f
@@ -19,145 +19,144 @@
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Robert M Supnik shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
Except as contained in this notice, the name of Robert M Supnik shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
lp20 line printer
|
||||
lp20 line printer
|
||||
|
||||
18-Mar-05 RMS Added attached test to detach routine
|
||||
29-Dec-03 RMS Fixed bug in scheduling
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
29-Sep-02 RMS Added variable vector support
|
||||
Modified to use common Unibus routines
|
||||
New data structures
|
||||
30-May-02 RMS Widened POS to 32b
|
||||
06-Jan-02 RMS Added enable/disable support
|
||||
30-Nov-01 RMS Added extended SET/SHOW support
|
||||
04-Sep-05 RMS Fixed missing return (found by Peter Schorn)
|
||||
07-Jul-05 RMS Removed extraneous externs
|
||||
18-Mar-05 RMS Added attached test to detach routine
|
||||
29-Dec-03 RMS Fixed bug in scheduling
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
29-Sep-02 RMS Added variable vector support
|
||||
Modified to use common Unibus routines
|
||||
New data structures
|
||||
30-May-02 RMS Widened POS to 32b
|
||||
06-Jan-02 RMS Added enable/disable support
|
||||
30-Nov-01 RMS Added extended SET/SHOW support
|
||||
*/
|
||||
|
||||
#include "pdp10_defs.h"
|
||||
|
||||
#define UNIT_DUMMY (1 << UNIT_V_UF)
|
||||
#define LP_WIDTH 132 /* printer width */
|
||||
#define UNIT_DUMMY (1 << UNIT_V_UF)
|
||||
#define LP_WIDTH 132 /* printer width */
|
||||
|
||||
/* DAVFU RAM */
|
||||
|
||||
#define DV_SIZE 143 /* DAVFU size */
|
||||
#define DV_DMASK 077 /* data mask per byte */
|
||||
#define DV_TOF 0 /* top of form channel */
|
||||
#define DV_MAX 11 /* max channel number */
|
||||
#define DV_SIZE 143 /* DAVFU size */
|
||||
#define DV_DMASK 077 /* data mask per byte */
|
||||
#define DV_TOF 0 /* top of form channel */
|
||||
#define DV_MAX 11 /* max channel number */
|
||||
|
||||
/* Translation RAM */
|
||||
|
||||
#define TX_SIZE 256 /* translation RAM */
|
||||
#define TX_AMASK (TX_SIZE - 1)
|
||||
#define TX_DMASK 07777
|
||||
#define TX_V_FL 8 /* flags */
|
||||
#define TX_M_FL 017
|
||||
/* define TX_INTR 04000 /* interrupt */
|
||||
#define TX_DELH 02000 /* delimiter */
|
||||
/* define TX_XLAT 01000 /* translate */
|
||||
/* define TX_DVFU 00400 /* DAVFU */
|
||||
#define TX_SLEW 00020 /* chan vs slew */
|
||||
#define TX_VMASK 00017 /* spacing mask */
|
||||
#define TX_CHR 0 /* states: pr char */
|
||||
#define TX_RAM 1 /* pr translation */
|
||||
#define TX_DVU 2 /* DAVFU action */
|
||||
#define TX_INT 3 /* interrupt */
|
||||
#define TX_GETFL(x) (((x) >> TX_V_FL) & TX_M_FL)
|
||||
#define TX_SIZE 256 /* translation RAM */
|
||||
#define TX_AMASK (TX_SIZE - 1)
|
||||
#define TX_DMASK 07777
|
||||
#define TX_V_FL 8 /* flags */
|
||||
#define TX_M_FL 017
|
||||
/* define TX_INTR 04000 /* interrupt */
|
||||
#define TX_DELH 02000 /* delimiter */
|
||||
/* define TX_XLAT 01000 /* translate */
|
||||
/* define TX_DVFU 00400 /* DAVFU */
|
||||
#define TX_SLEW 00020 /* chan vs slew */
|
||||
#define TX_VMASK 00017 /* spacing mask */
|
||||
#define TX_CHR 0 /* states: pr char */
|
||||
#define TX_RAM 1 /* pr translation */
|
||||
#define TX_DVU 2 /* DAVFU action */
|
||||
#define TX_INT 3 /* interrupt */
|
||||
#define TX_GETFL(x) (((x) >> TX_V_FL) & TX_M_FL)
|
||||
|
||||
/* LPCSRA (765400) */
|
||||
|
||||
#define CSA_GO 0000001 /* go */
|
||||
#define CSA_PAR 0000002 /* parity enable NI */
|
||||
#define CSA_V_FNC 2 /* function */
|
||||
#define CSA_M_FNC 03
|
||||
#define FNC_PR 0 /* print */
|
||||
#define FNC_TST 1 /* test */
|
||||
#define FNC_DVU 2 /* load DAVFU */
|
||||
#define FNC_RAM 3 /* load translation RAM */
|
||||
#define FNC_INTERNAL 1 /* internal function */
|
||||
#define CSA_FNC (CSA_M_FNC << CSA_V_FNC)
|
||||
#define CSA_V_UAE 4 /* Unibus addr extension */
|
||||
#define CSA_UAE (03 << CSA_V_UAE)
|
||||
#define CSA_IE 0000100 /* interrupt enable */
|
||||
#define CSA_DONE 0000200 /* done */
|
||||
#define CSA_INIT 0000400 /* init */
|
||||
#define CSA_ECLR 0001000 /* clear errors */
|
||||
#define CSA_DELH 0002000 /* delimiter hold */
|
||||
#define CSA_ONL 0004000 /* online */
|
||||
#define CSA_DVON 0010000 /* DAVFU online */
|
||||
#define CSA_UNDF 0020000 /* undefined char */
|
||||
#define CSA_PZRO 0040000 /* page counter zero */
|
||||
#define CSA_ERR 0100000 /* error */
|
||||
#define CSA_RW (CSA_DELH | CSA_IE | CSA_UAE | CSA_FNC | CSA_PAR | CSA_GO)
|
||||
#define CSA_MBZ (CSA_ECLR | CSA_INIT)
|
||||
#define CSA_GETUAE(x) (((x) & CSA_UAE) << (16 - CSA_V_UAE))
|
||||
#define CSA_GETFNC(x) (((x) >> CSA_V_FNC) & CSA_M_FNC)
|
||||
#define CSA_GO 0000001 /* go */
|
||||
#define CSA_PAR 0000002 /* parity enable NI */
|
||||
#define CSA_V_FNC 2 /* function */
|
||||
#define CSA_M_FNC 03
|
||||
#define FNC_PR 0 /* print */
|
||||
#define FNC_TST 1 /* test */
|
||||
#define FNC_DVU 2 /* load DAVFU */
|
||||
#define FNC_RAM 3 /* load translation RAM */
|
||||
#define FNC_INTERNAL 1 /* internal function */
|
||||
#define CSA_FNC (CSA_M_FNC << CSA_V_FNC)
|
||||
#define CSA_V_UAE 4 /* Unibus addr extension */
|
||||
#define CSA_UAE (03 << CSA_V_UAE)
|
||||
#define CSA_IE 0000100 /* interrupt enable */
|
||||
#define CSA_DONE 0000200 /* done */
|
||||
#define CSA_INIT 0000400 /* init */
|
||||
#define CSA_ECLR 0001000 /* clear errors */
|
||||
#define CSA_DELH 0002000 /* delimiter hold */
|
||||
#define CSA_ONL 0004000 /* online */
|
||||
#define CSA_DVON 0010000 /* DAVFU online */
|
||||
#define CSA_UNDF 0020000 /* undefined char */
|
||||
#define CSA_PZRO 0040000 /* page counter zero */
|
||||
#define CSA_ERR 0100000 /* error */
|
||||
#define CSA_RW (CSA_DELH | CSA_IE | CSA_UAE | CSA_FNC | CSA_PAR | CSA_GO)
|
||||
#define CSA_MBZ (CSA_ECLR | CSA_INIT)
|
||||
#define CSA_GETUAE(x) (((x) & CSA_UAE) << (16 - CSA_V_UAE))
|
||||
#define CSA_GETFNC(x) (((x) >> CSA_V_FNC) & CSA_M_FNC)
|
||||
|
||||
/* LPCSRB (765402) */
|
||||
|
||||
#define CSB_GOE 0000001 /* go error */
|
||||
#define CSB_DTE 0000002 /* DEM timing error NI */
|
||||
#define CSB_MTE 0000004 /* MSYN error (Ubus timeout) */
|
||||
#define CSB_RPE 0000010 /* RAM parity error NI */
|
||||
#define CSB_MPE 0000020 /* MEM parity error NI */
|
||||
#define CSB_LPE 0000040 /* LPT parity error NI */
|
||||
#define CSB_DVOF 0000100 /* DAVFU not ready */
|
||||
#define CSB_OFFL 0000200 /* offline */
|
||||
#define CSB_TEST 0003400 /* test mode */
|
||||
#define CSB_OVFU 0004000 /* optical VFU NI */
|
||||
#define CSB_PBIT 0010000 /* data parity bit NI */
|
||||
#define CSB_NRDY 0020000 /* printer error NI */
|
||||
#define CSB_LA180 0040000 /* LA180 printer NI */
|
||||
#define CSB_VLD 0100000 /* valid data NI */
|
||||
#define CSB_ECLR (CSB_GOE | CSB_DTE | CSB_MTE | CSB_RPE | CSB_MPE | CSB_LPE)
|
||||
#define CSB_ERR (CSB_ECLR | CSB_DVOF | CSB_OFFL)
|
||||
#define CSB_RW CSB_TEST
|
||||
#define CSB_MBZ (CSB_DTE | CSB_RPE | CSB_MPE | CSB_LPE | CSB_OVFU |\
|
||||
CSB_PBIT | CSB_NRDY | CSB_LA180 | CSB_VLD)
|
||||
#define CSB_GOE 0000001 /* go error */
|
||||
#define CSB_DTE 0000002 /* DEM timing error NI */
|
||||
#define CSB_MTE 0000004 /* MSYN error (Ubus timeout) */
|
||||
#define CSB_RPE 0000010 /* RAM parity error NI */
|
||||
#define CSB_MPE 0000020 /* MEM parity error NI */
|
||||
#define CSB_LPE 0000040 /* LPT parity error NI */
|
||||
#define CSB_DVOF 0000100 /* DAVFU not ready */
|
||||
#define CSB_OFFL 0000200 /* offline */
|
||||
#define CSB_TEST 0003400 /* test mode */
|
||||
#define CSB_OVFU 0004000 /* optical VFU NI */
|
||||
#define CSB_PBIT 0010000 /* data parity bit NI */
|
||||
#define CSB_NRDY 0020000 /* printer error NI */
|
||||
#define CSB_LA180 0040000 /* LA180 printer NI */
|
||||
#define CSB_VLD 0100000 /* valid data NI */
|
||||
#define CSB_ECLR (CSB_GOE | CSB_DTE | CSB_MTE | CSB_RPE | CSB_MPE | CSB_LPE)
|
||||
#define CSB_ERR (CSB_ECLR | CSB_DVOF | CSB_OFFL)
|
||||
#define CSB_RW CSB_TEST
|
||||
#define CSB_MBZ (CSB_DTE | CSB_RPE | CSB_MPE | CSB_LPE | CSB_OVFU |\
|
||||
CSB_PBIT | CSB_NRDY | CSB_LA180 | CSB_VLD)
|
||||
|
||||
/* LPBA (765404) */
|
||||
|
||||
/* LPBC (765506) */
|
||||
|
||||
#define BC_MASK 0007777 /* <15:12> MBZ */
|
||||
#define BC_MASK 0007777 /* <15:12> MBZ */
|
||||
|
||||
/* LPPAGC (765510) */
|
||||
|
||||
#define PAGC_MASK 0007777 /* <15:12> MBZ */
|
||||
#define PAGC_MASK 0007777 /* <15:12> MBZ */
|
||||
|
||||
/* LPRDAT (765512) */
|
||||
|
||||
#define RDAT_MASK 0007777 /* <15:12> MBZ */
|
||||
#define RDAT_MASK 0007777 /* <15:12> MBZ */
|
||||
|
||||
/* LPCOLC/LPCBUF (765514) */
|
||||
|
||||
/* LPCSUM/LPPDAT (765516) */
|
||||
|
||||
extern d10 *M; /* main memory */
|
||||
extern int32 int_req;
|
||||
extern int32 int_vec[32];
|
||||
extern int32 ubcs[UBANUM]; /* UBA csr */
|
||||
extern int32 ubmap[UBANUM][UMAP_MEMSIZE]; /* UBA map */
|
||||
|
||||
int32 lpcsa = 0; /* control/status A */
|
||||
int32 lpcsb = 0; /* control/status B */
|
||||
int32 lpba = 0; /* bus address */
|
||||
int32 lpbc = 0; /* byte count */
|
||||
int32 lppagc = 0; /* page count */
|
||||
int32 lprdat = 0; /* RAM data */
|
||||
int32 lpcbuf = 0; /* character buffer */
|
||||
int32 lpcolc = 0; /* column count */
|
||||
int32 lppdat = 0; /* printer data */
|
||||
int32 lpcsum = 0; /* checksum */
|
||||
int32 dvptr = 0; /* davfu pointer */
|
||||
int32 dvlnt = 0; /* davfu length */
|
||||
int32 lp20_irq = 0; /* int request */
|
||||
int32 lp20_stopioe = 0; /* stop on error */
|
||||
int16 txram[TX_SIZE] = { 0 }; /* translation RAM */
|
||||
int16 davfu[DV_SIZE] = { 0 }; /* DAVFU */
|
||||
extern d10 *M; /* main memory */
|
||||
extern int32 int_req;
|
||||
|
||||
int32 lpcsa = 0; /* control/status A */
|
||||
int32 lpcsb = 0; /* control/status B */
|
||||
int32 lpba = 0; /* bus address */
|
||||
int32 lpbc = 0; /* byte count */
|
||||
int32 lppagc = 0; /* page count */
|
||||
int32 lprdat = 0; /* RAM data */
|
||||
int32 lpcbuf = 0; /* character buffer */
|
||||
int32 lpcolc = 0; /* column count */
|
||||
int32 lppdat = 0; /* printer data */
|
||||
int32 lpcsum = 0; /* checksum */
|
||||
int32 dvptr = 0; /* davfu pointer */
|
||||
int32 dvlnt = 0; /* davfu length */
|
||||
int32 lp20_irq = 0; /* int request */
|
||||
int32 lp20_stopioe = 0; /* stop on error */
|
||||
int16 txram[TX_SIZE] = { 0 }; /* translation RAM */
|
||||
int16 davfu[DV_SIZE] = { 0 }; /* DAVFU */
|
||||
|
||||
DEVICE lp20_dev;
|
||||
t_stat lp20_rd (int32 *data, int32 pa, int32 access);
|
||||
@@ -175,285 +174,332 @@ void update_lpcs (int32 flg);
|
||||
|
||||
/* LP data structures
|
||||
|
||||
lp20_dev LPT device descriptor
|
||||
lp20_unit LPT unit descriptor
|
||||
lp20_reg LPT register list
|
||||
lp20_dev LPT device descriptor
|
||||
lp20_unit LPT unit descriptor
|
||||
lp20_reg LPT register list
|
||||
*/
|
||||
|
||||
DIB lp20_dib = { IOBA_LP20, IOLN_LP20, &lp20_rd, &lp20_wr,
|
||||
1, IVCL (LP20), VEC_LP20, { &lp20_inta } };
|
||||
DIB lp20_dib = {
|
||||
IOBA_LP20, IOLN_LP20, &lp20_rd, &lp20_wr,
|
||||
1, IVCL (LP20), VEC_LP20, { &lp20_inta }
|
||||
};
|
||||
|
||||
UNIT lp20_unit = {
|
||||
UDATA (&lp20_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT };
|
||||
UDATA (&lp20_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT
|
||||
};
|
||||
|
||||
REG lp20_reg[] = {
|
||||
{ ORDATA (LPCSA, lpcsa, 16) },
|
||||
{ ORDATA (LPCSB, lpcsb, 16) },
|
||||
{ ORDATA (LPBA, lpba, 16) },
|
||||
{ ORDATA (LPBC, lpbc, 12) },
|
||||
{ ORDATA (LPPAGC, lppagc, 12) },
|
||||
{ ORDATA (LPRDAT, lprdat, 12) },
|
||||
{ ORDATA (LPCBUF, lpcbuf, 8) },
|
||||
{ ORDATA (LPCOLC, lpcolc, 8) },
|
||||
{ ORDATA (LPPDAT, lppdat, 8) },
|
||||
{ ORDATA (LPCSUM, lpcsum, 8) },
|
||||
{ ORDATA (DVPTR, dvptr, 7) },
|
||||
{ ORDATA (DVLNT, dvlnt, 7), REG_RO + REG_NZ },
|
||||
{ FLDATA (INT, int_req, INT_V_LP20) },
|
||||
{ FLDATA (IRQ, lp20_irq, 0) },
|
||||
{ FLDATA (ERR, lpcsa, CSR_V_ERR) },
|
||||
{ FLDATA (DONE, lpcsa, CSR_V_DONE) },
|
||||
{ FLDATA (IE, lpcsa, CSR_V_IE) },
|
||||
{ DRDATA (POS, lp20_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TIME, lp20_unit.wait, 24), PV_LEFT },
|
||||
{ FLDATA (STOP_IOE, lp20_stopioe, 0) },
|
||||
{ BRDATA (TXRAM, txram, 8, 12, TX_SIZE) },
|
||||
{ BRDATA (DAVFU, davfu, 8, 12, DV_SIZE) },
|
||||
{ ORDATA (DEVADDR, lp20_dib.ba, 32), REG_HRO },
|
||||
{ ORDATA (DEVVEC, lp20_dib.vec, 16), REG_HRO },
|
||||
{ NULL } };
|
||||
{ ORDATA (LPCSA, lpcsa, 16) },
|
||||
{ ORDATA (LPCSB, lpcsb, 16) },
|
||||
{ ORDATA (LPBA, lpba, 16) },
|
||||
{ ORDATA (LPBC, lpbc, 12) },
|
||||
{ ORDATA (LPPAGC, lppagc, 12) },
|
||||
{ ORDATA (LPRDAT, lprdat, 12) },
|
||||
{ ORDATA (LPCBUF, lpcbuf, 8) },
|
||||
{ ORDATA (LPCOLC, lpcolc, 8) },
|
||||
{ ORDATA (LPPDAT, lppdat, 8) },
|
||||
{ ORDATA (LPCSUM, lpcsum, 8) },
|
||||
{ ORDATA (DVPTR, dvptr, 7) },
|
||||
{ ORDATA (DVLNT, dvlnt, 7), REG_RO + REG_NZ },
|
||||
{ FLDATA (INT, int_req, INT_V_LP20) },
|
||||
{ FLDATA (IRQ, lp20_irq, 0) },
|
||||
{ FLDATA (ERR, lpcsa, CSR_V_ERR) },
|
||||
{ FLDATA (DONE, lpcsa, CSR_V_DONE) },
|
||||
{ FLDATA (IE, lpcsa, CSR_V_IE) },
|
||||
{ DRDATA (POS, lp20_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TIME, lp20_unit.wait, 24), PV_LEFT },
|
||||
{ FLDATA (STOP_IOE, lp20_stopioe, 0) },
|
||||
{ BRDATA (TXRAM, txram, 8, 12, TX_SIZE) },
|
||||
{ BRDATA (DAVFU, davfu, 8, 12, DV_SIZE) },
|
||||
{ ORDATA (DEVADDR, lp20_dib.ba, 32), REG_HRO },
|
||||
{ ORDATA (DEVVEC, lp20_dib.vec, 16), REG_HRO },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
MTAB lp20_mod[] = {
|
||||
{ UNIT_DUMMY, 0, NULL, "VFUCLEAR", &lp20_clear_vfu },
|
||||
{ MTAB_XTD|MTAB_VDV, 004, "ADDRESS", "ADDRESS",
|
||||
&set_addr, &show_addr, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR",
|
||||
&set_vec, &show_vec, NULL },
|
||||
{ 0 } };
|
||||
{ UNIT_DUMMY, 0, NULL, "VFUCLEAR", &lp20_clear_vfu },
|
||||
{ MTAB_XTD|MTAB_VDV, 004, "ADDRESS", "ADDRESS",
|
||||
&set_addr, &show_addr, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR",
|
||||
&set_vec, &show_vec, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEVICE lp20_dev = {
|
||||
"LP20", &lp20_unit, lp20_reg, lp20_mod,
|
||||
1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &lp20_reset,
|
||||
NULL, &lp20_attach, &lp20_detach,
|
||||
&lp20_dib, DEV_DISABLE | DEV_UBUS };
|
||||
|
||||
"LP20", &lp20_unit, lp20_reg, lp20_mod,
|
||||
1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &lp20_reset,
|
||||
NULL, &lp20_attach, &lp20_detach,
|
||||
&lp20_dib, DEV_DISABLE | DEV_UBUS
|
||||
};
|
||||
|
||||
/* Line printer routines
|
||||
|
||||
lp20_rd I/O page read
|
||||
lp20_wr I/O page write
|
||||
lp20_svc process event (printer ready)
|
||||
lp20_reset process reset
|
||||
lp20_attach process attach
|
||||
lp20_detach process detach
|
||||
lp20_rd I/O page read
|
||||
lp20_wr I/O page write
|
||||
lp20_svc process event (printer ready)
|
||||
lp20_reset process reset
|
||||
lp20_attach process attach
|
||||
lp20_detach process detach
|
||||
*/
|
||||
|
||||
t_stat lp20_rd (int32 *data, int32 pa, int32 access)
|
||||
{
|
||||
update_lpcs (0); /* update csr's */
|
||||
switch ((pa >> 1) & 07) { /* case on PA<3:1> */
|
||||
case 00: /* LPCSA */
|
||||
*data = lpcsa = lpcsa & ~CSA_MBZ;
|
||||
break;
|
||||
case 01: /* LPCSB */
|
||||
*data = lpcsb = lpcsb & ~CSB_MBZ;
|
||||
break;
|
||||
case 02: /* LPBA */
|
||||
*data = lpba;
|
||||
break;
|
||||
case 03: /* LPBC */
|
||||
*data = lpbc = lpbc & BC_MASK;
|
||||
break;
|
||||
case 04: /* LPPAGC */
|
||||
*data = lppagc = lppagc & PAGC_MASK;
|
||||
break;
|
||||
case 05: /* LPRDAT */
|
||||
*data = lprdat = lprdat & RDAT_MASK;
|
||||
break;
|
||||
case 06: /* LPCOLC/LPCBUF */
|
||||
*data = (lpcolc << 8) | lpcbuf;
|
||||
break;
|
||||
case 07: /* LPCSUM/LPPDAT */
|
||||
*data = (lpcsum << 8) | lppdat;
|
||||
break; } /* end case PA */
|
||||
update_lpcs (0); /* update csr's */
|
||||
switch ((pa >> 1) & 07) { /* case on PA<3:1> */
|
||||
|
||||
case 00: /* LPCSA */
|
||||
*data = lpcsa = lpcsa & ~CSA_MBZ;
|
||||
break;
|
||||
|
||||
case 01: /* LPCSB */
|
||||
*data = lpcsb = lpcsb & ~CSB_MBZ;
|
||||
break;
|
||||
|
||||
case 02: /* LPBA */
|
||||
*data = lpba;
|
||||
break;
|
||||
|
||||
case 03: /* LPBC */
|
||||
*data = lpbc = lpbc & BC_MASK;
|
||||
break;
|
||||
|
||||
case 04: /* LPPAGC */
|
||||
*data = lppagc = lppagc & PAGC_MASK;
|
||||
break;
|
||||
|
||||
case 05: /* LPRDAT */
|
||||
*data = lprdat = lprdat & RDAT_MASK;
|
||||
break;
|
||||
|
||||
case 06: /* LPCOLC/LPCBUF */
|
||||
*data = (lpcolc << 8) | lpcbuf;
|
||||
break;
|
||||
|
||||
case 07: /* LPCSUM/LPPDAT */
|
||||
*data = (lpcsum << 8) | lppdat;
|
||||
break;
|
||||
} /* end case PA */
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat lp20_wr (int32 data, int32 pa, int32 access)
|
||||
{
|
||||
update_lpcs (0); /* update csr's */
|
||||
switch ((pa >> 1) & 07) { /* case on PA<3:1> */
|
||||
case 00: /* LPCSA */
|
||||
if (access == WRITEB) data = (pa & 1)?
|
||||
(lpcsa & 0377) | (data << 8): (lpcsa & ~0377) | data;
|
||||
if (data & CSA_ECLR) { /* error clear? */
|
||||
lpcsa = (lpcsa | CSA_DONE) & ~CSA_GO; /* set done, clr go */
|
||||
lpcsb = lpcsb & ~CSB_ECLR; /* clear err */
|
||||
sim_cancel (&lp20_unit); } /* cancel I/O */
|
||||
if (data & CSA_INIT) lp20_reset (&lp20_dev); /* init? */
|
||||
if (data & CSA_GO) { /* go set? */
|
||||
if ((lpcsa & CSA_GO) == 0) { /* not set before? */
|
||||
if (lpcsb & CSB_ERR) lpcsb = lpcsb | CSB_GOE;
|
||||
lpcsum = 0; /* clear checksum */
|
||||
sim_activate (&lp20_unit, lp20_unit.wait); } }
|
||||
else sim_cancel (&lp20_unit); /* go clr, stop DMA */
|
||||
lpcsa = (lpcsa & ~CSA_RW) | (data & CSA_RW);
|
||||
break;
|
||||
case 01: /* LPCSB */
|
||||
break; /* ignore writes to TEST */
|
||||
case 02: /* LPBA */
|
||||
if (access == WRITEB) data = (pa & 1)?
|
||||
(lpba & 0377) | (data << 8): (lpba & ~0377) | data;
|
||||
lpba = data;
|
||||
break;
|
||||
case 03: /* LPBC */
|
||||
if (access == WRITEB) data = (pa & 1)?
|
||||
(lpbc & 0377) | (data << 8): (lpbc & ~0377) | data;
|
||||
lpbc = data & BC_MASK;
|
||||
lpcsa = lpcsa & ~CSA_DONE;
|
||||
break;
|
||||
case 04: /* LPPAGC */
|
||||
if (access == WRITEB) data = (pa & 1)?
|
||||
(lppagc & 0377) | (data << 8): (lppagc & ~0377) | data;
|
||||
lppagc = data & PAGC_MASK;
|
||||
break;
|
||||
case 05: /* LPRDAT */
|
||||
if (access == WRITEB) data = (pa & 1)?
|
||||
(lprdat & 0377) | (data << 8): (lprdat & ~0377) | data;
|
||||
lprdat = data & RDAT_MASK;
|
||||
txram[lpcbuf & TX_AMASK] = lprdat; /* load RAM */
|
||||
break;
|
||||
case 06: /* LPCOLC/LPCBUF */
|
||||
if ((access == WRITEB) && (pa & 1)) /* odd byte */
|
||||
lpcolc = data & 0377;
|
||||
else {
|
||||
lpcbuf = data & 0377; /* even byte, word */
|
||||
if (access == WRITE) lpcolc = (data >> 8) & 0377; }
|
||||
break;
|
||||
case 07: /* LPCSUM/LPPDAT */
|
||||
break; } /* read only */
|
||||
update_lpcs (0); /* update csr's */
|
||||
switch ((pa >> 1) & 07) { /* case on PA<3:1> */
|
||||
|
||||
case 00: /* LPCSA */
|
||||
if (access == WRITEB) data = (pa & 1)?
|
||||
(lpcsa & 0377) | (data << 8): (lpcsa & ~0377) | data;
|
||||
if (data & CSA_ECLR) { /* error clear? */
|
||||
lpcsa = (lpcsa | CSA_DONE) & ~CSA_GO; /* set done, clr go */
|
||||
lpcsb = lpcsb & ~CSB_ECLR; /* clear err */
|
||||
sim_cancel (&lp20_unit); /* cancel I/O */
|
||||
}
|
||||
if (data & CSA_INIT) lp20_reset (&lp20_dev); /* init? */
|
||||
if (data & CSA_GO) { /* go set? */
|
||||
if ((lpcsa & CSA_GO) == 0) { /* not set before? */
|
||||
if (lpcsb & CSB_ERR) lpcsb = lpcsb | CSB_GOE;
|
||||
lpcsum = 0; /* clear checksum */
|
||||
sim_activate (&lp20_unit, lp20_unit.wait);
|
||||
}
|
||||
}
|
||||
else sim_cancel (&lp20_unit); /* go clr, stop DMA */
|
||||
lpcsa = (lpcsa & ~CSA_RW) | (data & CSA_RW);
|
||||
break;
|
||||
|
||||
case 01: /* LPCSB */
|
||||
break; /* ignore writes to TEST */
|
||||
|
||||
case 02: /* LPBA */
|
||||
if (access == WRITEB) data = (pa & 1)?
|
||||
(lpba & 0377) | (data << 8): (lpba & ~0377) | data;
|
||||
lpba = data;
|
||||
break;
|
||||
|
||||
case 03: /* LPBC */
|
||||
if (access == WRITEB) data = (pa & 1)?
|
||||
(lpbc & 0377) | (data << 8): (lpbc & ~0377) | data;
|
||||
lpbc = data & BC_MASK;
|
||||
lpcsa = lpcsa & ~CSA_DONE;
|
||||
break;
|
||||
|
||||
case 04: /* LPPAGC */
|
||||
if (access == WRITEB) data = (pa & 1)?
|
||||
(lppagc & 0377) | (data << 8): (lppagc & ~0377) | data;
|
||||
lppagc = data & PAGC_MASK;
|
||||
break;
|
||||
|
||||
case 05: /* LPRDAT */
|
||||
if (access == WRITEB) data = (pa & 1)?
|
||||
(lprdat & 0377) | (data << 8): (lprdat & ~0377) | data;
|
||||
lprdat = data & RDAT_MASK;
|
||||
txram[lpcbuf & TX_AMASK] = lprdat; /* load RAM */
|
||||
break;
|
||||
|
||||
case 06: /* LPCOLC/LPCBUF */
|
||||
if ((access == WRITEB) && (pa & 1)) /* odd byte */
|
||||
lpcolc = data & 0377;
|
||||
else {
|
||||
lpcbuf = data & 0377; /* even byte, word */
|
||||
if (access == WRITE) lpcolc = (data >> 8) & 0377;
|
||||
}
|
||||
break;
|
||||
|
||||
case 07: /* LPCSUM/LPPDAT */
|
||||
break; /* read only */
|
||||
} /* end case PA */
|
||||
|
||||
update_lpcs (0);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Line printer service
|
||||
|
||||
The translation RAM case table is derived from the LP20 spec and
|
||||
verified against the LP20 RAM simulator in TOPS10 7.04 LPTSPL.
|
||||
The equations are:
|
||||
|
||||
flags := inter, delim, xlate, paper, delim_hold (from CSRA)
|
||||
actions : = print_input, print_xlate, davfu_action, interrupt
|
||||
flags := inter, delim, xlate, paper, delim_hold (from CSRA)
|
||||
actions : = print_input, print_xlate, davfu_action, interrupt
|
||||
|
||||
if (inter) {
|
||||
if (!xlate || delim || delim_hold) interrupt;
|
||||
else if (paper) davfu_action;
|
||||
else print_xlate; }
|
||||
else if (paper) {
|
||||
if (xlate || delim || delim_hold) davfu_action;
|
||||
else print_input; }
|
||||
else {
|
||||
if (xlate || delim || delim_hold) print_xlate;
|
||||
else print_input; }
|
||||
if (inter) {
|
||||
if (!xlate || delim || delim_hold) interrupt;
|
||||
else if (paper) davfu_action;
|
||||
else print_xlate;
|
||||
}
|
||||
else if (paper) {
|
||||
if (xlate || delim || delim_hold) davfu_action;
|
||||
else print_input;
|
||||
}
|
||||
else {
|
||||
if (xlate || delim || delim_hold) print_xlate;
|
||||
else print_input;
|
||||
}
|
||||
*/
|
||||
|
||||
t_stat lp20_svc (UNIT *uptr)
|
||||
{
|
||||
int32 fnc, i, tbc, temp, txst;
|
||||
int32 dvld = -2; /* must be even */
|
||||
int32 err = 0;
|
||||
int32 dvld = -2; /* must be even */
|
||||
uint16 wd10;
|
||||
t_bool cont;
|
||||
a10 ba;
|
||||
|
||||
static const uint32 txcase[32] = {
|
||||
TX_CHR, TX_RAM, TX_CHR, TX_DVU, TX_RAM, TX_RAM, TX_DVU, TX_DVU,
|
||||
TX_RAM, TX_RAM, TX_DVU, TX_DVU, TX_RAM, TX_RAM, TX_DVU, TX_DVU,
|
||||
TX_INT, TX_INT, TX_INT, TX_INT, TX_RAM, TX_INT, TX_DVU, TX_INT,
|
||||
TX_INT, TX_INT, TX_INT, TX_INT, TX_INT, TX_INT, TX_INT, TX_INT };
|
||||
TX_CHR, TX_RAM, TX_CHR, TX_DVU, TX_RAM, TX_RAM, TX_DVU, TX_DVU,
|
||||
TX_RAM, TX_RAM, TX_DVU, TX_DVU, TX_RAM, TX_RAM, TX_DVU, TX_DVU,
|
||||
TX_INT, TX_INT, TX_INT, TX_INT, TX_RAM, TX_INT, TX_DVU, TX_INT,
|
||||
TX_INT, TX_INT, TX_INT, TX_INT, TX_INT, TX_INT, TX_INT, TX_INT
|
||||
};
|
||||
|
||||
lpcsa = lpcsa & ~CSA_GO;
|
||||
ba = CSA_GETUAE (lpcsa) | lpba;
|
||||
fnc = CSA_GETFNC (lpcsa);
|
||||
tbc = 010000 - lpbc;
|
||||
if (((fnc & FNC_INTERNAL) == 0) && ((lp20_unit.flags & UNIT_ATT) == 0)) {
|
||||
update_lpcs (CSA_ERR);
|
||||
IORETURN (lp20_stopioe, SCPE_UNATT); }
|
||||
update_lpcs (CSA_ERR);
|
||||
return IORETURN (lp20_stopioe, SCPE_UNATT);
|
||||
}
|
||||
if ((fnc == FNC_PR) && (dvlnt == 0)) {
|
||||
update_lpcs (CSA_ERR);
|
||||
return SCPE_OK; }
|
||||
update_lpcs (CSA_ERR);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
for (i = 0, cont = TRUE; (i < tbc) && cont; ba++, i++) {
|
||||
if (Map_ReadW (ba, 2, &wd10)) { /* get word, err? */
|
||||
lpcsb = lpcsb | CSB_MTE; /* set NXM error */
|
||||
update_lpcs (CSA_ERR); /* set done */
|
||||
break; }
|
||||
lpcbuf = (wd10 >> ((ba & 1)? 8: 0)) & 0377; /* get character */
|
||||
lpcsum = (lpcsum + lpcbuf) & 0377; /* add into checksum */
|
||||
switch (fnc) { /* switch on function */
|
||||
if (Map_ReadW (ba, 2, &wd10)) { /* get word, err? */
|
||||
lpcsb = lpcsb | CSB_MTE; /* set NXM error */
|
||||
update_lpcs (CSA_ERR); /* set done */
|
||||
break;
|
||||
}
|
||||
lpcbuf = (wd10 >> ((ba & 1)? 8: 0)) & 0377; /* get character */
|
||||
lpcsum = (lpcsum + lpcbuf) & 0377; /* add into checksum */
|
||||
switch (fnc) { /* switch on function */
|
||||
|
||||
/* Translation RAM load */
|
||||
|
||||
case FNC_RAM: /* RAM load */
|
||||
txram[(i >> 1) & TX_AMASK] = wd10 & TX_DMASK;
|
||||
break;
|
||||
case FNC_RAM: /* RAM load */
|
||||
txram[(i >> 1) & TX_AMASK] = wd10 & TX_DMASK;
|
||||
break;
|
||||
|
||||
/* DAVFU RAM load. The DAVFU RAM is actually loaded in bytes, delimited by
|
||||
a start (354 to 356) and stop (357) byte pair. If the number of bytes
|
||||
loaded is odd, or no bytes are loaded, the DAVFU is invalid.
|
||||
*/
|
||||
|
||||
case FNC_DVU: /* DVU load */
|
||||
if ((lpcbuf >= 0354) && (lpcbuf <= 0356)) /* start DVU load? */
|
||||
dvld = dvlnt = 0; /* reset lnt */
|
||||
else if (lpcbuf == 0357) { /* stop DVU load? */
|
||||
dvptr = 0; /* reset ptr */
|
||||
if (dvld & 1) dvlnt = 0; } /* if odd, invalid */
|
||||
else if (dvld == 0) { /* even state? */
|
||||
temp = lpcbuf & DV_DMASK;
|
||||
dvld = 1; }
|
||||
else if (dvld == 1) { /* odd state? */
|
||||
if (dvlnt < DV_SIZE) davfu[dvlnt++] =
|
||||
temp | ((lpcbuf & DV_DMASK) << 6);
|
||||
dvld = 0; }
|
||||
break;
|
||||
case FNC_DVU: /* DVU load */
|
||||
if ((lpcbuf >= 0354) && (lpcbuf <= 0356)) /* start DVU load? */
|
||||
dvld = dvlnt = 0; /* reset lnt */
|
||||
else if (lpcbuf == 0357) { /* stop DVU load? */
|
||||
dvptr = 0; /* reset ptr */
|
||||
if (dvld & 1) dvlnt = 0; /* if odd, invalid */
|
||||
}
|
||||
else if (dvld == 0) { /* even state? */
|
||||
temp = lpcbuf & DV_DMASK;
|
||||
dvld = 1;
|
||||
}
|
||||
else if (dvld == 1) { /* odd state? */
|
||||
if (dvlnt < DV_SIZE) davfu[dvlnt++] =
|
||||
temp | ((lpcbuf & DV_DMASK) << 6);
|
||||
dvld = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Print characters */
|
||||
|
||||
case FNC_PR: /* print */
|
||||
lprdat = txram[lpcbuf]; /* get RAM char */
|
||||
txst = (TX_GETFL (lprdat) << 1) | /* get state */
|
||||
((lpcsa & CSA_DELH)? 1: 0); /* plus delim hold */
|
||||
if (lprdat & TX_DELH) lpcsa = lpcsa | CSA_DELH;
|
||||
else lpcsa = lpcsa & ~CSA_DELH;
|
||||
lpcsa = lpcsa & ~CSA_UNDF; /* assume char ok */
|
||||
switch (txcase[txst]) { /* case on state */
|
||||
case TX_CHR: /* take char */
|
||||
cont = lp20_print (lpcbuf);
|
||||
break;
|
||||
case TX_RAM: /* take translation */
|
||||
cont = lp20_print (lprdat);
|
||||
break;
|
||||
case TX_DVU: /* DAVFU action */
|
||||
if (lprdat & TX_SLEW)
|
||||
cont = lp20_adv (lprdat & TX_VMASK, TRUE);
|
||||
else cont = lp20_davfu (lprdat & TX_VMASK);
|
||||
break;
|
||||
case TX_INT: /* interrupt */
|
||||
lpcsa = lpcsa | CSA_UNDF; /* set flag */
|
||||
cont = FALSE; /* force stop */
|
||||
break; } /* end case char state */
|
||||
break;
|
||||
case FNC_TST: /* test */
|
||||
break; } /* end case function */
|
||||
} /* end for */
|
||||
case FNC_PR: /* print */
|
||||
lprdat = txram[lpcbuf]; /* get RAM char */
|
||||
txst = (TX_GETFL (lprdat) << 1) | /* get state */
|
||||
((lpcsa & CSA_DELH)? 1: 0); /* plus delim hold */
|
||||
if (lprdat & TX_DELH) lpcsa = lpcsa | CSA_DELH;
|
||||
else lpcsa = lpcsa & ~CSA_DELH;
|
||||
lpcsa = lpcsa & ~CSA_UNDF; /* assume char ok */
|
||||
switch (txcase[txst]) { /* case on state */
|
||||
|
||||
case TX_CHR: /* take char */
|
||||
cont = lp20_print (lpcbuf);
|
||||
break;
|
||||
|
||||
case TX_RAM: /* take translation */
|
||||
cont = lp20_print (lprdat);
|
||||
break;
|
||||
|
||||
case TX_DVU: /* DAVFU action */
|
||||
if (lprdat & TX_SLEW)
|
||||
cont = lp20_adv (lprdat & TX_VMASK, TRUE);
|
||||
else cont = lp20_davfu (lprdat & TX_VMASK);
|
||||
break;
|
||||
|
||||
case TX_INT: /* interrupt */
|
||||
lpcsa = lpcsa | CSA_UNDF; /* set flag */
|
||||
cont = FALSE; /* force stop */
|
||||
break;
|
||||
} /* end case char state */
|
||||
break;
|
||||
|
||||
case FNC_TST: /* test */
|
||||
break;
|
||||
} /* end case function */
|
||||
} /* end for */
|
||||
lpba = ba & 0177777;
|
||||
lpcsa = (lpcsa & ~CSA_UAE) | ((ba >> (16 - CSA_V_UAE)) & CSA_UAE);
|
||||
lpbc = (lpbc + i) & BC_MASK;
|
||||
if (lpbc) update_lpcs (CSA_MBZ); /* intr, but not done */
|
||||
else update_lpcs (CSA_DONE); /* intr and done */
|
||||
if (lpbc) update_lpcs (CSA_MBZ); /* intr, but not done */
|
||||
else update_lpcs (CSA_DONE); /* intr and done */
|
||||
if ((fnc == FNC_PR) && ferror (lp20_unit.fileref)) {
|
||||
perror ("LP I/O error");
|
||||
clearerr (uptr->fileref);
|
||||
return SCPE_IOERR; }
|
||||
perror ("LP I/O error");
|
||||
clearerr (uptr->fileref);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Print routines
|
||||
|
||||
lp20_print print a character
|
||||
lp20_adv advance n lines
|
||||
lp20_davfu advance to channel on VFU
|
||||
lp20_print print a character
|
||||
lp20_adv advance n lines
|
||||
lp20_davfu advance to channel on VFU
|
||||
|
||||
Return TRUE to continue printing, FALSE to stop
|
||||
*/
|
||||
@@ -463,20 +509,24 @@ t_bool lp20_print (int32 c)
|
||||
t_bool r = TRUE;
|
||||
int32 i, rpt = 1;
|
||||
|
||||
lppdat = c & 0177; /* mask char to 7b */
|
||||
if (lppdat == 000) return TRUE; /* NUL? no op */
|
||||
if (lppdat == 012) return lp20_adv (1, TRUE); /* LF? adv carriage */
|
||||
if (lppdat == 014) return lp20_davfu (DV_TOF); /* FF? top of form */
|
||||
if (lppdat == 015) lpcolc = 0; /* CR? reset col cntr */
|
||||
else if (lppdat == 011) { /* TAB? simulate */
|
||||
lppdat = ' '; /* with spaces */
|
||||
if (lpcolc >= 128) {
|
||||
r = lp20_adv (1, TRUE); /* eol? adv carriage */
|
||||
rpt = 8; } /* adv to col 9 */
|
||||
else rpt = 8 - (lpcolc & 07); } /* else adv 1 to 8 */
|
||||
else { if (lppdat < 040) lppdat = ' '; /* cvt non-prnt to spc */
|
||||
if (lpcolc >= LP_WIDTH) /* line full? */
|
||||
r = lp20_adv (1, TRUE); } /* adv carriage */
|
||||
lppdat = c & 0177; /* mask char to 7b */
|
||||
if (lppdat == 000) return TRUE; /* NUL? no op */
|
||||
if (lppdat == 012) return lp20_adv (1, TRUE); /* LF? adv carriage */
|
||||
if (lppdat == 014) return lp20_davfu (DV_TOF); /* FF? top of form */
|
||||
if (lppdat == 015) lpcolc = 0; /* CR? reset col cntr */
|
||||
else if (lppdat == 011) { /* TAB? simulate */
|
||||
lppdat = ' '; /* with spaces */
|
||||
if (lpcolc >= 128) {
|
||||
r = lp20_adv (1, TRUE); /* eol? adv carriage */
|
||||
rpt = 8; /* adv to col 9 */
|
||||
}
|
||||
else rpt = 8 - (lpcolc & 07); /* else adv 1 to 8 */
|
||||
}
|
||||
else {
|
||||
if (lppdat < 040) lppdat = ' '; /* cvt non-prnt to spc */
|
||||
if (lpcolc >= LP_WIDTH) /* line full? */
|
||||
r = lp20_adv (1, TRUE); /* adv carriage */
|
||||
}
|
||||
for (i = 0; i < rpt; i++) putc (lppdat, lp20_unit.fileref);
|
||||
lp20_unit.pos = lp20_unit.pos + rpt;
|
||||
lpcolc = lpcolc + rpt;
|
||||
@@ -488,17 +538,20 @@ t_bool lp20_adv (int32 cnt, t_bool dvuadv)
|
||||
int32 i;
|
||||
|
||||
if (cnt == 0) return TRUE;
|
||||
lpcolc = 0; /* reset col cntr */
|
||||
lpcolc = 0; /* reset col cntr */
|
||||
for (i = 0; i < cnt; i++) putc ('\n', lp20_unit.fileref);
|
||||
lp20_unit.pos = lp20_unit.pos + cnt; /* print 'n' newlines */
|
||||
if (dvuadv) dvptr = (dvptr + cnt) % dvlnt; /* update DAVFU ptr */
|
||||
if (davfu[dvptr] & (1 << DV_TOF)) { /* at top of form? */
|
||||
if (lppagc = (lppagc - 1) & PAGC_MASK) { /* decr page cntr */
|
||||
lpcsa = lpcsa & ~CSA_PZRO; /* update status */
|
||||
return TRUE; }
|
||||
else {
|
||||
lpcsa = lpcsa | CSA_PZRO; /* stop if zero */
|
||||
return FALSE; } }
|
||||
lp20_unit.pos = lp20_unit.pos + cnt; /* print 'n' newlines */
|
||||
if (dvuadv) dvptr = (dvptr + cnt) % dvlnt; /* update DAVFU ptr */
|
||||
if (davfu[dvptr] & (1 << DV_TOF)) { /* at top of form? */
|
||||
if (lppagc = (lppagc - 1) & PAGC_MASK) { /* decr page cntr */
|
||||
lpcsa = lpcsa & ~CSA_PZRO; /* update status */
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
lpcsa = lpcsa | CSA_PZRO; /* stop if zero */
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -506,40 +559,45 @@ t_bool lp20_davfu (int32 cnt)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (cnt > DV_MAX) cnt = 7; /* inval chan? */
|
||||
for (i = 0; i < dvlnt; i++) { /* search DAVFU */
|
||||
dvptr = dvptr + 1; /* adv DAVFU ptr */
|
||||
if (dvptr >= dvlnt) dvptr = 0; /* wrap at end */
|
||||
if (davfu[dvptr] & (1 << cnt)) { /* channel stop set? */
|
||||
if (cnt) return lp20_adv (i + 1, FALSE); /* ~TOF, adv */
|
||||
if (lpcolc) lp20_adv (1, FALSE); /* TOF, need newline? */
|
||||
putc ('\f', lp20_unit.fileref); /* print form feed */
|
||||
lp20_unit.pos = lp20_unit.pos + 1;
|
||||
if (lppagc = (lppagc - 1) & PAGC_MASK) { /* decr page cntr */
|
||||
lpcsa = lpcsa & ~CSA_PZRO; /* update status */
|
||||
return TRUE; }
|
||||
else {
|
||||
lpcsa = lpcsa | CSA_PZRO; /* stop if zero */
|
||||
return FALSE; } }
|
||||
} /* end for */
|
||||
dvlnt = 0; /* DAVFU error */
|
||||
if (cnt > DV_MAX) cnt = 7; /* inval chan? */
|
||||
for (i = 0; i < dvlnt; i++) { /* search DAVFU */
|
||||
dvptr = dvptr + 1; /* adv DAVFU ptr */
|
||||
if (dvptr >= dvlnt) dvptr = 0; /* wrap at end */
|
||||
if (davfu[dvptr] & (1 << cnt)) { /* channel stop set? */
|
||||
if (cnt) return lp20_adv (i + 1, FALSE); /* ~TOF, adv */
|
||||
if (lpcolc) lp20_adv (1, FALSE); /* TOF, need newline? */
|
||||
putc ('\f', lp20_unit.fileref); /* print form feed */
|
||||
lp20_unit.pos = lp20_unit.pos + 1;
|
||||
if (lppagc = (lppagc - 1) & PAGC_MASK) { /* decr page cntr */
|
||||
lpcsa = lpcsa & ~CSA_PZRO; /* update status */
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
lpcsa = lpcsa | CSA_PZRO; /* stop if zero */
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
} /* end for */
|
||||
dvlnt = 0; /* DAVFU error */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* Update LPCSA, optionally request interrupt */
|
||||
|
||||
void update_lpcs (int32 flg)
|
||||
{
|
||||
if (flg) lp20_irq = 1; /* set int req */
|
||||
if (flg) lp20_irq = 1; /* set int req */
|
||||
lpcsa = (lpcsa | flg) & ~(CSA_MBZ | CSA_ERR | CSA_ONL | CSA_DVON);
|
||||
lpcsb = (lpcsb | CSB_OFFL | CSB_DVOF) & ~CSB_MBZ;
|
||||
if (lp20_unit.flags & UNIT_ATT) {
|
||||
lpcsa = lpcsa | CSA_ONL;
|
||||
lpcsb = lpcsb & ~CSB_OFFL; }
|
||||
lpcsa = lpcsa | CSA_ONL;
|
||||
lpcsb = lpcsb & ~CSB_OFFL;
|
||||
}
|
||||
else lpcsa = lpcsa & ~CSA_DONE;
|
||||
if (dvlnt) {
|
||||
lpcsa = lpcsa | CSA_DVON;
|
||||
lpcsb = lpcsb & ~CSB_DVOF; }
|
||||
lpcsa = lpcsa | CSA_DVON;
|
||||
lpcsb = lpcsb & ~CSB_DVOF;
|
||||
}
|
||||
if (lpcsb & CSB_ERR) lpcsa = lpcsa | CSA_ERR;
|
||||
if ((lpcsa & CSA_IE) && lp20_irq) int_req = int_req | INT_LP20;
|
||||
else int_req = int_req & ~INT_LP20;
|
||||
@@ -550,31 +608,31 @@ return;
|
||||
|
||||
int32 lp20_inta (void)
|
||||
{
|
||||
lp20_irq = 0; /* clear int req */
|
||||
lp20_irq = 0; /* clear int req */
|
||||
return lp20_dib.vec;
|
||||
}
|
||||
|
||||
|
||||
t_stat lp20_reset (DEVICE *dptr)
|
||||
{
|
||||
lpcsa = CSA_DONE;
|
||||
lpcsb = 0;
|
||||
lpba = lpbc = lppagc = lpcolc = 0; /* clear registers */
|
||||
lpba = lpbc = lppagc = lpcolc = 0; /* clear registers */
|
||||
lprdat = lppdat = lpcbuf = lpcsum = 0;
|
||||
lp20_irq = 0; /* clear int req */
|
||||
dvptr = 0; /* reset davfu ptr */
|
||||
sim_cancel (&lp20_unit); /* deactivate unit */
|
||||
update_lpcs (0); /* update status */
|
||||
lp20_irq = 0; /* clear int req */
|
||||
dvptr = 0; /* reset davfu ptr */
|
||||
sim_cancel (&lp20_unit); /* deactivate unit */
|
||||
update_lpcs (0); /* update status */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat lp20_attach (UNIT *uptr, char *cptr)
|
||||
{
|
||||
t_stat reason;
|
||||
|
||||
reason = attach_unit (uptr, cptr); /* attach file */
|
||||
if (lpcsa & CSA_ONL) return reason; /* just file chg? */
|
||||
if (sim_is_active (&lp20_unit)) update_lpcs (0); /* busy? no int */
|
||||
else update_lpcs (CSA_MBZ); /* interrupt */
|
||||
|
||||
reason = attach_unit (uptr, cptr); /* attach file */
|
||||
if (lpcsa & CSA_ONL) return reason; /* just file chg? */
|
||||
if (sim_is_active (&lp20_unit)) update_lpcs (0); /* busy? no int */
|
||||
else update_lpcs (CSA_MBZ); /* interrupt */
|
||||
return reason;
|
||||
}
|
||||
|
||||
@@ -582,7 +640,7 @@ t_stat lp20_detach (UNIT *uptr)
|
||||
{
|
||||
t_stat reason;
|
||||
|
||||
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; /* attached? */
|
||||
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; /* attached? */
|
||||
reason = detach_unit (uptr);
|
||||
sim_cancel (&lp20_unit);
|
||||
lpcsa = lpcsa & ~CSA_GO;
|
||||
|
||||
Reference in New Issue
Block a user