1
0
mirror of https://github.com/simh/simh.git synced 2026-01-25 19:56:25 +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:
Bob Supnik
2005-09-09 18:09:00 -07:00
committed by Mark Pizzolato
parent ec60bbf329
commit b7c1eae41f
257 changed files with 107140 additions and 97195 deletions

View File

@@ -1,6 +1,6 @@
/* s3_cd.c: IBM 1442 card reader/punch
Copyright (c) 2001-2003, Charles E. Owen
Copyright (c) 2001-2005, Charles E. Owen
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -19,16 +19,16 @@
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 Charles E. Owen 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 Charles E. Owen shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Charles E. Owen.
cdr card reader
cdp card punch
cdp2 card punch stacker 2
cdr card reader
cdp card punch
cdp2 card punch stacker 2
25-Apr-03 RMS Revised for extended file support
08-Oct-02 RMS Added impossible function catcher
25-Apr-03 RMS Revised for extended file support
08-Oct-02 RMS Added impossible function catcher
Normally, cards are represented as ASCII text streams terminated by newlines.
This allows cards to be created and edited as normal files. Set the EBCDIC
@@ -43,7 +43,7 @@ extern uint8 M[];
extern char ebcdic_to_ascii[256];
extern char ascii_to_ebcdic[256];
int32 s1sel, s2sel;
char rbuf[CBUFSIZE]; /* > CDR_WIDTH */
char rbuf[CBUFSIZE]; /* > CDR_WIDTH */
t_stat cdr_svc (UNIT *uptr);
t_stat cdr_boot (int32 unitno, DEVICE *dptr);
t_stat cdr_attach (UNIT *uptr, char *cptr);
@@ -51,92 +51,97 @@ t_stat cd_reset (DEVICE *dptr);
t_stat read_card (int32 ilnt, int32 mod);
t_stat punch_card (int32 ilnt, int32 mod);
int32 DAR; /* Data address register */
int32 LCR; /* Length Count Register */
int32 lastcard = 0; /* Last card switch */
int32 carderr = 0; /* Error switch */
int32 pcherror = 0; /* Punch error */
int32 notready = 0; /* Not ready error */
int32 cdr_ebcdic = 0; /* EBCDIC mode on reader */
int32 cdp_ebcdic = 0; /* EBCDIC mode on punch */
int32 DAR; /* Data address register */
int32 LCR; /* Length Count Register */
int32 lastcard = 0; /* Last card switch */
int32 carderr = 0; /* Error switch */
int32 pcherror = 0; /* Punch error */
int32 notready = 0; /* Not ready error */
int32 cdr_ebcdic = 0; /* EBCDIC mode on reader */
int32 cdp_ebcdic = 0; /* EBCDIC mode on punch */
extern int32 GetMem(int32 addr);
extern int32 PutMem(int32 addr, int32 data);
/* Card reader data structures
cdr_dev CDR descriptor
cdr_unit CDR unit descriptor
cdr_reg CDR register list
cdr_dev CDR descriptor
cdr_unit CDR unit descriptor
cdr_reg CDR register list
*/
UNIT cdr_unit = {
UDATA (&cdr_svc, UNIT_SEQ+UNIT_ATTABLE, 0), 100 };
UNIT cdr_unit = { UDATA (&cdr_svc, UNIT_SEQ+UNIT_ATTABLE, 0), 100 };
REG cdr_reg[] = {
{ FLDATA (LAST, lastcard, 0) },
{ FLDATA (ERR, carderr, 0) },
{ FLDATA (NOTRDY, notready, 0) },
{ HRDATA (DAR, DAR, 16) },
{ HRDATA (LCR, LCR, 16) },
{ FLDATA (EBCDIC, cdr_ebcdic, 0) },
{ FLDATA (S2, s2sel, 0) },
{ DRDATA (POS, cdr_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, cdr_unit.wait, 24), PV_LEFT },
{ BRDATA (BUF, rbuf, 8, 8, CDR_WIDTH) },
{ NULL } };
{ FLDATA (LAST, lastcard, 0) },
{ FLDATA (ERR, carderr, 0) },
{ FLDATA (NOTRDY, notready, 0) },
{ HRDATA (DAR, DAR, 16) },
{ HRDATA (LCR, LCR, 16) },
{ FLDATA (EBCDIC, cdr_ebcdic, 0) },
{ FLDATA (S2, s2sel, 0) },
{ DRDATA (POS, cdr_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, cdr_unit.wait, 24), PV_LEFT },
{ BRDATA (BUF, rbuf, 8, 8, CDR_WIDTH) },
{ NULL }
};
DEVICE cdr_dev = {
"CDR", &cdr_unit, cdr_reg, NULL,
1, 10, 31, 1, 8, 7,
NULL, NULL, &cd_reset,
&cdr_boot, &cdr_attach, NULL };
"CDR", &cdr_unit, cdr_reg, NULL,
1, 10, 31, 1, 8, 7,
NULL, NULL, &cd_reset,
&cdr_boot, &cdr_attach, NULL
};
/* CDP data structures
cdp_dev CDP device descriptor
cdp_unit CDP unit descriptor
cdp_reg CDP register list
cdp_dev CDP device descriptor
cdp_unit CDP unit descriptor
cdp_reg CDP register list
*/
UNIT cdp_unit = {
UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) };
UNIT cdp_unit = { UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) };
REG cdp_reg[] = {
{ FLDATA (ERR, pcherror, 0) },
{ FLDATA (EBCDIC, cdp_ebcdic, 0) },
{ FLDATA (S2, s2sel, 0) },
{ FLDATA (NOTRDY, notready, 0) },
{ HRDATA (DAR, DAR, 16) },
{ HRDATA (LCR, LCR, 16) },
{ DRDATA (POS, cdp_unit.pos, T_ADDR_W), PV_LEFT },
{ NULL } };
{ FLDATA (ERR, pcherror, 0) },
{ FLDATA (EBCDIC, cdp_ebcdic, 0) },
{ FLDATA (S2, s2sel, 0) },
{ FLDATA (NOTRDY, notready, 0) },
{ HRDATA (DAR, DAR, 16) },
{ HRDATA (LCR, LCR, 16) },
{ DRDATA (POS, cdp_unit.pos, T_ADDR_W), PV_LEFT },
{ NULL }
};
DEVICE cdp_dev = {
"CDP", &cdp_unit, cdp_reg, NULL,
1, 10, 31, 1, 8, 7,
NULL, NULL, &cd_reset,
NULL, NULL, NULL };
"CDP", &cdp_unit, cdp_reg, NULL,
1, 10, 31, 1, 8, 7,
NULL, NULL, &cd_reset,
NULL, NULL, NULL
};
/* Stacker data structures
stack_dev STACK device descriptor
stack_unit STACK unit descriptors
stack_reg STACK register list
stack_dev STACK device descriptor
stack_unit STACK unit descriptors
stack_reg STACK register list
*/
UNIT stack_unit[] = {
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) } };
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) }
};
REG stack_reg[] = {
{ DRDATA (POS0, stack_unit[0].pos, 32), PV_LEFT },
{ NULL } };
{ DRDATA (POS0, stack_unit[0].pos, 32), PV_LEFT },
{ NULL }
};
DEVICE stack_dev = {
"CDP2", stack_unit, stack_reg, NULL,
1, 10, 31, 1, 8, 7,
NULL, NULL, &cd_reset,
NULL, NULL, NULL };
"CDP2", stack_unit, stack_reg, NULL,
1, 10, 31, 1, 8, 7,
NULL, NULL, &cd_reset,
NULL, NULL, NULL
};
/* -------------------------------------------------------------------- */
@@ -145,126 +150,126 @@ DEVICE stack_dev = {
int32 crd (int32 op, int32 m, int32 n, int32 data)
{
int32 iodata;
switch (op) {
case 0: /* SIO 1442 */
/* if (n == 1)
return STOP_IBKPT; */
switch (data) { /* Select stacker */
case 0x00:
break;
case 0x01:
s2sel = 1;
break;
default:
break;
}
switch (n) {
case 0x00: /* Feed */
iodata = SCPE_OK;
break;
case 0x01: /* Read only */
if (cdr_ebcdic)
iodata = read_card(0, 1);
else
iodata = read_card(0, 0);
break;
case 0x02: /* Punch and feed */
iodata = punch_card(0, 0);
break;
case 0x03: /* Read Col Binary */
iodata = read_card(0, 1);
break;
case 0x04: /* Punch no feed */
iodata = punch_card(0, 1);
break;
default:
return STOP_INVDEV;
}
return iodata;
case 1: /* LIO 1442 */
switch (n) {
case 0x00: /* Load LCR */
LCR = data & 0xffff;
break;
case 0x04:
DAR = data & 0xffff;
break;
default:
return STOP_INVDEV;
}
return SCPE_OK;
case 2: /* TIO 1442 */
iodata = 0;
switch (n) {
case 0x00: /* Error */
if (carderr || pcherror || notready)
iodata = 1;
if ((cdr_unit.flags & UNIT_ATT) == 0)
iodata = 1; /* attached? */
break;
case 0x02: /* Busy */
if (sim_is_active (&cdr_unit))
iodata = 1;
break;
default:
return (STOP_INVDEV << 16);
}
return ((SCPE_OK << 16) | iodata);
case 3: /* SNS 1442 */
iodata = 0;
switch (n) {
case 0x01:
break;
case 0x02:
break;
case 0x03:
if (carderr)
iodata |= 0x80;
if (lastcard)
iodata |= 0x40;
if (pcherror)
iodata |= 0x20;
if ((cdr_unit.flags & UNIT_ATT) == 0)
iodata |= 0x08;
if (notready)
iodata |= 0x08;
break;
case 0x04:
iodata = DAR;
break;
default:
return (STOP_INVDEV << 16);
}
iodata |= ((SCPE_OK << 16) & 0xffff0000);
return (iodata);
case 4: /* APL 1442 */
iodata = 0;
switch (n) {
case 0x00: /* Error */
if (carderr || pcherror || notready)
iodata = 1;
if ((cdr_unit.flags & UNIT_ATT) == 0)
iodata = 1; /* attached? */
break;
case 0x02: /* Busy */
if (sim_is_active (&cdr_unit))
iodata = 1;
break;
default:
return (STOP_INVDEV << 16);
}
return ((SCPE_OK << 16) | iodata);
default:
break;
}
printf (">>CRD non-existent function %d\n", op);
return SCPE_OK;
int32 iodata;
switch (op) {
case 0: /* SIO 1442 */
/* if (n == 1)
return STOP_IBKPT; */
switch (data) { /* Select stacker */
case 0x00:
break;
case 0x01:
s2sel = 1;
break;
default:
break;
}
switch (n) {
case 0x00: /* Feed */
iodata = SCPE_OK;
break;
case 0x01: /* Read only */
if (cdr_ebcdic)
iodata = read_card(0, 1);
else
iodata = read_card(0, 0);
break;
case 0x02: /* Punch and feed */
iodata = punch_card(0, 0);
break;
case 0x03: /* Read Col Binary */
iodata = read_card(0, 1);
break;
case 0x04: /* Punch no feed */
iodata = punch_card(0, 1);
break;
default:
return STOP_INVDEV;
}
return iodata;
case 1: /* LIO 1442 */
switch (n) {
case 0x00: /* Load LCR */
LCR = data & 0xffff;
break;
case 0x04:
DAR = data & 0xffff;
break;
default:
return STOP_INVDEV;
}
return SCPE_OK;
case 2: /* TIO 1442 */
iodata = 0;
switch (n) {
case 0x00: /* Error */
if (carderr || pcherror || notready)
iodata = 1;
if ((cdr_unit.flags & UNIT_ATT) == 0)
iodata = 1; /* attached? */
break;
case 0x02: /* Busy */
if (sim_is_active (&cdr_unit))
iodata = 1;
break;
default:
return (STOP_INVDEV << 16);
}
return ((SCPE_OK << 16) | iodata);
case 3: /* SNS 1442 */
iodata = 0;
switch (n) {
case 0x01:
break;
case 0x02:
break;
case 0x03:
if (carderr)
iodata |= 0x80;
if (lastcard)
iodata |= 0x40;
if (pcherror)
iodata |= 0x20;
if ((cdr_unit.flags & UNIT_ATT) == 0)
iodata |= 0x08;
if (notready)
iodata |= 0x08;
break;
case 0x04:
iodata = DAR;
break;
default:
return (STOP_INVDEV << 16);
}
iodata |= ((SCPE_OK << 16) & 0xffff0000);
return (iodata);
case 4: /* APL 1442 */
iodata = 0;
switch (n) {
case 0x00: /* Error */
if (carderr || pcherror || notready)
iodata = 1;
if ((cdr_unit.flags & UNIT_ATT) == 0)
iodata = 1; /* attached? */
break;
case 0x02: /* Busy */
if (sim_is_active (&cdr_unit))
iodata = 1;
break;
default:
return (STOP_INVDEV << 16);
}
return ((SCPE_OK << 16) | iodata);
default:
break;
}
printf (">>CRD non-existent function %d\n", op);
return SCPE_OK;
}
/* Card read routine
mod 0 = ASCII read
mod 1 = EBCDIC read
mod 0 = ASCII read
mod 1 = EBCDIC read
*/
t_stat read_card (int32 ilnt, int32 mod)
@@ -272,59 +277,59 @@ t_stat read_card (int32 ilnt, int32 mod)
int32 i;
t_stat r;
if (sim_is_active (&cdr_unit)) { /* busy? */
sim_cancel (&cdr_unit); /* cancel */
if (r = cdr_svc (&cdr_unit)) return r; /* process */
}
if (sim_is_active (&cdr_unit)) { /* busy? */
sim_cancel (&cdr_unit); /* cancel */
if (r = cdr_svc (&cdr_unit)) return r; /* process */
}
if (((cdp_unit.flags & UNIT_ATT) != 0 ||
(stack_unit[0].flags & UNIT_ATT) != 0) && /* Punch is attached and */
(cdr_unit.flags & UNIT_ATT) == 0) { /* reader is not --- */
for (i = 0; i < 80; i++) { /* Assume blank cards in hopper */
PutMem(DAR, 0x40);
DAR++;
}
sim_activate (&cdr_unit, cdr_unit.wait); /* activate */
return SCPE_OK;
(stack_unit[0].flags & UNIT_ATT) != 0) && /* Punch is attached and */
(cdr_unit.flags & UNIT_ATT) == 0) { /* reader is not --- */
for (i = 0; i < 80; i++) { /* Assume blank cards in hopper */
PutMem(DAR, 0x40);
DAR++;
}
sim_activate (&cdr_unit, cdr_unit.wait); /* activate */
return SCPE_OK;
}
if ((cdr_unit.flags & UNIT_ATT) == 0) return SCPE_UNATT; /* attached? */
lastcard = carderr = notready = s1sel = s2sel = 0; /* default stacker */
lastcard = carderr = notready = s1sel = s2sel = 0; /* default stacker */
for (i = 0; i < CBUFSIZE; i++) rbuf[i] = 0x20; /* clear buffer */
for (i = 0; i < CBUFSIZE; i++) rbuf[i] = 0x20; /* clear buffer */
if (mod) {
for (i = 0; i < 80; i++) {
rbuf[i] = fgetc(cdr_unit.fileref); /* Read EBCDIC */
}
} else {
fgets (rbuf, CBUFSIZE, cdr_unit.fileref); /* read Ascii */
}
if (feof (cdr_unit.fileref)) { /* eof? */
notready = 1;
return STOP_NOCD;
}
if (ferror (cdr_unit.fileref)) { /* error? */
perror ("Card reader I/O error");
clearerr (cdr_unit.fileref);
carderr = 1;
return SCPE_OK; }
cdr_unit.pos = ftell (cdr_unit.fileref); /* update position */
i = getc (cdr_unit.fileref); /* see if more */
if (feof (cdr_unit.fileref)) lastcard = 1; /* eof? set flag */
for (i = 0; i < 80; i++) {
rbuf[i] = fgetc(cdr_unit.fileref); /* Read EBCDIC */
}
} else {
fgets (rbuf, CBUFSIZE, cdr_unit.fileref); /* read Ascii */
}
if (feof (cdr_unit.fileref)) { /* eof? */
notready = 1;
return STOP_NOCD;
}
if (ferror (cdr_unit.fileref)) { /* error? */
perror ("Card reader I/O error");
clearerr (cdr_unit.fileref);
carderr = 1;
return SCPE_OK; }
cdr_unit.pos = ftell (cdr_unit.fileref); /* update position */
i = getc (cdr_unit.fileref); /* see if more */
if (feof (cdr_unit.fileref)) lastcard = 1; /* eof? set flag */
fseek (cdr_unit.fileref, cdr_unit.pos, SEEK_SET);
for (i = 0; i < 80; i++) {
if (mod == 0) { /* If ASCII mode... */
if (rbuf[i] == '\n' || /* remove ASCII CR/LF */
rbuf[i] == '\r' ||
rbuf[i] == 0x00)
rbuf[i] = ' ';
rbuf[i] = ascii_to_ebcdic[rbuf[i]]; /* convert to EBCDIC */
}
PutMem(DAR, rbuf[i]); /* Copy to main memory */
DAR++;
for (i = 0; i < 80; i++) {
if (mod == 0) { /* If ASCII mode... */
if (rbuf[i] == '\n' || /* remove ASCII CR/LF */
rbuf[i] == '\r' ||
rbuf[i] == 0x00)
rbuf[i] = ' ';
rbuf[i] = ascii_to_ebcdic[rbuf[i]]; /* convert to EBCDIC */
}
PutMem(DAR, rbuf[i]); /* Copy to main memory */
DAR++;
}
sim_activate (&cdr_unit, cdr_unit.wait); /* activate */
sim_activate (&cdr_unit, cdr_unit.wait); /* activate */
return SCPE_OK;
}
@@ -337,22 +342,22 @@ t_stat cdr_svc (UNIT *uptr)
{
int32 i;
if (s2sel) uptr = &stack_unit[0]; /* stacker 1? */
else uptr = &stack_unit[0]; /* then default */
if ((uptr -> flags & UNIT_ATT) == 0) return SCPE_OK; /* attached? */
if (s2sel) uptr = &stack_unit[0]; /* stacker 1? */
else uptr = &stack_unit[0]; /* then default */
if ((uptr -> flags & UNIT_ATT) == 0) return SCPE_OK; /* attached? */
for (i = 0; i < CDR_WIDTH; i++) rbuf[i] = ebcdic_to_ascii[rbuf[i]];
for (i = CDR_WIDTH - 1; (i >= 0) && (rbuf[i] == ' '); i--) rbuf[i] = 0;
rbuf[CDR_WIDTH] = 0; /* null at end */
fputs (rbuf, uptr -> fileref); /* write card */
fputc ('\n', uptr -> fileref); /* plus new line */
if (ferror (uptr -> fileref)) { /* error? */
perror ("Card stacker I/O error");
clearerr (uptr -> fileref);
rbuf[CDR_WIDTH] = 0; /* null at end */
fputs (rbuf, uptr -> fileref); /* write card */
fputc ('\n', uptr -> fileref); /* plus new line */
if (ferror (uptr -> fileref)) { /* error? */
perror ("Card stacker I/O error");
clearerr (uptr -> fileref);
}
uptr -> pos = ftell (uptr -> fileref); /* update position */
uptr -> pos = ftell (uptr -> fileref); /* update position */
return SCPE_OK;
}
/* Card punch routine
mod: not used
@@ -361,44 +366,44 @@ return SCPE_OK;
t_stat punch_card (int32 ilnt, int32 mod)
{
int32 i, colcount;
static char pbuf[CDP_WIDTH + 1]; /* + null */
static char pbuf[CDP_WIDTH + 1]; /* + null */
UNIT *uptr;
if (s2sel) uptr = &stack_unit[0]; /* stack 2? */
else uptr = &cdp_unit; /* normal output */
if ((uptr -> flags & UNIT_ATT) == 0) { /* Attached? */
notready = 1;
return SCPE_OK;
if (s2sel) uptr = &stack_unit[0]; /* stack 2? */
else uptr = &cdp_unit; /* normal output */
if ((uptr -> flags & UNIT_ATT) == 0) { /* Attached? */
notready = 1;
return SCPE_OK;
}
pcherror = s1sel = notready = 0; /* clear flags */
pcherror = s1sel = notready = 0; /* clear flags */
colcount = 128 - LCR;
for (i = 0; i < colcount; i++) { /* Fetch data */
if (cdp_ebcdic)
pbuf[i] = GetMem(DAR) & 0xff;
else
pbuf[i] = ebcdic_to_ascii[GetMem(DAR)];
DAR++;
}
for (i = 0; i < colcount; i++) { /* Fetch data */
if (cdp_ebcdic)
pbuf[i] = GetMem(DAR) & 0xff;
else
pbuf[i] = ebcdic_to_ascii[GetMem(DAR)];
DAR++;
}
for (i = CDP_WIDTH - 1; (i >= 0) && (pbuf[i] == ' '); i--) pbuf[i] = 0;
pbuf[CDP_WIDTH] = 0; /* trailing null */
pbuf[CDP_WIDTH] = 0; /* trailing null */
if (!cdp_ebcdic) {
fputs (pbuf, uptr -> fileref); /* output card */
fputc ('\n', uptr -> fileref); /* plus new line */
fputs (pbuf, uptr -> fileref); /* output card */
fputc ('\n', uptr -> fileref); /* plus new line */
} else {
for (i = 0; i < 80; i++) {
fputc(pbuf[i], uptr -> fileref);
}
}
if (ferror (uptr -> fileref)) { /* error? */
perror ("Card punch I/O error");
clearerr (uptr -> fileref);
pcherror = 1;
for (i = 0; i < 80; i++) {
fputc(pbuf[i], uptr -> fileref);
}
}
if (ferror (uptr -> fileref)) { /* error? */
perror ("Card punch I/O error");
clearerr (uptr -> fileref);
pcherror = 1;
}
uptr -> pos = ftell (uptr -> fileref); /* update position */
uptr -> pos = ftell (uptr -> fileref); /* update position */
return SCPE_OK;
}
/* Select stack routine
Modifiers have been checked by the caller
@@ -416,9 +421,9 @@ return SCPE_OK;
t_stat cd_reset (DEVICE *dptr)
{
lastcard = carderr = notready = pcherror = 0; /* clear indicators */
s1sel = s2sel = 0; /* clear stacker sel */
sim_cancel (&cdr_unit); /* clear reader event */
lastcard = carderr = notready = pcherror = 0; /* clear indicators */
s1sel = s2sel = 0; /* clear stacker sel */
sim_cancel (&cdr_unit); /* clear reader event */
return SCPE_OK;
}
@@ -426,7 +431,7 @@ return SCPE_OK;
t_stat cdr_attach (UNIT *uptr, char *cptr)
{
carderr = lastcard = notready = 0; /* clear last card */
carderr = lastcard = notready = 0; /* clear last card */
return attach_unit (uptr, cptr);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/* s3_defs.h: IBM System/3 simulator definitions
Copyright (c) 2001-2003, Charles E. Owen
Copyright (c) 2001-2005, Charles E. Owen
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -19,76 +19,76 @@
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 Charles E. Owen 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 Charles E. Owen shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Charles E. Owen.
*/
#include "sim_defs.h" /* simulator defns */
#include "sim_defs.h" /* simulator defns */
/* Simulator stop codes */
#define STOP_RSRV 1 /* must be 1 */
#define STOP_HALT 2 /* HALT */
#define STOP_IBKPT 3 /* breakpoint */
#define STOP_INVOP 4 /* program check - invalid op */
#define STOP_INVQ 5 /* Prog check - invalid Q */
#define STOP_INVADDR 6 /* Prog check - invalid addr */
#define STOP_INVDEV 7 /* Prog check - invalid dev cmd */
#define STOP_NOCD 8 /* ATTN card reader */
#define RESET_INTERRUPT 77 /* special return from SIO */
#define STOP_RSRV 1 /* must be 1 */
#define STOP_HALT 2 /* HALT */
#define STOP_IBKPT 3 /* breakpoint */
#define STOP_INVOP 4 /* program check - invalid op */
#define STOP_INVQ 5 /* Prog check - invalid Q */
#define STOP_INVADDR 6 /* Prog check - invalid addr */
#define STOP_INVDEV 7 /* Prog check - invalid dev cmd */
#define STOP_NOCD 8 /* ATTN card reader */
#define RESET_INTERRUPT 77 /* special return from SIO */
/* Memory */
#define MAXMEMSIZE 65536 /* max memory size */
#define AMASK (MAXMEMSIZE - 1) /* logical addr mask */
#define PAMASK (MAXMEMSIZE - 1) /* physical addr mask */
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
#define MAXMEMSIZE 65536 /* max memory size */
#define AMASK (MAXMEMSIZE - 1) /* logical addr mask */
#define PAMASK (MAXMEMSIZE - 1) /* physical addr mask */
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
#define MAX_DECIMAL_DIGITS 31 /* max size of a decimal number */
#define CDR_WIDTH 80 /* Max card size */
#define CDP_WIDTH 80 /* Punch width */
#define LPT_WIDTH 132
#define CCT_LNT 132
#define MAX_DECIMAL_DIGITS 31 /* max size of a decimal number */
#define CDR_WIDTH 80 /* Max card size */
#define CDP_WIDTH 80 /* Punch width */
#define LPT_WIDTH 132
#define CCT_LNT 132
#define DSK_SECTSIZE 256 /* Sector length */
#define DSK_CYLSIZE 256*48 /* Cylinder length */
#define DSK_SECTSIZE 256 /* Sector length */
#define DSK_CYLSIZE 256*48 /* Cylinder length */
/* I/O structure
The I/O structure is tied together by dev_table, indexed by
the device number. Each entry in dev_table consists of
level Interrupt level for device (0-7)
priority Priority for device (1-8)
routine IOT action routine
level Interrupt level for device (0-7)
priority Priority for device (1-8)
routine IOT action routine
*/
struct ndev {
int32 level; /* interrupt level */
int32 pri; /* Device priority */
int32 (*routine)(); /* dispatch routine */
int32 level; /* interrupt level */
int32 pri; /* Device priority */
int32 (*routine)(); /* dispatch routine */
};
/* Structure to define operation codes */
struct opdef {
char op[6]; /* Mnemonic for op */
int32 opmask; /* Bits set on in opcode */
int32 q; /* Qbyte */
int32 form; /* Forms are:
0 - 1-byte hex operand
1 - 1-byte register addr, A-Addr
2 - A-addr,B-addr,Qbyte
3 - A-addr,Qbyte
4 - da,m,n
5 - da,m,n,cc
6 - da,m,n,A-addr
7 - 1-address implict Q
8 - 2-address implict Q */
int32 group; /* Group Code:
0 - Command Format (0xFx)
1 - 1-address A (0x<C,D,E>x)
2 - 2-address (0x<0,1,2,4,5,6,8,9,A>x)
3 - 1-address B (0x<3,7,B>x) */
char op[6]; /* Mnemonic for op */
int32 opmask; /* Bits set on in opcode */
int32 q; /* Qbyte */
int32 form; /* Forms are:
0 - 1-byte hex operand
1 - 1-byte register addr, A-Addr
2 - A-addr,B-addr,Qbyte
3 - A-addr,Qbyte
4 - da,m,n
5 - da,m,n,cc
6 - da,m,n,A-addr
7 - 1-address implict Q
8 - 2-address implict Q */
int32 group; /* Group Code:
0 - Command Format (0xFx)
1 - 1-address A (0x<C,D,E>x)
2 - 2-address (0x<0,1,2,4,5,6,8,9,A>x)
3 - 1-address B (0x<3,7,B>x) */
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/* s3_lp.c: IBM 1403 line printer simulator
Copyright (c) 2001-2003, Charles E. Owen
Copyright (c) 2001-2005, Charles E. Owen
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -19,14 +19,14 @@
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 Charles E. Owen 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 Charles E. Owen shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Charles E. Owen.
lpt 1403 line printer
lpt 1403 line printer
25-Apr-03 RMS Revised for extended file support
08-Oct-02 RMS Added impossible function catcher
25-Apr-03 RMS Revised for extended file support
08-Oct-02 RMS Added impossible function catcher
*/
#include "s3_defs.h"
@@ -43,63 +43,65 @@ t_stat space (int32 lines, int32 lflag);
t_stat carriage_control (int32 action, int32 mod);
extern unsigned char ebcdic_to_ascii[256];
#define UNIT_V_PCHAIN (UNIT_V_UF + 0)
#define UNIT_M_PCHAIN 03
#define M_UCS 00 /* Universal */
#define M_PCF 00 /* full */
#define M_PCA 01 /* business */
#define M_PCH 02 /* Fortran */
#define UNIT_PCHAIN (UNIT_M_PCHAIN << UNIT_V_PCHAIN)
#define UCS (M_UCS << UNIT_V_PCHAIN)
#define PCF (M_PCF << UNIT_V_PCHAIN)
#define PCA (M_PCA << UNIT_V_PCHAIN)
#define PCH (M_PCH << UNIT_V_PCHAIN)
#define GET_PCHAIN(x) (((x) >> UNIT_V_PCHAIN) & UNIT_M_PCHAIN)
#define CHP(ch,val) ((val) & (1 << (ch)))
#define UNIT_V_PCHAIN (UNIT_V_UF + 0)
#define UNIT_M_PCHAIN 03
#define M_UCS 00 /* Universal */
#define M_PCF 00 /* full */
#define M_PCA 01 /* business */
#define M_PCH 02 /* Fortran */
#define UNIT_PCHAIN (UNIT_M_PCHAIN << UNIT_V_PCHAIN)
#define UCS (M_UCS << UNIT_V_PCHAIN)
#define PCF (M_PCF << UNIT_V_PCHAIN)
#define PCA (M_PCA << UNIT_V_PCHAIN)
#define PCH (M_PCH << UNIT_V_PCHAIN)
#define GET_PCHAIN(x) (((x) >> UNIT_V_PCHAIN) & UNIT_M_PCHAIN)
#define CHP(ch,val) ((val) & (1 << (ch)))
int32 LPDAR; /* Data Address */
int32 LPFLR; /* Forms Length */
int32 LPIAR; /* Image address */
int32 linectr; /* current line # */
int32 LPDAR; /* Data Address */
int32 LPFLR; /* Forms Length */
int32 LPIAR; /* Image address */
int32 linectr; /* current line # */
int32 lpterror = 0;
int32 CC9 = 0;
int32 CC12 = 0;
/* LPT data structures
lpt_dev LPT device descriptor
lpt_unit LPT unit descriptor
lpt_reg LPT register list
lpt_dev LPT device descriptor
lpt_unit LPT unit descriptor
lpt_reg LPT register list
*/
UNIT lpt_unit = {
UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) };
UNIT lpt_unit = { UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) };
REG lpt_reg[] = {
{ FLDATA (ERR, lpterror, 0) },
{ HRDATA (LPDAR, LPDAR, 16) },
{ HRDATA (LPFLR, LPFLR, 8) },
{ HRDATA (LPIAR, LPIAR, 16) },
{ DRDATA (LINECT, linectr, 8) },
{ DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT },
{ BRDATA (CCT, cct, 8, 32, CCT_LNT) },
{ DRDATA (LINES, lines, 8), PV_LEFT },
{ DRDATA (CCTP, cctptr, 8), PV_LEFT },
{ DRDATA (CCTL, cctlnt, 8), REG_RO + PV_LEFT },
{ GRDATA (CHAIN, lpt_unit.flags, 10, 2, UNIT_V_PCHAIN), REG_HRO },
{ NULL } };
{ FLDATA (ERR, lpterror, 0) },
{ HRDATA (LPDAR, LPDAR, 16) },
{ HRDATA (LPFLR, LPFLR, 8) },
{ HRDATA (LPIAR, LPIAR, 16) },
{ DRDATA (LINECT, linectr, 8) },
{ DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT },
{ BRDATA (CCT, cct, 8, 32, CCT_LNT) },
{ DRDATA (LINES, lines, 8), PV_LEFT },
{ DRDATA (CCTP, cctptr, 8), PV_LEFT },
{ DRDATA (CCTL, cctlnt, 8), REG_RO + PV_LEFT },
{ GRDATA (CHAIN, lpt_unit.flags, 10, 2, UNIT_V_PCHAIN), REG_HRO },
{ NULL }
};
MTAB lpt_mod[] = {
{ UNIT_PCHAIN, UCS, "UCS", "UCS", NULL },
{ UNIT_PCHAIN, PCA, "A chain", "PCA", NULL },
{ UNIT_PCHAIN, PCH, "H chain", "PCH", NULL },
{ 0 } };
{ UNIT_PCHAIN, UCS, "UCS", "UCS", NULL },
{ UNIT_PCHAIN, PCA, "A chain", "PCA", NULL },
{ UNIT_PCHAIN, PCH, "H chain", "PCH", NULL },
{ 0 }
};
DEVICE lpt_dev = {
"LPT", &lpt_unit, lpt_reg, lpt_mod,
1, 10, 31, 1, 8, 7,
NULL, NULL, &lpt_reset,
NULL, NULL, NULL };
"LPT", &lpt_unit, lpt_reg, lpt_mod,
1, 10, 31, 1, 8, 7,
NULL, NULL, &lpt_reset,
NULL, NULL, NULL
};
/* -------------------------------------------------------------------- */
@@ -108,148 +110,151 @@ DEVICE lpt_dev = {
int32 lpt (int32 op, int32 m, int32 n, int32 data)
{
int32 iodata;
switch (op) {
case 0: /* SIO 1403 */
iodata = 0;
printf("\0");
switch (n) {
case 0x00: /* Spacing only */
if (data > 0 && data < 4)
iodata = carriage_control(2, data);
break;
case 0x02: /* Print & space */
iodata = write_line(0, 0);
if (data > 3) data = 0;
if (iodata == SCPE_OK)
iodata = carriage_control(2, data);
break;
case 0x04: /* Skip only */
iodata = carriage_control(4, data);
break;
case 0x06: /* Print and skip */
iodata = write_line(0, 0);
if (iodata == SCPE_OK)
iodata = carriage_control(4, data);
break;
default:
return STOP_INVDEV;
}
return iodata;
case 1: /* LIO 1403 */
switch (n) {
case 0x00: /* LPFLR */
LPFLR = (data >> 8) & 0xff;
break;
case 0x04:
LPIAR = data & 0xffff;
break;
case 0x06:
LPDAR = data & 0xffff;
break;
default:
return STOP_INVDEV;
}
return SCPE_OK;
case 2: /* TIO 1403 */
iodata = 0;
switch (n) {
case 0x00: /* Not ready/check */
if (lpterror)
iodata = 1;
if ((lpt_unit.flags & UNIT_ATT) == 0)
iodata = 1;
break;
case 0x02: /* Buffer Busy */
iodata = 0;
break;
case 0x04: /* Carriage Busy */
iodata = 0;
break;
case 0x06: /* Printer busy */
iodata = 0;
break;
default:
return (STOP_INVDEV << 16);
}
return ((SCPE_OK << 16) | iodata);
case 3: /* SNS 1403 */
switch (n) {
case 0x00: /* Line count */
iodata = (linectr << 8);
break;
case 0x02: /* Timing data */
iodata = 0;
break;
case 0x03: /* Check data */
iodata = 0;
break;
case 0x04: /* LPIAR */
iodata = LPIAR;
break;
case 0x06: /* LPDAR */
iodata = LPDAR;
break;
default:
return (STOP_INVDEV << 16);
}
return ((SCPE_OK << 16) | iodata);
case 4: /* APL 1403 */
iodata = 0;
return ((SCPE_OK << 16) | iodata);
default:
break;
}
printf (">>LPT non-existent function %d\n", op);
return SCPE_OK;
int32 iodata;
switch (op) {
case 0: /* SIO 1403 */
iodata = 0;
printf("\0");
switch (n) {
case 0x00: /* Spacing only */
if (data > 0 && data < 4)
iodata = carriage_control(2, data);
break;
case 0x02: /* Print & space */
iodata = write_line(0, 0);
if (data > 3) data = 0;
if (iodata == SCPE_OK)
iodata = carriage_control(2, data);
break;
case 0x04: /* Skip only */
iodata = carriage_control(4, data);
break;
case 0x06: /* Print and skip */
iodata = write_line(0, 0);
if (iodata == SCPE_OK)
iodata = carriage_control(4, data);
break;
default:
return STOP_INVDEV;
}
return iodata;
case 1: /* LIO 1403 */
switch (n) {
case 0x00: /* LPFLR */
LPFLR = (data >> 8) & 0xff;
break;
case 0x04:
LPIAR = data & 0xffff;
break;
case 0x06:
LPDAR = data & 0xffff;
break;
default:
return STOP_INVDEV;
}
return SCPE_OK;
case 2: /* TIO 1403 */
iodata = 0;
switch (n) {
case 0x00: /* Not ready/check */
if (lpterror)
iodata = 1;
if ((lpt_unit.flags & UNIT_ATT) == 0)
iodata = 1;
break;
case 0x02: /* Buffer Busy */
iodata = 0;
break;
case 0x04: /* Carriage Busy */
iodata = 0;
break;
case 0x06: /* Printer busy */
iodata = 0;
break;
default:
return (STOP_INVDEV << 16);
}
return ((SCPE_OK << 16) | iodata);
case 3: /* SNS 1403 */
switch (n) {
case 0x00: /* Line count */
iodata = (linectr << 8);
break;
case 0x02: /* Timing data */
iodata = 0;
break;
case 0x03: /* Check data */
iodata = 0;
break;
case 0x04: /* LPIAR */
iodata = LPIAR;
break;
case 0x06: /* LPDAR */
iodata = LPDAR;
break;
default:
return (STOP_INVDEV << 16);
}
return ((SCPE_OK << 16) | iodata);
case 4: /* APL 1403 */
iodata = 0;
return ((SCPE_OK << 16) | iodata);
default:
break;
}
printf (">>LPT non-existent function %d\n", op);
return SCPE_OK;
}
/* Print routine
Modifiers have been checked by the caller
S = suppress automatic newline
S = suppress automatic newline
*/
t_stat write_line (int32 ilnt, int32 mod)
{
int32 i, t, lc;
static char lbuf[LPT_WIDTH + 1]; /* + null */
static char lbuf[LPT_WIDTH + 1]; /* + null */
if ((lpt_unit.flags & UNIT_ATT) == 0)
return SCPE_UNATT;
return SCPE_UNATT;
lpterror = 0;
lc = LPDAR; /* clear error */
for (i = 0; i < LPT_WIDTH; i++) { /* convert print buf */
t = M[lc];
lbuf[i] = ebcdic_to_ascii[t & 0xff];
M[lc] = 0x40; /* HJS MOD */
lc++;
lc = LPDAR; /* clear error */
for (i = 0; i < LPT_WIDTH; i++) { /* convert print buf */
t = M[lc];
lbuf[i] = ebcdic_to_ascii[t & 0xff];
M[lc] = 0x40; /* HJS MOD */
lc++;
}
for (i = LPT_WIDTH - 1; (i >= 0) && (lbuf[i] == ' '); i--) lbuf[i] = 0;
fputs (lbuf, lpt_unit.fileref); /* write line */
if (lines) space (lines, lflag); /* cc action? do it */
else if (mod == 0) space (1, FALSE); /* default? 1 line */
else { fputc ('\r', lpt_unit.fileref); /* sup -> overprint */
lpt_unit.pos = ftell (lpt_unit.fileref); } /* update position */
lines = lflag = 0; /* clear cc action */
if (ferror (lpt_unit.fileref)) { /* error? */
perror ("Line printer I/O error");
clearerr (lpt_unit.fileref);
lpterror = 1; }
fputs (lbuf, lpt_unit.fileref); /* write line */
if (lines) space (lines, lflag); /* cc action? do it */
else if (mod == 0) space (1, FALSE); /* default? 1 line */
else {
fputc ('\r', lpt_unit.fileref); /* sup -> overprint */
lpt_unit.pos = ftell (lpt_unit.fileref); /* update position */
}
lines = lflag = 0; /* clear cc action */
if (ferror (lpt_unit.fileref)) { /* error? */
perror ("Line printer I/O error");
clearerr (lpt_unit.fileref);
lpterror = 1;
}
return SCPE_OK;
}
/* Carriage control routine
Parameters:
action = 00, skip to channel now
= 01, space lines after
= 02, space lines now
= 03, skip to channel after
= 04, skip to line number
mod = number of lines or channel number or line number
action = 00, skip to channel now
= 01, space lines after
= 02, space lines now
= 03, skip to channel after
= 04, skip to line number
mod = number of lines or channel number or line number
*/
t_stat carriage_control (int32 action, int32 mod)
@@ -257,58 +262,62 @@ t_stat carriage_control (int32 action, int32 mod)
int32 i;
if ((lpt_unit.flags & UNIT_ATT) == 0)
return SCPE_UNATT;
return SCPE_UNATT;
switch (action) {
case 0: /* to channel now */
if ((mod == 0) || (mod > 12) || CHP (mod, cct[cctptr])) return SCPE_OK;
for (i = 1; i < cctlnt + 1; i++) { /* sweep thru cct */
if (CHP (mod, cct[(cctptr + i) % cctlnt]))
return space (i, TRUE); }
return STOP_INVDEV; /* runaway channel */
case 1: /* space after */
if (mod <= 3) {
lines = mod; /* save # lines */
lflag = FALSE; /* flag spacing */
CC9 = CC12 = 0; }
return SCPE_OK;
case 2: /* space now */
if (mod <= 3) return space (mod, FALSE);
return SCPE_OK;
case 3: /* to channel after */
if ((mod == 0) || (mod > 12)) return SCPE_OK; /* check channel */
CC9 = CC12 = 0;
for (i = 1; i < cctlnt + 1; i++) { /* sweep thru cct */
if (CHP (mod, cct[(cctptr + i) % cctlnt])) {
lines = i; /* save # lines */
lflag = TRUE; /* flag skipping */
return SCPE_OK; }
return STOP_INVDEV;
case 4: /* To line # */
if (mod < 2) {
fputs ("\n\f", lpt_unit.fileref); /* nl, ff */
linectr = 1;
} else {
if (mod <= linectr) {
fputs ("\n\f", lpt_unit.fileref);
linectr = 1;
}
while (1) {
if (linectr == mod)
break;
space(1, 0);
}
}
return SCPE_OK; }
}
case 0: /* to channel now */
if ((mod == 0) || (mod > 12) || CHP (mod, cct[cctptr])) return SCPE_OK;
for (i = 1; i < cctlnt + 1; i++) { /* sweep thru cct */
if (CHP (mod, cct[(cctptr + i) % cctlnt]))
return space (i, TRUE);
}
return STOP_INVDEV; /* runaway channel */
case 1: /* space after */
if (mod <= 3) {
lines = mod; /* save # lines */
lflag = FALSE; /* flag spacing */
CC9 = CC12 = 0;
}
return SCPE_OK;
case 2: /* space now */
if (mod <= 3) return space (mod, FALSE);
return SCPE_OK;
case 3: /* to channel after */
if ((mod == 0) || (mod > 12)) return SCPE_OK; /* check channel */
CC9 = CC12 = 0;
for (i = 1; i < cctlnt + 1; i++) { /* sweep thru cct */
if (CHP (mod, cct[(cctptr + i) % cctlnt])) {
lines = i; /* save # lines */
lflag = TRUE; /* flag skipping */
return SCPE_OK;
}
}
return STOP_INVDEV;
case 4: /* To line # */
if (mod < 2) {
fputs ("\n\f", lpt_unit.fileref); /* nl, ff */
linectr = 1;
} else {
if (mod <= linectr) {
fputs ("\n\f", lpt_unit.fileref);
linectr = 1;
}
while (1) {
if (linectr == mod)
break;
space(1, 0);
}
}
return SCPE_OK;
}
return SCPE_OK;
}
/* Space routine - space or skip n lines
Inputs:
count = number of lines to space or skip
sflag = skip (TRUE) or space (FALSE)
count = number of lines to space or skip
sflag = skip (TRUE) or space (FALSE)
*/
t_stat space (int32 count, int32 sflag)
@@ -316,18 +325,19 @@ t_stat space (int32 count, int32 sflag)
int32 i;
if ((lpt_unit.flags & UNIT_ATT) == 0) return SCPE_UNATT;
cctptr = (cctptr + count) % cctlnt; /* adv cct, mod lnt */
if (sflag && CHP (0, cct[cctptr])) { /* skip, top of form? */
fputs ("\n\f", lpt_unit.fileref); /* nl, ff */
linectr = 1;
}
else { for (i = 0; i < count; i++) fputc ('\n', lpt_unit.fileref); }
lpt_unit.pos = ftell (lpt_unit.fileref); /* update position */
CC9 = CHP (9, cct[cctptr]) != 0; /* set indicators */
cctptr = (cctptr + count) % cctlnt; /* adv cct, mod lnt */
if (sflag && CHP (0, cct[cctptr])) { /* skip, top of form? */
fputs ("\n\f", lpt_unit.fileref); /* nl, ff */
linectr = 1;
} else {
for (i = 0; i < count; i++) fputc ('\n', lpt_unit.fileref);
}
lpt_unit.pos = ftell (lpt_unit.fileref); /* update position */
CC9 = CHP (9, cct[cctptr]) != 0; /* set indicators */
CC12 = CHP (12, cct[cctptr]) != 0;
linectr += count;
if (linectr > LPFLR)
linectr -= LPFLR;
linectr -= LPFLR;
return SCPE_OK;
}
@@ -335,8 +345,8 @@ return SCPE_OK;
t_stat lpt_reset (DEVICE *dptr)
{
cctptr = 0; /* clear cct ptr */
lines = linectr = lflag = 0; /* no cc action */
cctptr = 0; /* clear cct ptr */
lines = linectr = lflag = 0; /* no cc action */
lpterror = 0;
return SCPE_OK;
}
@@ -345,8 +355,8 @@ return SCPE_OK;
t_stat lpt_attach (UNIT *uptr, char *cptr)
{
cctptr = 0; /* clear cct ptr */
lines = 0; /* no cc action */
cctptr = 0; /* clear cct ptr */
lines = 0; /* no cc action */
lpterror = 0;
linectr = 0;
return attach_unit (uptr, cptr);

View File

@@ -1,6 +1,6 @@
/* s3_pkb.c: System/3 5471 console terminal simulator
Copyright (c) 2001, Charles E. Owen
Copyright (c) 2001-2005, Charles E. Owen
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -19,14 +19,14 @@
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 Charles E. Owen 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 Charles E. Owen shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Charles E. Owen.
pkb 5471 printer/keyboard
pkb 5471 printer/keyboard
25-Apr-03 RMS Revised for extended file support
08-Oct-02 RMS Added impossible function catcher
25-Apr-03 RMS Revised for extended file support
08-Oct-02 RMS Added impossible function catcher
*/
#include "s3_defs.h"
@@ -39,56 +39,59 @@ extern t_stat sim_poll_kbd (void);
extern t_stat sim_putchar (int32 out);
extern int32 IAR[], level;
extern int32 debug_reg;
/* 5471 data structures
pkb_dev TTI device descriptor
pkb_unit TTI unit descriptor
pkb_reg TTI register list
pkb_mod TTI/TTO modifiers list
pkb_dev TTI device descriptor
pkb_unit TTI unit descriptor
pkb_reg TTI register list
pkb_mod TTI/TTO modifiers list
*/
/* Flag bits : (kept in pkb_unit.u3) */
#define PRT_INTREQ 0x800 /* Printer interrupt pending */
#define KBD_INTREQ 0x400 /* Request key interrupt pending */
#define KBD_INTEND 0x200 /* End or cancel key interrupt pending */
#define KBD_INTKEY 0x100 /* Return or other key interrupt pending */
#define KBD_REQLIGHT 0x20 /* Request Pending Indicator (light on/off) */
#define KBD_PROLIGHT 0x10 /* Proceed indicator (light on/off) */
#define KBD_REQINT 0x04 /* Req key interrupts enabled */
#define KBD_KEYINT 0x02 /* Other key interrupts enabled */
#define PRT_PRTINT 0x01 /* Printer interrupts enabled */
#define PRT_INTREQ 0x800 /* Printer interrupt pending */
#define KBD_INTREQ 0x400 /* Request key interrupt pending */
#define KBD_INTEND 0x200 /* End or cancel key interrupt pending */
#define KBD_INTKEY 0x100 /* Return or other key interrupt pending */
#define KBD_REQLIGHT 0x20 /* Request Pending Indicator (light on/off) */
#define KBD_PROLIGHT 0x10 /* Proceed indicator (light on/off) */
#define KBD_REQINT 0x04 /* Req key interrupts enabled */
#define KBD_KEYINT 0x02 /* Other key interrupts enabled */
#define PRT_PRTINT 0x01 /* Printer interrupts enabled */
/* Keys mapped to 5471 functions */
int32 key_req = 0x01; /* Request key: ^A */
int32 key_rtn = 0x12; /* Return key: ^R */
int32 key_can = 0x1B; /* Cancel key: ESC */
int32 key_end = 0x0d; /* End key - CR */
int32 key_req = 0x01; /* Request key: ^A */
int32 key_rtn = 0x12; /* Return key: ^R */
int32 key_can = 0x1B; /* Cancel key: ESC */
int32 key_end = 0x0d; /* End key - CR */
UNIT pkb_unit = { UDATA (&pkb_svc, 0, 0), KBD_POLL_WAIT };
REG pkb_reg[] = {
{ HRDATA (FLAG, pkb_unit.u3, 16) },
{ HRDATA (IBUF, pkb_unit.buf, 8) },
{ HRDATA (OBUF, pkb_unit.u4, 8) },
{ HRDATA (REQKEY, key_req, 8) },
{ HRDATA (RTNKEY, key_rtn, 8) },
{ HRDATA (CANKEY, key_can, 8) },
{ HRDATA (ENDKEY, key_end, 8) },
{ DRDATA (POS, pkb_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, pkb_unit.wait, 24), REG_NZ + PV_LEFT },
{ NULL } };
{ HRDATA (FLAG, pkb_unit.u3, 16) },
{ HRDATA (IBUF, pkb_unit.buf, 8) },
{ HRDATA (OBUF, pkb_unit.u4, 8) },
{ HRDATA (REQKEY, key_req, 8) },
{ HRDATA (RTNKEY, key_rtn, 8) },
{ HRDATA (CANKEY, key_can, 8) },
{ HRDATA (ENDKEY, key_end, 8) },
{ DRDATA (POS, pkb_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, pkb_unit.wait, 24), REG_NZ + PV_LEFT },
{ NULL }
};
MTAB pkb_mod[] = {
{ 0 } };
{ 0 }
};
DEVICE pkb_dev = {
"PKB", &pkb_unit, pkb_reg, pkb_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &pkb_reset,
NULL, NULL, NULL };
"PKB", &pkb_unit, pkb_reg, pkb_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &pkb_reset,
NULL, NULL, NULL
};
/*-------------------------------------------------------------------*/
@@ -141,97 +144,97 @@ unsigned char ascii_to_ebcdic[] = {
int32 pkb (int32 op, int32 m, int32 n, int32 data)
{
int32 iodata= 0, ec, ac;
switch (op) {
case 0: /* SIO 5471 */
if (n != 0)
return STOP_INVDEV;
/*printf("%04X SIO %d,%d,%02X\n\r", IAR[level]-4, m, n, data);*/
if (m == 0) { /* Keyboard */
pkb_unit.u3 &= 0xFC1;
pkb_unit.u3 |= data;
if (data & 0x01) {
pkb_unit.u3 &= ~KBD_INTREQ;
pkb_unit.u3 &= ~KBD_INTKEY;
pkb_unit.u3 &= ~KBD_INTEND;
return RESET_INTERRUPT;
}
} else { /* Printer */
if (data & 0x80) { /* start print bit */
if (debug_reg & 0x80)
return STOP_IBKPT;
ec = pkb_unit.u4 & 0xff;
ac = ebcdic_to_ascii[ec];
sim_putchar(ac);
pkb_unit.u3 |= PRT_INTREQ;
}
if (data & 0x40) { /* Carr. Return */
sim_putchar('\n');
sim_putchar('\r');
pkb_unit.u3 |= PRT_INTREQ;
}
pkb_unit.u3 &= 0xFFe;
if (data & 0x04) /* Print interrupt flag */
pkb_unit.u3 |= PRT_PRTINT;
if (data & 0x01) { /* Reset Interrupt */
if (level < 8) {
if (!(data & 0x80))
pkb_unit.u3 &= ~PRT_INTREQ;
return RESET_INTERRUPT;
}
}
}
return SCPE_OK;
case 1: /* LIO 5471 */
if (n != 0)
return STOP_INVDEV;
if (m != 1)
return STOP_INVDEV;
pkb_unit.u4 = (data >> 8) & 0xff;
return SCPE_OK;
break;
case 2: /* TIO 5471 */
return STOP_INVDEV;
case 3: /* SNS 5471 */
if (n != 1 && n != 3)
return (STOP_INVDEV << 16);
if (m == 0) { /* Keyboard data */
if (n == 1) { /* Sense bytes 0 & 1 */
iodata = (pkb_unit.buf << 8) & 0xff00;
if (pkb_unit.u3 & KBD_INTREQ)
iodata |= 0x80;
if (pkb_unit.u3 & KBD_INTEND)
iodata |= 0x40;
if (pkb_unit.u3 & KBD_INTKEY)
iodata |= 0x08;
if (pkb_unit.buf == 0x12) /* Return key */
iodata |= 0x04;
if (pkb_unit.buf == 0x03) /* Cancel key */
iodata |= 0x20;
if (pkb_unit.buf == 0x0d) /* End key */
iodata |= 0x10;
iodata |= ((SCPE_OK << 16) & 0xffff0000);
} else { /* Sense bytes 2 & 3 */
iodata = 0; /* Manual says CE use only */
}
} else { /* Printer Data */
if (n == 1) { /* Sense bytes 0 & 1 */
iodata = 0;
if (pkb_unit.u3 & PRT_INTREQ)
iodata |= 0x80;
} else {
iodata = 0; /* CE use only */
}
}
iodata |= ((SCPE_OK << 16) & 0xffff0000);
return (iodata);
case 4: /* APL 5471 */
return STOP_INVDEV;
default:
break;
}
printf (">>PKB non-existent function %d\n", op);
return SCPE_OK;
int32 iodata= 0, ec, ac;
switch (op) {
case 0: /* SIO 5471 */
if (n != 0)
return STOP_INVDEV;
/*printf("%04X SIO %d,%d,%02X\n\r", IAR[level]-4, m, n, data);*/
if (m == 0) { /* Keyboard */
pkb_unit.u3 &= 0xFC1;
pkb_unit.u3 |= data;
if (data & 0x01) {
pkb_unit.u3 &= ~KBD_INTREQ;
pkb_unit.u3 &= ~KBD_INTKEY;
pkb_unit.u3 &= ~KBD_INTEND;
return RESET_INTERRUPT;
}
} else { /* Printer */
if (data & 0x80) { /* start print bit */
if (debug_reg & 0x80)
return STOP_IBKPT;
ec = pkb_unit.u4 & 0xff;
ac = ebcdic_to_ascii[ec];
sim_putchar(ac);
pkb_unit.u3 |= PRT_INTREQ;
}
if (data & 0x40) { /* Carr. Return */
sim_putchar('\n');
sim_putchar('\r');
pkb_unit.u3 |= PRT_INTREQ;
}
pkb_unit.u3 &= 0xFFe;
if (data & 0x04) /* Print interrupt flag */
pkb_unit.u3 |= PRT_PRTINT;
if (data & 0x01) { /* Reset Interrupt */
if (level < 8) {
if (!(data & 0x80))
pkb_unit.u3 &= ~PRT_INTREQ;
return RESET_INTERRUPT;
}
}
}
return SCPE_OK;
case 1: /* LIO 5471 */
if (n != 0)
return STOP_INVDEV;
if (m != 1)
return STOP_INVDEV;
pkb_unit.u4 = (data >> 8) & 0xff;
return SCPE_OK;
break;
case 2: /* TIO 5471 */
return STOP_INVDEV;
case 3: /* SNS 5471 */
if (n != 1 && n != 3)
return (STOP_INVDEV << 16);
if (m == 0) { /* Keyboard data */
if (n == 1) { /* Sense bytes 0 & 1 */
iodata = (pkb_unit.buf << 8) & 0xff00;
if (pkb_unit.u3 & KBD_INTREQ)
iodata |= 0x80;
if (pkb_unit.u3 & KBD_INTEND)
iodata |= 0x40;
if (pkb_unit.u3 & KBD_INTKEY)
iodata |= 0x08;
if (pkb_unit.buf == 0x12) /* Return key */
iodata |= 0x04;
if (pkb_unit.buf == 0x03) /* Cancel key */
iodata |= 0x20;
if (pkb_unit.buf == 0x0d) /* End key */
iodata |= 0x10;
iodata |= ((SCPE_OK << 16) & 0xffff0000);
} else { /* Sense bytes 2 & 3 */
iodata = 0; /* Manual says CE use only */
}
} else { /* Printer Data */
if (n == 1) { /* Sense bytes 0 & 1 */
iodata = 0;
if (pkb_unit.u3 & PRT_INTREQ)
iodata |= 0x80;
} else {
iodata = 0; /* CE use only */
}
}
iodata |= ((SCPE_OK << 16) & 0xffff0000);
return (iodata);
case 4: /* APL 5471 */
return STOP_INVDEV;
default:
break;
}
printf (">>PKB non-existent function %d\n", op);
return SCPE_OK;
}
/* Unit service */
@@ -240,58 +243,58 @@ t_stat pkb_svc (UNIT *uptr)
{
int32 temp, ac, ec;
sim_activate (&pkb_unit, pkb_unit.wait); /* continue poll */
sim_activate (&pkb_unit, pkb_unit.wait); /* continue poll */
if (pkb_unit.u3 & PRT_INTREQ) { /* Printer Interrupt */
int_req |= 2;
return SCPE_OK;
}
if (pkb_unit.u3 & PRT_INTREQ) { /* Printer Interrupt */
int_req |= 2;
return SCPE_OK;
}
/* Keyboard : handle input */
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG) return temp; /* no char or error? */
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG) return temp; /* no char or error? */
ac = temp & 0x7f; /* placed type ASCII char in ac */
ac = temp & 0x7f; /* placed type ASCII char in ac */
if (pkb_unit.u3 & KBD_REQINT) {
if (ac == key_req) { /* Request Key */
pkb_unit.u3 |= KBD_INTREQ;
int_req |= 2;
return SCPE_OK;
}
if (ac == key_req) { /* Request Key */
pkb_unit.u3 |= KBD_INTREQ;
int_req |= 2;
return SCPE_OK;
}
}
if (islower(ac))
ac = toupper(ac);
ec = ascii_to_ebcdic[ac]; /* Translate */
pkb_unit.buf = ec; /* put in buf */
ac = toupper(ac);
ec = ascii_to_ebcdic[ac]; /* Translate */
pkb_unit.buf = ec; /* put in buf */
pkb_unit.pos = pkb_unit.pos + 1;
if (ac == key_end) { /* End key */
if (pkb_unit.u3 & KBD_KEYINT) {
pkb_unit.u3 |= KBD_INTEND;
pkb_unit.buf = 0x0d;
int_req |= 2;
}
return SCPE_OK;
if (ac == key_end) { /* End key */
if (pkb_unit.u3 & KBD_KEYINT) {
pkb_unit.u3 |= KBD_INTEND;
pkb_unit.buf = 0x0d;
int_req |= 2;
}
return SCPE_OK;
}
if (ac == key_can) { /* Cancel key */
if (pkb_unit.u3 & KBD_KEYINT) {
pkb_unit.u3 |= KBD_INTEND;
pkb_unit.buf = 0x03;
int_req |= 2;
}
return SCPE_OK;
if (ac == key_can) { /* Cancel key */
if (pkb_unit.u3 & KBD_KEYINT) {
pkb_unit.u3 |= KBD_INTEND;
pkb_unit.buf = 0x03;
int_req |= 2;
}
return SCPE_OK;
}
if (ac == key_rtn) { /* Return key */
if (pkb_unit.u3 & KBD_KEYINT) {
pkb_unit.u3 |= KBD_INTKEY;
pkb_unit.buf = 0x12;
int_req |= 2;
}
return SCPE_OK;
if (ac == key_rtn) { /* Return key */
if (pkb_unit.u3 & KBD_KEYINT) {
pkb_unit.u3 |= KBD_INTKEY;
pkb_unit.buf = 0x12;
int_req |= 2;
}
return SCPE_OK;
}
if (pkb_unit.u3 & KBD_KEYINT) { /* Key interupts enabled ? */
int_req |= 2; /* Device 1 Interrupt! */
pkb_unit.u3 |= KBD_INTKEY; /* Set pending flag */
}
if (pkb_unit.u3 & KBD_KEYINT) { /* Key interupts enabled ? */
int_req |= 2; /* Device 1 Interrupt! */
pkb_unit.u3 |= KBD_INTKEY; /* Set pending flag */
}
return SCPE_OK;
}
@@ -300,8 +303,8 @@ return SCPE_OK;
t_stat pkb_reset (DEVICE *dptr)
{
pkb_unit.buf = 0;
int_req = int_req & ~0x02; /* reset interrupt */
sim_activate (&pkb_unit, pkb_unit.wait); /* activate unit */
int_req = int_req & ~0x02; /* reset interrupt */
sim_activate (&pkb_unit, pkb_unit.wait); /* activate unit */
return SCPE_OK;
}

File diff suppressed because it is too large Load Diff