KA10: Fixed bug in I/O instruction assembly

This commit is contained in:
Richard Cornwell 2020-11-19 21:13:44 -05:00
parent 486505741c
commit 9dd46a8b80

View file

@ -232,7 +232,7 @@ DEBTAB dev_debug[] = {
{"DETAIL", DEBUG_DETAIL, "Show details about device"},
{"EXP", DEBUG_EXP, "Show exception information"},
{"CONI", DEBUG_CONI, "Show coni instructions"},
{"CONO", DEBUG_CONO, "Show coni instructions"},
{"CONO", DEBUG_CONO, "Show cono instructions"},
{"DATAIO", DEBUG_DATAIO, "Show datai and datao instructions"},
{0, 0}
};
@ -244,7 +244,7 @@ DEBTAB crd_debug[] = {
{"DETAIL", DEBUG_DETAIL, "Show details about device"},
{"EXP", DEBUG_EXP, "Show exception information"},
{"CONI", DEBUG_CONI, "Show coni instructions"},
{"CONO", DEBUG_CONO, "Show coni instructions"},
{"CONO", DEBUG_CONO, "Show cono instructions"},
{"DATAIO", DEBUG_DATAIO, "Show datai and datao instructions"},
{"CARD", DEBUG_CARD, "Show Card read/punches"},
{0, 0}
@ -459,11 +459,11 @@ t_stat load_sblk (FILE *fileref)
#define RIM_EOF 0xFFFFFFFFFFFFFFFFLL
uint64 getrimw (FILE *fileref)
{
int32 i, tmp;
uint64 word;
int32 i, tmp;
uint64 word;
word = 0;
for (i = 0; i < 6;) {
word = 0;
for (i = 0; i < 6;) {
if ((tmp = getc (fileref)) == EOF)
return RIM_EOF;
if (tmp & 0200) {
@ -471,34 +471,34 @@ for (i = 0; i < 6;) {
i++;
}
}
return word;
return word;
}
#define TSTS(x) SMASK & (x)
#define AOB(x) FMASK & ((x) + 01000001LL)
t_stat load_rim (FILE *fileref)
{
uint64 count, cksm, data;
t_bool its_rim;
uint32 pa;
int32 op, i, ldrc;
uint64 count, cksm, data;
t_bool its_rim;
uint32 pa;
int32 op, i, ldrc;
data = getrimw (fileref); /* get first word */
if ((data & AMASK) != 0) /* error? SA != 0? */
data = getrimw (fileref); /* get first word */
if ((data & AMASK) != 0) /* error? SA != 0? */
return SCPE_FMT;
ldrc = 1 + (RMASK ^ ((int32) ((data >> 18) & RMASK))); /* get loader count */
if (ldrc == 016) /* 16? RIM10B */
ldrc = 1 + (RMASK ^ ((int32) ((data >> 18) & RMASK))); /* get loader count */
if (ldrc == 016) /* 16? RIM10B */
its_rim = FALSE;
else if (ldrc == 017) /* 17? ITS RIM */
else if (ldrc == 017) /* 17? ITS RIM */
its_rim = TRUE;
else return SCPE_FMT; /* unknown */
else return SCPE_FMT; /* unknown */
for (i = 0; i < ldrc; i++) { /* skip the loader */
for (i = 0; i < ldrc; i++) { /* skip the loader */
data = getrimw (fileref);
if (data == RIM_EOF)
return SCPE_FMT;
}
for ( ;; ) { /* loop until JRST */
for ( ;; ) { /* loop until JRST */
count = cksm = getrimw (fileref); /* get header */
if (count == RIM_EOF) /* read err? */
return SCPE_FMT;
@ -532,7 +532,7 @@ for ( ;; ) { /* loop until JRST */
break;
} /* end else */
} /* end for */
return SCPE_OK;
return SCPE_OK;
}
@ -631,14 +631,14 @@ t_stat load_sav (FILE *fileref, int ftype)
t_stat load_exe (FILE *fileref, int ftype)
{
uint64 data, dirbuf[DIRSIZ], pagbuf[PAG_SIZE], entbuf[2];
int32 ndir, entvec, i, j, k, cont, bsz, bty, rpt, wc;
int32 fpage, mpage;
uint32 ma;
uint64 data, dirbuf[DIRSIZ], pagbuf[PAG_SIZE], entbuf[2];
int32 ndir, entvec, i, j, k, cont, bsz, bty, rpt, wc;
int32 fpage, mpage;
uint32 ma;
ndir = entvec = 0; /* no dir, entvec */
cont = 1;
do {
ndir = entvec = 0; /* no dir, entvec */
cont = 1;
do {
wc = get_word(fileref, &data, ftype);
if (wc != 0) /* error? */
@ -685,7 +685,7 @@ do {
} /* end switch */
} while (cont); /* end do */
for (i = 0; i < ndir; i = i + 2) { /* loop thru dir */
for (i = 0; i < ndir; i = i + 2) { /* loop thru dir */
fpage = (int32) (dirbuf[i] & RMASK); /* file page */
mpage = (int32) (dirbuf[i + 1] & RMASK); /* memory page */
rpt = ((int32) ((dirbuf[i + 1] >> 27) + 1)) & 0777; /* repeat count */
@ -706,11 +706,11 @@ for (i = 0; i < ndir; i = i + 2) { /* loop thru dir */
} /* end copy */
} /* end rpt */
} /* end directory */
if (entvec && entbuf[1])
if (entvec && entbuf[1])
PC = (int32) (entbuf[1] & RMASK); /* start addr */
else if (entvec == 0)
else if (entvec == 0)
PC = (int32) (M[0120] & RMASK);
return SCPE_OK;
return SCPE_OK;
}
static int exb_pos = -1;
@ -797,40 +797,40 @@ t_stat load_exb (FILE *fileref, int ftype)
t_stat sim_load (FILE *fileref, CONST char *cptr, CONST char *fnam, int flag)
{
uint64 data;
int32 wc, fmt;
int ftype;
extern int32 sim_switches;
uint64 data;
int32 wc, fmt;
int ftype;
extern int32 sim_switches;
fmt = 0; /* no fmt */
ftype = 0;
if (sim_switches & SWMASK ('C')) /* -c? core dump */
fmt = 0; /* no fmt */
ftype = 0;
if (sim_switches & SWMASK ('C')) /* -c? core dump */
ftype = 1;
if (sim_switches & SWMASK ('R')) /* -r? */
if (sim_switches & SWMASK ('R')) /* -r? */
fmt = FMT_R;
else if (sim_switches & SWMASK ('S')) /* -s? */
else if (sim_switches & SWMASK ('S')) /* -s? */
fmt = FMT_S;
else if (sim_switches & SWMASK ('E')) /* -e? */
else if (sim_switches & SWMASK ('E')) /* -e? */
fmt = FMT_E;
else if (sim_switches & SWMASK ('D')) /* -d? */
else if (sim_switches & SWMASK ('D')) /* -d? */
fmt = FMT_D;
else if (sim_switches & SWMASK ('I')) /* -i? */
else if (sim_switches & SWMASK ('I')) /* -i? */
fmt = FMT_I;
else if (sim_switches & SWMASK ('B')) /* -b? */
else if (sim_switches & SWMASK ('B')) /* -b? */
fmt = FMT_B;
else if (match_ext (fnam, "RIM")) /* .RIM? */
else if (match_ext (fnam, "RIM")) /* .RIM? */
fmt = FMT_R;
else if (match_ext (fnam, "SAV")) /* .SAV? */
else if (match_ext (fnam, "SAV")) /* .SAV? */
fmt = FMT_S;
else if (match_ext (fnam, "EXE")) /* .EXE? */
else if (match_ext (fnam, "EXE")) /* .EXE? */
fmt = FMT_E;
else if (match_ext (fnam, "EXB")) /* .EXB? */
else if (match_ext (fnam, "EXB")) /* .EXB? */
fmt = FMT_B;
else if (match_ext (fnam, "DMP")) /* .DMP? */
else if (match_ext (fnam, "DMP")) /* .DMP? */
fmt = FMT_D;
else if (match_ext (fnam, "BIN")) /* .BIN? */
else if (match_ext (fnam, "BIN")) /* .BIN? */
fmt = FMT_I;
else {
else {
wc = sim_fread (&data, sizeof (uint64), 1, fileref);/* read hdr */
if (wc == 0) /* error? */
return SCPE_FMT;
@ -841,7 +841,7 @@ else {
fseek (fileref, 0, SEEK_SET); /* rewind */
}
switch (fmt) { /* case fmt */
switch (fmt) { /* case fmt */
case FMT_R: /* RIM */
return load_rim (fileref);
@ -862,8 +862,8 @@ switch (fmt) { /* case fmt */
return load_exb (fileref, ftype);
}
printf ("Can't determine load file format\n");
return SCPE_FMT;
printf ("Can't determine load file format\n");
return SCPE_FMT;
}
/* Symbol tables */
@ -1125,40 +1125,40 @@ static const char *devnam[NUMDEV] = {
t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,
UNIT *uptr, int32 sw)
{
int32 i, j, c, ac, xr, y, dev;
uint64 inst;
int32 i, j, c, ac, xr, y, dev;
uint64 inst;
inst = val[0];
if (sw & SWMASK ('A')) { /* ASCII? */
inst = val[0];
if (sw & SWMASK ('A')) { /* ASCII? */
if (inst > 0377)
return SCPE_ARG;
fprintf (of, FMTASC ((int32) (inst & 0177)));
return SCPE_OK;
}
if (sw & SWMASK ('C')) { /* character? */
if (sw & SWMASK ('C')) { /* character? */
for (i = 30; i >= 0; i = i - 6) {
c = (int32) ((inst >> i) & 077);
fprintf (of, "%c", SIXTOASC (c));
}
return SCPE_OK;
}
if (sw & SWMASK ('P')) { /* packed? */
if (sw & SWMASK ('P')) { /* packed? */
for (i = 29; i >= 0; i = i - 7) {
c = (int32) ((inst >> i) & 0177);
fprintf (of, FMTASC (c));
}
return SCPE_OK;
}
if (!(sw & SWMASK ('M')))
if (!(sw & SWMASK ('M')))
return SCPE_ARG;
/* Instruction decode */
/* Instruction decode */
ac = GET_AC (inst);
xr = GET_XR (inst);
y = GET_ADDR (inst);
dev = GET_DEV (inst);
for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
ac = GET_AC (inst);
xr = GET_XR (inst);
y = GET_ADDR (inst);
dev = GET_DEV (inst);
for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
j = (int32) ((opc_val[i] >> I_V_FL) & I_M_FL); /* get class */
if (((opc_val[i] & FMASK) == (inst & masks[j]))) { /* match? */
fprintf (of, "%s ", opcode[i]); /* opcode */
@ -1177,18 +1177,20 @@ for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
case I_V_IO: /* I/O */
if (dev < NUMDEV)
fprintf (of, "%s,", devnam[dev]);
else fprintf (of, "%-o,", dev<<2);
else
fprintf (of, "%-o,", dev << 2);
if (inst & INST_IND)
fprintf (of, "@");
if (xr)
fprintf (of, "%-o(%-o)", y, xr);
else fprintf (of, "%-o", y);
else
fprintf (of, "%-o", y);
break;
} /* end case */
return SCPE_OK;
} /* end if */
} /* end for */
return SCPE_ARG;
return SCPE_ARG;
}
/* Get operand, including indirect and index
@ -1202,28 +1204,28 @@ return SCPE_ARG;
t_value get_opnd (const char *cptr, t_stat *status)
{
int32 sign = 0;
t_value val, xr = 0, ind = 0;
const char *tptr;
int32 sign = 0;
t_value val, xr = 0, ind = 0;
const char *tptr;
*status = SCPE_ARG; /* assume fail */
if (*cptr == '@') {
*status = SCPE_ARG; /* assume fail */
if (*cptr == '@') {
ind = INST_IND;
cptr++;
}
if (*cptr == '+')
if (*cptr == '+')
cptr++;
else if (*cptr == '-') {
else if (*cptr == '-') {
sign = 1;
cptr++;
}
val = strtotv (cptr, &tptr, 8);
if (val > 0777777)
val = strtotv (cptr, &tptr, 8);
if (val > 0777777)
return 0;
if (sign)
if (sign)
val = (~val + 1) & 0777777;
cptr = tptr;
if (*cptr == '(') {
cptr = tptr;
if (*cptr == '(') {
cptr++;
xr = strtotv (cptr, &tptr, 8);
if ((cptr == tptr) || (*tptr != ')') ||
@ -1231,9 +1233,9 @@ if (*cptr == '(') {
return 0;
cptr = ++tptr;
}
if (*cptr == 0)
if (*cptr == 0)
*status = SCPE_OK;
return (ind | (xr << 18) | val);
return (ind | (xr << 18) | val);
}
/* Symbolic input
@ -1250,22 +1252,22 @@ return (ind | (xr << 18) | val);
t_stat parse_sym (CONST char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw)
{
int32 i, j;
t_value ac, dev;
t_stat r;
char gbuf[CBUFSIZE], cbuf[2*CBUFSIZE];
int32 i, j;
t_value ac, dev;
t_stat r;
char gbuf[CBUFSIZE], cbuf[2*CBUFSIZE];
while (isspace (*cptr)) cptr++;
memset (cbuf, '\0', sizeof(cbuf));
strncpy (cbuf, cptr, sizeof(cbuf)-7);
cptr = cbuf;
if ((sw & SWMASK ('A')) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */
while (isspace (*cptr)) cptr++;
memset (cbuf, '\0', sizeof(cbuf));
strncpy (cbuf, cptr, sizeof(cbuf)-7);
cptr = cbuf;
if ((sw & SWMASK ('A')) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */
if (cptr[0] == 0) /* must have 1 char */
return SCPE_ARG;
val[0] = (t_value) cptr[0];
return SCPE_OK;
}
if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* sixbit string? */
if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* sixbit string? */
if (cptr[0] == 0) /* must have 1 char */
return SCPE_ARG;
for (i = 0; i < 6; i++) {
@ -1275,7 +1277,7 @@ if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* sixbit string? */
}
return SCPE_OK;
}
if ((sw & SWMASK ('P')) || ((*cptr == '#') && cptr++)) { /* packed string? */
if ((sw & SWMASK ('P')) || ((*cptr == '#') && cptr++)) { /* packed string? */
if (cptr[0] == 0) /* must have 1 char */
return SCPE_ARG;
for (i = 0; i < 5; i++)
@ -1284,15 +1286,15 @@ if ((sw & SWMASK ('P')) || ((*cptr == '#') && cptr++)) { /* packed string? */
return SCPE_OK;
}
/* Instruction parse */
/* Instruction parse */
cptr = get_glyph (cptr, gbuf, 0); /* get opcode */
for (i = 0; (opcode[i] != NULL) && (strcmp (opcode[i], gbuf) != 0) ; i++) ;
if (opcode[i] == NULL)
cptr = get_glyph (cptr, gbuf, 0); /* get opcode */
for (i = 0; (opcode[i] != NULL) && (strcmp (opcode[i], gbuf) != 0) ; i++) ;
if (opcode[i] == NULL)
return SCPE_ARG;
val[0] = opc_val[i] & FMASK; /* get value */
j = (int32) ((opc_val[i] >> I_V_FL) & I_M_FL); /* get class */
switch (j) { /* case on class */
val[0] = opc_val[i] & FMASK; /* get value */
j = (int32) ((opc_val[i] >> I_V_FL) & I_M_FL); /* get class */
switch (j) { /* case on class */
case I_V_AC: /* AC + operand */
if (strchr (cptr, ',')) { /* AC specified? */
@ -1304,6 +1306,7 @@ switch (j) { /* case on class */
val[0] = val[0] | (ac << INST_V_AC);
}
} /* fall through */
case I_V_OP: /* operand */
cptr = get_glyph (cptr, gbuf, 0);
val[0] = val[0] | get_opnd (gbuf, &r);
@ -1313,11 +1316,14 @@ switch (j) { /* case on class */
case I_V_IO: /* I/O */
cptr = get_glyph (cptr, gbuf, ','); /* get glyph */
for (dev = 0; (dev < NUMDEV) && (strcmp (devnam[dev], gbuf) != 0); dev++);
for (dev = 0;
(dev < NUMDEV) && (strcmp (devnam[dev], gbuf) != 0);
dev++);
if (dev >= NUMDEV) {
dev = get_uint (gbuf, 8, INST_M_DEV, &r);
dev = get_uint (gbuf, 8, INST_M_DEV << 2, &r);
if (r != SCPE_OK)
return SCPE_ARG;
dev >>= 2;
}
val[0] = val[0] | (dev << INST_V_DEV);
cptr = get_glyph (cptr, gbuf, 0);
@ -1327,7 +1333,7 @@ switch (j) { /* case on class */
break;
} /* end case */
if (*cptr != 0) /* junk at end? */
if (*cptr != 0) /* junk at end? */
return SCPE_ARG;
return SCPE_OK;
return SCPE_OK;
}