mirror of
https://github.com/open-simh/simh.git
synced 2026-01-26 04:02:39 +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
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user