mirror of
https://github.com/simh/simh.git
synced 2026-01-30 21:32:27 +00:00
Notes For V3.4-0
The memory layout for the Interdata simulators has been changed. Do not use Interdata SAVE files from prior revisions with V3.4. 1. New Features in 3.4 1.1 SCP and Libraries - Revised interpretation of fprint_sym, fparse_sym returns - Revised syntax for SET DEBUG - DO command nesting allowed to ten levels 1.2 Interdata - Revised memory model to be 16b instead of 8b 1.3 HP2100 - Added Fast FORTRAN Processor instructions - Added SET OFFLINE/ONLINE and SET UNLOAD/LOAD commands to tapes and disks 2. Bugs Fixed in 3.4-0 2.1 Interdata - Fixed bug in show history routine (from Mark Hittinger) - Fixed bug in initial memory allocation 2.2 PDP-10 - Fixed TU bug, ERASE and WREOF should not clear done (reported by Rich Alderson) - Fixed TU error reporting 2.3 PDP-11 - Fixed TU error reporting
This commit is contained in:
committed by
Mark Pizzolato
parent
098200a126
commit
ec60bbf329
@@ -48,8 +48,8 @@ extern UNIT cpu_unit;
|
||||
extern REG cpu_reg[];
|
||||
extern uint32 *M;
|
||||
|
||||
t_stat fprint_sym_m (FILE *of, t_addr addr, t_value *val, t_bool cf);
|
||||
t_stat parse_sym_m (char *cptr, t_addr addr, t_value *val, t_bool cf);
|
||||
t_stat fprint_sym_m (FILE *of, t_addr addr, t_value *val);
|
||||
t_stat parse_sym_m (char *cptr, t_addr addr, t_value *val);
|
||||
extern t_stat lp_load (FILE *fileref, char *cptr, char *fnam);
|
||||
extern t_stat pt_dump (FILE *of, char *cptr, char *fnam);
|
||||
|
||||
@@ -290,7 +290,7 @@ static const uint32 opc_val[] = {
|
||||
/* Print an RX specifier */
|
||||
|
||||
t_stat fprint_addr (FILE *of, t_addr addr, uint32 rx, uint32 ea1,
|
||||
uint32 ea2, t_bool cf)
|
||||
uint32 ea2)
|
||||
{
|
||||
uint32 rx2;
|
||||
|
||||
@@ -299,25 +299,17 @@ if ((ea1 & 0xC000) == 0) { /* RX1 */
|
||||
if (rx) fprintf (of, "(R%d)", rx);
|
||||
return -3; }
|
||||
if (ea1 & 0x8000) { /* RX2 */
|
||||
if (cf) { /* for CPU? */
|
||||
ea1 = addr + 4 + SEXT15 (ea1);
|
||||
fprintf (of, "%-X", ea1 & VAMASK32); }
|
||||
else { /* for dev */
|
||||
int32 disp = SEXT15 (ea1); /* get disp */
|
||||
if (disp >= -4) fprintf (of, ".+%-X", disp + 4);
|
||||
else fprintf (of, ".-%-X", -4 - disp); }
|
||||
ea1 = addr + 4 + SEXT15 (ea1);
|
||||
fprintf (of, "%-X", ea1 & VAMASK32);
|
||||
if (rx) fprintf (of, "(R%d)", rx);
|
||||
return -3; }
|
||||
rx2 = (ea1 >> 8) & 0xF;
|
||||
rx2 = (ea1 >> 8) & 0xF; /* RX3 */
|
||||
fprintf (of, "%-X", ((ea1 << 16) | ea2) & VAMASK32);
|
||||
if (rx && !rx2) fprintf (of, "(R%d)", rx);
|
||||
if (rx2) fprintf (of, "(R%d,R%d)", rx, rx2);
|
||||
return -5;
|
||||
}
|
||||
|
||||
#define GETNUM(d,n) for (k = d = 0; k < n; k++) \
|
||||
d = (d << 8) | (((uint32) val[vp++]) & 0xFF)
|
||||
|
||||
/* Symbolic decode
|
||||
|
||||
Inputs:
|
||||
@@ -334,39 +326,42 @@ return -5;
|
||||
t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,
|
||||
UNIT *uptr, int32 sw)
|
||||
{
|
||||
int32 c, k, num, rdx, vp, lnt;
|
||||
int32 c1, c2, rdx;
|
||||
t_stat r;
|
||||
DEVICE *dptr;
|
||||
|
||||
if (uptr == NULL) uptr = &cpu_unit; /* anon = CPU */
|
||||
else if (uptr != &cpu_unit) return SCPE_ARG; /* only for CPU */
|
||||
dptr = find_dev_from_unit (uptr); /* find dev */
|
||||
if (dptr == NULL) return SCPE_IERR;
|
||||
if (dptr->dwidth != 8) return SCPE_ARG; /* byte dev only */
|
||||
if (sw & SWMASK ('B')) lnt = 1; /* get length */
|
||||
else if (sw & SWMASK ('W')) lnt = 2;
|
||||
else if (sw & SWMASK ('F')) lnt = 4;
|
||||
else lnt = (uptr == &cpu_unit)? 4: 1;
|
||||
if (sw & SWMASK ('D')) rdx = 10; /* get radix */
|
||||
else if (sw & SWMASK ('O')) rdx = 8;
|
||||
else if (sw & SWMASK ('H')) rdx = 16;
|
||||
else rdx = dptr->dradix;
|
||||
vp = 0; /* init ptr */
|
||||
if ((sw & SWMASK ('A')) || (sw & SWMASK ('C'))) { /* char format? */
|
||||
if (sw & SWMASK ('C')) lnt = sim_emax; /* -c -> string */
|
||||
if ((val[0] & 0x7F) == 0) return SCPE_ARG;
|
||||
while (vp < lnt) { /* print string */
|
||||
if ((c = (uint32) val[vp++] & 0x7F) == 0) break;
|
||||
fprintf (of, (c < 0x20)? "<%02X>": "%c", c); }
|
||||
return -(vp - 1); } /* return # chars */
|
||||
|
||||
if (sw & SWMASK ('A')) { /* ASCII char? */
|
||||
c1 = (val[0] >> ((addr & 1)? 0: 8)) & 0x7F; /* get byte */
|
||||
fprintf (of, (c1 < 0x20)? "<%02X>": "%c", c1);
|
||||
return 0; }
|
||||
if (sw & SWMASK ('B')) { /* byte? */
|
||||
c1 = (val[0] >> ((addr & 1)? 0: 8)) & 0xFF; /* get byte */
|
||||
fprint_val (of, c1, rdx, 8, PV_RZRO);
|
||||
return 0; }
|
||||
if (sw & SWMASK ('C')) { /* string? */
|
||||
c1 = (val[0] >> 8) & 0x7F;
|
||||
c2 = val[0] & 0x7F;
|
||||
fprintf (of, (c1 < 0x20)? "<%02X>": "%c", c1);
|
||||
fprintf (of, (c2 < 0x20)? "<%02X>": "%c", c2);
|
||||
return -1; }
|
||||
if (sw & SWMASK ('H')) { /* halfword? */
|
||||
fprint_val (of, val[0], rdx, 16, PV_RZRO);
|
||||
return -1; }
|
||||
if (sw & SWMASK ('M')) { /* inst format? */
|
||||
r = fprint_sym_m (of, addr, val, uptr == &cpu_unit); /* decode inst */
|
||||
if (r <= 0) return r; /* success? */
|
||||
lnt = 2; } /* no, skip 16b */
|
||||
r = fprint_sym_m (of, addr, val); /* decode inst */
|
||||
if (r <= 0) return r; }
|
||||
|
||||
GETNUM (num, lnt); /* get number */
|
||||
fprint_val (of, num, rdx, lnt * 8, PV_RZRO);
|
||||
return -(vp - 1);
|
||||
fprint_val (of, (val[0] << 16) | val[1], rdx, 32, PV_RZRO);
|
||||
return -3;
|
||||
}
|
||||
|
||||
/* Symbolic decode for -m
|
||||
@@ -381,14 +376,13 @@ return -(vp - 1);
|
||||
if < 0, number of extra bytes retired
|
||||
*/
|
||||
|
||||
t_stat fprint_sym_m (FILE *of, t_addr addr, t_value *val, t_bool cf)
|
||||
t_stat fprint_sym_m (FILE *of, t_addr addr, t_value *val)
|
||||
{
|
||||
uint32 i, j, k, inst, r1, r2, ea1, ea2, vp;
|
||||
uint32 i, j, inst, r1, r2, ea1, ea2;
|
||||
|
||||
vp = 0;
|
||||
GETNUM (inst,2); /* high 16b */
|
||||
GETNUM (ea1, 2); /* next 16b */
|
||||
GETNUM (ea2, 2); /* next 16b */
|
||||
inst = val[0];
|
||||
ea1 = val[1];
|
||||
ea2 = val[2];
|
||||
for (i = 0; opc_val[i] != 0xFFFF; i++) { /* loop thru ops */
|
||||
j = (opc_val[i] >> I_V_FL) & I_M_FL; /* get class */
|
||||
if ((opc_val[i] & 0xFFFF) == (inst & masks[j])) { /* match? */
|
||||
@@ -409,10 +403,8 @@ for (i = 0; opc_val[i] != 0xFFFF; i++) { /* loop thru ops */
|
||||
case I_V_SB: /* short branch */
|
||||
fprintf (of, "%-X,", r1);
|
||||
case I_V_SX: /* ext short branch */
|
||||
if (cf) fprintf (of, "%-X", ((inst & MSK_SBF)?
|
||||
fprintf (of, "%-X", ((inst & MSK_SBF)?
|
||||
(addr + r2 + r2): (addr - r2 - r2)));
|
||||
else fprintf (of, ((inst & MSK_SBF)?
|
||||
".+%-X": ".-%X"), r2 + r2);
|
||||
return -1;
|
||||
case I_V_R: /* register */
|
||||
fprintf (of, "R%d", r2);
|
||||
@@ -427,14 +419,16 @@ for (i = 0; opc_val[i] != 0xFFFF; i++) { /* loop thru ops */
|
||||
return -5;
|
||||
case I_V_MX: /* mask-memory */
|
||||
fprintf (of, "%-X,", r1);
|
||||
return fprint_addr (of, addr, r2, ea1, ea2, cf);
|
||||
return fprint_addr (of, addr, r2, ea1, ea2);
|
||||
case I_V_RX: /* register-memory */
|
||||
case I_V_FX: /* floating-memory */
|
||||
fprintf (of, "R%d,", r1);
|
||||
case I_V_X: /* memory */
|
||||
return fprint_addr (of, addr, r2, ea1, ea2, cf); }
|
||||
return SCPE_IERR; } /* end if */
|
||||
} /* end for */
|
||||
return fprint_addr (of, addr, r2, ea1, ea2);
|
||||
} /* end case */
|
||||
return SCPE_IERR;
|
||||
} /* end if */
|
||||
} /* end for */
|
||||
return SCPE_ARG; /* no match */
|
||||
}
|
||||
|
||||
@@ -503,74 +497,74 @@ return SCPE_OK;
|
||||
*cptr = pointer to input string
|
||||
**tptr = pointer to moved pointer
|
||||
*ea = effective address
|
||||
*rel = relative flag
|
||||
addr = base address
|
||||
cf = true if parsing for CPU
|
||||
Outputs:
|
||||
status = SCPE_OK if ok, else error code
|
||||
*/
|
||||
|
||||
t_stat get_addr (char *cptr, char **tptr, t_addr *ea, t_bool *rel,
|
||||
t_addr addr, t_bool cf)
|
||||
t_stat get_addr (char *cptr, char **tptr, t_addr *ea, t_addr addr)
|
||||
{
|
||||
int32 sign = 1;
|
||||
|
||||
*ea = 0;
|
||||
if (*cptr == '.') { /* relative? */
|
||||
*rel = TRUE;
|
||||
cptr++;
|
||||
if (cf) *ea = addr;
|
||||
*ea = addr;
|
||||
if (*cptr == '+') cptr++; /* .+? */
|
||||
else if (*cptr == '-') { /* .-? */
|
||||
sign = -1;
|
||||
cptr++; }
|
||||
else return SCPE_OK; }
|
||||
else *rel = FALSE;
|
||||
else *ea = 0;
|
||||
errno = 0;
|
||||
*ea = *ea + (sign * ((int32) strtoul (cptr, tptr, 16)));
|
||||
if (errno || (cptr == *tptr)) return SCPE_ARG;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
#define PUTNUM(d,n) for (k = n; k > 0; k--) \
|
||||
val[vp++] = (d >> ((k - 1) * 8)) & 0xFF
|
||||
|
||||
/* Symbolic input */
|
||||
|
||||
t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw)
|
||||
{
|
||||
int32 k, rdx, lnt, num, vp;
|
||||
int32 by, rdx, num;
|
||||
t_stat r;
|
||||
DEVICE *dptr;
|
||||
static const uint32 maxv[5] = { 0, 0xFF, 0xFFFF, 0, 0xFFFFFFFF };
|
||||
|
||||
if (uptr == NULL) uptr = &cpu_unit; /* anon = CPU */
|
||||
else if (uptr != &cpu_unit) return SCPE_ARG; /* CPU only */
|
||||
dptr = find_dev_from_unit (uptr); /* find dev */
|
||||
if (dptr == NULL) return SCPE_IERR;
|
||||
if (dptr->dwidth != 8) return SCPE_ARG; /* byte dev only */
|
||||
if (sw & SWMASK ('B')) lnt = 1; /* get length */
|
||||
else if (sw & SWMASK ('W')) lnt = 2;
|
||||
else if (sw & SWMASK ('F')) lnt = 4;
|
||||
else lnt = (uptr == &cpu_unit)? 4: 1;
|
||||
if (sw & SWMASK ('D')) rdx = 10; /* get radix */
|
||||
else if (sw & SWMASK ('O')) rdx = 8;
|
||||
else if (sw & SWMASK ('H')) rdx = 16;
|
||||
else rdx = dptr->dradix;
|
||||
vp = 0;
|
||||
if ((sw & SWMASK ('A')) || (sw & SWMASK ('C'))) { /* char format? */
|
||||
if (sw & SWMASK ('C')) lnt = sim_emax; /* -c -> string */
|
||||
if (*cptr == 0) return SCPE_ARG;
|
||||
while ((vp < lnt) && *cptr) { /* get chars */
|
||||
val[vp++] = *cptr++; }
|
||||
return -(vp - 1); } /* return # chars */
|
||||
|
||||
r = parse_sym_m (cptr, addr, val, uptr == &cpu_unit); /* try to parse */
|
||||
if ((sw & SWMASK ('A')) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */
|
||||
if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */
|
||||
if (addr & 1) val[0] = (val[0] & ~0xFF) | ((t_value) cptr[0]);
|
||||
else val[0] = (val[0] & 0xFF) | (((t_value) cptr[0]) << 8);
|
||||
return 0; }
|
||||
if (sw & SWMASK ('B')) { /* byte? */
|
||||
by = get_uint (cptr, rdx, DMASK8, &r); /* get byte */
|
||||
if (r != SCPE_OK) return SCPE_ARG;
|
||||
if (addr & 1) val[0] = (val[0] & ~0xFF) | by;
|
||||
else val[0] = (val[0] & 0xFF) | (by << 8);
|
||||
return 0; }
|
||||
if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* ASCII chars? */
|
||||
if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */
|
||||
val[0] = ((t_value) cptr[0] << 8) | (t_value) cptr[1];
|
||||
return -1; }
|
||||
if (sw & SWMASK ('H')) { /* halfword? */
|
||||
val[0] = (int32) get_uint (cptr, rdx, DMASK16, &r); /* get number */
|
||||
if (r != SCPE_OK) return r;
|
||||
return -1; }
|
||||
|
||||
r = parse_sym_m (cptr, addr, val); /* try to parse inst */
|
||||
if (r <= 0) return r;
|
||||
|
||||
num = (int32) get_uint (cptr, rdx, maxv[lnt], &r); /* get number */
|
||||
num = (int32) get_uint (cptr, rdx, DMASK32, &r); /* get number */
|
||||
if (r != SCPE_OK) return r;
|
||||
PUTNUM (num, lnt); /* store */
|
||||
return -(lnt - 1);
|
||||
val[0] = (num >> 16) & DMASK16;
|
||||
val[1] = num & DMASK16;
|
||||
return -3;
|
||||
}
|
||||
|
||||
/* Symbolic input for -m
|
||||
@@ -585,12 +579,11 @@ return -(lnt - 1);
|
||||
<= 0 -number of extra words
|
||||
*/
|
||||
|
||||
t_stat parse_sym_m (char *cptr, t_addr addr, t_value *val, t_bool cf)
|
||||
t_stat parse_sym_m (char *cptr, t_addr addr, t_value *val)
|
||||
{
|
||||
uint32 i, j, k, df, db, t, inst, vp;
|
||||
uint32 i, j, df, db, t, inst, vp;
|
||||
int32 st, r1, r2, rx2;
|
||||
t_stat r;
|
||||
t_bool rel;
|
||||
char *tptr, gbuf[CBUFSIZE];
|
||||
|
||||
vp = 0;
|
||||
@@ -622,7 +615,7 @@ case I_V_R: /* register */
|
||||
case I_V_FX: /* float-memory */
|
||||
case I_V_MX: case I_V_RX: /* mask/reg-memory */
|
||||
case I_V_X: /* memory */
|
||||
r = get_addr (gbuf, &tptr, &t, &rel, addr, cf); /* get addr */
|
||||
r = get_addr (gbuf, &tptr, &t, addr); /* get addr */
|
||||
if (r != SCPE_OK) return SCPE_ARG; /* error? */
|
||||
rx2 = 0; /* assume no 2nd */
|
||||
if (*tptr == '(') { /* index? */
|
||||
@@ -634,67 +627,52 @@ case I_V_X: /* memory */
|
||||
return SCPE_ARG; }
|
||||
if (*tptr++ != ')') return SCPE_ARG; } /* all done? */
|
||||
if (*tptr != 0) return SCPE_ARG;
|
||||
PUTNUM (inst, 2); /* store inst */
|
||||
if (!cf && rel) { /* periph, rel */
|
||||
st = t - 4; /* displ */
|
||||
if (rx2 || (st > 0x3FFF) || (st < -0x4000)) /* rx2 or too big? */
|
||||
return SCPE_ARG;
|
||||
t = (st & 0x7FFF) | 0x8000;
|
||||
PUTNUM (t, 2); /* store displ */
|
||||
return -3; }
|
||||
val[0] = inst; /* store inst */
|
||||
if (rx2 == 0) { /* no 2nd? */
|
||||
if (t < 0x4000) { /* RX1? */
|
||||
PUTNUM (t, 2); /* store ea */
|
||||
val[1] = t; /* store ea */
|
||||
return -3; }
|
||||
st = (t - (addr + 4)); /* displ */
|
||||
if (cf && (st <= 0x3FFF) && (st >= -0x4000)) { /* RX2? CPU only */
|
||||
if ((st <= 0x3FFF) && (st >= -0x4000)) { /* RX2? CPU only */
|
||||
t = (st & 0x7FFF) | 0x8000;
|
||||
PUTNUM (t, 2); /* store displ */
|
||||
val[1] = t; /* store displ */
|
||||
return -3; } }
|
||||
t = (t & VAMASK32) | 0x40000000 | (rx2 << 24);
|
||||
PUTNUM (t, 4); /* RX3 */
|
||||
val[1] = (t >> 16) & DMASK16;
|
||||
val[2] = t & DMASK16;
|
||||
return -5;
|
||||
|
||||
case I_V_RI: /* 16b immediate */
|
||||
r = get_imm (gbuf, &t, &inst, DMASK16); /* process imm */
|
||||
if (r != SCPE_OK) return r;
|
||||
PUTNUM (inst, 2); /* store inst */
|
||||
PUTNUM (t, 2); /* store 16b imm */
|
||||
val[0] = inst;
|
||||
val[1] = t;
|
||||
return -3;
|
||||
|
||||
case I_V_RF:
|
||||
r = get_imm (gbuf, &t, &inst, DMASK32); /* process imm */
|
||||
if (r != SCPE_OK) return r;
|
||||
PUTNUM (inst, 2); /* store inst */
|
||||
PUTNUM (t, 4); /* store 32b imm */
|
||||
val[0] = inst;
|
||||
val[1] = (t >> 16) & DMASK16;
|
||||
val[2] = t & DMASK16;
|
||||
return -5;
|
||||
|
||||
case I_V_SB: case I_V_SX: /* short branches */
|
||||
r = get_addr (gbuf, &tptr, &t, &rel, addr, cf); /* get addr */
|
||||
r = get_addr (gbuf, &tptr, &t, addr); /* get addr */
|
||||
if ((r != SCPE_OK) || (t & 1) || *tptr) /* error if odd */
|
||||
return SCPE_ARG;
|
||||
st = t; /* signed version */
|
||||
if (cf) { /* for CPU? */
|
||||
db = (addr - t) & 0x1F; /* back displ */
|
||||
df = (t - addr) & 0x1F; /* fwd displ */
|
||||
if ((t == ((addr - db) & VAMASK16)) && /* back work and */
|
||||
((j == I_V_SX) || !(inst & MSK_SBF))) /* ext or back br? */
|
||||
inst = inst | (db >> 1); /* or in back displ */
|
||||
else if ((t == ((addr + df) & VAMASK16)) && /* fwd work and */
|
||||
((j == I_V_SX) || (inst & MSK_SBF))) /* ext or fwd br? */
|
||||
inst = inst | (df >> 1) | MSK_SBF; /* or in fwd displ */
|
||||
else return SCPE_ARG; }
|
||||
else if (rel) { /* periph, must be rel */
|
||||
if ((st <= 0) && (st >= -0x1F) && /* relative back? */
|
||||
((j == I_V_SX) || !(inst & MSK_SBF)))
|
||||
inst = inst | ((-st & 0x1F) >> 1);
|
||||
else if ((st >= 0) && (st < 0x1F) && /* relative fwd? */
|
||||
((j == I_V_SX) || (inst & MSK_SBF)))
|
||||
inst = inst | ((t & 0x1F) >> 1);
|
||||
else return SCPE_ARG; }
|
||||
else return SCPE_ARG; /* periph & ~rel, err */
|
||||
db = (addr - t) & 0x1F; /* back displ */
|
||||
df = (t - addr) & 0x1F; /* fwd displ */
|
||||
if ((t == ((addr - db) & VAMASK16)) && /* back work and */
|
||||
((j == I_V_SX) || !(inst & MSK_SBF))) /* ext or back br? */
|
||||
inst = inst | (db >> 1); /* or in back displ */
|
||||
else if ((t == ((addr + df) & VAMASK16)) && /* fwd work and */
|
||||
((j == I_V_SX) || (inst & MSK_SBF))) /* ext or fwd br? */
|
||||
inst = inst | (df >> 1) | MSK_SBF; /* or in fwd displ */
|
||||
else return SCPE_ARG;
|
||||
} /* end case */
|
||||
|
||||
PUTNUM (inst, 2);
|
||||
val[0] = inst;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user