mirror of
https://github.com/simh/simh.git
synced 2026-01-26 20:12:23 +00:00
simh 3.10-RC1a
3.10 is mostly an attempt to get aligned with the current head of the GitHub 4.0 sources. While the core libraries and SCP have diverged too far for real forward and backward compatibility, enough 4.0 workalikes have been added to allow much closer convergence of the two streams. 3.10 will provide the basis for my future simulation work.
This commit is contained in:
committed by
Mark Pizzolato
parent
140ab5b350
commit
3fada8da5a
@@ -26,6 +26,7 @@
|
||||
cdr 1622 card reader
|
||||
cdp 1622 card punch
|
||||
|
||||
23-Jun-17 RMS Unattached error does not set RDCHK/WRCHK
|
||||
09-Mar-17 RMS Guardbanded translation table lookups (COVERITY)
|
||||
31-Jan-15 TFM Changes to translation tables (Tom McBride)
|
||||
10-Dec-13 RMS Fixed WA card punch translations (Bob Armstrong)
|
||||
@@ -339,10 +340,8 @@ t_stat cdr_read (void)
|
||||
int32 i;
|
||||
|
||||
ind[IN_LAST] = 0; /* clear last card */
|
||||
if ((cdr_unit.flags & UNIT_ATT) == 0) { /* attached? */
|
||||
ind[IN_RDCHK] = 1; /* no, error */
|
||||
if ((cdr_unit.flags & UNIT_ATT) == 0) /* attached? */
|
||||
return SCPE_UNATT;
|
||||
}
|
||||
|
||||
for (i = 0; i < CD_LEN + 2; i++) /* clear buffer */
|
||||
cdr_buf[i] = ' ';
|
||||
@@ -351,7 +350,7 @@ if (feof (cdr_unit.fileref)) /* eof? */
|
||||
return STOP_NOCD;
|
||||
if (ferror (cdr_unit.fileref)) { /* error? */
|
||||
ind[IN_RDCHK] = 1; /* set read check */
|
||||
perror ("CDR I/O error");
|
||||
sim_perror ("CDR I/O error");
|
||||
clearerr (cdr_unit.fileref);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
@@ -367,7 +366,7 @@ if ((i = strlen (cdr_buf)) > 0) { /* anything at all? */
|
||||
}
|
||||
else { /* line too long */
|
||||
ind[IN_RDCHK] = 1;
|
||||
perror ("CDR line too long");
|
||||
sim_perror ("CDR line too long");
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
}
|
||||
@@ -520,10 +519,8 @@ return SCPE_OK;
|
||||
|
||||
t_stat cdp_write (uint32 len)
|
||||
{
|
||||
if ((cdp_unit.flags & UNIT_ATT) == 0) { /* attached? */
|
||||
ind[IN_WRCHK] = 1; /* no, error */
|
||||
if ((cdp_unit.flags & UNIT_ATT) == 0) /* attached? */
|
||||
return SCPE_UNATT;
|
||||
}
|
||||
|
||||
while ((len > 0) && (cdp_buf[len - 1] == ' ')) /* trim spaces */
|
||||
--len;
|
||||
@@ -534,7 +531,7 @@ fputs (cdp_buf, cdp_unit.fileref); /* write card */
|
||||
cdp_unit.pos = ftell (cdp_unit.fileref); /* count char */
|
||||
if (ferror (cdp_unit.fileref)) { /* error? */
|
||||
ind[IN_WRCHK] = 1;
|
||||
perror ("CDP I/O error");
|
||||
sim_perror ("CDP I/O error");
|
||||
clearerr (cdp_unit.fileref);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
This CPU module incorporates code and comments from the 1620 simulator by
|
||||
Geoff Kuenning, with his permission.
|
||||
|
||||
23-Jun-17 RMS BS should not enable indexing unless configured
|
||||
15-Jun-17 RMS Added more information to IO in progress message
|
||||
26-May-17 RMS Added deferred IO mode for slow devices
|
||||
20-May-17 RMS Changed to commit PC on certain stops
|
||||
Added SET CPU RELEASE command
|
||||
@@ -94,6 +96,7 @@
|
||||
|
||||
cpuio_mode set if IO in progress
|
||||
cpuio_opc saved IO opcode
|
||||
cpuio_dev saved IO device number
|
||||
cpuio_cnt character counter; increments
|
||||
PAR P address; increments
|
||||
|
||||
@@ -152,6 +155,7 @@ uint32 io_stop = 1; /* I/O stop */
|
||||
uint32 ar_stop = 1; /* arith stop */
|
||||
uint32 cpuio_inp = 0; /* IO in progress */
|
||||
uint32 cpuio_opc = 0;
|
||||
uint32 cpuio_dev = 0;
|
||||
uint32 cpuio_cnt = 0;
|
||||
int32 ind_max = 16; /* iadr nest limit */
|
||||
uint16 pcq[PCQ_SIZE] = { 0 }; /* PC queue */
|
||||
@@ -245,9 +249,10 @@ REG cpu_reg[] = {
|
||||
{ FLDATA (WRCHK, ind[IN_WRCHK], 0) },
|
||||
{ FLDATA (ARSTOP, ar_stop, 0) },
|
||||
{ FLDATA (IOSTOP, io_stop, 0) },
|
||||
{ FLDATA (IOINP, cpuio_inp, 0), REG_RO },
|
||||
{ DRDATA (IOOPC, cpuio_opc, 6), REG_RO },
|
||||
{ DRDATA (IOCNT, cpuio_cnt, 16), REG_RO },
|
||||
{ FLDATA (IOINP, cpuio_inp, 0), REG_HRO },
|
||||
{ DRDATA (IOOPC, cpuio_opc, 6), REG_HRO },
|
||||
{ DRDATA (IODEV, cpuio_dev, 7), REG_HRO },
|
||||
{ DRDATA (IOCNT, cpuio_cnt, 16), REG_HRO },
|
||||
{ BRDATA (IND, ind, 10, 1, NUM_IND) },
|
||||
{ FLDATA (IAE, iae, 0) },
|
||||
{ FLDATA (IDXE, idxe, 0) },
|
||||
@@ -956,7 +961,7 @@ while (reason == SCPE_OK) { /* loop until halted */
|
||||
}
|
||||
break;
|
||||
|
||||
/* Branch and select - P is valid */
|
||||
/* Branch and select - P is valid - Model 2 only */
|
||||
|
||||
case OP_BS:
|
||||
t = M[ADDR_A (saved_PC, I_SEL)] & DIGIT; /* get select */
|
||||
@@ -965,10 +970,12 @@ while (reason == SCPE_OK) { /* loop until halted */
|
||||
idxe = idxb = 0; /* indexing off */
|
||||
break;
|
||||
case 1:
|
||||
idxe = 1; idxb = 0; /* index band A */
|
||||
if ((cpu_unit.flags & IF_IDX) != 0) /* indexing present? */
|
||||
idxe = 1; idxb = 0; /* index band A */
|
||||
break;
|
||||
case 2:
|
||||
idxe = idxb = 1; /* index band B */
|
||||
if ((cpu_unit.flags & IF_IDX) != 0) /* indexing present? */
|
||||
idxe = idxb = 1; /* index band B */
|
||||
break;
|
||||
case 8:
|
||||
iae = 0; /* indirect off */
|
||||
@@ -1107,8 +1114,13 @@ for (i = 0; commit_pc[i] != 0; i++) { /* check stop code */
|
||||
actual_PC = PC; /* save cur PC for RLS */
|
||||
pcq_r->qptr = pcq_p; /* update pc q ptr */
|
||||
upd_ind ();
|
||||
if (cpuio_inp != 0) /* flag IO in progress */
|
||||
sim_printf ("\r\nIO in progress");
|
||||
if (cpuio_inp != 0) { /* flag IO in progress */
|
||||
char *opstr = opc_lookup (cpuio_opc, cpuio_dev * 100, NULL);
|
||||
|
||||
if (opstr != NULL)
|
||||
sim_printf ("\r\nIO in progress (%s %05d)", opstr, PAR);
|
||||
else sim_printf ("\r\nIO in progress (%02d %05d,%05d)", cpuio_opc, PAR, cpuio_dev * 100);
|
||||
}
|
||||
return reason;
|
||||
}
|
||||
|
||||
@@ -2160,10 +2172,11 @@ return SCPE_OK;
|
||||
|
||||
/* Set and clear IO in progress */
|
||||
|
||||
t_stat cpuio_set_inp (uint32 op, UNIT *uptr)
|
||||
t_stat cpuio_set_inp (uint32 op, uint32 dev, UNIT *uptr)
|
||||
{
|
||||
cpuio_inp = 1;
|
||||
cpuio_opc = op;
|
||||
cpuio_dev = dev;
|
||||
cpuio_cnt = 0;
|
||||
if (uptr != NULL)
|
||||
sim_activate_abs (uptr, uptr->wait);
|
||||
@@ -2174,6 +2187,7 @@ t_stat cpuio_clr_inp (UNIT *uptr)
|
||||
{
|
||||
cpuio_inp = 0;
|
||||
cpuio_opc = 0;
|
||||
cpuio_dev = 0;
|
||||
cpuio_cnt = 0;
|
||||
if (uptr != NULL)
|
||||
sim_cancel (uptr);
|
||||
@@ -2221,6 +2235,7 @@ DEVICE *dptr;
|
||||
if (cpuio_inp != 0) { /* IO in progress? */
|
||||
cpuio_inp = 0;
|
||||
cpuio_opc = 0;
|
||||
cpuio_dev = 0;
|
||||
cpuio_cnt = 0;
|
||||
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) {
|
||||
if (((dptr->flags & DEV_DEFIO) != 0) && (dptr->reset != NULL))
|
||||
|
||||
@@ -242,7 +242,8 @@ enum opcodes {
|
||||
|
||||
/* Function declarations */
|
||||
|
||||
t_stat cpuio_set_inp (uint32 op, UNIT *uptr);
|
||||
t_stat cpuio_set_inp (uint32 op, uint32 dev, UNIT *uptr);
|
||||
t_stat cpuio_clr_inp (UNIT *uptr);
|
||||
char *opc_lookup (uint32 op, uint32 qv, uint32 *fl);
|
||||
|
||||
#endif
|
||||
|
||||
29
I1620/i1620_error_matrix.txt
Normal file
29
I1620/i1620_error_matrix.txt
Normal file
@@ -0,0 +1,29 @@
|
||||
Device Error Action
|
||||
|
||||
CDR RN, RA invalid char set RDCHK; if IOSTOP set, stop simulator with INVCHR
|
||||
unattached stop simulator with UNATT (CHANGED - used to set RDCHK too)
|
||||
end of file stop simulator witn NOCD (CHANGED - used to set RDCHK too)
|
||||
file read error set RDCHK; stop simulator with IOERR
|
||||
input line too long set RDCHK; stop simulator with IOERR
|
||||
|
||||
CDP WN,DN invalid digit set WRCHK; if IOSTOP set, stop simulator with INVCHR
|
||||
WA invalid char set WRCHK; if IOSTOP set, stop simulator with INVCHR
|
||||
unattached stop simulator with UNATT (CHANGED - used to set WRCHK too)
|
||||
file write error set WRCHK; stop simulator with IOERR
|
||||
|
||||
LPT bad K control field set PRCHK; if IOSTOP set, stop simulator with INVFNC
|
||||
WN,DN invalid digit set PRCHK and WRCHK; if IOSTOP set, stop simulator with INVFNC
|
||||
WA invalid char set PRCHK and WRCHK; if IOSTOP set, stop simulator with INVFNC
|
||||
unattached stop simulator with UNATT (CHANGED - used to set WRCHK too)
|
||||
file write error set PRCHK and WRCHK; stop simulator with IOERR
|
||||
|
||||
PTR RN, RA invalid char set RDCHK but complete operation; if IOSTOP set at end, stop simulator with INVCHR
|
||||
RN, RA parity error set RDCHK but complete operation; if IOSTOP set at end, stop simulator with INVCHR
|
||||
WN, DN invalid digit set WRCHK; if IOSTOP set, stop simulator with INVCHR
|
||||
WA invalid char set WRCHK; if IOSTOP set, stop simulator with INVCHR
|
||||
unattached stop simulator with UNATT (CHANGED - used to set WRCHK too)
|
||||
file write error set WRCHK; stop simulator with IOERR
|
||||
|
||||
TTY RN, RA invalid char ignored, echoed as beep/bell
|
||||
WN, DN invalid digit ignored, printed as :
|
||||
WA invalid char set WRCHK; if IOSTOP set, stop simulator with INVCHR
|
||||
@@ -186,7 +186,8 @@ uint8 d, l, z;
|
||||
z = 1; /* assume zero */
|
||||
for (l = 1; l <= FP_LMAX; l++) { /* scan to get length */
|
||||
d = M[ad] & DIGIT; /* get mant digit */
|
||||
if (d) z = 0; /* non-zero? */
|
||||
if (d) /* non-zero? */
|
||||
z = 0;
|
||||
if ((l != 1) && (M[ad] & FLAG)) { /* flag past first dig? */
|
||||
*lnt = l; /* set returns */
|
||||
if (zro)
|
||||
|
||||
144
I1620/i1620_lp.c
144
I1620/i1620_lp.c
@@ -1,6 +1,6 @@
|
||||
/* i1620_lp.c: IBM 1443 line printer simulator
|
||||
|
||||
Copyright (c) 2002-2015, Robert M. Supnik
|
||||
Copyright (c) 2002-2017, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
lpt 1443 line printer
|
||||
|
||||
15-Jun-17 RMS Fixed K constants and print-no-spacing (Tom McBride)
|
||||
Added option to emulate form feed with newlines
|
||||
31-Jan-15 TFM Fixed various problems ... see comments in code
|
||||
10-Dec-13 RMS Fixed DN wraparound (Bob Armstrong)
|
||||
Fixed test on VFU 10 (Bob Armstrong)
|
||||
@@ -37,10 +39,13 @@
|
||||
#include "i1620_defs.h"
|
||||
|
||||
#define LPT_BSIZE 197 /* buffer size */
|
||||
#define UNIT_V_FF (UNIT_V_UF + 0)
|
||||
#define UNIT_FF (1 << UNIT_V_FF)
|
||||
|
||||
#define K_IMM 0x10 /* control now */
|
||||
/* decoded print control */
|
||||
|
||||
#define K_IMM 0x10 /* before print */
|
||||
#define K_LIN 0x20 /* spc lines */
|
||||
#define K_CH10 0x40 /* chan 10 */
|
||||
#define K_LCNT 0x03 /* line count */
|
||||
#define K_CHAN 0x0F /* channel */
|
||||
|
||||
@@ -59,8 +64,9 @@ t_stat lpt_svc (UNIT *uptr);
|
||||
t_stat lpt_reset (DEVICE *dptr);
|
||||
t_stat lpt_attach (UNIT *uptr, char *cptr);
|
||||
void lpt_buf_init (void);
|
||||
t_stat lpt_num(uint32 pa, uint32 f1, t_bool dump); /* tfm: length parameter removed, not needed */
|
||||
t_stat lpt_print (void);
|
||||
t_stat lpt_num(uint32 pa, uint32 f1, t_bool dump);
|
||||
t_stat lpt_print (uint32 flag);
|
||||
t_stat lpt_spcop (int32 ctrl);
|
||||
t_stat lpt_space (int32 lines, int32 lflag);
|
||||
|
||||
#define CHP(ch,val) ((val) & (1 << (ch)))
|
||||
@@ -79,7 +85,7 @@ UNIT lpt_unit = {
|
||||
REG lpt_reg[] = {
|
||||
{ BRDATA (LBUF, lpt_buf, 8, 8, LPT_BSIZE + 1) },
|
||||
{ DRDATA (BPTR, lpt_bptr, 8) },
|
||||
{ HRDATA (PCTL, lpt_savctrl, 8) },
|
||||
{ HRDATA (PCTL, lpt_savctrl, 6) },
|
||||
{ FLDATA (PRCHK, ind[IN_PRCHK], 0) },
|
||||
{ FLDATA (PRCH9, ind[IN_PRCH9], 0) },
|
||||
{ FLDATA (PRCH12, ind[IN_PRCH12], 0) },
|
||||
@@ -91,8 +97,14 @@ REG lpt_reg[] = {
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
MTAB lp_mod[] = {
|
||||
{ UNIT_FF, 0, "no form feeds", "NOFF", NULL },
|
||||
{ UNIT_FF, UNIT_FF, "form feeds", "FF", NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEVICE lpt_dev = {
|
||||
"LPT", &lpt_unit, lpt_reg, NULL,
|
||||
"LPT", &lpt_unit, lpt_reg, lp_mod,
|
||||
1, 10, 31, 1, 8, 7,
|
||||
NULL, NULL, &lpt_reset,
|
||||
NULL, &lpt_attach, NULL
|
||||
@@ -103,10 +115,10 @@ DEVICE lpt_dev = {
|
||||
/* Numeric (flag plus digit) to lineprinter (ASCII) */
|
||||
|
||||
const int8 num_to_lpt[32] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', /* tfm: All invalid char treated as errors */
|
||||
'8', '9', '|', -1, '@', -1, -1, 'G', /* tfm: @, G only print on DN; else NB is blank */
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', /* All invalid char treated as errors */
|
||||
'8', '9', '|', -1, '@', -1, -1, 'G', /* @, G only print on DN; else NB is blank */
|
||||
'-', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'W', -1, '*', -1, -1, 'X' /* tfm: W, *, X only print on DN */
|
||||
'Q', 'R', 'W', -1, '*', -1, -1, 'X' /* W, *, X only print on DN */
|
||||
};
|
||||
|
||||
/* Alphameric (digit pair) to lineprinter (ASCII) */
|
||||
@@ -146,6 +158,24 @@ const int8 alp_to_lpt[256] = { /* tfm: invalid codes 02
|
||||
-1, -1, -1, -1, -1, -1, -1, -1
|
||||
};
|
||||
|
||||
/* K validation and translation table - entryies 80:FF always 0 */
|
||||
|
||||
static const int8 lpt_ktbl[128] = {
|
||||
0, 0, 0, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 */
|
||||
0, K_LIN|1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20 */
|
||||
0, 0, 0, K_IMM|11, K_IMM|12, 0, 0, 0, 0, 0, /* 30 */
|
||||
0, 0, 0, 0, 0, 0,
|
||||
10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 40 */
|
||||
0, K_IMM|K_LIN|1, K_IMM|K_LIN|2, K_IMM|K_LIN|3, 0, /* 50 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, K_LIN|2, K_LIN|3, 0, 0, 0, 0, 0, 0, /* 60 */
|
||||
0, 0, 0, 0, 0, 0,
|
||||
K_IMM|10, K_IMM|1, K_IMM|2, K_IMM|3, K_IMM|4, /* 70 */
|
||||
K_IMM|5, K_IMM|6, K_IMM|7, K_IMM|8, K_IMM|9,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
/* Line printer IO routine
|
||||
|
||||
- Hard errors halt the system.
|
||||
@@ -157,6 +187,7 @@ t_stat lpt (uint32 op, uint32 pa, uint32 f0, uint32 f1)
|
||||
{
|
||||
int8 lpc;
|
||||
uint8 z, d;
|
||||
int32 ctrl;
|
||||
t_stat r, sta;
|
||||
|
||||
sta = SCPE_OK;
|
||||
@@ -166,16 +197,24 @@ ind[IN_PRBSY] = 0; /* printer free */
|
||||
switch (op) { /* decode op */
|
||||
|
||||
case OP_K: /* control */
|
||||
lpt_savctrl = (f0 << 4) | f1; /* form ctrl */
|
||||
if (lpt_savctrl & K_IMM) /* immediate? */
|
||||
return lpt_print ();
|
||||
break;
|
||||
ctrl = lpt_ktbl[((f0 & 0x7) << 4) | (f1 & 0xF)]; /* xlate ctrl */
|
||||
if ((f0 > 7) || (ctrl == 0)) { /* invalid? */
|
||||
ind[IN_PRCHK] = 1; /* print chk */
|
||||
if (io_stop) /* set return status */
|
||||
sta = STOP_INVFNC;
|
||||
}
|
||||
else {
|
||||
if ((ctrl & K_IMM) != 0) /* immediate? */
|
||||
return lpt_spcop (ctrl); /* execute */
|
||||
else lpt_savctrl = ctrl; /* otherwise, save */
|
||||
}
|
||||
return sta;
|
||||
|
||||
case OP_DN:
|
||||
return lpt_num (pa, f1, TRUE); /* dump numeric (tfm: removed len parm ) */
|
||||
return lpt_num (pa, f1, TRUE); /* dump numeric */
|
||||
|
||||
case OP_WN:
|
||||
return lpt_num (pa, f1, FALSE); /* write numeric (tfm: removed len parm ) */
|
||||
return lpt_num (pa, f1, FALSE); /* write numeric */
|
||||
|
||||
case OP_WA:
|
||||
for ( ; lpt_bptr < LPT_BSIZE; lpt_bptr++) { /* only fill buf */
|
||||
@@ -192,11 +231,9 @@ switch (op) { /* decode op */
|
||||
lpt_buf[lpt_bptr] = lpc & 0x7F; /* fill buffer */
|
||||
pa = ADDR_A (pa, 2); /* incr mem addr */
|
||||
}
|
||||
if ((f1 & 1) == 0) { ; /* print now? */
|
||||
r = lpt_print (); /* print line */
|
||||
if (r != SCPE_OK)
|
||||
return r;
|
||||
}
|
||||
r = lpt_print (f1); /* print line */
|
||||
if (r != SCPE_OK)
|
||||
return r;
|
||||
return sta;
|
||||
|
||||
default: /* invalid function */
|
||||
@@ -208,7 +245,7 @@ return SCPE_OK;
|
||||
|
||||
/* Print numeric */
|
||||
|
||||
t_stat lpt_num (uint32 pa, uint32 f1, t_bool dump) /* tfm: removed len parm and reorganized code */
|
||||
t_stat lpt_num (uint32 pa, uint32 f1, t_bool dump)
|
||||
{
|
||||
uint8 d;
|
||||
int8 lpc;
|
||||
@@ -232,57 +269,55 @@ for ( ; lpt_bptr < LPT_BSIZE; lpt_bptr++) { /* only fill buf */
|
||||
lpt_buf[lpt_bptr] = lpc & 0x7F; /* put char into buffer (tfm: correct increment)*/
|
||||
PP (pa); /* incr mem addr */
|
||||
}
|
||||
if ((f1 & 1) == 0) { /* print now? */
|
||||
r = lpt_print (); /* print line */
|
||||
if (r != SCPE_OK)
|
||||
return r;
|
||||
}
|
||||
r = lpt_print (f1); /* print line */
|
||||
if (r != SCPE_OK)
|
||||
return r;
|
||||
return sta;
|
||||
}
|
||||
|
||||
/* Print and space */
|
||||
/* Print and possibly space - any spacing operation is non-immediate */
|
||||
|
||||
t_stat lpt_print (void)
|
||||
t_stat lpt_print (uint32 flag)
|
||||
{
|
||||
int32 i, chan, ctrl = lpt_savctrl;
|
||||
int32 i;
|
||||
|
||||
if ((lpt_unit.flags & UNIT_ATT) == 0) { /* not attached? */
|
||||
ind[IN_PRCHK] = ind[IN_WRCHK] = 1; /* wr, pri check */
|
||||
ind[IN_PRCHK] = 1; /* pri check */
|
||||
return SCPE_UNATT;
|
||||
}
|
||||
|
||||
ind[IN_PRBSY] = 1; /* print busy */
|
||||
sim_activate (&lpt_unit, lpt_unit.wait); /* start timer */
|
||||
|
||||
for (i = LPT_WIDTH; i <= LPT_BSIZE; i++) /* clear unprintable */
|
||||
lpt_buf[i] = ' ';
|
||||
while ((lpt_bptr > 0) && (lpt_buf[lpt_bptr - 1] == ' '))
|
||||
lpt_buf[--lpt_bptr] = 0; /* trim buffer */
|
||||
if (lpt_bptr) { /* any line? */
|
||||
if (lpt_bptr != 0) { /* any line? */
|
||||
fputs (lpt_buf, lpt_unit.fileref); /* print */
|
||||
if ((flag & 1) != 0) /* no space? */
|
||||
fputc ('\r', lpt_unit.fileref); /* bare return */
|
||||
lpt_unit.pos = ftell (lpt_unit.fileref); /* update pos */
|
||||
lpt_buf_init (); /* reinit buf */
|
||||
if (ferror (lpt_unit.fileref)) { /* error? */
|
||||
ind[IN_PRCHK] = ind[IN_WRCHK] = 1; /* wr, pri check */
|
||||
perror ("LPT I/O error");
|
||||
ind[IN_PRCHK] = 1; /* pri check */
|
||||
sim_perror ("LPT I/O error");
|
||||
clearerr (lpt_unit.fileref);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
}
|
||||
if ((flag & 1) == 0) /* spacing? */
|
||||
return lpt_spcop (lpt_savctrl); /* execute */
|
||||
return SCPE_OK; /* done */
|
||||
}
|
||||
|
||||
lpt_savctrl = 0x61; /* reset ctrl */
|
||||
if ((ctrl & K_LIN) == ((ctrl & K_IMM)? 0: K_LIN)) /* space lines? */
|
||||
return lpt_space (ctrl & K_LCNT, FALSE);
|
||||
chan = lpt_savctrl & K_CHAN; /* basic chan */
|
||||
if ((lpt_savctrl & K_CH10) == 0) { /* chan 10-12? */
|
||||
if (chan == 0)
|
||||
chan = 10;
|
||||
else if (chan == 3)
|
||||
chan = 11;
|
||||
else if (chan == 4)
|
||||
chan = 12;
|
||||
else chan = 0;
|
||||
}
|
||||
/* Space operation - direct (K) or deferred (WA, WN, DN) */
|
||||
|
||||
t_stat lpt_spcop (int32 ctrl)
|
||||
{
|
||||
int32 chan, i;
|
||||
|
||||
lpt_savctrl = K_LIN|1; /* reset saved control */
|
||||
if ((ctrl & K_LIN) != 0) /* space lines? */
|
||||
return lpt_space (ctrl & K_LCNT, FALSE); /* execute spacing op */
|
||||
chan = lpt_savctrl & K_CHAN; /* get chan */
|
||||
if ((chan == 0) || (chan > 12))
|
||||
return STOP_INVFNC;
|
||||
for (i = 1; i < cct_lnt + 1; i++) { /* sweep thru cct */
|
||||
@@ -304,7 +339,8 @@ t_stat lpt_space (int32 count, int32 sflag)
|
||||
int32 i;
|
||||
|
||||
cct_ptr = (cct_ptr + count) % cct_lnt; /* adv cct, mod lnt */
|
||||
if (sflag && CHP (0, cct[cct_ptr])) /* skip, top of form? */
|
||||
if (sflag && CHP (0, cct[cct_ptr]) && /* skip, top of form, */
|
||||
((lpt_unit.flags & UNIT_FF) != 0)) /* and use form feeds? */
|
||||
fputs ("\n\f", lpt_unit.fileref); /* nl, ff */
|
||||
else {
|
||||
for (i = 0; i < count; i++) /* count lines */
|
||||
@@ -315,10 +351,12 @@ ind[IN_PRCH9] = CHP (9, cct[cct_ptr]) != 0; /* set indicators */
|
||||
ind[IN_PRCH12] = CHP (12, cct[cct_ptr]) != 0;
|
||||
if (ferror (lpt_unit.fileref)) { /* error? */
|
||||
ind[IN_PRCHK] = ind[IN_WRCHK] = 1; /* wr, pri check */
|
||||
perror ("LPT I/O error");
|
||||
sim_perror ("LPT I/O error");
|
||||
clearerr (lpt_unit.fileref);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
ind[IN_PRBSY] = 1; /* print busy */
|
||||
sim_activate (&lpt_unit, lpt_unit.wait); /* start timer */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -348,7 +386,7 @@ t_stat lpt_reset (DEVICE *dptr)
|
||||
{
|
||||
lpt_buf_init (); /* clear buffer */
|
||||
cct_ptr = 0; /* clear cct ptr */
|
||||
lpt_savctrl = 0x61; /* clear cct action */
|
||||
lpt_savctrl = K_LIN|1; /* reset cct action */
|
||||
ind[IN_PRCHK] = ind[IN_PRBSY] = 0; /* clear indicators */
|
||||
ind[IN_PRCH9] = ind[IN_PRCH12] = 0;
|
||||
return SCPE_OK;
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
|
||||
ptr 1621 paper tape reader
|
||||
ptp 1624 paper tape punch
|
||||
|
||||
|
||||
23-Jun-17 RMS PTR/PTP errors does not set read check
|
||||
10-Jun-17 RMS Fixed typo in PTP unit (Dave Wise)
|
||||
26-May-17 RMS Added deferred IO
|
||||
25-May-17 RMS Fixed treatment of X0C82 on RN (Tom McBride)
|
||||
@@ -230,7 +231,7 @@ if ((op != OP_RN) && (op != OP_RA)) /* RN & RA only */
|
||||
if ((ptr_unit.flags & UNIT_ATT) == 0) /* catch unattached */
|
||||
return SCPE_UNATT;
|
||||
ptr_mode = 0;
|
||||
cpuio_set_inp (op, &ptr_unit);
|
||||
cpuio_set_inp (op, IO_PTR, &ptr_unit);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -243,7 +244,7 @@ if (op != OP_RA) /* RA only */
|
||||
if ((ptr_unit.flags & UNIT_ATT) == 0) /* catch unattached */
|
||||
return SCPE_UNATT;
|
||||
ptr_mode = 1;
|
||||
cpuio_set_inp (op, &ptr_unit);
|
||||
cpuio_set_inp (op, IO_BTR, &ptr_unit);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -341,13 +342,12 @@ int32 temp;
|
||||
|
||||
do {
|
||||
if ((temp = getc (ptr_unit.fileref)) == EOF) { /* read char */
|
||||
ind[IN_RDCHK] = 1; /* err, rd chk */
|
||||
if (feof (ptr_unit.fileref)) { /* EOF? */
|
||||
sim_printf ("PTR end of file\n");
|
||||
clearerr (ptr_unit.fileref);
|
||||
return SCPE_EOF;
|
||||
}
|
||||
else perror ("PTR I/O error"); /* no, io err */
|
||||
else sim_perror ("PTR I/O error"); /* no, io err */
|
||||
clearerr (ptr_unit.fileref);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
@@ -395,7 +395,7 @@ if ((op != OP_WN) && (op != OP_WA) && (op != OP_DN))
|
||||
if ((ptp_unit.flags & UNIT_ATT) == 0) /* catch unattached */
|
||||
return SCPE_UNATT;
|
||||
ptp_mode = 0;
|
||||
cpuio_set_inp (op, &ptp_unit);
|
||||
cpuio_set_inp (op, IO_PTP, &ptp_unit);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -408,7 +408,7 @@ if (op != OP_WA) /* WA only */
|
||||
if ((ptp_unit.flags & UNIT_ATT) == 0) /* catch unattached */
|
||||
return SCPE_UNATT;
|
||||
ptp_mode = 1;
|
||||
cpuio_set_inp (op, &ptp_unit);
|
||||
cpuio_set_inp (op, IO_BTP, &ptp_unit);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -502,8 +502,7 @@ return SCPE_OK;
|
||||
t_stat ptp_write (uint32 c)
|
||||
{
|
||||
if (putc (c, ptp_unit.fileref) == EOF) { /* write char */
|
||||
ind[IN_WRCHK] = 1; /* error? */
|
||||
perror ("PTP I/O error");
|
||||
sim_perror ("PTP I/O error");
|
||||
clearerr (ptp_unit.fileref);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
|
||||
@@ -304,6 +304,34 @@ if ((cpu_unit.flags & IF_IDX) && flg) { /* indexing? */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Look up an opcode
|
||||
|
||||
Inputs:
|
||||
op = opcode (decimal)
|
||||
qv = Q value (full 5 digits)
|
||||
Outputs:
|
||||
*opcst = pointer to opcode string
|
||||
(NULL if not found)
|
||||
*fl = opcode flags (optional)
|
||||
*/
|
||||
|
||||
char *opc_lookup (uint32 op, uint32 qv, uint32 *fl)
|
||||
{
|
||||
uint32 i, opfl;
|
||||
|
||||
for (i = 0; opcode[i].str != NULL; i++) { /* find opcode */
|
||||
opfl = opcode[i].opv & 0xFF0000; /* get flags */
|
||||
if ((op == (opcode[i].opv & 0xFF)) && /* op match? */
|
||||
((qv == opcode[i].qv) || /* q match or */
|
||||
((opfl != I_1E) && (opfl != I_0E)))) { /* not needed? */
|
||||
if (fl != NULL)
|
||||
*fl = opfl;
|
||||
return opcode[i].str;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Symbolic decode
|
||||
|
||||
Inputs:
|
||||
@@ -324,6 +352,7 @@ t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,
|
||||
{
|
||||
int32 pmp, qmp, i, c, d, any;
|
||||
uint32 op, qv, opfl;
|
||||
char *opstr;
|
||||
|
||||
if (uptr == NULL)
|
||||
uptr = &cpu_unit;
|
||||
@@ -384,14 +413,9 @@ for (i = qv = pmp = qmp = 0; i < ADDR_LEN; i++) { /* test addr */
|
||||
}
|
||||
if ((val[0] | val[1]) & FLAG) /* flags force */
|
||||
pmp = qmp = 1;
|
||||
for (i = 0; opcode[i].str != NULL; i++) { /* find opcode */
|
||||
opfl = opcode[i].opv & 0xFF0000;
|
||||
if ((op == (opcode[i].opv & 0xFF)) &&
|
||||
((qv == opcode[i].qv) ||
|
||||
((opfl != I_1E) && (opfl != I_0E))))
|
||||
break;
|
||||
}
|
||||
if (opcode[i].str == NULL) { /* invalid opcode */
|
||||
opstr = opc_lookup (op, qv, &opfl); /* find opcode */
|
||||
|
||||
if (opstr == NULL) { /* invalid opcode */
|
||||
if ((sw & SIM_SW_STOP) != 0) { /* stop message? */
|
||||
fprintf (of, "%02d", op); /* print numeric opcode */
|
||||
return -(INST_LEN - 1); /* report success */
|
||||
@@ -401,7 +425,7 @@ if (opcode[i].str == NULL) { /* invalid opcode */
|
||||
if (I_GETQP (opfl) == I_M_QNP) /* Q no print? */
|
||||
qmp = 0;
|
||||
|
||||
fprintf (of, "%-4s", opcode[i].str); /* print opcode */
|
||||
fprintf (of, ((sw & SIM_SW_STOP)? "%s": "%-4s"), opstr);/* print opcode */
|
||||
if (I_GETPP (opfl) == I_M_PP) /* P required? */
|
||||
fprint_addr (of, ' ', &val[I_P], I_M_QX);
|
||||
else if ((I_GETPP (opfl) == I_M_PCP) && (pmp || qmp)) /* P opt & needed? */
|
||||
|
||||
@@ -132,7 +132,7 @@ DEVICE tty_dev = {
|
||||
/* The following constant is a list of valid 1620 numeric characters
|
||||
that can be entered from the keyboard. They are the digits 0-9,
|
||||
record mark(|), numeric blank(@) and group mark(}). All others
|
||||
are cosidered invalid. When entering data, these characters may
|
||||
are considered invalid. When entering data, these characters may
|
||||
all be preceeded by tilde(~) or accent(`) to indicate that the
|
||||
following character should be entered into storage with a flag.
|
||||
|
||||
@@ -281,7 +281,7 @@ switch (op) { /* case on op */
|
||||
case OP_WN:
|
||||
case OP_DN:
|
||||
case OP_WA:
|
||||
cpuio_set_inp (op, &tty_unit[UTTO]); /* set IO in progress */
|
||||
cpuio_set_inp (op, IO_TTY, &tty_unit[UTTO]); /* set IO in progress */
|
||||
break;
|
||||
|
||||
case OP_RN:
|
||||
@@ -289,7 +289,7 @@ switch (op) { /* case on op */
|
||||
tti_unlock = 1; /* unlock keyboard */
|
||||
tti_flag = 0; /* init flag */
|
||||
tto_write ('>'); /* prompt user */
|
||||
cpuio_set_inp (op, NULL); /* set IO in progress */
|
||||
cpuio_set_inp (op, IO_TTY, NULL); /* set IO in progress */
|
||||
break;
|
||||
|
||||
default: /* invalid function */
|
||||
@@ -312,7 +312,7 @@ if ((temp = sim_poll_kbd ()) < SCPE_KFLAG) /* no char or error? */
|
||||
return temp;
|
||||
if (tti_unlock == 0) /* expecting input? */
|
||||
return SCPE_OK; /* no, ignore */
|
||||
raw = (int8) temp;
|
||||
raw = (int8) (temp & 0x7F);
|
||||
|
||||
if (raw == '\r') { /* return? */
|
||||
tto_write (raw); /* echo */
|
||||
|
||||
Reference in New Issue
Block a user