Merge branch 'Extra-VAXen'

This commit is contained in:
Mark Pizzolato 2012-12-17 03:19:07 -08:00
commit 762aacf7ad
87 changed files with 33869 additions and 8596 deletions

View file

@ -155,7 +155,10 @@ The pdp11_rq.c module has been refactored to leverage the asynch I/O
features of the sim_disk library. The impact to this code to adopt the
asynch I/O paradigm was quite minimal.
The pdp11_rp.c module has also been refactored to leverage the asynch I/O
features of the sim_disk library.
features of the sim_disk library. The impact to this code to adopt the
asynch I/O paradigm was also quite minimal. After conversion a latent
bug in the VAX Massbus adapter implementation was illuminated due to the
more realistic delays to perform I/O operations.
The pdp11_tq.c module has been refactored to leverage the asynch I/O
features of the sim_tape library. The impact to this code to adopt the
asynch I/O paradigm was very significant. This was due to the two facts:

View file

@ -695,7 +695,7 @@ void dp_goc (int32 fnc, int32 drv, int32 time)
{
int32 t;
t = sim_is_active (&dpc_unit[drv]);
t = sim_activate_time (&dpc_unit[drv]);
if (t) { /* still seeking? */
sim_cancel (&dpc_unit[drv]); /* stop seek */
dpc_sta[drv] = dpc_sta[drv] & ~STA_BSY; /* clear busy */

View file

@ -531,7 +531,7 @@ void dq_goc (int32 fnc, int32 drv, int32 time)
{
int32 t;
t = sim_is_active (&dqc_unit[drv]);
t = sim_activate_time (&dqc_unit[drv]);
if (t) { /* still seeking? */
sim_cancel (&dqc_unit[drv]); /* cancel */

View file

@ -1021,7 +1021,7 @@ int32 sync_poll (POLLMODE poll_mode)
int32 poll_time;
if (poll_mode == INITIAL) {
poll_time = sim_is_active (&tty_unit[TTI]);
poll_time = sim_activate_time (&tty_unit[TTI]);
if (poll_time)
return poll_time;

View file

@ -772,7 +772,7 @@ else if (uptr) { /* otherwise, we have a
uptr->wait = cvptr->cmd_time; /* most commands use the command delay */
if (props->unit_access) { /* does the command access the unit? */
is_seeking = sim_is_active (uptr) != 0; /* see if the unit is busy */
is_seeking = sim_activate_time (uptr) != 0; /* see if the unit is busy */
if (is_seeking) /* if a seek is in progress, */
uptr->wait = 0; /* set for no unit activation */

View file

@ -95,6 +95,7 @@ DEVICE console_dev = {
extern char *read_line (char *cptr, int size, FILE *stream);
extern FILE *sim_log;
extern DEVICE *find_unit (char *cptr, UNIT **uptr);
extern char *sim_prompt;
extern UNIT cr_unit; /* pointers to 1442 and 1132 (1403) printers */
extern UNIT prt_unit;
@ -1648,8 +1649,8 @@ void remark_cmd (char *remark)
if (sim_log) fprintf(sim_log, "%s\n", remark);
if (scp_reading) {
printf("sim> ");
if (sim_log) fprintf(sim_log, "sim> ");
printf("%s", sim_prompt);
if (sim_log) fprintf(sim_log, "%s", sim_prompt);
}
}

View file

@ -358,7 +358,7 @@ int32 lfc_cosched (int32 wait)
{
int32 t;
t = sim_is_active (&lfc_unit);
t = sim_activate_time (&lfc_unit);
return (t? t - 1: wait);
}

View file

@ -89,7 +89,7 @@ int32 used, incr;
if (clk_dev.flags & DEV_DIS) /* disabled? */
return (stop_inst << IOT_V_REASON) | dat; /* illegal inst */
used = tmxr_poll - (sim_is_active (&clk_unit) - 1);
used = tmxr_poll - (sim_activate_time (&clk_unit) - 1);
incr = (used * CLK_CNTS) / tmxr_poll;
return clk_cntr + incr;
}

View file

@ -1155,6 +1155,7 @@ return SCPE_OK;
t_stat rp_detach (UNIT *uptr)
{
int32 drv;
extern int32 sim_is_running;
if (!(uptr->flags & UNIT_ATT)) /* attached? */
return SCPE_OK;
@ -1167,7 +1168,8 @@ if (sim_is_active (uptr)) { /* unit active? */
if (uptr->FUNC >= FNC_WCHK) /* data transfer? */
rpcs1 = rpcs1 | CS1_DONE | CS1_TRE; /* set done, err */
}
update_rpcs (CS1_SC, drv); /* request intr */
if (!sim_is_running) /* from console? */
update_rpcs (CS1_SC, drv); /* request intr */
return detach_unit (uptr);
}

View file

@ -154,7 +154,7 @@ tempbase[1] = tim_base[1];
if (tim_mult != TIM_MULT_T20) { /* interpolate? */
int32 used;
d10 incr;
used = tmr_poll - (sim_is_active (&tim_unit) - 1);
used = tmr_poll - (sim_activate_time (&tim_unit) - 1);
incr = (d10) (((double) used * TIM_HW_FREQ) /
((double) tmr_poll * (double) clk_tps));
tim_incr_base (tempbase, incr);
@ -219,7 +219,7 @@ int32 t;
if (tim_mult == TIM_MULT_T20)
return wait;
t = sim_is_active (&tim_unit);
t = sim_activate_time (&tim_unit);
return (t? t - 1: wait);
}

View file

@ -1015,7 +1015,7 @@ return;
void update_tucs (int32 flag, int32 drv)
{
int32 act = sim_is_active (&tu_unit[drv]);
int32 act = sim_activate_time (&tu_unit[drv]);
if ((flag & ~tucs1) & CS1_DONE) /* DONE 0 to 1? */
tuiff = (tucs1 & CS1_IE)? 1: 0; /* CSTB INTR <- IE */

View file

@ -84,6 +84,11 @@ extern int32 int_req[IPL_HLVL];
#if !defined (DZ_LINES)
#define DZ_LINES 8
#endif
#define MAX_DZ_MUXES 32
#if DZ_MUXES > MAX_DZ_MUXES
#error "Too many DZ multiplexers"
#endif
#define DZ_MNOMASK (DZ_MUXES - 1) /* mask for mux no */
#define DZ_LNOMASK (DZ_LINES - 1) /* mask for lineno */
@ -146,19 +151,19 @@ extern int32 sim_switches;
extern FILE *sim_log;
extern int32 tmxr_poll; /* calibrated delay */
uint16 dz_csr[DZ_MUXES] = { 0 }; /* csr */
uint16 dz_rbuf[DZ_MUXES] = { 0 }; /* rcv buffer */
uint16 dz_lpr[DZ_MUXES] = { 0 }; /* line param */
uint16 dz_tcr[DZ_MUXES] = { 0 }; /* xmit control */
uint16 dz_msr[DZ_MUXES] = { 0 }; /* modem status */
uint16 dz_tdr[DZ_MUXES] = { 0 }; /* xmit data */
uint8 dz_sae[DZ_MUXES] = { 0 }; /* silo alarm enabled */
uint16 dz_csr[MAX_DZ_MUXES] = { 0 }; /* csr */
uint16 dz_rbuf[MAX_DZ_MUXES] = { 0 }; /* rcv buffer */
uint16 dz_lpr[MAX_DZ_MUXES] = { 0 }; /* line param */
uint16 dz_tcr[MAX_DZ_MUXES] = { 0 }; /* xmit control */
uint16 dz_msr[MAX_DZ_MUXES] = { 0 }; /* modem status */
uint16 dz_tdr[MAX_DZ_MUXES] = { 0 }; /* xmit data */
uint8 dz_sae[MAX_DZ_MUXES] = { 0 }; /* silo alarm enabled */
uint32 dz_rxi = 0; /* rcv interrupts */
uint32 dz_txi = 0; /* xmt interrupts */
int32 dz_mctl = 0; /* modem ctrl enabled */
int32 dz_auto = 0; /* autodiscon enabled */
TMLN dz_ldsc[DZ_MUXES * DZ_LINES] = { {0} }; /* line descriptors */
TMXR dz_desc = { DZ_MUXES * DZ_LINES, 0, 0, dz_ldsc }; /* mux descriptor */
TMLN *dz_ldsc = NULL; /* line descriptors */
TMXR dz_desc = { DZ_MUXES * DZ_LINES, 0, 0, NULL }; /* mux descriptor */
/* debugging bitmaps */
#define DBG_REG 0x0001 /* trace read/write registers */
@ -211,15 +216,15 @@ DIB dz_dib = {
UNIT dz_unit = { UDATA (&dz_svc, UNIT_IDLE|UNIT_ATTABLE|DZ_8B_DFLT, 0) };
REG dz_reg[] = {
{ BRDATA (CSR, dz_csr, DEV_RDX, 16, DZ_MUXES) },
{ BRDATA (RBUF, dz_rbuf, DEV_RDX, 16, DZ_MUXES) },
{ BRDATA (LPR, dz_lpr, DEV_RDX, 16, DZ_MUXES) },
{ BRDATA (TCR, dz_tcr, DEV_RDX, 16, DZ_MUXES) },
{ BRDATA (MSR, dz_msr, DEV_RDX, 16, DZ_MUXES) },
{ BRDATA (TDR, dz_tdr, DEV_RDX, 16, DZ_MUXES) },
{ BRDATA (SAENB, dz_sae, DEV_RDX, 1, DZ_MUXES) },
{ GRDATA (RXINT, dz_rxi, DEV_RDX, DZ_MUXES, 0) },
{ GRDATA (TXINT, dz_txi, DEV_RDX, DZ_MUXES, 0) },
{ BRDATA (CSR, dz_csr, DEV_RDX, 16, MAX_DZ_MUXES) },
{ BRDATA (RBUF, dz_rbuf, DEV_RDX, 16, MAX_DZ_MUXES) },
{ BRDATA (LPR, dz_lpr, DEV_RDX, 16, MAX_DZ_MUXES) },
{ BRDATA (TCR, dz_tcr, DEV_RDX, 16, MAX_DZ_MUXES) },
{ BRDATA (MSR, dz_msr, DEV_RDX, 16, MAX_DZ_MUXES) },
{ BRDATA (TDR, dz_tdr, DEV_RDX, 16, MAX_DZ_MUXES) },
{ BRDATA (SAENB, dz_sae, DEV_RDX, 1, MAX_DZ_MUXES) },
{ GRDATA (RXINT, dz_rxi, DEV_RDX, MAX_DZ_MUXES, 0) },
{ GRDATA (TXINT, dz_txi, DEV_RDX, MAX_DZ_MUXES, 0) },
{ FLDATA (MDMCTL, dz_mctl, 0) },
{ FLDATA (AUTODS, dz_auto, 0) },
{ GRDATA (DEVADDR, dz_dib.ba, DEV_RDX, 32, 0), REG_HRO },
@ -421,7 +426,7 @@ t_stat dz_svc (UNIT *uptr)
{
int32 dz, t, newln;
for (dz = t = 0; dz < DZ_MUXES; dz++) /* check enabled */
for (dz = t = 0; dz < dz_desc.lines/DZ_LINES; dz++) /* check enabled */
t = t | (dz_csr[dz] & CSR_MSE);
if (t) { /* any enabled? */
newln = tmxr_poll_conn (&dz_desc); /* poll connect */
@ -461,10 +466,10 @@ return c;
void dz_update_rcvi (void)
{
int32 i, dz, line, scnt[DZ_MUXES];
int32 i, dz, line, scnt[MAX_DZ_MUXES];
TMLN *lp;
for (dz = 0; dz < DZ_MUXES; dz++) { /* loop thru muxes */
for (dz = 0; dz < dz_desc.lines/DZ_LINES; dz++) { /* loop thru muxes */
scnt[dz] = 0; /* clr input count */
for (i = 0; i < DZ_LINES; i++) { /* poll lines */
line = (dz * DZ_LINES) + i; /* get line num */
@ -474,7 +479,7 @@ for (dz = 0; dz < DZ_MUXES; dz++) { /* loop thru muxes */
dz_msr[dz] &= ~(1 << (i + MSR_V_CD)); /* reset car det */
}
}
for (dz = 0; dz < DZ_MUXES; dz++) { /* loop thru muxes */
for (dz = 0; dz < dz_desc.lines/DZ_LINES; dz++) { /* loop thru muxes */
if (scnt[dz] && (dz_csr[dz] & CSR_MSE)) { /* input & enabled? */
dz_csr[dz] |= CSR_RDONE; /* set done */
if (dz_sae[dz] && (scnt[dz] >= DZ_SILO_ALM)) { /* alm enb & cnt hi? */
@ -498,7 +503,7 @@ void dz_update_xmti (void)
{
int32 dz, linemask, i, j, line;
for (dz = 0; dz < DZ_MUXES; dz++) { /* loop thru muxes */
for (dz = 0; dz < dz_desc.lines/DZ_LINES; dz++) { /* loop thru muxes */
linemask = dz_tcr[dz] & DZ_LMASK; /* enabled lines */
dz_csr[dz] &= ~CSR_TRDY; /* assume not rdy */
j = CSR_GETTL (dz_csr[dz]); /* start at current */
@ -540,7 +545,7 @@ int32 dz_rxinta (void)
{
int32 dz;
for (dz = 0; dz < DZ_MUXES; dz++) { /* find 1st mux */
for (dz = 0; dz < dz_desc.lines/DZ_LINES; dz++) { /* find 1st mux */
if (dz_rxi & (1 << dz)) {
sim_debug(DBG_INT, &dz_dev, "dz_rzinta(dz=%d)\n", dz);
dz_clr_rxint (dz); /* clear intr */
@ -570,7 +575,7 @@ int32 dz_txinta (void)
{
int32 dz;
for (dz = 0; dz < DZ_MUXES; dz++) { /* find 1st mux */
for (dz = 0; dz < dz_desc.lines/DZ_LINES; dz++) { /* find 1st mux */
if (dz_txi & (1 << dz)) {
sim_debug(DBG_INT, &dz_dev, "dz_txinta(dz=%d)\n", dz);
dz_clr_txint (dz); /* clear intr */
@ -609,7 +614,9 @@ t_stat dz_reset (DEVICE *dptr)
{
int32 i, ndev;
for (i = 0; i < DZ_MUXES; i++) /* init muxes */
if (dz_ldsc == NULL)
dz_desc.ldsc = dz_ldsc = calloc (dz_desc.lines, sizeof(*dz_ldsc));
for (i = 0; i < dz_desc.lines/DZ_LINES; i++) /* init muxes */
dz_clear (i, TRUE);
dz_rxi = dz_txi = 0; /* clr master int */
CLR_INT (DZRX);
@ -661,7 +668,7 @@ t_stat r;
if (cptr == NULL)
return SCPE_ARG;
newln = (int32) get_uint (cptr, 10, (DZ_MUXES * DZ_LINES), &r);
newln = (int32) get_uint (cptr, 10, (MAX_DZ_MUXES * DZ_LINES), &r);
if ((r != SCPE_OK) || (newln == dz_desc.lines))
return r;
if ((newln == 0) || (newln % DZ_LINES))
@ -682,8 +689,9 @@ if (newln < dz_desc.lines) {
}
dz_dib.lnt = (newln / DZ_LINES) * IOLN_DZ; /* set length */
dz_desc.lines = newln;
dz_desc.ldsc = dz_ldsc = realloc(dz_ldsc, dz_desc.lines*sizeof(*dz_ldsc));
ndev = ((dz_dev.flags & DEV_DIS)? 0: (dz_desc.lines / DZ_LINES));
return auto_config (dz_dev.name, ndev); /* auto config */
return dz_reset (&dz_dev); /* setup lines and auto config */
}
/* SET LOG processor */
@ -700,7 +708,7 @@ tptr = strchr (cptr, '=');
if ((tptr == NULL) || (*tptr == 0))
return SCPE_ARG;
*tptr++ = 0;
ln = (int32) get_uint (cptr, 10, (DZ_MUXES * DZ_LINES), &r);
ln = (int32) get_uint (cptr, 10, dz_desc.lines, &r);
if ((r != SCPE_OK) || (ln >= dz_desc.lines))
return SCPE_ARG;
return tmxr_set_log (NULL, ln, tptr, desc);
@ -715,7 +723,7 @@ int32 ln;
if (cptr == NULL)
return SCPE_ARG;
ln = (int32) get_uint (cptr, 10, (DZ_MUXES * DZ_LINES), &r);
ln = (int32) get_uint (cptr, 10, dz_desc.lines, &r);
if ((r != SCPE_OK) || (ln >= dz_desc.lines))
return SCPE_ARG;
return tmxr_set_nolog (NULL, ln, NULL, desc);

View file

@ -25,6 +25,7 @@
hk RK611/RK06/RK07 disk
10-Dec-12 RMS Fixed interrupt logic
19-Mar-12 RMS Fixed declaration of cpu_opt (Mark Pizzolato)
29-Apr-07 RMS NOP and DCLR (at least) do not check drive type
MR2 and MR3 only updated on NOP
@ -136,12 +137,44 @@ extern uint16 *M;
#define GET_UAE(x) (((x) >> CS1_V_UAE) & CS1_M_UAE)
#define PUT_UAE(x,n) (((x) & ~ CS1_UAE) | (((n) << CS1_V_UAE) & CS1_UAE))
static const char *hk_funcs[] = {
"NOP", "PACK", "DCLR", "UNLOAD", "START", "RECAL", "OFFSET", "SEEK",
"READ", "WRITE", "READH", "WRITEH", "WCHK"};
BITFIELD hk_cs1_bits[] = {
BIT(GO), /* go */
BITFNAM(FNC,4,hk_funcs), /* function */
BIT(SPARE), /* Spare Bit */
BIT(IE), /* Interrupt Enable */
BIT(RDY), /* Controller Ready */
BIT(BA16), /* Unibus addr ext bit 16 */
BIT(BA17), /* Unibus addr ext bit 17 */
BIT(DT), /* Controller Drive Type */
BIT(CTO), /* Controller Timeout */
BIT(CFMT), /* Controller Format */
BIT(DTCPAR), /* Drive-To-Controller Parity Error */
BIT(DI), /* Drive Interrupt */
BIT(ERR), /* error */
ENDBITS
};
/* HKWC - 177442 - word count */
BITFIELD hk_wc_bits[] = {
BITF(WC,16), /* Word Count */
ENDBITS
};
/* HKBA - 177444 - base address */
#define BA_MBZ 0000001 /* must be zero */
BITFIELD hk_ba_bits[] = {
BITF(BA,16), /* Bus Address */
ENDBITS
};
/* HKDA - 177446 - sector/track */
#define DA_V_SC 0 /* sector pos */
@ -152,6 +185,14 @@ extern uint16 *M;
#define GET_SC(x) (((x) >> DA_V_SC) & DA_M_SC)
#define GET_SF(x) (((x) >> DA_V_SF) & DA_M_SF)
BITFIELD hk_da_bits[] = {
BITF(SA,5), /* Sector */
BITNCF(3), /* 05:07 Zero */
BITF(TA,3), /* Track */
BITNCF(5), /* 11:15 Zero */
ENDBITS
};
/* HKCS2 - 177450 - control/status 2 */
#define CS2_V_UNIT 0 /* unit pos */
@ -176,6 +217,25 @@ extern uint16 *M;
CS2_NED | CS2_PE | CS2_WCE | CS2_DLT )
#define GET_UNIT(x) (((x) >> CS2_V_UNIT) & CS2_M_UNIT)
BITFIELD hk_cs2_bits[] = {
BITF(DS,3), /* Drive Select */
BIT(RLS), /* Release */
BIT(BAI), /* Bus Address Increment Inhibit */
BIT(SCLR), /* Subsystem Clear */
BIT(IR), /* Input Ready */
BIT(OR), /* Output Ready */
BIT(UFE), /* Unit Field Error */
BIT(MDS), /* Multiple Drive Select */
BIT(PGE), /* Programming Error */
BIT(NEM), /* Nonexistant Memory */
BIT(NED), /* Nonexistant Drive */
BIT(UPE), /* Unibus Parity Error */
BIT(WCE), /* Write Check Error */
BIT(DLT), /* Data Late Error */
ENDBITS
};
/* HKDS - 177452 - drive status ^ = calculated dynamically */
#define DS_DRA 0000001 /* ^drive avail */
@ -192,6 +252,25 @@ extern uint16 *M;
#define DS_VLD 0100000 /* ^status valid */
#define DS_MBZ 0013002
BITFIELD hk_ds_bits[] = {
BIT(DRA), /* Drive Available */
BITNCF(1), /* 01 Spare */
BIT(OFST), /* Offset */
BIT(ACLO), /* Drive AC Low */
BIT(SPLS), /* Speed Loss */
BIT(DROT), /* Drive Off Track */
BIT(VV), /* Volume Valid */
BIT(DRDY), /* Drive Ready */
BIT(DDT), /* Disk Drive Type */
BITNCF(2), /* 09:10 Spare */
BIT(WRL), /* Write Lock */
BITNCF(1), /* 12 Spare */
BIT(PIP), /* Positioning in Progress */
BIT(ATA), /* Current Drive Attention */
BIT(SVAL), /* Status Valid */
ENDBITS
};
/* HKER - 177454 - error status */
#define ER_ILF 0000001 /* illegal func */
@ -211,11 +290,44 @@ extern uint16 *M;
#define ER_UNS 0040000 /* drive unsafe */
#define ER_DCK 0100000 /* data check NI */
BITFIELD hk_er_bits[] = {
BIT(ILF), /* Illegal Function */
BIT(SKI), /* Seek Incomplete */
BIT(NXF), /* Nonexecutable Function */
BIT(DROAR), /* Control-to-Drive Parity Error */
BIT(FMTE), /* Format Error */
BIT(DTYE), /* Drive Type Error */
BIT(ECH), /* Error Correction Hard */
BIT(BSE), /* Bad Sector Error */
BIT(HRVC), /* Header Virtical Redundancy */
BIT(COE), /* Cylinder Overflow Error */
BIT(IDAE), /* Invalid Disk Address Error */
BIT(WLE), /* Write Lock Error */
BIT(DTE), /* Drive Timing Error */
BIT(OPI), /* Operation Incomplete */
BIT(UNS), /* Drive Unsafe */
BIT(DCK), /* Data Check */
ENDBITS
};
/* HKAS - 177456 - attention summary/offset */
#define AS_U0 0000400 /* unit 0 flag */
#define AS_OF 0000277 /* offset mask */
BITFIELD hk_as_bits[] = {
BITF(OF,8), /* Offset */
BIT(ATN0), /* Attention Drive 0 */
BIT(ATN1), /* Attention Drive 1 */
BIT(ATN2), /* Attention Drive 2 */
BIT(ATN3), /* Attention Drive 3 */
BIT(ATN4), /* Attention Drive 4 */
BIT(ATN5), /* Attention Drive 5 */
BIT(ATN6), /* Attention Drive 6 */
BIT(ATN7), /* Attention Drive 7 */
ENDBITS
};
/* HKDC - 177460 - desired cylinder */
#define DC_V_CY 0 /* cylinder pos */
@ -225,6 +337,12 @@ extern uint16 *M;
#define GET_DA(c,fs) ((((GET_CY (c) * HK_NUMSF) + \
GET_SF (fs)) * HK_NUMSC) + GET_SC (fs))
BITFIELD hk_dc_bits[] = {
BITF(DC,10), /* Desired Cylinder */
BITNCF(6), /* 10:15 Spare */
ENDBITS
};
/* Spare - 177462 - read/write */
#define XM_KMASK 0177700 /* Qbus XM key mask */
@ -234,6 +352,11 @@ extern uint16 *M;
/* HKDB - 177464 - read/write */
BITFIELD hk_db_bits[] = {
BITF(DB,16), /* Data Buffer Register */
ENDBITS
};
/* HKMR - 177466 - maintenance register 1 */
#define MR_V_MS 0 /* message select */
@ -244,9 +367,37 @@ extern uint16 *M;
#define MR_DMD 0000040 /* diagnostic mode */
#define MR_RW 0001777
BITFIELD hk_mr_bits[] = {
BITF(MS,4), /* Message Select */
BIT(PAT), /* Parity Test */
BIT(DMD), /* Diagnostic Mode */
BIT(MSP), /* Maintenance Selector Pulse */
BIT(MIND), /* Maintenance Index */
BIT(MCLK), /* Maintenance Clock */
BIT(MERD), /* Maintenance Encoded Read Data */
BIT(MEWD), /* Maintenance Encoded Write Data */
BIT(PCA), /* Precompensation Advance */
BIT(PCD), /* Precompensation Delay */
BIT(ECCW), /* ECC Word */
BIT(WRTGT), /* Write Gate */
BIT(RDGT), /* Read Gate */
ENDBITS
};
/* HKEC1 - 177470 - ECC status 1 - always reads as 0 */
BITFIELD hk_ec1_bits[] = {
BITF(EC1,16), /* ECC status 1 */
ENDBITS
};
/* HKEC2 - 177472 - ECC status 2 - always reads as 0 */
BITFIELD hk_ec2_bits[] = {
BITF(EC2,16), /* ECC status 2 */
ENDBITS
};
/* HKMR2 - 177474 - maintenance register 2 */
#define AX_V_UNIT 0 /* unit #, all msgs */
@ -280,6 +431,11 @@ extern uint16 *M;
#define A3_V_SNO 3 /* serial # */
BITFIELD hk_mr2_bits[] = {
BITF(MR2,16), /* Maintenance Register 2 */
ENDBITS
};
/* HKMR3 - 177476 - maintenance register 3 */
#define B0_IAE 0000040 /* invalid addr */
@ -317,14 +473,58 @@ extern uint16 *M;
#define RDH2_V_DHA 5 /* decoded head */
#define RDH2_GOOD 0140000 /* good sector flags */
BITFIELD hk_mr3_bits[] = {
BITF(MR3,16), /* Maintenance Register 3 */
ENDBITS
};
char *hk_regnames[] = {
"HKCS1",
"HKWC",
"HKBA",
"HKDA",
"HKCS2",
"HKDS",
"HKER",
"HKAS",
"HKDC",
"spare",
"HKDB",
"HKMR",
"HKEC1",
"HKEC2",
"HKMR2",
"HKMR3"
};
BITFIELD *hk_reg_bits[] = {
hk_cs1_bits,
hk_wc_bits,
hk_ba_bits,
hk_da_bits,
hk_cs2_bits,
hk_ds_bits,
hk_er_bits,
hk_as_bits,
hk_dc_bits,
NULL,
hk_db_bits,
hk_mr_bits,
hk_ec1_bits,
hk_ec2_bits,
hk_mr2_bits,
hk_mr3_bits,
};
/* Debug detail levels */
#define HKDEB_OPS 001 /* transactions */
#define HKDEB_RRD 002 /* reg reads */
#define HKDEB_RWR 004 /* reg writes */
#define HKDEB_TRC 010 /* trace */
#define HKDEB_INT 020 /* interrupts */
extern int32 int_req[IPL_HLVL];
extern FILE *sim_deb;
uint16 *hkxb = NULL; /* xfer buffer */
int32 hkcs1 = 0; /* control/status 1 */
@ -464,6 +664,8 @@ DEBTAB hk_deb[] = {
{ "OPS", HKDEB_OPS },
{ "RRD", HKDEB_RRD },
{ "RWR", HKDEB_RWR },
{ "INTERRUPT", HKDEB_INT },
{ "TRACE", HKDEB_TRC },
{ NULL, 0 }
};
@ -563,14 +765,14 @@ switch (j) { /* decode PA<4:1> */
break;
}
if (DEBUG_PRI (hk_dev, HKDEB_RRD))
fprintf (sim_deb, ">>HK%d read: reg%d=%o\n", drv, j, *data);
sim_debug (HKDEB_RRD, &hk_dev, ">>HK%d read: %s=0%o\n", drv, hk_regnames[j], *data);
sim_debug_bits (HKDEB_RRD, &hk_dev, hk_reg_bits[j], *data, *data, 1);
return SCPE_OK;
}
t_stat hk_wr (int32 data, int32 PA, int32 access)
{
int32 drv, i, j;
int32 drv, i, j, old_val, new_val;
UNIT *uptr;
drv = GET_UNIT (hkcs2); /* get current unit */
@ -584,11 +786,11 @@ if ((hkcs1 & CS1_GO) && /* busy? */
return SCPE_OK;
}
if (DEBUG_PRI (hk_dev, HKDEB_RWR))
fprintf (sim_deb, ">>HK%d write: reg%d=%o\n", drv, j, data);
sim_debug (HKDEB_RWR, &hk_dev, ">>HK%d write: %s=0%o\n", drv, hk_regnames[j], data);
switch (j) { /* decode PA<4:1> */
case 000: /* HKCS1 */
old_val = hkcs1;
if (data & CS1_CCLR) { /* controller reset? */
hkcs1 = CS1_DONE; /* CS1 = done */
hkcs2 = CS2_IR; /* CS2 = ready */
@ -599,68 +801,98 @@ switch (j) { /* decode PA<4:1> */
CLR_INT (HK); /* clr int */
for (i = 0; i < HK_NUMDR; i++) { /* stop data xfr */
if (sim_is_active (&hk_unit[i]) &&
((uptr->FNC & CS1_M_FNC) >= FNC_XFER))
((hk_unit[i].FNC & CS1_M_FNC) >= FNC_XFER))
sim_cancel (&hk_unit[i]);
}
drv = 0;
break;
}
if (data & CS1_IE) { /* setting IE? */
if (data & CS1_DONE) /* write to DONE+IE? */
if (data & CS1_DONE) { /* write to DONE+IE? */
sim_debug (HKDEB_INT, &hk_dev, "hk_wr(SET_INT)\n");
SET_INT (HK);
}
}
else {
sim_debug (HKDEB_INT, &hk_dev, "hk_wr(CLR_INT)\n");
CLR_INT (HK); /* no, clr intr */
}
else CLR_INT (HK); /* no, clr intr */
hkcs1 = (hkcs1 & ~CS1_RW) | (data & CS1_RW); /* merge data */
if (SC02C)
hkspr = (hkspr & ~CS1_M_UAE) | GET_UAE (hkcs1);
if ((data & CS1_GO) && !(hkcs1 & CS1_ERR)) /* go? */
hk_go (drv);
new_val = hkcs1;
break;
case 001: /* HKWC */
hkwc = data;
old_val = hkwc;
new_val = hkwc = data;
break;
case 002: /* HKBA */
hkba = data & ~BA_MBZ;
old_val = hkba;
new_val = hkba = data & ~BA_MBZ;
break;
case 003: /* HKDA */
hkda = data & ~DA_MBZ;
old_val = hkda;
new_val = hkda = data & ~DA_MBZ;
break;
case 004: /* HKCS2 */
old_val = hkcs2;
if (data & CS2_CLR) /* init? */
hk_reset (&hk_dev);
else hkcs2 = (hkcs2 & ~CS2_RW) | (data & CS2_RW) | CS2_IR;
drv = GET_UNIT (hkcs2);
new_val = hkcs2;
break;
case 007: /* HKAS */
hkof = data & AS_OF;
old_val = hkof;
new_val = hkof = data & AS_OF;
break;
case 010: /* HKDC */
hkdc = data & ~DC_MBZ;
old_val = hkdc;
new_val = hkdc = data & ~DC_MBZ;
break;
case 011: /* spare */
hkspr = data;
old_val = hkspr;
new_val = hkspr = data;
if (SC02C) /* SC02C? upd UAE */
hkcs1 = PUT_UAE (hkcs1, hkspr & 03);
break;
case 012: /* HKDB */
hkdb[0] = data;
old_val = hkdb[0];
new_val = hkdb[0] = data;
break;
case 013: /* HKMR */
hkmr = data & MR_RW;
old_val = hkmr;
new_val = hkmr = data & MR_RW;
break;
default: /* all others RO */
case 014: /* HKEC1 */
new_val = old_val = hkmr;
break;
case 015: /* HKEC2 */
new_val = old_val = hkmr;
break;
case 016: /* HKMR2 */
new_val = old_val = hkmr2;
break;
case 017: /* HKMR3 */
new_val = old_val = hkmr3;
break;
} /* end switch */
sim_debug_bits (HKDEB_RWR, &hk_dev, hk_reg_bits[j], old_val, new_val, 1);
update_hkcs (0, drv); /* update status */
return SCPE_OK;
@ -691,9 +923,8 @@ static uint8 fnc_cyl[16] = {
};
fnc = GET_FNC (hkcs1);
if (DEBUG_PRI (hk_dev, HKDEB_OPS))
fprintf (sim_deb, ">>HK%d strt: fnc=%o, cs1=%o, cs2=%o, ds=%o, er=%o, cyl=%o, da=%o, ba=%o, wc=%o\n",
drv, fnc, hkcs1, hkcs2, hkds[drv], hker[drv], hkdc, hkda, hkba, hkwc);
sim_debug (HKDEB_OPS, &hk_dev, ">>HK%d strt: fnc=%s, cs1=%o, cs2=%o, ds=%o, er=%o, cyl=%o, da=%o, ba=%o, wc=%o\n",
drv, hk_funcs[fnc], hkcs1, hkcs2, hkds[drv], hker[drv], hkdc, hkda, hkba, hkwc);
uptr = hk_dev.units + drv; /* get unit */
if (fnc != FNC_NOP) /* !nop, clr msg sel */
hkmr = hkmr & ~MR_MS;
@ -730,7 +961,7 @@ switch (fnc) { /* case on function */
/* Instantaneous functions (unit may be busy, can't schedule thread) */
case FNC_NOP: /* no operation */
case FNC_NOP: /* no operation/select drive */
hkmr2 = hk_rdmr2 (GET_MS (hkmr)); /* get serial msgs */
hkmr3 = hk_rdmr3 (GET_MS (hkmr));
update_hkcs (CS1_DONE, drv); /* done */
@ -804,6 +1035,7 @@ uint16 comp;
drv = (uint32) (uptr - hk_dev.units); /* get drv number */
fnc = uptr->FNC & CS1_M_FNC; /* get function */
sim_debug (HKDEB_TRC, &hk_dev, "hk_svc(HK%d, fnc=%s)\n", drv, hk_funcs[fnc]);
switch (fnc) { /* case on function */
/* Fast commands - start spindle only provides one interrupt
@ -985,27 +1217,37 @@ return SCPE_OK;
void update_hkcs (int32 flag, int32 drv)
{
int32 i;
int32 i, old_hkcs1 = hkcs1, old_hkcs2 = hkcs2;
sim_debug (HKDEB_TRC, &hk_dev, "update_hkcs(flag=0%o, drv=%d)\n", flag, drv);
update_hkds (drv); /* upd drv status */
if (flag & CS1_DONE) /* clear go */
hkcs1 = hkcs1 & ~CS1_GO;
if (hkcs1 & CS1_IE) { /* intr enable? */
if (((flag & CS1_DONE) && ((hkcs1 & CS1_DONE) == 0)) ||
((flag & CS1_DI) && (hkcs1 & CS1_DONE))) /* done 0->1 or DI? */
SET_INT (HK);
}
else CLR_INT (HK);
hkcs1 = (hkcs1 & (CS1_DT|CS1_UAE|CS1_DONE|CS1_IE|CS1_SPA|CS1_FNC|CS1_GO)) | flag;
if (hkcs1 & CS1_DONE) /* done? clear GO */
hkcs1 = hkcs1 & ~CS1_GO;
for (i = 0; i < HK_NUMDR; i++) { /* if ATA, set DI */
if (hkds[i] & DS_ATA) hkcs1 = hkcs1 | CS1_DI;
if (hkds[i] & DS_ATA)
hkcs1 = hkcs1 | CS1_DI;
}
if (hker[drv] | (hkcs1 & (CS1_PAR | CS1_CTO)) | /* if err, set ERR */
(hkcs2 & CS2_ERR)) hkcs1 = hkcs1 | CS1_ERR;
if ((flag & CS1_DONE) && /* set done && debug? */
(DEBUG_PRI (hk_dev, HKDEB_OPS)))
fprintf (sim_deb, ">>HK%d done: fnc=%o, cs1=%o, cs2=%o, ds=%o, er=%o, cyl=%o, da=%o, ba=%o, wc=%o\n",
drv, GET_FNC (hkcs1), hkcs1, hkcs2, hkds[drv], hker[drv], hkdc, hkda, hkba, hkwc);
if (hker[drv] || (hkcs1 & (CS1_PAR | CS1_CTO)) || (hkcs2 & CS2_ERR))
hkcs1 = hkcs1 | CS1_ERR; /* if err, set ERR */
if (hkcs1 & CS1_IE) { /* intr enable? */
if (((hkcs1 & CS1_DONE) && ((old_hkcs1 & CS1_DONE) == 0)) ||
((hkcs1 & CS1_DI) && (hkcs1 & CS1_DONE))) { /* done 0->1 or DI&done? */
sim_debug (HKDEB_INT, &hk_dev, "update_hkcs(SET_INT)\n");
SET_INT (HK);
}
}
else {
sim_debug (HKDEB_INT, &hk_dev, "update_hkcs(CLR_INT)\n");
CLR_INT (HK);
}
if (old_hkcs1 != hkcs1)
sim_debug_bits (HKDEB_OPS, &hk_dev, hk_cs1_bits, old_hkcs1, hkcs1, 1);
if (old_hkcs2 != hkcs2)
sim_debug_bits (HKDEB_OPS, &hk_dev, hk_cs2_bits, old_hkcs2, hkcs2, 1);
if (flag & CS1_DONE) /* set done */
sim_debug (HKDEB_OPS, &hk_dev, ">>HK%d done: fnc=%s, cs1=%o, cs2=%o, ds=%o, er=%o, cyl=%o, da=%o, ba=%o, wc=%o\n",
drv, hk_funcs[GET_FNC (hkcs1)], hkcs1, hkcs2, hkds[drv], hker[drv], hkdc, hkda, hkba, hkwc);
return;
}
@ -1013,10 +1255,13 @@ return;
void update_hkds (int32 drv)
{
int old_ds = hkds[drv];
if (hk_unit[drv].flags & UNIT_DIS) { /* disabled? */
hkds[drv] = hker[drv] = 0; /* all clear */
return;
}
sim_debug (HKDEB_TRC, &hk_dev, "update_hkds(drv=%d)\n", drv);
hkds[drv] = (hkds[drv] & (DS_VV | DS_PIP | DS_ATA)) | DS_VLD | DS_DRA;
if (hk_unit[drv].flags & UNIT_ATT) { /* attached? */
if (!sim_is_active (&hk_unit[drv])) /* not busy? */
@ -1034,6 +1279,8 @@ else {
}
if (hk_unit[drv].flags & UNIT_RK07)
hkds[drv] = hkds[drv] | DS_DT;
if (old_ds != hkds[drv])
sim_debug_bits (HKDEB_TRC, &hk_dev, hk_ds_bits, old_ds, hkds[drv], 1);
return;
}
@ -1041,6 +1288,7 @@ return;
void hk_cmderr (int32 err, int32 drv)
{
sim_debug (HKDEB_TRC, &hk_dev, "update_hkds(drv=%d, err=%d)\n", drv, err);
hker[drv] = hker[drv] | err; /* set error */
hkds[drv] = hkds[drv] | DS_ATA; /* set attn */
update_hkcs (CS1_DONE, drv); /* set done */
@ -1158,6 +1406,7 @@ t_stat hk_reset (DEVICE *dptr)
int32 i;
UNIT *uptr;
sim_debug (HKDEB_TRC, &hk_dev, "hk_reset()\n");
hkcs1 = CS1_DONE; /* set done */
hkcs2 = CS2_IR; /* clear state */
hkmr = hkmr2 = hkmr3 = 0;

View file

@ -24,6 +24,7 @@
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
24-Oct-12 MB Added working map base address
09-Jan-03 RMS Tape read/write end pkt is longer than disk read/write
20-Sep-02 RMS Merged TMSCP definitions
*/
@ -412,6 +413,8 @@
#define RW_WBAH 21
#define RW_WBLL 22 /* working lbn */
#define RW_WBLH 23
#define RW_WMPL 24 /* working map */
#define RW_WMPH 25
/* Tape specific status */

View file

@ -1093,7 +1093,7 @@ t_stat rl_show_dstate (FILE *st, UNIT *uptr, int32 val, void *desc)
(uptr->STAT & RLDS_WGE) ? '1' : '0',
(uptr->STAT & RLDS_SPE) ? '1' : '0');
if (uptr->flags & UNIT_ATT) {
if ((cnt = sim_is_active (uptr)) != 0)
if ((cnt = sim_activate_time (uptr)) != 0)
fprintf (st, "FNC: %d, %d\n", uptr->FNC, cnt);
else
fputs ("FNC: none\n", st);

View file

@ -131,6 +131,29 @@
#define CS1_DVA 04000 /* drive avail */
#define GET_FNC(x) (((x) >> CS1_V_FNC) & CS1_M_FNC)
static const char *rp_fname[CS1_N_FNC] = {
"NOP", "UNLD", "SEEK", "RECAL", "DCLR", "RLS", "OFFS", "RETN",
"PRESET", "PACK", "12", "13", "SEARCH", "15", "16", "17",
"20", "21", "22", "23", "WRCHK", "25", "26", "27",
"WRITE", "WRHDR", "32", "33", "READ", "RDHDR", "36", "37"
};
BITFIELD rp_cs1_bits[] = {
BIT(GO), /* Go */
BITFNAM(FUNC,5,rp_fname), /* Function Code */
BIT(IE), /* Interrupt Enable */
BIT(RDY), /* Drive Ready */
BIT(A16), /* Bus Address Extension Bit 16 */
BIT(A17), /* Bus Address Extension Bit 17 */
BIT(PSEL), /* Port Select */
BIT(DVA), /* Drive Available */
BITNCF(1), /* 12 Reserved */
BIT(MCPE), /* Massbus Control Parity Error */
BIT(TRE), /* Transfer Error */
BIT(SC), /* Special Condition */
ENDBITS
};
/* RPDS, RMDS - drive status - offset 1 */
#define RP_DS_OF 1
@ -148,6 +171,22 @@
#define DS_ATA 0100000 /* attention active */
#define DS_MBZ 0000076
BITFIELD rp_ds_bits[] = {
BIT(OM), /* offset mode */
BITF(MBZ,5), /* must be zero */
BIT(VV), /* volume valid */
BIT(RDY), /* drive ready */
BIT(DPR), /* drive present */
BIT(PGM), /* programmable NI */
BIT(LST), /* write clk fail NI */
BIT(WRL), /* ECC hard err NI */
BIT(MOL), /* hdr comp err NI */
BIT(PIP), /* hdr CRC err NI */
BIT(ERR), /* addr ovflo err */
BIT(ATA), /* invalid addr err */
ENDBITS
};
/* RPER1, RMER1 - error status 1 - offset 2 */
#define RP_ER1_OF 2
@ -169,17 +208,55 @@
#define ER1_UNS 0040000 /* drive unsafe */
#define ER1_DCK 0100000 /* data check NI */
BITFIELD rp_er1_bits[] = {
BIT(ILF), /* Illegal Function */
BIT(ILR), /* Illegal Register */
BIT(RMR), /* reg mod refused */
BIT(PAR), /* parity err */
BIT(FER), /* format err NI */
BIT(WCF), /* write clk fail NI */
BIT(ECH), /* ECC hard err NI */
BIT(HCE), /* hdr comp err NI */
BIT(HCR), /* hdr CRC err NI */
BIT(AOE), /* addr ovflo err */
BIT(IAE), /* invalid addr err */
BIT(WLE), /* write lock err */
BIT(DTE), /* drive time err NI */
BIT(OPI), /* op incomplete */
BIT(UNS), /* drive unsafe */
BIT(DCK), /* data check NI */
ENDBITS
};
/* RPMR, RMMR - maintenace register - offset 3*/
#define RP_MR_OF 3
#define RM_MR_OF (3 + RM_OF)
BITFIELD rp_mr_bits[] = {
BITF(MR,16), /* Maintenance Register */
ENDBITS
};
/* RPAS, RMAS - attention summary - offset 4 */
#define RP_AS_OF 4
#define RM_AS_OF (4 + RM_OF)
#define AS_U0 0000001 /* unit 0 flag */
BITFIELD rp_as_bits[] = {
BIT(ATA0), /* Drive 0 Attention */
BIT(ATA1), /* Drive 1 Attention */
BIT(ATA2), /* Drive 2 Attention */
BIT(ATA3), /* Drive 3 Attention */
BIT(ATA4), /* Drive 4 Attention */
BIT(ATA5), /* Drive 5 Attention */
BIT(ATA6), /* Drive 6 Attention */
BIT(ATA7), /* Drive 7 Attention */
BITNCF(8), /* 08:15 Reserved */
ENDBITS
};
/* RPDA, RMDA - sector/track - offset 5 */
#define RP_DA_OF 5
@ -192,22 +269,52 @@
#define GET_SC(x) (((x) >> DA_V_SC) & DA_M_SC)
#define GET_SF(x) (((x) >> DA_V_SF) & DA_M_SF)
BITFIELD rp_da_bits[] = {
BITF(SA,5), /* Sector Address */
BITNCF(3), /* 05:07 Reserved */
BITF(TA,5), /* Track Address */
BITNCF(3), /* 13:15 Reserved */
ENDBITS
};
/* RPDT, RMDT - drive type - offset 6 */
#define RP_DT_OF 6
#define RM_DT_OF (6 + RM_OF)
BITFIELD rp_dt_bits[] = {
BITF(DT,9), /* Drive Type */
BITNCF(2), /* 09:10 Reserved */
BIT(DRQ), /* Drive Request Required */
BITNCF(1), /* 12 Reserved */
BIT(MOH), /* Moving Head */
BITNCF(2), /* 14:15 Reserved */
ENDBITS
};
/* RPLA, RMLA - look ahead register - offset 7 */
#define RP_LA_OF 7
#define RM_LA_OF (7 + RM_OF)
#define LA_V_SC 6 /* sector pos */
BITFIELD rp_la_bits[] = {
BITNCF(6), /* 00:05 Reserved */
BITF(SC,5), /* sector pos */
BITNCF(5), /* 12:15 Reserved */
ENDBITS
};
/* RPSN, RMSN - serial number - offset 8 */
#define RP_SN_OF 8
#define RM_SN_OF (8 + RM_OF)
BITFIELD rp_sn_bits[] = {
BITF(SN,16), /* Serial Number */
ENDBITS
};
/* RPOF, RMOF - offset register - offset 9 */
#define RP_OF_OF 9
@ -217,6 +324,17 @@
#define OF_F22 0010000 /* format NI */
#define OF_MBZ 0161400
BITFIELD rp_of_bits[] = {
BITNCF(7), /* 00:06 Reserved */
BIT(OFFDIR), /* Offset Direction */
BITNCF(2), /* 08:09 Reserved */
BIT(HCI), /* hdr comp inh NI */
BIT(ECI), /* ECC inh NI */
BIT(FMT), /* format NI */
BITNCF(3), /* 13:15 Reserved */
ENDBITS
};
/* RPDC, RMDC - desired cylinder - offset 10 */
#define RP_DC_OF 10
@ -228,34 +346,125 @@
#define GET_DA(c,fs,d) ((((GET_CY (c) * drv_tab[d].surf) + \
GET_SF (fs)) * drv_tab[d].sect) + GET_SC (fs))
BITFIELD rp_dc_bits[] = {
BITF(DC,10), /* Offset Direction */
BITNCF(6), /* 10:15 Unused */
ENDBITS
};
/* RPCC - current cylinder - offset 11
RMHR - holding register - offset 11 */
#define RP_CC_OF 11
#define RM_HR_OF (11 + RM_OF)
BITFIELD rp_cc_bits[] = {
BITF(CC,16), /* current cylinder */
ENDBITS
};
/* RPER2 - error status 2 - drive unsafe conditions - unimplemented - offset 12
RMMR2 - maintenance register - unimplemented - offset 12 */
#define RP_ER2_OF 12
#define RM_MR2_OF (12 + RM_OF)
BITFIELD rp_er2_bits[] = {
BITNCF(3), /* 00:02 Unused */
BIT(DPE), /* data parity error */
BITNCF(3), /* 04:06 Unused */
BIT(DVC), /* device check */
BITNCF(2), /* 08:09 Unused */
BIT(LBC), /* Loss of bit clock */
BIT(LSC), /* Loss of system clock */
BIT(IVC), /* Invalid Command */
BIT(OPE), /* Operator Plug Error */
BIT(SKI), /* Seek Incomplete */
BIT(BSE), /* Bad Sector Error */
ENDBITS
};
/* RPER3 - error status 3 - more unsafe conditions - unimplemented - offset 13
RMER2 - error status 2 - unimplemented - offset 13 */
#define RP_ER3_OF 13
#define RM_ER2_OF (13 + RM_OF)
BITFIELD rp_er3_bits[] = {
BITNCF(3), /* 00:02 Unused */
BIT(DPE), /* data parity error */
BITNCF(3), /* 04:06 Unused */
BIT(DVC), /* device check */
BITNCF(2), /* 08:09 Unused */
BIT(LBC), /* Loss of bit clock */
BIT(LSC), /* Loss of system clock */
BIT(IVC), /* Invalid Command */
BIT(OPE), /* Operator Plug Error */
BIT(SKI), /* Seek Incomplete */
BIT(BSE), /* Bad Sector Error */
ENDBITS
};
/* RPEC1, RMEC1 - ECC status 1 - unimplemented - offset 14 */
#define RP_EC1_OF 14
#define RM_EC1_OF (14 + RM_OF)
BITFIELD rp_ec1_bits[] = {
BITF(P,13), /* ECC Position Register */
BITNCF(3), /* 13:15 Unused */
ENDBITS
};
/* RPEC2, RMEC1 - ECC status 2 - unimplemented - offset 15 */
#define RP_EC2_OF 15
#define RM_EC2_OF (15 + RM_OF)
BITFIELD rp_ec2_bits[] = {
BITF(PAT,11), /* ECC Pattern Register */
BITNCF(5), /* 11:15 Unused */
ENDBITS
};
BITFIELD *rp_reg_bits[] = {
rp_cs1_bits,
rp_ds_bits,
rp_er1_bits,
rp_mr_bits,
rp_as_bits,
rp_da_bits,
rp_dt_bits,
rp_la_bits,
rp_sn_bits,
rp_of_bits,
rp_dc_bits,
rp_cc_bits,
rp_er2_bits,
rp_er3_bits,
rp_ec1_bits,
rp_ec2_bits,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
rp_cs1_bits,
rp_ds_bits,
rp_er1_bits,
rp_mr_bits,
rp_as_bits,
rp_da_bits,
rp_dt_bits,
rp_la_bits,
rp_sn_bits,
rp_of_bits,
rp_dc_bits,
rp_cc_bits,
rp_er2_bits,
rp_er3_bits,
rp_ec1_bits,
rp_ec2_bits,
};
/* This controller supports many different disk drive types:
type #sectors/ #surfaces/ #cylinders/
@ -357,14 +566,6 @@ uint16 rpec2[RP_NUMDR] = { 0 }; /* ECC correction 2 */
int32 rp_stopioe = 1; /* stop on error */
int32 rp_swait = 26; /* seek time */
int32 rp_rwait = 10; /* rotate time */
static const char *rp_fname[CS1_N_FNC] = {
"NOP", "UNLD", "SEEK", "RECAL", "DCLR", "RLS", "OFFS", "RETN",
"PRESET", "PACK", "12", "13", "SCH", "15", "16", "17",
"20", "21", "22", "23", "WRCHK", "25", "26", "27",
"WRITE", "WRHDR", "32", "33", "READ", "RDHDR", "36", "37"
};
extern FILE *sim_deb;
t_stat rp_mbrd (int32 *data, int32 ofs, int32 drv);
t_stat rp_mbwr (int32 data, int32 ofs, int32 drv);
@ -479,12 +680,97 @@ MTAB rp_mod[] = {
{ 0 }
};
/* debugging bitmaps */
#define DBG_TRC 0x0001 /* trace routine calls */
#define DBG_REG 0x0002 /* trace read/write registers */
#define DBG_REQ 0x0004 /* display transfer requests */
#define DBG_DSK 0x0008 /* display sim_disk activities */
#define DBG_DAT 0x0010 /* display transfer data */
DEBTAB rp_debug[] = {
{"TRACE", DBG_TRC},
{"REG", DBG_REG},
{"REQ", DBG_REQ},
{"DISK", DBG_DSK},
{"DATA", DBG_DAT},
{0}
};
DEVICE rp_dev = {
"RP", rp_unit, rp_reg, rp_mod,
RP_NUMDR, DEV_RDX, 30, 1, DEV_RDX, 16,
NULL, NULL, &rp_reset,
&rp_boot, &rp_attach, &rp_detach,
&rp_dib, DEV_DISABLE | DEV_UBUS | DEV_QBUS | DEV_MBUS | DEV_DEBUG
&rp_dib, DEV_DISABLE | DEV_UBUS | DEV_QBUS | DEV_MBUS | DEV_DEBUG,
0, rp_debug
};
char *rp_regnam[] =
{
"RP_CS1", /* 0 */
"RP_DS", /* 1 */
"RP_ER1", /* 2 */
"RP_MR", /* 3 */
"RP_AS", /* 4 */
"RP_DA", /* 5 */
"RP_DT", /* 6 */
"RP_LA", /* 7 */
"RP_SN", /* 8 */
"RP_OF", /* 9 */
"RP_DC", /* 10 */
"RP_CC", /* 11 */
"RP_ER2", /* 12 */
"RP_ER3", /* 13 */
"RP_EC1", /* 14 */
"RP_EC2", /* 15 */
"16", /* 16 */
"17", /* 17 */
"18", /* 18 */
"19", /* 19 */
"20", /* 20 */
"21", /* 21 */
"22", /* 22 */
"23", /* 23 */
"24", /* 24 */
"25", /* 25 */
"26", /* 26 */
"27", /* 27 */
"28", /* 28 */
"29", /* 29 */
"30", /* 30 */
"31", /* 31 */
"RM_CS1", /* 32 */
"RM_DS", /* 33 */
"RM_ER1", /* 34 */
"RM_MR", /* 35 */
"RM_AS", /* 36 */
"RM_DA", /* 37 */
"RM_DT", /* 38 */
"RM_LA", /* 39 */
"RM_SN", /* 40 */
"RM_OF", /* 41 */
"RM_DC", /* 42 */
"RM_CC", /* 43 */
"RM_MR2", /* 44 */
"RM_ER2", /* 45 */
"RM_EC1", /* 46 */
"RM_EC2", /* 47 */
"48", /* 48 */
"49", /* 49 */
"50", /* 50 */
"51", /* 51 */
"52", /* 52 */
"53", /* 53 */
"54", /* 54 */
"55", /* 55 */
"56", /* 56 */
"57", /* 57 */
"58", /* 58 */
"59", /* 59 */
"60", /* 60 */
"61", /* 61 */
"62", /* 62 */
"63", /* 63 */
};
/* Massbus register read */
@ -588,6 +874,9 @@ switch (ofs) { /* decode offset */
return MBE_NXR;
}
sim_debug(DBG_REG, &rp_dev, "rp_mbrd(drv=%d(%s), %s=0x%X)\n", drv, drv_tab[dtype].name, rp_regnam[ofs], val);
sim_debug_bits(DBG_REG, &rp_dev, rp_reg_bits[ofs], val, val, 1);
*data = val;
return SCPE_OK;
}
@ -596,10 +885,12 @@ return SCPE_OK;
t_stat rp_mbwr (int32 data, int32 ofs, int32 drv)
{
int32 dtype;
UNIT *uptr;
uint32 old_reg;
UNIT *uptr = rp_dev.units + drv; /* get unit */
int32 dtype = GET_DTYPE (uptr->flags); /* get drive type */
sim_debug(DBG_REG, &rp_dev, "rp_mbwr(drv=%d(%s), %s=0x%X)\n", drv, drv_tab[dtype].name, rp_regnam[ofs], data);
uptr = rp_dev.units + drv; /* get unit */
if (uptr->flags & UNIT_DIS) /* nx disk */
return MBE_NXD;
if ((ofs != RP_AS_OF) && sim_is_active (uptr)) { /* unit busy? */
@ -608,7 +899,6 @@ if ((ofs != RP_AS_OF) && sim_is_active (uptr)) { /* unit busy? */
return SCPE_OK;
}
rmhr[drv] = data; /* save write */
dtype = GET_DTYPE (uptr->flags); /* get drive type */
ofs = ofs & MBA_RMASK; /* mask offset */
if (drv_tab[dtype].ctrl == RM_CTRL) /* RM? convert */
ofs = ofs + RM_OF;
@ -616,33 +906,46 @@ if (drv_tab[dtype].ctrl == RM_CTRL) /* RM? convert */
switch (ofs) { /* decode PA<5:1> */
case RP_CS1_OF: case RM_CS1_OF: /* RPCS1 */
old_reg = rpcs1[drv];
rpcs1[drv] = data & CS1_RW;
sim_debug_bits(DBG_REG, &rp_dev, rp_reg_bits[ofs], old_reg, rpcs1[drv], 1);
if (data & CS1_GO) /* start op */
return rp_go (drv);
break;
case RP_DA_OF: case RM_DA_OF: /* RPDA */
old_reg = rpds[drv];
rpda[drv] = data & ~DA_MBZ;
sim_debug_bits(DBG_REG, &rp_dev, rp_reg_bits[ofs], old_reg, rpds[drv], 1);
break;
case RP_AS_OF: case RM_AS_OF: /* RPAS */
sim_debug_bits(DBG_REG, &rp_dev, rp_reg_bits[ofs], data, data, 1);
rp_clr_as (data);
break;
case RP_MR_OF: case RM_MR_OF: /* RPMR */
old_reg = rpmr[drv];
rpmr[drv] = data;
sim_debug_bits(DBG_REG, &rp_dev, rp_reg_bits[ofs], old_reg, rpmr[drv], 1);
break;
case RP_OF_OF: case RM_OF_OF: /* RPOF */
old_reg = rpof[drv];
rpof[drv] = data & ~OF_MBZ;
sim_debug_bits(DBG_REG, &rp_dev, rp_reg_bits[ofs], old_reg, rpof[drv], 1);
break;
case RP_DC_OF: case RM_DC_OF: /* RPDC */
old_reg = rpdc[drv];
rpdc[drv] = data & ~DC_MBZ;
sim_debug_bits(DBG_REG, &rp_dev, rp_reg_bits[ofs], old_reg, rpdc[drv], 1);
break;
case RM_MR2_OF: /* RMMR2 */
old_reg = rmmr2[drv];
rmmr2[drv] = data;
sim_debug_bits(DBG_REG, &rp_dev, rp_reg_bits[ofs], old_reg, rmmr2[drv], 1);
break;
case RP_ER1_OF: case RM_ER1_OF: /* RPER1 */
@ -670,16 +973,17 @@ return SCPE_OK;
t_stat rp_go (int32 drv)
{
int32 dc, fnc, dtype, t;
UNIT *uptr;
int32 dc, fnc, t;
DEVICE *dptr = &rp_dev;
UNIT *uptr = dptr->units + drv; /* get unit */
int32 dtype = GET_DTYPE (uptr->flags); /* get drive type */
sim_debug(DBG_REQ, dptr, "rp_go(drv=%d(%s))\n", drv, drv_tab[dtype].name);
fnc = GET_FNC (rpcs1[drv]); /* get function */
if (DEBUG_PRS (rp_dev))
fprintf (sim_deb, ">>RP%d STRT: fnc=%s, ds=%o, cyl=%o, da=%o, er=%o\n",
drv, rp_fname[fnc], rpds[drv], rpdc[drv], rpda[drv], rper1[drv]);
uptr = rp_dev.units + drv; /* get unit */
sim_debug(DBG_REQ, dptr, ">>RP%d STRT: fnc=%s, ds=%o, cyl=%o, da=%o, er=%o\n",
drv, rp_fname[fnc], rpds[drv], rpdc[drv], rpda[drv], rper1[drv]);
rp_clr_as (AS_U0 << drv); /* clear attention */
dtype = GET_DTYPE (uptr->flags); /* get drive type */
dc = rpdc[drv]; /* assume seek, sch */
if ((fnc != FNC_DCLR) && (rpds[drv] & DS_ERR)) { /* err & ~clear? */
rp_set_er (ER1_ILF, drv); /* not allowed */
@ -689,14 +993,17 @@ if ((fnc != FNC_DCLR) && (rpds[drv] & DS_ERR)) { /* err & ~clear? */
switch (fnc) { /* case on function */
case FNC_RELEASE: /* port release */
case FNC_DCLR: /* drive clear */
rper1[drv] = rper2[drv] = rper3[drv] = 0; /* clear errors */
rpec2[drv] = 0; /* clear EC2 */
if (drv_tab[dtype].ctrl == RM_CTRL) /* RM? */
rpmr[drv] = 0; /* clear maint */
else rpec1[drv] = 0; /* RP, clear EC1 */
rpds[drv] = rpds[drv] & ~DS_ERR; /* Clear ERR */
case FNC_NOP: /* no operation */
case FNC_RELEASE: /* port release */
sim_debug (DBG_REQ, dptr, ">>RP%d DONE: fnc=%s, ds=%o, cyl=%o, da=%o, er=%d\n",
drv, rp_fname[fnc], rpds[drv], rpdc[drv], rpda[drv], rper1[drv]);
return SCPE_OK;
case FNC_PRESET: /* read-in preset */
@ -718,6 +1025,13 @@ switch (fnc) { /* case on function */
return SCPE_OK;
case FNC_UNLOAD: /* unload */
if (drv_tab[dtype].ctrl == RM_CTRL) { /* RM? */
rp_set_er (ER1_ILF, drv); /* not supported */
break;
}
rp_detach (uptr); /* detach unit */
return SCPE_OK;
case FNC_RECAL: /* recalibrate */
dc = 0; /* seek to 0 */
case FNC_SEEK: /* seek */
@ -773,6 +1087,7 @@ return MBE_GOE;
int32 rp_abort (void)
{
sim_debug(DBG_TRC, &rp_dev, "rp_abort()\n");
return rp_reset (&rp_dev);
}
@ -780,8 +1095,13 @@ return rp_reset (&rp_dev);
void rp_io_complete (UNIT *uptr, t_stat status)
{
DEVICE *dptr = find_dev_from_unit (uptr);
sim_debug(DBG_TRC, dptr, "rp_io_complete(rp%d, status=%d)\n", (int)(uptr - dptr->units), status);
uptr->io_status = status;
uptr->io_complete = 1;
/* Initiate Bottom End processing */
sim_activate (uptr, 0);
}
/* Service unit timeout
@ -795,16 +1115,20 @@ t_stat rp_svc (UNIT *uptr)
{
int32 i, fnc, dtype, drv, err;
int32 wc, abc, awc, mbc, da;
DEVICE *dptr = find_dev_from_unit (uptr);
DIB *dibp = (DIB *) dptr->ctxt;
dtype = GET_DTYPE (uptr->flags); /* get drive type */
drv = (int32) (uptr - rp_dev.units); /* get drv number */
da = GET_DA (rpdc[drv], rpda[drv], dtype) * RP_NUMWD; /* get disk addr */
fnc = GET_FNC (rpcs1[drv]); /* get function */
sim_debug(DBG_TRC, dptr, "rp_svc(rp%d(%s), %s, da=0x%X, fnc=%s)\n", drv, drv_tab[dtype].name, uptr->io_complete ? "Bottom" : "Top", da, rp_fname[fnc]);
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
rp_set_er (ER1_UNS, drv); /* set drive error */
if (fnc >= FNC_XFER) /* xfr? set done */
mba_set_don (rp_dib.ba);
mba_set_don (dibp->ba);
rp_update_ds (DS_ATA, drv); /* set attn */
return (rp_stopioe? SCPE_UNATT: SCPE_OK);
}
@ -821,10 +1145,6 @@ if (!uptr->io_complete) { /* Top End (I/O Initiation) Processing */
rp_update_ds (DS_ATA, drv);
break;
case FNC_UNLOAD: /* unload */
rp_detach (uptr); /* detach unit */
break;
case FNC_RECAL: /* recalibrate */
case FNC_SEARCH: /* search */
case FNC_SEEK: /* seek */
@ -834,31 +1154,32 @@ if (!uptr->io_complete) { /* Top End (I/O Initiation) Processing */
case FNC_WRITE: /* write */
if (uptr->flags & UNIT_WPRT) { /* write locked? */
rp_set_er (ER1_WLE, drv); /* set drive error */
mba_set_exc (rp_dib.ba); /* set exception */
mba_set_exc (dibp->ba); /* set exception */
rp_update_ds (DS_ATA, drv); /* set attn */
return SCPE_OK;
}
case FNC_WCHK: /* write check */
case FNC_READ: /* read */
case FNC_READH: /* read headers */
mbc = mba_get_bc (rp_dib.ba); /* get byte count */
mbc = mba_get_bc (dibp->ba); /* get byte count */
wc = (mbc + 1) >> 1; /* convert to words */
if ((da + wc) > drv_tab[dtype].size) { /* disk overrun? */
rp_set_er (ER1_AOE, drv); /* set err */
wc = drv_tab[dtype].size - da; /* trim xfer */
mbc = wc << 1; /* trim mb count */
if (da >= drv_tab[dtype].size) { /* none left? */
mba_set_exc (rp_dib.ba); /* set exception */
mba_set_exc (dibp->ba); /* set exception */
rp_update_ds (DS_ATA, drv); /* set attn */
break;
}
}
if (fnc == FNC_WRITE) { /* write? */
abc = mba_rdbufW (rp_dib.ba, mbc, rpxb[drv]);/* get buffer */
abc = mba_rdbufW (dibp->ba, mbc, rpxb[drv]);/* get buffer */
wc = (abc + 1) >> 1; /* actual # wds */
awc = (wc + (RP_NUMWD - 1)) & ~(RP_NUMWD - 1);
for (i = wc; i < awc; i++) /* fill buf */
rpxb[drv][i] = 0;
sim_disk_data_trace (uptr, (void *)rpxb[drv], da/RP_NUMWD, awc, "sim_disk_wrsect-WR", DBG_DAT & dptr->dctrl, DBG_REQ);
sim_disk_wrsect_a (uptr, da/RP_NUMWD, (void *)rpxb[drv], NULL, awc/RP_NUMWD, rp_io_complete);
return SCPE_OK;
} /* end if wr */
@ -869,7 +1190,7 @@ if (!uptr->io_complete) { /* Top End (I/O Initiation) Processing */
} /* end if read */
case FNC_WRITEH: /* write headers stub */
mba_set_don (rp_dib.ba); /* set done */
mba_set_don (dibp->ba); /* set done */
rp_update_ds (0, drv); /* update ds */
break;
} /* end case func */
@ -893,17 +1214,18 @@ else { /* Bottom End (After I/O processing) */
case FNC_WCHK: /* write check */
case FNC_READ: /* read */
case FNC_READH: /* read headers */
mbc = mba_get_bc (rp_dib.ba); /* get byte count */
mbc = mba_get_bc (dibp->ba); /* get byte count */
wc = (mbc + 1) >> 1; /* convert to words */
if (fnc == FNC_WRITE) { /* write? */
} /* end if wr */
else { /* read or wchk */
awc = uptr->sectsread * RP_NUMWD;
sim_disk_data_trace (uptr, (uint8*)rpxb[drv], da/RP_NUMWD, awc << 1, "sim_disk_rdsect", DBG_DAT & dptr->dctrl, DBG_REQ);
for (i = awc; i < wc; i++) /* fill buf */
rpxb[drv][i] = 0;
if (fnc == FNC_WCHK) /* write check? */
mba_chbufW (rp_dib.ba, mbc, rpxb[drv]); /* check vs mem */
else mba_wrbufW (rp_dib.ba, mbc, rpxb[drv]);/* store in mem */
mba_chbufW (dibp->ba, mbc, rpxb[drv]); /* check vs mem */
else mba_wrbufW (dibp->ba, mbc, rpxb[drv]);/* store in mem */
} /* end if read */
da = da + wc + (RP_NUMWD - 1);
if (da >= drv_tab[dtype].size)
@ -917,21 +1239,20 @@ else { /* Bottom End (After I/O processing) */
if (err != 0) { /* error? */
rp_set_er (ER1_PAR, drv); /* set drive error */
mba_set_exc (rp_dib.ba); /* set exception */
mba_set_exc (dibp->ba); /* set exception */
rp_update_ds (DS_ATA, drv);
perror ("RP I/O error");
return SCPE_IOERR;
}
mba_set_don (rp_dib.ba); /* set done */
mba_set_don (dibp->ba); /* set done */
rp_update_ds (0, drv); /* update ds */
break;
} /* end case func */
}
rpds[drv] = (rpds[drv] & ~DS_PIP) | DS_RDY; /* change drive status */
if (DEBUG_PRS (rp_dev))
fprintf (sim_deb, ">>RP%d DONE: fnc=%s, ds=%o, cyl=%o, da=%o, er=%d\n",
sim_debug (DBG_REQ, dptr, ">>RP%d DONE: fnc=%s, ds=%o, cyl=%o, da=%o, er=%d\n",
drv, rp_fname[fnc], rpds[drv], rpdc[drv], rpda[drv], rper1[drv]);
return SCPE_OK;
}
@ -940,6 +1261,7 @@ return SCPE_OK;
void rp_set_er (int32 flag, int32 drv)
{
sim_debug(DBG_TRC, &rp_dev, "rp_set_er(rp%d, flag=0x%X)\n", drv, flag);
rper1[drv] = rper1[drv] | flag;
rpds[drv] = rpds[drv] | DS_ATA;
mba_upd_ata (rp_dib.ba, 1);
@ -958,6 +1280,9 @@ for (i = as = 0; i < RP_NUMDR; i++) {
if (rpds[i] & DS_ATA)
as = 1;
}
sim_debug(DBG_TRC, &rp_dev, "rp_clr_as(mask=0x%X, as=0x%X)\n", mask, as);
mba_upd_ata (rp_dib.ba, as);
return;
}
@ -966,6 +1291,8 @@ return;
void rp_update_ds (int32 flag, int32 drv)
{
uint16 o_ds = rpds[drv];
if (rp_unit[drv].flags & UNIT_DIS)
rpds[drv] = rper1[drv] = 0;
else rpds[drv] = (rpds[drv] | DS_DPR) & ~DS_PGM;
@ -978,6 +1305,12 @@ else rpds[drv] = rpds[drv] & ~DS_ERR;
rpds[drv] = rpds[drv] | flag;
if (flag & DS_ATA)
mba_upd_ata (rp_dib.ba, 1);
if (o_ds != rpds[drv]) {
sim_debug(DBG_TRC, &rp_dev, "rp_update_ds(rp%d, flag=0x%X, ds=0x%X)\n", drv, flag, rpds[drv]);
sim_debug_bits(DBG_TRC, &rp_dev, rp_ds_bits, o_ds, rpds[drv], 1);
}
return;
}
@ -988,9 +1321,11 @@ t_stat rp_reset (DEVICE *dptr)
int32 i;
UNIT *uptr;
mba_set_enbdis (MBA_RP, rp_dev.flags & DEV_DIS);
sim_debug(DBG_TRC, dptr, "rp_reset()\n");
mba_set_enbdis (MBA_RP, dptr->flags & DEV_DIS);
for (i = 0; i < RP_NUMDR; i++) {
uptr = rp_dev.units + i;
uptr = dptr->units + i;
sim_cancel (uptr);
uptr->CYL = 0;
if (uptr->flags & UNIT_ATT)
@ -1025,6 +1360,7 @@ t_stat rp_attach (UNIT *uptr, char *cptr)
{
int32 drv, i, p;
t_stat r;
DEVICE *dptr = find_dev_from_unit (uptr);
uptr->capac = drv_tab[GET_DTYPE (uptr->flags)].size;
r = sim_disk_attach (uptr, cptr, RP_NUMWD * sizeof (uint16),
@ -1032,7 +1368,7 @@ r = sim_disk_attach (uptr, cptr, RP_NUMWD * sizeof (uint16),
drv_tab[GET_DTYPE (uptr->flags)].name, drv_tab[GET_DTYPE (uptr->flags)].sect, 0);
if (r != SCPE_OK) /* error? */
return r;
drv = (int32) (uptr - rp_dev.units); /* get drv number */
drv = (int32) (uptr - dptr->units); /* get drv number */
rpds[drv] = DS_MOL | DS_RDY | DS_DPR | /* upd drv status */
((uptr->flags & UNIT_WPRT)? DS_WRL: 0);
rper1[drv] = 0;
@ -1056,12 +1392,15 @@ return SCPE_OK;
t_stat rp_detach (UNIT *uptr)
{
int32 drv;
DEVICE *dptr = find_dev_from_unit (uptr);
extern int32 sim_is_running;
if (!(uptr->flags & UNIT_ATT)) /* attached? */
return SCPE_OK;
drv = (int32) (uptr - rp_dev.units); /* get drv number */
drv = (int32) (uptr - dptr->units); /* get drv number */
rpds[drv] = rpds[drv] & ~(DS_MOL | DS_RDY | DS_WRL | DS_VV | DS_OFM);
rp_update_ds (DS_ATA, drv); /* request intr */
if (!sim_is_running) /* from console? */
rp_update_ds (DS_ATA, drv); /* request intr */
return sim_disk_detach (uptr);
}
@ -1123,7 +1462,7 @@ t_stat rp_boot (int32 unitno, DEVICE *dptr)
int32 i;
extern int32 saved_PC;
extern uint16 *M;
UNIT *uptr = rp_dev.units + unitno;
UNIT *uptr = dptr->units + unitno;
for (i = 0; i < BOOT_LEN; i++)
M[(BOOT_START >> 1) + i] = boot_rom[i];

View file

@ -24,8 +24,22 @@
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
rq RQDX3 disk controller
rq MSCP disk controller
09-Dec-12 MB Added support for changing controller type.
24-Oct-12 MB Added mapped transfers for VAX
29-Jan-11 HUH Added RC25, RCF25 and RA80 disks
Not all disk parameters set yet
"KLESI" MSCP controller (3) / port (1) types for RC25
not yet implemented
Remarks on the RC25 disk drives:
In "real" life the RC25 drives exist in pairs only,
one RC25 (removable) and one RCF25 (fixed) in one housing.
The removable platter has always got an even drive number
(e.g. "0"), the fixed platter has always got the next (odd)
drive number (e.g. "1"). These two rules are not enforced
by the disk drive simulation.
07-Mar-11 MP Added working behaviors for removable device types.
This allows physical CDROM's to come online and be
ejected.
@ -127,8 +141,8 @@ extern uint32 cpu_opt;
#define RQU_UQPM 6 /* UB port model */
#define RQQ_UQPM 19 /* QB port model */
#define RQ_UQPM (UNIBUS? RQU_UQPM: RQQ_UQPM)
#define RQU_MODEL 6 /* UB MSCP ctrl model */
#define RQQ_MODEL 19 /* QB MSCP ctrl model */
#define RQU_MODEL 6 /* UB MSCP ctrl model (UDA50A) */
#define RQQ_MODEL 19 /* QB MSCP ctrl model (RQDX3) */
#define RQ_MODEL (UNIBUS? RQU_MODEL: RQQ_MODEL)
#define RQ_HVER 1 /* hardware version */
#define RQ_SVER 3 /* software version */
@ -137,6 +151,8 @@ extern uint32 cpu_opt;
#define RQ_NUMDR 4 /* # drives */
#define RQ_NUMBY 512 /* bytes per block */
#define RQ_MAXFR (1 << 16) /* max xfer */
#define RQ_MAPXFER (1 << 31) /* mapped xfer */
#define RQ_M_PFN 0x1FFFFF /* map entry PFN */
#define UNIT_V_ONL (UNIT_V_UF + 0) /* online */
#define UNIT_V_WLK (UNIT_V_UF + 1) /* hwre write lock */
@ -249,6 +265,7 @@ x RD33 17 7 1170 ? ? ? 138565
RA60 42(+1) 6 1600 6 1 1008 400176
x RA70 33(+1) 11 1507+ 11 1 ? 547041
RA80 31 14 546 ? ? ? 237212
RA81 51(+1) 14 1258 14 1 2856 891072
RA82 57(+1) 15 1435 15 1 3420 1216665
RA71 51(+1) 14 1921 14 1 1428 1367310
@ -257,6 +274,11 @@ x RA70 33(+1) 11 1507+ 11 1 ? 547041
RA92 73(+1) 13 3101 13 1 949 2940951
x RA73 70(+1) 21 2667+ 21 1 ? 3920490
LESI attached RC25 disks (one removable, one fixed)
type sec surf cyl tpg gpc RCT LBNs
RC25 31 2 821 ? ? ? 50902
RCF25 31 2 821 ? ? ? 50902
Each drive can be a different type. The drive field in the
unit flags specified the drive type and thus, indirectly,
the drive size.
@ -533,7 +555,7 @@ x RA73 70(+1) 21 2667+ 21 1 ? 3920490
#define RD32_GPC 1
#define RD32_XBN 54
#define RD32_DBN 48
#define RD32_LBN 83204
#define RD32_LBN 83236
#define RD32_RCTS 4
#define RD32_RCTC 8
#define RD32_RBN 200
@ -541,6 +563,74 @@ x RA73 70(+1) 21 2667+ 21 1 ? 3920490
#define RD32_MED 0x25644020
#define RD32_FLGS 0
#define RC25_DTYPE 17 /* */
#define RC25_SECT 50 /* */
#define RC25_SURF 8
#define RC25_CYL 1260 /* */
#define RC25_TPG RC25_SURF
#define RC25_GPC 1
#define RC25_XBN 0 /* */
#define RC25_DBN 0 /* */
#define RC25_LBN 50902 /* ? 50*8*1260 ? */
#define RC25_RCTS 0 /* */
#define RC25_RCTC 1
#define RC25_RBN 0 /* */
#define RC25_MOD 3
#define RC25_MED 0x20643019
#define RC25_FLGS RQDF_RMV
#define RCF25_DTYPE 18 /* */
#define RCF25_SECT 50 /* */
#define RCF25_SURF 8
#define RCF25_CYL 1260 /* */
#define RCF25_TPG RCF25_SURF
#define RCF25_GPC 1
#define RCF25_XBN 0 /* */
#define RCF25_DBN 0 /* */
#define RCF25_LBN 50902 /* ? 50*8*1260 ? */
#define RCF25_RCTS 0 /* */
#define RCF25_RCTC 1
#define RCF25_RBN 0 /* */
#define RCF25_MOD 3
#define RCF25_MED 0x20643319
#define RCF25_FLGS 0
#define RA80_DTYPE 19 /* SDI drive */
#define RA80_SECT 31 /* +1 spare/track */
#define RA80_SURF 14
#define RA80_CYL 546 /* */
#define RA80_TPG RA80_SURF
#define RA80_GPC 1
#define RA80_XBN 0 /* */
#define RA80_DBN 0 /* */
#define RA80_LBN 237212 /* 31*14*546 */
#define RA80_RCTS 0 /* */
#define RA80_RCTC 1
#define RA80_RBN 0 /* */
#define RA80_MOD 1
#define RA80_MED 0x25641050
#define RA80_FLGS RQDF_SDI
/* Controller parameters */
#define DEFAULT_CTYPE 0
#define KLESI_CTYPE 1
#define KLESI_UQPM 1
#define KLESI_MODEL 1
#define RUX50_CTYPE 2
#define RUX50_UQPM 2
#define RUX50_MODEL 2
#define UDA50_CTYPE 3
#define UDA50_UQPM 6
#define UDA50_MODEL 6
#define RQDX3_CTYPE 4
#define RQDX3_UQPM 19
#define RQDX3_MODEL 19
struct drvtyp {
int32 sect; /* sectors */
int32 surf; /* surfaces */
@ -567,22 +657,49 @@ struct drvtyp {
#define RQ_SIZE(d) (d##_LBN * RQ_NUMBY)
static struct drvtyp drv_tab[] = {
{ RQ_DRV (RX50), "RX50" }, { RQ_DRV (RX33), "RX33" },
{ RQ_DRV (RD51), "RD51" }, { RQ_DRV (RD31), "RD31" },
{ RQ_DRV (RD52), "RD52" }, { RQ_DRV (RD53), "RD53" },
{ RQ_DRV (RD54), "RD54" }, { RQ_DRV (RA82), "RA82" },
{ RQ_DRV (RRD40), "RRD40" }, { RQ_DRV (RA72), "RA72" },
{ RQ_DRV (RA90), "RA90" }, { RQ_DRV (RA92), "RA92" },
{ RQ_DRV (RA8U), "RAUSER" }, { RQ_DRV (RA60), "RA60" },
{ RQ_DRV (RA81), "RA81" }, { RQ_DRV (RA71), "RA71" },
{ RQ_DRV (RD32), "RD32" },
{ RQ_DRV (RX50), "RX50" },
{ RQ_DRV (RX33), "RX33" },
{ RQ_DRV (RD51), "RD51" },
{ RQ_DRV (RD31), "RD31" },
{ RQ_DRV (RD52), "RD52" },
{ RQ_DRV (RD53), "RD53" },
{ RQ_DRV (RD54), "RD54" },
{ RQ_DRV (RA82), "RA82" },
{ RQ_DRV (RRD40), "RRD40" },
{ RQ_DRV (RA72), "RA72" },
{ RQ_DRV (RA90), "RA90" },
{ RQ_DRV (RA92), "RA92" },
{ RQ_DRV (RA8U), "RAUSER" },
{ RQ_DRV (RA60), "RA60" },
{ RQ_DRV (RA81), "RA81" },
{ RQ_DRV (RA71), "RA71" },
{ RQ_DRV (RD32), "RD32" },
{ RQ_DRV (RC25), "RC25" },
{ RQ_DRV (RCF25), "RCF25" },
{ RQ_DRV (RA80), "RA80" },
{ 0 }
};
struct ctlrtyp {
uint32 uqpm; /* port model */
uint32 model; /* controller model */
char *name; /* name */
};
#define RQ_CTLR(d) \
d##_UQPM, d##_MODEL
static struct ctlrtyp ctlr_tab[] = {
{ 0, 0, "DEFAULT" },
{ RQ_CTLR (KLESI), "KLESI" },
{ RQ_CTLR (RUX50), "RUX50" },
{ RQ_CTLR (UDA50), "UDA50" },
{ RQ_CTLR (RQDX3), "RQDX3" },
{ 0 }
};
extern int32 int_req[IPL_HLVL];
extern int32 tmr_poll, clk_tps;
extern UNIT cpu_unit;
extern FILE *sim_deb;
extern uint32 sim_taddr_64;
extern int32 sim_switches;
@ -610,6 +727,7 @@ typedef struct {
uint32 credits; /* credits */
uint32 hat; /* host timer */
uint32 htmo; /* host timeout */
uint32 ctype; /* controller type */
struct uq_ring cq; /* cmd ring */
struct uq_ring rq; /* rsp ring */
struct rqpkt pak[RQ_NPKTS]; /* packet queue */
@ -677,7 +795,9 @@ t_stat rq_detach (UNIT *uptr);
t_stat rq_boot (int32 unitno, DEVICE *dptr);
t_stat rq_set_wlk (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat rq_set_type (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat rq_set_ctype (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat rq_show_type (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat rq_show_ctype (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat rq_show_wlk (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat rq_show_ctrl (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat rq_show_unitq (FILE *st, UNIT *uptr, int32 val, void *desc);
@ -707,6 +827,10 @@ t_bool rq_getdesc (MSC *cp, struct uq_ring *ring, uint32 *desc);
t_bool rq_putdesc (MSC *cp, struct uq_ring *ring, uint32 desc);
int32 rq_rw_valid (MSC *cp, int32 pkt, UNIT *uptr, uint32 cmd);
t_bool rq_rw_end (MSC *cp, UNIT *uptr, uint32 flg, uint32 sts);
uint32 rq_map_ba (uint32 ba, uint32 ma);
int32 rq_readb (uint32 ba, int32 bc, uint32 ma, uint8 *buf);
int32 rq_readw (uint32 ba, int32 bc, uint32 ma, uint16 *buf);
int32 rq_writew (uint32 ba, int32 bc, uint32 ma, uint16 *buf);
void rq_putr (MSC *cp, int32 pkt, uint32 cmd, uint32 flg,
uint32 sts, uint32 lnt, uint32 typ);
void rq_putr_unit (MSC *cp, int32 pkt, UNIT *uptr, uint32 lu, t_bool all);
@ -801,6 +925,14 @@ MTAB rq_mod[] = {
NULL, &rq_show_ctrl, 0 },
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, RQ_SH_ALL, "ALL", NULL,
NULL, &rq_show_ctrl, 0 },
{ MTAB_XTD | MTAB_VDV, KLESI_CTYPE, NULL, "KLESI",
&rq_set_ctype, NULL, NULL },
{ MTAB_XTD | MTAB_VDV, RUX50_CTYPE, NULL, "RUX50",
&rq_set_ctype, NULL, NULL },
{ MTAB_XTD | MTAB_VDV, UDA50_CTYPE, NULL, "UDA50",
&rq_set_ctype, NULL, NULL },
{ MTAB_XTD | MTAB_VDV, RQDX3_CTYPE, NULL, "RQDX3",
&rq_set_ctype, NULL, NULL },
{ MTAB_XTD | MTAB_VUN | MTAB_NMO, 0, "UNITQ", NULL,
NULL, &rq_show_unitq, 0 },
{ MTAB_XTD | MTAB_VUN, 0, "WRITE", NULL,
@ -839,6 +971,12 @@ MTAB rq_mod[] = {
&rq_set_type, NULL, NULL },
{ MTAB_XTD | MTAB_VUN, RA92_DTYPE, NULL, "RA92",
&rq_set_type, NULL, NULL },
{ MTAB_XTD | MTAB_VUN, RC25_DTYPE, NULL, "RC25",
&rq_set_type, NULL, NULL },
{ MTAB_XTD | MTAB_VUN, RCF25_DTYPE, NULL, "RCF25",
&rq_set_type, NULL, NULL },
{ MTAB_XTD | MTAB_VUN, RA80_DTYPE, NULL, "RA80",
&rq_set_type, NULL, NULL },
{ MTAB_XTD | MTAB_VUN, RA8U_DTYPE, NULL, "RAUSER",
&rq_set_type, NULL, NULL },
{ MTAB_XTD | MTAB_VUN, 0, "TYPE", NULL,
@ -858,6 +996,8 @@ MTAB rq_mod[] = {
#endif
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL,
NULL, &show_vec, NULL },
{ MTAB_XTD | MTAB_VDV, 0, "TYPE", NULL,
NULL, &rq_show_ctype, NULL },
{ 0 }
};
@ -1203,7 +1343,8 @@ for (i = 0; i < (lnt >> 1); i++) /* clr buffer */
zero[i] = 0;
if (Map_WriteW (base, lnt, zero)) /* zero comm area */
return rq_fatal (cp, PE_QWE); /* error? */
cp->sa = SA_S4 | (RQ_UQPM << SA_S4C_V_MOD) | /* send step 4 */
cp->sa = SA_S4 | /* send step 4 */
(ctlr_tab[cp->ctype].uqpm << SA_S4C_V_MOD) |
(RQ_SVER << SA_S4C_V_VER);
cp->csta = CST_S4; /* set step 4 */
rq_init_int (cp); /* poke host */
@ -1636,7 +1777,7 @@ else {
cp->pak[pkt].d[SCC_CIDB] = 0;
cp->pak[pkt].d[SCC_CIDC] = 0;
cp->pak[pkt].d[SCC_CIDD] = (RQ_CLASS << SCC_CIDD_V_CLS) |
(RQ_MODEL << SCC_CIDD_V_MOD);
(ctlr_tab[cp->ctype].model << SCC_CIDD_V_MOD);
cp->pak[pkt].d[SCC_MBCL] = 0; /* max bc */
cp->pak[pkt].d[SCC_MBCH] = 0;
}
@ -1737,6 +1878,8 @@ if ((uptr = rq_getucb (cp, lu))) { /* unit exist? */
cp->pak[pkt].d[RW_WBCH] = cp->pak[pkt].d[RW_BCH];
cp->pak[pkt].d[RW_WBLL] = cp->pak[pkt].d[RW_LBNL];
cp->pak[pkt].d[RW_WBLH] = cp->pak[pkt].d[RW_LBNH];
cp->pak[pkt].d[RW_WMPL] = cp->pak[pkt].d[RW_MAPL];
cp->pak[pkt].d[RW_WMPH] = cp->pak[pkt].d[RW_MAPH];
uptr->iostarttime = sim_grtime();
sim_activate (uptr, 0); /* activate */
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_rw - started\n");
@ -1803,6 +1946,100 @@ uptr->io_complete = 1;
sim_activate_notbefore (uptr, uptr->iostarttime+rq_xtime);
}
/* Map buffer address */
uint32 rq_map_ba (uint32 ba, uint32 ma)
{
#if defined (VM_VAX) /* VAX version */
int32 idx;
uint32 rg;
idx = (VA_GETVPN(ba) << 2); /* map register index */
rg = ReadL (ma + idx); /* map register */
if (rg & PTE_V) /* valid? */
return ((rg & RQ_M_PFN) << VA_N_OFF) | (ba & VA_M_OFF);
#endif
return 0;
}
/* Read byte buffer from memory */
int32 rq_readb (uint32 ba, int32 bc, uint32 ma, uint8 *buf)
{
#if defined (VM_VAX) /* VAX version */
int32 lbc, t, tbc = 0;
uint32 pba;
if (ba & RQ_MAPXFER) { /* mapped xfer? */
while (tbc < bc) {
if (!(pba = rq_map_ba (ba, ma))) /* get physical ba */
return (bc - tbc);
lbc = 0x200 - (ba & VA_M_OFF); /* bc for this tx */
if (lbc > (bc - tbc)) lbc = (bc - tbc);
t = Map_ReadB (pba, lbc, buf);
tbc += (lbc - t); /* bytes xfer'd so far */
if (t) return (bc - tbc); /* incomplete xfer? */
ba += lbc;
buf += lbc;
}
return 0;
}
#endif
return Map_ReadB (ba, bc, buf); /* unmapped xfer */
}
/* Read word buffer from memory */
int32 rq_readw (uint32 ba, int32 bc, uint32 ma, uint16 *buf)
{
#if defined (VM_VAX) /* VAX version */
int32 lbc, t, tbc = 0;
uint32 pba;
if (ba & RQ_MAPXFER) { /* mapped xfer? */
while (tbc < bc) {
if (!(pba = rq_map_ba (ba, ma))) /* get physical ba */
return (bc - tbc);
lbc = 0x200 - (ba & VA_M_OFF); /* bc for this tx */
if (lbc > (bc - tbc)) lbc = (bc - tbc);
t = Map_ReadW (pba, lbc, buf);
tbc += (lbc - t); /* bytes xfer'd so far */
if (t) return (bc - tbc); /* incomplete xfer? */
ba += lbc;
buf += (lbc >> 1);
}
return 0;
}
#endif
return Map_ReadW (ba, bc, buf); /* unmapped xfer */
}
/* Write word buffer to memory */
int32 rq_writew (uint32 ba, int32 bc, uint32 ma, uint16 *buf)
{
#if defined (VM_VAX) /* VAX version */
int32 lbc, t, tbc = 0;
uint32 pba;
if (ba & RQ_MAPXFER) { /* mapped xfer? */
while (tbc < bc) {
if (!(pba = rq_map_ba (ba, ma))) /* get physical ba */
return (bc - tbc);
lbc = 0x200 - (ba & VA_M_OFF); /* bc for this tx */
if (lbc > (bc - tbc)) lbc = (bc - tbc);
t = Map_WriteW (pba, lbc, buf);
tbc += (lbc - t); /* bytes xfer'd so far */
if (t) return (bc - tbc); /* incomplete xfer? */
ba += lbc;
buf += (lbc >> 1);
}
return 0;
}
#endif
return Map_WriteW (ba, bc, buf); /* unmapped xfer */
}
/* Unit service for data transfer commands */
t_stat rq_svc (UNIT *uptr)
@ -1815,6 +2052,7 @@ uint32 cmd = GETP (pkt, CMD_OPC, OPC); /* get cmd */
uint32 ba = GETP32 (pkt, RW_WBAL); /* buf addr */
uint32 bc = GETP32 (pkt, RW_WBCL); /* byte count */
uint32 bl = GETP32 (pkt, RW_WBLL); /* block addr */
uint32 ma = GETP32 (pkt, RW_WMPL); /* block addr */
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_svc(unit=%d, pkt=%d, cmd=%s, lbn=%0X, bc=%0x, phase=%s)\n",
uptr-rq_devmap[cp->cnum]->units, pkt, rq_cmdname[cp->pak[pkt].d[CMD_OPC]&0x3f], bl, bc,
@ -1853,7 +2091,7 @@ if (!uptr->io_complete) { /* Top End (I/O Initiation) Processing */
}
else if (cmd == OP_WR) { /* write? */
t = Map_ReadW (ba, tbc, uptr->rqxb); /* fetch buffer */
t = rq_readw (ba, tbc, ma, uptr->rqxb); /* fetch buffer */
if ((abc = tbc - t)) { /* any xfer? */
wwc = ((abc + (RQ_NUMBY - 1)) & ~(RQ_NUMBY - 1)) >> 1;
for (i = (abc >> 1); i < wwc; i++)
@ -1875,7 +2113,7 @@ else { /* Bottom End (After I/O processing) */
}
else if (cmd == OP_WR) { /* write? */
t = Map_ReadW (ba, tbc, uptr->rqxb); /* fetch buffer */
t = rq_readw (ba, tbc, ma, uptr->rqxb); /* fetch buffer */
abc = tbc - t; /* any xfer? */
if (t) { /* nxm? */
PUTP32 (pkt, RW_WBCL, bc - abc); /* adj bc */
@ -1889,7 +2127,7 @@ else { /* Bottom End (After I/O processing) */
else {
sim_disk_data_trace(uptr, uptr->rqxb, bl, tbc, "sim_disk_rdsect", DBG_DAT & rq_devmap[cp->cnum]->dctrl, DBG_REQ);
if ((cmd == OP_RD) && !err) { /* read? */
if ((t = Map_WriteW (ba, tbc, uptr->rqxb))) {/* store, nxm? */
if ((t = rq_writew (ba, tbc, ma, uptr->rqxb))) {/* store, nxm? */
PUTP32 (pkt, RW_WBCL, bc - (tbc - t)); /* adj bc */
PUTP32 (pkt, RW_WBAL, ba + (tbc - t)); /* adj ba */
if (rq_hbe (cp, uptr)) /* post err log */
@ -1900,7 +2138,7 @@ else { /* Bottom End (After I/O processing) */
else if ((cmd == OP_CMP) && !err) { /* compare? */
uint8 dby, mby;
for (i = 0; i < tbc; i++) { /* loop */
if (Map_ReadB (ba + i, 1, &mby)) { /* fetch, nxm? */
if (rq_readb (ba + i, 1, ma, &mby)) { /* fetch, nxm? */
PUTP32 (pkt, RW_WBCL, bc - i); /* adj bc */
PUTP32 (pkt, RW_WBAL, bc - i); /* adj ba */
if (rq_hbe (cp, uptr)) /* post err log */
@ -1957,6 +2195,8 @@ cp->pak[pkt].d[RW_WBCL] = 0;
cp->pak[pkt].d[RW_WBCH] = 0;
cp->pak[pkt].d[RW_WBLL] = 0;
cp->pak[pkt].d[RW_WBLH] = 0;
cp->pak[pkt].d[RW_WMPL] = 0;
cp->pak[pkt].d[RW_WMPH] = 0;
rq_putr (cp, pkt, cmd | OP_END, flg, sts, RW_LNT_D, UQ_TYP_SEQ); /* fill pkt */
if (!rq_putpkt (cp, pkt, TRUE)) /* send pkt */
return ERR;
@ -1999,7 +2239,7 @@ cp->pak[pkt].d[DTE_CIDA] = 0; /* ctrl ID */
cp->pak[pkt].d[DTE_CIDB] = 0;
cp->pak[pkt].d[DTE_CIDC] = 0;
cp->pak[pkt].d[DTE_CIDD] = (RQ_CLASS << DTE_CIDD_V_CLS) |
(RQ_MODEL << DTE_CIDD_V_MOD);
(ctlr_tab[cp->ctype].model << DTE_CIDD_V_MOD);
cp->pak[pkt].d[DTE_VER] = (RQ_HVER << DTE_VER_V_HVER) |
(RQ_SVER << DTE_VER_V_SVER);
cp->pak[pkt].d[DTE_MLUN] = lu; /* MLUN */
@ -2041,7 +2281,7 @@ cp->pak[pkt].d[HBE_CIDA] = 0; /* ctrl ID */
cp->pak[pkt].d[HBE_CIDB] = 0;
cp->pak[pkt].d[HBE_CIDC] = 0;
cp->pak[pkt].d[HBE_CIDD] = (RQ_CLASS << DTE_CIDD_V_CLS) |
(RQ_MODEL << DTE_CIDD_V_MOD);
(ctlr_tab[cp->ctype].model << DTE_CIDD_V_MOD);
cp->pak[pkt].d[HBE_VER] = (RQ_HVER << HBE_VER_V_HVER) | /* versions */
(RQ_SVER << HBE_VER_V_SVER);
cp->pak[pkt].d[HBE_RSV] = 0;
@ -2069,7 +2309,7 @@ cp->pak[pkt].d[PLF_CIDA] = 0; /* cntl ID */
cp->pak[pkt].d[PLF_CIDB] = 0;
cp->pak[pkt].d[PLF_CIDC] = 0;
cp->pak[pkt].d[PLF_CIDD] = (RQ_CLASS << PLF_CIDD_V_CLS) |
(RQ_MODEL << PLF_CIDD_V_MOD);
(ctlr_tab[cp->ctype].model << PLF_CIDD_V_MOD);
cp->pak[pkt].d[PLF_VER] = (RQ_SVER << PLF_VER_V_SVER) |
(RQ_HVER << PLF_VER_V_HVER);
cp->pak[pkt].d[PLF_ERR] = err;
@ -2480,6 +2720,27 @@ fprintf (st, "%s", drv_tab[GET_DTYPE (uptr->flags)].name);
return SCPE_OK;
}
/* Set controller type */
t_stat rq_set_ctype (UNIT *uptr, int32 val, char *cptr, void *desc)
{
MSC *cp = rq_ctxmap[uptr->cnum];
if (val < 0)
return SCPE_ARG;
cp->ctype = val;
return SCPE_OK;
}
/* Show controller type */
t_stat rq_show_ctype (FILE *st, UNIT *uptr, int32 val, void *desc)
{
MSC *cp = rq_ctxmap[uptr->cnum];
fprintf (st, "%s", ctlr_tab[cp->ctype].name);
return SCPE_OK;
}
/* Device attach */
t_stat rq_attach (UNIT *uptr, char *cptr)
@ -2529,6 +2790,8 @@ if (cidx < 0) /* not found??? */
return SCPE_IERR;
cp = rq_ctxmap[cidx]; /* get context */
cp->cnum = cidx; /* init index */
if (cp->ctype == DEFAULT_CTYPE)
cp->ctype = (UNIBUS? UDA50_CTYPE : RQDX3_CTYPE);
#if defined (VM_VAX) /* VAX */
cp->ubase = 0; /* unit base = 0 */

View file

@ -462,7 +462,7 @@ int32 clk_cosched (int32 wait)
{
int32 t;
t = sim_is_active (&clk_unit);
t = sim_activate_time (&clk_unit);
return (t? t - 1: wait);
}

View file

@ -822,7 +822,7 @@ return;
void tu_update_fs (int32 flg, int32 drv)
{
int32 act = sim_is_active (&tu_unit[drv]);
int32 act = sim_activate_time (&tu_unit[drv]);
tufs = (tufs & ~FS_DYN) | FS_FPR | flg;
if (tu_unit[drv].flags & UNIT_ATT) {

View file

@ -95,7 +95,16 @@ extern int32 tmxr_poll, clk_tps;
#endif
#define VH_MNOMASK (VH_MUXES - 1)
#if defined(VM_VAX)
#if VEC_QBUS
#define VH_LINES (8)
#else
#define VH_LINES (16)
#endif
#else
#define VH_LINES (UNIBUS?16:8)
#endif
#define VH_LINES_ALLOC 16
#define UNIT_V_MODEDHU (UNIT_V_UF + 0)
#define UNIT_V_FASTDMA (UNIT_V_UF + 1)
@ -286,9 +295,9 @@ typedef struct {
uint16 txchar; /* single character I/O */
} TMLX;
static TMLN vh_ldsc[VH_MUXES * VH_LINES] = { { 0 } };
static TMXR vh_desc = { VH_MUXES * VH_LINES, 0, 0, vh_ldsc };
static TMLX vh_parm[VH_MUXES * VH_LINES] = { { 0 } };
static TMLN vh_ldsc[VH_MUXES * VH_LINES_ALLOC] = { { 0 } };
static TMXR vh_desc = { VH_MUXES * VH_LINES_ALLOC, 0, 0, vh_ldsc };
static TMLX vh_parm[VH_MUXES * VH_LINES_ALLOC] = { { 0 } };
/* debugging bitmaps */
#define DBG_REG 0x0001 /* trace read/write registers */
@ -319,6 +328,8 @@ static t_stat vh_show_rbuf (FILE *st, UNIT *uptr, int32 val, void *desc);
static t_stat vh_show_txq (FILE *st, UNIT *uptr, int32 val, void *desc);
static t_stat vh_putc (int32 vh, TMLX *lp, int32 chan, int32 data);
static void doDMA (int32 vh, int32 chan);
static t_stat vh_setmode (UNIT *uptr, int32 val, char *cptr, void *desc);
static t_stat vh_show_vec (FILE *st, UNIT *uptr, int32 val, void *desc);
static t_stat vh_setnl (UNIT *uptr, int32 val, char *cptr, void *desc);
static t_stat vh_set_log (UNIT *uptr, int32 val, char *cptr, void *desc);
static t_stat vh_set_nolog (UNIT *uptr, int32 val, char *cptr, void *desc);
@ -351,8 +362,10 @@ static const REG vh_reg[] = {
};
static const MTAB vh_mod[] = {
{ UNIT_MODEDHU, 0, "DHV mode", "DHV", NULL },
{ UNIT_MODEDHU, UNIT_MODEDHU, "DHU mode", "DHU", NULL },
#if !UNIBUS
{ UNIT_MODEDHU, 0, "DHV mode", "DHV", &vh_setmode },
#endif
{ UNIT_MODEDHU, UNIT_MODEDHU, "DHU mode", "DHU", &vh_setmode },
{ UNIT_FASTDMA, 0, NULL, "NORMAL", NULL },
{ UNIT_FASTDMA, UNIT_FASTDMA, "fast DMA", "FASTDMA", NULL },
{ UNIT_MODEM, 0, NULL, "NOMODEM", NULL },
@ -361,8 +374,8 @@ static const MTAB vh_mod[] = {
{ UNIT_HANGUP, UNIT_HANGUP, "hangup", "HANGUP", NULL },
{ MTAB_XTD|MTAB_VDV, 020, "ADDRESS", "ADDRESS",
&set_addr, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, VH_LINES, "VECTOR", "VECTOR",
&set_vec, &show_vec_mux, (void *) &vh_desc },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR",
&set_vec, &vh_show_vec, (void *) &vh_desc },
{ MTAB_XTD|MTAB_VDV, 0, NULL, "AUTOCONFIGURE",
&set_addr_flt, NULL, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "LINES", "LINES",
@ -713,7 +726,7 @@ static void vh_getc ( int32 vh )
uint32 i, c;
TMLX *lp;
for (i = 0; i < VH_LINES; i++) {
for (i = 0; i < (uint32)VH_LINES; i++) {
lp = &vh_parm[(vh * VH_LINES) + i];
while ((c = tmxr_getc_ln (lp->tmln)) != 0) {
if (c & SCPE_BREAK) {
@ -1281,14 +1294,15 @@ static t_stat vh_reset ( DEVICE *dptr )
{
int32 i;
if (vh_desc.lines > VH_MUXES*VH_LINES)
vh_desc.lines = VH_MUXES*VH_LINES;
for (i = 0; i < vh_desc.lines; i++)
vh_parm[i].tmln = &vh_ldsc[i];
vh_dev.numunits = (vh_desc.lines / VH_LINES);
for (i = 0; i < vh_desc.lines/VH_LINES; i++) {
#if defined (VM_PDP11)
/* if Unibus, force DHU mode */
if (UNIBUS)
vh_unit[i].flags |= UNIT_MODEDHU;
#endif
vh_clear (i, TRUE);
}
vh_rxi = vh_txi = 0;
@ -1312,6 +1326,13 @@ static t_stat vh_detach ( UNIT *uptr )
return (tmxr_detach (&vh_desc, uptr));
}
t_stat vh_show_vec (FILE *st, UNIT *uptr, int32 arg, void *desc)
{
TMXR *mp = (TMXR *) desc;
return show_vec (st, uptr, ((mp->lines * 2) / VH_LINES), desc);
}
static void vh_detail_line ( FILE *st,
int32 vh,
int32 chan )
@ -1408,6 +1429,17 @@ vh_dev.numunits = (newln / VH_LINES);
return auto_config (vh_dev.name, ndev); /* auto config */
}
/* SET DHU/DHV mode processor */
static t_stat vh_setmode (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if (cptr)
return SCPE_ARG;
if ((UNIBUS) && (val != UNIT_MODEDHU))
return SCPE_ARG;
return SCPE_OK;
}
/* SET LOG processor */
static t_stat vh_set_log (UNIT *uptr, int32 val, char *cptr, void *desc)

View file

@ -256,6 +256,7 @@ extern int32 tmxr_poll;
extern int32 tmr_poll, clk_tps;
extern t_bool sim_idle_enab;
extern FILE* sim_deb;
extern int32 sim_switches;
extern FILE *sim_log;
extern char* read_line (char *ptr, int32 size, FILE *stream);
@ -278,6 +279,7 @@ t_stat xq_show_sanity (FILE* st, UNIT* uptr, int32 val, void* desc);
t_stat xq_set_sanity (UNIT* uptr, int32 val, char* cptr, void* desc);
t_stat xq_show_poll (FILE* st, UNIT* uptr, int32 val, void* desc);
t_stat xq_set_poll (UNIT* uptr, int32 val, char* cptr, void* desc);
t_stat xq_show_leds (FILE* st, UNIT* uptr, int32 val, void* desc);
t_stat xq_process_xbdl(CTLR* xq);
t_stat xq_dispatch_xbdl(CTLR* xq);
t_stat xq_process_turbo_rbdl(CTLR* xq);
@ -458,6 +460,8 @@ MTAB xq_mod[] = {
#endif
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "SANITY", "SANITY={ON|OFF}",
&xq_set_sanity, &xq_show_sanity, NULL },
{ MTAB_XTD | MTAB_VDV , 0, "LEDS", "LEDS",
NULL, &xq_show_leds, NULL },
{ 0 },
};
@ -514,19 +518,22 @@ const char* const xqt_xmit_regnames[] = {
"IBAL", "IBAH", "ICR", "", "SRQR", "", "", "ARQR"
};
const char* const xq_csr_bits[] = {
"RE", "SR", "NI", "BD", "XL", "RL", "IE", "XI",
"IL", "EL", "SE", "RR", "OK", "CA", "PE", "RI"
BITFIELD xq_csr_bits[] = {
BIT(RE), BIT(SR), BIT(NI), BIT(BD), BIT(XL), BIT(RL), BIT(IE), BIT(XI),
BIT(IL), BIT(EL), BIT(SE), BIT(RR), BIT(OK), BIT(CA), BIT(PE), BIT(RI),
ENDBITS
};
const char* const xq_var_bits[] = {
"ID", "RR", "V0", "V1", "V2", "V3", "V4", "V5",
"V6", "V7", "S1", "S2", "S3", "RS", "OS", "MS"
BITFIELD xq_var_bits[] = {
BIT(ID), BIT(RR), BIT(V0), BIT(V1), BIT(V2), BIT(V3), BIT(V4), BIT(V5),
BIT(V6), BIT(V7), BIT(S1), BIT(S2), BIT(S3), BIT(RS), BIT(OS), BIT(MS),
ENDBITS
};
const char* const xq_srr_bits[] = {
"RS0", "RS1", "", "", "", "", "", "",
"", "TBL", "IME", "PAR", "NXM", "", "CHN", "FES"
BITFIELD xq_srr_bits[] = {
BIT(RS0), BIT(RS1), BITNC, BITNC, BITNC, BITNC, BITNC, BITNC,
BITNC, BIT(TBL), BIT(IME), BIT(PAR), BIT(NXM), BITNC, BIT(CHN), BIT(FES),
ENDBITS
};
/* internal debugging routines */
@ -822,6 +829,16 @@ t_stat xq_set_sanity (UNIT* uptr, int32 val, char* cptr, void* desc)
return SCPE_OK;
}
t_stat xq_show_leds (FILE* st, UNIT* uptr, int32 val, void* desc)
{
CTLR* xq = xq_unit2ctlr(uptr);
fprintf(st, "leds=(%s,%s,%s)", xq->var->setup.l1 ? "ON" : "OFF",
xq->var->setup.l2 ? "ON" : "OFF",
xq->var->setup.l3 ? "ON" : "OFF");
return SCPE_OK;
}
/*============================================================================*/
t_stat xq_nxm_error(CTLR* xq)
@ -912,16 +929,16 @@ t_stat xq_rd(int32* data, int32 PA, int32 access)
break;
case 6:
if (xq->var->mode != XQ_T_DELQA_PLUS) {
sim_debug_u16(DBG_VAR, xq->dev, xq_var_bits, xq->var->var, xq->var->var, 0);
sim_debug (DBG_VAR, xq->dev, ", vec = 0%o\n", (xq->var->var & XQ_VEC_IV));
sim_debug_bits(DBG_VAR, xq->dev, xq_var_bits, xq->var->var, xq->var->var, 0);
sim_debug (DBG_VAR, xq->dev, ", vec = 0%o\n", (xq->var->var & XQ_VEC_IV));
*data = xq->var->var;
} else {
sim_debug_u16(DBG_VAR, xq->dev, xq_srr_bits, xq->var->srr, xq->var->srr, 0);
sim_debug_bits(DBG_VAR, xq->dev, xq_srr_bits, xq->var->srr, xq->var->srr, 0);
*data = xq->var->srr;
}
break;
case 7:
sim_debug_u16(DBG_CSR, xq->dev, xq_csr_bits, xq->var->csr, xq->var->csr, 1);
sim_debug_bits(DBG_CSR, xq->dev, xq_csr_bits, xq->var->csr, xq->var->csr, 1);
*data = xq->var->csr;
break;
}
@ -985,6 +1002,8 @@ t_stat xq_process_rbdl(CTLR* xq)
item = &xq->var->ReadQ.item[xq->var->ReadQ.head];
rbl = item->packet.len;
rbuf = item->packet.msg;
if (item->packet.oversize)
rbuf = item->packet.oversize;
/* see if packet must be size-adjusted or is splitting */
if (item->packet.used) {
@ -992,8 +1011,11 @@ t_stat xq_process_rbdl(CTLR* xq)
rbl -= used;
rbuf = &item->packet.msg[used];
} else {
/* adjust runt packets */
if (rbl < ETH_MIN_PACKET) {
/* there should be no need to adjust runt packets
the physical layer (sim_ether) won't deliver any short packets
via eth_read, so the only short packets which get here are loopback
packets sent by the host diagnostics */
if ((item->type != 1) && (rbl < ETH_MIN_PACKET)) {
xq->var->stats.runt += 1;
sim_debug(DBG_WRN, xq->dev, "Runt detected, size = %d\n", rbl);
/* pad runts with zeros up to minimum size - this allows "legal" (size - 60)
@ -1003,12 +1025,14 @@ t_stat xq_process_rbdl(CTLR* xq)
};
/* adjust oversized packets */
if (rbl > ETH_MAX_PACKET) {
if (rbl > ETH_FRAME_SIZE) {
xq->var->stats.giant += 1;
sim_debug(DBG_WRN, xq->dev, "Giant detected, size=%d\n", rbl);
/* trim giants down to maximum size - no documentation on how to handle the data loss */
item->packet.len = ETH_MAX_PACKET;
rbl = ETH_MAX_PACKET;
if (rbl > XQ_MAX_RCV_PACKET) {
item->packet.len = XQ_MAX_RCV_PACKET;
rbl = XQ_MAX_RCV_PACKET;
}
};
};
@ -1038,6 +1062,7 @@ t_stat xq_process_rbdl(CTLR* xq)
case 2: /* normal packet */
rbl -= 60; /* keeps max packet size in 11 bits */
xq->var->rbdl_buf[4] = (rbl & 0x0700); /* high bits of rbl */
xq->var->rbdl_buf[4] |= 0x00f8; /* set reserved bits to 1 */
break;
}
if (item->packet.used < item->packet.len)
@ -1048,12 +1073,16 @@ t_stat xq_process_rbdl(CTLR* xq)
xq->var->rbdl_buf[4] |= 0x0001; /* set overflow bit */
xq->var->stats.dropped += xq->var->ReadQ.loss;
xq->var->ReadQ.loss = 0; /* reset loss counter */
}
}
if ((rbl + ((item->type == 2) ? 60 : 0)) > ETH_MAX_PACKET)
xq->var->rbdl_buf[4] |= 0x4000; /* set Error bit (LONG) */
/* update read status words*/
wstatus = Map_WriteW(xq->var->rbdl_ba + 8, 4, &xq->var->rbdl_buf[4]);
if (wstatus) return xq_nxm_error(xq);
sim_debug(DBG_TRC, xq->dev, "xq_process_rdbl(bd=0x%X, addr=0x%X, size=0x%X, len=0x%X, st1=0x%04X, st2=0x%04X)\n", xq->var->rbdl_ba, address, b_length, rbl + ((item->type == 2) ? 60 : 0), xq->var->rbdl_buf[4], xq->var->rbdl_buf[5]);
/* remove packet from queue */
if (item->packet.used >= item->packet.len)
ethq_remove(&xq->var->ReadQ);
@ -1263,6 +1292,8 @@ t_stat xq_process_xbdl(CTLR* xq)
/* clear write buffer */
xq->var->write_buffer.len = 0;
free (xq->var->write_buffer.oversize);
xq->var->write_buffer.oversize = NULL;
/* process buffer descriptors until not valid */
while (1) {
@ -1297,9 +1328,12 @@ t_stat xq_process_xbdl(CTLR* xq)
}
/* add to transmit buffer, making sure it's not too big */
if ((xq->var->write_buffer.len + b_length) > sizeof(xq->var->write_buffer.msg))
b_length = (uint16)(sizeof(xq->var->write_buffer.msg) - xq->var->write_buffer.len);
rstatus = Map_ReadB(address, b_length, &xq->var->write_buffer.msg[xq->var->write_buffer.len]);
if ((xq->var->write_buffer.len + b_length) > sizeof(xq->var->write_buffer.msg)) {
xq->var->write_buffer.oversize = realloc (xq->var->write_buffer.oversize, xq->var->write_buffer.len + b_length);
if (xq->var->write_buffer.len <= sizeof(xq->var->write_buffer.msg))
memcpy (xq->var->write_buffer.oversize, xq->var->write_buffer.msg, xq->var->write_buffer.len);
}
rstatus = Map_ReadB(address, b_length, xq->var->write_buffer.oversize ? &xq->var->write_buffer.oversize[xq->var->write_buffer.len] : &xq->var->write_buffer.msg[xq->var->write_buffer.len]);
if (rstatus) return xq_nxm_error(xq);
xq->var->write_buffer.len += b_length;
@ -1315,6 +1349,8 @@ t_stat xq_process_xbdl(CTLR* xq)
} else { /* loopback */
/* put packet in read buffer */
ethq_insert (&xq->var->ReadQ, 1, &xq->var->write_buffer, 0);
if ((DBG_PCK & xq->dev->dctrl) && xq->var->etherface)
eth_packet_trace_ex(xq->var->etherface, xq->var->write_buffer.msg, xq->var->write_buffer.len, "xq-write-loopback", DBG_DAT & xq->dev->dctrl, DBG_PCK);
}
/* update write status */
@ -1323,6 +1359,8 @@ t_stat xq_process_xbdl(CTLR* xq)
/* clear write buffer */
xq->var->write_buffer.len = 0;
free (xq->var->write_buffer.oversize);
xq->var->write_buffer.oversize = NULL;
/* reset sanity timer */
xq_reset_santmr(xq);
@ -1361,6 +1399,54 @@ t_stat xq_process_xbdl(CTLR* xq)
} /* while */
}
void xq_show_debug_bdl(CTLR* xq, uint32 bdl_ba)
{
uint16 bdl_buf[6];
uint16 b_length, w_length;
uint32 address, initial_bdl_ba = bdl_ba;
int32 rstatus;
sim_debug(DBG_TRC, xq->dev, " Descriptor list at: 0x%X\n", bdl_ba);
while (1) {
/* get the beginning of the buffer descriptor */
rstatus = Map_ReadW (bdl_ba, 4, &bdl_buf[0]);
if (rstatus) return;
/* invalid buffer? */
if (~bdl_buf[1] & XQ_DSC_V)
break;
/* get the rest of the buffer descriptor */
rstatus = Map_ReadW (bdl_ba + 4, 8, &bdl_buf[2]);
if (rstatus) return;
/* explicit chain buffer? */
if (bdl_buf[1] & XQ_DSC_C) {
sim_debug(DBG_TRC, xq->dev, " descriptor=0x%X, flags=0x%04X, chain=0x%X\n", bdl_ba, bdl_buf[0], ((bdl_buf[1] & 0x3F) << 16) | bdl_buf[2]);
bdl_ba = ((bdl_buf[1] & 0x3F) << 16) | bdl_buf[2];
if (initial_bdl_ba == bdl_ba)
break;
continue;
}
/* get host memory address */
address = ((bdl_buf[1] & 0x3F) << 16) | bdl_buf[2];
/* decode buffer length - two's complement (in words) */
w_length = ~bdl_buf[3] + 1;
b_length = w_length * 2;
if (bdl_buf[1] & XQ_DSC_H) b_length -= 1;
if (bdl_buf[1] & XQ_DSC_L) b_length -= 1;
sim_debug(DBG_TRC, xq->dev, " descriptor=0x%X, flags=0x%04X, bits=0x%04X, addr=0x%X, len=0x%X, st1=0x%04X, st2=0x%04X\n",
bdl_ba, bdl_buf[0], bdl_buf[1] & 0xFFC0, address, b_length, bdl_buf[4], bdl_buf[5]);
bdl_ba += 12;
}
}
t_stat xq_dispatch_rbdl(CTLR* xq)
{
int i;
@ -1388,7 +1474,10 @@ t_stat xq_dispatch_rbdl(CTLR* xq)
if (~xq->var->rbdl_buf[1] & XQ_DSC_V) {
xq_csr_set_clr(xq, XQ_CSR_RL, 0);
return SCPE_OK;
}
}
/* When debugging, walk and display the buffer descriptor list */
xq_show_debug_bdl(xq, xq->var->rbdl_ba);
/* process any waiting packets in receive queue */
if (xq->var->ReadQ.count)
@ -1413,10 +1502,15 @@ t_stat xq_dispatch_xbdl(CTLR* xq)
/* clear transmit buffer */
xq->var->write_buffer.len = 0;
free (xq->var->write_buffer.oversize);
xq->var->write_buffer.oversize = NULL;
/* get base address of first transmit descriptor */
xq->var->xbdl_ba = ((xq->var->xbdl[1] & 0x3F) << 16) | (xq->var->xbdl[0] & ~01);
/* When debugging, walk and display the buffer descriptor list */
xq_show_debug_bdl(xq, xq->var->xbdl_ba);
/* process xbdl */
status = xq_process_xbdl(xq);
@ -1475,8 +1569,8 @@ t_stat xq_process_turbo_rbdl(CTLR* xq)
rbl -= used;
rbuf = &item->packet.msg[used];
} else {
/* adjust runt packets */
if (rbl < ETH_MIN_PACKET) {
/* adjust non loopback runt packets */
if ((item->type != 1) && (rbl < ETH_MIN_PACKET)) {
xq->var->stats.runt += 1;
sim_debug(DBG_WRN, xq->dev, "Runt detected, size = %d\n", rbl);
/* pad runts with zeros up to minimum size - this allows "legal" (size - 60)
@ -1564,6 +1658,8 @@ t_stat xq_process_turbo_xbdl(CTLR* xq)
/* clear transmit buffer */
xq->var->write_buffer.len = 0;
free (xq->var->write_buffer.oversize);
xq->var->write_buffer.oversize = NULL;
/* Process each descriptor in the transmit ring */
do {
@ -1587,10 +1683,13 @@ t_stat xq_process_turbo_xbdl(CTLR* xq)
address = ((xq->var->xring[i].hadr & 0x3F ) << 16) | xq->var->xring[i].ladr;
b_length = (xq->var->xring[i].tmd3 & XQ_TMD3_BCT);
/* add to transmit buffer, making sure it's not too big */
if ((xq->var->write_buffer.len + b_length) > sizeof(xq->var->write_buffer.msg))
b_length = (uint16)(sizeof(xq->var->write_buffer.msg) - xq->var->write_buffer.len);
status = Map_ReadB(address, b_length, &xq->var->write_buffer.msg[xq->var->write_buffer.len]);
/* add to transmit buffer, accomodating it if it is too big */
if ((xq->var->write_buffer.len + b_length) > sizeof(xq->var->write_buffer.msg)) {
xq->var->write_buffer.oversize = realloc (xq->var->write_buffer.oversize, xq->var->write_buffer.len + b_length);
if (xq->var->write_buffer.len <= sizeof(xq->var->write_buffer.msg))
memcpy (xq->var->write_buffer.oversize, xq->var->write_buffer.msg, xq->var->write_buffer.len);
}
status = Map_ReadB(address, b_length, xq->var->write_buffer.oversize ? &xq->var->write_buffer.oversize[xq->var->write_buffer.len] : &xq->var->write_buffer.msg[xq->var->write_buffer.len]);
if (status != SCPE_OK)
return xq_nxm_error(xq);
@ -1895,7 +1994,7 @@ t_stat xq_wr_var(CTLR* xq, int32 data)
else
xq->dib->vec = 0;
sim_debug_u16(DBG_VAR, xq->dev, xq_var_bits, save_var, xq->var->var, 1);
sim_debug_bits(DBG_VAR, xq->dev, xq_var_bits, save_var, xq->var->var, 1);
return SCPE_OK;
}
@ -2086,6 +2185,11 @@ t_stat xq_process_bootrom (CTLR* xq)
/* reset sanity timer */
xq_reset_santmr(xq);
/* Turn on all 3 DEQNA Leds */
xq->var->setup.l1 = 1;
xq->var->setup.l2 = 1;
xq->var->setup.l3 = 1;
return SCPE_OK;
}
#endif /* ifdef VM_PDP11 */
@ -2387,6 +2491,13 @@ t_stat xq_reset(DEVICE* dptr)
xq->var->sanity.quarter_secs = XQ_HW_SANITY_SECS * 4/*qsec*/;
}
if (sim_switches & SWMASK ('P')) { /* Powerup? */
/* Turn on all 3 DEQNA Leds */
xq->var->setup.l1 = 1;
xq->var->setup.l2 = 1;
xq->var->setup.l3 = 1;
}
return auto_config (0, 0); /* run autoconfig */
}
@ -2731,7 +2842,7 @@ void xq_csr_set_clr (CTLR* xq, uint16 set_bits, uint16 clear_bits)
/* set the bits in the csr */
xq->var->csr = (xq->var->csr | set_bits) & ~clear_bits;
sim_debug_u16(DBG_CSR, xq->dev, xq_csr_bits, saved_csr, xq->var->csr, 1);
sim_debug_bits(DBG_CSR, xq->dev, xq_csr_bits, saved_csr, xq->var->csr, 1);
/* check and correct the state of controller interrupt */

View file

@ -96,6 +96,8 @@ extern int32 int_req[IPL_HLVL];
#define XQ_HW_SANITY_SECS 240 /* seconds before HW sanity timer expires */
#define XQ_MAX_CONTROLLERS 2 /* maximum controllers allowed */
#define XQ_MAX_RCV_PACKET 1600 /* Maximum receive packet data */
enum xq_type {XQ_T_DEQNA, XQ_T_DELQA, XQ_T_DELQA_PLUS};
struct xq_sanity {

BIN
VAX/ka610.bin Normal file

Binary file not shown.

BIN
VAX/ka620.bin Normal file

Binary file not shown.

25
VAX/ka620_patch.com Normal file
View file

@ -0,0 +1,25 @@
$!
$! This procedure patches KA620.BIN (V1.1) Boot ROM image to work under
$! the SIMH simulator
$!
$ PATCH /ABSOLUTE /NEW_VERSION /OUTPUT=KA620.BIN KA620_ORIG.BIN
!
! Test D - ROM checksum & TOY RAM
!
! - ROM checksum needs to be updated to reflect changes below
!
REPLACE/WORD 0B888 = 0279F
0163D
EXIT
!
! Test 3 - Interrupt tests
!
! - Need to skip console loopback test and memory parity test
!
REPLACE/INSTRUCTION 0547C = 'MOVAL W^0000571A,B^04(R11)'
'BRW 05CCC'
EXIT
!
UPDATE
EXIT
$

BIN
VAX/ka630.bin Normal file

Binary file not shown.

25
VAX/ka630_patch.com Normal file
View file

@ -0,0 +1,25 @@
$!
$! This procedure patches KA630.BIN (V1.3) Boot ROM image to work under
$! the SIMH simulator
$!
$ PATCH /ABSOLUTE /NEW_VERSION /OUTPUT=KA630.BIN KA630_ORIG.BIN
!
! Test D - ROM checksum & TOY RAM
!
! - ROM checksum needs to be updated to reflect changes below
!
REPLACE/WORD 0B888 = 0EAAA
0FAB3
EXIT
!
! Test 3 - Interrupt tests
!
! - Need to skip console loopback test and memory parity test
!
REPLACE/INSTRUCTION 0547C = 'MOVAL W^0000571A,B^04(R11)'
'BRW 05CCC'
EXIT
!
UPDATE
EXIT
$

397
VAX/vax610_defs.h Normal file
View file

@ -0,0 +1,397 @@
/* vax610_defs.h: MicroVAX I model-specific definitions file
Copyright (c) 2011-2012, 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).
15-Feb-2012 MB First Version
This file covers the MicroVAX I
System memory map
0000 0000 - 003F FFFF main memory
0040 0000 - 1FFF FFFF reserved
2000 0000 - 2000 1FFF qbus address space
2000 2000 - 3FFF FFFF reserved
*/
#ifdef FULL_VAX /* subset VAX */
#undef FULL_VAX
#endif
#ifndef _VAX_610_DEFS_H_
#define _VAX_610_DEFS_H_ 1
/* Microcode constructs */
#define VAX610_SID (7 << 24) /* system ID */
#define VAX610_FLOAT (1 << 16) /* floating point type */
#define VAX610_MREV (5 << 8) /* microcode revision */
#define VAX610_HWREV 1 /* hardware revision */
#define CON_HLTPIN 0x0200 /* external CPU halt */
#define CON_PWRUP 0x0300 /* powerup code */
#define CON_HLTINS 0x0600 /* HALT instruction */
#define CON_BADPSL 0x4000 /* invalid PSL flag */
#define CON_MAPON 0x8000 /* mapping on flag */
#define MCHK_TBM_P0 0x05 /* PPTE in P0 */
#define MCHK_TBM_P1 0x06 /* PPTE in P1 */
#define MCHK_M0_P0 0x07 /* PPTE in P0 */
#define MCHK_M0_P1 0x08 /* PPTE in P1 */
#define MCHK_INTIPL 0x09 /* invalid ireq */
#define MCHK_READ 0x02 /* read check */
#define MCHK_WRITE 0x02 /* write check */
/* Machine specific IPRs */
#define MT_TBDR 36 /* Translation Buffer Disable */
#define MT_CADR 37 /* Cache Disable Register */
#define MT_MCESR 38 /* Machine Check Error Summary */
#define MT_CAER 39 /* Cache Error Register */
#define MT_CONISP 41 /* Console Saved ISP */
#define MT_CONPC 42 /* Console Saved PC */
#define MT_CONPSL 43 /* Console Saved PSL */
#define MT_SBIFS 48 /* SBI fault status */
#define MT_SBIS 49 /* SBI silo */
#define MT_SBISC 50 /* SBI silo comparator */
#define MT_SBIMT 51 /* SBI maint */
#define MT_SBIER 52 /* SBI error */
#define MT_SBITA 53 /* SBI timeout addr */
#define MT_SBIQC 54 /* SBI timeout clear */
#define MT_IORESET 55 /* I/O Bus Reset */
#define MT_TBDATA 59 /* Translation Buffer Data */
#define MT_MBRK 60 /* microbreak */
/* Memory */
#define MAXMEMWIDTH 22 /* max mem, KA610 */
#define MAXMEMSIZE (1 << MAXMEMWIDTH) /* max mem size */
#define MAXMEMWIDTH_X 22 /* max mem, KA610 */
#define MAXMEMSIZE_X (1 << MAXMEMWIDTH_X)
#define INITMEMSIZE (1 << 22) /* initial memory size */
#define MEMSIZE (cpu_unit.capac)
#define ADDR_IS_MEM(x) (((uint32) (x)) < MEMSIZE)
#undef PAMASK
#define PAMASK 0x203FFFFF /* KA610 needs a special mask */
#define MEM_MODIFIERS { UNIT_MSIZE, (1u << 19), NULL, "512k", &cpu_set_size }, \
{ UNIT_MSIZE, (1u << 20), NULL, "1M", &cpu_set_size }, \
{ UNIT_MSIZE, (1u << 21), NULL, "2M", &cpu_set_size }, \
{ UNIT_MSIZE, (1u << 22), NULL, "4M", &cpu_set_size }
#define CPU_MODEL_MODIFIERS { MTAB_XTD|MTAB_VDV, 0, "LEDS", NULL, \
NULL, &cpu_show_leds }, \
{ MTAB_XTD|MTAB_VDV, 0, "MODEL", NULL, \
NULL, &cpu_show_model },
/* Qbus I/O page */
#define IOPAGEAWIDTH 13 /* IO addr width */
#define IOPAGESIZE (1u << IOPAGEAWIDTH) /* IO page length */
#define IOPAGEMASK (IOPAGESIZE - 1) /* IO addr mask */
#define IOPAGEBASE 0x20000000 /* IO page base */
#define ADDR_IS_IO(x) ((((uint32) (x)) >= IOPAGEBASE) && \
(((uint32) (x)) < (IOPAGEBASE + IOPAGESIZE)))
/* Other address spaces */
#define ADDR_IS_CDG(x) (0)
#define ADDR_IS_ROM(x) (0)
#define ADDR_IS_NVR(x) (0)
/* 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)
/* Qbus 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 DZ_LINES 4 /* lines per DZV mux */
#define VH_MUXES 4 /* max # of DHQ muxes */
#define DLX_LINES 16 /* max # of KL11/DL11's */
#define DCX_LINES 16 /* max # of DC11's */
#define MT_MAXFR (1 << 16) /* magtape max rec */
#define AUTO_LNT 34 /* autoconfig ranks */
#define DEV_V_UBUS (DEV_V_UF + 0) /* Unibus */
#define DEV_V_QBUS (DEV_V_UF + 1) /* Qbus */
#define DEV_V_Q18 (DEV_V_UF + 2) /* Qbus, mem <= 256KB */
#define DEV_V_FLTA (DEV_V_UF + 3) /* flt addr */
#define DEV_UBUS (1u << DEV_V_UBUS)
#define DEV_QBUS (1u << DEV_V_QBUS)
#define DEV_Q18 (1u << DEV_V_Q18)
#define DEV_FLTA (1u << DEV_V_FLTA)
#define UNIBUS FALSE /* 22b only */
#define DEV_RDX 16 /* default device radix */
/* Device information block */
#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 */
} DIB;
/* I/O page layout - RQB,RQC,RQD float based on number of DZ's */
#define IOBA_DZ (IOPAGEBASE + 000100) /* DZ11 */
#define IOLN_DZ 010
#define IOBA_RQB (IOPAGEBASE + 000334 + (020 * (DZ_MUXES / 2)))
#define IOLN_RQB 004
#define IOBA_RQC (IOPAGEBASE + IOBA_RQB + IOLN_RQB)
#define IOLN_RQC 004
#define IOBA_RQD (IOPAGEBASE + IOBA_RQC + IOLN_RQC)
#define IOLN_RQD 004
#define IOBA_VH (IOPAGEBASE + 000440) /* DHQ11 */
#define IOLN_VH 020
#define IOBA_MEM (IOPAGEBASE + 012100) /* MSV11-P */
#define IOLN_MEM 040
#define IOBA_RQ (IOPAGEBASE + 012150) /* RQDX3 */
#define IOLN_RQ 004
#define IOBA_TS (IOPAGEBASE + 012520) /* TS11 */
#define IOLN_TS 004
#define IOBA_RL (IOPAGEBASE + 014400) /* RL11 */
#define IOLN_RL 012
#define IOBA_XQ (IOPAGEBASE + 014440) /* DEQNA/DELQA */
#define IOLN_XQ 020
#define IOBA_XQB (IOPAGEBASE + 014460) /* 2nd DEQNA/DELQA */
#define IOLN_XQB 020
#define IOBA_TQ (IOPAGEBASE + 014500) /* TMSCP */
#define IOLN_TQ 004
#define IOBA_XU (IOPAGEBASE + 014510) /* DEUNA/DELUA */
#define IOLN_XU 010
#define IOBA_RP (IOPAGEBASE + 016700) /* RP/RM */
#define IOLN_RP 054
#define IOBA_CR (IOPAGEBASE + 017160) /* CD/CR/CM */
#define IOLN_CR 010
#define IOBA_RX (IOPAGEBASE + 017170) /* RXV11 */
#define IOLN_RX 004
#define IOBA_RY (IOPAGEBASE + 017170) /* RXV21 */
#define IOLN_RY 004
#define IOBA_QVSS (IOPAGEBASE + 017200) /* QVSS */
#define IOLN_QVSS 0100
#define IOBA_QDSS (IOPAGEBASE + 017400) /* QDSS */
#define IOLN_QDSS 002
#define IOBA_DBL (IOPAGEBASE + 017500) /* doorbell */
#define IOLN_DBL 002
#define IOBA_LPT (IOPAGEBASE + 017514) /* LP11 */
#define IOLN_LPT 004
#define IOBA_PTR (IOPAGEBASE + 017550) /* PC11 reader */
#define IOLN_PTR 004
#define IOBA_PTP (IOPAGEBASE + 017554) /* PC11 punch */
#define IOLN_PTP 004
/* The KA610 maintains 4 separate hardware IPL levels, IPL 17 to IPL 14;
however, DEC Qbus controllers all interrupt on IPL 14
Within each IPL, priority is right to left
*/
/* IPL 17 */
/* IPL 16 */
#define INT_V_CLK 0 /* clock */
/* IPL 15 */
/* IPL 14 - devices through RY are IPL 15 on Unibus systems */
#define INT_V_RQ 0 /* RQDX3 */
#define INT_V_RL 1 /* RLV12/RL02 */
#define INT_V_DZRX 2 /* DZ11 */
#define INT_V_DZTX 3
#define INT_V_TS 4 /* TS11/TSV05 */
#define INT_V_TQ 5 /* TMSCP */
#define INT_V_XQ 6 /* DEQNA/DELQA */
#define INT_V_RY 7 /* RXV21 */
#define INT_V_TTI 8 /* console */
#define INT_V_TTO 9
#define INT_V_PTR 10 /* PC11 */
#define INT_V_PTP 11
#define INT_V_LPT 12 /* LP11 */
#define INT_V_CSI 13 /* SSC cons UART */
#define INT_V_CSO 14
#define INT_V_TMR0 15 /* SSC timers */
#define INT_V_TMR1 16
#define INT_V_VHRX 17 /* DHQ11 */
#define INT_V_VHTX 18
#define INT_V_QDSS 19 /* QDSS */
#define INT_V_CR 20
#define INT_V_QVSS 21 /* QVSS */
#define INT_CLK (1u << INT_V_CLK)
#define INT_RQ (1u << INT_V_RQ)
#define INT_RL (1u << INT_V_RL)
#define INT_DZRX (1u << INT_V_DZRX)
#define INT_DZTX (1u << INT_V_DZTX)
#define INT_TS (1u << INT_V_TS)
#define INT_TQ (1u << INT_V_TQ)
#define INT_XQ (1u << INT_V_XQ)
#define INT_RY (1u << INT_V_RY)
#define INT_TTI (1u << INT_V_TTI)
#define INT_TTO (1u << INT_V_TTO)
#define INT_PTR (1u << INT_V_PTR)
#define INT_PTP (1u << INT_V_PTP)
#define INT_LPT (1u << INT_V_LPT)
#define INT_CSI (1u << INT_V_CSI)
#define INT_CSO (1u << INT_V_CSO)
#define INT_TMR0 (1u << INT_V_TMR0)
#define INT_TMR1 (1u << INT_V_TMR1)
#define INT_VHRX (1u << INT_V_VHRX)
#define INT_VHTX (1u << INT_V_VHTX)
#define INT_QDSS (1u << INT_V_QDSS)
#define INT_CR (1u << INT_V_CR)
#define INT_QVSS (1u << INT_V_QVSS)
#define IPL_CLK (0x16 - IPL_HMIN) /* relative IPL */
#define IPL_RQ (0x14 - IPL_HMIN)
#define IPL_RL (0x14 - IPL_HMIN)
#define IPL_DZRX (0x14 - IPL_HMIN)
#define IPL_DZTX (0x14 - IPL_HMIN)
#define IPL_TS (0x14 - IPL_HMIN)
#define IPL_TQ (0x14 - IPL_HMIN)
#define IPL_XQ (0x14 - IPL_HMIN)
#define IPL_RY (0x14 - IPL_HMIN)
#define IPL_TTI (0x14 - IPL_HMIN)
#define IPL_TTO (0x14 - IPL_HMIN)
#define IPL_PTR (0x14 - IPL_HMIN)
#define IPL_PTP (0x14 - IPL_HMIN)
#define IPL_LPT (0x14 - IPL_HMIN)
#define IPL_CSI (0x14 - IPL_HMIN)
#define IPL_CSO (0x14 - IPL_HMIN)
#define IPL_TMR0 (0x14 - IPL_HMIN)
#define IPL_TMR1 (0x14 - IPL_HMIN)
#define IPL_VHRX (0x14 - IPL_HMIN)
#define IPL_VHTX (0x14 - IPL_HMIN)
#define IPL_QDSS (0x14 - IPL_HMIN)
#define IPL_CR (0x14 - IPL_HMIN)
#define IPL_QVSS (0x14 - IPL_HMIN)
#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 */
/* Device vectors */
#define VEC_QBUS 1 /* Qbus system */
#define VEC_Q 0x200 /* Qbus vector offset */
#define VEC_PTR (VEC_Q + 0070)
#define VEC_PTP (VEC_Q + 0074)
#define VEC_XQ (VEC_Q + 0120)
#define VEC_XU (VEC_Q + 0120)
#define VEC_RQ (VEC_Q + 0154)
#define VEC_RL (VEC_Q + 0160)
#define VEC_LPT (VEC_Q + 0200)
#define VEC_TS (VEC_Q + 0224)
#define VEC_CR (VEC_Q + 0230)
#define VEC_TQ (VEC_Q + 0260)
#define VEC_RX (VEC_Q + 0264)
#define VEC_RY (VEC_Q + 0264)
#define VEC_DZRX (VEC_Q + 0300)
#define VEC_DZTX (VEC_Q + 0304)
#define VEC_VHRX (VEC_Q + 0310)
#define VEC_VHTX (VEC_Q + 0314)
/* Interrupt macros */
#define IVCL(dv) ((IPL_##dv * 32) + INT_V_##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 */
/* Logging */
#define LOG_CPU_I 0x1 /* intexc */
#define LOG_CPU_R 0x2 /* REI */
#define LOG_CPU_P 0x4 /* context */
/* Function prototypes for virtual memory interface */
int32 Read (uint32 va, int32 lnt, int32 acc);
void Write (uint32 va, int32 val, int32 lnt, int32 acc);
/* Function prototypes for physical memory interface (inlined) */
SIM_INLINE int32 ReadB (uint32 pa);
SIM_INLINE int32 ReadW (uint32 pa);
SIM_INLINE int32 ReadL (uint32 pa);
SIM_INLINE int32 ReadLP (uint32 pa);
SIM_INLINE void WriteB (uint32 pa, int32 val);
SIM_INLINE void WriteW (uint32 pa, int32 val);
SIM_INLINE void WriteL (uint32 pa, int32 val);
void WriteLP (uint32 pa, int32 val);
/* 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, uint8 *buf);
int32 Map_WriteW (uint32 ba, int32 bc, uint16 *buf);
int32 clk_cosched (int32 wait);
t_stat cpu_show_model (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat cpu_show_leds (FILE *st, UNIT *uptr, int32 val, void *desc);
#include "pdp11_io_lib.h"
#endif

376
VAX/vax610_io.c Normal file
View file

@ -0,0 +1,376 @@
/* vax610_io.c: MicroVAX I Qbus IO simulator
Copyright (c) 2011-2012, 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).
qba Qbus adapter
15-Feb-2012 MB First Version
*/
#include "vax_defs.h"
int32 int_req[IPL_HLVL] = { 0 }; /* intr, IPL 14-17 */
int32 autcon_enb = 1; /* autoconfig enable */
extern int32 PSL, SISR, trpirq, mem_err, hlt_pin;
extern int32 p1;
extern jmp_buf save_env;
extern DEVICE *sim_devices[];
int32 eval_int (void);
t_stat qba_reset (DEVICE *dptr);
/* Qbus adapter data structures
qba_dev QBA device descriptor
qba_unit QBA units
qba_reg QBA register list
*/
UNIT qba_unit = { UDATA (NULL, 0, 0) };
REG qba_reg[] = {
{ HRDATA (IPL17, int_req[3], 32), REG_RO },
{ HRDATA (IPL16, int_req[2], 32), REG_RO },
{ HRDATA (IPL15, int_req[1], 32), REG_RO },
{ HRDATA (IPL14, int_req[0], 32), REG_RO },
{ FLDATA (AUTOCON, autcon_enb, 0), REG_HRO },
{ NULL }
};
MTAB qba_mod[] = {
{ 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 },
{ 0 }
};
DEVICE qba_dev = {
"QBA", &qba_unit, qba_reg, qba_mod,
1, 16, 4, 2, 16, 16,
NULL, NULL, &qba_reset,
NULL, NULL, NULL,
NULL, DEV_QBUS
};
/* 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);
/* Interrupt request to interrupt action map */
int32 (*int_ack[IPL_HLVL][32])(void); /* int ack routines */
/* Interrupt request to vector map */
int32 int_vec[IPL_HLVL][32]; /* int req to vector */
/* The KA610 handles errors in I/O space as follows
- read: machine check
- write: machine check (?)
*/
int32 ReadQb (uint32 pa)
{
int32 idx, val;
idx = (pa & IOPAGEMASK) >> 1;
if (iodispR[idx]) {
iodispR[idx] (&val, pa, READ);
return val;
}
MACH_CHECK (MCHK_READ);
return 0;
}
void WriteQb (uint32 pa, int32 val, int32 mode)
{
int32 idx;
idx = (pa & IOPAGEMASK) >> 1;
if (iodispW[idx]) {
iodispW[idx] (val, pa, mode);
return;
}
MACH_CHECK (MCHK_WRITE); /* FIXME: is this correct? */
return;
}
/* ReadIO - read I/O space
Inputs:
pa = physical address
lnt = length (BWLQ)
Output:
longword of data
*/
int32 ReadIO (uint32 pa, int32 lnt)
{
int32 iod;
iod = ReadQb (pa); /* wd from Qbus */
if (lnt < L_LONG) /* bw? position */
iod = iod << ((pa & 2)? 16: 0);
else iod = (ReadQb (pa + 2) << 16) | iod; /* lw, get 2nd wd */
SET_IRQL;
return iod;
}
/* WriteIO - write I/O space
Inputs:
pa = physical address
val = data to write, right justified in 32b longword
lnt = length (BWLQ)
Outputs:
none
*/
void WriteIO (uint32 pa, int32 val, int32 lnt)
{
if (lnt == L_BYTE)
WriteQb (pa, val, WRITEB);
else if (lnt == L_WORD)
WriteQb (pa, val, WRITE);
else {
WriteQb (pa, val & 0xFFFF, WRITE);
WriteQb (pa + 2, (val >> 16) & 0xFFFF, WRITE);
}
SET_IRQL;
return;
}
/* Find highest priority outstanding interrupt */
int32 eval_int (void)
{
int32 ipl = PSL_GETIPL (PSL);
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_MEMERR) && mem_err) /* mem err int */
return IPL_MEMERR;
for (i = IPL_HMAX; i >= IPL_HMIN; i--) { /* chk hwre int */
if (i <= ipl) /* at ipl? no int */
return 0;
if (int_req[i - IPL_HMIN]) /* req != 0? int */
return i;
}
if (ipl >= IPL_SMAX) /* ipl >= sw max? */
return 0;
if ((t = SISR & sw_int_mask[ipl]) == 0) /* eligible req */
return 0;
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;
int32 l = lvl - IPL_HMIN;
if (lvl == IPL_MEMERR) { /* mem error? */
mem_err = 0;
return SCB_MEMERR;
}
if (lvl > IPL_HMAX) { /* error req lvl? */
ABORT (STOP_UIPL); /* unknown intr */
}
for (i = 0; int_req[l] && (i < 32); i++) {
if ((int_req[l] >> i) & 1) {
int_req[l] = int_req[l] & ~(1u << i);
if (int_ack[l][i])
return int_ack[l][i]();
return int_vec[l][i];
}
}
return 0;
}
/* Reset I/O bus */
void ioreset_wr (int32 data)
{
reset_all (5); /* from qba on... */
return;
}
/* Reset Qbus */
t_stat qba_reset (DEVICE *dptr)
{
int32 i;
for (i = 0; i < IPL_HLVL; i++)
int_req[i] = 0;
return SCPE_OK;
}
/* Qbus I/O buffer routines, aligned access
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;
uint32 ma = ba & 0x3FFFFF;
uint32 dat;
if ((ba | bc) & 03) { /* check alignment */
for (i = 0; i < bc; i++, buf++) { /* by bytes */
*buf = ReadB (ma);
ma = ma + 1;
}
}
else {
for (i = 0; i < bc; i = i + 4, buf++) { /* by longwords */
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;
ma = ma + 4;
}
}
return 0;
}
int32 Map_ReadW (uint32 ba, int32 bc, uint16 *buf)
{
int32 i;
uint32 ma = ba & 0x3FFFFF;
uint32 dat;
ba = ba & ~01;
bc = bc & ~01;
if ((ba | bc) & 03) { /* check alignment */
for (i = 0; i < bc; i = i + 2, buf++) { /* by words */
*buf = ReadW (ma);
ma = ma + 2;
}
}
else {
for (i = 0; i < bc; i = i + 4, buf++) { /* by longwords */
dat = ReadL (ma); /* get lw */
*buf++ = dat & WMASK; /* low 16b */
*buf = (dat >> 16) & WMASK; /* high 16b */
ma = ma + 4;
}
}
return 0;
}
int32 Map_WriteB (uint32 ba, int32 bc, uint8 *buf)
{
int32 i;
uint32 ma = ba & 0x3FFFFF;
uint32 dat;
if ((ba | bc) & 03) { /* check alignment */
for (i = 0; i < bc; i++, buf++) { /* by bytes */
WriteB (ma, *buf);
ma = ma + 1;
}
}
else {
for (i = 0; i < bc; i = i + 4, buf++) { /* by longwords */
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 */
ma = ma + 4;
}
}
return 0;
}
int32 Map_WriteW (uint32 ba, int32 bc, uint16 *buf)
{
int32 i;
uint32 ma = ba & 0x3FFFFF;
uint32 dat;
ba = ba & ~01;
bc = bc & ~01;
if ((ba | bc) & 03) { /* check alignment */
for (i = 0; i < bc; i = i + 2, buf++) { /* by words */
WriteW (ma, *buf);
ma = ma + 2;
}
}
else {
for (i = 0; i < bc; i = i + 4, buf++) { /* by longwords */
dat = (uint32) *buf++; /* get low 16b */
dat = dat | (((uint32) *buf) << 16); /* merge hi 16b */
WriteL (ma, dat); /* store lw */
ma = ma + 4;
}
}
return 0;
}
/* Build dib_tab from device list */
t_stat build_dib_tab (void)
{
int32 i;
DEVICE *dptr;
DIB *dibp;
t_stat r;
init_ubus_tab (); /* init bus tables */
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 ((r = build_ubus_tab (dptr, dibp))) /* add to bus tab */
return r;
} /* end if enabled */
} /* end for */
return SCPE_OK;
}

112
VAX/vax610_mem.c Normal file
View file

@ -0,0 +1,112 @@
/* vax610_mem.c: MSV11-P memory controller
Copyright (c) 2011-2012, 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.
15-Feb-2012 MB First Version
*/
#include "vax_defs.h"
#define MAX_MCTL_COUNT 16
#define MCSR_PEN 0x0001 /* parity enable */
#define MCSR_WWP 0x0004 /* write wrong parity */
#define MCSR_ECR 0x4000 /* extended CSR read enable */
#define MCSR_RW (MCSR_ECR|MCSR_WWP|MCSR_PEN)
extern UNIT cpu_unit;
int32 mctl_csr[MAX_MCTL_COUNT];
int32 mctl_count = 0;
t_stat mctl_rd (int32 *data, int32 PA, int32 access);
t_stat mctl_wr (int32 data, int32 PA, int32 access);
t_stat mctl_reset (DEVICE *dptr);
/* MCTL data structures
mctl_dev MCTL device descriptor
mctl_unit MCTL unit list
mctl_reg MCTL register list
mctl_mod MCTL modifier list
*/
DIB mctl_dib = {
IOBA_MEM, IOLN_MEM, &mctl_rd, &mctl_wr,
1, 0, 0, { NULL }
};
UNIT mctl_unit[] = { UDATA (NULL, 0, 0) };
REG mctl_reg[] = {
{ DRDATA (COUNT, mctl_count, 16) },
{ BRDATA (CSR, mctl_csr, DEV_RDX, 16, MAX_MCTL_COUNT) },
{ NULL }
};
DEVICE mctl_dev = {
"MCTL", mctl_unit, mctl_reg, NULL,
1, DEV_RDX, 20, 1, DEV_RDX, 8,
NULL, NULL, &mctl_reset,
NULL, NULL, NULL,
&mctl_dib, DEV_Q18
};
/* I/O dispatch routines */
t_stat mctl_rd (int32 *data, int32 PA, int32 access)
{
int32 rg = (PA >> 1) & 0xF;
if (rg >= mctl_count)
return SCPE_NXM;
*data = mctl_csr[rg];
return SCPE_OK;
}
t_stat mctl_wr (int32 data, int32 PA, int32 access)
{
int32 rg = (PA >> 1) & 0xF;
if (rg >= mctl_count)
return SCPE_NXM;
mctl_csr[rg] = data & MCSR_RW;
return SCPE_OK;
}
t_stat mctl_reset (DEVICE *dptr)
{
int32 rg;
for (rg = 0; rg < MAX_MCTL_COUNT; rg++) {
mctl_csr[rg] = 0;
}
mctl_count = (int32)(MEMSIZE >> 18); /* memory controllers enabled */
return SCPE_OK;
}
/* Used by CPU */
void rom_wr_B (int32 pa, int32 val)
{
return;
}

423
VAX/vax610_stddev.c Normal file
View file

@ -0,0 +1,423 @@
/* vax610_stddev.c: MicroVAX I standard I/O devices
Copyright (c) 2011-2012, 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).
tti terminal input
tto terminal output
clk 100Hz clock
15-Feb-2012 MB First Version
*/
#include "vax_defs.h"
#include <time.h>
#define TTICSR_IMP (CSR_DONE + CSR_IE) /* terminal input */
#define TTICSR_RW (CSR_IE)
#define TTIBUF_ERR 0x8000 /* error */
#define TTIBUF_OVR 0x4000 /* overrun */
#define TTIBUF_FRM 0x2000 /* framing error */
#define TTIBUF_RBR 0x0400 /* receive break */
#define TTOCSR_IMP (CSR_DONE + CSR_IE) /* terminal output */
#define TTOCSR_RW (CSR_IE)
#define TXDB_V_SEL 8 /* unit select */
#define TXDB_M_SEL 0xF
#define TXDB_MISC 0xF /* console misc */
#define MISC_MASK 0xFF /* console data mask */
#define MISC_NOOP0 0x0 /* no operation */
#define MISC_NOOP1 0x1 /* no operation */
#define MISC_BOOT 0x2 /* reboot */
#define MISC_CLWS 0x3 /* clear warm start */
#define MISC_CLCS 0x4 /* clear cold start */
#define MISC_SWDN 0x5 /* software done */
#define MISC_LEDS0 0x8 /* LEDs 000 (all on) */
#define MISC_LEDS1 0x9 /* LEDs 001 (on, on, off) */
#define MISC_LEDS2 0xA /* LEDs 010 (on, off, on)*/
#define MISC_LEDS3 0xB /* LEDs 011 (on, off, off)*/
#define MISC_LEDS4 0xC /* LEDs 100 (off, on, on)*/
#define MISC_LEDS5 0xD /* LEDs 101 (off, on, off)*/
#define MISC_LEDS6 0xE /* LEDs 110 (off, off, on)*/
#define MISC_LEDS7 0xF /* LEDs 111 (all off)*/
#define TXDB_SEL (TXDB_M_SEL << TXDB_V_SEL) /* non-terminal */
#define TXDB_GETSEL(x) (((x) >> TXDB_V_SEL) & TXDB_M_SEL)
#define CLKCSR_IMP (CSR_IE) /* real-time clock */
#define CLKCSR_RW (CSR_IE)
#define CLK_DELAY 5000 /* 100 Hz */
#define TMXR_MULT 1 /* 100 Hz */
extern int32 int_req[IPL_HLVL];
extern int32 hlt_pin;
extern int32 sim_switches;
extern jmp_buf save_env;
extern int32 p1;
int32 tti_csr = 0; /* control/status */
int32 tto_csr = 0; /* control/status */
int32 tto_leds = 0; /* processor board LEDs */
int32 clk_csr = 0; /* control/status */
int32 clk_tps = 100; /* ticks/second */
int32 tmxr_poll = CLK_DELAY * TMXR_MULT; /* term mux poll */
int32 tmr_poll = CLK_DELAY; /* pgm timer poll */
t_stat tti_svc (UNIT *uptr);
t_stat tto_svc (UNIT *uptr);
t_stat clk_svc (UNIT *uptr);
t_stat tti_reset (DEVICE *dptr);
t_stat tto_reset (DEVICE *dptr);
t_stat clk_reset (DEVICE *dptr);
void txdb_func (int32 data);
extern int32 sysd_hlt_enb (void);
extern int32 con_halt (int32 code, int32 cc);
/* TTI data structures
tti_dev TTI device descriptor
tti_unit TTI unit descriptor
tti_reg TTI register list
*/
DIB tti_dib = { 0, 0, NULL, NULL, 1, IVCL (TTI), SCB_TTI, { NULL } };
UNIT tti_unit = { UDATA (&tti_svc, UNIT_IDLE|TT_MODE_8B, 0), 0 };
REG tti_reg[] = {
{ HRDATA (BUF, tti_unit.buf, 16) },
{ HRDATA (CSR, tti_csr, 16) },
{ FLDATA (INT, int_req[IPL_TTI], INT_V_TTI) },
{ FLDATA (DONE, tti_csr, CSR_V_DONE) },
{ FLDATA (IE, tti_csr, CSR_V_IE) },
{ DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tti_unit.wait, 24), PV_LEFT },
{ NULL }
};
MTAB tti_mod[] = {
{ TT_MODE, TT_MODE_7B, "7b", "7B", NULL },
{ TT_MODE, TT_MODE_8B, "8b", "8B", NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL,
NULL, &show_vec, NULL },
{ 0 }
};
DEVICE tti_dev = {
"TTI", &tti_unit, tti_reg, tti_mod,
1, 10, 31, 1, 16, 8,
NULL, NULL, &tti_reset,
NULL, NULL, NULL,
&tti_dib, 0
};
/* TTO data structures
tto_dev TTO device descriptor
tto_unit TTO unit descriptor
tto_reg TTO register list
*/
DIB tto_dib = { 0, 0, NULL, NULL, 1, IVCL (TTO), SCB_TTO, { NULL } };
UNIT tto_unit = { UDATA (&tto_svc, TT_MODE_8B, 0), SERIAL_OUT_WAIT };
REG tto_reg[] = {
{ HRDATA (BUF, tto_unit.buf, 8) },
{ HRDATA (CSR, tto_csr, 16) },
{ FLDATA (INT, int_req[IPL_TTO], INT_V_TTO) },
{ FLDATA (DONE, tto_csr, CSR_V_DONE) },
{ FLDATA (IE, tto_csr, CSR_V_IE) },
{ DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
{ NULL }
};
MTAB tto_mod[] = {
{ TT_MODE, TT_MODE_7B, "7b", "7B", NULL },
{ TT_MODE, TT_MODE_8B, "8b", "8B", NULL },
{ TT_MODE, TT_MODE_7P, "7p", "7P", NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL, NULL, &show_vec },
{ 0 }
};
DEVICE tto_dev = {
"TTO", &tto_unit, tto_reg, tto_mod,
1, 10, 31, 1, 16, 8,
NULL, NULL, &tto_reset,
NULL, NULL, NULL,
&tto_dib, 0
};
/* CLK data structures
clk_dev CLK device descriptor
clk_unit CLK unit descriptor
clk_reg CLK register list
*/
DIB clk_dib = { 0, 0, NULL, NULL, 1, IVCL (CLK), SCB_INTTIM, { NULL } };
UNIT clk_unit = { UDATA (&clk_svc, UNIT_IDLE, 0), CLK_DELAY };
REG clk_reg[] = {
{ HRDATA (CSR, clk_csr, 16) },
{ FLDATA (INT, int_req[IPL_CLK], INT_V_CLK) },
{ FLDATA (IE, clk_csr, CSR_V_IE) },
{ DRDATA (TIME, clk_unit.wait, 24), REG_NZ + PV_LEFT },
{ DRDATA (TPS, clk_tps, 8), REG_NZ + PV_LEFT },
{ NULL }
};
DEVICE clk_dev = {
"CLK", &clk_unit, clk_reg, NULL,
1, 0, 0, 0, 0, 0,
NULL, NULL, &clk_reset,
NULL, NULL, NULL,
&clk_dib, 0
};
/* Clock and terminal MxPR routines
iccs_rd/wr interval timer
rxcs_rd/wr input control/status
rxdb_rd input buffer
txcs_rd/wr output control/status
txdb_wr output buffer
*/
int32 iccs_rd (void)
{
return (clk_csr & CLKCSR_IMP);
}
int32 rxcs_rd (void)
{
return (tti_csr & TTICSR_IMP);
}
int32 rxdb_rd (void)
{
int32 t = tti_unit.buf; /* char + error */
tti_csr = tti_csr & ~CSR_DONE; /* clr done */
tti_unit.buf = tti_unit.buf & 0377; /* clr errors */
CLR_INT (TTI);
return t;
}
int32 txcs_rd (void)
{
return (tto_csr & TTOCSR_IMP);
}
void iccs_wr (int32 data)
{
if ((data & CSR_IE) == 0)
CLR_INT (CLK);
clk_csr = (clk_csr & ~CLKCSR_RW) | (data & CLKCSR_RW);
return;
}
void rxcs_wr (int32 data)
{
if ((data & CSR_IE) == 0)
CLR_INT (TTI);
else if ((tti_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
SET_INT (TTI);
tti_csr = (tti_csr & ~TTICSR_RW) | (data & TTICSR_RW);
return;
}
void txcs_wr (int32 data)
{
if ((data & CSR_IE) == 0)
CLR_INT (TTO);
else if ((tto_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
SET_INT (TTO);
tto_csr = (tto_csr & ~TTOCSR_RW) | (data & TTOCSR_RW);
return;
}
void txdb_wr (int32 data)
{
if (data & TXDB_SEL) { /* internal function? */
txdb_func (data);
return;
}
tto_unit.buf = data & 0377;
tto_csr = tto_csr & ~CSR_DONE;
CLR_INT (TTO);
sim_activate (&tto_unit, tto_unit.wait);
return;
}
void txdb_func (int32 data)
{
int32 sel = TXDB_GETSEL (data); /* get selection */
if (sel == TXDB_MISC) { /* misc function? */
switch (data & MISC_MASK) { /* case on function */
case MISC_SWDN:
ABORT (STOP_SWDN);
break;
case MISC_BOOT:
con_halt (0, 0); /* set up reboot */
break;
case MISC_LEDS0: case MISC_LEDS1: case MISC_LEDS2: case MISC_LEDS3:
case MISC_LEDS4: case MISC_LEDS5: case MISC_LEDS6: case MISC_LEDS7:
tto_leds = 0x7 & (~((data & MISC_MASK)-MISC_LEDS0));
sim_putchar ('.');
sim_putchar ('0' + tto_leds);
sim_putchar ('.');
break;
}
}
else
if (sel != 0)
RSVD_OPND_FAULT;
}
t_stat cpu_show_leds (FILE *st, UNIT *uptr, int32 val, void *desc)
{
fprintf (st, "leds=%d(%s,%s,%s)", tto_leds, tto_leds&4 ? "ON" : "OFF",
tto_leds&2 ? "ON" : "OFF",
tto_leds&1 ? "ON" : "OFF");
return SCPE_OK;
}
/* Terminal input routines
tti_svc process event (character ready)
tti_reset process reset
*/
t_stat tti_svc (UNIT *uptr)
{
int32 c;
sim_activate (uptr, KBD_WAIT (uptr->wait, tmr_poll)); /* continue poll */
if ((c = sim_poll_kbd ()) < SCPE_KFLAG) /* no char or error? */
return c;
if (c & SCPE_BREAK) { /* break? */
if (sysd_hlt_enb ()) /* if enabled, halt */
hlt_pin = 1;
tti_unit.buf = TTIBUF_ERR | TTIBUF_FRM | TTIBUF_RBR;
}
else tti_unit.buf = sim_tt_inpcvt (c, TT_GET_MODE (uptr->flags));
uptr->pos = uptr->pos + 1;
tti_csr = tti_csr | CSR_DONE;
if (tti_csr & CSR_IE)
SET_INT (TTI);
return SCPE_OK;
}
t_stat tti_reset (DEVICE *dptr)
{
tti_unit.buf = 0;
tti_csr = 0;
CLR_INT (TTI);
sim_activate_abs (&tti_unit, KBD_WAIT (tti_unit.wait, tmr_poll));
return SCPE_OK;
}
/* Terminal output routines
tto_svc process event (character typed)
tto_reset process reset
*/
t_stat tto_svc (UNIT *uptr)
{
int32 c;
t_stat r;
c = sim_tt_outcvt (tto_unit.buf, TT_GET_MODE (uptr->flags));
if (c >= 0) {
if ((r = sim_putchar_s (c)) != SCPE_OK) { /* output; error? */
sim_activate (uptr, uptr->wait); /* retry */
return ((r == SCPE_STALL)? SCPE_OK: r); /* !stall? report */
}
}
tto_csr = tto_csr | CSR_DONE;
if (tto_csr & CSR_IE)
SET_INT (TTO);
uptr->pos = uptr->pos + 1;
return SCPE_OK;
}
t_stat tto_reset (DEVICE *dptr)
{
tto_unit.buf = 0;
tto_csr = CSR_DONE;
CLR_INT (TTO);
sim_cancel (&tto_unit); /* deactivate unit */
return SCPE_OK;
}
/* Clock routines
clk_svc process event (clock tick)
clk_reset process reset
*/
t_stat clk_svc (UNIT *uptr)
{
int32 t;
if (clk_csr & CSR_IE)
SET_INT (CLK);
t = sim_rtcn_calb (clk_tps, TMR_CLK); /* calibrate clock */
sim_activate (&clk_unit, t); /* reactivate unit */
tmr_poll = t; /* set tmr poll */
tmxr_poll = t * TMXR_MULT; /* set mux poll */
return SCPE_OK;
}
/* Clock coscheduling routine */
int32 clk_cosched (int32 wait)
{
int32 t;
t = sim_activate_time (&clk_unit);
return (t? t - 1: wait);
}
/* Reset routine */
t_stat clk_reset (DEVICE *dptr)
{
int32 t;
clk_csr = 0;
CLR_INT (CLK);
t = sim_rtcn_init (clk_unit.wait, TMR_CLK); /* init timer */
sim_activate_abs (&clk_unit, t); /* activate unit */
tmr_poll = t; /* set tmr poll */
tmxr_poll = t * TMXR_MULT; /* set mux poll */
return SCPE_OK;
}

496
VAX/vax610_sysdev.c Normal file
View file

@ -0,0 +1,496 @@
/* vax610_sysdev.c: MicroVAX I system-specific logic
Copyright (c) 2011-2012, 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).
This module contains the MicroVAX I system-specific registers and devices.
sysd system devices
15-Feb-2012 MB First Version
*/
#include "vax_defs.h"
#include <time.h>
#ifdef DONT_USE_INTERNAL_ROM
#define BOOT_CODE_FILENAME "ka610.bin"
#else /* !DONT_USE_INTERNAL_ROM */
#include "vax_ka610_bin.h" /* Defines BOOT_CODE_FILENAME and BOOT_CODE_ARRAY, etc */
#endif /* DONT_USE_INTERNAL_ROM */
/* MicroVAX I boot device definitions */
struct boot_dev {
char *devname;
char *devalias;
int32 code;
};
extern int32 R[16];
extern int32 in_ie;
extern int32 mchk_va, mchk_ref;
extern int32 int_req[IPL_HLVL];
extern jmp_buf save_env;
extern int32 p1;
extern int32 sim_switches;
extern FILE *sim_log;
extern CTAB *sim_vm_cmd;
extern int32 trpirq, mem_err;
int32 conisp, conpc, conpsl; /* console reg */
char cpu_boot_cmd[CBUFSIZE] = { 0 }; /* boot command */
static struct boot_dev boot_tab[] = {
{ "RQ", "DUA", 0x00415544 }, /* DUAn */
{ "RQ", "DU", 0x00415544 }, /* DUAn */
{ "XQ", "XQA", 0x00415158 }, /* XQAn */
{ NULL }
};
t_stat sysd_reset (DEVICE *dptr);
t_stat vax610_boot (int32 flag, char *ptr);
t_stat vax610_boot_parse (int32 flag, char *ptr);
t_stat cpu_boot (int32 unitno, DEVICE *dptr);
extern int32 intexc (int32 vec, int32 cc, int32 ipl, int ei);
extern int32 iccs_rd (void);
extern int32 todr_rd (void);
extern int32 rxcs_rd (void);
extern int32 rxdb_rd (void);
extern int32 txcs_rd (void);
extern void iccs_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 ioreset_wr (int32 dat);
extern int32 eval_int (void);
/* SYSD data structures
sysd_dev SYSD device descriptor
sysd_unit SYSD units
sysd_reg SYSD register list
*/
UNIT sysd_unit = { UDATA (NULL, 0, 0) };
REG sysd_reg[] = {
{ HRDATA (CONISP, conisp, 32) },
{ HRDATA (CONPC, conpc, 32) },
{ HRDATA (CONPSL, conpsl, 32) },
{ BRDATA (BOOTCMD, cpu_boot_cmd, 16, 8, CBUFSIZE), REG_HRO },
{ NULL }
};
DEVICE sysd_dev = {
"SYSD", &sysd_unit, sysd_reg, NULL,
1, 16, 16, 1, 16, 8,
NULL, NULL, &sysd_reset,
NULL, NULL, NULL,
NULL, 0
};
/* Special boot command, overrides regular boot */
CTAB vax610_cmd[] = {
{ "BOOT", &vax610_boot, RU_BOOT,
"bo{ot} <device>{/R5:flg} boot device\n", &run_cmd_message },
{ NULL }
};
/* Read KA610 specific IPR's */
int32 ReadIPR (int32 rg)
{
int32 val;
switch (rg) {
case MT_ICCS: /* ICCS */
val = iccs_rd ();
break;
case MT_RXCS: /* RXCS */
val = rxcs_rd ();
break;
case MT_RXDB: /* RXDB */
val = rxdb_rd ();
break;
case MT_TXCS: /* TXCS */
val = txcs_rd ();
break;
case MT_TXDB: /* TXDB */
val = 0;
break;
case MT_CONISP: /* console ISP */
val = conisp;
break;
case MT_CONPC: /* console PC */
val = conpc;
break;
case MT_CONPSL: /* console PSL */
val = conpsl;
break;
case MT_SID: /* SID */
val = (VAX610_SID | VAX610_FLOAT | VAX610_MREV | VAX610_HWREV);
break;
case MT_NICR: /* NICR */
case MT_ICR: /* ICR */
case MT_TODR: /* TODR */
case MT_CSRS: /* CSRS */
case MT_CSRD: /* CSRD */
case MT_CSTS: /* CSTS */
case MT_CSTD: /* CSTD */
case MT_TBDR: /* TBDR */
case MT_CADR: /* CADR */
case MT_MCESR: /* MCESR */
case MT_CAER: /* CAER */
case MT_SBIFS: /* SBIFS */
case MT_SBIS: /* SBIS */
case MT_SBISC: /* SBISC */
case MT_SBIMT: /* SBIMT */
case MT_SBIER: /* SBIER */
case MT_SBITA: /* SBITA */
case MT_SBIQC: /* SBIQC */
case MT_TBDATA: /* TBDATA */
case MT_MBRK: /* MBRK */
case MT_PME: /* PME */
val = 0;
break;
default:
RSVD_OPND_FAULT;
}
return val;
}
/* Write KA610 specific IPR's */
void WriteIPR (int32 rg, int32 val)
{
switch (rg) {
case MT_ICCS: /* ICCS */
iccs_wr (val);
break;
case MT_RXCS: /* RXCS */
rxcs_wr (val);
break;
case MT_RXDB: /* RXDB */
break;
case MT_TXCS: /* TXCS */
txcs_wr (val);
break;
case MT_TXDB: /* TXDB */
txdb_wr (val);
break;
case MT_IORESET: /* IORESET */
ioreset_wr (val);
break;
case MT_SID:
case MT_CONISP:
case MT_CONPC:
case MT_CONPSL: /* halt reg */
RSVD_OPND_FAULT;
case MT_NICR: /* NICR */
case MT_ICR: /* ICR */
case MT_TODR: /* TODR */
case MT_CSRS: /* CSRS */
case MT_CSRD: /* CSRD */
case MT_CSTS: /* CSTS */
case MT_CSTD: /* CSTD */
case MT_TBDR: /* TBDR */
case MT_CADR: /* CADR */
case MT_MCESR: /* MCESR */
case MT_CAER: /* CAER */
case MT_SBIFS: /* SBIFS */
case MT_SBIS: /* SBIS */
case MT_SBISC: /* SBISC */
case MT_SBIMT: /* SBIMT */
case MT_SBIER: /* SBIER */
case MT_SBITA: /* SBITA */
case MT_SBIQC: /* SBIQC */
case MT_TBDATA: /* TBDATA */
case MT_MBRK: /* MBRK */
case MT_PME: /* PME */
break;
default:
RSVD_OPND_FAULT;
}
return;
}
/* Read/write I/O register space
These routines are the 'catch all' for address space map. Any
address that doesn't explicitly belong to memory or I/O
is given to these routines for processing.
*/
struct reglink { /* register linkage */
uint32 low; /* low addr */
uint32 high; /* high addr */
t_stat (*read)(int32 pa); /* read routine */
void (*write)(int32 pa, int32 val, int32 lnt); /* write routine */
};
struct reglink regtable[] = {
/* { QVMBASE, QVMBASE+QVMSIZE, &qv_mem_rd, &qv_mem_wr }, */
{ 0, 0, NULL, NULL }
};
/* ReadReg - read register space
Inputs:
pa = physical address
lnt = length (BWLQ) - ignored
Output:
longword of data
*/
int32 ReadReg (uint32 pa, int32 lnt)
{
struct reglink *p;
for (p = &regtable[0]; p->low != 0; p++) {
if ((pa >= p->low) && (pa < p->high) && p->read)
return p->read (pa);
}
MACH_CHECK (MCHK_READ);
}
/* 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)
{
struct reglink *p;
for (p = &regtable[0]; p->low != 0; p++) {
if ((pa >= p->low) && (pa < p->high) && p->write) {
p->write (pa, val, lnt);
return;
}
}
mem_err = 1;
SET_IRQL;
}
/* 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 vax610_boot (int32 flag, char *ptr)
{
t_stat r;
r = vax610_boot_parse (flag, ptr); /* parse the boot cmd */
if (r != SCPE_OK) /* error? */
return r;
strncpy (cpu_boot_cmd, ptr, CBUFSIZE); /* save for reboot */
return run_cmd (flag, "CPU");
}
/* Parse boot command, set up registers - also used on reset */
t_stat vax610_boot_parse (int32 flag, char *ptr)
{
char gbuf[CBUFSIZE], dbuf[CBUFSIZE], rbuf[CBUFSIZE];
char *slptr, *regptr;
int32 i, r5v, unitno;
DEVICE *dptr;
UNIT *uptr;
t_stat r;
if (ptr && (*ptr == '/')) { /* handle "BOOT /R5:n DEV" format */
ptr = get_glyph (ptr, rbuf, 0); /* get glyph */
regptr = rbuf;
ptr = get_glyph (ptr, gbuf, 0); /* get glyph */
}
else { /* handle "BOOT DEV /R5:n" format */
regptr = get_glyph (ptr, gbuf, 0); /* get glyph */
if ((slptr = strchr (gbuf, '/'))) { /* found slash? */
regptr = strchr (ptr, '/'); /* locate orig */
*slptr = 0; /* zero in string */
}
}
/* parse R5 parameter value */
r5v = 0;
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 == '/') {
r5v = (int32) get_uint (regptr + 1, 16, LMASK, &r);
if (r != SCPE_OK)
return r;
}
else if (*regptr != 0)
return SCPE_ARG;
if (gbuf[0]) {
unitno = -1;
for (i = 0; boot_tab[i].devname != NULL; i++) {
if (memcmp (gbuf, boot_tab[i].devalias, strlen(boot_tab[i].devalias)) == 0) {
sprintf(dbuf, "%s%s", boot_tab[i].devname, gbuf + strlen(boot_tab[i].devalias));
dptr = find_unit (dbuf, &uptr);
if ((dptr == NULL) || (uptr == NULL))
return SCPE_ARG;
unitno = (int32) (uptr - dptr->units);
}
if ((unitno == -1) &&
(memcmp (gbuf, boot_tab[i].devname, strlen(boot_tab[i].devname)) == 0)) {
sprintf(dbuf, "%s%s", boot_tab[i].devname, gbuf + strlen(boot_tab[i].devname));
dptr = find_unit (dbuf, &uptr);
if ((dptr == NULL) || (uptr == NULL))
return SCPE_ARG;
unitno = (int32) (uptr - dptr->units);
}
if (unitno == -1)
continue;
R[0] = boot_tab[i].code | (('0' + unitno) << 24);
R[1] = 0xC0;
R[2] = 0;
R[3] = 0;
R[4] = 0;
R[5] = r5v;
return SCPE_OK;
}
}
else {
R[0] = 0;
R[1] = 0xC0;
R[2] = 0;
R[3] = 0;
R[4] = 0;
R[5] = r5v;
return SCPE_OK;
}
return SCPE_NOFNC;
}
int32 sysd_hlt_enb (void)
{
return 1;
}
/* Machine check */
int32 machine_check (int32 p1, int32 opc, int32 cc, int32 delta)
{
int32 p2, acc;
p2 = mchk_va + 4; /* save vap */
cc = intexc (SCB_MCHK, cc, 0, IE_EXC); /* take exception */
acc = ACC_MASK (KERN); /* in kernel mode */
in_ie = 1;
SP = SP - 16; /* push 4 words */
Write (SP, 12, L_LONG, WA); /* # bytes */
Write (SP + 4, p1, L_LONG, WA); /* mcheck type */
Write (SP + 8, p2, L_LONG, WA); /* parameter 1 */
Write (SP + 12, p2, L_LONG, WA); /* parameter 2 */
in_ie = 0;
return cc;
}
/* Console entry */
int32 con_halt (int32 code, int32 cc)
{
if ((cpu_boot_cmd[0] == 0) || /* saved boot cmd? */
(vax610_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? */
printf ("Rebooting...\n");
if (sim_log)
fprintf (sim_log, "Rebooting...\n");
return cc;
}
/* Bootstrap */
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;
AP = 1;
return SCPE_OK;
}
/* SYSD reset */
t_stat sysd_reset (DEVICE *dptr)
{
sim_vm_cmd = vax610_cmd;
return SCPE_OK;
}
t_stat cpu_set_model (UNIT *uptr, int32 val, char *cptr, void *desc)
{
return SCPE_NOFNC;
}
t_stat cpu_show_model (FILE *st, UNIT *uptr, int32 val, void *desc)
{
fprintf (st, "model=MicroVAX I");
return SCPE_OK;
}

114
VAX/vax610_syslist.c Normal file
View file

@ -0,0 +1,114 @@
/* vax610_syslist.c: MicroVAX I device list
Copyright (c) 2011-2012, 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).
15-Feb-2012 MB First version
*/
#include "vax_defs.h"
char sim_name[] = "VAX610";
extern DEVICE cpu_dev;
extern DEVICE mctl_dev;
extern DEVICE tlb_dev;
extern DEVICE sysd_dev;
extern DEVICE qba_dev;
extern DEVICE tti_dev, tto_dev;
extern DEVICE cr_dev;
extern DEVICE lpt_dev;
extern DEVICE clk_dev;
extern DEVICE rq_dev, rqb_dev, rqc_dev, rqd_dev;
extern DEVICE rl_dev;
extern DEVICE ry_dev;
extern DEVICE ts_dev;
extern DEVICE tq_dev;
extern DEVICE dz_dev;
extern DEVICE xq_dev, xqb_dev;
extern DEVICE vh_dev;
extern int32 sim_switches;
extern void WriteB (uint32 pa, int32 val);
extern UNIT cpu_unit;
DEVICE *sim_devices[] = {
&cpu_dev,
&mctl_dev,
&tlb_dev,
&sysd_dev,
&qba_dev,
&clk_dev,
&tti_dev,
&tto_dev,
&dz_dev,
&vh_dev,
&cr_dev,
&lpt_dev,
&rl_dev,
&rq_dev,
&rqb_dev,
&rqc_dev,
&rqd_dev,
&ry_dev,
&ts_dev,
&tq_dev,
&xq_dev,
&xqb_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, char *cptr, char *fnam, int flag)
{
t_stat r;
int32 i;
uint32 origin, limit;
if (flag) /* dump? */
return SCPE_ARG;
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 ((i = getc (fileref)) != EOF) { /* read byte stream */
if (origin >= limit) /* NXM? */
return SCPE_NXM;
else WriteB (origin, i); /* store byte */
origin = origin + 1;
}
return SCPE_OK;
}

439
VAX/vax630_defs.h Normal file
View file

@ -0,0 +1,439 @@
/* vax630_defs.h: MicroVAX II model-specific definitions file
Copyright (c) 2009-2012, 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).
08-Nov-12 MB First version
This file covers the KA630 ("Mayflower") Qbus system.
System memory map
0000 0000 - 00FF FFFF main memory
0100 0000 - 1FFF FFFF reserved
2000 0000 - 2000 1FFF Qbus I/O page
2004 0000 - 2004 FFFF ROM space, halt protected
2005 0000 - 2005 FFFF ROM space, halt unprotected
2008 0000 - 2008 000F Local register space
2008 8000 - 2008 FFFF Qbus mapping registers
200B 8000 - 200B 80FF Watch chip registers
3000 0000 - 303F FFFF Qbus memory space
3400 0000 - 3FFF FFFF reserved
*/
#ifdef FULL_VAX /* subset VAX */
#undef FULL_VAX
#endif
#ifndef _VAX_630_DEFS_H_
#define _VAX_630_DEFS_H_ 1
/* Microcode constructs */
#define VAX620_SID (16 << 24) /* system ID */
#define VAX630_SID (8 << 24) /* system ID */
#define CON_HLTPIN 0x0200 /* external CPU halt */
#define CON_PWRUP 0x0300 /* powerup code */
#define CON_HLTINS 0x0600 /* HALT instruction */
#define CON_DBLMCK 0x0500 /* Machine check in machine check */
#define CON_BADPSL 0x4000 /* invalid PSL flag */
#define CON_MAPON 0x8000 /* mapping on flag */
#define MCHK_TBM_P0 0x05 /* PPTE in P0 */
#define MCHK_TBM_P1 0x06 /* PPTE in P1 */
#define MCHK_M0_P0 0x07 /* PPTE in P0 */
#define MCHK_M0_P1 0x08 /* PPTE in P1 */
#define MCHK_INTIPL 0x09 /* invalid ireq */
#define MCHK_READ 0x80 /* read check */
#define MCHK_WRITE 0x82 /* write check */
/* Machine specific IPRs */
#define MT_TBDR 36 /* Translation Buffer Disable */
#define MT_CADR 37 /* Cache Disable Register */
#define MT_MCESR 38 /* Machine Check Error Summary */
#define MT_CAER 39 /* Cache Error Register */
#define MT_CONISP 41 /* Console Saved ISP */
#define MT_CONPC 42 /* Console Saved PC */
#define MT_CONPSL 43 /* Console Saved PSL */
#define MT_SBIFS 48 /* SBI fault status */
#define MT_SBIS 49 /* SBI silo */
#define MT_SBISC 50 /* SBI silo comparator */
#define MT_SBIMT 51 /* SBI maint */
#define MT_SBIER 52 /* SBI error */
#define MT_SBITA 53 /* SBI timeout addr */
#define MT_SBIQC 54 /* SBI timeout clear */
#define MT_IORESET 55 /* I/O Bus Reset */
#define MT_TBDATA 59 /* Translation Buffer Data */
#define MT_MBRK 60 /* microbreak */
/* CPU */
#define CPU_MODEL_MODIFIERS \
{ MTAB_XTD|MTAB_VDV, 0, "MODEL", NULL, \
NULL, &cpu_show_model },
/* Memory */
#define MAXMEMWIDTH 24 /* max mem, std KA655 */
#define MAXMEMSIZE (1 << MAXMEMWIDTH) /* max mem size */
#define MAXMEMWIDTH_X 24 /* max mem, KA655X */
#define MAXMEMSIZE_X (1 << MAXMEMWIDTH_X)
#define INITMEMSIZE (1 << 24) /* initial memory size */
#define MEMSIZE (cpu_unit.capac)
#define ADDR_IS_MEM(x) (((uint32) (x)) < MEMSIZE)
#define MEM_MODIFIERS { UNIT_MSIZE, (1u << 20), NULL, "1M", &cpu_set_size }, \
{ UNIT_MSIZE, (1u << 21), NULL, "2M", &cpu_set_size }, \
{ UNIT_MSIZE, (1u << 22), NULL, "4M", &cpu_set_size }, \
{ UNIT_MSIZE, (1u << 23), NULL, "8M", &cpu_set_size }, \
{ UNIT_MSIZE, (1u << 23) + (1u << 22), NULL, "12M", &cpu_set_size }, \
{ UNIT_MSIZE, (1u << 24), NULL, "16M", &cpu_set_size }
/* Qbus I/O page */
#define IOPAGEAWIDTH 13 /* IO addr width */
#define IOPAGESIZE (1u << IOPAGEAWIDTH) /* IO page length */
#define IOPAGEMASK (IOPAGESIZE - 1) /* IO addr mask */
#define IOPAGEBASE 0x20000000 /* IO page base */
#define ADDR_IS_IO(x) ((((uint32) (x)) >= IOPAGEBASE) && \
(((uint32) (x)) < (IOPAGEBASE + IOPAGESIZE)))
/* Read only memory - appears twice */
#define ROMAWIDTH 16 /* ROM addr width */
#define ROMSIZE (1u << ROMAWIDTH) /* ROM length */
#define ROMAMASK (ROMSIZE - 1) /* ROM addr mask */
#define ROMBASE 0x20040000 /* ROM base */
#define ADDR_IS_ROM(x) ((((uint32) (x)) >= ROMBASE) && \
(((uint32) (x)) < (ROMBASE + ROMSIZE + ROMSIZE)))
/* KA630 board registers */
#define KAAWIDTH 4 /* REG addr width */
#define KASIZE (1u << KAAWIDTH) /* REG length */
#define KABASE 0x20080000 /* REG addr base */
/* Qbus map registers */
#define QBMAPAWIDTH 15 /* map addr width */
#define QBMAPSIZE (1u << QBMAPAWIDTH) /* map length */
#define QBMAPAMASK (QBMAPSIZE - 1) /* map addr mask */
#define QBMAPBASE 0x20088000 /* map addr base */
/* Non-volatile RAM - 128 Bytes long */
#define NVRAWIDTH 7 /* NVR addr width */
#define NVRSIZE (1u << NVRAWIDTH) /* NVR length */
#define NVRAMASK (NVRSIZE - 1) /* NVR addr mask */
#define NVRBASE 0x200B8000 /* NVR base */
#define ADDR_IS_NVR(x) ((((uint32) (x)) >= NVRBASE) && \
(((uint32) (x)) < (NVRBASE + NVRSIZE)))
/* Qbus memory space */
#define QBMAWIDTH 22 /* Qmem addr width */
#define QBMSIZE (1u << QBMAWIDTH) /* Qmem length */
#define QBMAMASK (QBMSIZE - 1) /* Qmem addr mask */
#define QBMBASE 0x30000000 /* Qmem base */
#define ADDR_IS_QBM(x) ((((uint32) (x)) >= QBMBASE) && \
(((uint32) (x)) < (QBMBASE + QBMSIZE)))
/* Other address spaces */
#define ADDR_IS_CDG(x) (0)
/* 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)
/* Qbus 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 DZ_LINES 4 /* lines per DZV mux */
#define VH_MUXES 4 /* max # of DHQ muxes */
#define DLX_LINES 16 /* max # of KL11/DL11's */
#define DCX_LINES 16 /* max # of DC11's */
#define MT_MAXFR (1 << 16) /* magtape max rec */
#define AUTO_LNT 34 /* autoconfig ranks */
#define DEV_V_UBUS (DEV_V_UF + 0) /* Unibus */
#define DEV_V_QBUS (DEV_V_UF + 1) /* Qbus */
#define DEV_V_Q18 (DEV_V_UF + 2) /* Qbus, mem <= 256KB */
#define DEV_V_FLTA (DEV_V_UF + 3) /* flt addr */
#define DEV_UBUS (1u << DEV_V_UBUS)
#define DEV_QBUS (1u << DEV_V_QBUS)
#define DEV_Q18 (1u << DEV_V_Q18)
#define DEV_FLTA (1u << DEV_V_FLTA)
#define UNIBUS FALSE /* 22b only */
#define DEV_RDX 16 /* default device radix */
/* Device information block */
#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 */
} DIB;
/* I/O page layout - RQB,RQC,RQD float based on number of DZ's */
#define IOBA_DZ (IOPAGEBASE + 000100) /* DZ11 */
#define IOLN_DZ 010
#define IOBA_RQB (IOPAGEBASE + 000334 + (020 * (DZ_MUXES / 2)))
#define IOLN_RQB 004
#define IOBA_RQC (IOPAGEBASE + IOBA_RQB + IOLN_RQB)
#define IOLN_RQC 004
#define IOBA_RQD (IOPAGEBASE + IOBA_RQC + IOLN_RQC)
#define IOLN_RQD 004
#define IOBA_VH (IOPAGEBASE + 000440) /* DHQ11 */
#define IOLN_VH 020
#define IOBA_RQ (IOPAGEBASE + 012150) /* RQDX3 */
#define IOLN_RQ 004
#define IOBA_TS (IOPAGEBASE + 012520) /* TS11 */
#define IOLN_TS 004
#define IOBA_RL (IOPAGEBASE + 014400) /* RL11 */
#define IOLN_RL 012
#define IOBA_XQ (IOPAGEBASE + 014440) /* DEQNA/DELQA */
#define IOLN_XQ 020
#define IOBA_XQB (IOPAGEBASE + 014460) /* 2nd DEQNA/DELQA */
#define IOLN_XQB 020
#define IOBA_TQ (IOPAGEBASE + 014500) /* TMSCP */
#define IOLN_TQ 004
#define IOBA_XU (IOPAGEBASE + 014510) /* DEUNA/DELUA */
#define IOLN_XU 010
#define IOBA_RP (IOPAGEBASE + 016700) /* RP/RM */
#define IOLN_RP 054
#define IOBA_CR (IOPAGEBASE + 017160) /* CD/CR/CM */
#define IOLN_CR 010
#define IOBA_RX (IOPAGEBASE + 017170) /* RXV11 */
#define IOLN_RX 004
#define IOBA_RY (IOPAGEBASE + 017170) /* RXV21 */
#define IOLN_RY 004
#define IOBA_QVSS (IOPAGEBASE + 017200) /* QVSS */
#define IOLN_QVSS 0100
#define IOBA_QDSS (IOPAGEBASE + 017400) /* QDSS */
#define IOLN_QDSS 002
#define IOBA_DBL (IOPAGEBASE + 017500) /* doorbell */
#define IOLN_DBL 002
#define IOBA_LPT (IOPAGEBASE + 017514) /* LP11 */
#define IOLN_LPT 004
#define IOBA_PTR (IOPAGEBASE + 017550) /* PC11 reader */
#define IOLN_PTR 004
#define IOBA_PTP (IOPAGEBASE + 017554) /* PC11 punch */
#define IOLN_PTP 004
/* The KA620/KA630 maintains 4 separate hardware IPL levels, IPL 17 to IPL 14;
however, DEC Qbus controllers all interrupt on IPL 14
Within each IPL, priority is right to left
*/
/* IPL 17 */
/* IPL 16 */
#define INT_V_CLK 0 /* clock */
/* IPL 15 */
/* IPL 14 - devices through RY are IPL 15 on Unibus systems */
#define INT_V_RQ 0 /* RQDX3 */
#define INT_V_RL 1 /* RLV12/RL02 */
#define INT_V_DZRX 2 /* DZ11 */
#define INT_V_DZTX 3
#define INT_V_TS 4 /* TS11/TSV05 */
#define INT_V_TQ 5 /* TMSCP */
#define INT_V_XQ 6 /* DEQNA/DELQA */
#define INT_V_RY 7 /* RXV21 */
#define INT_V_TTI 8 /* console */
#define INT_V_TTO 9
#define INT_V_PTR 10 /* PC11 */
#define INT_V_PTP 11
#define INT_V_LPT 12 /* LP11 */
#define INT_V_CSI 13 /* SSC cons UART */
#define INT_V_CSO 14
#define INT_V_TMR0 15 /* SSC timers */
#define INT_V_TMR1 16
#define INT_V_VHRX 17 /* DHQ11 */
#define INT_V_VHTX 18
#define INT_V_QDSS 19 /* QDSS */
#define INT_V_CR 20
#define INT_V_QVSS 21 /* QVSS */
#define INT_CLK (1u << INT_V_CLK)
#define INT_RQ (1u << INT_V_RQ)
#define INT_RL (1u << INT_V_RL)
#define INT_DZRX (1u << INT_V_DZRX)
#define INT_DZTX (1u << INT_V_DZTX)
#define INT_TS (1u << INT_V_TS)
#define INT_TQ (1u << INT_V_TQ)
#define INT_XQ (1u << INT_V_XQ)
#define INT_RY (1u << INT_V_RY)
#define INT_TTI (1u << INT_V_TTI)
#define INT_TTO (1u << INT_V_TTO)
#define INT_PTR (1u << INT_V_PTR)
#define INT_PTP (1u << INT_V_PTP)
#define INT_LPT (1u << INT_V_LPT)
#define INT_CSI (1u << INT_V_CSI)
#define INT_CSO (1u << INT_V_CSO)
#define INT_TMR0 (1u << INT_V_TMR0)
#define INT_TMR1 (1u << INT_V_TMR1)
#define INT_VHRX (1u << INT_V_VHRX)
#define INT_VHTX (1u << INT_V_VHTX)
#define INT_QDSS (1u << INT_V_QDSS)
#define INT_CR (1u << INT_V_CR)
#define INT_QVSS (1u << INT_V_QVSS)
#define IPL_CLK (0x16 - IPL_HMIN) /* relative IPL */
#define IPL_RQ (0x14 - IPL_HMIN)
#define IPL_RL (0x14 - IPL_HMIN)
#define IPL_DZRX (0x14 - IPL_HMIN)
#define IPL_DZTX (0x14 - IPL_HMIN)
#define IPL_TS (0x14 - IPL_HMIN)
#define IPL_TQ (0x14 - IPL_HMIN)
#define IPL_XQ (0x14 - IPL_HMIN)
#define IPL_RY (0x14 - IPL_HMIN)
#define IPL_TTI (0x14 - IPL_HMIN)
#define IPL_TTO (0x14 - IPL_HMIN)
#define IPL_PTR (0x14 - IPL_HMIN)
#define IPL_PTP (0x14 - IPL_HMIN)
#define IPL_LPT (0x14 - IPL_HMIN)
#define IPL_CSI (0x14 - IPL_HMIN)
#define IPL_CSO (0x14 - IPL_HMIN)
#define IPL_TMR0 (0x14 - IPL_HMIN)
#define IPL_TMR1 (0x14 - IPL_HMIN)
#define IPL_VHRX (0x14 - IPL_HMIN)
#define IPL_VHTX (0x14 - IPL_HMIN)
#define IPL_QDSS (0x14 - IPL_HMIN)
#define IPL_CR (0x14 - IPL_HMIN)
#define IPL_QVSS (0x14 - IPL_HMIN)
#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 */
/* Device vectors */
#define VEC_QBUS 1 /* Qbus system */
#define VEC_Q 0x200 /* Qbus vector offset */
#define VEC_PTR (VEC_Q + 0070)
#define VEC_PTP (VEC_Q + 0074)
#define VEC_XQ (VEC_Q + 0120)
#define VEC_XU (VEC_Q + 0120)
#define VEC_RQ (VEC_Q + 0154)
#define VEC_RL (VEC_Q + 0160)
#define VEC_LPT (VEC_Q + 0200)
#define VEC_TS (VEC_Q + 0224)
#define VEC_CR (VEC_Q + 0230)
#define VEC_TQ (VEC_Q + 0260)
#define VEC_RX (VEC_Q + 0264)
#define VEC_RY (VEC_Q + 0264)
#define VEC_DZRX (VEC_Q + 0300)
#define VEC_DZTX (VEC_Q + 0304)
#define VEC_VHRX (VEC_Q + 0310)
#define VEC_VHTX (VEC_Q + 0314)
/* Interrupt macros */
#define IVCL(dv) ((IPL_##dv * 32) + INT_V_##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 */
/* Logging */
#define LOG_CPU_I 0x1 /* intexc */
#define LOG_CPU_R 0x2 /* REI */
#define LOG_CPU_P 0x4 /* context */
/* Function prototypes for virtual memory interface */
int32 Read (uint32 va, int32 lnt, int32 acc);
void Write (uint32 va, int32 val, int32 lnt, int32 acc);
/* Function prototypes for physical memory interface (inlined) */
SIM_INLINE int32 ReadB (uint32 pa);
SIM_INLINE int32 ReadW (uint32 pa);
SIM_INLINE int32 ReadL (uint32 pa);
SIM_INLINE int32 ReadLP (uint32 pa);
SIM_INLINE void WriteB (uint32 pa, int32 val);
SIM_INLINE void WriteW (uint32 pa, int32 val);
SIM_INLINE void WriteL (uint32 pa, int32 val);
void WriteLP (uint32 pa, int32 val);
/* 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, uint8 *buf);
int32 Map_WriteW (uint32 ba, int32 bc, uint16 *buf);
int32 clk_cosched (int32 wait);
t_stat cpu_show_model (FILE *st, UNIT *uptr, int32 val, void *desc);
#include "pdp11_io_lib.h"
#endif

623
VAX/vax630_io.c Normal file
View file

@ -0,0 +1,623 @@
/* vax630_io.c: MicroVAX II Qbus IO simulator
Copyright (c) 2009-2012, 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).
qba Qbus adapter
08-Nov-2012 MB First version
*/
#include "vax_defs.h"
/* Qbus IPC register */
#define QBIPC_QPE 0x00008000 /* Qbus dma parity err */
#define QBIPC_AHLT 0x00000100 /* aux halt NI */
#define QBIPC_DBIE 0x00000040 /* dbell int enb NI */
#define QBIPC_LME 0x00000020 /* local mem enb */
#define QBIPC_DB 0x00000001 /* doorbell req NI */
#define QBIPC_RW (QBIPC_AHLT | QBIPC_DBIE | QBIPC_LME | QBIPC_DB)
#define QBIPC_MASK (QBIPC_RW | QBIPC_QPE )
/* Qbus map registers */
#define QBNMAPR 8192 /* number of map reg */
#define QBMAP_VLD 0x80000000 /* valid */
#define QBMAP_PAG 0x00007FFF /* mem page */
#define QBMAP_RD (QBMAP_VLD | QBMAP_PAG)
#define QBMAP_WR (QBMAP_VLD | QBMAP_PAG)
/* KA630 Memory system error register */
#define MSER_NXM 0x00000080 /* CPU NXM */
int32 int_req[IPL_HLVL] = { 0 }; /* intr, IPL 14-17 */
int32 qb_ipc = 0; /* IPC */
int32 qb_map[QBNMAPR] = { 0 }; /* map registers */
int32 autcon_enb = 1; /* autoconfig enable */
extern int32 R[16];
extern uint32 *M;
extern UNIT cpu_unit;
extern int32 PSL, SISR, trpirq, mem_err, hlt_pin;
extern int32 p1;
extern jmp_buf save_env;
extern int32 sim_switches;
extern DEVICE *sim_devices[];
extern FILE *sim_log;
extern int32 ka_mser; /* KA630 mem sys err */
t_stat dbl_rd (int32 *data, int32 addr, int32 access);
t_stat dbl_wr (int32 data, int32 addr, int32 access);
int32 eval_int (void);
t_stat qba_reset (DEVICE *dptr);
t_stat qba_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw);
t_stat qba_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw);
t_bool qba_map_addr (uint32 qa, uint32 *ma);
t_bool qba_map_addr_c (uint32 qa, uint32 *ma);
t_stat set_autocon (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat show_autocon (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat show_iospace (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat qba_show_virt (FILE *of, UNIT *uptr, int32 val, void *desc);
/* Qbus adapter data structures
qba_dev QBA device descriptor
qba_unit QBA units
qba_reg QBA register list
*/
DIB qba_dib = { IOBA_DBL, IOLN_DBL, &dbl_rd, &dbl_wr, 0 };
UNIT qba_unit = { UDATA (NULL, 0, 0) };
REG qba_reg[] = {
{ HRDATA (IPC, qb_ipc, 16) },
{ HRDATA (IPL17, int_req[3], 32), REG_RO },
{ HRDATA (IPL16, int_req[2], 32), REG_RO },
{ HRDATA (IPL15, int_req[1], 32), REG_RO },
{ HRDATA (IPL14, int_req[0], 32), REG_RO },
{ BRDATA (MAP, qb_map, 16, 32, QBNMAPR) },
{ FLDATA (AUTOCON, autcon_enb, 0), REG_HRO },
{ NULL }
};
MTAB qba_mod[] = {
{ 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, &qba_show_virt },
{ 0 }
};
DEVICE qba_dev = {
"QBA", &qba_unit, qba_reg, qba_mod,
1, 16, QBMAWIDTH, 2, 16, 16,
&qba_ex, &qba_dep, &qba_reset,
NULL, NULL, NULL,
&qba_dib, DEV_QBUS
};
/* 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);
/* Interrupt request to interrupt action map */
int32 (*int_ack[IPL_HLVL][32])(void); /* int ack routines */
/* Interrupt request to vector map */
int32 int_vec[IPL_HLVL][32]; /* int req to vector */
/* The KA620/KA630 handles errors in I/O space as follows
- read: machine check
- write: machine check (?)
*/
int32 ReadQb (uint32 pa)
{
int32 idx, val;
idx = (pa & IOPAGEMASK) >> 1;
if (iodispR[idx]) {
iodispR[idx] (&val, pa, READ);
return val;
}
MACH_CHECK (MCHK_READ);
return 0;
}
void WriteQb (uint32 pa, int32 val, int32 mode)
{
int32 idx;
idx = (pa & IOPAGEMASK) >> 1;
if (iodispW[idx]) {
iodispW[idx] (val, pa, mode);
return;
}
MACH_CHECK (MCHK_WRITE);
return;
}
/* ReadIO - read I/O space
Inputs:
pa = physical address
lnt = length (BWLQ)
Output:
longword of data
*/
int32 ReadIO (uint32 pa, int32 lnt)
{
int32 iod;
iod = ReadQb (pa); /* wd from Qbus */
if (lnt < L_LONG) /* bw? position */
iod = iod << ((pa & 2)? 16: 0);
else iod = (ReadQb (pa + 2) << 16) | iod; /* lw, get 2nd wd */
SET_IRQL;
return iod;
}
/* WriteIO - write I/O space
Inputs:
pa = physical address
val = data to write, right justified in 32b longword
lnt = length (BWLQ)
Outputs:
none
*/
void WriteIO (uint32 pa, int32 val, int32 lnt)
{
if (lnt == L_BYTE)
WriteQb (pa, val, WRITEB);
else if (lnt == L_WORD)
WriteQb (pa, val, WRITE);
else {
WriteQb (pa, val & 0xFFFF, WRITE);
WriteQb (pa + 2, (val >> 16) & 0xFFFF, WRITE);
}
SET_IRQL;
return;
}
/* Find highest priority outstanding interrupt */
int32 eval_int (void)
{
int32 ipl = PSL_GETIPL (PSL);
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;
for (i = IPL_HMAX; i >= IPL_HMIN; i--) { /* chk hwre int */
if (i <= ipl) /* at ipl? no int */
return 0;
if (int_req[i - IPL_HMIN]) /* req != 0? int */
return i;
}
if (ipl >= IPL_SMAX) /* ipl >= sw max? */
return 0;
if ((t = SISR & sw_int_mask[ipl]) == 0) /* eligible req */
return 0;
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;
int32 l = lvl - IPL_HMIN;
if (lvl > IPL_HMAX) { /* error req lvl? */
ABORT (STOP_UIPL); /* unknown intr */
}
for (i = 0; int_req[l] && (i < 32); i++) {
if ((int_req[l] >> i) & 1) {
int_req[l] = int_req[l] & ~(1u << i);
if (int_ack[l][i])
return int_ack[l][i]();
return int_vec[l][i];
}
}
return 0;
}
/* I/O page routines */
t_stat dbl_rd (int32 *data, int32 addr, int32 access)
{
*data = qb_ipc & QBIPC_MASK;
return SCPE_OK;
}
t_stat dbl_wr (int32 data, int32 addr, int32 access)
{
int32 sc = (addr & 3) << 3;
int32 nval = data << sc;
qb_ipc = nval & QBIPC_RW;
if ((addr & 3) == 0) /* low byte only */
qb_ipc = ((qb_ipc & ~QBIPC_RW) | (data & QBIPC_RW)) & QBIPC_MASK;
qb_ipc = qb_ipc & ~QBIPC_AHLT; /* Read only on arbiter */
if (!(qb_ipc & QBIPC_DBIE))
qb_ipc = qb_ipc & ~QBIPC_DB; /* Read only when not DBIE */
return SCPE_OK;
}
/* Qbus map read and write
Read error: machine check?
Write error: machine check?
*/
int32 qbmap_rd (int32 pa)
{
int32 idx = ((pa - QBMAPBASE) >> 2);
return qb_map[idx] & QBMAP_RD;
}
void qbmap_wr (int32 pa, int32 val, int32 lnt)
{
int32 idx = ((pa - QBMAPBASE) >> 2);
if (idx < QBNMAPR) {
if (lnt < L_LONG) {
int32 sc = (pa & 3) << 3;
int32 mask = (lnt == L_WORD)? 0xFFFF: 0xFF;
int32 t = qb_map[idx];
val = ((val & mask) << sc) | (t & ~(mask << sc));
}
qb_map[idx] = val & QBMAP_WR;
}
else
ka_mser |= MSER_NXM;
return;
}
/* Qbus memory read and write (reflects to main memory)
May give master or slave error, depending on where the failure occurs
*/
int32 qbmem_rd (int32 pa)
{
int32 qa = pa & QBMAMASK; /* Qbus addr */
uint32 ma;
if (qba_map_addr (qa, &ma)) { /* map addr */
return M[ma >> 2];
}
MACH_CHECK (MCHK_READ); /* err? mcheck */
return 0;
}
void qbmem_wr (int32 pa, int32 val, int32 lnt)
{
int32 qa = pa & QBMAMASK; /* Qbus addr */
uint32 ma;
if (qba_map_addr (qa, &ma)) { /* map addr */
if (lnt < L_LONG) {
int32 sc = (pa & 3) << 3;
int32 mask = (lnt == L_WORD)? 0xFFFF: 0xFF;
int32 t = M[ma >> 2];
val = ((val & mask) << sc) | (t & ~(mask << sc));
}
M[ma >> 2] = val;
}
else mem_err = 1;
return;
}
/* Map an address via the translation map */
t_bool qba_map_addr (uint32 qa, uint32 *ma)
{
int32 qblk = (qa >> VA_V_VPN); /* Qbus blk */
if (qblk <= QBNMAPR) {
int32 qmap = qb_map[qblk];
if (qmap & QBMAP_VLD) { /* valid? */
*ma = ((qmap & QBMAP_PAG) << VA_V_VPN) + VA_GETOFF (qa);
if (ADDR_IS_MEM (*ma)) /* legit addr */
return TRUE;
ka_mser |= MSER_NXM;
return FALSE;
}
ka_mser |= MSER_NXM;
return FALSE;
}
ka_mser |= MSER_NXM;
return FALSE;
}
/* Map an address via the translation map - console version (no status changes) */
t_bool qba_map_addr_c (uint32 qa, uint32 *ma)
{
int32 qblk = (qa >> VA_V_VPN); /* Qbus blk */
if (qblk <= QBNMAPR) {
int32 qmap = qb_map[qblk];
if (qmap & QBMAP_VLD) { /* valid? */
*ma = ((qmap & QBMAP_PAG) << VA_V_VPN) + VA_GETOFF (qa);
return TRUE;
}
}
return FALSE;
}
/* Reset I/O bus */
void ioreset_wr (int32 data)
{
reset_all (5); /* from qba on... */
return;
}
/* Reset Qbus */
t_stat qba_reset (DEVICE *dptr)
{
int32 i;
for (i = 0; i < IPL_HLVL; i++)
int_req[i] = 0;
return SCPE_OK;
}
/* Qbus I/O buffer routines, aligned access
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;
uint32 ma, dat;
if ((ba | bc) & 03) { /* check alignment */
for (i = ma = 0; i < bc; i++, buf++) { /* by bytes */
if ((ma & VA_M_OFF) == 0) { /* need map? */
if (!qba_map_addr (ba + i, &ma)) /* inv or NXM? */
return (bc - i);
}
*buf = ReadB (ma);
ma = ma + 1;
}
}
else {
for (i = ma = 0; i < bc; i = i + 4, buf++) { /* by longwords */
if ((ma & VA_M_OFF) == 0) { /* need map? */
if (!qba_map_addr (ba + i, &ma)) /* inv or NXM? */
return (bc - i);
}
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;
ma = ma + 4;
}
}
return 0;
}
int32 Map_ReadW (uint32 ba, int32 bc, uint16 *buf)
{
int32 i;
uint32 ma,dat;
ba = ba & ~01;
bc = bc & ~01;
if ((ba | bc) & 03) { /* check alignment */
for (i = ma = 0; i < bc; i = i + 2, buf++) { /* by words */
if ((ma & VA_M_OFF) == 0) { /* need map? */
if (!qba_map_addr (ba + i, &ma)) /* inv or NXM? */
return (bc - i);
}
*buf = ReadW (ma);
ma = ma + 2;
}
}
else {
for (i = ma = 0; i < bc; i = i + 4, buf++) { /* by longwords */
if ((ma & VA_M_OFF) == 0) { /* need map? */
if (!qba_map_addr (ba + i, &ma)) /* inv or NXM? */
return (bc - i);
}
dat = ReadL (ma); /* get lw */
*buf++ = dat & WMASK; /* low 16b */
*buf = (dat >> 16) & WMASK; /* high 16b */
ma = ma + 4;
}
}
return 0;
}
int32 Map_WriteB (uint32 ba, int32 bc, uint8 *buf)
{
int32 i;
uint32 ma, dat;
if ((ba | bc) & 03) { /* check alignment */
for (i = ma = 0; i < bc; i++, buf++) { /* by bytes */
if ((ma & VA_M_OFF) == 0) { /* need map? */
if (!qba_map_addr (ba + i, &ma)) /* inv or NXM? */
return (bc - i);
}
WriteB (ma, *buf);
ma = ma + 1;
}
}
else {
for (i = ma = 0; i < bc; i = i + 4, buf++) { /* by longwords */
if ((ma & VA_M_OFF) == 0) { /* need map? */
if (!qba_map_addr (ba + i, &ma)) /* inv or NXM? */
return (bc - i);
}
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 */
ma = ma + 4;
}
}
return 0;
}
int32 Map_WriteW (uint32 ba, int32 bc, uint16 *buf)
{
int32 i;
uint32 ma, dat;
ba = ba & ~01;
bc = bc & ~01;
if ((ba | bc) & 03) { /* check alignment */
for (i = ma = 0; i < bc; i = i + 2, buf++) { /* by words */
if ((ma & VA_M_OFF) == 0) { /* need map? */
if (!qba_map_addr (ba + i, &ma)) /* inv or NXM? */
return (bc - i);
}
WriteW (ma, *buf);
ma = ma + 2;
}
}
else {
for (i = ma = 0; i < bc; i = i + 4, buf++) { /* by longwords */
if ((ma & VA_M_OFF) == 0) { /* need map? */
if (!qba_map_addr (ba + i, &ma)) /* inv or NXM? */
return (bc - i);
}
dat = (uint32) *buf++; /* get low 16b */
dat = dat | (((uint32) *buf) << 16); /* merge hi 16b */
WriteL (ma, dat); /* store lw */
ma = ma + 4;
}
}
return 0;
}
/* Memory examine via map (word only) */
t_stat qba_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw)
{
uint32 qa = (uint32) exta, pa;
if ((vptr == NULL) || (qa >= QBMSIZE))
return SCPE_ARG;
if (qba_map_addr_c (qa, &pa) && ADDR_IS_MEM (pa)) {
*vptr = (uint32) ReadW (pa);
return SCPE_OK;
}
return SCPE_NXM;
}
/* Memory deposit via map (word only) */
t_stat qba_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw)
{
uint32 qa = (uint32) exta, pa;
if (qa >= QBMSIZE)
return SCPE_ARG;
if (qba_map_addr_c (qa, &pa) && ADDR_IS_MEM (pa)) {
WriteW (pa, (int32) val);
return SCPE_OK;
}
return SCPE_NXM;
}
/* Build dib_tab from device list */
t_stat build_dib_tab (void)
{
int32 i;
DEVICE *dptr;
DIB *dibp;
t_stat r;
init_ubus_tab (); /* init bus tables */
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? */
r = build_ubus_tab (dptr, dibp); /* add to bus tab */
if (r)
return r;
} /* end if enabled */
} /* end for */
return SCPE_OK;
}
/* Show QBA virtual address */
t_stat qba_show_virt (FILE *of, UNIT *uptr, int32 val, void *desc)
{
t_stat r;
char *cptr = (char *) desc;
uint32 qa, pa;
if (cptr) {
qa = (uint32) get_uint (cptr, 16, QBMSIZE - 1, &r);
if (r == SCPE_OK) {
if (qba_map_addr_c (qa, &pa))
fprintf (of, "Qbus %-X = physical %-X\n", qa, pa);
else fprintf (of, "Qbus %-X: invalid mapping\n", qa);
return SCPE_OK;
}
}
fprintf (of, "Invalid argument\n");
return SCPE_OK;
}

359
VAX/vax630_stddev.c Normal file
View file

@ -0,0 +1,359 @@
/* vax630_stddev.c: MicroVAX II standard I/O devices
Copyright (c) 2009-2012, 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).
tti terminal input
tto terminal output
clk 100Hz and TODR clock
08-Nov-2012 MB First version
*/
#include "vax_defs.h"
#include <time.h>
#define TTICSR_IMP (CSR_DONE + CSR_IE) /* terminal input */
#define TTICSR_RW (CSR_IE)
#define TTIBUF_ERR 0x8000 /* error */
#define TTIBUF_OVR 0x4000 /* overrun */
#define TTIBUF_FRM 0x2000 /* framing error */
#define TTIBUF_RBR 0x0400 /* receive break */
#define TTOCSR_IMP (CSR_DONE + CSR_IE) /* terminal output */
#define TTOCSR_RW (CSR_IE)
#define CLKCSR_IMP (CSR_IE) /* real-time clock */
#define CLKCSR_RW (CSR_IE)
#define CLK_DELAY 5000 /* 100 Hz */
#define TMXR_MULT 1 /* 100 Hz */
extern int32 int_req[IPL_HLVL];
extern int32 hlt_pin;
extern int32 sim_switches;
int32 tti_csr = 0; /* control/status */
int32 tto_csr = 0; /* control/status */
int32 clk_csr = 0; /* control/status */
int32 clk_tps = 100; /* ticks/second */
int32 tmxr_poll = CLK_DELAY * TMXR_MULT; /* term mux poll */
int32 tmr_poll = CLK_DELAY; /* pgm timer poll */
t_stat tti_svc (UNIT *uptr);
t_stat tto_svc (UNIT *uptr);
t_stat clk_svc (UNIT *uptr);
t_stat tti_reset (DEVICE *dptr);
t_stat tto_reset (DEVICE *dptr);
t_stat clk_reset (DEVICE *dptr);
extern int32 sysd_hlt_enb (void);
/* TTI data structures
tti_dev TTI device descriptor
tti_unit TTI unit descriptor
tti_reg TTI register list
*/
DIB tti_dib = { 0, 0, NULL, NULL, 1, IVCL (TTI), SCB_TTI, { NULL } };
UNIT tti_unit = { UDATA (&tti_svc, UNIT_IDLE|TT_MODE_8B, 0), 0 };
REG tti_reg[] = {
{ HRDATA (BUF, tti_unit.buf, 16) },
{ HRDATA (CSR, tti_csr, 16) },
{ FLDATA (INT, int_req[IPL_TTI], INT_V_TTI) },
{ FLDATA (DONE, tti_csr, CSR_V_DONE) },
{ FLDATA (IE, tti_csr, CSR_V_IE) },
{ DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tti_unit.wait, 24), PV_LEFT },
{ NULL }
};
MTAB tti_mod[] = {
{ TT_MODE, TT_MODE_7B, "7b", "7B", NULL },
{ TT_MODE, TT_MODE_8B, "8b", "8B", NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL,
NULL, &show_vec, NULL },
{ 0 }
};
DEVICE tti_dev = {
"TTI", &tti_unit, tti_reg, tti_mod,
1, 10, 31, 1, 16, 8,
NULL, NULL, &tti_reset,
NULL, NULL, NULL,
&tti_dib, 0
};
/* TTO data structures
tto_dev TTO device descriptor
tto_unit TTO unit descriptor
tto_reg TTO register list
*/
DIB tto_dib = { 0, 0, NULL, NULL, 1, IVCL (TTO), SCB_TTO, { NULL } };
UNIT tto_unit = { UDATA (&tto_svc, TT_MODE_8B, 0), SERIAL_OUT_WAIT };
REG tto_reg[] = {
{ HRDATA (BUF, tto_unit.buf, 8) },
{ HRDATA (CSR, tto_csr, 16) },
{ FLDATA (INT, int_req[IPL_TTO], INT_V_TTO) },
{ FLDATA (DONE, tto_csr, CSR_V_DONE) },
{ FLDATA (IE, tto_csr, CSR_V_IE) },
{ DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
{ NULL }
};
MTAB tto_mod[] = {
{ TT_MODE, TT_MODE_7B, "7b", "7B", NULL },
{ TT_MODE, TT_MODE_8B, "8b", "8B", NULL },
{ TT_MODE, TT_MODE_7P, "7p", "7P", NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL, NULL, &show_vec },
{ 0 }
};
DEVICE tto_dev = {
"TTO", &tto_unit, tto_reg, tto_mod,
1, 10, 31, 1, 16, 8,
NULL, NULL, &tto_reset,
NULL, NULL, NULL,
&tto_dib, 0
};
/* CLK data structures
clk_dev CLK device descriptor
clk_unit CLK unit descriptor
clk_reg CLK register list
*/
DIB clk_dib = { 0, 0, NULL, NULL, 1, IVCL (CLK), SCB_INTTIM, { NULL } };
UNIT clk_unit = { UDATA (&clk_svc, UNIT_IDLE, 0), CLK_DELAY };
REG clk_reg[] = {
{ HRDATA (CSR, clk_csr, 16) },
{ FLDATA (INT, int_req[IPL_CLK], INT_V_CLK) },
{ FLDATA (IE, clk_csr, CSR_V_IE) },
{ DRDATA (TIME, clk_unit.wait, 24), REG_NZ + PV_LEFT },
{ DRDATA (TPS, clk_tps, 8), REG_NZ + PV_LEFT },
{ NULL }
};
DEVICE clk_dev = {
"CLK", &clk_unit, clk_reg, NULL,
1, 0, 0, 0, 0, 0,
NULL, NULL, &clk_reset,
NULL, NULL, NULL,
&clk_dib, 0
};
/* Clock and terminal MxPR routines
iccs_rd/wr interval timer
todr_rd/wr time of year clock
rxcs_rd/wr input control/status
rxdb_rd input buffer
txcs_rd/wr output control/status
txdb_wr output buffer
*/
int32 iccs_rd (void)
{
return (clk_csr & CLKCSR_IMP);
}
int32 rxcs_rd (void)
{
return (tti_csr & TTICSR_IMP);
}
int32 rxdb_rd (void)
{
int32 t = tti_unit.buf; /* char + error */
tti_csr = tti_csr & ~CSR_DONE; /* clr done */
tti_unit.buf = tti_unit.buf & 0377; /* clr errors */
CLR_INT (TTI);
return t;
}
int32 txcs_rd (void)
{
return (tto_csr & TTOCSR_IMP);
}
void iccs_wr (int32 data)
{
if ((data & CSR_IE) == 0)
CLR_INT (CLK);
clk_csr = (clk_csr & ~CLKCSR_RW) | (data & CLKCSR_RW);
return;
}
void rxcs_wr (int32 data)
{
if ((data & CSR_IE) == 0)
CLR_INT (TTI);
else if ((tti_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
SET_INT (TTI);
tti_csr = (tti_csr & ~TTICSR_RW) | (data & TTICSR_RW);
return;
}
void txcs_wr (int32 data)
{
if ((data & CSR_IE) == 0)
CLR_INT (TTO);
else if ((tto_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
SET_INT (TTO);
tto_csr = (tto_csr & ~TTOCSR_RW) | (data & TTOCSR_RW);
return;
}
void txdb_wr (int32 data)
{
tto_unit.buf = data & 0377;
tto_csr = tto_csr & ~CSR_DONE;
CLR_INT (TTO);
sim_activate (&tto_unit, tto_unit.wait);
return;
}
/* Terminal input routines
tti_svc process event (character ready)
tti_reset process reset
*/
t_stat tti_svc (UNIT *uptr)
{
int32 c;
sim_activate (uptr, KBD_WAIT (uptr->wait, tmr_poll)); /* continue poll */
if ((c = sim_poll_kbd ()) < SCPE_KFLAG) /* no char or error? */
return c;
if (c & SCPE_BREAK) { /* break? */
if (sysd_hlt_enb ()) /* if enabled, halt */
hlt_pin = 1;
tti_unit.buf = TTIBUF_ERR | TTIBUF_FRM | TTIBUF_RBR;
}
else tti_unit.buf = sim_tt_inpcvt (c, TT_GET_MODE (uptr->flags));
uptr->pos = uptr->pos + 1;
tti_csr = tti_csr | CSR_DONE;
if (tti_csr & CSR_IE)
SET_INT (TTI);
return SCPE_OK;
}
t_stat tti_reset (DEVICE *dptr)
{
tti_unit.buf = 0;
tti_csr = 0;
CLR_INT (TTI);
sim_activate_abs (&tti_unit, KBD_WAIT (tti_unit.wait, tmr_poll));
return SCPE_OK;
}
/* Terminal output routines
tto_svc process event (character typed)
tto_reset process reset
*/
t_stat tto_svc (UNIT *uptr)
{
int32 c;
t_stat r;
c = sim_tt_outcvt (tto_unit.buf, TT_GET_MODE (uptr->flags));
if (c >= 0) {
if ((r = sim_putchar_s (c)) != SCPE_OK) { /* output; error? */
sim_activate (uptr, uptr->wait); /* retry */
return ((r == SCPE_STALL)? SCPE_OK: r); /* !stall? report */
}
}
tto_csr = tto_csr | CSR_DONE;
if (tto_csr & CSR_IE)
SET_INT (TTO);
uptr->pos = uptr->pos + 1;
return SCPE_OK;
}
t_stat tto_reset (DEVICE *dptr)
{
tto_unit.buf = 0;
tto_csr = CSR_DONE;
CLR_INT (TTO);
sim_cancel (&tto_unit); /* deactivate unit */
return SCPE_OK;
}
/* Clock routines
clk_svc process event (clock tick)
clk_reset process reset
todr_powerup powerup for TODR (get date from system)
*/
t_stat clk_svc (UNIT *uptr)
{
int32 t;
if (clk_csr & CSR_IE)
SET_INT (CLK);
t = sim_rtcn_calb (clk_tps, TMR_CLK); /* calibrate clock */
sim_activate (&clk_unit, t); /* reactivate unit */
tmr_poll = t; /* set tmr poll */
tmxr_poll = t * TMXR_MULT; /* set mux poll */
return SCPE_OK;
}
/* Clock coscheduling routine */
int32 clk_cosched (int32 wait)
{
int32 t;
t = sim_activate_time (&clk_unit);
return (t? t - 1: wait);
}
/* Reset routine */
t_stat clk_reset (DEVICE *dptr)
{
int32 t;
clk_csr = 0;
CLR_INT (CLK);
t = sim_rtcn_init (clk_unit.wait, TMR_CLK); /* init timer */
sim_activate_abs (&clk_unit, t); /* activate unit */
tmr_poll = t; /* set tmr poll */
tmxr_poll = t * TMXR_MULT; /* set mux poll */
return SCPE_OK;
}

899
VAX/vax630_sysdev.c Normal file
View file

@ -0,0 +1,899 @@
/* vax630_sysdev.c: MicroVAX II system-specific logic
Copyright (c) 2009-2012, 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).
This module contains the MicroVAX II system-specific registers and devices.
rom bootstrap ROM (no registers)
nvr non-volatile ROM (no registers)
sysd system devices
08-Nov-2012 MB First version
*/
#include "vax_defs.h"
#include <time.h>
#ifdef DONT_USE_INTERNAL_ROM
#if defined(VAX_620)
#define BOOT_CODE_FILENAME "ka620.bin"
#else
#define BOOT_CODE_FILENAME "ka320.bin"
#endif
#else /* !DONT_USE_INTERNAL_ROM */
#if defined(VAX_620)
#include "vax_ka620_bin.h" /* Defines BOOT_CODE_FILENAME and BOOT_CODE_ARRAY, etc */
#else
#include "vax_ka630_bin.h" /* Defines BOOT_CODE_FILENAME and BOOT_CODE_ARRAY, etc */
#endif
#endif /* DONT_USE_INTERNAL_ROM */
#define UNIT_V_NODELAY (UNIT_V_UF + 0) /* ROM access equal to RAM access */
#define UNIT_NODELAY (1u << UNIT_V_NODELAY)
extern CTAB *sim_vm_cmd;
t_stat vax630_boot (int32 flag, char *ptr);
/* Special boot command, overrides regular boot */
CTAB vax630_cmd[] = {
{ "BOOT", &vax630_boot, RU_BOOT,
"bo{ot} boot simulator\n", &run_cmd_message },
{ NULL }
};
/* KA630 boot/diagnostic register */
#define BDR_DISP 0x0000000F /* LED display */
#define BDR_V_BDC 8 /* boot/diag code */
#define BDR_M_BDC 0x3
#define BDR_BDC (BDR_M_BDC << BDR_V_BDC)
#define BDR_V_CPUC 11 /* cpu code */
#define BDR_M_CPUC 0x3
#define BDR_CPUC (BDR_M_CPUC << BDR_V_CPUC)
#define BDR_BRKENB 0x00004000 /* break enable */
#define BDR_POK 0x00008000 /* power ok */
#define BDR_RD (BDR_DISP | BDR_BDC | BDR_CPUC | BDR_BRKENB | BDR_POK)
#define BDR_WR (BDR_DISP)
/* BDR boot/diagnostic codes */
#define BDC_NORM 0x0 /* normal startup */
#define BDC_LNGI 0x1 /* language inquiry */
#define BDC_TSTL 0x2 /* test loop */
#define BDC_SKPM 0x3 /* skip mem test */
/* BDR CPU codes */
#define CPUC_ARB 0x0 /* arbiter */
#define CPUC_AUX1 0x1 /* auxiliary 1 */
#define CPUC_AUX2 0x2 /* auxiliary 2 */
#define CPUC_AUX3 0x3 /* auxiliary 3 */
/* KA630 Memory system error register */
#define MSER_PE 0x00000001 /* Parity Enable */
#define MSER_WWP 0x00000002 /* Write Wrong Parity */
#define MSER_LEB 0x00000008 /* Lost Error Bit */
#define MSER_DQPE 0x00000010 /* DMA Q22 Parity Err */
#define MSER_CQPE 0x00000020 /* CPU Q22 Parity Err */
#define MSER_CLPE 0x00000040 /* CPU Mem Parity Err */
#define MSER_NXM 0x00000080 /* CPU NXM */
#define MSER_MCD0 0x00000100 /* Mem Code 0 */
#define MSER_MCD1 0x00000200 /* Mem Code 1 */
#define MSER_MBZ 0xFFFFFC04
#define MSER_RD (MSER_PE | MSER_WWP | MSER_LEB | \
MSER_DQPE | MSER_CQPE | MSER_CLPE | \
MSER_NXM | MSER_MCD0 | MSER_MCD1)
#define MSER_WR (MSER_PE | MSER_WWP)
#define MSER_RS (MSER_LEB | MSER_DQPE | MSER_CQPE | MSER_CLPE | MSER_NXM)
/* KA630 CPU error address reg */
#define CEAR_LMADD 0x00007FFF /* local mem addr */
#define CEAR_RD (CEAR_LMADD)
/* KA630 DMA error address reg */
#define DEAR_LMADD 0x00007FFF /* local mem addr */
#define DEAR_RD (DEAR_LMADD)
extern int32 R[16];
extern int32 STK[5];
extern int32 PSL;
extern int32 SISR;
extern int32 SCBB;
extern int32 mapen;
extern int32 pcq[PCQ_SIZE];
extern int32 pcq_p;
extern int32 ibcnt, ppc;
extern int32 in_ie;
extern int32 mchk_va, mchk_ref;
extern int32 fault_PC;
extern int32 int_req[IPL_HLVL];
extern UNIT cpu_unit;
extern UNIT clk_unit;
extern jmp_buf save_env;
extern int32 p1;
extern int32 sim_switches;
extern int32 tmr_poll;
uint32 *rom = NULL; /* boot ROM */
uint32 *nvr = NULL; /* non-volatile mem */
int32 conisp, conpc, conpsl; /* console reg */
int32 ka_bdr = BDR_BRKENB; /* KA630 boot diag */
int32 ka_mser = 0; /* KA630 mem sys err */
int32 ka_cear = 0; /* KA630 cpu err */
int32 ka_dear = 0; /* KA630 dma err */
static uint32 rom_delay = 0;
t_bool rom_diag_full = 0;
t_stat rom_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw);
t_stat rom_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw);
t_stat rom_reset (DEVICE *dptr);
t_stat rom_set_diag (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat rom_show_diag (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat nvr_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw);
t_stat nvr_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw);
t_stat nvr_reset (DEVICE *dptr);
t_stat nvr_attach (UNIT *uptr, char *cptr);
t_stat nvr_detach (UNIT *uptr);
t_stat sysd_reset (DEVICE *dptr);
int32 rom_rd (int32 pa);
int32 nvr_rd (int32 pa);
void nvr_wr (int32 pa, int32 val, int32 lnt);
int32 ka_rd (int32 pa);
void ka_wr (int32 pa, int32 val, int32 lnt);
t_stat sysd_powerup (void);
int32 con_halt (int32 code, int32 cc);
extern int32 intexc (int32 vec, int32 cc, int32 ipl, int ei);
extern int32 qbmap_rd (int32 pa);
extern void qbmap_wr (int32 pa, int32 val, int32 lnt);
extern int32 qbmem_rd (int32 pa);
extern void qbmem_wr (int32 pa, int32 val, int32 lnt);
extern int32 wtc_rd (int32 pa);
extern void wtc_wr (int32 pa, int32 val, int32 lnt);
extern void wtc_set_valid (void);
extern void wtc_set_invalid (void);
extern int32 iccs_rd (void);
extern int32 todr_rd (void);
extern int32 rxcs_rd (void);
extern int32 rxdb_rd (void);
extern int32 txcs_rd (void);
extern void iccs_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 ioreset_wr (int32 dat);
extern uint32 sim_os_msec();
/* ROM data structures
rom_dev ROM device descriptor
rom_unit ROM units
rom_reg ROM register list
*/
UNIT rom_unit = { UDATA (NULL, UNIT_FIX+UNIT_BINK, ROMSIZE) };
REG rom_reg[] = {
{ NULL }
};
MTAB rom_mod[] = {
{ UNIT_NODELAY, UNIT_NODELAY, "fast access", "NODELAY", NULL },
{ UNIT_NODELAY, 0, "1usec calibrated access", "DELAY", NULL },
{ MTAB_XTD|MTAB_VDV, 0, "DIAG", "DIAG={FULL|MIN}", &rom_set_diag, &rom_show_diag },
{ 0 }
};
DEVICE rom_dev = {
"ROM", &rom_unit, rom_reg, rom_mod,
1, 16, ROMAWIDTH, 4, 16, 32,
&rom_ex, &rom_dep, &rom_reset,
NULL, NULL, NULL,
NULL, 0
};
/* NVR data structures
nvr_dev NVR device descriptor
nvr_unit NVR units
nvr_reg NVR register list
*/
UNIT nvr_unit =
{ UDATA (NULL, UNIT_FIX+UNIT_BINK, NVRSIZE) };
REG nvr_reg[] = {
{ NULL }
};
DEVICE nvr_dev = {
"NVR", &nvr_unit, nvr_reg, NULL,
1, 16, NVRAWIDTH, 4, 16, 32,
&nvr_ex, &nvr_dep, &nvr_reset,
NULL, &nvr_attach, &nvr_detach,
NULL, 0
};
/* SYSD data structures
sysd_dev SYSD device descriptor
sysd_unit SYSD units
sysd_reg SYSD register list
*/
UNIT sysd_unit = { UDATA (NULL, 0, 0) };
REG sysd_reg[] = {
{ HRDATA (CONISP, conisp, 32) },
{ HRDATA (CONPC, conpc, 32) },
{ HRDATA (CONPSL, conpsl, 32) },
{ HRDATA (BDR, ka_bdr, 16) },
{ HRDATA (MSER, ka_mser, 8) },
{ HRDATA (CEAR, ka_cear, 8) },
{ HRDATA (DEAR, ka_dear, 8) },
{ NULL }
};
DEVICE sysd_dev = {
"SYSD", &sysd_unit, sysd_reg, NULL,
1, 16, 16, 1, 16, 8,
NULL, NULL, &sysd_reset,
NULL, NULL, NULL,
NULL, 0
};
/* ROM: read only memory - stored in a buffered file
Register space access routines see ROM twice
ROM access has been 'regulated' to about 1Mhz to avoid issues
with testing the interval timers in self-test. Specifically,
the VAX boot ROM (ka630.bin) contains code which presumes that
the VAX runs at a particular slower speed when code is running
from ROM (which is not cached). These assumptions are built
into instruction based timing loops. As the host platform gets
much faster than the original VAX, the assumptions embedded in
these code loops are no longer valid.
Code has been added to the ROM implementation to limit CPU speed
to about 500K instructions per second. This heads off any future
issues with the embedded timing loops.
*/
int32 rom_swapb(int32 val)
{
return ((val << 24) & 0xff000000) | (( val << 8) & 0xff0000) |
((val >> 8) & 0xff00) | ((val >> 24) & 0xff);
}
int32 rom_read_delay (int32 val)
{
uint32 i, l = rom_delay;
int32 loopval = 0;
if (rom_unit.flags & UNIT_NODELAY)
return val;
/* Calibrate the loop delay factor when first used.
Do this 4 times to and use the largest value computed. */
if (rom_delay == 0) {
uint32 ts, te, c = 10000, samples = 0;
while (1) {
c = c * 2;
te = sim_os_msec();
while (te == (ts = sim_os_msec ())); /* align on ms tick */
/* This is merely a busy wait with some "work" that won't get optimized
away by a good compiler. loopval always is zero. To avoid smart compilers,
the loopval variable is referenced in the function arguments so that the
function expression is not loop invariant. It also must be referenced
by subsequent code or to avoid the whole computation being eliminated. */
for (i = 0; i < c; i++)
loopval |= (loopval + ts) ^ rom_swapb (rom_swapb (loopval + ts));
te = sim_os_msec ();
if ((te - ts) < 50) /* sample big enough? */
continue;
if (rom_delay < (loopval + (c / (te - ts) / 1000) + 1))
rom_delay = loopval + (c / (te - ts) / 1000) + 1;
if (++samples >= 4)
break;
c = c / 2;
}
if (rom_delay < 5)
rom_delay = 5;
}
for (i = 0; i < l; i++)
loopval |= (loopval + val) ^ rom_swapb (rom_swapb (loopval + val));
return val + loopval;
}
int32 rom_rd (int32 pa)
{
int32 rg = ((pa - ROMBASE) & ROMAMASK) >> 2;
return rom_read_delay (rom[rg]);
}
void rom_wr_B (int32 pa, int32 val)
{
int32 rg = ((pa - ROMBASE) & ROMAMASK) >> 2;
int32 sc = (pa & 3) << 3;
rom[rg] = ((val & 0xFF) << sc) | (rom[rg] & ~(0xFF << sc));
return;
}
/* ROM examine */
t_stat rom_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw)
{
uint32 addr = (uint32) exta;
if ((vptr == NULL) || (addr & 03))
return SCPE_ARG;
if (addr >= ROMSIZE)
return SCPE_NXM;
*vptr = rom[addr >> 2];
return SCPE_OK;
}
/* ROM deposit */
t_stat rom_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw)
{
uint32 addr = (uint32) exta;
if (addr & 03)
return SCPE_ARG;
if (addr >= ROMSIZE)
return SCPE_NXM;
rom[addr >> 2] = (uint32) val;
return SCPE_OK;
}
/* ROM reset */
t_stat rom_reset (DEVICE *dptr)
{
if (rom == NULL)
rom = (uint32 *) calloc (ROMSIZE >> 2, sizeof (uint32));
if (rom == NULL)
return SCPE_MEM;
return SCPE_OK;
}
/* NVR: non-volatile RAM - stored in a buffered file */
int32 nvr_rd (int32 pa)
{
int32 rg = (pa - NVRBASE) >> 2;
if (rg < 7) /* watch chip */
return wtc_rd (pa);
else
return nvr[rg];
}
void nvr_wr (int32 pa, int32 val, int32 lnt)
{
int32 rg = (pa - NVRBASE) >> 2;
if (rg < 7) /* watch chip */
wtc_wr (pa, val, lnt);
else {
int32 sc = (pa & 3) << 3; /* merge */
int32 mask = 0xFF;
nvr[rg] = ((val & mask) << sc) | (nvr[rg] & ~(mask << sc));
}
}
/* NVR examine */
t_stat nvr_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw)
{
uint32 addr = (uint32) exta;
if ((vptr == NULL) || (addr & 03))
return SCPE_ARG;
if (addr >= NVRSIZE)
return SCPE_NXM;
*vptr = nvr[addr >> 2];
return SCPE_OK;
}
/* NVR deposit */
t_stat nvr_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw)
{
uint32 addr = (uint32) exta;
if (addr & 03)
return SCPE_ARG;
if (addr >= NVRSIZE)
return SCPE_NXM;
nvr[addr >> 2] = (uint32) val;
return SCPE_OK;
}
/* NVR reset */
t_stat nvr_reset (DEVICE *dptr)
{
if (nvr == NULL) {
nvr = (uint32 *) calloc (NVRSIZE >> 2, sizeof (uint32));
nvr_unit.filebuf = nvr;
}
if (nvr == NULL)
return SCPE_MEM;
return SCPE_OK;
}
/* NVR attach */
t_stat nvr_attach (UNIT *uptr, char *cptr)
{
t_stat r;
uptr->flags = uptr->flags | (UNIT_ATTABLE | UNIT_BUFABLE);
r = attach_unit (uptr, cptr);
if (r != SCPE_OK)
uptr->flags = uptr->flags & ~(UNIT_ATTABLE | UNIT_BUFABLE);
else {
uptr->hwmark = (uint32) uptr->capac;
wtc_set_valid ();
}
return r;
}
/* NVR detach */
t_stat nvr_detach (UNIT *uptr)
{
t_stat r;
r = detach_unit (uptr);
if ((uptr->flags & UNIT_ATT) == 0) {
uptr->flags = uptr->flags & ~(UNIT_ATTABLE | UNIT_BUFABLE);
wtc_set_invalid ();
}
return r;
}
/* Read KA630 specific IPR's */
int32 ReadIPR (int32 rg)
{
int32 val;
switch (rg) {
case MT_ICCS: /* ICCS */
val = iccs_rd ();
break;
case MT_RXCS: /* RXCS */
val = rxcs_rd ();
break;
case MT_RXDB: /* RXDB */
val = rxdb_rd ();
break;
case MT_TXCS: /* TXCS */
val = txcs_rd ();
break;
case MT_TXDB: /* TXDB */
val = 0;
break;
case MT_CONISP: /* console ISP */
val = conisp;
break;
case MT_CONPC: /* console PC */
val = conpc;
break;
case MT_CONPSL: /* console PSL */
val = conpsl;
break;
case MT_SID: /* SID */
#if defined(VAX_620)
val = VAX620_SID;
#else
val = VAX630_SID;
#endif
break;
case MT_NICR: /* NICR */
case MT_ICR: /* ICR */
case MT_TODR: /* TODR */
case MT_CSRS: /* CSRS */
case MT_CSRD: /* CSRD */
case MT_CSTS: /* CSTS */
case MT_CSTD: /* CSTD */
case MT_TBDR: /* TBDR */
case MT_CADR: /* CADR */
case MT_MCESR: /* MCESR */
case MT_CAER: /* CAER */
case MT_SBIFS: /* SBIFS */
case MT_SBIS: /* SBIS */
case MT_SBISC: /* SBISC */
case MT_SBIMT: /* SBIMT */
case MT_SBIER: /* SBIER */
case MT_SBITA: /* SBITA */
case MT_SBIQC: /* SBIQC */
case MT_TBDATA: /* TBDATA */
case MT_MBRK: /* MBRK */
case MT_PME: /* PME */
val = 0;
break;
default:
RSVD_OPND_FAULT;
}
return val;
}
/* Write KA630 specific IPR's */
void WriteIPR (int32 rg, int32 val)
{
switch (rg) {
case MT_ICCS: /* ICCS */
iccs_wr (val);
break;
case MT_RXCS: /* RXCS */
rxcs_wr (val);
break;
case MT_RXDB: /* RXDB */
break;
case MT_TXCS: /* TXCS */
txcs_wr (val);
break;
case MT_TXDB: /* TXDB */
txdb_wr (val);
break;
case MT_IORESET: /* IORESET */
ioreset_wr (val);
break;
case MT_SID:
case MT_CONISP:
case MT_CONPC:
case MT_CONPSL: /* halt reg */
RSVD_OPND_FAULT;
case MT_NICR: /* NICR */
case MT_ICR: /* ICR */
case MT_TODR: /* TODR */
case MT_CSRS: /* CSRS */
case MT_CSRD: /* CSRD */
case MT_CSTS: /* CSTS */
case MT_CSTD: /* CSTD */
case MT_TBDR: /* TBDR */
case MT_CADR: /* CADR */
case MT_MCESR: /* MCESR */
case MT_CAER: /* CAER */
case MT_SBIFS: /* SBIFS */
case MT_SBIS: /* SBIS */
case MT_SBISC: /* SBISC */
case MT_SBIMT: /* SBIMT */
case MT_SBIER: /* SBIER */
case MT_SBITA: /* SBITA */
case MT_SBIQC: /* SBIQC */
case MT_TBDATA: /* TBDATA */
case MT_MBRK: /* MBRK */
case MT_PME: /* PME */
break;
default:
RSVD_OPND_FAULT;
}
return;
}
/* Read/write I/O register space
These routines are the 'catch all' for address space map. Any
address that doesn't explicitly belong to memory, I/O, or ROM
is given to these routines for processing.
*/
struct reglink { /* register linkage */
uint32 low; /* low addr */
uint32 high; /* high addr */
t_stat (*read)(int32 pa); /* read routine */
void (*write)(int32 pa, int32 val, int32 lnt); /* write routine */
};
struct reglink regtable[] = {
{ QBMAPBASE, QBMAPBASE+QBMAPSIZE, &qbmap_rd, &qbmap_wr },
{ ROMBASE, ROMBASE+ROMSIZE+ROMSIZE, &rom_rd, NULL },
{ NVRBASE, NVRBASE+NVRSIZE, &nvr_rd, &nvr_wr },
{ KABASE, KABASE+KASIZE, &ka_rd, &ka_wr },
/* { QVMBASE, QVMBASE+QVMSIZE, &qv_mem_rd, &qv_mem_wr }, */
{ QBMBASE, QBMBASE+QBMSIZE, &qbmem_rd, &qbmem_wr },
{ 0, 0, NULL, NULL }
};
/* ReadReg - read register space
Inputs:
pa = physical address
lnt = length (BWLQ) - ignored
Output:
longword of data
*/
int32 ReadReg (uint32 pa, int32 lnt)
{
struct reglink *p;
for (p = &regtable[0]; p->low != 0; p++) {
if ((pa >= p->low) && (pa < p->high) && p->read)
return p->read (pa);
}
MACH_CHECK (MCHK_READ);
}
/* 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)
{
struct reglink *p;
for (p = &regtable[0]; p->low != 0; p++) {
if ((pa >= p->low) && (pa < p->high) && p->write) {
p->write (pa, val, lnt);
return;
}
}
MACH_CHECK (MCHK_WRITE);
}
/* KA630 registers */
int32 ka_rd (int32 pa)
{
int32 rg = (pa - KABASE) >> 2;
switch (rg) {
case 0: /* BDR */
return ka_bdr & BDR_RD;
case 1: /* MSER */
return ka_mser & MSER_RD;
case 2: /* CEAR */
return ka_cear & CEAR_RD;
case 3: /* DEAR */
return ka_dear & DEAR_RD;
}
return 0;
}
void ka_wr (int32 pa, int32 val, int32 lnt)
{
int32 rg = (pa - KABASE) >> 2;
switch (rg) {
case 0: /* BDR */
ka_bdr = (ka_bdr & ~BDR_WR) | (val & BDR_WR);
break;
case 1: /* MSER */
ka_mser = (ka_mser & ~MSER_WR) | (val & MSER_WR);
ka_mser = ka_mser & ~(val & MSER_RS);
break;
case 2: /* CEAR */
case 3: /* DEAR */
break;
}
return;
}
int32 sysd_hlt_enb (void)
{
return ka_bdr & BDR_BRKENB;
}
/* Machine check */
int32 machine_check (int32 p1, int32 opc, int32 cc, int32 delta)
{
int32 st, p2, acc;
if (in_ie) {
in_ie = 0;
return con_halt(CON_DBLMCK, cc); /* double machine check */
}
if (p1 & 0x80) /* mref? set v/p */
p1 = p1 + mchk_ref;
p2 = mchk_va + 4; /* save vap */
st = 0;
if (p1 & 0x80) { /* mref? */
cc = intexc (SCB_MCHK, cc, 0, IE_EXC); /* take normal exception */
if (!(ka_mser & MSER_CQPE) && !(ka_mser & MSER_CLPE))
ka_mser |= MSER_NXM;
}
else cc = intexc (SCB_MCHK, cc, 0, IE_SVE); /* take severe exception */
acc = ACC_MASK (KERN); /* in kernel mode */
in_ie = 1;
SP = SP - 16; /* push 4 words */
Write (SP, 12, L_LONG, WA); /* # bytes */
Write (SP + 4, p1, L_LONG, WA); /* mcheck type */
Write (SP + 8, p2, L_LONG, WA); /* address */
Write (SP + 12, st, L_LONG, WA); /* state */
in_ie = 0;
return cc;
}
/* Console entry */
int32 con_halt (int32 code, int32 cc)
{
int32 temp;
conisp = IS; /* save ISP */
conpc = PC; /* save PC */
conpsl = ((PSL | cc) & 0xFFFF00FF) | code; /* PSL, param */
temp = (PSL >> PSL_V_CUR) & 0x7; /* get is'cur */
if (temp > 4) /* invalid? */
conpsl = conpsl | CON_BADPSL;
else STK[temp] = SP; /* save stack */
if (mapen) /* mapping on? */
conpsl = conpsl | CON_MAPON;
mapen = 0; /* turn off map */
SP = IS; /* set SP from IS */
PSL = PSL_IS | PSL_IPL1F; /* PSL = 41F0000 */
JUMP (ROMBASE); /* PC = 20040000 */
return 0; /* new cc = 0 */
}
/* Special boot command - linked into SCP by initial reset
Syntax: BOOT {CPU}
*/
t_stat vax630_boot (int32 flag, char *ptr)
{
char gbuf[CBUFSIZE];
get_glyph (ptr, gbuf, 0); /* get glyph */
if (gbuf[0] && strcmp (gbuf, "CPU"))
return SCPE_ARG; /* Only can specify CPU device */
return run_cmd (flag, "CPU");
}
/* Bootstrap */
t_stat cpu_boot (int32 unitno, DEVICE *dptr)
{
extern t_stat load_cmd (int32 flag, char *cptr);
extern FILE *sim_log;
t_stat r;
PC = ROMBASE;
PSL = PSL_IS | PSL_IPL1F;
conisp = 0;
conpc = 0;
conpsl = PSL_IS | PSL_IPL1F | CON_PWRUP;
if (rom == NULL)
return SCPE_IERR;
if (*rom == 0) { /* no boot? */
r = cpu_load_bootcode (BOOT_CODE_FILENAME, BOOT_CODE_ARRAY, BOOT_CODE_SIZE, TRUE, 0);
if (r != SCPE_OK)
return r;
}
return SCPE_OK;
}
t_stat rom_set_diag (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if (cptr != NULL) rom_diag_full = strcmp(cptr, "MIN");
return SCPE_OK;
}
t_stat rom_show_diag (FILE *st, UNIT *uptr, int32 val, void *desc)
{
fprintf(st, "diag=%s", (rom_diag_full ? "full" :"min"));
return SCPE_OK;
}
/* SYSD reset */
t_stat sysd_reset (DEVICE *dptr)
{
if (sim_switches & SWMASK ('P')) sysd_powerup (); /* powerup? */
ka_bdr = (BDR_POK | \
((rom_diag_full ? BDC_NORM : BDC_SKPM) << BDR_V_BDC) | \
(CPUC_ARB << BDR_V_CPUC) | \
BDR_BRKENB | \
0xF);
ka_mser = 0;
ka_cear = 0;
ka_dear = 0;
sim_vm_cmd = vax630_cmd;
return SCPE_OK;
}
/* SYSD powerup */
t_stat sysd_powerup (void)
{
rom_diag_full = 0;
return SCPE_OK;
}
t_stat cpu_show_model (FILE *st, UNIT *uptr, int32 val, void *desc)
{
#if defined(VAX_620)
fprintf (st, "model=rtVAX 1000");
#else
fprintf (st, "model=MicroVAX II");
#endif
return SCPE_OK;
}

136
VAX/vax630_syslist.c Normal file
View file

@ -0,0 +1,136 @@
/* vax630_syslist.c: MicroVAX II device list
Copyright (c) 2009-2012, 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).
08-Nov-2012 MB First version
*/
#include "vax_defs.h"
#if defined(VAX_620)
char sim_name[] = "VAX620";
#else
char sim_name[] = "VAX630";
#endif
extern DEVICE cpu_dev;
extern DEVICE tlb_dev;
extern DEVICE rom_dev;
extern DEVICE nvr_dev;
extern DEVICE wtc_dev;
extern DEVICE sysd_dev;
extern DEVICE qba_dev;
extern DEVICE tti_dev, tto_dev;
extern DEVICE cr_dev;
extern DEVICE lpt_dev;
extern DEVICE clk_dev;
extern DEVICE rq_dev, rqb_dev, rqc_dev, rqd_dev;
extern DEVICE rl_dev;
extern DEVICE ry_dev;
extern DEVICE ts_dev;
extern DEVICE tq_dev;
extern DEVICE dz_dev;
extern DEVICE xq_dev, xqb_dev;
extern DEVICE vh_dev;
extern int32 sim_switches;
extern void WriteB (uint32 pa, int32 val);
extern void rom_wr_B (int32 pa, int32 val);
extern UNIT cpu_unit;
DEVICE *sim_devices[] = {
&cpu_dev,
&tlb_dev,
&rom_dev,
&nvr_dev,
&wtc_dev,
&sysd_dev,
&qba_dev,
&clk_dev,
&tti_dev,
&tto_dev,
&dz_dev,
&vh_dev,
&cr_dev,
&lpt_dev,
&rl_dev,
&rq_dev,
&rqb_dev,
&rqc_dev,
&rqd_dev,
&ry_dev,
&ts_dev,
&tq_dev,
&xq_dev,
&xqb_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.
-r load ROM
-n load NVR
-o for memory, specify origin
*/
t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag)
{
t_stat r;
int32 i;
uint32 origin, limit;
if (flag) /* dump? */
return SCPE_ARG;
if (sim_switches & SWMASK ('R')) { /* ROM? */
origin = ROMBASE;
limit = ROMBASE + ROMSIZE;
}
else if (sim_switches & SWMASK ('N')) { /* NVR? */
origin = NVRBASE;
limit = NVRBASE + NVRSIZE;
}
else {
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 ((i = getc (fileref)) != EOF) { /* read byte stream */
if (origin >= limit) /* NXM? */
return SCPE_NXM;
if (sim_switches & SWMASK ('R')) /* ROM? */
rom_wr_B (origin, i); /* not writeable */
else WriteB (origin, i); /* store byte */
origin = origin + 1;
}
return SCPE_OK;
}

404
VAX/vax730_defs.h Normal file
View file

@ -0,0 +1,404 @@
/* vax730_defs.h: VAX 730 model-specific definitions file
Copyright (c) 2010-2011, 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).
29-Mar-2011 MB First Version
This file covers the VAX 11/730, the third VAX.
System memory map
00 0000 - EF FFFF main memory
F0 0000 - F1 FFFF reserved
F2 0000 - F3 FFFF nexus register space
F4 0000 - FB FFFF reserved
FC 0000 - FF FFFF Unibus address space
*/
#ifndef FULL_VAX
#define FULL_VAX 1
#endif
#ifndef _VAX_730_DEFS_H_
#define _VAX_730_DEFS_H_ 1
/* Microcode constructs */
#define VAX730_SID (3 << 24) /* system ID */
#define VAX730_MICRO (123 << 8) /* ucode revision */
#define CON_HLTPIN 0x0200 /* external CPU halt */
#define CON_HLTINS 0x0600 /* HALT instruction */
#define MCHK_NXM 0x08 /* NXM */
#define MCHK_IIA 0x0A /* illegal i/o addr */
#define MCHK_IUA 0x0B /* illegal unibus addr */
/* 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 TR_MCTL 0 /* nexus assignments */
#define TR_UBA 3
#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_TTINT 0x14 /* console IPL */
#define IPL_CSINT 0x14 /* console storage IPL */
#define IPL_UBA (0x15 - IPL_HMIN)
/* Machine specific IPRs */
#define MT_CSRS 28 /* Console storage */
#define MT_CSRD 29
#define MT_CSTS 30
#define MT_CSTD 31
#define MT_CDR 37 /* Cache disable */
#define MT_MCESR 38 /* MCHK err sts */
#define MT_ACCS 40 /* FPA control */
#define MT_ACCR 41 /* FPA maint */
#define MT_SBIFS 48 /* SBI fault status */
#define MT_SBIS 49 /* SBI silo */
#define MT_SBISC 50 /* SBI silo comparator */
#define MT_SBIMT 51 /* SBI maint */
#define MT_SBIER 52 /* SBI error */
#define MT_SBITA 53 /* SBI timeout addr */
#define MT_SBIQC 54 /* SBI timeout clear */
#define MT_UBINIT 55 /* Unibus Init */
/* Machine specific reserved operand tests */
/* 780 microcode patch 37 - only test LR<23:0> for appropriate length */
#define ML_LR_TEST(r) if ((uint32)((r) & 0xFFFFFF) > 0x200000) RSVD_OPND_FAULT
/* 780 microcode patch 38 - only test PxBR<31>=1 and xBR<1:0> = 0 */
#define ML_PXBR_TEST(r) if ((((r) & 0x80000000) == 0) || \
((r) & 0x00000003)) RSVD_OPND_FAULT
#define ML_SBR_TEST(r) if ((r) & 0x00000003) RSVD_OPND_FAULT
/* 780 microcode patch 78 - only test xCBB<1:0> = 0 */
#define ML_PA_TEST(r) if ((r) & 0x00000003) RSVD_OPND_FAULT
#define LP_AST_TEST(r) if ((r) > AST_MAX) RSVD_OPND_FAULT
#define LP_MBZ84_TEST(r) if ((r) & 0xF8C00000) RSVD_OPND_FAULT
#define LP_MBZ92_TEST(r) if ((r) & 0x7FC00000) RSVD_OPND_FAULT
/* Memory */
#define MAXMEMWIDTH 21 /* max mem, 16k chips */
#define MAXMEMSIZE (1 << MAXMEMWIDTH)
#define MAXMEMWIDTH_X 23 /* max mem, 64k chips */
#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 << 20), NULL, "1M", &cpu_set_size }, \
{ UNIT_MSIZE, (1u << 21), NULL, "2M", &cpu_set_size }, \
{ UNIT_MSIZE, (1u << 22), NULL, "4M", &cpu_set_size }
/* 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 UBAMAPWIDTH 11 /* Unibus map width */
#define UBAMAPSIZE 0x7FC /* Unibus map length */
#define UBADDRBASE 0xFC0000 /* Unibus addr base */
#define IOPAGEBASE 0xFFE000 /* IO page base */
#define UBAMAPBASE 0xF26800 /* Unibus map base */
#define ADDR_IS_IO(x) ((((uint32) (x)) >= UBADDRBASE) && \
(((uint32) (x)) < (UBADDRBASE + UBADDRSIZE)))
#define ADDR_IS_IOP(x) (((uint32) (x)) >= IOPAGEBASE)
#define ADDR_IS_IOM(x) ((((uint32) (x)) >= UBAMAPBASE) && \
(((uint32) (x)) < (UBAMAPBASE + UBAMAPSIZE)))
/* Nexus register space */
#define REGAWIDTH 19 /* 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 0xF00000 /* 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)
/* 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 DZ_LINES 8 /* lines per DZV mux */
#define VH_MUXES 4 /* max # of DHQ muxes */
#define DLX_LINES 16 /* max # of KL11/DL11's */
#define DCX_LINES 16 /* max # of DC11's */
#define MT_MAXFR (1 << 16) /* magtape max rec */
#define DEV_V_UBUS (DEV_V_UF + 0) /* Unibus */
#define DEV_V_NEXUS (DEV_V_UF + 1) /* Nexus */
#define DEV_V_FLTA (DEV_V_UF + 2) /* flt addr */
#define DEV_V_FFUF (DEV_V_UF + 3) /* first free flag */
#define DEV_UBUS (1u << DEV_V_UBUS)
#define DEV_NEXUS (1u << DEV_V_NEXUS)
#define DEV_FLTA (1u << DEV_V_FLTA)
#define DEV_QBUS (0)
#define DEV_Q18 (0)
#define UNIBUS TRUE /* Unibus only */
#define DEV_RDX 16 /* default device radix */
/* Device information block
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 */
} DIB;
/* Unibus I/O page layout - XUB,RQB,RQC,RQD float based on number of DZ's */
#define IOBA_DZ (IOPAGEBASE + 000100) /* DZ11 */
#define IOLN_DZ 010
#define IOBA_XUB (IOPAGEBASE + 000330 + (020 * (DZ_MUXES / 2)))
#define IOLN_XUB 010
#define IOBA_RQB (IOPAGEBASE + 000334 + (020 * (DZ_MUXES / 2)))
#define IOLN_RQB 004
#define IOBA_RQC (IOPAGEBASE + IOBA_RQB + IOLN_RQB)
#define IOLN_RQC 004
#define IOBA_RQD (IOPAGEBASE + IOBA_RQC + IOLN_RQC)
#define IOLN_RQD 004
#define IOBA_RQ (IOPAGEBASE + 012150) /* UDA50 */
#define IOLN_RQ 004
#define IOBA_TS (IOPAGEBASE + 012520) /* TS11 */
#define IOLN_TS 004
#define IOBA_RL (IOPAGEBASE + 014400) /* RL11 */
#define IOLN_RL 012
#define IOBA_XQ (IOPAGEBASE + 014440) /* DEQNA/DELQA */
#define IOLN_XQ 020
#define IOBA_XQB (IOPAGEBASE + 014460) /* 2nd DEQNA/DELQA */
#define IOLN_XQB 020
#define IOBA_TQ (IOPAGEBASE + 014500) /* TMSCP */
#define IOLN_TQ 004
#define IOBA_XU (IOPAGEBASE + 014510) /* DEUNA/DELUA */
#define IOLN_XU 010
#define IOBA_RB (IOPAGEBASE + 015606) /* RB730 */
#define IOLN_RB 002
#define IOBA_CR (IOPAGEBASE + 017160) /* CD/CR/CM */
#define IOLN_CR 010
#define IOBA_RX (IOPAGEBASE + 017170) /* RX11 */
#define IOLN_RX 004
#define IOBA_RY (IOPAGEBASE + 017170) /* RXV21 */
#define IOLN_RY 004
#define IOBA_QDSS (IOPAGEBASE + 017400) /* QDSS */
#define IOLN_QDSS 002
#define IOBA_HK (IOPAGEBASE + 017440) /* RK611 */
#define IOLN_HK 040
#define IOBA_LPT (IOPAGEBASE + 017514) /* LP11 */
#define IOLN_LPT 004
#define IOBA_PTR (IOPAGEBASE + 017550) /* PC11 reader */
#define IOLN_PTR 004
#define IOBA_PTP (IOPAGEBASE + 017554) /* PC11 punch */
#define IOLN_PTP 004
/* Interrupt assignments; within each level, priority is right to left */
#define INT_V_DZRX 0 /* BR5 */
#define INT_V_DZTX 1
#define INT_V_HK 2
#define INT_V_RL 3
#define INT_V_RB 4
#define INT_V_RQ 5
#define INT_V_TQ 6
#define INT_V_TS 7
#define INT_V_RY 8
#define INT_V_XU 9
#define INT_V_LPT 0 /* BR4 */
#define INT_V_PTR 1
#define INT_V_PTP 2
#define INT_V_CR 3
#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_RB (1u << INT_V_RB)
#define INT_LPT (1u << INT_V_LPT)
#define INT_PTR (1u << INT_V_PTR)
#define INT_PTP (1u << INT_V_PTP)
#define INT_CR (1u << INT_V_CR)
#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_RB (0x15 - IPL_HMIN)
#define IPL_LPT (0x14 - IPL_HMIN)
#define IPL_PTR (0x14 - IPL_HMIN)
#define IPL_PTP (0x14 - IPL_HMIN)
#define IPL_CR (0x14 - IPL_HMIN)
/* Device vectors */
#define VEC_QBUS 0
#define VEC_Q 0x200
#define VEC_PTR (VEC_Q + 0070)
#define VEC_PTP (VEC_Q + 0074)
#define VEC_XQ (VEC_Q + 0120)
#define VEC_XU (VEC_Q + 0120)
#define VEC_RQ (VEC_Q + 0154)
#define VEC_RL (VEC_Q + 0160)
#define VEC_LPT (VEC_Q + 0200)
#define VEC_HK (VEC_Q + 0210)
#define VEC_TS (VEC_Q + 0224)
#define VEC_CR (VEC_Q + 0230)
#define VEC_RB (VEC_Q + 0250)
#define VEC_TQ (VEC_Q + 0260)
#define VEC_RX (VEC_Q + 0264)
#define VEC_RY (VEC_Q + 0264)
#define VEC_DZRX (VEC_Q + 0300)
#define VEC_DZTX (VEC_Q + 0304)
/* 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 */
/* Logging */
#define LOG_CPU_I 0x1 /* intexc */
#define LOG_CPU_R 0x2 /* REI */
#define LOG_CPU_P 0x4 /* context */
/* Boot definitions */
#define BOOT_MB 0 /* device codes */
#define BOOT_HK 1 /* for VMB */
#define BOOT_RL 2
#define BOOT_RB 3
#define BOOT_UDA 17
#define BOOT_TK 18
#define BOOT_TD 64
/* Function prototypes for virtual memory interface */
int32 Read (uint32 va, int32 lnt, int32 acc);
void Write (uint32 va, int32 val, int32 lnt, int32 acc);
/* Function prototypes for physical memory interface (inlined) */
SIM_INLINE int32 ReadB (uint32 pa);
SIM_INLINE int32 ReadW (uint32 pa);
SIM_INLINE int32 ReadL (uint32 pa);
SIM_INLINE int32 ReadLP (uint32 pa);
SIM_INLINE void WriteB (uint32 pa, int32 val);
SIM_INLINE void WriteW (uint32 pa, int32 val);
SIM_INLINE void WriteL (uint32 pa, int32 val);
void WriteLP (uint32 pa, int32 val);
/* 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, uint8 *buf);
int32 Map_WriteW (uint32 ba, int32 bc, uint16 *buf);
t_stat show_nexus (FILE *st, UNIT *uptr, int32 val, void *desc);
void sbi_set_errcnf (void);
int32 clk_cosched (int32 wait);
#include "pdp11_io_lib.h"
#endif

196
VAX/vax730_mem.c Normal file
View file

@ -0,0 +1,196 @@
/* vax730_mem.c: VAX 11/730 memory adapter
Copyright (c) 2010-2011, 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
ROBERT M SUPNIK 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 11/730 memory controller registers.
mctl MS730 memory adapter
29-Mar-2011 MB First Version
*/
#include "vax_defs.h"
/* Memory adapter register 0 */
#define MCSR0_OF 0x00
#define MCSR0_ES 0x0000007F /* Error syndrome */
#define MCSR0_V_FPN 9
#define MCSR0_M_FPN 0x7FFF
#define MCSR0_FPN (MCSR0_M_FPN << MCSR0_V_FPN) /* Failing page number */
/* Memory adapter register 1 */
#define MCSR1_OF 0x01
#define MCSR1_RW 0x3E000000
#define MCSR1_MBZ 0x01FFFF80
/* Memory adapter register 2 */
#define MCSR2_OF 0x02
#define MCSR2_M_MAP 0xFFFF;
#define MCSR2_V_CS 24
#define MCSR2_CS (1u << MCSR2_V_CS)
#define MCSR2_MBZ 0xFEFF0000
/* Debug switches */
#define MCTL_DEB_RRD 0x01 /* reg reads */
#define MCTL_DEB_RWR 0x02 /* reg writes */
#define MEM_SIZE_16K (1u << 17) /* Board size (16k chips) */
#define MEM_SIZE_64K (1u << 19) /* Board size (64k chips) */
#define MEM_BOARD_MASK(x,y) ((1u << (uint32)(x/y)) - 1)
extern UNIT cpu_unit;
extern FILE *sim_log, *sim_deb;
uint32 mcsr0 = 0;
uint32 mcsr1 = 0;
uint32 mcsr2 = 0;
t_stat mctl_reset (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 mctl_dib[] = { TR_MCTL, 0, &mctl_rdreg, &mctl_wrreg, 0 };
UNIT mctl_unit = { UDATA (NULL, 0, 0) };
REG mctl_reg[] = {
{ HRDATA (CSR0, mcsr0, 32) },
{ HRDATA (CSR1, mcsr1, 32) },
{ HRDATA (CSR2, mcsr2, 32) },
{ NULL }
};
MTAB mctl_mod[] = {
{ MTAB_XTD|MTAB_VDV, TR_MCTL, "NEXUS", NULL,
NULL, &show_nexus },
{ 0 }
};
DEBTAB mctl_deb[] = {
{ "REGREAD", MCTL_DEB_RRD },
{ "REGWRITE", MCTL_DEB_RWR },
{ NULL, 0 }
};
DEVICE mctl_dev = {
"MCTL", &mctl_unit, mctl_reg, mctl_mod,
1, 16, 16, 1, 16, 8,
NULL, NULL, &mctl_reset,
NULL, NULL, NULL,
&mctl_dib, DEV_NEXUS | DEV_DEBUG, 0,
mctl_deb, 0, 0
};
/* Memory controller register read */
t_stat mctl_rdreg (int32 *val, int32 pa, int32 lnt)
{
int32 ofs;
ofs = NEXUS_GETOFS (pa); /* get offset */
switch (ofs) { /* case on offset */
case MCSR0_OF: /* CSR0 */
*val = mcsr0;
break;
case MCSR1_OF: /* CSR1 */
*val = mcsr1 & ~MCSR1_MBZ;
break;
case MCSR2_OF: /* CSR2 */
*val = mcsr2 & ~MCSR2_MBZ;
break;
default:
return SCPE_NXM;
}
if (DEBUG_PRI (mctl_dev, MCTL_DEB_RRD))
fprintf (sim_deb, ">>MCTL: reg %d read, value = %X\n", ofs, *val);
return SCPE_OK;
}
/* Memory controller register write */
t_stat mctl_wrreg (int32 val, int32 pa, int32 lnt)
{
int32 ofs;
ofs = NEXUS_GETOFS (pa); /* get offset */
switch (ofs) { /* case on offset */
case MCSR0_OF: /* CSR0 */
break;
case MCSR1_OF: /* CSR1 */
mcsr1 = val & MCSR1_RW;
break;
case MCSR2_OF: /* CSR2 */
break;
default:
return SCPE_NXM;
}
if (DEBUG_PRI (mctl_dev, MCTL_DEB_RWR))
fprintf (sim_deb, ">>MCTL: reg %d write, value = %X\n", ofs, val);
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)
{
mcsr0 = 0;
mcsr1 = 0;
mcsr2 = 0;
if (MEMSIZE > MAXMEMSIZE) /* More than 2MB? */
mcsr2 = mcsr2 | MEM_BOARD_MASK(MEMSIZE, MEM_SIZE_64K) | MCSR2_CS; /* Use 64k chips */
else
mcsr2 = mcsr2 | MEM_BOARD_MASK(MEMSIZE, MEM_SIZE_16K); /* Use 16k chips */
return SCPE_OK;
}

670
VAX/vax730_rb.c Normal file
View file

@ -0,0 +1,670 @@
/* vax730_rb.c: RB730 disk simulator
Copyright (c) 2010-2011, Matt Burke
This module incorporates code from SimH, Copyright (c) 1993-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).
rb RB730 - RB02/RB80 disk controller
29-Mar-2011 MB First Version
The RB730 is a four drive disk subsystem consisting of up to three RL02
drives (known as RB02) and one optional RA80 drive (known as RB80).
Unlike the RL11 controller seeks are not done relative to the current
disk address.
The RB730 has two regiter address spaces:
- One dummy 16-bit register in unibus I/O space to allow the controller to
be detected by SYSGEN autoconfigure (and others).
- Eight 32-bit registers in the unibus controller space for the actual
device control.
*/
#include "vax_defs.h"
/* Constants */
#define RB02_NUMWD 128 /* words/sector */
#define RB02_NUMSC 40 /* sectors/track */
#define RB02_NUMSF 2 /* tracks/cylinder */
#define RB02_NUMCY 512 /* cylinders/drive */
#define RB02_SIZE (RB02_NUMCY * RB02_NUMSF * \
RB02_NUMSC * RB02_NUMWD) /* words/drive */
#define RB80_NUMWD 256 /* words/sector */
#define RB80_NUMSC 32 /* sectors/track */
#define RB80_NUMSF 14 /* tracks/cylinder */
#define RB80_NUMCY 559 /* cylinders/drive */
#define RB80_SIZE (RB80_NUMCY * RB80_NUMSF * \
RB80_NUMSC * RB80_NUMWD) /* words/drive */
#define RB_NUMWD(u) ((u->flags & UNIT_RB80) ? RB80_NUMWD : RB02_NUMWD)
#define RB_NUMSC(u) ((u->flags & UNIT_RB80) ? RB80_NUMSC : RB02_NUMSC)
#define RB_NUMSF(u) ((u->flags & UNIT_RB80) ? RB80_NUMSF : RB02_NUMSF)
#define RB_NUMCY(u) ((u->flags & UNIT_RB80) ? RB80_NUMCY : RB02_NUMCY)
#define RB_SIZE(u) ((u->flags & UNIT_RB80) ? RB80_SIZE : RB02_SIZE)
#define RB_NUMDR 4 /* drives/controller */
#define RB_MAXFR (1 << 16) /* max transfer */
/* Flags in the unit flags word */
#define UNIT_V_WLK (UNIT_V_UF + 0) /* hwre write lock */
#define UNIT_V_RB80 (UNIT_V_UF + 1) /* RB02 vs RB80 */
#define UNIT_V_DUMMY (UNIT_V_UF + 2) /* dummy flag */
#define UNIT_DUMMY (1 << UNIT_V_DUMMY)
#define UNIT_WLK (1u << UNIT_V_WLK)
#define UNIT_RB80 (1u << UNIT_V_RB80)
#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write protected */
/* Parameters in the unit descriptor */
#define TRK u3 /* current track */
#define STAT u4 /* status */
#define SIP u5 /* seek in progress */
/* RBDS, NI = not implemented, * = kept in STAT, ^ = kept in TRK */
#define RB02DS_LOAD 0 /* no cartridge */
#define RB02DS_LOCK 5 /* lock on */
#define RB02DS_BHO 0000010 /* brushes home NI */
#define RB02DS_HDO 0000020 /* heads out NI */
#define RB02DS_CVO 0000040 /* cover open NI */
#define RB02DS_HD 0000100 /* head select ^ */
#define RB02DS_DSE 0000400 /* drv sel err NI */
#define RB02DS_VCK 0001000 /* vol check * */
#define RB02DS_WGE 0002000 /* wr gate err * */
#define RB02DS_SPE 0004000 /* spin err * */
#define RB02DS_STO 0010000 /* seek time out NI */
#define RB02DS_WLK 0020000 /* wr locked */
#define RB02DS_HCE 0040000 /* hd curr err NI */
#define RB02DS_WDE 0100000 /* wr data err NI */
#define RB02DS_ATT (RB02DS_HDO+RB02DS_BHO+RB02DS_LOCK) /* att status */
#define RB02DS_UNATT (RB02DS_CVO+RB02DS_LOAD) /* unatt status */
#define RB02DS_ERR (RB02DS_WDE+RB02DS_HCE+RB02DS_STO+RB02DS_SPE+RB02DS_WGE+ \
RB02DS_VCK+RB02DS_DSE) /* errors bits */
#define RB80DS_SCNT 0x0000000F
#define RB80DS_FLT 0x00000100
#define RB80DS_PLV 0x00000200
#define RB80DS_SKE 0x00000400
#define RB80DS_OCY 0x00000800
#define RB80DS_RDY 0x00001000
#define RB80DS_WLK 0x00002000
/* RBCS */
#define RBCS_DRDY 0x00000001 /* drive ready */
#define RBCS_M_FUNC 0x7 /* function */
#define RBCS_NOP 0
#define RBCS_WCHK 1
#define RBCS_GSTA 2
#define RBCS_SEEK 3
#define RBCS_RHDR 4
#define RBCS_WRITE 5
#define RBCS_READ 6
#define RBCS_RNOHDR 7
#define RBCS_V_FUNC 1
#define RBCS_M_DRIVE 0x3
#define RBCS_V_DRIVE 8
#define RBCS_INCMP 0x00000400 /* incomplete */
#define RBCS_CRC 0x00000800 /* CRC error */
#define RBCS_DLT 0x00001000 /* data late */
#define RBCS_HDE 0x00001400 /* header error */
#define RBCS_NXM 0x00002000 /* non-exist memory */
#define RBCS_DRE 0x00004000 /* drive error */
#define RBCS_ERR 0x00008000 /* error summary */
#define RBCS_ALLERR (RBCS_ERR+RBCS_DRE+RBCS_NXM+RBCS_CRC+RBCS_INCMP)
#define RBCS_M_ATN 0xF
#define RBCS_V_ATN 16
#define RBCS_ATN (RBCS_M_ATN << RBCS_V_ATN)
#define RBCS_M_ECC 0x2
#define RBCS_V_ECC 20
#define RBCS_SSI 0x00400000
#define RBCS_SSE 0x00800000
#define RBCS_IRQ 0x01000000
#define RBCS_MTN 0x02000000
#define RBCS_R80 0x04000000
#define RBCS_ASI 0x08000000
#define RBCS_TOI 0x10000000
#define RBCS_FMT 0x20000000
#define RBCS_MATN 0x80000000
//#define RBCS_RW 0001716 /* read/write */
#define RBCS_RW ((RBCS_M_FUNC << RBCS_V_FUNC) + \
CSR_IE + CSR_DONE + \
(RBCS_M_DRIVE << RBCS_V_DRIVE) + \
RBCS_SSI + RBCS_MTN + RBCS_ASI + \
RBCS_TOI + RBCS_FMT + RBCS_MATN)
#define RBCS_C0 RBCS_SSE
#define RBCS_C1 (rbcs & RBCS_MATN) ? RBCS_IRQ : \
((RBCS_M_ATN << RBCS_V_ATN) + RBCS_IRQ)
#define GET_FUNC(x) (((x) >> RBCS_V_FUNC) & RBCS_M_FUNC)
#define GET_DRIVE(x) (((x) >> RBCS_V_DRIVE) & RBCS_M_DRIVE)
/* RBBA */
#define RBBA_RW 0x0003FFFF
/* RBBC */
/* RBMP */
#define RBMP_MRK 0x00000001
#define RBMP_GST 0x00000002
#define RBMP_RST 0x00000008
/* RBDA */
#define RBDA_V_SECT 0 /* sector */
#define RBDA_M_SECT 0xFF
#define RBDA_V_TRACK 8 /* track */
#define RBDA_M_TRACK 0xFF
#define RBDA_V_CYL 16 /* cylinder */
#define RBDA_M_CYL 0xFFFF
#define RBDA_TRACK (RBDA_M_TRACK << RBDA_V_TRACK)
#define RBDA_CYL (RBDA_M_CYL << RBDA_V_CYL)
#define GET_SECT(x) (((x) >> RBDA_V_SECT) & RBDA_M_SECT)
#define GET_CYL(x) (((x) >> RBDA_V_CYL) & RBDA_M_CYL)
#define GET_TRACK(x) (((x) >> RBDA_V_TRACK) & RBDA_M_TRACK)
//#define GET_DA(x) ((GET_CYL(x) * RB02_NUMSF * GET_TRACK (x) * RB02_NUMSC) + GET_SECT (x))
#define GET_DA(x,u) ((GET_TRACK (x) * RB_NUMCY(u) * RB_NUMSC(u) * RB_NUMWD(u)) + \
(GET_CYL(x) * RB_NUMSC(u) * RB_NUMWD(u)) + \
(GET_SECT (x) * RB_NUMWD(u)))
#define DBG_REG 0x0001 /* registers */
#define DBG_CMD 0x0002 /* commands */
#define DBG_RD 0x0004 /* disk reads */
#define DBG_WR 0x0008 /* disk writes */
extern int32 int_req[IPL_HLVL];
uint16 *rbxb = NULL; /* xfer buffer */
int32 rbcs = 0; /* control/status */
int32 rbba = 0; /* memory address */
int32 rbbc = 0; /* bytes count */
int32 rbda = 0; /* disk addr */
int32 rbmp = 0, rbmp1 = 0, rbmp2 = 0; /* mp register queue */
int32 rb_swait = 150; /* seek wait */
int32 rb_mwait = 300; /* seek wait */
int32 rb_cwait = 50; /* seek wait */
t_stat rb_rd16 (int32 *data, int32 PA, int32 access);
t_stat rb_wr16 (int32 data, int32 PA, int32 access);
t_stat rb_rd32 (int32 *data, int32 PA, int32 access);
t_stat rb_wr32 (int32 data, int32 PA, int32 access);
t_stat rb_svc (UNIT *uptr);
t_stat rb_reset (DEVICE *dptr);
void rb_set_done (int32 error);
t_stat rb_attach (UNIT *uptr, char *cptr);
t_stat rb_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat rb_set_bad (UNIT *uptr, int32 val, char *cptr, void *desc);
/* RB730 data structures
rb_dev RB device descriptor
rb_unit RB unit list
rb_reg RB register list
rb_mod RB modifier list
*/
DIB rb_dib = {
IOBA_RB, IOLN_RB, &rb_rd16, &rb_wr16,
1, IVCL (RB), VEC_RB, { NULL } };
UNIT rb_unit[] = {
{ UDATA (&rb_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
UNIT_ROABLE+UNIT_RB80, RB80_SIZE) },
{ UDATA (&rb_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
UNIT_ROABLE, RB02_SIZE) },
{ UDATA (&rb_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
UNIT_ROABLE, RB02_SIZE) },
{ UDATA (&rb_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
UNIT_ROABLE, RB02_SIZE) },
};
REG rb_reg[] = {
{ NULL }
};
DEBTAB rb_debug[] = {
{"REG", DBG_REG},
{"CMD", DBG_CMD},
{"RD", DBG_RD},
{"WR", DBG_WR},
{0}
};
MTAB rb_mod[] = {
{ UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL },
{ UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL },
{ UNIT_DUMMY, 0, NULL, "BADBLOCK", &rb_set_bad },
{ (UNIT_RB80+UNIT_ATT), UNIT_ATT, "RB02", NULL, NULL },
{ (UNIT_RB80+UNIT_ATT), (UNIT_RB80+UNIT_ATT), "RB80", NULL, NULL },
{ (UNIT_RB80+UNIT_ATT), 0, "RB02", NULL, NULL },
{ (UNIT_RB80+UNIT_ATT), UNIT_RB80, "RB80", NULL, NULL },
{ (UNIT_RB80), 0, NULL, "RB02", &rb_set_size },
{ (UNIT_RB80), UNIT_RB80, NULL, "RB80", &rb_set_size },
{ MTAB_XTD|MTAB_VDV, 010, "ADDRESS", "ADDRESS",
&set_addr, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR",
&set_vec, &show_vec, NULL },
{ 0 }
};
DEVICE rb_dev = {
"RB", rb_unit, rb_reg, rb_mod,
RB_NUMDR, DEV_RDX, T_ADDR_W, 1, DEV_RDX, 16,
NULL, NULL, &rb_reset,
NULL, &rb_attach, NULL,
&rb_dib, DEV_DISABLE | DEV_UBUS | DEV_DEBUG, 0,
rb_debug, 0, 0
};
/* I/O dispatch routines
17775606 RBDCS dummy csr to trigger sysgen
*/
t_stat rb_rd16 (int32 *data, int32 PA, int32 access)
{
*data = 0;
return SCPE_OK;
}
t_stat rb_wr16 (int32 data, int32 PA, int32 access)
{
return SCPE_OK;
}
t_stat rb_rd32 (int32 *data, int32 PA, int32 access)
{
UNIT *uptr;
switch ((PA >> 2) & 07) {
case 0: /* RBCS */
if (rbcs & RBCS_ALLERR)
rbcs = rbcs | RBCS_ERR;
uptr = rb_dev.units + GET_DRIVE (rbcs);
if ((sim_is_active (uptr)) || (uptr->flags & UNIT_DIS))
rbcs = rbcs & ~RBCS_DRDY;
else rbcs = rbcs | RBCS_DRDY; /* see if ready */
if (uptr->flags & UNIT_RB80)
rbcs = rbcs | RBCS_R80;
else rbcs = rbcs & ~RBCS_R80;
*data = rbcs;
break;
case 1: /* RBBA */
*data = rbba & RBBA_RW;
break;
case 2: /* RBBC */
*data = rbbc;
break;
case 3: /* RBDA */
*data = rbda;
break;
case 4: /* RBMP */
*data = rbmp;
rbmp = rbmp1; /* ripple data */
rbmp1 = rbmp2;
break;
case 5: /* ECCPS */
case 6: /* ECCPT */
case 7: /* INIT */
*data = 0;
break;
}
sim_debug(DBG_REG, &rb_dev, "reg %d read, value = %X\n", (PA >> 2) & 07, *data);
return SCPE_OK;
}
t_stat rb_wr32 (int32 data, int32 PA, int32 access)
{
UNIT *uptr;
sim_debug(DBG_REG, &rb_dev, "reg %d write, value = %X\n", (PA >> 2) & 07, data);
switch ((PA >> 2) & 07) {
case 0: /* CSR */
if (rbcs & RBCS_ALLERR)
rbcs = rbcs | RBCS_ERR;
uptr = rb_dev.units + GET_DRIVE (data);
if ((sim_is_active (uptr)) || (uptr->flags & UNIT_DIS))
rbcs = rbcs & ~RBCS_DRDY;
else rbcs = rbcs | RBCS_DRDY; /* see if ready */
if (uptr->flags & UNIT_RB80)
rbcs = rbcs | RBCS_R80;
else rbcs = rbcs & ~RBCS_R80;
rbcs = rbcs & ~(data & RBCS_C1);
rbcs = rbcs & ~(~data & RBCS_C0);
rbcs = (rbcs & ~RBCS_RW) | (data & RBCS_RW);
if (data & RBCS_ATN) CLR_INT (RB);
if ((data & CSR_DONE) || (sim_is_active (uptr))) /* ready set? */
return SCPE_OK;
CLR_INT (RB); /* clear interrupt */
rbcs = rbcs & ~RBCS_ALLERR; /* clear errors */
uptr->SIP = 0;
if (uptr->flags & UNIT_DIS) {
rbcs = rbcs | (1u << (RBCS_V_ATN + GET_DRIVE (rbcs)));
rb_set_done (RBCS_ERR | RBCS_INCMP);
break;
}
switch (GET_FUNC (rbcs)) { /* case on RBCS<3:1> */
case RBCS_NOP: /* nop */
rb_set_done (0);
break;
case RBCS_SEEK: /* seek */
sim_activate (uptr, rb_swait);
break;
default: /* data transfer */
sim_activate (uptr, rb_cwait); /* activate unit */
break;
} /* end switch func */
break;
case 1: /* BAR */
rbba = data & RBBA_RW;
break;
case 2: /* BCR */
rbbc = data;
break;
case 3: /* DAR */
rbda = data;
break;
case 4: /* MPR */
rbmp = rbmp1 = rbmp2 = data;
break;
case 5: /* ECCPS */
case 6: /* ECCPT */
break;
case 7: /* INIT */
return rb_reset(&rb_dev);
}
return SCPE_OK;
}
/* Service unit timeout
If seek in progress, complete seek command
Else complete data transfer command
The unit control block contains the function and cylinder for
the current command.
*/
t_stat rb_svc (UNIT *uptr)
{
int32 curr, newc, swait;
int32 err, wc, maxwc, t;
int32 i, func, da, awc;
uint32 ma;
uint16 comp;
func = GET_FUNC (rbcs); /* get function */
if (func == RBCS_GSTA) { /* get status */
sim_debug(DBG_CMD, &rb_dev, "Get Status\n");
if (uptr->flags & UNIT_RB80) {
rbmp = uptr->STAT | RB80DS_PLV;
if (uptr->flags & UNIT_ATT)
rbmp = rbmp | RB80DS_RDY | RB80DS_OCY;
if (uptr->flags & UNIT_WPRT)
rbmp = rbmp | RB80DS_WLK;
}
else {
if (rbmp & RBMP_RST)
uptr->STAT = uptr->STAT & ~RB02DS_ERR;
rbmp = uptr->STAT | (uptr->flags & UNIT_ATT)? RB02DS_ATT: RB02DS_UNATT;
if (uptr->flags & UNIT_WPRT)
rbmp = rbmp | RB02DS_WLK;
}
rbmp2 = rbmp1 = rbmp;
rb_set_done (0); /* done */
return SCPE_OK;
}
if (func == RBCS_RHDR) { /* read header? */
sim_debug(DBG_CMD, &rb_dev, "Read Header\n");
rbmp = (uptr->TRK & RBDA_TRACK) | GET_SECT (rbda);
rbmp1 = rbmp2 = 0;
rbcs = rbcs | (1 << (RBCS_V_ATN + GET_DRIVE (rbcs)));
rb_set_done (0); /* done */
return SCPE_OK;
}
if ((uptr->flags & UNIT_ATT) == 0) { /* attached? */
rbcs = rbcs & ~RBCS_DRDY; /* clear drive ready */
rbcs = rbcs | (1u << (RBCS_V_ATN + GET_DRIVE (rbcs)));
if ((uptr->flags & UNIT_RB80) == 0)
uptr->STAT = uptr->STAT | RB02DS_SPE; /* spin error */
rb_set_done (RBCS_ERR | RBCS_INCMP); /* flag error */
//return IORETURN (rl_stopioe, SCPE_UNATT);
return SCPE_OK;
}
if ((func == RBCS_WRITE) && (uptr->flags & UNIT_WPRT)) {
if ((uptr->flags & UNIT_RB80) == 0)
uptr->STAT = uptr->STAT | RB02DS_WGE; /* write and locked */
rb_set_done (RBCS_ERR | RBCS_DRE);
return SCPE_OK;
}
if (func == RBCS_SEEK) { /* seek? */
if (uptr->SIP == 0) {
sim_debug(DBG_CMD, &rb_dev, "Seek, CYL=%d, TRK=%d, SECT=%d\n", GET_CYL(rbda), GET_TRACK(rbda), GET_SECT(rbda));
uptr->SIP = 1;
if (rbda == 0xFFFFFFFF) swait = rb_swait;
else {
curr = GET_CYL (uptr->TRK); /* current cylinder */
newc = GET_CYL (rbda); /* offset */
uptr->TRK = (newc << RBDA_V_CYL); /* put on track */
swait = rb_cwait * abs (newc - curr);
if (swait < rb_mwait) swait = rb_mwait;
}
sim_activate (uptr, swait);
rbcs = rbcs | (1 << (RBCS_V_ATN + GET_DRIVE (rbcs)));
rbcs = rbcs | RBCS_IRQ;
rb_set_done(0);
return SCPE_OK;
}
else {
sim_debug(DBG_CMD, &rb_dev, "Seek done\n");
rbcs = rbcs | (1 << (RBCS_V_ATN + GET_DRIVE (rbcs)));
uptr->SIP = 0;
rb_set_done (0); /* done */
return SCPE_OK;
}
}
if (((func != RBCS_RNOHDR) && ((uptr->TRK & RBDA_CYL) != (rbda & RBDA_CYL)))
|| (GET_SECT (rbda) >= RB_NUMSC(uptr))) { /* bad cyl or sector? */
sim_debug(DBG_CMD, &rb_dev, "Invalid cylinder or sector, CYL=%d, TRK=%d, SECT=%d\n", GET_CYL(rbda), GET_TRACK(rbda), GET_SECT(rbda));
rb_set_done (RBCS_ERR | RBCS_HDE | RBCS_INCMP); /* wrong cylinder? */
return SCPE_OK;
}
ma = rbba; /* get mem addr */
da = GET_DA (rbda, uptr); /* get disk addr */
wc = ((rbbc * -1) >> 1); /* get true wc */
maxwc = (RB_NUMSC(uptr) - GET_SECT (rbda)) * RB_NUMWD(uptr); /* max transfer */
if (wc > maxwc) /* track overrun? */
wc = maxwc;
err = sim_fseek (uptr->fileref, da * sizeof (int16), SEEK_SET);
if ((func >= RBCS_READ) && (err == 0)) { /* read (no hdr)? */
sim_debug(DBG_CMD, &rb_dev, "Read, CYL=%d, TRK=%d, SECT=%d, WC=%d, DA=%d\n", GET_CYL(rbda), GET_TRACK(rbda), GET_SECT(rbda), wc, da);
i = sim_fread (rbxb, sizeof (uint16), wc, uptr->fileref);
err = ferror (uptr->fileref);
for ( ; i < wc; i++) /* fill buffer */
rbxb[i] = 0;
if ((t = Map_WriteW (ma, wc << 1, rbxb))) { /* store buffer */
rbcs = rbcs | RBCS_ERR | RBCS_NXM; /* nxm */
wc = wc - t; /* adjust wc */
}
} /* end read */
if ((func == RBCS_WRITE) && (err == 0)) { /* write? */
sim_debug(DBG_CMD, &rb_dev, "Write, CYL=%d, TRK=%d, SECT=%d, WC=%d, DA=%d\n", GET_CYL(rbda), GET_TRACK(rbda), GET_SECT(rbda), wc, da);
if ((t = Map_ReadW (ma, wc << 1, rbxb))) { /* fetch buffer */
rbcs = rbcs | RBCS_ERR | RBCS_NXM; /* nxm */
wc = wc - t; /* adj xfer lnt */
}
if (wc) { /* any xfer? */
awc = (wc + (RB_NUMWD(uptr) - 1)) & ~(RB_NUMWD(uptr) - 1); /* clr to */
for (i = wc; i < awc; i++) /* end of blk */
rbxb[i] = 0;
sim_fwrite (rbxb, sizeof (uint16), awc, uptr->fileref);
err = ferror (uptr->fileref);
}
} /* end write */
if ((func == RBCS_WCHK) && (err == 0)) { /* write check? */
sim_debug(DBG_CMD, &rb_dev, "WCheck, CYL=%d, TRK=%d, SECT=%d, WC=%d, DA=%d\n", GET_CYL(rbda), GET_TRACK(rbda), GET_SECT(rbda), wc, da);
i = sim_fread (rbxb, sizeof (uint16), wc, uptr->fileref);
err = ferror (uptr->fileref);
for ( ; i < wc; i++) /* fill buffer */
rbxb[i] = 0;
awc = wc; /* save wc */
for (wc = 0; (err == 0) && (wc < awc); wc++) { /* loop thru buf */
if (Map_ReadW (ma + (wc << 1), 2, &comp)) { /* mem wd */
rbcs = rbcs | RBCS_ERR | RBCS_NXM; /* nxm */
break;
}
if (comp != rbxb[wc]) /* check to buf */
rbcs = rbcs | RBCS_ERR | RBCS_CRC;
} /* end for */
} /* end wcheck */
rbbc = (rbbc + (wc << 1)); /* final byte count */
if (rbbc != 0) { /* completed? */
rbcs = rbcs | RBCS_ERR | RBCS_INCMP;
}
ma = ma + (wc << 1); /* final byte addr */
rbba = ma & RBBA_RW;
rbda = rbda + ((wc + (RB_NUMWD(uptr) - 1)) / RB_NUMWD(uptr));
rb_set_done (0);
if (err != 0) { /* error? */
perror ("RB I/O error");
clearerr (uptr->fileref);
return SCPE_IOERR;
}
return SCPE_OK;
}
/* Set done and possibly errors */
void rb_set_done (int32 status)
{
rbcs = rbcs | status | CSR_DONE; /* set done */
rbcs = rbcs | RBCS_IRQ;
if (rbcs & CSR_IE) {
sim_debug(DBG_CMD, &rb_dev, "Done, INT\n");
SET_INT (RB);
}
else {
sim_debug(DBG_CMD, &rb_dev, "Done, no INT\n");
CLR_INT (RB);
}
return;
}
/* Device reset */
t_stat rb_reset (DEVICE *dptr)
{
int32 i;
UNIT *uptr;
rbcs = CSR_DONE;
rbda = rbba = rbbc = rbmp = 0;
CLR_INT (RB);
for (i = 0; i < RB_NUMDR; i++) {
uptr = rb_dev.units + i;
sim_cancel (uptr);
uptr->STAT = 0;
uptr->SIP = 0;
}
if (rbxb == NULL)
rbxb = (uint16 *) calloc (RB_MAXFR, sizeof (uint16));
if (rbxb == NULL)
return SCPE_MEM;
return SCPE_OK;
}
/* Attach routine */
t_stat rb_attach (UNIT *uptr, char *cptr)
{
uint32 p;
t_stat r;
uptr->capac = (uptr->flags & UNIT_RB80)? RB80_SIZE: RB02_SIZE;
r = attach_unit (uptr, cptr); /* attach unit */
if (r != SCPE_OK) /* error? */
return r;
uptr->TRK = 0; /* cylinder 0 */
if ((uptr->flags & UNIT_RB80) == 0)
uptr->STAT = RB02DS_VCK; /* new volume */
if ((p = sim_fsize (uptr->fileref)) == 0) { /* new disk image? */
if (uptr->flags & UNIT_RO) /* if ro, done */
return SCPE_OK;
return pdp11_bad_block (uptr, RB_NUMSC(uptr), RB_NUMWD(uptr));
}
return SCPE_OK;
}
/* Set size routine */
t_stat rb_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if (uptr->flags & UNIT_ATT)
return SCPE_ALATT;
uptr->capac = (val & UNIT_RB80)? RB80_SIZE: RB02_SIZE;
return SCPE_OK;
}
/* Set bad block routine */
t_stat rb_set_bad (UNIT *uptr, int32 val, char *cptr, void *desc)
{
return pdp11_bad_block (uptr, RB_NUMSC(uptr), RB_NUMWD(uptr));
}

1197
VAX/vax730_stddev.c Normal file

File diff suppressed because it is too large Load diff

649
VAX/vax730_sys.c Normal file
View file

@ -0,0 +1,649 @@
/* vax730_sys.c: VAX 11/730 system-specific logic
Copyright (c) 2010-2011, 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 11/730 system-specific registers and devices.
sysb system bus controller
29-Mar-2011 MB First Version
*/
#include "vax_defs.h"
#ifdef DONT_USE_INTERNAL_ROM
#define BOOT_CODE_FILENAME "vmb.exe"
#define BOOT_CODE_ARRAY NULL
#define BOOT_CODE_SIZE 0
#else /* !DONT_USE_INTERNAL_ROM */
#include "vax_vmb_exe.h" /* Defines BOOT_CODE_FILENAME and BOOT_CODE_ARRAY, etc */
#endif /* DONT_USE_INTERNAL_ROM */
static char cpu_boot_cmd[CBUFSIZE] = { 0 }; /* boot command */
/* VAX-11/730 boot device definitions */
struct boot_dev {
char *name;
int32 code;
int32 let;
};
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 },
{ "TQ", BOOT_TK, 1 << 24 },
{ "TD", BOOT_TD, 0 },
{ "RB", BOOT_RB, 0 },
{ NULL }
};
extern int32 R[16];
extern int32 PSL;
extern int32 ASTLVL, SISR;
extern int32 mapen, pme, trpirq;
extern int32 in_ie;
extern int32 mchk_va, mchk_ref;
extern int32 crd_err, mem_err, hlt_pin;
extern int32 tmr_int, tti_int, tto_int, csi_int, cso_int;
extern jmp_buf save_env;
extern int32 p1;
extern int32 sim_switches;
extern DEVICE *sim_devices[];
extern FILE *sim_log;
extern CTAB *sim_vm_cmd;
t_stat sysb_reset (DEVICE *dptr);
t_stat vax730_boot (int32 flag, char *ptr);
t_stat vax730_boot_parse (int32 flag, char *ptr);
t_stat cpu_boot (int32 unitno, DEVICE *dptr);
extern int32 intexc (int32 vec, int32 cc, int32 ipl, int ei);
extern int32 iccs_rd (void);
extern int32 nicr_rd (void);
extern int32 icr_rd (t_bool interp);
extern int32 todr_rd (void);
extern int32 rxcs_rd (void);
extern int32 rxdb_rd (void);
extern int32 txcs_rd (void);
extern int32 csrs_rd (void);
extern int32 csrd_rd (void);
extern int32 csts_rd (void);
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 csrs_wr (int32 dat);
extern void csts_wr (int32 dat);
extern void cstd_wr (int32 dat);
extern void init_ubus_tab (void);
extern t_stat build_ubus_tab (DEVICE *dptr, DIB *dibp);
extern int32 ubamap_rd (int32 pa);
extern void ubamap_wr (int32 pa, int32 val, int32 lnt);
extern t_bool uba_eval_int (int32 lvl);
extern int32 uba_get_ubvector (int32 lvl);
/* SYSB data structures
sysb_dev SYSB device descriptor
sysb_unit SYSB unit
sysb_reg SYSB register list
*/
UNIT sysb_unit = { UDATA (NULL, 0, 0) };
REG sysb_reg[] = {
{ BRDATA (BOOTCMD, cpu_boot_cmd, 16, 8, CBUFSIZE), REG_HRO },
{ NULL }
};
DEVICE sysb_dev = {
"SYSB", &sysb_unit, sysb_reg, NULL,
1, 16, 16, 1, 16, 8,
NULL, NULL, &sysb_reset,
NULL, NULL, NULL,
NULL, 0
};
/* Special boot command, overrides regular boot */
CTAB vax730_cmd[] = {
{ "BOOT", &vax730_boot, RU_BOOT,
"bo{ot} <device>{/R5:flg} boot device\n", &run_cmd_message },
{ NULL }
};
/* The VAX 11/730 has two sources of interrupts
- internal device interrupts (CPU, console, clock, console storage)
- external device interrupts (Unibus)
Find highest priority vectorable interrupt */
int32 eval_int (void)
{
int32 ipl = PSL_GETIPL (PSL);
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_CLKINT) && tmr_int) /* clock int */
return IPL_CLKINT;
for (i = IPL_HMAX; i >= IPL_HMIN; i--) { /* chk hwre int */
if (i <= ipl) /* at ipl? no int */
return 0;
if (uba_eval_int(i - IPL_HMIN))
return i;
}
if ((ipl < IPL_TTINT) && (tti_int || tto_int)) /* console int */
return IPL_TTINT;
if ((ipl < IPL_CSINT) && (csi_int || cso_int)) /* console storage int */
return IPL_CSINT;
if (ipl >= IPL_SMAX) /* ipl >= sw max? */
return 0;
if ((t = SISR & sw_int_mask[ipl]) == 0) /* eligible req */
return 0;
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 l;
if (lvl == IPL_CLKINT) { /* clock? */
tmr_int = 0; /* 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 (uba_eval_int(l))
return uba_get_ubvector(l);
}
if (lvl == IPL_TTINT) { /* console? */
if (tti_int) { /* input? */
tti_int = 0; /* clear req */
return SCB_TTI; /* return vector */
}
if (tto_int) { /* output? */
tto_int = 0; /* clear req */
return SCB_TTO; /* return vector */
}
}
if (lvl == IPL_CSINT) { /* console storage? */
if (csi_int) { /* input? */
csi_int = 0; /* clear req */
return SCB_CSI; /* return vector */
}
if (cso_int) { /* output? */
cso_int = 0; /* clear req */
return SCB_CSO; /* return vector */
}
}
return 0;
}
/* Read 730-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 (FALSE);
break;
case MT_TODR: /* TODR */
val = todr_rd ();
break;
case MT_ACCS: /* ACCS (not impl) */
val = 0;
break;
case MT_RXCS: /* RXCS */
val = rxcs_rd ();
break;
case MT_RXDB: /* RXDB */
val = rxdb_rd ();
break;
case MT_TXCS: /* TXCS */
val = txcs_rd ();
break;
case MT_SID: /* SID */
val = VAX730_SID | VAX730_MICRO;
break;
case MT_MCESR: /* MCESR (not impl) */
val = 0;
break;
case MT_CSRS: /* CSRS */
val = csrs_rd ();
break;
case MT_CSRD: /* CSRD */
val = csrd_rd ();
break;
case MT_CSTS: /* CSTS */
val = csts_rd ();
break;
case MT_CDR: /* CDR */
case MT_SBIFS: /* SBIFS */
case MT_SBIS: /* SBIS */
case MT_SBISC: /* SBISC */
case MT_SBIMT: /* SBIMT */
case MT_SBIER: /* SBIER */
case MT_SBITA: /* SBITA */
val = 0;
break;
default:
RSVD_OPND_FAULT;
}
return val;
}
/* Write 730-specific IPR's */
void WriteIPR (int32 rg, int32 val)
{
switch (rg) {
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_ACCS: /* ACCS (not impl) */
break;
case MT_RXCS: /* RXCS */
rxcs_wr (val);
break;
case MT_TXCS: /* TXCS */
txcs_wr (val);
break;
case MT_TXDB: /* TXDB */
txdb_wr (val);
break;
case MT_MCESR: /* MCESR (not impl) */
break;
case MT_UBINIT: /* UBINIT (not impl) */
break;
case MT_CSRS: /* CSRS */
csrs_wr (val);
break;
case MT_CSTS: /* CSTS */
csts_wr (val);
break;
case MT_CSTD: /* CSTD */
cstd_wr (val);
break;
case MT_CDR: /* CDR */
case MT_SBIFS: /* SBIFS */
case MT_SBISC: /* SBISC */
case MT_SBIMT: /* SBIMT */
case MT_SBIER: /* SBIER */
case MT_SBIQC: /* SBIQC */
break;
default:
RSVD_OPND_FAULT;
}
return;
}
/* ReadReg - read register space
Inputs:
pa = physical address
lnt = length (BWLQ)
Output:
longword of data
*/
int32 ReadReg (int32 pa, int32 lnt)
{
int32 nexus, val;
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_NXM);
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 (int32 pa, int32 val, int32 lnt)
{
int32 nexus;
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;
}
}
MACH_CHECK (MCHK_NXM);
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, nxm;
nxm = ((p1 == MCHK_NXM) || (p1 == MCHK_IIA) || (p1 == MCHK_IUA));
if (nxm)
cc = intexc (SCB_MCHK, cc, 0, IE_EXC); /* take normal exception */
else
cc = intexc (SCB_MCHK, cc, 0, IE_SVE); /* take severe exception */
acc = ACC_MASK (KERN); /* in kernel mode */
in_ie = 1;
SP = SP - 16; /* push 4 words */
Write (SP, 12, L_LONG, WA); /* # bytes */
Write (SP + 4, p1, L_LONG, WA); /* mcheck type */
if (nxm)
Write (SP + 8, mchk_va, L_LONG, WA); /* NXM addr */
else
Write (SP + 8, 0, L_LONG, WA); /* first parameter */
Write (SP + 12, 0, L_LONG, WA); /* second parameter */
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? */
(vax730_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? */
printf ("Rebooting...\n");
if (sim_log)
fprintf (sim_log, "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 vax730_boot (int32 flag, char *ptr)
{
t_stat r;
r = vax730_boot_parse (flag, ptr); /* parse the boot cmd */
if (r != SCPE_OK) /* error? */
return r;
strncpy (cpu_boot_cmd, ptr, CBUFSIZE); /* save for reboot */
return run_cmd (flag, "CPU");
}
/* Parse boot command, set up registers - also used on reset */
t_stat vax730_boot_parse (int32 flag, char *ptr)
{
char gbuf[CBUFSIZE];
char *slptr, *regptr;
int32 i, r5v, unitno;
DEVICE *dptr;
UNIT *uptr;
DIB *dibp;
uint32 ba;
t_stat r;
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)
ba = 0;
else
ba = dibp->ba;
unitno = (int32) (uptr - dptr->units);
r5v = 0;
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;
if (boot_tab[i].code == BOOT_RB) /* vector set by console for RB730 */
R[0] = R[0] | ((VEC_RB - VEC_Q) << 16);
R[1] = TR_UBA;
R[2] = boot_tab[i].let | (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;
}
/* SYSB reset */
t_stat sysb_reset (DEVICE *dptr)
{
sim_vm_cmd = vax730_cmd;
return SCPE_OK;
}
/* Show nexus */
t_stat show_nexus (FILE *st, UNIT *uptr, int32 val, 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))) {
printf ("Nexus %s conflict at %d\n", sim_dname (dptr), dibp->ba);
if (sim_log)
fprintf (sim_log, "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;
}

130
VAX/vax730_syslist.c Normal file
View file

@ -0,0 +1,130 @@
/* vax730_syslist.c: VAX 730 device list
Copyright (c) 2010-2011, 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).
29-Mar-2011 MB First Version
*/
#include "vax_defs.h"
char sim_name[] = "VAX730";
extern DEVICE cpu_dev;
extern DEVICE tlb_dev;
extern DEVICE sysb_dev;
extern DEVICE mctl_dev;
extern DEVICE uba_dev;
extern DEVICE clk_dev;
extern DEVICE tmr_dev;
extern DEVICE tti_dev, tto_dev;
extern DEVICE td_dev;
extern DEVICE cr_dev;
extern DEVICE lpt_dev;
extern DEVICE rq_dev, rqb_dev, rqc_dev, rqd_dev;
extern DEVICE rb_dev;
extern DEVICE rl_dev;
extern DEVICE hk_dev;
extern DEVICE ry_dev;
extern DEVICE ts_dev;
extern DEVICE tq_dev;
extern DEVICE dz_dev;
extern DEVICE xu_dev, xub_dev;
extern int32 sim_switches;
extern UNIT cpu_unit;
extern void WriteB (uint32 pa, int32 val);
DEVICE *sim_devices[] = {
&cpu_dev,
&tlb_dev,
&sysb_dev,
&mctl_dev,
&uba_dev,
&clk_dev,
&tmr_dev,
&tti_dev,
&tto_dev,
&td_dev,
&dz_dev,
&cr_dev,
&lpt_dev,
&rl_dev,
&hk_dev,
&rq_dev,
&rqb_dev,
&rqc_dev,
&rqd_dev,
&rb_dev,
&ry_dev,
&ts_dev,
&tq_dev,
&xu_dev,
&xub_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.
-r load ROM0
-s load ROM1
-o for memory, specify origin
*/
t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag)
{
t_stat r;
int32 val;
uint32 origin, limit;
if (flag) /* dump? */
return SCPE_ARG;
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 = getc (fileref)) != EOF) { /* read byte stream */
if (sim_switches & SWMASK ('R')) { /* ROM0? */
return SCPE_NXM;
}
else if (sim_switches & SWMASK ('S')) { /* ROM1? */
return SCPE_NXM;
}
else {
if (origin >= limit) /* NXM? */
return SCPE_NXM;
WriteB (origin, val); /* memory */
}
origin = origin + 1;
}
return SCPE_OK;
}

667
VAX/vax730_uba.c Normal file
View file

@ -0,0 +1,667 @@
/* vax730_uba.c: VAX 11/730 Unibus adapter
Copyright (c) 2010-2011, 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 DW730 Unibus adapter
29-Mar-2011 MB First Version
*/
#include "vax_defs.h"
/* Unibus adapter */
#define UBA_NMAPR 496 /* number of map reg */
/* Unibus configuration register */
#define UBACNF_OF 0x00
#define UBACNF_CODE 0x00000028 /* adapter code */
/* Data path registers */
#define UBADPR_OF 0x01
/* Control & Status register */
#define UBACSR_OF 0x04
#define UBACSR_WNV 0x00004000 /* write not valid */
#define UBACSR_TBPAR 0x00008000 /* TB parity err */
#define UBACSR_NXM 0x00010000 /* UB NXM */
#define UBACSR_RDS 0x80000000 /* UB read data subs */
/* Vector registers - read only */
#define UBA_UVEC 0x80000000
/* RB730 registers */
#define RB730_OF 0x80
#define RB730_LN 8
/* Map registers */
#define UBAMAP_OF 0x200
#define UBAMAP_VLD 0x80000000 /* valid */
#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 0xF
#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 (0x86000000 | 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 */
uint32 uba_csr = 0; /* control & status reg */
uint32 uba_fmer = 0; /* failing map reg */
uint32 uba_map[UBA_NMAPR] = { 0 }; /* map registers */
int32 autcon_enb = 1; /* autoconfig enable */
extern int32 trpirq;
extern int32 autcon_enb;
extern jmp_buf save_env;
extern DEVICE *sim_devices[];
extern UNIT cpu_unit;
extern int32 sim_switches;
extern FILE *sim_log, *sim_deb;
extern int32 p1;
t_stat uba_reset (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);
t_bool uba_eval_int (int32 lvl);
void uba_ubpdn (int32 time);
t_bool uba_map_addr (uint32 ua, uint32 *ma);
t_stat set_autocon (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat show_autocon (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat show_iospace (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat uba_show_virt (FILE *st, UNIT *uptr, int32 val, void *desc);
extern int32 eval_int (void);
extern t_stat build_dib_tab (void);
extern t_stat rb_rd32 (int32 *data, int32 PA, int32 access);
extern t_stat rb_wr32 (int32 data, int32 PA, int32 access);
/* 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);
/* Unibus interrupt request to interrupt action map */
int32 (*int_ack[IPL_HLVL][32])(); /* 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 (0, 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) },
{ BRDATA (MAP, uba_map, 16, 32, 496) },
{ 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, 0, 0
};
/* Read Unibus adapter register - aligned lw only */
t_stat uba_rdreg (int32 *val, int32 pa, int32 lnt)
{
int32 idx, ofs;
if ((pa & 3) || (lnt != L_LONG)) { /* unaligned or not lw? */
printf (">>UBA: invalid adapter read mask, pa = %X, lnt = %d\r\n", pa, lnt);
// **FIXME** - Set error bit?
return SCPE_OK;
}
ofs = NEXUS_GETOFS (pa); /* get offset */
if (ofs >= UBAMAP_OF) { /* map? */
idx = ofs - UBAMAP_OF;
if (idx >= UBA_NMAPR) return SCPE_NXM; /* valid? */
*val = uba_map[idx] & UBAMAP_RD;
if (DEBUG_PRI (uba_dev, UBA_DEB_MRD))
fprintf (sim_deb, ">>UBA: map %d read, value = %X\n", idx, *val);
return SCPE_OK;
}
if (ofs >= RB730_OF) { /* RB730? */
idx = ofs - RB730_OF;
if (idx >= RB730_LN) return SCPE_NXM; /* valid? */
return rb_rd32 (val, pa, lnt);
}
switch (ofs) { /* case on offset */
case UBACNF_OF: /* Config Reg */
*val = UBACNF_CODE;
break;
case UBADPR_OF + 0: /* DP Regs */
case UBADPR_OF + 1:
case UBADPR_OF + 2:
*val = 0x0; /* Not used on 11/730 */
break;
case UBACSR_OF: /* CSR */
*val = uba_csr;
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;
if ((pa & 3) || (lnt != L_LONG)) { /* unaligned or not lw? */
printf (">>UBA: invalid adapter write mask, pa = %X, lnt = %d\r\n", pa, lnt);
// **FIXME** - Set error bit?
return SCPE_OK;
}
ofs = NEXUS_GETOFS (pa); /* get offset */
if (ofs >= UBAMAP_OF) { /* map? */
idx = ofs - UBAMAP_OF;
if (idx >= UBA_NMAPR) return SCPE_NXM; /* valid? */
uba_map[idx] = val & UBAMAP_WR;
if (DEBUG_PRI (uba_dev, UBA_DEB_MWR))
fprintf (sim_deb, ">>UBA: map %d write, value = %X\n", idx, val);
return SCPE_OK;
}
if (ofs >= RB730_OF) { /* RB730? */
idx = ofs - RB730_OF;
if (idx >= RB730_LN) return SCPE_NXM; /* valid? */
return rb_wr32 (val, pa, lnt);
}
switch (ofs) { /* case on offset */
case UBACNF_OF: /* Config Reg */
case UBADPR_OF + 0: /* DP Regs */
case UBADPR_OF + 1:
case UBADPR_OF + 2:
break; /* ignore writes */
case UBACSR_OF: /* CSR */
if(val & 0x10000) uba_csr = 0;
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 */
idx = (pa & IOPAGEMASK) >> 1;
if (iodispR[idx]) {
iodispR[idx] (&val, pa, READ);
return val;
}
}
MACH_CHECK(MCHK_IIA);
return 0;
}
void WriteUb (uint32 pa, int32 val, int32 mode)
{
int32 idx;
if (ADDR_IS_IOP (pa)) { /* iopage */
idx = (pa & IOPAGEMASK) >> 1;
if (iodispW[idx]) {
iodispW[idx] (val, pa, mode);
return;
}
}
MACH_CHECK(MCHK_IIA);
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);
// **FIXME** - 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) && ((pa & 1) == 0)) /* aligned word? */
WriteUb (pa, val, WRITE); /* DATO */
else {
printf (">>UBA: invalid write mask, pa = %x, lnt = %d\n", pa, lnt);
// **FIXME** - Set error bit?
}
SET_IRQL; /* update ints */
return;
}
/* Update UBA nexus interrupts */
t_bool uba_eval_int (int32 lvl)
{
return (int_req[lvl] != 0);
}
/* Return vector for Unibus interrupt at relative IPL level [0-3] */
int32 uba_get_ubvector (int32 lvl)
{
int32 i, vec;
vec = 0;
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, ma = %X, bc = %X\n", 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, 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, 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;
ublk = ua >> VA_V_VPN; /* Unibus blk */
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 (ADDR_IS_MEM (*ma)); /* legit addr */
}
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 >= 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;
}
/* Unibus power fail routines */
void uba_ubpdn (int32 time)
{
int32 i;
DEVICE *dptr;
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;
}
/* Reset Unibus adapter */
t_stat uba_reset (DEVICE *dptr)
{
int32 i;
for (i = 0; i < IPL_HLVL; i++) {
int_req[i] = 0;
}
for (i = 0; i < UBA_NMAPR; i++)
uba_map[i] = 0;
uba_csr = 0;
return SCPE_OK;
}
/* 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, 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;
}

743
VAX/vax750_cmi.c Normal file
View file

@ -0,0 +1,743 @@
/* vax750_cmi.c: VAX 11/750 CMI
Copyright (c) 2010-2011, Matt Burke
This module incorporates code from SimH, Copyright (c) 2004-2011, 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 11/750 system-specific registers and devices.
cmi bus controller
21-Oct-2012 MB First Version
*/
#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 */
/* 11/750 specific IPRs */
#define CMIERR_CRD 0x00000001
#define CMIERR_LEB 0x00000002
#define CMIERR_RDS 0x00000004
#define CMIERR_ME 0x00000008
#define CMIERR_TBH 0x00000010
#define CMIERR_TBG0DE 0x00000100
#define CMIERR_TBG1DE 0x00000200
#define CMIERR_TBG0TE 0x00000400
#define CMIERR_TBG1TE 0x00000800
#define CMIERR_V_MODE 16
#define CMIERR_M_MODE 0x3
#define CMIERR_MODE (CMIERR_M_MODE << CMIERR_V_MODE)
#define CMIERR_REF 0x00040000
#define CMIERR_RM 0x00080000
#define CMIERR_EN 0x00100000
/* System registers */
/* VAX-11/750 boot device definitions */
struct boot_dev {
char *name;
int32 code;
int32 let;
};
uint32 nexus_req[NEXUS_HLVL]; /* nexus int req */
uint32 cmi_err = 0;
uint32 cmi_cadr = 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[] = {
{ "RP", BOOT_MB, 0 },
{ "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 },
{ "TQ", BOOT_TK, 1 << 24 },
{ "TD", BOOT_TD, 0 },
{ NULL }
};
extern int32 R[16];
extern int32 PSL;
extern int32 ASTLVL, SISR;
extern int32 mapen, pme, trpirq;
extern int32 in_ie;
extern int32 mchk_va, mchk_ref;
extern int32 crd_err, mem_err, hlt_pin;
extern int32 tmr_int, tti_int, tto_int, csi_int, cso_int;
extern jmp_buf save_env;
extern int32 p1;
extern int32 sim_switches;
extern DEVICE *sim_devices[];
extern FILE *sim_log;
extern CTAB *sim_vm_cmd;
t_stat cmi_reset (DEVICE *dptr);
void cmi_set_tmo (void);
t_stat vax750_boot (int32 flag, char *ptr);
t_stat vax750_boot_parse (int32 flag, char *ptr);
t_stat cpu_boot (int32 unitno, DEVICE *dptr);
extern int32 intexc (int32 vec, int32 cc, int32 ipl, int ei);
extern int32 iccs_rd (void);
extern int32 nicr_rd (void);
extern int32 icr_rd (t_bool interp);
extern int32 todr_rd (void);
extern int32 rxcs_rd (void);
extern int32 rxdb_rd (void);
extern int32 txcs_rd (void);
extern int32 csrs_rd (void);
extern int32 csrd_rd (void);
extern int32 csts_rd (void);
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 csrs_wr (int32 dat);
extern void csts_wr (int32 dat);
extern void cstd_wr (int32 dat);
extern void init_mbus_tab (void);
extern void init_ubus_tab (void);
extern t_stat build_mbus_tab (DEVICE *dptr, DIB *dibp);
extern t_stat build_ubus_tab (DEVICE *dptr, DIB *dibp);
extern void uba_eval_int (void);
extern int32 uba_get_ubvector (int32 lvl);
extern void uba_ioreset (void);
/* CMI data structures
cmi_dev CMI device descriptor
cmi_unit CMI unit
cmi_reg CMI register list
*/
UNIT cmi_unit = { UDATA (NULL, 0, 0) };
REG cmi_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 (CMIERR, cmi_err, 32) },
{ BRDATA (BOOTCMD, cpu_boot_cmd, 16, 8, CBUFSIZE), REG_HRO },
{ NULL }
};
DEVICE cmi_dev = {
"CMI", &cmi_unit, cmi_reg, NULL,
1, 16, 16, 1, 16, 8,
NULL, NULL, &cmi_reset,
NULL, NULL, NULL,
NULL, 0
};
/* Special boot command, overrides regular boot */
CTAB vax750_cmd[] = {
{ "BOOT", &vax750_boot, RU_BOOT,
"bo{ot} <device>{/R5:flg} boot device\n", &run_cmd_message },
{ NULL }
};
/* The VAX 11/750 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 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_MEMERR) && mem_err) /* mem err int */
return IPL_MEMERR;
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_TTINT) && (tti_int || tto_int || csi_int || cso_int)) /* 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;
if (lvl == IPL_MEMERR) { /* mem error? */
mem_err = 0;
return SCB_MEMERR;
}
if (lvl == IPL_CRDERR) { /* CRD error? */
crd_err = 0;
return SCB_CRDERR;
}
if (lvl == IPL_CLKINT) { /* clock? */
tmr_int = 0; /* 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);
return uba_get_ubvector(l);
}
for (i = 0; nexus_req[l] && (i < NEXUS_NUM); i++) {
if ((nexus_req[l] >> i) & 1) {
nexus_req[l] = nexus_req[l] & ~(1u << i);
return SCB_NEXUS + (l << 6) + (i << 2); /* return vector */
}
}
}
if (lvl == IPL_TTINT) { /* console? */
if (tti_int) { /* input? */
tti_int = 0; /* clear req */
return SCB_TTI; /* return vector */
}
if (tto_int) { /* output? */
tto_int = 0; /* clear req */
return SCB_TTO; /* return vector */
}
if (csi_int) { /* input? */
csi_int = 0; /* clear req */
return SCB_CSI; /* return vector */
}
if (cso_int) { /* output? */
cso_int = 0; /* clear req */
return SCB_CSO; /* return vector */
}
}
return 0;
}
/* Read 750-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 (FALSE);
break;
case MT_TODR: /* TODR */
val = todr_rd ();
break;
case MT_ACCS: /* ACCS (not impl) */
val = 0;
break;
case MT_RXCS: /* RXCS */
val = rxcs_rd ();
break;
case MT_RXDB: /* RXDB */
val = rxdb_rd ();
break;
case MT_TXCS: /* TXCS */
val = txcs_rd ();
break;
case MT_CADR: /* CADR */
val = cmi_cadr;
break;
case MT_CAER: /* CAER (not impl) */
val = 0;
break;
case MT_MCESR: /* MCESR (not impl) */
val = 0;
break;
case MT_CMIE: /* CMIE */
val = cmi_err;
break;
case MT_CSRS: /* CSRS */
val = csrs_rd ();
break;
case MT_CSRD: /* CSRD */
val = csrd_rd ();
break;
case MT_CSTS: /* CSTS */
val = csts_rd ();
break;
case MT_TBDR: /* TBDR */
val = 0;
break;
case MT_SID: /* SID */
val = VAX750_SID | VAX750_MICRO | VAX750_HWREV;
break;
default:
RSVD_OPND_FAULT;
}
return val;
}
/* Write 750-specific IPR's */
void WriteIPR (int32 rg, int32 val)
{
switch (rg) {
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_ACCS: /* ACCS (not impl) */
break;
case MT_RXCS: /* RXCS */
rxcs_wr (val);
break;
case MT_TXCS: /* TXCS */
txcs_wr (val);
break;
case MT_TXDB: /* TXDB */
txdb_wr (val);
break;
case MT_CADR: /* CADR */
cmi_cadr = (val & 0x1);
break;
case MT_CAER: /* CAER (not impl) */
break;
case MT_MCESR: /* MCESR (not impl) */
break;
case MT_IORESET: /* IORESET */
uba_ioreset ();
break;
case MT_CSRS: /* CSRS */
csrs_wr (val);
break;
case MT_CSTS: /* CSTS */
csts_wr (val);
break;
case MT_CSTD: /* CSTD */
cstd_wr (val);
break;
case MT_TBDR: /* TBDR */
break;
default:
RSVD_OPND_FAULT;
}
return;
}
/* ReadReg - read register space
Inputs:
pa = physical address
lnt = length (BWLQ)
Output:
longword of data
*/
int32 ReadReg (int32 pa, int32 lnt)
{
int32 nexus, val;
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;
}
}
cmi_set_tmo (); /* timeout */
MACH_CHECK (MCHK_BPE); /* machine check */
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 (int32 pa, int32 val, int32 lnt)
{
int32 nexus;
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;
}
}
cmi_set_tmo (); /* timeout */
mem_err = 1; /* interrupt */
SET_IRQL;
return;
}
/* Set CMI timeout */
void cmi_set_tmo ()
{
if ((cmi_err & CMIERR_ME) == 0) { /* not yet set? */
if (mchk_ref == REF_V) /* virt? add mode */
cmi_err |= CMIERR_REF | (PSL_GETCUR (PSL) << CMIERR_V_MODE);
cmi_err |= CMIERR_ME; /* set tmo flag */
}
else cmi_err |= CMIERR_LEB; /* yes, multiple */
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, err;
err = (GET_TRAP (trpirq) << 4) | (pme << 3) | ASTLVL; /* error word */
if (p1 == MCHK_BPE) /* bus error? */
cc = intexc (SCB_MCHK, cc, 0, IE_EXC); /* take normal exception */
else
cc = intexc (SCB_MCHK, cc, 0, IE_SVE); /* take severe exception */
acc = ACC_MASK (KERN); /* in kernel mode */
in_ie = 1;
SP = SP - 44; /* push 11 words */
Write (SP, 40, L_LONG, WA); /* # bytes */
Write (SP + 4, p1, L_LONG, WA); /* error code */
Write (SP + 8, mchk_va, L_LONG, WA); /* VA register */
Write (SP + 12, 0, L_LONG, WA); /* Fault PC */
Write (SP + 16, 0, L_LONG, WA); /* MDR */
Write (SP + 20, 0, L_LONG, WA); /* saved mode reg */
Write (SP + 24, 0, L_LONG, WA); /* read lock timeout */
Write (SP + 28, 0, L_LONG, WA); /* TB group parity error reg */
Write (SP + 32, 0, L_LONG, WA); /* cache error reg */
Write (SP + 36, cmi_err, L_LONG, WA); /* bus error reg */
Write (SP + 40, 0, L_LONG, WA); /* MCESR */
in_ie = 0;
cmi_err = cmi_err & ~CMIERR_ME; /* clr CMIERR<me> etc */
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? */
(vax750_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? */
printf ("Rebooting...\n");
if (sim_log)
fprintf (sim_log, "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 vax750_boot (int32 flag, char *ptr)
{
t_stat r;
r = vax750_boot_parse (flag, ptr); /* parse the boot cmd */
if (r != SCPE_OK) /* error? */
return r;
strncpy (cpu_boot_cmd, ptr, CBUFSIZE); /* save for reboot */
return run_cmd (flag, "CPU");
}
/* Parse boot command, set up registers - also used on reset */
t_stat vax750_boot_parse (int32 flag, char *ptr)
{
char gbuf[CBUFSIZE];
char *slptr, *regptr;
int32 i, r5v, unitno;
DEVICE *dptr;
UNIT *uptr;
DIB *dibp;
uint32 ba;
t_stat r;
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)
ba = 0;
else
ba = dibp->ba;
unitno = (int32) (uptr - dptr->units);
r5v = 0;
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;
if (dptr->flags & DEV_MBUS) {
R[1] = (NEXUSBASE + (TR_MBA0 * NEXUSSIZE));
R[2] = unitno;
}
else {
R[1] = ba;
R[2] = (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;
}
/* CMI reset */
t_stat cmi_reset (DEVICE *dptr)
{
sim_vm_cmd = vax750_cmd;
cmi_err = CMIERR_EN;
cmi_cadr = 0;
return SCPE_OK;
}
/* Show nexus */
t_stat show_nexus (FILE *st, UNIT *uptr, int32 val, 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))) {
printf ("Nexus %s conflict at %d\n", sim_dname (dptr), dibp->ba);
if (sim_log)
fprintf (sim_log, "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 ();
init_mbus_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 if (dptr->flags & DEV_MBUS) { /* Massbus? */
if ((r = build_mbus_tab (dptr, dibp)))
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;
}

453
VAX/vax750_defs.h Normal file
View file

@ -0,0 +1,453 @@
/* vax750_defs.h: VAX 750 model-specific definitions file
Copyright (c) 2010-2011, 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).
21-Oct-2012 MB First Version
This file covers the VAX 11/750, the second VAX.
System memory map
00 0000 - 7F FFFF main memory
80 0000 - EF FFFF reserved
F0 0000 - F0 FFFF writeable control store
F1 0000 - F1 FFFF reserved
F2 0000 - F2 0010 memory controller
F2 0400 - F2 07FF bootstrap ROM
F2 8000 - F2 88FF Massbus adapter 0
F2 A000 - F2 A8FF Massbus adapter 1
F2 C000 - F2 C8FF Massbus adapter 2
F3 0000 - F3 09FF Unibus adapter 0
F3 2000 - F3 29FF Unibus adapter 1
*/
#ifndef FULL_VAX
#define FULL_VAX 1
#endif
#ifndef _VAX_750_DEFS_H_
#define _VAX_750_DEFS_H_ 1
/* Microcode constructs */
#define VAX750_SID (2 << 24) /* system ID */
#define VAX750_MICRO (99 << 8) /* ucode revision */
#define VAX750_HWREV (156) /* hw revision */
#define CON_HLTPIN 0x0200 /* external CPU halt */
#define CON_HLTINS 0x0600 /* HALT instruction */
#define MCHK_CSPE 0x01 /* control store parity error */
#define MCHK_BPE 0x02 /* bus error or tb/cache parity 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 MCTL_NUM 2 /* number of mem ctrl */
#define MBA_NUM 2 /* number of MBA's */
#define TR_MCTL 0 /* nexus assignments */
#define TR_MBA0 4
#define TR_MBA1 5
#define TR_UBA 8
#define TR_CI 15
#define NEXUS_HLVL (IPL_HMAX - IPL_HMIN + 1)
#define SCB_NEXUS 0x100 /* nexus intr base */
#define SBI_FAULTS 0xFC000000 /* SBI fault flags */
/* Internal I/O interrupts - relative except for clock and console */
#define IPL_CLKINT 0x18 /* clock IPL */
#define IPL_TTINT 0x14 /* console IPL */
#define IPL_MCTL0 (0x15 - IPL_HMIN)
#define IPL_MCTL1 (0x15 - IPL_HMIN)
#define IPL_UBA (0x15 - IPL_HMIN)
#define IPL_MBA0 (0x15 - IPL_HMIN)
#define IPL_MBA1 (0x15 - IPL_HMIN)
#define IPL_CI (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_CSRS 28 /* Console storage */
#define MT_CSRD 29
#define MT_CSTS 30
#define MT_CSTD 31
#define MT_CMIE 23 /* CMI error */
#define MT_TBDR 36 /* TB disable */
#define MT_CADR 37 /* Cache disable */
#define MT_MCESR 38 /* MCHK err sts */
#define MT_CAER 39 /* Cache error */
#define MT_ACCS 40 /* FPA control */
#define MT_IORESET 55 /* Unibus Init */
/* Machine specific reserved operand tests */
/* 780 microcode patch 37 - only test LR<23:0> for appropriate length */
#define ML_LR_TEST(r) if (((uint32)((r) & 0xFFFFFF)) > 0x200000) RSVD_OPND_FAULT
/* 780 microcode patch 38 - only test PxBR<31>=1, PxBR<30> = 0, and xBR<1:0> = 0 */
#define ML_PXBR_TEST(r) if (((((uint32)(r)) & 0x80000000) == 0) || \
((((uint32)(r)) & 0x40000003) != 0)) RSVD_OPND_FAULT
#define ML_SBR_TEST(r) if ((((uint32)(r)) & 0xC0000003) != 0) RSVD_OPND_FAULT
/* 780 microcode patch 78 - only test xCBB<1:0> = 0 */
#define ML_PA_TEST(r) if ((((uint32)(r)) & 0x00000003) != 0) RSVD_OPND_FAULT
#define LP_AST_TEST(r) if ((r) > AST_MAX) RSVD_OPND_FAULT
#define LP_MBZ84_TEST(r) if ((((uint32)(r)) & 0xF8C00000) != 0) RSVD_OPND_FAULT
#define LP_MBZ92_TEST(r) if ((((uint32)(r)) & 0x7FC00000) != 0) RSVD_OPND_FAULT
/* Memory */
#define MAXMEMWIDTH 21 /* max mem, 16k chips */
#define MAXMEMSIZE (1 << MAXMEMWIDTH)
#define MAXMEMWIDTH_X 23 /* max mem, 64k chips */
#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 << 20), NULL, "1M", &cpu_set_size }, \
{ UNIT_MSIZE, (1u << 21), NULL, "2M", &cpu_set_size }, \
{ UNIT_MSIZE, (1u << 22), NULL, "4M", &cpu_set_size }, \
{ UNIT_MSIZE, (1u << 23), NULL, "8M", &cpu_set_size }
/* 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 0xFC0000 /* Unibus addr base */
#define IOPAGEBASE 0xFFE000 /* 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 19 /* 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 0xF00000 /* REG addr base */
#define ADDR_IS_REG(x) ((((uint32) (x)) >= REGBASE) && \
(((uint32) (x)) < (REGBASE + REGSIZE)))
#define NEXUSBASE (REGBASE + 0x20000)
#define NEXUSSIZE 0x2000
#define NEXUS_GETNEX(x) (((x) >> REG_V_NEXUS) & REG_M_NEXUS)
#define NEXUS_GETOFS(x) (((x) >> REG_V_OFS) & REG_M_OFS)
/* ROM address space in memory controllers */
#define ROMAWIDTH 12 /* ROM addr width */
#define ROMSIZE (1u << ROMAWIDTH) /* ROM size */
#define ROMBASE (REGBASE + (TR_MCTL << REG_V_NEXUS) + 0x400)
#define ADDR_IS_ROM(x) ((((uint32) (x)) >= ROMBASE) && \
(((uint32) (x)) < (ROMBASE + ROMSIZE)))
/* Other address spaces */
#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 DZ_LINES 8 /* lines per DZV mux */
#define VH_MUXES 4 /* max # of DHQ muxes */
#define DLX_LINES 16 /* max # of KL11/DL11's */
#define DCX_LINES 16 /* max # of DC11'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_FLTA (DEV_V_UF + 3) /* flt addr */
#define DEV_V_CI (DEV_V_UF + 4) /* CI */
#define DEV_V_FFUF (DEV_V_UF + 5) /* 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_CI (1u << DEV_V_CI)
#define DEV_FLTA (1u << DEV_V_FLTA)
#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 */
} 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_DZ (IOPAGEBASE + 000100) /* DZ11 */
#define IOLN_DZ 010
#define IOBA_XUB (IOPAGEBASE + 000330 + (020 * (DZ_MUXES / 2)))
#define IOLN_XUB 010
#define IOBA_RQB (IOPAGEBASE + 000334 + (020 * (DZ_MUXES / 2)))
#define IOLN_RQB 004
#define IOBA_RQC (IOPAGEBASE + IOBA_RQB + IOLN_RQB)
#define IOLN_RQC 004
#define IOBA_RQD (IOPAGEBASE + IOBA_RQC + IOLN_RQC)
#define IOLN_RQD 004
#define IOBA_RQ (IOPAGEBASE + 012150) /* UDA50 */
#define IOLN_RQ 004
#define IOBA_TS (IOPAGEBASE + 012520) /* TS11 */
#define IOLN_TS 004
#define IOBA_RL (IOPAGEBASE + 014400) /* RL11 */
#define IOLN_RL 012
#define IOBA_XQ (IOPAGEBASE + 014440) /* DEQNA/DELQA */
#define IOLN_XQ 020
#define IOBA_XQB (IOPAGEBASE + 014460) /* 2nd DEQNA/DELQA */
#define IOLN_XQB 020
#define IOBA_TQ (IOPAGEBASE + 014500) /* TMSCP */
#define IOLN_TQ 004
#define IOBA_XU (IOPAGEBASE + 014510) /* DEUNA/DELUA */
#define IOLN_XU 010
#define IOBA_CR (IOPAGEBASE + 017160) /* CD/CR/CM */
#define IOLN_CR 010
#define IOBA_RX (IOPAGEBASE + 017170) /* RX11 */
#define IOLN_RX 004
#define IOBA_RY (IOPAGEBASE + 017170) /* RXV21 */
#define IOLN_RY 004
#define IOBA_QDSS (IOPAGEBASE + 017400) /* QDSS */
#define IOLN_QDSS 002
#define IOBA_HK (IOPAGEBASE + 017440) /* RK611 */
#define IOLN_HK 040
#define IOBA_LPT (IOPAGEBASE + 017514) /* LP11 */
#define IOLN_LPT 004
#define IOBA_PTR (IOPAGEBASE + 017550) /* PC11 reader */
#define IOLN_PTR 004
#define IOBA_PTP (IOPAGEBASE + 017554) /* PC11 punch */
#define IOLN_PTP 004
/* Interrupt assignments; within each level, priority is right to left */
#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_LPT 0 /* BR4 */
#define INT_V_PTR 1
#define INT_V_PTP 2
#define INT_V_CR 3
#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_PTR (1u << INT_V_PTR)
#define INT_PTP (1u << INT_V_PTP)
#define INT_CR (1u << INT_V_CR)
#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_LPT (0x14 - IPL_HMIN)
#define IPL_PTR (0x14 - IPL_HMIN)
#define IPL_PTP (0x14 - IPL_HMIN)
#define IPL_CR (0x14 - IPL_HMIN)
/* Device vectors */
#define VEC_QBUS 0
#define VEC_Q 0x200
#define VEC_PTR (VEC_Q + 0070)
#define VEC_PTP (VEC_Q + 0074)
#define VEC_XQ (VEC_Q + 0120)
#define VEC_XU (VEC_Q + 0120)
#define VEC_RQ (VEC_Q + 0154)
#define VEC_RL (VEC_Q + 0160)
#define VEC_LPT (VEC_Q + 0200)
#define VEC_HK (VEC_Q + 0210)
#define VEC_TS (VEC_Q + 0224)
#define VEC_CR (VEC_Q + 0230)
#define VEC_TQ (VEC_Q + 0260)
#define VEC_RX (VEC_Q + 0264)
#define VEC_RY (VEC_Q + 0264)
#define VEC_DZRX (VEC_Q + 0300)
#define VEC_DZTX (VEC_Q + 0304)
/* 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 */
/* Logging */
#define LOG_CPU_I 0x1 /* intexc */
#define LOG_CPU_R 0x2 /* REI */
#define LOG_CPU_P 0x4 /* context */
/* Massbus definitions */
#define MBA_RP (TR_MBA0 - TR_MBA0) /* MBA for RP */
#define MBA_TU (TR_MBA1 - TR_MBA0) /* MBA for TU */
#define MBA_RMASK 0x1F /* max 32 reg */
#define MBE_NXD 1 /* nx drive */
#define MBE_NXR 2 /* nx reg */
#define MBE_GOE 3 /* err on GO */
/* Boot definitions */
#define BOOT_MB 0 /* device codes */
#define BOOT_HK 1 /* for VMB */
#define BOOT_RL 2
#define BOOT_UDA 17
#define BOOT_TK 18
#define BOOT_CI 32
#define BOOT_TD 64
/* Function prototypes for virtual memory interface */
int32 Read (uint32 va, int32 lnt, int32 acc);
void Write (uint32 va, int32 val, int32 lnt, int32 acc);
/* Function prototypes for physical memory interface (inlined) */
SIM_INLINE int32 ReadB (uint32 pa);
SIM_INLINE int32 ReadW (uint32 pa);
SIM_INLINE int32 ReadL (uint32 pa);
SIM_INLINE int32 ReadLP (uint32 pa);
SIM_INLINE void WriteB (uint32 pa, int32 val);
SIM_INLINE void WriteW (uint32 pa, int32 val);
SIM_INLINE void WriteL (uint32 pa, int32 val);
void WriteLP (uint32 pa, int32 val);
/* 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, uint8 *buf);
int32 Map_WriteW (uint32 ba, int32 bc, uint16 *buf);
int32 mba_rdbufW (uint32 mbus, int32 bc, uint16 *buf);
int32 mba_wrbufW (uint32 mbus, int32 bc, 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 (uint32 mbus, t_bool dis);
t_stat mba_show_num (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat show_nexus (FILE *st, UNIT *uptr, int32 val, void *desc);
void sbi_set_errcnf (void);
int32 clk_cosched (int32 wait);
#include "pdp11_io_lib.h"
#endif

207
VAX/vax750_mem.c Normal file
View file

@ -0,0 +1,207 @@
/* vax750_mem.c: VAX 11/750 memory controllers
Copyright (c) 2010-2012, 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.
mctl MS750 memory controller
21-Oct-2012 MB First Version
*/
#include "vax_defs.h"
/* Memory adapter register 0 */
#define MCSR0_OF 0x00
#define MCSR0_ES 0x0000007F /* Error syndrome */
#define MCSR0_V_EP 9
#define MCSR0_M_EP 0x7FFF
#define MCSR0_EP (MCSR0_M_EP << MCSR0_V_EP) /* Error page */
#define MCSR0_CRD 0x20000000 /* Corrected read data */
#define MCSR0_RDSH 0x40000000 /* Read data subs high */
#define MCSR0_RDS 0x80000000 /* Read data substitute */
#define MCSR0_RS (MCSR0_CRD | MCSR0_RDSH | MCSR0_RDS)
/* Memory adapter register 1 */
#define MCSR1_OF 0x01
#define MCSR1_CS 0x0000007F /* Check syndrome */
#define MCSR1_V_EP 9
#define MCSR1_M_EP 0x7FFF
#define MCSR1_EP (MCSR1_M_EP << MCSR1_V_EP) /* Page mode address */
#define MCSR1_ECCD 0x02000000 /* ECC disable */
#define MCSR1_DIAG 0x04000000 /* Diag mode */
#define MCSR1_PM 0x08000000 /* Page mode */
#define MCSR1_CRE 0x10000000 /* CRD enable */
#define MCSR1_RW (MCSR1_CS | MCSR1_ECCD | MCSR1_DIAG | \
MCSR1_PM | MCSR1_CRE)
/* Memory adapter register 2 */
#define MCSR2_OF 0x02
#define MCSR2_M_MAP 0xFFFF /* Memory present */
#define MCSR2_INIT 0x00010000 /* Cold/warm restart flag */
#define MCSR2_V_SA 17
#define MCSR2_M_SA 0x7F /* Start address */
#define MCSR2_V_CS 24
#define MCSR2_CS (1u << MCSR2_V_CS) /* Chip size */
#define MCSR2_MBZ 0xFF000000
/* Debug switches */
#define MCTL_DEB_RRD 0x01 /* reg reads */
#define MCTL_DEB_RWR 0x02 /* reg writes */
#define MEM_SIZE_16K (1u << 17) /* Board size (16k chips) */
#define MEM_SIZE_64K (1u << 19) /* Board size (64k chips) */
#define MEM_BOARD_MASK(x,y) ((1u << (uint32)(x/y)) - 1)
#define MEM_64K_MASK 0x5555
extern UNIT cpu_unit;
extern FILE *sim_log, *sim_deb;
uint32 mcsr0 = 0;
uint32 mcsr1 = 0;
uint32 mcsr2 = 0;
t_stat mctl_reset (DEVICE *dptr);
t_stat mctl_rdreg (int32 *val, int32 pa, int32 mode);
t_stat mctl_wrreg (int32 val, int32 pa, int32 mode);
/* MCTL data structures
mctl_dev MCTL device descriptor
mctl_unit MCTL unit
mctl_reg MCTL register list
*/
DIB mctl_dib[] = { TR_MCTL, 0, &mctl_rdreg, &mctl_wrreg, 0 };
UNIT mctl_unit = { UDATA (NULL, 0, 0) };
REG mctl_reg[] = {
{ NULL }
};
MTAB mctl_mod[] = {
{ MTAB_XTD|MTAB_VDV, TR_MCTL, "NEXUS", NULL,
NULL, &show_nexus },
{ 0 }
};
DEBTAB mctl_deb[] = {
{ "REGREAD", MCTL_DEB_RRD },
{ "REGWRITE", MCTL_DEB_RWR },
{ NULL, 0 }
};
DEVICE mctl_dev = {
"MCTL", &mctl_unit, mctl_reg, mctl_mod,
1, 16, 16, 1, 16, 8,
NULL, NULL, &mctl_reset,
NULL, NULL, NULL,
&mctl_dib, DEV_NEXUS | DEV_DEBUG, 0,
mctl_deb, 0, 0
};
/* Memory controller register read */
t_stat mctl_rdreg (int32 *val, int32 pa, int32 lnt)
{
int32 ofs;
ofs = NEXUS_GETOFS (pa); /* get offset */
switch (ofs) { /* case on offset */
case MCSR0_OF: /* CSR0 */
*val = mcsr0;
break;
case MCSR1_OF: /* CSR1 */
*val = mcsr1;
break;
case MCSR2_OF: /* CSR2 */
*val = mcsr2 & ~MCSR2_MBZ;
break;
default:
return SCPE_NXM;
}
if (DEBUG_PRI (mctl_dev, MCTL_DEB_RRD))
fprintf (sim_deb, ">>MCTL: reg %d read, value = %X\n", ofs, *val);
return SCPE_OK;
}
/* Memory controller register write */
t_stat mctl_wrreg (int32 val, int32 pa, int32 lnt)
{
int32 ofs;
ofs = NEXUS_GETOFS (pa); /* get offset */
switch (ofs) { /* case on offset */
case MCSR0_OF: /* CSR0 */
mcsr0 = mcsr0 & ~(MCSR0_RS & val);
break;
case MCSR1_OF: /* CSR1 */
mcsr1 = val & MCSR1_RW;
break;
case MCSR2_OF: /* CSR2 */
break;
default:
return SCPE_NXM;
}
if (DEBUG_PRI (mctl_dev, MCTL_DEB_RWR))
fprintf (sim_deb, ">>MCTL: reg %d write, value = %X\n", ofs, val);
return SCPE_OK;
}
/* Used by CPU */
void rom_wr_B (int32 pa, int32 val)
{
return;
}
/* Memory controller reset */
t_stat mctl_reset (DEVICE *dptr)
{
mcsr0 = 0;
mcsr1 = 0;
if (MEMSIZE > MAXMEMSIZE) /* More than 2MB? */
mcsr2 = MCSR2_INIT | (MEM_BOARD_MASK(MEMSIZE, MEM_SIZE_64K) & MEM_64K_MASK) | MCSR2_CS; /* Use 64k chips */
else
mcsr2 = MCSR2_INIT | MEM_BOARD_MASK(MEMSIZE, MEM_SIZE_16K); /* Use 16k chips */
return SCPE_OK;
}

1195
VAX/vax750_stddev.c Normal file

File diff suppressed because it is too large Load diff

125
VAX/vax750_syslist.c Normal file
View file

@ -0,0 +1,125 @@
/* vax750_syslist.c: VAX 11/750 device list
Copyright (c) 2010-2012, 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).
21-Oct-2012 MB First Version
*/
#include "vax_defs.h"
char sim_name[] = "VAX750";
extern DEVICE cpu_dev;
extern DEVICE tlb_dev;
extern DEVICE cmi_dev;
extern DEVICE mctl_dev;
extern DEVICE uba_dev;
extern DEVICE mba_dev[MBA_NUM];
extern DEVICE clk_dev;
extern DEVICE tmr_dev;
extern DEVICE tti_dev, tto_dev;
extern DEVICE td_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 rp_dev;
extern DEVICE ry_dev;
extern DEVICE ts_dev;
extern DEVICE tq_dev;
extern DEVICE tu_dev;
extern DEVICE dz_dev;
extern DEVICE xu_dev, xub_dev;
extern int32 sim_switches;
extern UNIT cpu_unit;
extern void WriteB (uint32 pa, int32 val);
DEVICE *sim_devices[] = {
&cpu_dev,
&tlb_dev,
&cmi_dev,
&mctl_dev,
&uba_dev,
&mba_dev[0],
&mba_dev[1],
&clk_dev,
&tmr_dev,
&tti_dev,
&tto_dev,
&td_dev,
&dz_dev,
&cr_dev,
&lpt_dev,
&rp_dev,
&rl_dev,
&hk_dev,
&rq_dev,
&rqb_dev,
&rqc_dev,
&rqd_dev,
&ry_dev,
&tu_dev,
&ts_dev,
&tq_dev,
&xu_dev,
&xub_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, char *cptr, char *fnam, int flag)
{
t_stat r;
int32 val;
uint32 origin, limit;
if (flag) /* dump? */
return SCPE_ARG;
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 = getc (fileref)) != EOF) { /* read byte stream */
if (origin >= limit) /* NXM? */
return SCPE_NXM;
WriteB (origin, val); /* memory */
origin = origin + 1;
}
return SCPE_OK;
}

687
VAX/vax750_uba.c Normal file
View file

@ -0,0 +1,687 @@
/* vax750_uba.c: VAX 11/750 Unibus adapter
Copyright (c) 2010-2011, 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 DW750 Unibus adapter
21-Oct-2012 MB First Version
*/
#include "vax_defs.h"
/* Unibus adapter */
#define UBA_NDPATH 16 /* number of data paths */
#define UBA_NMAPR 496 /* number of map reg */
/* Unibus adapter configuration register */
#define UBACNF_OF 0x00
#define UBACNF_CODE 0x00000028 /* adapter code */
/* Control/Status registers */
#define UBACSR1_OF 0x01
#define UBACSR2_OF 0x02
#define UBACSR3_OF 0x03
#define UBACSR_PUR 0x00000001 /* Purge request */
#define UBACSR_UCE 0x20000000 /* Uncorrectable err */
#define UBACSR_NXM 0x40000000 /* NXM */
#define UBACSR_ERR 0x80000000 /* Error flag */
#define UBACSR_RD (UBACSR_PUR | UBACSR_UCE | UBACSR_NXM | \
UBACSR_ERR)
#define UBACSR_WR 0
/* Map registers */
#define UBAMAP_OF 0x200
#define UBAMAP_VLD 0x80000000 /* valid */
#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 0xF
#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 (0x86000000 | 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 */
uint32 uba_csr1 = 0; /* csr reg 1 */
uint32 uba_csr2 = 0; /* csr reg 2 */
uint32 uba_csr3 = 0; /* csr reg 3 */
uint32 uba_int = 0; /* UBA interrupt */
uint32 uba_map[UBA_NMAPR] = { 0 }; /* map registers */
int32 autcon_enb = 1; /* autoconfig enable */
extern int32 trpirq;
extern int32 autcon_enb;
extern jmp_buf save_env;
extern DEVICE *sim_devices[];
extern UNIT cpu_unit;
extern uint32 nexus_req[NEXUS_HLVL];
extern int32 sim_switches;
extern FILE *sim_log, *sim_deb;
extern int32 p1;
extern int32 fault_PC; /* fault PC */
extern int32 mem_err;
t_stat uba_reset (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_eval_int (void);
void uba_ioreset (void);
t_bool uba_map_addr (uint32 ua, uint32 *ma);
t_stat set_autocon (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat show_autocon (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat show_iospace (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat uba_show_virt (FILE *st, UNIT *uptr, int32 val, void *desc);
extern int32 eval_int (void);
extern t_stat build_dib_tab (void);
extern void cmi_set_tmo (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);
/* 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 (0, 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 (CSR1, uba_csr1, 32) },
{ HRDATA (CSR2, uba_csr2, 32) },
{ HRDATA (CSR3, uba_csr3, 32) },
{ FLDATA (INT, uba_int, 0) },
{ FLDATA (NEXINT, nexus_req[IPL_UBA], TR_UBA) },
{ BRDATA (MAP, uba_map, 16, 32, 496) },
{ 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, 0, 0
};
/* Read Unibus adapter register - aligned lw only */
t_stat uba_rdreg (int32 *val, int32 pa, int32 lnt)
{
int32 idx, ofs;
if ((pa & 3) || (lnt != L_LONG)) { /* unaligned or not lw? */
printf (">>UBA: invalid adapter read mask, pa = %X, lnt = %d\r\n", pa, lnt);
/* FIXME: set appropriate error bits */
return SCPE_OK;
}
ofs = NEXUS_GETOFS (pa); /* get offset */
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 at PC = %08X\n", idx, *val, fault_PC);
return SCPE_OK;
}
switch (ofs) { /* case on offset */
case UBACNF_OF: /* Config Reg */
*val = UBACNF_CODE;
break;
case UBACSR1_OF: /* CSR1 */
*val = (uba_csr1 & UBACSR_RD);
break;
case UBACSR2_OF: /* CSR2 */
*val = (uba_csr2 & UBACSR_RD);
break;
case UBACSR3_OF: /* CSR3 */
*val = (uba_csr3 & UBACSR_RD);
break;
default:
return SCPE_NXM;
}
if (DEBUG_PRI (uba_dev, UBA_DEB_RRD))
fprintf (sim_deb, ">>UBA: reg %d read, value = %X at PC = %08X\n", ofs, *val, fault_PC);
return SCPE_OK;
}
/* Write Unibus adapter register */
t_stat uba_wrreg (int32 val, int32 pa, int32 lnt)
{
int32 idx, ofs;
if ((pa & 3) || (lnt != L_LONG)) { /* unaligned or not lw? */
printf (">>UBA: invalid adapter write mask, pa = %X, lnt = %d\r\n", pa, lnt);
/* FIXME: set appropriate error bits */
return SCPE_OK;
}
ofs = NEXUS_GETOFS (pa); /* get offset */
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 at PC = %08X\n", idx, val, fault_PC);
return SCPE_OK;
}
switch (ofs) { /* case on offset */
case UBACNF_OF: /* Config Reg */
break;
case UBACSR1_OF: /* CSR1 */
uba_csr1 = (val & UBACSR_WR);
break;
case UBACSR2_OF: /* CSR2 */
uba_csr2 = (val & UBACSR_WR);
break;
case UBACSR3_OF: /* CSR3 */
uba_csr3 = (val & UBACSR_WR);
break;
default:
return SCPE_NXM;
break;
}
if (DEBUG_PRI (uba_dev, UBA_DEB_RWR))
fprintf (sim_deb, ">>UBA: reg %d write, value = %X at PC = %08X\n", ofs, val, fault_PC);
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;
}
}
cmi_set_tmo();
MACH_CHECK(MCHK_BPE);
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;
}
}
cmi_set_tmo();
mem_err = 1; /* interrupt */
SET_IRQL;
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);
/* FIXME: set appropriate error bits */
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) && ((pa & 1) == 0)) /* aligned word? */
WriteUb (pa, val, WRITE); /* DATO */
else {
printf (">>UBA: invalid write mask, pa = %x, lnt = %d\n", pa, lnt);
/* FIXME: set appropriate error bits */
}
SET_IRQL; /* update ints */
return;
}
/* Update UBA nexus interrupts */
void uba_eval_int (void)
{
int32 i;
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;
vec = 0;
if ((lvl == (IPL_UBA - IPL_HMIN)) && uba_int) { /* UBA lvl, int? */
uba_int = 0; /* clear int */
}
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, ma = %X, bc = %X\n", 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, 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, 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;
ublk = ua >> VA_V_VPN; /* Unibus blk */
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 (ADDR_IS_MEM (*ma)); /* legit addr */
}
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 >= 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;
}
/* Reset Unibus devices */
void uba_ioreset (void)
{
int32 i;
DEVICE *dptr;
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;
}
/* Reset Unibus adapter */
t_stat uba_reset (DEVICE *dptr)
{
int32 i;
for (i = 0; i < IPL_HLVL; i++) {
nexus_req[i] &= ~(1 << TR_UBA);
int_req[i] = 0;
}
for (i = 0; i < UBA_NMAPR; i++)
uba_map[i] = 0;
uba_csr1 = 0;
uba_csr2 = 0;
uba_csr3 = 0;
return SCPE_OK;
}
/* 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, 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;
}

View file

@ -150,6 +150,12 @@
#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 << 23), NULL, "8M", &cpu_set_size }, \
{ UNIT_MSIZE, (1u << 24), NULL, "16M", &cpu_set_size }, \
{ UNIT_MSIZE, (1u << 25), NULL, "32M", &cpu_set_size }, \
{ UNIT_MSIZE, (1u << 25) + (1u << 24), NULL, "48M", &cpu_set_size }, \
{ UNIT_MSIZE, (1u << 26), NULL, "64M", &cpu_set_size }, \
{ UNIT_MSIZE, (1u << 27), NULL, "128M", &cpu_set_size }
/* Unibus I/O registers */
@ -223,7 +229,7 @@
#define DZ_MUXES 4 /* max # of DZV muxes */
#define DZ_LINES 8 /* lines per DZV mux */
#define VH_MUXES 4 /* max # of DHQ 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 MT_MAXFR (1 << 16) /* magtape max rec */

View file

@ -36,9 +36,11 @@
#include "vax_defs.h"
#ifndef DONT_USE_INTERNAL_ROM
#include "vax780_vmb_exe.h"
#endif
#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 */
/* 11/780 specific IPRs */
@ -106,7 +108,7 @@ uint32 sbi_sc = 0; /* SBI silo comparator *
uint32 sbi_mt = 0; /* SBI maintenance */
uint32 sbi_er = 0; /* SBI error status */
uint32 sbi_tmo = 0; /* SBI timeout addr */
char cpu_boot_cmd[CBUFSIZE] = { 0 }; /* boot command */
static 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);
@ -203,7 +205,7 @@ DEVICE sbi_dev = {
CTAB vax780_cmd[] = {
{ "BOOT", &vax780_boot, RU_BOOT,
"bo{ot} <device>{/R5:flg} boot device\n" },
"bo{ot} <device>{/R5:flg} boot device\n", &run_cmd_message },
{ "FLOAD", &vax780_fload, 0,
"fl{oad} <file> {<start>} load file from console floppy\n" },
{ NULL }
@ -694,30 +696,9 @@ t_stat cpu_boot (int32 unitno, DEVICE *dptr)
{
t_stat r;
printf ("Loading boot code from vmb.exe\n");
if (sim_log)
fprintf (sim_log, "Loading boot code from vmb.exe\n");
r = load_cmd (0, "-O vmb.exe 200");
if (r != SCPE_OK) {
#ifndef DONT_USE_INTERNAL_ROM
FILE *f;
if ((f = sim_fopen ("vmb.exe", "wb"))) {
printf ("Saving boot code to vmb.exe\n");
if (sim_log)
fprintf (sim_log, "Saving boot code to vmb.exe\n");
sim_fwrite (vax780_vmb_exe, sizeof(vax780_vmb_exe[0]), sizeof(vax780_vmb_exe)/sizeof(vax780_vmb_exe[0]), f);
fclose (f);
printf ("Loading boot code from vmb.exe\n");
if (sim_log)
fprintf (sim_log, "Loading boot code from vmb.exe\n");
r = load_cmd (0, "-O vmb.exe 200");
if (r == SCPE_OK)
SP = PC = 512;
}
#endif
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;
}

View file

@ -672,7 +672,7 @@ int32 clk_cosched (int32 wait)
{
int32 t;
t = sim_is_active (&clk_unit);
t = sim_activate_time (&clk_unit);
return (t? t - 1: wait);
}

View file

@ -1,4 +1,4 @@
/* vax780_mba.c: VAX 11/780 Massbus adapter
/* vax7x0_mba.c: VAX 11/780 snf VAX 11/750 Massbus adapter
Copyright (c) 2004-2008, Robert M Supnik
@ -49,6 +49,8 @@
#define MBA_EXTDRV(x) (((x) >> MBA_V_DRV) & MBA_M_DRV)
#define MBA_EXTOFS(x) (((x) >> MBA_V_DEVOFS) & MBA_M_DEVOFS)
char *mba_regnames[] = {"CNF", "CR", "SR", "VA", "BC", "DR", "SMR", "CMD"};
/* Massbus configuration register */
#define MBACNF_OF 0x0
@ -58,6 +60,22 @@
#define MBACNF_RD (SBI_FAULTS|MBACNF_W1C)
#define MBACNF_W1C 0x00C00000
BITFIELD mba_cnf_bits[] = {
BITF(CODE,8), /* Adapter Code */
BITNCF(13), /* 08:20 Reserved */
BIT(OT), /* Over Temperature */
BIT(PU), /* Power Up */
BIT(PD), /* Power Down */
BITNCF(2), /* 24:25 Reserved */
BIT(XMTFLT), /* Transmit Fault */
BIT(MT), /* Multiple Transmitter */
BITNCF(1), /* 28 Reserved */
BIT(URD), /* Unexpected Read Data */
BIT(WS), /* Write Data Sequence (Fault B) */
BIT(PE), /* SBI Parity Error */
ENDBITS
};
/* Control register */
#define MBACR_OF 0x1
@ -68,6 +86,15 @@
#define MBACR_RD 0x0000000E
#define MBACR_WR 0x0000000E
BITFIELD mba_cr_bits[] = {
BIT(INIT), /* Initialization */
BIT(ABORT), /* Abort Data Transfer */
BIT(IE), /* Interrupt Enable */
BIT(MM), /* Maintenance Mode */
BITNCF(28), /* 04:31 Reserved */
ENDBITS
};
/* Status register */
#define MBASR_OF 0x2
@ -100,33 +127,98 @@
#define MBASR_ERRORS 0x608E49FF
#define MBASR_INTR 0x000F7000
BITFIELD mba_sr_bits[] = {
BIT(RDTIMEOUT), /* Read Data Timeout */
BIT(ISTIMEOUT), /* Interface Sequence Timeout */
BIT(RDS), /* Read Data Substitute */
BIT(ERRCONF), /* Error Confirmation */
BIT(INVMAP), /* Invalid Map */
BIT(MAPPE), /* Page Frame Map Parity Error */
BIT(MDPE), /* Massbus Data Parity Error */
BIT(MBEXC), /* Massbus Exception */
BIT(MXF), /* Missed Transfer Error */
BIT(WCLWRERR), /* Write Check Lower Byte Error */
BIT(WCUPERR), /* Write Check Upper Byte Error */
BIT(DLT), /* Data Late */
BIT(DTABT), /* Data Transfer Aborted */
BIT(DTCOMP), /* Data Transfer Complete */
BITNCF(2), /* 14:15 Reserved */
BIT(ATTN), /* Attention */
BIT(MCPE), /* Massbus Control Parity Error */
BIT(NED), /* Non Existing Drive */
BIT(PGE), /* Programming Error */
BITNCF(9), /* 20:28 Reserved */
BIT(CRD), /* Corrected Read Data */
BIT(NRCONF), /* No Response Confirmation */
BIT(DTBUSY), /* Data Transfer Busy */
ENDBITS
};
/* Virtual address register */
#define MBAVA_OF 0x3
#define MBAVA_RD 0x0001FFFF
#define MBAVA_WR (MBAVA_RD)
BITFIELD mba_va_bits[] = {
BITF(PAGEBYTE,9), /* Page Byte Address */
BITF(MAPPOINTER,8), /* Map Pointer */
ENDBITS
};
/* Byte count */
#define MBABC_OF 0x4
#define MBABC_WR 0x0000FFFF
#define MBABC_V_MBC 16 /* MB count */
BITFIELD mba_bc_bits[] = {
BITF(SBIBYTECOUNT,16), /* SBI Byte Counter */
BITF(MBBYTECOUNT,16), /* Massbus Byte Counter */
ENDBITS
};
/* Diagnostic register */
#define MBADR_OF 0x5
#define MBADR_RD 0xFFFFFFFF
#define MBADR_WR 0xFFC00000
BITFIELD mba_dr_bits[] = {
BITF(DR,32), /* Diagnostic Register */
ENDBITS
};
/* Selected map entry - read only */
#define MBASMR_OF 0x6
#define MBASMR_RD (MBAMAP_RD)
BITFIELD mba_smr_bits[] = {
BITF(SMR,32), /* Selected Map Register */
ENDBITS
};
/* Command register (SBI) - read only */
#define MBACMD_OF 0x7
BITFIELD mba_cmd_bits[] = {
BITF(CAR,32), /* Command Address Register */
ENDBITS
};
BITFIELD *mba_reg_bits[] = {
mba_cnf_bits,
mba_cr_bits,
mba_sr_bits,
mba_va_bits,
mba_bc_bits,
mba_dr_bits,
mba_smr_bits,
mba_cmd_bits
};
/* External registers */
#define MBA_CS1 0x00 /* device CSR1 */
@ -148,6 +240,7 @@
#define MBA_DEB_MWR 0x08 /* map writes */
#define MBA_DEB_XFR 0x10 /* transfers */
#define MBA_DEB_ERR 0x20 /* errors */
#define MBA_DEB_INT 0x40 /* interrupts */
uint32 mba_cnf[MBA_NUM]; /* config reg */
uint32 mba_cr[MBA_NUM]; /* control reg */
@ -161,7 +254,6 @@ uint32 mba_map[MBA_NUM][MBA_NMAPR]; /* map */
extern uint32 nexus_req[NEXUS_HLVL];
extern UNIT cpu_unit;
extern FILE *sim_log;
extern FILE *sim_deb;
extern int32 sim_switches;
t_stat mba_reset (DEVICE *dptr);
@ -239,6 +331,7 @@ DEBTAB mba_deb[] = {
{ "MAPWRITE", MBA_DEB_MWR },
{ "XFER", MBA_DEB_XFR },
{ "ERROR", MBA_DEB_ERR },
{ "INTERRUPT", MBA_DEB_INT },
{ NULL, 0 }
};
@ -271,8 +364,10 @@ t_stat r;
mb = NEXUS_GETNEX (pa) - TR_MBA0; /* get MBA */
if ((pa & 3) || (lnt != L_LONG)) { /* unaligned or not lw? */
printf (">>MBA%d: invalid adapter read mask, pa = %X, lnt = %d\r\n", mb, pa, lnt);
printf (">>MBA%d: invalid adapter read mask, pa = 0x%X, lnt = %d\r\n", mb, pa, lnt);
#if defined(VAX_780)
sbi_set_errcnf (); /* err confirmation */
#endif
return SCPE_OK;
}
if (mb >= MBA_NUM) /* valid? */
@ -321,8 +416,8 @@ switch (rtype) { /* case on type */
default:
return SCPE_NXM;
}
if (DEBUG_PRI (mba_dev[mb], MBA_DEB_RRD))
fprintf (sim_deb, ">>MBA%d: int reg %d read, value = %X\n", mb, ofs, *val);
sim_debug (MBA_DEB_RRD, &mba_dev[mb], "mba_rdreg(Reg=%s, val=0x%X)\n", mba_regnames[ofs], *val);
sim_debug_bits(MBA_DEB_RRD, &mba_dev[mb], mba_reg_bits[ofs], *val, *val, 1);
break;
case MBART_EXT: /* external */
@ -336,15 +431,13 @@ switch (rtype) { /* case on type */
else if (r == MBE_NXR) /* nx reg? */
return SCPE_NXM;
*val |= (mba_sr[mb] & ~WMASK); /* upper 16b from SR */
if (DEBUG_PRI (mba_dev[mb], MBA_DEB_RRD))
fprintf (sim_deb, ">>MBA%d: drv %d ext reg %d read, value = %X\n", mb, drv, ofs, *val);
sim_debug (MBA_DEB_RRD, &mba_dev[mb], "mba_rdreg(drv %d ext reg=%d, val=0x%X)\n", drv, ofs, *val);
break;
case MBART_MAP: /* map */
ofs = MBA_INTOFS (pa);
*val = mba_map[mb][ofs] & MBAMAP_RD;
if (DEBUG_PRI (mba_dev[mb], MBA_DEB_MRD))
fprintf (sim_deb, ">>MBA%d: map %d read, value = %X\n", mb, ofs, *val);
sim_debug (MBA_DEB_MRD, &mba_dev[mb], "mba_rdreg(map %d read, val=0x%X)\n", ofs, *val);
break;
default:
@ -359,30 +452,40 @@ return SCPE_OK;
t_stat mba_wrreg (int32 val, int32 pa, int32 lnt)
{
int32 mb, ofs, drv, rtype;
uint32 old_reg, old_sr;
t_stat r;
t_bool cs1dt;
mb = NEXUS_GETNEX (pa) - TR_MBA0; /* get MBA */
if ((pa & 3) || (lnt != L_LONG)) { /* unaligned or not lw? */
printf (">>MBA%d: invalid adapter write mask, pa = %X, lnt = %d\r\n", mb, pa, lnt);
printf (">>MBA%d: invalid adapter write mask, pa = 0x%X, lnt = %d\r\n", mb, pa, lnt);
#if defined(VAX_780)
sbi_set_errcnf (); /* err confirmation */
#endif
return SCPE_OK;
}
if (mb >= MBA_NUM) /* valid? */
return SCPE_NXM;
rtype = MBA_RTYPE (pa); /* get reg type */
old_sr = mba_sr[mb];
switch (rtype) { /* case on type */
case MBART_INT: /* internal */
ofs = MBA_INTOFS (pa); /* check range */
sim_debug (MBA_DEB_RWR, &mba_dev[mb], "mba_wrreg(reg=%s write, val=0x%X)\n", mba_regnames[ofs], val);
switch (ofs) {
case MBACNF_OF: /* CNF */
old_reg = mba_cnf[mb];
mba_cnf[mb] &= ~(val & MBACNF_W1C);
sim_debug_bits(MBA_DEB_RWR, &mba_dev[mb], mba_reg_bits[ofs], old_reg, mba_cnf[mb], 1);
break;
case MBACR_OF: /* CR */
old_reg = mba_cr[mb];
if (val & MBACR_INIT) /* init? */
mba_reset (&mba_dev[mb]); /* reset MBA */
if ((val & MBACR_ABORT) &&
@ -400,6 +503,7 @@ switch (rtype) { /* case on type */
mba_clr_int (mb);
mba_cr[mb] = (mba_cr[mb] & ~MBACR_WR) |
(val & MBACR_WR);
sim_debug_bits(MBA_DEB_RWR, &mba_dev[mb], mba_reg_bits[ofs], old_reg, mba_cr[mb], 1);
break;
case MBASR_OF: /* SR */
@ -407,27 +511,32 @@ switch (rtype) { /* case on type */
break;
case MBAVA_OF: /* VA */
old_reg = mba_va[mb];
sim_debug_bits(MBA_DEB_RWR, &mba_dev[mb], mba_reg_bits[ofs], mba_va[mb], val, 1);
if (mba_sr[mb] & MBASR_DTBUSY) /* err if xfr */
mba_upd_sr (MBASR_PGE, 0, mb);
else mba_va[mb] = val & MBAVA_WR;
sim_debug_bits(MBA_DEB_RWR, &mba_dev[mb], mba_reg_bits[ofs], old_reg, mba_va[mb], 1);
break;
case MBABC_OF: /* BC */
old_reg = mba_bc[mb];
if (mba_sr[mb] & MBASR_DTBUSY) /* err if xfr */
mba_upd_sr (MBASR_PGE, 0, mb);
else mba_bc[mb] = val & MBABC_WR;
sim_debug_bits(MBA_DEB_RWR, &mba_dev[mb], mba_reg_bits[ofs], old_reg, mba_bc[mb], 1);
break;
case MBADR_OF: /* DR */
old_reg = mba_dr[mb];
mba_dr[mb] = (mba_dr[mb] & ~MBADR_WR) |
(val & MBADR_WR);
sim_debug_bits(MBA_DEB_RWR, &mba_dev[mb], mba_reg_bits[ofs], old_reg, mba_dr[mb], 1);
break;
default:
return SCPE_NXM;
}
if (DEBUG_PRI (mba_dev[mb], MBA_DEB_RWR))
fprintf (sim_deb, ">>MBA%d: int reg %d write, value = %X\n", mb, ofs, val);
break;
case MBART_EXT: /* external */
@ -435,6 +544,7 @@ switch (rtype) { /* case on type */
return SCPE_NXM;
drv = MBA_EXTDRV (pa); /* get dev num */
ofs = MBA_EXTOFS (pa); /* get reg offs */
sim_debug (MBA_DEB_RWR, &mba_dev[mb], "mba_wrreg(drv=%d ext reg=%d write, val=0x%X)\n", drv, ofs, val);
cs1dt = (ofs == MBA_CS1) && (val & CSR_GO) && /* starting xfr? */
((val & MBA_CS1_WR) >= MBA_CS1_DT);
if (cs1dt && (mba_sr[mb] & MBASR_DTBUSY)) { /* xfr while busy? */
@ -448,21 +558,21 @@ switch (rtype) { /* case on type */
return SCPE_NXM;
if (cs1dt && (r == SCPE_OK)) /* did dt start? */
mba_sr[mb] = (mba_sr[mb] | MBASR_DTBUSY) & ~MBASR_W1C;
if (DEBUG_PRI (mba_dev[mb], MBA_DEB_RWR))
fprintf (sim_deb, ">>MBA%d: drv %d ext reg %d write, value = %X\n", mb, drv, ofs, val);
break;
case MBART_MAP: /* map */
ofs = MBA_INTOFS (pa);
mba_map[mb][ofs] = val & MBAMAP_WR;
if (DEBUG_PRI (mba_dev[mb], MBA_DEB_MWR))
fprintf (sim_deb, ">>MBA%d: map %d write, value = %X\n", mb, ofs, val);
sim_debug (MBA_DEB_MWR, &mba_dev[mb], "mba_wrreg(map %d write, val=0x%X)\n", ofs, val);
break;
default:
return SCPE_NXM;
}
if (old_sr != mba_sr[mb])
sim_debug_bits(MBA_DEB_RWR, &mba_dev[mb], mba_sr_bits, old_sr, mba_sr[mb], 1);
return SCPE_OK;
}
@ -496,8 +606,7 @@ for (i = 0; i < bc; i = i + pbc) { /* loop by pages */
pbc = VA_PAGSIZE - VA_GETOFF (pa); /* left in page */
if (pbc > (bc - i)) /* limit to rem xfr */
pbc = bc - i;
if (DEBUG_PRI (mba_dev[mb], MBA_DEB_XFR))
fprintf (sim_deb, ">>MBA%d: read, pa = %X, bc = %X\n", mb, pa, pbc);
sim_debug (MBA_DEB_XFR, &mba_dev[mb], "mba_rdbufW(pa=0x%X, bc=0x%X)\n", pa, pbc);
if ((pa | pbc) & 1) { /* aligned word? */
for (j = 0; j < pbc; pa++, j++) { /* no, bytes */
if ((i + j) & 1) { /* odd byte? */
@ -546,8 +655,7 @@ for (i = 0; i < bc; i = i + pbc) { /* loop by pages */
pbc = VA_PAGSIZE - VA_GETOFF (pa); /* left in page */
if (pbc > (bc - i)) /* limit to rem xfr */
pbc = bc - i;
if (DEBUG_PRI (mba_dev[mb], MBA_DEB_XFR))
fprintf (sim_deb, ">>MBA%d: write, pa = %X, bc = %X\n", mb, pa, pbc);
sim_debug (MBA_DEB_XFR, &mba_dev[mb], "mba_wrbufW(pa=0x%X, bc=0x%X)\n", pa, pbc);
if ((pa | pbc) & 1) { /* aligned word? */
for (j = 0; j < pbc; pa++, j++) { /* no, bytes */
if ((i + j) & 1) {
@ -595,8 +703,7 @@ for (i = 0; i < bc; i = i + pbc) { /* loop by pages */
break;
}
pbc = VA_PAGSIZE - VA_GETOFF (pa); /* left in page */
if (DEBUG_PRI (mba_dev[mb], MBA_DEB_XFR))
fprintf (sim_deb, ">>MBA%d: check, pa = %X, bc = %X\n", mb, pa, pbc);
sim_debug (MBA_DEB_XFR, &mba_dev[mb], "mba_chbufW(pa=0x%X, bc=0x%X)\n", pa, pbc);
if (pbc > (bc - i)) /* limit to rem xfr */
pbc = bc - i;
for (j = 0; j < pbc; j++, pa++) { /* byte by byte */
@ -635,23 +742,30 @@ return 0;
void mba_set_don (uint32 mb)
{
uint32 old_sr = mba_sr[mb];
mba_upd_sr (MBASR_DTCMP, 0, mb);
if (old_sr != mba_sr[mb])
sim_debug_bits(MBA_DEB_RWR, &mba_dev[mb], mba_sr_bits, old_sr, mba_sr[mb], 1);
return;
}
void mba_upd_ata (uint32 mb, uint32 val)
{
uint32 old_sr = mba_sr[mb];
if (val)
mba_upd_sr (MBASR_ATA, 0, mb);
else mba_upd_sr (0, MBASR_ATA, mb);
if (old_sr != mba_sr[mb])
sim_debug_bits(MBA_DEB_RWR, &mba_dev[mb], mba_sr_bits, old_sr, mba_sr[mb], 1);
return;
}
void mba_set_exc (uint32 mb)
{
sim_debug (MBA_DEB_ERR, &mba_dev[mb], "mba_set_exc(EXC write)\n");
mba_upd_sr (MBASR_MBEXC, 0, mb);
if (DEBUG_PRI (mba_dev[mb], MBA_DEB_ERR))
fprintf (sim_deb, ">>MBA%d: EXC write\n", mb);
return;
}
@ -669,8 +783,10 @@ DIB *dibp;
if (mb >= MBA_NUM)
return;
dibp = (DIB *) mba_dev[mb].ctxt;
if (dibp)
if (dibp) {
nexus_req[dibp->vloc >> 5] |= (1u << (dibp->vloc & 0x1F));
sim_debug (MBA_DEB_INT, &mba_dev[mb], "mba_set_int(0x%X)\n", dibp->vloc);
}
return;
}
@ -681,24 +797,31 @@ DIB *dibp;
if (mb >= MBA_NUM)
return;
dibp = (DIB *) mba_dev[mb].ctxt;
if (dibp)
if (dibp) {
nexus_req[dibp->vloc >> 5] &= ~(1u << (dibp->vloc & 0x1F));
sim_debug (MBA_DEB_INT, &mba_dev[mb], "mba_clr_int(0x%X)\n", dibp->vloc);
}
return;
}
void mba_upd_sr (uint32 set, uint32 clr, uint32 mb)
{
uint32 o_sr;
if (mb >= MBA_NUM)
return;
o_sr = mba_sr[mb];
if (set & MBASR_ABORTS)
set |= (MBASR_DTCMP|MBASR_DTABT);
if (set & (MBASR_DTCMP|MBASR_DTABT))
mba_sr[mb] &= ~MBASR_DTBUSY;
mba_sr[mb] = (mba_sr[mb] | set) & ~clr;
if ((set & MBASR_INTR) && (mba_cr[mb] & MBACR_IE))
if (mba_sr[mb] != o_sr)
sim_debug_bits(MBA_DEB_RWR, &mba_dev[mb], mba_sr_bits, o_sr, mba_sr[mb], 1);
if ((set & MBASR_INTR) && (mba_cr[mb] & MBACR_IE) && !(mba_sr[mb] & MBASR_DTBUSY))
mba_set_int (mb);
if ((set & MBASR_ERRORS) && (DEBUG_PRI (mba_dev[mb], MBA_DEB_ERR)))
fprintf (sim_deb, ">>MBA%d: CS error = %X\n", mb, mba_sr[mb]);
if (set & MBASR_ERRORS)
sim_debug (MBA_DEB_ERR, &mba_dev[mb], "mba_upd_sr(CS error=0x%X)\n", mba_sr[mb]);
return;
}

View file

@ -468,22 +468,14 @@ REG cpu_reg[] = {
MTAB cpu_mod[] = {
{ UNIT_CONH, 0, "HALT to SIMH", "SIMHALT", NULL },
{ UNIT_CONH, UNIT_CONH, "HALT to console", "CONHALT", NULL },
{ MTAB_XTD|MTAB_VDV, 0, "IDLE", "IDLE", &cpu_set_idle, &cpu_show_idle },
{ MTAB_XTD|MTAB_VDV, 0, "IDLE", "IDLE={VMS|ULTRIX|NETBSD|OPENBSD|ULTRIXOLD|OPENBSDOLD|QUASIJARUS|32V|ALL}", &cpu_set_idle, &cpu_show_idle },
{ MTAB_XTD|MTAB_VDV, 0, NULL, "NOIDLE", &sim_clr_idle, NULL },
{ UNIT_MSIZE, (1u << 23), NULL, "8M", &cpu_set_size },
{ UNIT_MSIZE, (1u << 24), NULL, "16M", &cpu_set_size },
{ UNIT_MSIZE, (1u << 25), NULL, "32M", &cpu_set_size },
{ UNIT_MSIZE, (1u << 25) + (1u << 24), NULL, "48M", &cpu_set_size },
{ UNIT_MSIZE, (1u << 26), NULL, "64M", &cpu_set_size },
{ UNIT_MSIZE, (1u << 27), NULL, "128M", &cpu_set_size },
#if !defined (VAX_780)
{ UNIT_MSIZE, (1u << 28), NULL, "256M", &cpu_set_size },
{ UNIT_MSIZE, (1u << 29), NULL, "512M", &cpu_set_size },
#endif
MEM_MODIFIERS, /* Model specific memory modifiers from vaxXXX_defs.h */
{ MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "HISTORY", "HISTORY",
&cpu_set_hist, &cpu_show_hist },
{ MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "VIRTUAL", NULL,
NULL, &cpu_show_virt },
CPU_MODEL_MODIFIERS /* Model specific cpu modifiers from vaxXXX_defs.h */
{ 0 }
};
@ -591,8 +583,11 @@ else if (abortval < 0) { /* mm or rsrv or int */
break;
case SCB_MCHK: /* machine check */
/* The ka630 and ka620 CPU ROMs use double machine checks to size memory */
#if !defined(VAX_620) && !defined(VAX_630)
if (in_ie) /* in exc? panic */
ABORT (STOP_INIE);
#endif
cc = machine_check (p1, opc, cc, delta); /* system specific */
in_ie = 0;
GET_CUR; /* PSL<cur> changed */
@ -3462,3 +3457,39 @@ if (sim_idle_enab && (cpu_idle_type != 0))
sim_show_idle (st, uptr, val, desc);
return SCPE_OK;
}
t_stat cpu_load_bootcode (const char *filename, const unsigned char *builtin_code, size_t size, t_bool rom, t_addr offset)
{
extern FILE *sim_log;
char args[CBUFSIZE];
t_stat r;
printf ("Loading boot code from %s\n", filename);
if (sim_log)
fprintf (sim_log, "Loading boot code from %s\n", filename);
if (rom)
sprintf (args, "-R %s", filename);
else
sprintf (args, "-O %s %X", filename, (int)offset);
r = load_cmd (0, args);
if (r != SCPE_OK) {
if (builtin_code) {
FILE *f;
if ((f = sim_fopen (filename, "wb"))) {
printf ("Saving boot code to %s\n", filename);
if (sim_log)
fprintf (sim_log, "Saving boot code to %s\n", filename);
sim_fwrite ((void *)builtin_code, 1, size, f);
fclose (f);
printf ("Loading boot code from %s\n", filename);
if (sim_log)
fprintf (sim_log, "Loading boot code from %s\n", filename);
r = load_cmd (0, args);
}
}
return r;
}
return SCPE_OK;
}

View file

@ -730,8 +730,25 @@ void cpu_idle (void);
#if defined (VAX_780)
#include "vax780_defs.h"
#else
#elif defined (VAX_750)
#include "vax750_defs.h"
#elif defined (VAX_730)
#include "vax730_defs.h"
#elif defined (VAX_610)
#include "vax610_defs.h"
#elif defined (VAX_620) || defined (VAX_630)
#include "vax630_defs.h"
#else /* VAX 3900 */
#include "vaxmod_defs.h"
#endif
#ifndef CPU_MODEL_MODIFIERS
#define CPU_MODEL_MODIFIERS /* No model specific CPU modifiers */
#endif
#ifdef DONT_USE_INTERNAL_ROM
#define BOOT_CODE_ARRAY NULL
#define BOOT_CODE_SIZE 0
#endif
extern t_stat cpu_load_bootcode (const char *filename, const unsigned char *builtin_code, size_t size, t_bool rom, t_addr offset);
#endif /* _VAX_DEFS_H */

1037
VAX/vax_ka610_bin.h Normal file

File diff suppressed because it is too large Load diff

4109
VAX/vax_ka620_bin.h Normal file

File diff suppressed because it is too large Load diff

4109
VAX/vax_ka630_bin.h Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -23,6 +23,7 @@
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
24-Oct-12 MB Added support for KA620 virtual addressing
21-Jul-08 RMS Removed inlining support
28-May-08 RMS Inlined physical memory routines
29-Apr-07 RMS Added address masking for system page table reads
@ -474,6 +475,7 @@ else {
MM_ERR (PR_LNV);
ptead = d_p0br + ptidx;
}
#if !defined (VAX_620)
if ((ptead & VA_S0) == 0)
ABORT (STOP_PPTE); /* ppte must be sys */
vpn = VA_GETVPN (ptead); /* get vpn, tbi */
@ -494,6 +496,7 @@ else {
((pte << VA_N_OFF) & TLB_PFN); /* set stlb data */
}
ptead = (stlb[tbi].pte & TLB_PFN) | VA_GETOFF (ptead);
#endif
}
pte = ReadL (ptead); /* read pte */
tlbpte = cvtacc[PTE_GETACC (pte)] | /* cvt access */

View file

@ -410,7 +410,7 @@ int32 clk_cosched (int32 wait)
{
int32 t;
t = sim_is_active (&clk_unit);
t = sim_activate_time (&clk_unit);
return (t? t - 1: wait);
}

View file

@ -54,13 +54,27 @@
#include "vax_defs.h"
#ifndef DONT_USE_INTERNAL_ROM
#include "vax_ka655x_bin.h"
#endif
#ifdef DONT_USE_INTERNAL_ROM
#define BOOT_CODE_FILENAME "ka655x.bin"
#else /* !DONT_USE_INTERNAL_ROM */
#include "vax_ka655x_bin.h" /* Defines BOOT_CODE_FILENAME and BOOT_CODE_ARRAY, etc */
#endif /* DONT_USE_INTERNAL_ROM */
#define UNIT_V_NODELAY (UNIT_V_UF + 0) /* ROM access equal to RAM access */
#define UNIT_NODELAY (1u << UNIT_V_NODELAY)
extern CTAB *sim_vm_cmd;
t_stat vax_boot (int32 flag, char *ptr);
/* Special boot command, overrides regular boot */
CTAB vax_cmd[] = {
{ "BOOT", &vax_boot, RU_BOOT,
"bo{ot} boot simulator\n", &run_cmd_message },
{ NULL }
};
/* Console storage control/status */
#define CSICSR_IMP (CSR_DONE + CSR_IE) /* console input */
@ -1450,7 +1464,7 @@ return;
void tmr_sched (int32 tmr)
{
int32 clk_time = sim_is_active (&clk_unit) - 1;
int32 clk_time = sim_activate_time (&clk_unit) - 1;
int32 tmr_time;
tmr_sav[tmr] = sim_grtime (); /* save intvl base */
@ -1541,6 +1555,23 @@ JUMP (ROMBASE); /* PC = 20040000 */
return 0; /* new cc = 0 */
}
/* Special boot command - linked into SCP by initial reset
Syntax: BOOT {CPU}
*/
t_stat vax_boot (int32 flag, char *ptr)
{
char gbuf[CBUFSIZE];
get_glyph (ptr, gbuf, 0); /* get glyph */
if (gbuf[0] && strcmp (gbuf, "CPU"))
return SCPE_ARG; /* Only can specify CPU device */
return run_cmd (flag, "CPU");
}
/* Bootstrap */
t_stat cpu_boot (int32 unitno, DEVICE *dptr)
@ -1556,28 +1587,9 @@ conpsl = PSL_IS | PSL_IPL1F | CON_PWRUP;
if (rom == NULL)
return SCPE_IERR;
if (*rom == 0) { /* no boot? */
printf ("Loading boot code from ka655x.bin\n");
if (sim_log)
fprintf (sim_log, "Loading boot code from ka655x.bin\n");
r = load_cmd (0, "-R ka655x.bin");
if (r != SCPE_OK) {
#ifndef DONT_USE_INTERNAL_ROM
FILE *f;
if ((f = sim_fopen ("ka655x.bin", "wb"))) {
printf ("Saving boot code to ka655x.bin\n");
if (sim_log)
fprintf (sim_log, "Saving boot code to ka655x.bin\n");
sim_fwrite (vax_ka655x_bin, sizeof(vax_ka655x_bin[0]), sizeof(vax_ka655x_bin)/sizeof(vax_ka655x_bin[0]), f);
fclose (f);
printf ("Loading boot code from ka655x.bin\n");
if (sim_log)
fprintf (sim_log, "Loading boot code from ka655x.bin\n");
r = load_cmd (0, "-R ka655x.bin");
}
#endif
r = cpu_load_bootcode (BOOT_CODE_FILENAME, BOOT_CODE_ARRAY, BOOT_CODE_SIZE, TRUE, 0);
if (r != SCPE_OK)
return r;
}
}
sysd_powerup ();
return SCPE_OK;
@ -1603,6 +1615,7 @@ cso_csr = CSR_DONE;
cso_unit.buf = 0;
sim_cancel (&cso_unit);
CLR_INT (CSO);
sim_vm_cmd = vax_cmd;
return SCPE_OK;
}

View file

@ -1,11 +1,15 @@
#ifndef ROM_vax780_vmb_exe_H
#define ROM_vax780_vmb_exe_H 0
#ifndef ROM_vax_vmb_exe_H
#define ROM_vax_vmb_exe_H 0
/*
VAX/vax780_vmb_exe.h produced at Sun Feb 26 12:32:44 2012
from VAX/vmb.exe which was last modified at Sat Feb 18 00:01:12 2012
VAX/vax_vmb_exe.h produced at Fri Nov 09 06:40:16 2012
from VAX/vmb.exe which was last modified at Sun Oct 21 17:12:55 2012
file size: 44544 (0xAE00) - checksum: 0xFFC014CC
This file is a generated file and should NOT be edited or changed by hand.
*/
unsigned char vax780_vmb_exe[] = {
#define BOOT_CODE_SIZE 0xAE00
#define BOOT_CODE_FILENAME "vmb.exe"
#define BOOT_CODE_ARRAY vax_vmb_exe
unsigned char vax_vmb_exe[] = {
0xD4,0xEF,0x34,0x61,0x00,0x00,0x17,0xEF,0xB8,0x5D,0x00,0x00,0xC1,0xAB,0x38,0xAB,
0x34,0x57,0xC0,0x8F,0x00,0x02,0x00,0x00,0x57,0xCA,0x8F,0xFF,0x01,0x00,0x00,0x57,
0x95,0xCF,0x18,0x03,0x13,0x08,0xD4,0x50,0x7D,0xAB,0x44,0x52,0x11,0x24,0x7D,0xAB,
@ -2790,4 +2794,4 @@ unsigned char vax780_vmb_exe[] = {
0x4C,0x52,0x45,0x41,0x44,0x3A,0x58,0x2D,0x32,0x20,0x20,0x43,0x4F,0x4E,0x49,0x4F,
0x3A,0x58,0x2D,0x33,0x20,0x20,0x2A,0x45,0x6E,0x64,0x20,0x6F,0x66,0x20,0x49,0x64,
0x65,0x6E,0x74,0x20,0x6C,0x69,0x73,0x74,0x73,0x2A,0x00,0x00,0x00,0x00,0x00,0x00,};
#endif /* ROM_vax780_vmb_exe_H */
#endif /* ROM_vax_vmb_exe_H */

217
VAX/vax_watch.c Normal file
View file

@ -0,0 +1,217 @@
/* vax_watch.c: VAX watch chip
Copyright (c) 2011-2012, 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.
wtc Watch chip
08-Nov-2012 MB First version
This file covers the watch chip (MC146818) which is used by several VAX
models including the KA620, KA630, KA410, KA420 and KA820.
*/
#include "vax_defs.h"
#include <time.h>
/* control/status registers */
#define WTC_CSRA_RS 0x0F
#define WTC_CSRA_V_DV 4
#define WTC_CSRA_M_DV 0x7
#define WTC_CSRA_DV (WTC_CSRA_M_DV << WTC_CSRA_V_DV)
#define WTC_CSRA_UIP 0x80 /* update in progess */
#define WTC_CSRA_WR (WTC_CSRA_RS | WTC_CSRA_DV)
#define WTC_CSRB_DSE 0x01 /* daylight saving en */
#define WTC_CSRB_2412 0x02 /* 24/12hr select */
#define WTC_CSRB_DM 0x04 /* data mode */
#define WTC_CSRB_SET 0x80 /* set time */
#define WTC_CSRB_WR (WTC_CSRB_DSE | WTC_CSRB_2412 | WTC_CSRB_DM | WTC_CSRB_SET)
#define WTC_CSRD_VRT 0x80 /* valid time */
#define WTC_CSRD_RD (WTC_CSRD_VRT)
#define WTC_MODE_STD 0
#define WTC_MODE_VMS 1
extern int32 sim_switches;
int32 wtc_csra = 0;
int32 wtc_csrb = 0;
int32 wtc_csrc = 0;
int32 wtc_csrd = 0;
int32 wtc_mode = WTC_MODE_VMS;
t_stat wtc_set (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat wtc_show (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat wtc_reset (DEVICE *dptr);
void wtc_set_valid (void);
void wtc_set_invalid (void);
UNIT wtc_unit = { UDATA (NULL, 0, 0) };
REG wtc_reg[] = {
{ HRDATA (CSRA, wtc_csra, 8) },
{ HRDATA (CSRB, wtc_csrb, 8) },
{ HRDATA (CSRC, wtc_csrc, 8) },
{ HRDATA (CSRD, wtc_csrd, 8) },
{ NULL }
};
MTAB wtc_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "TIME", "TIME={VMS|STD}", &wtc_set, &wtc_show },
{ 0 }
};
DEVICE wtc_dev = {
"WTC", &wtc_unit, wtc_reg, wtc_mod,
1, 16, 16, 1, 16, 8,
NULL, NULL, &wtc_reset,
NULL, NULL, NULL,
NULL, 0
};
int32 wtc_rd (int32 pa)
{
int32 rg = (pa >> 1) & 0xF;
int32 val = 0;
time_t curr;
struct tm *ctm;
if (rg < 10) { /* time reg? */
curr = time (NULL); /* get curr time */
if (curr == (time_t) -1) /* error? */
return 0;
ctm = localtime (&curr); /* decompose */
if (ctm == NULL) /* error? */
return 0;
}
switch(rg) {
case 0: /* seconds */
val = ctm->tm_sec;
break;
case 2: /* minutes */
val = ctm->tm_min;
break;
case 4: /* hours */
val = ctm->tm_hour;
break;
case 6: /* day of week */
val = ctm->tm_wday;
break;
case 7: /* day of month */
val = ctm->tm_mday;
break;
case 8: /* month */
val = ctm->tm_mon;
break;
case 9: /* year */
if (wtc_mode == WTC_MODE_VMS)
val = 82; /* always 1982 for VMS */
else
val = (int32)(ctm->tm_year % 100);
break;
case 10: /* CSR A */
val = wtc_csra;
break;
case 11: /* CSR B */
val = wtc_csrb;
break;
case 12: /* CSR C */
val = wtc_csrc;
break;
case 13: /* CSR D */
val = wtc_csrd & WTC_CSRD_RD;
break;
}
return ((rg & 1) ? (val << 16) : val); /* word aligned? */
}
void wtc_wr (int32 pa, int32 val, int32 lnt)
{
int32 rg = (pa >> 1) & 0xF;
val = val & 0xFF;
switch(rg) {
case 10: /* CSR A */
val = val & WTC_CSRA_WR;
wtc_csra = (wtc_csra & ~WTC_CSRA_WR) | val;
break;
case 11: /* CSR B */
val = val & WTC_CSRB_WR;
wtc_csrb = (wtc_csrb & ~WTC_CSRB_WR) | val;
break;
}
}
t_stat wtc_reset (DEVICE *dptr)
{
if (sim_switches & SWMASK ('P')) { /* powerup? */
wtc_csra = 0;
wtc_csrb = 0;
wtc_csrc = 0;
wtc_csrd = 0;
wtc_mode = WTC_MODE_VMS;
}
return SCPE_OK;
}
t_stat wtc_set (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if (cptr != NULL) wtc_mode = strcmp(cptr, "STD");
return SCPE_OK;
}
t_stat wtc_show (FILE *st, UNIT *uptr, int32 val, void *desc)
{
fprintf(st, "time=%s", (wtc_mode ? "vms" :"std"));
return SCPE_OK;
}
void wtc_set_valid (void)
{
wtc_csra |= (2 << WTC_CSRA_V_DV);
wtc_csrb |= (WTC_CSRB_DM | WTC_CSRB_2412);
wtc_csrd |= WTC_CSRD_VRT;
}
void wtc_set_invalid (void)
{
wtc_csrd &= ~WTC_CSRD_VRT;
}

View file

@ -117,6 +117,15 @@
#define INITMEMSIZE (1 << 24) /* initial memory size */
#define MEMSIZE (cpu_unit.capac)
#define ADDR_IS_MEM(x) (((uint32) (x)) < MEMSIZE)
#define MEM_MODIFIERS { UNIT_MSIZE, (1u << 23), NULL, "8M", &cpu_set_size }, \
{ UNIT_MSIZE, (1u << 24), NULL, "16M", &cpu_set_size }, \
{ UNIT_MSIZE, (1u << 25), NULL, "32M", &cpu_set_size }, \
{ UNIT_MSIZE, (1u << 25) + (1u << 24), NULL, "48M", &cpu_set_size }, \
{ UNIT_MSIZE, (1u << 26), NULL, "64M", &cpu_set_size }, \
{ UNIT_MSIZE, (1u << 27), NULL, "128M", &cpu_set_size }, \
{ UNIT_MSIZE, (1u << 28), NULL, "256M", &cpu_set_size }, \
{ UNIT_MSIZE, (1u << 29), NULL, "512M", &cpu_set_size }
/* Cache diagnostic space */

View file

@ -65,6 +65,31 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "swtp6800mp-a2", "swtp6800mp
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BuildROMs", "BuildROMs.vcproj", "{D40F3AF1-EEE7-4432-9807-2AD287B490F8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VAX730", "VAX730.vcproj", "{C526F7F2-9476-44BC-B1E9-9522B693BEA7}"
ProjectSection(ProjectDependencies) = postProject
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VAX750", "VAX750.vcproj", "{43A9CF64-5705-4FB7-B837-ED9AAFF97DAC}"
ProjectSection(ProjectDependencies) = postProject
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VAX610", "VAX610.vcproj", "{B3671ABB-4FFF-4EEB-8A5B-06716C9BCE9E}"
ProjectSection(ProjectDependencies) = postProject
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VAX620", "VAX620.vcproj", "{E359921B-DC18-42ED-AFB9-1FC603B9C1B3}"
ProjectSection(ProjectDependencies) = postProject
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VAX630", "VAX630.vcproj", "{3048F582-98C9-447D-BBB9-6F969467D4EA}"
ProjectSection(ProjectDependencies) = postProject
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TX-0", "TX-0.vcproj", "{24BC7F75-FB56-44A9-BB7C-78AE6A694D0C}"
EndProject
Global
@ -189,6 +214,26 @@ Global
{D40F3AF1-EEE7-4432-9807-2AD287B490F8}.Debug|Win32.Build.0 = Debug|Win32
{D40F3AF1-EEE7-4432-9807-2AD287B490F8}.Release|Win32.ActiveCfg = Release|Win32
{D40F3AF1-EEE7-4432-9807-2AD287B490F8}.Release|Win32.Build.0 = Release|Win32
{C526F7F2-9476-44BC-B1E9-9522B693BEA7}.Debug|Win32.ActiveCfg = Debug|Win32
{C526F7F2-9476-44BC-B1E9-9522B693BEA7}.Debug|Win32.Build.0 = Debug|Win32
{C526F7F2-9476-44BC-B1E9-9522B693BEA7}.Release|Win32.ActiveCfg = Release|Win32
{C526F7F2-9476-44BC-B1E9-9522B693BEA7}.Release|Win32.Build.0 = Release|Win32
{43A9CF64-5705-4FB7-B837-ED9AAFF97DAC}.Debug|Win32.ActiveCfg = Debug|Win32
{43A9CF64-5705-4FB7-B837-ED9AAFF97DAC}.Debug|Win32.Build.0 = Debug|Win32
{43A9CF64-5705-4FB7-B837-ED9AAFF97DAC}.Release|Win32.ActiveCfg = Release|Win32
{43A9CF64-5705-4FB7-B837-ED9AAFF97DAC}.Release|Win32.Build.0 = Release|Win32
{B3671ABB-4FFF-4EEB-8A5B-06716C9BCE9E}.Debug|Win32.ActiveCfg = Debug|Win32
{B3671ABB-4FFF-4EEB-8A5B-06716C9BCE9E}.Debug|Win32.Build.0 = Debug|Win32
{B3671ABB-4FFF-4EEB-8A5B-06716C9BCE9E}.Release|Win32.ActiveCfg = Release|Win32
{B3671ABB-4FFF-4EEB-8A5B-06716C9BCE9E}.Release|Win32.Build.0 = Release|Win32
{E359921B-DC18-42ED-AFB9-1FC603B9C1B3}.Debug|Win32.ActiveCfg = Debug|Win32
{E359921B-DC18-42ED-AFB9-1FC603B9C1B3}.Debug|Win32.Build.0 = Debug|Win32
{E359921B-DC18-42ED-AFB9-1FC603B9C1B3}.Release|Win32.ActiveCfg = Release|Win32
{E359921B-DC18-42ED-AFB9-1FC603B9C1B3}.Release|Win32.Build.0 = Release|Win32
{3048F582-98C9-447D-BBB9-6F969467D4EA}.Debug|Win32.ActiveCfg = Debug|Win32
{3048F582-98C9-447D-BBB9-6F969467D4EA}.Debug|Win32.Build.0 = Debug|Win32
{3048F582-98C9-447D-BBB9-6F969467D4EA}.Release|Win32.ActiveCfg = Release|Win32
{3048F582-98C9-447D-BBB9-6F969467D4EA}.Release|Win32.Build.0 = Release|Win32
{24BC7F75-FB56-44A9-BB7C-78AE6A694D0C}.Debug|Win32.ActiveCfg = Debug|Win32
{24BC7F75-FB56-44A9-BB7C-78AE6A694D0C}.Debug|Win32.Build.0 = Debug|Win32
{24BC7F75-FB56-44A9-BB7C-78AE6A694D0C}.Release|Win32.ActiveCfg = Release|Win32

View file

@ -0,0 +1,449 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="VAX610"
ProjectGUID="{B3671ABB-4FFF-4EEB-8A5B-06716C9BCE9E}"
RootNamespace="VAX610"
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\VAX610\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Build Dependent ROM include File(s) &amp; Check for required build dependencies"
CommandLine="pushd ..&#x0D;&#x0A;$(TargetDir)BuildROMs&#x0D;&#x0A;popd&#x0D;&#x0A;&#x0D;&#x0A;if not exist ../../windows-build/winpcap/Wpdpack/Include/pcap.h goto _notice&#x0D;&#x0A;if not exist ../../windows-build/pthreads/pthread.h goto _notice&#x0D;&#x0A;goto _good&#x0D;&#x0A;&#x0D;&#x0A;:_notice&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ** The required build support is not available. **&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;type 0ReadMe_Projects.txt&#x0D;&#x0A;exit 1&#x0D;&#x0A;&#x0D;&#x0A;:_good&#x0D;&#x0A;"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;&quot;../../windows-build/winpcap/Wpdpack/Include&quot;;&quot;../../windows-build/pthreads&quot;"
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_610;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO"
KeepComments="false"
MinimalRebuild="true"
BasicRuntimeChecks="0"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
CompileAs="1"
ShowIncludes="false"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/fixed:no"
AdditionalDependencies="wpcap.lib packet.lib wsock32.lib winmm.lib"
OutputFile="$(OutDir)\VAX610.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="&quot;../../windows-build/winpcap/Wpdpack/Lib/&quot;"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)\VAX610.pdb"
SubSystem="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"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\VAX610\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Build Dependent ROM include File(s) &amp; Check for required build dependencies"
CommandLine="pushd ..&#x0D;&#x0A;$(TargetDir)BuildROMs&#x0D;&#x0A;popd&#x0D;&#x0A;&#x0D;&#x0A;if not exist ../../windows-build/winpcap/Wpdpack/Include/pcap.h goto _notice&#x0D;&#x0A;if not exist ../../windows-build/pthreads/pthread.h goto _notice&#x0D;&#x0A;goto _good&#x0D;&#x0A;&#x0D;&#x0A;:_notice&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ** The required build support is not available. **&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;type 0ReadMe_Projects.txt&#x0D;&#x0A;exit 1&#x0D;&#x0A;&#x0D;&#x0A;:_good&#x0D;&#x0A;"
/>
<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/;&quot;../../windows-build/winpcap/Wpdpack/Include&quot;;&quot;../../windows-build/pthreads&quot;"
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_610;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO"
KeepComments="false"
StringPooling="true"
RuntimeLibrary="0"
BufferSecurityCheck="false"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
CompileAs="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/fixed:no"
AdditionalDependencies="wpcap.lib packet.lib wsock32.lib winmm.lib"
OutputFile="$(OutDir)\VAX610.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="&quot;../../windows-build/winpcap/Wpdpack/Lib/&quot;"
GenerateDebugInformation="true"
SubSystem="1"
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"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
>
<File
RelativePath="..\PDP11\pdp11_cr.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_dz.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_io_lib.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_lp.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_tq.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_ts.c"
>
</File>
<File
RelativePath="..\Pdp11\pdp11_vh.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_xq.c"
>
</File>
<File
RelativePath="..\..\windows-build\pthreads\pthread.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="HAVE_PTW32_CONFIG_H;PTW32_BUILD_INLINED;PTW32_STATIC_LIB;__CLEANUP_C;$(NOINHERIT)"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
WholeProgramOptimization="false"
PreprocessorDefinitions="HAVE_PTW32_CONFIG_H;PTW32_BUILD_INLINED;PTW32_STATIC_LIB;__CLEANUP_C;$(NOINHERIT)"
/>
</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_sock.c"
>
</File>
<File
RelativePath="..\sim_tape.c"
>
</File>
<File
RelativePath="..\sim_timer.c"
>
</File>
<File
RelativePath="..\sim_tmxr.c"
>
</File>
<File
RelativePath="..\VAX\vax610_io.c"
>
</File>
<File
RelativePath="..\VAX\vax610_mem.c"
>
</File>
<File
RelativePath="..\VAX\vax610_stddev.c"
>
</File>
<File
RelativePath="..\VAX\vax610_sysdev.c"
>
</File>
<File
RelativePath="..\VAX\vax610_syslist.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>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc"
>
<File
RelativePath="..\PDP11\pdp11_io_lib.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_mscp.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_uqssp.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_xq.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_xq_bootrom.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_sock.h"
>
</File>
<File
RelativePath="..\sim_tape.h"
>
</File>
<File
RelativePath="..\sim_timer.h"
>
</File>
<File
RelativePath="..\sim_tmxr.h"
>
</File>
<File
RelativePath="..\VAX\vax610_defs.h"
>
</File>
<File
RelativePath="..\VAX\vax_defs.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

@ -0,0 +1,453 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="VAX620"
ProjectGUID="{E359921B-DC18-42ED-AFB9-1FC603B9C1B3}"
RootNamespace="VAX620"
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\VAX620\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Build Dependent ROM include File(s) &amp; Check for required build dependencies"
CommandLine="pushd ..&#x0D;&#x0A;$(TargetDir)BuildROMs&#x0D;&#x0A;popd&#x0D;&#x0A;&#x0D;&#x0A;if not exist ../../windows-build/winpcap/Wpdpack/Include/pcap.h goto _notice&#x0D;&#x0A;if not exist ../../windows-build/pthreads/pthread.h goto _notice&#x0D;&#x0A;goto _good&#x0D;&#x0A;&#x0D;&#x0A;:_notice&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ** The required build support is not available. **&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;type 0ReadMe_Projects.txt&#x0D;&#x0A;exit 1&#x0D;&#x0A;&#x0D;&#x0A;:_good&#x0D;&#x0A;"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;&quot;../../windows-build/winpcap/Wpdpack/Include&quot;;&quot;../../windows-build/pthreads&quot;"
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_620;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO"
KeepComments="false"
MinimalRebuild="true"
BasicRuntimeChecks="0"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
CompileAs="1"
ShowIncludes="false"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/fixed:no"
AdditionalDependencies="wpcap.lib packet.lib wsock32.lib winmm.lib"
OutputFile="$(OutDir)\VAX620.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="&quot;../../windows-build/winpcap/Wpdpack/Lib/&quot;"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)\VAX620.pdb"
SubSystem="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"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\VAX620\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Build Dependent ROM include File(s) &amp; Check for required build dependencies"
CommandLine="pushd ..&#x0D;&#x0A;$(TargetDir)BuildROMs&#x0D;&#x0A;popd&#x0D;&#x0A;&#x0D;&#x0A;if not exist ../../windows-build/winpcap/Wpdpack/Include/pcap.h goto _notice&#x0D;&#x0A;if not exist ../../windows-build/pthreads/pthread.h goto _notice&#x0D;&#x0A;goto _good&#x0D;&#x0A;&#x0D;&#x0A;:_notice&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ** The required build support is not available. **&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;type 0ReadMe_Projects.txt&#x0D;&#x0A;exit 1&#x0D;&#x0A;&#x0D;&#x0A;:_good&#x0D;&#x0A;"
/>
<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/;&quot;../../windows-build/winpcap/Wpdpack/Include&quot;;&quot;../../windows-build/pthreads&quot;"
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_620;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO"
KeepComments="false"
StringPooling="true"
RuntimeLibrary="0"
BufferSecurityCheck="false"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
CompileAs="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/fixed:no"
AdditionalDependencies="wpcap.lib packet.lib wsock32.lib winmm.lib"
OutputFile="$(OutDir)\VAX620.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="&quot;../../windows-build/winpcap/Wpdpack/Lib/&quot;"
GenerateDebugInformation="true"
SubSystem="1"
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"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
>
<File
RelativePath="..\PDP11\pdp11_cr.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_dz.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_io_lib.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_lp.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_tq.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_ts.c"
>
</File>
<File
RelativePath="..\Pdp11\pdp11_vh.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_xq.c"
>
</File>
<File
RelativePath="..\..\windows-build\pthreads\pthread.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="HAVE_PTW32_CONFIG_H;PTW32_BUILD_INLINED;PTW32_STATIC_LIB;__CLEANUP_C;$(NOINHERIT)"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
WholeProgramOptimization="false"
PreprocessorDefinitions="HAVE_PTW32_CONFIG_H;PTW32_BUILD_INLINED;PTW32_STATIC_LIB;__CLEANUP_C;$(NOINHERIT)"
/>
</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_sock.c"
>
</File>
<File
RelativePath="..\sim_tape.c"
>
</File>
<File
RelativePath="..\sim_timer.c"
>
</File>
<File
RelativePath="..\sim_tmxr.c"
>
</File>
<File
RelativePath="..\VAX\vax630_io.c"
>
</File>
<File
RelativePath="..\VAX\vax630_stddev.c"
>
</File>
<File
RelativePath="..\VAX\vax630_sysdev.c"
>
</File>
<File
RelativePath="..\VAX\vax630_syslist.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>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc"
>
<File
RelativePath="..\PDP11\pdp11_io_lib.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_mscp.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_uqssp.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_xq.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_xq_bootrom.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_sock.h"
>
</File>
<File
RelativePath="..\sim_tape.h"
>
</File>
<File
RelativePath="..\sim_timer.h"
>
</File>
<File
RelativePath="..\sim_tmxr.h"
>
</File>
<File
RelativePath="..\VAX\vax630_defs.h"
>
</File>
<File
RelativePath="..\VAX\vax_defs.h"
>
</File>
<File
RelativePath="..\VAX\vaxmod_defs.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

@ -0,0 +1,453 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="VAX630"
ProjectGUID="{3048F582-98C9-447D-BBB9-6F969467D4EA}"
RootNamespace="VAX630"
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\VAX630\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Build Dependent ROM include File(s) &amp; Check for required build dependencies"
CommandLine="pushd ..&#x0D;&#x0A;$(TargetDir)BuildROMs&#x0D;&#x0A;popd&#x0D;&#x0A;&#x0D;&#x0A;if not exist ../../windows-build/winpcap/Wpdpack/Include/pcap.h goto _notice&#x0D;&#x0A;if not exist ../../windows-build/pthreads/pthread.h goto _notice&#x0D;&#x0A;goto _good&#x0D;&#x0A;&#x0D;&#x0A;:_notice&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ** The required build support is not available. **&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;type 0ReadMe_Projects.txt&#x0D;&#x0A;exit 1&#x0D;&#x0A;&#x0D;&#x0A;:_good&#x0D;&#x0A;"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;&quot;../../windows-build/winpcap/Wpdpack/Include&quot;;&quot;../../windows-build/pthreads&quot;"
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_630;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO"
KeepComments="false"
MinimalRebuild="true"
BasicRuntimeChecks="0"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
CompileAs="1"
ShowIncludes="false"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/fixed:no"
AdditionalDependencies="wpcap.lib packet.lib wsock32.lib winmm.lib"
OutputFile="$(OutDir)\VAX630.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="&quot;../../windows-build/winpcap/Wpdpack/Lib/&quot;"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)\VAX630.pdb"
SubSystem="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"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\VAX630\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Build Dependent ROM include File(s) &amp; Check for required build dependencies"
CommandLine="pushd ..&#x0D;&#x0A;$(TargetDir)BuildROMs&#x0D;&#x0A;popd&#x0D;&#x0A;&#x0D;&#x0A;if not exist ../../windows-build/winpcap/Wpdpack/Include/pcap.h goto _notice&#x0D;&#x0A;if not exist ../../windows-build/pthreads/pthread.h goto _notice&#x0D;&#x0A;goto _good&#x0D;&#x0A;&#x0D;&#x0A;:_notice&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ** The required build support is not available. **&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;type 0ReadMe_Projects.txt&#x0D;&#x0A;exit 1&#x0D;&#x0A;&#x0D;&#x0A;:_good&#x0D;&#x0A;"
/>
<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/;&quot;../../windows-build/winpcap/Wpdpack/Include&quot;;&quot;../../windows-build/pthreads&quot;"
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_630;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO"
KeepComments="false"
StringPooling="true"
RuntimeLibrary="0"
BufferSecurityCheck="false"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
CompileAs="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/fixed:no"
AdditionalDependencies="wpcap.lib packet.lib wsock32.lib winmm.lib"
OutputFile="$(OutDir)\VAX630.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="&quot;../../windows-build/winpcap/Wpdpack/Lib/&quot;"
GenerateDebugInformation="true"
SubSystem="1"
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"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
>
<File
RelativePath="..\PDP11\pdp11_cr.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_dz.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_io_lib.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_lp.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_tq.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_ts.c"
>
</File>
<File
RelativePath="..\Pdp11\pdp11_vh.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_xq.c"
>
</File>
<File
RelativePath="..\..\windows-build\pthreads\pthread.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="HAVE_PTW32_CONFIG_H;PTW32_BUILD_INLINED;PTW32_STATIC_LIB;__CLEANUP_C;$(NOINHERIT)"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
WholeProgramOptimization="false"
PreprocessorDefinitions="HAVE_PTW32_CONFIG_H;PTW32_BUILD_INLINED;PTW32_STATIC_LIB;__CLEANUP_C;$(NOINHERIT)"
/>
</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_sock.c"
>
</File>
<File
RelativePath="..\sim_tape.c"
>
</File>
<File
RelativePath="..\sim_timer.c"
>
</File>
<File
RelativePath="..\sim_tmxr.c"
>
</File>
<File
RelativePath="..\VAX\vax630_io.c"
>
</File>
<File
RelativePath="..\VAX\vax630_stddev.c"
>
</File>
<File
RelativePath="..\VAX\vax630_sysdev.c"
>
</File>
<File
RelativePath="..\VAX\vax630_syslist.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>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc"
>
<File
RelativePath="..\PDP11\pdp11_io_lib.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_mscp.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_uqssp.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_xq.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_xq_bootrom.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_sock.h"
>
</File>
<File
RelativePath="..\sim_tape.h"
>
</File>
<File
RelativePath="..\sim_timer.h"
>
</File>
<File
RelativePath="..\sim_tmxr.h"
>
</File>
<File
RelativePath="..\VAX\vax630_defs.h"
>
</File>
<File
RelativePath="..\VAX\vax_defs.h"
>
</File>
<File
RelativePath="..\VAX\vaxmod_defs.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

@ -0,0 +1,447 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="VAX730"
ProjectGUID="{C526F7F2-9476-44BC-B1E9-9522B693BEA7}"
RootNamespace="VAX730"
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\VAX730\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
Description="Build Dependent ROM include File(s) &amp; Check for required build dependencies"
CommandLine="pushd ..&#x0D;&#x0A;$(TargetDir)BuildROMs&#x0D;&#x0A;popd&#x0D;&#x0A;&#x0D;&#x0A;if not exist ../../windows-build/winpcap/Wpdpack/Include/pcap.h goto _notice&#x0D;&#x0A;if not exist ../../windows-build/pthreads/pthread.h goto _notice&#x0D;&#x0A;goto _good&#x0D;&#x0A;&#x0D;&#x0A;:_notice&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ** The required build support is not available. **&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;type 0ReadMe_Projects.txt&#x0D;&#x0A;exit 1&#x0D;&#x0A;&#x0D;&#x0A;:_good&#x0D;&#x0A;"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;&quot;../../windows-build/winpcap/Wpdpack/Include&quot;;&quot;../../windows-build/pthreads&quot;"
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_730;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO"
MinimalRebuild="true"
BasicRuntimeChecks="0"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
CompileAs="1"
ShowIncludes="false"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/fixed:no"
AdditionalDependencies="wpcap.lib packet.lib wsock32.lib winmm.lib"
OutputFile="$(OutDir)\VAX730.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../winpcap/Wpdpack/Lib/;&quot;../../pthreads/Pre-built.2/lib/&quot;"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)\VAX730.pdb"
SubSystem="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"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\VAX730\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
Description="Build Dependent ROM include File(s) &amp; Check for required build dependencies"
CommandLine="pushd ..&#x0D;&#x0A;$(TargetDir)BuildROMs&#x0D;&#x0A;popd&#x0D;&#x0A;&#x0D;&#x0A;if not exist ../../windows-build/winpcap/Wpdpack/Include/pcap.h goto _notice&#x0D;&#x0A;if not exist ../../windows-build/pthreads/pthread.h goto _notice&#x0D;&#x0A;goto _good&#x0D;&#x0A;&#x0D;&#x0A;:_notice&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ** The required build support is not available. **&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;type 0ReadMe_Projects.txt&#x0D;&#x0A;exit 1&#x0D;&#x0A;&#x0D;&#x0A;:_good&#x0D;&#x0A;"
/>
<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"
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;&quot;../../windows-build/winpcap/Wpdpack/Include&quot;;&quot;../../windows-build/pthreads&quot;"
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_730;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
CompileAs="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/fixed:no"
AdditionalDependencies="wpcap.lib packet.lib wsock32.lib winmm.lib"
OutputFile="$(OutDir)\VAX730.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../winpcap/Wpdpack/Lib/;&quot;../../pthreads/Pre-built.2/lib/&quot;"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
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"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
>
<File
RelativePath="..\PDP11\pdp11_cr.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_rl.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_rq.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_ry.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_tq.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_ts.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_PTW32_CONFIG_H;PTW32_BUILD_INLINED;PTW32_STATIC_LIB;__CLEANUP_C;$(NOINHERIT)"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="HAVE_PTW32_CONFIG_H;PTW32_BUILD_INLINED;PTW32_STATIC_LIB;__CLEANUP_C;$(NOINHERIT)"
/>
</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_sock.c"
>
</File>
<File
RelativePath="..\sim_tape.c"
>
</File>
<File
RelativePath="..\sim_timer.c"
>
</File>
<File
RelativePath="..\sim_tmxr.c"
>
</File>
<File
RelativePath="..\VAX\vax730_mem.c"
>
</File>
<File
RelativePath="..\VAX\vax730_rb.c"
>
</File>
<File
RelativePath="..\VAX\vax730_stddev.c"
>
</File>
<File
RelativePath="..\VAX\vax730_sys.c"
>
</File>
<File
RelativePath="..\VAX\vax730_syslist.c"
>
</File>
<File
RelativePath="..\VAX\vax730_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>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc"
>
<File
RelativePath="..\dec_dz.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_io_lib.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_mscp.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_sock.h"
>
</File>
<File
RelativePath="..\sim_tape.h"
>
</File>
<File
RelativePath="..\sim_timer.h"
>
</File>
<File
RelativePath="..\sim_tmxr.h"
>
</File>
<File
RelativePath="..\VAX\vax730_defs.h"
>
</File>
<File
RelativePath="..\VAX\vax_defs.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

@ -0,0 +1,455 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="VAX750"
ProjectGUID="{43A9CF64-5705-4FB7-B837-ED9AAFF97DAC}"
RootNamespace="VAX750"
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\VAX750\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
Description="Build Dependent ROM include File(s) &amp; Check for required build dependencies"
CommandLine="pushd ..&#x0D;&#x0A;$(TargetDir)BuildROMs&#x0D;&#x0A;popd&#x0D;&#x0A;&#x0D;&#x0A;if not exist ../../windows-build/winpcap/Wpdpack/Include/pcap.h goto _notice&#x0D;&#x0A;if not exist ../../windows-build/pthreads/pthread.h goto _notice&#x0D;&#x0A;goto _good&#x0D;&#x0A;&#x0D;&#x0A;:_notice&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ** The required build support is not available. **&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;type 0ReadMe_Projects.txt&#x0D;&#x0A;exit 1&#x0D;&#x0A;&#x0D;&#x0A;:_good&#x0D;&#x0A;"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;&quot;../../windows-build/winpcap/Wpdpack/Include&quot;;&quot;../../windows-build/pthreads&quot;"
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_750;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO"
MinimalRebuild="true"
BasicRuntimeChecks="0"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
CompileAs="1"
ShowIncludes="false"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/fixed:no"
AdditionalDependencies="wpcap.lib packet.lib wsock32.lib winmm.lib"
OutputFile="$(OutDir)\VAX750.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../winpcap/Wpdpack/Lib/;&quot;../../pthreads/Pre-built.2/lib/&quot;"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)\VAX750.pdb"
SubSystem="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"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\VAX750\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
Description="Build Dependent ROM include File(s) &amp; Check for required build dependencies"
CommandLine="pushd ..&#x0D;&#x0A;$(TargetDir)BuildROMs&#x0D;&#x0A;popd&#x0D;&#x0A;&#x0D;&#x0A;if not exist ../../windows-build/winpcap/Wpdpack/Include/pcap.h goto _notice&#x0D;&#x0A;if not exist ../../windows-build/pthreads/pthread.h goto _notice&#x0D;&#x0A;goto _good&#x0D;&#x0A;&#x0D;&#x0A;:_notice&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ** The required build support is not available. **&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;echo ****************************************************&#x0D;&#x0A;type 0ReadMe_Projects.txt&#x0D;&#x0A;exit 1&#x0D;&#x0A;&#x0D;&#x0A;:_good&#x0D;&#x0A;"
/>
<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"
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;&quot;../../windows-build/winpcap/Wpdpack/Include&quot;;&quot;../../windows-build/pthreads&quot;"
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_750;USE_SHARED;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
CompileAs="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/fixed:no"
AdditionalDependencies="wpcap.lib packet.lib wsock32.lib winmm.lib"
OutputFile="$(OutDir)\VAX750.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../winpcap/Wpdpack/Lib/;&quot;../../pthreads/Pre-built.2/lib/&quot;"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
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"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
>
<File
RelativePath="..\PDP11\pdp11_cr.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_rl.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_rp.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_rq.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_ry.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_tq.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_ts.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_tu.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_PTW32_CONFIG_H;PTW32_BUILD_INLINED;PTW32_STATIC_LIB;__CLEANUP_C;$(NOINHERIT)"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="HAVE_PTW32_CONFIG_H;PTW32_BUILD_INLINED;PTW32_STATIC_LIB;__CLEANUP_C;$(NOINHERIT)"
/>
</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_sock.c"
>
</File>
<File
RelativePath="..\sim_tape.c"
>
</File>
<File
RelativePath="..\sim_timer.c"
>
</File>
<File
RelativePath="..\sim_tmxr.c"
>
</File>
<File
RelativePath="..\VAX\vax750_cmi.c"
>
</File>
<File
RelativePath="..\VAX\vax750_mem.c"
>
</File>
<File
RelativePath="..\VAX\vax750_stddev.c"
>
</File>
<File
RelativePath="..\VAX\vax750_syslist.c"
>
</File>
<File
RelativePath="..\VAX\vax750_uba.c"
>
</File>
<File
RelativePath="..\VAX\vax7x0_mba.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>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc"
>
<File
RelativePath="..\dec_dz.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_io_lib.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_mscp.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_sock.h"
>
</File>
<File
RelativePath="..\sim_tape.h"
>
</File>
<File
RelativePath="..\sim_timer.h"
>
</File>
<File
RelativePath="..\sim_tmxr.h"
>
</File>
<File
RelativePath="..\VAX\vax750_defs.h"
>
</File>
<File
RelativePath="..\VAX\vax_defs.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

@ -322,10 +322,6 @@
RelativePath="..\VAX\vax780_fload.c"
>
</File>
<File
RelativePath="..\VAX\vax780_mba.c"
>
</File>
<File
RelativePath="..\VAX\vax780_mem.c"
>
@ -346,6 +342,10 @@
RelativePath="..\VAX\vax780_uba.c"
>
</File>
<File
RelativePath="..\VAX\vax7x0_mba.c"
>
</File>
<File
RelativePath="..\VAX\vax_cis.c"
>
@ -455,10 +455,6 @@
RelativePath="..\VAX\vax_defs.h"
>
</File>
<File
RelativePath="..\VAX\vaxmod_defs.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"

View file

@ -3,6 +3,7 @@
# Modified By: Mark Pizzolato / mark@infocomm.com
# Norman Lastovica / norman.lastovica@oracle.com
# Camiel Vanderhoeven / camiel@camicom.com
# Matt Burke / scope.matthew@btinternet.com
#
# This MMS/MMK build script is used to compile the various simulators in
# the SIMH package for OpenVMS using DEC C v6.0-001(AXP), v6.5-001(AXP),
@ -41,6 +42,9 @@
# SWTP6800MP-A Just Build The SWTP6800MP-A.
# SWTP6800MP-A2 Just Build The SWTP6800MP-A2.
# VAX Just Build The DEC VAX.
# VAX610 Just Build The DEC VAX610 (MicroVAX I).
# VAX730 Just Build The DEC VAX730.
# VAX750 Just Build The DEC VAX750.
# VAX780 Just Build The DEC VAX780.
# CLEAN Will Clean Files Back To Base Kit.
#
@ -598,7 +602,7 @@ SWTP6800MP_A2_SOURCE = $(SWTP6800MP_A2_COMMON)mp-a2.c,$(SWTP6800MP_A2_COMMON)m68
SWTP6800MP_A2_OPTIONS = /INCL=($(SIMH_DIR),$(SWTP6800MP_A2_DIR))/DEF=($(CC_DEFS))
#
# Digital Equipment VAX Simulator Definitions.
# Digital Equipment VAX 3900 Simulator Definitions.
#
VAX_DIR = SYS$DISK:[.VAX]
VAX_LIB1 = $(LIB_DIR)VAXL1-$(ARCH).OLB
@ -626,6 +630,93 @@ VAX_OPTIONS = /INCL=($(SIMH_DIR),$(VAX_DIR),$(PDP11_DIR)$(PCAP_INC))\
VAX_SIMH_LIB = $(SIMH_LIB)
.ENDIF
# Digital Equipment VAX610 (MicroVAX I) Simulator Definitions.
#
VAX610_DIR = SYS$DISK:[.VAX]
VAX610_LIB1 = $(LIB_DIR)VAX610L1-$(ARCH).OLB
VAX610_SOURCE1 = $(VAX610_DIR)VAX_CPU.C,$(VAX610_DIR)VAX_CPU1.C,\
$(VAX610_DIR)VAX_FPA.C,$(VAX610_DIR)VAX_CIS.C,\
$(VAX610_DIR)VAX_OCTA.C,$(VAX610_DIR)VAX_CMODE.C,\
$(VAX610_DIR)VAX_MMU.C,$(VAX610_DIR)VAX_SYS.C,\
$(VAX610_DIR)VAX_SYSCM.C,$(VAX610_DIR)VAX610_STDDEV.C,\
$(VAX610_DIR)VAX610_MEM.C,$(VAX610_DIR)VAX610_SYSDEV.C,\
$(VAX610_DIR)VAX610_IO.C,$(VAX610_DIR)VAX610_SYSLIST.C
VAX610_LIB2 = $(LIB_DIR)VAX610L2-$(ARCH).OLB
VAX610_SOURCE2 = $(PDP11_DIR)PDP11_IO_LIB.C,\
$(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_TQ.C,\
$(PDP11_DIR)PDP11_XQ.C,$(PDP11_DIR)PDP11_CR.C,\
$(PDP11_DIR)PDP11_RY.C,$(PDP11_DIR)PDP11_VH.C
.IFDEF ALPHA_OR_IA64
VAX610_OPTIONS = /INCL=($(SIMH_DIR),$(VAX610_DIR),$(PDP11_DIR)$(PCAP_INC))\
/DEF=($(CC_DEFS),"VM_VAX=1","USE_ADDR64=1","USE_INT64=1"$(PCAP_DEFS),"VAX_610=1")
VAX610_SIMH_LIB = $(SIMH_LIB64)
.ELSE
VAX610_OPTIONS = /INCL=($(SIMH_DIR),$(VAX610_DIR),$(PDP11_DIR)$(PCAP_INC))\
/DEF=($(CC_DEFS),"VM_VAX=1"$(PCAP_DEFS),"VAX_610=1")
VAX610_SIMH_LIB = $(SIMH_LIB)
.ENDIF
# Digital Equipment VAX730 Simulator Definitions.
#
VAX730_DIR = SYS$DISK:[.VAX]
VAX730_LIB1 = $(LIB_DIR)VAX730L1-$(ARCH).OLB
VAX730_SOURCE1 = $(VAX730_DIR)VAX_CPU.C,$(VAX730_DIR)VAX_CPU1.C,\
$(VAX730_DIR)VAX_FPA.C,$(VAX730_DIR)VAX_CIS.C,\
$(VAX730_DIR)VAX_OCTA.C,$(VAX730_DIR)VAX_CMODE.C,\
$(VAX730_DIR)VAX_MMU.C,$(VAX730_DIR)VAX_SYS.C,\
$(VAX730_DIR)VAX_SYSCM.C,$(VAX730_DIR)VAX730_STDDEV.C,\
$(VAX730_DIR)VAX730_SYS.C,$(VAX730_DIR)VAX730_MEM.C,\
$(VAX730_DIR)VAX730_UBA.C,$(VAX730_DIR)VAX730_RB.C,\
$(VAX730_DIR)VAX730_SYSLIST.C
VAX730_LIB2 = $(LIB_DIR)VAX730L2-$(ARCH).OLB
VAX730_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_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_IO_LIB.C
.IFDEF ALPHA_OR_IA64
VAX730_OPTIONS = /INCL=($(SIMH_DIR),$(VAX730_DIR),$(PDP11_DIR)$(PCAP_INC))\
/DEF=($(CC_DEFS),"VM_VAX=1","USE_ADDR64=1","USE_INT64=1"$(PCAP_DEFS),"VAX_730=1")
VAX730_SIMH_LIB = $(SIMH_LIB64)
.ELSE
VAX730_OPTIONS = /INCL=($(SIMH_DIR),$(VAX730_DIR),$(PDP11_DIR)$(PCAP_INC))\
/DEF=($(CC_DEFS),"VM_VAX=1"$(PCAP_DEFS),"VAX_730=1")
VAX730_SIMH_LIB = $(SIMH_LIB)
.ENDIF
# Digital Equipment VAX750 Simulator Definitions.
#
VAX750_DIR = SYS$DISK:[.VAX]
VAX750_LIB1 = $(LIB_DIR)VAX750L1-$(ARCH).OLB
VAX750_SOURCE1 = $(VAX750_DIR)VAX_CPU.C,$(VAX750_DIR)VAX_CPU1.C,\
$(VAX750_DIR)VAX_FPA.C,$(VAX750_DIR)VAX_CIS.C,\
$(VAX750_DIR)VAX_OCTA.C,$(VAX750_DIR)VAX_CMODE.C,\
$(VAX750_DIR)VAX_MMU.C,$(VAX750_DIR)VAX_SYS.C,\
$(VAX750_DIR)VAX_SYSCM.C,$(VAX750_DIR)VAX750_STDDEV.C,\
$(VAX750_DIR)VAX750_CMI.C,$(VAX750_DIR)VAX750_MEM.C,\
$(VAX750_DIR)VAX750_UBA.C,$(VAX750_DIR)VAX7X0_MBA.C,\
$(VAX750_DIR)VAX750_SYSLIST.C
VAX750_LIB2 = $(LIB_DIR)VAX750L2-$(ARCH).OLB
VAX750_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_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_RP.C,$(PDP11_DIR)PDP11_TU.C,\
$(PDP11_DIR)PDP11_IO_LIB.C
.IFDEF ALPHA_OR_IA64
VAX750_OPTIONS = /INCL=($(SIMH_DIR),$(VAX750_DIR),$(PDP11_DIR)$(PCAP_INC))\
/DEF=($(CC_DEFS),"VM_VAX=1","USE_ADDR64=1","USE_INT64=1"$(PCAP_DEFS),"VAX_750=1")
VAX750_SIMH_LIB = $(SIMH_LIB64)
.ELSE
VAX750_OPTIONS = /INCL=($(SIMH_DIR),$(VAX750_DIR),$(PDP11_DIR)$(PCAP_INC))\
/DEF=($(CC_DEFS),"VM_VAX=1"$(PCAP_DEFS),"VAX_750=1")
VAX750_SIMH_LIB = $(SIMH_LIB)
.ENDIF
# Digital Equipment VAX780 Simulator Definitions.
#
VAX780_DIR = SYS$DISK:[.VAX]
@ -636,7 +727,7 @@ VAX780_SOURCE1 = $(VAX780_DIR)VAX_CPU.C,$(VAX780_DIR)VAX_CPU1.C,\
$(VAX780_DIR)VAX_MMU.C,$(VAX780_DIR)VAX_SYS.C,\
$(VAX780_DIR)VAX_SYSCM.C,$(VAX780_DIR)VAX780_STDDEV.C,\
$(VAX780_DIR)VAX780_SBI.C,$(VAX780_DIR)VAX780_MEM.C,\
$(VAX780_DIR)VAX780_UBA.C,$(VAX780_DIR)VAX780_MBA.C,\
$(VAX780_DIR)VAX780_UBA.C,$(VAX780_DIR)VAX7X0_MBA.C,\
$(VAX780_DIR)VAX780_FLOAD.C,$(VAX780_DIR)VAX780_SYSLIST.C
VAX780_LIB2 = $(LIB_DIR)VAX780L2-$(ARCH).OLB
VAX780_SOURCE2 = $(PDP11_DIR)PDP11_RL.C,$(PDP11_DIR)PDP11_RQ.C,\
@ -672,16 +763,17 @@ I7094_OPTIONS = /INCL=($(SIMH_DIR),$(I7094_DIR))/DEF=($(CC_DEFS))
#
.IFDEF ALPHA_OR_IA64
ALL : ALTAIR ALTAIRZ80 ECLIPSE GRI LGP H316 HP2100 I1401 I1620 IBM1130 ID16 \
ID32 NOVA PDP1 PDP4 PDP7 PDP8 PDP9 PDP10 PDP11 PDP15 S3 VAX VAX780 SDS \
I7094 SWTP6800MP-A SWTP6800MP-A2
ID32 NOVA PDP1 PDP4 PDP7 PDP8 PDP9 PDP10 PDP11 PDP15 S3 \
VAX VAX610 VAX730 VAX750 VAX780 \
SDS I7094 SWTP6800MP-A SWTP6800MP-A2
$! No further actions necessary
.ELSE
#
# Else We Are On VAX And Build Everything EXCEPT the 64b simulators
#
ALL : ALTAIR ALTAIRZ80 GRI H316 HP2100 I1401 I1620 IBM1130 ID16 ID32 \
NOVA PDP1 PDP4 PDP7 PDP8 PDP9 PDP11 PDP15 S3 VAX VAX780 SDS SWTP6800MP-A \
SWTP6800MP-A2
NOVA PDP1 PDP4 PDP7 PDP8 PDP9 PDP11 PDP15 S3 \
VAX VAX510 VAX730 VAX750 VAX780 SDS SWTP6800MP-A SWTP6800MP-A2
$! No further actions necessary
.ENDIF
@ -1098,6 +1190,75 @@ $(VAX_LIB2) : $(VAX_SOURCE2)
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
$(VAX610_LIB1) : $(VAX610_SOURCE1)
$!
$! Building The $(VAX610_LIB1) Library.
$!
$ RUN/NODEBUG $(BIN_DIR)BuildROMs-$(ARCH).EXE
$ $(CC)$(VAX610_OPTIONS)/OBJ=$(VAX610_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;*
$(VAX610_LIB2) : $(VAX610_SOURCE2)
$!
$! Building The $(VAX610_LIB2) Library.
$!
$ $(CC)$(VAX610_OPTIONS)/OBJ=$(VAX610_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;*
$(VAX730_LIB1) : $(VAX730_SOURCE1)
$!
$! Building The $(VAX730_LIB1) Library.
$!
$ RUN/NODEBUG $(BIN_DIR)BuildROMs-$(ARCH).EXE
$ $(CC)$(VAX730_OPTIONS)/OBJ=$(VAX730_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;*
$(VAX730_LIB2) : $(VAX730_SOURCE2)
$!
$! Building The $(VAX730_LIB2) Library.
$!
$ $(CC)$(VAX730_OPTIONS)/OBJ=$(VAX730_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;*
$(VAX750_LIB1) : $(VAX750_SOURCE1)
$!
$! Building The $(VAX750_LIB1) Library.
$!
$ RUN/NODEBUG $(BIN_DIR)BuildROMs-$(ARCH).EXE
$ $(CC)$(VAX750_OPTIONS)/OBJ=$(VAX750_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;*
$(VAX750_LIB2) : $(VAX750_SOURCE2)
$!
$! Building The $(VAX750_LIB2) Library.
$!
$ $(CC)$(VAX750_OPTIONS)/OBJ=$(VAX750_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;*
$(VAX780_LIB1) : $(VAX780_SOURCE1)
$!
$! Building The $(VAX780_LIB1) Library.
@ -1501,6 +1662,51 @@ $(BIN_DIR)VAX-$(ARCH).EXE : $(SIMH_MAIN) $(VAX_SIMH_LIB) $(PCAP_LIBD) $(VAX_LIB1
$(VAX_SIMH_LIB)/LIBRARY$(PCAP_LIBR)
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
VAX610 : $(BIN_DIR)VAX610-$(ARCH).EXE
$! VAX610 done
$(BIN_DIR)VAX610-$(ARCH).EXE : $(SIMH_MAIN) $(VAX610_SIMH_LIB) $(PCAP_LIBD) $(VAX610_LIB1) $(VAX610_LIB2) $(PCAP_EXECLET)
$!
$! Building The $(BIN_DIR)VAX610-$(ARCH).EXE Simulator.
$!
$ $(CC)$(VAX610_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
$ LINK $(LINK_DEBUG)$(LINK_SECTION_BINDING)-
/EXE=$(BIN_DIR)VAX610-$(ARCH).EXE -
$(BLD_DIR)SCP.OBJ,-
$(VAX610_LIB1)/LIBRARY,$(VAX610_LIB2)/LIBRARY,-
$(VAX610_SIMH_LIB)/LIBRARY$(PCAP_LIBR)
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
VAX730 : $(BIN_DIR)VAX730-$(ARCH).EXE
$! VAX730 done
$(BIN_DIR)VAX730-$(ARCH).EXE : $(SIMH_MAIN) $(VAX730_SIMH_LIB) $(PCAP_LIBD) $(VAX730_LIB1) $(VAX730_LIB2) $(PCAP_EXECLET)
$!
$! Building The $(BIN_DIR)VAX730-$(ARCH).EXE Simulator.
$!
$ $(CC)$(VAX730_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
$ LINK $(LINK_DEBUG)$(LINK_SECTION_BINDING)-
/EXE=$(BIN_DIR)VAX730-$(ARCH).EXE -
$(BLD_DIR)SCP.OBJ,-
$(VAX730_LIB1)/LIBRARY,$(VAX730_LIB2)/LIBRARY,-
$(VAX730_SIMH_LIB)/LIBRARY$(PCAP_LIBR)
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
VAX750 : $(BIN_DIR)VAX750-$(ARCH).EXE
$! VAX750 done
$(BIN_DIR)VAX750-$(ARCH).EXE : $(SIMH_MAIN) $(VAX750_SIMH_LIB) $(PCAP_LIBD) $(VAX750_LIB1) $(VAX750_LIB2) $(PCAP_EXECLET)
$!
$! Building The $(BIN_DIR)VAX750-$(ARCH).EXE Simulator.
$!
$ $(CC)$(VAX750_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
$ LINK $(LINK_DEBUG)$(LINK_SECTION_BINDING)-
/EXE=$(BIN_DIR)VAX750-$(ARCH).EXE -
$(BLD_DIR)SCP.OBJ,-
$(VAX750_LIB1)/LIBRARY,$(VAX750_LIB2)/LIBRARY,-
$(VAX750_SIMH_LIB)/LIBRARY$(PCAP_LIBR)
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
VAX780 : $(BIN_DIR)VAX780-$(ARCH).EXE
$! VAX780 done

Binary file not shown.

Binary file not shown.

122
makefile
View file

@ -98,6 +98,14 @@ ifeq ($(WIN32),) #*nix Environments (&& cygwin)
ifeq (Darwin,$(OSTYPE))
OSNAME = OSX
LIBEXT = dylib
ifeq (incopt,$(shell if $(TEST) -d /opt/local/include; then echo incopt; fi))
INCPATH += /opt/local/include
OS_CCDEFS += -I/opt/local/include
endif
ifeq (libopt,$(shell if $(TEST) -d /opt/local/lib; then echo libopt; fi))
LIBPATH += /opt/local/lib
OS_LDFLAGS += -L/opt/local/lib
endif
# OSX's XCode gcc doesn't support LTO, but gcc built to explicitly enable it will work
ifneq (,$(GCC_VERSION))
ifeq (,$(shell $(GCC) -v /dev/null 2>&1 | grep '\-\-enable-lto'))
@ -226,7 +234,7 @@ ifeq ($(WIN32),) #*nix Environments (&& cygwin)
$(info *** Warning *** Some users have had problems using the www.tcpdump.org libpcap)
$(info *** Warning *** components for simh networking. For best results, with)
$(info *** Warning *** simh networking, it is recommended that you install the)
$(info *** Warning *** libpcap-dev package from your $(OSTYPE) distribution)
$(info *** Warning *** libpcap-dev package from your $(OSNAME) distribution)
$(info *** Warning ***)
endif
else
@ -236,10 +244,10 @@ ifeq ($(WIN32),) #*nix Environments (&& cygwin)
LIBEXT = $(LIBEXTSAVE)
endif
ifneq (,$(findstring USE_NETWORK,$(NETWORK_CCDEFS))$(findstring USE_SHARED,$(NETWORK_CCDEFS)))
# Given we have libpcap components, consider other network connections as well
# Given we have libpcap components, consider other network connections as well
ifneq (,$(call find_lib,vdeplug))
# libvdeplug requires the use of the OS provided libpcap
ifeq (,$(findstring usr/local,$(NETWORK_CCDEFS)))
ifeq (,$(findstring usr/local,$(NETWORK_CCDEFS)))
ifneq (,$(call find_include,libvdeplug))
# Provide support for vde networking
NETWORK_CCDEFS += -DUSE_VDE_NETWORK
@ -248,6 +256,23 @@ ifeq ($(WIN32),) #*nix Environments (&& cygwin)
endif
endif
endif
ifeq (,$(findstring USE_VDE_NETWORK,$(NETWORK_CCDEFS)))
# Support is available on Linux for libvdeplug. Advise on its usage
ifneq (,$(findstring Linux,$(OSTYPE)))
$(info *** Warning ***)
$(info *** Warning *** $(BUILD_SINGLE)Simulator$(BUILD_MULTIPLE) are being built with)
$(info *** Warning *** minimal libpcap networking support)
$(info *** Warning ***)
$(info *** Warning *** Simulators on your $(OSNAME) platform can also be built with)
$(info *** Warning *** extended Ethernet networking support by using VDE Ethernet.)
$(info *** Warning ***)
$(info *** Warning *** To build simulator(s) with extended networking support you)
$(info *** Warning *** should read 0readme_ethernet.txt and follow the instructions)
$(info *** Warning *** regarding the needed libvdeplug components for your $(OSNAME))
$(info *** Warning *** platform)
$(info *** Warning ***)
endif
endif
ifneq (,$(call find_include,linux/if_tun))
# Provide support for Tap networking on Linux
NETWORK_CCDEFS += -DUSE_TAP_NETWORK
@ -276,6 +301,7 @@ else
GCC = gcc
GCC_Path := $(dir $(shell where gcc.exe))
GCC_VERSION = $(word 3,$(shell $(GCC) --version))
COMPILER_NAME = GCC Version: $(GCC_VERSION)
LTO_EXCLUDE_VERSIONS = 4.5.2
ifeq (pthreads,$(shell if exist ..\windows-build\pthreads\Pre-built.2\include\pthread.h echo pthreads))
PTHREADS_CCDEFS = -DUSE_READER_THREAD -DPTW32_STATIC_LIB -I../windows-build/pthreads/Pre-built.2/include
@ -470,11 +496,61 @@ VAX = ${VAXD}/vax_cpu.c ${VAXD}/vax_cpu1.c ${VAXD}/vax_fpa.c ${VAXD}/vax_io.c \
VAX_OPT = -DVM_VAX -DUSE_INT64 -DUSE_ADDR64 -I ${VAXD} -I ${PDP11D} ${NETWORK_OPT}
VAX610 = ${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}/vax610_stddev.c ${VAXD}/vax610_sysdev.c \
${VAXD}/vax610_io.c ${VAXD}/vax610_syslist.c ${VAXD}/vax610_mem.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_xq.c ${PDP11D}/pdp11_ry.c ${PDP11D}/pdp11_vh.c \
${PDP11D}/pdp11_cr.c ${PDP11D}/pdp11_io_lib.c
VAX610_OPT = -DVM_VAX -DVAX_610 -DUSE_INT64 -DUSE_ADDR64 -I ${VAXD} -I ${PDP11D} ${NETWORK_OPT}
VAX630 = ${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}/vax630_stddev.c ${VAXD}/vax630_sysdev.c \
${VAXD}/vax630_io.c ${VAXD}/vax630_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_xq.c ${PDP11D}/pdp11_ry.c ${PDP11D}/pdp11_vh.c \
${PDP11D}/pdp11_cr.c ${PDP11D}/pdp11_io_lib.c
VAX620_OPT = -DVM_VAX -DVAX_620 -DUSE_INT64 -DUSE_ADDR64 -I ${VAXD} -I ${PDP11D} ${NETWORK_OPT}
VAX630_OPT = -DVM_VAX -DVAX_630 -DUSE_INT64 -DUSE_ADDR64 -I ${VAXD} -I ${PDP11D} ${NETWORK_OPT}
VAX730 = ${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}/vax730_stddev.c ${VAXD}/vax730_sys.c \
${VAXD}/vax730_mem.c ${VAXD}/vax730_uba.c ${VAXD}/vax730_rb.c \
${VAXD}/vax730_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_io_lib.c
VAX730_OPT = -DVM_VAX -DVAX_730 -DUSE_INT64 -DUSE_ADDR64 -I VAX -I ${PDP11D} ${NETWORK_OPT}
VAX750 = ${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}/vax750_stddev.c ${VAXD}/vax750_cmi.c \
${VAXD}/vax750_mem.c ${VAXD}/vax750_uba.c ${VAXD}/vax7x0_mba.c \
${VAXD}/vax750_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_rp.c ${PDP11D}/pdp11_tu.c \
${PDP11D}/pdp11_io_lib.c
VAX750_OPT = -DVM_VAX -DVAX_750 -DUSE_INT64 -DUSE_ADDR64 -I VAX -I ${PDP11D} ${NETWORK_OPT}
VAX780 = ${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}/vax780_stddev.c ${VAXD}/vax780_sbi.c \
${VAXD}/vax780_mem.c ${VAXD}/vax780_uba.c ${VAXD}/vax780_mba.c \
${VAXD}/vax780_mem.c ${VAXD}/vax780_uba.c ${VAXD}/vax7x0_mba.c \
${VAXD}/vax780_fload.c ${VAXD}/vax780_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 \
@ -656,10 +732,10 @@ TX0_OPT = -I ${TX0D} $(DISPLAY_OPT)
# Build everything
#
ALL = pdp1 pdp4 pdp7 pdp8 pdp9 pdp15 pdp11 pdp10 \
vax vax780 nova eclipse hp2100 i1401 i1620 s3 \
altair altairz80 gri i7094 ibm1130 id16 \
id32 sds lgp h316 swtp6800mp-a swtp6800mp-a2 \
tx-0
vax vax610 vax620 vax630 vax730 vax750 vax780 \
nova eclipse hp2100 i1401 i1620 s3 altair altairz80 gri \
i7094 ibm1130 id16 id32 sds lgp h316 \
swtp6800mp-a swtp6800mp-a2 tx-0
all : ${ALL}
@ -746,6 +822,36 @@ ${BIN}vax${EXE} : ${VAX} ${SIM} ${BUILD_ROMS}
${MKDIRBIN}
${CC} ${VAX} ${SIM} ${VAX_OPT} $(CC_OUTSPEC) ${LDFLAGS}
vax610 : ${BIN}vax610${EXE}
${BIN}vax610${EXE} : ${VAX610} ${SIM} ${BUILD_ROMS}
${MKDIRBIN}
${CC} ${VAX610} ${SIM} ${VAX610_OPT} -o $@ ${LDFLAGS}
vax620 : ${BIN}vax620${EXE}
${BIN}vax620${EXE} : ${VAX630} ${SIM} ${BUILD_ROMS}
${MKDIRBIN}
${CC} ${VAX630} ${SIM} ${VAX620_OPT} -o $@ ${LDFLAGS}
vax630 : ${BIN}vax630${EXE}
${BIN}vax630${EXE} : ${VAX630} ${SIM} ${BUILD_ROMS}
${MKDIRBIN}
${CC} ${VAX630} ${SIM} ${VAX630_OPT} -o $@ ${LDFLAGS}
vax730 : ${BIN}vax730${EXE}
${BIN}vax730${EXE} : ${VAX730} ${SIM} ${BUILD_ROMS}
${MKDIRBIN}
${CC} ${VAX730} ${SIM} ${VAX730_OPT} -o $@ ${LDFLAGS}
vax750 : ${BIN}vax750${EXE}
${BIN}vax750${EXE} : ${VAX750} ${SIM} ${BUILD_ROMS}
${MKDIRBIN}
${CC} ${VAX750} ${SIM} ${VAX750_OPT} -o $@ ${LDFLAGS}
vax780 : ${BIN}vax780${EXE}
${BIN}vax780${EXE} : ${VAX780} ${SIM} ${BUILD_ROMS}

212
scp.c
View file

@ -411,7 +411,7 @@ t_stat ex_addr (FILE *ofile, int32 flag, t_addr addr, DEVICE *dptr, UNIT *uptr);
t_stat dep_addr (int32 flag, char *cptr, t_addr addr, DEVICE *dptr,
UNIT *uptr, int32 dfltinc);
t_stat step_svc (UNIT *ptr);
void sub_args (char *instr, char *tmpbuf, int32 maxstr, char *do_arg[]);
void sub_args (char *instr, size_t instr_size, char *do_arg[]);
t_stat shift_args (char *do_arg[], size_t arg_count);
t_stat set_on (int32 flag, char *cptr);
t_stat set_verify (int32 flag, char *cptr);
@ -420,7 +420,7 @@ t_stat set_quiet (int32 flag, char *cptr);
t_stat set_asynch (int32 flag, char *cptr);
t_stat do_cmd_label (int32 flag, char *cptr, char *label);
void int_handler (int signal);
void run_cmd_message (const char *unechod_cmdline, t_stat r);
t_stat set_prompt (int32 flag, char *cptr);
/* Global data */
@ -455,6 +455,7 @@ FILE *sim_log = NULL; /* log file */
FILEREF *sim_log_ref = NULL; /* log file file reference */
FILE *sim_deb = NULL; /* debug file */
FILEREF *sim_deb_ref = NULL; /* debug file file reference */
char *sim_prompt = NULL; /* prompt string */
static FILE *sim_gotofile; /* the currently open do file */
static int32 sim_goto_line[MAX_DO_NEST_LVL+1]; /* the current line number in the currently open do file */
static int32 sim_do_echo = 0; /* the echo status of the currently open do file */
@ -672,6 +673,7 @@ static CTAB cmd_table[] = {
"set nomessage disables display of command file error messages\n"
"set quiet disables suppression of some output and messages\n"
"set noquiet re-enables suppression of some output and messages\n"
"set prompt \"string\" sets an alternate simulator prompt string\n"
"set <dev> OCT|DEC|HEX set device display radix\n"
"set <dev> ENABLED enable device\n"
"set <dev> DISABLED disable device\n"
@ -757,7 +759,7 @@ int setenv(const char *envname, const char *envval, int overwrite)
int main (int argc, char *argv[])
{
char cbuf[CBUFSIZE], gbuf[CBUFSIZE], *cptr, *cptr2;
char cbuf[4*CBUFSIZE], gbuf[CBUFSIZE], *cptr, *cptr2;
char nbuf[PATH_MAX + 7];
int32 i, sw;
t_bool lookswitch;
@ -768,6 +770,7 @@ CTAB *cmdp;
argc = ccommand (&argv);
#endif
set_prompt (0, "sim>"); /* start with set standard prompt */
*cbuf = 0; /* init arg buffer */
sim_switches = 0; /* init switches */
lookswitch = TRUE;
@ -782,7 +785,7 @@ for (i = 1; i < argc; i++) { /* loop thru args */
sim_switches = sim_switches | sw;
}
else {
if ((strlen (argv[i]) + strlen (cbuf) + 3) >= CBUFSIZE) {
if ((strlen (argv[i]) + strlen (cbuf) + 3) >= sizeof(cbuf)) {
fprintf (stderr, "Argument string too long\n");
return 0;
}
@ -865,21 +868,21 @@ else if (*argv[0]) { /* sim name arg? */
stat = SCPE_BARE_STATUS(stat); /* remove possible flag */
while (stat != SCPE_EXIT) { /* in case exit */
if ((cptr = sim_brk_getact (cbuf, CBUFSIZE))) /* pending action? */
printf ("sim> %s\n", cptr); /* echo */
if ((cptr = sim_brk_getact (cbuf, sizeof(cbuf)))) /* pending action? */
printf ("%s%s\n", sim_prompt, cptr); /* echo */
else if (sim_vm_read != NULL) { /* sim routine? */
printf ("sim> "); /* prompt */
cptr = (*sim_vm_read) (cbuf, CBUFSIZE, stdin);
printf ("%s", sim_prompt); /* prompt */
cptr = (*sim_vm_read) (cbuf, sizeof(cbuf), stdin);
}
else cptr = read_line_p ("sim> ", cbuf, CBUFSIZE, stdin);/* read with prmopt*/
else cptr = read_line_p (sim_prompt, cbuf, sizeof(cbuf), stdin);/* read with prmopt*/
if (cptr == NULL) /* EOF? */
if (sim_ttisatty()) continue; /* ignore tty EOF */
else break; /* otherwise exit */
if (*cptr == 0) /* ignore blank */
continue;
sub_args (cbuf, gbuf, sizeof(gbuf), argv);
sub_args (cbuf, sizeof(cbuf), argv);
if (sim_log) /* log cmd */
fprintf (sim_log, "sim> %s\n", cptr);
fprintf (sim_log, "%s%s\n", sim_prompt, cptr);
cptr = get_glyph (cptr, gbuf, 0); /* get command glyph */
sim_switches = 0; /* init switches */
if ((cmdp = find_cmd (gbuf))) /* lookup command */
@ -889,15 +892,15 @@ while (stat != SCPE_EXIT) { /* in case exit */
stat_nomessage = stat_nomessage || (!sim_show_message);/* Apply global suppression */
stat = SCPE_BARE_STATUS(stat); /* remove possible flag */
sim_last_cmd_stat = stat; /* save command error status */
if ((stat >= SCPE_BASE) && (!stat_nomessage)) { /* error? */
if (cmdp && cmdp->message) /* special message handler? */
cmdp->message (NULL, stat);
else {
printf ("%s\n", sim_error_text (stat));
if (sim_log)
fprintf (sim_log, "%s\n", sim_error_text (stat));
}
}
if (!stat_nomessage) /* displaying message status? */
if (cmdp && (cmdp->message)) /* special message handler? */
cmdp->message (NULL, stat); /* let it deal with display */
else
if (stat >= SCPE_BASE) { /* error? */
printf ("%s\n", sim_error_text (stat));
if (sim_log)
fprintf (sim_log, "%s\n", sim_error_text (stat));
}
if (sim_vm_post != NULL)
(*sim_vm_post) (TRUE);
} /* end while */
@ -911,6 +914,28 @@ AIO_CLEANUP; /* Asynch I/O */
return 0;
}
/* Set prompt routine */
t_stat set_prompt (int32 flag, char *cptr)
{
char gbuf[CBUFSIZE];
if ((!cptr) || (*cptr == '\0'))
return SCPE_ARG;
cptr = get_glyph_nc (cptr, gbuf, '"'); /* get quote delimted token */
if (gbuf[0] == '\0') { /* Token started with quote */
gbuf[sizeof (gbuf)-1] = '\0';
strncpy (gbuf, cptr, sizeof (gbuf)-1);
cptr = strchr (gbuf, '"');
if (cptr)
*cptr = '\0';
}
sim_prompt = realloc (sim_prompt, strlen (gbuf) + 2); /* nul terminator and trailing blank */
sprintf (sim_prompt, "%s ", gbuf);
return SCPE_OK;
}
/* Find command routine */
CTAB *find_cmd (char *gbuf)
@ -1048,7 +1073,7 @@ return cbuf;
t_stat do_cmd_label (int32 flag, char *fcptr, char *label)
{
char *cptr, cbuf[CBUFSIZE], gbuf[CBUFSIZE], *c, quote, *do_arg[10];
char *cptr, cbuf[4*CBUFSIZE], gbuf[CBUFSIZE], *c, quote, *do_arg[10];
FILE *fpin;
CTAB *cmdp = NULL;
int32 echo, nargs, errabort, i;
@ -1139,12 +1164,12 @@ if (errabort) /* -e flag? */
set_on (1, NULL); /* equivalent to ON ERROR RETURN */
do {
ocptr = cptr = sim_brk_getact (cbuf, CBUFSIZE); /* get bkpt action */
ocptr = cptr = sim_brk_getact (cbuf, sizeof(cbuf)); /* get bkpt action */
if (!ocptr) { /* no pending action? */
ocptr = cptr = read_line (cbuf, CBUFSIZE, fpin); /* get cmd line */
ocptr = cptr = read_line (cbuf, sizeof(cbuf), fpin);/* get cmd line */
sim_goto_line[sim_do_depth] += 1;
}
sub_args (cbuf, gbuf, sizeof(gbuf), do_arg); /* substitute args */
sub_args (cbuf, sizeof(cbuf), do_arg); /* substitute args */
if (cptr == NULL) { /* EOF? */
stat = SCPE_OK; /* set good return */
break;
@ -1211,15 +1236,15 @@ do {
fprintf (sim_log, "%s> %s\n", do_position(), ocptr);
}
}
if ((stat >= SCPE_BASE) && !stat_nomessage) { /* report error if not suppressed */
if (cmdp && cmdp->message) { /* special message handler */
if (!stat_nomessage) { /* report error if not suppressed */
if (cmdp && cmdp->message) /* special message handler */
cmdp->message ((!echo && !sim_quiet) ? ocptr : NULL, stat);
}
else {
printf ("%s\n", sim_error_text (stat));
if (sim_log)
fprintf (sim_log, "%s\n", sim_error_text (stat));
}
else
if (stat >= SCPE_BASE) { /* report error if not suppressed */
printf ("%s\n", sim_error_text (stat));
if (sim_log)
fprintf (sim_log, "%s\n", sim_error_text (stat));
}
}
if (staying &&
(sim_on_check[sim_do_depth]) &&
@ -1266,8 +1291,7 @@ return stat | SCPE_NOMESSAGE; /* suppress message sinc
Calling sequence
instr = input string
tmpbuf = temp buffer
maxstr = min (len (instr), len (tmpbuf))
instr_size = sizeof input string buffer
do_arg[10] = arguments
Token "%0" expands to the command file name.
@ -1301,13 +1325,16 @@ return stat | SCPE_NOMESSAGE; /* suppress message sinc
untouched.
*/
void sub_args (char *instr, char *tmpbuf, int32 maxstr, char *do_arg[])
void sub_args (char *instr, size_t instr_size, char *do_arg[])
{
char gbuf[CBUFSIZE];
char *ip = instr, *op = tmpbuf, *ap, *oend = tmpbuf + maxstr - 2, *istart;
char *ip = instr, *op, *ap, *oend, *istart, *tmpbuf;
char rbuf[CBUFSIZE];
int i;
tmpbuf = malloc(instr_size);
op = tmpbuf;
oend = tmpbuf + instr_size - 2;
while (isspace (*ip)) /* skip leading spaces */
*op++ = *ip++;
istart = ip;
@ -1425,6 +1452,7 @@ for (; *ip && (op < oend); ) {
}
*op = 0; /* term buffer */
strcpy (instr, tmpbuf);
free (tmpbuf);
return;
}
@ -1508,7 +1536,7 @@ rewind(sim_gotofile); /* start search for labe
sim_goto_line[sim_do_depth] = 0; /* reset line number */
sim_do_echo = 0; /* Don't echo while searching for label */
while (1) {
cptr = read_line (cbuf, CBUFSIZE, sim_gotofile); /* get cmd line */
cptr = read_line (cbuf, sizeof(cbuf), sim_gotofile);/* get cmd line */
if (cptr == NULL) break; /* exit on eof */
sim_goto_line[sim_do_depth] += 1; /* record line number */
if (*cptr == 0) continue; /* ignore blank */
@ -1787,6 +1815,7 @@ static CTAB set_glob_tab[] = {
{ "NOMESSAGE", &set_message, 0 },
{ "QUIET", &set_quiet, 1 },
{ "NOQUIET", &set_quiet, 0 },
{ "PROMPT", &set_prompt, 0 },
{ NULL, NULL, 0 }
};
@ -3115,7 +3144,7 @@ for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru devices */
WRITE_I (dptr->flags); /* [V2.10] flags */
for (j = 0; j < dptr->numunits; j++) {
uptr = dptr->units + j;
t = sim_is_active (uptr);
t = sim_activate_time (uptr);
WRITE_I (j); /* unit number */
WRITE_I (t); /* activation time */
WRITE_I (uptr->u3); /* unit specific */
@ -3234,7 +3263,7 @@ REG *rptr;
struct stat rstat;
t_bool force_restore = sim_switches & SWMASK ('F');
#define READ_S(xx) if (read_line ((xx), CBUFSIZE, rfile) == NULL) \
#define READ_S(xx) if (read_line ((xx), sizeof(xx), rfile) == NULL) \
return SCPE_IOERR;
#define READ_I(xx) if (sim_fread (&xx, sizeof (xx), 1, rfile) == 0) \
return SCPE_IOERR;
@ -4026,7 +4055,7 @@ if ((cptr == NULL) || (rptr == NULL))
if (rptr->flags & REG_RO)
return SCPE_RO;
if (flag & EX_I) {
cptr = read_line (gbuf, CBUFSIZE, stdin);
cptr = read_line (gbuf, sizeof(gbuf), stdin);
if (sim_log)
fprintf (sim_log, "%s\n", cptr? cptr: "");
if (cptr == NULL) /* force exit */
@ -4244,7 +4273,7 @@ char gbuf[CBUFSIZE];
if (dptr == NULL)
return SCPE_IERR;
if (flag & EX_I) {
cptr = read_line (gbuf, CBUFSIZE, stdin);
cptr = read_line (gbuf, sizeof(gbuf), stdin);
if (sim_log)
fprintf (sim_log, "%s\n", cptr? cptr: "");
if (cptr == NULL) /* force exit */
@ -4516,7 +4545,7 @@ t_stat get_yn (char *ques, t_stat deflt)
char cbuf[CBUFSIZE], *cptr;
printf ("%s ", ques);
cptr = read_line (cbuf, CBUFSIZE, stdin);
cptr = read_line (cbuf, sizeof(cbuf), stdin);
if ((cptr == NULL) || (*cptr == 0))
return deflt;
if ((*cptr == 'Y') || (*cptr == 'y'))
@ -4626,7 +4655,7 @@ t_stat r;
if ((cptr == NULL) || (*cptr == 0))
return SCPE_ARG;
strncpy (gbuf, cptr, CBUFSIZE);
strncpy (gbuf, cptr, sizeof(gbuf));
addrp = gbuf; /* default addr */
if ((portp = strchr (gbuf, ':'))) /* x:y? split */
*portp++ = 0;
@ -5192,6 +5221,7 @@ return SCPE_OK;
sim_cancel remove entry from event queue
sim_process_event process entries on event queue
sim_is_active see if entry is on event queue
sim_activate_time return time until activation
sim_atime return absolute time for an entry
sim_gtime return global time
sim_qcount return event queue entry count
@ -5328,7 +5358,6 @@ uint32 rtimenow, urtime = (uint32)rtime;
AIO_ACTIVATE (sim_activate_notbefore, uptr, rtime);
sim_cancel (uptr);
rtimenow = sim_grtime();
sim_cancel (uptr);
if (0x80000000 <= urtime-rtimenow)
return sim_activate (uptr, 0);
else
@ -5349,9 +5378,13 @@ t_stat sim_cancel (UNIT *uptr)
UNIT *cptr, *nptr;
AIO_VALIDATE;
AIO_CANCEL(uptr);
AIO_UPDATE_QUEUE;
if (sim_clock_queue == NULL)
return SCPE_OK;
UPDATE_SIM_TIME (sim_clock_queue->time); /* update sim time */
if (!sim_is_active (uptr))
return SCPE_OK;
nptr = NULL;
if (sim_clock_queue == uptr)
nptr = sim_clock_queue = uptr->next;
@ -5373,7 +5406,7 @@ else sim_interval = noqueue_time = NOQUEUE_WAIT;
return SCPE_OK;
}
/* sim_is_active - test for entry in queue, return activation time
/* sim_is_active - test for entry in queue
Inputs:
uptr = pointer to unit
@ -5381,7 +5414,50 @@ return SCPE_OK;
result = absolute activation time + 1, 0 if inactive
*/
int32 sim_is_active (UNIT *uptr)
t_bool sim_is_active (UNIT *uptr)
{
UNIT *cptr;
int32 accum;
AIO_VALIDATE;
AIO_UPDATE_QUEUE;
accum = 0;
for (cptr = sim_clock_queue; cptr != NULL; cptr = cptr->next) {
if (cptr == sim_clock_queue) {
if (sim_interval > 0)
accum = accum + sim_interval;
}
else accum = accum + cptr->time;
if (cptr == uptr)
return accum + 1;
}
return 0;
}
/* sim_is_active_bool - test for entry in queue
Inputs:
uptr = pointer to unit
Outputs:
result = TRUE if unit is busy, FALSE inactive
*/
t_bool sim_is_active_bool (UNIT *uptr)
{
AIO_VALIDATE;
AIO_UPDATE_QUEUE;
return (((uptr->next) || AIO_IS_ACTIVE(uptr)) ? TRUE : FALSE);
}
/* sim_activate_time - return activation time
Inputs:
uptr = pointer to unit
Outputs:
result = absolute activation time + 1, 0 if inactive
*/
int32 sim_activate_time (UNIT *uptr)
{
UNIT *cptr;
int32 accum;
@ -5834,19 +5910,49 @@ if (!debug_unterm) {
}
/* Prints state of a register: bit translation + state (0,1,_,^)
indicating the state and transition of the bit. States:
indicating the state and transition of the bit and bitfields. States:
0=steady(0->0), 1=steady(1->1), _=falling(1->0), ^=rising(0->1) */
void sim_debug_u16(uint32 dbits, DEVICE* dptr, const char* const* bitdefs,
uint16 before, uint16 after, int terminate)
void sim_debug_bits(uint32 dbits, DEVICE* dptr, BITFIELD* bitdefs,
uint32 before, uint32 after, int terminate)
{
if (sim_deb && (dptr->dctrl & dbits)) {
int32 i;
int32 i, fields, offset;
uint32 value, beforevalue, mask;
for (fields=offset=0; bitdefs[fields].name; ++fields) {
if (bitdefs[fields].offset == -1) /* fixup uninitialized offsets */
bitdefs[fields].offset = offset;
offset += bitdefs[fields].width;
}
sim_debug_prefix(dbits, dptr); /* print prefix if required */
for (i = 15; i >= 0; i--) { /* print xlation, transition */
int off = ((after >> i) & 1) + (((before ^ after) >> i) & 1) * 2;
fprintf(sim_deb, "%s%c ", bitdefs[i], debug_bstates[off]);
for (i = fields-1; i >= 0; i--) { /* print xlation, transition */
if (bitdefs[i].name[0] == '\0')
continue;
if ((bitdefs[i].width == 1) && (bitdefs[i].valuenames == NULL)) {
int off = ((after >> bitdefs[i].offset) & 1) + (((before ^ after) >> bitdefs[i].offset) & 1) * 2;
fprintf(sim_deb, "%s%c ", bitdefs[i].name, debug_bstates[off]);
}
else {
char *delta = "";
mask = 0xFFFFFFFF >> (32-bitdefs[i].width);
value = ((after >> bitdefs[i].offset) & mask);
beforevalue = ((before >> bitdefs[i].offset) & mask);
if (value < beforevalue)
delta = "_";
if (value > beforevalue)
delta = "^";
if (bitdefs[i].valuenames)
fprintf(sim_deb, "%s=%s%s ", bitdefs[i].name, delta, bitdefs[i].valuenames[value]);
else
if (bitdefs[i].format) {
fprintf(sim_deb, "%s=%s", bitdefs[i].name, delta);
fprintf(sim_deb, bitdefs[i].format, value);
}
else
fprintf(sim_deb, "%s=%s0x%X ", bitdefs[i].name, delta, value);
}
}
if (terminate)
fprintf(sim_deb, "\r\n");

8
scp.h
View file

@ -59,6 +59,7 @@ t_stat exdep_cmd (int32 flag, char *ptr);
t_stat eval_cmd (int32 flag, char *ptr);
t_stat load_cmd (int32 flag, char *ptr);
t_stat run_cmd (int32 flag, char *ptr);
void run_cmd_message (const char *unechod_cmdline, t_stat r);
t_stat attach_cmd (int32 flag, char *ptr);
t_stat detach_cmd (int32 flag, char *ptr);
t_stat assign_cmd (int32 flag, char *ptr);
@ -88,7 +89,8 @@ t_stat sim_activate (UNIT *uptr, int32 interval);
t_stat sim_activate_abs (UNIT *uptr, int32 interval);
t_stat sim_activate_notbefore (UNIT *uptr, int32 rtime);
t_stat sim_cancel (UNIT *uptr);
int32 sim_is_active (UNIT *uptr);
t_bool sim_is_active (UNIT *uptr);
int32 sim_activate_time (UNIT *uptr);
double sim_gtime (void);
uint32 sim_grtime (void);
int32 sim_qcount (void);
@ -124,8 +126,8 @@ char *match_ext (char *fnam, char *ext);
const char *sim_error_text (t_stat stat);
t_stat sim_string_to_stat (char *cptr, t_stat *cond);
t_stat sim_cancel_step (void);
void sim_debug_u16 (uint32 dbits, DEVICE* dptr, const char* const* bitdefs,
uint16 before, uint16 after, int terminate);
void sim_debug_bits (uint32 dbits, DEVICE* dptr, BITFIELD* bitdefs,
uint32 before, uint32 after, int terminate);
#if defined (__DECC) && defined (__VMS) && (defined (__VAX) || (__DECC_VER < 60590001))
#define CANT_USE_MACRO_VA_ARGS 1
#endif

View file

@ -278,7 +278,7 @@ t_mtrlnt tbc;
t_stat r;
if (cmd == MCM_INIT) { /* init state */
if ((t = sim_is_active (uptr + MT_REW)) != 0) { /* rewinding? */
if ((t = sim_activate_time (uptr + MT_REW)) != 0) { /* rewinding? */
sim_activate (uptr, t); /* retry later */
return SCPE_OK;
}

View file

@ -40,7 +40,10 @@
struct ROM_File_Descriptor {
char *BinaryName; char *IncludeFileName; size_t expected_size; unsigned int checksum; char *ArrayName;} ROMs[] = {
{"VAX/ka655x.bin", "VAX/vax_ka655x_bin.h", 131072, 0xFF7673B6, "vax_ka655x_bin"},
{"VAX/vmb.exe", "VAX/vax780_vmb_exe.h", 44544, 0xFFC014CC, "vax780_vmb_exe"},
{"VAX/ka620.bin", "VAX/vax_ka620_bin.h", 65536, 0xFF7F930F, "vax_ka620_bin"},
{"VAX/ka630.bin", "VAX/vax_ka630_bin.h", 65536, 0xFF7F73EF, "vax_ka630_bin"},
{"VAX/ka610.bin", "VAX/vax_ka610_bin.h", 16384, 0xFFEF3312, "vax_ka610_bin"},
{"VAX/vmb.exe", "VAX/vax_vmb_exe.h", 44544, 0xFFC014CC, "vax_vmb_exe"},
};
@ -61,13 +64,17 @@ int sim_read_ROM_include(const char *include_filename,
int *psize,
unsigned char **pROMData,
unsigned int *pchecksum,
char **prom_array_name)
char **prom_array_name,
int *defines_found)
{
FILE *iFile;
char line[256];
size_t i;
size_t bytes_written = 0;
size_t allocated_size = 0;
int define_size_found = 0;
int define_filename_found = 0;
int define_array_found = 0;
*psize = 0;
*pchecksum = 0;
@ -84,6 +91,13 @@ while (fgets (line, sizeof(line)-1, iFile)) {
switch (line[0]) {
case '#':
if (0 == strncmp ("#define BOOT_CODE_SIZE ", line, 23))
define_size_found = 1;
if (0 == strncmp ("#define BOOT_CODE_FILENAME ", line, 27))
define_filename_found = 1;
if (0 == strncmp ("#define BOOT_CODE_ARRAY ", line, 24))
define_array_found = 1;
break;
case ' ':
case '/':
case '*':
@ -117,6 +131,7 @@ for (i=0; i<bytes_written; ++i)
*pchecksum += *(*pROMData + i);
*pchecksum = ~*pchecksum;
*psize = bytes_written;
*defines_found = (3 == (define_size_found + define_filename_found + define_array_found));
return 0;
}
@ -151,14 +166,21 @@ fclose (rFile);
for (i=0; i<statb.st_size; ++i)
checksum += ROMData[i];
checksum = ~checksum;
sprintf (include_filename, "%s.h", rom_filename);
if ((c = strchr (include_filename, '.')))
*c = '_';
if (!(c = strchr (rom_filename, '/')))
c = strchr (rom_filename, '/');
strcpy (array_name, c);
while ((c = strchr (rom_filename, '\\')))
*c = '/';
strcpy (array_name, rom_filename);
for (c=array_name; *c; ++c)
if (isupper(*c))
*c = tolower(*c);
if ((c = strchr (array_name, '.')))
*c = '_';
if ((c = strchr (array_name, '/')))
*c = '_';
sprintf (include_filename, "%s.h", rom_filename);
if ((c = strrchr (include_filename, '/')))
sprintf (c+1, "%s.h", array_name);
else
sprintf (include_filename, "%s.h", array_name);
printf ("The ROMs array entry for this new ROM image file should look something like:\n");
printf ("{\"%s\", \"%s\", %d, 0x%08X, \"%s\"}\n",
rom_filename, include_filename, (int)(statb.st_size), checksum, array_name);
@ -178,11 +200,13 @@ int bytes_written = 0;
int include_bytes;
int c;
struct stat statb;
const char *load_filename;
unsigned char *ROMData = NULL;
unsigned char *include_ROMData = NULL;
char *include_array_name = NULL;
unsigned int checksum = 0;
unsigned int include_checksum;
int defines_found;
if (NULL == (rFile = fopen (rom_filename, "rb"))) {
printf ("Error Opening ROM binary file '%s' for input: %s\n", rom_filename, strerror(errno));
@ -190,11 +214,13 @@ if (NULL == (rFile = fopen (rom_filename, "rb"))) {
&include_bytes,
&include_ROMData,
&include_checksum,
&include_array_name))
&include_array_name,
&defines_found))
return -1;
c = ((include_checksum == expected_checksum) &&
(include_bytes == expected_size) &&
(0 == strcmp(include_array_name, rom_array_name)));
(0 == strcmp(include_array_name, rom_array_name)) &&
defines_found);
free(include_ROMData);
free(include_array_name);
if (!c)
@ -243,11 +269,13 @@ if (0 == sim_read_ROM_include(include_filename,
&include_bytes,
&include_ROMData,
&include_checksum,
&include_array_name)) {
&include_array_name,
&defines_found)) {
c = ((include_checksum == expected_checksum) &&
(include_bytes == expected_size) &&
(0 == strcmp (include_array_name, rom_array_name)) &&
(0 == memcmp (include_ROMData, ROMData, include_bytes)));
(0 == memcmp (include_ROMData, ROMData, include_bytes)) &&
defines_found);
free(include_ROMData);
free(include_array_name);
if (c) {
@ -260,6 +288,11 @@ if (NULL == (iFile = fopen (include_filename, "w"))) {
printf ("Error Opening '%s' for output: %s\n", include_filename, strerror(errno));
return -1;
}
load_filename = strrchr (rom_filename, '/');
if (load_filename)
++load_filename;
else
load_filename = rom_filename;
time (&now);
fprintf (iFile, "#ifndef ROM_%s_H\n", rom_array_name);
fprintf (iFile, "#define ROM_%s_H 0\n", rom_array_name);
@ -269,6 +302,9 @@ fprintf (iFile, " from %s which was last modified at %s", rom_filename, ctime(
fprintf (iFile, " file size: %d (0x%X) - checksum: 0x%08X\n", (int)statb.st_size, (int)statb.st_size, checksum);
fprintf (iFile, " This file is a generated file and should NOT be edited or changed by hand.\n");
fprintf (iFile, "*/\n");
fprintf (iFile, "#define BOOT_CODE_SIZE 0x%X\n", (int)statb.st_size);
fprintf (iFile, "#define BOOT_CODE_FILENAME \"%s\"\n", load_filename);
fprintf (iFile, "#define BOOT_CODE_ARRAY %s\n", rom_array_name);
fprintf (iFile, "unsigned char %s[] = {", rom_array_name);
for (bytes_written=0;bytes_written<statb.st_size; ++bytes_written) {
c = ROMData[bytes_written];

View file

@ -368,6 +368,8 @@ struct sim_unit {
void *up8; /* device specific */
#ifdef SIM_ASYNCH_IO
void (*a_check_completion)(struct sim_unit *);
t_bool (*a_is_active)(struct sim_unit *);
void (*a_cancel)(struct sim_unit *);
struct sim_unit *a_next; /* next asynch active */
int32 a_event_time;
t_stat (*a_activate_call)(struct sim_unit *, int32);
@ -506,6 +508,14 @@ struct sim_debtab {
#define DEBUG_PRI(d,m) (sim_deb && (d.dctrl & (m)))
#define DEBUG_PRJ(d,m) (sim_deb && (d->dctrl & (m)))
struct sim_bitfield {
char *name; /* field name */
uint32 offset; /* starting bit */
uint32 width; /* width */
const char **valuenames; /* map of values to strings */
const char *format; /* value format string */
};
/* File Reference */
struct sim_fileref {
char name[CBUFSIZE]; /* file name */
@ -526,6 +536,12 @@ struct sim_fileref {
#define BRDATA(nm,loc,rdx,wd,dep) #nm, (loc), (rdx), (wd), 0, (dep)
#define URDATA(nm,loc,rdx,wd,off,dep,fl) \
#nm, &(loc), (rdx), (wd), (off), (dep), ((fl) | REG_UNIT)
#define BIT(nm) {#nm, -1, 1} /* Single Bit definition */
#define BITNC {"", -1, 1} /* Don't care Bit definition */
#define BITF(nm,sz) {#nm, -1, sz} /* Bit Field definition */
#define BITNCF(sz) {"", -1, sz} /* Don't care Bit Field definition */
#define BITFFMT(nm,sz,fmt) {#nm, -1, sz, NULL, #fmt}/* Bit Field definition with Output format */
#define BITFNAM(nm,sz,names) {#nm, -1, sz, names} /* Bit Field definition with value->name map */
#else
#define ORDATA(nm,loc,wd) "nm", &(loc), 8, (wd), 0, 1
#define DRDATA(nm,loc,wd) "nm", &(loc), 10, (wd), 0, 1
@ -535,7 +551,14 @@ struct sim_fileref {
#define BRDATA(nm,loc,rdx,wd,dep) "nm", (loc), (rdx), (wd), 0, (dep)
#define URDATA(nm,loc,rdx,wd,off,dep,fl) \
"nm", &(loc), (rdx), (wd), (off), (dep), ((fl) | REG_UNIT)
#define BIT(nm) {"nm", -1, 1} /* Single Bit definition */
#define BITNC {"", -1, 1} /* Don't care Bit definition */
#define BITF(nm,sz) {"nm", -1, sz} /* Bit Field definition */
#define BITNCF(sz) {"", -1, sz} /* Don't care Bit Field definition */
#define BITFFMT(nm,sz,fmt) {"nm", -1, sz, NULL, "fmt"}/* Bit Field definition with Output format */
#define BITFNAM(nm,sz,names) {"nm", -1, sz, names} /* Bit Field definition with value->name map */
#endif
#define ENDBITS {NULL} /* end of bitfield list */
/* Typedefs for principal structures */
@ -550,6 +573,7 @@ typedef struct sim_schtab SCHTAB;
typedef struct sim_brktab BRKTAB;
typedef struct sim_debtab DEBTAB;
typedef struct sim_fileref FILEREF;
typedef struct sim_bitfield BITFIELD;
/* Function prototypes */
@ -587,7 +611,8 @@ extern int32 sim_asynch_inst_latency;
pthread_mutex_destroy(&sim_asynch_lock); \
pthread_cond_destroy(&sim_asynch_wake); \
}
#define AIO_IS_ACTIVE(uptr) (((uptr)->a_is_active ? (uptr)->a_is_active (uptr) : FALSE) || ((uptr)->a_next))
#define AIO_CANCEL(uptr) if ((uptr)->a_cancel) (uptr)->a_cancel (uptr); else (void)0
#if defined(__DECC_VER)
#include <builtins>
#if defined(__IA64)
@ -728,6 +753,8 @@ extern int32 sim_asynch_inst_latency;
#define AIO_CHECK_EVENT
#define AIO_INIT
#define AIO_CLEANUP
#define AIO_IS_ACTIVE(uptr) FALSE
#define AIO_CANCEL(uptr)
#define AIO_SET_INTERRUPT_LATENCY(instpersec)
#endif /* SIM_ASYNCH_IO */

View file

@ -108,6 +108,7 @@ struct disk_context {
pthread_t io_thread; /* I/O Thread Id */
pthread_mutex_t io_lock;
pthread_cond_t io_cond;
pthread_cond_t io_done;
pthread_cond_t startup_cond;
int io_dop;
uint8 *buf;
@ -196,6 +197,7 @@ while (ctx->asynch_io) {
}
pthread_mutex_lock (&ctx->io_lock);
ctx->io_dop = DOP_DONE;
pthread_cond_signal (&ctx->io_done);
sim_activate (uptr, ctx->asynch_io_latency);
}
pthread_mutex_unlock (&ctx->io_lock);
@ -209,7 +211,7 @@ return NULL;
processing events for any unit. It is only called when an asynchronous
thread has called sim_activate() to activate a unit. The job of this
routine is to put the unit in proper condition to digest what may have
occurred in the asynchrcondition thread.
occurred in the asynchrconous thread.
Since disk processing only handles a single I/O at a time to a
particular disk device (due to using stdio for the SimH Disk format
@ -231,6 +233,25 @@ if (ctx->callback && ctx->io_dop == DOP_DONE) {
callback (uptr, ctx->io_status);
}
}
static t_bool _disk_is_active (UNIT *uptr)
{
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
sim_debug (ctx->dbit, ctx->dptr, "_disk_is_active(unit=%d, dop=%d)\n", uptr-ctx->dptr->units, ctx->io_dop);
return (ctx->io_dop != DOP_DONE);
}
static void _disk_cancel (UNIT *uptr)
{
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
sim_debug (ctx->dbit, ctx->dptr, "_disk_cancel(unit=%d, dop=%d)\n", uptr-ctx->dptr->units, ctx->io_dop);
pthread_mutex_lock (&ctx->io_lock);
while (ctx->io_dop != DOP_DONE)
pthread_cond_wait (&ctx->io_done, &ctx->io_lock);
pthread_mutex_unlock (&ctx->io_lock);
}
#else
#define AIO_CALLSETUP
#define AIO_CALL(op, _lba, _buf, _rsects, _sects, _callback) \
@ -425,6 +446,7 @@ ctx->asynch_io_latency = latency;
if (ctx->asynch_io) {
pthread_mutex_init (&ctx->io_lock, NULL);
pthread_cond_init (&ctx->io_cond, NULL);
pthread_cond_init (&ctx->io_done, NULL);
pthread_cond_init (&ctx->startup_cond, NULL);
pthread_attr_init(&attr);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
@ -434,8 +456,10 @@ if (ctx->asynch_io) {
pthread_cond_wait (&ctx->startup_cond, &ctx->io_lock); /* Wait for thread to stabilize */
pthread_mutex_unlock (&ctx->io_lock);
pthread_cond_destroy (&ctx->startup_cond);
uptr->a_check_completion = _disk_completion_dispatch;
}
uptr->a_check_completion = _disk_completion_dispatch;
uptr->a_is_active = _disk_is_active;
uptr->a_cancel = _disk_cancel;
#endif
return SCPE_OK;
}
@ -460,6 +484,7 @@ if (ctx->asynch_io) {
pthread_join (ctx->io_thread, NULL);
pthread_mutex_destroy (&ctx->io_lock);
pthread_cond_destroy (&ctx->io_cond);
pthread_cond_destroy (&ctx->io_done);
}
return SCPE_OK;
#endif

View file

@ -757,6 +757,14 @@ t_stat ethq_destroy(ETH_QUE* que)
void ethq_clear(ETH_QUE* que)
{
int i;
/* free up any extended packets */
for (i=0; i<que->max; ++i)
if (que->item[i].packet.oversize) {
free (que->item[i].packet.oversize);
que->item[i].packet.oversize = NULL;
}
/* clear packet array */
memset(que->item, 0, sizeof(struct eth_item) * que->max);
/* clear rest of structure */
@ -768,6 +776,8 @@ void ethq_remove(ETH_QUE* que)
struct eth_item* item = &que->item[que->head];
if (que->count) {
if (item->packet.oversize)
free (item->packet.oversize);
memset(item, 0, sizeof(struct eth_item));
if (++que->head == que->max)
que->head = 0;
@ -804,15 +814,23 @@ void ethq_insert_data(ETH_QUE* que, int32 type, const uint8 *data, int used, int
item->packet.len = len;
item->packet.used = used;
item->packet.crc_len = crc_len;
memcpy(item->packet.msg, data, ((len > crc_len) ? len : crc_len));
if (crc_data && (crc_len > len))
memcpy(&item->packet.msg[len], crc_data, ETH_CRC_SIZE);
if (len <= sizeof (item->packet.msg)) {
memcpy(item->packet.msg, data, ((len > crc_len) ? len : crc_len));
if (crc_data && (crc_len > len))
memcpy(&item->packet.msg[len], crc_data, ETH_CRC_SIZE);
}
else {
item->packet.oversize = realloc (item->packet.oversize, ((len > crc_len) ? len : crc_len));
memcpy(item->packet.oversize, data, ((len > crc_len) ? len : crc_len));
if (crc_data && (crc_len > len))
memcpy(&item->packet.oversize[len], crc_data, ETH_CRC_SIZE);
}
item->packet.status = status;
}
void ethq_insert(ETH_QUE* que, int32 type, ETH_PACK* pack, int32 status)
{
ethq_insert_data(que, type, pack->msg, pack->used, pack->len, pack->crc_len, NULL, status);
ethq_insert_data(que, type, pack->oversize ? pack->oversize : pack->msg, pack->used, pack->len, pack->crc_len, NULL, status);
}
/*============================================================================*/

View file

@ -173,6 +173,7 @@
struct eth_packet {
uint8 msg[ETH_FRAME_SIZE]; /* ethernet frame (message) */
uint8 *oversize; /* oversized frame (message) */
uint32 len; /* packet length without CRC */
uint32 used; /* bytes processed (used in packet chaining) */
int status; /* transmit/receive status */

View file

@ -125,6 +125,7 @@ struct tape_context {
pthread_t io_thread; /* I/O Thread Id */
pthread_mutex_t io_lock;
pthread_cond_t io_cond;
pthread_cond_t io_done;
pthread_cond_t startup_cond;
int io_top;
uint8 *buf;
@ -273,6 +274,7 @@ struct tape_context *ctx = (struct tape_context *)uptr->tape_ctx;
}
pthread_mutex_lock (&ctx->io_lock);
ctx->io_top = TOP_DONE;
pthread_cond_signal (&ctx->io_done);
sim_activate (uptr, ctx->asynch_io_latency);
}
pthread_mutex_unlock (&ctx->io_lock);
@ -286,7 +288,7 @@ struct tape_context *ctx = (struct tape_context *)uptr->tape_ctx;
processing events for any unit. It is only called when an asynchronous
thread has called sim_activate() to activate a unit. The job of this
routine is to put the unit in proper condition to digest what may have
occurred in the asynchrcondition thread.
occurred in the asynchronous thread.
Since tape processing only handles a single I/O at a time to a
particular tape device, we have the opportunity to possibly detect
@ -306,6 +308,25 @@ if (ctx->callback && ctx->io_top == TOP_DONE) {
callback (uptr, ctx->io_status);
}
}
static t_bool _tape_is_active (UNIT *uptr)
{
struct tape_context *ctx = (struct tape_context *)uptr->tape_ctx;
sim_debug (ctx->dbit, ctx->dptr, "_tape_is_active(unit=%d, top=%d)\n", uptr-ctx->dptr->units, ctx->io_top);
return (ctx->io_top != TOP_DONE);
}
static void _tape_cancel (UNIT *uptr)
{
struct tape_context *ctx = (struct tape_context *)uptr->tape_ctx;
sim_debug (ctx->dbit, ctx->dptr, "_tape_cancel(unit=%d, top=%d)\n", uptr-ctx->dptr->units, ctx->io_top);
pthread_mutex_lock (&ctx->io_lock);
while (ctx->io_top != TOP_DONE)
pthread_cond_wait (&ctx->io_done, &ctx->io_lock);
pthread_mutex_unlock (&ctx->io_lock);
}
#else
#define AIO_CALLSETUP
#define AIO_CALL(op, _buf, _fc, _bc, _max, _vbc, _gaplen, _bpi, _obj, _callback) \
@ -333,6 +354,7 @@ ctx->asynch_io_latency = latency;
if (ctx->asynch_io) {
pthread_mutex_init (&ctx->io_lock, NULL);
pthread_cond_init (&ctx->io_cond, NULL);
pthread_cond_init (&ctx->io_done, NULL);
pthread_cond_init (&ctx->startup_cond, NULL);
pthread_attr_init(&attr);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
@ -344,6 +366,8 @@ if (ctx->asynch_io) {
pthread_cond_destroy (&ctx->startup_cond);
}
uptr->a_check_completion = _tape_completion_dispatch;
uptr->a_is_active = _tape_is_active;
uptr->a_cancel = _tape_cancel;
#endif
return SCPE_OK;
}
@ -368,6 +392,7 @@ if (ctx->asynch_io) {
pthread_join (ctx->io_thread, NULL);
pthread_mutex_destroy (&ctx->io_lock);
pthread_cond_destroy (&ctx->io_cond);
pthread_cond_destroy (&ctx->io_done);
}
return SCPE_OK;
#endif