mirror of
https://github.com/simh/simh.git
synced 2026-04-09 14:33:52 +00:00
Notes For V3.8
The makefile now works for Linux and most Unix's. However, for Solaris and MacOS, you must first export the OSTYPE environment variable: > export OSTYPE > make Otherwise, you will get build errors. 1. New Features 1.1 3.8-0 1.1.1 SCP and Libraries - BREAK, NOBREAK, and SHOW BREAK with no argument will set, clear, and show (respectively) a breakpoint at the current PC. 1.1.2 GRI - Added support for the GRI-99 processor. 1.1.3 HP2100 - Added support for the BACI terminal interface. - Added support for RTE OS/VMA/EMA, SIGNAL, VIS firmware extensions. 1.1.4 Nova - Added support for 64KW memory (implemented in third-party CPU's). 1.1.5 PDP-11 - Added support for DC11, RC11, KE11A, KG11A. - Added modem control support for DL11. - Added ASCII character support for all 8b devices. 1.2 3.8-1 1.2.1 SCP and libraries - Added capability to set line connection order for terminal multiplexers. 1.2.2 HP2100 - Added support for 12620A/12936A privileged interrupt fence. - Added support for 12792C eight-channel asynchronous multiplexer. 1.3 3.8-2 1.3.1 SCP and libraries - Added line history capability for *nix hosts. - Added "SHOW SHOW" and "SHOW <dev> SHOW" commands. 1.3.2 1401 - Added "no rewind" option to magtape boot. 1.3.3 PDP-11 - Added RD32 support to RQ - Added debug support to RL 1.3.4 PDP-8 - Added FPP support (many thanks to Rick Murphy for debugging the code) 1.3.5 VAX-11/780 - Added AUTORESTART switch support, and VMS REBOOT command support 2. Bugs Fixed Please see the revision history on http://simh.trailing-edge.com or in the source module sim_rev.h.
This commit is contained in:
committed by
Mark Pizzolato
parent
35eac703c3
commit
a9fd3dd518
@@ -1,6 +1,6 @@
|
||||
/* pdp11_defs.h: PDP-11 simulator definitions
|
||||
|
||||
Copyright (c) 1993-2008, Robert M Supnik
|
||||
Copyright (c) 1993-2010, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -26,6 +26,7 @@
|
||||
The author gratefully acknowledges the help of Max Burnet, Megan Gentry,
|
||||
and John Wilson in resolving questions about the PDP-11
|
||||
|
||||
22-May-10 RMS Added check for 64b definitions
|
||||
19-Nov-08 RMS Moved I/O support routines to I/O library
|
||||
16-May-08 RMS Added KE11A, DC11 support
|
||||
02-Feb-08 RMS Fixed DMA memory address limit test (found by John Dundas)
|
||||
@@ -80,6 +81,10 @@
|
||||
#include "sim_defs.h" /* simulator defns */
|
||||
#include <setjmp.h>
|
||||
|
||||
#if defined(USE_INT64) || defined(USE_ADDR64)
|
||||
#error "PDP-11 does not support 64b values!"
|
||||
#endif
|
||||
|
||||
/* Architectural constants */
|
||||
|
||||
#define STKL_R 0340 /* stack limit */
|
||||
|
||||
127
PDP11/pdp11_tq.c
127
PDP11/pdp11_tq.c
@@ -1,6 +1,6 @@
|
||||
/* pdp11_tq.c: TMSCP tape controller simulator
|
||||
|
||||
Copyright (c) 2002-2008, Robert M Supnik
|
||||
Copyright (c) 2002-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"),
|
||||
@@ -25,6 +25,20 @@
|
||||
|
||||
tq TQK50 tape controller
|
||||
|
||||
14-Jan-11 MP Various fixes discovered while exploring Ultrix issue:
|
||||
- Set UNIT_SXC flag when a tape mark is encountered
|
||||
during forward motion read operations
|
||||
- Fixed logic which clears UNIT_SXC to check command
|
||||
modifier
|
||||
- Added CMF_WR flag to tq_cmf entry for OP_WTM
|
||||
- Made non-immediate rewind positioning operations
|
||||
take 2 seconds
|
||||
- Added UNIT_IDLE flag to tq units
|
||||
- Fixed debug output of tape file positions when they
|
||||
are 64b
|
||||
- Added more debug output after positioning operations.
|
||||
- Added textual display of the command being performed
|
||||
23-Dec-10 RMS Fixed comments about register addresses
|
||||
18-Jun-07 RMS Added UNIT_IDLE flag to timer thread
|
||||
16-Feb-06 RMS Revised for new magtape capacity checking
|
||||
31-Oct-05 RMS Fixed address width for large files
|
||||
@@ -223,7 +237,6 @@ static struct drvtyp drv_tab[] = {
|
||||
|
||||
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;
|
||||
|
||||
@@ -249,6 +262,7 @@ int32 tq_itime = 200; /* init time, except */
|
||||
int32 tq_itime4 = 10; /* stage 4 */
|
||||
int32 tq_qtime = 200; /* queue time */
|
||||
int32 tq_xtime = 500; /* transfer time */
|
||||
int32 tq_rwtime = 2000000; /* rewind time 2 sec (adjusted later) */
|
||||
int32 tq_typ = INIT_TYPE; /* device type */
|
||||
|
||||
/* Command table - legal modifiers (low 16b) and flags (high 16b) */
|
||||
@@ -280,7 +294,7 @@ static uint32 tq_cmf[64] = {
|
||||
CMF_SEQ|CMF_RW|CMF_WR|MD_CDL|MD_CSE|MD_IMM| /* write */
|
||||
MD_CMP|MD_ERW|MD_SEC|MD_SER,
|
||||
0, /* 35 */
|
||||
CMF_SEQ|MD_CDL|MD_CSE|MD_IMM, /* wr tape mark */
|
||||
CMF_SEQ|CMF_WR|MD_CDL|MD_CSE|MD_IMM, /* wr tape mark */
|
||||
CMF_SEQ|MD_CDL|MD_CSE|MD_IMM|MD_OBC| /* reposition */
|
||||
MD_REV|MD_RWD|MD_DLE|
|
||||
MD_SCH|MD_SEC|MD_SER,
|
||||
@@ -289,6 +303,37 @@ static uint32 tq_cmf[64] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static char *tq_cmdname[] = {
|
||||
"", /* 0 */
|
||||
"ABO", /* 1 b: abort */
|
||||
"GCS", /* 2 b: get command status */
|
||||
"GUS", /* 3 b: get unit status */
|
||||
"SCC", /* 4 b: set controller char */
|
||||
"","","", /* 5-7 */
|
||||
"AVL", /* 8 b: available */
|
||||
"ONL", /* 9 b: online */
|
||||
"SUC", /* 10 b: set unit char */
|
||||
"DAP", /* 11 b: det acc paths - nop */
|
||||
"","","","", /* 12-15 */
|
||||
"ACC", /* 16 b: access */
|
||||
"CCD", /* 17 d: compare - nop */
|
||||
"ERS", /* 18 b: erase */
|
||||
"FLU", /* 19 d: flush - nop */
|
||||
"","", /* 20-21 */
|
||||
"ERG", /* 22 t: erase gap */
|
||||
"","","","","","","","","", /* 23-31 */
|
||||
"CMP", /* 32 b: compare */
|
||||
"RD", /* 33 b: read */
|
||||
"WR", /* 34 b: write */
|
||||
"", /* 35 */
|
||||
"WTM", /* 36 t: write tape mark */
|
||||
"POS", /* 37 t: reposition */
|
||||
"","","","","","","","","", /* 38-46 */
|
||||
"FMT", /* 47 d: format */
|
||||
"","","","","","","","","","","","","","","","", /* 48-63 */
|
||||
"AVA", /* 64 b: unit now avail */
|
||||
};
|
||||
|
||||
/* Forward references */
|
||||
|
||||
DEVICE tq_dev;
|
||||
@@ -369,12 +414,12 @@ DIB tq_dib = {
|
||||
};
|
||||
|
||||
UNIT tq_unit[] = {
|
||||
{ UDATA (&tq_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0), INIT_CAP },
|
||||
{ UDATA (&tq_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0), INIT_CAP },
|
||||
{ UDATA (&tq_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0), INIT_CAP },
|
||||
{ UDATA (&tq_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0), INIT_CAP },
|
||||
{ UDATA (&tq_tmrsvc, UNIT_DIS, 0) },
|
||||
{ UDATA (&tq_quesvc, UNIT_DIS, 0) }
|
||||
{ UDATA (&tq_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE|UNIT_ROABLE, 0), INIT_CAP },
|
||||
{ UDATA (&tq_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE|UNIT_ROABLE, 0), INIT_CAP },
|
||||
{ UDATA (&tq_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE|UNIT_ROABLE, 0), INIT_CAP },
|
||||
{ UDATA (&tq_svc, UNIT_IDLE|UNIT_ATTABLE|UNIT_DISABLE|UNIT_ROABLE, 0), INIT_CAP },
|
||||
{ UDATA (&tq_tmrsvc, UNIT_IDLE|UNIT_DIS, 0) },
|
||||
{ UDATA (&tq_quesvc, UNIT_IDLE|UNIT_DIS, 0) }
|
||||
};
|
||||
|
||||
#define TQ_TIMER (TQ_NUMDR)
|
||||
@@ -411,6 +456,7 @@ REG tq_reg[] = {
|
||||
{ DRDATA (I4TIME, tq_itime4, 24), PV_LEFT + REG_NZ },
|
||||
{ DRDATA (QTIME, tq_qtime, 24), PV_LEFT + REG_NZ },
|
||||
{ DRDATA (XTIME, tq_xtime, 24), PV_LEFT + REG_NZ },
|
||||
{ DRDATA (RWTIME, tq_rwtime, 32), PV_LEFT + REG_NZ },
|
||||
{ BRDATA (PKTS, tq_pkt, DEV_RDX, 16, TQ_NPKTS * (TQ_PKT_SIZE_W + 1)) },
|
||||
{ DRDATA (DEVTYPE, tq_typ, 2), REG_HRO },
|
||||
{ DRDATA (DEVCAP, drv_tab[TQU_TYPE].cap, T_ADDR_W), PV_LEFT | REG_HRO },
|
||||
@@ -466,10 +512,10 @@ DEVICE tq_dev = {
|
||||
&tq_dib, DEV_DISABLE | DEV_UBUS | DEV_QBUS | DEV_DEBUG
|
||||
};
|
||||
|
||||
/* I/O dispatch routines, I/O addresses 17772150 - 17772152
|
||||
/* I/O dispatch routines, I/O addresses 17774500 - 17774502
|
||||
|
||||
17772150 IP read/write
|
||||
17772152 SA read/write
|
||||
17774500 IP read/write
|
||||
17774502 SA read/write
|
||||
*/
|
||||
|
||||
t_stat tq_rd (int32 *data, int32 PA, int32 access)
|
||||
@@ -643,13 +689,16 @@ if ((pkt == 0) && tq_pip) { /* polling? */
|
||||
if (pkt) { /* got one? */
|
||||
if (DEBUG_PRS (tq_dev)) {
|
||||
UNIT *up = tq_getucb (tq_pkt[pkt].d[CMD_UN]);
|
||||
fprintf (sim_deb, ">>TQ: cmd=%04X, mod=%04X, unit=%d, ",
|
||||
tq_pkt[pkt].d[CMD_OPC], tq_pkt[pkt].d[CMD_MOD], tq_pkt[pkt].d[CMD_UN]);
|
||||
fprintf (sim_deb, ">>TQ: cmd=%04X(%3s), mod=%04X, unit=%d, ",
|
||||
tq_pkt[pkt].d[CMD_OPC], tq_cmdname[tq_pkt[pkt].d[CMD_OPC]&0x3f], tq_pkt[pkt].d[CMD_MOD], tq_pkt[pkt].d[CMD_UN]);
|
||||
fprintf (sim_deb, "bc=%04X%04X, ma=%04X%04X",
|
||||
tq_pkt[pkt].d[RW_BCH], tq_pkt[pkt].d[RW_BCL],
|
||||
tq_pkt[pkt].d[RW_BAH], tq_pkt[pkt].d[RW_BAL]);
|
||||
if (up)
|
||||
fprintf (sim_deb, ", pos=%d, obj=%d\n", up->pos, up->objp);
|
||||
if (up) {
|
||||
fprintf (sim_deb, ", pos=");
|
||||
fprint_val (sim_deb, up->pos, 10, T_ADDR_W, PV_LEFT);
|
||||
fprintf (sim_deb, ", obj=%d\n", up->objp);
|
||||
}
|
||||
else fprintf (sim_deb, "\n");
|
||||
fflush (sim_deb);
|
||||
}
|
||||
@@ -734,7 +783,7 @@ else { /* valid cmd */
|
||||
}
|
||||
/* if (tq_cmf[cmd] & MD_CDL) /* clr cch lost? */
|
||||
/* uptr->flags = uptr->flags & ~UNIT_CDL; */
|
||||
if (tq_cmf[cmd] & MD_CSE) /* clr ser exc? */
|
||||
if ((mdf & MD_CSE) && (uptr->flags & UNIT_SXC)) /* clr ser exc? */
|
||||
uptr->flags = uptr->flags & ~UNIT_SXC;
|
||||
}
|
||||
switch (cmd) {
|
||||
@@ -847,19 +896,19 @@ uint32 sts;
|
||||
UNIT *uptr;
|
||||
|
||||
if (uptr = tq_getucb (lu)) { /* unit exist? */
|
||||
if (uptr->flags & UNIT_SXC) /* ser exc pending? */
|
||||
if (uptr->flags & UNIT_SXC) /* ser exc pending? */
|
||||
sts = ST_SXC;
|
||||
else {
|
||||
uptr->flags = uptr->flags & ~(UNIT_ONL | UNIT_TMK | UNIT_POL);
|
||||
sim_tape_rewind (uptr); /* rewind */
|
||||
uptr->uf = uptr->objp = 0; /* clr flags */
|
||||
if (uptr->flags & UNIT_ATT) { /* attached? */
|
||||
sts = ST_SUC; /* success */
|
||||
if (mdf & MD_UNL) /* unload? */
|
||||
else {
|
||||
uptr->flags = uptr->flags & ~(UNIT_ONL | UNIT_TMK | UNIT_POL);
|
||||
sim_tape_rewind (uptr); /* rewind */
|
||||
uptr->uf = uptr->objp = 0; /* clr flags */
|
||||
if (uptr->flags & UNIT_ATT) { /* attached? */
|
||||
sts = ST_SUC; /* success */
|
||||
if (mdf & MD_UNL) /* unload? */
|
||||
tq_detach (uptr);
|
||||
}
|
||||
else sts = ST_OFL | SB_OFL_NV; /* no, offline */
|
||||
}
|
||||
}
|
||||
else sts = ST_OFL | SB_OFL_NV; /* no, offline */
|
||||
}
|
||||
}
|
||||
else sts = ST_OFL; /* offline */
|
||||
tq_putr (pkt, OP_AVL | OP_END, tq_efl (uptr), sts, AVL_LNT, UQ_TYP_SEQ);
|
||||
@@ -1066,7 +1115,12 @@ if (uptr = tq_getucb (lu)) { /* unit exist? */
|
||||
sts = tq_mot_valid (uptr, OP_POS); /* validity checks */
|
||||
if (sts == ST_SUC) { /* ok? */
|
||||
uptr->cpkt = pkt; /* op in progress */
|
||||
sim_activate (uptr, tq_xtime); /* activate */
|
||||
tq_rwtime = 2 * tmr_poll * clk_tps; /* 2 second rewind time */
|
||||
if ((tq_pkt[pkt].d[CMD_MOD] & MD_RWD) && /* rewind? */
|
||||
(!(tq_pkt[pkt].d[CMD_MOD] & MD_IMM))) /* !immediate? */
|
||||
sim_activate (uptr, tq_rwtime); /* use 2 sec rewind execute time */
|
||||
else /* otherwise */
|
||||
sim_activate (uptr, tq_xtime); /* use normal execute time */
|
||||
return OK; /* done */
|
||||
}
|
||||
}
|
||||
@@ -1180,6 +1234,8 @@ switch (cmd) { /* case on command */
|
||||
return tq_mot_err (uptr, tbc); /* log, done */
|
||||
}
|
||||
if ((sts != ST_SUC) || (cmd == OP_ACC)) { /* error or access? */
|
||||
if (sts == ST_TMK)
|
||||
uptr->flags = uptr->flags | UNIT_SXC; /* set ser exc */
|
||||
PUTP32 (pkt, RW_BCL, 0); /* no bytes processed */
|
||||
break;
|
||||
}
|
||||
@@ -1286,6 +1342,11 @@ switch (cmd) { /* case on command */
|
||||
}
|
||||
PUTP32 (pkt, POS_RCL, skrec); /* #rec skipped */
|
||||
PUTP32 (pkt, POS_TMCL, sktmk); /* #tmk skipped */
|
||||
if (DEBUG_PRS (tq_dev)) {
|
||||
fprintf (sim_deb, ">>TQ: Position Done: mdf=%04X, nrec=%04X, ntmk=%04X, skrec=%04X, sktmk=%04X\n",
|
||||
mdf, nrec, ntmk, skrec, sktmk);
|
||||
fflush (sim_deb);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1690,8 +1751,11 @@ if (DEBUG_PRS (tq_dev)) {
|
||||
UNIT *up = tq_getucb (tq_pkt[pkt].d[CMD_UN]);
|
||||
fprintf (sim_deb, ">>TQ: rsp=%04X, sts=%04X",
|
||||
tq_pkt[pkt].d[RSP_OPF], tq_pkt[pkt].d[RSP_STS]);
|
||||
if (up)
|
||||
fprintf (sim_deb, ", pos=%d, obj=%d\n", up->pos, up->objp);
|
||||
if (up) {
|
||||
fprintf (sim_deb, ", pos=");
|
||||
fprint_val (sim_deb, up->pos, 10, T_ADDR_W, PV_LEFT);
|
||||
fprintf (sim_deb, ", obj=%d\n", up->objp);
|
||||
}
|
||||
else fprintf (sim_deb, "\n");
|
||||
fflush (sim_deb);
|
||||
}
|
||||
@@ -1816,6 +1880,7 @@ void tq_putr_unit (int32 pkt, UNIT *uptr, uint32 lu, t_bool all)
|
||||
{
|
||||
tq_pkt[pkt].d[ONL_MLUN] = lu; /* multi-unit */
|
||||
tq_pkt[pkt].d[ONL_UFL] = uptr->uf | TQ_WPH (uptr); /* unit flags */
|
||||
tq_pkt[pkt].d[ONL_UFL] |= tq_efl (uptr); /* end flags accordingly */
|
||||
tq_pkt[pkt].d[ONL_RSVL] = tq_pkt[pkt].d[ONL_RSVH] = 0; /* reserved */
|
||||
tq_pkt[pkt].d[ONL_UIDA] = lu; /* UID low */
|
||||
tq_pkt[pkt].d[ONL_UIDB] = 0;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* pdp11_ts.c: TS11/TSV05 magnetic tape simulator
|
||||
|
||||
Copyright (c) 1993-2008, Robert M Supnik
|
||||
Copyright (c) 1993-2010, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
ts TS11/TSV05 magtape
|
||||
|
||||
22-May-10 RMS Fixed t_addr printouts for 64b big-endian systems
|
||||
(found by Mark Pizzolato)
|
||||
16-Feb-06 RMS Added tape capacity checking
|
||||
31-Oct-05 RMS Fixed address width for large files
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
@@ -733,9 +735,12 @@ if (!(cmdhdr & CMD_ACK)) { /* no acknowledge? */
|
||||
}
|
||||
fnc = GET_FNC (cmdhdr); /* get fnc+mode */
|
||||
mod = GET_MOD (cmdhdr);
|
||||
if (DEBUG_PRS (ts_dev))
|
||||
fprintf (sim_deb, ">>TS: cmd=%s, mod=%o, buf=%o, lnt=%d, pos=%d\n",
|
||||
fnc_name[fnc], mod, cmdadl, cmdlnt, ts_unit.pos);
|
||||
if (DEBUG_PRS (ts_dev)) {
|
||||
fprintf (sim_deb, ">>TS: cmd=%s, mod=%o, buf=%o, lnt=%d, pos=",
|
||||
fnc_name[fnc], mod, cmdadl, cmdlnt);
|
||||
fprint_val (sim_deb, ts_unit.pos, 10, T_ADDR_W, PV_LEFT);
|
||||
fprintf (sim_deb, "\n");
|
||||
}
|
||||
if ((fnc != FNC_WCHR) && (tssr & TSSR_NBA)) { /* ~wr chr & nba? */
|
||||
ts_endcmd (TC3, 0, 0); /* error */
|
||||
return SCPE_OK;
|
||||
@@ -1016,9 +1021,12 @@ tssr = ts_updtssr (tssr | tc | TSSR_SSR | (tc? TSSR_SC: 0));
|
||||
if (cmdhdr & CMD_IE)
|
||||
SET_INT (TS);
|
||||
ts_ownm = 0; ts_ownc = 0;
|
||||
if (DEBUG_PRS (ts_dev))
|
||||
fprintf (sim_deb, ">>TS: sta=%o, tc=%o, rfc=%d, pos=%d\n",
|
||||
msgxs0, GET_TC (tssr), msgrfc, ts_unit.pos);
|
||||
if (DEBUG_PRS (ts_dev)) {
|
||||
fprintf (sim_deb, ">>TS: sta=%o, tc=%o, rfc=%d, pos=",
|
||||
msgxs0, GET_TC (tssr), msgrfc);
|
||||
fprint_val (sim_deb, ts_unit.pos, 10, T_ADDR_W, PV_LEFT);
|
||||
fprintf (sim_deb, "\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
1032
PDP11/pdp11_xq.c
1032
PDP11/pdp11_xq.c
File diff suppressed because it is too large
Load Diff
187
PDP11/pdp11_xq.h
187
PDP11/pdp11_xq.h
@@ -28,6 +28,14 @@
|
||||
|
||||
Modification history:
|
||||
|
||||
03-Mar-08 MP Added DELQA-T (aka DELQA Plus) device emulation support.
|
||||
06-Feb-08 MP Added dropped frame statistics to record when the receiver discards
|
||||
received packets due to the receiver being disabled, or due to the
|
||||
XQ device's packet receive queue being full. Also removed the
|
||||
filter statistic counter since there was no code which ever set it.
|
||||
29-Jan-08 MP Dynamically determine the timer polling rate based on the
|
||||
calibrated tmr_poll and clk_tps values of the simulator.
|
||||
23-Jan-08 MP Added debugging support to display packet headers and packet data
|
||||
07-Jul-05 RMS Removed extraneous externs
|
||||
20-Jan-04 DTH Added new sanity timer and system id timer
|
||||
19-Jan-04 DTH Added XQ_SERVICE_INTERVAL, poll
|
||||
@@ -84,12 +92,11 @@ 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 */
|
||||
|
||||
enum xq_type {XQ_T_DEQNA, XQ_T_DELQA};
|
||||
enum xq_type {XQ_T_DEQNA, XQ_T_DELQA, XQ_T_DELQA_PLUS};
|
||||
|
||||
struct xq_sanity {
|
||||
int enabled; /* sanity timer enabled? 2=HW, 1=SW, 0=off */
|
||||
int quarter_secs; /* sanity timer value in 1/4 seconds */
|
||||
int max; /* maximum timeout (based on poll) */
|
||||
int timer; /* countdown timer */
|
||||
};
|
||||
|
||||
@@ -104,17 +111,132 @@ struct xq_setup {
|
||||
ETH_MAC macs[XQ_FILTER_MAX]; /* MAC addresses to respond to */
|
||||
};
|
||||
|
||||
struct xq_turbo_init_block { /* DELQA-T Initialization Block */
|
||||
uint16 mode;
|
||||
#define XQ_IN_MO_PRO 0x8000 /* Promiscuous Mode */
|
||||
#define XQ_IN_MO_INT 0x0040 /* Internal Loopback Mode */
|
||||
#define XQ_IN_MO_DRT 0x0020 /* Disable Retry */
|
||||
#define XQ_IN_MO_DTC 0x0008 /* Disable Transmit CRC */
|
||||
#define XQ_IN_MO_LOP 0x0004 /* Loopback */
|
||||
ETH_MAC phys; /* Physical MAC Address */
|
||||
ETH_MULTIHASH hash_filter; /* 64bit LANCE Hash Filter for Multicast Address selection */
|
||||
uint16 rdra_l;
|
||||
uint16 rdra_h;
|
||||
uint16 tdra_l;
|
||||
uint16 tdra_h;
|
||||
uint16 options;
|
||||
#define XQ_IN_OP_HIT 0x0002 /* Host Inactivity Timer Enable Flag */
|
||||
#define XQ_IN_OP_INT 0x0001 /* Interrupt Enable Flag*/
|
||||
uint16 vector; /* Interrupt Vector */
|
||||
uint16 hit_timeout; /* Host Inactivity Timer Timeout Value */
|
||||
uint8 bootpassword[6]; /* MOP Console Boot Password */
|
||||
};
|
||||
|
||||
/* DELQA-T Mode - Transmit Buffer Descriptor */
|
||||
struct transmit_buffer_descriptor {
|
||||
uint16 tmd0;
|
||||
#define XQ_TMD0_ERR1 0x4000 /* Error Summary. The OR of TMD1 (LC0, LCA, and RTR) */
|
||||
#define XQ_TMD0_MOR 0x1000 /* More than one retry on transmit */
|
||||
#define XQ_TMD0_ONE 0x0800 /* One retry on transmit */
|
||||
#define XQ_TMD0_DEF 0x0400 /* Deferral during transmit */
|
||||
uint16 tmd1;
|
||||
#define XQ_TMD1_LCO 0x1000 /* Late collision on transmit - packet not transmitted */
|
||||
#define XQ_TMD1_LCA 0x0800 /* Loss of carrier on transmit - packet not transmitted */
|
||||
#define XQ_TMD1_RTR 0x0400 /* Retry error on transmit - packet not transmitted */
|
||||
#define XQ_TMD1_TDR 0x03FF /* Time Domain Reflectometry value */
|
||||
uint16 tmd2;
|
||||
#define XQ_TMD2_ERR2 0x8000 /* Error Summary. The OR of TMD2 (BBL, CER, and MIS) */
|
||||
#define XQ_TMD2_BBL 0x4000 /* Babble error on transmit */
|
||||
#define XQ_TMD2_CER 0x2000 /* Collision error on transmit */
|
||||
#define XQ_TMD2_MIS 0x1000 /* Packet lost on receive */
|
||||
#define XQ_TMD2_EOR 0x0800 /* End Of Receive Ring Reached */
|
||||
#define XQ_TMD2_RON 0x0020 /* Receiver On */
|
||||
#define XQ_TMD2_TON 0x0010 /* Transmitter On */
|
||||
uint16 tmd3;
|
||||
#define XQ_TMD3_OWN 0x8000 /* Ownership field. 0 = DELQA-T, 1 = Host Driver */
|
||||
#define XQ_TMD3_FOT 0x4000 /* First Of Two flag. 1 = first in chained, 0 = no chain or last in chain */
|
||||
#define XQ_TMD3_BCT 0x0FFF /* Byte Count */
|
||||
uint16 ladr; /* Low 16bits of Buffer Address */
|
||||
uint16 hadr; /* Most significant bits of the Buffer Address */
|
||||
uint16 hostuse1;
|
||||
uint16 hostuse2;
|
||||
};
|
||||
#define XQ_TURBO_XM_BCNT 12 /* Transmit Buffer Descriptor Count */
|
||||
|
||||
struct receive_buffer_descriptor {
|
||||
uint16 rmd0;
|
||||
#define XQ_RMD0_ERR3 0x4000 /* Error Summary. The OR of FRA, CRC, OFL and BUF */
|
||||
#define XQ_RMD0_FRA 0x2000 /* Framing error on receive */
|
||||
#define XQ_RMD0_OFL 0x1000 /* Overflow error on receive (Giant packet) */
|
||||
#define XQ_RMD0_CRC 0x0800 /* CRC error on receive */
|
||||
#define XQ_RMD0_BUF 0x0400 /* Internal device buffer error. Part of Giant packet lost */
|
||||
#define XQ_RMD0_STP 0x0200 /* Start of Packet Flag */
|
||||
#define XQ_RMD0_ENP 0x0100 /* End of Packet Flag */
|
||||
uint16 rmd1;
|
||||
#define XQ_RMD1_MCNT 0x0FFF /* Message byte count (including CRC) */
|
||||
uint16 rmd2;
|
||||
#define XQ_RMD2_ERR4 0x8000 /* Error Summary. The OR of RMD2 (RBL, CER, and MIS) */
|
||||
#define XQ_RMD2_BBL 0x4000 /* Babble error on transmit */
|
||||
#define XQ_RMD2_CER 0x2000 /* Collision error on transmit */
|
||||
#define XQ_RMD2_MIS 0x1000 /* Packet lost on receive */
|
||||
#define XQ_RMD2_EOR 0x0800 /* End Of Receive Ring Reached */
|
||||
#define XQ_RMD2_RON 0x0020 /* Receiver On */
|
||||
#define XQ_RMD2_TON 0x0010 /* Transmitter On */
|
||||
uint16 rmd3;
|
||||
#define XQ_RMD3_OWN 0x8000 /* Ownership field. 0 = DELQA-T, 1 = Host Driver */
|
||||
uint16 ladr; /* Low 16bits of Buffer Address */
|
||||
uint16 hadr; /* Most significant bits of the Buffer Address */
|
||||
uint16 hostuse1;
|
||||
uint16 hostuse2;
|
||||
};
|
||||
#define XQ_TURBO_RC_BCNT 32 /* Receive Buffer Descriptor Count */
|
||||
|
||||
struct xq_stats {
|
||||
int recv; /* received packets */
|
||||
int filter; /* filtered packets */
|
||||
int dropped; /* received packets dropped */
|
||||
int xmit; /* transmitted packets */
|
||||
int fail; /* transmit failed */
|
||||
int runt; /* runts */
|
||||
int reset; /* reset count */
|
||||
int giant; /* oversize packets */
|
||||
int setup; /* setup packets */
|
||||
int loop; /* loopback packets */
|
||||
};
|
||||
|
||||
#pragma pack(2)
|
||||
struct xq_mop_counters {
|
||||
uint16 seconds; /* Seconds since last zeroed */
|
||||
uint32 b_rcvd; /* Bytes Received */
|
||||
uint32 b_xmit; /* Bytes Transmitted */
|
||||
uint32 p_rcvd; /* Packets Received */
|
||||
uint32 p_xmit; /* Packets Transmitted */
|
||||
uint32 mb_rcvd; /* Multicast Bytes Received */
|
||||
uint32 mp_rcvd; /* Multicast Packets Received */
|
||||
uint32 p_x_col1; /* Packets Transmitted Initially Deferred */
|
||||
uint32 p_x_col2; /* Packets Transmitted after 2 attempts */
|
||||
uint32 p_x_col3; /* Packets Transmitted after 3+ attempts */
|
||||
uint16 p_x_fail; /* Transmit Packets Aborted (Send Failure) */
|
||||
uint16 p_x_f_bitmap; /* Transmit Packets Aborted (Send Failure) Bitmap */
|
||||
#define XQ_XF_RTRY 0x0001 /* Excessive Collisions */
|
||||
#define XQ_XF_LCAR 0x0002 /* Loss of Carrier */
|
||||
#define XQ_XF_MLEN 0x0010 /* Data Block Too Long */
|
||||
#define XQ_XF_LCOL 0x0020 /* Late Collision */
|
||||
uint16 p_r_fail; /* Packets received with Error (Receive Failure) */
|
||||
uint16 p_r_f_bitmap; /* Packets received with Error (Receive Failure) Bitmap */
|
||||
#define XQ_RF_CRC 0x0001 /* Block Check Error */
|
||||
#define XQ_RF_FRAM 0x0002 /* Framing Error */
|
||||
#define XQ_RF_MLEN 0x0004 /* Message Length Error */
|
||||
uint16 h_dest_err; /* Host Counter - Unrecognized Frame Destination Error */
|
||||
uint16 r_p_lost_i; /* Receive Packet Lost: Internal Buffer Error */
|
||||
uint16 r_p_lost_s; /* Receive Packet Lost: System Buffer Error (Unavailable or Truncated) */
|
||||
uint16 h_no_buf; /* Host Counter - User Buffer Unavailable */
|
||||
uint32 mb_xmit; /* Multicast Bytes Tramsmitted */
|
||||
uint16 reserved1; /* */
|
||||
uint16 reserved2; /* */
|
||||
uint16 babble; /* Babble Counter */
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
struct xq_meb { /* MEB block */
|
||||
uint8 type;
|
||||
uint8 add_lo;
|
||||
@@ -128,18 +250,36 @@ struct xq_device {
|
||||
/*+ initialized values - DO NOT MOVE */
|
||||
ETH_PCALLBACK rcallback; /* read callback routine */
|
||||
ETH_PCALLBACK wcallback; /* write callback routine */
|
||||
ETH_MAC mac; /* MAC address */
|
||||
ETH_MAC mac; /* Hardware MAC address */
|
||||
enum xq_type type; /* controller type */
|
||||
int poll; /* poll ethernet times/sec */
|
||||
enum xq_type mode; /* controller operating mode */
|
||||
uint16 poll; /* configured poll ethernet times/sec for receive */
|
||||
uint16 coalesce_latency; /* microseconds to hold-off interrupts when not polling */
|
||||
uint16 coalesce_latency_ticks; /* instructions in coalesce_latency microseconds */
|
||||
struct xq_sanity sanity; /* sanity timer information */
|
||||
/*- initialized values - DO NOT MOVE */
|
||||
|
||||
/* I/O register storage */
|
||||
uint16 addr[6];
|
||||
|
||||
uint16 rbdl[2];
|
||||
uint16 xbdl[2];
|
||||
uint16 var;
|
||||
uint16 csr;
|
||||
|
||||
uint16 srr; /* Status and Response Register - DELQA-T only */
|
||||
uint16 srqr; /* Synchronous Request Register - DELQA-T only */
|
||||
uint32 iba; /* Init Block Address Register - DELQA-T only */
|
||||
uint16 icr; /* Interrupt Request Register - DELQA-T only */
|
||||
uint16 pending_interrupt; /* Pending Interrupt - DELQA-T only */
|
||||
struct xq_turbo_init_block
|
||||
init;
|
||||
struct transmit_buffer_descriptor
|
||||
xring[XQ_TURBO_XM_BCNT]; /* Transmit Buffer Ring */
|
||||
uint32 tbindx; /* Transmit Buffer Ring Index */
|
||||
struct receive_buffer_descriptor
|
||||
rring[XQ_TURBO_RC_BCNT]; /* Receive Buffer Ring */
|
||||
uint32 rbindx; /* Receive Buffer Ring Index */
|
||||
|
||||
uint32 irq; /* interrupt request flag */
|
||||
|
||||
/* buffers, etc. */
|
||||
@@ -151,11 +291,11 @@ struct xq_device {
|
||||
uint32 rbdl_ba;
|
||||
uint32 xbdl_ba;
|
||||
ETH_DEV* etherface;
|
||||
int receiving;
|
||||
ETH_PACK read_buffer;
|
||||
ETH_PACK write_buffer;
|
||||
ETH_QUE ReadQ;
|
||||
int idtmr; /* countdown for ID Timer */
|
||||
uint32 idtmr; /* countdown for ID Timer */
|
||||
uint32 must_poll; /* receiver must poll instead of counting on asynch polls */
|
||||
};
|
||||
|
||||
struct xq_controller {
|
||||
@@ -207,6 +347,7 @@ typedef struct xq_controller CTLR;
|
||||
#define XQ_VEC_RO 0x5C02 /* Read-Only bits */
|
||||
#define XQ_VEC_RW 0xA3FD /* Read/Write bits */
|
||||
|
||||
/* DEQNA - DELQA Normal Mode Buffer Descriptors */
|
||||
#define XQ_DSC_V 0x8000 /* Valid bit */
|
||||
#define XQ_DSC_C 0x4000 /* Chain bit */
|
||||
#define XQ_DSC_E 0x2000 /* End of Message bit [Transmit only] */
|
||||
@@ -214,11 +355,38 @@ typedef struct xq_controller CTLR;
|
||||
#define XQ_DSC_L 0x0080 /* Low Byte Termination bit [Transmit only] */
|
||||
#define XQ_DSC_H 0x0040 /* High Byte Start bit [Transmit only] */
|
||||
|
||||
/* DEQNA - DELQA Normal Mode Setup Packet Flags */
|
||||
#define XQ_SETUP_MC 0x0001 /* multicast bit */
|
||||
#define XQ_SETUP_PM 0x0002 /* promiscuous bit */
|
||||
#define XQ_SETUP_LD 0x000C /* led bits */
|
||||
#define XQ_SETUP_ST 0x0070 /* sanity timer bits */
|
||||
|
||||
/* DELQA-T Mode - Status and Response Register (SRR) */
|
||||
#define XQ_SRR_FES 0x8000 /* Fatal Error Summary [RO] */
|
||||
#define XQ_SRR_CHN 0x4000 /* Chaining Error [RO] */
|
||||
#define XQ_SRR_NXM 0x1000 /* Non-Existant Memory Error [RO] */
|
||||
#define XQ_SRR_PAR 0x0800 /* Parity Error (Qbus) [RO] */
|
||||
#define XQ_SRR_IME 0x0400 /* Internal Memory Error [RO] */
|
||||
#define XQ_SRR_TBL 0x0200 /* Transmit Buffer Too Long Error [RO] */
|
||||
#define XQ_SRR_RESP 0x0003 /* Synchronous Response Field [RO] */
|
||||
#define XQ_SRR_TRBO 0x0001 /* Select Turbo Response [RO] */
|
||||
#define XQ_SRR_STRT 0x0002 /* Start Device Response [RO] */
|
||||
#define XQ_SRR_STOP 0x0003 /* Stop Device Response [RO] */
|
||||
|
||||
/* DELQA-T Mode - Synchronous Request Register (SRQR) */
|
||||
#define XQ_SRQR_STRT 0x0002 /* Start Device Request [WO] */
|
||||
#define XQ_SRQR_STOP 0x0003 /* Stop Device Request [WO] */
|
||||
#define XQ_SRQR_RW 0x0003 /* Writable Bits in SRQR [WO] */
|
||||
|
||||
/* DELQA-T Mode - Asynchronous Request Register (ARQR) */
|
||||
#define XQ_ARQR_TRQ 0x8000 /* Transmit Request [WO] */
|
||||
#define XQ_ARQR_RRQ 0x0080 /* Receieve Request [WO] */
|
||||
#define XQ_ARQR_SR 0x0002 /* Software Reset Request [WO] */
|
||||
|
||||
/* DELQA-T Mode - Interrupt Control Register (ICR) */
|
||||
#define XQ_ICR_ENA 0x0001 /* Interrupt Enabled [WO] */
|
||||
|
||||
|
||||
/* debugging bitmaps */
|
||||
#define DBG_TRC 0x0001 /* trace routine calls */
|
||||
#define DBG_REG 0x0002 /* trace read/write registers */
|
||||
@@ -227,7 +395,8 @@ typedef struct xq_controller CTLR;
|
||||
#define DBG_WRN 0x0010 /* display warnings */
|
||||
#define DBG_SAN 0x0020 /* display sanity timer info */
|
||||
#define DBG_SET 0x0040 /* display setup info */
|
||||
#define DBG_PCK 0x0080 /* display packets */
|
||||
#define DBG_PCK 0x0080 /* display packet headers */
|
||||
#define DBG_DAT 0x0100 /* display packet data */
|
||||
#define DBG_ETH 0x8000 /* debug ethernet device */
|
||||
|
||||
#endif /* _PDP11_XQ_H */
|
||||
|
||||
180
PDP11/pdp11_xu.c
180
PDP11/pdp11_xu.c
@@ -1,7 +1,7 @@
|
||||
/* pdp11_xu.c: DEUNA/DELUA ethernet controller simulator
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2003-2007, David T. Hittner
|
||||
Copyright (c) 2003-2011, 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"),
|
||||
@@ -30,7 +30,7 @@
|
||||
Digital DELUA Users Guide, Part# EK-DELUA-UG-002
|
||||
Digital DEUNA Users Guide, Part# EK-DEUNA-UG-001
|
||||
These manuals can be found online at:
|
||||
http://www.spies.com/~aek/pdf/dec/unibus
|
||||
http://www.bitsavers.org/pdf/dec/unibus
|
||||
|
||||
Testing performed:
|
||||
1) Receives/Transmits single packet under custom RSX driver
|
||||
@@ -41,7 +41,13 @@
|
||||
DECNET - SET HOST in/out, COPY in/out
|
||||
TCP/IP - PING in/out; SET HOST/TELNET in/out, COPY/FTP in/out
|
||||
Clustering - Successfully clustered with AlphaVMS 8.2
|
||||
4) Runs VAX EVDWA diagnostic tests 1-10; tests 11-19 (M68000/ROM/RAM) fail
|
||||
4) VMS 4.7 on VAX780 summary:
|
||||
(Jan/2011: Win7 x64 host; MS VC++ 2008; SIMH v3.8-2 rc1 base; WinPcap 4.1)
|
||||
LAT - SET HOST/LAT in (no outbound exists)
|
||||
DECNET - SET HOST in/out, DIR in/out, COPY in/out
|
||||
TCP/IP - no kit available to test
|
||||
Clustering - not tested
|
||||
5) Runs VAX EVDWA diagnostic tests 1-10; tests 11-19 (M68000/ROM/RAM) fail
|
||||
|
||||
Known issues:
|
||||
1) Most auxiliary commands are not implemented yet.
|
||||
@@ -56,6 +62,14 @@
|
||||
|
||||
Modification history:
|
||||
|
||||
12-Jan-11 DTH Added SHOW XU FILTERS modifier
|
||||
11-Jan-11 DTH Corrected SELFTEST command, enabling use by VMS 3.7, VMS 4.7, and Ultrix 1.1
|
||||
09-Dec-10 MP Added address conflict check during attach.
|
||||
06-Dec-10 MP Added loopback processing support
|
||||
30-Nov-10 MP Fixed the fact that no broadcast packets were received by the DEUNA
|
||||
15-Aug-08 MP Fixed transmitted packets to have the correct source MAC address.
|
||||
Fixed incorrect address filter setting calling eth_filter().
|
||||
23-Jan-08 MP Added debugging support to display packet headers and packet data
|
||||
18-Jun-07 RMS Added UNIT_IDLE flag
|
||||
03-May-07 DTH Added missing FC_RMAL command; cleared multicast on write
|
||||
29-Oct-06 RMS Synced poll and clock
|
||||
@@ -112,6 +126,7 @@ void xu_clrint (CTLR* xu);
|
||||
void xu_process_receive(CTLR* xu);
|
||||
void xu_dump_rxring(CTLR* xu);
|
||||
void xu_dump_txring(CTLR* xu);
|
||||
t_stat xu_show_filters (FILE* st, UNIT* uptr, int32 val, void* desc);
|
||||
|
||||
DIB xua_dib = { IOBA_XU, IOLN_XU, &xu_rd, &xu_wr,
|
||||
1, IVCL (XU), VEC_XU, {&xu_int} };
|
||||
@@ -143,6 +158,8 @@ MTAB xu_mod[] = {
|
||||
NULL, ð_show, NULL },
|
||||
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATS", "STATS",
|
||||
&xu_set_stats, &xu_show_stats, NULL },
|
||||
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "FILTERS", "FILTERS",
|
||||
NULL, &xu_show_filters, NULL },
|
||||
{ MTAB_XTD | MTAB_VDV, 0, "TYPE", "TYPE={DEUNA|DELUA}",
|
||||
&xu_set_type, &xu_show_type, NULL },
|
||||
{ 0 },
|
||||
@@ -156,6 +173,7 @@ DEBTAB xu_debug[] = {
|
||||
{"WARN", DBG_WRN},
|
||||
{"REG", DBG_REG},
|
||||
{"PACKET", DBG_PCK},
|
||||
{"DATA", DBG_DAT},
|
||||
{"ETH", DBG_ETH},
|
||||
{0}
|
||||
};
|
||||
@@ -294,20 +312,39 @@ t_stat xu_set_stats (UNIT* uptr, int32 val, char* cptr, void* desc)
|
||||
|
||||
t_stat xu_show_stats (FILE* st, UNIT* uptr, int32 val, void* desc)
|
||||
{
|
||||
char* fmt = " %-24s%d\n";
|
||||
char* fmt = " %-26s%d\n";
|
||||
CTLR* xu = xu_unit2ctlr(uptr);
|
||||
struct xu_stats* stats = &xu->var->stats;
|
||||
|
||||
fprintf(st, "Ethernet statistics:\n");
|
||||
fprintf(st, fmt, "Seconds since cleared:", stats->secs);
|
||||
fprintf(st, fmt, "Recv frames:", stats->frecv);
|
||||
fprintf(st, fmt, "Recv dbytes:", stats->rbytes);
|
||||
fprintf(st, fmt, "Xmit frames:", stats->ftrans);
|
||||
fprintf(st, fmt, "Xmit dbytes:", stats->tbytes);
|
||||
fprintf(st, fmt, "Recv frames(multicast):", stats->mfrecv);
|
||||
fprintf(st, fmt, "Recv dbytes(multicast):", stats->mrbytes);
|
||||
fprintf(st, fmt, "Xmit frames(multicast):", stats->mftrans);
|
||||
fprintf(st, fmt, "Xmit dbytes(multicast):", stats->mtbytes);
|
||||
fprintf(st, fmt, "Seconds since cleared:", stats->secs);
|
||||
fprintf(st, fmt, "Recv frames:", stats->frecv);
|
||||
fprintf(st, fmt, "Recv dbytes:", stats->rbytes);
|
||||
fprintf(st, fmt, "Xmit frames:", stats->ftrans);
|
||||
fprintf(st, fmt, "Xmit dbytes:", stats->tbytes);
|
||||
fprintf(st, fmt, "Recv frames(multicast):", stats->mfrecv);
|
||||
fprintf(st, fmt, "Recv dbytes(multicast):", stats->mrbytes);
|
||||
fprintf(st, fmt, "Xmit frames(multicast):", stats->mftrans);
|
||||
fprintf(st, fmt, "Xmit dbytes(multicast):", stats->mtbytes);
|
||||
fprintf(st, fmt, "Loopback forward Frames:", stats->loopf);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat xu_show_filters (FILE* st, UNIT* uptr, int32 val, void* desc)
|
||||
{
|
||||
CTLR* xu = xu_unit2ctlr(uptr);
|
||||
char buffer[20];
|
||||
int i;
|
||||
|
||||
fprintf(st, "Filters:\n");
|
||||
for (i=0; i<XU_FILTER_MAX; i++) {
|
||||
eth_mac_fmt((ETH_MAC*)xu->var->setup.macs[i], buffer);
|
||||
fprintf(st, " [%2d]: %s\n", i, buffer);
|
||||
}
|
||||
if (xu->var->setup.multicast)
|
||||
fprintf(st, "All Multicast Receive Mode\n");
|
||||
if (xu->var->setup.promiscuous)
|
||||
fprintf(st, "Promiscuous Receive Mode\n");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -359,13 +396,63 @@ void bit_stat16(uint16* stat, uint16 bits)
|
||||
*stat |= bits;
|
||||
}
|
||||
|
||||
t_stat xu_process_loopback(CTLR* xu, ETH_PACK* pack)
|
||||
{
|
||||
ETH_PACK response;
|
||||
ETH_MAC physical_address;
|
||||
t_stat status;
|
||||
int offset = 16 + (pack->msg[14] | (pack->msg[15] << 8));
|
||||
int function = pack->msg[offset] | (pack->msg[offset+1] << 8);
|
||||
|
||||
sim_debug(DBG_TRC, xu->dev, "xu_process_loopback()\n");
|
||||
|
||||
if (function != 2 /*forward*/)
|
||||
return SCPE_NOFNC;
|
||||
|
||||
/* create forward response packet */
|
||||
memcpy (&response, pack, sizeof(ETH_PACK));
|
||||
memcpy (physical_address, xu->var->setup.macs[0], sizeof(ETH_MAC));
|
||||
memcpy (&response.msg[0], &response.msg[offset+2], sizeof(ETH_MAC));
|
||||
memcpy (&response.msg[6], physical_address, sizeof(ETH_MAC));
|
||||
offset += 8;
|
||||
response.msg[14] = offset & 0xFF;
|
||||
response.msg[15] = (offset >> 8) & 0xFF;
|
||||
|
||||
/* send response packet */
|
||||
status = eth_write(xu->var->etherface, &response, NULL);
|
||||
++xu->var->stats.loopf;
|
||||
|
||||
if (DBG_PCK & xu->dev->dctrl)
|
||||
eth_packet_trace_ex(xu->var->etherface, response.msg, response.len, ((function == 1) ? "xu-loopbackreply" : "xu-loopbackforward"), DBG_DAT & xu->dev->dctrl, DBG_PCK);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
t_stat xu_process_local (CTLR* xu, ETH_PACK* pack)
|
||||
{
|
||||
return SCPE_NOFNC; /* not implemented yet */
|
||||
/* returns SCPE_OK if local processing occurred,
|
||||
otherwise returns SCPE_NOFNC or some other code */
|
||||
int protocol;
|
||||
|
||||
sim_debug(DBG_TRC, xu->dev, "xu_process_local()\n");
|
||||
|
||||
protocol = pack->msg[12] | (pack->msg[13] << 8);
|
||||
switch (protocol) {
|
||||
case 0x0090: /* ethernet loopback */
|
||||
return xu_process_loopback(xu, pack);
|
||||
break;
|
||||
case 0x0260: /* MOP remote console */
|
||||
return SCPE_NOFNC; /* not implemented yet */
|
||||
break;
|
||||
}
|
||||
return SCPE_NOFNC;
|
||||
}
|
||||
|
||||
void xu_read_callback(CTLR* xu, int status)
|
||||
{
|
||||
if (DBG_PCK & xu->dev->dctrl)
|
||||
eth_packet_trace_ex(xu->var->etherface, xu->var->read_buffer.msg, xu->var->read_buffer.len, "xu-recvd", DBG_DAT & xu->dev->dctrl, DBG_PCK);
|
||||
|
||||
/* process any packets locally that can be */
|
||||
status = xu_process_local (xu, &xu->var->read_buffer);
|
||||
|
||||
@@ -442,6 +529,8 @@ t_stat xu_system_id (CTLR* xu, const ETH_MAC dest, uint16 receipt_id)
|
||||
/* write system id */
|
||||
system_id.len = 60;
|
||||
status = eth_write(xu->var->etherface, &system_id, NULL);
|
||||
if (DBG_PCK & xu->dev->dctrl)
|
||||
eth_packet_trace_ex(xu->var->etherface, system_id.msg, system_id.len, "xu-systemid", DBG_DAT & xu->dev->dctrl, DBG_PCK);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -524,6 +613,7 @@ void xu_setclrint(CTLR* xu, int32 bits)
|
||||
t_stat xu_sw_reset (CTLR* xu)
|
||||
{
|
||||
t_stat status;
|
||||
int i;
|
||||
|
||||
sim_debug(DBG_TRC, xu->dev, "xu_sw_reset()\n");
|
||||
|
||||
@@ -559,10 +649,12 @@ t_stat xu_sw_reset (CTLR* xu)
|
||||
|
||||
/* reset ethernet interface */
|
||||
memcpy (xu->var->setup.macs[0], xu->var->mac, sizeof(ETH_MAC));
|
||||
xu->var->setup.mac_count = 1;
|
||||
for (i=0; i<6; i++)
|
||||
xu->var->setup.macs[1][i] = 0xff; /* Broadcast Address */
|
||||
xu->var->setup.mac_count = 2;
|
||||
if (xu->var->etherface)
|
||||
status = eth_filter (xu->var->etherface, xu->var->setup.mac_count,
|
||||
&xu->var->mac, xu->var->setup.multicast,
|
||||
xu->var->setup.macs, xu->var->setup.multicast,
|
||||
xu->var->setup.promiscuous);
|
||||
|
||||
/* activate device if not disabled */
|
||||
@@ -670,24 +762,24 @@ int32 xu_command(CTLR* xu)
|
||||
case FC_RMAL: /* read multicast address list */
|
||||
mtlen = (xu->var->pcb[2] & 0xFF00) >> 8;
|
||||
udbb = xu->var->pcb[1] | ((xu->var->pcb[2] & 03) << 16);
|
||||
wstatus = Map_WriteB(udbb, mtlen * 3, (uint8*) &xu->var->setup.macs[1]);
|
||||
break;
|
||||
wstatus = Map_WriteB(udbb, mtlen * 3, (uint8*) &xu->var->setup.macs[2]);
|
||||
break;
|
||||
|
||||
case FC_WMAL: /* write multicast address list */
|
||||
mtlen = (xu->var->pcb[2] & 0xFF00) >> 8;
|
||||
sim_debug(DBG_TRC, xu->dev, "FC_WAL: mtlen=%d\n", mtlen);
|
||||
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);
|
||||
/* clear existing multicast list */
|
||||
for (i=1; i<XU_FILTER_MAX; i++) {
|
||||
for (j=0; j<6; j++)
|
||||
xu->var->setup.macs[i][j] = 0;
|
||||
}
|
||||
/* get multicast list from host */
|
||||
rstatus = Map_ReadB(udbb, mtlen * 6, (uint8*) &xu->var->setup.macs[1]);
|
||||
/* clear existing multicast list */
|
||||
for (i=2; i<XU_FILTER_MAX; i++) {
|
||||
for (j=0; j<6; j++)
|
||||
xu->var->setup.macs[i][j] = 0;
|
||||
}
|
||||
/* get multicast list from host */
|
||||
rstatus = Map_ReadB(udbb, mtlen * 6, (uint8*) &xu->var->setup.macs[2]);
|
||||
if (rstatus == 0) {
|
||||
xu->var->setup.mac_count = mtlen + 1;
|
||||
xu->var->setup.mac_count = mtlen + 2;
|
||||
status = eth_filter (xu->var->etherface, xu->var->setup.mac_count,
|
||||
xu->var->setup.macs, xu->var->setup.multicast,
|
||||
xu->var->setup.promiscuous);
|
||||
@@ -807,7 +899,7 @@ sim_debug(DBG_TRC, xu->dev, "FC_WAL: mtlen=%d\n", mtlen);
|
||||
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);
|
||||
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;
|
||||
@@ -816,7 +908,7 @@ sim_debug(DBG_TRC, xu->dev, "FC_WMODE: mode=%04x\n", xu->var->mode);
|
||||
/* if promiscuous or multicast flags changed, change filter */
|
||||
if ((value ^ xu->var->mode) & (MODE_PROM | MODE_ENAL))
|
||||
status = eth_filter (xu->var->etherface, xu->var->setup.mac_count,
|
||||
&xu->var->mac, xu->var->setup.multicast,
|
||||
xu->var->setup.macs, xu->var->setup.multicast,
|
||||
xu->var->setup.promiscuous);
|
||||
break;
|
||||
|
||||
@@ -1151,6 +1243,11 @@ void xu_process_transmit(CTLR* xu)
|
||||
runt = 1;
|
||||
}
|
||||
|
||||
/* As described in the DEUNA User Guide (Section 4.7), the DEUNA is responsible
|
||||
for inserting the appropriate source MAC address in the outgoing packet header,
|
||||
so we do that now. */
|
||||
memcpy(xu->var->write_buffer.msg+6, (uint8*)&xu->var->setup.macs[0], sizeof(ETH_MAC));
|
||||
|
||||
/* are we in internal loopback mode ? */
|
||||
if ((xu->var->mode & MODE_LOOP) && (xu->var->mode & MODE_INTL)) {
|
||||
/* just put packet in receive buffer */
|
||||
@@ -1160,6 +1257,9 @@ void xu_process_transmit(CTLR* xu)
|
||||
wstatus = eth_write(xu->var->etherface, &xu->var->write_buffer, xu->var->wcallback);
|
||||
if (wstatus)
|
||||
xu->var->pcsr0 |= PCSR0_PCEI;
|
||||
else
|
||||
if (DBG_PCK & xu->dev->dctrl)
|
||||
eth_packet_trace_ex(xu->var->etherface, xu->var->write_buffer.msg, xu->var->write_buffer.len, "xu-write", DBG_DAT & xu->dev->dctrl, DBG_PCK);
|
||||
}
|
||||
|
||||
/* update transmit status in transmit buffer */
|
||||
@@ -1263,7 +1363,14 @@ void xu_port_command (CTLR* xu)
|
||||
break;
|
||||
|
||||
case CMD_SELFTEST: /* SELFTEST */
|
||||
xu_sw_reset(xu);
|
||||
/*
|
||||
SELFTEST is a <=15-second self diagnostic test, setting various
|
||||
error flags and the DONE (DNI) flag when complete. For simulation
|
||||
purposes, signal completion immediately with no errors. This
|
||||
inexact behavior could be incompatible with any guest machine
|
||||
diagnostics that are expecting to be able to monitor the
|
||||
controller's progress through the diagnostic testing.
|
||||
*/
|
||||
xu->var->pcsr0 |= PCSR0_DNI;
|
||||
break;
|
||||
|
||||
@@ -1348,7 +1455,7 @@ 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);
|
||||
sim_debug(DBG_REG, 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;
|
||||
@@ -1375,7 +1482,7 @@ t_stat xu_wr(int32 data, int32 PA, int32 access)
|
||||
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);
|
||||
sim_debug(DBG_REG, 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 */
|
||||
@@ -1458,6 +1565,15 @@ t_stat xu_attach(UNIT* uptr, char* cptr)
|
||||
xu->var->etherface = 0;
|
||||
return status;
|
||||
}
|
||||
if (SCPE_OK != eth_check_address_conflict (xu->var->etherface, &xu->var->mac)) {
|
||||
char buf[32];
|
||||
|
||||
eth_mac_fmt(&xu->var->mac, buf); /* format ethernet mac address */
|
||||
printf("%s: MAC Address Conflict on LAN for address %s\n", xu->dev->name, buf);
|
||||
if (sim_log) fprintf (sim_log, "%s: MAC Address Conflict on LAN for address %s\n", xu->dev->name, buf);
|
||||
eth_close(xu->var->etherface);
|
||||
return SCPE_NOATT;
|
||||
}
|
||||
uptr->filename = tptr;
|
||||
uptr->flags |= UNIT_ATT;
|
||||
eth_setcrc(xu->var->etherface, 1); /* enable CRC */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* pdp11_xu.h: DEUNA/DELUA ethernet controller information
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2003-2008, David T. Hittner
|
||||
Copyright (c) 2003-2005, 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"),
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
Modification history:
|
||||
|
||||
23-Jan-08 MP Added debugging support to display packet headers and packet data
|
||||
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
|
||||
@@ -66,7 +67,7 @@ extern int32 int_req[IPL_HLVL];
|
||||
#include "sim_ether.h"
|
||||
|
||||
#define XU_QUE_MAX 500 /* message queue array */
|
||||
#define XU_FILTER_MAX 11 /* mac + 10 multicast addrs */
|
||||
#define XU_FILTER_MAX 12 /* mac + broadcast + 10 multicast addrs */
|
||||
#define XU_SERVICE_INTERVAL 100 /* times per second */
|
||||
#define XU_ID_TIMER_VAL 540 /* 9 min * 60 sec */
|
||||
#define UDBSIZE 200 /* max size of UDB (in words) */
|
||||
@@ -107,6 +108,7 @@ struct xu_stats {
|
||||
uint16 txccf; /* transmit collision test failure */
|
||||
uint16 porterr; /* port driver errors */
|
||||
uint16 bablcnt; /* babble counter */
|
||||
uint32 loopf; /* loopback frames processed */
|
||||
};
|
||||
|
||||
struct xu_device {
|
||||
@@ -300,7 +302,8 @@ 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_PCK 0x0080 /* display packet headers */
|
||||
#define DBG_DAT 0x0100 /* display packet data */
|
||||
#define DBG_ETH 0x8000 /* debug ethernet device */
|
||||
|
||||
#endif /* _PDP11_XU_H */
|
||||
|
||||
Reference in New Issue
Block a user