1
0
mirror of https://github.com/simh/simh.git synced 2026-04-12 23:17:31 +00:00

Notes For V3.1-0

RESTRICTION: The FP15 and XVM features of the PDP-15 are only partially
debugged.  Do NOT enable these features for normal operations.

1. New Features in 3.1-0

1.1 SCP and libraries

- Added simulated Ethernet support for VMS, FreeBSD, Mac OS/X.
- Added status return to tmxr_putc_ln.
- Added sim_putchar_s to handle possible output stalls.

1.2 All DECtapes

- Added "DECtape off reel" error stop.

1.3 All Asynchronous Consoles

- Added support for output congestion stall if using a Telnet connection.

1.4 PDP-1

- Added Type 23 parallel drum support.

1.5 PDP-8

- Added instruction history.
- Added TSC8-75 option support for ETOS.
- Added TD8E DECtape support.

1.6 PDP-18b

- Added instruction history.
- Changed PDP-9, PDP-15 API default to enabled.

1.7 PDP-11

- Added support for 18b only Qbus devices.
- Formalized bus and addressing definitions.
- Added control to enable/disable autoconfiguration.
- Added stub support for second Unibus Ethernet controller.

1.7 Interdata 32b

- Added instruction history.

1.8 Eclipse

- Added floating point support.
- Added programmable interval timer support.

1.9 H316

- Added DMA/DMC support.
- Added fixed head disk support.
- Added moving head disk support.
- Added magtape support.

1.10 IBM 1130 (Brian Knittel)

- Added support for physical card reader, using the Cardread
interface (www.ibm1130.org/sim/downloads).
- Added support for physical printer (flushes output buffer after
each line).

2. Bugs Fixed in 3.1-0

2.1 SCP and libraries

- Fixed numerous bugs in Ethernet library.

2.2 All DECtapes

- Fixed reverse checksum value in 'read all' mode.
- Simplified (and sped up) timing.

2.3 PDP-8

- Fixed bug in RX28 read status (found by Charles Dickman).
- Fixed RX28 double density write.

2.4 PDP-18b

- Fixed autoincrement bug in PDP-4, PDP-7, PDP-9.

2.5 PDP-11/VAX

- Revised RQ MB->LBN conversion for greater accuracy.
- Fixed bug in IO configuration (found by David Hittner).
- Fixed bug with multiple RQ RAUSER drives.
- Fixed bug in second Qbus Ethernet controller interrupts.

2.6 Nova/Eclipse

- Fixed bugs in DKP flag clear, map setup, map usage (Charles Owen).
- Fixed bug in MT, reset completes despite I/O reset (Charles Owen).
- Fixed bug in MT, space operations return word count (Charles Owen).

2.7 IBM 1130 (Brian Knittel)

- Fixed bug in setting carry bit in subtract and subtract double.
- Fixed timing problem in console printer simulation.

2.8 1620

- Fixed bug in branch digit (found by Dave Babcock).

3. New Features in 3.0 vs prior releases

3.1 SCP and Libraries

- Added ASSIGN/DEASSIGN (logical name) commands.
- Changed RESTORE to unconditionally detach files.
- Added E11 and TPC format support to magtape library.
- Fixed bug in SHOW CONNECTIONS.
- Added USE_ADDR64 support.

3.2 All magtapes

- Magtapes support SIMH format, E11 format, and TPC format (read only).
- SET <tape_unit> FORMAT=format sets the specified tape unit's format.
- SHOW <tape_unit> FORMAT displays the specified tape unit's format.
- Tape format can also be set as part of the ATTACH command, using
  the -F switch.

3.3 VAX

- VAX can be compiled without USE_INT64.
- If compiled with USE_INT64 and USE_ADDR64, RQ and TQ controllers support
  files > 2GB.
- VAX ROM has speed control (SET ROM DELAY/NODELAY).

3.4 PDP-1

- Added block loader format support to LOAD.
- Changed BOOT PTR to allow loading of all of the first bank of memory.
- The LOAD command takes an optional argument specifying the memory field
  to be loaded.
- The PTR BOOT command takes its starting memory field from the TA (address
  switch) register.

3.5 PDP-18b Family

- Added PDP-4 EAE support.
- Added PDP-15 FP15 support.
- Added PDP-15 XVM support.
- Added PDP-15 "re-entrancy ECO".
- Added PDP-7, PDP-9, PDP-15 hardware RIM loader support in BOOT PTR.

4. Bugs Fixed in 3.0 vs prior releases

4.1 SCP and Libraries

- Fixed end of file problem in dep, idep.
- Fixed handling of trailing spaces in dep, idep.

4.2 VAX

- Fixed CVTfi bug: integer overflow not set if exponent out of range
- Fixed EMODx bugs:
  o First and second operands reversed
  o Separated fraction received wrong exponent
  o Overflow calculation on separated integer incorrect
  o Fraction not set to zero if exponent out of range
- Fixed interval timer and ROM access to pass power-up self-test even on very
  fast host processors (fixes from Mark Pizzolato).
- Fixed bug in user disk size (found by Chaskiel M Grundman).

4.3 1401

- Fixed mnemonic, instruction lengths, and reverse scan length check bug for MCS.
- Fixed MCE bug, BS off by 1 if zero suppress.
- Fixed chaining bug, D lost if return to SCP.
- Fixed H branch, branch occurs after continue.
- Added check for invalid 8 character MCW, LCA.
- Fixed magtape load-mode end of record response.
- Revised fetch to model hardware more closely.
- Fixed tape read end-of-record handling based on real 1401.
- Added diagnostic read (space forward).

4.4 Nova

- Fixed DSK variable size interaction with restore.
- Fixed bug in DSK set size routine.

4.5 PDP-1

- Fixed DT variable size interaction with restore.
- Updated CPU, line printer, standard devices to detect indefinite I/O wait.
- Fixed incorrect logical, missing activate, break in drum simulator.
- Fixed bugs in instruction decoding, overprinting for line printer.
- Fixed system hang if continue after PTR error.
- Fixed PTR to start/stop on successive rpa instructions.

4.6 PDP-11

- Fixed DT variable size interaction with restore.
- Fixed bug in MMR1 update (found by Tim Stark).
- Added XQ features and fixed bugs:
  o Corrected XQ interrupts on IE state transition (code by Tom Evans).
  o Added XQ interrupt clear on soft reset.
  o Removed XQ interrupt when setting XL or RL (multiple people).
  o Added SET/SHOW XQ STATS.
  o Added SHOW XQ FILTERS.
  o Added ability to split received packet into multiple buffers.
  o Added explicit runt and giant packet processing.
- Fixed bug in user disk size (found by Chaskiel M Grundman).

4.7 PDP-18B

- Fixed DT, RF variable size interaction with restore.
- Fixed MT bug in MTTR.
- Fixed bug in PDP-4 line printer overprinting.
- Fixed bug in PDP-15 memory protect/skip interaction.
- Fixed bug in RF set size routine.
- Increased PTP TIME for PDP-15 operating systems.
- Fixed priorities in PDP-15 API (differs from PDP-9).
- Fixed sign handling in PDP-15 EAE unsigned mul/div (differs from PDP-9).
- Fixed bug in CAF, clears API subsystem.

4.8 PDP-8

- Fixed DT, DF, RF, RX variable size interaction with restore.
- Fixed MT bug in SKTR.
- Fixed bug in DF, RF set size routine.

4.9 HP2100

- Fixed bug in DP (13210A controller only), DQ read status.
- Fixed bug in DP, DQ seek complete.
- Fixed DR drum sizes.
- Fixed DR variable capacity interaction with SAVE/RESTORE.

4.10 GRI

- Fixed bug in SC queue pointer management.

4.11 PDP-10

- Fixed bug in RP read header.

4.12 Ibm1130

- Fixed bugs found by APL 1130.

4.13 Altairz80

- Fixed bug in real-time clock on Windows host.

4.14 1620

- Fixed bug in immediate index add (found by Michael Short).
This commit is contained in:
Bob Supnik
2003-12-31 11:49:00 -08:00
committed by Mark Pizzolato
parent b2101ecdd4
commit 1da2d9452d
140 changed files with 17663 additions and 16338 deletions

View File

@@ -1,6 +1,6 @@
/* pdp11_cpu.c: PDP-11 CPU simulator
Copyright (c) 1993-2003, Robert M Supnik
Copyright (c) 1993-2004, 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 @@
cpu PDP-11 CPU (J-11 microprocessor)
29-Dec-03 RMS Formalized 18b Qbus support
21-Dec-03 RMS Added autoconfiguration controls
05-Jun-03 RMS Fixed bugs in memory size table
12-Mar-03 RMS Added logical name support
01-Feb-03 RMS Changed R display to follow PSW<rs>, added SP display
@@ -276,6 +278,7 @@ int32 stop_vecabort = 1; /* stop on vec abort */
int32 stop_spabort = 1; /* stop on SP abort */
int32 wait_enable = 0; /* wait state enable */
int32 cpu_log = 0; /* logging */
int32 autcon_enb = 1; /* autoconfig enable */
uint16 pcq[PCQ_SIZE] = { 0 }; /* PC queue */
int32 pcq_p = 0; /* PC queue ptr */
REG *pcq_r = NULL; /* PC queue reg ptr */
@@ -323,6 +326,8 @@ void set_r_display (int32 rs, int32 cm);
extern t_stat build_dib_tab (int32 ubm);
extern t_stat show_iospace (FILE *st, UNIT *uptr, int32 val, void *desc);
extern t_stat set_autocon (UNIT *uptr, int32 val, char *cptr, void *desc);
extern t_stat show_autocon (FILE *st, UNIT *uptr, int32 val, void *desc);
extern t_stat iopageR (int32 *data, uint32 addr, int32 access);
extern t_stat iopageW (int32 data, uint32 addr, int32 access);
extern int32 calc_ints (int32 nipl, int32 trq);
@@ -532,6 +537,7 @@ REG cpu_reg[] = {
{ GRDATA (UDPAR7, APRFILE[077], 8, 16, 16) },
{ GRDATA (UDPDR7, APRFILE[077], 8, 16, 0) },
{ BRDATA (UBMAP, ub_map, 8, 22, UBM_LNT_LW) },
{ FLDATA (AUTOCON, autcon_enb, 0), REG_HRO },
{ BRDATA (PCQ, pcq, 8, 16, PCQ_SIZE), REG_RO+REG_CIRC },
{ ORDATA (PCQP, pcq_p, 6), REG_HRO },
{ ORDATA (WRU, sim_int_char, 8) },
@@ -539,10 +545,10 @@ REG cpu_reg[] = {
{ NULL} };
MTAB cpu_mod[] = {
{ UNIT_MAP, UNIT_18B, "18b addressing", "18B", NULL },
{ UNIT_MAP, UNIT_18B, "18b Unibus", "U18", &cpu_set_bus },
{ UNIT_MAP, UNIT_UBM, "22b Unibus + RH70", "URH70", &cpu_set_bus },
{ UNIT_MAP, UNIT_UBM + UNIT_RH11, "22b Unibus + RH11", "URH11", &cpu_set_bus },
{ UNIT_MAP, 0, "22b addressing", "22B", &cpu_set_bus },
{ UNIT_MAP, 0, "22b Qbus", "Q22", &cpu_set_bus },
{ UNIT_CIS, UNIT_CIS, "CIS", "CIS", NULL },
{ UNIT_CIS, 0, "no CIS", "NOCIS", NULL },
{ UNIT_MSIZE, 16384, NULL, "16K", &cpu_set_size},
@@ -566,6 +572,10 @@ MTAB cpu_mod[] = {
{ UNIT_MSIZE, 4186112, NULL, "4M", &cpu_set_size},
{ MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "IOSPACE", NULL,
NULL, &show_iospace },
{ MTAB_XTD|MTAB_VDV, 1, "AUTOCONFIG", "AUTOCONFIG",
&set_autocon, &show_autocon },
{ MTAB_XTD|MTAB_VDV, 0, NULL, "NOAUTOCONFIG",
&set_autocon, NULL },
{ 0 } };
DEVICE cpu_dev = {
@@ -2467,23 +2477,24 @@ for (i = 0; i < clim; i = i + 2) nM[i >> 1] = M[i >> 1];
free (M);
M = nM;
MEMSIZE = val;
return cpu_set_bus (uptr, (cpu_unit.flags & UNIT_MAP) | 1, cptr, desc); }
return cpu_set_bus (uptr, cpu_unit.flags, cptr, desc); }
/* Bus configuration, disable Unibus or Qbus devices */
t_stat cpu_set_bus (UNIT *uptr, int32 val, char *cptr, void *desc)
{
DEVICE *dptr;
uint32 i, target;
uint32 i, mask;
if ((MEMSIZE <= UNIMEMSIZE) || (val & UNIT_18B) ||
(!(val & 1) && ((uint32) val == (cpu_unit.flags & UNIT_MAP)))) return SCPE_OK;
if (val & UNIT_MAP) target = DEV_QBUS; /* going to Ubus? */
else target = DEV_UBUS; /* going to Qbus */
if ((val & UNIT_MAP) || (val & UNIT_18B)) /* Unibus variant? */
mask = DEV_UBUS;
else if (MEMSIZE <= UNIMEMSIZE) /* 18b Qbus? */
mask = DEV_QBUS | DEV_Q18;
else mask = DEV_QBUS; /* must be 22b */
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) {
if ((dptr->flags & DEV_DISABLE) && /* disable-able? */
!(dptr->flags & DEV_DIS) && /* enabled? */
((dptr->flags & (DEV_QBUS|DEV_UBUS)) == target)) {
((dptr->flags & mask) == 0)) { /* not allowed? */
printf ("Disabling %s\n", sim_dname (dptr));
if (sim_log) fprintf (sim_log, "Disabling %s\n", sim_dname (dptr));
dptr->flags = dptr->flags | DEV_DIS; } }

View File

@@ -26,6 +26,8 @@
The author gratefully acknowledges the help of Max Burnet, Megan Gentry,
and John Wilson in resolving questions about the PDP-11
22-Dec-03 RMS Added second DEUNA/DELUA support
18-Oct-03 RMS Added DECtape off reel message
19-May-03 RMS Revised for new conditional compilation
05-Apr-03 RMS Fixed bug in MMR1 update (found by Tim Stark)
28-Feb-03 RMS Added TM logging support
@@ -295,6 +297,7 @@ typedef struct fpac fpac_t;
#define STOP_SPABORT (TRAP_V_MAX + 5) /* abort trap push */
#define STOP_RQ (TRAP_V_MAX + 6) /* RQDX3 panic */
#define STOP_SANITY (TRAP_V_MAX + 7) /* sanity timer exp */
#define STOP_DTOFF (TRAP_V_MAX + 8) /* DECtape off reel */
#define IORETURN(f,v) ((f)? (v): SCPE_OK) /* cond error return */
/* Timers */
@@ -312,9 +315,11 @@ typedef struct fpac fpac_t;
#define DEV_V_UBUS (DEV_V_UF + 0) /* Unibus */
#define DEV_V_QBUS (DEV_V_UF + 1) /* Qbus */
#define DEV_V_FLTA (DEV_V_UF + 2) /* flt addr */
#define DEV_V_Q18 (DEV_V_UF + 2) /* Qbus with <= 256KB */
#define DEV_V_FLTA (DEV_V_UF + 3) /* flt addr */
#define DEV_UBUS (1u << DEV_V_UBUS)
#define DEV_QBUS (1u << DEV_V_QBUS)
#define DEV_Q18 (1u << DEV_V_Q18)
#define DEV_FLTA (1u << DEV_V_FLTA)
#define UNIBUS (cpu_18b || cpu_ubm) /* T if 18b */
@@ -341,11 +346,13 @@ struct pdp_dib {
typedef struct pdp_dib DIB;
/* I/O page layout - RQB,RQC,RQD float based on number of DZ's */
/* I/O page layout - XUB, RQB,RQC,RQD float based on number of DZ's */
#define IOBA_DZ (IOPAGEBASE + 000100) /* DZ11 */
#define IOLN_DZ 010
#define IOBA_RQB (IOPAGEBASE + 000334 + (020 * (DZ_MUXES / 2)))
#define IOBA_XUB (IOPAGEBASE + 000330 + (020 * (DZ_MUXES / 2)))
#define IOLN_XUB 010
#define IOBA_RQB (IOPAGEBASE + 000334 + (020 * (DZ_MUXES / 2)))
#define IOLN_RQB 004
#define IOBA_RQC (IOPAGEBASE + IOBA_RQB + IOLN_RQB)
#define IOLN_RQC 004

View File

@@ -1,7 +1,7 @@
To: Users
From: Bob Supnik
Subj: PDP-11 Simulator Usage
Date: 15-Sep-2003
Date: 15-Dec-2003
COPYRIGHT NOTICE
@@ -127,6 +127,7 @@ The PDP-11 simulator implements several unique stop conditions:
- trap condition 'n' occurs, and register STOP_TRAP<n> is set
- wait state entered, and no I/O operations outstanding
(ie, no interrupt can ever occur)
- a simulated DECtape runs off the end of its reel
The PDP-11 loader supports standard binary format tapes. The DUMP command
is not implemented.
@@ -289,11 +290,13 @@ In addition to autoconfiguration, most devices support the SET ADDRESS
command, which allows the I/O page address of the device to be changed,
and the SET VECTOR command, which allows the vector of the device to be
changed. Explicitly setting the I/O address of a device which normally
uses autoconfiguration DISABLES autoconfiguration for that device. As
a consequence, the user may have to manually configure all other
autoconfigured devices, because the autoconfiguration algorithm no
longer recognizes the explicitly configured device. A device can be
reset to autoconfigure with the SET <device> AUTOCONFIGURE command.
uses autoconfiguration DISABLES autoconfiguration for that device and for
the entire system. As a consequence, the user may have to manually configure
all other autoconfigured devices, because the autoconfiguration algorithm
no longer recognizes the explicitly configured device. A device can be
reset to autoconfigure with the SET <device> AUTOCONFIGURE command. Auto-
configuration can be restored for the entire system with the SET CPU
AUTOCONFIGURE command.
The current I/O map can be displayed with the SHOW CPU IOSPACE command.
Addresses that have set by autoconfiguration are marked with an asterisk (*).
@@ -994,7 +997,6 @@ The TC controller implements these registers:
IE 1 interrupt enable flag
CTIME 31 time to complete transport stop
LTIME 31 time between lines
ACTIME 31 time to accelerate to full speed
DCTIME 31 time to decelerate to a full stop
SUBSTATE 2 read/write command substate
POS[0:7] 32 position, in lines, units 0-7
@@ -1005,8 +1007,9 @@ among the DECtape parameters, or the DECtape simulator will fail to
operate correctly.
- LTIME must be at least 6
- ACTIME must be less than DCTIME, and both need to be at
least 100 times LTIME
- DCTIME needs to be at least 100 times LTIME
Acceleration time is set to 75% of deceleration time.
2.9 Magnetic Tape Controllers

View File

@@ -25,6 +25,7 @@
hk RK611/RK06/RK07 disk
29-Dec-03 RMS Added 18b Qbus support
25-Apr-03 RMS Revised for extended file support
This is a somewhat abstracted implementation of the RK611, more closely
@@ -438,7 +439,7 @@ DEVICE hk_dev = {
HK_NUMDR, HK_RDX, 24, 1, HK_RDX, HK_WID,
NULL, NULL, &hk_reset,
&hk_boot, &hk_attach, &hk_detach,
&hk_dib, DEV_DISABLE | DEV_UBUS };
&hk_dib, DEV_DISABLE | DEV_UBUS | DEV_Q18 };
/* I/O dispatch routines, I/O addresses 17777440 - 17777476 */

View File

@@ -23,6 +23,8 @@
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
21-Dec-03 RMS Fixed bug in autoconfigure vector assignment; added controls
21-Nov-03 RMS Added check for interrupt slot conflict (found by Dave Hittner)
12-Mar-03 RMS Added logical name support
08-Oct-02 RMS Trimmed I/O bus addresses
Added support for dynamic tables
@@ -43,6 +45,7 @@ extern UNIT cpu_unit;
extern int32 cpu_bme, cpu_18b, cpu_ubm;
extern int32 trap_req, ipl;
extern int32 cpu_log;
extern int32 autcon_enb;
extern FILE *sim_log;
extern DEVICE *sim_devices[];
@@ -297,6 +300,24 @@ else { /* physical */
return (lim - alim); }
}
/* Enable/disable autoconfiguration */
t_stat set_autocon (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if (cptr != NULL) return SCPE_ARG;
autcon_enb = val;
return auto_config (0, 0);
}
/* Show autoconfiguration status */
t_stat show_autocon (FILE *st, UNIT *uptr, int32 val, void *desc)
{
fprintf (st, "autoconfiguration ");
fprintf (st, autcon_enb? "enabled": "disabled");
return SCPE_OK;
}
/* Change device address */
t_stat set_addr (UNIT *uptr, int32 val, char *cptr, void *desc)
@@ -318,7 +339,8 @@ if ((newba <= IOPAGEBASE) || /* > IO page base? */
(newba % ((uint32) val))) return SCPE_ARG; /* check modulus */
dibp->ba = newba; /* store */
dptr->flags = dptr->flags & ~DEV_FLTA; /* not floating */
return auto_config (0, 0); /* autoconfigure */
autcon_enb = 0; /* autoconfig off */
return SCPE_OK;
}
/* Show device address */
@@ -374,6 +396,8 @@ if ((r != SCPE_OK) || (newvec <= VEC_Q) ||
((newvec + (dibp->vnum * 4)) >= (VEC_Q + 01000)) ||
(newvec & ((dibp->vnum > 1)? 07: 03))) return SCPE_ARG;
dibp->vec = newvec;
dptr->flags = dptr->flags & ~DEV_FLTA; /* not floating */
autcon_enb = 0; /* autoconfig off */
return SCPE_OK;
}
@@ -427,14 +451,20 @@ return FALSE;
/* Build interrupt tables */
void build_int_vec (int32 vloc, int32 ivec, int32 (*iack)(void) )
t_bool build_int_vec (int32 vloc, int32 ivec, int32 (*iack)(void) )
{
int32 ilvl = vloc / 32;
int32 ibit = vloc % 32;
if (iack != NULL) int_ack[ilvl][ibit] = iack;
else int_vec[ilvl][ibit] = ivec;
return;
if (iack != NULL) {
if (int_ack[ilvl][ibit] &&
(int_ack[ilvl][ibit] != iack)) return TRUE;
int_ack[ilvl][ibit] = iack; }
else if (ivec != 0) {
if (int_vec[ilvl][ibit] &&
(int_vec[ilvl][ibit] != ivec)) return TRUE;
int_vec[ilvl][ibit] = ivec; }
return FALSE;
}
/* Build dib_tab from device list */
@@ -453,9 +483,15 @@ for (i = j = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */
dibp = (DIB *) dptr->ctxt; /* get DIB */
if (dibp && !(dptr->flags & DEV_DIS)) { /* defined, enabled? */
if (dibp->vnum > VEC_DEVMAX) return SCPE_IERR;
for (k = 0; k < dibp->vnum; k++) /* loop thru vec */
build_int_vec (dibp->vloc + k, /* add vector */
dibp->vec + (k * 4), dibp->ack[k]);
for (k = 0; k < dibp->vnum; k++) { /* loop thru vec */
if (build_int_vec (dibp->vloc + k, /* add vector */
dibp->vec + (k * 4), dibp->ack[k])) {
printf ("Device %s interrupt slot conflict at %d\n",
sim_dname (dptr), dibp->vloc + k);
if (sim_log) fprintf (sim_log,
"Device %s interrupt slot conflict at %d\n",
sim_dname (dptr), dibp->vloc + k);
return SCPE_IERR; } }
if (dibp->lnt != 0) { /* I/O addresses? */
dib_tab[j++] = dibp; /* add DIB to dib_tab */
if (j >= DIB_MAX) return SCPE_IERR; } /* too many? */
@@ -575,6 +611,7 @@ DIB *dibp;
int32 i, j, k;
extern DEVICE *find_dev (char *ptr);
if (autcon_enb == 0) return SCPE_OK; /* enabled? */
if (rank > AUTO_LNT) return SCPE_IERR; /* legal rank? */
if (rank) auto_tab[rank - 1].num = nctrl; /* update num? */
for (i = 0, autp = auto_tab; i < AUTO_LNT; i++) { /* loop thru table */

View File

@@ -1,6 +1,6 @@
/* pdp11_rk.c: RK11 cartridge disk simulator
/* pdp11_rk.c: RK11/RKV11 cartridge disk simulator
Copyright (c) 1993-2003, Robert M Supnik
Copyright (c) 1993-2004, 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"),
@@ -23,8 +23,9 @@
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
rk RK11/RK05 cartridge disk
rk RK11/RKV11/RK05 cartridge disk
29-Dec-03 RMS Added RKV11 support
29-Sep-02 RMS Added variable address support to bootstrap
Added vector change/display support
Revised mapping mnemonics
@@ -261,7 +262,7 @@ DEVICE rk_dev = {
RK_NUMDR, 8, 24, 1, 8, 16,
NULL, NULL, &rk_reset,
&rk_boot, NULL, NULL,
&rk_dib, DEV_DISABLE | DEV_UBUS };
&rk_dib, DEV_DISABLE | DEV_UBUS | DEV_Q18 };
/* I/O dispatch routine, I/O addresses 17777400 - 17777416

View File

@@ -26,6 +26,8 @@
rq RQDX3 disk controller
07-Oct-03 RMS Fixed problem with multiple RAUSER drives
17-Sep-03 RMS Fixed MB to LBN conversion to be more accurate
11-Jul-03 RMS Fixed bug in user disk size (found by Chaskiel M Grundman)
19-May-03 RMS Revised for new conditional compilation scheme
25-Apr-03 RMS Revised for extended file support
@@ -1422,7 +1424,8 @@ int32 rq_rw_valid (MSC *cp, int32 pkt, UNIT *uptr, uint32 cmd)
uint32 dtyp = GET_DTYPE (uptr->flags); /* get drive type */
uint32 lbn = GETP32 (pkt, RW_LBNL); /* get lbn */
uint32 bc = GETP32 (pkt, RW_BCL); /* get byte cnt */
uint32 maxlbn = drv_tab[dtyp].lbn; /* get max lbn */
uint32 maxlbn = uptr->capac / RQ_NUMBY; /* get max lbn */
/* uint32 maxlbn = drv_tab[dtyp].lbn; /* get max lbn */
if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */
return (ST_OFL | SB_OFL_NV); /* offl no vol */
@@ -1866,6 +1869,7 @@ return;
void rq_putr_unit (MSC *cp, int32 pkt, UNIT *uptr, uint32 lu, t_bool all)
{
uint32 dtyp = GET_DTYPE (uptr->flags); /* get drive type */
uint32 maxlbn = uptr->capac / RQ_NUMBY; /* get max lbn */
cp->pak[pkt].d[ONL_MLUN] = lu; /* unit */
cp->pak[pkt].d[ONL_UFL] = uptr->uf | UF_RPL | RQ_WPH (uptr) | RQ_RMV (uptr);
@@ -1878,7 +1882,7 @@ cp->pak[pkt].d[ONL_UIDD] = (UID_DISK << ONL_UIDD_V_CLS) |
(drv_tab[dtyp].mod << ONL_UIDD_V_MOD); /* UID hi */
PUTP32 (pkt, ONL_MEDL, drv_tab[dtyp].med); /* media type */
if (all) { /* if long form */
PUTP32 (pkt, ONL_SIZL, drv_tab[dtyp].lbn); /* user LBNs */
PUTP32 (pkt, ONL_SIZL, maxlbn); /* user LBNs */
cp->pak[pkt].d[ONL_VSNL] = 01234 + lu; /* vol serial # */
cp->pak[pkt].d[ONL_VSNH] = 0; }
return;
@@ -2012,13 +2016,13 @@ if (uptr->flags & UNIT_ATT) return SCPE_ALATT;
if (cptr) {
cap = (int32) get_uint (cptr, 10, max, &r);
if ((r != SCPE_OK) || (cap < RA8U_MINC)) return SCPE_ARG;
drv_tab[val].lbn = cap << (20 - 9); }
drv_tab[val].lbn = cap * 1954; }
uptr->flags = (uptr->flags & ~UNIT_DTYPE) | (val << UNIT_V_DTYPE);
uptr->capac = ((t_addr) drv_tab[val].lbn) * RQ_NUMBY;
return SCPE_OK;
}
/* Show unit type (and capacity if user defined) */
/* Show unit type */
t_stat rq_show_type (FILE *st, UNIT *uptr, int32 val, void *desc)
{
@@ -2034,7 +2038,6 @@ int32 dtyp = GET_DTYPE (uptr->flags);
MSC *cp = rq_ctxmap[uptr->cnum];
t_stat r;
uptr->capac = drv_tab[dtyp].lbn * RQ_NUMBY;
r = attach_unit (uptr, cptr);
if (r != SCPE_OK) return r;
if (cp->csta == CST_UP) uptr->flags = uptr->flags | UNIT_ATP;

View File

@@ -121,7 +121,7 @@ int32 rx_cwait = 100; /* command time */
int32 rx_swait = 10; /* seek, per track */
int32 rx_xwait = 1; /* tr set time */
uint8 rx_buf[RX_NUMBY] = { 0 }; /* sector buffer */
static int32 bptr = 0; /* buffer pointer */
int32 rx_bptr = 0; /* buffer pointer */
int32 rx_enb = 1; /* device enable */
DEVICE rx_dev;
@@ -157,7 +157,7 @@ REG rx_reg[] = {
{ ORDATA (RXTA, rx_track, 8) },
{ ORDATA (RXSA, rx_sector, 8) },
{ DRDATA (STAPTR, rx_state, 3), REG_RO },
{ DRDATA (BUFPTR, bptr, 7) },
{ DRDATA (BUFPTR, rx_bptr, 7) },
{ FLDATA (INT, IREQ (RX), INT_V_RX) },
{ FLDATA (ERR, rx_csr, RXCS_V_ERR) },
{ FLDATA (TR, rx_csr, RXCS_V_TR) },
@@ -237,7 +237,7 @@ case 0: /* RXCS */
if ((data & CSR_GO) && (rx_state == IDLE)) { /* new function? */
rx_csr = data & (RXCS_IE + RXCS_DRV + RXCS_FUNC);
drv = ((rx_csr & RXCS_DRV)? 1: 0); /* reselect drive */
bptr = 0; /* clear buf pointer */
rx_bptr = 0; /* clear buf pointer */
switch (RXCS_GETFNC (data)) { /* case on func */
case RXCS_FILL:
rx_state = FILL; /* state = fill */
@@ -287,10 +287,10 @@ return SCPE_OK;
RWDS Save sector, set TR, set RWDT
RWDT Save track, set RWXFR
RWXFR Read/write buffer
FILL copy ir to rx_buf[bptr], advance ptr
if bptr > max, finish command, else set tr
EMPTY if bptr > max, finish command, else
copy rx_buf[bptr] to ir, advance ptr, set tr
FILL copy ir to rx_buf[rx_bptr], advance ptr
if rx_bptr > max, finish command, else set tr
EMPTY if rx_bptr > max, finish command, else
copy rx_buf[rx_bptr] to ir, advance ptr, set tr
CMD_COMPLETE copy requested data to ir, finish command
INIT_COMPLETE read drive 0, track 1, sector 1 to buffer, finish command
@@ -302,6 +302,7 @@ t_stat rx_svc (UNIT *uptr)
{
int32 i, func;
uint32 da;
int8 *fbuf = uptr->filebuf;
func = RXCS_GETFNC (rx_csr); /* get function */
switch (rx_state) { /* case on state */
@@ -310,17 +311,17 @@ case IDLE: /* idle */
return SCPE_IERR; /* done */
case EMPTY: /* empty buffer */
if (bptr >= RX_NUMBY) rx_done (0, 0); /* done all? */
if (rx_bptr >= RX_NUMBY) rx_done (0, 0); /* done all? */
else {
rx_dbr = rx_buf[bptr]; /* get next */
bptr = bptr + 1;
rx_dbr = rx_buf[rx_bptr]; /* get next */
rx_bptr = rx_bptr + 1;
rx_csr = rx_csr | RXCS_TR; } /* set xfer */
break;
case FILL: /* fill buffer */
rx_buf[bptr] = rx_dbr; /* write next */
bptr = bptr + 1;
if (bptr < RX_NUMBY) rx_csr = rx_csr | RXCS_TR; /* if more, set xfer */
rx_buf[rx_bptr] = rx_dbr; /* write next */
rx_bptr = rx_bptr + 1;
if (rx_bptr < RX_NUMBY) rx_csr = rx_csr | RXCS_TR; /* more? set xfer */
else rx_done (0, 0); /* else done */
break;
@@ -350,13 +351,13 @@ case RWXFR:
if (func == RXCS_WRDEL) rx_esr = rx_esr | RXES_DD; /* del data? */
if (func == RXCS_READ) { /* read? */
for (i = 0; i < RX_NUMBY; i++)
rx_buf[i] = *(((int8 *) uptr->filebuf) + da + i); }
rx_buf[i] = fbuf[da + i]; }
else {
if (uptr->flags & UNIT_WPRT) { /* write and locked? */
rx_done (RXES_WLK, 0100); /* done, error */
break; }
for (i = 0; i < RX_NUMBY; i++) /* write */
*(((int8 *) uptr->filebuf) + da + i) = rx_buf[i];
fbuf[da + i] = rx_buf[i];
da = da + RX_NUMBY;
if (da > uptr->hwmark) uptr->hwmark = da; }
rx_done (0, 0); /* done */
@@ -377,7 +378,7 @@ case INIT_COMPLETE: /* init complete */
break; }
da = CALC_DA (1, 1); /* track 1, sector 1 */
for (i = 0; i < RX_NUMBY; i++) /* read sector */
rx_buf[i] = *(((int8 *) uptr->filebuf) + da + i);
rx_buf[i] = fbuf[da + i];
rx_done (RXES_ID, 0); /* set done */
if ((rx_unit[1].flags & UNIT_ATT) == 0) rx_ecode = 0020;
break; } /* end case state */

View File

@@ -1,6 +1,6 @@
/* pdp11_ry.c: RY11/RX02 floppy disk simulator
/* pdp11_ry.c: RX211/RXV21/RX02 floppy disk simulator
Copyright (c) 1993-2003, Robert M Supnik
Copyright (c) 1993-2004, 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"),
@@ -23,8 +23,9 @@
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
ry RY11/RX02 floppy disk
ry RX211/RXV21/RX02 floppy disk
29-Dec-03 RMS Added RXV21 support
19-May-03 RMS Revised for new conditional compilation scheme
25-Apr-03 RMS Revised for extended file support
14-Mar-03 RMS Fixed variable size interaction with save/restore
@@ -146,7 +147,6 @@ int32 ry_cwait = 100; /* command time */
int32 ry_swait = 10; /* seek, per track */
int32 ry_xwait = 1; /* tr set time */
uint8 rx2xb[RY_NUMBY] = { 0 }; /* sector buffer */
int32 ry_enb = 0; /* device enable */
DEVICE ry_dev;
t_stat ry_rd (int32 *data, int32 PA, int32 access);
@@ -227,7 +227,7 @@ DEVICE ry_dev = {
RX_NUMDR, 8, 20, 1, 8, 8,
NULL, NULL, &ry_reset,
&ry_boot, &ry_attach, NULL,
&ry_dib, DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS };
&ry_dib, DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_Q18 };
/* I/O dispatch routine, I/O addresses 17777170 - 17777172
@@ -341,6 +341,7 @@ t_stat ry_svc (UNIT *uptr)
int32 i, t, func, bps;
static uint8 estat[8];
uint32 ba, da;
int8 *fbuf = uptr->filebuf;
func = RYCS_GETFNC (ry_csr); /* get function */
bps = (ry_csr & RYCS_DEN)? RY_NUMBY: RX_NUMBY; /* get sector size */
@@ -401,12 +402,12 @@ case RWXFR: /* read/write */
if (func == RYCS_WRDEL) ry_esr = ry_esr | RYES_DD; /* del data? */
if (func == RYCS_READ) { /* read? */
for (i = 0; i < bps; i++)
rx2xb[i] = *(((int8 *) uptr->filebuf) + da + i); }
rx2xb[i] = fbuf[da + i]; }
else { if (uptr->flags & UNIT_WPRT) { /* write and locked? */
ry_done (0, 0100); /* done, error */
break; }
for (i = 0; i < bps; i++) /* write */
*(((int8 *) uptr->filebuf) + da + i) = rx2xb[i];
fbuf[da + i] = rx2xb[i];
da = da + bps;
if (da > uptr->hwmark) uptr->hwmark = da; }
ry_done (0, 0); /* done */
@@ -420,8 +421,7 @@ case SDCNF: /* confirm set density */
sim_activate (uptr, ry_cwait * 100); /* schedule operation */
break;
case SDXFR: /* erase disk */
for (i = 0; i < (int32) uptr->capac; i++)
*(((int8 *) uptr->filebuf) + i) = 0;
for (i = 0; i < (int32) uptr->capac; i++) fbuf[i] = 0;
uptr->hwmark = uptr->capac;
if (ry_csr & RYCS_DEN) uptr->flags = uptr->flags | UNIT_DEN;
else uptr->flags = uptr->flags & ~UNIT_DEN;
@@ -462,7 +462,7 @@ case INIT_COMPLETE: /* init complete */
break; }
da = CALC_DA (1, 1, bps); /* track 1, sector 1 */
for (i = 0; i < bps; i++) /* read sector */
rx2xb[i] = *(((int8 *) uptr->filebuf) + da + i);
rx2xb[i] = fbuf[da + i];
ry_done (RYES_ID, 0); /* set done */
if ((ry_unit[1].flags & UNIT_ATT) == 0) ry_ecode = 0020;
break; } /* end case state */

View File

@@ -1,6 +1,6 @@
/* pdp11_stddev.c: PDP-11 standard I/O devices simulator
Copyright (c) 1993-2003, Robert M Supnik
Copyright (c) 1993-2004, 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 @@
tti,tto DL11 terminal input/output
clk KW11L line frequency clock
29-Dec-03 RMS Added console backpressure support
25-Apr-03 RMS Revised for extended file support
01-Mar-03 RMS Added SET/SHOW CLOCK FREQ, SET TTI CTRL-C
22-Nov-02 RMS Changed terminal default to 7B for UNIX
@@ -319,10 +320,12 @@ 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 */
tto_csr = tto_csr | CSR_DONE;
if (tto_csr & CSR_IE) SET_INT (TTO);
c = tto_unit.buf & ((tto_unit.flags & UNIT_8B)? 0377: 0177);
if ((r = sim_putchar (c)) != SCPE_OK) return r;
tto_unit.pos = tto_unit.pos + 1;
return SCPE_OK;
}

View File

@@ -23,8 +23,10 @@
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
22-Dec-03 RMS Added second DEUNA/DELUA support
18-Oct-03 RMS Added DECtape off reel message
06-May-03 RMS Added support for second DEQNA/DELQA
09-Jan-03 RMS Added DELUA support
09-Jan-03 RMS Added DELUA/DEUNA support
17-Oct-02 RMS Fixed bugs in branch, SOB address parsing
09-Oct-02 RMS Added DELQA support
12-Sep-02 RMS Added TMSCP, KW11P, RX211 support, RAD50 examine
@@ -64,7 +66,7 @@ extern DEVICE dt_dev;
extern DEVICE tm_dev, ts_dev;
extern DEVICE tq_dev;
extern DEVICE xq_dev, xqb_dev;
extern DEVICE xu_dev;
extern DEVICE xu_dev, xub_dev;
extern UNIT cpu_unit;
extern REG cpu_reg[];
extern uint16 *M;
@@ -113,6 +115,7 @@ DEVICE *sim_devices[] = {
&xq_dev,
&xqb_dev,
&xu_dev,
&xub_dev,
NULL };
const char *sim_stop_messages[] = {
@@ -138,7 +141,8 @@ const char *sim_stop_messages[] = {
"Trap vector fetch abort",
"Trap stack push abort",
"RQDX3 consistency error",
"Sanity timer expired" };
"Sanity timer expired"
"DECtape off reel" };
/* Binary loader.

View File

@@ -1,6 +1,6 @@
/* pdp11_tc.c: PDP-11 DECtape simulator
Copyright (c) 1993-2003, Robert M Supnik
Copyright (c) 1993-2004, 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,10 @@
tc TC11/TU56 DECtape
29-Dec-03 RMS Changed initial status to disabled (in Qbus system)
18-Oct-03 RMS Fixed reverse checksum in read all
Added DECtape off reel message
Simplified timing
25-Apr-03 RMS Revised for extended file support
14-Mar-03 RMS Fixed variable size interaction with save/restore
29-Sep-02 RMS Added variable address support to bootstrap
@@ -58,13 +62,16 @@
When a 16b or 12b DECtape file is read in, it is converted to 18b/36b format.
DECtape motion is measured in 3b lines. Time between lines is 33.33us.
Tape density is nominally 300 lines per inch. The format of a DECtape is
Tape density is nominally 300 lines per inch. The format of a DECtape (as
taken from the TD8E formatter) is:
reverse end zone 36000 lines ~ 10 feet
reverse end zone 8192 reverse end zone codes ~ 10 feet
reverse buffer 200 interblock codes
block 0
:
block n
forward end zone 36000 lines ~ 10 feet
forward buffer 200 interblock codes
forward end zone 8192 forward end zone codes ~ 10 feet
A block consists of five 18b header words, a tape-specific number of data
words, and five 18b trailer words. All systems except the PDP-8 use a
@@ -79,9 +86,9 @@
header word 0 0
header word 1 block number (for forward reads)
header words 2,3 0
header word 4 0
header word 4 checksum (for reverse reads)
:
trailer word 4 checksum
trailer word 4 checksum (for forward reads)
trailer words 3,2 0
trailer word 1 block number (for reverse reads)
trailer word 0 0
@@ -106,13 +113,15 @@
/* System independent DECtape constants */
#define DT_EZLIN 36000 /* end zone length */
#define DT_HTLIN 30 /* header/trailer lines */
#define DT_BLKLN 6 /* blk no line in h/t */
#define DT_CSMLN 24 /* checksum line in h/t */
#define DT_HTWRD (DT_HTLIN / DT_WSIZE) /* header/trailer words */
#define DT_BLKWD (DT_BLKLN / DT_WSIZE) /* blk no word in h/t */
#define DT_CSMWD (DT_CSMLN / DT_WSIZE) /* checksum word in h/t */
#define DT_LPERMC 6 /* lines per mark track */
#define DT_BLKWD 1 /* blk no word in h/t */
#define DT_CSMWD 4 /* checksum word in h/t */
#define DT_HTWRD 5 /* header/trailer words */
#define DT_EZLIN (8192 * DT_LPERMC) /* end zone length */
#define DT_BFLIN (200 * DT_LPERMC) /* buffer length */
#define DT_BLKLN (DT_BLKWD * DT_LPERMC) /* blk no line in h/t */
#define DT_CSMLN (DT_CSMWD * DT_LPERMC) /* csum line in h/t */
#define DT_HTLIN (DT_HTWRD * DT_LPERMC) /* header/trailer lines */
/* 16b, 18b, 36b DECtape constants */
@@ -270,8 +279,7 @@ int32 tcba = 0; /* bus address */
int32 tcdt = 0; /* data */
int32 dt_ctime = 100; /* fast cmd time */
int32 dt_ltime = 12; /* interline time */
int32 dt_actime = 54000; /* accel time */
int32 dt_dctime = 72000; /* decel time */
int32 dt_dctime = 40000; /* decel time */
int32 dt_substate = 0;
int32 dt_logblk = 0;
@@ -340,7 +348,6 @@ REG dt_reg[] = {
{ FLDATA (IE, tccm, CSR_V_DONE) },
{ DRDATA (CTIME, dt_ctime, 31), REG_NZ },
{ DRDATA (LTIME, dt_ltime, 31), REG_NZ },
{ DRDATA (ACTIME, dt_actime, 31), REG_NZ },
{ DRDATA (DCTIME, dt_dctime, 31), REG_NZ },
{ ORDATA (SUBSTATE, dt_substate, 1) },
{ DRDATA (LBLK, dt_logblk, 12), REG_HIDDEN },
@@ -371,7 +378,7 @@ DEVICE dt_dev = {
DT_NUMDR + 1, 8, 24, 1, 8, 18,
NULL, NULL, &dt_reset,
&dt_boot, &dt_attach, &dt_detach,
&dt_dib, DEV_DISABLE | DEV_UBUS };
&dt_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS };
/* IO dispatch routines, I/O addresses 17777340 - 17777350 */
@@ -523,7 +530,7 @@ if (new_fnc == FNC_SSEL) { /* stop unit? */
if (prev_mot == DTS_STOP) { /* start? */
if (dt_setpos (uptr)) return; /* update pos */
sim_cancel (uptr); /* stop current */
sim_activate (uptr, dt_actime); /* schedule accel */
sim_activate (uptr, dt_dctime - (dt_dctime >> 2)); /* sched accel */
DTS_SETSTA (DTS_ACCF | new_dir, 0); /* state = accel */
DTS_SET2ND (DTS_ATSF | new_dir, new_fnc); /* next = fnc */
return; }
@@ -537,7 +544,7 @@ if (prev_dir ^ new_dir) { /* dir chg? */
if (prev_mot < DTS_ACCF) { /* not accel/at speed? */
if (dt_setpos (uptr)) return; /* update pos */
sim_cancel (uptr); /* cancel cur */
sim_activate (uptr, dt_actime); /* schedule accel */
sim_activate (uptr, dt_dctime - (dt_dctime >> 2)); /* sched accel */
DTS_SETSTA (DTS_ACCF | new_dir, 0); /* state = accel */
DTS_SET2ND (DTS_ATSF | new_dir, new_fnc); /* next = fnc */
return; }
@@ -674,11 +681,13 @@ case DTS_STOP: /* stop */
delta = 0;
break;
case DTS_DECF: /* slowing */
ulin = ut / (uint32) dt_ltime; udelt = dt_dctime / dt_ltime;
ulin = ut / (uint32) dt_ltime;
udelt = dt_dctime / dt_ltime;
delta = ((ulin * udelt * 2) - (ulin * ulin)) / (2 * udelt);
break;
case DTS_ACCF: /* accelerating */
ulin = ut / (uint32) dt_ltime; udelt = dt_actime / dt_ltime;
ulin = ut / (uint32) dt_ltime;
udelt = (dt_dctime - (dt_dctime >> 2)) / dt_ltime;
delta = (ulin * ulin) / (2 * udelt);
break;
case DTS_ATSF: /* at speed */
@@ -715,7 +724,7 @@ t_stat dt_svc (UNIT *uptr)
int32 mot = DTS_GETMOT (uptr->STATE);
int32 dir = mot & DTS_DIR;
int32 fnc = DTS_GETFNC (uptr->STATE);
int32 *bptr = uptr->filebuf;
int32 *fbuf = uptr->filebuf;
int32 blk, wrd, relpos, dat;
uint32 ba, ma, mma;
@@ -728,10 +737,10 @@ uint32 ba, ma, mma;
switch (mot) {
case DTS_DECF: case DTS_DECR: /* decelerating */
if (dt_setpos (uptr)) return SCPE_OK; /* update pos */
if (dt_setpos (uptr)) return STOP_DTOFF; /* update pos */
uptr->STATE = DTS_NXTSTA (uptr->STATE); /* advance state */
if (uptr->STATE) /* not stopped? */
sim_activate (uptr, dt_actime); /* must be reversing */
sim_activate (uptr, dt_dctime - (dt_dctime >> 2)); /* reversing */
return SCPE_OK;
case DTS_ACCF: case DTS_ACCR: /* accelerating */
dt_newfnc (uptr, DTS_NXTSTA (uptr->STATE)); /* adv state, sched */
@@ -748,7 +757,7 @@ default: /* other */
Off reel - detach unit (it must be deselected)
*/
if (dt_setpos (uptr)) return SCPE_OK; /* update pos */
if (dt_setpos (uptr)) return STOP_DTOFF; /* update pos */
if (DT_QEZ (uptr)) { /* in end zone? */
dt_seterr (uptr, STA_END); /* end zone error */
return SCPE_OK; }
@@ -785,7 +794,7 @@ case FNC_READ: /* read */
dt_seterr (uptr, STA_NXM);
break; }
ba = (blk * DTU_BSIZE (uptr)) + wrd; /* buffer ptr */
M[mma >> 1] = tcdt = bptr[ba] & DMASK; /* read word */
M[mma >> 1] = tcdt = fbuf[ba] & DMASK; /* read word */
tcwc = (tcwc + 1) & DMASK; /* incr MA, WC */
tcba = (tcba + 2) & DMASK;
if (tcba <= 1) tccm = CSR_INCMEX (tccm);
@@ -822,7 +831,7 @@ case FNC_WRIT: /* write */
tcba = (tcba + 2) & DMASK;
if (tcba <= 1) tccm = CSR_INCMEX (tccm); }
ba = (blk * DTU_BSIZE (uptr)) + wrd; /* buffer ptr */
bptr[ba] = tcdt; /* write word */
fbuf[ba] = tcdt; /* write word */
if (ba >= uptr->hwmark) uptr->hwmark = ba + 1;
if (tcwc == 0) dt_substate = 1;
if (wrd != (dir? 0: DTU_BSIZE (uptr) - 1)) /* not end blk? */
@@ -844,7 +853,7 @@ case FNC_RALL:
(relpos < (DTU_LPERB (uptr) - DT_HTLIN))) {
wrd = DT_LIN2WD (uptr->pos, uptr);
ba = (blk * DTU_BSIZE (uptr)) + wrd; /* buffer ptr */
dat = bptr[ba]; } /* get tape word */
dat = fbuf[ba]; } /* get tape word */
else dat = dt_gethdr (uptr, blk, relpos); /* get hdr */
if (dir) dat = dt_comobv (dat); /* rev? comp obv */
tcdt = dat & DMASK; /* low 16b */
@@ -866,7 +875,7 @@ case FNC_WALL:
dat = (STA_GETXD (tcst) << 16) | tcdt; /* get data word */
if (dir) dat = dt_comobv (dat); /* rev? comp obv */
ba = (blk * DTU_BSIZE (uptr)) + wrd; /* buffer ptr */
bptr[ba] = dat; /* write word */
fbuf[ba] = dat; /* write word */
if (ba >= uptr->hwmark) uptr->hwmark = ba + 1; }
/* else /* ignore hdr */
sim_activate (uptr, DT_WSIZE * dt_ltime);
@@ -941,13 +950,13 @@ return dat;
int32 dt_csum (UNIT *uptr, int32 blk)
{
int32 *bptr = uptr->filebuf;
int32 *fbuf = uptr->filebuf;
int32 ba = blk * DTU_BSIZE (uptr);
int32 i, csum, wrd;
csum = 077; /* init csum */
for (i = 0; i < DTU_BSIZE (uptr); i++) { /* loop thru buf */
wrd = bptr[ba + i] ^ 0777777; /* get ~word */
wrd = fbuf[ba + i] ^ 0777777; /* get ~word */
csum = csum ^ (wrd >> 12) ^ (wrd >> 6) ^ wrd; }
return (csum & 077);
}
@@ -959,6 +968,7 @@ int32 dt_gethdr (UNIT *uptr, int32 blk, int32 relpos)
int32 wrd = relpos / DT_WSIZE;
if (wrd == DT_BLKWD) return blk; /* fwd blknum */
if (wrd == DT_CSMWD) return 077; /* rev csum */
if (wrd == (2 * DT_HTWRD + DTU_BSIZE (uptr) - DT_CSMWD - 1)) /* fwd csum */
return (dt_csum (uptr, blk) << 12);
if (wrd == (2 * DT_HTWRD + DTU_BSIZE (uptr) - DT_BLKWD - 1)) /* rev blkno */
@@ -1067,7 +1077,7 @@ t_stat dt_attach (UNIT *uptr, char *cptr)
{
uint16 pdp8b[D8_NBSIZE];
uint16 pdp11b[D18_BSIZE];
uint32 ba, sz, k, *bptr;
uint32 ba, sz, k, *fbuf;
int32 u = uptr - dt_dev.units;
t_stat r;
@@ -1089,7 +1099,7 @@ uptr->filebuf = calloc (uptr->capac, sizeof (int32));
if (uptr->filebuf == NULL) { /* can't alloc? */
detach_unit (uptr);
return SCPE_MEM; }
bptr = uptr->filebuf; /* file buffer */
fbuf = uptr->filebuf; /* file buffer */
printf ("%s%d: ", sim_dname (&dt_dev), u);
if (uptr->flags & UNIT_8FMT) printf ("12b format");
else if (uptr->flags & UNIT_11FMT) printf ("16b format");
@@ -1101,9 +1111,9 @@ if (uptr->flags & UNIT_8FMT) { /* 12b? */
if (k == 0) break;
for ( ; k < D8_NBSIZE; k++) pdp8b[k] = 0;
for (k = 0; k < D8_NBSIZE; k = k + 3) { /* loop thru blk */
bptr[ba] = ((uint32) (pdp8b[k] & 07777) << 6) |
fbuf[ba] = ((uint32) (pdp8b[k] & 07777) << 6) |
((uint32) (pdp8b[k + 1] >> 6) & 077);
bptr[ba + 1] = ((pdp8b[k + 1] & 077) << 12) |
fbuf[ba + 1] = ((pdp8b[k + 1] & 077) << 12) |
((uint32) (pdp8b[k + 2] & 07777));
ba = ba + 2; } /* end blk loop */
} /* end file loop */
@@ -1114,7 +1124,7 @@ else if (uptr->flags & UNIT_11FMT) { /* 16b? */
if (k == 0) break;
for ( ; k < D18_BSIZE; k++) pdp11b[k] = 0;
for (k = 0; k < D18_BSIZE; k++)
bptr[ba++] = pdp11b[k]; }
fbuf[ba++] = pdp11b[k]; }
uptr->hwmark = ba; } /* end elif */
else uptr->hwmark = fxread (uptr->filebuf, sizeof (int32),
uptr->capac, uptr->fileref);
@@ -1137,7 +1147,7 @@ t_stat dt_detach (UNIT* uptr)
{
uint16 pdp8b[D8_NBSIZE];
uint16 pdp11b[D18_BSIZE];
uint32 ba, k, *bptr;
uint32 ba, k, *fbuf;
int32 u = uptr - dt_dev.units;
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK;
@@ -1148,17 +1158,17 @@ if (sim_is_active (uptr)) { /* active? cancel op */
tccm = tccm | CSR_ERR | CSR_DONE;
if (tccm & CSR_IE) SET_INT (DTA); }
uptr->STATE = uptr->pos = 0; }
bptr = uptr->filebuf; /* file buffer */
fbuf = uptr->filebuf; /* file buffer */
if (uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) { /* any data? */
printf ("%s%d: writing buffer to file\n", sim_dname (&dt_dev), u);
rewind (uptr->fileref); /* start of file */
if (uptr->flags & UNIT_8FMT) { /* 12b? */
for (ba = 0; ba < uptr->hwmark; ) { /* loop thru file */
for (k = 0; k < D8_NBSIZE; k = k + 3) { /* loop blk */
pdp8b[k] = (bptr[ba] >> 6) & 07777;
pdp8b[k + 1] = ((bptr[ba] & 077) << 6) |
((bptr[ba + 1] >> 12) & 077);
pdp8b[k + 2] = bptr[ba + 1] & 07777;
pdp8b[k] = (fbuf[ba] >> 6) & 07777;
pdp8b[k + 1] = ((fbuf[ba] & 077) << 6) |
((fbuf[ba + 1] >> 12) & 077);
pdp8b[k + 2] = fbuf[ba + 1] & 07777;
ba = ba + 2; } /* end loop blk */
fxwrite (pdp8b, sizeof (int16), D8_NBSIZE, uptr->fileref);
if (ferror (uptr->fileref)) break; } /* end loop file */
@@ -1166,7 +1176,7 @@ if (uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) { /* any data? */
else if (uptr->flags & UNIT_11FMT) { /* 16b? */
for (ba = 0; ba < uptr->hwmark; ) { /* loop thru file */
for (k = 0; k < D18_BSIZE; k++) /* loop blk */
pdp11b[k] = bptr[ba++] & DMASK;
pdp11b[k] = fbuf[ba++] & DMASK;
fxwrite (pdp11b, sizeof (int16), D18_BSIZE, uptr->fileref);
if (ferror (uptr->fileref)) break; } /* end loop file */
} /* end if 16b */

View File

@@ -1,6 +1,6 @@
/* pdp11_tm.c: PDP-11 magnetic tape simulator
Copyright (c) 1993-2003, Robert M Supnik
Copyright (c) 1993-2004, 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,7 @@
tm TM11/TU10 magtape
29-Dec-03 RMS Added 18b Qbus support
25-Apr-03 RMS Revised for extended file support
28-Mar-03 RMS Added multiformat support
28-Feb-03 RMS Revised for magtape library, added logging
@@ -231,7 +232,7 @@ DEVICE tm_dev = {
TM_NUMDR, 10, 31, 1, 8, 8,
NULL, NULL, &tm_reset,
&tm_boot, &tm_attach, &tm_detach,
&tm_dib, DEV_DISABLE | DEV_UBUS };
&tm_dib, DEV_DISABLE | DEV_UBUS | DEV_Q18 };
/* I/O dispatch routine, I/O addresses 17772520 - 17772532

View File

@@ -69,6 +69,27 @@
Modification history:
03-Dec-03 DTH Added minimum name length to show xq eth
25-Nov-03 DTH Reworked interrupts to fix broken XQB implementation
19-Nov-03 MP Rearranged timer reset sequencing to allow for a device to be
disabled after it had been enabled.
17-Nov-03 DTH Standardized #include of timeb.h
28-Sep-03 MP - Fixed bug in xq_process_setup which would leave the
device in promiscuous or all multicast mode once it
ever had been there.
- Fixed output format in show_xq_sanity to end in "\n"
- Added display of All Multicase and promiscuous to
xq_show_filters
- The stuck in All Multicast or Promiscuous issue is
worse than previously thought. See comments in
xq_process_setup.
- Change xq_setmac to also allow ":" as a address
separator character, since sim_ether's eth_mac_fmt
formats them with this separator character.
- Changed xq_sw_reset to behave more like the set of
actions described in Table 3-6 of the DELQA manua.
The manual mentions "N/A" which I'm interpreting to
mean "Not Affected".
05-Jun-03 DTH Added receive packet splitting
03-Jun-03 DTH Added SHOW XQ FILTERS
02-Jun-03 DTH Added SET/SHOW XQ STATS (packet statistics), runt & giant processing
@@ -92,7 +113,7 @@
of Receiver Enabled. This was an issue since the
it seems that at least VMS's XQ driver makes this
transition often and the resulting overhead reduces
the simulated CPU instruction execution thruput by
the simulated CPU instruction execution throughput by
about 40%. I start the system id timer on device
reset and it fires once a second so that it can
leverage the reasonably recalibrated tmr_poll value.
@@ -100,7 +121,7 @@
dynamically computed clock values to achieve an
approximate interval of 100 per second. This is
more than sufficient for normal system behaviour
expecially since we service recieves with every
expecially since we service receives with every
transmit. The previous fixed value of 2500
attempted to get 200/sec but it was a guess that
didn't adapt. On faster host systems (possibly
@@ -128,7 +149,7 @@
05-Dec-02 MP Restructured the flow of processing in xq_svc so that eth_read
is called repeatedly until either a packet isn't found or
there is no room for another one in the queue. Once that has
been done, xq_processrdbl is called to pass the queued packets
been done, xq_process_rdbl is called to pass the queued packets
into the simulated system as space is available there.
xq_process_rdbl is also called at the beginning of xq_svc to
drain the queue into the simulated system, making more room
@@ -216,8 +237,6 @@ t_stat xq_process_xbdl(CTLR* xq);
t_stat xq_dispatch_xbdl(CTLR* xq);
void xq_start_receiver(void);
void xq_sw_reset(CTLR* xq);
int32 xq_inta (void);
int32 xq_intb (void);
t_stat xq_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
t_stat xq_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);
void xq_start_santmr(CTLR* xq);
@@ -230,6 +249,9 @@ void xqa_read_callback(int status);
void xqb_read_callback(int status);
void xqa_write_callback(int status);
void xqb_write_callback(int status);
void xq_setint (CTLR* xq);
void xq_clrint (CTLR* xq);
int32 xq_int (void);
struct xq_device xqa = {
xqa_read_callback, /* read callback routine */
@@ -249,7 +271,7 @@ struct xq_device xqb = {
/* SIMH device structures */
DIB xqa_dib = { IOBA_XQ, IOLN_XQ, &xq_rd, &xq_wr,
1, IVCL (XQ), 0, { &xq_inta } };
1, IVCL (XQ), 0, { &xq_int } };
UNIT xqa_unit[] = {
{ UDATA (&xq_svc, UNIT_ATTABLE + UNIT_DISABLE, 2047) }, /* receive timer */
@@ -268,6 +290,7 @@ REG xqa_reg[] = {
{ GRDATA ( XBDL, xqa.xbdl, XQ_RDX, 32, 0) },
{ GRDATA ( VAR, xqa.var, XQ_RDX, 16, 0) },
{ GRDATA ( CSR, xqa.csr, XQ_RDX, 16, 0) },
{ 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},
{ GRDATA ( SETUP_L1, xqa.setup.l1, XQ_RDX, 32, 0), REG_HRO},
@@ -279,7 +302,7 @@ REG xqa_reg[] = {
};
DIB xqb_dib = { IOBA_XQB, IOLN_XQB, &xq_rd, &xq_wr,
1, IVCL (XQ), 0, { &xq_intb } };
1, IVCL (XQ), 0, { &xq_int } };
UNIT xqb_unit[] = {
{ UDATA (&xq_svc, UNIT_ATTABLE + UNIT_DISABLE, 2047) }, /* receive timer */
@@ -298,6 +321,7 @@ REG xqb_reg[] = {
{ GRDATA ( XBDL, xqb.xbdl, XQ_RDX, 32, 0) },
{ GRDATA ( VAR, xqb.var, XQ_RDX, 16, 0) },
{ GRDATA ( CSR, xqb.csr, XQ_RDX, 16, 0) },
{ FLDATA ( INT, xqb.irq, 0) },
{ GRDATA ( SETUP_PRM, xqb.setup.promiscuous, XQ_RDX, 32, 0), REG_HRO},
{ GRDATA ( SETUP_MLT, xqb.setup.multicast, XQ_RDX, 32, 0), REG_HRO},
{ GRDATA ( SETUP_L1, xqb.setup.l1, XQ_RDX, 32, 0), REG_HRO},
@@ -372,7 +396,7 @@ void xq_csr_changes(CTLR* xq, uint16 data);
void xq_var_changes(CTLR* xq, uint16 data);
/* sanity timer debugging */
#include <sys\timeb.h>
#include <sys/timeb.h>
struct timeb start, finish;
#endif /* XQ_DEBUG */
@@ -575,7 +599,9 @@ t_stat xq_setmac (UNIT* uptr, int32 val, char* cptr, void* desc)
if (len != 17) return SCPE_ARG;
/* make sure byte separators are OK */
for (i=2; i<len; i=i+3) {
if ((cptr[i] != '-') && (cptr[i] != '.')) return SCPE_ARG;
if ((cptr[i] != '-') &&
(cptr[i] != '.') &&
(cptr[i] != ':')) return SCPE_ARG;
cptr[i] = '\0';
}
/* get and set address bytes */
@@ -601,15 +627,17 @@ t_stat xq_setmac (UNIT* uptr, int32 val, char* cptr, void* desc)
t_stat xq_showeth (FILE* st, UNIT* uptr, int32 val, void* desc)
{
#define XQ_MAX_LIST 10
int i;
ETH_LIST list[XQ_MAX_LIST];
int number = eth_devices(XQ_MAX_LIST, list);
fprintf(st, "ETH devices:\n");
if (number)
if (number) {
int i, min, len;
for (i=0, min=0; i<number; i++)
if ((len = strlen(list[i].name)) > min) min = len;
for (i=0; i<number; i++)
fprintf(st," %d %s (%s)\n", i, list[i].name, list[i].desc);
else
fprintf(st," %d %-*s (%s)\n", i, min, list[i].name, list[i].desc);
} else
fprintf(st, " no network devices are available\n");
return SCPE_OK;
}
@@ -662,6 +690,10 @@ t_stat xq_show_filters (FILE* st, UNIT* uptr, int32 val, void* desc)
eth_mac_fmt((ETH_MAC*)xq->var->setup.macs[i], buffer);
fprintf(st, " [%2d]: %s\n", i, buffer);
};
if (xq->var->setup.multicast)
fprintf(st, "All Multicast Receive Mode\n");
if (xq->var->setup.promiscuous)
fprintf(st, "Promiscuous Receive Mode\n");
return SCPE_OK;
}
@@ -695,8 +727,8 @@ t_stat xq_show_sanity (FILE* st, UNIT* uptr, int32 val, void* desc)
fprintf(st, "sanity=");
switch (xq->var->sanity.enabled) {
case 0: fprintf(st, "OFF"); break;
case 1: fprintf(st, "ON"); break;
case 0: fprintf(st, "OFF\n"); break;
case 1: fprintf(st, "ON\n"); break;
}
return SCPE_OK;
}
@@ -724,7 +756,7 @@ t_stat xq_nxm_error(CTLR* xq)
/* interrupt if required */
if (xq->var->csr & XQ_CSR_IE)
SET_INT(XQ);
xq_setint(xq);
return SCPE_OK;
}
@@ -761,7 +793,7 @@ void xq_write_callback (CTLR* xq, int status)
/* update csr */
xq->var->csr |= XQ_CSR_XI;
if (xq->var->csr & XQ_CSR_IE)
SET_INT(XQ);
xq_setint(xq);
/* reset sanity timer */
xq_reset_santmr(xq);
@@ -846,7 +878,7 @@ t_stat xq_process_rbdl(CTLR* xq)
uint16 b_length, w_length, rbl;
uint32 address;
struct xq_msg_itm* item;
char* rbuf;
uint8* rbuf;
#ifdef XQ_DEBUG
fprintf(stderr,"%s: CSR - Processing read\n", xq->dev->name);
@@ -906,7 +938,7 @@ t_stat xq_process_rbdl(CTLR* xq)
#endif
/* pad runts with zeros up to minimum size - this allows "legal" (size - 60)
processing of those weird short ARP packets that seem to occur occasionally */
memset(&item->packet.msg[rbl], 0, ETH_MIN_PACKET);
memset(&item->packet.msg[rbl], 0, ETH_MIN_PACKET-rbl);
rbl = ETH_MIN_PACKET;
};
@@ -976,7 +1008,7 @@ t_stat xq_process_rbdl(CTLR* xq)
/* mark transmission complete */
xq->var->csr |= XQ_CSR_RI;
if (xq->var->csr & XQ_CSR_IE)
SET_INT(XQ);
xq_setint(xq);
/* set to next bdl (implicit chain) */
xq->var->rbdl_ba += 12;
@@ -1059,15 +1091,42 @@ t_stat xq_process_setup(CTLR* xq)
xq->var->setup.macs[i+7][j] = xq->var->write_buffer.msg[(i + 0101) + (j * 8)];
}
/*
Under VMS the setup packet that is passed to turn promiscuous
off after it has been on doesn't seem to follow the rules documented
in both the DEQNA and DELQA manuals.
These rules seem to say that setup packets less than 128 should only
modify the address filter set and probably not the All-Multicast and
Promiscuous modes, however, VMS V5-5 and V7.3 seem to send a 127 byte
packet to turn this functionality off. I'm not sure how real hardware
behaves in this case, since the only consequence is extra interrupt
load. To realize and retain the benefits of the newly added BPF
functionality in sim_ether, I've modified the logic implemented here
to disable Promiscuous mode when a "small" setup packet is processed.
I'm deliberately not modifying the All-Multicast mode the same way
since I don't have an observable case of its behavior. These two
different modes come from very different usage situations:
1) Promiscuous mode is usually entered for relatively short periods
of time due to the needs of a specific application program which
is doing some sort of management/monitoring function (i.e. tcpdump)
2) All-Multicast mode is only entered by the OS Kernel Port Driver
when it happens to have clients (usually network stacks or service
programs) which as a group need to listen to more multicast ethernet
addresses than the 12 (or so) which the hardware supports directly.
so, I believe that the All-Multicast mode, is first rarely used, and if
it ever is used, once set, it will probably be set either forever or for
long periods of time, and the additional interrupt processing load to
deal with the distinctly lower multicast traffic set is clearly lower than
that of the promiscuous mode.
*/
xq->var->setup.promiscuous = 0;
/* process high byte count */
if (xq->var->write_buffer.len > 128) {
uint16 len = xq->var->write_buffer.len;
uint16 led, san;
if (len & XQ_SETUP_MC)
xq->var->setup.multicast = 1;
if (len & XQ_SETUP_PM)
xq->var->setup.promiscuous = 1;
xq->var->setup.multicast = (0 != (len & XQ_SETUP_MC));
xq->var->setup.promiscuous = (0 != (len & XQ_SETUP_PM));
if (led = (len & XQ_SETUP_LD) >> 2) {
switch (led) {
case 1: xq->var->setup.l1 = 0; break;
@@ -1214,7 +1273,7 @@ t_stat xq_process_xbdl(CTLR* xq)
/* mark transmission complete */
xq->var->csr |= XQ_CSR_XI;
if (xq->var->csr & XQ_CSR_IE)
SET_INT(XQ);
xq_setint(xq);
/* now trigger "read" of setup or loopback packet */
if (~xq->var->csr & XQ_CSR_RL)
@@ -1446,13 +1505,26 @@ void xq_sw_reset(CTLR* xq)
xq->var->csr |= XQ_CSR_OK;
/* clear CPU interrupts */
CLR_INT(XQ);
xq_clrint(xq);
/* flush read queue */
xq_clear_queue(&xq->var->ReadQ);
/* clear setup info */
memset (&xq->var->setup, 0, sizeof(xq->var->setup));
xq->var->setup.multicast = 0;
xq->var->setup.promiscuous = 0;
if (xq->var->etherface) {
int count = 0;
ETH_MAC zeros = {0, 0, 0, 0, 0, 0};
ETH_MAC filters[XQ_FILTER_MAX + 1];
/* set ethernet filter */
/* memcpy (filters[count++], xq->mac, sizeof(ETH_MAC)); */
for (i = 0; i < XQ_FILTER_MAX; i++)
if (memcmp(zeros, &xq->var->setup.macs[i], sizeof(ETH_MAC)))
memcpy (filters[count++], xq->var->setup.macs[i], sizeof(ETH_MAC));
eth_filter (xq->var->etherface, count, filters, xq->var->setup.multicast, xq->var->setup.promiscuous);
}
}
/* write registers: */
@@ -1676,7 +1748,7 @@ t_stat xq_process_bootrom (CTLR* xq)
/* mark transmission complete */
xq->var->csr |= XQ_CSR_RI;
if (xq->var->csr & XQ_CSR_IE)
SET_INT(XQ);
xq_setint(xq);
/* reset sanity timer */
xq_reset_santmr(xq);
@@ -1724,8 +1796,8 @@ t_stat xq_wr_csr(CTLR* xq, int32 data)
/* check and correct CPU interrupt state */
old_int_state = (saved_csr & XQ_CSR_IE) && (saved_csr & (XQ_CSR_XI | XQ_CSR_RI));
new_int_state = (xq->var->csr & XQ_CSR_IE) && (xq->var->csr & (XQ_CSR_XI | XQ_CSR_RI));
if ( old_int_state && !new_int_state) CLR_INT(XQ);
if (!old_int_state && new_int_state) SET_INT(XQ);
if ( old_int_state && !new_int_state) xq_clrint(xq);
if (!old_int_state && new_int_state) xq_setint(xq);
#ifdef VM_PDP11
/* request boot/diagnostic rom? [PDP-11 only] */
@@ -1803,12 +1875,6 @@ t_stat xq_reset(DEVICE* dptr)
/* init control status register */
xq->var->csr = XQ_CSR_RL | XQ_CSR_XL;
/* reset ethernet interface */
if (xq->var->etherface) {
status = eth_filter (xq->var->etherface, 1, &xq->var->mac, 0, 0);
xq->var->csr |= XQ_CSR_OK;
}
/* init read queue (first time only) */
status = xq_init_queue (xq, &xq->var->ReadQ);
if (status != SCPE_OK)
@@ -1817,6 +1883,11 @@ t_stat xq_reset(DEVICE* dptr)
/* clear read queue */
xq_clear_queue(&xq->var->ReadQ);
/* reset ethernet interface */
if (xq->var->etherface) {
status = eth_filter (xq->var->etherface, 1, &xq->var->mac, 0, 0);
xq->var->csr |= XQ_CSR_OK;
/* start sanity timer if power-on SANITY is set */
switch (xq->var->type) {
case XQ_T_DEQNA:
@@ -1830,6 +1901,8 @@ t_stat xq_reset(DEVICE* dptr)
xq_start_idtmr(xq);
break;
};
}
return SCPE_OK;
}
@@ -1841,11 +1914,9 @@ void xq_start_santmr(CTLR* xq)
/* must be recalculated each time since tmr_poll is a dynamic number */
const int32 quarter_sec = (clk_tps * tmr_poll) / 4;
#if 0
#ifdef XQ_DEBUG
fprintf(stderr,"%s: SANITY TIMER ENABLED, qsecs: %d, poll:%d\n",
xq->dev->name, xq->var->sanity.quarter_secs, tmr_poll);
#endif
#endif
if (sim_is_active(xq_santmr)) /* cancel timer, just in case */
sim_cancel(xq_santmr);
@@ -1897,12 +1968,10 @@ t_stat xq_sansvc(UNIT* uptr)
If this section is entered, it means that the sanity timer has expired
without being reset, and the controller must reboot the processor.
*/
#if 0
#ifdef XQ_DEBUG
ftime(&finish);
fprintf(stderr,"%s: SANITY TIMER EXPIRED, qsecs: %d, poll: %d, elapsed: %d\n",
xq->dev->name, xq->var->sanity.quarter_secs, tmr_poll, finish.time - start.time);
#endif
#endif
xq_boot_host();
}
@@ -1944,6 +2013,9 @@ t_stat xq_system_id (CTLR* xq, const ETH_MAC dest, uint16 receipt_id)
uint8* const msg = &system_id.msg[0];
t_stat status;
#ifdef XQ_DEBUG
fprintf(stderr,"%s: SYSTEM ID BROADCAST\n", xq->dev->name);
#endif
memset (&system_id, 0, sizeof(system_id));
memcpy (&msg[0], dest, sizeof(ETH_MAC));
memcpy (&msg[6], xq->var->setup.valid ? xq->var->setup.macs[0] : xq->var->mac, sizeof(ETH_MAC));
@@ -2089,6 +2161,9 @@ t_stat xq_attach(UNIT* uptr, char* cptr)
/* turn on transceiver power indicator */
xq->var->csr |= XQ_CSR_OK;
/* reset the device with the new attach info */
xq_reset(xq->dev);
return SCPE_OK;
}
@@ -2098,6 +2173,7 @@ t_stat xq_detach(UNIT* uptr)
{
t_stat status;
CTLR* xq = xq_unit2ctlr(uptr);
int i;
if (uptr->flags & UNIT_ATT) {
status = eth_close (xq->var->etherface);
@@ -2106,6 +2182,9 @@ t_stat xq_detach(UNIT* uptr)
free(uptr->filename);
uptr->filename = NULL;
uptr->flags &= ~UNIT_ATT;
/* cancel all timers (ethernet, sanity, system_id) */
for (i=0; i<3; i++)
sim_cancel(&xq->unit[i]);
}
/* turn off transceiver power indicator */
@@ -2114,14 +2193,38 @@ t_stat xq_detach(UNIT* uptr)
return SCPE_OK;
}
int32 xq_inta (void)
void xq_setint(CTLR* xq)
{
return xqa_dib.vec;
xq->var->irq = 1;
SET_INT(XQ);
return;
}
int32 xq_intb (void)
void xq_clrint(CTLR* xq)
{
return xqb_dib.vec;
int i;
xq->var->irq = 0; /* set controller irq off */
/* clear master interrupt? */
for (i=0; i<XQ_MAX_CONTROLLERS; i++) /* check all controllers.. */
if (xq_ctrl[i].var->irq) { /* if any irqs enabled */
SET_INT(XQ); /* set master interrupt on */
return;
}
CLR_INT(XQ); /* clear master interrupt */
return;
}
int32 xq_int (void)
{
int i;
for (i=0; i<XQ_MAX_CONTROLLERS; i++) {
CTLR* xq = &xq_ctrl[i];
if (xq->var->irq) { /* if interrupt pending */
xq_clrint(xq); /* clear interrupt */
return xq->dib->vec; /* return vector */
}
}
return 0; /* no interrupt request active */
}
/*==============================================================================

View File

@@ -28,6 +28,7 @@
Modification history:
25-Nov-03 DTH Added interrupt request flag
02-Jun-03 DTH Added struct xq_stats
28-May-03 DTH Made xq_msg_que.item dynamic
28-May-03 MP Optimized structures, removed rtime variable
@@ -152,6 +153,7 @@ struct xq_device {
uint16 xbdl[2];
uint16 var;
uint16 csr;
uint32 irq; /* interrupt request flag */
/* buffers, etc. */
struct xq_setup setup;

View File

@@ -24,6 +24,8 @@
in this Software without prior written authorization from Robert M Supnik.
xu DEUNA/DELUNA Ethernet interface (stub)
22-Dec-03 RMS Added second (stub) device
*/
#if defined (VM_PDP10) /* PDP10 version */
@@ -61,3 +63,29 @@ DEVICE xu_dev = {
NULL, NULL, NULL,
NULL, NULL, NULL,
&xu_dib, DEV_DIS | DEV_UBUS };
#if defined (VM_PDP11)
/* XUB data structures
xub_dev XUB device descriptor
xub_unit XUB unit list
xub_reg XUB register list
*/
DIB xub_dib = { IOBA_XUB, IOLN_XUB, NULL, NULL,
1, IVCL (XU), VEC_XU, { NULL } };
UNIT xub_unit = { UDATA (NULL, 0, 0) };
REG xub_reg[] = {
{ NULL } };
DEVICE xub_dev = {
"XUB", &xub_unit, xub_reg, NULL,
1, 8, 8, 1, 8, 8,
NULL, NULL, NULL,
NULL, NULL, NULL,
&xub_dib, DEV_DIS | DEV_UBUS };
#endif