I7000: Group update for IBM 7000 series simulators.
I7010 updated to pass diagnostics. I7080 updated to pass diagnostics. I7090 updated to better pass 9IOT updated to allow Stress and other applications to run better. Updated card punch to allow input of card decks for overpunching.
This commit is contained in:
parent
e425c75d0d
commit
1a1396d0ba
11 changed files with 800 additions and 353 deletions
|
@ -40,6 +40,12 @@
|
||||||
/* Flags for punch and reader. */
|
/* Flags for punch and reader. */
|
||||||
#define ATTENA (1 << (UNIT_V_UF+7))
|
#define ATTENA (1 << (UNIT_V_UF+7))
|
||||||
#define ATTENB (1 << (UNIT_V_UF+14))
|
#define ATTENB (1 << (UNIT_V_UF+14))
|
||||||
|
#define INPUT_V (UNIT_V_UF+7)
|
||||||
|
#define INPUT_FULL (1 << INPUT_V)
|
||||||
|
#define INPUT_EMPTY (2 << INPUT_V)
|
||||||
|
#define INPUT_DECK (3 << INPUT_V)
|
||||||
|
#define INPUT_BLANK (4 << INPUT_V)
|
||||||
|
#define INPUT_MASK (7 << INPUT_V)
|
||||||
|
|
||||||
|
|
||||||
/* std devices. data structures
|
/* std devices. data structures
|
||||||
|
@ -56,6 +62,8 @@ t_stat cdp_srv(UNIT *);
|
||||||
t_stat cdp_reset(DEVICE *);
|
t_stat cdp_reset(DEVICE *);
|
||||||
t_stat cdp_attach(UNIT *, CONST char *);
|
t_stat cdp_attach(UNIT *, CONST char *);
|
||||||
t_stat cdp_detach(UNIT *);
|
t_stat cdp_detach(UNIT *);
|
||||||
|
t_stat cdp_get_input(FILE *, UNIT *, int32, CONST void *);
|
||||||
|
t_stat cdp_set_input(UNIT *, int32, CONST char *, void *);
|
||||||
t_stat cdp_help(FILE *, DEVICE *, UNIT *, int32, const char *);
|
t_stat cdp_help(FILE *, DEVICE *, UNIT *, int32, const char *);
|
||||||
const char *cdp_description(DEVICE *dptr);
|
const char *cdp_description(DEVICE *dptr);
|
||||||
t_stat stk_help(FILE *, DEVICE *, UNIT *, int32, const char *);
|
t_stat stk_help(FILE *, DEVICE *, UNIT *, int32, const char *);
|
||||||
|
@ -68,6 +76,13 @@ UNIT cdp_unit[] = {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
UNIT cdp_input_unit[] = {
|
||||||
|
{UDATA(NULL, UNIT_ATTABLE | INPUT_FULL | UNIT_RO, 0), 600}, /* A */
|
||||||
|
#if NUM_DEVS_CDP > 1
|
||||||
|
{UDATA(NULL, UNIT_ATTABLE | INPUT_FULL | UNIT_RO, 0), 600}, /* B */
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
MTAB cdp_mod[] = {
|
MTAB cdp_mod[] = {
|
||||||
{MTAB_XTD | MTAB_VUN, 0, "FORMAT", "FORMAT",
|
{MTAB_XTD | MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||||
&sim_card_set_fmt, &sim_card_show_fmt, NULL, "Set card format"},
|
&sim_card_set_fmt, &sim_card_show_fmt, NULL, "Set card format"},
|
||||||
|
@ -80,17 +95,27 @@ MTAB cdp_mod[] = {
|
||||||
{MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "CHAN", "CHAN", &set_chan,
|
{MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "CHAN", "CHAN", &set_chan,
|
||||||
&get_chan, NULL, "Set device channel"},
|
&get_chan, NULL, "Set device channel"},
|
||||||
#endif
|
#endif
|
||||||
|
{MTAB_XTD | MTAB_VUN | MTAB_VALR | MTAB_NC, 0, "INPUT", "INPUT", &cdp_set_input, &cdp_get_input,
|
||||||
|
NULL, "Set input to card punch"},
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
DEVICE cdp_dev = {
|
DEVICE cdp_dev = {
|
||||||
"CDP", cdp_unit, NULL, cdp_mod,
|
"CDP", cdp_unit, NULL, cdp_mod,
|
||||||
NUM_DEVS_CDP, 8, 15, 1, 8, 8,
|
NUM_DEVS_CDP, 8, 15, 1, 8, 8,
|
||||||
NULL, NULL, NULL, NULL, &cdp_attach, &cdp_detach,
|
NULL, NULL, &cdp_reset, NULL, &cdp_attach, &cdp_detach,
|
||||||
&cdp_dib, DEV_DISABLE | DEV_DEBUG | DEV_CARD, 0, crd_debug,
|
&cdp_dib, DEV_DISABLE | DEV_DEBUG | DEV_CARD, 0, crd_debug,
|
||||||
NULL, NULL, &cdp_help, NULL, NULL, &cdp_description
|
NULL, NULL, &cdp_help, NULL, NULL, &cdp_description
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DEVICE cdp_input_dev = {
|
||||||
|
"INPUT", cdp_input_unit, NULL, NULL,
|
||||||
|
NUM_DEVS_CDP, 8, 15, 1, 8, 8,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, DEV_DISABLE | DEV_DIS, 0, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef STACK_DEV
|
#ifdef STACK_DEV
|
||||||
UNIT stack_unit[] = {
|
UNIT stack_unit[] = {
|
||||||
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) },
|
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) },
|
||||||
|
@ -140,10 +165,15 @@ uint32 cdp_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
|
||||||
int chan = UNIT_G_CHAN(uptr->flags);
|
int chan = UNIT_G_CHAN(uptr->flags);
|
||||||
int u = (uptr - cdp_unit);
|
int u = (uptr - cdp_unit);
|
||||||
int stk = dev & 017;
|
int stk = dev & 017;
|
||||||
|
UNIT *iuptr = &cdp_input_unit[u];
|
||||||
|
uint16 *image = (uint16 *)(uptr->up7);
|
||||||
|
int i;
|
||||||
|
|
||||||
/* Are we currently tranfering? */
|
/* Are we currently tranfering? */
|
||||||
if (uptr->u5 & URCSTA_WRITE)
|
if (uptr->u5 & URCSTA_WRITE) {
|
||||||
|
sim_debug(DEBUG_DETAIL, &cdp_dev, "%d: Busy\n", u);
|
||||||
return SCPE_BUSY;
|
return SCPE_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
if (stk == 10)
|
if (stk == 10)
|
||||||
stk = 0;
|
stk = 0;
|
||||||
|
@ -173,6 +203,37 @@ uint32 cdp_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
|
||||||
uptr->u5 |= stk << 16;
|
uptr->u5 |= stk << 16;
|
||||||
#endif
|
#endif
|
||||||
sim_debug(DEBUG_CMD, &cdp_dev, "%d: Cmd WRS\n", u);
|
sim_debug(DEBUG_CMD, &cdp_dev, "%d: Cmd WRS\n", u);
|
||||||
|
|
||||||
|
switch((iuptr->flags & INPUT_MASK) >> INPUT_V) {
|
||||||
|
case INPUT_EMPTY >> INPUT_V:
|
||||||
|
case INPUT_BLANK >> INPUT_V:
|
||||||
|
if (iuptr->u3 == 0) {
|
||||||
|
sim_debug(DEBUG_DETAIL, &cdp_dev, "%d: Empty\n", u);
|
||||||
|
return SCPE_IOERR;
|
||||||
|
}
|
||||||
|
iuptr->u3--;
|
||||||
|
/* Fall through */
|
||||||
|
|
||||||
|
case INPUT_FULL >> INPUT_V:
|
||||||
|
for (i = 0; i < 80; image[i++] = 0);
|
||||||
|
break;
|
||||||
|
case INPUT_DECK >> INPUT_V:
|
||||||
|
switch(sim_read_card(iuptr, image)) {
|
||||||
|
case CDSE_ERROR:
|
||||||
|
uptr->u5 |= URCSTA_ERR;
|
||||||
|
/* Fall through */
|
||||||
|
|
||||||
|
case CDSE_EOF:
|
||||||
|
case CDSE_EMPTY:
|
||||||
|
sim_debug(DEBUG_DETAIL, &cdp_dev, "%d: Empty deck\n", u);
|
||||||
|
return SCPE_IOERR;
|
||||||
|
case CDSE_OK:
|
||||||
|
sim_debug(DEBUG_DETAIL, &cdp_dev, "%d: left %d\n", u,
|
||||||
|
sim_card_input_hopper_count(iuptr));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
chan_set_sel(chan, 1);
|
chan_set_sel(chan, 1);
|
||||||
uptr->u5 |= URCSTA_WRITE;
|
uptr->u5 |= URCSTA_WRITE;
|
||||||
uptr->u4 = 0;
|
uptr->u4 = 0;
|
||||||
|
@ -180,7 +241,6 @@ uint32 cdp_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
|
||||||
sim_activate(uptr, 50);
|
sim_activate(uptr, 50);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
chan_set_attn(chan);
|
|
||||||
return SCPE_IOERR;
|
return SCPE_IOERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,9 +317,12 @@ cdp_srv(UNIT *uptr) {
|
||||||
ch = 020;
|
ch = 020;
|
||||||
else if (ch == 020)
|
else if (ch == 020)
|
||||||
ch = 0;
|
ch = 0;
|
||||||
sim_debug(DEBUG_DATA, &cdp_dev, "%d: Char < %02o\n", u, ch);
|
image[uptr->u4] |= sim_bcd_to_hol(ch);
|
||||||
image[uptr->u4++] = sim_bcd_to_hol(ch);
|
if (sim_hol_to_bcd(image[uptr->u4]) == 0x7f) {
|
||||||
if (uptr->u4 == 80) {
|
chan_set_eof(chan);
|
||||||
|
}
|
||||||
|
sim_debug(DEBUG_DATA, &cdp_dev, "%d: Char < %02o %04o\n", u, ch, image[uptr->u4]);
|
||||||
|
if (++uptr->u4 == 80) {
|
||||||
chan_set(chan, DEV_REOR);
|
chan_set(chan, DEV_REOR);
|
||||||
uptr->u5 |= URCSTA_WDISCO|URCSTA_BUSY|URCSTA_FULL;
|
uptr->u5 |= URCSTA_WDISCO|URCSTA_BUSY|URCSTA_FULL;
|
||||||
uptr->u5 &= ~URCSTA_WRITE;
|
uptr->u5 &= ~URCSTA_WRITE;
|
||||||
|
@ -271,6 +334,10 @@ cdp_srv(UNIT *uptr) {
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t_stat
|
||||||
|
cdp_reset(DEVICE *dptr) {
|
||||||
|
return sim_register_internal_device (&cdp_input_dev);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cdp_ini(UNIT *uptr, t_bool f) {
|
cdp_ini(UNIT *uptr, t_bool f) {
|
||||||
|
@ -285,7 +352,7 @@ cdp_attach(UNIT * uptr, CONST char *file)
|
||||||
if ((r = sim_card_attach(uptr, file)) != SCPE_OK)
|
if ((r = sim_card_attach(uptr, file)) != SCPE_OK)
|
||||||
return r;
|
return r;
|
||||||
if (uptr->up7 == 0) {
|
if (uptr->up7 == 0) {
|
||||||
uptr->up7 = calloc(80, sizeof(uint16));
|
uptr->up7 = calloc(80, sizeof(uint16));
|
||||||
uptr->u5 = 0;
|
uptr->u5 = 0;
|
||||||
}
|
}
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
@ -306,12 +373,119 @@ cdp_detach(UNIT * uptr)
|
||||||
sim_punch_card(uptr, image);
|
sim_punch_card(uptr, image);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (uptr->up7 == 0)
|
if (uptr->up7 == 0)
|
||||||
free(uptr->up7);
|
free(uptr->up7);
|
||||||
uptr->up7 = 0;
|
uptr->up7 = 0;
|
||||||
return sim_card_detach(uptr);
|
return sim_card_detach(uptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t_stat
|
||||||
|
cdp_set_input(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
|
||||||
|
{
|
||||||
|
int nflag = 1;
|
||||||
|
int num = 0;
|
||||||
|
char gbuf[30];
|
||||||
|
char *p;
|
||||||
|
int u = (uptr - cdp_unit);
|
||||||
|
UNIT *iuptr = &cdp_input_unit[u];
|
||||||
|
t_stat r = SCPE_ARG;
|
||||||
|
|
||||||
|
if (cptr == NULL)
|
||||||
|
return SCPE_ARG;
|
||||||
|
if (uptr == NULL)
|
||||||
|
return SCPE_IERR;
|
||||||
|
|
||||||
|
/* Clear existing input */
|
||||||
|
sim_card_detach(iuptr);
|
||||||
|
iuptr->u3 = 0;
|
||||||
|
iuptr->flags &= ~INPUT_MASK;
|
||||||
|
iuptr->flags |= INPUT_EMPTY;
|
||||||
|
|
||||||
|
/* Get first argument */
|
||||||
|
cptr = get_glyph(cptr, gbuf, ';');
|
||||||
|
|
||||||
|
/* Check if it is a number */
|
||||||
|
for (p = gbuf; *p != '\0'; p++) {
|
||||||
|
if (*p < '0' || *p > '9') {
|
||||||
|
nflag = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
num = (num * 10) + (*p) - '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If valid number, set to number of blank cards */
|
||||||
|
if (nflag) {
|
||||||
|
iuptr->u3 = num;
|
||||||
|
iuptr->flags &= ~INPUT_MASK;
|
||||||
|
iuptr->flags |= INPUT_BLANK;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for given format */
|
||||||
|
if (sim_strcasecmp(gbuf, "EMPTY") == 0) {
|
||||||
|
iuptr->u3 = 0;
|
||||||
|
iuptr->flags &= ~INPUT_MASK;
|
||||||
|
iuptr->flags |= INPUT_EMPTY;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sim_strcasecmp(gbuf, "FULL") == 0) {
|
||||||
|
iuptr->u3 = 0;
|
||||||
|
iuptr->flags &= ~INPUT_MASK;
|
||||||
|
iuptr->flags |= INPUT_FULL;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If deck attach it to input */
|
||||||
|
if (sim_strcasecmp(gbuf, "DECK") == 0) {
|
||||||
|
int32 saved_switches = sim_switches;
|
||||||
|
|
||||||
|
sim_switches = SWMASK('E') | SWMASK('R');
|
||||||
|
if ((saved_switches & SWMASK('F')) != 0) {
|
||||||
|
cptr = get_glyph(cptr, gbuf, ';');
|
||||||
|
sim_card_set_fmt(iuptr, 0, gbuf, NULL);
|
||||||
|
}
|
||||||
|
r = sim_card_attach(iuptr, cptr);
|
||||||
|
if (r == SCPE_OK) {
|
||||||
|
iuptr->flags &= ~INPUT_MASK;
|
||||||
|
iuptr->flags |= INPUT_DECK;
|
||||||
|
}
|
||||||
|
sim_switches = saved_switches;
|
||||||
|
}
|
||||||
|
/* Error, set to empty */
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat
|
||||||
|
cdp_get_input(FILE *st, UNIT *uptr, int32 v, CONST void *desc)
|
||||||
|
{
|
||||||
|
int u = (uptr - cdp_unit);
|
||||||
|
UNIT *iuptr = &cdp_input_unit[u];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (uptr == NULL)
|
||||||
|
return SCPE_IERR;
|
||||||
|
|
||||||
|
i = (iuptr->flags & INPUT_MASK) >> INPUT_V;
|
||||||
|
switch((iuptr->flags & INPUT_MASK) >> INPUT_V) {
|
||||||
|
case INPUT_BLANK >> INPUT_V:
|
||||||
|
fprintf(st, "%d blanks", iuptr->u3);
|
||||||
|
break;
|
||||||
|
case INPUT_FULL >> INPUT_V:
|
||||||
|
fprintf(st, "full");
|
||||||
|
break;
|
||||||
|
case INPUT_EMPTY >> INPUT_V:
|
||||||
|
fprintf(st, "empty");
|
||||||
|
break;
|
||||||
|
case INPUT_DECK >> INPUT_V:
|
||||||
|
fprintf(st, "deck %s", iuptr->filename);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef STACK_DEV
|
#ifdef STACK_DEV
|
||||||
t_stat
|
t_stat
|
||||||
stk_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
stk_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||||
|
|
|
@ -122,8 +122,10 @@ uint32 cdr_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
|
||||||
uptr->u5 &= ~0xF0000;
|
uptr->u5 &= ~0xF0000;
|
||||||
uptr->u5 |= stk << 16;
|
uptr->u5 |= stk << 16;
|
||||||
#endif
|
#endif
|
||||||
if (uptr->u5 & (URCSTA_EOF|URCSTA_ERR))
|
if (uptr->u5 & (URCSTA_EOF|URCSTA_ERR)) {
|
||||||
|
uptr->u5 &= ~(URCSTA_EOF|URCSTA_ERR);
|
||||||
return SCPE_IOERR;
|
return SCPE_IOERR;
|
||||||
|
}
|
||||||
|
|
||||||
/* Process commands */
|
/* Process commands */
|
||||||
switch(cmd) {
|
switch(cmd) {
|
||||||
|
@ -141,15 +143,19 @@ uint32 cdr_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
sim_debug(DEBUG_CMD, &cdr_dev, "%d: CMD none %02o\n", u, cmd);
|
||||||
chan_set_attn(chan);
|
chan_set_attn(chan);
|
||||||
return SCPE_IOERR;
|
return SCPE_IOERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If at eof, just return EOF */
|
/* If at eof, just return EOF */
|
||||||
if (uptr->u5 & URCSTA_EOF) {
|
if (sim_card_eof(uptr)) {
|
||||||
|
uint16 *image = (uint16 *)(uptr->up7);
|
||||||
chan_set_eof(chan);
|
chan_set_eof(chan);
|
||||||
chan_set_attn(chan);
|
chan_set_attn(chan);
|
||||||
return SCPE_OK;
|
uptr->u5 &= ~(URCSTA_EOF|URCSTA_ERR);
|
||||||
|
(void)sim_read_card(uptr, image);
|
||||||
|
return SCPE_IOERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
uptr->u5 |= URCSTA_READ;
|
uptr->u5 |= URCSTA_READ;
|
||||||
|
@ -256,6 +262,10 @@ cdr_srv(UNIT *uptr) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ch = sim_hol_to_bcd(image[uptr->u4]);
|
ch = sim_hol_to_bcd(image[uptr->u4]);
|
||||||
|
/* Handle 7-9 to generate 20 */
|
||||||
|
if (ch == 012 && image[uptr->u4] == 0202) {
|
||||||
|
ch = 020;
|
||||||
|
}
|
||||||
|
|
||||||
/* Handle invalid punch */
|
/* Handle invalid punch */
|
||||||
if (ch == 0x7f) {
|
if (ch == 0x7f) {
|
||||||
|
@ -288,7 +298,7 @@ cdr_srv(UNIT *uptr) {
|
||||||
uptr->u4++;
|
uptr->u4++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sim_debug(DEBUG_DATA, &cdr_dev, "%d: Char > %02o\n", u, ch);
|
sim_debug(DEBUG_DATA, &cdr_dev, "%d: Char > %04o %02o\n", u, image[uptr->u4-1], ch);
|
||||||
sim_activate(uptr, 10);
|
sim_activate(uptr, 10);
|
||||||
}
|
}
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
|
|
@ -78,6 +78,8 @@
|
||||||
#define MT_EOR 002000 /* Set EOR on next record */
|
#define MT_EOR 002000 /* Set EOR on next record */
|
||||||
#define MT_UNLOAD 004000 /* Unload when rewind done */
|
#define MT_UNLOAD 004000 /* Unload when rewind done */
|
||||||
#define MT_EGAP 010000 /* Write extended gap on next write */
|
#define MT_EGAP 010000 /* Write extended gap on next write */
|
||||||
|
#define MT_LWR 020000 /* Last command was a write */
|
||||||
|
#define MT_CLRIND 040000 /* On I7010 flag for SKR to clear indicator */
|
||||||
|
|
||||||
/* u6 holds the current buffer position */
|
/* u6 holds the current buffer position */
|
||||||
|
|
||||||
|
@ -90,8 +92,8 @@
|
||||||
#define IPS 75 /* Inches per second 75 or 112 */
|
#define IPS 75 /* Inches per second 75 or 112 */
|
||||||
#define HS_IPS 500 /* High speed rewind Inches per second */
|
#define HS_IPS 500 /* High speed rewind Inches per second */
|
||||||
|
|
||||||
#define LD 200
|
#define LD 300
|
||||||
#define HD 555
|
#define HD 150
|
||||||
|
|
||||||
#define LT_GAP_LEN ((3 * LD)/ 4) /* Gap length for low density */
|
#define LT_GAP_LEN ((3 * LD)/ 4) /* Gap length for low density */
|
||||||
#define HT_GAP_LEN ((3 * HD)/ 4) /* Gap length for high density */
|
#define HT_GAP_LEN ((3 * HD)/ 4) /* Gap length for high density */
|
||||||
|
@ -238,9 +240,9 @@ UNIT mta_unit[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
MTAB mt_mod[] = {
|
MTAB mt_mod[] = {
|
||||||
{ MTAB_XTD|MTAB_VUN, 0, "write enabled", "WRITEENABLED",
|
{ MTAB_XTD|MTAB_VUN, 0, "write enabled", "WRITEENABLED",
|
||||||
&set_writelock, &show_writelock, NULL, "Write ring in place" },
|
&set_writelock, &show_writelock, NULL, "Write ring in place" },
|
||||||
{ MTAB_XTD|MTAB_VUN, 1, NULL, "LOCKED",
|
{ MTAB_XTD|MTAB_VUN, 1, NULL, "LOCKED",
|
||||||
&set_writelock, NULL, NULL, "no Write ring in place" },
|
&set_writelock, NULL, NULL, "no Write ring in place" },
|
||||||
{MTUF_LDN, 0, "high density", "HIGH", &mt_tape_density, NULL, NULL,
|
{MTUF_LDN, 0, "high density", "HIGH", &mt_tape_density, NULL, NULL,
|
||||||
"556 BPI"},
|
"556 BPI"},
|
||||||
|
@ -393,7 +395,7 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
|
||||||
/* If drive is offline or not attached return not ready */
|
/* If drive is offline or not attached return not ready */
|
||||||
if ((uptr->flags & (UNIT_ATT | MTUF_ONLINE)) !=
|
if ((uptr->flags & (UNIT_ATT | MTUF_ONLINE)) !=
|
||||||
(UNIT_ATT | MTUF_ONLINE)) {
|
(UNIT_ATT | MTUF_ONLINE)) {
|
||||||
sim_printf("Attempt to access offline unit %s%d\n\r", dptr->name, unit);
|
sim_messagef(SCPE_OK, "Attempt to access offline unit %s%d\n\r", dptr->name, unit);
|
||||||
return SCPE_IOERR;
|
return SCPE_IOERR;
|
||||||
}
|
}
|
||||||
/* Check if drive is ready to recieve a command */
|
/* Check if drive is ready to recieve a command */
|
||||||
|
@ -798,6 +800,7 @@ t_stat mt_srv(UNIT * uptr)
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case 0: /* No command, stop tape */
|
case 0: /* No command, stop tape */
|
||||||
uptr->u5 |= MT_RDY; /* Ready since command is done */
|
uptr->u5 |= MT_RDY; /* Ready since command is done */
|
||||||
|
mt_chan[chan] &= ~MTC_BSY;
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "Idle unit=%d\n", unit);
|
sim_debug(DEBUG_DETAIL, dptr, "Idle unit=%d\n", unit);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
|
||||||
|
@ -820,6 +823,7 @@ t_stat mt_srv(UNIT * uptr)
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
|
|
||||||
case MT_RDSB:
|
case MT_RDSB:
|
||||||
|
uptr->u5 &= ~MT_LWR; /* Not write command */
|
||||||
/* Post EOR */
|
/* Post EOR */
|
||||||
if (uptr->u5 & MT_EOR) {
|
if (uptr->u5 & MT_EOR) {
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "Read unit=%d post EOR\n", unit);
|
sim_debug(DEBUG_DETAIL, dptr, "Read unit=%d post EOR\n", unit);
|
||||||
|
@ -900,13 +904,14 @@ t_stat mt_srv(UNIT * uptr)
|
||||||
uptr->u3++;
|
uptr->u3++;
|
||||||
/* Do BCD translation */
|
/* Do BCD translation */
|
||||||
if ((parity_table[ch & 077] ^ (ch & 0100) ^ mode) == 0) {
|
if ((parity_table[ch & 077] ^ (ch & 0100) ^ mode) == 0) {
|
||||||
|
sim_debug(DEBUG_DETAIL, dptr, "%s parity error %d %03o\n",
|
||||||
|
(cmd == MT_RDS) ? "BCD" : "Binary", uptr->u3-1, ch);
|
||||||
#ifdef I7010
|
#ifdef I7010
|
||||||
if (astmode)
|
if (astmode)
|
||||||
ch = 054;
|
ch = 054;
|
||||||
#else
|
|
||||||
chan_set_attn(chan);
|
|
||||||
#endif
|
#endif
|
||||||
chan_set_error(chan);
|
chan_set_error(chan);
|
||||||
|
|
||||||
}
|
}
|
||||||
#if I7090 | I704 | I701
|
#if I7090 | I704 | I701
|
||||||
/* Not needed on decimal machines */
|
/* Not needed on decimal machines */
|
||||||
|
@ -972,6 +977,7 @@ t_stat mt_srv(UNIT * uptr)
|
||||||
mode = 0100;
|
mode = 0100;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case MT_WRSB:
|
case MT_WRSB:
|
||||||
|
uptr->u5 |= MT_LWR; /* write command */
|
||||||
if (uptr->u5 & MT_EGAP) {
|
if (uptr->u5 & MT_EGAP) {
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "Write extended Gap unit=%d\n", unit);
|
sim_debug(DEBUG_DETAIL, dptr, "Write extended Gap unit=%d\n", unit);
|
||||||
uptr->u5 &= ~MT_EGAP;
|
uptr->u5 &= ~MT_EGAP;
|
||||||
|
@ -984,6 +990,8 @@ t_stat mt_srv(UNIT * uptr)
|
||||||
(uptr->u6 > BUFFSIZE) ? DEV_WEOR : 0)) {
|
(uptr->u6 > BUFFSIZE) ? DEV_WEOR : 0)) {
|
||||||
case TIME_ERROR:
|
case TIME_ERROR:
|
||||||
#if I7090 | I701 | I704
|
#if I7090 | I701 | I704
|
||||||
|
uptr->u5 &= ~MT_CMDMSK;
|
||||||
|
uptr->u5 |= MT_SKIP;
|
||||||
/* If no data was written, simulate a write gap */
|
/* If no data was written, simulate a write gap */
|
||||||
if (uptr->u6 == 0) {
|
if (uptr->u6 == 0) {
|
||||||
r = sim_tape_wrgap(uptr, 35);
|
r = sim_tape_wrgap(uptr, 35);
|
||||||
|
@ -993,7 +1001,6 @@ t_stat mt_srv(UNIT * uptr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
chan_set_attn(chan);
|
|
||||||
/* fall through */
|
/* fall through */
|
||||||
|
|
||||||
case END_RECORD:
|
case END_RECORD:
|
||||||
|
@ -1034,6 +1041,7 @@ t_stat mt_srv(UNIT * uptr)
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
|
||||||
case MT_RDB:
|
case MT_RDB:
|
||||||
|
uptr->u5 &= ~MT_LWR; /* not write command */
|
||||||
/* If tape mark pending, return it */
|
/* If tape mark pending, return it */
|
||||||
if (chan_test(chan, DEV_FULL) == 0 && uptr->u5 & MT_MARK) {
|
if (chan_test(chan, DEV_FULL) == 0 && uptr->u5 & MT_MARK) {
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "Read unit=%d post ", unit);
|
sim_debug(DEBUG_DETAIL, dptr, "Read unit=%d post ", unit);
|
||||||
|
@ -1116,6 +1124,7 @@ t_stat mt_srv(UNIT * uptr)
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
|
||||||
case MT_WEF:
|
case MT_WEF:
|
||||||
|
uptr->u5 &= ~MT_LWR; /* not write command */
|
||||||
if (uptr->u5 & MT_EGAP) {
|
if (uptr->u5 & MT_EGAP) {
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "Write extended Gap unit=%d\n", unit);
|
sim_debug(DEBUG_DETAIL, dptr, "Write extended Gap unit=%d\n", unit);
|
||||||
uptr->u5 &= ~MT_EGAP;
|
uptr->u5 &= ~MT_EGAP;
|
||||||
|
@ -1137,8 +1146,17 @@ t_stat mt_srv(UNIT * uptr)
|
||||||
|
|
||||||
case MT_BSR:
|
case MT_BSR:
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "Backspace rec unit=%d ", unit);
|
sim_debug(DEBUG_DETAIL, dptr, "Backspace rec unit=%d ", unit);
|
||||||
|
/* If last command was a write, put extended gap on tape */
|
||||||
|
if (uptr->u5 & MT_LWR) {
|
||||||
|
sim_debug(DEBUG_DETAIL, dptr, "Write extended Gap unit=%d bsr\n", unit);
|
||||||
|
r = sim_tape_wrgap(uptr, 35);
|
||||||
|
uptr->u5 &= ~MT_LWR;
|
||||||
|
sim_activate(uptr, 10*T3_us);
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/* Clear tape mark, command, idle since we will need to change dir */
|
/* Clear tape mark, command, idle since we will need to change dir */
|
||||||
uptr->u5 &= ~(MT_CMDMSK | MT_EOT | MT_RDY);
|
uptr->u5 &= ~(MT_CMDMSK | MT_EOT | MT_RDY | MT_LWR);
|
||||||
r = sim_tape_sprecr(uptr, &reclen);
|
r = sim_tape_sprecr(uptr, &reclen);
|
||||||
if (r != MTSE_BOT)
|
if (r != MTSE_BOT)
|
||||||
uptr->u3 -= GAP_LEN;
|
uptr->u3 -= GAP_LEN;
|
||||||
|
@ -1146,8 +1164,6 @@ t_stat mt_srv(UNIT * uptr)
|
||||||
if (r == MTSE_TMK) {
|
if (r == MTSE_TMK) {
|
||||||
#ifdef I7080
|
#ifdef I7080
|
||||||
chan_set_eof(chan);
|
chan_set_eof(chan);
|
||||||
#else
|
|
||||||
/* We don't set EOF on BSR */
|
|
||||||
#endif
|
#endif
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "MARK\n");
|
sim_debug(DEBUG_DETAIL, dptr, "MARK\n");
|
||||||
sim_activate(uptr, T2_us);
|
sim_activate(uptr, T2_us);
|
||||||
|
@ -1159,7 +1175,7 @@ t_stat mt_srv(UNIT * uptr)
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
|
||||||
case MT_BSF:
|
case MT_BSF:
|
||||||
uptr->u5 &= ~(MT_IDLE | MT_RDY | MT_EOT);
|
uptr->u5 &= ~(MT_IDLE | MT_RDY | MT_EOT | MT_LWR);
|
||||||
r = sim_tape_sprecr(uptr, &reclen);
|
r = sim_tape_sprecr(uptr, &reclen);
|
||||||
if (r != MTSE_BOT)
|
if (r != MTSE_BOT)
|
||||||
uptr->u3 -= GAP_LEN;
|
uptr->u3 -= GAP_LEN;
|
||||||
|
@ -1171,45 +1187,54 @@ t_stat mt_srv(UNIT * uptr)
|
||||||
sim_activate(uptr, T2_us);
|
sim_activate(uptr, T2_us);
|
||||||
} else {
|
} else {
|
||||||
uptr->u3 -= reclen;
|
uptr->u3 -= reclen;
|
||||||
|
sim_debug(DEBUG_DETAIL, dptr, "Backspace file record unit=%d\n", unit);
|
||||||
sim_activate(uptr, T2_us + (reclen * T1_us));
|
sim_activate(uptr, T2_us + (reclen * T1_us));
|
||||||
}
|
}
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
|
||||||
case MT_SKR:
|
case MT_SKR:
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "Skip rec unit=%d ", unit);
|
sim_debug(DEBUG_DETAIL, dptr, "Skip rec unit=%d ", unit);
|
||||||
/* Clear tape mark, command, idle since we will need to change dir */
|
if (uptr->u5 & MT_CLRIND) {
|
||||||
uptr->u5 &= ~(MT_CMDMSK | MT_EOT);
|
sim_debug(DEBUG_DETAIL, dptr, "clear ind\n");
|
||||||
uptr->u5 |= (MT_RDY | MT_IDLE);
|
#if I7010
|
||||||
|
if ((uptr->u5 & MT_MARK) == 0) {
|
||||||
|
chan_clear(chan, STA_PEND);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
chan_clear(chan, STA_TWAIT);
|
||||||
|
uptr->u5 &= ~(MT_CMDMSK | MT_EOT | MT_LWR | MT_MARK | MT_CLRIND);
|
||||||
|
uptr->u5 |= (MT_RDY | MT_IDLE);
|
||||||
|
mt_chan[chan] &= ~MTC_BSY;
|
||||||
|
sim_activate(uptr, (uptr->u6 * T1_us) + T2_us);
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
uptr->u5 |= (MT_CLRIND);
|
||||||
r = sim_tape_sprecf(uptr, &reclen);
|
r = sim_tape_sprecf(uptr, &reclen);
|
||||||
uptr->u3 += GAP_LEN;
|
uptr->u3 += GAP_LEN;
|
||||||
mt_chan[chan] &= ~MTC_BSY;
|
uptr->u6 = reclen;
|
||||||
#if I7010 | I7080
|
#if I7080
|
||||||
chan_clear(chan, STA_TWAIT);
|
chan_clear(chan, STA_TWAIT);
|
||||||
#endif
|
#endif
|
||||||
#ifdef I7010
|
#ifdef I7010
|
||||||
chan_set(chan, STA_PEND);
|
chan_set(chan, STA_PEND);
|
||||||
#else
|
#endif
|
||||||
/* We are like read that transfers nothing */
|
/* We are like read that transfers nothing */
|
||||||
chan_set(chan, DEV_REOR);
|
chan_set(chan, DEV_REOR);
|
||||||
#endif
|
|
||||||
/* We don't set EOF on SKR */
|
/* We don't set EOF on SKR */
|
||||||
if (r == MTSE_TMK) {
|
if (r == MTSE_TMK) {
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "MARK\n");
|
sim_debug(DEBUG_DETAIL, dptr, "MARK\n");
|
||||||
sim_activate(uptr, T1_us);
|
uptr->u5 |= MT_MARK;
|
||||||
|
uptr->u6 = 1;
|
||||||
|
sim_activate(uptr, 2*T1_us);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
#ifdef I7010
|
|
||||||
} else if (r == MTSE_EOM) {
|
|
||||||
chan_set(chan, STA_PEND);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "%d\n", reclen);
|
sim_debug(DEBUG_DETAIL, dptr, "%d\n", reclen);
|
||||||
uptr->u3 += reclen;
|
sim_activate(uptr, 2*T1_us);
|
||||||
sim_activate(uptr, (reclen * T1_us));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MT_ERG:
|
case MT_ERG:
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "Erase unit=%d\n", unit);
|
sim_debug(DEBUG_DETAIL, dptr, "Erase unit=%d\n", unit);
|
||||||
uptr->u5 &= ~(MT_CMDMSK|MT_MARK);
|
uptr->u5 &= ~(MT_CMDMSK|MT_MARK|MT_LWR);
|
||||||
uptr->u5 |= (MT_RDY | MT_IDLE);
|
uptr->u5 |= (MT_RDY | MT_IDLE);
|
||||||
#if I7010 | I7080
|
#if I7010 | I7080
|
||||||
chan_clear(chan, STA_TWAIT);
|
chan_clear(chan, STA_TWAIT);
|
||||||
|
@ -1223,7 +1248,7 @@ t_stat mt_srv(UNIT * uptr)
|
||||||
case MT_REW:
|
case MT_REW:
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "Rewind unit=%d %d %d\n", unit, uptr->u3,
|
sim_debug(DEBUG_DETAIL, dptr, "Rewind unit=%d %d %d\n", unit, uptr->u3,
|
||||||
uptr->u3 / ((uptr->flags & MTUF_LDN) ? 200 : 555) / 1200);
|
uptr->u3 / ((uptr->flags & MTUF_LDN) ? 200 : 555) / 1200);
|
||||||
uptr->u5 &= ~(MT_CMDMSK | MT_IDLE | MT_RDY);
|
uptr->u5 &= ~(MT_CMDMSK | MT_IDLE | MT_RDY | MT_LWR);
|
||||||
if ((uptr->u3 / ((uptr->flags & MTUF_LDN) ? 200 : 555) / 1200) > 2) {
|
if ((uptr->u3 / ((uptr->flags & MTUF_LDN) ? 200 : 555) / 1200) > 2) {
|
||||||
uptr->u5 |= MT_HREW;
|
uptr->u5 |= MT_HREW;
|
||||||
sim_activate(uptr, us_to_ticks(5000000));
|
sim_activate(uptr, us_to_ticks(5000000));
|
||||||
|
@ -1236,7 +1261,7 @@ t_stat mt_srv(UNIT * uptr)
|
||||||
|
|
||||||
case MT_RUN:
|
case MT_RUN:
|
||||||
sim_debug(DEBUG_DETAIL, dptr, "Unload unit=%d\n", unit);
|
sim_debug(DEBUG_DETAIL, dptr, "Unload unit=%d\n", unit);
|
||||||
uptr->u5 &= ~(MT_CMDMSK | MT_IDLE | MT_RDY);
|
uptr->u5 &= ~(MT_CMDMSK | MT_IDLE | MT_RDY | MT_LWR);
|
||||||
uptr->u5 |= MT_UNLOAD;
|
uptr->u5 |= MT_UNLOAD;
|
||||||
if ((uptr->u3 / ((uptr->flags & MTUF_LDN) ? 200 : 555) / 1200) > 2) {
|
if ((uptr->u3 / ((uptr->flags & MTUF_LDN) ? 200 : 555) / 1200) > 2) {
|
||||||
uptr->u5 |= MT_HREW;
|
uptr->u5 |= MT_HREW;
|
||||||
|
@ -1348,6 +1373,7 @@ mt_attach(UNIT * uptr, CONST char *file)
|
||||||
|
|
||||||
if ((r = sim_tape_attach_ex(uptr, file, 0, 0)) != SCPE_OK)
|
if ((r = sim_tape_attach_ex(uptr, file, 0, 0)) != SCPE_OK)
|
||||||
return r;
|
return r;
|
||||||
|
sim_tape_set_dens(uptr, (uptr->flags == MTUF_LDN) ? MT_DENS_200 : MT_DENS_556, NULL, NULL);
|
||||||
uptr->u3 = 0;
|
uptr->u3 = 0;
|
||||||
uptr->u5 |= MT_RDY;
|
uptr->u5 |= MT_RDY;
|
||||||
uptr->flags |= MTUF_ONLINE;
|
uptr->flags |= MTUF_ONLINE;
|
||||||
|
|
|
@ -371,33 +371,30 @@ chan_proc()
|
||||||
|
|
||||||
/* If device put up EOR, terminate transfer. */
|
/* If device put up EOR, terminate transfer. */
|
||||||
if (chan_flags[chan] & DEV_REOR) {
|
if (chan_flags[chan] & DEV_REOR) {
|
||||||
|
sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d EOR %02o Check\n",
|
||||||
|
chan, chan_io_status[chan]);
|
||||||
if (chan_flags[chan] & DEV_WRITE) {
|
if (chan_flags[chan] & DEV_WRITE) {
|
||||||
if ((cmd[chan] & (CHAN_LOAD|CHAN_WM)) == (CHAN_WM|CHAN_LOAD))
|
if ((cmd[chan] & (CHAN_LOAD|CHAN_WM)) == (CHAN_WM|CHAN_LOAD))
|
||||||
M[caddr[chan]++] = 035;
|
M[caddr[chan]++] = 035;
|
||||||
caddr[chan]++;
|
caddr[chan]++;
|
||||||
} else {
|
} else if ((chan_flags[chan] & (CTL_READ|CTL_WRITE)) != 0) {
|
||||||
if ((cmd[chan] & CHAN_NOREC) == 0 &&
|
if ((cmd[chan] & CHAN_NOREC) == 0 &&
|
||||||
(chan_flags[chan] & STA_WAIT) == 0) {
|
(chan_flags[chan] & STA_WAIT) == 0) {
|
||||||
if (MEM_ADDR_OK(caddr[chan])) {
|
if (MEM_ADDR_OK(caddr[chan])) {
|
||||||
if (M[caddr[chan]++] != (WM|077)) {
|
uint8 ch = M[caddr[chan]++];
|
||||||
if (MEM_ADDR_OK(caddr[chan])) {
|
if (ch != (WM|077)) {
|
||||||
chan_io_status[chan] |= IO_CHS_WRL;
|
sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d WRL\n", chan);
|
||||||
if (!MEM_ADDR_OK(caddr[chan]+1)) {
|
chan_io_status[chan] |= IO_CHS_WRL;
|
||||||
caddr[chan]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
chan_io_status[chan] |= IO_CHS_WRL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((cmd[chan] & CHAN_NOREC) && MEM_ADDR_OK(caddr[chan])) {
|
|
||||||
chan_io_status[chan] |= IO_CHS_WRL;
|
|
||||||
if (!MEM_ADDR_OK(caddr[chan]+1)) {
|
|
||||||
chan_io_status[chan] &= ~IO_CHS_WRL;
|
|
||||||
}
|
}
|
||||||
caddr[chan]++;
|
}
|
||||||
}
|
if ((cmd[chan] & CHAN_NOREC) && MEM_ADDR_OK(caddr[chan])) {
|
||||||
|
chan_io_status[chan] |= IO_CHS_WRL;
|
||||||
|
if (!MEM_ADDR_OK(caddr[chan]+1)) {
|
||||||
|
chan_io_status[chan] &= ~IO_CHS_WRL;
|
||||||
|
}
|
||||||
|
caddr[chan]++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
chan_flags[chan] &= ~(STA_ACTIVE|STA_WAIT|DEV_WRITE|DEV_REOR);
|
chan_flags[chan] &= ~(STA_ACTIVE|STA_WAIT|DEV_WRITE|DEV_REOR);
|
||||||
chan_io_status[chan] |= IO_CHS_DONE;
|
chan_io_status[chan] |= IO_CHS_DONE;
|
||||||
|
@ -460,6 +457,7 @@ chan_cmd(uint16 dev, uint16 dcmd, uint32 addr)
|
||||||
/* Unit is busy doing something, wait */
|
/* Unit is busy doing something, wait */
|
||||||
if (chan_flags[chan] & (DEV_SEL|DEV_DISCO|STA_TWAIT|STA_WAIT|STA_ACTIVE))
|
if (chan_flags[chan] & (DEV_SEL|DEV_DISCO|STA_TWAIT|STA_WAIT|STA_ACTIVE))
|
||||||
return SCPE_BUSY;
|
return SCPE_BUSY;
|
||||||
|
sim_debug(DEBUG_CMD, &chan_dev, "chan %d %o cmd %02o %d\n", chan, dev, dcmd, addr);
|
||||||
/* Ok, try and find the unit */
|
/* Ok, try and find the unit */
|
||||||
caddr[chan] = addr;
|
caddr[chan] = addr;
|
||||||
assembly[chan] = 0;
|
assembly[chan] = 0;
|
||||||
|
@ -509,6 +507,7 @@ chan_cmd(uint16 dev, uint16 dcmd, uint32 addr)
|
||||||
chan_flags[chan] |= STA_ACTIVE;
|
chan_flags[chan] |= STA_ACTIVE;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
/* Handle com device special also */
|
||||||
if ((com_dib.mask & dev) == (com_dib.addr & com_dib.mask)) {
|
if ((com_dib.mask & dev) == (com_dib.addr & com_dib.mask)) {
|
||||||
switch(dcmd) {
|
switch(dcmd) {
|
||||||
case IO_RDS: chan_flags[chan] |= CTL_READ; break;
|
case IO_RDS: chan_flags[chan] |= CTL_READ; break;
|
||||||
|
@ -525,6 +524,12 @@ chan_cmd(uint16 dev, uint16 dcmd, uint32 addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
r = chan_issue_cmd(chan, dcmd, dev);
|
r = chan_issue_cmd(chan, dcmd, dev);
|
||||||
|
switch(dcmd) {
|
||||||
|
case IO_RDS: chan_flags[chan] |= CTL_READ; break;
|
||||||
|
case IO_WRS: chan_flags[chan] |= CTL_WRITE; break;
|
||||||
|
case IO_TRS: chan_flags[chan] |= CTL_SNS; break;
|
||||||
|
case IO_CTL: chan_flags[chan] |= CTL_CNTL; break;
|
||||||
|
}
|
||||||
/* Activate channel if select raised */
|
/* Activate channel if select raised */
|
||||||
if (chan_flags[chan] & DEV_SEL) {
|
if (chan_flags[chan] & DEV_SEL) {
|
||||||
chan_flags[chan] |= STA_ACTIVE;
|
chan_flags[chan] |= STA_ACTIVE;
|
||||||
|
@ -560,11 +565,11 @@ chan_write_char(int chan, uint8 * data, int flags)
|
||||||
{
|
{
|
||||||
uint8 ch = *data;
|
uint8 ch = *data;
|
||||||
|
|
||||||
sim_debug(DEBUG_DATA, &chan_dev, "chan %d char %o %d %o %o\n", chan,
|
sim_debug(DEBUG_DATA, &chan_dev, "write chan %d char %o %d %o %o %o\n", chan,
|
||||||
*data, caddr[chan], chan_io_status[chan], flags);
|
*data, caddr[chan], M[caddr[chan]], chan_io_status[chan], flags);
|
||||||
|
|
||||||
if (chan_flags[chan] & STA_WAIT) {
|
if (chan_flags[chan] & STA_WAIT) {
|
||||||
sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d setWR %d %o\n", chan,
|
sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d setWRL %d %o\n", chan,
|
||||||
caddr[chan], chan_io_status[chan]);
|
caddr[chan], chan_io_status[chan]);
|
||||||
chan_io_status[chan] |= IO_CHS_WRL;
|
chan_io_status[chan] |= IO_CHS_WRL;
|
||||||
return END_RECORD;
|
return END_RECORD;
|
||||||
|
@ -586,8 +591,7 @@ chan_write_char(int chan, uint8 * data, int flags)
|
||||||
chan_flags[chan] |= DEV_REOR;
|
chan_flags[chan] |= DEV_REOR;
|
||||||
if (chan_flags[chan] & DEV_SEL)
|
if (chan_flags[chan] & DEV_SEL)
|
||||||
chan_flags[chan] |= DEV_DISCO;
|
chan_flags[chan] |= DEV_DISCO;
|
||||||
chan_io_status[chan] |= IO_CHS_DONE;
|
chan_io_status[chan] |= IO_CHS_DONE|IO_CHS_WRL;
|
||||||
caddr[chan]++;
|
|
||||||
sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d past mem %d %o\n", chan,
|
sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d past mem %d %o\n", chan,
|
||||||
caddr[chan], chan_io_status[chan]);
|
caddr[chan], chan_io_status[chan]);
|
||||||
chan_flags[chan] &= ~(DEV_WRITE|STA_ACTIVE);
|
chan_flags[chan] &= ~(DEV_WRITE|STA_ACTIVE);
|
||||||
|
@ -630,6 +634,8 @@ int
|
||||||
chan_read_char(int chan, uint8 * data, int flags)
|
chan_read_char(int chan, uint8 * data, int flags)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
sim_debug(DEBUG_DATA, &chan_dev, "read chan %d char %o %d %o %o\n", chan,
|
||||||
|
M[caddr[chan]], caddr[chan], chan_io_status[chan], flags);
|
||||||
/* Return END_RECORD if requested */
|
/* Return END_RECORD if requested */
|
||||||
if (flags & DEV_WEOR) {
|
if (flags & DEV_WEOR) {
|
||||||
chan_flags[chan] &= ~(DEV_WEOR);
|
chan_flags[chan] &= ~(DEV_WEOR);
|
||||||
|
@ -656,11 +662,11 @@ chan_read_char(int chan, uint8 * data, int flags)
|
||||||
*data = assembly[chan];
|
*data = assembly[chan];
|
||||||
cmd[chan] &= ~CHAN_WM;
|
cmd[chan] &= ~CHAN_WM;
|
||||||
} else {
|
} else {
|
||||||
if (!MEM_ADDR_OK(caddr[chan]+1)) {
|
if (!MEM_ADDR_OK(caddr[chan])) {
|
||||||
chan_flags[chan] &= ~STA_ACTIVE;
|
chan_flags[chan] &= ~STA_ACTIVE;
|
||||||
if (chan_flags[chan] & DEV_SEL)
|
if (chan_flags[chan] & DEV_SEL)
|
||||||
chan_flags[chan] |= DEV_DISCO;
|
chan_flags[chan] |= DEV_DISCO;
|
||||||
caddr[chan]++;
|
chan_io_status[chan] |= IO_CHS_DONE;
|
||||||
return END_RECORD;
|
return END_RECORD;
|
||||||
}
|
}
|
||||||
assembly[chan] = M[caddr[chan]++];
|
assembly[chan] = M[caddr[chan]++];
|
||||||
|
@ -670,6 +676,7 @@ chan_read_char(int chan, uint8 * data, int flags)
|
||||||
if (chan_flags[chan] & DEV_SEL)
|
if (chan_flags[chan] & DEV_SEL)
|
||||||
chan_flags[chan] |= DEV_DISCO;
|
chan_flags[chan] |= DEV_DISCO;
|
||||||
chan_io_status[chan] |= IO_CHS_DONE;
|
chan_io_status[chan] |= IO_CHS_DONE;
|
||||||
|
sim_debug(DEBUG_DATA, &chan_dev, "read return EOR %d\n", chan);
|
||||||
return END_RECORD;
|
return END_RECORD;
|
||||||
}
|
}
|
||||||
if (cmd[chan] & CHAN_LOAD &&
|
if (cmd[chan] & CHAN_LOAD &&
|
||||||
|
@ -691,6 +698,7 @@ chan_read_char(int chan, uint8 * data, int flags)
|
||||||
chan_flags[chan] |= DEV_DISCO;
|
chan_flags[chan] |= DEV_DISCO;
|
||||||
chan_io_status[chan] |= IO_CHS_DONE;
|
chan_io_status[chan] |= IO_CHS_DONE;
|
||||||
chan_flags[chan] |= DEV_REOR;
|
chan_flags[chan] |= DEV_REOR;
|
||||||
|
sim_debug(DEBUG_DATA, &chan_dev, "read return EOR2 %d\n", chan);
|
||||||
return END_RECORD;
|
return END_RECORD;
|
||||||
} else
|
} else
|
||||||
chan_flags[chan] |= DEV_WRITE;
|
chan_flags[chan] |= DEV_WRITE;
|
||||||
|
|
|
@ -409,6 +409,10 @@ void WriteP(uint32 MA, uint8 v) {
|
||||||
if (fault)
|
if (fault)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
if (MA == 275) {
|
||||||
|
int x = v+1;
|
||||||
|
}
|
||||||
if (reloc && (MA & BBIT) == 0 && MAR > 100) {
|
if (reloc && (MA & BBIT) == 0 && MAR > 100) {
|
||||||
if (low_addr > 0) {
|
if (low_addr > 0) {
|
||||||
MAR += low_addr;
|
MAR += low_addr;
|
||||||
|
@ -596,7 +600,7 @@ sim_instr(void)
|
||||||
if (hst_lnt) /* History enabled? */
|
if (hst_lnt) /* History enabled? */
|
||||||
hst[hst_p].bend = BAR;
|
hst[hst_p].bend = BAR;
|
||||||
}
|
}
|
||||||
chan_io_status[chwait & 07] &= ~0100;
|
chan_io_status[chwait & 07] &= ~IO_CHS_DONE;
|
||||||
chwait = 0;
|
chwait = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1198,7 +1202,7 @@ sim_instr(void)
|
||||||
case OP_IO4:
|
case OP_IO4:
|
||||||
/* Not in protected mode */
|
/* Not in protected mode */
|
||||||
if (prot_enb || reloc) {
|
if (prot_enb || reloc) {
|
||||||
reason = STOP_PROG;
|
reason = STOP_IOCHECK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_STS:
|
case OP_STS:
|
||||||
|
@ -1242,10 +1246,6 @@ sim_instr(void)
|
||||||
break;
|
break;
|
||||||
case OP_UC:
|
case OP_UC:
|
||||||
/* Not in protected mode */
|
/* Not in protected mode */
|
||||||
if (prot_enb || reloc) {
|
|
||||||
reason = STOP_PROG;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Valid forms */
|
/* Valid forms */
|
||||||
/* Op xxx mod */
|
/* Op xxx mod */
|
||||||
|
@ -1323,8 +1323,10 @@ sim_instr(void)
|
||||||
if (cpu_unit.flags & OPTION_PRIO && (pri_enb || timer_enable)) {
|
if (cpu_unit.flags & OPTION_PRIO && (pri_enb || timer_enable)) {
|
||||||
int irq = inquiry;
|
int irq = inquiry;
|
||||||
int ok_irq = 0;
|
int ok_irq = 0;
|
||||||
|
|
||||||
for(i = 1; i < NUM_CHAN; i++ ) {
|
for(i = 1; i < NUM_CHAN; i++ ) {
|
||||||
if ((chan_io_status[i] & 0300) == 0300 &&
|
if ((chan_io_status[i] & (IO_CHS_OVER|IO_CHS_DONE))
|
||||||
|
== (IO_CHS_OVER|IO_CHS_DONE) &&
|
||||||
chan_irq_enb[i])
|
chan_irq_enb[i])
|
||||||
irq = 1;
|
irq = 1;
|
||||||
if (chan_test(i, SNS_ATTN1))
|
if (chan_test(i, SNS_ATTN1))
|
||||||
|
@ -1333,7 +1335,6 @@ sim_instr(void)
|
||||||
irq = 1;
|
irq = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (irq || (timer_enable && timer_irq == 1)) {
|
if (irq || (timer_enable && timer_irq == 1)) {
|
||||||
/* Check if we can interupt this opcode */
|
/* Check if we can interupt this opcode */
|
||||||
switch(op) {
|
switch(op) {
|
||||||
|
@ -1387,24 +1388,25 @@ sim_instr(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ok_irq) {
|
if (ok_irq) {
|
||||||
sim_debug(DEBUG_PRIO, &cpu_dev, "Irq IAR=%d\n",IAR);
|
|
||||||
prot_enb = reloc = 0;
|
prot_enb = reloc = 0;
|
||||||
if (pri_enb && irq) {
|
if (pri_enb && irq) {
|
||||||
|
sim_debug(DEBUG_PRIO, &cpu_dev, "Irq=%d\n",IAR);
|
||||||
IAR = temp;
|
IAR = temp;
|
||||||
AAR = 101;
|
AAR = 101;
|
||||||
op = OP_PRI;
|
op = OP_PRI;
|
||||||
op_mod = CHR_X; /* X */
|
op_mod = CHR_X;
|
||||||
if (hst_lnt) { /* History enabled? */
|
if (hst_lnt) { /* History enabled? */
|
||||||
hst[hst_p].inst[0] = op;
|
hst[hst_p].inst[0] = op;
|
||||||
hst[hst_p].inst[1] = op_mod;
|
hst[hst_p].inst[1] = op_mod;
|
||||||
hst[hst_p].inst[2] = WM;
|
hst[hst_p].inst[2] = WM;
|
||||||
}
|
}
|
||||||
} else if (timer_enable && timer_irq == 1) {
|
} else if (timer_enable && timer_irq == 1) {
|
||||||
|
sim_debug(DEBUG_PRIO, &cpu_dev, "Tim=%d\n",IAR);
|
||||||
IAR = temp;
|
IAR = temp;
|
||||||
AAR = 301;
|
AAR = 301;
|
||||||
timer_irq = 2;
|
timer_irq = 2;
|
||||||
op = OP_PRI;
|
op = OP_PRI;
|
||||||
op_mod = CHR_X; /* X */
|
op_mod = CHR_X;
|
||||||
if (hst_lnt) { /* History enabled? */
|
if (hst_lnt) { /* History enabled? */
|
||||||
hst[hst_p].inst[0] = op;
|
hst[hst_p].inst[0] = op;
|
||||||
hst[hst_p].inst[1] = op_mod;
|
hst[hst_p].inst[1] = op_mod;
|
||||||
|
@ -1980,20 +1982,16 @@ sim_instr(void)
|
||||||
case CHR_STAR: /* * Inq req ch 2 */
|
case CHR_STAR: /* * Inq req ch 2 */
|
||||||
break;
|
break;
|
||||||
case CHR_1: /* 1 Overlap in Proc Ch 1 */
|
case CHR_1: /* 1 Overlap in Proc Ch 1 */
|
||||||
jump = ((chan_io_status[1] & 0300) == 0200) &&
|
jump = chan_active(1);
|
||||||
chan_active(1);
|
|
||||||
break;
|
break;
|
||||||
case CHR_2: /* 2 Overlap in Proc Ch 2 */
|
case CHR_2: /* 2 Overlap in Proc Ch 2 */
|
||||||
jump = ((chan_io_status[2] & 0300) == 0200) &&
|
jump = chan_active(2);
|
||||||
chan_active(2);
|
|
||||||
break;
|
break;
|
||||||
case CHR_4: /* 4 Channel 3 */
|
case CHR_4: /* 4 Channel 3 */
|
||||||
jump = ((chan_io_status[3] & 0300) == 0200) &&
|
jump = chan_active(3);
|
||||||
chan_active(3);
|
|
||||||
break;
|
break;
|
||||||
case CHR_RPARN: /* ) Channel 4 */
|
case CHR_RPARN: /* ) Channel 4 */
|
||||||
jump = ((chan_io_status[4] & 0300) == 0200) &&
|
jump = chan_active(4);
|
||||||
chan_active(4);
|
|
||||||
break;
|
break;
|
||||||
case CHR_9: /* 9 Carriage 9 CH1 */ /* 1401 same */
|
case CHR_9: /* 9 Carriage 9 CH1 */ /* 1401 same */
|
||||||
jump = lpr_chan9[1];
|
jump = lpr_chan9[1];
|
||||||
|
@ -2250,15 +2248,19 @@ sim_instr(void)
|
||||||
sim_six_to_ascii[op], ch & 07,
|
sim_six_to_ascii[op], ch & 07,
|
||||||
(ch & 010)?"": "overlap",
|
(ch & 010)?"": "overlap",
|
||||||
sim_six_to_ascii[op_mod], chan_io_status[ch & 07]);
|
sim_six_to_ascii[op_mod], chan_io_status[ch & 07]);
|
||||||
chan_io_status[ch & 07] = IO_CHS_BUSY;
|
chan_io_status[ch & 07] |= IO_CHS_BUSY;
|
||||||
break;
|
break;
|
||||||
case SCPE_NODEV:
|
case SCPE_NODEV:
|
||||||
|
fprintf(stderr, "No device %d %d\n\r", ch, temp);
|
||||||
|
/* Fall through */
|
||||||
case SCPE_IOERR:
|
case SCPE_IOERR:
|
||||||
chan_io_status[ch & 07] = IO_CHS_NORDY;
|
chan_io_status[ch & 07] |= IO_CHS_NORDY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (CPU_MODEL == 1)
|
if (CPU_MODEL == 1) {
|
||||||
chan_io_status[ch & 07] &= 0177;
|
chan_io_status[ch & 07] &= 0177;
|
||||||
|
chwait = (ch & 07) | 040;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_CC1:
|
case OP_CC1:
|
||||||
|
@ -2274,13 +2276,17 @@ sim_instr(void)
|
||||||
chan_irq_enb[ch & 7] = 0;
|
chan_irq_enb[ch & 7] = 0;
|
||||||
break;
|
break;
|
||||||
case SCPE_BUSY:
|
case SCPE_BUSY:
|
||||||
chan_io_status[ch & 07] = IO_CHS_BUSY;
|
chan_io_status[ch & 07] |= IO_CHS_BUSY;
|
||||||
break;
|
break;
|
||||||
case SCPE_NODEV:
|
case SCPE_NODEV:
|
||||||
case SCPE_IOERR:
|
case SCPE_IOERR:
|
||||||
chan_io_status[ch & 07] = IO_CHS_NORDY;
|
chan_io_status[ch & 07] |= IO_CHS_NORDY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
sim_debug(DEBUG_CMD, &cpu_dev,
|
||||||
|
"%d CC1 on %o %o %s %c %o\n", IAR, ch & 07, temp,
|
||||||
|
(ch & 010)?"": "overlap",
|
||||||
|
sim_six_to_ascii[op_mod], chan_io_status[ch & 07]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_CC2:
|
case OP_CC2:
|
||||||
|
@ -2350,12 +2356,13 @@ sim_instr(void)
|
||||||
switch (chan_cmd(temp, t, 0)) {
|
switch (chan_cmd(temp, t, 0)) {
|
||||||
case SCPE_OK:
|
case SCPE_OK:
|
||||||
chan_io_status[ch & 07] = 0000;
|
chan_io_status[ch & 07] = 0000;
|
||||||
|
chan_irq_enb[ch & 7] = 0;
|
||||||
if (ch & 010) {
|
if (ch & 010) {
|
||||||
chwait = (ch & 07) | 040;
|
chwait = (ch & 07) | 040;
|
||||||
} else if (op_mod == CHR_M) {
|
} else if (op_mod == CHR_M) {
|
||||||
chan_io_status[ch & 07] = IO_CHS_OVER;
|
chan_io_status[ch & 07] = IO_CHS_OVER;
|
||||||
|
chan_irq_enb[ch & 7] = 1;
|
||||||
}
|
}
|
||||||
chan_irq_enb[ch & 7] = 0;
|
|
||||||
sim_debug(DEBUG_CMD, &cpu_dev,
|
sim_debug(DEBUG_CMD, &cpu_dev,
|
||||||
"%d UC on %o %o %s %c %o\n", IAR, ch & 07, temp,
|
"%d UC on %o %o %s %c %o\n", IAR, ch & 07, temp,
|
||||||
(ch & 010)?"": "overlap",
|
(ch & 010)?"": "overlap",
|
||||||
|
@ -2370,8 +2377,9 @@ sim_instr(void)
|
||||||
chan_io_status[ch & 07] = IO_CHS_NORDY;
|
chan_io_status[ch & 07] = IO_CHS_NORDY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (CPU_MODEL == 1)
|
if (CPU_MODEL == 1) {
|
||||||
chan_io_status[ch & 07] &= 0177;
|
chan_io_status[ch & 07] &= 0177;
|
||||||
|
}
|
||||||
sim_interval -= 100;
|
sim_interval -= 100;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2380,12 +2388,19 @@ sim_instr(void)
|
||||||
ch = 1;
|
ch = 1;
|
||||||
checkchan:
|
checkchan:
|
||||||
chan_proc();
|
chan_proc();
|
||||||
|
/* If channel is active, wait for it to finish */
|
||||||
|
if (chan_active(ch)) {
|
||||||
|
chwait = (ch & 07) | 040;
|
||||||
|
IAR = temp-6; /* Still holds the start of the instruction.*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (chan_io_status[ch] & op_mod) {
|
if (chan_io_status[ch] & op_mod) {
|
||||||
jump = 1;
|
jump = 1;
|
||||||
}
|
}
|
||||||
chan_io_status[ch] &= 077;
|
if (pri_enb == 0) {
|
||||||
sim_debug(DEBUG_CMD, &cpu_dev, "Check chan %d %o %x\n", ch,
|
chan_io_status[ch] &= 077;
|
||||||
chan_io_status[ch], chan_flags[ch]);
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_IO2:
|
case OP_IO2:
|
||||||
|
@ -2732,6 +2747,7 @@ sim_instr(void)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CHR_M: /* M - Floating mul */
|
case CHR_M: /* M - Floating mul */
|
||||||
|
CAR = AAR;
|
||||||
temp = oind;
|
temp = oind;
|
||||||
oind = 0;
|
oind = 0;
|
||||||
reason = do_addsub(0);
|
reason = do_addsub(0);
|
||||||
|
@ -2746,16 +2762,18 @@ sim_instr(void)
|
||||||
eoind = 1;
|
eoind = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
CAR = AAR;
|
|
||||||
DAR = 279;
|
|
||||||
/* Scan for A word mark */
|
/* Scan for A word mark */
|
||||||
qsign = 1;
|
zind = 1;
|
||||||
|
ix = 0;
|
||||||
|
AAR = CAR - 2;
|
||||||
ar = ReadP(AAR);
|
ar = ReadP(AAR);
|
||||||
DownReg(AAR);
|
DownReg(AAR);
|
||||||
|
qsign = ((ar & 060) == 040);
|
||||||
while (1) {
|
while (1) {
|
||||||
if ((ar & 017) != 10)
|
if ((ar & 017) != 10)
|
||||||
qsign = 0;
|
zind = 0;
|
||||||
ClrBit(DAR--, WM); /* Clear word marks */
|
ix++;
|
||||||
if (ar & WM || AAR == 0)
|
if (ar & WM || AAR == 0)
|
||||||
break;
|
break;
|
||||||
ar = ReadP(AAR);
|
ar = ReadP(AAR);
|
||||||
|
@ -2763,64 +2781,117 @@ sim_instr(void)
|
||||||
sim_interval -= 4;
|
sim_interval -= 4;
|
||||||
};
|
};
|
||||||
|
|
||||||
ClrBit(DAR--, WM); /* Extra zero */
|
if (zind)
|
||||||
if (qsign)
|
|
||||||
goto zerofacc;
|
goto zerofacc;
|
||||||
|
DAR = 279 - ix;
|
||||||
|
BAR = 297;
|
||||||
|
|
||||||
|
br = ReadP(BAR--);
|
||||||
|
|
||||||
|
/* Compute sign of product */
|
||||||
|
qsign ^= ((br & 060) == 040);
|
||||||
|
qsign = (qsign)?040:060;
|
||||||
|
|
||||||
/* Scan for B word mark */
|
/* Scan for B word mark */
|
||||||
zind = 1;
|
zind = 1;
|
||||||
br = ReadP(BAR--);
|
WriteP(DAR--, WM);
|
||||||
|
temp = DAR;
|
||||||
|
|
||||||
|
/* Copy B over */
|
||||||
while (1) {
|
while (1) {
|
||||||
|
WriteP(DAR--, CHR_0 | qsign);
|
||||||
|
qsign = 0;
|
||||||
if ((br & 017) != 10)
|
if ((br & 017) != 10)
|
||||||
zind = 0;
|
zind = 0;
|
||||||
WriteP(DAR--, br);
|
|
||||||
if (br & WM || BAR == 279)
|
if (br & WM || BAR == 279)
|
||||||
break;
|
break;
|
||||||
br = ReadP(BAR--);
|
br = ReadP(BAR--);
|
||||||
sim_interval -= 2;
|
sim_interval -= 2;
|
||||||
};
|
};
|
||||||
|
SetBit(DAR+1, WM);
|
||||||
|
|
||||||
/* If B zero, scan to A word mark and set B zero */
|
/* If B zero, scan to A word mark and set B zero */
|
||||||
if (zind || qsign)
|
if (zind)
|
||||||
goto zerofacc;
|
goto zerofacc;
|
||||||
|
|
||||||
temp = BAR; /* Save for later */
|
qsign = ReadP(temp) & 060;
|
||||||
BAR = 279;
|
DAR = 297;
|
||||||
AAR = CAR;
|
br = ReadP(DAR);
|
||||||
reason = do_mult();
|
BAR = temp = 279;
|
||||||
if (reason != SCPE_OK)
|
WriteP(BAR--, CHR_0 | qsign);
|
||||||
break;
|
for (;ix > 0; ix--) {
|
||||||
|
WriteP(BAR--, CHR_0);
|
||||||
|
}
|
||||||
|
WriteP(BAR--, CHR_0);
|
||||||
|
zind = 1;
|
||||||
|
/* Do multiple loop until B word mark */
|
||||||
|
while(1) {
|
||||||
|
uint8 bx;
|
||||||
|
/* Interloop, multiply one digit */
|
||||||
|
ch = bcd_bin[br & 0xf];
|
||||||
|
|
||||||
|
while (ch != 0) {
|
||||||
|
WriteP(DAR, bin_bcd[ch - 1] | (br & WM));
|
||||||
|
BAR = temp;
|
||||||
|
bx = ReadP(BAR);
|
||||||
|
cy = 0;
|
||||||
|
AAR = CAR-2;
|
||||||
|
ar = ReadP(AAR);
|
||||||
|
DownReg(AAR);
|
||||||
|
while(1) {
|
||||||
|
ch = bcd_bin[bx & 0xf];
|
||||||
|
ch = bcd_bin[ar & 0xf] + ch + cy;
|
||||||
|
if (ch != 0) /* Clear zero */
|
||||||
|
zind = 0;
|
||||||
|
cy = ch > 9; /* Update carry */
|
||||||
|
WriteP(BAR--, bin_bcd[ch] | (bx & 0160));
|
||||||
|
bx = ReadP(BAR);
|
||||||
|
if (ar & WM)
|
||||||
|
break;
|
||||||
|
ar = ReadP(AAR);
|
||||||
|
DownReg(AAR);
|
||||||
|
sim_interval -= 4;
|
||||||
|
}
|
||||||
|
/* Add carry to next digit */
|
||||||
|
ch = bcd_bin[bx & 0xf] + cy;
|
||||||
|
if (ch != 0) /* Clear zero */
|
||||||
|
zind = 0;
|
||||||
|
sim_interval -= 2;
|
||||||
|
WriteP(BAR--, bin_bcd[ch] | (bx & WM));
|
||||||
|
br = ReadP(DAR);
|
||||||
|
ch = bcd_bin[br & 0xf];
|
||||||
|
}
|
||||||
|
if (br & WM)
|
||||||
|
break;
|
||||||
|
temp--;
|
||||||
|
DAR--;
|
||||||
|
br = ReadP(DAR);
|
||||||
|
}
|
||||||
|
|
||||||
/* Count number of leading zeros */
|
/* Count number of leading zeros */
|
||||||
ix = 0;
|
ix = -1;
|
||||||
BAR++; /* Skip first zero */
|
|
||||||
while (BAR != 280) {
|
while (BAR != 280) {
|
||||||
br = ReadP(++BAR);
|
br = ReadP(BAR);
|
||||||
if ((br & 017) != 10)
|
if ((br & 017) != 10)
|
||||||
break;
|
break;
|
||||||
|
BAR++;
|
||||||
ix++;
|
ix++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Find end of result */
|
||||||
|
|
||||||
|
/* Copy result */
|
||||||
|
br = ReadP(BAR++) | WM;
|
||||||
|
while(DAR != 297) {
|
||||||
|
WriteP(DAR++, br);
|
||||||
|
br = ReadP(BAR++);
|
||||||
|
}
|
||||||
|
WriteP(DAR, br | qsign);
|
||||||
|
BAR = 299;
|
||||||
if (ix != 0) {
|
if (ix != 0) {
|
||||||
DAR = BAR;
|
|
||||||
BAR = 299;
|
|
||||||
if(do_addint(-ix))
|
if(do_addint(-ix))
|
||||||
goto undfacc;
|
goto undfacc;
|
||||||
BAR = DAR;
|
|
||||||
}
|
}
|
||||||
/* Find end of result */
|
|
||||||
CAR = 297;
|
|
||||||
ar = ReadP(CAR--);
|
|
||||||
while((ar & WM) == 0)
|
|
||||||
ar = ReadP(CAR--);
|
|
||||||
br = (ReadP(BAR) & 017) | WM;
|
|
||||||
/* Copy result */
|
|
||||||
while(CAR != 297 && BAR != 279) {
|
|
||||||
WriteP(++CAR, br);
|
|
||||||
br = ReadP(++BAR) & 017;
|
|
||||||
}
|
|
||||||
while(CAR != 297) /* Zero fill rest */
|
|
||||||
WriteP(++CAR, 10);
|
|
||||||
SetBit(297, ReadP(279) & 060); /* Copy sign */
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CHR_D: /* D - Floating div */
|
case CHR_D: /* D - Floating div */
|
||||||
|
@ -2857,8 +2928,10 @@ sim_instr(void)
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Are fractions same size? */
|
/* Are fractions same size? */
|
||||||
if ((br & WM) && (ar & WM) == 0)
|
if ((br & WM) && (ar & WM) == 0) {
|
||||||
|
dind = 1;
|
||||||
goto zerofacc;
|
goto zerofacc;
|
||||||
|
}
|
||||||
|
|
||||||
/* Is A zero? */
|
/* Is A zero? */
|
||||||
if (qsign) {
|
if (qsign) {
|
||||||
|
@ -2912,13 +2985,15 @@ sim_instr(void)
|
||||||
goto zerofacc;
|
goto zerofacc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if exponent went to small */
|
||||||
if (sign) {
|
if (sign) {
|
||||||
eoind = 1;
|
eoind = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ch)
|
if (ch) {
|
||||||
goto undfacc;
|
goto undfacc;
|
||||||
|
}
|
||||||
|
|
||||||
AAR = CAR;
|
AAR = CAR;
|
||||||
/* Do actual divide */
|
/* Do actual divide */
|
||||||
|
@ -3096,20 +3171,16 @@ sim_instr(void)
|
||||||
urec_irq[2] = 0;
|
urec_irq[2] = 0;
|
||||||
break;
|
break;
|
||||||
case CHR_1: /* 1 branch if ch 1 overlap priority */
|
case CHR_1: /* 1 branch if ch 1 overlap priority */
|
||||||
if (chan_irq_enb[1])
|
jump = (chan_io_status[1] & 0200) == 0200;
|
||||||
jump = (chan_io_status[1] & 0300) == 0300;
|
|
||||||
break;
|
break;
|
||||||
case CHR_2: /* 2 branch if ch 2 overlap priority */
|
case CHR_2: /* 2 branch if ch 2 overlap priority */
|
||||||
if (chan_irq_enb[2])
|
jump = (chan_io_status[2] & 0200) == 0200;
|
||||||
jump = (chan_io_status[2] & 0300) == 0300;
|
|
||||||
break;
|
break;
|
||||||
case CHR_3: /* 3 branch if ch 3 overlap priority */
|
case CHR_3: /* 3 branch if ch 3 overlap priority */
|
||||||
if (chan_irq_enb[3])
|
jump = (chan_io_status[3] & 0300) == 0300;
|
||||||
jump = (chan_io_status[3] & 0300) == 0300;
|
|
||||||
break;
|
break;
|
||||||
case CHR_4: /* 4 branch if ch 4 overlap priority */
|
case CHR_4: /* 4 branch if ch 4 overlap priority */
|
||||||
if (chan_irq_enb[4])
|
jump = (chan_io_status[4] & 0300) == 0300;
|
||||||
jump = (chan_io_status[4] & 0300) == 0300;
|
|
||||||
break;
|
break;
|
||||||
case CHR_Q: /* Q branch if inquiry ch 1 */
|
case CHR_Q: /* Q branch if inquiry ch 1 */
|
||||||
jump = inquiry;
|
jump = inquiry;
|
||||||
|
@ -3138,12 +3209,12 @@ sim_instr(void)
|
||||||
break;
|
break;
|
||||||
case CHR_X: /* X branch and exit */
|
case CHR_X: /* X branch and exit */
|
||||||
pri_enb = 0;
|
pri_enb = 0;
|
||||||
sim_debug(DEBUG_PRIO, &cpu_dev, "dis irq\n");
|
sim_debug(DEBUG_PRIO, &cpu_dev, "dis irq\n");
|
||||||
jump = 1;
|
jump = 1;
|
||||||
break;
|
break;
|
||||||
case CHR_E: /* E branch and enter */
|
case CHR_E: /* E branch and enter */
|
||||||
pri_enb = 1;
|
pri_enb = 1;
|
||||||
sim_debug(DEBUG_PRIO, &cpu_dev, "enb irq\n");
|
sim_debug(DEBUG_PRIO, &cpu_dev, "enb irq\n");
|
||||||
jump = 1;
|
jump = 1;
|
||||||
break;
|
break;
|
||||||
case CHR_A: /* A branch if ch1 attention */
|
case CHR_A: /* A branch if ch1 attention */
|
||||||
|
@ -3182,19 +3253,17 @@ sim_instr(void)
|
||||||
"Leave Protect mode %d %d %d\n",
|
"Leave Protect mode %d %d %d\n",
|
||||||
AAR & AMASK, prot_enb, reloc);
|
AAR & AMASK, prot_enb, reloc);
|
||||||
/* If in protect mode, abort */
|
/* If in protect mode, abort */
|
||||||
if ((prot_enb /*|| reloc*/) /*&& (AAR & BBIT) == 0*/) {
|
if (prot_enb) {
|
||||||
reason = STOP_PROG;
|
jump = 1;
|
||||||
|
prot_enb = 0;
|
||||||
|
prot_fault |= 2;
|
||||||
} else {
|
} else {
|
||||||
/* Test protect mode */
|
/* Test protect mode */
|
||||||
if (reloc && (AAR & BBIT) == 0) {
|
jump = 0;
|
||||||
reason = STOP_PROG;
|
prot_enb = 0;
|
||||||
} else {
|
reloc = 0;
|
||||||
jump = 1;
|
high_addr = -1;
|
||||||
prot_enb = 0;
|
low_addr = -1;
|
||||||
reloc = 0;
|
|
||||||
high_addr = -1;
|
|
||||||
low_addr = -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -3218,7 +3287,7 @@ sim_instr(void)
|
||||||
if (cpu_unit.flags & OPTION_PROT) {
|
if (cpu_unit.flags & OPTION_PROT) {
|
||||||
sim_debug(DEBUG_DETAIL, &cpu_dev,
|
sim_debug(DEBUG_DETAIL, &cpu_dev,
|
||||||
"Check prog fault %d %d\n",
|
"Check prog fault %d %d\n",
|
||||||
AAR, prot_fault&2);
|
AAR, prot_fault);
|
||||||
/* If in protect mode, abort */
|
/* If in protect mode, abort */
|
||||||
if (prot_enb) {
|
if (prot_enb) {
|
||||||
reason = STOP_PROG;
|
reason = STOP_PROG;
|
||||||
|
@ -3266,29 +3335,24 @@ sim_instr(void)
|
||||||
sim_debug(DEBUG_DETAIL, &cpu_dev,
|
sim_debug(DEBUG_DETAIL, &cpu_dev,
|
||||||
"Enable relocation + prot %d\n",
|
"Enable relocation + prot %d\n",
|
||||||
AAR & AMASK);
|
AAR & AMASK);
|
||||||
if (prot_enb) {
|
reloc = 1;
|
||||||
reason = STOP_PROG;
|
prot_fault = 0;
|
||||||
} else {
|
BAR = IAR;
|
||||||
prot_enb = 1;
|
IAR = AAR;
|
||||||
reloc = 1;
|
if ((IAR & BBIT) == 0 && low_addr >= 0) {
|
||||||
prot_fault = 0;
|
if (IAR < low_addr)
|
||||||
BAR = IAR;
|
IAR += 100000 - low_addr;
|
||||||
IAR = AAR;
|
else
|
||||||
if ((IAR & BBIT) == 0 && low_addr >= 0) {
|
IAR -= low_addr;
|
||||||
if (IAR < low_addr)
|
|
||||||
IAR += 100000 - low_addr;
|
|
||||||
else
|
|
||||||
IAR -= low_addr;
|
|
||||||
}
|
|
||||||
/* Fix BAR for correct return address */
|
|
||||||
if ((BAR & BBIT) == 0 && low_addr >= 0) {
|
|
||||||
if (BAR < low_addr)
|
|
||||||
BAR += 100000 - low_addr;
|
|
||||||
else
|
|
||||||
BAR -= low_addr;
|
|
||||||
}
|
|
||||||
AAR = BAR;
|
|
||||||
}
|
}
|
||||||
|
/* Fix BAR for correct return address */
|
||||||
|
if ((BAR & BBIT) == 0 && low_addr >= 0) {
|
||||||
|
if (BAR < low_addr)
|
||||||
|
BAR += 100000 - low_addr;
|
||||||
|
else
|
||||||
|
BAR -= low_addr;
|
||||||
|
}
|
||||||
|
AAR = BAR;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -3404,6 +3468,7 @@ check_prot:
|
||||||
"IAR = %d Prog check AAR=%d BAR=%d low=%d high=%d\n",
|
"IAR = %d Prog check AAR=%d BAR=%d low=%d high=%d\n",
|
||||||
IAR, AAR, BAR, low_addr, high_addr);
|
IAR, AAR, BAR, low_addr, high_addr);
|
||||||
prot_fault |= 2;
|
prot_fault |= 2;
|
||||||
|
prot_enb = 0;
|
||||||
reason = 0;
|
reason = 0;
|
||||||
break;
|
break;
|
||||||
case STOP_PROT:
|
case STOP_PROT:
|
||||||
|
@ -3411,6 +3476,7 @@ check_prot:
|
||||||
"IAR = %d Prot check AAR=%d BAR=%d low=%d high=%d\n",
|
"IAR = %d Prot check AAR=%d BAR=%d low=%d high=%d\n",
|
||||||
IAR, AAR, BAR, low_addr, high_addr);
|
IAR, AAR, BAR, low_addr, high_addr);
|
||||||
prot_fault |= 1;
|
prot_fault |= 1;
|
||||||
|
prot_enb = 0;
|
||||||
reason = 0;
|
reason = 0;
|
||||||
break;
|
break;
|
||||||
default: /* Anything else halt sim */
|
default: /* Anything else halt sim */
|
||||||
|
|
|
@ -190,7 +190,6 @@ chan_reset(DEVICE * dptr)
|
||||||
|
|
||||||
/* Clear channel assignment */
|
/* Clear channel assignment */
|
||||||
for (i = 0; i < NUM_CHAN; i++) {
|
for (i = 0; i < NUM_CHAN; i++) {
|
||||||
chan_flags[i] = 0;
|
|
||||||
caddr[i] = 0;
|
caddr[i] = 0;
|
||||||
cmd[i] = 0;
|
cmd[i] = 0;
|
||||||
bcnt[i] = 0;
|
bcnt[i] = 0;
|
||||||
|
@ -361,7 +360,8 @@ int chan_zero_reccnt(int chan) {
|
||||||
|
|
||||||
/* Return next channel data address, advance address by 5 if channel */
|
/* Return next channel data address, advance address by 5 if channel */
|
||||||
uint32 chan_next_addr(int chan) {
|
uint32 chan_next_addr(int chan) {
|
||||||
int unit = 0;
|
uint32 unit = 0;
|
||||||
|
uint32 s_unit = 0;
|
||||||
uint32 addr = 0;
|
uint32 addr = 0;
|
||||||
switch(CHAN_G_TYPE(chan_unit[chan].flags)) {
|
switch(CHAN_G_TYPE(chan_unit[chan].flags)) {
|
||||||
case CHAN_754:
|
case CHAN_754:
|
||||||
|
@ -375,8 +375,9 @@ uint32 chan_next_addr(int chan) {
|
||||||
unit = 8 + 1024 + chan_unit[chan].u3 * 32;
|
unit = 8 + 1024 + chan_unit[chan].u3 * 32;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
addr = load_addr(unit);
|
s_unit = unit;
|
||||||
store_addr(addr + 5, unit);
|
addr = load_addr(&unit);
|
||||||
|
store_addr(addr + 5, &s_unit);
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -831,11 +832,19 @@ chan_cmd(uint16 dev, uint16 dcmd, uint32 addr)
|
||||||
switch(CHAN_G_TYPE(chan_unit[chan].flags)) {
|
switch(CHAN_G_TYPE(chan_unit[chan].flags)) {
|
||||||
case CHAN_754:
|
case CHAN_754:
|
||||||
case CHAN_UREC:
|
case CHAN_UREC:
|
||||||
|
if (M[caddr[chan]] == CHR_GM) {
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
cmd[chan] |= CHAN_NOREC;
|
cmd[chan] |= CHAN_NOREC;
|
||||||
break;
|
break;
|
||||||
case CHAN_7621:
|
case CHAN_7621:
|
||||||
dcmd &= ~ CHAN_ZERO;
|
dcmd &= ~ CHAN_ZERO;
|
||||||
switch(dcmd & 0xf) {
|
switch(dcmd & 0xf) {
|
||||||
|
case 0:
|
||||||
|
if (M[caddr[chan]] == CHR_GM) {
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 1: cmd[chan] |= CHAN_NOREC; break;
|
case 1: cmd[chan] |= CHAN_NOREC; break;
|
||||||
case 2:
|
case 2:
|
||||||
unit = 512 + chan_unit[chan].u3 * 32;
|
unit = 512 + chan_unit[chan].u3 * 32;
|
||||||
|
@ -901,6 +910,7 @@ chan_cmd(uint16 dev, uint16 dcmd, uint32 addr)
|
||||||
chan_flags[chan] &= ~(CHS_EOF|CHS_ERR|CHS_ATTN);
|
chan_flags[chan] &= ~(CHS_EOF|CHS_ERR|CHS_ATTN);
|
||||||
/* Activate channel if select raised */
|
/* Activate channel if select raised */
|
||||||
if (r == SCPE_OK && chan_flags[chan] & DEV_SEL) {
|
if (r == SCPE_OK && chan_flags[chan] & DEV_SEL) {
|
||||||
|
uint32 t_unit;
|
||||||
chan_flags[chan] |= STA_ACTIVE;
|
chan_flags[chan] |= STA_ACTIVE;
|
||||||
irqdev[chan] = dev;
|
irqdev[chan] = dev;
|
||||||
irqflags &= ~(1 << chan);
|
irqflags &= ~(1 << chan);
|
||||||
|
@ -920,13 +930,17 @@ chan_cmd(uint16 dev, uint16 dcmd, uint32 addr)
|
||||||
unit = 512 + chan_unit[chan].u3 * 32;
|
unit = 512 + chan_unit[chan].u3 * 32;
|
||||||
AC[unit+16+5] = 10; /* Set digit next to 0 */
|
AC[unit+16+5] = 10; /* Set digit next to 0 */
|
||||||
AC[unit+24+5] = 10;
|
AC[unit+24+5] = 10;
|
||||||
store_addr(caddr[chan], 8 + unit);
|
sim_debug(DEBUG_DETAIL, &chan_dev,
|
||||||
|
"chan %d set addr %d\n", chan, caddr[chan]);
|
||||||
|
t_unit = 8 + unit;
|
||||||
|
store_addr(caddr[chan], &t_unit);
|
||||||
if (cmd[chan] & CHAN_RECCNT && chan_zero_reccnt(chan)) {
|
if (cmd[chan] & CHAN_RECCNT && chan_zero_reccnt(chan)) {
|
||||||
cmd[chan] &= ~CHAN_RECCNT;
|
cmd[chan] &= ~CHAN_RECCNT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CHAN_7908:
|
case CHAN_7908:
|
||||||
store_addr(caddr[chan], 8+1024 + chan_unit[chan].u3 * 32);
|
t_unit = 8+1024+chan_unit[chan].u3 * 32;
|
||||||
|
store_addr(caddr[chan], &t_unit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,6 +74,10 @@
|
||||||
#define EMULATE2 (2 << UNIT_EMU)
|
#define EMULATE2 (2 << UNIT_EMU)
|
||||||
#define UNIT_V_NONSTOP (UNIT_EMU + 2)
|
#define UNIT_V_NONSTOP (UNIT_EMU + 2)
|
||||||
#define NONSTOP (1 << UNIT_V_NONSTOP)
|
#define NONSTOP (1 << UNIT_V_NONSTOP)
|
||||||
|
#define UNIT_V_IOIRQ (UNIT_V_NONSTOP + 1)
|
||||||
|
#define IOIRQ (1 << UNIT_V_IOIRQ)
|
||||||
|
#define UNIT_V_40K (UNIT_V_IOIRQ + 1)
|
||||||
|
#define EMU40K (1 << UNIT_V_40K)
|
||||||
|
|
||||||
#define CPU_702 0x0
|
#define CPU_702 0x0
|
||||||
#define CPU_705 0x1
|
#define CPU_705 0x1
|
||||||
|
@ -116,8 +120,8 @@ const char *cpu_description (DEVICE *dptr);
|
||||||
|
|
||||||
uint32 read_addr(uint8 *reg, uint8 *zone);
|
uint32 read_addr(uint8 *reg, uint8 *zone);
|
||||||
void write_addr(uint32 addr, uint8 reg, uint8 zone);
|
void write_addr(uint32 addr, uint8 reg, uint8 zone);
|
||||||
uint32 load_addr(int loc);
|
uint32 load_addr(uint32 *loc);
|
||||||
void store_addr(uint32 addr, int loc);
|
void store_addr(uint32 addr, uint32 *loc);
|
||||||
void store_cpu(uint32 addr, int full);
|
void store_cpu(uint32 addr, int full);
|
||||||
void load_cpu(uint32 addr, int full);
|
void load_cpu(uint32 addr, int full);
|
||||||
uint16 get_acstart(uint8 reg);
|
uint16 get_acstart(uint8 reg);
|
||||||
|
@ -197,7 +201,7 @@ uint8 cmp_order[0100] = {
|
||||||
|
|
||||||
#define SIGN (ASIGN|BSIGN)
|
#define SIGN (ASIGN|BSIGN)
|
||||||
#define ZERO (AZERO|BZERO)
|
#define ZERO (AZERO|BZERO)
|
||||||
#define IRQFLAGS (INSTFLAG|MCHCHK|IOCHK|RECCHK|ACOFLAG|SGNFLAG)
|
#define IRQFLAGS (ANYFLAG)
|
||||||
|
|
||||||
uint8 M[MAXMEMSIZE] = { 0 }; /* memory */
|
uint8 M[MAXMEMSIZE] = { 0 }; /* memory */
|
||||||
uint32 EMEMSIZE; /* Physical memory size */
|
uint32 EMEMSIZE; /* Physical memory size */
|
||||||
|
@ -298,6 +302,10 @@ MTAB cpu_mod[] = {
|
||||||
{EMULATE3, EMULATE3, "EMU7053", "EMU7053", NULL, NULL, NULL},
|
{EMULATE3, EMULATE3, "EMU7053", "EMU7053", NULL, NULL, NULL},
|
||||||
{NONSTOP, 0, "PROGRAM", "PROGRAM", NULL, NULL, NULL},
|
{NONSTOP, 0, "PROGRAM", "PROGRAM", NULL, NULL, NULL},
|
||||||
{NONSTOP, NONSTOP, "NONSTOP", "NONSTOP", NULL, NULL, NULL},
|
{NONSTOP, NONSTOP, "NONSTOP", "NONSTOP", NULL, NULL, NULL},
|
||||||
|
{IOIRQ, 0, "NOIOIRQ", "NOIOIRQ", NULL, NULL, NULL},
|
||||||
|
{IOIRQ, IOIRQ, "IOIRQ", "IOIRQ", NULL, NULL, NULL},
|
||||||
|
{EMU40K, 0, "NOEMU40K", "NOEMU40K", NULL, NULL, NULL},
|
||||||
|
{EMU40K, EMU40K, "EMU40K", "EMU40K", NULL, NULL, NULL},
|
||||||
{MTAB_XTD | MTAB_VDV | MTAB_NMO | MTAB_SHP, 0, "HISTORY", "HISTORY",
|
{MTAB_XTD | MTAB_VDV | MTAB_NMO | MTAB_SHP, 0, "HISTORY", "HISTORY",
|
||||||
&cpu_set_hist, &cpu_show_hist},
|
&cpu_set_hist, &cpu_show_hist},
|
||||||
{0}
|
{0}
|
||||||
|
@ -318,7 +326,7 @@ uint16 prev_addr[6 * 256]; /* Previous storage location */
|
||||||
uint16 next_half[6 * 256]; /* Forward half loop locations */
|
uint16 next_half[6 * 256]; /* Forward half loop locations */
|
||||||
|
|
||||||
/*#define ReadP(addr) M[(addr) % EMEMSIZE] */
|
/*#define ReadP(addr) M[(addr) % EMEMSIZE] */
|
||||||
#define WriteP(addr, data) M[(addr) % EMEMSIZE] = data
|
/*#define WriteP(addr, data) M[(addr) % EMEMSIZE] = data */
|
||||||
|
|
||||||
#define Next(reg) if (reg == 0) reg = EMEMSIZE; reg--
|
#define Next(reg) if (reg == 0) reg = EMEMSIZE; reg--
|
||||||
#define Prev5(reg) reg += 5; if (reg > EMEMSIZE) reg -= EMEMSIZE
|
#define Prev5(reg) reg += 5; if (reg > EMEMSIZE) reg -= EMEMSIZE
|
||||||
|
@ -328,7 +336,11 @@ uint16 next_half[6 * 256]; /* Forward half loop locations */
|
||||||
/* Read 1 character from memory, checking for reducancy error. */
|
/* Read 1 character from memory, checking for reducancy error. */
|
||||||
uint8 ReadP(uint32 addr, uint16 flag) {
|
uint8 ReadP(uint32 addr, uint16 flag) {
|
||||||
uint8 value;
|
uint8 value;
|
||||||
value = M[(addr) % EMEMSIZE];
|
addr %= EMEMSIZE;
|
||||||
|
if ((flags & EMU40K) != 0) {
|
||||||
|
addr %= 40000;
|
||||||
|
}
|
||||||
|
value = M[addr];
|
||||||
if (value & 0100) {
|
if (value & 0100) {
|
||||||
if (flag == 0)
|
if (flag == 0)
|
||||||
return value;
|
return value;
|
||||||
|
@ -336,7 +348,7 @@ uint8 ReadP(uint32 addr, uint16 flag) {
|
||||||
} else if (value == 0) {
|
} else if (value == 0) {
|
||||||
flags |= flag|ANYFLAG;
|
flags |= flag|ANYFLAG;
|
||||||
}
|
}
|
||||||
return value & 077;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read 5 characters from memory starting at addr */
|
/* Read 5 characters from memory starting at addr */
|
||||||
|
@ -351,6 +363,15 @@ uint32 Read5(uint32 addr, uint16 flag) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Write 1 character to memory. */
|
||||||
|
void WriteP(uint32 addr, uint8 value) {
|
||||||
|
addr %= EMEMSIZE;
|
||||||
|
if ((flags & EMU40K) != 0) {
|
||||||
|
addr %= 40000;
|
||||||
|
}
|
||||||
|
M[addr] = value;
|
||||||
|
}
|
||||||
|
|
||||||
/* Write 5 characters from memory starting at addr */
|
/* Write 5 characters from memory starting at addr */
|
||||||
void Write5(uint32 addr, uint32 value) {
|
void Write5(uint32 addr, uint32 value) {
|
||||||
WriteP(addr-4, 077 & (value >> (4 * 6)));
|
WriteP(addr-4, 077 & (value >> (4 * 6)));
|
||||||
|
@ -453,11 +474,6 @@ stop_cpu:
|
||||||
if ((cpu_unit.flags & NONSTOP) && (intprog == 0) && intmode != 0 &&
|
if ((cpu_unit.flags & NONSTOP) && (intprog == 0) && intmode != 0 &&
|
||||||
selreg2 == 0 && (IRQFLAGS & flags)) {
|
selreg2 == 0 && (IRQFLAGS & flags)) {
|
||||||
/* Process as interrupt */
|
/* Process as interrupt */
|
||||||
Next(IC); /* Back up to start of instruction */
|
|
||||||
Next(IC);
|
|
||||||
Next(IC);
|
|
||||||
Next(IC);
|
|
||||||
Next(IC);
|
|
||||||
store_cpu(0x3E0, 1);
|
store_cpu(0x3E0, 1);
|
||||||
load_cpu(0x2A0, 0);
|
load_cpu(0x2A0, 0);
|
||||||
intprog = 1;
|
intprog = 1;
|
||||||
|
@ -495,41 +511,8 @@ stop_cpu:
|
||||||
flags &= ~(SGNFLAG|ANYFLAG);
|
flags &= ~(SGNFLAG|ANYFLAG);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (cpu_unit.flags & NONSTOP && intprog && (IRQFLAGS & flags)) {
|
|
||||||
/* Issue sim halt */
|
|
||||||
if (flags & INSTFLAG) {
|
|
||||||
reason = STOP_UUO;
|
|
||||||
flags &= ~ (INSTFLAG|ANYFLAG);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (flags & MCHCHK) {
|
|
||||||
reason = STOP_MMTRP;
|
|
||||||
flags &= ~(MCHCHK|ANYFLAG);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (flags & IOCHK) {
|
|
||||||
reason = STOP_IOCHECK;
|
|
||||||
flags &= ~(IOCHK|ANYFLAG);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (flags & RECCHK) {
|
|
||||||
reason = STOP_RECCHK;
|
|
||||||
flags &= ~(RECCHK|ANYFLAG);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (flags & ACOFLAG) {
|
|
||||||
reason = STOP_ACOFL;
|
|
||||||
flags &= ~(ACOFLAG|ANYFLAG);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (flags & SGNFLAG) {
|
|
||||||
reason = STOP_SIGN;
|
|
||||||
flags &= ~(SGNFLAG|ANYFLAG);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* If we are waiting on I/O, don't fetch */
|
/* If we are waiting on I/O, don't fetch */
|
||||||
if (!chwait) {
|
if (!chwait) {
|
||||||
if (!iowait) {
|
if (!iowait) {
|
||||||
|
@ -763,6 +746,12 @@ stop_cpu:
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (CPU_MODEL == CPU_7080 &&
|
||||||
|
(cpu_unit.flags & IOIRQ) != 0 && reg < 4 &&
|
||||||
|
(flags & EIGHTMODE) == 0) {
|
||||||
|
flags |= INSTFLAG|ANYFLAG;
|
||||||
|
t = 0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
switch((selreg >> 8) & 0xff) {
|
switch((selreg >> 8) & 0xff) {
|
||||||
case 20: /* Tape DS */
|
case 20: /* Tape DS */
|
||||||
|
@ -824,6 +813,15 @@ stop_cpu:
|
||||||
default: /* Drum */
|
default: /* Drum */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (CPU_MODEL == CPU_7080 &&
|
||||||
|
(cpu_unit.flags & IOIRQ) != 0 &&
|
||||||
|
(flags & EIGHTMODE) == 0) {
|
||||||
|
temp = (selreg >> 8) & 0xff;
|
||||||
|
if (temp != 9 && temp != 5) {
|
||||||
|
flags |= INSTFLAG|ANYFLAG;
|
||||||
|
t = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (t) {
|
if (t) {
|
||||||
IC = MAC;
|
IC = MAC;
|
||||||
|
@ -962,8 +960,10 @@ stop_cpu:
|
||||||
cr2 &= 060;
|
cr2 &= 060;
|
||||||
cr2 |= 012;
|
cr2 |= 012;
|
||||||
}
|
}
|
||||||
if ((cr2 & 060) == 040 || (cr2 & 060) == 020)
|
if ((cr2 & 060) == 040 || (cr2 & 060) == 020) {
|
||||||
cr2 |= 0100;
|
cr2 |= 0100;
|
||||||
|
flags |= MCHCHK|ANYFLAG;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
WriteP(MA, cr2);
|
WriteP(MA, cr2);
|
||||||
Next(MA);
|
Next(MA);
|
||||||
|
@ -1045,6 +1045,9 @@ stop_cpu:
|
||||||
AC[addr] = 10;
|
AC[addr] = 10;
|
||||||
} else if (AC[addr] != 10)
|
} else if (AC[addr] != 10)
|
||||||
flags &= ~(ZERO & fmsk); /* No zero, adjust flag */
|
flags &= ~(ZERO & fmsk); /* No zero, adjust flag */
|
||||||
|
if (AC[addr] & 0100) {
|
||||||
|
flags |= MCHCHK|ANYFLAG;
|
||||||
|
}
|
||||||
MAC--;
|
MAC--;
|
||||||
addr = next_addr[addr];
|
addr = next_addr[addr];
|
||||||
sim_interval --; /* count down */
|
sim_interval --; /* count down */
|
||||||
|
@ -1405,6 +1408,12 @@ stop_cpu:
|
||||||
chan_chr_13();
|
chan_chr_13();
|
||||||
memset(ioflags, 0, sizeof(ioflags));
|
memset(ioflags, 0, sizeof(ioflags));
|
||||||
flags &= ~(IRQFLAGS);
|
flags &= ~(IRQFLAGS);
|
||||||
|
if (CPU_MODEL == CPU_7080 &&
|
||||||
|
(cpu_unit.flags & IOIRQ) != 0 &&
|
||||||
|
(flags & EIGHTMODE) == 0 &&
|
||||||
|
((selreg >> 8) & 0xff) != 5) {
|
||||||
|
flags |= ANYFLAG|INSTFLAG;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 14: /* EEM */
|
case 14: /* EEM */
|
||||||
|
@ -1521,6 +1530,12 @@ stop_cpu:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (iowait == 0 && CPU_MODEL == CPU_7080 &&
|
||||||
|
(cpu_unit.flags & IOIRQ) != 0 &&
|
||||||
|
(flags & EIGHTMODE) == 0 &&
|
||||||
|
((selreg >> 8) & 0xff) != 5) {
|
||||||
|
flags |= ANYFLAG|INSTFLAG;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_RD: /* READ */
|
case OP_RD: /* READ */
|
||||||
|
@ -1538,6 +1553,12 @@ stop_cpu:
|
||||||
flags |= ANYFLAG|INSTFLAG;
|
flags |= ANYFLAG|INSTFLAG;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (iowait == 0 && CPU_MODEL == CPU_7080 &&
|
||||||
|
(cpu_unit.flags & IOIRQ) != 0 &&
|
||||||
|
(flags & EIGHTMODE) == 0 &&
|
||||||
|
((selreg >> 8) & 0xff) != 5) {
|
||||||
|
flags |= ANYFLAG|INSTFLAG;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_WR: /* WRITE */
|
case OP_WR: /* WRITE */
|
||||||
|
@ -1555,6 +1576,12 @@ stop_cpu:
|
||||||
flags |= ANYFLAG|INSTFLAG;
|
flags |= ANYFLAG|INSTFLAG;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (iowait == 0 && CPU_MODEL == CPU_7080 &&
|
||||||
|
(cpu_unit.flags & IOIRQ) != 0 &&
|
||||||
|
(flags & EIGHTMODE) == 0 &&
|
||||||
|
((selreg >> 8) & 0xff) != 5) {
|
||||||
|
flags |= ANYFLAG|INSTFLAG;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_WRE: /* WR ER */
|
case OP_WRE: /* WR ER */
|
||||||
|
@ -1572,11 +1599,25 @@ stop_cpu:
|
||||||
flags |= ANYFLAG|INSTFLAG;
|
flags |= ANYFLAG|INSTFLAG;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (iowait == 0 && CPU_MODEL == CPU_7080 &&
|
||||||
|
(cpu_unit.flags & IOIRQ) != 0 &&
|
||||||
|
(flags & EIGHTMODE) == 0 &&
|
||||||
|
((selreg >> 8) & 0xff) != 5) {
|
||||||
|
flags |= ANYFLAG|INSTFLAG;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_RWW: /* RWW 705 only */
|
case OP_RWW: /* RWW 705 only */
|
||||||
MAC2 = MAC;
|
MAC2 = MAC;
|
||||||
selreg2 = selreg | 0x8000;
|
if (CPU_MODEL == CPU_7080 &&
|
||||||
|
(cpu_unit.flags & IOIRQ) != 0 &&
|
||||||
|
(flags & EIGHTMODE) == 0 &&
|
||||||
|
((selreg >> 8) & 0xff) != 5) {
|
||||||
|
flags |= ANYFLAG|INSTFLAG;
|
||||||
|
selreg2 = selreg;
|
||||||
|
} else {
|
||||||
|
selreg2 = selreg | 0x8000;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* 7080 opcodes */
|
/* 7080 opcodes */
|
||||||
|
@ -1786,7 +1827,7 @@ stop_cpu:
|
||||||
case 14: /* SMT */
|
case 14: /* SMT */
|
||||||
write_addr(MAC2, 0, 0);
|
write_addr(MAC2, 0, 0);
|
||||||
WriteP(MA, 10); /* Finish with zero */
|
WriteP(MA, 10); /* Finish with zero */
|
||||||
store_addr(MAC2, addr);
|
store_addr(MAC2, &addr);
|
||||||
sim_interval -= 10;
|
sim_interval -= 10;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2186,8 +2227,6 @@ stop_cpu:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
t = ReadP(MA, 0);
|
t = ReadP(MA, 0);
|
||||||
if (t & 0100)
|
|
||||||
flags |= MCHCHK|ANYFLAG;
|
|
||||||
sim_interval --; /* count down */
|
sim_interval --; /* count down */
|
||||||
switch(reg) {
|
switch(reg) {
|
||||||
case 0: /* Nop */
|
case 0: /* Nop */
|
||||||
|
@ -2198,12 +2237,20 @@ stop_cpu:
|
||||||
case 4: /* 8 */
|
case 4: /* 8 */
|
||||||
case 5: /* A */
|
case 5: /* A */
|
||||||
case 6: /* B */
|
case 6: /* B */
|
||||||
|
if (t & 0100)
|
||||||
|
flags |= MCHCHK|ANYFLAG;
|
||||||
t &= ~(1<<(reg-1));
|
t &= ~(1<<(reg-1));
|
||||||
|
t &= 077;
|
||||||
break;
|
break;
|
||||||
case 7: /* Reverse A */
|
case 7: /* Reverse A */
|
||||||
|
if (t & 0100)
|
||||||
|
flags |= MCHCHK|ANYFLAG;
|
||||||
t ^= 020;
|
t ^= 020;
|
||||||
|
t &= 077;
|
||||||
break;
|
break;
|
||||||
case 8: /* Reverse C */
|
case 8: /* Reverse C */
|
||||||
|
if (t & 0100)
|
||||||
|
flags |= MCHCHK;
|
||||||
t = M[MA % EMEMSIZE] ^ 0100;
|
t = M[MA % EMEMSIZE] ^ 0100;
|
||||||
break;
|
break;
|
||||||
case 9: /* 1 */
|
case 9: /* 1 */
|
||||||
|
@ -2212,7 +2259,10 @@ stop_cpu:
|
||||||
case 12: /* 8 */
|
case 12: /* 8 */
|
||||||
case 13: /* A */
|
case 13: /* A */
|
||||||
case 14: /* B */
|
case 14: /* B */
|
||||||
|
if (t & 0100)
|
||||||
|
flags |= MCHCHK|ANYFLAG;
|
||||||
t |= 1<<(reg-9);
|
t |= 1<<(reg-9);
|
||||||
|
t &= 077;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
WriteP(MA, t);
|
WriteP(MA, t);
|
||||||
|
@ -2224,7 +2274,7 @@ stop_cpu:
|
||||||
}
|
}
|
||||||
if (hst_lnt) { /* history enabled? */
|
if (hst_lnt) { /* history enabled? */
|
||||||
hst[hst_p].flags = flags;
|
hst[hst_p].flags = flags;
|
||||||
addr = get_acstart(reg);
|
addr = spc;
|
||||||
for (t = 0; t < 254; t++) {
|
for (t = 0; t < 254; t++) {
|
||||||
hst[hst_p].store[t] = AC[addr];
|
hst[hst_p].store[t] = AC[addr];
|
||||||
addr = next_addr[addr];
|
addr = next_addr[addr];
|
||||||
|
@ -2356,7 +2406,7 @@ void write_addr(uint32 addr, uint8 reg, uint8 zone) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store converted address in storage */
|
/* Store converted address in storage */
|
||||||
void store_addr(uint32 addr, int loc) {
|
void store_addr(uint32 addr, uint32 *loc) {
|
||||||
uint8 value[4];
|
uint8 value[4];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -2386,7 +2436,7 @@ void store_addr(uint32 addr, int loc) {
|
||||||
if ((cpu_unit.flags & EMULATE2))
|
if ((cpu_unit.flags & EMULATE2))
|
||||||
value[3] |= (addr & 0xc) << 2;
|
value[3] |= (addr & 0xc) << 2;
|
||||||
else /* 20k */
|
else /* 20k */
|
||||||
value[3] |= (addr & 0x8) << 2;
|
value[3] |= (addr & 0xc) << 2;
|
||||||
break;
|
break;
|
||||||
case CPU_702: /* 702 */
|
case CPU_702: /* 702 */
|
||||||
break;
|
break;
|
||||||
|
@ -2398,32 +2448,37 @@ void store_addr(uint32 addr, int loc) {
|
||||||
value[i] &= 0360;
|
value[i] &= 0360;
|
||||||
if (value[i] == 0)
|
if (value[i] == 0)
|
||||||
value[i] = 10;
|
value[i] = 10;
|
||||||
AC[loc] = value[i];
|
AC[*loc] = value[i];
|
||||||
loc = next_addr[loc];
|
*loc = next_addr[*loc];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Read address from storage */
|
/* Read address from storage */
|
||||||
uint32 load_addr(int loc) {
|
uint32 load_addr(uint32 *loc) {
|
||||||
uint8 t;
|
uint8 t;
|
||||||
|
uint8 f;
|
||||||
uint8 zone;
|
uint8 zone;
|
||||||
uint32 addr;
|
uint32 addr;
|
||||||
|
|
||||||
t = AC[loc]; /* First digit */
|
t = AC[*loc]; /* First digit */
|
||||||
loc = next_addr[loc];
|
f = t;
|
||||||
zone = (t & 060) >> 2;
|
zone = (t & 060) >> 2;
|
||||||
addr = bcd_bin[t & 0xf];
|
addr = bcd_bin[t & 0xf];
|
||||||
t = AC[loc]; /* Second digit */
|
*loc = next_addr[*loc];
|
||||||
loc = next_addr[loc];
|
t = AC[*loc]; /* Second digit */
|
||||||
|
f |= t;
|
||||||
addr += dig2[bcd_bin[t & 0xf]];
|
addr += dig2[bcd_bin[t & 0xf]];
|
||||||
t = AC[loc]; /* Read third digit */
|
*loc = next_addr[*loc];
|
||||||
loc = next_addr[loc];
|
t = AC[*loc]; /* Read third digit */
|
||||||
|
f |= t;
|
||||||
addr += dig3[bcd_bin[t & 0xf]];
|
addr += dig3[bcd_bin[t & 0xf]];
|
||||||
t = AC[loc]; /* Save High order address */
|
*loc = next_addr[*loc];
|
||||||
loc = next_addr[loc];
|
t = AC[*loc]; /* Save High order address */
|
||||||
|
f |= t;
|
||||||
zone |= (t & 060) >> 4;
|
zone |= (t & 060) >> 4;
|
||||||
addr += dig4[bcd_bin[t & 0xf]];
|
addr += dig4[bcd_bin[t & 0xf]];
|
||||||
|
*loc = next_addr[*loc];
|
||||||
switch (cpu_type) {
|
switch (cpu_type) {
|
||||||
case CPU_7080: /* 7080 */
|
case CPU_7080: /* 7080 */
|
||||||
break;
|
break;
|
||||||
|
@ -2432,50 +2487,65 @@ uint32 load_addr(int loc) {
|
||||||
if (cpu_unit.flags & EMULATE2)
|
if (cpu_unit.flags & EMULATE2)
|
||||||
zone &= 3; /* 40k */
|
zone &= 3; /* 40k */
|
||||||
else
|
else
|
||||||
zone &= 013; /* 80k */
|
zone &= 7; /* 80k */
|
||||||
break;
|
break;
|
||||||
case CPU_705: /* 705 */
|
case CPU_705: /* 705 */
|
||||||
if (cpu_unit.flags & EMULATE2)
|
if (cpu_unit.flags & EMULATE2)
|
||||||
zone &= 3; /* 40K */
|
zone &= 3; /* 40K */
|
||||||
else
|
else
|
||||||
zone &= 1; /* 20k */
|
zone &= 3; /* 20k */
|
||||||
break;
|
break;
|
||||||
case CPU_702: /* 702 */
|
case CPU_702: /* 702 */
|
||||||
zone = 0; /* 10k Memory */
|
zone = 0; /* 10k Memory */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
addr += dig_zone[zone];
|
addr += dig_zone[zone];
|
||||||
|
/* Set Machine Check if got redundant data */
|
||||||
|
if (f & 0100) {
|
||||||
|
flags |= MCHCHK|ANYFLAG;
|
||||||
|
}
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store converted hex address in storage */
|
/* Store converted hex address in storage */
|
||||||
void store_hex(uint32 addr, int loc) {
|
void store_hex(uint32 addr, uint32 *loc) {
|
||||||
/* Convert address into BCD first */
|
/* Convert address into BCD first */
|
||||||
AC[loc] = bin_bcd[addr & 0xf];
|
AC[*loc] = bin_bcd[addr & 0xf];
|
||||||
loc = next_addr[loc];
|
*loc = next_addr[*loc];
|
||||||
AC[loc] = bin_bcd[(addr >> 4) & 0xf];
|
AC[*loc] = bin_bcd[(addr >> 4) & 0xf];
|
||||||
loc = next_addr[loc];
|
*loc = next_addr[*loc];
|
||||||
AC[loc] = bin_bcd[(addr >> 8) & 0xf];
|
AC[*loc] = bin_bcd[(addr >> 8) & 0xf];
|
||||||
loc = next_addr[loc];
|
*loc = next_addr[*loc];
|
||||||
AC[loc] = bin_bcd[(addr >> 12) & 0xf];
|
AC[*loc] = bin_bcd[(addr >> 12) & 0xf];
|
||||||
|
*loc = next_addr[*loc];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read hex address from storage */
|
/* Read hex address from storage */
|
||||||
uint32 load_hex(int loc) {
|
uint32 load_hex(uint32 *loc) {
|
||||||
uint8 t;
|
uint8 t;
|
||||||
|
uint8 f;
|
||||||
uint32 addr;
|
uint32 addr;
|
||||||
|
|
||||||
t = AC[loc]; /* First digit */
|
t = AC[*loc]; /* First digit */
|
||||||
|
f = t;
|
||||||
addr = bcd_bin[t & 0xf];
|
addr = bcd_bin[t & 0xf];
|
||||||
loc = next_addr[loc];
|
*loc = next_addr[*loc];
|
||||||
t = AC[loc]; /* Second digit */
|
t = AC[*loc]; /* Second digit */
|
||||||
|
f |= t;
|
||||||
addr += bcd_bin[t & 0xf] << 4;
|
addr += bcd_bin[t & 0xf] << 4;
|
||||||
loc = next_addr[loc];
|
*loc = next_addr[*loc];
|
||||||
t = AC[loc]; /* Read third digit */
|
t = AC[*loc]; /* Read third digit */
|
||||||
|
f |= t;
|
||||||
addr += bcd_bin[t & 0xf] << 8;
|
addr += bcd_bin[t & 0xf] << 8;
|
||||||
loc = next_addr[loc];
|
*loc = next_addr[*loc];
|
||||||
t = AC[loc]; /* Save High order address */
|
t = AC[*loc]; /* Save High order address */
|
||||||
|
f |= t;
|
||||||
addr += bcd_bin[t & 0xf] << 12;
|
addr += bcd_bin[t & 0xf] << 12;
|
||||||
|
*loc = next_addr[*loc];
|
||||||
|
/* Set Machine Check if got redundant data */
|
||||||
|
if (f & 0100) {
|
||||||
|
flags |= MCHCHK|ANYFLAG;
|
||||||
|
}
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2497,89 +2567,137 @@ uint16 get_acstart(uint8 reg) {
|
||||||
|
|
||||||
/* Store CPU state in CASU 15 */
|
/* Store CPU state in CASU 15 */
|
||||||
void store_cpu(uint32 addr, int full) {
|
void store_cpu(uint32 addr, int full) {
|
||||||
uint8 t;
|
uint8 t;
|
||||||
|
|
||||||
store_addr(IC, addr);
|
store_addr(IC, &addr);
|
||||||
addr = next_addr[addr];
|
|
||||||
addr = next_addr[addr];
|
|
||||||
addr = next_addr[addr];
|
|
||||||
addr = next_addr[addr];
|
|
||||||
/* Save status characters */
|
/* Save status characters */
|
||||||
t = flags & 0xf;
|
t = flags & 0xf;
|
||||||
AC[addr] = 040 | ((t + 8) & 027);
|
AC[addr] = 040 | ((t + 8) & 027);
|
||||||
addr = next_addr[addr];
|
addr = next_addr[addr];
|
||||||
t = (flags >> 4) & 0xf;
|
t = (flags >> 4) & 0xf;
|
||||||
AC[addr] = 040 | ((t + 8) & 027);
|
AC[addr] = 040 | ((t + 8) & 027);
|
||||||
addr = next_addr[addr];
|
addr = next_addr[addr];
|
||||||
t = (flags >> 8) & 0xf;
|
t = (flags >> 8) & 0xf;
|
||||||
AC[addr] = 040 | ((t + 8) & 027);
|
AC[addr] = 040 | ((t + 8) & 027);
|
||||||
addr = next_addr[addr];
|
addr = next_addr[addr];
|
||||||
t = (flags >> 12) & 0x3;
|
t = (flags >> 12) & 0x3;
|
||||||
AC[addr] = 040 | t;
|
AC[addr] = 040 | t;
|
||||||
if (full) {
|
if (full) {
|
||||||
addr = next_addr[addr];
|
addr = next_addr[addr];
|
||||||
AC[addr] = bin_bcd[spc & 7];
|
AC[addr] = bin_bcd[spc & 7];
|
||||||
addr = next_addr[addr];
|
addr = next_addr[addr];
|
||||||
AC[addr] = bin_bcd[(spc >> 3) & 3];
|
AC[addr] = bin_bcd[(spc >> 3) & 3];
|
||||||
addr = next_addr[addr];
|
addr = next_addr[addr];
|
||||||
AC[addr] = bin_bcd[(spc >> 5) & 7];
|
AC[addr] = bin_bcd[(spc >> 5) & 7];
|
||||||
addr = next_addr[addr];
|
addr = next_addr[addr];
|
||||||
AC[addr] = bin_bcd[(spc >> 8) & 7];
|
AC[addr] = bin_bcd[(spc >> 8) & 7];
|
||||||
addr = next_addr[addr];
|
addr = next_addr[addr];
|
||||||
for(; addr < 0x3F8; addr++)
|
AC[addr] = 10;
|
||||||
AC[addr] = 10;
|
addr = next_addr[addr];
|
||||||
for(; addr < 0x400; addr++)
|
AC[addr] = 10;
|
||||||
AC[addr] = 0;
|
addr = next_addr[addr];
|
||||||
store_addr(MAC2, 0x3F0);
|
AC[addr] = 10;
|
||||||
store_hex(selreg, 0x3F8);
|
addr = next_addr[addr];
|
||||||
}
|
AC[addr] = 10;
|
||||||
|
addr = next_addr[addr];
|
||||||
|
store_addr(MAC2, &addr);
|
||||||
|
AC[addr] = 10;
|
||||||
|
addr = next_addr[addr];
|
||||||
|
AC[addr] = 10;
|
||||||
|
addr = next_addr[addr];
|
||||||
|
AC[addr] = 10;
|
||||||
|
addr = next_addr[addr];
|
||||||
|
AC[addr] = 10;
|
||||||
|
addr = next_addr[addr];
|
||||||
|
store_hex(selreg, &addr);
|
||||||
|
AC[addr] = 0;
|
||||||
|
addr = next_addr[addr];
|
||||||
|
AC[addr] = 0;
|
||||||
|
addr = next_addr[addr];
|
||||||
|
AC[addr] = 0;
|
||||||
|
addr = next_addr[addr];
|
||||||
|
AC[addr] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load CPU State from storage */
|
/* Load CPU State from storage */
|
||||||
void load_cpu(uint32 addr, int full) {
|
void load_cpu(uint32 addr, int full) {
|
||||||
uint8 t;
|
uint8 t;
|
||||||
|
uint8 f;
|
||||||
|
|
||||||
IC = load_addr(addr);
|
|
||||||
addr = next_addr[addr];
|
|
||||||
addr = next_addr[addr];
|
|
||||||
addr = next_addr[addr];
|
|
||||||
addr = next_addr[addr];
|
|
||||||
flags = 0;
|
flags = 0;
|
||||||
t = AC[addr++];
|
IC = load_addr(&addr);
|
||||||
|
t = AC[addr];
|
||||||
|
addr = next_addr[addr];
|
||||||
|
f = t;
|
||||||
flags |= (t & 0x7) | ((t >> 1) & 0x8);
|
flags |= (t & 0x7) | ((t >> 1) & 0x8);
|
||||||
t = AC[addr++];
|
t = AC[addr];
|
||||||
|
addr = next_addr[addr];
|
||||||
|
f |= t;
|
||||||
flags |= ((t & 0x7) | ((t >> 1) & 0x8)) << 4;
|
flags |= ((t & 0x7) | ((t >> 1) & 0x8)) << 4;
|
||||||
t = AC[addr++];
|
t = AC[addr];
|
||||||
|
addr = next_addr[addr];
|
||||||
|
f |= t;
|
||||||
flags |= ((t & 0x7) | ((t >> 1) & 0x8)) << 8;
|
flags |= ((t & 0x7) | ((t >> 1) & 0x8)) << 8;
|
||||||
t = AC[addr++];
|
t = AC[addr];
|
||||||
|
addr = next_addr[addr];
|
||||||
|
f |= t;
|
||||||
flags |= (t & 0x3) << 12;
|
flags |= (t & 0x3) << 12;
|
||||||
/* Adjust Max memory if mode changed */
|
/* Update emulation mode */
|
||||||
EMEMSIZE = MEMSIZE;
|
if (CPU_MODEL == CPU_7080) {
|
||||||
if (flags & EIGHTMODE) {
|
if (flags & EIGHTMODE) {
|
||||||
cpu_type = CPU_7080;
|
EMEMSIZE = MEMSIZE;
|
||||||
} else {
|
cpu_type = CPU_7080;
|
||||||
cpu_type = (cpu_unit.flags & EMULATE3)? CPU_7053:CPU_705;
|
} else {
|
||||||
EMEMSIZE = MEMSIZE;
|
cpu_type = (cpu_unit.flags & EMULATE3)? CPU_7053:CPU_705;
|
||||||
if (cpu_unit.flags & EMULATE2 && EMEMSIZE > 40000)
|
EMEMSIZE = MEMSIZE;
|
||||||
EMEMSIZE = 40000;
|
if (cpu_unit.flags & EMULATE2 && EMEMSIZE > 40000)
|
||||||
if (cpu_type == CPU_705 && (cpu_unit.flags & EMULATE2) == 0
|
EMEMSIZE = 40000;
|
||||||
&& EMEMSIZE > 20000)
|
if (cpu_type == CPU_705 && (cpu_unit.flags & EMULATE2) == 0 &&
|
||||||
EMEMSIZE = 20000;
|
EMEMSIZE > 20000)
|
||||||
if (EMEMSIZE > 80000)
|
EMEMSIZE = 20000;
|
||||||
EMEMSIZE = 80000;
|
if (EMEMSIZE > 80000)
|
||||||
|
EMEMSIZE = 80000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (full) {
|
if (full) {
|
||||||
spc = bcd_bin[AC[addr++]] & 07; /* Units digit */
|
int i;
|
||||||
|
t = AC[addr];
|
||||||
|
addr = next_addr[addr];
|
||||||
|
f |= t;
|
||||||
|
spc = bcd_bin[t & 0xf] & 07; /* Units digit */
|
||||||
/* One of words */
|
/* One of words */
|
||||||
spc += (bcd_bin[AC[addr++]] & 3) << 3; /* Tens digit */
|
t = AC[addr];
|
||||||
|
addr = next_addr[addr];
|
||||||
|
f |= t;
|
||||||
|
spc += (bcd_bin[t & 0xf] & 3) << 3; /* Tens digit */
|
||||||
/* One of four word sets */
|
/* One of four word sets */
|
||||||
spc += (bcd_bin[AC[addr++]] & 7) << 5; /* Hundreds */
|
t = AC[addr];
|
||||||
|
addr = next_addr[addr];
|
||||||
|
f |= t;
|
||||||
|
spc += (bcd_bin[t & 0xf] & 7) << 5; /* Hundreds */
|
||||||
/* Bank */
|
/* Bank */
|
||||||
spc += (bcd_bin[AC[addr++]] & 7) << 8; /* Thousands */
|
t = AC[addr];
|
||||||
addr += 4;
|
addr = next_addr[addr];
|
||||||
MAC2 = load_addr(addr);
|
f |= t;
|
||||||
addr += 8;
|
spc += (bcd_bin[t & 0xf] & 7) << 8; /* Thousands */
|
||||||
selreg = load_hex(addr);
|
for (i = 0; i < 4; i++) {
|
||||||
|
f |= AC[addr];
|
||||||
|
addr = next_addr[addr];
|
||||||
|
}
|
||||||
|
MAC2 = load_addr(&addr);
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
f |= AC[addr];
|
||||||
|
addr = next_addr[addr];
|
||||||
|
}
|
||||||
|
selreg = load_hex(&addr);
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
f |= AC[addr];
|
||||||
|
addr = next_addr[addr];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (f & 0100) {
|
||||||
|
flags |= MCHCHK | ANYFLAG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2825,6 +2943,7 @@ do_divide(int reg, uint16 fmsk)
|
||||||
int remtrig;
|
int remtrig;
|
||||||
int carry;
|
int carry;
|
||||||
int dzt;
|
int dzt;
|
||||||
|
int over;
|
||||||
|
|
||||||
/* Step I, put storage mark before start of AC */
|
/* Step I, put storage mark before start of AC */
|
||||||
at = 0;
|
at = 0;
|
||||||
|
@ -2833,6 +2952,7 @@ do_divide(int reg, uint16 fmsk)
|
||||||
smt = 1;
|
smt = 1;
|
||||||
carry = 0;
|
carry = 0;
|
||||||
msign = 0;
|
msign = 0;
|
||||||
|
over = 0;
|
||||||
|
|
||||||
/* Step II, step address until we find storage mark */
|
/* Step II, step address until we find storage mark */
|
||||||
step2:
|
step2:
|
||||||
|
@ -2947,6 +3067,8 @@ step6:
|
||||||
tsac = tspc;
|
tsac = tspc;
|
||||||
if (t >= 10) {
|
if (t >= 10) {
|
||||||
flags |= ACOFLAG|ANYFLAG;
|
flags |= ACOFLAG|ANYFLAG;
|
||||||
|
msign = 0;
|
||||||
|
over = 1;
|
||||||
at = 1;
|
at = 1;
|
||||||
goto step2;
|
goto step2;
|
||||||
}
|
}
|
||||||
|
@ -2967,6 +3089,8 @@ step6:
|
||||||
at = 1;
|
at = 1;
|
||||||
if (t >= 10) {
|
if (t >= 10) {
|
||||||
flags |= ACOFLAG|ANYFLAG;
|
flags |= ACOFLAG|ANYFLAG;
|
||||||
|
msign = 0;
|
||||||
|
over = 1;
|
||||||
goto step2;
|
goto step2;
|
||||||
}
|
}
|
||||||
dzt = 0;
|
dzt = 0;
|
||||||
|
@ -3065,7 +3189,9 @@ done:
|
||||||
|
|
||||||
/* Update sign and zero */
|
/* Update sign and zero */
|
||||||
flags ^= msign;
|
flags ^= msign;
|
||||||
flags &= ~(((flags & ZERO) >> 2) & fmsk);
|
if (over == 0) {
|
||||||
|
flags &= ~(((flags & ZERO) >> 2) & fmsk);
|
||||||
|
}
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3380,8 +3506,12 @@ cpu_show_hist(FILE * st, UNIT * uptr, int32 val, CONST void *desc)
|
||||||
(h->flags & LOWFLAG)? 'l' :
|
(h->flags & LOWFLAG)? 'l' :
|
||||||
((h->flags & HIGHFLAG) ? 'h' : 'e'));
|
((h->flags & HIGHFLAG) ? 'h' : 'e'));
|
||||||
|
|
||||||
for(len--; len >= 0; len--)
|
for(len--; len >= 0; len--) {
|
||||||
fputc(mem_to_ascii[h->store[len] & 077], st);
|
fputc(mem_to_ascii[h->store[len] & 077], st);
|
||||||
|
if (h->store[len] & 0100) {
|
||||||
|
fputc('|', st);
|
||||||
|
}
|
||||||
|
}
|
||||||
fputc('@', st);
|
fputc('@', st);
|
||||||
if (h->flags & 0x7f0) {
|
if (h->flags & 0x7f0) {
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -36,8 +36,8 @@ int chan_cmd(uint16 dev, uint16 cmd, uint32 addr);
|
||||||
int chan_mapdev(uint16 dev);
|
int chan_mapdev(uint16 dev);
|
||||||
/* Process the CHR 3 13 command and abort all channel activity */
|
/* Process the CHR 3 13 command and abort all channel activity */
|
||||||
void chan_chr_13();
|
void chan_chr_13();
|
||||||
uint32 load_addr(int loc);
|
uint32 load_addr(uint32 *loc);
|
||||||
void store_addr(uint32 addr, int loc);
|
void store_addr(uint32 addr, uint32 *loc);
|
||||||
|
|
||||||
/* Opcode definitions. */
|
/* Opcode definitions. */
|
||||||
#define OP_TR CHR_1
|
#define OP_TR CHR_1
|
||||||
|
|
|
@ -109,8 +109,12 @@ uint32 cdr_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
|
||||||
}
|
}
|
||||||
return SCPE_BUSY;
|
return SCPE_BUSY;
|
||||||
}
|
}
|
||||||
chan_set_attn(chan);
|
uptr->wait = 0;
|
||||||
return SCPE_NODEV;
|
uptr->u5 |= URCSTA_READ | URCSTA_CMD | (24 << CDRPOSSHIFT);
|
||||||
|
chan_set_sel(chan, 0);
|
||||||
|
chan_clear_status(chan);
|
||||||
|
sim_activate(uptr, us_to_ticks(1000)); /* activate */
|
||||||
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_stat cdr_srv(UNIT * uptr)
|
t_stat cdr_srv(UNIT * uptr)
|
||||||
|
|
|
@ -376,11 +376,10 @@ chan_proc()
|
||||||
if ((chan_flags[chan] & DEV_SEL) == 0
|
if ((chan_flags[chan] & DEV_SEL) == 0
|
||||||
&& (chan_flags[chan] & STA_TWAIT)) {
|
&& (chan_flags[chan] & STA_TWAIT)) {
|
||||||
if (chan_dev.dctrl & cmask)
|
if (chan_dev.dctrl & cmask)
|
||||||
sim_debug(DEBUG_TRAP, &chan_dev, "chan %d Trap\n",
|
sim_debug(DEBUG_TRAP, &chan_dev, "chan %d Trap IC=%06o\n",
|
||||||
chan);
|
chan, IC);
|
||||||
iotraps |= 1 << chan;
|
iotraps |= 1 << chan;
|
||||||
chan_flags[chan] &=
|
chan_flags[chan] &= ~(STA_START | STA_ACTIVE | STA_WAIT | STA_TWAIT);
|
||||||
~(STA_START | STA_ACTIVE | STA_WAIT | STA_TWAIT);
|
|
||||||
chan_info[chan] = 0;
|
chan_info[chan] = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -441,7 +440,7 @@ chan_proc()
|
||||||
/* Device has given us a dataword */
|
/* Device has given us a dataword */
|
||||||
case DEV_FULL:
|
case DEV_FULL:
|
||||||
/* If we are not waiting EOR save it in memory */
|
/* If we are not waiting EOR save it in memory */
|
||||||
if ((cmd[chan] & 1) == 0) {
|
if (/*(chan_flags[chan] & CHS_ERR) == 0 &&*/ (cmd[chan] & 1) == 0) {
|
||||||
if (chan_dev.dctrl & cmask)
|
if (chan_dev.dctrl & cmask)
|
||||||
sim_debug(DEBUG_DATA, &chan_dev, "chan %d data < %012llo\n",
|
sim_debug(DEBUG_DATA, &chan_dev, "chan %d data < %012llo\n",
|
||||||
chan, assembly[chan]);
|
chan, assembly[chan]);
|
||||||
|
@ -1569,6 +1568,7 @@ chan_write_char(int chan, uint8 * data, int flags)
|
||||||
} else {
|
} else {
|
||||||
int cnt = --bcnt[chan];
|
int cnt = --bcnt[chan];
|
||||||
t_uint64 wd;
|
t_uint64 wd;
|
||||||
|
|
||||||
if (CHAN_G_TYPE(chan_unit[chan].flags) == CHAN_PIO)
|
if (CHAN_G_TYPE(chan_unit[chan].flags) == CHAN_PIO)
|
||||||
wd = MQ;
|
wd = MQ;
|
||||||
else
|
else
|
||||||
|
|
|
@ -815,6 +815,8 @@ sim_instr(void)
|
||||||
MA = 012;
|
MA = 012;
|
||||||
f = 0;
|
f = 0;
|
||||||
|
|
||||||
|
sim_debug(DEBUG_TRAP, &cpu_dev,
|
||||||
|
"Checking trap chan IC=%06o %06o\n", IC, iotraps);
|
||||||
for (shiftcnt = 1; shiftcnt < NUM_CHAN; shiftcnt++) {
|
for (shiftcnt = 1; shiftcnt < NUM_CHAN; shiftcnt++) {
|
||||||
/* CRC *//* Trap *//* EOF */
|
/* CRC *//* Trap *//* EOF */
|
||||||
/* Wait until channel stops to trigger interupts */
|
/* Wait until channel stops to trigger interupts */
|
||||||
|
@ -828,10 +830,12 @@ sim_instr(void)
|
||||||
iotraps &= ~(1 << shiftcnt);
|
iotraps &= ~(1 << shiftcnt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mask & DMASK & ioflags && chan_stat(shiftcnt, CHS_ERR))
|
if (mask & DMASK & ioflags && chan_stat(shiftcnt, CHS_ERR)) {
|
||||||
f |= 2; /* We have device error */
|
f |= 2; /* We have device error */
|
||||||
|
}
|
||||||
/* check if we need to perform a trap */
|
/* check if we need to perform a trap */
|
||||||
if (f) {
|
if (f) {
|
||||||
|
// iotraps &= ~(1 << (shiftcnt + 18));
|
||||||
/* HTR/HPR behave like wait if protected */
|
/* HTR/HPR behave like wait if protected */
|
||||||
if (hltinst)
|
if (hltinst)
|
||||||
temp = (((t_uint64) bcore & 3) << 31) |
|
temp = (((t_uint64) bcore & 3) << 31) |
|
||||||
|
@ -854,8 +858,8 @@ sim_instr(void)
|
||||||
sim_interval = sim_interval - 1; /* count down */
|
sim_interval = sim_interval - 1; /* count down */
|
||||||
SR = ReadP(MA);
|
SR = ReadP(MA);
|
||||||
sim_debug(DEBUG_TRAP, &cpu_dev,
|
sim_debug(DEBUG_TRAP, &cpu_dev,
|
||||||
"Doing trap chan %c %o >%012llo loc %o %012llo IC=%06o\n",
|
"Doing trap chan %c %o >%012llo loc %o %012llo IC=%06o %06o\n",
|
||||||
shiftcnt + 'A' - 1, f, temp, MA, SR, IC);
|
shiftcnt + 'A' - 1, f, temp, MA, SR, IC, iotraps);
|
||||||
if (hst_lnt) { /* history enabled? */
|
if (hst_lnt) { /* history enabled? */
|
||||||
hst_p = (hst_p + 1); /* next entry */
|
hst_p = (hst_p + 1); /* next entry */
|
||||||
if (hst_p >= hst_lnt)
|
if (hst_p >= hst_lnt)
|
||||||
|
@ -1329,10 +1333,12 @@ prottrap:
|
||||||
if ((bcore & 4) || STM)
|
if ((bcore & 4) || STM)
|
||||||
goto seltrap;
|
goto seltrap;
|
||||||
itrap = 1;
|
itrap = 1;
|
||||||
|
// iotraps &= ~(AMASK & (ioflags << 1));
|
||||||
if (CPU_MODEL == CPU_709)
|
if (CPU_MODEL == CPU_709)
|
||||||
ihold = 1;
|
ihold = 1;
|
||||||
else
|
else
|
||||||
ihold = 2;
|
ihold = 2;
|
||||||
|
sim_debug(DEBUG_TRAP, &cpu_dev, "rxt %06o\n", iotraps);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OP_LMTM:
|
case OP_LMTM:
|
||||||
|
@ -1481,7 +1487,7 @@ prottrap:
|
||||||
hltinst = 1;
|
hltinst = 1;
|
||||||
ihold = 0; /* Kill any hold on traps now */
|
ihold = 0; /* Kill any hold on traps now */
|
||||||
if (opcode == OP_HTR) {
|
if (opcode == OP_HTR) {
|
||||||
fptemp = IC-1;
|
fptemp = IC;
|
||||||
IC = MA;
|
IC = MA;
|
||||||
} else
|
} else
|
||||||
fptemp = IC;
|
fptemp = IC;
|
||||||
|
@ -3339,14 +3345,16 @@ prottrap:
|
||||||
itrap = 1;
|
itrap = 1;
|
||||||
else
|
else
|
||||||
itrap = 0;
|
itrap = 0;
|
||||||
sim_debug(DEBUG_TRAP, &cpu_dev, "ENB %012llo\n", ioflags);
|
sim_debug(DEBUG_TRAP, &cpu_dev, "ENB %012llo %06o\n", ioflags, iotraps);
|
||||||
ihold = 1;
|
|
||||||
/*
|
/*
|
||||||
* IBSYS can't have an trap right after ENB or it will hang
|
* IBSYS can't have an trap right after ENB or it will hang
|
||||||
* on a TTR * in IBNUC.
|
* on a TTR * in IBNUC.
|
||||||
*/
|
*/
|
||||||
if (CPU_MODEL >= CPU_7090)
|
if (CPU_MODEL >= CPU_7090) {
|
||||||
|
ihold = 1;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
temp = 00000001000001LL;
|
temp = 00000001000001LL;
|
||||||
|
|
||||||
for (shiftcnt = 1; shiftcnt < NUM_CHAN; shiftcnt++) {
|
for (shiftcnt = 1; shiftcnt < NUM_CHAN; shiftcnt++) {
|
||||||
|
@ -3360,6 +3368,7 @@ prottrap:
|
||||||
ihold = 0;
|
ihold = 0;
|
||||||
temp <<= 1;
|
temp <<= 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -3393,15 +3402,21 @@ prottrap:
|
||||||
switch (chan_cmd(MA, opcode)) {
|
switch (chan_cmd(MA, opcode)) {
|
||||||
case SCPE_BUSY:
|
case SCPE_BUSY:
|
||||||
iowait = 1; /* Channel is active, hold */
|
iowait = 1; /* Channel is active, hold */
|
||||||
|
ihold = 1; /* Hold interupts for one cycle */
|
||||||
break;
|
break;
|
||||||
case SCPE_OK:
|
case SCPE_OK:
|
||||||
if (((MA >> 9) & 017) == 0) {
|
{ uint16 temp16;
|
||||||
if (opcode==IO_RDS)
|
temp16 = (MA >> 9) & 017;
|
||||||
MQ = 0;
|
if (temp16 == 0) {
|
||||||
chan_clear(0, CHS_EOF|CHS_EOT|DEV_REOR);
|
if (opcode==IO_RDS)
|
||||||
|
MQ = 0;
|
||||||
|
chan_clear(0, CHS_EOF|CHS_EOT|DEV_REOR);
|
||||||
|
} else {
|
||||||
|
iotraps &= ~(1 << temp16);
|
||||||
|
chan_clear(temp16, CHS_EOF|CHS_EOT|DEV_REOR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ihold = 1; /* Hold interupts for one cycle */
|
ihold = 1; /* Hold interupts for one cycle */
|
||||||
iotraps &= ~(1 << ((MA >> 9) & 017));
|
|
||||||
break;
|
break;
|
||||||
case SCPE_IOERR:
|
case SCPE_IOERR:
|
||||||
iocheck = 1;
|
iocheck = 1;
|
||||||
|
@ -4183,7 +4198,7 @@ cpu_reset(DEVICE * dptr)
|
||||||
interval_irq = dcheck = acoflag = mqoflag = iocheck = 0;
|
interval_irq = dcheck = acoflag = mqoflag = iocheck = 0;
|
||||||
sim_brk_types = sim_brk_dflt = SWMASK('E');
|
sim_brk_types = sim_brk_dflt = SWMASK('E');
|
||||||
limitaddr = 077777;
|
limitaddr = 077777;
|
||||||
memmask = MEMMASK;
|
memmask = MEMSIZE-1;
|
||||||
if (cpu_unit.flags & OPTION_TIMER) {
|
if (cpu_unit.flags & OPTION_TIMER) {
|
||||||
sim_rtcn_init_unit (&cpu_unit, cpu_unit.wait, TMR_RTC);
|
sim_rtcn_init_unit (&cpu_unit, cpu_unit.wait, TMR_RTC);
|
||||||
sim_activate(&cpu_unit, cpu_unit.wait);
|
sim_activate(&cpu_unit, cpu_unit.wait);
|
||||||
|
|
Loading…
Add table
Reference in a new issue