mirror of
https://github.com/simh/simh.git
synced 2026-04-10 14:49:16 +00:00
Notes For V3.5-1
The source set has been extensively overhauled. For correct viewing, set Visual C++ or Emacs to have tab stops every 4 characters. 1. New Features 1.1 3.5-0 1.1.1 All Ethernet devices - Added Windows user-defined adapter names (from Timothe Litt) 1.1.2 Interdata, SDS, HP, PDP-8, PDP-18b terminal multiplexors - Added support for SET <unit>n DISCONNECT 1.1.3 VAX - Added latent QDSS support - Revised autoconfigure to handle QDSS 1.1.4 PDP-11 - Revised autoconfigure to handle more cases 1.2 3.5-1 No new features 1.3 3.5-2 1.3.1 All ASCII terminals - Most ASCII terminal emulators have supported 7-bit and 8-bit operation; where required, they have also supported an upper- case only or KSR-emulation mode. This release adds a new mode, 7P, for 7-bit printing characters. In 7P mode, non-printing characters in the range 0-31 (decimal), and 127 (decimal), are automatically suppressed. This prevents printing of fill characters under Windows. The printable character set for ASCII code values 0-31 can be changed with the SET CONSOLE PCHAR command. Code value 127 (DELETE) is always suppressed. 1.3.2 VAX-11/780 - First release. The VAX-11/780 has successfully run VMS V7.2. The commercial instructions and compatability mode have not been extensively tested. The Ethernet controller is not working yet and is disabled. 2. Bugs Fixed 2.1 3.5-0 2.1.1 SCP and libraries - Trim trailing spaces on all input (for example, attach file names) - Fixed sim_sock spurious SIGPIPE error in Unix/Linux - Fixed sim_tape misallocation of TPC map array for 64b simulators 2.1.2 1401 - Fixed bug, CPU reset was clearing SSB through SSG 2.1.3 PDP-11 - Fixed bug in VH vector display routine - Fixed XU runt packet processing (found by Tim Chapman) 2.1.4 Interdata - Fixed bug in SHOW PAS CONN/STATS - Fixed potential integer overflow exception in divide 2.1.5 SDS - Fixed bug in SHOW MUX CONN/STATS 2.1.6 HP - Fixed bug in SHOW MUX CONN/STATS 2.1.7 PDP-8 - Fixed bug in SHOW TTIX CONN/STATS - Fixed bug in SET/SHOW TTOXn LOG 2.1.8 PDP-18b - Fixed bug in SHOW TTIX CONN/STATS - Fixed bug in SET/SHOW TTOXn LOG 2.1.9 Nova, Eclipse - Fixed potential integer overflow exception in divide 2.2 3.5-1 2.2.1 1401 - Changed character encodings to be compatible with Pierce 709X simulator - Added mode for old/new character encodings 2.2.2 1620 - Changed character encodings to be compatible with Pierce 709X simulator 2.2.3 PDP-10 - Changed MOVNI to eliminate GCC warning 2.2.4 VAX - Fixed bug in structure definitions with 32b compilation options - Fixed bug in autoconfiguration table 2.2.5 PDP-11 - Fixed bug in autoconfiguration table 2.3 3.5-2 2.3.1 PDP-10 - RP: fixed drive clear not to clear disk address 2.3.2 PDP-11 (VAX, VAX-11/780, for shared peripherals) - HK: fixed overlap seek interaction with drive select, drive clear, etc - RQ, TM, TQ, TS, TU: widened address display to 64b when USE_ADDR64 option selected - TU: changed default adapter from TM02 to TM03 (required by VMS) - RP: fixed drive clear not to clear disk address - RP, TU: fixed device enable/disable to enabled/disable Massbus adapter as well - XQ: fixed register access alignment bug (found by Doug Carman) 2.3.3 PDP-8 - RL: fixed IOT 61 decoding bug (found by David Gesswein) - DF, DT, RF: fixed register access alignment bug (found by Doug Carman) 2.3.4 VAX - Fixed CVTfi to trap on integer overflow if PSW<iv> is set - Fixed breakpoint detection when USE_ADDR64 option selected
This commit is contained in:
committed by
Mark Pizzolato
parent
1e704bf185
commit
a12e4a1c39
@@ -780,6 +780,7 @@ int32 mba_get_csr (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 mb, t_bool dis);
|
||||
t_stat mba_show_num (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
To: Users
|
||||
From: Bob Supnik
|
||||
Subj: PDP-11 Simulator Usage
|
||||
Date: 01-Jul-2005
|
||||
Date: 01-Dec-2005
|
||||
|
||||
COPYRIGHT NOTICE
|
||||
|
||||
@@ -486,10 +486,18 @@ Error handling is as follows:
|
||||
|
||||
2.3.3 DL11 Terminal Input (TTI)
|
||||
|
||||
The terminal interfaces (TTI, TTO) can be set to one of two modes:
|
||||
7B or 8B. In 7B mode, input and output characters are masked to 7
|
||||
bits. In 8B mode, characters are not modified. Changing the mode
|
||||
of either interface changes both. The default mode is 8B.
|
||||
The terminal interfaces (TTI, TTO) can be set to one of three modes,
|
||||
7P, 7B or 8B:
|
||||
|
||||
mode input characters output characters
|
||||
|
||||
7P high-order bit cleared high-order bit cleared,
|
||||
non-printing characters
|
||||
suppressed
|
||||
7B high-order bit cleared high-order bit cleared
|
||||
8B no changes no changes
|
||||
|
||||
The default mode is 8B.
|
||||
|
||||
The terminal input (TTI) polls the console keyboard for input. It
|
||||
implements these registers:
|
||||
@@ -1310,12 +1318,17 @@ are supported. The number of lines can be changed with the command
|
||||
|
||||
The line count must be a multiple of 8, with a maximum of 32.
|
||||
|
||||
The DZ11 supports 8-bit input and output of characters. 8-bit output
|
||||
may be incompatible with certain operating systems. The command
|
||||
The DZ11 supports three character processing modes, 7P, 7B, and 8B:
|
||||
|
||||
SET DZ 7B
|
||||
mode input characters output characters
|
||||
|
||||
forces output characters (only) to be masked to 7 bits.
|
||||
7P high-order bit cleared high-order bit cleared,
|
||||
non-printing characters
|
||||
suppressed
|
||||
7B high-order bit cleared high-order bit cleared
|
||||
8B no changes no changes
|
||||
|
||||
The default is 8B.
|
||||
|
||||
The DZ11 supports logging on a per-line basis. The command
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
dz DZ11 terminal multiplexor
|
||||
|
||||
22-Nov-05 RMS Revised for new terminal processing routines
|
||||
07-Jul-05 RMS Removed extraneous externs
|
||||
15-Jun-05 RMS Revised for new autoconfigure interface
|
||||
04-Apr-04 RMS Added per-line logging
|
||||
@@ -61,12 +62,12 @@ extern int32 int_req;
|
||||
|
||||
#elif defined (VM_VAX) /* VAX version */
|
||||
#include "vax_defs.h"
|
||||
#define DZ_8B_DFLT UNIT_8B
|
||||
#define DZ_8B_DFLT TT_MODE_8B
|
||||
extern int32 int_req[IPL_HLVL];
|
||||
|
||||
#else /* PDP-11 version */
|
||||
#include "pdp11_defs.h"
|
||||
#define DZ_8B_DFLT UNIT_8B
|
||||
#define DZ_8B_DFLT TT_MODE_8B
|
||||
extern int32 int_req[IPL_HLVL];
|
||||
#endif
|
||||
|
||||
@@ -80,9 +81,6 @@ extern int32 int_req[IPL_HLVL];
|
||||
#define DZ_LINES 8
|
||||
#endif
|
||||
|
||||
#define UNIT_V_8B (UNIT_V_UF + 0) /* 8b output */
|
||||
#define UNIT_8B (1 << UNIT_V_8B)
|
||||
|
||||
#define DZ_MNOMASK (DZ_MUXES - 1) /* mask for mux no */
|
||||
#define DZ_LNOMASK (DZ_LINES - 1) /* mask for lineno */
|
||||
#define DZ_LMASK ((1 << DZ_LINES) - 1) /* mask of lines */
|
||||
@@ -217,8 +215,9 @@ REG dz_reg[] = {
|
||||
};
|
||||
|
||||
MTAB dz_mod[] = {
|
||||
{ UNIT_8B, 0, "7b", "7B", NULL },
|
||||
{ UNIT_8B, UNIT_8B, "8b", "8B", NULL },
|
||||
{ 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, 1, NULL, "DISCONNECT",
|
||||
&tmxr_dscln, NULL, &dz_desc },
|
||||
{ UNIT_ATT, UNIT_ATT, "connections", NULL, NULL, &dz_summ },
|
||||
@@ -295,7 +294,7 @@ return SCPE_OK;
|
||||
t_stat dz_wr (int32 data, int32 PA, int32 access)
|
||||
{
|
||||
int32 dz = ((PA - dz_dib.ba) >> 3) & DZ_MNOMASK; /* get mux num */
|
||||
int32 i, line;
|
||||
int32 i, c, line;
|
||||
TMLN *lp;
|
||||
|
||||
switch ((PA >> 1) & 03) { /* case on PA<2:1> */
|
||||
@@ -364,8 +363,8 @@ switch ((PA >> 1) & 03) { /* case on PA<2:1> */
|
||||
if (dz_csr[dz] & CSR_MSE) { /* enabled? */
|
||||
line = (dz * DZ_LINES) + CSR_GETTL (dz_csr[dz]);
|
||||
lp = &dz_ldsc[line]; /* get line desc */
|
||||
tmxr_putc_ln (lp, dz_tdr[dz] & /* store char */
|
||||
((dz_unit.flags & UNIT_8B)? 0377: 0177));
|
||||
c = sim_tt_outcvt (dz_tdr[dz], TT_GET_MODE (dz_unit.flags));
|
||||
if (c >= 0) tmxr_putc_ln (lp, c); /* store char */
|
||||
tmxr_poll_tx (&dz_desc); /* poll output */
|
||||
dz_update_xmti (); /* update int */
|
||||
}
|
||||
|
||||
101
PDP11/pdp11_hk.c
101
PDP11/pdp11_hk.c
@@ -25,6 +25,8 @@
|
||||
|
||||
hk RK611/RK06/RK07 disk
|
||||
|
||||
17-Nov-05 RMS Removed unused variable
|
||||
13-Nov-05 RMS Fixed overlapped seek interaction with NOP, DCLR, PACK
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
07-Jul-05 RMS Removed extraneous externs
|
||||
18-Mar-05 RMS Added attached test to detach routine
|
||||
@@ -126,7 +128,7 @@ extern uint16 *M;
|
||||
#define CS1_DI 0040000 /* drive intr */
|
||||
#define CS1_ERR 0100000 /* error */
|
||||
#define CS1_CCLR 0100000 /* ctrl clear */
|
||||
#define CS1_RW (CS1_DT|CS1_UAE|CS1_IE|CS1_SPA|CS1_FNC|CS1_GO)
|
||||
#define CS1_RW (CS1_DT|CS1_UAE|CS1_IE|CS1_SPA|CS1_FNC)
|
||||
#define GET_FNC(x) (((x) >> CS1_V_FNC) & CS1_M_FNC)
|
||||
#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))
|
||||
@@ -329,10 +331,10 @@ int32 hkmr2 = 0;
|
||||
int32 hkmr3 = 0;
|
||||
int32 hkdc = 0; /* cylinder */
|
||||
int32 hkspr = 0; /* spare */
|
||||
int32 hk_stopioe = 1; /* stop on error */
|
||||
int32 hk_cwait = 5; /* command time */
|
||||
int32 hk_swait = 10; /* seek time */
|
||||
int32 hk_rwait = 10; /* rotate time */
|
||||
int32 hk_min2wait = 300; /* min time to 2nd int */
|
||||
int16 hkdb[3] = { 0 }; /* data buffer silo */
|
||||
int16 hk_off[HK_NUMDR] = { 0 }; /* saved offset */
|
||||
int16 hk_dif[HK_NUMDR] = { 0 }; /* cylinder diff */
|
||||
@@ -409,8 +411,10 @@ REG hk_reg[] = {
|
||||
{ FLDATA (ERR, hkcs1, CSR_V_ERR) },
|
||||
{ FLDATA (DONE, hkcs1, CSR_V_DONE) },
|
||||
{ FLDATA (IE, hkcs1, CSR_V_IE) },
|
||||
{ DRDATA (CTIME, hk_cwait, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (STIME, hk_swait, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (RTIME, hk_rwait, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (MIN2TIME, hk_min2wait, 24), REG_NZ + PV_LEFT + REG_HRO },
|
||||
{ URDATA (FNC, hk_unit[0].FNC, DEV_RDX, 5, 0,
|
||||
HK_NUMDR, REG_HRO) },
|
||||
{ URDATA (CYL, hk_unit[0].CYL, DEV_RDX, 10, 0,
|
||||
@@ -419,7 +423,6 @@ REG hk_reg[] = {
|
||||
{ BRDATA (CYLDIF, hk_dif, DEV_RDX, 16, HK_NUMDR), REG_HRO },
|
||||
{ URDATA (CAPAC, hk_unit[0].capac, 10, T_ADDR_W, 0,
|
||||
HK_NUMDR, PV_LEFT | REG_HRO) },
|
||||
{ FLDATA (STOP_IOE, hk_stopioe, 0) },
|
||||
{ GRDATA (DEVADDR, hk_dib.ba, DEV_RDX, 32, 0), REG_HRO },
|
||||
{ GRDATA (DEVVEC, hk_dib.vec, DEV_RDX, 16, 0), REG_HRO },
|
||||
{ NULL }
|
||||
@@ -587,10 +590,8 @@ switch (j) { /* decode PA<4:1> */
|
||||
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 (hkcs1 & CS1_GO) { /* go? */
|
||||
if (hkcs1 & CS1_ERR) hkcs1 = hkcs1 & ~CS1_GO;
|
||||
else hk_go (drv);
|
||||
}
|
||||
if ((data & CS1_GO) && !(hkcs1 & CS1_ERR)) /* go? */
|
||||
hk_go (drv);
|
||||
break;
|
||||
|
||||
case 001: /* HKWC */
|
||||
@@ -640,7 +641,7 @@ update_hkcs (0, drv); /* update status */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Initiate operation - unit not busy, function set */
|
||||
/* Initiate operation - go set, not previously set */
|
||||
|
||||
void hk_go (int32 drv)
|
||||
{
|
||||
@@ -662,7 +663,7 @@ static int32 fnc_cyl[16] = {
|
||||
|
||||
fnc = GET_FNC (hkcs1);
|
||||
if (DEBUG_PRS (hk_dev)) fprintf (sim_deb,
|
||||
">>HK%d: fnc=%o, ds=%o, cyl=%o, da=%o, ba=%o, wc=%o\n",
|
||||
">>HK%d go: fnc=%o, ds=%o, cyl=%o, da=%o, ba=%o, wc=%o\n",
|
||||
drv, fnc, hkds[drv], hkdc, hkda, hkba, hkwc);
|
||||
uptr = hk_dev.units + drv; /* get unit */
|
||||
if (fnc != FNC_NOP) hkmr = hkmr & ~MR_MS; /* !nop, clr msg sel */
|
||||
@@ -680,34 +681,40 @@ if (fnc_nxf[fnc] && ((hkds[drv] & DS_VV) == 0)) { /* need vol valid? */
|
||||
hk_cmderr (ER_NXF, drv); /* non exec func */
|
||||
return;
|
||||
}
|
||||
if (fnc_att[fnc] && ((uptr->flags & UNIT_ATT) == 0)) { /* need attached? */
|
||||
if (fnc_att[fnc] && !(uptr->flags & UNIT_ATT)) { /* need attached? */
|
||||
hk_cmderr (ER_UNS, drv); /* unsafe */
|
||||
return;
|
||||
}
|
||||
if (fnc_rdy[fnc] && sim_is_active (uptr)) { /* need inactive? */
|
||||
hkcs1 = (hkcs1 | CS1_DONE) & ~CS1_GO; /* ignore if busy */
|
||||
return;
|
||||
}
|
||||
if (fnc_rdy[fnc] && sim_is_active (uptr)) return; /* need inactive? */
|
||||
if (fnc_cyl[fnc] && /* need valid cyl */
|
||||
((GET_CY (hkdc) >= HK_CYL (uptr)) || /* bad cylinder */
|
||||
(GET_SF (hkda) >= HK_NUMSF) || /* bad surface */
|
||||
(GET_SC (hkda) >= HK_NUMSC))) { /* or bad sector? */
|
||||
hk_cmderr (ER_IAE, drv); /* illegal addr */
|
||||
hk_cmderr (ER_IAE, drv); /* illegal addr */
|
||||
return;
|
||||
}
|
||||
|
||||
hkcs1 = hkcs1 & ~CS1_DONE; /* clear done */
|
||||
hkds[drv] = hkds[drv] & ~DS_ATA; /* clear attention */
|
||||
uptr->FNC = fnc; /* save function */
|
||||
hkcs1 = (hkcs1 | CS1_GO) & ~CS1_DONE; /* set go, clear done */
|
||||
switch (fnc) { /* case on function */
|
||||
|
||||
/* Instantaneous functions (unit may be busy, can't schedule thread) */
|
||||
|
||||
case FNC_DCLR: /* drive clear */
|
||||
hkds[drv] &= ~DS_ATA; /* clr ATA */
|
||||
hker[drv] = 0; /* clear errors */
|
||||
case FNC_NOP: /* no operation */
|
||||
update_hkcs (CS1_DONE, drv); /* done */
|
||||
break;
|
||||
case FNC_PACK: /* pack acknowledge */
|
||||
hkds[drv] = hkds[drv] | DS_VV; /* set volume valid */
|
||||
update_hkcs (CS1_DONE, drv); /* done */
|
||||
break;
|
||||
|
||||
/* "Fast functions" finish in less than 15 usec */
|
||||
|
||||
case FNC_NOP: /* no operation */
|
||||
case FNC_DCLR: /* drive clear */
|
||||
case FNC_START: /* start spindle */
|
||||
case FNC_UNLOAD: /* unload */
|
||||
case FNC_PACK: /* pack acknowledge */
|
||||
uptr->FNC = fnc; /* save function */
|
||||
sim_activate (uptr, hk_cwait); /* schedule */
|
||||
return;
|
||||
|
||||
@@ -718,6 +725,7 @@ switch (fnc) { /* case on function */
|
||||
case FNC_RECAL: /* recalibrate */
|
||||
case FNC_SEEK: /* seek */
|
||||
hkds[drv] = hkds[drv] | DS_PIP; /* set positioning */
|
||||
uptr->FNC = fnc; /* save function */
|
||||
sim_activate (uptr, hk_cwait); /* schedule */
|
||||
return;
|
||||
|
||||
@@ -732,6 +740,7 @@ switch (fnc) { /* case on function */
|
||||
hk_dif[drv] = hkdc - uptr->CYL; /* cyl diff */
|
||||
t = abs (hk_dif[drv]); /* |cyl diff| */
|
||||
sim_activate (uptr, hk_rwait + (hk_swait * t)); /* Schedule */
|
||||
uptr->FNC = fnc; /* save function */
|
||||
uptr->CYL = hkdc; /* update cyl */
|
||||
return;
|
||||
|
||||
@@ -751,32 +760,21 @@ return;
|
||||
|
||||
t_stat hk_svc (UNIT *uptr)
|
||||
{
|
||||
int32 i, t, dc, drv, fnc, err;
|
||||
int32 i, t, dc, fnc, err;
|
||||
int32 wc, awc, da;
|
||||
uint32 ba;
|
||||
uint32 drv, ba;
|
||||
uint16 comp;
|
||||
|
||||
drv = (int32) (uptr - hk_dev.units); /* get drv number */
|
||||
drv = (uint32) (uptr - hk_dev.units); /* get drv number */
|
||||
fnc = uptr->FNC & CS1_M_FNC; /* get function */
|
||||
switch (fnc) { /* case on function */
|
||||
|
||||
/* Fast commands and other NOPs - start spindle only provides one interrupt
|
||||
/* Fast commands - start spindle only provides one interrupt
|
||||
because ATTACH implicitly spins up the drive */
|
||||
|
||||
case FNC_DCLR: /* drive clear */
|
||||
hker[drv] = 0; /* clear errors */
|
||||
update_hkcs (CS1_DONE, drv); /* done */
|
||||
break;
|
||||
|
||||
case FNC_PACK: /* pack acknowledge */
|
||||
hkds[drv] = hkds[drv] | DS_VV; /* set volume valid */
|
||||
update_hkcs (CS1_DONE, drv); /* done */
|
||||
break;
|
||||
|
||||
case FNC_UNLOAD: /* unload */
|
||||
hk_detach (uptr); /* detach unit */
|
||||
case FNC_START: /* start spindle */
|
||||
case FNC_NOP: /* select */
|
||||
update_hkcs (CS1_DONE, drv); /* done */
|
||||
break;
|
||||
|
||||
@@ -791,7 +789,7 @@ switch (fnc) { /* case on function */
|
||||
else {
|
||||
uptr->FNC = uptr->FNC | FNC_2ND; /* second state */
|
||||
hk_off[drv] = hkof & AS_OF; /* save offset */
|
||||
sim_activate (uptr, hk_swait * 10); /* wait for compl */
|
||||
sim_activate (uptr, hk_min2wait); /* wait for compl */
|
||||
update_hkcs (CS1_DONE, drv); /* done */
|
||||
}
|
||||
break;
|
||||
@@ -807,10 +805,10 @@ switch (fnc) { /* case on function */
|
||||
hk_off[drv] = 0; /* clr offset */
|
||||
dc = (fnc == FNC_SEEK)? hkdc: 0; /* get cyl */
|
||||
hk_dif[drv] = dc - uptr->CYL; /* cyl diff */
|
||||
t = abs (hk_dif[drv]); /* |cyl diff| */
|
||||
if (t == 0) t = 1; /* min time */
|
||||
t = abs (hk_dif[drv]) * hk_swait; /* |cyl diff| */
|
||||
if (t < hk_min2wait) t = hk_min2wait; /* min time */
|
||||
uptr->CYL = dc; /* save cyl */
|
||||
sim_activate (uptr, hk_swait * t); /* schedule */
|
||||
sim_activate (uptr, t); /* schedule */
|
||||
update_hkcs (CS1_DONE, drv); /* done */
|
||||
}
|
||||
break;
|
||||
@@ -839,6 +837,7 @@ switch (fnc) { /* case on function */
|
||||
|
||||
if ((da + wc) > HK_SIZE (uptr)) { /* disk overrun? */
|
||||
hker[drv] = hker[drv] | ER_AOE; /* set err */
|
||||
hkds[drv] = hkds[drv] | DS_ATA; /* set attn */
|
||||
wc = HK_SIZE (uptr) - da; /* trim xfer */
|
||||
if (da >= HK_SIZE (uptr)) { /* none left? */
|
||||
update_hkcs (CS1_DONE, drv); /* then done */
|
||||
@@ -923,11 +922,15 @@ switch (fnc) { /* case on function */
|
||||
clearerr (uptr->fileref);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
|
||||
case FNC_WRITEH: /* write headers stub */
|
||||
update_hkcs (CS1_DONE, drv); /* set done */
|
||||
break;
|
||||
} /* end case func */
|
||||
|
||||
if (DEBUG_PRS (hk_dev)) fprintf (sim_deb,
|
||||
">>HK%d done: fnc=%o, cs1 = %o, cs2 = %o, ds=%o, cyl=%o, da=%o, ba=%o, wc=%o\n",
|
||||
drv, fnc, hkcs1, hkcs2, hkds[drv], hkdc, hkda, hkba, hkwc);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -954,7 +957,7 @@ else CLR_INT (HK);
|
||||
hkcs1 = (hkcs1 & (CS1_DT|CS1_UAE|CS1_DONE|CS1_IE|CS1_SPA|CS1_FNC|CS1_GO)) | flag;
|
||||
for (i = 0; i < HK_NUMDR; i++) { /* if ATA, set 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;
|
||||
return;
|
||||
@@ -991,7 +994,6 @@ void hk_cmderr (int32 err, int32 drv)
|
||||
{
|
||||
hker[drv] = hker[drv] | err; /* set error */
|
||||
hkds[drv] = hkds[drv] | DS_ATA; /* set attn */
|
||||
hkcs1 = hkcs1 & ~CS1_GO; /* clear go */
|
||||
update_hkcs (CS1_DONE, drv); /* set done */
|
||||
return;
|
||||
}
|
||||
@@ -1135,7 +1137,7 @@ t_stat r;
|
||||
uptr->capac = HK_SIZE (uptr);
|
||||
r = attach_unit (uptr, cptr); /* attach unit */
|
||||
if (r != SCPE_OK) return r; /* error? */
|
||||
drv = (int32) (uptr - hk_dev.units); /* get drv number */
|
||||
drv = (uint32) (uptr - hk_dev.units); /* get drv number */
|
||||
hkds[drv] = DS_ATA | DS_RDY | ((uptr->flags & UNIT_WPRT)? DS_WRL: 0);
|
||||
hker[drv] = 0; /* upd drv status */
|
||||
hk_off[drv] = 0;
|
||||
@@ -1143,12 +1145,13 @@ hk_dif[drv] = 0;
|
||||
uptr->CYL = 0;
|
||||
update_hkcs (CS1_DI, drv); /* upd ctlr status */
|
||||
|
||||
if ((p = sim_fsize (uptr->fileref)) == 0) { /* new disk image? */
|
||||
p = sim_fsize (uptr->fileref); /* get file size */
|
||||
if (p == 0) { /* new disk image? */
|
||||
if (uptr->flags & UNIT_RO) return SCPE_OK;
|
||||
return pdp11_bad_block (uptr, HK_NUMSC, HK_NUMWD);
|
||||
}
|
||||
if ((uptr->flags & UNIT_AUTO) == 0) return SCPE_OK; /* autosize? */
|
||||
if (p > (RK06_SIZE * sizeof (int16))) {
|
||||
if (p > (RK06_SIZE * sizeof (uint16))) {
|
||||
uptr->flags = uptr->flags | UNIT_RK07;
|
||||
uptr->capac = RK07_SIZE;
|
||||
}
|
||||
@@ -1163,16 +1166,16 @@ return SCPE_OK;
|
||||
|
||||
t_stat hk_detach (UNIT *uptr)
|
||||
{
|
||||
int32 drv;
|
||||
uint32 drv;
|
||||
|
||||
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; /* attached? */
|
||||
drv = (int32) (uptr - hk_dev.units); /* get drv number */
|
||||
drv = (uint32) (uptr - hk_dev.units); /* get drv number */
|
||||
hkds[drv] = (hkds[drv] & ~(DS_RDY | DS_WRL | DS_VV | DS_OF)) | DS_ATA;
|
||||
if (sim_is_active (uptr)) { /* unit active? */
|
||||
sim_cancel (uptr); /* cancel operation */
|
||||
hker[drv] = hker[drv] | ER_OPI; /* set drive error */
|
||||
if ((uptr->FNC & CS1_M_FNC) >= FNC_XFER) /* data transfer? */
|
||||
hkcs1 = hkcs1 | CS1_DONE | CS1_ERR; /* set done, err */
|
||||
if ((uptr->FNC & FNC_2ND) == 0) /* expecting done? */
|
||||
update_hkcs (CS1_DONE, drv); /* set done */
|
||||
}
|
||||
update_hkcs (CS1_DI, drv); /* request intr */
|
||||
return detach_unit (uptr);
|
||||
|
||||
254
PDP11/pdp11_rh.c
254
PDP11/pdp11_rh.c
@@ -25,6 +25,7 @@
|
||||
|
||||
rha, rhb RH11/RH70 Massbus adapter
|
||||
|
||||
21-Nov-05 RMS Added enable/disable routine
|
||||
07-Jul-05 RMS Removed extraneous externs
|
||||
|
||||
WARNING: The interupt logic of the RH11/RH70 is unusual and must be
|
||||
@@ -177,11 +178,6 @@ DEVICE mba0_dev, mba1_dev;
|
||||
|
||||
extern uint32 Map_Addr (uint32 ba);
|
||||
|
||||
/* Maps */
|
||||
|
||||
static MBACTX *ctxmap[MBA_NUM] = { &massbus[0], &massbus[1] };
|
||||
static DEVICE *devmap[MBA_NUM] = { &mba0_dev, &mba1_dev };
|
||||
|
||||
/* Massbus register dispatches */
|
||||
|
||||
static t_stat (*mbregR[MBA_NUM])(int32 *dat, int32 ad, int32 md);
|
||||
@@ -237,14 +233,6 @@ MTAB mba0_mod[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEVICE mba0_dev = {
|
||||
"RHA", &mba0_unit, mba0_reg, mba0_mod,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
NULL, NULL, &mba_reset,
|
||||
NULL, NULL, NULL,
|
||||
&mba0_dib, DEV_DEBUG | DEV_DISABLE | DEV_UBUS | DEV_QBUS
|
||||
};
|
||||
|
||||
DIB mba1_dib = {
|
||||
IOBA_TU, IOLN_TU, &mba_rd, &mba_wr,
|
||||
1, IVCL (TU), VEC_TU, { &mba1_inta }
|
||||
@@ -278,12 +266,21 @@ MTAB mba1_mod[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEVICE mba1_dev = {
|
||||
DEVICE mba_dev[] = {
|
||||
{
|
||||
"RHA", &mba0_unit, mba0_reg, mba0_mod,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
NULL, NULL, &mba_reset,
|
||||
NULL, NULL, NULL,
|
||||
&mba0_dib, DEV_DEBUG | DEV_DISABLE | DEV_UBUS | DEV_QBUS
|
||||
},
|
||||
{
|
||||
"RHB", &mba1_unit, mba1_reg, mba1_mod,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
NULL, NULL, &mba_reset,
|
||||
NULL, NULL, NULL,
|
||||
&mba1_dib, DEV_DEBUG | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS
|
||||
}
|
||||
};
|
||||
|
||||
/* Read Massbus adapter register */
|
||||
@@ -292,12 +289,10 @@ t_stat mba_rd (int32 *val, int32 pa, int32 mode)
|
||||
{
|
||||
int32 ofs, dat, mb, drv;
|
||||
t_stat r;
|
||||
MBACTX *mbp;
|
||||
|
||||
mb = mba_map_pa (pa, &ofs); /* get mb number */
|
||||
if ((mb < 0) || (ofs < 0)) return SCPE_NXM; /* valid? */
|
||||
mbp = ctxmap[mb]; /* get context */
|
||||
drv = GET_UNIT (mbp->cs2); /* get drive */
|
||||
drv = GET_UNIT (massbus[mb].cs2); /* get drive */
|
||||
mba_upd_cs1 (0, 0, mb); /* update CS1 */
|
||||
|
||||
if (ofs & EXT) { /* external? */
|
||||
@@ -314,31 +309,32 @@ switch (ofs) { /* case on reg */
|
||||
if (!mbregR[mb]) return SCPE_NXM; /* nx device? */
|
||||
r = mbregR[mb] (&dat, ofs, drv); /* get dev cs1 */
|
||||
if (r == MBE_NXD) mba_set_cs2 (CS2_NED, mb); /* nx drive? */
|
||||
*val = mbp->cs1 | dat;
|
||||
*val = massbus[mb].cs1 | dat;
|
||||
break;
|
||||
|
||||
case WC_OF: /* WC */
|
||||
*val = mbp->wc;
|
||||
*val = massbus[mb].wc;
|
||||
break;
|
||||
|
||||
case BA_OF: /* BA */
|
||||
*val = mbp->ba & ~BA_MBZ;
|
||||
*val = massbus[mb].ba & ~BA_MBZ;
|
||||
break;
|
||||
|
||||
case CS2_OF: /* CS2 */
|
||||
*val = mbp->cs2 = (mbp->cs2 & ~CS2_MBZ) | CS2_IR | CS2_OR;
|
||||
*val = massbus[mb].cs2 = (massbus[mb].cs2 & ~CS2_MBZ) | CS2_IR | CS2_OR;
|
||||
break;
|
||||
|
||||
case DB_OF: /* DB */
|
||||
*val = mbp->db;
|
||||
*val = massbus[mb].db;
|
||||
break;
|
||||
|
||||
case BAE_OF: /* BAE */
|
||||
*val = mbp->bae = mbp->bae & ~AE_MBZ;
|
||||
*val = massbus[mb].bae = massbus[mb].bae & ~AE_MBZ;
|
||||
break;
|
||||
|
||||
case CS3_OF: /* CS3 */
|
||||
*val = mbp->cs3 = (mbp->cs3 & ~(CS1_IE | CS3_MBZ)) | (mbp->cs1 & CS1_IE);
|
||||
*val = massbus[mb].cs3 = (massbus[mb].cs3 & ~(CS1_IE | CS3_MBZ)) |
|
||||
(massbus[mb].cs1 & CS1_IE);
|
||||
break;
|
||||
|
||||
default: /* huh? */
|
||||
@@ -353,12 +349,10 @@ t_stat mba_wr (int32 val, int32 pa, int32 access)
|
||||
int32 ofs, cs1f, drv, mb;
|
||||
t_stat r;
|
||||
t_bool cs1dt;
|
||||
MBACTX *mbp;
|
||||
|
||||
mb = mba_map_pa (pa, &ofs); /* get mb number */
|
||||
if ((mb < 0) || (ofs < 0)) return SCPE_NXM; /* valid? */
|
||||
mbp = ctxmap[mb]; /* get context */
|
||||
drv = GET_UNIT (mbp->cs2); /* get drive */
|
||||
drv = GET_UNIT (massbus[mb].cs2); /* get drive */
|
||||
|
||||
if (ofs & EXT) { /* external? */
|
||||
if (!mbregW[mb]) return SCPE_NXM; /* device there? */
|
||||
@@ -378,81 +372,84 @@ switch (ofs) { /* case on reg */
|
||||
if (!mbregW[mb]) return SCPE_NXM; /* device exist? */
|
||||
if ((access == WRITEB) && (pa & 1)) val = val << 8;
|
||||
if (val & CS1_TRE) { /* error clear? */
|
||||
mbp->cs1 = mbp->cs1 & ~CS1_TRE; /* clr CS1<TRE> */
|
||||
mbp->cs2 = mbp->cs2 & ~CS2_ERR; /* clr CS2<15:8> */
|
||||
mbp->cs3 = mbp->cs3 & ~CS3_ERR; /* clr CS3<15:11> */
|
||||
massbus[mb].cs1 &= ~CS1_TRE; /* clr CS1<TRE> */
|
||||
massbus[mb].cs2 &= ~CS2_ERR; /* clr CS2<15:8> */
|
||||
massbus[mb].cs3 &= ~CS3_ERR; /* clr CS3<15:11> */
|
||||
}
|
||||
if ((access == WRITE) || (pa & 1)) { /* hi byte write? */
|
||||
if (mbp->cs1 & CS1_DONE) /* done set? */
|
||||
mbp->cs1 = (mbp->cs1 & ~CS1_UAE) | (val & CS1_UAE);
|
||||
if (massbus[mb].cs1 & CS1_DONE) /* done set? */
|
||||
massbus[mb].cs1 = (massbus[mb].cs1 & ~CS1_UAE) | (val & CS1_UAE);
|
||||
}
|
||||
if ((access == WRITE) || !(pa & 1)) { /* lo byte write? */
|
||||
if ((val & CS1_DONE) && (val & CS1_IE)) /* to DONE+IE? */
|
||||
mbp->iff = 1; /* set CSTB INTR */
|
||||
mbp->cs1 = (mbp->cs1 & ~CS1_IE) | (val & CS1_IE);
|
||||
massbus[mb].iff = 1; /* set CSTB INTR */
|
||||
massbus[mb].cs1 = (massbus[mb].cs1 & ~CS1_IE) | (val & CS1_IE);
|
||||
cs1dt = (val & CS1_GO) && (GET_FNC (val) >= FNC_XFER);
|
||||
if (cs1dt && ((mbp->cs1 & CS1_DONE) == 0)) /* dt, done clr? */
|
||||
if (cs1dt && ((massbus[mb].cs1 & CS1_DONE) == 0)) /* dt, done clr? */
|
||||
mba_set_cs2 (CS2_PGE, mb); /* prgm error */
|
||||
else {
|
||||
r = mbregW[mb] (val & 077, ofs, drv); /* write dev CS1 */
|
||||
if (r == MBE_NXD) mba_set_cs2 (CS2_NED, mb); /* nx drive? */
|
||||
else if (r == MBE_NXR) return SCPE_NXM; /* nx reg? */
|
||||
else if (cs1dt && (r == SCPE_OK)) { /* xfer, no err? */
|
||||
mbp->cs1 &= ~(CS1_TRE | CS1_MCPE | CS1_DONE);
|
||||
mbp->cs2 &= ~CS2_ERR; /* clear errors */
|
||||
mbp->cs3 &= ~(CS3_ERR | CS3_DBL);
|
||||
massbus[mb].cs1 &= ~(CS1_TRE | CS1_MCPE | CS1_DONE);
|
||||
massbus[mb].cs2 &= ~CS2_ERR; /* clear errors */
|
||||
massbus[mb].cs3 &= ~(CS3_ERR | CS3_DBL);
|
||||
}
|
||||
}
|
||||
}
|
||||
mbp->cs3 = (mbp->cs3 & ~CS1_IE) | /* update CS3 */
|
||||
(mbp->cs1 & CS1_IE);
|
||||
mbp->bae = (mbp->bae & ~CS1_M_UAE) | /* update BAE */
|
||||
((mbp->cs1 >> CS1_V_UAE) & CS1_M_UAE);
|
||||
massbus[mb].cs3 = (massbus[mb].cs3 & ~CS1_IE) | /* update CS3 */
|
||||
(massbus[mb].cs1 & CS1_IE);
|
||||
massbus[mb].bae = (massbus[mb].bae & ~CS1_M_UAE) | /* update BAE */
|
||||
((massbus[mb].cs1 >> CS1_V_UAE) & CS1_M_UAE);
|
||||
break;
|
||||
|
||||
case WC_OF: /* WC */
|
||||
if (access == WRITEB) val = (pa & 1)?
|
||||
(mbp->wc & 0377) | (val << 8): (mbp->wc & ~0377) | val;
|
||||
mbp->wc = val;
|
||||
(massbus[mb].wc & 0377) | (val << 8):
|
||||
(massbus[mb].wc & ~0377) | val;
|
||||
massbus[mb].wc = val;
|
||||
break;
|
||||
|
||||
case BA_OF: /* BA */
|
||||
if (access == WRITEB) val = (pa & 1)?
|
||||
(mbp->ba & 0377) | (val << 8): (mbp->ba & ~0377) | val;
|
||||
mbp->ba = val & ~BA_MBZ;
|
||||
(massbus[mb].ba & 0377) | (val << 8):
|
||||
(massbus[mb].ba & ~0377) | val;
|
||||
massbus[mb].ba = val & ~BA_MBZ;
|
||||
break;
|
||||
|
||||
case CS2_OF: /* CS2 */
|
||||
if ((access == WRITEB) && (pa & 1)) val = val << 8;
|
||||
if (val & CS2_CLR) mba_reset (devmap[mb]); /* init? */
|
||||
if (val & CS2_CLR) mba_reset (&mba_dev[mb]); /* init? */
|
||||
else {
|
||||
if ((val & ~mbp->cs2) & (CS2_PE | CS2_MXF))
|
||||
if ((val & ~massbus[mb].cs2) & (CS2_PE | CS2_MXF))
|
||||
cs1f = CS1_SC; /* diagn intr */
|
||||
if (access == WRITEB) val = (mbp->cs2 & /* merge val */
|
||||
if (access == WRITEB) val = (massbus[mb].cs2 & /* merge val */
|
||||
((pa & 1)? 0377: 0177400)) | val;
|
||||
mbp->cs2 = (mbp->cs2 & ~CS2_RW) |
|
||||
massbus[mb].cs2 = (massbus[mb].cs2 & ~CS2_RW) |
|
||||
(val & CS2_RW) | CS2_IR | CS2_OR;
|
||||
}
|
||||
break;
|
||||
|
||||
case DB_OF: /* DB */
|
||||
if (access == WRITEB) val = (pa & 1)?
|
||||
(mbp->db & 0377) | (val << 8): (mbp->db & ~0377) | val;
|
||||
mbp->db = val;
|
||||
(massbus[mb].db & 0377) | (val << 8):
|
||||
(massbus[mb].db & ~0377) | val;
|
||||
massbus[mb].db = val;
|
||||
break;
|
||||
|
||||
case BAE_OF: /* BAE */
|
||||
if ((access == WRITEB) && (pa & 1)) break;
|
||||
mbp->bae = val & ~AE_MBZ;
|
||||
mbp->cs1 = (mbp->cs1 & ~CS1_UAE) | /* update CS1 */
|
||||
((mbp->bae << CS1_V_UAE) & CS1_UAE);
|
||||
massbus[mb].bae = val & ~AE_MBZ;
|
||||
massbus[mb].cs1 = (massbus[mb].cs1 & ~CS1_UAE) | /* update CS1 */
|
||||
((massbus[mb].bae << CS1_V_UAE) & CS1_UAE);
|
||||
break;
|
||||
|
||||
case CS3_OF: /* CS3 */
|
||||
if ((access == WRITEB) && (pa & 1)) break;
|
||||
mbp->cs3 = (mbp->cs3 & ~CS3_RW) | (val & CS3_RW);
|
||||
mbp->cs1 = (mbp->cs1 & ~CS1_IE) | /* update CS1 */
|
||||
(mbp->cs3 & CS1_IE);
|
||||
massbus[mb].cs3 = (massbus[mb].cs3 & ~CS3_RW) | (val & CS3_RW);
|
||||
massbus[mb].cs1 = (massbus[mb].cs1 & ~CS1_IE) | /* update CS1 */
|
||||
(massbus[mb].cs3 & CS1_IE);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -474,15 +471,13 @@ return SCPE_OK;
|
||||
|
||||
int32 mba_rdbufW (uint32 mb, int32 bc, uint16 *buf)
|
||||
{
|
||||
MBACTX *mbp;
|
||||
int32 i, j, ba, mbc, pbc;
|
||||
uint32 pa;
|
||||
|
||||
bc = bc & ~1; /* bc even */
|
||||
if (mb >= MBA_NUM) return 0; /* valid MBA? */
|
||||
mbp = ctxmap[mb]; /* get context */
|
||||
ba = (mbp->bae << 16) | mbp->ba; /* get busaddr */
|
||||
mbc = (0200000 - mbp->wc) << 1; /* MB byte count */
|
||||
ba = (massbus[mb].bae << 16) | massbus[mb].ba; /* get busaddr */
|
||||
mbc = (0200000 - massbus[mb].wc) << 1; /* MB byte count */
|
||||
if (bc > mbc) bc = mbc; /* use smaller */
|
||||
for (i = 0; i < bc; i = i + pbc) { /* loop by pages */
|
||||
if (RH11 && cpu_bme) pa = Map_Addr (ba); /* map addr */
|
||||
@@ -495,31 +490,29 @@ for (i = 0; i < bc; i = i + pbc) { /* loop by pages */
|
||||
if (pbc > (bc - i)) pbc = bc - i; /* limit to rem xfr */
|
||||
for (j = 0; j < pbc; j = j + 2) { /* loop by words */
|
||||
*buf++ = M[pa >> 1]; /* fetch word */
|
||||
if (!(mbp->cs2 & CS2_UAI)) { /* if not inhb */
|
||||
if (!(massbus[mb].cs2 & CS2_UAI)) { /* if not inhb */
|
||||
ba = ba + 2; /* incr ba, pa */
|
||||
pa = pa + 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
mbp->wc = (mbp->wc + (bc >> 1)) & DMASK; /* update wc */
|
||||
mbp->ba = ba & DMASK; /* update ba */
|
||||
mbp->bae = (ba >> 16) & ~AE_MBZ; /* upper 6b */
|
||||
mbp->cs1 = (mbp->cs1 & ~ CS1_UAE) | /* update CS1 */
|
||||
((mbp->bae << CS1_V_UAE) & CS1_UAE);
|
||||
massbus[mb].wc = (massbus[mb].wc + (bc >> 1)) & DMASK; /* update wc */
|
||||
massbus[mb].ba = ba & DMASK; /* update ba */
|
||||
massbus[mb].bae = (ba >> 16) & ~AE_MBZ; /* upper 6b */
|
||||
massbus[mb].cs1 = (massbus[mb].cs1 & ~ CS1_UAE) | /* update CS1 */
|
||||
((massbus[mb].bae << CS1_V_UAE) & CS1_UAE);
|
||||
return i;
|
||||
}
|
||||
|
||||
int32 mba_wrbufW (uint32 mb, int32 bc, uint16 *buf)
|
||||
{
|
||||
MBACTX *mbp;
|
||||
int32 i, j, ba, mbc, pbc;
|
||||
uint32 pa;
|
||||
|
||||
bc = bc & ~1; /* bc even */
|
||||
if (mb >= MBA_NUM) return 0; /* valid MBA? */
|
||||
mbp = ctxmap[mb]; /* get context */
|
||||
ba = (mbp->bae << 16) | mbp->ba; /* get busaddr */
|
||||
mbc = (0200000 - mbp->wc) << 1; /* MB byte count */
|
||||
ba = (massbus[mb].bae << 16) | massbus[mb].ba; /* get busaddr */
|
||||
mbc = (0200000 - massbus[mb].wc) << 1; /* MB byte count */
|
||||
if (bc > mbc) bc = mbc; /* use smaller */
|
||||
for (i = 0; i < bc; i = i + pbc) { /* loop by pages */
|
||||
if (RH11 && cpu_bme) pa = Map_Addr (ba); /* map addr */
|
||||
@@ -532,31 +525,29 @@ for (i = 0; i < bc; i = i + pbc) { /* loop by pages */
|
||||
if (pbc > (bc - i)) pbc = bc - i; /* limit to rem xfr */
|
||||
for (j = 0; j < pbc; j = j + 2) { /* loop by words */
|
||||
M[pa >> 1] = *buf++; /* put word */
|
||||
if (!(mbp->cs2 & CS2_UAI)) { /* if not inhb */
|
||||
if (!(massbus[mb].cs2 & CS2_UAI)) { /* if not inhb */
|
||||
ba = ba + 2; /* incr ba, pa */
|
||||
pa = pa + 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
mbp->wc = (mbp->wc + (bc >> 1)) & DMASK; /* update wc */
|
||||
mbp->ba = ba & DMASK; /* update ba */
|
||||
mbp->bae = (ba >> 16) & ~AE_MBZ; /* upper 6b */
|
||||
mbp->cs1 = (mbp->cs1 & ~ CS1_UAE) | /* update CS1 */
|
||||
((mbp->bae << CS1_V_UAE) & CS1_UAE);
|
||||
massbus[mb].wc = (massbus[mb].wc + (bc >> 1)) & DMASK; /* update wc */
|
||||
massbus[mb].ba = ba & DMASK; /* update ba */
|
||||
massbus[mb].bae = (ba >> 16) & ~AE_MBZ; /* upper 6b */
|
||||
massbus[mb].cs1 = (massbus[mb].cs1 & ~ CS1_UAE) | /* update CS1 */
|
||||
((massbus[mb].bae << CS1_V_UAE) & CS1_UAE);
|
||||
return i;
|
||||
}
|
||||
|
||||
int32 mba_chbufW (uint32 mb, int32 bc, uint16 *buf)
|
||||
{
|
||||
MBACTX *mbp;
|
||||
int32 i, j, ba, mbc, pbc;
|
||||
uint32 pa;
|
||||
|
||||
bc = bc & ~1; /* bc even */
|
||||
if (mb >= MBA_NUM) return 0; /* valid MBA? */
|
||||
mbp = ctxmap[mb]; /* get context */
|
||||
ba = (mbp->bae << 16) | mbp->ba; /* get busaddr */
|
||||
mbc = (0200000 - mbp->wc) << 1; /* MB byte count */
|
||||
ba = (massbus[mb].bae << 16) | massbus[mb].ba; /* get busaddr */
|
||||
mbc = (0200000 - massbus[mb].wc) << 1; /* MB byte count */
|
||||
if (bc > mbc) bc = mbc; /* use smaller */
|
||||
for (i = 0; i < bc; i = i + pbc) { /* loop by pages */
|
||||
if (RH11 && cpu_bme) pa = Map_Addr (ba); /* map addr */
|
||||
@@ -568,24 +559,24 @@ for (i = 0; i < bc; i = i + pbc) { /* loop by pages */
|
||||
pbc = UBM_PAGSIZE - UBM_GETOFF (pa); /* left in page */
|
||||
if (pbc > (bc - i)) pbc = bc - i; /* limit to rem xfr */
|
||||
for (j = 0; j < pbc; j = j + 2) { /* loop by words */
|
||||
mbp->db = *buf++; /* get dev word */
|
||||
if (M[pa >> 1] != mbp->db) { /* miscompare? */
|
||||
massbus[mb].db = *buf++; /* get dev word */
|
||||
if (M[pa >> 1] != massbus[mb].db) { /* miscompare? */
|
||||
mba_set_cs2 (CS2_WCE, mb); /* set error */
|
||||
mbp->cs3 = mbp->cs3 | /* set even/odd */
|
||||
massbus[mb].cs3 = massbus[mb].cs3 | /* set even/odd */
|
||||
((pa & 1)? CS3_WCO: CS3_WCE);
|
||||
break;
|
||||
}
|
||||
if (!(mbp->cs2 & CS2_UAI)) { /* if not inhb */
|
||||
if (!(massbus[mb].cs2 & CS2_UAI)) { /* if not inhb */
|
||||
ba = ba + 2; /* incr ba, pa */
|
||||
pa = pa + 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
mbp->wc = (mbp->wc + (bc >> 1)) & DMASK; /* update wc */
|
||||
mbp->ba = ba & DMASK; /* update ba */
|
||||
mbp->bae = (ba >> 16) & ~AE_MBZ; /* upper 6b */
|
||||
mbp->cs1 = (mbp->cs1 & ~ CS1_UAE) | /* update CS1 */
|
||||
((mbp->bae << CS1_V_UAE) & CS1_UAE);
|
||||
massbus[mb].wc = (massbus[mb].wc + (bc >> 1)) & DMASK; /* update wc */
|
||||
massbus[mb].ba = ba & DMASK; /* update ba */
|
||||
massbus[mb].bae = (ba >> 16) & ~AE_MBZ; /* upper 6b */
|
||||
massbus[mb].cs1 = (massbus[mb].cs1 & ~ CS1_UAE) | /* update CS1 */
|
||||
((massbus[mb].bae << CS1_V_UAE) & CS1_UAE);
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -612,63 +603,51 @@ return;
|
||||
|
||||
int32 mba_get_bc (uint32 mb)
|
||||
{
|
||||
MBACTX *mbp;
|
||||
|
||||
if (mb >= MBA_NUM) return 0;
|
||||
mbp = ctxmap[mb];
|
||||
return ((0200000 - mbp->wc) << 1);
|
||||
return ((0200000 - massbus[mb].wc) << 1);
|
||||
}
|
||||
|
||||
int32 mba_get_csr (uint32 mb)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
DIB *dibp;
|
||||
|
||||
if (mb >= MBA_NUM) return 0;
|
||||
dptr = devmap[mb];
|
||||
dibp = (DIB *) dptr->ctxt;
|
||||
dibp = (DIB *) mba_dev[mb].ctxt;
|
||||
return dibp->ba;
|
||||
}
|
||||
|
||||
void mba_set_int (uint32 mb)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
DIB *dibp;
|
||||
|
||||
if (mb >= MBA_NUM) return;
|
||||
dptr = devmap[mb];
|
||||
dibp = (DIB *) dptr->ctxt;
|
||||
dibp = (DIB *) mba_dev[mb].ctxt;
|
||||
int_req[dibp->vloc >> 5] |= (1 << (dibp->vloc & 037));
|
||||
return;
|
||||
}
|
||||
|
||||
void mba_clr_int (uint32 mb)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
DIB *dibp;
|
||||
|
||||
if (mb >= MBA_NUM) return;
|
||||
dptr = devmap[mb];
|
||||
dibp = (DIB *) dptr->ctxt;
|
||||
dibp = (DIB *) mba_dev[mb].ctxt;
|
||||
int_req[dibp->vloc >> 5] &= ~(1 << (dibp->vloc & 037));
|
||||
return;
|
||||
}
|
||||
|
||||
void mba_upd_cs1 (uint32 set, uint32 clr, uint32 mb)
|
||||
{
|
||||
MBACTX *mbp;
|
||||
|
||||
if (mb >= MBA_NUM) return;
|
||||
mbp = ctxmap[mb];
|
||||
if ((set & ~mbp->cs1) & CS1_DONE) /* DONE 0 to 1? */
|
||||
mbp->iff = (mbp->cs1 & CS1_IE)? 1: 0; /* CSTB INTR <- IE */
|
||||
mbp->cs1 = (mbp->cs1 & ~(clr | CS1_MCPE | CS1_MBZ | CS1_DRV)) | CS1_DVA | set;
|
||||
if (mbp->cs2 & CS2_ERR) mbp->cs1 = mbp->cs1 | CS1_TRE | CS1_SC;
|
||||
else if (mbp->cs1 & CS1_TRE) mbp->cs1 = mbp->cs1 | CS1_SC;
|
||||
if (mbp->iff ||
|
||||
((mbp->cs1 & CS1_SC) &&
|
||||
(mbp->cs1 & CS1_DONE) &&
|
||||
(mbp->cs1 & CS1_IE)))
|
||||
if ((set & ~massbus[mb].cs1) & CS1_DONE) /* DONE 0 to 1? */
|
||||
massbus[mb].iff = (massbus[mb].cs1 & CS1_IE)? 1: 0; /* CSTB INTR <- IE */
|
||||
massbus[mb].cs1 = (massbus[mb].cs1 & ~(clr | CS1_MCPE | CS1_MBZ | CS1_DRV)) | CS1_DVA | set;
|
||||
if (massbus[mb].cs2 & CS2_ERR) massbus[mb].cs1 = massbus[mb].cs1 | CS1_TRE | CS1_SC;
|
||||
else if (massbus[mb].cs1 & CS1_TRE) massbus[mb].cs1 = massbus[mb].cs1 | CS1_SC;
|
||||
if (massbus[mb].iff ||
|
||||
((massbus[mb].cs1 & CS1_SC) &&
|
||||
(massbus[mb].cs1 & CS1_DONE) &&
|
||||
(massbus[mb].cs1 & CS1_IE)))
|
||||
mba_set_int (mb);
|
||||
else mba_clr_int (mb);
|
||||
return;
|
||||
@@ -676,11 +655,8 @@ return;
|
||||
|
||||
void mba_set_cs2 (uint32 flag, uint32 mb)
|
||||
{
|
||||
MBACTX *mbp;
|
||||
|
||||
if (mb >= MBA_NUM) return;
|
||||
mbp = ctxmap[mb];
|
||||
mbp->cs2 = mbp->cs2 | flag;
|
||||
massbus[mb].cs2 = massbus[mb].cs2 | flag;
|
||||
mba_upd_cs1 (0, 0, mb);
|
||||
return;
|
||||
}
|
||||
@@ -708,12 +684,10 @@ return mba1_dib.vec; /* acknowledge */
|
||||
uint32 mba_map_pa (int32 pa, int32 *ofs)
|
||||
{
|
||||
int32 i, uo, ba, lnt;
|
||||
DEVICE *dptr;
|
||||
DIB *dibp;
|
||||
|
||||
for (i = 0; i < MBA_NUM; i++) { /* loop thru ctrls */
|
||||
dptr = devmap[i]; /* get device */
|
||||
dibp = (DIB *) dptr->ctxt; /* get DIB */
|
||||
dibp = (DIB *) mba_dev[i].ctxt; /* get DIB */
|
||||
ba = dibp->ba;
|
||||
lnt = dibp->lnt;
|
||||
if ((pa >= ba) && /* in range? */
|
||||
@@ -738,27 +712,33 @@ return -1;
|
||||
|
||||
t_stat mba_reset (DEVICE *dptr)
|
||||
{
|
||||
int32 mb;
|
||||
MBACTX *mbp;
|
||||
uint32 mb;
|
||||
|
||||
for (mb = 0; mb < MBA_NUM; mb++) {
|
||||
mbp = ctxmap[mb];
|
||||
if (dptr == devmap[mb]) break;
|
||||
}
|
||||
mb = dptr - mba_dev;
|
||||
if (mb >= MBA_NUM) return SCPE_NOFNC;
|
||||
mbp->cs1 = CS1_DONE;
|
||||
mbp->wc = 0;
|
||||
mbp->ba = 0;
|
||||
mbp->cs2 = 0;
|
||||
mbp->db = 0;
|
||||
mbp->bae= 0;
|
||||
mbp->cs3 = 0;
|
||||
mbp->iff = 0;
|
||||
massbus[mb].cs1 = CS1_DONE;
|
||||
massbus[mb].wc = 0;
|
||||
massbus[mb].ba = 0;
|
||||
massbus[mb].cs2 = 0;
|
||||
massbus[mb].db = 0;
|
||||
massbus[mb].bae= 0;
|
||||
massbus[mb].cs3 = 0;
|
||||
massbus[mb].iff = 0;
|
||||
mba_clr_int (mb);
|
||||
if (mbabort[mb]) mbabort[mb] ();
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Enable/disable Massbus adapter */
|
||||
|
||||
void mba_set_enbdis (uint32 mb, t_bool dis)
|
||||
{
|
||||
if (mb >= MBA_NUM) return; /* valid MBA? */
|
||||
if (dis) mba_dev[mb].flags |= DEV_DIS;
|
||||
else mba_dev[mb].flags &= ~DEV_DIS;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Show Massbus adapter number */
|
||||
|
||||
t_stat mba_show_num (FILE *st, UNIT *uptr, int32 val, void *desc)
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
rp RH/RP/RM moving head disks
|
||||
|
||||
21-Nov-05 RMS Enable/disable device also enables/disables Massbus adapter
|
||||
12-Nov-05 RMS Fixed DriveClear, does not clear disk address
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
18-Mar-05 RMS Added attached test to detach routine
|
||||
12-Sep-04 RMS Cloned from pdp11_rp.c
|
||||
@@ -673,8 +675,11 @@ if ((fnc != FNC_DCLR) && (rpds[drv] & DS_ERR)) { /* err & ~clear? */
|
||||
switch (fnc) { /* case on function */
|
||||
|
||||
case FNC_DCLR: /* drive clear */
|
||||
rpda[drv] = 0; /* clear disk addr */
|
||||
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 */
|
||||
case FNC_NOP: /* no operation */
|
||||
case FNC_RELEASE: /* port release */
|
||||
return SCPE_OK;
|
||||
@@ -918,6 +923,7 @@ t_stat rp_reset (DEVICE *dptr)
|
||||
int32 i;
|
||||
UNIT *uptr;
|
||||
|
||||
mba_set_enbdis (MBA_RP, rp_dev.flags & DEV_DIS);
|
||||
for (i = 0; i < RP_NUMDR; i++) {
|
||||
uptr = rp_dev.units + i;
|
||||
sim_cancel (uptr);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
rq RQDX3 disk controller
|
||||
|
||||
31-Oct-05 RMS Fixed address width for large files
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
22-Jul-05 RMS Fixed warning from Solaris C (from Doug Gwyn)
|
||||
17-Jan-05 RMS Added more RA and RD disks
|
||||
@@ -768,7 +769,7 @@ MTAB rq_mod[] = {
|
||||
|
||||
DEVICE rq_dev = {
|
||||
"RQ", rq_unit, rq_reg, rq_mod,
|
||||
RQ_NUMDR + 2, DEV_RDX, 31, 2, DEV_RDX, 16,
|
||||
RQ_NUMDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16,
|
||||
NULL, NULL, &rq_reset,
|
||||
&rq_boot, &rq_attach, &rq_detach,
|
||||
&rq_dib, DEV_FLTA | DEV_DISABLE | DEV_UBUS | DEV_QBUS | DEV_DEBUG
|
||||
@@ -837,7 +838,7 @@ REG rqb_reg[] = {
|
||||
|
||||
DEVICE rqb_dev = {
|
||||
"RQB", rqb_unit, rqb_reg, rq_mod,
|
||||
RQ_NUMDR + 2, DEV_RDX, 31, 2, DEV_RDX, 16,
|
||||
RQ_NUMDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16,
|
||||
NULL, NULL, &rq_reset,
|
||||
&rq_boot, &rq_attach, &rq_detach,
|
||||
&rqb_dib, DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS | DEV_DEBUG
|
||||
@@ -906,7 +907,7 @@ REG rqc_reg[] = {
|
||||
|
||||
DEVICE rqc_dev = {
|
||||
"RQC", rqc_unit, rqc_reg, rq_mod,
|
||||
RQ_NUMDR + 2, DEV_RDX, 31, 2, DEV_RDX, 16,
|
||||
RQ_NUMDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16,
|
||||
NULL, NULL, &rq_reset,
|
||||
&rq_boot, &rq_attach, &rq_detach,
|
||||
&rqc_dib, DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS | DEV_DEBUG
|
||||
@@ -975,7 +976,7 @@ REG rqd_reg[] = {
|
||||
|
||||
DEVICE rqd_dev = {
|
||||
"RQD", rqd_unit, rqd_reg, rq_mod,
|
||||
RQ_NUMDR + 2, DEV_RDX, 31, 2, DEV_RDX, 16,
|
||||
RQ_NUMDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16,
|
||||
NULL, NULL, &rq_reset,
|
||||
&rq_boot, &rq_attach, &rq_detach,
|
||||
&rqd_dib, DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS | DEV_DEBUG
|
||||
@@ -1213,7 +1214,7 @@ if ((pkt == 0) && cp->pip) { /* polling? */
|
||||
} /* end if pip */
|
||||
if (cp->rspq) { /* resp q? */
|
||||
pkt = rq_deqh (cp, &cp->rspq); /* get top of q */
|
||||
if (!rq_putpkt (cp, pkt, FALSE)) return SCPE_OK; /* send to hst */
|
||||
if (!rq_putpkt (cp, pkt, FALSE)) return SCPE_OK; /* send to host */
|
||||
} /* end if resp q */
|
||||
if (pkt) sim_activate (uptr, rq_qtime); /* more to do? */
|
||||
return SCPE_OK; /* done */
|
||||
@@ -1605,7 +1606,7 @@ if ((uptr->flags & UNIT_ONL) == 0) /* not online? */
|
||||
return ST_AVL; /* only avail */
|
||||
if ((cmd != OP_ACC) && (cmd != OP_ERS) && /* 'real' xfer */
|
||||
(cp->pak[pkt].d[RW_BAL] & 1)) /* odd address? */
|
||||
return (ST_HST | SB_HST_OA); /* host buf odd */
|
||||
return (ST_HST | SB_HST_OA); /* host buf odd */
|
||||
if (bc & 1) return (ST_HST | SB_HST_OC); /* odd byte cnt? */
|
||||
if (bc & 0xF0000000) return (ST_CMD | I_BCNT); /* 'reasonable' bc? */
|
||||
/* if (lbn & 0xF0000000) return (ST_CMD | I_LBN); /* 'reasonable' lbn? */
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
tti,tto DL11 terminal input/output
|
||||
clk KW11L (and other) line frequency clock
|
||||
|
||||
22-Nov-05 RMS Revised for new terminal processing routines
|
||||
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
|
||||
07-Jul-05 RMS Removed extraneous externs
|
||||
11-Oct-04 RMS Added clock model dependencies
|
||||
@@ -63,9 +64,6 @@
|
||||
#define CLKCSR_RW (CSR_IE)
|
||||
#define CLK_DELAY 8000
|
||||
|
||||
#define UNIT_V_8B (UNIT_V_UF + 0) /* 8B */
|
||||
#define UNIT_8B (1 << UNIT_V_8B)
|
||||
|
||||
extern int32 int_req[IPL_HLVL];
|
||||
extern uint32 cpu_type;
|
||||
|
||||
@@ -123,8 +121,9 @@ REG tti_reg[] = {
|
||||
};
|
||||
|
||||
MTAB tti_mod[] = {
|
||||
{ UNIT_8B, 0 , "7b" , "7B" , &tty_set_mode },
|
||||
{ UNIT_8B, UNIT_8B , "8b" , "8B" , &tty_set_mode },
|
||||
{ TT_MODE, TT_MODE_7B, "7b", "7B", &tty_set_mode },
|
||||
{ TT_MODE, TT_MODE_8B, "8b", "8B", &tty_set_mode },
|
||||
{ TT_MODE, TT_MODE_7P, "7b", NULL, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL,
|
||||
NULL, &show_addr, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL,
|
||||
@@ -167,8 +166,9 @@ REG tto_reg[] = {
|
||||
};
|
||||
|
||||
MTAB tto_mod[] = {
|
||||
{ UNIT_8B, 0 , "7b" , "7B" , &tty_set_mode },
|
||||
{ UNIT_8B, UNIT_8B , "8b" , "8B" , &tty_set_mode },
|
||||
{ TT_MODE, TT_MODE_7B, "7b", "7B", &tty_set_mode },
|
||||
{ TT_MODE, TT_MODE_8B, "8b", "8B", &tty_set_mode },
|
||||
{ TT_MODE, TT_MODE_7P, "7p", "7P", &tty_set_mode },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL,
|
||||
NULL, &show_addr, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL,
|
||||
@@ -278,11 +278,11 @@ t_stat tti_svc (UNIT *uptr)
|
||||
{
|
||||
int32 c;
|
||||
|
||||
sim_activate (&tti_unit, tti_unit.wait); /* continue poll */
|
||||
sim_activate (uptr, uptr->wait); /* continue poll */
|
||||
if ((c = sim_poll_kbd ()) < SCPE_KFLAG) return c; /* no char or error? */
|
||||
if (c & SCPE_BREAK) tti_unit.buf = 0; /* break? */
|
||||
else tti_unit.buf = c & ((tti_unit.flags & UNIT_8B)? 0377: 0177);
|
||||
tti_unit.pos = tti_unit.pos + 1;
|
||||
if (c & SCPE_BREAK) uptr->buf = 0; /* break? */
|
||||
else uptr->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;
|
||||
@@ -347,14 +347,16 @@ t_stat tto_svc (UNIT *uptr)
|
||||
int32 c;
|
||||
t_stat r;
|
||||
|
||||
c = tto_unit.buf & ((tto_unit.flags & UNIT_8B)? 0377: 0177);
|
||||
if ((r = sim_putchar_s (c)) != SCPE_OK) { /* output; error? */
|
||||
sim_activate (uptr, uptr->wait); /* try again */
|
||||
return ((r == SCPE_STALL)? SCPE_OK: r); /* !stall? report */
|
||||
c = sim_tt_outcvt (uptr->buf, TT_GET_MODE (uptr->flags));
|
||||
if (c >= 0) {
|
||||
if ((r = sim_putchar_s (c)) != SCPE_OK) { /* output; error? */
|
||||
sim_activate (uptr, uptr->wait); /* try again */
|
||||
return ((r == SCPE_STALL)? SCPE_OK: r); /* !stall? report */
|
||||
}
|
||||
}
|
||||
tto_csr = tto_csr | CSR_DONE;
|
||||
if (tto_csr & CSR_IE) SET_INT (TTO);
|
||||
tto_unit.pos = tto_unit.pos + 1;
|
||||
uptr->pos = uptr->pos + 1;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -371,8 +373,8 @@ return SCPE_OK;
|
||||
|
||||
t_stat tty_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
tti_unit.flags = (tti_unit.flags & ~UNIT_8B) | val;
|
||||
tto_unit.flags = (tto_unit.flags & ~UNIT_8B) | val;
|
||||
tti_unit.flags = (tti_unit.flags & ~TT_MODE) | val;
|
||||
tto_unit.flags = (tto_unit.flags & ~TT_MODE) | val;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ extern DEVICE vh_dev;
|
||||
extern DEVICE rk_dev, rl_dev;
|
||||
extern DEVICE hk_dev;
|
||||
extern DEVICE rx_dev, ry_dev;
|
||||
extern DEVICE mba0_dev, mba1_dev;
|
||||
extern DEVICE mba_dev[];
|
||||
extern DEVICE rp_dev, tu_dev;
|
||||
extern DEVICE rq_dev, rqb_dev, rqc_dev, rqd_dev;
|
||||
extern DEVICE dt_dev;
|
||||
@@ -95,8 +95,8 @@ int32 sim_emax = 4;
|
||||
DEVICE *sim_devices[] = {
|
||||
&cpu_dev,
|
||||
&sys_dev,
|
||||
&mba0_dev,
|
||||
&mba1_dev,
|
||||
&mba_dev[0],
|
||||
&mba_dev[1],
|
||||
&ptr_dev,
|
||||
&ptp_dev,
|
||||
&tti_dev,
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
tm TM11/TU10 magtape
|
||||
|
||||
31-Oct-05 RMS Fixed address width for large files
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
07-Jul-05 RMS Removed extraneous externs
|
||||
18-Mar-05 RMS Added attached test to detach routine
|
||||
@@ -238,7 +239,7 @@ MTAB tm_mod[] = {
|
||||
|
||||
DEVICE tm_dev = {
|
||||
"TM", tm_unit, tm_reg, tm_mod,
|
||||
TM_NUMDR, 10, 31, 1, 8, 8,
|
||||
TM_NUMDR, 10, T_ADDR_W, 1, 8, 8,
|
||||
NULL, NULL, &tm_reset,
|
||||
&tm_boot, &tm_attach, &tm_detach,
|
||||
&tm_dib, DEV_DISABLE | DEV_UBUS | DEV_Q18 | DEV_DEBUG
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
tq TQK50 tape controller
|
||||
|
||||
31-Oct-05 RMS Fixed address width for large files
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
22-Jul-05 RMS Fixed warning from Solaris C (from Doug Gwyn)
|
||||
30-Sep-04 RMS Revised Unibus interface
|
||||
@@ -454,7 +455,7 @@ MTAB tq_mod[] = {
|
||||
|
||||
DEVICE tq_dev = {
|
||||
"TQ", tq_unit, tq_reg, tq_mod,
|
||||
TQ_NUMDR + 2, 10, 31, 1, DEV_RDX, 8,
|
||||
TQ_NUMDR + 2, 10, T_ADDR_W, 1, DEV_RDX, 8,
|
||||
NULL, NULL, &tq_reset,
|
||||
&tq_boot, &tq_attach, &tq_detach,
|
||||
&tq_dib, DEV_DISABLE | DEV_UBUS | DEV_QBUS | DEV_DEBUG
|
||||
@@ -651,7 +652,7 @@ if ((pkt == 0) && tq_pip) { /* polling? */
|
||||
} /* end if pip */
|
||||
if (tq_rspq) { /* resp q? */
|
||||
pkt = tq_deqh (&tq_rspq); /* get top of q */
|
||||
if (!tq_putpkt (pkt, FALSE)) return SCPE_OK; /* send to hst */
|
||||
if (!tq_putpkt (pkt, FALSE)) return SCPE_OK; /* send to host */
|
||||
} /* end if resp q */
|
||||
if (pkt) sim_activate (&tq_unit[TQ_QUEUE], tq_qtime); /* more to do? */
|
||||
return SCPE_OK; /* done */
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
ts TS11/TSV05 magtape
|
||||
|
||||
31-Oct-05 RMS Fixed address width for large files
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
07-Jul-05 RMS Removed extraneous externs
|
||||
18-Mar-05 RMS Added attached test to detach routine
|
||||
@@ -354,7 +355,7 @@ MTAB ts_mod[] = {
|
||||
|
||||
DEVICE ts_dev = {
|
||||
"TS", &ts_unit, ts_reg, ts_mod,
|
||||
1, 10, 31, 1, DEV_RDX, 8,
|
||||
1, 10, T_ADDR_W, 1, DEV_RDX, 8,
|
||||
NULL, NULL, &ts_reset,
|
||||
&ts_boot, &ts_attach, &ts_detach,
|
||||
&ts_dib, DEV_DISABLE | TS_DIS | DEV_UBUS | DEV_QBUS | DEV_DEBUG
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
tu TM02/TM03 magtape
|
||||
|
||||
12-Nov-05 RMS Changed default formatter to TM03 (for VMS)
|
||||
31-Oct-05 RMS Fixed address width for large files
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
31-Mar-05 RMS Fixed inaccuracies in error reporting
|
||||
18-Mar-05 RMS Added attached test to detach routine
|
||||
@@ -290,10 +292,15 @@ REG tu_reg[] = {
|
||||
|
||||
MTAB tu_mod[] = {
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "MASSBUS", "MASSBUS", NULL, &mba_show_num },
|
||||
#if defined (VM_PDP11)
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "FORMATTER", "TM02",
|
||||
&tu_set_fmtr, &tu_show_fmtr },
|
||||
{ MTAB_XTD|MTAB_VDV, 1, NULL, "TM03",
|
||||
&tu_set_fmtr, NULL },
|
||||
#else
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "FORMATTER", NULL,
|
||||
NULL, &tu_show_fmtr },
|
||||
#endif
|
||||
{ MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL },
|
||||
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL },
|
||||
{ UNIT_TYPE, UNIT_TE16, "TE16", "TE16", NULL },
|
||||
@@ -306,10 +313,10 @@ MTAB tu_mod[] = {
|
||||
|
||||
DEVICE tu_dev = {
|
||||
"TU", tu_unit, tu_reg, tu_mod,
|
||||
TU_NUMDR, 10, 31, 1, DEV_RDX, 8,
|
||||
TU_NUMDR, 10, T_ADDR_W, 1, DEV_RDX, 8,
|
||||
NULL, NULL, &tu_reset,
|
||||
&tu_boot, &tu_attach, &tu_detach,
|
||||
&tu_dib, DEV_MBUS | DEV_UBUS | DEV_QBUS | DEV_DEBUG | DEV_DISABLE | DEV_DIS_INIT
|
||||
&tu_dib, DEV_MBUS|DEV_UBUS|DEV_QBUS|DEV_DEBUG|DEV_DISABLE|DEV_DIS_INIT|DEV_TM03
|
||||
};
|
||||
|
||||
/* Massbus register read */
|
||||
@@ -846,6 +853,7 @@ t_stat tu_reset (DEVICE *dptr)
|
||||
int32 u;
|
||||
UNIT *uptr;
|
||||
|
||||
mba_set_enbdis (MBA_TU, tu_dev.flags & DEV_DIS);
|
||||
tucs1 = 0;
|
||||
tufc = 0;
|
||||
tuer = 0;
|
||||
|
||||
@@ -24,28 +24,28 @@
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from the Author.
|
||||
|
||||
vh DHQ11 asynch multiplexor for SIMH
|
||||
vh DHQ11 asynch multiplexor for SIMH
|
||||
|
||||
07-Jul-05 RMS Removed extraneous externs
|
||||
15-Jun-05 RMS Revised for new autoconfigure interface
|
||||
Fixed bug in vector display routine
|
||||
12-Jun-04 RMS Repair MS2SIMH macro to avoid divide by 0 bug
|
||||
08-Jun-04 JAD Repair vh_dev initialization; remove unused
|
||||
variables, cast to avoid conversion confusion
|
||||
07-Jun-04 JAD Complete function prototypes of forward declarations.
|
||||
Repair broken prototypes of vh_rd() and vh_wr()
|
||||
Explicitly size integer declarations
|
||||
4-Jun-04 JAD Preliminary code: If operating in a PDP-11 Unibus
|
||||
environment, force DHU mode
|
||||
29-May-04 JAD Make certain RX.TIMER is within allowable range
|
||||
25-May-04 JAD All time-based operations are scaled by tmxr_poll units
|
||||
23-May-04 JAD Change to fifo_get() and dq_tx_report() to avoid
|
||||
gratuitous stack manipulation
|
||||
20-May-04 JAD Made modem control and auto-hangup unit flags
|
||||
19-May-04 JAD Fix problem with modem status where the line number
|
||||
was not being included
|
||||
12-May-04 JAD Revised for updated tmxr interfaces
|
||||
28-Jan-04 JAD Original creation and testing
|
||||
07-Jul-05 RMS Removed extraneous externs
|
||||
15-Jun-05 RMS Revised for new autoconfigure interface
|
||||
Fixed bug in vector display routine
|
||||
12-Jun-04 RMS Repair MS2SIMH macro to avoid divide by 0 bug
|
||||
08-Jun-04 JAD Repair vh_dev initialization; remove unused
|
||||
variables, cast to avoid conversion confusion
|
||||
07-Jun-04 JAD Complete function prototypes of forward declarations.
|
||||
Repair broken prototypes of vh_rd() and vh_wr()
|
||||
Explicitly size integer declarations
|
||||
4-Jun-04 JAD Preliminary code: If operating in a PDP-11 Unibus
|
||||
environment, force DHU mode
|
||||
29-May-04 JAD Make certain RX.TIMER is within allowable range
|
||||
25-May-04 JAD All time-based operations are scaled by tmxr_poll units
|
||||
23-May-04 JAD Change to fifo_get() and dq_tx_report() to avoid
|
||||
gratuitous stack manipulation
|
||||
20-May-04 JAD Made modem control and auto-hangup unit flags
|
||||
19-May-04 JAD Fix problem with modem status where the line number
|
||||
was not being included
|
||||
12-May-04 JAD Revised for updated tmxr interfaces
|
||||
28-Jan-04 JAD Original creation and testing
|
||||
|
||||
I/O Page Registers
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* pdp11_xq.c: DEQNA/DELQA ethernet controller simulator
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2002-2005, David T. Hittner
|
||||
Copyright (c) 2002-2006, David T. Hittner
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -66,6 +66,7 @@
|
||||
|
||||
Modification history:
|
||||
|
||||
07-Jan-06 RMS Fixed unaligned access bugs (found by Doug Carman)
|
||||
07-Sep-05 DTH Removed unused variable
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
01-Dec-04 DTH Added runtime attach prompt
|
||||
@@ -274,16 +275,18 @@ UNIT xqa_unit[] = {
|
||||
};
|
||||
|
||||
REG xqa_reg[] = {
|
||||
{ GRDATA ( SA0, xqa.addr[0], XQ_RDX, 16, 0), REG_RO},
|
||||
{ GRDATA ( SA1, xqa.addr[1], XQ_RDX, 16, 0), REG_RO},
|
||||
{ GRDATA ( SA2, xqa.addr[2], XQ_RDX, 16, 0), REG_RO},
|
||||
{ GRDATA ( SA3, xqa.addr[3], XQ_RDX, 16, 0), REG_RO},
|
||||
{ GRDATA ( SA4, xqa.addr[4], XQ_RDX, 16, 0), REG_RO},
|
||||
{ GRDATA ( SA5, xqa.addr[5], XQ_RDX, 16, 0), REG_RO},
|
||||
{ GRDATA ( RBDL, xqa.rbdl, XQ_RDX, 32, 0) },
|
||||
{ GRDATA ( XBDL, xqa.xbdl, XQ_RDX, 32, 0) },
|
||||
{ GRDATA ( VAR, xqa.var, XQ_RDX, 16, 0) },
|
||||
{ GRDATA ( CSR, xqa.csr, XQ_RDX, 16, 0) },
|
||||
{ GRDATA ( SA0, xqa.addr[0], XQ_RDX, 8, 0), REG_RO|REG_FIT},
|
||||
{ GRDATA ( SA1, xqa.addr[1], XQ_RDX, 8, 0), REG_RO|REG_FIT},
|
||||
{ GRDATA ( SA2, xqa.addr[2], XQ_RDX, 8, 0), REG_RO|REG_FIT},
|
||||
{ GRDATA ( SA3, xqa.addr[3], XQ_RDX, 8, 0), REG_RO|REG_FIT},
|
||||
{ GRDATA ( SA4, xqa.addr[4], XQ_RDX, 8, 0), REG_RO|REG_FIT},
|
||||
{ GRDATA ( SA5, xqa.addr[5], XQ_RDX, 8, 0), REG_RO|REG_FIT},
|
||||
{ GRDATA ( RBDL, xqa.rbdl[0], XQ_RDX, 16, 0), REG_FIT },
|
||||
{ GRDATA ( RBDH, xqa.rbdl[1], XQ_RDX, 16, 0), REG_FIT },
|
||||
{ GRDATA ( XBDL, xqa.xbdl[0], XQ_RDX, 16, 0), REG_FIT },
|
||||
{ GRDATA ( XBDH, xqa.xbdl[1], XQ_RDX, 16, 0), REG_FIT },
|
||||
{ GRDATA ( VAR, xqa.var, XQ_RDX, 16, 0), REG_FIT },
|
||||
{ GRDATA ( CSR, xqa.csr, XQ_RDX, 16, 0), REG_FIT },
|
||||
{ FLDATA ( INT, xqa.irq, 0) },
|
||||
{ GRDATA ( SETUP_PRM, xqa.setup.promiscuous, XQ_RDX, 32, 0), REG_HRO},
|
||||
{ GRDATA ( SETUP_MLT, xqa.setup.multicast, XQ_RDX, 32, 0), REG_HRO},
|
||||
|
||||
285
PDP11/pdp11_xu.c
285
PDP11/pdp11_xu.c
@@ -40,6 +40,11 @@
|
||||
Testing performed:
|
||||
1) Receives/Transmits single packet under custom RSX driver
|
||||
2) Passes RSTS 10.1 controller diagnostics during boot
|
||||
3) VMS 7.2 on VAX780 summary:
|
||||
LAT - Runs properly both in and out
|
||||
DECNET - Starts without error, but will not do anything
|
||||
TCP/IP - Starts with errors, will ping in/out but nothing else
|
||||
Clustering - Not tested
|
||||
|
||||
Known issues:
|
||||
1) Transmit/Receive rings have not been thoroughly tested,
|
||||
@@ -52,6 +57,8 @@
|
||||
|
||||
Modification history:
|
||||
|
||||
08-Dec-05 DTH Implemented ancilliary functions 022/023/024/025
|
||||
18-Nov-05 DTH Corrected time between system ID packets
|
||||
07-Sep-05 DTH Corrected runt packet processing (found by Tim Chapman),
|
||||
Removed unused variable
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
@@ -76,7 +83,7 @@
|
||||
|
||||
#include "pdp11_xu.h"
|
||||
|
||||
extern int32 tmr_poll, clk_tps;
|
||||
extern int32 tmr_poll, clk_tps, cpu_astop;
|
||||
extern FILE *sim_log;
|
||||
|
||||
t_stat xu_rd(int32* data, int32 PA, int32 access);
|
||||
@@ -101,6 +108,8 @@ void xub_write_callback(int status);
|
||||
void xu_setint (CTLR* xu);
|
||||
void xu_clrint (CTLR* xu);
|
||||
void xu_process_receive(CTLR* xu);
|
||||
void xu_dump_rxring(CTLR* xu);
|
||||
void xu_dump_txring(CTLR* xu);
|
||||
|
||||
DIB xua_dib = { IOBA_XU, IOLN_XU, &xu_rd, &xu_wr,
|
||||
1, IVCL (XU), VEC_XU, {&xu_int} };
|
||||
@@ -144,6 +153,7 @@ DEBTAB xu_debug[] = {
|
||||
{"TRACE", DBG_TRC},
|
||||
{"WARN", DBG_WRN},
|
||||
{"REG", DBG_REG},
|
||||
{"PACKET", DBG_PCK},
|
||||
{"ETH", DBG_ETH},
|
||||
{0}
|
||||
};
|
||||
@@ -463,7 +473,7 @@ t_stat xu_svc(UNIT* uptr)
|
||||
if (--xu->var->idtmr <= 0) {
|
||||
if ((xu->var->mode & MODE_DMNT) == 0) /* if maint msg is not disabled */
|
||||
status = xu_system_id(xu, mop_multicast, 0); /* then send ID packet */
|
||||
xu->var->idtmr = XU_ID_TIMER_VAL; /* reset timer */
|
||||
xu->var->idtmr = XU_ID_TIMER_VAL * one_second; /* reset timer */
|
||||
}
|
||||
|
||||
/* has one second timer expired? if so, update stats and reset timer */
|
||||
@@ -517,11 +527,17 @@ t_stat xu_sw_reset (CTLR* xu)
|
||||
sim_debug(DBG_TRC, xu->dev, "xu_sw_reset()\n");
|
||||
|
||||
/* Clear the registers. */
|
||||
xu->var->pcsr0 = 0;
|
||||
xu->var->pcsr0 = PCSR0_DNI | PCSR0_INTR;
|
||||
xu->var->pcsr1 = STATE_READY;
|
||||
switch (xu->var->type) {
|
||||
case XU_T_DELUA: xu->var->pcsr1 |= TYPE_DELUA; break;
|
||||
case XU_T_DEUNA: xu->var->pcsr1 |= TYPE_DEUNA; break;
|
||||
case XU_T_DELUA:
|
||||
xu->var->pcsr1 |= TYPE_DELUA;
|
||||
break;
|
||||
case XU_T_DEUNA:
|
||||
xu->var->pcsr1 |= TYPE_DEUNA;
|
||||
if (!xu->var->etherface) /* if not attached, set transceiver powerfail */
|
||||
xu->var->pcsr1 |= PCSR1_XPWR;
|
||||
break;
|
||||
}
|
||||
xu->var->pcsr2 = 0;
|
||||
xu->var->pcsr3 = 0;
|
||||
@@ -554,6 +570,9 @@ t_stat xu_sw_reset (CTLR* xu)
|
||||
sim_activate(&xu->unit[0], one_second/XU_SERVICE_INTERVAL);
|
||||
}
|
||||
|
||||
/* clear load_server address */
|
||||
memset(xu->var->load_server, 0, sizeof(ETH_MAC));
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -563,6 +582,7 @@ t_stat xu_reset(DEVICE* dptr)
|
||||
t_stat status;
|
||||
CTLR* xu = xu_dev2ctlr(dptr);
|
||||
|
||||
sim_debug(DBG_TRC, xu->dev, "xu_reset()\n");
|
||||
/* init read queue (first time only) */
|
||||
status = ethq_init (&xu->var->ReadQ, XU_QUE_MAX);
|
||||
if (status != SCPE_OK)
|
||||
@@ -574,15 +594,19 @@ t_stat xu_reset(DEVICE* dptr)
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Perform one of the defined ancillary functions. */
|
||||
int32 xu_command(CTLR* xu)
|
||||
{
|
||||
uint32 udbb;
|
||||
int fnc, mtlen;
|
||||
uint16 value;
|
||||
uint16 value, pltlen;
|
||||
t_stat status, rstatus, wstatus, wstatus2, wstatus3;
|
||||
struct xu_stats* stats = &xu->var->stats;
|
||||
uint16* udb = xu->var->udb;
|
||||
uint16* mac_w = (uint16*) xu->var->mac;
|
||||
static const ETH_MAC zeros = {0,0,0,0,0,0};
|
||||
static const ETH_MAC mcast_load_server = {0xAB, 0x00, 0x00, 0x01, 0x00, 0x00};
|
||||
static char* command[] = {
|
||||
"NO-OP",
|
||||
"Start Microaddress",
|
||||
@@ -610,11 +634,12 @@ int32 xu_command(CTLR* xu)
|
||||
|
||||
/* Grab the PCB from the host. */
|
||||
rstatus = Map_ReadW(xu->var->pcbb, 8, xu->var->pcb);
|
||||
if (rstatus != SCPE_OK)
|
||||
if (rstatus != 0)
|
||||
return PCSR0_PCEI + 1;
|
||||
|
||||
/* High 8 bits are defined as MBZ. */
|
||||
if (xu->var->pcb[0] & 0177400) return PCSR0_PCEI;
|
||||
if (xu->var->pcb[0] & 0177400)
|
||||
return PCSR0_PCEI;
|
||||
|
||||
/* Decode the function to be performed. */
|
||||
fnc = xu->var->pcb[0] & 0377;
|
||||
@@ -625,28 +650,31 @@ int32 xu_command(CTLR* xu)
|
||||
break;
|
||||
|
||||
case FC_RDPA: /* read default physical address */
|
||||
wstatus = Map_WriteW(xu->var->pcbb + 2, 6, (uint16*)xu->var->mac);
|
||||
if (wstatus != SCPE_OK)
|
||||
wstatus = Map_WriteB(xu->var->pcbb + 2, 6, xu->var->mac);
|
||||
if (wstatus)
|
||||
return PCSR0_PCEI + 1;
|
||||
break;
|
||||
|
||||
case FC_RPA: /* read current physical address */
|
||||
wstatus = Map_WriteW(xu->var->pcbb + 2, 6, (uint16*)&xu->var->setup.macs[0]);
|
||||
if (wstatus != SCPE_OK)
|
||||
wstatus = Map_WriteB(xu->var->pcbb + 2, 6, (uint8*)&xu->var->setup.macs[0]);
|
||||
if (wstatus)
|
||||
return PCSR0_PCEI + 1;
|
||||
break;
|
||||
|
||||
case FC_WPA: /* write current physical address */
|
||||
rstatus = Map_ReadW(xu->var->pcbb + 2, 6, (uint16*)&xu->var->setup.macs[0]);
|
||||
if (xu->var->pcb[1] & 1) return PCSR0_PCEI;
|
||||
rstatus = Map_ReadB(xu->var->pcbb + 2, 6, (uint8*)&xu->var->setup.macs[0]);
|
||||
if (xu->var->pcb[1] & 1)
|
||||
return PCSR0_PCEI;
|
||||
break;
|
||||
|
||||
case FC_WMAL: /* write multicast address list */
|
||||
mtlen = (xu->var->pcb[2] & 0xFF00) >> 8;
|
||||
if (mtlen > 10) return PCSR0_PCEI;
|
||||
sim_debug(DBG_TRC, xu->dev, "FC_WAL: mtlen=%d\n", mtlen);
|
||||
if (mtlen > 10)
|
||||
return PCSR0_PCEI;
|
||||
udbb = xu->var->pcb[1] | ((xu->var->pcb[2] & 03) << 16);
|
||||
rstatus = Map_ReadW(udbb, mtlen * 6, (uint16*) &xu->var->setup.macs[1]);
|
||||
if (rstatus == SCPE_OK) {
|
||||
rstatus = Map_ReadB(udbb, mtlen * 6, (uint8*) &xu->var->setup.macs[1]);
|
||||
if (rstatus == 0) {
|
||||
xu->var->setup.mac_count = mtlen + 1;
|
||||
status = eth_filter (xu->var->etherface, xu->var->setup.mac_count,
|
||||
xu->var->setup.macs, xu->var->setup.multicast,
|
||||
@@ -669,7 +697,7 @@ int32 xu_command(CTLR* xu)
|
||||
/* Write UDB to host memory. */
|
||||
udbb = xu->var->pcb[1] + ((xu->var->pcb[2] & 3) << 16);
|
||||
wstatus = Map_WriteW(udbb, 12, xu->var->pcb);
|
||||
if (wstatus != SCPE_OK)
|
||||
if (wstatus != 0)
|
||||
return PCSR0_PCEI+1;
|
||||
break;
|
||||
|
||||
@@ -682,7 +710,7 @@ int32 xu_command(CTLR* xu)
|
||||
/* Read UDB into local memory. */
|
||||
udbb = xu->var->pcb[1] + ((xu->var->pcb[2] & 3) << 16);
|
||||
rstatus = Map_ReadW(udbb, 12, xu->var->udb);
|
||||
if (rstatus != SCPE_OK)
|
||||
if (rstatus)
|
||||
return PCSR0_PCEI+1;
|
||||
|
||||
if ((xu->var->udb[0] & 1) || (xu->var->udb[1] & 0374) ||
|
||||
@@ -699,6 +727,9 @@ int32 xu_command(CTLR* xu)
|
||||
xu->var->rrlen = xu->var->udb[5];
|
||||
xu->var->rxnext = 0;
|
||||
xu->var->txnext = 0;
|
||||
xu_dump_rxring(xu);
|
||||
xu_dump_txring(xu);
|
||||
/*cpu_astop=1;*/
|
||||
break;
|
||||
|
||||
case FC_RDCTR: /* read counters */
|
||||
@@ -745,7 +776,7 @@ int32 xu_command(CTLR* xu)
|
||||
/* transfer udb to host */
|
||||
udbb = xu->var->pcb[1] + ((xu->var->pcb[2] & 3) << 16);
|
||||
wstatus = Map_WriteW(udbb, 68, xu->var->udb);
|
||||
if (wstatus != SCPE_OK) {
|
||||
if (wstatus) {
|
||||
xu->var->pcsr0 |= PCSR0_PCEI;
|
||||
}
|
||||
|
||||
@@ -757,13 +788,14 @@ int32 xu_command(CTLR* xu)
|
||||
case FC_RMODE: /* read mode register */
|
||||
value = xu->var->mode;
|
||||
wstatus = Map_WriteW(xu->var->pcbb+2, 2, &value);
|
||||
if (wstatus != SCPE_OK)
|
||||
if (wstatus)
|
||||
return PCSR0_PCEI + 1;
|
||||
break;
|
||||
|
||||
case FC_WMODE: /* write mode register */
|
||||
value = xu->var->mode;
|
||||
xu->var->mode = xu->var->pcb[1];
|
||||
sim_debug(DBG_TRC, xu->dev, "FC_WMODE: mode=%04x\n", xu->var->mode);
|
||||
|
||||
/* set promiscuous and multicast flags */
|
||||
xu->var->setup.promiscuous = (xu->var->mode & MODE_PROM) ? 1 : 0;
|
||||
@@ -784,13 +816,79 @@ int32 xu_command(CTLR* xu)
|
||||
wstatus2 = Map_WriteW(xu->var->pcbb+4, 2, &value);
|
||||
value = 32;
|
||||
wstatus3 = Map_WriteW(xu->var->pcbb+6, 2, &value);
|
||||
if ((wstatus != SCPE_OK) || (wstatus2 != SCPE_OK) || (wstatus3 != SCPE_OK))
|
||||
if (wstatus + wstatus2 + wstatus3)
|
||||
return PCSR0_PCEI + 1;
|
||||
|
||||
if (fnc == FC_RCSTAT)
|
||||
xu->var->stat &= 0377; /* clear high byte */
|
||||
break;
|
||||
|
||||
case FC_RSID: /* read system id parameters */
|
||||
/* prepare udb for transfer */
|
||||
memset(xu->var->udb, 0, sizeof(xu->var->udb));
|
||||
|
||||
udb[11] = 0x260; /* type */
|
||||
udb[12] = 28/* + parameter size */; /* ccount */
|
||||
udb[13] = 7; /* code */
|
||||
udb[14] = 0; /* recnum */
|
||||
/* mop information */
|
||||
udb[15] = 1; /* mvtype */
|
||||
udb[16] = 0x0303; /* mvver + mvlen */
|
||||
udb[17] = 0; /* mvueco + mveco */
|
||||
/* function information */
|
||||
udb[18] = 2; /* ftype */
|
||||
udb[19] = 0x0502; /* fval1 + flen */
|
||||
udb[20] = 0x0700; /* hatype<07:00> + fval2 */
|
||||
udb[21] = 0x0600; /* halen + hatype<15:08> */
|
||||
/* built-in MAC address */
|
||||
udb[21] = mac_w[0]; /* HA<15:00> */
|
||||
udb[22] = mac_w[1]; /* HA<31:16> */
|
||||
udb[23] = mac_w[2]; /* HA<47:32> */
|
||||
udb[24] = 0x64; /* dtype */
|
||||
udb[25] = (11 << 8) + 1; /* dvalue + dlen */
|
||||
|
||||
/* transfer udb to host */
|
||||
udbb = xu->var->pcb[1] + ((xu->var->pcb[2] & 3) << 16);
|
||||
wstatus = Map_WriteW(udbb, 52, xu->var->udb);
|
||||
if (wstatus)
|
||||
xu->var->pcsr0 |= PCSR0_PCEI;
|
||||
break;
|
||||
|
||||
case FC_WSID: /* write system id parameters */
|
||||
/* get udb base */
|
||||
udbb = xu->var->pcb[1] + ((xu->var->pcb[2] & 3) << 16);
|
||||
/* get udb length */
|
||||
pltlen = xu->var->pcb[3];
|
||||
|
||||
/* transfer udb from host */
|
||||
rstatus = Map_ReadW(udbb, pltlen * 2, xu->var->udb);
|
||||
if (rstatus)
|
||||
return PCSR0_PCEI + 1;
|
||||
|
||||
/* decode and store system ID fields , if we ever need to.
|
||||
for right now, just return "success" */
|
||||
|
||||
break;
|
||||
|
||||
case FC_RLSA: /* read load server address */
|
||||
if (memcmp(xu->var->load_server, zeros, sizeof(ETH_MAC))) {
|
||||
/* not set, use default multicast load address */
|
||||
wstatus = Map_WriteB(xu->var->pcbb + 2, 6, (uint8*) mcast_load_server);
|
||||
} else {
|
||||
/* is set, use load_server */
|
||||
wstatus = Map_WriteB(xu->var->pcbb + 2, 6, xu->var->load_server);
|
||||
}
|
||||
if (wstatus)
|
||||
return PCSR0_PCEI + 1;
|
||||
break;
|
||||
|
||||
|
||||
case FC_WLSA: /* write load server address */
|
||||
rstatus = Map_ReadB(xu->var->pcbb + 2, 6, xu->var->load_server);
|
||||
if (rstatus)
|
||||
return PCSR0_PCEI + 1;
|
||||
break;
|
||||
|
||||
default: /* Unknown (unimplemented) command. */
|
||||
printf("%s: unknown ancilliary command 0%o requested !\n", xu->dev->name, fnc);
|
||||
return PCSR0_PCEI;
|
||||
@@ -813,6 +911,8 @@ void xu_process_receive(CTLR* xu)
|
||||
|
||||
sim_debug(DBG_TRC, xu->dev, "xu_process_receive(), buffers: %d\n", xu->var->rrlen);
|
||||
|
||||
/* xu_dump_rxring(xu); /* debug receive ring */
|
||||
|
||||
/* process only when in the running state, and host buffers are available */
|
||||
if ((state != STATE_RUNNING) || no_buffers)
|
||||
return;
|
||||
@@ -839,7 +939,7 @@ void xu_process_receive(CTLR* xu)
|
||||
/* if buffer not owned by controller, exit [at end of ring] */
|
||||
if (!(xu->var->rxhdr[2] & RXR_OWN)) {
|
||||
/* tell the host there are no more buffers */
|
||||
xu->var->pcsr0 |= PCSR0_RCBI;
|
||||
/* xu->var->pcsr0 |= PCSR0_RCBI; */ /* I don't think this is correct 08-dec-2005 dth */
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -881,7 +981,7 @@ void xu_process_receive(CTLR* xu)
|
||||
}
|
||||
|
||||
/* figure out chained packet size */
|
||||
wlen = item->packet.len - item->packet.used;
|
||||
wlen = item->packet.crc_len - item->packet.used;
|
||||
if (wlen > slen)
|
||||
wlen = slen;
|
||||
|
||||
@@ -899,7 +999,7 @@ void xu_process_receive(CTLR* xu)
|
||||
off += wlen;
|
||||
|
||||
/* Is this the end-of-frame? */
|
||||
if (item->packet.used == item->packet.len) {
|
||||
if (item->packet.used == item->packet.crc_len) {
|
||||
/* mark end-of-frame */
|
||||
xu->var->rxhdr[2] |= RXR_ENF;
|
||||
|
||||
@@ -918,9 +1018,14 @@ void xu_process_receive(CTLR* xu)
|
||||
* size is only 1514, not 1518, I doubt the CRC is actually
|
||||
* transferred in normal mode. Maybe CRC is transferred
|
||||
* and used in Loopback mode.. -- DTH
|
||||
*
|
||||
* The VMS XEDRIVER indicates that CRC is transferred as
|
||||
* part of the packet, and is included in the MLEN count. -- DTH
|
||||
*/
|
||||
xu->var->rxhdr[3] &= ~RXR_MLEN;
|
||||
xu->var->rxhdr[3] |= (item->packet.len + 4/*CRC*/);
|
||||
xu->var->rxhdr[3] |= (item->packet.crc_len);
|
||||
if (xu->var->mode & MODE_DRDC) /* data chaining disabled */
|
||||
xu->var->rxhdr[3] |= RXR_NCHN;
|
||||
|
||||
/* update stats */
|
||||
upd_stat32(&xu->var->stats.frecv, 1);
|
||||
@@ -967,6 +1072,8 @@ void xu_process_receive(CTLR* xu)
|
||||
|
||||
/* set or clear interrupt, depending on what happened */
|
||||
xu_setclrint(xu, 0);
|
||||
xu_dump_rxring(xu); /* debug receive ring */
|
||||
|
||||
}
|
||||
|
||||
void xu_process_transmit(CTLR* xu)
|
||||
@@ -976,6 +1083,7 @@ void xu_process_transmit(CTLR* xu)
|
||||
t_stat rstatus, wstatus;
|
||||
|
||||
sim_debug(DBG_TRC, xu->dev, "xu_process_transmit()\n");
|
||||
/* xu_dump_txring(xu); /* debug receive ring */
|
||||
|
||||
for (;;) {
|
||||
|
||||
@@ -1125,13 +1233,10 @@ void xu_port_command (CTLR* xu)
|
||||
};
|
||||
|
||||
sim_debug(DBG_TRC, xu->dev, "xu_port_command(), Command = %s [0%o]\n", commands[command], command);
|
||||
switch (command) {
|
||||
case CMD_NOOP: /* NO-OP */
|
||||
/* NOOP does NOT set DNI */
|
||||
break;
|
||||
|
||||
case CMD_GETPCBB: /* GET PCB-BASE */
|
||||
xu->var->pcbb = (xu->var->pcsr3 << 16) | xu->var->pcsr2;
|
||||
switch (command) { /* cases in order of most used to least used */
|
||||
case CMD_PDMD: /* POLLING DEMAND */
|
||||
/* process transmit buffers, receive buffers are done in the service timer */
|
||||
xu_process_transmit(xu);
|
||||
xu->var->pcsr0 |= PCSR0_DNI;
|
||||
break;
|
||||
|
||||
@@ -1140,6 +1245,11 @@ void xu_port_command (CTLR* xu)
|
||||
xu->var->pcsr0 |= PCSR0_DNI;
|
||||
break;
|
||||
|
||||
case CMD_GETPCBB: /* GET PCB-BASE */
|
||||
xu->var->pcbb = (xu->var->pcsr3 << 16) | xu->var->pcsr2;
|
||||
xu->var->pcsr0 |= PCSR0_DNI;
|
||||
break;
|
||||
|
||||
case CMD_SELFTEST: /* SELFTEST */
|
||||
xu_sw_reset(xu);
|
||||
xu->var->pcsr0 |= PCSR0_DNI;
|
||||
@@ -1159,21 +1269,6 @@ void xu_port_command (CTLR* xu)
|
||||
xu->var->pcsr0 |= PCSR0_PCEI;
|
||||
break;
|
||||
|
||||
case CMD_BOOT: /* BOOT */
|
||||
/* not implemented */
|
||||
msg = "%s: BOOT command not implemented!\n";
|
||||
printf (msg, xu->dev->name);
|
||||
if (sim_log) fprintf(sim_log, msg, xu->dev->name);
|
||||
|
||||
xu->var->pcsr0 |= PCSR0_PCEI;
|
||||
break;
|
||||
|
||||
case CMD_PDMD: /* POLLING DEMAND */
|
||||
/* process transmit buffers, receive buffers are done in the service timer */
|
||||
xu_process_transmit(xu);
|
||||
xu->var->pcsr0 |= PCSR0_DNI;
|
||||
break;
|
||||
|
||||
case CMD_HALT: /* HALT */
|
||||
if ((state == STATE_READY) || (state == STATE_RUNNING)) {
|
||||
sim_cancel (&xu->unit[0]); /* cancel service timer */
|
||||
@@ -1193,6 +1288,19 @@ void xu_port_command (CTLR* xu)
|
||||
xu->var->pcsr0 |= PCSR0_PCEI;
|
||||
break;
|
||||
|
||||
case CMD_BOOT: /* BOOT */
|
||||
/* not implemented */
|
||||
msg = "%s: BOOT command not implemented!\n";
|
||||
printf (msg, xu->dev->name);
|
||||
if (sim_log) fprintf(sim_log, msg, xu->dev->name);
|
||||
|
||||
xu->var->pcsr0 |= PCSR0_PCEI;
|
||||
break;
|
||||
|
||||
case CMD_NOOP: /* NO-OP */
|
||||
/* NOOP does NOT set DNI */
|
||||
break;
|
||||
|
||||
case CMD_RSV06: /* RESERVED */
|
||||
case CMD_RSV07: /* RESERVED */
|
||||
case CMD_RSV11: /* RESERVED */
|
||||
@@ -1200,8 +1308,9 @@ void xu_port_command (CTLR* xu)
|
||||
case CMD_RSV13: /* RESERVED */
|
||||
case CMD_RSV14: /* RESERVED */
|
||||
case CMD_RSV15: /* RESERVED */
|
||||
/* all reserved commands act as a no-op but set DNI */
|
||||
xu->var->pcsr0 |= PCSR0_DNI;
|
||||
break; /* all reserved commands act as a no-op but set DNI */
|
||||
break;
|
||||
} /* switch */
|
||||
|
||||
/* set interrupt if needed */
|
||||
@@ -1213,10 +1322,6 @@ t_stat xu_rd(int32 *data, int32 PA, int32 access)
|
||||
CTLR* xu = xu_pa2ctlr(PA);
|
||||
int reg = (PA >> 1) & 03;
|
||||
|
||||
sim_debug(DBG_TRC, xu->dev, "xu_rd(), PCSR%d\n", reg);
|
||||
if (PA & 1)
|
||||
sim_debug(DBG_WRN, xu->dev, "xu_rd(), Unexpected Odd address access of PCSR%d\n", reg);
|
||||
|
||||
switch (reg) {
|
||||
case 00:
|
||||
*data = xu->var->pcsr0;
|
||||
@@ -1231,6 +1336,9 @@ t_stat xu_rd(int32 *data, int32 PA, int32 access)
|
||||
*data = xu->var->pcsr3;
|
||||
break;
|
||||
}
|
||||
sim_debug(DBG_TRC, xu->dev, "xu_rd(), PCSR%d, data=%04x\n", reg, *data);
|
||||
if (PA & 1)
|
||||
sim_debug(DBG_WRN, xu->dev, "xu_rd(), Unexpected Odd address access of PCSR%d\n", reg);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -1238,10 +1346,27 @@ t_stat xu_wr(int32 data, int32 PA, int32 access)
|
||||
{
|
||||
CTLR* xu = xu_pa2ctlr(PA);
|
||||
int reg = (PA >> 1) & 03;
|
||||
char desc[10];
|
||||
|
||||
sim_debug(DBG_TRC, xu->dev, "xu_wr(), PCSR%d\n", reg);
|
||||
switch (access) {
|
||||
case WRITE :
|
||||
strcpy(desc, "Word");
|
||||
break;
|
||||
case WRITEB:
|
||||
if (PA & 1) {
|
||||
strcpy(desc, "ByteHi");
|
||||
} else {
|
||||
strcpy(desc, "ByteLo");
|
||||
}
|
||||
break;
|
||||
default :
|
||||
strcpy(desc, "Unknown");
|
||||
break;
|
||||
}
|
||||
sim_debug(DBG_TRC, xu->dev, "xu_wr(), PCSR%d, data=%08x, PA=%08x, access=%d[%s]\n", reg, data, PA, access, desc);
|
||||
switch (reg) {
|
||||
case 00:
|
||||
/* Clear write-one-to-clear interrupt bits */
|
||||
if (access == WRITEB) {
|
||||
data &= 0377;
|
||||
if (PA & 1) {
|
||||
@@ -1252,20 +1377,27 @@ t_stat xu_wr(int32 data, int32 PA, int32 access)
|
||||
xu_setclrint(xu, 0);
|
||||
|
||||
/* Bail out early to avoid PCMD crap. */
|
||||
break;
|
||||
return SCPE_OK;
|
||||
}
|
||||
} else { /* access == WRITE [Word] */
|
||||
uint16 mask = data & 0xFF00; /* only interested in high byte */
|
||||
xu->var->pcsr0 &= ~mask; /* clear write-one-to-clear bits */
|
||||
}
|
||||
/* RESET function requested? */
|
||||
if (data & PCSR0_RSET) {
|
||||
xu_sw_reset(xu);
|
||||
xu->var->pcsr0 |= PCSR0_DNI;
|
||||
xu_setclrint(xu, 0);
|
||||
return SCPE_OK;
|
||||
return SCPE_OK; /* nothing else to do on reset */
|
||||
}
|
||||
/* Nope. Handle the INTE interlock thingie. */
|
||||
/* Handle the INTE interlock; if INTE changes state, no commands can occur */
|
||||
if ((xu->var->pcsr0 ^ data) & PCSR0_INTE) {
|
||||
xu->var->pcsr0 ^= PCSR0_INTE;
|
||||
xu->var->pcsr0 |= PCSR0_DNI;
|
||||
if (xu->var->pcsr0 & PCSR0_INTE) {
|
||||
sim_debug(DBG_TRC, xu->dev, "xu_wr(), Interrupts Enabled\n");
|
||||
} else {
|
||||
sim_debug(DBG_TRC, xu->dev, "xu_wr(), Interrupts Disabled\n");
|
||||
}
|
||||
} else {
|
||||
/* Normal write, no interlock. */
|
||||
xu->var->pcsr0 &= ~PCSR0_PCMD;
|
||||
@@ -1316,6 +1448,7 @@ t_stat xu_attach(UNIT* uptr, char* cptr)
|
||||
}
|
||||
uptr->filename = tptr;
|
||||
uptr->flags |= UNIT_ATT;
|
||||
eth_setcrc(xu->var->etherface, 1); /* enable CRC */
|
||||
|
||||
/* reset the device with the new attach info */
|
||||
xu_reset(xu->dev);
|
||||
@@ -1377,3 +1510,39 @@ int32 xu_int (void)
|
||||
}
|
||||
return 0; /* no interrupt request active */
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
/ debugging routines
|
||||
/=============================================================================*/
|
||||
|
||||
void xu_dump_rxring (CTLR* xu)
|
||||
{
|
||||
int i;
|
||||
int rrlen = xu->var->rrlen;
|
||||
printf ("receive ring[%s]: base address: %08x headers: %d, header size: %d, current: %d\n", xu->dev->name, xu->var->rdrb, xu->var->rrlen, xu->var->relen, xu->var->rxnext);
|
||||
for (i=0; i<rrlen; i++) {
|
||||
uint16 rxhdr[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
|
||||
uint32 ba = xu->var->rdrb + (xu->var->relen * 2) * i;
|
||||
t_stat rstatus = Map_ReadW (ba, 8, rxhdr); /* get rxring entry[i] */
|
||||
int own = (rxhdr[2] & RXR_OWN) >> 15;
|
||||
int len = rxhdr[0];
|
||||
uint32 addr = rxhdr[1] + ((rxhdr[2] & 3) << 16);
|
||||
printf (" header[%d]: own:%d, len:%d, address:%08x data:{%04x,%04x,%04x,%04x}\n", i, own, len, addr, rxhdr[0], rxhdr[1], rxhdr[2], rxhdr[3]);
|
||||
}
|
||||
}
|
||||
|
||||
void xu_dump_txring (CTLR* xu)
|
||||
{
|
||||
int i;
|
||||
int trlen = xu->var->trlen;
|
||||
printf ("transmit ring[%s]: base address: %08x headers: %d, header size: %d, current: %d\n", xu->dev->name, xu->var->tdrb, xu->var->trlen, xu->var->telen, xu->var->txnext);
|
||||
for (i=0; i<trlen; i++) {
|
||||
uint16 txhdr[4];
|
||||
uint32 ba = xu->var->tdrb + (xu->var->telen * 2) * i;
|
||||
t_stat tstatus = Map_ReadW (ba, 8, txhdr); /* get rxring entry[i] */
|
||||
int own = (txhdr[2] & RXR_OWN) >> 15;
|
||||
int len = txhdr[0];
|
||||
uint32 addr = txhdr[1] + ((txhdr[2] & 3) << 16);
|
||||
printf (" header[%d]: own:%d, len:%d, address:%08x data:{%04x,%04x,%04x,%04x}\n", i, own, len, addr, txhdr[0], txhdr[1], txhdr[2], txhdr[3]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
Modification history:
|
||||
|
||||
08-Dec-05 DTH Added load_server, increased UDBSIZE for system ID parameters
|
||||
07-Jul-05 RMS Removed extraneous externs
|
||||
05-Jan-04 DTH Added network statistics
|
||||
31-Dec-03 DTH Added reserved states
|
||||
@@ -68,7 +69,7 @@ extern int32 int_req[IPL_HLVL];
|
||||
#define XU_FILTER_MAX 11 /* mac + 10 multicast addrs */
|
||||
#define XU_SERVICE_INTERVAL 100 /* times per second */
|
||||
#define XU_ID_TIMER_VAL 540 /* 9 min * 60 sec */
|
||||
#define UDBSIZE 100 /* max size of UDB (in words) */
|
||||
#define UDBSIZE 200 /* max size of UDB (in words) */
|
||||
|
||||
enum xu_type {XU_T_DEUNA, XU_T_DELUA};
|
||||
|
||||
@@ -124,6 +125,7 @@ struct xu_device {
|
||||
ETH_PACK read_buffer;
|
||||
ETH_PACK write_buffer;
|
||||
ETH_QUE ReadQ;
|
||||
ETH_MAC load_server; /* load server address */
|
||||
int idtmr; /* countdown for ID Timer */
|
||||
int sectmr; /* countup for one second timer */
|
||||
struct xu_setup setup;
|
||||
@@ -298,6 +300,7 @@ typedef struct xu_controller CTLR;
|
||||
#define DBG_TRC 0x0001 /* trace routine calls */
|
||||
#define DBG_REG 0x0002 /* trace read/write registers */
|
||||
#define DBG_WRN 0x0004 /* display warnings */
|
||||
#define DBG_PCK 0x0080 /* display packets */
|
||||
#define DBG_ETH 0x8000 /* debug ethernet device */
|
||||
|
||||
#endif /* _PDP11_XU_H */
|
||||
|
||||
Reference in New Issue
Block a user