1
0
mirror of https://github.com/simh/simh.git synced 2026-01-26 12:02:14 +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:
Bob Supnik
2005-05-03 04:10:00 -07:00
committed by Mark Pizzolato
parent 098200a126
commit ec60bbf329
62 changed files with 4332 additions and 7632 deletions

View File

@@ -1,6 +1,6 @@
/* id16_cpu.c: Interdata 16b CPU simulator
Copyright (c) 2000-2004, Robert M. Supnik
Copyright (c) 2000-2005, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -25,6 +25,8 @@
cpu Interdata 16b CPU
10-Mar-05 RMS Fixed bug in show history routine (from Mark Hittinger)
Revised examine/deposit to do words rather than bytes
07-Nov-04 RMS Added instruction history
22-Sep-03 RMS Added additional instruction decode types
07-Feb-03 RMS Fixed bug in SETM, SETMR (found by Mark Pizzolato)
@@ -521,7 +523,7 @@ MTAB cpu_mod[] = {
DEVICE cpu_dev = {
"CPU", &cpu_unit, cpu_reg, cpu_mod,
1, 16, 18, 1, 16, 8,
1, 16, 18, 2, 16, 16,
&cpu_ex, &cpu_dep, &cpu_reset,
NULL, NULL, NULL,
&cpu_dib, 0 };
@@ -1681,6 +1683,17 @@ M[loc >> 1] = ((loc & 1)?
((M[loc >> 1] & DMASK8) | (val << 8)));
return;
}
uint32 IOReadH (uint32 loc)
{
return (M[loc >> 1] & DMASK16);
}
void IOWriteH (uint32 loc, uint32 val)
{
M[loc >> 1] = val & DMASK16;
return;
}
/* Reset routine */
@@ -1708,7 +1721,7 @@ if (sw & SWMASK ('V')) {
if (addr > VAMASK) return SCPE_NXM;
addr = (addr + ((addr & VA_S1)? s1_rel: s0_rel)) & PAMASK16E; }
if (addr >= MEMSIZE) return SCPE_NXM;
if (vptr != NULL) *vptr = IOReadB (addr);
if (vptr != NULL) *vptr = IOReadH (addr);
return SCPE_OK;
}
@@ -1720,7 +1733,7 @@ if (sw & SWMASK ('V')) {
if (addr > VAMASK) return SCPE_NXM;
addr = (addr + ((addr & VA_S1)? s1_rel: s0_rel)) & PAMASK16E; }
if (addr >= MEMSIZE) return SCPE_NXM;
IOWriteB (addr, val & 0xFF);
IOWriteH (addr, val);
return SCPE_OK;
}
@@ -1794,9 +1807,9 @@ return SCPE_OK;
t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, void *desc)
{
uint32 op, k, di, lnt;
int32 op, k, di, lnt;
char *cptr = (char *) desc;
t_value sim_eval[4];
t_value sim_eval[2];
t_stat r;
struct InstHistory *h;
extern t_stat fprint_sym (FILE *ofile, t_addr addr, t_value *val,
@@ -1814,12 +1827,11 @@ for (k = 0; k < lnt; k++) { /* print specified */
h = &hst[(di++) % hst_lnt]; /* entry pointer */
if (h->vld) { /* instruction? */
fprintf (st, "%04X %04X %04X ", h->pc, h->r1, h->opnd);
sim_eval[0] = op = (h->ir1 >> 8) & 0xFF;
sim_eval[1] = h->ir1 & 0xFF;
sim_eval[2] = (h->ir2 >> 8) & 0xFF;
sim_eval[3] = h->ir2 & 0xFF;
op = (h->ir1 >> 8) & 0xFF;
if (OP_TYPE (op) >= OP_RX) fprintf (st, "%04X ", h->ea);
else fprintf (st, " ");
sim_eval[0] = h->ir1;
sim_eval[1] = h->ir2;
if ((fprint_sym (st, h->pc, sim_eval, &cpu_unit, SWMASK ('M'))) > 0)
fprintf (st, "(undefined) %04X", h->ir1);
fputc ('\n', st); /* end line */

View File

@@ -45,8 +45,8 @@ extern UNIT cpu_unit;
extern REG cpu_reg[];
extern uint16 *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);
@@ -64,7 +64,7 @@ char sim_name[] = "Interdata 16b";
REG *sim_PC = &cpu_reg[0];
int32 sim_emax = 8;
int32 sim_emax = 2;
DEVICE *sim_devices[] = {
&cpu_dev,
@@ -255,9 +255,6 @@ static const uint32 opc_val[] = {
0xEC00+I_RX, 0xED00+I_RX, 0xEE00+I_RX, 0xEF00+I_RX,
0xFFFF };
#define GETNUM(d,n) for (k = d = 0; k < n; k++) \
d = (d << 8) | (((uint32) val[vp++]) & 0xFF)
/* Symbolic decode
Inputs:
@@ -274,38 +271,42 @@ static const uint32 opc_val[] = {
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; /* 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)? 2: 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 ('F')) { /* fullword? */
fprint_val (of, (val[0] << 16) | val[1], rdx, 32, PV_RZRO);
return -3; }
if (sw & SWMASK ('M')) { /* inst format? */
r = fprint_sym_m (of, addr, val, uptr == &cpu_unit); /* decode inst */
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], rdx, 16, PV_RZRO);
return -1;
}
/* Symbolic decode for -m
@@ -314,19 +315,18 @@ return -(vp - 1);
of = output stream
addr = current PC
*val = values to decode
cf = true if decoding for CPU
Outputs:
return = if >= 0, error code
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, ea, vp;
uint32 i, j, inst, r1, r2, ea, vp;
vp = 0;
GETNUM (inst, 2); /* first 16b */
GETNUM (ea, 2); /* second 16b */
inst = val[0]; /* first 16b */
ea = val[1]; /* second 16b */
for (i = 0; opcode[i] != NULL; 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? */
@@ -347,10 +347,8 @@ for (i = 0; opcode[i] != NULL; 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);
@@ -408,74 +406,74 @@ return reg;
*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)? 2: 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 inst */
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 ('F')) {
num = (int32) get_uint (cptr, rdx, DMASK32, &r);/* get number */
if (r != SCPE_OK) return r;
val[0] = (num >> 16) & DMASK16;
val[1] = num & DMASK16;
return -3; }
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 */
val[0] = (int32) get_uint (cptr, rdx, DMASK16, &r); /* get number */
if (r != SCPE_OK) return r;
PUTNUM (num, lnt); /* store */
return -(lnt - 1);
return -1;
}
/* Symbolic input for -m
@@ -490,15 +488,13 @@ 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, t, df, db, inst, vp;
uint32 i, j, t, df, db, inst;
int32 st, r1, r2;
t_bool rel;
t_stat r;
char *tptr, gbuf[CBUFSIZE];
vp = 0;
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;
@@ -527,45 +523,35 @@ case I_V_R: /* register */
case I_V_FX: /* float-memory */
case I_V_MX: case I_V_RX: /* mask/reg-mem */
case I_V_X: /* memory */
r = get_addr (gbuf, &tptr, &t, &rel, addr, cf); /* get addr */
if ((r != SCPE_OK) || (t > PAMASK16) ||
(!cf && rel)) return SCPE_ARG;
r = get_addr (gbuf, &tptr, &t, addr); /* get addr */
if ((r != SCPE_OK) || (t > PAMASK16)) return SCPE_ARG;
if (*tptr == '(') { /* index? */
if ((r2 = get_reg (tptr + 1, &tptr, R_R)) < 0)
return SCPE_ARG;
if (*tptr++ != ')') return SCPE_ARG;
inst = inst | r2; } /* or in R2 */
if (*tptr != 0) return SCPE_ARG;
PUTNUM (inst, 2);
PUTNUM (t, 2);
val[0] = inst;
val[1] = t;
return -3;
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;
break;
} /* end case */
PUTNUM (inst, 2);
val[0] = inst;
return -1;
}

View File

@@ -25,6 +25,9 @@
cpu Interdata 32b CPU
10-Mar-05 RMS Fixed bug in initial memory allocation
RMS Fixed bug in show history routine (from Mark Hittinger)
RMS Revised examine/deposit to do words rather than bytes
18-Feb-05 RMS Fixed branches to mask new PC (from Greg Johnson)
06-Nov-04 RMS Added =n to SHOW HISTORY
25-Jan-04 RMS Revised for device debug support
@@ -574,7 +577,7 @@ DEBTAB cpu_deb[] = {
DEVICE cpu_dev = {
"CPU", &cpu_unit, cpu_reg, cpu_mod,
1, 16, 20, 1, 16, 8,
1, 16, 20, 2, 16, 16,
&cpu_ex, &cpu_dep, &cpu_reset,
NULL, NULL, NULL,
&cpu_dib, DEV_DEBUG, 0,
@@ -1870,6 +1873,8 @@ return 0; /* ok */
WriteF write fullword (processor)
IOReadB read byte (IO)
IOWriteB write byte (IO)
IOReadH read halfword (IO)
IOWriteH write halfword (IO)
*/
uint32 ReadB (uint32 loc, uint32 rel)
@@ -1987,6 +1992,11 @@ uint32 sc = (3 - (loc & 3)) << 3;
return (M[loc >> 2] >> sc) & DMASK8;
}
uint32 IOReadH (uint32 loc)
{
return (M[loc >> 2] >> ((loc & 2)? 0: 16)) & DMASK16;
}
void IOWriteB (uint32 loc, uint32 val)
{
uint32 sc = (3 - (loc & 3)) << 3;
@@ -1995,6 +2005,15 @@ val = val & DMASK8;
M[loc >> 2] = (M[loc >> 2] & ~(DMASK8 << sc)) | (val << sc);
return;
}
void IOWriteH (uint32 loc, uint32 val)
{
uint32 sc = (loc & 2)? 0: 16;
val = val & DMASK16;
M[loc >> 2] = (M[loc >> 2] & ~(DMASK16 << sc)) | (val << sc);
return;
}
/* Reset routine */
@@ -2008,7 +2027,7 @@ DR = 0; /* clear display */
drmod = 0;
blk_io.dfl = blk_io.cur = blk_io.end = 0; /* no block I/O */
sim_brk_types = sim_brk_dflt = SWMASK ('E'); /* init bkpts */
if (M == NULL) M = calloc (MAXMEMSIZE32 >> 1, sizeof (uint16));
if (M == NULL) M = calloc (MAXMEMSIZE32 >> 2, sizeof (uint32));
if (M == NULL) return SCPE_MEM;
pcq_r = find_reg ("PCQ", NULL, dptr); /* init PCQ */
if (pcq_r) pcq_r->qptr = 0;
@@ -2024,7 +2043,7 @@ if ((sw & SWMASK ('V')) && (PSW & PSW_REL)) {
int32 cc = RelocT (addr, MAC_BASE, P, &addr);
if (cc & (CC_C | CC_V)) return SCPE_NXM; }
if (addr >= MEMSIZE) return SCPE_NXM;
if (vptr != NULL) *vptr = IOReadB (addr);
if (vptr != NULL) *vptr = IOReadH (addr);
return SCPE_OK;
}
@@ -2036,7 +2055,7 @@ if ((sw & SWMASK ('V')) && (PSW & PSW_REL)) {
int32 cc = RelocT (addr, MAC_BASE, P, &addr);
if (cc & (CC_C | CC_V)) return SCPE_NXM; }
if (addr >= MEMSIZE) return SCPE_NXM;
IOWriteB (addr, val & 0xFF);
IOWriteH (addr, val);
return SCPE_OK;
}
@@ -2108,9 +2127,9 @@ return SCPE_OK;
t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, void *desc)
{
uint32 op, k, di, lnt;
int32 op, k, di, lnt;
char *cptr = (char *) desc;
t_value sim_eval[6];
t_value sim_eval[3];
t_stat r;
struct InstHistory *h;
extern t_stat fprint_sym (FILE *ofile, t_addr addr, t_value *val,
@@ -2128,14 +2147,12 @@ for (k = 0; k < lnt; k++) { /* print specified */
h = &hst[(di++) % hst_lnt]; /* entry pointer */
if (h->pc & HIST_PC) { /* instruction? */
fprintf (st, "%06X %08X %08X ", h->pc & VAMASK32, h->r1, h->opnd);
sim_eval[0] = op = (h->ir1 >> 8) & 0xFF;
sim_eval[1] = h->ir1 & 0xFF;
sim_eval[2] = (h->ir2 >> 8) & 0xFF;
sim_eval[3] = h->ir2 & 0xFF;
sim_eval[4] = (h->ir3 >> 8) & 0xFF;
sim_eval[5] = h->ir3 & 0xFF;
op = (h->ir1 >> 8) & 0xFF;
if (OP_TYPE (op) >= OP_RX) fprintf (st, "%06X ", h->ea);
else fprintf (st, " ");
sim_eval[0] = h->ir1;
sim_eval[1] = h->ir2;
sim_eval[2] = h->ir3;
if ((fprint_sym (st, h->pc & VAMASK32, sim_eval, &cpu_unit, SWMASK ('M'))) > 0)
fprintf (st, "(undefined) %04X", h->ir1);
fputc ('\n', st); /* end line */

View File

@@ -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;
}

View File

@@ -464,6 +464,8 @@ int32 int_chg (uint32 irq, int32 dat, int32 armdis);
int32 io_2b (int32 val, int32 pos, int32 old);
uint32 IOReadB (uint32 loc);
void IOWriteB (uint32 loc, uint32 val);
uint32 IOReadH (uint32 loc);
void IOWriteH (uint32 loc, uint32 val);
uint32 ReadF (uint32 loc, uint32 rel);
void WriteF (uint32 loc, uint32 val, uint32 rel);
uint32 IOReadBlk (uint32 loc, uint32 cnt, uint8 *buf);

View File

@@ -1,14 +1,14 @@
To: Users
From: Bob Supnik
Subj: Interdata 16b/32b Simulator Usage
Date: 15-Nov-2004
Date: 15-Mar-2005
COPYRIGHT NOTICE
The following copyright notice applies to both the SIMH source and binary:
Original code published in 1993-2004, written by Robert M Supnik
Copyright (c) 1993-2004, Robert M Supnik
Original code published in 1993-2005, written by Robert M Supnik
Copyright (c) 1993-2005, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -166,17 +166,23 @@ If memory size is being reduced, and the memory being truncated contains
non-zero data, the simulator asks for confirmation. Data in the truncated
portion of memory is lost. Initial memory size is 64KB.
These switches are recognized when examining or depositing in CPU memory
(or any other byte oriented device):
These switches are recognized when examining or depositing in CPU memory:
-a examine/deposit ASCII characters
-b examine/deposit bytes
-c examine/deposit packed ASCII characters
-w examine/deposit halfwords (CPU default)
-f examine/deposit fullwords
-d data radix is decimal
-o data radix is octal
-h data radix is hexadecimal
-m examine as instruction mnemonics
-v interpret address as virtual
Packed characters, halfwords, fullwords, and instructions must be aligned
on a halfword (16b) boundary. If an odd address is specified, the low
order bit is ignored.
CPU registers include the visible state of the processor as well as the
control registers for the interrupt system.
@@ -234,17 +240,22 @@ If memory size is being reduced, and the memory being truncated contains
non-zero data, the simulator asks for confirmation. Data in the truncated
portion of memory is lost. Initial memory size is 1024KB.
These switches are recognized when examining or depositing in CPU memory
(or any other byte oriented device):
These switches are recognized when examining or depositing in CPU memory:
-a examine/deposit ASCII characters
-b examine/deposit bytes
-w examine/deposit halfwords
-c examine/deposit packed ASCII characters
-f examine/deposit fullwords (CPU default)
-d data radix is decimal
-o data radix is octal
-h data radix is hexadecimal
-m examine as instruction mnemonics
-v interpret address as virtual
Packed characters, halfwords, fullwords, and instructions must be aligned
on a halfword (16b) boundary. If an odd address is specified, the low
order bit is ignored.
CPU registers include the visible state of the processor as well as the
control registers for the interrupt system.
@@ -845,8 +856,8 @@ Error handling is as follows:
The Interdata simulator implements symbolic display and input. Display is
controlled by command line switches:
-a display as ASCII character
-c display as two character string
-a display byte as ASCII character
-c display halfword as two packed ASCII characters
-m display instruction mnemonics
Input parsing is controlled by the first character typed in or by command
@@ -855,7 +866,7 @@ line switches:
' or -a ASCII character
" or -c two character sixbit string
alphabetic instruction mnemonic
numeric octal number
numeric hexadecimal number
2.8.1 16b Instruction Input

View File

@@ -1,6 +1,6 @@
/* id_dp.c: Interdata 2.5MB/10MB cartridge disk simulator
Copyright (c) 2001-2004, Robert M. Supnik
Copyright (c) 2001-2005, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -25,6 +25,7 @@
dp M46-421 2.5MB/10MB cartridge disk
18-Mar-05 RMS Added attached test to detach routine
25-Jan-04 RMS Revised for device debug support
25-Apr-03 RMS Revised for extended file support
16-Feb-03 RMS Fixed read to test transfer ok before selch operation
@@ -532,6 +533,7 @@ t_stat dp_detach (UNIT *uptr)
{
uint32 u = uptr - dp_dev.units;
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; /* attached? */
if (dpd_arm[u]) SET_INT (v_DPC + u + 1); /* if arm, intr */
return detach_unit (uptr);
}

View File

@@ -1,6 +1,6 @@
/* id_mt.c: Interdata magnetic tape simulator
Copyright (c) 2001-2004, Robert M Supnik
Copyright (c) 2001-2005, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -25,6 +25,7 @@
mt M46-494 dual density 9-track magtape controller
18-Mar-05 RMS Added attached test to detach routine
07-Dec-04 RMS Added read-only file support
25-Apr-03 RMS Revised for extended file support
28-Mar-03 RMS Added multiformat support
@@ -445,6 +446,7 @@ t_stat mt_detach (UNIT* uptr)
int32 u = uptr - mt_dev.units;
t_stat r;
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK;
r = sim_tape_detach (uptr);
if (r != SCPE_OK) return r;
if (mt_arm[u]) SET_INT (v_MT + u);