Merge branch 'Extra-VAXen'
This commit is contained in:
commit
762aacf7ad
87 changed files with 33869 additions and 8596 deletions
|
@ -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:
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
325
PDP11/pdp11_hk.c
325
PDP11/pdp11_hk.c
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
427
PDP11/pdp11_rp.c
427
PDP11/pdp11_rp.c
|
@ -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];
|
||||
|
|
311
PDP11/pdp11_rq.c
311
PDP11/pdp11_rq.c
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
173
PDP11/pdp11_xq.c
173
PDP11/pdp11_xq.c
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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
BIN
VAX/ka610.bin
Normal file
Binary file not shown.
BIN
VAX/ka620.bin
Normal file
BIN
VAX/ka620.bin
Normal file
Binary file not shown.
25
VAX/ka620_patch.com
Normal file
25
VAX/ka620_patch.com
Normal 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
BIN
VAX/ka630.bin
Normal file
Binary file not shown.
25
VAX/ka630_patch.com
Normal file
25
VAX/ka630_patch.com
Normal 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
397
VAX/vax610_defs.h
Normal 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
376
VAX/vax610_io.c
Normal 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
112
VAX/vax610_mem.c
Normal 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
423
VAX/vax610_stddev.c
Normal 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
496
VAX/vax610_sysdev.c
Normal 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 = ®table[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 = ®table[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
114
VAX/vax610_syslist.c
Normal 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
439
VAX/vax630_defs.h
Normal 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
623
VAX/vax630_io.c
Normal 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
359
VAX/vax630_stddev.c
Normal 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
899
VAX/vax630_sysdev.c
Normal 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 = ®table[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 = ®table[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
136
VAX/vax630_syslist.c
Normal 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
404
VAX/vax730_defs.h
Normal 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
196
VAX/vax730_mem.c
Normal 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
670
VAX/vax730_rb.c
Normal 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
1197
VAX/vax730_stddev.c
Normal file
File diff suppressed because it is too large
Load diff
649
VAX/vax730_sys.c
Normal file
649
VAX/vax730_sys.c
Normal 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
130
VAX/vax730_syslist.c
Normal 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
667
VAX/vax730_uba.c
Normal 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
743
VAX/vax750_cmi.c
Normal 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
453
VAX/vax750_defs.h
Normal 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
207
VAX/vax750_mem.c
Normal 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
1195
VAX/vax750_stddev.c
Normal file
File diff suppressed because it is too large
Load diff
125
VAX/vax750_syslist.c
Normal file
125
VAX/vax750_syslist.c
Normal 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
687
VAX/vax750_uba.c
Normal 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;
|
||||
}
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
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
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
4109
VAX/vax_ka630_bin.h
Normal file
File diff suppressed because it is too large
Load diff
16406
VAX/vax_ka655x_bin.h
16406
VAX/vax_ka655x_bin.h
File diff suppressed because it is too large
Load diff
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
217
VAX/vax_watch.c
Normal 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;
|
||||
}
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
449
Visual Studio Projects/VAX610.vcproj
Normal file
449
Visual Studio Projects/VAX610.vcproj
Normal 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) & Check for required build dependencies"
|
||||
CommandLine="pushd ..
$(TargetDir)BuildROMs
popd

if not exist ../../windows-build/winpcap/Wpdpack/Include/pcap.h goto _notice
if not exist ../../windows-build/pthreads/pthread.h goto _notice
goto _good

:_notice
echo ****************************************************
echo ****************************************************
echo ** The required build support is not available. **
echo ****************************************************
echo ****************************************************
type 0ReadMe_Projects.txt
exit 1

:_good
"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/pthreads""
|
||||
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=""../../windows-build/winpcap/Wpdpack/Lib/""
|
||||
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) & Check for required build dependencies"
|
||||
CommandLine="pushd ..
$(TargetDir)BuildROMs
popd

if not exist ../../windows-build/winpcap/Wpdpack/Include/pcap.h goto _notice
if not exist ../../windows-build/pthreads/pthread.h goto _notice
goto _good

:_notice
echo ****************************************************
echo ****************************************************
echo ** The required build support is not available. **
echo ****************************************************
echo ****************************************************
type 0ReadMe_Projects.txt
exit 1

:_good
"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="true"
|
||||
WholeProgramOptimization="true"
|
||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/pthreads""
|
||||
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=""../../windows-build/winpcap/Wpdpack/Lib/""
|
||||
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>
|
453
Visual Studio Projects/VAX620.vcproj
Normal file
453
Visual Studio Projects/VAX620.vcproj
Normal 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) & Check for required build dependencies"
|
||||
CommandLine="pushd ..
$(TargetDir)BuildROMs
popd

if not exist ../../windows-build/winpcap/Wpdpack/Include/pcap.h goto _notice
if not exist ../../windows-build/pthreads/pthread.h goto _notice
goto _good

:_notice
echo ****************************************************
echo ****************************************************
echo ** The required build support is not available. **
echo ****************************************************
echo ****************************************************
type 0ReadMe_Projects.txt
exit 1

:_good
"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/pthreads""
|
||||
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=""../../windows-build/winpcap/Wpdpack/Lib/""
|
||||
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) & Check for required build dependencies"
|
||||
CommandLine="pushd ..
$(TargetDir)BuildROMs
popd

if not exist ../../windows-build/winpcap/Wpdpack/Include/pcap.h goto _notice
if not exist ../../windows-build/pthreads/pthread.h goto _notice
goto _good

:_notice
echo ****************************************************
echo ****************************************************
echo ** The required build support is not available. **
echo ****************************************************
echo ****************************************************
type 0ReadMe_Projects.txt
exit 1

:_good
"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="true"
|
||||
WholeProgramOptimization="true"
|
||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/pthreads""
|
||||
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=""../../windows-build/winpcap/Wpdpack/Lib/""
|
||||
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>
|
453
Visual Studio Projects/VAX630.vcproj
Normal file
453
Visual Studio Projects/VAX630.vcproj
Normal 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) & Check for required build dependencies"
|
||||
CommandLine="pushd ..
$(TargetDir)BuildROMs
popd

if not exist ../../windows-build/winpcap/Wpdpack/Include/pcap.h goto _notice
if not exist ../../windows-build/pthreads/pthread.h goto _notice
goto _good

:_notice
echo ****************************************************
echo ****************************************************
echo ** The required build support is not available. **
echo ****************************************************
echo ****************************************************
type 0ReadMe_Projects.txt
exit 1

:_good
"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/pthreads""
|
||||
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=""../../windows-build/winpcap/Wpdpack/Lib/""
|
||||
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) & Check for required build dependencies"
|
||||
CommandLine="pushd ..
$(TargetDir)BuildROMs
popd

if not exist ../../windows-build/winpcap/Wpdpack/Include/pcap.h goto _notice
if not exist ../../windows-build/pthreads/pthread.h goto _notice
goto _good

:_notice
echo ****************************************************
echo ****************************************************
echo ** The required build support is not available. **
echo ****************************************************
echo ****************************************************
type 0ReadMe_Projects.txt
exit 1

:_good
"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="true"
|
||||
WholeProgramOptimization="true"
|
||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/pthreads""
|
||||
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=""../../windows-build/winpcap/Wpdpack/Lib/""
|
||||
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>
|
447
Visual Studio Projects/VAX730.vcproj
Normal file
447
Visual Studio Projects/VAX730.vcproj
Normal 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) & Check for required build dependencies"
|
||||
CommandLine="pushd ..
$(TargetDir)BuildROMs
popd

if not exist ../../windows-build/winpcap/Wpdpack/Include/pcap.h goto _notice
if not exist ../../windows-build/pthreads/pthread.h goto _notice
goto _good

:_notice
echo ****************************************************
echo ****************************************************
echo ** The required build support is not available. **
echo ****************************************************
echo ****************************************************
type 0ReadMe_Projects.txt
exit 1

:_good
"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/pthreads""
|
||||
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/;"../../pthreads/Pre-built.2/lib/""
|
||||
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) & Check for required build dependencies"
|
||||
CommandLine="pushd ..
$(TargetDir)BuildROMs
popd

if not exist ../../windows-build/winpcap/Wpdpack/Include/pcap.h goto _notice
if not exist ../../windows-build/pthreads/pthread.h goto _notice
goto _good

:_notice
echo ****************************************************
echo ****************************************************
echo ** The required build support is not available. **
echo ****************************************************
echo ****************************************************
type 0ReadMe_Projects.txt
exit 1

:_good
"
|
||||
/>
|
||||
<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/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/pthreads""
|
||||
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/;"../../pthreads/Pre-built.2/lib/""
|
||||
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>
|
455
Visual Studio Projects/VAX750.vcproj
Normal file
455
Visual Studio Projects/VAX750.vcproj
Normal 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) & Check for required build dependencies"
|
||||
CommandLine="pushd ..
$(TargetDir)BuildROMs
popd

if not exist ../../windows-build/winpcap/Wpdpack/Include/pcap.h goto _notice
if not exist ../../windows-build/pthreads/pthread.h goto _notice
goto _good

:_notice
echo ****************************************************
echo ****************************************************
echo ** The required build support is not available. **
echo ****************************************************
echo ****************************************************
type 0ReadMe_Projects.txt
exit 1

:_good
"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/pthreads""
|
||||
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/;"../../pthreads/Pre-built.2/lib/""
|
||||
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) & Check for required build dependencies"
|
||||
CommandLine="pushd ..
$(TargetDir)BuildROMs
popd

if not exist ../../windows-build/winpcap/Wpdpack/Include/pcap.h goto _notice
if not exist ../../windows-build/pthreads/pthread.h goto _notice
goto _good

:_notice
echo ****************************************************
echo ****************************************************
echo ** The required build support is not available. **
echo ****************************************************
echo ****************************************************
type 0ReadMe_Projects.txt
exit 1

:_good
"
|
||||
/>
|
||||
<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/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/pthreads""
|
||||
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/;"../../pthreads/Pre-built.2/lib/""
|
||||
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>
|
|
@ -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"
|
||||
|
|
218
descrip.mms
218
descrip.mms
|
@ -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.
BIN
doc/vax_doc.doc
BIN
doc/vax_doc.doc
Binary file not shown.
122
makefile
122
makefile
|
@ -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
212
scp.c
|
@ -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
8
scp.h
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
29
sim_defs.h
29
sim_defs.h
|
@ -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 */
|
||||
|
||||
|
|
29
sim_disk.c
29
sim_disk.c
|
@ -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
|
||||
|
|
26
sim_ether.c
26
sim_ether.c
|
@ -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);
|
||||
}
|
||||
|
||||
/*============================================================================*/
|
||||
|
|
|
@ -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 */
|
||||
|
|
27
sim_tape.c
27
sim_tape.c
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue