VAX: New simulator for VAX 8200

This commit is contained in:
Matt Burke 2019-04-21 09:09:32 -07:00 committed by Mark Pizzolato
parent 4e0450cff9
commit 1d15966191
14 changed files with 5163 additions and 6 deletions

View file

@ -55,9 +55,10 @@
VAX/11 730
VAX/11 750
VAX 8200
VAX 8600/8650
MicroVAX I & VAXStation I
MicroVAX II & VAXStation II
MicroVAX II & VAXStation II & VAXStation II GPX
rtVAX 1000 (or Industrial VAX 620)
#### Howard Harte has implemented a Lincoln Labs TX-0 simulator.

826
VAX/vax820_bi.c Normal file
View file

@ -0,0 +1,826 @@
/* vax820_bi.c: VAX 8200 BI
Copyright (c) 2019, Matt Burke
This module incorporates code from SimH, Copyright (c) 2004-2008, 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"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name(s) of the author(s) shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the author(s).
This module contains the VAX 8200 system-specific registers and devices.
bi bus controller
*/
#include "vax_defs.h"
#ifdef DONT_USE_INTERNAL_ROM
#define BOOT_CODE_FILENAME "vmb.exe"
#else /* !DONT_USE_INTERNAL_ROM */
#include "vax_vmb_exe.h" /* Defines BOOT_CODE_FILENAME and BOOT_CODE_ARRAY, etc */
#endif /* DONT_USE_INTERNAL_ROM */
/* KA820 specific IPRs */
/* Writeable control store */
#define WCSA_RW 0x3FFFFF /* writeable */
#define WCSD_RD_VAL 0xFF /* fixed read val */
#define WCSD_WR 0xFFFFFFFF /* write */
#define MBRK_RW 0x1FFF /* microbreak */
/* KA820 boot device definitions */
struct boot_dev {
const char *name;
int32 code;
int32 let;
};
uint32 wcs_addr = 0;
uint32 wcs_data = 0;
uint32 nexus_req[NEXUS_HLVL]; /* nexus int req */
int32 ipr_int = 0;
int32 rxcd_int = 0;
int32 ipir = 0;
int32 sys_model = 0;
int32 mchk_flag[KA_NUM] = { 0 };
char cpu_boot_cmd[CBUFSIZE] = { 0 }; /* boot command */
static t_stat (*nexusR[NEXUS_NUM])(int32 *dat, int32 ad, int32 md);
static t_stat (*nexusW[NEXUS_NUM])(int32 dat, int32 ad, int32 md);
static struct boot_dev boot_tab[] = {
{ "HK", BOOT_HK, 0 },
{ "RL", BOOT_RL, 0 },
{ "RQ", BOOT_UDA, 1 << 24 },
{ "RQB", BOOT_UDA, 1 << 24 },
{ "RQC", BOOT_UDA, 1 << 24 },
{ "RQD", BOOT_UDA, 1 << 24 },
{ "CS", BOOT_CS, 0 },
{ NULL }
};
extern int32 tmr_int, tti_int, tto_int, fl_int;
extern int32 cur_cpu;
t_stat bi_reset (DEVICE *dptr);
t_stat vax820_boot (int32 flag, CONST char *ptr);
t_stat vax820_boot_parse (int32 flag, CONST char *ptr);
t_stat cpu_boot (int32 unitno, DEVICE *dptr);
extern void uba_eval_int (void);
extern int32 uba_get_ubvector (int32 lvl);
extern void wtc_set_valid (void);
extern void wtc_set_invalid (void);
extern int32 iccs_rd (void);
extern int32 nicr_rd (void);
extern int32 icr_rd (void);
extern int32 todr_rd (void);
extern int32 rxcs_rd (void);
extern int32 rxdb_rd (void);
extern int32 txcs_rd (void);
extern int32 rxcd_rd (void);
extern int32 wtc_rd (int32 pa);
extern int32 pcsr_rd (int32 pa);
extern int32 fl_rd (int32 pa);
extern void iccs_wr (int32 dat);
extern void nicr_wr (int32 dat);
extern void todr_wr (int32 dat);
extern void rxcs_wr (int32 dat);
extern void txcs_wr (int32 dat);
extern void txdb_wr (int32 dat);
extern void rxcd_wr (int32 val);
extern void wtc_wr (int32 pa, int32 val, int32 lnt);
extern void pcsr_wr (int32 pa, int32 val, int32 lnt);
extern void fl_wr (int32 pa, int32 val, int32 lnt);
extern void init_ubus_tab (void);
extern t_stat build_ubus_tab (DEVICE *dptr, DIB *dibp);
/* BI data structures
bi_dev BI device descriptor
bi_unit BI unit
bi_reg BI register list
*/
UNIT bi_unit = { UDATA (NULL, 0, 0) };
REG bi_reg[] = {
{ HRDATA (NREQ14, nexus_req[0], 16) },
{ HRDATA (NREQ15, nexus_req[1], 16) },
{ HRDATA (NREQ16, nexus_req[2], 16) },
{ HRDATA (NREQ17, nexus_req[3], 16) },
{ HRDATA (WCSA, wcs_addr, 21) },
{ HRDATA (WCSD, wcs_data, 32) },
{ NULL }
};
DEVICE bi_dev = {
"BI", &bi_unit, bi_reg, NULL,
1, 16, 16, 1, 16, 8,
NULL, NULL, &bi_reset,
NULL, NULL, NULL,
NULL, 0
};
/* Special boot command, overrides regular boot */
CTAB vax820_cmd[] = {
{ "BOOT", &vax820_boot, RU_BOOT,
"bo{ot} <device>{/R5:flg} boot device\n"
" type HELP CPU to see bootable devices\n", NULL, &run_cmd_message },
{ NULL }
};
/* The VAX 8200 has three sources of interrupts
- internal device interrupts (CPU, console, clock)
- nexus interupts (e.g., memory controller, MBA, UBA)
- external device interrupts (Unibus)
Internal devices vector to fixed SCB locations.
Nexus interrupts vector to an SCB location based on this
formula: SCB_NEXUS + ((IPL - 0x14) * 0x40) + (TR# * 0x4)
External device interrupts do not vector directly.
Instead, the interrupt handler for a given UBA IPL
reads a vector register that contains the Unibus vector
for that IPL.
*/
/* Find highest priority vectorable interrupt */
int32 eval_int (void)
{
int32 ipl = PSL_GETIPL (PSL);
int32 cpu_msk = (1u << cur_cpu);
int32 i, t;
static const int32 sw_int_mask[IPL_SMAX] = {
0xFFFE, 0xFFFC, 0xFFF8, 0xFFF0, /* 0 - 3 */
0xFFE0, 0xFFC0, 0xFF80, 0xFF00, /* 4 - 7 */
0xFE00, 0xFC00, 0xF800, 0xF000, /* 8 - B */
0xE000, 0xC000, 0x8000 /* C - E */
};
if (hlt_pin) /* hlt pin int */
return IPL_HLTPIN;
if ((ipl < IPL_CRDERR) && crd_err) /* crd err int */
return IPL_CRDERR;
if ((ipl < IPL_CLKINT) && tmr_int) /* clock int */
return IPL_CLKINT;
uba_eval_int (); /* update UBA */
for (i = IPL_HMAX; i >= IPL_HMIN; i--) { /* chk hwre int */
if (i <= ipl) /* at ipl? no int */
return 0;
if (nexus_req[i - IPL_HMIN]) /* req != 0? int */
return i;
}
if ((ipl < IPL_RXCDINT) && rxcd_int) /* rxcd int */
return IPL_RXCDINT;
if ((ipl < IPL_IPRINT) && (ipir & cpu_msk)) /* ipr int */
return IPL_IPRINT;
if ((ipl < IPL_FLINT) && fl_int) /* console floppy int */
return IPL_FLINT;
if ((ipl < IPL_TTINT) && (tti_int && (cur_cpu == 0))) /* console int */
return IPL_TTINT;
if ((ipl < IPL_TTINT) && (tto_int & cpu_msk)) /* console int */
return IPL_TTINT;
if (ipl >= IPL_SMAX) /* ipl >= sw max? */
return 0;
if ((t = SISR & sw_int_mask[ipl]) == 0)
return 0; /* eligible req */
for (i = IPL_SMAX; i > ipl; i--) { /* check swre int */
if ((t >> i) & 1) /* req != 0? int */
return i;
}
return 0;
}
/* Return vector for highest priority hardware interrupt at IPL lvl */
int32 get_vector (int32 lvl)
{
int32 i, l;
int32 vec;
int32 cpu_msk = (1u << cur_cpu);
if (lvl == IPL_CRDERR) { /* CRD error? */
crd_err = 0;
return SCB_CRDERR;
}
if (lvl == IPL_CLKINT) { /* clock? */
tmr_int = tmr_int & ~(1u << cur_cpu); /* clear req */
return SCB_INTTIM; /* return vector */
}
if (lvl > IPL_HMAX) { /* error req lvl? */
ABORT (STOP_UIPL); /* unknown intr */
}
if ((lvl <= IPL_HMAX) && (lvl >= IPL_HMIN)) { /* nexus? */
l = lvl - IPL_HMIN;
if (nexus_req[l] & (1u << TR_UBA)) { /* unibus int? */
nexus_req[l] = nexus_req[l] & ~(1u << TR_UBA);
vec = uba_get_ubvector(l);
return vec; /* return vector */
}
for (i = 0; nexus_req[l] && (i < NEXUS_NUM); i++) {
if ((nexus_req[l] >> i) & 1) {
nexus_req[l] = nexus_req[l] & ~(1u << i);
vec = SCB_NEXUS + (l << 6) + (i << 2);
return vec; /* return vector */
}
}
}
if (lvl == IPL_RXCDINT) {
if (rxcd_int) {
rxcd_int = 0; /* clear req */
return SCB_RXCD; /* return vector */
}
}
if (lvl == IPL_IPRINT) { /* inter-processor? */
if (ipir & (1u << cur_cpu)) {
ipir = ipir & ~(1u << cur_cpu); /* clear req */
return SCB_IPRINT; /* return vector */
}
}
if (lvl == IPL_FLINT) { /* console floppy? */
if (fl_int) {
fl_int = 0; /* clear req */
return SCB_FLINT; /* return vector */
}
}
if (lvl == IPL_TTINT) { /* console? */
if (tti_int && (cur_cpu == 0)) { /* input? */
tti_int = 0; /* clear req */
return SCB_TTI; /* return vector */
}
if (tto_int & cpu_msk) { /* output? */
tto_int = 0; /* clear req */
return SCB_TTO; /* return vector */
}
}
return 0;
}
/* Read 8200-specific IPR's */
int32 ReadIPR (int32 rg)
{
int32 val;
switch (rg) {
case MT_ICCS: /* ICCS */
val = iccs_rd ();
break;
case MT_NICR: /* NICR */
val = nicr_rd ();
break;
case MT_ICR: /* ICR */
val = icr_rd ();
break;
case MT_TODR: /* TODR */
val = todr_rd ();
break;
case MT_RXCS: /* RXCS */
if (cur_cpu == 0)
val = rxcs_rd ();
else
val = 0;
break;
case MT_RXDB: /* RXDB */
if (cur_cpu == 0)
val = rxdb_rd ();
else
val = 0;
break;
case MT_TXCS: /* TXCS */
val = txcs_rd ();
break;
case MT_TBDR: /* TBDR (not impl) */
val = 0;
break;
case MT_CADR: /* CADR (not impl) */
val = 0;
break;
case MT_ACCS: /* ACCS (not impl) */
val = 0;
break;
case MT_WCSA: /* WCSA */
val = wcs_addr & WCSA_RW;
break;
case MT_WCSD: /* WCSD */
val = WCSD_RD_VAL;
break;
case MT_SID: /* SID */
if (sys_model)
val = VAX820_SID | VAX820_REV | VAX820_PATCH | VAX825_TYP | VAX820_UCODE;
else
val = VAX820_SID | VAX820_REV | VAX820_PATCH | VAX820_TYP | VAX820_UCODE;
break;
case MT_RXCS1: /* RXCS1 */
val = 0;
break;
case MT_RXDB1: /* RXDB1 */
val = 0;
break;
case MT_TXCS1: /* TXCS1 */
val = CSR_DONE;
break;
case MT_RXCS2: /* RXCS2 */
val = 0;
break;
case MT_RXDB2: /* RXDB2 */
val = 0;
break;
case MT_TXCS2: /* TXCS2 */
val = CSR_DONE;
break;
case MT_RXCS3: /* RXCS3 */
val = 0;
break;
case MT_RXDB3: /* RXDB3 */
val = 0;
break;
case MT_TXCS3: /* TXCS3 */
val = CSR_DONE;
break;
case MT_BINID: /* BINID */
val = TR_KA0 + cur_cpu;
break;
case MT_RXCD: /* RXCD */
val = rxcd_rd ();
break;
default:
RSVD_OPND_FAULT;
}
return val;
}
/* Write 8200-specific IPR's */
void WriteIPR (int32 rg, int32 val)
{
switch (rg) {
case MT_IPIR: /* IPIR */
ipir = val;
break;
case MT_ICCS: /* ICCS */
iccs_wr (val);
break;
case MT_NICR: /* NICR */
nicr_wr (val);
break;
case MT_TODR: /* TODR */
todr_wr (val);
break;
case MT_RXCS: /* RXCS */
if (cur_cpu == 0)
rxcs_wr (val);
break;
case MT_TXCS: /* TXCS */
txcs_wr (val);
break;
case MT_TXDB: /* TXDB */
txdb_wr (val);
break;
case MT_TBDR: /* TBDR (not impl) */
break;
case MT_CADR: /* CADR (not impl) */
break;
case MT_MCESR: /* MCESR */
mchk_flag[cur_cpu] = 0;
break;
case MT_ACCS: /* ACCS (not impl) */
break;
case MT_WCSA: /* WCSA */
wcs_addr = val & WCSA_RW;
break;
case MT_WCSL: /* WCSL */
wcs_data = val & WCSD_WR;
break;
case MT_RXCS1: /* RXCS1 */
case MT_TXCS1: /* TXCS1 */
case MT_TXDB1: /* TXDB1 */
case MT_RXCS2: /* RXCS2 */
case MT_TXCS2: /* TXCS2 */
case MT_TXDB2: /* TXDB2 */
case MT_RXCS3: /* RXCS3 */
case MT_TXCS3: /* TXCS3 */
case MT_TXDB3: /* TXDB3 */
case MT_CACHEX: /* CACHEX */
case MT_BISTOP: /* BISTOP */
break;
case MT_RXCD: /* RXCD */
rxcd_wr (val);
break;
default:
RSVD_OPND_FAULT;
}
return;
}
struct reglink { /* register linkage */
uint32 low; /* low addr */
uint32 high; /* high addr */
int32 (*read)(int32 pa); /* read routine */
void (*write)(int32 pa, int32 val, int32 lnt); /* write routine */
};
struct reglink regtable[] = {
{ WATCHBASE, WATCHBASE+WATCHSIZE, &wtc_rd, &wtc_wr },
{ 0x20088000, 0x20088004, &pcsr_rd, &pcsr_wr },
{ 0x200B0000, 0x200B0020, &fl_rd, &fl_wr },
{ 0, 0, NULL, NULL }
};
/* ReadReg - read register space
Inputs:
pa = physical address
lnt = length (BWLQ)
Output:
longword of data
*/
int32 ReadReg (uint32 pa, int32 lnt)
{
int32 nexus, val;
struct reglink *p;
if (ADDR_IS_REG (pa)) { /* reg space? */
nexus = NEXUS_GETNEX (pa); /* get nexus */
if (nexusR[nexus] && /* valid? */
(nexusR[nexus] (&val, pa, lnt) == SCPE_OK)) {
SET_IRQL;
return val;
}
MACH_CHECK (MCHK_BIERR); /* machine check */
return 0;
}
for (p = &regtable[0]; p->low != 0; p++) {
if ((pa >= p->low) && (pa < p->high) && p->read)
return p->read (pa);
}
return 0;
}
/* WriteReg - write register space
Inputs:
pa = physical address
val = data to write, right justified in 32b longword
lnt = length (BWLQ)
Outputs:
none
*/
void WriteReg (uint32 pa, int32 val, int32 lnt)
{
int32 nexus;
struct reglink *p;
if (ADDR_IS_REG (pa)) { /* reg space? */
nexus = NEXUS_GETNEX (pa); /* get nexus */
if (nexusW[nexus] && /* valid? */
(nexusW[nexus] (val, pa, lnt) == SCPE_OK)) {
SET_IRQL;
return;
}
}
for (p = &regtable[0]; p->low != 0; p++) {
if ((pa >= p->low) && (pa < p->high) && p->write) {
p->write (pa, val, lnt);
return;
}
}
return;
}
/* Machine check
Error status word format
<2:0> = ASTLVL
<3> = PME
<6:4> = arith trap code
Rest will be zero
*/
int32 machine_check (int32 p1, int32 opc, int32 cc, int32 delta)
{
int32 acc;
if (mchk_flag[cur_cpu]) /* double error? */
ABORT (STOP_INIE); /* halt */
mchk_flag[cur_cpu] = 1;
if (in_ie) /* in exc? panic */
ABORT (STOP_INIE);
cc = intexc (SCB_MCHK, cc, 0, IE_SVE); /* take exception */
acc = ACC_MASK (KERN); /* in kernel mode */
in_ie = 1;
SP = SP - 36; /* push 8 words */
Write (SP, 32, L_LONG, WA); /* # bytes */
Write (SP + 4, p1, L_LONG, WA); /* mcheck type */
Write (SP + 8, 0, L_LONG, WA); /* parameter 1 */
Write (SP + 12, mchk_va, L_LONG, WA); /* VA */
Write (SP + 16, mchk_va, L_LONG, WA); /* VA prime */
Write (SP + 20, 0, L_LONG, WA); /* memory address */
Write (SP + 24, 0x00400000, L_LONG, WA); /* status word */
Write (SP + 28, PC, L_LONG, WA); /* PC at failure */
Write (SP + 32, 0, L_LONG, WA); /* uPC at failure */
in_ie = 0;
return cc;
}
/* Console entry - only reached if CONHALT is set (AUTORESTART is set */
int32 con_halt (int32 code, int32 cc)
{
if ((cpu_boot_cmd[0] == 0) || /* saved boot cmd? */
(vax820_boot_parse (0, cpu_boot_cmd) != SCPE_OK) || /* reparse the boot cmd */
(reset_all (0) != SCPE_OK) || /* reset the world */
(cpu_boot (0, NULL) != SCPE_OK)) /* set up boot code */
ABORT (STOP_BOOT); /* any error? */
sim_printf ("Rebooting...\n");
return cc;
}
/* Special boot command - linked into SCP by initial reset
Syntax: BOOT <device>{/R5:val}
Sets up R0-R5, calls SCP boot processor with effective BOOT CPU
*/
t_stat vax820_boot (int32 flag, CONST char *ptr)
{
t_stat r;
r = vax820_boot_parse (flag, ptr); /* parse the boot cmd */
if (r != SCPE_OK) { /* error? */
if (r >= SCPE_BASE) { /* message available? */
sim_printf ("%s\n", sim_error_text (r));
r |= SCPE_NOMESSAGE;
}
return r;
}
strncpy (cpu_boot_cmd, ptr, CBUFSIZE-1); /* save for reboot */
return run_cmd (flag, "CPU");
}
t_stat vax820_boot_parse (int32 flag, CONST char *ptr)
{
char gbuf[CBUFSIZE];
char *slptr;
const char *regptr;
int32 i, r5v, unitno;
DEVICE *dptr;
UNIT *uptr;
DIB *dibp;
t_stat r;
if (!ptr || !*ptr)
return SCPE_2FARG;
regptr = get_glyph (ptr, gbuf, 0); /* get glyph */
if ((slptr = strchr (gbuf, '/'))) { /* found slash? */
regptr = strchr (ptr, '/'); /* locate orig */
*slptr = 0; /* zero in string */
}
dptr = find_unit (gbuf, &uptr); /* find device */
if ((dptr == NULL) || (uptr == NULL))
return SCPE_ARG;
dibp = (DIB *) dptr->ctxt; /* get DIB */
if (dibp == NULL)
return SCPE_ARG;
unitno = (int32) (uptr - dptr->units);
r5v = 0;
/* coverity[NULL_RETURNS] */
if ((strncmp (regptr, "/R5:", 4) == 0) ||
(strncmp (regptr, "/R5=", 4) == 0) ||
(strncmp (regptr, "/r5:", 4) == 0) ||
(strncmp (regptr, "/r5=", 4) == 0)) {
r5v = (int32) get_uint (regptr + 4, 16, LMASK, &r);
if (r != SCPE_OK)
return r;
}
else if (*regptr != 0)
return SCPE_ARG;
for (i = 0; boot_tab[i].name != NULL; i++) {
if (strcmp (dptr->name, boot_tab[i].name) == 0) {
R[0] = boot_tab[i].code;
R[1] = TR_UBA;
R[2] = boot_tab[i].let | (dibp->ba & UBADDRMASK);
R[3] = unitno;
R[4] = 0;
R[5] = r5v;
return SCPE_OK;
}
}
return SCPE_NOFNC;
}
/* Bootstrap - finish up bootstrap process */
t_stat cpu_boot (int32 unitno, DEVICE *dptr)
{
t_stat r;
r = cpu_load_bootcode (BOOT_CODE_FILENAME, BOOT_CODE_ARRAY, BOOT_CODE_SIZE, FALSE, 0x200);
if (r != SCPE_OK)
return r;
SP = PC = 512;
return SCPE_OK;
}
/* BI reset */
t_stat bi_reset (DEVICE *dptr)
{
wcs_addr = 0;
wcs_data = 0;
ipr_int = 0;
rxcd_int = 0;
ipir = 0;
sim_vm_cmd = vax820_cmd;
return SCPE_OK;
}
/* Show nexus */
t_stat show_nexus (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
fprintf (st, "nexus=%d", val);
return SCPE_OK;
}
/* Init nexus tables */
void init_nexus_tab (void)
{
uint32 i;
for (i = 0; i < NEXUS_NUM; i++) {
nexusR[i] = NULL;
nexusW[i] = NULL;
}
return;
}
/* Build nexus tables
Inputs:
dptr = pointer to device
dibp = pointer to DIB
Outputs:
status
*/
t_stat build_nexus_tab (DEVICE *dptr, DIB *dibp)
{
uint32 idx;
if ((dptr == NULL) || (dibp == NULL))
return SCPE_IERR;
idx = dibp->ba;
if (idx >= NEXUS_NUM)
return SCPE_IERR;
if ((nexusR[idx] && dibp->rd && /* conflict? */
(nexusR[idx] != dibp->rd)) ||
(nexusW[idx] && dibp->wr &&
(nexusW[idx] != dibp->wr))) {
sim_printf ("Nexus %s conflict at %d\n", sim_dname (dptr), dibp->ba);
return SCPE_STOP;
}
if (dibp->rd) /* set rd dispatch */
nexusR[idx] = dibp->rd;
if (dibp->wr) /* set wr dispatch */
nexusW[idx] = dibp->wr;
return SCPE_OK;
}
/* Build dib_tab from device list */
t_stat build_dib_tab (void)
{
uint32 i;
DEVICE *dptr;
DIB *dibp;
t_stat r;
init_nexus_tab ();
init_ubus_tab ();
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */
dibp = (DIB *) dptr->ctxt; /* get DIB */
if (dibp && !(dptr->flags & DEV_DIS)) { /* defined, enabled? */
if (dptr->flags & DEV_NEXUS) { /* Nexus? */
if ((r = build_nexus_tab (dptr, dibp))) /* add to dispatch table */
return r;
}
else { /* no, Unibus device */
if ((r = build_ubus_tab (dptr, dibp))) /* add to dispatch tab */
return r;
} /* end else */
} /* end if enabled */
} /* end for */
return SCPE_OK;
}
t_stat cpu_set_model (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
if (cptr == NULL)
return SCPE_ARG;
if (strcmp(cptr, "8200") == 0) {
sys_model = 0;
strcpy (sim_name, "VAX 8200 (KA820)");
}
else if (strcmp(cptr, "8250") == 0) {
sys_model = 1;
strcpy (sim_name, "VAX 8250 (KA825)");
}
else
return SCPE_ARG;
return SCPE_OK;
}
t_stat cpu_print_model (FILE *st)
{
fprintf (st, "model=%s", (sys_model ? "8250" : "8200"));
return SCPE_OK;
}
t_stat cpu_model_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
{
fprintf (st, "Initial memory size is 32MB.\n\n");
fprintf (st, "The simulator is booted with the BOOT command:\n\n");
fprintf (st, " sim> BO{OT} <device>{/R5:flags}\n\n");
fprintf (st, "where <device> is one of:\n\n");
fprintf (st, " HKn to boot from hkn\n");
fprintf (st, " RLn to boot from rln\n");
fprintf (st, " RQn to boot from rqn\n");
fprintf (st, " RQBn to boot from rqbn\n");
fprintf (st, " RQCn to boot from rqcn\n");
fprintf (st, " RQDn to boot from rqdn\n");
fprintf (st, " TQn to boot from tqn\n");
fprintf (st, " CS to boot from console RL\n\n");
return SCPE_OK;
}

452
VAX/vax820_defs.h Normal file
View file

@ -0,0 +1,452 @@
/* vax820_defs.h: VAX 8200 model-specific definitions file
Copyright (c) 2019, Matt Burke
This module incorporates code from SimH, Copyright (c) 2004-2008, 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"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name(s) of the author(s) shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the author(s).
This file covers the VAX 8200, the fifth VAX.
System memory map
0000 0000 - 1FFF FFFF main memory
2000 0000 - 2001 FFFF bi node space
2002 0000 - 2007 FFFF reserved
2008 0000 - 2008 00FC ka820 biic internal registers
2008 0200 - 2008 0203 rxcd register
2008 0204 - 2008 FFFF reserved
2009 0000 - 2009 1FFF boot RAM
2009 2000 - 2009 7FFF reserved
2009 8000 - 2009 FFFF eeprom
200A 0000 - 200A FFFF reserved
200B 0000 - 200B 0017 rcx50
200B 0020 - 200B 7FFF reserved
200B 8000 - 200B 807F watch chip
200B 8080 - 203F FFFF reserved
2040 0000 - 207F FFFF bi window space
2080 0000 - 3FFF FFFF reserved
*/
#ifndef FULL_VAX
#define FULL_VAX 1
#endif
#ifndef _VAX_820_DEFS_H_
#define _VAX_820_DEFS_H_ 1
/* Microcode constructs */
#define VAX820_SID (5 << 24) /* system ID */
#define VAX820_TYP (0 << 23) /* sys type: 8200 */
#define VAX825_TYP (1 << 23) /* sys type: 8250 */
#define VAX820_REV (5 << 19) /* CPU revision */
#define VAX820_PATCH (21 << 9) /* patch revision */
#define VAX820_UCODE (20) /* ucode revision */
#define CON_HLTPIN 0x0200 /* external CPU halt */
#define CON_HLTINS 0x0600 /* HALT instruction */
#define MCHK_BIERR 0x10 /* BI bus error */
#define VER_FPLA 0x0C /* FPLA version */
#define VER_WCSP (VER_FPLA) /* WCS primary version */
#define VER_WCSS 0x12 /* WCS secondary version */
#define VER_PCS ((VER_WCSS >> 4) & 0x3) /* PCS version */
/* Interrupts */
#define IPL_HMAX 0x17 /* highest hwre level */
#define IPL_HMIN 0x14 /* lowest hwre level */
#define IPL_HLVL (IPL_HMAX - IPL_HMIN + 1) /* # hardware levels */
#define IPL_SMAX 0xF /* highest swre level */
/* Nexus constants */
#define NEXUS_NUM 16 /* number of nexus */
#define KA_NUM 2 /* number of CPU's */
#define MCTL_NUM 2 /* number of mem ctrl */
#define MBA_NUM 2 /* number of MBA's */
#define TR_KA0 0 /* nexus assignments */
#define TR_KA1 1
#define TR_MCTL0 2
#define TR_MCTL1 3
#define TR_UBA 4
#define NEXUS_HLVL (IPL_HMAX - IPL_HMIN + 1)
#define SCB_NEXUS 0x100 /* nexus intr base */
/* Internal I/O interrupts - relative except for clock and console */
#define IPL_CLKINT 0x18 /* clock IPL */
#define IPL_IPRINT 0x14 /* interprocessor IPL */
#define IPL_RXCDINT 0x14 /* RXCD IPL */
#define IPL_TTINT 0x14 /* console IPL */
#define IPL_FLINT 0x14 /* console floppy IPL */
#define SCB_RXCD 0x58
#define SCB_IPRINT 0x80
#define SCB_FLINT 0xF0
#define IPL_MCTL0 (0x15 - IPL_HMIN)
#define IPL_MCTL1 (0x15 - IPL_HMIN)
#define IPL_UBA (0x15 - IPL_HMIN)
/* Nexus interrupt macros */
#define SET_NEXUS_INT(dv) nexus_req[IPL_##dv] |= (1 << TR_##dv)
#define CLR_NEXUS_INT(dv) nexus_req[IPL_##dv] &= ~(1 << TR_##dv)
/* Machine specific IPRs */
#define MT_IPIR 22 /* interprocessor interrupt */
#define MT_TBDR 36 /* translation buffer disable */
#define MT_CADR 37 /* cache disable */
#define MT_MCESR 38 /* MCHK error summary */
#define MT_ACCS 40 /* FPA control */
#define MT_WCSA 44 /* WCS address */
#define MT_WCSD 45 /* WCS data */
#define MT_WCSL 46 /* WCS load */
#define MT_RXCS1 80 /* Serial line 1 rx ctrl */
#define MT_RXDB1 81 /* Serial line 1 rx data */
#define MT_TXCS1 82 /* Serial line 1 tx ctrl */
#define MT_TXDB1 83 /* Serial line 1 tx data */
#define MT_RXCS2 84 /* Serial line 2 rx ctrl */
#define MT_RXDB2 85 /* Serial line 2 rx data */
#define MT_TXCS2 86 /* Serial line 2 tx ctrl */
#define MT_TXDB2 87 /* Serial line 2 tx data */
#define MT_RXCS3 88 /* Serial line 3 rx ctrl */
#define MT_RXDB3 89 /* Serial line 3 rx data */
#define MT_TXCS3 90 /* Serial line 3 tx ctrl */
#define MT_TXDB3 91 /* Serial line 3 tx data */
#define MT_RXCD 92 /* rx console data */
#define MT_CACHEX 93 /* Cache invalidate */
#define MT_BINID 94 /* BI node ident */
#define MT_BISTOP 95 /* BI stop */
#define MT_MAX 95 /* last valid IPR */
/* Machine specific reserved operand tests (all NOPs) */
#define ML_PA_TEST(r)
#define ML_LR_TEST(r)
#define ML_SBR_TEST(r)
#define ML_PXBR_TEST(r)
#define LP_AST_TEST(r)
#define LP_MBZ84_TEST(r)
#define LP_MBZ92_TEST(r)
#define MT_AST_TEST(r) r = (r) & 07; \
if ((r) > AST_MAX) RSVD_OPND_FAULT
/* CPU */
#define CPU_MODEL_MODIFIERS \
{ MTAB_XTD|MTAB_VDV, 0, "MODEL", "MODEL={8200|8250}", \
&cpu_set_model, &cpu_show_model, NULL, "Set/Display processor model" }
/* Memory */
#define MAXMEMWIDTH 22 /* max mem, std MS820 */
#define MAXMEMSIZE (1 << MAXMEMWIDTH)
#define MAXMEMWIDTH_X 29 /* max mem, extended */
#define MAXMEMSIZE_X (1 << MAXMEMWIDTH_X)
#define INITMEMSIZE (1 << MAXMEMWIDTH) /* initial memory size */
#define MEMSIZE (cpu_unit.capac)
#define ADDR_IS_MEM(x) (((uint32) (x)) < MEMSIZE)
#define MEM_MODIFIERS { UNIT_MSIZE, (1u << 22), NULL, "4M", &cpu_set_size, NULL, NULL, "Set Memory to 4M bytes" }, \
{ UNIT_MSIZE, (1u << 23), NULL, "8M", &cpu_set_size, NULL, NULL, "Set Memory to 8M bytes" }, \
{ UNIT_MSIZE, (1u << 24), NULL, "16M", &cpu_set_size, NULL, NULL, "Set Memory to 16M bytes" }, \
{ UNIT_MSIZE, (1u << 25), NULL, "32M", &cpu_set_size, NULL, NULL, "Set Memory to 32M bytes" }, \
{ UNIT_MSIZE, (1u << 25) + (1u << 24), NULL, "48M", &cpu_set_size, NULL, NULL, "Set Memory to 48M bytes" }, \
{ UNIT_MSIZE, (1u << 26), NULL, "64M", &cpu_set_size, NULL, NULL, "Set Memory to 64M bytes" }, \
{ UNIT_MSIZE, (1u << 27), NULL, "128M", &cpu_set_size, NULL, NULL, "Set Memory to 128M bytes" }, \
{ UNIT_MSIZE, (1u << 28), NULL, "256M", &cpu_set_size, NULL, NULL, "Set Memory to 256M bytes" }, \
{ UNIT_MSIZE, (1u << 29), NULL, "512M", &cpu_set_size, NULL, NULL, "Set Memory to 512M bytes" }, \
{ MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "MEMORY", NULL, NULL, &cpu_show_memory, NULL, "Display memory configuration" }
extern t_stat cpu_show_memory (FILE* st, UNIT* uptr, int32 val, CONST void* desc);
/* Node window space */
#define WINAWIDTH 18 /* VAXBI node window width */
#define WINBASE 0x20400000 /* VAXBI node window base */
#define WINADDR(n) (WINBASE + (n << WINAWIDTH)) /* node -> window addr */
/* Unibus I/O registers */
#define UBADDRWIDTH 18 /* Unibus addr width */
#define UBADDRSIZE (1u << UBADDRWIDTH) /* Unibus addr length */
#define UBADDRMASK (UBADDRSIZE - 1) /* Unibus addr mask */
#define IOPAGEAWIDTH 13 /* IO addr width */
#define IOPAGESIZE (1u << IOPAGEAWIDTH) /* IO page length */
#define IOPAGEMASK (IOPAGESIZE - 1) /* IO addr mask */
#define UBADDRBASE WINADDR(TR_UBA) /* Unibus addr base */
#define IOPAGEBASE (UBADDRBASE + 0x3E000) /* IO page base */
#define ADDR_IS_IO(x) ((((uint32) (x)) >= UBADDRBASE) && \
(((uint32) (x)) < (UBADDRBASE + UBADDRSIZE)))
#define ADDR_IS_IOP(x) (((uint32) (x)) >= IOPAGEBASE)
/* Nexus register space */
#define REGAWIDTH 17 /* REG addr width */
#define REG_V_NEXUS 13 /* nexus number */
#define REG_M_NEXUS 0xF
#define REG_V_OFS 2 /* register number */
#define REG_M_OFS 0x7FF
#define REGSIZE (1u << REGAWIDTH) /* REG length */
#define REGBASE 0x20000000 /* REG addr base */
#define ADDR_IS_REG(x) ((((uint32) (x)) >= REGBASE) && \
(((uint32) (x)) < (REGBASE + REGSIZE)))
#define NEXUS_GETNEX(x) (((x) >> REG_V_NEXUS) & REG_M_NEXUS)
#define NEXUS_GETOFS(x) (((x) >> REG_V_OFS) & REG_M_OFS)
/* Watch Chip */
#define WATCHWIDTH 7 /* WATCH addr width */
#define WATCHSIZE (1u << REGAWIDTH) /* WATCH length */
#define WATCHBASE 0x200B8000 /* WATCH addr base */
/* Other address spaces */
#define ADDR_IS_ROM(x) (0)
#define ADDR_IS_CDG(x) (0)
#define ADDR_IS_NVR(x) (0)
/* Unibus I/O modes */
#define READ 0 /* PDP-11 compatibility */
#define WRITE (L_WORD)
#define WRITEB (L_BYTE)
/* Common CSI flags */
#define CSR_V_GO 0 /* go */
#define CSR_V_IE 6 /* interrupt enable */
#define CSR_V_DONE 7 /* done */
#define CSR_V_BUSY 11 /* busy */
#define CSR_V_ERR 15 /* error */
#define CSR_GO (1u << CSR_V_GO)
#define CSR_IE (1u << CSR_V_IE)
#define CSR_DONE (1u << CSR_V_DONE)
#define CSR_BUSY (1u << CSR_V_BUSY)
#define CSR_ERR (1u << CSR_V_ERR)
/* Timers */
#define TMR_CLK 0 /* 100Hz clock */
/* I/O system definitions */
#define DZ_MUXES 4 /* max # of DZV muxes */
#define VH_MUXES 4 /* max # of DHU muxes */
#define DLX_LINES 16 /* max # of KL11/DL11's */
#define DCX_LINES 16 /* max # of DC11's */
#define DUP_LINES 8 /* max # of DUP11's */
#define MT_MAXFR (1 << 16) /* magtape max rec */
#define DEV_V_UBUS (DEV_V_UF + 0) /* Unibus */
#define DEV_V_MBUS (DEV_V_UF + 1) /* Massbus */
#define DEV_V_NEXUS (DEV_V_UF + 2) /* Nexus */
#define DEV_V_FFUF (DEV_V_UF + 3) /* first free flag */
#define DEV_UBUS (1u << DEV_V_UBUS)
#define DEV_MBUS (1u << DEV_V_MBUS)
#define DEV_NEXUS (1u << DEV_V_NEXUS)
#define DEV_QBUS (0)
#define DEV_Q18 (0)
#define UNIBUS TRUE /* Unibus only */
#define DEV_RDX 16 /* default device radix */
/* Device information block
For Massbus devices,
ba = Massbus number
lnt = Massbus ctrl type
ack[0] = abort routine
For Nexus devices,
ba = Nexus number
lnt = number of consecutive nexi */
#define VEC_DEVMAX 4 /* max device vec */
typedef struct {
uint32 ba; /* base addr */
uint32 lnt; /* length */
t_stat (*rd)(int32 *dat, int32 ad, int32 md);
t_stat (*wr)(int32 dat, int32 ad, int32 md);
int32 vnum; /* vectors: number */
int32 vloc; /* locator */
int32 vec; /* value */
int32 (*ack[VEC_DEVMAX])(void); /* ack routine */
uint32 ulnt; /* IO length per-device */
/* Only need to be populated */
/* when numunits != num devices */
int32 numc; /* Number of controllers */
/* this field handles devices */
/* where multiple instances are */
/* simulated through a single */
/* DEVICE structure (e.g., DZ, VH, DL, DC). */
/* Populated by auto-configure */
DEVICE *dptr; /* back pointer to related device */
/* Populated by auto-configure */
} DIB;
/* Unibus I/O page layout - XUB,RQB,RQC,RQD float based on number of DZ's
Massbus devices (RP, TU) do not appear in the Unibus IO page */
#define IOBA_AUTO (0) /* Assigned by Auto Configure */
/* Interrupt assignments; within each level, priority is right to left */
#define INT_V_DTA 0 /* BR6 */
#define INT_V_CR 1
#define INT_V_DZRX 0 /* BR5 */
#define INT_V_DZTX 1
#define INT_V_HK 2
#define INT_V_RL 3
#define INT_V_RQ 4
#define INT_V_TQ 5
#define INT_V_TS 6
#define INT_V_RY 7
#define INT_V_XU 8
#define INT_V_DMCRX 9
#define INT_V_DMCTX 10
#define INT_V_DUPRX 11
#define INT_V_DUPTX 12
#define INT_V_RK 13
#define INT_V_CH 14
#define INT_V_LPT 0 /* BR4 */
#define INT_V_PTR 1
#define INT_V_PTP 2
//#define XXXXXXXX 3 /* Former CR */
#define INT_V_VHRX 4
#define INT_V_VHTX 5
#define INT_V_TDRX 6
#define INT_V_TDTX 7
#define INT_DTA (1u << INT_V_DTA)
#define INT_CR (1u << INT_V_CR)
#define INT_DZRX (1u << INT_V_DZRX)
#define INT_DZTX (1u << INT_V_DZTX)
#define INT_HK (1u << INT_V_HK)
#define INT_RL (1u << INT_V_RL)
#define INT_RQ (1u << INT_V_RQ)
#define INT_TQ (1u << INT_V_TQ)
#define INT_TS (1u << INT_V_TS)
#define INT_RY (1u << INT_V_RY)
#define INT_XU (1u << INT_V_XU)
#define INT_LPT (1u << INT_V_LPT)
#define INT_VHRX (1u << INT_V_VHRX)
#define INT_VHTX (1u << INT_V_VHTX)
#define INT_PTR (1u << INT_V_PTR)
#define INT_PTP (1u << INT_V_PTP)
#define INT_DMCRX (1u << INT_V_DMCRX)
#define INT_DMCTX (1u << INT_V_DMCTX)
#define INT_DUPRX (1u << INT_V_DUPRX)
#define INT_DUPTX (1u << INT_V_DUPTX)
#define INT_RK (1u << INT_V_RK)
#define INT_TDRX (1u << INT_V_TDRX)
#define INT_TDTX (1u << INT_V_TDTX)
#define INT_CH (1u << INT_V_CH)
#define IPL_DTA (0x16 - IPL_HMIN)
#define IPL_CR (0x16 - IPL_HMIN)
#define IPL_DZRX (0x15 - IPL_HMIN)
#define IPL_DZTX (0x15 - IPL_HMIN)
#define IPL_HK (0x15 - IPL_HMIN)
#define IPL_RL (0x15 - IPL_HMIN)
#define IPL_RQ (0x15 - IPL_HMIN)
#define IPL_TQ (0x15 - IPL_HMIN)
#define IPL_TS (0x15 - IPL_HMIN)
#define IPL_RY (0x15 - IPL_HMIN)
#define IPL_XU (0x15 - IPL_HMIN)
#define IPL_CH (0x15 - IPL_HMIN)
#define IPL_LPT (0x14 - IPL_HMIN)
#define IPL_PTR (0x14 - IPL_HMIN)
#define IPL_PTP (0x14 - IPL_HMIN)
#define IPL_VHRX (0x14 - IPL_HMIN)
#define IPL_VHTX (0x14 - IPL_HMIN)
#define IPL_DMCRX (0x15 - IPL_HMIN)
#define IPL_DMCTX (0x15 - IPL_HMIN)
#define IPL_DUPRX (0x15 - IPL_HMIN)
#define IPL_DUPTX (0x15 - IPL_HMIN)
#define IPL_RK (0x15 - IPL_HMIN)
#define IPL_TDRX (0x14 - IPL_HMIN)
#define IPL_TDTX (0x14 - IPL_HMIN)
/* Device vectors */
#define VEC_AUTO (0) /* Assigned by Auto Configure */
#define VEC_FLOAT (0) /* Assigned by Auto Configure */
#define VEC_QBUS 0
#define VEC_Q 0000
/* Interrupt macros */
#define IVCL(dv) ((IPL_##dv * 32) + INT_V_##dv)
#define NVCL(dv) ((IPL_##dv * 32) + TR_##dv)
#define IREQ(dv) int_req[IPL_##dv]
#define SET_INT(dv) int_req[IPL_##dv] = int_req[IPL_##dv] | (INT_##dv)
#define CLR_INT(dv) int_req[IPL_##dv] = int_req[IPL_##dv] & ~(INT_##dv)
#define IORETURN(f,v) ((f)? (v): SCPE_OK) /* cond error return */
/* Boot definitions */
#define BOOT_MB 0 /* device codes */
#define BOOT_HK 1 /* for VMB */
#define BOOT_RL 2
#define BOOT_UDA 17
#define BOOT_CS 64
/* Function prototypes for I/O */
int32 Map_ReadB (uint32 ba, int32 bc, uint8 *buf);
int32 Map_ReadW (uint32 ba, int32 bc, uint16 *buf);
int32 Map_WriteB (uint32 ba, int32 bc, const uint8 *buf);
int32 Map_WriteW (uint32 ba, int32 bc, const uint16 *buf);
int32 mba_rdbufW (uint32 mbus, int32 bc, uint16 *buf);
int32 mba_wrbufW (uint32 mbus, int32 bc, const uint16 *buf);
int32 mba_chbufW (uint32 mbus, int32 bc, uint16 *buf);
int32 mba_get_bc (uint32 mbus);
void mba_upd_ata (uint32 mbus, uint32 val);
void mba_set_exc (uint32 mbus);
void mba_set_don (uint32 mbus);
void mba_set_enbdis (DEVICE *dptr);
t_stat mba_show_num (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat show_nexus (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
/* Function prototypes for system-specific unaligned support
8200 treats unaligned like aligned? */
#define ReadIOU(p,l) ReadIO (p,l)
#define ReadRegU(p,l) ReadReg (p,l)
#define WriteIOU(p,v,l) WriteIO (p, v, l)
#define WriteRegU(p,v,l) WriteReg (p, v, l)
#include "pdp11_io_lib.h"
#include "vax_bi.h"
/* Function prototypes for virtual and physical memory interface (inlined) */
#include "vax_mmu.h"
#endif

365
VAX/vax820_ka.c Normal file
View file

@ -0,0 +1,365 @@
/* vax820_ka.c: VAX 8200 CPU
Copyright (c) 2019, Matt Burke
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of the author shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the author.
This module contains the VAX 8200 CPU registers and devices.
ka0, ka1 KA820 CPU
*/
#include "vax_defs.h"
#define PCSR_RSTH 0x80000000 /* restart halt */
#define PCSR_LCON 0x40000000 /* logical console */
#define PCSR_CONEN 0x20000000 /* console enable */
#define PCSR_BIRST 0x10000000 /* BI reset */
#define PCSR_BISTF 0x08000000 /* self test fast/slow */
#define PCSR_ENAPT 0x04000000 /* APT connection status */
#define PCSR_STPASS 0x02000000 /* self test pass */
#define PCSR_RUN 0x01000000 /* pgm mode run */
#define PCSR_WWPE 0x00800000 /* write wrong parity, even */
#define PCSR_EVLCK 0x00400000 /* event lock */
#define PCSR_WMEM 0x00200000 /* write mem status */
#define PCSR_V_EVENT 16
#define PCSR_M_EVENT 0xF
#define PCSR_EVENT (PCSR_M_EVENT << PCSR_V_EVENT) /* BI event */
#define PCSR_WWPO 0x00008000 /* write wrong parity, odd */
#define PCSR_PER 0x00004000 /* parity error */
#define PCSR_ENPIPE 0x00002000 /* enable BI pipeline */
#define PCSR_TIMEOUT 0x00001000 /* timeout */
#define PCSR_RSVD 0x00000800 /* reserved */
#define PCSR_CONIE 0x00000400 /* console interrupt enable */
#define PCSR_CONCLR 0x00000200 /* clear console interrupt */
#define PCSR_V_CONINT 8
#define PCSR_CONINT (1u << PCSR_V_CONINT) /* console interrupt req */
#define PCSR_RXIE 0x00000080 /* RX50 interrupt enable */
#define PCSR_RXCLR 0x00000040 /* clear RX50 interrupt */
#define PCSR_RXINT 0x00000020 /* RX50 interrupt request */
#define PCSR_IPCLR 0x00000010 /* clear IP interrupt */
#define PCSR_V_IPINT 3
#define PCSR_IPINT (1u << PCSR_V_IPINT) /* IP interrupt request */
#define PCSR_CRDEN 0x00000004 /* enable CRD interrupts */
#define PCSR_CRDCLR 0x00000002 /* clear CRD interrupt */
#define PCSR_CRDINT 0x00000001 /* CRD interrupt request */
#define PCSR_WR (PCSR_RUN | PCSR_WWPE | PCSR_WWPO | \
PCSR_ENPIPE | PCSR_CONIE | PCSR_RXIE | \
PCSR_CRDEN)
#define PCSR_W1C (PCSR_EVLCK | PCSR_PER | PCSR_TIMEOUT)
int32 rxcd_count = 0;
char rxcd_ibuf[20];
char rxcd_obuf[20];
int32 rxcd_iptr = 0;
int32 rxcd_optr = 0;
char rxcd_char = '\0';
BIIC ka_biic[KA_NUM];
uint32 ka_rxcd[KA_NUM];
uint32 ka_pcsr[KA_NUM];
extern int32 rxcd_int;
extern int32 ipir;
#if defined (VAX_MP)
extern int32 cur_cpu;
#else
int32 cur_cpu;
#endif
t_stat ka_reset (DEVICE *dptr);
t_stat ka_rdreg (int32 *val, int32 pa, int32 mode);
t_stat ka_wrreg (int32 val, int32 pa, int32 mode);
t_stat ka_svc (UNIT *uptr);
#if defined (VAX_MP)
extern void cpu_setreg (int32 cpu, int32 rg, int32 val);
extern void cpu_start (int32 cpu, uint32 addr);
#endif
/* KAx data structures
kax_dev KAx device descriptor
kax_unit KAx unit
kax_reg KAx register list
*/
DIB ka0_dib[] = { TR_KA0, 0, &ka_rdreg, &ka_wrreg, 0 };
UNIT ka0_unit = { UDATA (&ka_svc, 0, 0) };
REG ka0_reg[] = {
{ NULL }
};
MTAB ka0_mod[] = {
{ MTAB_XTD|MTAB_VDV, TR_KA0, "NEXUS", NULL,
NULL, &show_nexus },
{ 0 }
};
DIB ka1_dib[] = { TR_KA1, 0, &ka_rdreg, &ka_wrreg, 0 };
UNIT ka1_unit = { UDATA (&ka_svc, 0, 0) };
MTAB ka1_mod[] = {
{ MTAB_XTD|MTAB_VDV, TR_KA1, "NEXUS", NULL,
NULL, &show_nexus },
{ 0 } };
REG ka1_reg[] = {
{ NULL }
};
DEVICE ka_dev[] = {
{
"KA0", &ka0_unit, ka0_reg, ka0_mod,
1, 16, 16, 1, 16, 8,
NULL, NULL, &ka_reset,
NULL, NULL, NULL,
&ka0_dib, DEV_NEXUS
},
{
"KA1", &ka1_unit, ka1_reg, ka1_mod,
1, 16, 16, 1, 16, 8,
NULL, NULL, &ka_reset,
NULL, NULL, NULL,
&ka1_dib, DEV_NEXUS | DEV_DISABLE | DEV_DIS
}
};
/* KA read */
t_stat ka_rdreg (int32 *val, int32 pa, int32 lnt)
{
int32 ka, ofs;
t_bool extmem = MEMSIZE > MAXMEMSIZE;
ka = NEXUS_GETNEX (pa) - TR_KA0; /* get CPU num */
ofs = NEXUS_GETOFS (pa); /* get offset */
switch (ofs) {
case BI_DTYPE:
*val = DTYPE_KA820;
break;
case BI_CSR:
*val = ka_biic[ka].csr & BICSR_RD;
break;
case BI_BER:
*val = ka_biic[ka].ber & BIBER_RD;
break;
case BI_EICR:
*val = ka_biic[ka].eicr & BIECR_RD;
break;
case BI_IDEST:
*val = ka_biic[ka].idest & BIID_RD;
break;
case BI_SA:
case BI_EA:
*val = 0;
break;
default:
return SCPE_NXM;
}
return SCPE_OK;
}
/* KA write */
t_stat ka_wrreg (int32 val, int32 pa, int32 lnt)
{
int32 ka, ofs;
t_bool extmem = MEMSIZE > MAXMEMSIZE;
ka = NEXUS_GETNEX (pa) - TR_KA0; /* get CPU num */
ofs = NEXUS_GETOFS (pa); /* get offset */
switch (ofs) {
case BI_CSR:
ka_biic[ka].csr = (ka_biic[ka].csr & ~BICSR_RW) | (val & BICSR_RW);
break;
case BI_BER:
ka_biic[ka].ber = ka_biic[ka].ber & ~(val & BIBER_W1C);
break;
case BI_EICR:
ka_biic[ka].eicr = (ka_biic[ka].eicr & ~BIECR_RW) | (val & BIECR_RW);
ka_biic[ka].eicr = ka_biic[ka].eicr & ~(val & BIECR_W1C);
break;
case BI_IDEST:
ka_biic[ka].idest = val & BIID_RW;
break;
case BI_IMSK:
break;
default:
return SCPE_NXM;
}
return SCPE_OK;
}
/* KA reset */
t_stat ka_reset (DEVICE *dptr)
{
int32 i;
rxcd_count = 0;
ka_rxcd[0] = 0;
ka_rxcd[1] = 0;
for (i = 0; i < KA_NUM; i++) {
ka_biic[i].csr = (1u << BICSR_V_IF) | BICSR_STS | ((TR_KA0 + i) & BICSR_NODE);
ka_biic[i].ber = 0;
ka_biic[i].eicr = 0;
ka_biic[i].idest = 0;
}
ka_pcsr[0] = PCSR_CONEN | PCSR_ENAPT | PCSR_STPASS | PCSR_RUN;
ka_pcsr[1] = PCSR_RSTH | PCSR_LCON | PCSR_CONEN | PCSR_ENAPT | PCSR_STPASS | PCSR_RUN;
sim_cancel (&ka0_unit);
sim_cancel (&ka1_unit);
return SCPE_OK;
}
t_stat ka_svc (UNIT *uptr)
{
if ((rxcd_count > 0) && rxcd_int)
sim_activate (uptr, 20);
rxcd_int = 1;
return SCPE_OK;
}
int32 rxcd_rd (void)
{
int32 val;
if (rxcd_count) { /* data available? */
val = rxcd_obuf[rxcd_optr] | (1 << 8);
rxcd_optr++;
rxcd_count--;
if (rxcd_count)
sim_activate (&ka0_unit, 20);
}
else {
val = 0x52584344; /* "RXCD" */
mxpr_cc_vc |= CC_V; /* set overflow */
}
return val;
}
void rxcd_wr (int32 val)
{
int32 cpu = (val >> 8) & 7;
int32 ch = val & 0xFF;
int32 rg;
int32 rval;
t_stat r;
char conv[10];
if (ka_rxcd[cpu] & 0x8000) { /* busy? */
mxpr_cc_vc |= CC_V; /* set overflow */
return;
}
switch (ch) {
case 0x0D: /* CR */
rxcd_ibuf[rxcd_iptr++] = '\0'; /* terminator */
printf (">>> %s\n", &rxcd_ibuf[0]);
if (rxcd_ibuf[0] == 'D') { /* DEPOSIT */
snprintf (&conv[0], 2, "%s", &rxcd_ibuf[4]);
rg = (int32)get_uint (&conv[0], 16, 0xF, &r); /* get register number */
snprintf (&conv[0], 9, "%s", &rxcd_ibuf[6]);
rval = (int32)get_uint (&conv[0], 16, 0xFFFFFFFF, &r); /* get deposit value */
#if defined (VAX_MP)
cpu_setreg (cpu, rg, rval);
#endif
rxcd_count = 3; /* ready for next cmd */
sprintf (&rxcd_obuf[0], ">>>");
rxcd_optr = 0;
}
else if (rxcd_ibuf[0] == 'I') { /* INIT */
rxcd_count = 3; /* ready for next cmd */
sprintf (&rxcd_obuf[0], ">>>");
rxcd_optr = 0;
}
else if (rxcd_ibuf[0] == 'S') { /* START */
snprintf (&conv[0], 9, "%s", &rxcd_ibuf[2]);
rval = (int32)get_uint (&conv[0], 16, 0xFFFFFFFF, &r);
#if defined (VAX_MP)
cpu_start (cpu, rval);
#endif
}
rxcd_iptr = 0;
break;
case 0x10: /* CTRL-P */
rxcd_count = 3; /* ready for next cmd */
sprintf (&rxcd_obuf[0], ">>>");
rxcd_optr = 0;
break;
default:
rxcd_count = 1;
rxcd_obuf[0] = ch; /* echo characters back */
rxcd_optr = 0;
rxcd_ibuf[rxcd_iptr++] = ch; /* store incoming charactes */
break;
}
if (rxcd_count) {
if (cpu == 0)
sim_activate (&ka0_unit, 20);
else
sim_activate (&ka1_unit, 20);
}
return;
}
int32 pcsr_rd (int32 pa)
{
int32 data;
int32 ip_int = (ipir >> cur_cpu) & 0x1;
data = ka_pcsr[cur_cpu] | (rxcd_int << PCSR_V_CONINT) | (ip_int << PCSR_V_IPINT);
printf ("pcsr_rd: %08X\n", data);
return data;
}
void pcsr_wr (int32 pa, int32 val, int32 lnt)
{
printf ("pcsr_wr: %08X\n", val);
ka_pcsr[cur_cpu] &= ~(val & PCSR_W1C);
ka_pcsr[cur_cpu] &= ~(PCSR_WR) | (val & PCSR_WR);
if (val & PCSR_CONCLR)
rxcd_int = 0;
if (val & PCSR_IPCLR)
ipir &= ~(1u << cur_cpu);
}

212
VAX/vax820_mem.c Normal file
View file

@ -0,0 +1,212 @@
/* vax820_mem.c: VAX 8200 memory controllers
Copyright (c) 2019, Matt Burke
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of the author shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the author.
mctl0, mctl1 MS820 memory controllers
*/
#include "vax_defs.h"
/* Memory CSR 1 */
#define MCSR1_OF 0x40
#define MCSR1_V_SIZE 18 /* memory size */
#define MCSR1_M_SIZE 0x7FF
#define MCSR1_MWE 0x00000400 /* masked write error - NI */
#define MCSR1_ICE 0x00000200 /* internal controller error - NI */
#define MCSR1_CDI 0x00008000 /* CRD interrupt inhibit - NI */
/* Memory CSR 2 */
#define MCSR2_OF 0x41
uint32 mcsr_1[MCTL_NUM];
uint32 mcsr_2[MCTL_NUM];
t_stat mctl_reset (DEVICE *dptr);
const char *mctl_description (DEVICE *dptr);
t_stat mctl_rdreg (int32 *val, int32 pa, int32 mode);
t_stat mctl_wrreg (int32 val, int32 pa, int32 mode);
/* MCTLx data structures
mctlx_dev MCTLx device descriptor
mctlx_unit MCTLx unit
mctlx_reg MCTLx register list
*/
DIB mctl0_dib[] = { TR_MCTL0, 0, &mctl_rdreg, &mctl_wrreg, 0 };
UNIT mctl0_unit = { UDATA (NULL, 0, 0) };
REG mctl0_reg[] = {
{ HRDATA (CSR1, mcsr_1[0], 32) },
{ HRDATA (CSR2, mcsr_2[0], 32) },
{ NULL }
};
MTAB mctl0_mod[] = {
{ MTAB_XTD|MTAB_VDV, TR_MCTL0, "NEXUS", NULL,
NULL, &show_nexus, NULL, "Display nexus" },
{ 0 }
};
DIB mctl1_dib[] = { TR_MCTL1, 0, &mctl_rdreg, &mctl_wrreg, 0 };
UNIT mctl1_unit = { UDATA (NULL, 0, 0) };
MTAB mctl1_mod[] = {
{ MTAB_XTD|MTAB_VDV, TR_MCTL1, "NEXUS", NULL,
NULL, &show_nexus },
{ 0 } };
REG mctl1_reg[] = {
{ HRDATA (CSR1, mcsr_1[1], 32) },
{ HRDATA (CSR2, mcsr_2[1], 32) },
{ NULL }
};
DEVICE mctl_dev[] = {
{
"MCTL0", &mctl0_unit, mctl0_reg, mctl0_mod,
1, 16, 16, 1, 16, 8,
NULL, NULL, &mctl_reset,
NULL, NULL, NULL,
&mctl0_dib, DEV_NEXUS, 0,
NULL, NULL, NULL, NULL, NULL, NULL,
&mctl_description
},
{
"MCTL1", &mctl1_unit, mctl1_reg, mctl1_mod,
1, 16, 16, 1, 16, 8,
NULL, NULL, &mctl_reset,
NULL, NULL, NULL,
&mctl1_dib, DEV_NEXUS, 0,
NULL, NULL, NULL, NULL, NULL, NULL,
&mctl_description
}
};
/* Memory controller register read */
t_stat mctl_rdreg (int32 *val, int32 pa, int32 lnt)
{
int32 mctl, ofs;
t_bool extmem = MEMSIZE > MAXMEMSIZE;
mctl = NEXUS_GETNEX (pa) - TR_MCTL0; /* get mctl num */
ofs = NEXUS_GETOFS (pa); /* get offset */
switch (ofs) {
case BI_DTYPE:
*val = DTYPE_MS820;
break;
case BI_CSR:
case BI_BER:
case BI_EICR:
case BI_IDEST:
*val = 0;
break;
case BI_SA: /* start address */
*val = (mctl == 0) ? 0 : (int32)(MEMSIZE >> 1);
break;
case BI_EA: /* end address */
*val = (mctl == 0) ? (int32)(MEMSIZE >> 1) : (int32)MEMSIZE;
break;
case MCSR1_OF: /* CSR 1 */
*val = mcsr_1[mctl];
break;
case MCSR2_OF: /* CSR 2 */
*val = mcsr_2[mctl];
break;
default:
return SCPE_NXM;
}
return SCPE_OK;
}
/* Memory controller register write */
t_stat mctl_wrreg (int32 val, int32 pa, int32 lnt)
{
int32 mctl, ofs;
t_bool extmem = MEMSIZE > MAXMEMSIZE;
mctl = NEXUS_GETNEX (pa) - TR_MCTL0; /* get mctl num */
ofs = NEXUS_GETOFS (pa); /* get offset */
switch (ofs) {
case BI_CSR:
case BI_BER:
case BI_EICR:
case BI_IDEST:
break;
case MCSR1_OF: /* CSR 1 */
case MCSR2_OF: /* CSR 2 */
break;
default:
return SCPE_NXM;
}
return SCPE_OK;
}
/* Used by CPU and loader */
void rom_wr_B (int32 pa, int32 val)
{
return;
}
/* MEMCTL reset */
t_stat mctl_reset (DEVICE *dptr)
{
int32 i;
for (i = 0; i < MCTL_NUM; i++) { /* init for MS820 */
mcsr_1[i] = (MCSR1_M_SIZE << MCSR1_V_SIZE);
mcsr_2[i] = 0;
}
return SCPE_OK;
}
const char *mctl_description (DEVICE *dptr)
{
return "memory controller";
}
t_stat cpu_show_memory (FILE* st, UNIT* uptr, int32 val, CONST void* desc)
{
// TODO
return SCPE_OK;
}

1216
VAX/vax820_stddev.c Normal file

File diff suppressed because it is too large Load diff

139
VAX/vax820_syslist.c Normal file
View file

@ -0,0 +1,139 @@
/* vax820_syslist.c: VAX 8200 device list
Copyright (c) 2019, Matt Burke
This module incorporates code from SimH, Copyright (c) 1998-2008, 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"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name(s) of the author(s) shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the author(s).
*/
#include "vax_defs.h"
char sim_name[] = "VAX 8200 (KA820)";
void vax_init(void)
{
sim_savename = "VAX820";
}
WEAK void (*sim_vm_init) (void) = &vax_init;
extern DEVICE cpu_dev;
extern DEVICE tlb_dev;
extern DEVICE bi_dev;
extern DEVICE ka_dev[KA_NUM];
extern DEVICE mctl_dev[MCTL_NUM];
extern DEVICE uba_dev;
extern DEVICE clk_dev;
extern DEVICE tmr_dev;
extern DEVICE tti_dev, tto_dev;
extern DEVICE fl_dev;
extern DEVICE dt_dev;
extern DEVICE tdc_dev;
extern DEVICE cr_dev;
extern DEVICE lpt_dev;
extern DEVICE rq_dev, rqb_dev, rqc_dev, rqd_dev;
extern DEVICE rl_dev;
extern DEVICE hk_dev;
extern DEVICE rk_dev;
extern DEVICE ry_dev;
extern DEVICE ts_dev;
extern DEVICE tq_dev;
extern DEVICE dz_dev;
extern DEVICE vh_dev;
extern DEVICE xu_dev, xub_dev;
extern DEVICE dmc_dev;
extern DEVICE ch_dev;
extern UNIT cpu_unit;
extern void WriteB (uint32 pa, int32 val);
extern void rom_wr_B (int32 pa, int32 val);
DEVICE *sim_devices[] = {
&cpu_dev,
&tlb_dev,
&bi_dev,
&ka_dev[0],
&ka_dev[1],
&mctl_dev[0],
&mctl_dev[1],
&uba_dev,
&clk_dev,
&tmr_dev,
&tti_dev,
&tto_dev,
&fl_dev,
&dt_dev,
&tdc_dev,
&dz_dev,
&vh_dev,
&cr_dev,
&lpt_dev,
&rl_dev,
&hk_dev,
&rk_dev,
&rq_dev,
&rqb_dev,
&rqc_dev,
&rqd_dev,
&ry_dev,
&ts_dev,
&tq_dev,
&xu_dev,
&xub_dev,
&dmc_dev,
&ch_dev,
NULL
};
/* Binary loader
The binary loader handles absolute system images, that is, system
images linked /SYSTEM. These are simply a byte stream, with no
origin or relocation information.
-o for memory, specify origin
*/
t_stat sim_load (FILE *fileref, CONST char *cptr, CONST char *fnam, int flag)
{
t_stat r;
int32 val;
uint32 origin, limit;
if (flag) /* dump? */
return sim_messagef (SCPE_NOFNC, "Command Not Implemented\n");
origin = 0; /* memory */
limit = (uint32) cpu_unit.capac;
if (sim_switches & SWMASK ('O')) { /* origin? */
origin = (int32) get_uint (cptr, 16, 0xFFFFFFFF, &r);
if (r != SCPE_OK)
return SCPE_ARG;
}
while ((val = Fgetc (fileref)) != EOF) { /* read byte stream */
if (origin >= limit) /* NXM? */
return SCPE_NXM;
WriteB (origin, val); /* memory */
origin = origin + 1;
}
return SCPE_OK;
}

996
VAX/vax820_uba.c Normal file
View file

@ -0,0 +1,996 @@
/* vax820_uba.c: VAXBI Unibus adapter (DWBUA)
Copyright (c) 2019, Matt Burke
This module incorporates code from SimH, Copyright (c) 2004-2008, 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"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name(s) of the author(s) shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the author(s).
uba DWBUA Unibus adapter
*/
#include "vax_defs.h"
/* Unibus adapter */
#define UBA_NDPATH 6 /* number of data paths */
#define UBA_NMAPR 512 /* number of map reg */
#define UBA_NMAPU 496 /* number of usable map reg */
/* BI general purpose register 0 */
#define BIGPR0_IEN 0x00FF0000 /* internal error number */
#define BIGPR0_UPU 0x00000001 /* unibus power up */
/* Control/Status register */
#define UBACSR_OF 0x1C8
#define UBACSR_ERR 0x80000000 /* error */
#define UBACSR_BIF 0x10000000 /* VAXBI failure */
#define UBACSR_TO 0x08000000 /* unibus ssyn timeout */
#define UBACSR_UIE 0x04000000 /* unibus interlock error */
#define UBACSR_IMR 0x02000000 /* invalid map reg */
#define UBACSR_BDP 0x01000000 /* bad buffered datapath */
#define UBACSR_EIE 0x00100000 /* error interrupt en */
#define UBACSR_UPI 0x00020000 /* unibus power init */
#define UBACSR_RD 0x00010000 /* register dump */
#define UBACSR_ONE 0x00008000 /* must be one */
#define UBACSR_IEN 0x000000FF /* internal error - NI */
#define UBACSR_WR (UBACSR_EIE)
#define UBACSR_W1C (UBACSR_BIF | UBACSR_TO | UBACSR_UIE | \
UBACSR_IMR | UBACSR_BDP)
/* Vector offset register */
#define UBAVO_OF 0x1C9
#define UBAVO_VEC 0x00003E00
/* Failing Unibus address - read only */
#define UBAFUBAR_OF 0x1CA
#define UBAFUBAR_RD 0xFFFF
/* VAXBI failed address - read only */
#define UBABIFA_OF 0x1CB
/* Microdiagnostic registers */
#define UBADR_OF 0x1CC
/* Data path registers */
#define UBADPR_OF 0x1D4
#define UBADPR_V_SEL 21 /* datapath select */
#define UBADPR_M_SEL 0x7
#define UBADPR_PURGE 0x00000001 /* purge datapath */
#define UBADPR_RD (UBADPR_M_SEL << UBADPR_V_SEL)
/* Buffered data path space */
#define UBABDPS_OF 0x1E4
/* Map registers */
#define UBAMAP_OF 0x200
#define UBAMAP_VLD 0x80000000 /* valid */
#define UBAMAP_IOAD 0x40000000 /* i/o address */
#define UBAMAP_LWAE 0x04000000 /* LW access enb - ni */
#define UBAMAP_ODD 0x02000000 /* odd byte */
#define UBAMAP_V_DP 21 /* data path */
#define UBAMAP_M_DP 0x7
#define UBAMAP_DP (UBAMAP_M_DP << UBAMAP_V_DP)
#define UBAMAP_GETDP(x) (((x) >> UBAMAP_V_DP) & UBAMAP_M_DP)
#define UBAMAP_PAG 0x001FFFFF
#define UBAMAP_RD (0xC6000000 | UBAMAP_DP | UBAMAP_PAG)
#define UBAMAP_WR (UBAMAP_RD)
/* Debug switches */
#define UBA_DEB_RRD 0x01 /* reg reads */
#define UBA_DEB_RWR 0x02 /* reg writes */
#define UBA_DEB_MRD 0x04 /* map reads */
#define UBA_DEB_MWR 0x08 /* map writes */
#define UBA_DEB_XFR 0x10 /* transfers */
#define UBA_DEB_ERR 0x20 /* errors */
int32 int_req[IPL_HLVL] = { 0 }; /* intr, IPL 14-17 */
BIIC uba_biic; /* BIIC standard registers */
uint32 uba_csr = 0; /* control/status reg */
uint32 uba_vo = 0; /* vector offset */
uint32 uba_int = 0; /* UBA interrupt */
uint32 uba_fubar = 0; /* failing Unibus addr */
uint32 uba_bifa = 0; /* BI failing addr */
uint32 uba_dpr[UBA_NDPATH] = { 0 }; /* number data paths */
uint32 uba_map[UBA_NMAPR] = { 0 }; /* map registers */
uint32 uba_aiip = 0; /* adapter init in prog */
uint32 uba_uiip = 0; /* Unibus init in prog */
uint32 uba_aitime = 250; /* adapter init time */
uint32 uba_uitime = 12250; /* Unibus init time */
int32 autcon_enb = 1; /* autoconfig enable */
extern uint32 nexus_req[NEXUS_HLVL];
t_stat uba_svc (UNIT *uptr);
t_stat uba_reset (DEVICE *dptr);
t_stat uba_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
const char *uba_description (DEVICE *dptr);
t_stat uba_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw);
t_stat uba_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw);
t_stat uba_rdreg (int32 *val, int32 pa, int32 mode);
t_stat uba_wrreg (int32 val, int32 pa, int32 lnt);
int32 uba_get_ubvector (int32 lvl);
void uba_ub_nxm (int32 ua);
void uba_bi_nxm (int32 ba);
void uba_inv_map (int32 ublk);
void uba_eval_int (void);
void uba_adap_set_int ();
void uba_adap_clr_int ();
void uba_ubpdn (int32 time);
t_bool uba_map_addr (uint32 ua, uint32 *ma);
t_stat set_autocon (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat show_autocon (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat show_iospace (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat uba_show_virt (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
extern int32 eval_int (void);
extern t_stat build_dib_tab (void);
/* Unibus IO page dispatches */
t_stat (*iodispR[IOPAGESIZE >> 1])(int32 *dat, int32 ad, int32 md);
t_stat (*iodispW[IOPAGESIZE >> 1])(int32 dat, int32 ad, int32 md);
DIB *iodibp[IOPAGESIZE >> 1];
/* Unibus interrupt request to interrupt action map */
int32 (*int_ack[IPL_HLVL][32])(void); /* int ack routines */
/* Unibus interrupt request to vector map */
int32 int_vec[IPL_HLVL][32]; /* int req to vector */
/* Unibus adapter data structures
uba_dev UBA device descriptor
uba_unit UBA units
uba_reg UBA register list
*/
DIB uba_dib = { TR_UBA, 0, &uba_rdreg, &uba_wrreg, 0, 0 };
UNIT uba_unit = { UDATA (&uba_svc, 0, 0) };
REG uba_reg[] = {
{ HRDATA (IPL14, int_req[0], 32), REG_RO },
{ HRDATA (IPL15, int_req[1], 32), REG_RO },
{ HRDATA (IPL16, int_req[2], 32), REG_RO },
{ HRDATA (IPL17, int_req[3], 32), REG_RO },
{ HRDATA (CSR, uba_csr, 32) },
{ HRDATA (VO, uba_vo, 32) },
{ FLDATA (INT, uba_int, 0) },
{ FLDATA (NEXINT, nexus_req[IPL_UBA], TR_UBA) },
{ HRDATA (FUBAR, uba_fubar, 32) },
{ HRDATA (BIFA, uba_bifa, 32) },
{ HRDATA (BICSR, uba_biic.csr, 32) },
{ HRDATA (BIBER, uba_biic.ber, 32) },
{ HRDATA (BIECR, uba_biic.eicr, 32) },
{ HRDATA (BIDEST, uba_biic.idest, 32) },
{ HRDATA (BISRC, uba_biic.isrc, 32) },
{ HRDATA (BIMSK, uba_biic.imsk, 32) },
{ HRDATA (BIUIIC, uba_biic.uiic, 32) },
{ BRDATA (DPR, uba_dpr, 16, 32, 16) },
{ BRDATA (MAP, uba_map, 16, 32, UBA_NMAPR) },
{ FLDATA (AUTOCON, autcon_enb, 0), REG_HRO },
{ NULL }
};
MTAB uba_mod[] = {
{ MTAB_XTD|MTAB_VDV, TR_UBA, "NEXUS", NULL,
NULL, &show_nexus },
{ MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "IOSPACE", NULL,
NULL, &show_iospace },
{ MTAB_XTD|MTAB_VDV, 1, "AUTOCONFIG", "AUTOCONFIG",
&set_autocon, &show_autocon },
{ MTAB_XTD|MTAB_VDV, 0, NULL, "NOAUTOCONFIG",
&set_autocon, NULL },
{ MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "VIRTUAL", NULL,
NULL, &uba_show_virt },
{ 0 }
};
DEBTAB uba_deb[] = {
{ "REGREAD", UBA_DEB_RRD },
{ "REGWRITE", UBA_DEB_RWR },
{ "MAPREAD", UBA_DEB_MRD },
{ "MAPWRITE", UBA_DEB_MWR },
{ "XFER", UBA_DEB_XFR },
{ "ERROR", UBA_DEB_ERR },
{ NULL, 0 }
};
DEVICE uba_dev = {
"UBA", &uba_unit, uba_reg, uba_mod,
1, 16, UBADDRWIDTH, 2, 16, 16,
&uba_ex, &uba_dep, &uba_reset,
NULL, NULL, NULL,
&uba_dib, DEV_NEXUS | DEV_DEBUG, 0,
uba_deb, NULL, NULL, &uba_help, NULL, NULL,
&uba_description
};
/* Read Unibus adapter register - aligned lw only */
t_stat uba_rdreg (int32 *val, int32 pa, int32 lnt)
{
int32 idx, ofs;
ofs = NEXUS_GETOFS (pa); /* get offset */
if (uba_aiip && (ofs >= UBACSR_OF)) { /* init in prog? */
*val = 0;
return SCPE_OK; /* only BIIC */
}
if ((ofs >= UBABDPS_OF) && (ofs < UBABDPS_OF + 0x10)) {
*val = 0;
return SCPE_OK;
}
if (ofs >= UBAMAP_OF) { /* map? */
idx = ofs - UBAMAP_OF;
if (idx >= UBA_NMAPR) /* valid? */
return SCPE_NXM;
*val = uba_map[idx] & UBAMAP_RD;
if (DEBUG_PRI (uba_dev, UBA_DEB_MRD))
fprintf (sim_deb, ">>UBA: map %d read, value = %X, PC = %X\n", idx, *val, fault_PC);
return SCPE_OK;
}
switch (ofs) { /* case on offset */
case BI_DTYPE:
*val = DTYPE_DWBUA;
break;
case BI_CSR:
*val = uba_biic.csr & BICSR_RD;
break;
case BI_BER:
*val = uba_biic.ber & BIBER_RD;
break;
case BI_EICR:
*val = uba_biic.eicr & BIECR_RD;
break;
case BI_IDEST:
*val = uba_biic.idest & BIID_RD;
break;
case BI_IMSK:
case BI_FIDEST:
case BI_ISRC:
*val = 0;
break;
case BI_SA:
*val = UBADDRBASE;
//*val = uba_biic.sa;
break;
case BI_EA:
*val = UBADDRBASE + 0x40000;
//*val = uba_biic.ea;
break;
case BI_BCIC:
*val = uba_biic.bcic;
break;
case BI_UIIC:
*val = uba_biic.uiic;
break;
case BI_GPR0:
*val = uba_biic.gpr0;
break;
case BI_GPR1:
case BI_GPR2:
case BI_GPR3:
*val = 0;
break;
case UBACSR_OF: /* CSR */
*val = uba_csr | UBACSR_ONE;
break;
case UBAVO_OF: /* VO */
*val = uba_vo & UBAVO_VEC; // should be UBAVO_RD?
break;
case UBAFUBAR_OF: /* FUBAR */
*val = uba_fubar & UBAFUBAR_RD;
break;
case UBABIFA_OF: /* BIFA */
*val = uba_bifa;
break;
case UBADR_OF + 0: /* DR */
case UBADR_OF + 1:
case UBADR_OF + 2:
case UBADR_OF + 3:
case UBADR_OF + 4:
*val = 0;
break;
case UBADPR_OF + 0: /* DPR */
case UBADPR_OF + 1:
case UBADPR_OF + 2:
case UBADPR_OF + 3:
case UBADPR_OF + 4:
case UBADPR_OF + 5:
idx = ofs - UBADPR_OF;
*val = uba_dpr[idx] & UBADPR_RD;
break;
case UBADPR_OF + 6:
case UBADPR_OF + 7:
uba_csr |= UBACSR_BDP;
break;
default:
return SCPE_NXM;
}
if (DEBUG_PRI (uba_dev, UBA_DEB_RRD))
fprintf (sim_deb, ">>UBA: reg %d read, value = %X\n", ofs, *val);
return SCPE_OK;
}
/* Write Unibus adapter register */
t_stat uba_wrreg (int32 val, int32 pa, int32 lnt)
{
int32 idx, ofs;
ofs = NEXUS_GETOFS (pa); /* get offset */
if (uba_aiip && (ofs >= UBACSR_OF)) { /* init in prog? */
return SCPE_OK; /* only BIIC */
}
if (ofs >= UBAMAP_OF) { /* map? */
idx = ofs - UBAMAP_OF;
if (idx >= UBA_NMAPR) /* valid? */
return SCPE_NXM;
uba_map[idx] = val & UBAMAP_WR;
if (DEBUG_PRI (uba_dev, UBA_DEB_MWR))
fprintf (sim_deb, ">>UBA: map %d write, value = %X, PC = %X\n", idx, val, fault_PC);
return SCPE_OK;
}
switch (ofs) { /* case on offset */
case BI_CSR:
if (val & BICSR_RST) { /* unibus power init */
uba_reset (&uba_dev); /* reset adapter */
uba_aiip = 1; /* set init in prog */
uba_ubpdn (uba_aitime); /* power fail UB */
}
uba_biic.csr = (uba_biic.csr & ~BICSR_RW) | (val & BICSR_RW);
break;
case BI_BER:
uba_biic.ber = uba_biic.ber & ~(val & BIBER_W1C);
break;
case BI_EICR:
uba_biic.eicr = (uba_biic.eicr & ~BIECR_RW) | (val & BIECR_RW);
uba_biic.eicr = uba_biic.eicr & ~(val & BIECR_W1C);
break;
case BI_IDEST:
uba_biic.idest = val & BIID_RW;
break;
case BI_UIIC:
break;
case BI_GPR0:
case BI_GPR1:
case BI_GPR2:
case BI_GPR3:
break;
case UBACSR_OF: /* CSR */
if (val & UBACSR_UPI) { /* unibus power init */
uba_aiip = 1; /* set init in prog */
uba_ubpdn (uba_aitime); /* power fail UB */
}
uba_csr = (uba_csr & ~UBACSR_WR) | (val & UBACSR_WR);
uba_csr = uba_csr & ~(val & UBACSR_W1C);
break;
case UBAVO_OF: /* VO */
uba_vo = val & UBAVO_VEC;
break;
case UBADPR_OF + 0: /* DPR */
case UBADPR_OF + 1:
case UBADPR_OF + 2:
case UBADPR_OF + 3:
case UBADPR_OF + 4:
case UBADPR_OF + 5:
break;
case UBADPR_OF + 6:
case UBADPR_OF + 7:
uba_csr |= UBACSR_BDP;
break;
default:
return SCPE_NXM;
}
if (DEBUG_PRI (uba_dev, UBA_DEB_RWR))
fprintf (sim_deb, ">>UBA: reg %d write, value = %X\n", ofs, val);
return SCPE_OK;
}
/* Read and write Unibus I/O space */
int32 ReadUb (uint32 pa)
{
int32 idx, val;
if (ADDR_IS_IOP (pa)) { /* iopage,!init */
idx = (pa & IOPAGEMASK) >> 1;
if (iodispR[idx]) {
iodispR[idx] (&val, pa, READ);
return val;
}
}
uba_biic.ber = uba_biic.ber | BIBER_RDS;
uba_ub_nxm (pa); /* UB nxm */
//MACH_CHECK (MCHK_BIERR); /* machine check */
return 0;
}
void WriteUb (uint32 pa, int32 val, int32 mode)
{
int32 idx;
if (ADDR_IS_IOP (pa)) { /* iopage,!init */
idx = (pa & IOPAGEMASK) >> 1;
if (iodispW[idx]) {
iodispW[idx] (val, pa, mode);
return;
}
}
uba_ub_nxm (pa); /* UB nxm */
return;
}
/* ReadIO - read from IO - UBA only responds to byte, aligned word
Inputs:
pa = physical address
lnt = length (BWLQ)
Output:
longword of data
*/
int32 ReadIO (uint32 pa, int32 lnt)
{
uint32 iod;
if ((lnt == L_BYTE) || /* byte? */
((lnt == L_WORD) && ((pa & 1) == 0))) { /* aligned word? */
iod = ReadUb (pa); /* DATI from Unibus */
if (pa & 2) /* position */
iod = iod << 16;
}
else {
printf (">>UBA: invalid read mask, pa = %x, lnt = %d\n", pa, lnt);
//TODO: Set error bit?
iod = 0;
}
SET_IRQL;
return iod;
}
/* WriteIO - write to IO - UBA only responds to byte, aligned word
Inputs:
pa = physical address
val = data to write, right justified in 32b longword
lnt = length (BWL)
Outputs:
none
*/
void WriteIO (uint32 pa, int32 val, int32 lnt)
{
if (lnt == L_BYTE) /* byte? DATOB */
WriteUb (pa, val, WRITEB);
else if (((lnt == L_WORD) || (lnt == L_LONG)) && ((pa & 1) == 0))/* aligned word? */
WriteUb (pa, val, WRITE); /* DATO */
else {
printf (">>UBA: invalid write mask, pa = %x, lnt = %d\n", pa, lnt);
//TODO: Set error bit?
}
SET_IRQL; /* update ints */
return;
}
/* Update UBA nexus interrupts */
void uba_eval_int (void)
{
int32 i, lvl;
// TODO: Check BIIC register?
if (uba_int) {
lvl = (uba_biic.eicr >> BIECR_V_LVL) & BIECR_M_LVL;
for (i = 0; i < (IPL_HMAX - IPL_HMIN); i++) {
if (lvl & (1u << i)) {
nexus_req[i] |= (1 << TR_UBA);
}
}
}
else {
for (i = 0; i < (IPL_HMAX - IPL_HMIN); i++) /* clear all UBA req */
nexus_req[i] &= ~(1 << TR_UBA);
for (i = 0; i < (IPL_HMAX - IPL_HMIN); i++) {
if (int_req[i])
nexus_req[i] |= (1 << TR_UBA);
}
}
//if (uba_int) /* adapter int? */
// SET_NEXUS_INT (UBA);
return;
}
/* Return vector for Unibus interrupt at relative IPL level [0-3] */
int32 uba_get_ubvector (int32 lvl)
{
int32 i, vec;
if ((uba_biic.eicr & (1u << (lvl + BIECR_V_LVL))) && uba_int) { /* UBA err lvl, int? */
//if ((lvl == (IPL_UBA - IPL_HMIN)) && uba_int) { /* UBA lvl, int? */
vec = uba_biic.eicr & BIECR_VEC;
uba_int = 0; /* clear int */
}
else {
vec = uba_vo & UBAVO_VEC;
for (i = 0; int_req[lvl] && (i < 32); i++) {
if ((int_req[lvl] >> i) & 1) {
int_req[lvl] = int_req[lvl] & ~(1u << i);
if (int_ack[lvl][i])
return (vec | int_ack[lvl][i]());
return (vec | int_vec[lvl][i]);
}
}
}
return vec;
}
/* Unibus I/O buffer routines
Map_ReadB - fetch byte buffer from memory
Map_ReadW - fetch word buffer from memory
Map_WriteB - store byte buffer into memory
Map_WriteW - store word buffer into memory
*/
int32 Map_ReadB (uint32 ba, int32 bc, uint8 *buf)
{
int32 i, j, pbc;
uint32 ma, dat;
ba = ba & UBADDRMASK; /* mask UB addr */
for (i = 0; i < bc; i = i + pbc) { /* loop by pages */
if (!uba_map_addr (ba + i, &ma)) /* page inv or NXM? */
return (bc - i);
pbc = VA_PAGSIZE - VA_GETOFF (ma); /* left in page */
if (pbc > (bc - i)) /* limit to rem xfr */
pbc = bc - i;
if (DEBUG_PRI (uba_dev, UBA_DEB_XFR))
fprintf (sim_deb, ">>UBA: 8b read, ma = %X, bc = %X\n", ma, pbc);
if ((ma | pbc) & 3) { /* aligned LW? */
for (j = 0; j < pbc; ma++, j++) { /* no, do by bytes */
*buf++ = ReadB (ma);
}
}
else { /* yes, do by LW */
for (j = 0; j < pbc; ma = ma + 4, j = j + 4) {
dat = ReadL (ma); /* get lw */
*buf++ = dat & BMASK; /* low 8b */
*buf++ = (dat >> 8) & BMASK; /* next 8b */
*buf++ = (dat >> 16) & BMASK; /* next 8b */
*buf++ = (dat >> 24) & BMASK;
}
}
}
return 0;
}
int32 Map_ReadW (uint32 ba, int32 bc, uint16 *buf)
{
int32 i, j, pbc;
uint32 ma, dat;
ba = ba & UBADDRMASK; /* mask UB addr */
bc = bc & ~01;
for (i = 0; i < bc; i = i + pbc) { /* loop by pages */
if (!uba_map_addr (ba + i, &ma)) /* page inv or NXM? */
return (bc - i);
pbc = VA_PAGSIZE - VA_GETOFF (ma); /* left in page */
if (pbc > (bc - i)) /* limit to rem xfr */
pbc = bc - i;
if (DEBUG_PRI (uba_dev, UBA_DEB_XFR))
fprintf (sim_deb, ">>UBA: 16b read, ba = %X, ma = %X, bc = %X\n", ba, ma, pbc);
if ((ma | pbc) & 1) { /* aligned word? */
for (j = 0; j < pbc; ma++, j++) { /* no, do by bytes */
if ((i + j) & 1) { /* odd byte? */
*buf = (*buf & BMASK) | (ReadB (ma) << 8);
buf++;
}
else *buf = (*buf & ~BMASK) | ReadB (ma);
}
}
else if ((ma | pbc) & 3) { /* aligned LW? */
for (j = 0; j < pbc; ma = ma + 2, j = j + 2) { /* no, words */
*buf++ = ReadW (ma); /* get word */
}
}
else { /* yes, do by LW */
for (j = 0; j < pbc; ma = ma + 4, j = j + 4) {
dat = ReadL (ma); /* get lw */
*buf++ = dat & WMASK; /* low 16b */
*buf++ = (dat >> 16) & WMASK; /* high 16b */
}
}
}
return 0;
}
int32 Map_WriteB (uint32 ba, int32 bc, const uint8 *buf)
{
int32 i, j, pbc;
uint32 ma, dat;
ba = ba & UBADDRMASK; /* mask UB addr */
for (i = 0; i < bc; i = i + pbc) { /* loop by pages */
if (!uba_map_addr (ba + i, &ma)) /* page inv or NXM? */
return (bc - i);
pbc = VA_PAGSIZE - VA_GETOFF (ma); /* left in page */
if (pbc > (bc - i)) /* limit to rem xfr */
pbc = bc - i;
if (DEBUG_PRI (uba_dev, UBA_DEB_XFR))
fprintf (sim_deb, ">>UBA: 8b write, ma = %X, bc = %X\n", ma, pbc);
if ((ma | pbc) & 3) { /* aligned LW? */
for (j = 0; j < pbc; ma++, j++) { /* no, do by bytes */
WriteB (ma, *buf);
buf++;
}
}
else { /* yes, do by LW */
for (j = 0; j < pbc; ma = ma + 4, j = j + 4) {
dat = (uint32) *buf++; /* get low 8b */
dat = dat | (((uint32) *buf++) << 8); /* merge next 8b */
dat = dat | (((uint32) *buf++) << 16); /* merge next 8b */
dat = dat | (((uint32) *buf++) << 24); /* merge hi 8b */
WriteL (ma, dat); /* store lw */
}
}
}
return 0;
}
int32 Map_WriteW (uint32 ba, int32 bc, const uint16 *buf)
{
int32 i, j, pbc;
uint32 ma, dat;
ba = ba & UBADDRMASK; /* mask UB addr */
bc = bc & ~01;
for (i = 0; i < bc; i = i + pbc) { /* loop by pages */
if (!uba_map_addr (ba + i, &ma)) /* page inv or NXM? */
return (bc - i);
pbc = VA_PAGSIZE - VA_GETOFF (ma); /* left in page */
if (pbc > (bc - i)) /* limit to rem xfr */
pbc = bc - i;
if (DEBUG_PRI (uba_dev, UBA_DEB_XFR))
fprintf (sim_deb, ">>UBA: 16b write, ma = %X, bc = %X\n", ma, pbc);
if ((ma | pbc) & 1) { /* aligned word? */
for (j = 0; j < pbc; ma++, j++) { /* no, bytes */
if ((i + j) & 1) {
WriteB (ma, (*buf >> 8) & BMASK);
buf++;
}
else WriteB (ma, *buf & BMASK);
}
}
else if ((ma | pbc) & 3) { /* aligned LW? */
for (j = 0; j < pbc; ma = ma + 2, j = j + 2) { /* no, words */
WriteW (ma, *buf); /* write word */
buf++;
}
}
else { /* yes, do by LW */
for (j = 0; j < pbc; ma = ma + 4, j = j + 4) {
dat = (uint32) *buf++; /* get low 16b */
dat = dat | (((uint32) *buf++) << 16); /* merge hi 16b */
WriteL (ma, dat); /* store LW */
}
}
}
return 0;
}
/* Map an address via the translation map */
t_bool uba_map_addr (uint32 ua, uint32 *ma)
{
uint32 ublk, umap, dpr;
ublk = ua >> VA_V_VPN; /* Unibus blk */
//if ((ublk < UBACR_GETDSB (uba_cr)) || /* map disabled? */
if (ublk >= UBA_NMAPR) /* unimplemented? */
return FALSE;
umap = uba_map[ublk]; /* get map */
if (umap == 0xFFFFFFFF)
return FALSE; /* ignore transaction */
if (umap & UBAMAP_VLD) { /* valid? */
*ma = ((umap & UBAMAP_PAG) << VA_V_VPN) + VA_GETOFF (ua);
if ((umap & UBAMAP_DP) && (umap & UBAMAP_ODD)) { /* buffered dp? */
if (umap & UBAMAP_LWAE) {
dpr = UBAMAP_GETDP (umap); /* get datapath */
if ((dpr == 6) || (dpr == 7))
return FALSE; /* ignore transfer */
}
*ma = *ma + 1; /* byte offset? */
}
if (ADDR_IS_MEM (*ma)) /* valid mem address */
return TRUE;
if ((umap & UBAMAP_IOAD) && (ADDR_IS_IO (*ma))) /* valid i/o address */
return TRUE;
uba_bi_nxm (*ma);
return FALSE;
}
uba_inv_map (ua); /* invalid map */
return FALSE;
}
/* Map an address via the translation map - console version (no status changes) */
t_bool uba_map_addr_c (uint32 ua, uint32 *ma)
{
uint32 ublk, umap;
ublk = ua >> VA_V_VPN; /* Unibus blk */
//if ((ublk < UBACR_GETDSB (uba_cr)) || /* map disabled? */
if (ublk >= UBA_NMAPR) /* unimplemented? */
return FALSE;
umap = uba_map[ublk]; /* get map */
if (umap & UBAMAP_VLD) { /* valid? */
*ma = ((umap & UBAMAP_PAG) << VA_V_VPN) + VA_GETOFF (ua);
if ((umap & UBAMAP_DP) && (umap & UBAMAP_ODD)) /* buffered dp? */
*ma = *ma + 1; /* byte offset? */
return TRUE; /* legit addr */
}
return FALSE;
}
/* Error routines
uba_ub_nxm SBI read/write to nx Unibus address
uba_inv_map Unibus reference to invalid map reg
*/
void uba_ub_nxm (int32 ua)
{
if ((uba_csr & UBACSR_TO) == 0) {
uba_csr |= UBACSR_TO;
uba_fubar = (ua >> 2) & UBAFUBAR_RD;
uba_adap_set_int ();
}
sim_debug (UBA_DEB_ERR, &uba_dev,
">>UBA: nxm error, ua = %X, PC = %X\n", ua, fault_PC);
return;
}
void uba_bi_nxm (int32 ba)
{
if ((uba_biic.ber & BIBER_BTO) == 0) {
uba_biic.ber |= BIBER_BTO;
uba_bifa = ba;
uba_adap_set_int ();
}
sim_debug (UBA_DEB_ERR, &uba_dev,
">>UBA: BI nxm error, ba = %X, PC = %X\n", ba, fault_PC);
return;
}
void uba_inv_map (int32 ublk)
{
if ((uba_csr & UBACSR_IMR) == 0) {
uba_csr |= UBACSR_IMR;
uba_adap_set_int ();
}
sim_debug (UBA_DEB_ERR, &uba_dev,
">>UBA: inv map error, ublk = %X\n", ublk);
return;
}
/* Unibus power fail routines */
void uba_ubpdn (int32 time)
{
int32 i;
DEVICE *dptr;
uba_biic.gpr0 = uba_biic.gpr0 & ~BIGPR0_UPU; /* UB power down */
sim_activate (&uba_unit, time); /* schedule */
uba_uiip = 1; /* UB init in prog */
for (i = 0; sim_devices[i] != NULL; i++) { /* reset Unibus */
dptr = sim_devices[i];
if (dptr->reset && (dptr->flags & DEV_UBUS))
dptr->reset (dptr);
}
return;
}
/* Init timeout service routine */
t_stat uba_svc (UNIT *uptr)
{
if (uba_aiip) { /* adapter init? */
uba_aiip = 0; /* clear in prog */
sim_activate (uptr, uba_uitime); /* schedule UB */
}
else {
uba_uiip = 0; /* no, UB */
uba_biic.gpr0 = uba_biic.gpr0 | BIGPR0_UPU; /* UB power up */
}
uba_adap_set_int (); /* possible int */
return SCPE_OK;
}
/* Interrupt routines */
void uba_adap_set_int ()
{
if (uba_csr & UBACSR_EIE) {
uba_int = 1;
sim_debug (UBA_DEB_ERR, &uba_dev,
">>UBA: adapter int req, csr = %X\n", uba_csr);
}
return;
}
void uba_adap_clr_int ()
{
if (!(uba_csr & UBACSR_EIE))
uba_int = 0;
return;
}
/* Reset Unibus adapter */
t_stat uba_reset (DEVICE *dptr)
{
int32 i;
uba_int = 0;
uba_aiip = uba_uiip = 0;
sim_cancel (&uba_unit);
for (i = 0; i < IPL_HLVL; i++) {
nexus_req[i] &= ~(1 << TR_UBA);
int_req[i] = 0;
}
for (i = 0; i < UBA_NMAPR; i++) { /* clear map registers */
if (i < UBA_NMAPU)
uba_map[i] = 0;
else
uba_map[i] = 0xffffffff;
}
for (i = 0; i < UBA_NDPATH; i++) /* setup datapaths */
uba_dpr[i] = (i << UBADPR_V_SEL);
uba_csr = 0;
uba_biic.csr = (1u << BICSR_V_IF) | BICSR_STS | (TR_UBA & BICSR_NODE);
uba_biic.ber = 0;
uba_biic.eicr = 0;
uba_biic.idest = 0;
uba_biic.uiic = BIICR_EXV;
uba_biic.gpr0 = BIGPR0_UPU;
return SCPE_OK;
}
t_stat uba_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
{
fprintf (st, "Unibus Adapter (UBA)\n\n");
fprintf (st, "The Unibus adapter (UBA) simulates the DWBUA.\n");
fprint_set_help (st, dptr);
fprint_show_help (st, dptr);
fprintf (st, "\nThe UBA implements main memory examination and modification via the Unibus\n");
fprintf (st, "map. The data width is always 16b:\n\n");
fprintf (st, "EXAMINE UBA 0/10 examine main memory words corresponding\n");
fprintf (st, " to Unibus addresses 0-10\n");
fprint_reg_help (st, dptr);
return SCPE_OK;
}
const char *uba_description (DEVICE *dptr)
{
return "Unibus adapter";
}
/* Memory examine via map (word only) */
t_stat uba_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw)
{
uint32 ua = (uint32) exta, pa;
if ((vptr == NULL) || (ua >= UBADDRSIZE))
return SCPE_ARG;
if (uba_map_addr_c (ua, &pa) && ADDR_IS_MEM (pa)) {
*vptr = (uint32) ReadW (pa);
return SCPE_OK;
}
return SCPE_NXM;
}
/* Memory deposit via map (word only) */
t_stat uba_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw)
{
uint32 ua = (uint32) exta, pa;
if (ua >= UBADDRSIZE)
return SCPE_ARG;
if (uba_map_addr_c (ua, &pa) && ADDR_IS_MEM (pa)) {
WriteW (pa, (int32) val);
return SCPE_OK;
}
return SCPE_NXM;
}
/* Show UBA virtual address */
t_stat uba_show_virt (FILE *of, UNIT *uptr, int32 val, CONST void *desc)
{
t_stat r;
char *cptr = (char *) desc;
uint32 ua, pa;
if (cptr) {
ua = (uint32) get_uint (cptr, 16, UBADDRSIZE - 1, &r);
if (r == SCPE_OK) {
if (uba_map_addr_c (ua, &pa))
fprintf (of, "Unibus %-X = physical %-X\n", ua, pa);
else fprintf (of, "Unibus %-X: invalid mapping\n", ua);
return SCPE_OK;
}
}
fprintf (of, "Invalid argument\n");
return SCPE_OK;
}

163
VAX/vax_bi.h Normal file
View file

@ -0,0 +1,163 @@
/* vax_bi.h: VAXBI Standard Definitions
Copyright (c) 2019, Matt Burke
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of the author shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the author.
This file covers the VAXBI registers that are contained in the BIIC chip
on each VAXBI node.
*/
#ifndef _VAXBI_DEFS_H_
#define _VAXBI_DEFS_H_ 1
/* Register Offsets */
#define BI_DTYPE 0 /* device type */
#define BI_CSR 1 /* control/status */
#define BI_BER 2 /* bus error */
#define BI_EICR 3 /* error interrupt control */
#define BI_IDEST 4 /* interrupt destination */
#define BI_IMSK 5 /* IPINTR mask */
#define BI_FIDEST 6 /* force IPINTR destination */
#define BI_ISRC 7 /* IPINTR source */
#define BI_SA 8 /* start address */
#define BI_EA 9 /* end address */
#define BI_BCIC 10 /* BCI control */
#define BI_WSTS 11 /* write status */
#define BI_FICMD 12 /* force IPINTR command */
#define BI_UIIC 16 /* user interface interrupt control */
#define BI_GPR0 60 /* general purpose register 0 */
#define BI_GPR1 61 /* general purpose register 1 */
#define BI_GPR2 62 /* general purpose register 2 */
#define BI_GPR3 63 /* general purpose register 3 */
#define BI_SOSR 64 /* slave only status register */
#define BI_RXCD 128 /* receive console data register */
/* VAXBI device types */
#define DTYPE_MS820 0x0001 /* MS820 MOS Memory */
#define DTYPE_DWBUA 0x0102 /* DWBUA Unibus Adapter */
#define DTYPE_KA820 0x0105 /* KA820 CPU */
#define DTYPE_CIBCA 0x0105 /* CI Adapter */
#define DTYPE_KDB50 0x010E /* Disk Adapter */
#define DTYPE_DEBNA 0x410F /* Ethernet Adapter */
/* VAXBI control/status register */
#define BICSR_V_IR 24 /* interface revision */
#define BICSR_M_IR 0xFF
#define BICSR_V_IF 16 /* interface type */
#define BICSR_M_IF 0xFF
#define BICSR_HES 0x00004000 /* hard error summary */
#define BICSR_SES 0x00004000 /* soft error summary */
#define BICSR_INI 0x00002000 /* initialise */
#define BICSR_BRK 0x00001000 /* broke - NI */
#define BICSR_STS 0x00000800 /* self test status */
#define BICSR_RST 0x00000400 /* node reset */
#define BICSR_UWP 0x00000100 /* unlock write pending */
#define BICSR_HIE 0x00000080 /* hard error interrupt en */
#define BICSR_SIE 0x00000040 /* soft error interrupt en */
#define BICSR_AC 0x00000030 /* arbitration control */
#define BICSR_NODE 0x0000000F /* BI node ID */
#define BICSR_RW (BICSR_HIE | BICSR_SIE | BICSR_AC)
#define BICSR_RD 0xFFFFFDFF
/* VAXBI bus error register */
#define BIBER_NMR 0x40000000 /* no ACK to multi resp command */
#define BIBER_MTCE 0x20000000 /* master transmit check error */
#define BIBER_CTE 0x10000000 /* control transmit error */
#define BIBER_MPE 0x08000000 /* master parity error */
#define BIBER_ISE 0x04000000 /* interlock sequence error */
#define BIBER_TDF 0x02000000 /* transmitter during fault */
#define BIBER_IVE 0x01000000 /* ident vector error */
#define BIBER_CPE 0x00800000 /* command parity error */
#define BIBER_SPE 0x00400000 /* slave parity error */
#define BIBER_RDS 0x00200000 /* read data substitute */
#define BIBER_RTO 0x00100000 /* retry timeout */
#define BIBER_STO 0x00080000 /* stall timeout */
#define BIBER_BTO 0x00040000 /* bus timeout */
#define BIBER_NEX 0x00020000 /* nonexistant address */
#define BIBER_ICE 0x00010000 /* illegal confirmation error */
#define BIBER_UPE 0x00000008 /* user parity enable */
#define BIBER_IPE 0x00000004 /* ID parity error */
#define BIBER_CRD 0x00000002 /* corrected read data */
#define BIBER_NPE 0x00000001 /* null bus parity error */
#define BIBER_RD 0xFFFF000F
#define BIBER_W1C 0xFFFF0007
/* VAXBI error interrupt control register */
#define BIECR_ABO 0x01000000 /* interrupt abort */
#define BIECR_COM 0x00800000 /* interrupt complete */
#define BIECR_SNT 0x00200000 /* interrupt sent */
#define BIECR_FRC 0x00100000 /* force */
#define BIECR_LVL 0x000F0000 /* interrupt level */
#define BIECR_V_LVL 16
#define BIECR_M_LVL 0xF
#define BIECR_VEC 0x00003FFC /* vector */
#define BIECR_RW 0x001F3FFC
#define BIECR_W1C 0x01A00000
#define BIECR_RD (BIECR_RW | BIECR_W1C)
/* VAXBI interrupt destination register */
#define BIID_RW 0x0000FFFF
#define BIID_RD BIID_RW
/* VAXBI user interface interrupt control register */
#define BIICR_ABO 0xF0000000 /* interrupt abort */
#define BIICR_ITC 0x0F000000 /* interrupt complete */
#define BIICR_SNT 0x00F00000 /* interrupt sent */
#define BIICR_FRC 0x000F0000 /* force */
#define BIICR_EXV 0x00008000 /* external vector */
#define BIICR_VEC 0x00003FFC /* vector */
#define BIICR_RW 0x000FBFFC
#define BIICR_W1C 0xFFF00000
#define BIICR_RD (BIICR_RW | BIICR_W1C)
typedef struct {
uint32 dtype;
uint32 csr;
uint32 ber;
uint32 eicr;
uint32 idest;
uint32 imsk;
uint32 fidest;
uint32 isrc;
uint32 sa;
uint32 ea;
uint32 bcic;
uint32 wsts;
uint32 ficmd;
uint32 uiic;
uint32 gpr0;
uint32 gpr1;
uint32 gpr2;
uint32 gpr3;
uint32 sosr;
uint32 rxcd;
} BIIC;
#endif

View file

@ -817,6 +817,7 @@ extern int32 pcq_p; /* PC queue ptr */
extern int32 in_ie; /* in exc, int */
extern int32 ibcnt, ppc; /* prefetch ctl */
extern int32 hlt_pin; /* HLT pin intr */
extern int32 mxpr_cc_vc; /* cc V & C bits from mtpr/mfpr operations */
extern int32 mem_err;
extern int32 crd_err;
@ -912,6 +913,8 @@ extern void rom_wr_B (int32 pa, int32 val);
#include "vax610_defs.h"
#elif defined (VAX_620) || defined (VAX_630)
#include "vax630_defs.h"
#elif defined (VAX_820)
#include "vax820_defs.h"
#elif defined (VAX_860)
#include "vax860_defs.h"
#else /* VAX 3900 */

View file

@ -303,6 +303,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UC15", "UC15.vcproj", "{B5E
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VAX8200", "VAX8200.vcproj", "{B9BA7B49-AFAD-4950-B8DC-2FAD61AE8B7E}"
ProjectSection(ProjectDependencies) = postProject
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@ -553,6 +558,10 @@ Global
{B5E9D32E-53F9-4C9B-B037-5A2D34E370CF}.Debug|Win32.Build.0 = Debug|Win32
{B5E9D32E-53F9-4C9B-B037-5A2D34E370CF}.Release|Win32.ActiveCfg = Release|Win32
{B5E9D32E-53F9-4C9B-B037-5A2D34E370CF}.Release|Win32.Build.0 = Release|Win32
{B9BA7B49-AFAD-4950-B8DC-2FAD61AE8B7E}.Debug|Win32.ActiveCfg = Debug|Win32
{B9BA7B49-AFAD-4950-B8DC-2FAD61AE8B7E}.Debug|Win32.Build.0 = Debug|Win32
{B9BA7B49-AFAD-4950-B8DC-2FAD61AE8B7E}.Release|Win32.ActiveCfg = Release|Win32
{B9BA7B49-AFAD-4950-B8DC-2FAD61AE8B7E}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View file

@ -0,0 +1,681 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="VAX8200"
ProjectGUID="{B9BA7B49-AFAD-4950-B8DC-2FAD61AE8B7E}"
RootNamespace="VAX8200"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Build Dependent ROM include File(s) &amp; Check for required build dependencies &amp; git commit id"
CommandLine="Pre-Build-Event.cmd &quot;$(TargetDir)$(TargetName).exe&quot; LIBPCRE ROM BUILD"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../VAX/;../pdp11/;../../windows-build/libSDL/SDL2-2.0.5/include;./;../;../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include;../../windows-build/winpcap/Wpdpack/Include;../../windows-build/PCRE/include/;../../windows-build/pthreads;../../windows-build/libSDL/SDL2-2.0.8/include;../../windows-build/libpng-1.6.18"
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_820;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG"
MinimalRebuild="true"
BasicRuntimeChecks="0"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
CompileAs="1"
ShowIncludes="false"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/fixed:no"
AdditionalDependencies="libcmtd.lib wsock32.lib winmm.lib Iphlpapi.lib pcrestaticd.lib pcreposixstaticd.lib SDL2-StaticD.lib SDL2_ttf-StaticD.lib freetype2412MT_D.lib libpng16.lib zlib.lib dxguid.lib Imm32.lib Version.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="../../windows-build/lib/Debug/"
GenerateDebugInformation="true"
SubSystem="1"
StackReserveSize="10485760"
StackCommitSize="10485760"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
Description="Running Available Tests"
CommandLine="Post-Build-Event.cmd VAX &quot;$(TargetDir)$(TargetName).exe&quot; vax-diag_test"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Build Dependent ROM include File(s) &amp; Check for required build dependencies &amp; git commit id"
CommandLine="Pre-Build-Event.cmd &quot;$(TargetDir)$(TargetName).exe&quot; LIBPCRE ROM BUILD"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
WholeProgramOptimization="true"
AdditionalIncludeDirectories="../VAX/;../pdp11/;../../windows-build/libSDL/SDL2-2.0.5/include;./;../;../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include;../../windows-build/winpcap/Wpdpack/Include;../../windows-build/PCRE/include/;../../windows-build/pthreads;../../windows-build/libSDL/SDL2-2.0.8/include;../../windows-build/libpng-1.6.18"
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_820;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
CompileAs="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/fixed:no"
AdditionalDependencies="libcmt.lib wsock32.lib winmm.lib Iphlpapi.lib pcrestatic.lib pcreposixstatic.lib SDL2-Static.lib SDL2_ttf-Static.lib freetype2412MT.lib libpng16.lib zlib.lib dxguid.lib Imm32.lib Version.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="../../windows-build/lib/Release/"
GenerateDebugInformation="false"
SubSystem="1"
StackReserveSize="10485760"
StackCommitSize="10485760"
OptimizeReferences="2"
EnableCOMDATFolding="2"
LinkTimeCodeGeneration="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
Description="Running Available Tests"
CommandLine="Post-Build-Event.cmd VAX &quot;$(TargetDir)$(TargetName).exe&quot; vax-diag_test"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
>
<File
RelativePath="..\PDP11\pdp11_ch.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_cr.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_dmc.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_dz.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_hk.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_io_lib.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_lp.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_rk.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_rl.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_rq.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_ry.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_tc.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_td.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_tq.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_ts.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_vh.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_xu.c"
>
</File>
<File
RelativePath="..\..\windows-build\pthreads\pthread.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="HAVE_CONFIG_H;PTW32_BUILD_INLINED;PTW32_STATIC_LIB;__CLEANUP_C;$(NOINHERIT)"
CompileAs="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
WholeProgramOptimization="false"
PreprocessorDefinitions="HAVE_CONFIG_H;PTW32_BUILD_INLINED;PTW32_STATIC_LIB;__CLEANUP_C;$(NOINHERIT)"
CompileAs="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\scp.c"
>
</File>
<File
RelativePath="..\sim_console.c"
>
</File>
<File
RelativePath="..\sim_disk.c"
>
</File>
<File
RelativePath="..\sim_ether.c"
>
</File>
<File
RelativePath="..\sim_fio.c"
>
</File>
<File
RelativePath="..\sim_serial.c"
>
</File>
<File
RelativePath="..\sim_sock.c"
>
</File>
<File
RelativePath="..\sim_tape.c"
>
</File>
<File
RelativePath="..\sim_timer.c"
>
</File>
<File
RelativePath="..\sim_tmxr.c"
>
</File>
<File
RelativePath="..\sim_video.c"
>
</File>
<File
RelativePath="..\VAX\vax820_bi.c"
>
</File>
<File
RelativePath="..\VAX\vax820_ka.c"
>
</File>
<File
RelativePath="..\VAX\vax820_mem.c"
>
</File>
<File
RelativePath="..\VAX\vax820_stddev.c"
>
</File>
<File
RelativePath="..\VAX\vax820_syslist.c"
>
</File>
<File
RelativePath="..\VAX\vax820_uba.c"
>
</File>
<File
RelativePath="..\VAX\vax_cis.c"
>
</File>
<File
RelativePath="..\VAX\vax_cmode.c"
>
</File>
<File
RelativePath="..\VAX\vax_cpu.c"
>
</File>
<File
RelativePath="..\VAX\vax_cpu1.c"
>
</File>
<File
RelativePath="..\VAX\vax_fpa.c"
>
</File>
<File
RelativePath="..\VAX\vax_mmu.c"
>
</File>
<File
RelativePath="..\VAX\vax_octa.c"
>
</File>
<File
RelativePath="..\VAX\vax_sys.c"
>
</File>
<File
RelativePath="..\VAX\vax_syscm.c"
>
</File>
<File
RelativePath="..\VAX\vax_watch.c"
>
</File>
<Filter
Name="slirp"
>
<File
RelativePath="..\slirp\arp_table.c"
>
</File>
<File
RelativePath="..\slirp\bootp.c"
>
</File>
<File
RelativePath="..\slirp\bootp.h"
>
</File>
<File
RelativePath="..\slirp\cksum.c"
>
</File>
<File
RelativePath="..\slirp\debug.h"
>
</File>
<File
RelativePath="..\slirp\dnssearch.c"
>
</File>
<File
RelativePath="..\slirp_glue\glib_qemu_stubs.c"
>
</File>
<File
RelativePath="..\slirp\if.c"
>
</File>
<File
RelativePath="..\slirp\if.h"
>
</File>
<File
RelativePath="..\slirp\ip.h"
>
</File>
<File
RelativePath="..\slirp\ip_icmp.c"
>
</File>
<File
RelativePath="..\slirp\ip_icmp.h"
>
</File>
<File
RelativePath="..\slirp\ip_input.c"
>
</File>
<File
RelativePath="..\slirp\ip_output.c"
>
</File>
<File
RelativePath="..\slirp\libslirp.h"
>
</File>
<File
RelativePath="..\slirp\main.h"
>
</File>
<File
RelativePath="..\slirp\mbuf.c"
>
</File>
<File
RelativePath="..\slirp\mbuf.h"
>
</File>
<File
RelativePath="..\slirp\misc.c"
>
</File>
<File
RelativePath="..\slirp\misc.h"
>
</File>
<File
RelativePath="..\slirp\sbuf.c"
>
</File>
<File
RelativePath="..\slirp\sbuf.h"
>
</File>
<File
RelativePath="..\slirp_glue\sim_slirp.c"
>
</File>
<File
RelativePath="..\slirp\slirp.c"
>
</File>
<File
RelativePath="..\slirp\slirp.h"
>
</File>
<File
RelativePath="..\slirp\slirp_config.h"
>
</File>
<File
RelativePath="..\slirp\socket.c"
>
</File>
<File
RelativePath="..\slirp\socket.h"
>
</File>
<File
RelativePath="..\slirp\tcp.h"
>
</File>
<File
RelativePath="..\slirp\tcp_input.c"
>
</File>
<File
RelativePath="..\slirp\tcp_output.c"
>
</File>
<File
RelativePath="..\slirp\tcp_subr.c"
>
</File>
<File
RelativePath="..\slirp\tcp_timer.c"
>
</File>
<File
RelativePath="..\slirp\tcp_timer.h"
>
</File>
<File
RelativePath="..\slirp\tcp_var.h"
>
</File>
<File
RelativePath="..\slirp\tcpip.h"
>
</File>
<File
RelativePath="..\slirp\tftp.c"
>
</File>
<File
RelativePath="..\slirp\tftp.h"
>
</File>
<File
RelativePath="..\slirp\udp.c"
>
</File>
<File
RelativePath="..\slirp\udp.h"
>
</File>
</Filter>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc"
>
<File
RelativePath="..\dec_dz.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_ddcmp.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_dup.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_io_lib.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_mscp.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_td.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_uqssp.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_xu.h"
>
</File>
<File
RelativePath="..\scp.h"
>
</File>
<File
RelativePath="..\sim_console.h"
>
</File>
<File
RelativePath="..\sim_defs.h"
>
</File>
<File
RelativePath="..\sim_disk.h"
>
</File>
<File
RelativePath="..\sim_ether.h"
>
</File>
<File
RelativePath="..\sim_fio.h"
>
</File>
<File
RelativePath="..\sim_rev.h"
>
</File>
<File
RelativePath="..\sim_serial.h"
>
</File>
<File
RelativePath="..\sim_sock.h"
>
</File>
<File
RelativePath="..\sim_tape.h"
>
</File>
<File
RelativePath="..\sim_timer.h"
>
</File>
<File
RelativePath="..\sim_tmxr.h"
>
</File>
<File
RelativePath="..\sim_video.h"
>
</File>
<File
RelativePath="..\VAX\vax820_defs.h"
>
</File>
<File
RelativePath="..\VAX\vax_bi.h"
>
</File>
<File
RelativePath="..\VAX\vax_defs.h"
>
</File>
<File
RelativePath="..\VAX\vax_mmu.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -56,6 +56,7 @@
# VAX730 Just Build The DEC VAX730.
# VAX750 Just Build The DEC VAX750.
# VAX780 Just Build The DEC VAX780.
# VAX8200 Just Build The DEC VAX8200.
# VAX8600 Just Build The DEC VAX8600.
# CLEAN Will Clean Files Back To Base Kit.
#
@ -921,6 +922,37 @@ VAX780_OPTIONS = /INCL=($(SIMH_DIR),$(VAX780_DIR),$(PDP11_DIR)$(PCAP_INC))\
VAX780_SIMH_LIB = $(SIMH_LIB)
.ENDIF
# Digital Equipment VAX8200 Simulator Definitions.
#
VAX8200_DIR = SYS$DISK:[.VAX]
VAX8200_LIB1 = $(LIB_DIR)VAX820L1-$(ARCH).OLB
VAX8200_SOURCE1 = $(VAX8200_DIR)VAX_CPU.C,$(VAX8200_DIR)VAX_CPU1.C,\
$(VAX8200_DIR)VAX_FPA.C,$(VAX8200_DIR)VAX_CIS.C,\
$(VAX8200_DIR)VAX_OCTA.C,$(VAX8200_DIR)VAX_CMODE.C,\
$(VAX8200_DIR)VAX_MMU.C,$(VAX8200_DIR)VAX_SYS.C,\
$(VAX8200_DIR)VAX_SYSCM.C,$(VAX8200_DIR)VAX_WATCH.C,\
$(VAX8200_DIR)VAX820_STDDEV.C,$(VAX8200_DIR)VAX820_BI.C,\
$(VAX8200_DIR)VAX820_MEM.C,$(VAX8200_DIR)VAX820_UBA.C,\
$(VAX8200_DIR)VAX820_KA.C,$(VAX8200_DIR)VAX820_SYSLIST.C
VAX8200_LIB2 = $(LIB_DIR)VAX820L2-$(ARCH).OLB
VAX8200_SOURCE2 = $(PDP11_DIR)PDP11_RL.C,$(PDP11_DIR)PDP11_RQ.C,\
$(PDP11_DIR)PDP11_TS.C,$(PDP11_DIR)PDP11_DZ.C,\
$(PDP11_DIR)PDP11_LP.C,$(PDP11_DIR)PDP11_TD.C,$(PDP11_DIR)PDP11_TQ.C,\
$(PDP11_DIR)PDP11_XU.C,$(PDP11_DIR)PDP11_RY.C,\
$(PDP11_DIR)PDP11_CR.C,$(PDP11_DIR)PDP11_HK.C,\
$(PDP11_DIR)PDP11_VH.C,$(PDP11_DIR)PDP11_DMC.C,\
$(PDP11_DIR)PDP11_TC.C,$(PDP11_DIR)PDP11_RK.C,\
$(PDP11_DIR)PDP11_CH.C,$(PDP11_DIR)PDP11_IO_LIB.C
.IFDEF ALPHA_OR_IA64
VAX8200_OPTIONS = /INCL=($(SIMH_DIR),$(VAX8200_DIR),$(PDP11_DIR)$(PCAP_INC))\
/DEF=($(CC_DEFS),"VM_VAX=1","USE_ADDR64=1","USE_INT64=1"$(PCAP_DEFS),"VAX_820=1")
VAX8200_SIMH_LIB = $(SIMH_LIB64)
.ELSE
VAX8200_OPTIONS = /INCL=($(SIMH_DIR),$(VAX8200_DIR),$(PDP11_DIR)$(PCAP_INC))\
/DEF=($(CC_DEFS),"VM_VAX=1"$(PCAP_DEFS),"VAX_860=1")
VAX8200_SIMH_LIB = $(SIMH_LIB)
.ENDIF
# Digital Equipment VAX8600 Simulator Definitions.
#
VAX8600_DIR = SYS$DISK:[.VAX]
@ -970,8 +1002,8 @@ I7094_OPTIONS = /INCL=($(SIMH_DIR),$(I7094_DIR))/DEF=($(CC_DEFS))
.IFDEF ALPHA_OR_IA64
ALL : ALTAIR ALTAIRZ80 CDC1700 ECLIPSE GRI LGP H316 HP2100 HP3000 I1401 I1620 \
IBM1130 ID16 ID32 NOVA PDP1 PDP4 PDP7 PDP8 PDP9 PDP10 PDP11 PDP15 S3 \
VAX MICROVAX3900 MICROVAX1 RTVAX1000 MICROVAX2 VAX730 VAX750 VAX780 VAX8600 \
SDS I7094 SWTP6800MP-A SWTP6800MP-A2 SSEM BESM6 B5500
VAX MICROVAX3900 MICROVAX1 RTVAX1000 MICROVAX2 VAX730 VAX750 VAX780 \
VAX8200 VAX8600 SDS I7094 SWTP6800MP-A SWTP6800MP-A2 SSEM BESM6 B5500
$! No further actions necessary
.ELSE
#
@ -979,8 +1011,8 @@ ALL : ALTAIR ALTAIRZ80 CDC1700 ECLIPSE GRI LGP H316 HP2100 HP3000 I1401 I1620 \
#
ALL : ALTAIR GRI H316 HP2100 I1401 I1620 IBM1130 ID16 ID32 \
NOVA PDP1 PDP4 PDP7 PDP8 PDP9 PDP11 PDP15 S3 \
VAX MICROVAX3900 MICROVAX1 RTVAX1000 MICROVAX2 VAX730 VAX750 VAX780 VAX8600 \
SDS SWTP6800MP-A SWTP6800MP-A2 SSEM
VAX MICROVAX3900 MICROVAX1 RTVAX1000 MICROVAX2 VAX730 VAX750 VAX780 \
VAX8200 VAX8600 SDS SWTP6800MP-A SWTP6800MP-A2 SSEM
$! No further actions necessary
.ENDIF
@ -1668,6 +1700,28 @@ $(VAX780_LIB2) : $(VAX780_SOURCE2)
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
$(VAX8200_LIB1) : $(VAX8200_SOURCE1)
$!
$! Building The $(VAX8200_LIB1) Library.
$!
$ $(CC)$(VAX8200_OPTIONS)/OBJ=$(VAX8200_DIR) -
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
LIBRARY/CREATE $(MMS$TARGET)
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
$(VAX8200_LIB2) : $(VAX8200_SOURCE2)
$!
$! Building The $(VAX8200_LIB2) Library.
$!
$ $(CC)$(VAX8200_OPTIONS)/OBJ=$(VAX8200_DIR) -
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
LIBRARY/CREATE $(MMS$TARGET)
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
$(VAX8600_LIB1) : $(VAX8600_SOURCE1)
$!
$! Building The $(VAX8600_LIB1) Library.
@ -2307,6 +2361,21 @@ $(BIN_DIR)VAX780-$(ARCH).EXE : $(SIMH_MAIN) $(VAX780_SIMH_LIB) $(PCAP_LIBD) $(VA
$(VAX780_SIMH_LIB)/LIBRARY$(PCAP_LIBR)
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
VAX8200 : $(BIN_DIR)VAX8200-$(ARCH).EXE
$! VAX8200 done
$(BIN_DIR)VAX8200-$(ARCH).EXE : $(SIMH_MAIN) $(VAX8200_SIMH_LIB) $(PCAP_LIBD) $(VAX8200_LIB1) $(VAX8200_LIB2) $(PCAP_EXECLET)
$!
$! Building The $(BIN_DIR)VAX8200-$(ARCH).EXE Simulator.
$!
$ $(CC)$(VAX8200_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
$ LINK $(LINK_DEBUG)$(LINK_SECTION_BINDING)-
/EXE=$(BIN_DIR)VAX8200-$(ARCH).EXE -
$(BLD_DIR)SCP.OBJ,-
$(VAX8200_LIB1)/LIBRARY,$(VAX8200_LIB2)/LIBRARY,-
$(VAX8200_SIMH_LIB)/LIBRARY$(PCAP_LIBR)
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
VAX8600 : $(BIN_DIR)VAX8600-$(ARCH).EXE
$! VAX8600 done

View file

@ -1382,6 +1382,21 @@ VAX780 = ${VAXD}/vax_cpu.c ${VAXD}/vax_cpu1.c ${VAXD}/vax_fpa.c \
VAX780_OPT = -DVM_VAX -DVAX_780 -DUSE_INT64 -DUSE_ADDR64 -I VAX -I ${PDP11D} ${NETWORK_OPT}
VAX8200 = ${VAXD}/vax_cpu.c ${VAXD}/vax_cpu1.c ${VAXD}/vax_fpa.c \
${VAXD}/vax_cis.c ${VAXD}/vax_octa.c ${VAXD}/vax_cmode.c \
${VAXD}/vax_mmu.c ${VAXD}/vax_sys.c ${VAXD}/vax_syscm.c \
${VAXD}/vax_watch.c ${VAXD}/vax820_stddev.c ${VAXD}/vax820_bi.c \
${VAXD}/vax820_mem.c ${VAXD}/vax820_uba.c ${VAXD}/vax820_ka.c \
${VAXD}/vax820_syslist.c \
${PDP11D}/pdp11_rl.c ${PDP11D}/pdp11_rq.c ${PDP11D}/pdp11_ts.c \
${PDP11D}/pdp11_dz.c ${PDP11D}/pdp11_lp.c ${PDP11D}/pdp11_tq.c \
${PDP11D}/pdp11_xu.c ${PDP11D}/pdp11_ry.c ${PDP11D}/pdp11_cr.c \
${PDP11D}/pdp11_hk.c ${PDP11D}/pdp11_vh.c ${PDP11D}/pdp11_dmc.c \
${PDP11D}/pdp11_td.c ${PDP11D}/pdp11_tc.c ${PDP11D}/pdp11_rk.c \
${PDP11D}/pdp11_io_lib.c ${PDP11D}/pdp11_ch.c
VAX8200_OPT = -DVM_VAX -DVAX_820 -DUSE_INT64 -DUSE_ADDR64 -I VAX -I ${PDP11D} ${NETWORK_OPT}
VAX8600 = ${VAXD}/vax_cpu.c ${VAXD}/vax_cpu1.c ${VAXD}/vax_fpa.c \
${VAXD}/vax_cis.c ${VAXD}/vax_octa.c ${VAXD}/vax_cmode.c \
${VAXD}/vax_mmu.c ${VAXD}/vax_sys.c ${VAXD}/vax_syscm.c \
@ -1849,7 +1864,8 @@ ATT3B2_OPT = -DUSE_INT64 -DUSE_ADDR64 -I ${ATT3B2D} ${NETWORK_OPT}
# Build everything (not the unsupported/incomplete or experimental simulators)
#
ALL = pdp1 pdp4 pdp7 pdp8 pdp9 pdp15 pdp11 pdp10 \
vax microvax3900 microvax1 rtvax1000 microvax2 vax730 vax750 vax780 vax8600 \
vax microvax3900 microvax1 rtvax1000 microvax2 vax730 vax750 vax780 \
vax8200 vax8600 \
nova eclipse hp2100 hp3000 i1401 i1620 s3 altair altairz80 gri \
i7094 ibm1130 id16 id32 sds lgp h316 cdc1700 \
swtp6800mp-a swtp6800mp-a2 tx-0 ssem b5500 isys8010 isys8020 \
@ -2042,6 +2058,15 @@ ifneq (,$(call find_test,$(VAXD),vax-diag))
$@ $(call find_test,$(VAXD),vax-diag) $(TEST_ARG)
endif
vax8200 : ${BIN}vax8200${EXE}
${BIN}vax8200${EXE} : ${VAX8200} ${SIM} ${BUILD_ROMS}
${MKDIRBIN}
${CC} ${VAX8200} ${SIM} ${VAX8200_OPT} $(CC_OUTSPEC) ${LDFLAGS}
ifneq (,$(call find_test,$(VAXD),vax-diag))
$@ $(call find_test,$(VAXD),vax-diag) $(TEST_ARG)
endif
vax8600 : ${BIN}BuildROMs${EXE} ${BIN}vax8600${EXE}
${BIN}vax8600${EXE} : ${VAX8600} ${SIM} ${BUILD_ROMS}