mirror of
https://github.com/open-simh/simh.git
synced 2026-04-29 05:15:30 +00:00
simh 3.11
This commit is contained in:
committed by
Mark Pizzolato
parent
cf9ead8d04
commit
43360191c8
@@ -1,6 +1,6 @@
|
||||
/* vax_cis.c: VAX CIS instructions
|
||||
|
||||
Copyright (c) 2004-2016, Robert M Supnik
|
||||
Copyright (c) 2004-2019, 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"),
|
||||
@@ -26,6 +26,7 @@
|
||||
On a full VAX, this module simulates the VAX commercial instruction set (CIS).
|
||||
On a subset VAX, this module implements the emulated instruction fault.
|
||||
|
||||
03-May-19 RMS Documnted fall through cases (COVERITY)
|
||||
30-May-16 RMS Fixed WordLshift FOR REAL
|
||||
16-Oct-08 RMS Fixed bug in ASHP left overflow calc (Word/NibbleLshift)
|
||||
Fixed bug in DIVx (LntDstr calculation)
|
||||
@@ -460,7 +461,7 @@ switch (opc) { /* case on opcode */
|
||||
|
||||
case ADDP4: case SUBP4:
|
||||
op[4] = op[2]; /* copy dst */
|
||||
op[5] = op[3];
|
||||
op[5] = op[3]; /* fall through */
|
||||
case ADDP6: case SUBP6:
|
||||
if ((PSL & PSL_FPD) || (op[0] > 31) ||
|
||||
(op[2] > 31) || (op[4] > 31))
|
||||
@@ -629,7 +630,7 @@ switch (opc) { /* case on opcode */
|
||||
|
||||
case CMPP3:
|
||||
op[3] = op[2]; /* reposition ops */
|
||||
op[2] = op[0];
|
||||
op[2] = op[0]; /* fall through */
|
||||
case CMPP4:
|
||||
if ((PSL & PSL_FPD) || (op[0] > 31) || (op[2] > 31))
|
||||
RSVD_OPND_FAULT;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* vax_fpa.c - VAX f_, d_, g_floating instructions
|
||||
|
||||
Copyright (c) 1998-2012, Robert M Supnik
|
||||
Copyright (c) 1998-2019, 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"),
|
||||
@@ -23,6 +23,7 @@
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
20-Nov-19 RMS Fixed argument ordering in vax_fdiv declaration (Mark Pizzolata)
|
||||
23-Mar-12 RMS Fixed missing arguments in 32b floating add (Mark Pizzolato)
|
||||
15-Sep-11 RMS Fixed integer overflow bug in EMODx
|
||||
Fixed POLYx normalizing before add mask bug
|
||||
@@ -109,7 +110,7 @@ int32 rpackfd (UFP *a, int32 *rh);
|
||||
int32 rpackg (UFP *a, int32 *rh);
|
||||
void vax_fadd (UFP *a, UFP *b, uint32 mhi, uint32 mlo);
|
||||
void vax_fmul (UFP *a, UFP *b, t_bool qd, int32 bias, uint32 mhi, uint32 mlo);
|
||||
void vax_fdiv (UFP *b, UFP *a, int32 prec, int32 bias);
|
||||
void vax_fdiv (UFP *a, UFP *b, int32 prec, int32 bias);
|
||||
void vax_fmod (UFP *a, int32 bias, int32 *intgr, int32 *flg);
|
||||
|
||||
/* Quadword arithmetic shift
|
||||
@@ -653,7 +654,7 @@ int32 rpackg (UFP *a, int32 *rh);
|
||||
void vax_fadd (UFP *a, UFP *b, uint32 mhi, uint32 mlo);
|
||||
void vax_fmul (UFP *a, UFP *b, t_bool qd, int32 bias, uint32 mhi, uint32 mlo);
|
||||
void vax_fmod (UFP *a, int32 bias, int32 *intgr, int32 *flg);
|
||||
void vax_fdiv (UFP *b, UFP *a, int32 prec, int32 bias);
|
||||
void vax_fdiv (UFP *a, UFP *b, int32 prec, int32 bias);
|
||||
void dp_add (UDP *a, UDP *b);
|
||||
void dp_inc (UDP *a);
|
||||
void dp_sub (UDP *a, UDP *b);
|
||||
|
||||
78
VAX/vax_io.c
78
VAX/vax_io.c
@@ -1,6 +1,6 @@
|
||||
/* vax_io.c: VAX 3900 Qbus IO simulator
|
||||
|
||||
Copyright (c) 1998-2013, Robert M Supnik
|
||||
Copyright (c) 1998-2019, 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 @@
|
||||
|
||||
qba Qbus adapter
|
||||
|
||||
05-May-19 RMS Added length parameter to ReadReg routines
|
||||
Revamped Qbus memory as Qbus peripheral
|
||||
20-Dec-13 RMS Added unaligned access routines
|
||||
25-Mar-12 RMS Added parameter to int_ack prototype (Mark Pizzolata)
|
||||
28-May-08 RMS Inlined physical memory routines
|
||||
@@ -121,6 +123,8 @@ extern jmp_buf save_env;
|
||||
|
||||
t_stat dbl_rd (int32 *data, int32 addr, int32 access);
|
||||
t_stat dbl_wr (int32 data, int32 addr, int32 access);
|
||||
t_stat cqm_rd(int32 *dat, int32 ad, int32 md);
|
||||
t_stat cqm_wr(int32 dat, int32 ad, int32 md);
|
||||
int32 eval_int (void);
|
||||
void cq_merr (int32 pa);
|
||||
void cq_serr (int32 pa);
|
||||
@@ -203,6 +207,10 @@ int32 ReadQb (uint32 pa)
|
||||
{
|
||||
int32 idx, val;
|
||||
|
||||
if (ADDR_IS_CQM (pa)) { /* Qbus memory? */
|
||||
cqm_rd (&val, pa, READ);
|
||||
return val;
|
||||
}
|
||||
idx = (pa & IOPAGEMASK) >> 1;
|
||||
if (iodispR[idx]) {
|
||||
iodispR[idx] (&val, pa, READ);
|
||||
@@ -217,6 +225,10 @@ void WriteQb (uint32 pa, int32 val, int32 mode)
|
||||
{
|
||||
int32 idx;
|
||||
|
||||
if (ADDR_IS_CQM (pa)) { /* Qbus memory? */
|
||||
cqm_wr (val, pa, mode);
|
||||
return;
|
||||
}
|
||||
idx = (pa & IOPAGEMASK) >> 1;
|
||||
if (iodispW[idx]) {
|
||||
iodispW[idx] (val, pa, mode);
|
||||
@@ -438,7 +450,7 @@ return 0;
|
||||
IPC inter-processor communication register
|
||||
*/
|
||||
|
||||
int32 cqbic_rd (int32 pa)
|
||||
int32 cqbic_rd (int32 pa, int32 lnt)
|
||||
{
|
||||
int32 rg = (pa - CQBICBASE) >> 2;
|
||||
|
||||
@@ -470,7 +482,7 @@ int32 nval, rg = (pa - CQBICBASE) >> 2;
|
||||
if (lnt < L_LONG) {
|
||||
int32 sc = (pa & 3) << 3;
|
||||
int32 mask = (lnt == L_WORD)? 0xFFFF: 0xFF;
|
||||
int32 t = cqbic_rd (pa);
|
||||
int32 t = cqbic_rd (pa, lnt);
|
||||
nval = ((val & mask) << sc) | (t & ~(mask << sc));
|
||||
val = val << sc;
|
||||
}
|
||||
@@ -502,7 +514,7 @@ return;
|
||||
/* IPC can be read as local register or as Qbus I/O
|
||||
Because of the W1C */
|
||||
|
||||
int32 cqipc_rd (int32 pa)
|
||||
int32 cqipc_rd (int32 pa, int32 lnt)
|
||||
{
|
||||
return cq_ipc & CQIPC_MASK; /* IPC */
|
||||
}
|
||||
@@ -542,7 +554,7 @@ return SCPE_OK;
|
||||
Write error: set DSER<0>, latch slave address, memory error interrupt
|
||||
*/
|
||||
|
||||
int32 cqmap_rd (int32 pa)
|
||||
int32 cqmap_rd (int32 pa, int32 lnt)
|
||||
{
|
||||
int32 ma = (pa & CQMAPAMASK) + cq_mbr; /* mem addr */
|
||||
|
||||
@@ -575,36 +587,58 @@ return;
|
||||
|
||||
/* CQBIC Qbus memory read and write (reflects to main memory)
|
||||
|
||||
May give master or slave error, depending on where the failure occurs
|
||||
Qbus memory is modeled like any other Qbus peripheral.
|
||||
On read, it returns 16b, right justified.
|
||||
On write, it handles either 16b or 8b writes.
|
||||
|
||||
Qbus memory may reflect to main memory or may be locally
|
||||
implemented for graphics cards. If reflected to main memory,
|
||||
the normal ReadW, WriteB, and WriteW routines cannot be used,
|
||||
as that could create a recursive loop.
|
||||
*/
|
||||
|
||||
int32 cqmem_rd (int32 pa)
|
||||
t_stat cqm_rd (int32 *dat, int32 pa, int32 md)
|
||||
{
|
||||
int32 qa = pa & CQMAMASK; /* Qbus addr */
|
||||
uint32 ma;
|
||||
|
||||
if (qba_map_addr (qa, &ma)) /* map addr */
|
||||
return M[ma >> 2];
|
||||
if (qba_map_addr (qa, &ma)) { /* in map? */
|
||||
if (ADDR_IS_MEM (ma)) { /* real memory? */
|
||||
*dat = (M[ma >> 2] >> ((pa & 2) ? 16 : 0)) & WMASK;
|
||||
return SCPE_OK; /* return word */
|
||||
} /* end if mem */
|
||||
cq_serr (ma);
|
||||
MACH_CHECK (MCHK_READ); /* mcheck */
|
||||
} /* end if mapped */
|
||||
// insert graphics code here
|
||||
MACH_CHECK (MCHK_READ); /* err? mcheck */
|
||||
return 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
void cqmem_wr (int32 pa, int32 val, int32 lnt)
|
||||
t_stat cqm_wr (int32 dat, int32 pa, int32 md)
|
||||
{
|
||||
int32 qa = pa & CQMAMASK; /* Qbus addr */
|
||||
uint32 ma;
|
||||
|
||||
if (qba_map_addr (qa, &ma)) { /* map addr */
|
||||
if (lnt < L_LONG) {
|
||||
int32 sc = (pa & 3) << 3;
|
||||
int32 mask = (lnt == L_WORD)? 0xFFFF: 0xFF;
|
||||
int32 t = M[ma >> 2];
|
||||
val = ((val & mask) << sc) | (t & ~(mask << sc));
|
||||
}
|
||||
M[ma >> 2] = val;
|
||||
}
|
||||
else mem_err = 1;
|
||||
return;
|
||||
if (qba_map_addr (qa, &ma)) { /* in map? */
|
||||
if (ADDR_IS_MEM (ma)) { /* real memory? */
|
||||
if (md == WRITE) { /* word access? */
|
||||
int32 sc = (ma & 2) << 3; /* aligned only */
|
||||
M[ma >> 2] = (M[ma >> 2] & ~(WMASK << sc)) |
|
||||
((dat & WMASK) << sc);
|
||||
}
|
||||
else { /* byte access */
|
||||
int32 sc = (ma & 3) << 3;
|
||||
M[ma >> 2] = (M[ma >> 2] & ~(BMASK << sc)) |
|
||||
((dat & BMASK) << sc);
|
||||
}
|
||||
} /* end if mem */
|
||||
else mem_err = 1;
|
||||
return SCPE_OK;
|
||||
} /* end if mapped */
|
||||
//insert graphics code here
|
||||
mem_err = 1;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Map an address via the translation map */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* vax_octa.c - VAX octaword and h_floating instructions
|
||||
|
||||
Copyright (c) 2004-2011, Robert M Supnik
|
||||
Copyright (c) 2004-2019, 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 @@
|
||||
|
||||
This module simulates the VAX h_floating instruction set.
|
||||
|
||||
03-May-19 RMS Fixed COVERITY complaint in h_unpackh
|
||||
15-Sep-11 RMS Fixed integer overflow bug in EMODH
|
||||
Fixed POLYH normalizing before add mask bug
|
||||
(Camiel Vanderhoeven)
|
||||
@@ -1059,7 +1060,8 @@ if (r->exp == 0) { /* exp = 0? */
|
||||
r->frac.f2 = r->frac.f3 = 0;
|
||||
return;
|
||||
}
|
||||
r->frac.f3 = WORDSWAP ((hflt[0] & ~(FPSIGN | H_EXP)) | H_HB);
|
||||
r->frac.f3 = (hflt[0] & ~(FPSIGN | H_EXP)) | H_HB; /* del sign, exp, add hb */
|
||||
r->frac.f3 = WORDSWAP (r->frac.f3);
|
||||
r->frac.f2 = WORDSWAP (hflt[1]);
|
||||
r->frac.f1 = WORDSWAP (hflt[2]);
|
||||
r->frac.f0 = WORDSWAP (hflt[3]);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* vax_sysdev.c: VAX 3900 system-specific logic
|
||||
|
||||
Copyright (c) 1998-2013, Robert M Supnik
|
||||
Copyright (c) 1998-2019, 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"),
|
||||
@@ -33,6 +33,8 @@
|
||||
cmctl memory controller
|
||||
sysd system devices (SSC miscellany)
|
||||
|
||||
05-May-19 RMS Added length to register read routines
|
||||
Removed Qbus memory space from register space
|
||||
20-Dec-13 RMS Added unaligned register space access routines
|
||||
23-Dec-10 RMS Added power clear call to boot routine (Mark Pizzolato)
|
||||
25-Oct-05 RMS Automated CMCTL extended memory
|
||||
@@ -233,8 +235,8 @@ t_stat cso_svc (UNIT *uptr);
|
||||
t_stat tmr_svc (UNIT *uptr);
|
||||
t_stat sysd_reset (DEVICE *dptr);
|
||||
|
||||
int32 rom_rd (int32 pa);
|
||||
int32 nvr_rd (int32 pa);
|
||||
int32 rom_rd (int32 pa, int32 lnt);
|
||||
int32 nvr_rd (int32 pa, int32 lnt);
|
||||
void nvr_wr (int32 pa, int32 val, int32 lnt);
|
||||
int32 csrs_rd (void);
|
||||
int32 csrd_rd (void);
|
||||
@@ -242,13 +244,13 @@ int32 csts_rd (void);
|
||||
void csrs_wr (int32 dat);
|
||||
void csts_wr (int32 dat);
|
||||
void cstd_wr (int32 dat);
|
||||
int32 cmctl_rd (int32 pa);
|
||||
int32 cmctl_rd (int32 pa, int32 lnt);
|
||||
void cmctl_wr (int32 pa, int32 val, int32 lnt);
|
||||
int32 ka_rd (int32 pa);
|
||||
int32 ka_rd (int32 pa, int32 lnt);
|
||||
void ka_wr (int32 pa, int32 val, int32 lnt);
|
||||
int32 cdg_rd (int32 pa);
|
||||
int32 cdg_rd (int32 pa, int32 lnt);
|
||||
void cdg_wr (int32 pa, int32 val, int32 lnt);
|
||||
int32 ssc_rd (int32 pa);
|
||||
int32 ssc_rd (int32 pa, int32 lnt);
|
||||
void ssc_wr (int32 pa, int32 val, int32 lnt);
|
||||
int32 tmr_tir_rd (int32 tmr, t_bool interp);
|
||||
void tmr_csr_wr (int32 tmr, int32 val);
|
||||
@@ -260,14 +262,12 @@ int32 parity (int32 val, int32 odd);
|
||||
t_stat sysd_powerup (void);
|
||||
|
||||
extern int32 intexc (int32 vec, int32 cc, int32 ipl, int ei);
|
||||
extern int32 cqmap_rd (int32 pa);
|
||||
extern int32 cqmap_rd (int32 pa, int32 lnt);
|
||||
extern void cqmap_wr (int32 pa, int32 val, int32 lnt);
|
||||
extern int32 cqipc_rd (int32 pa);
|
||||
extern int32 cqipc_rd (int32 pa, int32 lnt);
|
||||
extern void cqipc_wr (int32 pa, int32 val, int32 lnt);
|
||||
extern int32 cqbic_rd (int32 pa);
|
||||
extern int32 cqbic_rd (int32 pa, int32 lnt);
|
||||
extern void cqbic_wr (int32 pa, int32 val, int32 lnt);
|
||||
extern int32 cqmem_rd (int32 pa);
|
||||
extern void cqmem_wr (int32 pa, int32 val, int32 lnt);
|
||||
extern int32 iccs_rd (void);
|
||||
extern int32 todr_rd (void);
|
||||
extern int32 rxcs_rd (void);
|
||||
@@ -526,7 +526,7 @@ for (i = 0; i < l; i++)
|
||||
return val + rom_loopval;
|
||||
}
|
||||
|
||||
int32 rom_rd (int32 pa)
|
||||
int32 rom_rd (int32 pa, int32 lnt)
|
||||
{
|
||||
int32 rg = ((pa - ROMBASE) & ROMAMASK) >> 2;
|
||||
|
||||
@@ -583,7 +583,7 @@ return SCPE_OK;
|
||||
|
||||
/* NVR: non-volatile RAM - stored in a buffered file */
|
||||
|
||||
int32 nvr_rd (int32 pa)
|
||||
int32 nvr_rd (int32 pa, int32 lnt)
|
||||
{
|
||||
int32 rg = (pa - NVRBASE) >> 2;
|
||||
|
||||
@@ -925,7 +925,7 @@ return;
|
||||
struct reglink { /* register linkage */
|
||||
uint32 low; /* low addr */
|
||||
uint32 high; /* high addr */
|
||||
int32 (*read)(int32 pa); /* read routine */
|
||||
int32 (*read)(int32 pa, int32 lnt); /* read routine */
|
||||
void (*write)(int32 pa, int32 val, int32 lnt); /* write routine */
|
||||
};
|
||||
|
||||
@@ -938,7 +938,6 @@ struct reglink regtable[] = {
|
||||
{ KABASE, KABASE+KASIZE, &ka_rd, &ka_wr },
|
||||
{ CQBICBASE, CQBICBASE+CQBICSIZE, &cqbic_rd, &cqbic_wr },
|
||||
{ CQIPCBASE, CQIPCBASE+CQIPCSIZE, &cqipc_rd, &cqipc_wr },
|
||||
{ CQMBASE, CQMBASE+CQMSIZE, &cqmem_rd, &cqmem_wr },
|
||||
{ CDGBASE, CDGBASE+CDGSIZE, &cdg_rd, &cdg_wr },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
@@ -958,7 +957,7 @@ struct reglink *p;
|
||||
|
||||
for (p = ®table[0]; p->low != 0; p++) {
|
||||
if ((pa >= p->low) && (pa < p->high) && p->read)
|
||||
return p->read (pa);
|
||||
return p->read(pa, lnt);
|
||||
}
|
||||
ssc_bto = ssc_bto | SSCBTO_BTO | SSCBTO_RWT;
|
||||
MACH_CHECK (MCHK_READ);
|
||||
@@ -1037,7 +1036,7 @@ return;
|
||||
The CMCTL registers are cleared at power up.
|
||||
*/
|
||||
|
||||
int32 cmctl_rd (int32 pa)
|
||||
int32 cmctl_rd (int32 pa, int32 lnt)
|
||||
{
|
||||
int32 rg = (pa - CMCTLBASE) >> 2;
|
||||
|
||||
@@ -1100,7 +1099,7 @@ return;
|
||||
|
||||
/* KA655 registers */
|
||||
|
||||
int32 ka_rd (int32 pa)
|
||||
int32 ka_rd (int32 pa, int32 lnt)
|
||||
{
|
||||
int32 rg = (pa - KABASE) >> 2;
|
||||
|
||||
@@ -1134,7 +1133,7 @@ return ka_bdr & BDR_BRKENB;
|
||||
|
||||
/* Cache diagnostic space */
|
||||
|
||||
int32 cdg_rd (int32 pa)
|
||||
int32 cdg_rd (int32 pa, int32 lnt)
|
||||
{
|
||||
int32 t, row = CDG_GETROW (pa);
|
||||
|
||||
@@ -1171,9 +1170,9 @@ for ( ; val != 0; val = val >> 1) {
|
||||
return odd;
|
||||
}
|
||||
|
||||
/* SSC registers - byte/word merges done in WriteReg */
|
||||
/* SSC registers - byte/word merges done in ssc_wr */
|
||||
|
||||
int32 ssc_rd (int32 pa)
|
||||
int32 ssc_rd (int32 pa, int32 lnt)
|
||||
{
|
||||
int32 rg = (pa - SSCBASE) >> 2;
|
||||
|
||||
@@ -1259,7 +1258,7 @@ int32 rg = (pa - SSCBASE) >> 2;
|
||||
if (lnt < L_LONG) { /* byte or word? */
|
||||
int32 sc = (pa & 3) << 3; /* merge */
|
||||
int32 mask = (lnt == L_WORD)? 0xFFFF: 0xFF;
|
||||
int32 t = ssc_rd (pa);
|
||||
int32 t = ssc_rd (pa, lnt);
|
||||
val = ((val & mask) << sc) | (t & ~(mask << sc));
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
05-May-19 RMS Added Qbus memory space to ADDR_IS_IO test
|
||||
23-Apr-19 RMS Added hook for unpredictable indexed immediate .aw
|
||||
18-May-17 RMS Added model-specific AST validation test
|
||||
29-Mar-15 RMS Added model-specific IPR max
|
||||
@@ -147,7 +148,7 @@
|
||||
#define IOPAGESIZE (1u << IOPAGEAWIDTH) /* IO page length */
|
||||
#define IOPAGEMASK (IOPAGESIZE - 1) /* IO addr mask */
|
||||
#define IOPAGEBASE 0x20000000 /* IO page base */
|
||||
#define ADDR_IS_IO(x) ((((uint32) (x)) >= IOPAGEBASE) && \
|
||||
#define ADDR_IS_IOP(x) ((((uint32) (x)) >= IOPAGEBASE) && \
|
||||
(((uint32) (x)) < (IOPAGEBASE + IOPAGESIZE)))
|
||||
|
||||
/* Read only memory - appears twice */
|
||||
@@ -208,6 +209,13 @@
|
||||
#define CQMSIZE (1u << CQMAWIDTH) /* Qmem length */
|
||||
#define CQMAMASK (CQMSIZE - 1) /* Qmem addr mask */
|
||||
#define CQMBASE 0x30000000 /* Qmem base */
|
||||
#define ADDR_IS_CQM(x) ((((uint32) (x)) >= CQMBASE) && \
|
||||
(((uint32) (x)) < (CQMBASE + CQMSIZE)))
|
||||
|
||||
/* Reflect to IO on either IO space or Qbus memory */
|
||||
|
||||
#define ADDR_IS_IO(x) (ADDR_IS_IOP(x) || ADDR_IS_CQM(x))
|
||||
|
||||
|
||||
/* Machine specific reserved operand tests (mostly NOPs) */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user