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:
committed by
Mark Pizzolato
parent
ec60bbf329
commit
b7c1eae41f
539
S3/s3_cd.c
539
S3/s3_cd.c
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
2074
S3/s3_cpu.c
2074
S3/s3_cpu.c
File diff suppressed because it is too large
Load Diff
98
S3/s3_defs.h
98
S3/s3_defs.h
@@ -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) */
|
||||
};
|
||||
|
||||
1086
S3/s3_disk.c
1086
S3/s3_disk.c
File diff suppressed because it is too large
Load Diff
464
S3/s3_lp.c
464
S3/s3_lp.c
@@ -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);
|
||||
|
||||
347
S3/s3_pkb.c
347
S3/s3_pkb.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
1472
S3/s3_sys.c
1472
S3/s3_sys.c
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user