KA10: Fixed bug in I/O instruction assembly
This commit is contained in:
parent
486505741c
commit
9dd46a8b80
1 changed files with 347 additions and 341 deletions
218
PDP10/kx10_sys.c
218
PDP10/kx10_sys.c
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue