1
0
mirror of https://github.com/simh/simh.git synced 2026-04-06 05:32:34 +00:00

Notes For V3.5-0

The source set has been extensively overhauled.  For correct
viewing, set Visual C++ or Emacs to have tab stops every 4
characters.

1. New Features in 3.4-1

1.1 All Ethernet devices

- Added Windows user-defined adapter names (from Timothe Litt)

1.2 Interdata, SDS, HP, PDP-8, PDP-18b terminal multiplexors

- Added support for SET <unit>n DISCONNECT

1.3 VAX

- Added latent QDSS support
- Revised autoconfigure to handle QDSS

1.4 PDP-11

- Revised autoconfigure to handle more casees

2. Bugs Fixed in 3.4-1

2.1 SCP and libraries

- Trim trailing spaces on all input (for example, attach file names)
- Fixed sim_sock spurious SIGPIPE error in Unix/Linux
- Fixed sim_tape misallocation of TPC map array for 64b simulators

2.2 1401

- Fixed bug, CPU reset was clearing SSB through SSG

2.3 PDP-11

- Fixed bug in VH vector display routine
- Fixed XU runt packet processing (found by Tim Chapman)

2.4 Interdata

- Fixed bug in SHOW PAS CONN/STATS
- Fixed potential integer overflow exception in divide

2.5 SDS

- Fixed bug in SHOW MUX CONN/STATS

2.6 HP

- Fixed bug in SHOW MUX CONN/STATS

2.7 PDP-8

- Fixed bug in SHOW TTIX CONN/STATS
- Fixed bug in SET/SHOW TTOXn LOG

2.8 PDP-18b

- Fixed bug in SHOW TTIX CONN/STATS
- Fixed bug in SET/SHOW TTOXn LOG

2.9 Nova, Eclipse

- Fixed potential integer overflow exception in divide
This commit is contained in:
Bob Supnik
2005-09-09 18:09:00 -07:00
committed by Mark Pizzolato
parent ec60bbf329
commit b7c1eae41f
257 changed files with 107140 additions and 97195 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/* pdp11_cpumod.h: PDP-11 CPU model definitions
Copyright (c) 2004, Robert M Supnik
Copyright (c) 2004-2005, 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"),
@@ -19,252 +19,268 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not 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.
30-Aug-05 RMS Added additional 11/60 registers
*/
#ifndef _PDP11_CPUMOD_H_
#define _PDP11_CPUMOD_H_ 1
#define _PDP11_CPUMOD_H_ 0
#define SOP_1103 (BUS_Q)
#define OPT_1103 (OPT_EIS|OPT_FIS)
#define PSW_1103 0000377
#define SOP_1103 (BUS_Q)
#define OPT_1103 (OPT_EIS|OPT_FIS)
#define PSW_1103 0000377
#define SOP_1104 (BUS_U)
#define OPT_1104 0
#define PSW_1104 0000377
#define SOP_1104 (BUS_U)
#define OPT_1104 0
#define PSW_1104 0000377
#define SOP_1105 (BUS_U)
#define OPT_1105 0
#define PSW_1105 0000377
#define SOP_1105 (BUS_U)
#define OPT_1105 0
#define PSW_1105 0000377
#define SOP_1120 (BUS_U)
#define OPT_1120 0
#define PSW_1120 0000377
#define SOP_1120 (BUS_U)
#define OPT_1120 0
#define PSW_1120 0000377
#define SOP_1123 (BUS_Q|OPT_EIS|OPT_FPP|OPT_MMU)
#define OPT_1123 (OPT_FPP|OPT_CIS)
#define PSW_F 0170777
#define PAR_F 0177777
#define PDR_F 0077516
#define MM0_F 0160157
#define MM3_F 0000060
#define SOP_1123 (BUS_Q|OPT_EIS|OPT_FPP|OPT_MMU)
#define OPT_1123 (OPT_FPP|OPT_CIS)
#define PSW_F 0170777
#define PAR_F 0177777
#define PDR_F 0077516
#define MM0_F 0160157
#define MM3_F 0000060
#define SOP_1123P (BUS_Q|OPT_EIS|OPT_FPP|OPT_MMU)
#define OPT_1123P (OPT_FPP|OPT_CIS)
#define SOP_1123P (BUS_Q|OPT_EIS|OPT_FPP|OPT_MMU)
#define OPT_1123P (OPT_FPP|OPT_CIS)
#define SOP_1124 (BUS_U|OPT_EIS|OPT_FPP|OPT_MMU|OPT_UBM)
#define OPT_1124 (OPT_FPP|OPT_CIS)
#define SOP_1124 (BUS_U|OPT_EIS|OPT_FPP|OPT_MMU|OPT_UBM)
#define OPT_1124 (OPT_FPP|OPT_CIS)
#define SOP_1134 (BUS_U|OPT_EIS|OPT_MMU)
#define OPT_1134 (OPT_FPP)
#define PSW_1134 0170377
#define PAR_1134 0007777
#define PDR_1134 0077516
#define MM0_1134 0160557
#define SOP_1134 (BUS_U|OPT_EIS|OPT_MMU)
#define OPT_1134 (OPT_FPP)
#define PSW_1134 0170377
#define PAR_1134 0007777
#define PDR_1134 0077516
#define MM0_1134 0160557
#define SOP_1140 (BUS_U|OPT_EIS|OPT_MMU)
#define OPT_1140 (OPT_FIS)
#define PSW_1140 0170377
#define PAR_1140 0007777
#define PDR_1140 0077516
#define MM0_1140 0160557
#define SOP_1140 (BUS_U|OPT_EIS|OPT_MMU)
#define OPT_1140 (OPT_FIS)
#define PSW_1140 0170377
#define PAR_1140 0007777
#define PDR_1140 0077516
#define MM0_1140 0160557
#define SOP_1144 (BUS_U|OPT_EIS|OPT_FPP|OPT_MMU|OPT_UBM)
#define OPT_1144 (OPT_FPP|OPT_CIS)
#define PSW_1144 0170777
#define PAR_1144 0177777
#define PDR_1144 0177516
#define MM0_1144 0160557
#define MM3_1144 0000077
#define SOP_1144 (BUS_U|OPT_EIS|OPT_FPP|OPT_MMU|OPT_UBM)
#define OPT_1144 (OPT_FPP|OPT_CIS)
#define PSW_1144 0170777
#define PAR_1144 0177777
#define PDR_1144 0177516
#define MM0_1144 0160557
#define MM3_1144 0000077
#define SOP_1145 (BUS_U|OPT_EIS|OPT_FPP|OPT_MMU|OPT_RH11)
#define OPT_1145 (OPT_FPP)
#define PSW_1145 0174377
#define PAR_1145 0007777
#define PDR_1145 0077717
#define MM0_1145 0171777
#define MM3_1145 0000007
#define SOP_1145 (BUS_U|OPT_EIS|OPT_FPP|OPT_MMU|OPT_RH11)
#define OPT_1145 (OPT_FPP)
#define PSW_1145 0174377
#define PAR_1145 0007777
#define PDR_1145 0077717
#define MM0_1145 0171777
#define MM3_1145 0000007
#define SOP_1160 (BUS_U|OPT_EIS|OPT_FPP|OPT_MMU)
#define OPT_1160 0
#define PSW_1160 0170377
#define PAR_1160 0007777
#define PDR_1160 0077516
#define MM0_1160 0160557
#define SOP_1160 (BUS_U|OPT_EIS|OPT_FPP|OPT_MMU)
#define OPT_1160 0
#define PSW_1160 0170377
#define PAR_1160 0007777
#define PDR_1160 0077516
#define MM0_1160 0160557
#define SOP_1170 (BUS_U|OPT_EIS|OPT_FPP|OPT_MMU|OPT_UBM)
#define OPT_1170 (OPT_FPP|OPT_RH11)
#define PSW_1170 0174377
#define PAR_1170 0177777
#define PDR_1170 0077717
#define MM0_1170 0171777
#define MM3_1170 0000067
#define SOP_1170 (BUS_U|OPT_EIS|OPT_FPP|OPT_MMU|OPT_UBM)
#define OPT_1170 (OPT_FPP|OPT_RH11)
#define PSW_1170 0174377
#define PAR_1170 0177777
#define PDR_1170 0077717
#define MM0_1170 0171777
#define MM3_1170 0000067
#define SOP_1173 (BUS_Q|OPT_EIS|OPT_FPP|OPT_MMU)
#define OPT_1173 (OPT_CIS)
#define PSW_J 0174777
#define PAR_J 0177777
#define PDR_J 0177516
#define MM0_J 0160177
#define MM3_J 0000077
#define SOP_1173 (BUS_Q|OPT_EIS|OPT_FPP|OPT_MMU)
#define OPT_1173 (OPT_CIS)
#define PSW_J 0174777
#define PAR_J 0177777
#define PDR_J 0177516
#define MM0_J 0160177
#define MM3_J 0000077
#define SOP_1153 (BUS_Q|OPT_EIS|OPT_FPP|OPT_MMU)
#define OPT_1153 (OPT_CIS)
#define SOP_1153 (BUS_Q|OPT_EIS|OPT_FPP|OPT_MMU)
#define OPT_1153 (OPT_CIS)
#define SOP_1173B (BUS_Q|OPT_EIS|OPT_FPP|OPT_MMU)
#define OPT_1173B (OPT_CIS)
#define SOP_1173B (BUS_Q|OPT_EIS|OPT_FPP|OPT_MMU)
#define OPT_1173B (OPT_CIS)
#define SOP_1183 (BUS_Q|OPT_EIS|OPT_FPP|OPT_MMU)
#define OPT_1183 (OPT_CIS)
#define SOP_1183 (BUS_Q|OPT_EIS|OPT_FPP|OPT_MMU)
#define OPT_1183 (OPT_CIS)
#define SOP_1184 (BUS_U|OPT_EIS|OPT_FPP|OPT_MMU|OPT_UBM|OPT_RH11)
#define OPT_1184 (OPT_CIS)
#define SOP_1184 (BUS_U|OPT_EIS|OPT_FPP|OPT_MMU|OPT_UBM|OPT_RH11)
#define OPT_1184 (OPT_CIS)
#define SOP_1193 (BUS_Q|OPT_EIS|OPT_FPP|OPT_MMU)
#define OPT_1193 (OPT_CIS)
#define SOP_1193 (BUS_Q|OPT_EIS|OPT_FPP|OPT_MMU)
#define OPT_1193 (OPT_CIS)
#define SOP_1194 (BUS_U|OPT_EIS|OPT_FPP|OPT_MMU|OPT_UBM|OPT_RH11)
#define OPT_1194 (OPT_CIS)
#define SOP_1194 (BUS_U|OPT_EIS|OPT_FPP|OPT_MMU|OPT_UBM|OPT_RH11)
#define OPT_1194 (OPT_CIS)
#define MOD_MAX 20
#define MOD_MAX 20
/* MFPT codes */
#define MFPT_44 1
#define MFPT_F 3
#define MFPT_T 4
#define MFPT_J 5
#define MFPT_44 1
#define MFPT_F 3
#define MFPT_T 4
#define MFPT_J 5
/* KDF11B specific register */
#define PCRFB_RW 0037477 /* page ctrl reg */
#define PCRFB_RW 0037477 /* page ctrl reg */
#define CDRFB_RD 0000377 /* config reg */
#define CDRFB_WR 0000017
#define CDRFB_RD 0000377 /* config reg */
#define CDRFB_WR 0000017
/* KT24 Unibus map specific registers */
#define LMAL_RD 0177777 /* last mapped low */
#define LMAL_RD 0177777 /* last mapped low */
#define LMAH_RD 0000177 /* last mapped high */
#define LMAH_WR 0000100
#define LMAH_RD 0000177 /* last mapped high */
#define LMAH_WR 0000100
/* 11/44 specific registers */
#define CCR44_RD 0033315 /* cache control */
#define CCR44_WR 0003315
#define CCR44_RD 0033315 /* cache control */
#define CCR44_WR 0003315
#define CMR44_RD 0177437 /* cache maint */
#define CMR44_WR 0000037
#define CMR44_RD 0177437 /* cache maint */
#define CMR44_WR 0000037
#define CPUE44_BUSE 0004000
#define CPUE44_BUSE 0004000
/* 11/60 specific registers */
#define WCS60_RD 0161776 /* WCS control */
#define WCS60_WR 0061676
#define MEME60_RD 0100340 /* memory error */
#define CCR60_RD 0000315 /* cache control */
#define CCR60_WR 0000115
#define MBRK60_WR 0007777 /* microbreak */
#define CPUE60_RD (CPUE_ODD|CPUE_TMO|CPUE_RED)
/* J11 specific registers */
/* Maintenance register */
#define MAINT_V_UQ 9 /* Q/U flag */
#define MAINT_Q (0 << MAINT_V_UQ) /* Qbus */
#define MAINT_U (1 << MAINT_V_UQ)
#define MAINT_V_FPA 8 /* FPA flag */
#define MAINT_NOFPA (0 << MAINT_V_FPA)
#define MAINT_FPA (1 << MAINT_V_FPA)
#define MAINT_V_TYP 4 /* system type */
#define MAINT_KDJA (1 << MAINT_V_TYP) /* KDJ11A */
#define MAINT_KDJB (2 << MAINT_V_TYP) /* KDJ11B */
#define MAINT_KDJD (4 << MAINT_V_TYP) /* KDJ11D */
#define MAINT_KDJE (5 << MAINT_V_TYP) /* KDJ11E */
#define MAINT_V_HTRAP 3 /* trap 4 on HALT */
#define MAINT_HTRAP (1 << MAINT_V_HTRAP)
#define MAINT_V_POM 1 /* power on option */
#define MAINT_POODT (0 << MAINT_V_POM) /* power up ODT */
#define MAINT_POROM (2 << MAINT_V_POM) /* power up ROM */
#define MAINT_V_BPOK 0 /* power OK */
#define MAINT_BPOK (1 << MAINT_V_BPOK)
#define MAINT_V_UQ 9 /* Q/U flag */
#define MAINT_Q (0 << MAINT_V_UQ) /* Qbus */
#define MAINT_U (1 << MAINT_V_UQ)
#define MAINT_V_FPA 8 /* FPA flag */
#define MAINT_NOFPA (0 << MAINT_V_FPA)
#define MAINT_FPA (1 << MAINT_V_FPA)
#define MAINT_V_TYP 4 /* system type */
#define MAINT_KDJA (1 << MAINT_V_TYP) /* KDJ11A */
#define MAINT_KDJB (2 << MAINT_V_TYP) /* KDJ11B */
#define MAINT_KDJD (4 << MAINT_V_TYP) /* KDJ11D */
#define MAINT_KDJE (5 << MAINT_V_TYP) /* KDJ11E */
#define MAINT_V_HTRAP 3 /* trap 4 on HALT */
#define MAINT_HTRAP (1 << MAINT_V_HTRAP)
#define MAINT_V_POM 1 /* power on option */
#define MAINT_POODT (0 << MAINT_V_POM) /* power up ODT */
#define MAINT_POROM (2 << MAINT_V_POM) /* power up ROM */
#define MAINT_V_BPOK 0 /* power OK */
#define MAINT_BPOK (1 << MAINT_V_BPOK)
/* KDJ11B control */
#define CSRJB_RD 0177767
#define CSRJB_WR 0037767
#define CSRJ_LTCI 0020000 /* force LTC int */
#define CSRJ_LTCD 0010000 /* disable LTC reg */
#define CSRJ_V_LTCSEL 10
#define CSRJ_M_LTCSEL 03
#define CSRJ_LTCSEL(x) (((x) >> CSRJ_V_LTCSEL) & CSRJ_M_LTCSEL)
#define CSRJ_HBREAK 0001000 /* halt on break */
#define CSRJB_RD 0177767
#define CSRJB_WR 0037767
#define CSRJ_LTCI 0020000 /* force LTC int */
#define CSRJ_LTCD 0010000 /* disable LTC reg */
#define CSRJ_V_LTCSEL 10
#define CSRJ_M_LTCSEL 03
#define CSRJ_LTCSEL(x) (((x) >> CSRJ_V_LTCSEL) & CSRJ_M_LTCSEL)
#define CSRJ_HBREAK 0001000 /* halt on break */
#define PCRJB_RW 0077176 /* page ctrl reg */
#define PCRJB_RW 0077176 /* page ctrl reg */
#define CDRJB_RD 0000377 /* config register */
#define CDRJB_WR 0000377
#define CDRJB_RD 0000377 /* config register */
#define CDRJB_WR 0000377
/* KDJ11D control */
#define CSRJD_RD 0157777 /* native register */
#define CSRJD_WR 0000377
#define CSRJD_15M 0040000 /* 1.5M mem on board */
#define CSRJD_RD 0157777 /* native register */
#define CSRJD_WR 0000377
#define CSRJD_15M 0040000 /* 1.5M mem on board */
/* KDJ11E control */
#define CSRJE_RD 0137360 /* control reg */
#define CSRJE_WR 0037370
#define CSRJE_RD 0137360 /* control reg */
#define CSRJE_WR 0037370
#define PCRJE_RW 0177376 /* page ctrl reg */
#define PCRJE_RW 0177376 /* page ctrl reg */
#define CDRJE_RD 0000377 /* config register */
#define CDRJE_WR 0000077
#define CDRJE_RD 0000377 /* config register */
#define CDRJE_WR 0000077
#define ASRJE_RW 0030462 /* additional status */
#define ASRJE_V_TOY 8
#define ASRJE_TOY (1u << ASRJE_V_TOY) /* TOY serial bit */
#define ASRJE_TOYBIT(x) (((x) >> ASRJE_V_TOY) & 1)
#define ASRJE_RW 0030462 /* additional status */
#define ASRJE_V_TOY 8
#define ASRJE_TOY (1u << ASRJE_V_TOY) /* TOY serial bit */
#define ASRJE_TOYBIT(x) (((x) >> ASRJE_V_TOY) & 1)
/* KDJ11E TOY clock */
#define TOY_HSEC 0
#define TOY_SEC 1
#define TOY_MIN 2
#define TOY_HR 3
#define TOY_DOW 4
#define TOY_DOM 5
#define TOY_MON 6
#define TOY_YR 7
#define TOY_LNT 8
#define TOY_HSEC 0
#define TOY_SEC 1
#define TOY_MIN 2
#define TOY_HR 3
#define TOY_DOW 4
#define TOY_DOM 5
#define TOY_MON 6
#define TOY_YR 7
#define TOY_LNT 8
/* KTJ11B Unibus map */
#define DCRKTJ_RD 0100616 /* diag control */
#define DCRKTJ_WR 0000416
#define DCRKTJ_RD 0100616 /* diag control */
#define DCRKTJ_WR 0000416
#define DDRKTJ_RW 0177777 /* diag data */
#define DDRKTJ_RW 0177777 /* diag data */
#define MCRKTJ_RD 0000377 /* control register */
#define MCRKTJ_WR 0000177
#define MCRKTJ_RD 0000377 /* control register */
#define MCRKTJ_WR 0000177
/* Data tables */
struct cpu_table {
char *name; /* model name */
uint32 std; /* standard flags */
uint32 opt; /* set/clear flags */
uint32 maxm; /* max memory */
uint32 psw; /* PSW mask */
uint32 mfpt; /* MFPT code */
uint32 par; /* PAR mask */
uint32 pdr; /* PDR mask */
uint32 mm0; /* MMR0 mask */
uint32 mm3; /* MMR3 mask */
};
char *name; /* model name */
uint32 std; /* standard flags */
uint32 opt; /* set/clear flags */
uint32 maxm; /* max memory */
uint32 psw; /* PSW mask */
uint32 mfpt; /* MFPT code */
uint32 par; /* PAR mask */
uint32 pdr; /* PDR mask */
uint32 mm0; /* MMR0 mask */
uint32 mm3; /* MMR3 mask */
};
typedef struct cpu_table CPUTAB;
struct conf_table {
uint32 cpum;
uint32 optm;
DIB *dib;
};
uint32 cpum;
uint32 optm;
DIB *dib;
};
typedef struct conf_table CNFTAB;

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
To: Users
From: Bob Supnik
Subj: PDP-11 Simulator Usage
Date: 20-Jan-2005
Date: 01-Jul-2005
COPYRIGHT NOTICE
@@ -27,8 +27,8 @@ The following copyright notice applies to both the SIMH source and binary:
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not 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.
This memorandum documents the PDP-11 simulator.
@@ -104,7 +104,7 @@ PTR,PTP PC11 paper tape reader/punch
TTI,TTO DL11 console terminal
LPT LP11 line printer
CLK line frequency clock
PCLK KW11P programmable clock
PCLK KW11-P programmable clock
DZ DZ11 8-line terminal multiplexor (up to 4)
VH DHU11/DHQ11 8-line terminal multiplexor (up to 4)
RK RK11/RK05 cartridge disk controller with eight drives
@@ -228,14 +228,14 @@ type bus memory MMU? Umap? EIS? FIS? FPP? CIS?
If a capability is standard, it cannot be disabled; if a capability is
not included, it cannot be enabled.
The CPU implements a show command to display the I/O address assignments:
The CPU implements a SHOW command to display the I/O address assignments:
SHOW CPU IOSPACE show I/O space address assignments
If memory size is being reduced, and the memory being truncated contains
non-zero data, the simulator asks for confirmation. Data in the truncated
portion of memory is lost. Initial memory size is 256KB. If memory size
is being increased to more than 256KB, or the bus structue is being changed,
is being increased to more than 256KB, or the bus structure is being changed,
the simulator asks whether it should disable peripherals that can't run
in the current bus structure.
@@ -378,7 +378,7 @@ disabled in a Qbus configuration with more than 256KB memory.
PDP-11 I/O space is not large enough to allow all possible devices to be
configured simultaneously at fixed addresses. Instead, many devices have
floating addresses; that is, the assigned device address depends on the
presense of other devices in the configuration:
presence of other devices in the configuration:
DZ11 all instances have floating addresses
DHU11/DHQ11 all instances have floating addresses
@@ -1355,7 +1355,7 @@ DISCONNECT command, or a DETACH DZ command.
The SHOW DZ CONNECTIONS command displays the current connections to the DZ.
The SHOW DZ STATISTICS command displays statistics for active connections.
The SET DZ DISCONNECT=linenumber disconnects the specified line.
The SET DZ DISCONNECT=linenumber command disconnects the specified line.
The DZ11 implements these registers:
@@ -1439,7 +1439,7 @@ a SET VH DISCONNECT command, or a DETACH VH command.
The SHOW VH CONNECTIONS command displays the current connections to the VH.
The SHOW VH STATISTICS command displays statistics for active connections.
The SET VH DISCONNECT=linenumber disconnects the specified line.
The SET VH DISCONNECT=linenumber command disconnects the specified line.
The DHQ11 implements these registers, though not all can be examined
from SCP:
@@ -1537,7 +1537,7 @@ XQ and XQB have the following registers:
VAR 16 vector address register
INT 1 interrupt request flag
One final note: because of it's asynchronous nature, the XQ controller is
One final note: because of its asynchronous nature, the XQ controller is
not limited to the ~1.5Mbit/sec of the real DEQNA/DELQA controllers,
nor the 10Mbit/sec of a standard Ethernet. Attach it to a Fast Ethernet
(100 Mbit/sec) card, and "Feel the Power!" :-)

View File

@@ -1,6 +1,6 @@
/* pdp11_dz.c: DZ11 terminal multiplexor simulator
Copyright (c) 2001-2004, Robert M Supnik
Copyright (c) 2001-2005, 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"),
@@ -19,145 +19,144 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not 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.
dz DZ11 terminal multiplexor
dz DZ11 terminal multiplexor
4-Apr-04 RMS Added per-line logging
05-Jan-04 RMS Revised for tmxr library changes
19-May-03 RMS Revised for new conditional compilation scheme
09-May-03 RMS Added network device flag
22-Dec-02 RMS Added break (framing error) support
31-Oct-02 RMS Added 8b support
12-Oct-02 RMS Added autoconfigure support
29-Sep-02 RMS Fixed bug in set number of lines routine
Added variable vector support
New data structures
22-Apr-02 RMS Updated for changes in sim_tmxr
28-Apr-02 RMS Fixed interrupt acknowledge, fixed SHOW DZ ADDRESS
14-Jan-02 RMS Added multiboard support
30-Dec-01 RMS Added show statistics, set disconnect
Removed statistics registers
03-Dec-01 RMS Modified for extended SET/SHOW
09-Nov-01 RMS Added VAX support
20-Oct-01 RMS Moved getchar from sim_tmxr, changed interrupt
logic to use tmxr_rqln
06-Oct-01 RMS Fixed bug in carrier detect logic
03-Oct-01 RMS Added support for BSD-style "ringless" modems
27-Sep-01 RMS Fixed bug in xmte initialization
17-Sep-01 RMS Added separate autodisconnect switch
16-Sep-01 RMS Fixed modem control bit offsets
07-Jul-05 RMS Removed extraneous externs
15-Jun-05 RMS Revised for new autoconfigure interface
04-Apr-04 RMS Added per-line logging
05-Jan-04 RMS Revised for tmxr library changes
19-May-03 RMS Revised for new conditional compilation scheme
09-May-03 RMS Added network device flag
22-Dec-02 RMS Added break (framing error) support
31-Oct-02 RMS Added 8b support
12-Oct-02 RMS Added autoconfigure support
29-Sep-02 RMS Fixed bug in set number of lines routine
Added variable vector support
New data structures
22-Apr-02 RMS Updated for changes in sim_tmxr
28-Apr-02 RMS Fixed interrupt acknowledge, fixed SHOW DZ ADDRESS
14-Jan-02 RMS Added multiboard support
30-Dec-01 RMS Added show statistics, set disconnect
Removed statistics registers
03-Dec-01 RMS Modified for extended SET/SHOW
09-Nov-01 RMS Added VAX support
20-Oct-01 RMS Moved getchar from sim_tmxr, changed interrupt
logic to use tmxr_rqln
06-Oct-01 RMS Fixed bug in carrier detect logic
03-Oct-01 RMS Added support for BSD-style "ringless" modems
27-Sep-01 RMS Fixed bug in xmte initialization
17-Sep-01 RMS Added separate autodisconnect switch
16-Sep-01 RMS Fixed modem control bit offsets
*/
#if defined (VM_PDP10) /* PDP10 version */
#if defined (VM_PDP10) /* PDP10 version */
#include "pdp10_defs.h"
#define RANK_DZ 0 /* no autoconfig */
#define DZ_8B_DFLT 0
#define RANK_DZ 0 /* no autoconfig */
#define DZ_8B_DFLT 0
extern int32 int_req;
extern int32 int_vec[32];
#elif defined (VM_VAX) /* VAX version */
#elif defined (VM_VAX) /* VAX version */
#include "vax_defs.h"
#define DZ_8B_DFLT UNIT_8B
#define DZ_8B_DFLT UNIT_8B
extern int32 int_req[IPL_HLVL];
extern int32 int_vec[IPL_HLVL][32];
#else /* PDP-11 version */
#else /* PDP-11 version */
#include "pdp11_defs.h"
#define DZ_8B_DFLT UNIT_8B
#define DZ_8B_DFLT UNIT_8B
extern int32 int_req[IPL_HLVL];
extern int32 int_vec[IPL_HLVL][32];
#endif
#include "sim_sock.h"
#include "sim_tmxr.h"
#if !defined (DZ_MUXES)
#define DZ_MUXES 1
#define DZ_MUXES 1
#endif
#if !defined (DZ_LINES)
#define DZ_LINES 8
#define DZ_LINES 8
#endif
#define UNIT_V_8B (UNIT_V_UF + 0) /* 8b output */
#define UNIT_8B (1 << UNIT_V_8B)
#define UNIT_V_8B (UNIT_V_UF + 0) /* 8b output */
#define UNIT_8B (1 << UNIT_V_8B)
#define DZ_MNOMASK (DZ_MUXES - 1) /* mask for mux no */
#define DZ_LNOMASK (DZ_LINES - 1) /* mask for lineno */
#define DZ_LMASK ((1 << DZ_LINES) - 1) /* mask of lines */
#define DZ_SILO_ALM 16 /* silo alarm level */
#define DZ_MNOMASK (DZ_MUXES - 1) /* mask for mux no */
#define DZ_LNOMASK (DZ_LINES - 1) /* mask for lineno */
#define DZ_LMASK ((1 << DZ_LINES) - 1) /* mask of lines */
#define DZ_SILO_ALM 16 /* silo alarm level */
/* DZCSR - 160100 - control/status register */
#define CSR_MAINT 0000010 /* maint - NI */
#define CSR_CLR 0000020 /* clear */
#define CSR_MSE 0000040 /* master scan enb */
#define CSR_RIE 0000100 /* rcv int enb */
#define CSR_RDONE 0000200 /* rcv done - RO */
#define CSR_V_TLINE 8 /* xmit line - RO */
#define CSR_TLINE (DZ_LNOMASK << CSR_V_TLINE)
#define CSR_SAE 0010000 /* silo alm enb */
#define CSR_SA 0020000 /* silo alm - RO */
#define CSR_TIE 0040000 /* xmit int enb */
#define CSR_TRDY 0100000 /* xmit rdy - RO */
#define CSR_RW (CSR_MSE | CSR_RIE | CSR_SAE | CSR_TIE)
#define CSR_MBZ (0004003 | CSR_CLR | CSR_MAINT)
#define CSR_MAINT 0000010 /* maint - NI */
#define CSR_CLR 0000020 /* clear */
#define CSR_MSE 0000040 /* master scan enb */
#define CSR_RIE 0000100 /* rcv int enb */
#define CSR_RDONE 0000200 /* rcv done - RO */
#define CSR_V_TLINE 8 /* xmit line - RO */
#define CSR_TLINE (DZ_LNOMASK << CSR_V_TLINE)
#define CSR_SAE 0010000 /* silo alm enb */
#define CSR_SA 0020000 /* silo alm - RO */
#define CSR_TIE 0040000 /* xmit int enb */
#define CSR_TRDY 0100000 /* xmit rdy - RO */
#define CSR_RW (CSR_MSE | CSR_RIE | CSR_SAE | CSR_TIE)
#define CSR_MBZ (0004003 | CSR_CLR | CSR_MAINT)
#define CSR_GETTL(x) (((x) >> CSR_V_TLINE) & DZ_LNOMASK)
#define CSR_PUTTL(x,y) x = ((x) & ~CSR_TLINE) | (((y) & DZ_LNOMASK) << CSR_V_TLINE)
#define CSR_GETTL(x) (((x) >> CSR_V_TLINE) & DZ_LNOMASK)
#define CSR_PUTTL(x,y) x = ((x) & ~CSR_TLINE) | (((y) & DZ_LNOMASK) << CSR_V_TLINE)
/* DZRBUF - 160102 - receive buffer, read only */
#define RBUF_CHAR 0000377 /* rcv char */
#define RBUF_V_RLINE 8 /* rcv line */
#define RBUF_PARE 0010000 /* parity err - NI */
#define RBUF_FRME 0020000 /* frame err */
#define RBUF_OVRE 0040000 /* overrun err - NI */
#define RBUF_VALID 0100000 /* rcv valid */
#define RBUF_MBZ 0004000
#define RBUF_CHAR 0000377 /* rcv char */
#define RBUF_V_RLINE 8 /* rcv line */
#define RBUF_PARE 0010000 /* parity err - NI */
#define RBUF_FRME 0020000 /* frame err */
#define RBUF_OVRE 0040000 /* overrun err - NI */
#define RBUF_VALID 0100000 /* rcv valid */
#define RBUF_MBZ 0004000
/* DZLPR - 160102 - line parameter register, write only, word access only */
#define LPR_V_LINE 0 /* line */
#define LPR_LPAR 0007770 /* line pars - NI */
#define LPR_RCVE 0010000 /* receive enb */
#define LPR_GETLN(x) (((x) >> LPR_V_LINE) & DZ_LNOMASK)
#define LPR_V_LINE 0 /* line */
#define LPR_LPAR 0007770 /* line pars - NI */
#define LPR_RCVE 0010000 /* receive enb */
#define LPR_GETLN(x) (((x) >> LPR_V_LINE) & DZ_LNOMASK)
/* DZTCR - 160104 - transmission control register */
#define TCR_V_XMTE 0 /* xmit enables */
#define TCR_V_DTR 8 /* DTRs */
#define TCR_V_XMTE 0 /* xmit enables */
#define TCR_V_DTR 8 /* DTRs */
/* DZMSR - 160106 - modem status register, read only */
#define MSR_V_RI 0 /* ring indicators */
#define MSR_V_CD 8 /* carrier detect */
#define MSR_V_RI 0 /* ring indicators */
#define MSR_V_CD 8 /* carrier detect */
/* DZTDR - 160106 - transmit data, write only */
#define TDR_CHAR 0000377 /* xmit char */
#define TDR_V_TBR 8 /* xmit break - NI */
#define TDR_CHAR 0000377 /* xmit char */
#define TDR_V_TBR 8 /* xmit break - NI */
extern int32 IREQ (HLVL);
extern int32 sim_switches;
extern FILE *sim_log;
extern int32 tmxr_poll; /* calibrated delay */
extern int32 tmxr_poll; /* calibrated delay */
uint16 dz_csr[DZ_MUXES] = { 0 }; /* csr */
uint16 dz_rbuf[DZ_MUXES] = { 0 }; /* rcv buffer */
uint16 dz_lpr[DZ_MUXES] = { 0 }; /* line param */
uint16 dz_tcr[DZ_MUXES] = { 0 }; /* xmit control */
uint16 dz_msr[DZ_MUXES] = { 0 }; /* modem status */
uint16 dz_tdr[DZ_MUXES] = { 0 }; /* xmit data */
uint8 dz_sae[DZ_MUXES] = { 0 }; /* silo alarm enabled */
uint32 dz_rxi = 0; /* rcv interrupts */
uint32 dz_txi = 0; /* xmt interrupts */
int32 dz_mctl = 0; /* modem ctrl enabled */
int32 dz_auto = 0; /* autodiscon enabled */
TMLN dz_ldsc[DZ_MUXES * DZ_LINES] = { 0 }; /* line descriptors */
TMXR dz_desc = { DZ_MUXES * DZ_LINES, 0, 0, dz_ldsc }; /* mux descriptor */
uint16 dz_csr[DZ_MUXES] = { 0 }; /* csr */
uint16 dz_rbuf[DZ_MUXES] = { 0 }; /* rcv buffer */
uint16 dz_lpr[DZ_MUXES] = { 0 }; /* line param */
uint16 dz_tcr[DZ_MUXES] = { 0 }; /* xmit control */
uint16 dz_msr[DZ_MUXES] = { 0 }; /* modem status */
uint16 dz_tdr[DZ_MUXES] = { 0 }; /* xmit data */
uint8 dz_sae[DZ_MUXES] = { 0 }; /* silo alarm enabled */
uint32 dz_rxi = 0; /* rcv interrupts */
uint32 dz_txi = 0; /* xmt interrupts */
int32 dz_mctl = 0; /* modem ctrl enabled */
int32 dz_auto = 0; /* autodiscon enabled */
TMLN dz_ldsc[DZ_MUXES * DZ_LINES] = { 0 }; /* line descriptors */
TMXR dz_desc = { DZ_MUXES * DZ_LINES, 0, 0, dz_ldsc }; /* mux descriptor */
DEVICE dz_dev;
t_stat dz_rd (int32 *data, int32 PA, int32 access);
@@ -183,178 +182,199 @@ t_stat dz_setnl (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat dz_set_log (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat dz_set_nolog (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat dz_show_log (FILE *st, UNIT *uptr, int32 val, void *desc);
/* DZ data structures
dz_dev DZ device descriptor
dz_unit DZ unit list
dz_reg DZ register list
dz_dev DZ device descriptor
dz_unit DZ unit list
dz_reg DZ register list
*/
DIB dz_dib = { IOBA_DZ, IOLN_DZ * DZ_MUXES, &dz_rd, &dz_wr,
2, IVCL (DZRX), VEC_DZRX, { &dz_rxinta, &dz_txinta } };
DIB dz_dib = {
IOBA_DZ, IOLN_DZ * DZ_MUXES, &dz_rd, &dz_wr,
2, IVCL (DZRX), VEC_DZRX, { &dz_rxinta, &dz_txinta }
};
UNIT dz_unit = { UDATA (&dz_svc, UNIT_ATTABLE + DZ_8B_DFLT, 0) };
REG dz_nlreg = { DRDATA (NLINES, dz_desc.lines, 6), PV_LEFT };
REG dz_reg[] = {
{ BRDATA (CSR, dz_csr, DEV_RDX, 16, DZ_MUXES) },
{ BRDATA (RBUF, dz_rbuf, DEV_RDX, 16, DZ_MUXES) },
{ BRDATA (LPR, dz_lpr, DEV_RDX, 16, DZ_MUXES) },
{ BRDATA (TCR, dz_tcr, DEV_RDX, 16, DZ_MUXES) },
{ BRDATA (MSR, dz_msr, DEV_RDX, 16, DZ_MUXES) },
{ BRDATA (TDR, dz_tdr, DEV_RDX, 16, DZ_MUXES) },
{ BRDATA (SAENB, dz_sae, DEV_RDX, 1, DZ_MUXES) },
{ GRDATA (RXINT, dz_rxi, DEV_RDX, DZ_MUXES, 0) },
{ GRDATA (TXINT, dz_txi, DEV_RDX, DZ_MUXES, 0) },
{ FLDATA (MDMCTL, dz_mctl, 0) },
{ FLDATA (AUTODS, dz_auto, 0) },
{ GRDATA (DEVADDR, dz_dib.ba, DEV_RDX, 32, 0), REG_HRO },
{ GRDATA (DEVVEC, dz_dib.vec, DEV_RDX, 16, 0), REG_HRO },
{ NULL } };
{ BRDATA (CSR, dz_csr, DEV_RDX, 16, DZ_MUXES) },
{ BRDATA (RBUF, dz_rbuf, DEV_RDX, 16, DZ_MUXES) },
{ BRDATA (LPR, dz_lpr, DEV_RDX, 16, DZ_MUXES) },
{ BRDATA (TCR, dz_tcr, DEV_RDX, 16, DZ_MUXES) },
{ BRDATA (MSR, dz_msr, DEV_RDX, 16, DZ_MUXES) },
{ BRDATA (TDR, dz_tdr, DEV_RDX, 16, DZ_MUXES) },
{ BRDATA (SAENB, dz_sae, DEV_RDX, 1, DZ_MUXES) },
{ GRDATA (RXINT, dz_rxi, DEV_RDX, DZ_MUXES, 0) },
{ GRDATA (TXINT, dz_txi, DEV_RDX, DZ_MUXES, 0) },
{ FLDATA (MDMCTL, dz_mctl, 0) },
{ FLDATA (AUTODS, dz_auto, 0) },
{ GRDATA (DEVADDR, dz_dib.ba, DEV_RDX, 32, 0), REG_HRO },
{ GRDATA (DEVVEC, dz_dib.vec, DEV_RDX, 16, 0), REG_HRO },
{ NULL }
};
MTAB dz_mod[] = {
{ UNIT_8B, 0, "7b", "7B", NULL },
{ UNIT_8B, UNIT_8B, "8b", "8B", NULL },
{ MTAB_XTD | MTAB_VDV, 1, NULL, "DISCONNECT",
&tmxr_dscln, NULL, &dz_desc },
{ UNIT_ATT, UNIT_ATT, "connections", NULL, NULL, &dz_summ },
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", NULL,
NULL, &dz_show, NULL },
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATISTICS", NULL,
NULL, &dz_show, NULL },
{ MTAB_XTD|MTAB_VDV, 010, "ADDRESS", "ADDRESS",
&set_addr, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR",
&set_vec, &dz_show_vec, NULL },
{ UNIT_8B, 0, "7b", "7B", NULL },
{ UNIT_8B, UNIT_8B, "8b", "8B", NULL },
{ MTAB_XTD | MTAB_VDV, 1, NULL, "DISCONNECT",
&tmxr_dscln, NULL, &dz_desc },
{ UNIT_ATT, UNIT_ATT, "connections", NULL, NULL, &dz_summ },
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", NULL,
NULL, &dz_show, NULL },
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATISTICS", NULL,
NULL, &dz_show, NULL },
{ MTAB_XTD|MTAB_VDV, 010, "ADDRESS", "ADDRESS",
&set_addr, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR",
&set_vec, &dz_show_vec, NULL },
#if !defined (VM_PDP10)
{ MTAB_XTD | MTAB_VDV, 0, NULL, "AUTOCONFIGURE",
&set_addr_flt, NULL, NULL },
{ MTAB_XTD | MTAB_VDV, 0, NULL, "AUTOCONFIGURE",
&set_addr_flt, NULL, NULL },
#endif
{ MTAB_XTD | MTAB_VDV | MTAB_VAL, 0, "lines", "LINES",
&dz_setnl, NULL, &dz_nlreg },
{ MTAB_XTD | MTAB_VDV, 0, NULL, "LOG",
&dz_set_log, NULL, &dz_desc },
{ MTAB_XTD | MTAB_VDV, 0, NULL, "NOLOG",
&dz_set_nolog, NULL, &dz_desc },
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "LOG", NULL,
NULL, &dz_show_log, &dz_desc },
{ 0 } };
{ MTAB_XTD | MTAB_VDV | MTAB_VAL, 0, "lines", "LINES",
&dz_setnl, NULL, &dz_nlreg },
{ MTAB_XTD | MTAB_VDV, 0, NULL, "LOG",
&dz_set_log, NULL, &dz_desc },
{ MTAB_XTD | MTAB_VDV, 0, NULL, "NOLOG",
&dz_set_nolog, NULL, &dz_desc },
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "LOG", NULL,
NULL, &dz_show_log, &dz_desc },
{ 0 }
};
DEVICE dz_dev = {
"DZ", &dz_unit, dz_reg, dz_mod,
1, DEV_RDX, 8, 1, DEV_RDX, 8,
&tmxr_ex, &tmxr_dep, &dz_reset,
NULL, &dz_attach, &dz_detach,
&dz_dib, DEV_FLTA | DEV_DISABLE | DEV_NET | DEV_UBUS | DEV_QBUS };
"DZ", &dz_unit, dz_reg, dz_mod,
1, DEV_RDX, 8, 1, DEV_RDX, 8,
&tmxr_ex, &tmxr_dep, &dz_reset,
NULL, &dz_attach, &dz_detach,
&dz_dib, DEV_FLTA | DEV_DISABLE | DEV_NET | DEV_UBUS | DEV_QBUS
};
/* IO dispatch routines, I/O addresses 177601x0 - 177601x7 */
t_stat dz_rd (int32 *data, int32 PA, int32 access)
{
int32 dz = ((PA - dz_dib.ba) >> 3) & DZ_MNOMASK; /* get mux num */
int32 dz = ((PA - dz_dib.ba) >> 3) & DZ_MNOMASK; /* get mux num */
switch ((PA >> 1) & 03) { /* case on PA<2:1> */
case 00: /* CSR */
*data = dz_csr[dz] = dz_csr[dz] & ~CSR_MBZ;
break;
case 01: /* RBUF */
dz_csr[dz] = dz_csr[dz] & ~CSR_SA; /* clr silo alarm */
if (dz_csr[dz] & CSR_MSE) { /* scanner on? */
dz_rbuf[dz] = dz_getc (dz); /* get top of silo */
if (!dz_rbuf[dz]) dz_sae[dz] = 1; /* empty? re-enable */
tmxr_poll_rx (&dz_desc); /* poll input */
dz_update_rcvi (); /* update rx intr */
}
else {
dz_rbuf[dz] = 0; /* no data */
dz_update_rcvi (); /* no rx intr */
}
*data = dz_rbuf[dz];
break;
case 02: /* TCR */
*data = dz_tcr[dz];
break;
case 03: /* MSR */
*data = dz_msr[dz];
break;
}
switch ((PA >> 1) & 03) { /* case on PA<2:1> */
case 00: /* CSR */
*data = dz_csr[dz] = dz_csr[dz] & ~CSR_MBZ;
break;
case 01: /* RBUF */
dz_csr[dz] = dz_csr[dz] & ~CSR_SA; /* clr silo alarm */
if (dz_csr[dz] & CSR_MSE) { /* scanner on? */
dz_rbuf[dz] = dz_getc (dz); /* get top of silo */
if (!dz_rbuf[dz]) dz_sae[dz] = 1; /* empty? re-enable */
tmxr_poll_rx (&dz_desc); /* poll input */
dz_update_rcvi (); } /* update rx intr */
else {
dz_rbuf[dz] = 0; /* no data */
dz_update_rcvi (); } /* no rx intr */
*data = dz_rbuf[dz];
break;
case 02: /* TCR */
*data = dz_tcr[dz];
break;
case 03: /* MSR */
*data = dz_msr[dz];
break; }
return SCPE_OK;
}
t_stat dz_wr (int32 data, int32 PA, int32 access)
{
int32 dz = ((PA - dz_dib.ba) >> 3) & DZ_MNOMASK; /* get mux num */
int32 dz = ((PA - dz_dib.ba) >> 3) & DZ_MNOMASK; /* get mux num */
int32 i, line;
TMLN *lp;
switch ((PA >> 1) & 03) { /* case on PA<2:1> */
case 00: /* CSR */
if (access == WRITEB) data = (PA & 1)? /* byte? merge */
(dz_csr[dz] & 0377) | (data << 8):
(dz_csr[dz] & ~0377) | data;
if (data & CSR_CLR) dz_clear (dz, FALSE); /* clr? reset */
if (data & CSR_MSE) sim_activate (&dz_unit, tmxr_poll);
else dz_csr[dz] &= ~(CSR_SA | CSR_RDONE | CSR_TRDY);
if ((data & CSR_RIE) == 0) dz_clr_rxint (dz); /* RIE = 0? */
else if (((dz_csr[dz] & CSR_IE) == 0) && /* RIE 0->1? */
((dz_csr[dz] & CSR_SAE)?
(dz_csr[dz] & CSR_SA): (dz_csr[dz] & CSR_RDONE)))
dz_set_rxint (dz);
if ((data & CSR_TIE) == 0) dz_clr_txint (dz); /* TIE = 0? */
else if (((dz_csr[dz] & CSR_TIE) == 0) && (dz_csr[dz] & CSR_TRDY))
dz_set_txint (dz);
dz_csr[dz] = (dz_csr[dz] & ~CSR_RW) | (data & CSR_RW);
break;
case 01: /* LPR */
dz_lpr[dz] = data;
line = (dz * DZ_LINES) + LPR_GETLN (data); /* get line num */
lp = &dz_ldsc[line]; /* get line desc */
if (dz_lpr[dz] & LPR_RCVE) lp->rcve = 1; /* rcv enb? on */
else lp->rcve = 0; /* else line off */
tmxr_poll_rx (&dz_desc); /* poll input */
dz_update_rcvi (); /* update rx intr */
break;
case 02: /* TCR */
if (access == WRITEB) data = (PA & 1)? /* byte? merge */
(dz_tcr[dz] & 0377) | (data << 8):
(dz_tcr[dz] & ~0377) | data;
if (dz_mctl) { /* modem ctl? */
dz_msr[dz] |= ((data & 0177400) & /* dcd |= dtr & ring */
((dz_msr[dz] & DZ_LMASK) << MSR_V_CD));
dz_msr[dz] &= ~(data >> TCR_V_DTR); /* ring &= ~dtr */
if (dz_auto) { /* auto disconnect? */
int32 drop;
drop = (dz_tcr[dz] & ~data) >> TCR_V_DTR; /* drop = dtr & ~data */
for (i = 0; i < DZ_LINES; i++) { /* drop hangups */
line = (dz * DZ_LINES) + i; /* get line num */
lp = &dz_ldsc[line]; /* get line desc */
if (lp->conn && (drop & (1 << i))) {
tmxr_linemsg (lp, "\r\nLine hangup\r\n");
tmxr_reset_ln (lp); /* reset line, cdet */
dz_msr[dz] &= ~(1 << (i + MSR_V_CD));
} /* end if drop */
} /* end for */
} /* end if auto */
} /* end if modem */
dz_tcr[dz] = data;
tmxr_poll_tx (&dz_desc); /* poll output */
dz_update_xmti (); /* update int */
break;
case 03: /* TDR */
if (PA & 1) { /* odd byte? */
dz_tdr[dz] = (dz_tdr[dz] & 0377) | (data << 8); /* just save */
break; }
dz_tdr[dz] = data;
if (dz_csr[dz] & CSR_MSE) { /* enabled? */
line = (dz * DZ_LINES) + CSR_GETTL (dz_csr[dz]);
lp = &dz_ldsc[line]; /* get line desc */
tmxr_putc_ln (lp, dz_tdr[dz] & /* store char */
((dz_unit.flags & UNIT_8B)? 0377: 0177));
tmxr_poll_tx (&dz_desc); /* poll output */
dz_update_xmti (); } /* update int */
break; }
switch ((PA >> 1) & 03) { /* case on PA<2:1> */
case 00: /* CSR */
if (access == WRITEB) data = (PA & 1)? /* byte? merge */
(dz_csr[dz] & 0377) | (data << 8):
(dz_csr[dz] & ~0377) | data;
if (data & CSR_CLR) dz_clear (dz, FALSE); /* clr? reset */
if (data & CSR_MSE) sim_activate (&dz_unit, tmxr_poll);
else dz_csr[dz] &= ~(CSR_SA | CSR_RDONE | CSR_TRDY);
if ((data & CSR_RIE) == 0) dz_clr_rxint (dz); /* RIE = 0? */
else if (((dz_csr[dz] & CSR_IE) == 0) && /* RIE 0->1? */
((dz_csr[dz] & CSR_SAE)?
(dz_csr[dz] & CSR_SA): (dz_csr[dz] & CSR_RDONE)))
dz_set_rxint (dz);
if ((data & CSR_TIE) == 0) dz_clr_txint (dz); /* TIE = 0? */
else if (((dz_csr[dz] & CSR_TIE) == 0) && (dz_csr[dz] & CSR_TRDY))
dz_set_txint (dz);
dz_csr[dz] = (dz_csr[dz] & ~CSR_RW) | (data & CSR_RW);
break;
case 01: /* LPR */
dz_lpr[dz] = data;
line = (dz * DZ_LINES) + LPR_GETLN (data); /* get line num */
lp = &dz_ldsc[line]; /* get line desc */
if (dz_lpr[dz] & LPR_RCVE) lp->rcve = 1; /* rcv enb? on */
else lp->rcve = 0; /* else line off */
tmxr_poll_rx (&dz_desc); /* poll input */
dz_update_rcvi (); /* update rx intr */
break;
case 02: /* TCR */
if (access == WRITEB) data = (PA & 1)? /* byte? merge */
(dz_tcr[dz] & 0377) | (data << 8):
(dz_tcr[dz] & ~0377) | data;
if (dz_mctl) { /* modem ctl? */
dz_msr[dz] |= ((data & 0177400) & /* dcd |= dtr & ring */
((dz_msr[dz] & DZ_LMASK) << MSR_V_CD));
dz_msr[dz] &= ~(data >> TCR_V_DTR); /* ring &= ~dtr */
if (dz_auto) { /* auto disconnect? */
int32 drop;
drop = (dz_tcr[dz] & ~data) >> TCR_V_DTR; /* drop = dtr & ~data */
for (i = 0; i < DZ_LINES; i++) { /* drop hangups */
line = (dz * DZ_LINES) + i; /* get line num */
lp = &dz_ldsc[line]; /* get line desc */
if (lp->conn && (drop & (1 << i))) {
tmxr_linemsg (lp, "\r\nLine hangup\r\n");
tmxr_reset_ln (lp); /* reset line, cdet */
dz_msr[dz] &= ~(1 << (i + MSR_V_CD));
} /* end if drop */
} /* end for */
} /* end if auto */
} /* end if modem */
dz_tcr[dz] = data;
tmxr_poll_tx (&dz_desc); /* poll output */
dz_update_xmti (); /* update int */
break;
case 03: /* TDR */
if (PA & 1) { /* odd byte? */
dz_tdr[dz] = (dz_tdr[dz] & 0377) | (data << 8); /* just save */
break;
}
dz_tdr[dz] = data;
if (dz_csr[dz] & CSR_MSE) { /* enabled? */
line = (dz * DZ_LINES) + CSR_GETTL (dz_csr[dz]);
lp = &dz_ldsc[line]; /* get line desc */
tmxr_putc_ln (lp, dz_tdr[dz] & /* store char */
((dz_unit.flags & UNIT_8B)? 0377: 0177));
tmxr_poll_tx (&dz_desc); /* poll output */
dz_update_xmti (); /* update int */
}
break;
}
return SCPE_OK;
}
/* Unit service routine
The DZ11 polls to see if asynchronous activity has occurred and now
@@ -370,20 +390,22 @@ t_stat dz_svc (UNIT *uptr)
{
int32 dz, t, newln;
for (dz = t = 0; dz < DZ_MUXES; dz++) /* check enabled */
t = t | (dz_csr[dz] & CSR_MSE);
if (t) { /* any enabled? */
newln = tmxr_poll_conn (&dz_desc); /* poll connect */
if ((newln >= 0) && dz_mctl) { /* got a live one? */
dz = newln / DZ_LINES; /* get mux num */
if (dz_tcr[dz] & (1 << (newln + TCR_V_DTR))) /* DTR set? */
dz_msr[dz] |= (1 << (newln + MSR_V_CD)); /* set cdet */
else dz_msr[dz] |= (1 << newln); } /* set ring */
tmxr_poll_rx (&dz_desc); /* poll input */
dz_update_rcvi (); /* upd rcv intr */
tmxr_poll_tx (&dz_desc); /* poll output */
dz_update_xmti (); /* upd xmt intr */
sim_activate (uptr, tmxr_poll); } /* reactivate */
for (dz = t = 0; dz < DZ_MUXES; dz++) /* check enabled */
t = t | (dz_csr[dz] & CSR_MSE);
if (t) { /* any enabled? */
newln = tmxr_poll_conn (&dz_desc); /* poll connect */
if ((newln >= 0) && dz_mctl) { /* got a live one? */
dz = newln / DZ_LINES; /* get mux num */
if (dz_tcr[dz] & (1 << (newln + TCR_V_DTR))) /* DTR set? */
dz_msr[dz] |= (1 << (newln + MSR_V_CD)); /* set cdet */
else dz_msr[dz] |= (1 << newln); /* set ring */
}
tmxr_poll_rx (&dz_desc); /* poll input */
dz_update_rcvi (); /* upd rcv intr */
tmxr_poll_tx (&dz_desc); /* poll output */
dz_update_xmti (); /* upd xmt intr */
sim_activate (uptr, tmxr_poll); /* reactivate */
}
return SCPE_OK;
}
@@ -393,12 +415,12 @@ int32 dz_getc (int32 dz)
{
uint32 i, line, c;
for (i = c = 0; (i < DZ_LINES) && (c == 0); i++) { /* loop thru lines */
line = (dz * DZ_LINES) + i; /* get line num */
c = tmxr_getc_ln (&dz_ldsc[line]); /* test for input */
if (c & SCPE_BREAK) c = RBUF_VALID | RBUF_FRME; /* break? frame err */
if (c) c = c | (i << RBUF_V_RLINE); /* or in line # */
} /* end for */
for (i = c = 0; (i < DZ_LINES) && (c == 0); i++) { /* loop thru lines */
line = (dz * DZ_LINES) + i; /* get line num */
c = tmxr_getc_ln (&dz_ldsc[line]); /* test for input */
if (c & SCPE_BREAK) c = RBUF_VALID | RBUF_FRME; /* break? frame err */
if (c) c = c | (i << RBUF_V_RLINE); /* or in line # */
} /* end for */
return c;
}
@@ -409,28 +431,30 @@ void dz_update_rcvi (void)
int32 i, dz, line, scnt[DZ_MUXES];
TMLN *lp;
for (dz = 0; dz < DZ_MUXES; dz++) { /* loop thru muxes */
scnt[dz] = 0; /* clr input count */
for (i = 0; i < DZ_LINES; i++) { /* poll lines */
line = (dz * DZ_LINES) + i; /* get line num */
lp = &dz_ldsc[line]; /* get line desc */
scnt[dz] = scnt[dz] + tmxr_rqln (lp); /* sum buffers */
if (dz_mctl && !lp->conn) /* if disconn */
dz_msr[dz] &= ~(1 << (i + MSR_V_CD)); /* reset car det */
}
for (dz = 0; dz < DZ_MUXES; dz++) { /* loop thru muxes */
scnt[dz] = 0; /* clr input count */
for (i = 0; i < DZ_LINES; i++) { /* poll lines */
line = (dz * DZ_LINES) + i; /* get line num */
lp = &dz_ldsc[line]; /* get line desc */
scnt[dz] = scnt[dz] + tmxr_rqln (lp); /* sum buffers */
if (dz_mctl && !lp->conn) /* if disconn */
dz_msr[dz] &= ~(1 << (i + MSR_V_CD)); /* reset car det */
}
}
for (dz = 0; dz < DZ_MUXES; dz++) { /* loop thru muxes */
if (scnt[dz] && (dz_csr[dz] & CSR_MSE)) { /* input & enabled? */
dz_csr[dz] |= CSR_RDONE; /* set done */
if (dz_sae[dz] && (scnt[dz] >= DZ_SILO_ALM)) { /* alm enb & cnt hi? */
dz_csr[dz] |= CSR_SA; /* set status */
dz_sae[dz] = 0; } } /* disable alarm */
else dz_csr[dz] &= ~CSR_RDONE; /* no, clear done */
if ((dz_csr[dz] & CSR_RIE) && /* int enable */
((dz_csr[dz] & CSR_SAE)?
(dz_csr[dz] & CSR_SA): (dz_csr[dz] & CSR_RDONE)))
dz_set_rxint (dz); /* and alm/done? */
else dz_clr_rxint (dz); /* no, clear int */
for (dz = 0; dz < DZ_MUXES; dz++) { /* loop thru muxes */
if (scnt[dz] && (dz_csr[dz] & CSR_MSE)) { /* input & enabled? */
dz_csr[dz] |= CSR_RDONE; /* set done */
if (dz_sae[dz] && (scnt[dz] >= DZ_SILO_ALM)) { /* alm enb & cnt hi? */
dz_csr[dz] |= CSR_SA; /* set status */
dz_sae[dz] = 0; /* disable alarm */
}
}
else dz_csr[dz] &= ~CSR_RDONE; /* no, clear done */
if ((dz_csr[dz] & CSR_RIE) && /* int enable */
((dz_csr[dz] & CSR_SAE)?
(dz_csr[dz] & CSR_SA): (dz_csr[dz] & CSR_RDONE)))
dz_set_rxint (dz); /* and alm/done? */
else dz_clr_rxint (dz); /* no, clear int */
}
return;
}
@@ -441,38 +465,40 @@ void dz_update_xmti (void)
{
int32 dz, linemask, i, j, line;
for (dz = 0; dz < DZ_MUXES; dz++) { /* loop thru muxes */
linemask = dz_tcr[dz] & DZ_LMASK; /* enabled lines */
dz_csr[dz] &= ~CSR_TRDY; /* assume not rdy */
j = CSR_GETTL (dz_csr[dz]); /* start at current */
for (i = 0; i < DZ_LINES; i++) { /* loop thru lines */
j = (j + 1) & DZ_LNOMASK; /* next line */
line = (dz * DZ_LINES) + j; /* get line num */
if ((linemask & (1 << j)) && dz_ldsc[line].xmte) {
CSR_PUTTL (dz_csr[dz], j); /* put ln in csr */
dz_csr[dz] |= CSR_TRDY; /* set xmt rdy */
break; } }
for (dz = 0; dz < DZ_MUXES; dz++) { /* loop thru muxes */
linemask = dz_tcr[dz] & DZ_LMASK; /* enabled lines */
dz_csr[dz] &= ~CSR_TRDY; /* assume not rdy */
j = CSR_GETTL (dz_csr[dz]); /* start at current */
for (i = 0; i < DZ_LINES; i++) { /* loop thru lines */
j = (j + 1) & DZ_LNOMASK; /* next line */
line = (dz * DZ_LINES) + j; /* get line num */
if ((linemask & (1 << j)) && dz_ldsc[line].xmte) {
CSR_PUTTL (dz_csr[dz], j); /* put ln in csr */
dz_csr[dz] |= CSR_TRDY; /* set xmt rdy */
break;
}
}
if ((dz_csr[dz] & CSR_TIE) && (dz_csr[dz] & CSR_TRDY)) /* ready plus int? */
dz_set_txint (dz);
else dz_clr_txint (dz); /* no int req */
dz_set_txint (dz);
else dz_clr_txint (dz); /* no int req */
}
return;
}
/* Interrupt routines */
void dz_clr_rxint (int32 dz)
{
dz_rxi = dz_rxi & ~(1 << dz); /* clr mux rcv int */
if (dz_rxi == 0) CLR_INT (DZRX); /* all clr? */
else SET_INT (DZRX); /* no, set intr */
dz_rxi = dz_rxi & ~(1 << dz); /* clr mux rcv int */
if (dz_rxi == 0) CLR_INT (DZRX); /* all clr? */
else SET_INT (DZRX); /* no, set intr */
return;
}
void dz_set_rxint (int32 dz)
{
dz_rxi = dz_rxi | (1 << dz); /* set mux rcv int */
SET_INT (DZRX); /* set master intr */
dz_rxi = dz_rxi | (1 << dz); /* set mux rcv int */
SET_INT (DZRX); /* set master intr */
return;
}
@@ -480,25 +506,27 @@ int32 dz_rxinta (void)
{
int32 dz;
for (dz = 0; dz < DZ_MUXES; dz++) { /* find 1st mux */
if (dz_rxi & (1 << dz)) {
dz_clr_rxint (dz); /* clear intr */
return (dz_dib.vec + (dz * 010)); } } /* return vector */
for (dz = 0; dz < DZ_MUXES; dz++) { /* find 1st mux */
if (dz_rxi & (1 << dz)) {
dz_clr_rxint (dz); /* clear intr */
return (dz_dib.vec + (dz * 010)); /* return vector */
}
}
return 0;
}
void dz_clr_txint (int32 dz)
{
dz_txi = dz_txi & ~(1 << dz); /* clr mux xmt int */
if (dz_txi == 0) CLR_INT (DZTX); /* all clr? */
else SET_INT (DZTX); /* no, set intr */
dz_txi = dz_txi & ~(1 << dz); /* clr mux xmt int */
if (dz_txi == 0) CLR_INT (DZTX); /* all clr? */
else SET_INT (DZTX); /* no, set intr */
return;
}
void dz_set_txint (int32 dz)
{
dz_txi = dz_txi | (1 << dz); /* set mux xmt int */
SET_INT (DZTX); /* set master intr */
dz_txi = dz_txi | (1 << dz); /* set mux xmt int */
SET_INT (DZTX); /* set master intr */
return;
}
@@ -506,32 +534,35 @@ int32 dz_txinta (void)
{
int32 dz;
for (dz = 0; dz < DZ_MUXES; dz++) { /* find 1st mux */
if (dz_txi & (1 << dz)) {
dz_clr_txint (dz); /* clear intr */
return (dz_dib.vec + 4 + (dz * 010)); } } /* return vector */
for (dz = 0; dz < DZ_MUXES; dz++) { /* find 1st mux */
if (dz_txi & (1 << dz)) {
dz_clr_txint (dz); /* clear intr */
return (dz_dib.vec + 4 + (dz * 010)); /* return vector */
}
}
return 0;
}
/* Device reset */
t_stat dz_clear (int32 dz, t_bool flag)
{
int32 i, line;
dz_csr[dz] = 0; /* clear CSR */
dz_rbuf[dz] = 0; /* silo empty */
dz_lpr[dz] = 0; /* no params */
if (flag) dz_tcr[dz] = 0; /* INIT? clr all */
else dz_tcr[dz] &= ~0377; /* else save dtr */
dz_csr[dz] = 0; /* clear CSR */
dz_rbuf[dz] = 0; /* silo empty */
dz_lpr[dz] = 0; /* no params */
if (flag) dz_tcr[dz] = 0; /* INIT? clr all */
else dz_tcr[dz] &= ~0377; /* else save dtr */
dz_tdr[dz] = 0;
dz_sae[dz] = 1; /* alarm on */
dz_clr_rxint (dz); /* clear int */
dz_sae[dz] = 1; /* alarm on */
dz_clr_rxint (dz); /* clear int */
dz_clr_txint (dz);
for (i = 0; i < DZ_LINES; i++) { /* loop thru lines */
line = (dz * DZ_LINES) + i;
if (!dz_ldsc[line].conn) dz_ldsc[line].xmte = 1;/* set xmt enb */
dz_ldsc[line].rcve = 0; } /* clr rcv enb */
for (i = 0; i < DZ_LINES; i++) { /* loop thru lines */
line = (dz * DZ_LINES) + i;
if (!dz_ldsc[line].conn) dz_ldsc[line].xmte = 1; /* set xmt enb */
dz_ldsc[line].rcve = 0; /* clr rcv enb */
}
return SCPE_OK;
}
@@ -539,13 +570,13 @@ t_stat dz_reset (DEVICE *dptr)
{
int32 i, ndev;
for (i = 0; i < DZ_MUXES; i++) dz_clear (i, TRUE); /* init muxes */
dz_rxi = dz_txi = 0; /* clr master int */
for (i = 0; i < DZ_MUXES; i++) dz_clear (i, TRUE); /* init muxes */
dz_rxi = dz_txi = 0; /* clr master int */
CLR_INT (DZRX);
CLR_INT (DZTX);
sim_cancel (&dz_unit); /* stop poll */
sim_cancel (&dz_unit); /* stop poll */
ndev = ((dptr->flags & DEV_DIS)? 0: (dz_desc.lines / DZ_LINES));
return auto_config (RANK_DZ, ndev); /* auto config */
return auto_config (dptr->name, ndev); /* auto config */
}
/* Attach */
@@ -555,19 +586,19 @@ t_stat dz_attach (UNIT *uptr, char *cptr)
t_stat r;
extern int32 sim_switches;
dz_mctl = dz_auto = 0; /* modem ctl off */
r = tmxr_attach (&dz_desc, uptr, cptr); /* attach mux */
if (r != SCPE_OK) return r; /* error? */
if (sim_switches & SWMASK ('M')) { /* modem control? */
dz_mctl = 1;
printf ("Modem control activated\n");
if (sim_log) fprintf (sim_log, "Modem control activated\n");
if (sim_switches & SWMASK ('A')) { /* autodisconnect? */
dz_auto = 1;
printf ("Auto disconnect activated\n");
if (sim_log) fprintf (sim_log, "Auto disconnect activated\n");
}
}
dz_mctl = dz_auto = 0; /* modem ctl off */
r = tmxr_attach (&dz_desc, uptr, cptr); /* attach mux */
if (r != SCPE_OK) return r; /* error? */
if (sim_switches & SWMASK ('M')) { /* modem control? */
dz_mctl = 1;
printf ("Modem control activated\n");
if (sim_log) fprintf (sim_log, "Modem control activated\n");
if (sim_switches & SWMASK ('A')) { /* autodisconnect? */
dz_auto = 1;
printf ("Auto disconnect activated\n");
if (sim_log) fprintf (sim_log, "Auto disconnect activated\n");
}
}
return SCPE_OK;
}
@@ -577,15 +608,16 @@ t_stat dz_detach (UNIT *uptr)
{
return tmxr_detach (&dz_desc, uptr);
}
/* Show summary processor */
t_stat dz_summ (FILE *st, UNIT *uptr, int32 val, void *desc)
{
int32 i, t;
for (i = t = 0; i < dz_desc.lines; i++) { /* get num conn */
if (dz_ldsc[i].conn) t = t + 1; }
for (i = t = 0; i < dz_desc.lines; i++) { /* get num conn */
if (dz_ldsc[i].conn) t = t + 1;
}
if (t == 1) fprintf (st, "1 connection");
else fprintf (st, "%d connections", t);
return SCPE_OK;
@@ -597,11 +629,13 @@ t_stat dz_show (FILE *st, UNIT *uptr, int32 val, void *desc)
{
int32 i, t;
for (i = t = 0; i < dz_desc.lines; i++) { /* loop thru conn */
if (dz_ldsc[i].conn) {
t = 1;
if (val) tmxr_fconns (st, &dz_ldsc[i], i);
else tmxr_fstats (st, &dz_ldsc[i], i); } }
for (i = t = 0; i < dz_desc.lines; i++) { /* loop thru conn */
if (dz_ldsc[i].conn) {
t = 1;
if (val) tmxr_fconns (st, &dz_ldsc[i], i);
else tmxr_fstats (st, &dz_ldsc[i], i);
}
}
if (t == 0) fprintf (st, "all disconnected\n");
return SCPE_OK;
}
@@ -620,18 +654,20 @@ if ((newln == 0) || (newln % DZ_LINES)) return SCPE_ARG;
if (newln < dz_desc.lines) {
for (i = newln, t = 0; i < dz_desc.lines; i++) t = t | dz_ldsc[i].conn;
if (t && !get_yn ("This will disconnect users; proceed [N]?", FALSE))
return SCPE_OK;
return SCPE_OK;
for (i = newln; i < dz_desc.lines; i++) {
if (dz_ldsc[i].conn) {
tmxr_linemsg (&dz_ldsc[i], "\r\nOperator disconnected line\r\n");
tmxr_reset_ln (&dz_ldsc[i]); } /* reset line */
if ((i % DZ_LINES) == (DZ_LINES - 1))
dz_clear (i / DZ_LINES, TRUE); } /* reset mux */
if (dz_ldsc[i].conn) {
tmxr_linemsg (&dz_ldsc[i], "\r\nOperator disconnected line\r\n");
tmxr_reset_ln (&dz_ldsc[i]); /* reset line */
}
if ((i % DZ_LINES) == (DZ_LINES - 1))
dz_clear (i / DZ_LINES, TRUE); /* reset mux */
}
}
dz_dib.lnt = (newln / DZ_LINES) * IOLN_DZ; /* set length */
dz_dib.lnt = (newln / DZ_LINES) * IOLN_DZ; /* set length */
dz_desc.lines = newln;
ndev = ((dz_dev.flags & DEV_DIS)? 0: (dz_desc.lines / DZ_LINES));
return auto_config (RANK_DZ, ndev); /* auto config */
return auto_config (dz_dev.name, ndev); /* auto config */
}
/* SHOW VECTOR processor */
@@ -678,10 +714,10 @@ t_stat dz_show_log (FILE *st, UNIT *uptr, int32 val, void *desc)
int32 i;
for (i = 0; i < dz_desc.lines; i++) {
fprintf (st, "line %d: ", i);
tmxr_show_log (st, NULL, i, desc);
fprintf (st, "\n");
}
fprintf (st, "line %d: ", i);
tmxr_show_log (st, NULL, i, desc);
fprintf (st, "\n");
}
return SCPE_OK;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/* pdp11_io.c: PDP-11 I/O simulator
Copyright (c) 1993-2004, Robert M Supnik
Copyright (c) 1993-2005, 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"),
@@ -19,28 +19,29 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not 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.
30-Sep-04 RMS Revised Unibus interface
28-May-04 RMS Revised I/O dispatching (from John Dundas)
25-Jan-04 RMS Removed local debug logging support
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
Added show I/O space, autoconfigure routines
12-Sep-02 RMS Added support for TMSCP, KW11P, RX211
26-Jan-02 RMS Revised for multiple DZ's
06-Jan-02 RMS Revised I/O access, enable/disable support
11-Dec-01 RMS Moved interrupt debug code
08-Nov-01 RMS Cloned from cpu sources
25-Jul-05 RMS Revised autoconfiguration algorithm and interface
30-Sep-04 RMS Revised Unibus interface
28-May-04 RMS Revised I/O dispatching (from John Dundas)
25-Jan-04 RMS Removed local debug logging support
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
Added show I/O space, autoconfigure routines
12-Sep-02 RMS Added support for TMSCP, KW11P, RX211
26-Jan-02 RMS Revised for multiple DZ's
06-Jan-02 RMS Revised I/O access, enable/disable support
11-Dec-01 RMS Moved interrupt debug code
08-Nov-01 RMS Cloned from cpu sources
*/
#include "pdp11_defs.h"
extern uint16 *M;
extern int32 int_req[IPL_HLVL];
extern int32 ub_map[UBM_LNT_LW];
@@ -65,23 +66,24 @@ static t_stat (*iodispR[IOPAGESIZE >> 1])(int32 *dat, int32 ad, int32 md);
static t_stat (*iodispW[IOPAGESIZE >> 1])(int32 dat, int32 ad, int32 md);
static DIB *iodibp[IOPAGESIZE >> 1];
int32 int_vec[IPL_HLVL][32]; /* int req to vector */
int32 int_vec[IPL_HLVL][32]; /* int req to vector */
int32 (*int_ack[IPL_HLVL][32])(void); /* int ack routines */
int32 (*int_ack[IPL_HLVL][32])(void); /* int ack routines */
static const int32 pirq_bit[7] = {
INT_V_PIR1, INT_V_PIR2, INT_V_PIR3, INT_V_PIR4,
INT_V_PIR5, INT_V_PIR6, INT_V_PIR7 };
INT_V_PIR1, INT_V_PIR2, INT_V_PIR3, INT_V_PIR4,
INT_V_PIR5, INT_V_PIR6, INT_V_PIR7
};
/* I/O page lookup and linkage routines
Inputs:
*data = pointer to data to read, if READ
data = data to store, if WRITE or WRITEB
pa = address
access = READ, WRITE, or WRITEB
*data = pointer to data to read, if READ
data = data to store, if WRITE or WRITEB
pa = address
access = READ, WRITE, or WRITEB
Outputs:
status = SCPE_OK or SCPE_NXM
status = SCPE_OK or SCPE_NXM
*/
t_stat iopageR (int32 *data, uint32 pa, int32 access)
@@ -91,9 +93,10 @@ t_stat stat;
idx = (pa & IOPAGEMASK) >> 1;
if (iodispR[idx]) {
stat = iodispR[idx] (data, pa, access);
trap_req = calc_ints (ipl, trap_req);
return stat; }
stat = iodispR[idx] (data, pa, access);
trap_req = calc_ints (ipl, trap_req);
return stat;
}
return SCPE_NXM;
}
@@ -104,9 +107,10 @@ t_stat stat;
idx = (pa & IOPAGEMASK) >> 1;
if (iodispW[idx]) {
stat = iodispW[idx] (data, pa, access);
trap_req = calc_ints (ipl, trap_req);
return stat; }
stat = iodispW[idx] (data, pa, access);
trap_req = calc_ints (ipl, trap_req);
return stat;
}
return SCPE_NXM;
}
@@ -117,7 +121,8 @@ int32 calc_ints (int32 nipl, int32 trq)
int32 i;
for (i = IPL_HLVL - 1; i > nipl; i--) {
if (int_req[i]) return (trq | TRAP_INT); }
if (int_req[i]) return (trq | TRAP_INT);
}
return (trq & ~TRAP_INT);
}
@@ -127,20 +132,20 @@ int32 get_vector (int32 nipl)
{
int32 i, j, t, vec;
for (i = IPL_HLVL - 1; i > nipl; i--) { /* loop thru lvls */
t = int_req[i]; /* get level */
for (j = 0; t && (j < 32); j++) { /* srch level */
if ((t >> j) & 1) { /* irq found? */
int_req[i] = int_req[i] & ~(1u << j); /* clr irq */
if (int_ack[i][j]) vec = int_ack[i][j]();
else vec = int_vec[i][j];
return vec; /* return vector */
} /* end if t */
} /* end for j */
} /* end for i */
for (i = IPL_HLVL - 1; i > nipl; i--) { /* loop thru lvls */
t = int_req[i]; /* get level */
for (j = 0; t && (j < 32); j++) { /* srch level */
if ((t >> j) & 1) { /* irq found? */
int_req[i] = int_req[i] & ~(1u << j); /* clr irq */
if (int_ack[i][j]) vec = int_ack[i][j]();
else vec = int_vec[i][j];
return vec; /* return vector */
} /* end if t */
} /* end for j */
} /* end for i */
return 0;
}
/* Read and write Unibus map registers
In any even/odd pair
@@ -156,47 +161,51 @@ t_stat ubm_rd (int32 *data, int32 addr, int32 access)
int32 pg = (addr >> 2) & UBM_M_PN;
*data = (addr & 2)? ((ub_map[pg] >> 16) & 077):
(ub_map[pg] & 0177776);
(ub_map[pg] & 0177776);
return SCPE_OK;
}
t_stat ubm_wr (int32 data, int32 addr, int32 access)
{
int32 sc, pg = (addr >> 2) & UBM_M_PN;
if (access == WRITEB) {
sc = (addr & 3) << 3;
ub_map[pg] = (ub_map[pg] & ~(0377 << sc)) |
((data & 0377) << sc); }
else { sc = (addr & 2) << 3;
ub_map[pg] = (ub_map[pg] & ~(0177777 << sc)) |
((data & 0177777) << sc); }
sc = (addr & 3) << 3;
ub_map[pg] = (ub_map[pg] & ~(0377 << sc)) |
((data & 0377) << sc);
}
else {
sc = (addr & 2) << 3;
ub_map[pg] = (ub_map[pg] & ~(0177777 << sc)) |
((data & 0177777) << sc);
}
ub_map[pg] = ub_map[pg] & 017777776;
return SCPE_OK;
}
/* Mapped memory access routines for DMA devices */
#define BUSMASK ((UNIBUS)? UNIMASK: PAMASK)
#define BUSMASK ((UNIBUS)? UNIMASK: PAMASK)
/* Map I/O address to memory address - caller checks cpu_bme */
uint32 Map_Addr (uint32 ba)
{
int32 pg = UBM_GETPN (ba); /* map entry */
int32 off = UBM_GETOFF (ba); /* offset */
int32 pg = UBM_GETPN (ba); /* map entry */
int32 off = UBM_GETOFF (ba); /* offset */
if (pg != UBM_M_PN) /* last page? */
uba_last = (ub_map[pg] + off) & PAMASK; /* no, use map */
else uba_last = (IOPAGEBASE + off) & PAMASK; /* yes, use fixed */
if (pg != UBM_M_PN) /* last page? */
uba_last = (ub_map[pg] + off) & PAMASK; /* no, use map */
else uba_last = (IOPAGEBASE + off) & PAMASK; /* yes, use fixed */
return uba_last;
}
/* I/O buffer routines, aligned access
Map_ReadB - fetch byte buffer from memory
Map_ReadW - fetch word buffer from memory
Map_WriteB - store byte buffer into memory
Map_WriteW - store word buffer into memory
Map_ReadB - fetch byte buffer from memory
Map_ReadW - fetch word buffer from memory
Map_WriteB - store byte buffer into memory
Map_WriteW - store word buffer into memory
These routines are used only for Unibus and Qbus devices.
Massbus devices have their own IO routines. As a result,
@@ -215,99 +224,115 @@ int32 Map_ReadB (uint32 ba, int32 bc, uint8 *buf)
{
uint32 alim, lim, ma;
ba = ba & BUSMASK; /* trim address */
ba = ba & BUSMASK; /* trim address */
lim = ba + bc;
if (cpu_bme) { /* map enabled? */
for ( ; ba < lim; ba++) { /* by bytes */
ma = Map_Addr (ba); /* map addr */
if (!ADDR_IS_MEM (ma)) return (lim - ba); /* NXM? err */
if (ma & 1) *buf++ = (M[ma >> 1] >> 8) & 0377; /* get byte */
else *buf++ = M[ma >> 1] & 0377; }
return 0; }
else { /* physical */
if (ADDR_IS_MEM (lim)) alim = lim; /* end ok? */
else if (ADDR_IS_MEM (ba)) alim = MEMSIZE; /* no, strt ok? */
else return bc; /* no, err */
for ( ; ba < alim; ba++) { /* by bytes */
if (ba & 1) *buf++ = (M[ba >> 1] >> 8) & 0377; /* get byte */
else *buf++ = M[ba >> 1] & 0377; }
return (lim - alim); }
if (cpu_bme) { /* map enabled? */
for ( ; ba < lim; ba++) { /* by bytes */
ma = Map_Addr (ba); /* map addr */
if (!ADDR_IS_MEM (ma)) return (lim - ba); /* NXM? err */
if (ma & 1) *buf++ = (M[ma >> 1] >> 8) & 0377; /* get byte */
else *buf++ = M[ma >> 1] & 0377;
}
return 0;
}
else { /* physical */
if (ADDR_IS_MEM (lim)) alim = lim; /* end ok? */
else if (ADDR_IS_MEM (ba)) alim = MEMSIZE; /* no, strt ok? */
else return bc; /* no, err */
for ( ; ba < alim; ba++) { /* by bytes */
if (ba & 1) *buf++ = (M[ba >> 1] >> 8) & 0377; /* get byte */
else *buf++ = M[ba >> 1] & 0377;
}
return (lim - alim);
}
}
int32 Map_ReadW (uint32 ba, int32 bc, uint16 *buf)
{
uint32 alim, lim, ma;
ba = (ba & BUSMASK) & ~01; /* trim, align addr */
ba = (ba & BUSMASK) & ~01; /* trim, align addr */
lim = ba + (bc & ~01);
if (cpu_bme) { /* map enabled? */
for (; ba < lim; ba = ba + 2) { /* by words */
ma = Map_Addr (ba); /* map addr */
if (!ADDR_IS_MEM (ma)) return (lim - ba); /* NXM? err */
*buf++ = M[ma >> 1]; }
return 0; }
else { /* physical */
if (ADDR_IS_MEM (lim)) alim = lim; /* end ok? */
else if (ADDR_IS_MEM (ba)) alim = MEMSIZE; /* no, strt ok? */
else return bc; /* no, err */
for ( ; ba < alim; ba = ba + 2) { /* by words */
*buf++ = M[ba >> 1]; }
return (lim - alim); }
if (cpu_bme) { /* map enabled? */
for (; ba < lim; ba = ba + 2) { /* by words */
ma = Map_Addr (ba); /* map addr */
if (!ADDR_IS_MEM (ma)) return (lim - ba); /* NXM? err */
*buf++ = M[ma >> 1];
}
return 0;
}
else { /* physical */
if (ADDR_IS_MEM (lim)) alim = lim; /* end ok? */
else if (ADDR_IS_MEM (ba)) alim = MEMSIZE; /* no, strt ok? */
else return bc; /* no, err */
for ( ; ba < alim; ba = ba + 2) { /* by words */
*buf++ = M[ba >> 1];
}
return (lim - alim);
}
}
int32 Map_WriteB (uint32 ba, int32 bc, uint8 *buf)
{
uint32 alim, lim, ma;
ba = ba & BUSMASK; /* trim address */
ba = ba & BUSMASK; /* trim address */
lim = ba + bc;
if (cpu_bme) { /* map enabled? */
for ( ; ba < lim; ba++) { /* by bytes */
ma = Map_Addr (ba); /* map addr */
if (!ADDR_IS_MEM (ma)) return (lim - ba); /* NXM? err */
if (ma & 1) M[ma >> 1] = (M[ma >> 1] & 0377) |
((uint16) *buf++ << 8);
else M[ma >> 1] = (M[ma >> 1] & ~0377) | *buf++; }
return 0; }
else { /* physical */
if (ADDR_IS_MEM (lim)) alim = lim; /* end ok? */
else if (ADDR_IS_MEM (ba)) alim = MEMSIZE; /* no, strt ok? */
else return bc; /* no, err */
for ( ; ba < alim; ba++) { /* by bytes */
if (ba & 1) M[ba >> 1] = (M[ba >> 1] & 0377) |
((uint16) *buf++ << 8);
else M[ba >> 1] = (M[ba >> 1] & ~0377) | *buf++; }
return (lim - alim); }
if (cpu_bme) { /* map enabled? */
for ( ; ba < lim; ba++) { /* by bytes */
ma = Map_Addr (ba); /* map addr */
if (!ADDR_IS_MEM (ma)) return (lim - ba); /* NXM? err */
if (ma & 1) M[ma >> 1] = (M[ma >> 1] & 0377) |
((uint16) *buf++ << 8);
else M[ma >> 1] = (M[ma >> 1] & ~0377) | *buf++;
}
return 0;
}
else { /* physical */
if (ADDR_IS_MEM (lim)) alim = lim; /* end ok? */
else if (ADDR_IS_MEM (ba)) alim = MEMSIZE; /* no, strt ok? */
else return bc; /* no, err */
for ( ; ba < alim; ba++) { /* by bytes */
if (ba & 1) M[ba >> 1] = (M[ba >> 1] & 0377) |
((uint16) *buf++ << 8);
else M[ba >> 1] = (M[ba >> 1] & ~0377) | *buf++;
}
return (lim - alim);
}
}
int32 Map_WriteW (uint32 ba, int32 bc, uint16 *buf)
{
uint32 alim, lim, ma;
ba = (ba & BUSMASK) & ~01; /* trim, align addr */
ba = (ba & BUSMASK) & ~01; /* trim, align addr */
lim = ba + (bc & ~01);
if (cpu_bme) { /* map enabled? */
for (; ba < lim; ba = ba + 2) { /* by words */
ma = Map_Addr (ba); /* map addr */
if (!ADDR_IS_MEM (ma)) return (lim - ba); /* NXM? err */
M[ma >> 1] = *buf++; } /* store word */
return 0; }
else { /* physical */
if (ADDR_IS_MEM (lim)) alim = lim; /* end ok? */
else if (ADDR_IS_MEM (ba)) alim = MEMSIZE; /* no, strt ok? */
else return bc; /* no, err */
for ( ; ba < alim; ba = ba + 2) { /* by words */
M[ba >> 1] = *buf++; }
return (lim - alim); }
if (cpu_bme) { /* map enabled? */
for (; ba < lim; ba = ba + 2) { /* by words */
ma = Map_Addr (ba); /* map addr */
if (!ADDR_IS_MEM (ma)) return (lim - ba); /* NXM? err */
M[ma >> 1] = *buf++;
}
return 0;
}
else { /* physical */
if (ADDR_IS_MEM (lim)) alim = lim; /* end ok? */
else if (ADDR_IS_MEM (ba)) alim = MEMSIZE; /* no, strt ok? */
else return bc; /* no, err */
for ( ; ba < alim; ba = ba + 2) { /* by words */
M[ba >> 1] = *buf++;
}
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);
return auto_config (NULL, 0);
}
/* Show autoconfiguration status */
@@ -333,13 +358,13 @@ dptr = find_dev_from_unit (uptr);
if (dptr == NULL) return SCPE_IERR;
dibp = (DIB *) dptr->ctxt;
if (dibp == NULL) return SCPE_IERR;
newba = get_uint (cptr, 8, PAMASK, &r); /* get new */
if (r != SCPE_OK) return r; /* error? */
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 */
autcon_enb = 0; /* autoconfig off */
newba = get_uint (cptr, 8, PAMASK, &r); /* get new */
if (r != SCPE_OK) return r; /* error? */
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 */
autcon_enb = 0; /* autoconfig off */
return SCPE_OK;
}
@@ -357,7 +382,7 @@ dibp = (DIB *) dptr->ctxt;
if ((dibp == NULL) || (dibp->ba <= IOPAGEBASE)) return SCPE_IERR;
fprintf (st, "address=%08o", dibp->ba);
if (dibp->lnt > 1)
fprintf (st, "-%08o", dibp->ba + dibp->lnt - 1);
fprintf (st, "-%08o", dibp->ba + dibp->lnt - 1);
if (dptr->flags & DEV_FLTA) fprintf (st, "*");
return SCPE_OK;
}
@@ -372,8 +397,8 @@ if (cptr != NULL) return SCPE_ARG;
if (uptr == NULL) return SCPE_IERR;
dptr = find_dev_from_unit (uptr);
if (dptr == NULL) return SCPE_IERR;
dptr->flags = dptr->flags | DEV_FLTA; /* floating */
return auto_config (0, 0); /* autoconfigure */
dptr->flags = dptr->flags | DEV_FLTA; /* floating */
return auto_config (NULL, 0); /* autoconfigure */
}
/* Change device vector */
@@ -396,8 +421,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 */
dptr->flags = dptr->flags & ~DEV_FLTA; /* not floating */
autcon_enb = 0; /* autoconfig off */
return SCPE_OK;
}
@@ -418,25 +443,30 @@ vec = dibp->vec;
if (arg) numvec = arg;
else numvec = dibp->vnum;
if (vec == 0) fprintf (st, "no vector");
else { fprintf (st, "vector=%o", vec);
if (numvec > 1) fprintf (st, "-%o", vec + (4 * (numvec - 1))); }
else {
fprintf (st, "vector=%o", vec);
if (numvec > 1) fprintf (st, "-%o", vec + (4 * (numvec - 1)));
}
return SCPE_OK;
}
/* Init Unibus tables */
void init_ubus_tab (void)
{
int32 i, j;
for (i = 0; i < IPL_HLVL; i++) { /* clear intr tab */
for (j = 0; j < 32; j++) {
int_vec[i][j] = 0;
int_ack[i][j] = NULL; } }
for (i = 0; i < (IOPAGESIZE >> 1); i++) { /* clear dispatch tab */
iodispR[i] = NULL;
iodispW[i] = NULL;
iodibp[i] = NULL; }
for (i = 0; i < IPL_HLVL; i++) { /* clear intr tab */
for (j = 0; j < 32; j++) {
int_vec[i][j] = 0;
int_ack[i][j] = NULL;
}
}
for (i = 0; i < (IOPAGESIZE >> 1); i++) { /* clear dispatch tab */
iodispR[i] = NULL;
iodispW[i] = NULL;
iodibp[i] = NULL;
}
return;
}
@@ -446,44 +476,44 @@ t_stat build_ubus_tab (DEVICE *dptr, DIB *dibp)
{
int32 i, idx, vec, ilvl, ibit;
if ((dptr == NULL) || (dibp == NULL)) return SCPE_IERR; /* validate args */
if ((dptr == NULL) || (dibp == NULL)) return SCPE_IERR; /* validate args */
if (dibp->vnum > VEC_DEVMAX) return SCPE_IERR;
for (i = 0; i < dibp->vnum; i++) { /* loop thru vec */
idx = dibp->vloc + i; /* vector index */
vec = dibp->vec? (dibp->vec + (i * 4)): 0; /* vector addr */
ilvl = idx / 32;
ibit = idx % 32;
if ((int_ack[ilvl][ibit] && dibp->ack[i] && /* conflict? */
(int_ack[ilvl][ibit] != dibp->ack[i])) ||
(int_vec[ilvl][ibit] && vec &&
(int_vec[ilvl][ibit] != vec))) {
printf ("Device %s interrupt slot conflict at %d\n",
sim_dname (dptr), idx);
if (sim_log) fprintf (sim_log,
"Device %s interrupt slot conflict at %d\n",
sim_dname (dptr), idx);
return SCPE_STOP;
}
if (dibp->ack[i]) int_ack[ilvl][ibit] = dibp->ack[i];
else if (vec) int_vec[ilvl][ibit] = vec;
}
for (i = 0; i < (int32) dibp->lnt; i = i + 2) { /* create entries */
idx = ((dibp->ba + i) & IOPAGEMASK) >> 1; /* index into disp */
if ((iodispR[idx] && dibp->rd && /* conflict? */
(iodispR[idx] != dibp->rd)) ||
(iodispW[idx] && dibp->wr &&
(iodispW[idx] != dibp->wr))) {
printf ("Device %s address conflict at %08o\n",
sim_dname (dptr), dibp->ba);
if (sim_log) fprintf (sim_log,
"Device %s address conflict at %08o\n",
sim_dname (dptr), dibp->ba);
return SCPE_STOP;
}
if (dibp->rd) iodispR[idx] = dibp->rd; /* set rd dispatch */
if (dibp->wr) iodispW[idx] = dibp->wr; /* set wr dispatch */
iodibp[idx] = dibp; /* remember DIB */
}
for (i = 0; i < dibp->vnum; i++) { /* loop thru vec */
idx = dibp->vloc + i; /* vector index */
vec = dibp->vec? (dibp->vec + (i * 4)): 0; /* vector addr */
ilvl = idx / 32;
ibit = idx % 32;
if ((int_ack[ilvl][ibit] && dibp->ack[i] && /* conflict? */
(int_ack[ilvl][ibit] != dibp->ack[i])) ||
(int_vec[ilvl][ibit] && vec &&
(int_vec[ilvl][ibit] != vec))) {
printf ("Device %s interrupt slot conflict at %d\n",
sim_dname (dptr), idx);
if (sim_log) fprintf (sim_log,
"Device %s interrupt slot conflict at %d\n",
sim_dname (dptr), idx);
return SCPE_STOP;
}
if (dibp->ack[i]) int_ack[ilvl][ibit] = dibp->ack[i];
else if (vec) int_vec[ilvl][ibit] = vec;
}
for (i = 0; i < (int32) dibp->lnt; i = i + 2) { /* create entries */
idx = ((dibp->ba + i) & IOPAGEMASK) >> 1; /* index into disp */
if ((iodispR[idx] && dibp->rd && /* conflict? */
(iodispR[idx] != dibp->rd)) ||
(iodispW[idx] && dibp->wr &&
(iodispW[idx] != dibp->wr))) {
printf ("Device %s address conflict at %08o\n",
sim_dname (dptr), dibp->ba);
if (sim_log) fprintf (sim_log,
"Device %s address conflict at %08o\n",
sim_dname (dptr), dibp->ba);
return SCPE_STOP;
}
if (dibp->rd) iodispR[idx] = dibp->rd; /* set rd dispatch */
if (dibp->wr) iodispW[idx] = dibp->wr; /* set wr dispatch */
iodibp[idx] = dibp; /* remember DIB */
}
return SCPE_OK;
}
@@ -496,24 +526,24 @@ DEVICE *dptr;
DIB *dibp;
t_stat r;
init_ubus_tab (); /* init Unibus tables */
init_mbus_tab (); /* init Massbus tables */
for (i = 0; i < 7; i++) /* seed PIRQ intr */
int_vec[i + 1][pirq_bit[i]] = VEC_PIRQ;
if (r = cpu_build_dib ()) return r; /* build CPU entries */
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */
dibp = (DIB *) dptr->ctxt; /* get DIB */
if (dibp && !(dptr->flags & DEV_DIS)) { /* defined, enabled? */
if (dptr->flags & DEV_MBUS) { /* Massbus? */
if (r = build_mbus_tab (dptr, dibp)) /* add to Mbus tab */
return r;
}
else { /* no, Unibus */
if (r = build_ubus_tab (dptr, dibp)) /* add to Unibus tab */
return r;
}
} /* end if enabled */
} /* end for */
init_ubus_tab (); /* init Unibus tables */
init_mbus_tab (); /* init Massbus tables */
for (i = 0; i < 7; i++) /* seed PIRQ intr */
int_vec[i + 1][pirq_bit[i]] = VEC_PIRQ;
if (r = cpu_build_dib ()) return r; /* build CPU entries */
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */
dibp = (DIB *) dptr->ctxt; /* get DIB */
if (dibp && !(dptr->flags & DEV_DIS)) { /* defined, enabled? */
if (dptr->flags & DEV_MBUS) { /* Massbus? */
if (r = build_mbus_tab (dptr, dibp)) /* add to Mbus tab */
return r;
}
else { /* no, Unibus */
if (r = build_ubus_tab (dptr, dibp)) /* add to Unibus tab */
return r;
}
} /* end if enabled */
} /* end for */
return SCPE_OK;
}
@@ -525,117 +555,162 @@ uint32 i, j;
DEVICE *dptr;
DIB *dibp;
if (build_dib_tab ()) return SCPE_OK; /* build IO page */
for (i = 0, dibp = NULL; i < (IOPAGESIZE >> 1); i++) { /* loop thru entries */
if (iodibp[i] && (iodibp[i] != dibp)) { /* new block? */
dibp = iodibp[i]; /* DIB for block */
for (j = 0, dptr = NULL; sim_devices[j] != NULL; j++) {
if (((DIB*) sim_devices[j]->ctxt) == dibp) {
dptr = sim_devices[j]; /* locate device */
break;
} /* end if */
} /* end for j */
fprintf (st, "%08o - %08o%c\t%s\n", /* print block entry */
dibp->ba, dibp->ba + dibp->lnt - 1,
(dptr && (dptr->flags & DEV_FLTA))? '*': ' ',
dptr? sim_dname (dptr): "CPU");
} /* end if */
} /* end for i */
if (build_dib_tab ()) return SCPE_OK; /* build IO page */
for (i = 0, dibp = NULL; i < (IOPAGESIZE >> 1); i++) { /* loop thru entries */
if (iodibp[i] && (iodibp[i] != dibp)) { /* new block? */
dibp = iodibp[i]; /* DIB for block */
for (j = 0, dptr = NULL; sim_devices[j] != NULL; j++) {
if (((DIB*) sim_devices[j]->ctxt) == dibp) {
dptr = sim_devices[j]; /* locate device */
break;
} /* end if */
} /* end for j */
fprintf (st, "%08o - %08o%c\t%s\n", /* print block entry */
dibp->ba, dibp->ba + dibp->lnt - 1,
(dptr && (dptr->flags & DEV_FLTA))? '*': ' ',
dptr? sim_dname (dptr): "CPU");
} /* end if */
} /* end for i */
return SCPE_OK;
}
/* Autoconfiguration */
#define AUTO_DYN 0001
#define AUTO_VEC 0002
#define AUTO_MAXC 4
#define AUTO_CSRBASE 0010
#define AUTO_VECBASE 0300
/* Autoconfiguration
struct auto_con {
uint32 amod;
uint32 vmod;
uint32 flags;
uint32 num;
uint32 fix;
char *dnam[AUTO_MAXC]; };
The table reflects the MicroVAX 3900 microcode, with one addition - the
number of controllers field handles devices where multiple instances
are simulated through a single DEVICE structure (e.g., DZ, VH).
struct auto_con auto_tab[AUTO_LNT + 1] = {
{ 0x7, 0x7 }, /* DJ11 */
{ 0xf, 0x7 }, /* DH11 */
{ 0x7, 0x7 }, /* DQ11 */
{ 0x7, 0x7 }, /* DU11 */
{ 0x7, 0x7 }, /* DUP11 */
{ 0x7, 0x7 }, /* LK11A */
{ 0x7, 0x7 }, /* DMC11 */
{ 0x7, 0x7, AUTO_VEC, DZ_MUXES, 0, { "DZ" } },
A minus number of vectors indicates a field that should be calculated
but not placed in the DIB (RQ, TQ dynamic vectors) */
{ 0x7, 0x7 }, /* KMC11 */
{ 0x7, 0x7 }, /* LPP11 */
{ 0x7, 0x7 }, /* VMV21 */
{ 0xf, 0x7 }, /* VMV31 */
{ 0x7, 0x7 }, /* DWR70 */
{ 0x7, 0x3, AUTO_DYN|AUTO_VEC, 0, IOBA_RL, { "RL", "RLB" } },
{ 0xf, 0x7 }, /* LPA11K */
{ 0x7, 0x7 }, /* KW11C */
#define AUTO_MAXC 4
#define AUTO_CSRBASE 0010
#define AUTO_VECBASE 0300
{ 0x7, 0 }, /* reserved */
{ 0x7, 0x3, AUTO_DYN|AUTO_VEC, 0, IOBA_RX, { "RX", "RY" } },
{ 0x7, 0x3 }, /* DR11W */
{ 0x7, 0x3 }, /* DR11B */
{ 0x7, 0x7 }, /* DMP11 */
{ 0x7, 0x7 }, /* DPV11 */
{ 0x7, 0x7 }, /* ISB11 */
{ 0xf, 0x7 }, /* DMV11 */
typedef struct {
char *dnam[AUTO_MAXC];
int32 numc;
int32 numv;
uint32 amod;
uint32 vmod;
uint32 fixa[AUTO_MAXC];
uint32 fixv[AUTO_MAXC];
} AUTO_CON;
{ 0x7, 0x3, AUTO_DYN|AUTO_VEC, 0, IOBA_XU, { "XU", "XUB" } },
{ 0x3, 0x3, AUTO_DYN|AUTO_VEC, 0, IOBA_RQ, { "RQ", "RQB", "RQC", "RQD" } },
{ 0x1f, 0x3 }, /* DMF32 */
{ 0xf, 0x7 }, /* KMS11 */
{ 0xf, 0x3 }, /* VS100 */
{ 0x3, 0x3, AUTO_DYN|AUTO_VEC, 0, IOBA_TQ, { "TQ", "TQB" } },
{ 0xf, 0x7 }, /* KMV11 */
{ 0x1f, 0x7, AUTO_VEC, VH_MUXES, 0, { "VH" } }, /* DHU11/DHQ11 */
{ 0x1f, 0x7 }, /* DMZ32 */
{ 0x1f, 0x7 }, /* CP132 */
{ 0 }, /* padding */
AUTO_CON auto_tab[] = {
{ { NULL }, 1, 2, 0, 8, { 0 } }, /* DLV11J - fx CSRs */
{ { NULL }, 1, 2, 8, 8 }, /* DJ11 */
{ { NULL }, 1, 2, 16, 8 }, /* DH11 */
{ { NULL }, 1, 2, 8, 8 }, /* DQ11 */
{ { NULL }, 1, 2, 8, 8 }, /* DU11 */
{ { NULL }, 1, 2, 8, 8 }, /* DUP11 */
{ { NULL }, 10, 2, 8, 8 }, /* LK11A */
{ { NULL }, 1, 2, 8, 8 }, /* DMC11 */
{ { "DZ" }, DZ_MUXES, 2, 8, 8 }, /* DZ11 */
{ { NULL }, 1, 2, 8, 8 }, /* KMC11 */
{ { NULL }, 1, 2, 8, 8 }, /* LPP11 */
{ { NULL }, 1, 2, 8, 8 }, /* VMV21 */
{ { NULL }, 1, 2, 16, 8 }, /* VMV31 */
{ { NULL }, 1, 2, 8, 8 }, /* DWR70 */
{ { "RL", "RLB" }, 1, 1, 8, 4, {IOBA_RL}, {VEC_RL} }, /* RL11 */
{ { "TS", "TSB", "TSC", "TSD" }, 1, 1, 0, 4, /* TS11 */
{IOBA_TS, IOBA_TS + 4, IOBA_TS + 8, IOBA_TS + 12},
{VEC_TS} },
{ { NULL }, 1, 2, 16, 8 }, /* LPA11K */
{ { NULL }, 1, 2, 8, 8 }, /* KW11C */
{ { NULL }, 1, 1, 8, 8 }, /* reserved */
{ { "RX", "RY" }, 1, 1, 8, 4, {IOBA_RX} , {VEC_RX} }, /* RX11/RX211 */
{ { NULL }, 1, 1, 8, 4 }, /* DR11W */
{ { NULL }, 1, 1, 8, 4, { 0, 0 }, { 0 } }, /* DR11B - fx CSRs,vec */
{ { NULL }, 1, 2, 8, 8 }, /* DMP11 */
{ { NULL }, 1, 2, 8, 8 }, /* DPV11 */
{ { NULL }, 1, 2, 8, 8 }, /* ISB11 */
{ { NULL }, 1, 2, 16, 8 }, /* DMV11 */
// { { "XU", "XUB" }, 1, 1, 8, 4, {IOBA_XU}, {VEC_XU} }, /* DEUNA */
{ { "XQ", "XQB" }, 1, 1, 0, 4, /* DEQNA */
{IOBA_XQ,IOBA_XQB}, {VEC_XQ} },
{ { "RQ", "RQB", "RQC", "RQD" }, 1, -1, 4, 4, /* RQDX3 */
{IOBA_RQ}, {VEC_RQ} },
{ { NULL }, 1, 8, 32, 4 }, /* DMF32 */
{ { NULL }, 1, 2, 16, 8 }, /* KMS11 */
{ { NULL }, 1, 1, 16, 4 }, /* VS100 */
{ { "TQ", "TQB" }, 1, -1, 4, 4, {IOBA_TQ}, {VEC_TQ} }, /* TQK50 */
{ { NULL }, 1, 2, 16, 8 }, /* KMV11 */
{ { "VH" }, VH_MUXES, 2, 16, 8 }, /* DHU11/DHQ11 */
{ { NULL }, 1, 6, 32, 4 }, /* DMZ32 */
{ { NULL }, 1, 6, 32, 4 }, /* CP132 */
{ { NULL }, 1, 2, 64, 8, { 0 } }, /* QVSS - fx CSR */
{ { NULL }, 1, 1, 8, 4 }, /* VS31 */
{ { NULL }, 1, 1, 0, 4, { 0 } }, /* LNV11 - fx CSR */
{ { NULL }, 1, 1, 16, 4 }, /* LNV21/QPSS */
{ { NULL }, 1, 1, 8, 4, { 0 } }, /* QTA - fx CSR */
{ { NULL }, 1, 1, 8, 4 }, /* DSV11 */
{ { NULL }, 1, 2, 8, 8 }, /* CSAM */
{ { NULL }, 1, 2, 8, 8 }, /* ADV11C */
{ { NULL }, 1, 0, 8, 0 }, /* AAV11C */
{ { NULL }, 1, 2, 8, 8, { 0 }, { 0 } }, /* AXV11C - fx CSR,vec */
{ { NULL }, 1, 2, 4, 8, { 0 } }, /* KWV11C - fx CSR */
{ { NULL }, 1, 2, 8, 8, { 0 } }, /* ADV11D - fx CSR */
{ { NULL }, 1, 2, 8, 8, { 0 } }, /* AAV11D - fx CSR */
/* { { "QDSS" }, 1, 3, 0, 16, {IOBA_QDSS} }, /* QDSS - fx CSR */
{ { NULL }, -1 } /* end table */
};
t_stat auto_config (uint32 rank, uint32 nctrl)
t_stat auto_config (char *name, int32 nctrl)
{
uint32 csr = IOPAGEBASE + AUTO_CSRBASE;
uint32 vec = VEC_Q + AUTO_VECBASE;
struct auto_con *autp;
AUTO_CON *autp;
DEVICE *dptr;
DIB *dibp;
int32 i, j, k;
extern DEVICE *find_dev (char *ptr);
uint32 j, k, vmask, amask;
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 */
for (j = k = 0; (j < AUTO_MAXC) && autp->dnam[j]; j++) {
dptr = find_dev (autp->dnam[j]); /* find ctrl */
if ((dptr == NULL) || (dptr->flags & DEV_DIS) ||
!(dptr->flags & DEV_FLTA)) continue; /* enabled, floating? */
dibp = (DIB *) dptr->ctxt; /* get DIB */
if ((k++ == 0) && autp->fix) /* 1st & fixed? */
dibp->ba = autp->fix; /* gets fixed CSR */
else { /* no, float */
dibp->ba = csr; /* set CSR */
csr = (csr + autp->amod + 1) & ~autp->amod; /* next CSR */
if ((autp->flags & AUTO_DYN) == 0) /* static? */
csr = csr + ((autp->num - 1) * (autp->amod + 1));
if (autp->flags & AUTO_VEC) { /* vectors too? */
dibp->vec = (vec + autp->vmod) & ~autp->vmod;
if (autp->flags & AUTO_DYN) vec = vec + autp->vmod + 1;
else vec = vec + (autp->num * (autp->vmod + 1)); }
} /* end else flt */
} /* end for j */
autp++;
csr = (csr + autp->amod + 1) & ~autp->amod; /* gap */
} /* end for i */
if (autcon_enb == 0) return SCPE_OK; /* enabled? */
if (name) { /* updating? */
if (nctrl < 0) return SCPE_ARG;
for (autp = auto_tab; autp->numc >= 0; autp++) {
for (j = 0; (j < AUTO_MAXC) && autp->dnam[j]; j++) {
if (strcmp (name, autp->dnam[j]) == 0)
autp->numc = nctrl;
}
}
}
for (autp = auto_tab; autp->numc >= 0; autp++) { /* loop thru table */
if (autp->amod) { /* floating csr? */
amask = autp->amod - 1;
csr = (csr + amask) & ~amask; /* align csr */
}
for (j = k = 0; (j < AUTO_MAXC) && autp->dnam[j]; j++) {
dptr = find_dev (autp->dnam[j]); /* find ctrl */
if ((dptr == NULL) || (dptr->flags & DEV_DIS) ||
!(dptr->flags & DEV_FLTA)) continue; /* enabled, floating? */
dibp = (DIB *) dptr->ctxt; /* get DIB */
if (dibp == NULL) return SCPE_IERR; /* not there??? */
if (autp->amod) { /* dyn csr needed? */
if (autp->fixa[k]) /* fixed csr avail? */
dibp->ba = autp->fixa[k]; /* use it */
else { /* no fixed left */
dibp->ba = csr; /* set CSR */
csr += (autp->numc * autp->amod); /* next CSR */
} /* end else */
} /* end if dyn csr */
if (autp->numv && autp->vmod) { /* dyn vec needed? */
uint32 numv = abs (autp->numv); /* get num vec */
if (autp->fixv[k]) { /* fixed vec avail? */
if (autp->numv > 0)
dibp->vec = autp->fixv[k]; /* use it */
}
else { /* no fixed left */
vmask = autp->vmod - 1;
vec = (vec + vmask) & ~vmask; /* align vector */
if (autp->numv > 0)
dibp->vec = vec; /* set vector */
vec += (autp->numc * numv * 4);
} /* end else */
} /* end if dyn vec */
k++; /* next instance */
} /* end for j */
if (autp->amod) csr = csr + 2; /* flt CSR? gap */
} /* end for i */
return SCPE_OK;
}

View File

@@ -1,6 +1,6 @@
/* pdp11_lp.c: PDP-11 line printer simulator
Copyright (c) 1993-2004, Robert M Supnik
Copyright (c) 1993-2005, 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"),
@@ -19,41 +19,41 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not 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.
lpt LP11 line printer
lpt LP11 line printer
19-May-03 RMS Revised for new conditional compilation scheme
25-Apr-03 RMS Revised for extended file support
29-Sep-02 RMS Added vector change/display support
New data structures
30-May-02 RMS Widened POS to 32b
06-Jan-02 RMS Added enable/disable support
09-Nov-01 RMS Added VAX support
07-Sep-01 RMS Revised interrupt mechanism
30-Oct-00 RMS Standardized register naming
07-Jul-05 RMS Removed extraneous externs
19-May-03 RMS Revised for new conditional compilation scheme
25-Apr-03 RMS Revised for extended file support
29-Sep-02 RMS Added vector change/display support
New data structures
30-May-02 RMS Widened POS to 32b
06-Jan-02 RMS Added enable/disable support
09-Nov-01 RMS Added VAX support
07-Sep-01 RMS Revised interrupt mechanism
30-Oct-00 RMS Standardized register naming
*/
#if defined (VM_PDP10) /* PDP10 version */
#if defined (VM_PDP10) /* PDP10 version */
#error "LP11 is not supported on the PDP-10!"
#elif defined (VM_VAX) /* VAX version */
#elif defined (VM_VAX) /* VAX version */
#include "vax_defs.h"
#else /* PDP-11 version */
#else /* PDP-11 version */
#include "pdp11_defs.h"
#endif
#define LPTCSR_IMP (CSR_ERR + CSR_DONE + CSR_IE) /* implemented */
#define LPTCSR_RW (CSR_IE) /* read/write */
#define LPTCSR_IMP (CSR_ERR + CSR_DONE + CSR_IE) /* implemented */
#define LPTCSR_RW (CSR_IE) /* read/write */
extern int32 int_req[IPL_HLVL];
extern int32 int_vec[IPL_HLVL][32];
int32 lpt_csr = 0; /* control/status */
int32 lpt_stopioe = 0; /* stop on error */
int32 lpt_csr = 0; /* control/status */
int32 lpt_stopioe = 0; /* stop on error */
DEVICE lpt_dev;
t_stat lpt_rd (int32 *data, int32 PA, int32 access);
@@ -65,76 +65,85 @@ t_stat lpt_detach (UNIT *uptr);
/* LPT data structures
lpt_dev LPT device descriptor
lpt_unit LPT unit descriptor
lpt_reg LPT register list
lpt_dev LPT device descriptor
lpt_unit LPT unit descriptor
lpt_reg LPT register list
*/
DIB lpt_dib = { IOBA_LPT, IOLN_LPT, &lpt_rd, &lpt_wr,
1, IVCL (LPT), VEC_LPT, { NULL } };
DIB lpt_dib = {
IOBA_LPT, IOLN_LPT, &lpt_rd, &lpt_wr,
1, IVCL (LPT), VEC_LPT, { NULL }
};
UNIT lpt_unit = {
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT };
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT
};
REG lpt_reg[] = {
{ GRDATA (BUF, lpt_unit.buf, DEV_RDX, 8, 0) },
{ GRDATA (CSR, lpt_csr, DEV_RDX, 16, 0) },
{ FLDATA (INT, IREQ (LPT), INT_V_LPT) },
{ FLDATA (ERR, lpt_csr, CSR_V_ERR) },
{ FLDATA (DONE, lpt_csr, CSR_V_DONE) },
{ FLDATA (IE, lpt_csr, CSR_V_IE) },
{ DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, lpt_unit.wait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, lpt_stopioe, 0) },
{ GRDATA (DEVADDR, lpt_dib.ba, DEV_RDX, 32, 0), REG_HRO },
{ GRDATA (DEVVEC, lpt_dib.vec, DEV_RDX, 16, 0), REG_HRO },
{ NULL } };
{ GRDATA (BUF, lpt_unit.buf, DEV_RDX, 8, 0) },
{ GRDATA (CSR, lpt_csr, DEV_RDX, 16, 0) },
{ FLDATA (INT, IREQ (LPT), INT_V_LPT) },
{ FLDATA (ERR, lpt_csr, CSR_V_ERR) },
{ FLDATA (DONE, lpt_csr, CSR_V_DONE) },
{ FLDATA (IE, lpt_csr, CSR_V_IE) },
{ DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, lpt_unit.wait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, lpt_stopioe, 0) },
{ GRDATA (DEVADDR, lpt_dib.ba, DEV_RDX, 32, 0), REG_HRO },
{ GRDATA (DEVVEC, lpt_dib.vec, DEV_RDX, 16, 0), REG_HRO },
{ NULL }
};
MTAB lpt_mod[] = {
{ MTAB_XTD|MTAB_VDV, 004, "ADDRESS", "ADDRESS",
&set_addr, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR",
&set_vec, &show_vec, NULL },
{ 0 } };
{ MTAB_XTD|MTAB_VDV, 004, "ADDRESS", "ADDRESS",
&set_addr, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR",
&set_vec, &show_vec, NULL },
{ 0 }
};
DEVICE lpt_dev = {
"LPT", &lpt_unit, lpt_reg, lpt_mod,
1, 10, 31, 1, DEV_RDX, 8,
NULL, NULL, &lpt_reset,
NULL, &lpt_attach, &lpt_detach,
&lpt_dib, DEV_DISABLE | DEV_UBUS | DEV_QBUS };
"LPT", &lpt_unit, lpt_reg, lpt_mod,
1, 10, 31, 1, DEV_RDX, 8,
NULL, NULL, &lpt_reset,
NULL, &lpt_attach, &lpt_detach,
&lpt_dib, DEV_DISABLE | DEV_UBUS | DEV_QBUS
};
/* Line printer routines
lpt_rd I/O page read
lpt_wr I/O page write
lpt_svc process event (printer ready)
lpt_reset process reset
lpt_attach process attach
lpt_detach process detach
lpt_rd I/O page read
lpt_wr I/O page write
lpt_svc process event (printer ready)
lpt_reset process reset
lpt_attach process attach
lpt_detach process detach
*/
t_stat lpt_rd (int32 *data, int32 PA, int32 access)
{
if ((PA & 02) == 0) *data = lpt_csr & LPTCSR_IMP; /* csr */
else *data = lpt_unit.buf; /* buffer */
if ((PA & 02) == 0) *data = lpt_csr & LPTCSR_IMP; /* csr */
else *data = lpt_unit.buf; /* buffer */
return SCPE_OK;
}
t_stat lpt_wr (int32 data, int32 PA, int32 access)
{
if ((PA & 02) == 0) { /* csr */
if (PA & 1) return SCPE_OK;
if ((data & CSR_IE) == 0) CLR_INT (LPT);
else if ((lpt_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
SET_INT (LPT);
lpt_csr = (lpt_csr & ~LPTCSR_RW) | (data & LPTCSR_RW); }
else { if ((PA & 1) == 0) lpt_unit.buf = data & 0177; /* buffer */
lpt_csr = lpt_csr & ~CSR_DONE;
CLR_INT (LPT);
if ((lpt_unit.buf == 015) || (lpt_unit.buf == 014) ||
(lpt_unit.buf == 012)) sim_activate (&lpt_unit, lpt_unit.wait);
else sim_activate (&lpt_unit, 0); }
if ((PA & 02) == 0) { /* csr */
if (PA & 1) return SCPE_OK;
if ((data & CSR_IE) == 0) CLR_INT (LPT);
else if ((lpt_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
SET_INT (LPT);
lpt_csr = (lpt_csr & ~LPTCSR_RW) | (data & LPTCSR_RW);
}
else {
if ((PA & 1) == 0) lpt_unit.buf = data & 0177; /* buffer */
lpt_csr = lpt_csr & ~CSR_DONE;
CLR_INT (LPT);
if ((lpt_unit.buf == 015) || (lpt_unit.buf == 014) ||
(lpt_unit.buf == 012)) sim_activate (&lpt_unit, lpt_unit.wait);
else sim_activate (&lpt_unit, 0);
}
return SCPE_OK;
}
@@ -143,23 +152,24 @@ t_stat lpt_svc (UNIT *uptr)
lpt_csr = lpt_csr | CSR_ERR | CSR_DONE;
if (lpt_csr & CSR_IE) SET_INT (LPT);
if ((lpt_unit.flags & UNIT_ATT) == 0)
return IORETURN (lpt_stopioe, SCPE_UNATT);
return IORETURN (lpt_stopioe, SCPE_UNATT);
if (putc (lpt_unit.buf & 0177, lpt_unit.fileref) == EOF) {
perror ("LPT I/O error");
clearerr (lpt_unit.fileref);
return SCPE_IOERR; }
perror ("LPT I/O error");
clearerr (lpt_unit.fileref);
return SCPE_IOERR;
}
lpt_csr = lpt_csr & ~CSR_ERR;
lpt_unit.pos = lpt_unit.pos + 1;
return SCPE_OK;
}
t_stat lpt_reset (DEVICE *dptr)
{
lpt_unit.buf = 0;
lpt_csr = CSR_DONE;
if ((lpt_unit.flags & UNIT_ATT) == 0) lpt_csr = lpt_csr | CSR_ERR;
CLR_INT (LPT);
sim_cancel (&lpt_unit); /* deactivate unit */
sim_cancel (&lpt_unit); /* deactivate unit */
return SCPE_OK;
}

View File

@@ -1,6 +1,6 @@
/* pdp11_mscp.h: DEC MSCP and TMSCP definitionsn
Copyright (c) 2001-2004, Robert M Supnik
Copyright (c) 2001-2005, Robert M Supnik
Derived from work by Stephen F. Shirron
Permission is hereby granted, free of charge, to any person obtaining a
@@ -20,495 +20,495 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not 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.
09-Jan-03 RMS Tape read/write end pkt is longer than disk read/write
20-Sep-02 RMS Merged TMSCP definitions
09-Jan-03 RMS Tape read/write end pkt is longer than disk read/write
20-Sep-02 RMS Merged TMSCP definitions
*/
#ifndef _PDP11_MSCP_H_
#define _PDP11_MSCP_H_ 0
#define _PDP11_MSCP_H_ 0
/* Misc constants */
#define UID_DISK 2 /* disk class */
#define UID_TAPE 3 /* tape class */
#define UID_DISK 2 /* disk class */
#define UID_TAPE 3 /* tape class */
/* Opcodes */
#define OP_ABO 1 /* b: abort */
#define OP_GCS 2 /* b: get command status */
#define OP_GUS 3 /* b: get unit status */
#define OP_SCC 4 /* b: set controller char */
#define OP_AVL 8 /* b: available */
#define OP_ONL 9 /* b: online */
#define OP_SUC 10 /* b: set unit char */
#define OP_DAP 11 /* b: det acc paths - nop */
#define OP_ACC 16 /* b: access */
#define OP_CCD 17 /* d: compare - nop */
#define OP_ERS 18 /* b: erase */
#define OP_FLU 19 /* d: flush - nop */
#define OP_ERG 22 /* t: erase gap */
#define OP_CMP 32 /* b: compare */
#define OP_RD 33 /* b: read */
#define OP_WR 34 /* b: write */
#define OP_WTM 36 /* t: write tape mark */
#define OP_POS 37 /* t: reposition */
#define OP_FMT 47 /* d: format */
#define OP_AVA 64 /* b: unit now avail */
#define OP_END 0x80 /* b: end flag */
#define OP_ABO 1 /* b: abort */
#define OP_GCS 2 /* b: get command status */
#define OP_GUS 3 /* b: get unit status */
#define OP_SCC 4 /* b: set controller char */
#define OP_AVL 8 /* b: available */
#define OP_ONL 9 /* b: online */
#define OP_SUC 10 /* b: set unit char */
#define OP_DAP 11 /* b: det acc paths - nop */
#define OP_ACC 16 /* b: access */
#define OP_CCD 17 /* d: compare - nop */
#define OP_ERS 18 /* b: erase */
#define OP_FLU 19 /* d: flush - nop */
#define OP_ERG 22 /* t: erase gap */
#define OP_CMP 32 /* b: compare */
#define OP_RD 33 /* b: read */
#define OP_WR 34 /* b: write */
#define OP_WTM 36 /* t: write tape mark */
#define OP_POS 37 /* t: reposition */
#define OP_FMT 47 /* d: format */
#define OP_AVA 64 /* b: unit now avail */
#define OP_END 0x80 /* b: end flag */
/* Modifiers */
#define MD_EXP 0x8000 /* d: express NI */
#define MD_CMP 0x4000 /* b: compare NI */
#define MD_CSE 0x2000 /* b: clr ser err */
#define MD_ERR 0x1000 /* d: force error NI*/
#define MD_CDL 0x1000 /* t: clr data lost NI*/
#define MD_SCH 0x0800 /* t: supr cache NI */
#define MD_SEC 0x0200 /* b: supr err corr NI */
#define MD_SER 0x0100 /* b: supr err rec NI */
#define MD_DLE 0x0080 /* t: detect LEOT */
#define MD_IMM 0x0040 /* t: immediate NI */
#define MD_EXA 0x0020 /* b: excl access NI */
#define MD_SHD 0x0010 /* d: shadow NI */
#define MD_UNL 0x0010 /* t avl: unload */
#define MD_ERW 0x0008 /* t wr: enb rewrite */
#define MD_REV 0x0008 /* t rd, pos: reverse */
#define MD_SWP 0x0004 /* b suc: enb set wrp */
#define MD_OBC 0x0004 /* t: pos: obj count */
#define MD_IMF 0x0002 /* d onl: ign fmte NI */
#define MD_RWD 0x0002 /* t pos: rewind */
#define MD_ACL 0x0002 /* t avl: all class NI */
#define MD_NXU 0x0001 /* b gus: next unit */
#define MD_RIP 0x0001 /* d onl: allow rip NI */
#define MD_EXP 0x8000 /* d: express NI */
#define MD_CMP 0x4000 /* b: compare NI */
#define MD_CSE 0x2000 /* b: clr ser err */
#define MD_ERR 0x1000 /* d: force error NI*/
#define MD_CDL 0x1000 /* t: clr data lost NI*/
#define MD_SCH 0x0800 /* t: supr cache NI */
#define MD_SEC 0x0200 /* b: supr err corr NI */
#define MD_SER 0x0100 /* b: supr err rec NI */
#define MD_DLE 0x0080 /* t: detect LEOT */
#define MD_IMM 0x0040 /* t: immediate NI */
#define MD_EXA 0x0020 /* b: excl access NI */
#define MD_SHD 0x0010 /* d: shadow NI */
#define MD_UNL 0x0010 /* t avl: unload */
#define MD_ERW 0x0008 /* t wr: enb rewrite */
#define MD_REV 0x0008 /* t rd, pos: reverse */
#define MD_SWP 0x0004 /* b suc: enb set wrp */
#define MD_OBC 0x0004 /* t: pos: obj count */
#define MD_IMF 0x0002 /* d onl: ign fmte NI */
#define MD_RWD 0x0002 /* t pos: rewind */
#define MD_ACL 0x0002 /* t avl: all class NI */
#define MD_NXU 0x0001 /* b gus: next unit */
#define MD_RIP 0x0001 /* d onl: allow rip NI */
/* End flags */
#define EF_LOG 0x0020 /* b: error log */
#define EF_SXC 0x0010 /* b: serious exc */
#define EF_EOT 0x0008 /* end of tape */
#define EF_PLS 0x0004 /* pos lost */
#define EF_DLS 0x0002 /* cached data lost NI */
#define EF_LOG 0x0020 /* b: error log */
#define EF_SXC 0x0010 /* b: serious exc */
#define EF_EOT 0x0008 /* end of tape */
#define EF_PLS 0x0004 /* pos lost */
#define EF_DLS 0x0002 /* cached data lost NI */
/* Controller flags */
#define CF_RPL 0x8000 /* ctrl bad blk repl */
#define CF_ATN 0x0080 /* enb attention */
#define CF_MSC 0x0040 /* enb misc msgs */
#define CF_OTH 0x0020 /* enb othr host msgs */
#define CF_THS 0x0010 /* enb this host msgs */
#define CF_MSK (CF_ATN|CF_MSC|CF_OTH|CF_THS)
#define CF_RPL 0x8000 /* ctrl bad blk repl */
#define CF_ATN 0x0080 /* enb attention */
#define CF_MSC 0x0040 /* enb misc msgs */
#define CF_OTH 0x0020 /* enb othr host msgs */
#define CF_THS 0x0010 /* enb this host msgs */
#define CF_MSK (CF_ATN|CF_MSC|CF_OTH|CF_THS)
/* Unit flags */
#define UF_RPL 0x8000 /* d: ctrl bad blk repl */
#define UF_CAC 0x8000 /* t: cache write back */
#define UF_WPH 0x2000 /* b: wr prot hwre */
#define UF_WPS 0x1000 /* b: wr prot swre */
#define UF_SCH 0x0800 /* t: supr cache NI */
#define UF_EXA 0x0400 /* b: exclusive NI */
#define UF_WPD 0x0100 /* b: wr prot data NI */
#define UF_RMV 0x0080 /* d: removable */
#define UF_WBN 0x0040 /* t: write back NI */
#define UF_VSS 0x0020 /* t: supr var speed NI */
#define UF_VSU 0x0010 /* t: var speed unit NI */
#define UF_EWR 0x0008 /* t: enh wr recovery NI */
#define UF_CMW 0x0002 /* cmp writes NI */
#define UF_CMR 0x0001 /* cmp reads NI */
#define UF_RPL 0x8000 /* d: ctrl bad blk repl */
#define UF_CAC 0x8000 /* t: cache write back */
#define UF_WPH 0x2000 /* b: wr prot hwre */
#define UF_WPS 0x1000 /* b: wr prot swre */
#define UF_SCH 0x0800 /* t: supr cache NI */
#define UF_EXA 0x0400 /* b: exclusive NI */
#define UF_WPD 0x0100 /* b: wr prot data NI */
#define UF_RMV 0x0080 /* d: removable */
#define UF_WBN 0x0040 /* t: write back NI */
#define UF_VSS 0x0020 /* t: supr var speed NI */
#define UF_VSU 0x0010 /* t: var speed unit NI */
#define UF_EWR 0x0008 /* t: enh wr recovery NI */
#define UF_CMW 0x0002 /* cmp writes NI */
#define UF_CMR 0x0001 /* cmp reads NI */
/* Error log flags */
#define LF_SUC 0x0080 /* b: successful */
#define LF_CON 0x0040 /* b: continuing */
#define LF_BBR 0x0020 /* d: bad blk repl NI */
#define LF_RCT 0x0010 /* d: err in repl NI */
#define LF_SNR 0x0001 /* b: seq # reset */
#define LF_SUC 0x0080 /* b: successful */
#define LF_CON 0x0040 /* b: continuing */
#define LF_BBR 0x0020 /* d: bad blk repl NI */
#define LF_RCT 0x0010 /* d: err in repl NI */
#define LF_SNR 0x0001 /* b: seq # reset */
/* Error log formats */
#define FM_CNT 0 /* b: port lf err */
#define FM_BAD 1 /* b: bad host addr */
#define FM_DSK 2 /* d: disk xfer */
#define FM_SDI 3 /* d: SDI err */
#define FM_SDE 4 /* d: sm disk err */
#define FM_TAP 5 /* t: tape errors */
#define FM_RPL 9 /* d: bad blk repl */
#define FM_CNT 0 /* b: port lf err */
#define FM_BAD 1 /* b: bad host addr */
#define FM_DSK 2 /* d: disk xfer */
#define FM_SDI 3 /* d: SDI err */
#define FM_SDE 4 /* d: sm disk err */
#define FM_TAP 5 /* t: tape errors */
#define FM_RPL 9 /* d: bad blk repl */
/* Status codes */
#define ST_SUC 0 /* b: successful */
#define ST_CMD 1 /* b: invalid cmd */
#define ST_ABO 2 /* b: aborted cmd */
#define ST_OFL 3 /* b: unit offline */
#define ST_AVL 4 /* b: unit avail */
#define ST_MFE 5 /* b: media fmt err */
#define ST_WPR 6 /* b: write prot err */
#define ST_CMP 7 /* b: compare err */
#define ST_DAT 8 /* b: data err */
#define ST_HST 9 /* b: host acc err */
#define ST_CNT 10 /* b: ctrl err */
#define ST_DRV 11 /* b: drive err */
#define ST_FMT 12 /* t: formatter err */
#define ST_BOT 13 /* t: BOT encountered */
#define ST_TMK 14 /* t: tape mark */
#define ST_RDT 16 /* t: record trunc */
#define ST_POL 17 /* t: pos lost */
#define ST_SXC 18 /* b: serious exc */
#define ST_LED 19 /* t: LEOT detect */
#define ST_BBR 20 /* d: bad block */
#define ST_DIA 31 /* b: diagnostic */
#define ST_V_SUB 5 /* subcode */
#define ST_V_INV 8 /* invalid op */
#define ST_SUC 0 /* b: successful */
#define ST_CMD 1 /* b: invalid cmd */
#define ST_ABO 2 /* b: aborted cmd */
#define ST_OFL 3 /* b: unit offline */
#define ST_AVL 4 /* b: unit avail */
#define ST_MFE 5 /* b: media fmt err */
#define ST_WPR 6 /* b: write prot err */
#define ST_CMP 7 /* b: compare err */
#define ST_DAT 8 /* b: data err */
#define ST_HST 9 /* b: host acc err */
#define ST_CNT 10 /* b: ctrl err */
#define ST_DRV 11 /* b: drive err */
#define ST_FMT 12 /* t: formatter err */
#define ST_BOT 13 /* t: BOT encountered */
#define ST_TMK 14 /* t: tape mark */
#define ST_RDT 16 /* t: record trunc */
#define ST_POL 17 /* t: pos lost */
#define ST_SXC 18 /* b: serious exc */
#define ST_LED 19 /* t: LEOT detect */
#define ST_BBR 20 /* d: bad block */
#define ST_DIA 31 /* b: diagnostic */
#define ST_V_SUB 5 /* subcode */
#define ST_V_INV 8 /* invalid op */
/* Status subcodes */
#define SB_SUC_IGN (1 << ST_V_SUB) /* t: unload ignored */
#define SB_SUC_ON (8 << ST_V_SUB) /* b: already online */
#define SB_SUC_EOT (32 << ST_V_SUB) /* t: EOT encountered */
#define SB_SUC_RO (128 << ST_V_SUB) /* t: read only */
#define SB_OFL_NV (1 << ST_V_SUB) /* b: no volume */
#define SB_OFL_INOP (2 << ST_V_SUB) /* t: inoperative */
#define SB_AVL_INU (32 << ST_V_SUB) /* b: in use */
#define SB_WPR_SW (128 << ST_V_SUB) /* b: swre wlk */
#define SB_WPR_HW (256 << ST_V_SUB) /* b: hwre wlk */
#define SB_HST_OA (1 << ST_V_SUB) /* b: odd addr */
#define SB_HST_OC (2 << ST_V_SUB) /* d: odd count */
#define SB_HST_NXM (3 << ST_V_SUB) /* b: nx memory */
#define SB_HST_PAR (4 << ST_V_SUB) /* b: parity err */
#define SB_HST_PTE (5 << ST_V_SUB) /* b: mapping err */
#define SB_DAT_RDE (7 << ST_V_SUB) /* t: read err */
#define SB_SUC_IGN (1 << ST_V_SUB) /* t: unload ignored */
#define SB_SUC_ON (8 << ST_V_SUB) /* b: already online */
#define SB_SUC_EOT (32 << ST_V_SUB) /* t: EOT encountered */
#define SB_SUC_RO (128 << ST_V_SUB) /* t: read only */
#define SB_OFL_NV (1 << ST_V_SUB) /* b: no volume */
#define SB_OFL_INOP (2 << ST_V_SUB) /* t: inoperative */
#define SB_AVL_INU (32 << ST_V_SUB) /* b: in use */
#define SB_WPR_SW (128 << ST_V_SUB) /* b: swre wlk */
#define SB_WPR_HW (256 << ST_V_SUB) /* b: hwre wlk */
#define SB_HST_OA (1 << ST_V_SUB) /* b: odd addr */
#define SB_HST_OC (2 << ST_V_SUB) /* d: odd count */
#define SB_HST_NXM (3 << ST_V_SUB) /* b: nx memory */
#define SB_HST_PAR (4 << ST_V_SUB) /* b: parity err */
#define SB_HST_PTE (5 << ST_V_SUB) /* b: mapping err */
#define SB_DAT_RDE (7 << ST_V_SUB) /* t: read err */
/* Status invalid command subcodes */
#define I_OPCD (8 << ST_V_INV) /* inv opcode */
#define I_FLAG (9 << ST_V_INV) /* inv flags */
#define I_MODF (10 << ST_V_INV) /* inv modifier */
#define I_BCNT (12 << ST_V_INV) /* inv byte cnt */
#define I_LBN (28 << ST_V_INV) /* inv LBN */
#define I_VRSN (12 << ST_V_INV) /* inv version */
#define I_FMTI (28 << ST_V_INV) /* inv format */
#define I_OPCD (8 << ST_V_INV) /* inv opcode */
#define I_FLAG (9 << ST_V_INV) /* inv flags */
#define I_MODF (10 << ST_V_INV) /* inv modifier */
#define I_BCNT (12 << ST_V_INV) /* inv byte cnt */
#define I_LBN (28 << ST_V_INV) /* inv LBN */
#define I_VRSN (12 << ST_V_INV) /* inv version */
#define I_FMTI (28 << ST_V_INV) /* inv format */
/* Tape format flags */
#define TF_9TK 0x0100 /* 9 track */
#define TF_9TK_NRZ 0x0001 /* 800 bpi */
#define TF_9TK_PE 0x0002 /* 1600 bpi */
#define TF_9TK_GRP 0x0004 /* 6250 bpi */
#define TF_CTP 0x0200 /* TK50 */
#define TF_CTP_LO 0x0001 /* low density */
#define TF_CTP_HI 0x0002 /* hi density */
#define TF_3480 0x0300 /* 3480 */
#define TF_WOD 0x0400 /* RV80 */
#define TF_9TK 0x0100 /* 9 track */
#define TF_9TK_NRZ 0x0001 /* 800 bpi */
#define TF_9TK_PE 0x0002 /* 1600 bpi */
#define TF_9TK_GRP 0x0004 /* 6250 bpi */
#define TF_CTP 0x0200 /* TK50 */
#define TF_CTP_LO 0x0001 /* low density */
#define TF_CTP_HI 0x0002 /* hi density */
#define TF_3480 0x0300 /* 3480 */
#define TF_WOD 0x0400 /* RV80 */
/* Packet formats - note that all packet lengths must be multiples of 4 bytes */
/* Command packet header */
#define CMD_REFL 2 /* ref # */
#define CMD_REFH 3
#define CMD_UN 4 /* unit # */
/* 5 /* reserved */
#define CMD_OPC 6 /* opcode */
#define CMD_MOD 7 /* modifier */
#define CMD_REFL 2 /* ref # */
#define CMD_REFH 3
#define CMD_UN 4 /* unit # */
/* 5 /* reserved */
#define CMD_OPC 6 /* opcode */
#define CMD_MOD 7 /* modifier */
#define CMD_OPC_V_OPC 0 /* opcode */
#define CMD_OPC_M_OPC 0xFF
#define CMD_OPC_V_CAA 8 /* cache NI */
#define CMD_OPC_M_CAA 0xFF
#define CMD_OPC_V_FLG 8 /* flags */
#define CMD_OPC_M_FLG 0xFF
#define CMD_OPC_V_OPC 0 /* opcode */
#define CMD_OPC_M_OPC 0xFF
#define CMD_OPC_V_CAA 8 /* cache NI */
#define CMD_OPC_M_CAA 0xFF
#define CMD_OPC_V_FLG 8 /* flags */
#define CMD_OPC_M_FLG 0xFF
/* Response packet header */
#define RSP_LNT 12
#define RSP_REFL 2 /* ref # */
#define RSP_REFH 3
#define RSP_UN 4 /* unit # */
#define RSP_RSV 5 /* reserved */
#define RSP_OPF 6 /* opcd,flg */
#define RSP_STS 7 /* modifiers */
#define RSP_LNT 12
#define RSP_REFL 2 /* ref # */
#define RSP_REFH 3
#define RSP_UN 4 /* unit # */
#define RSP_RSV 5 /* reserved */
#define RSP_OPF 6 /* opcd,flg */
#define RSP_STS 7 /* modifiers */
#define RSP_OPF_V_OPC 0 /* opcode */
#define RSP_OPF_V_FLG 8 /* flags */
#define RSP_OPF_V_OPC 0 /* opcode */
#define RSP_OPF_V_FLG 8 /* flags */
/* Abort packet - 2 W parameter, 2 W status */
#define ABO_LNT 16
#define ABO_REFL 8 /* ref # */
#define ABO_REFH 9
#define ABO_LNT 16
#define ABO_REFL 8 /* ref # */
#define ABO_REFH 9
/* Avail packet - min size */
#define AVL_LNT 12
#define AVL_LNT 12
/* Erase packet - min size */
#define ERS_LNT 12
#define ERS_LNT 12
/* Erase gap - min size */
#define ERG_LNT 12
#define ERG_LNT 12
/* Flush - 10 W status (8 undefined) */
#define FLU_LNT 32
/* 8 - 15 /* reserved */
#define FLU_POSL 16 /* position */
#define FLU_POSH 17
#define FLU_LNT 32
/* 8 - 15 /* reserved */
#define FLU_POSL 16 /* position */
#define FLU_POSH 17
/* Write tape mark - 10W status (8 undefined) */
#define WTM_LNT 32
/* 8 - 15 /* reserved */
#define WTM_POSL 16 /* position */
#define WTM_POSH 17
#define WTM_LNT 32
/* 8 - 15 /* reserved */
#define WTM_POSL 16 /* position */
#define WTM_POSH 17
/* Get command status packet - 2 W parameter, 4 W status */
#define GCS_LNT 20
#define GCS_REFL 8 /* ref # */
#define GCS_REFH 9
#define GCS_STSL 10 /* status */
#define GCS_STSH 11
#define GCS_LNT 20
#define GCS_REFL 8 /* ref # */
#define GCS_REFH 9
#define GCS_STSL 10 /* status */
#define GCS_STSH 11
/* Format packet - 8 W parameters, none returned */
#define FMT_LNT 12
#define FMT_IH 17 /* magic bit */
#define FMT_LNT 12
#define FMT_IH 17 /* magic bit */
/* Get unit status packet - 18 W status (disk), 16W status (tape) */
#define GUS_LNT_D 48
#define GUS_LNT_T 44
#define GUS_MLUN 8 /* mlun */
#define GUS_UFL 9 /* flags */
#define GUS_RSVL 10 /* reserved */
#define GUS_RSVH 11
#define GUS_UIDA 12 /* unit ID */
#define GUS_UIDB 13
#define GUS_UIDC 14
#define GUS_UIDD 15
#define GUS_MEDL 16 /* media ID */
#define GUS_MEDH 17
#define GUS_UVER 23 /* unit version */
#define GUS_LNT_D 48
#define GUS_LNT_T 44
#define GUS_MLUN 8 /* mlun */
#define GUS_UFL 9 /* flags */
#define GUS_RSVL 10 /* reserved */
#define GUS_RSVH 11
#define GUS_UIDA 12 /* unit ID */
#define GUS_UIDB 13
#define GUS_UIDC 14
#define GUS_UIDD 15
#define GUS_MEDL 16 /* media ID */
#define GUS_MEDH 17
#define GUS_UVER 23 /* unit version */
/* Disk specific status */
#define GUS_SHUN 18 /* shadowing */
#define GUS_SHST 19
#define GUS_TRK 20 /* track */
#define GUS_GRP 21 /* group */
#define GUS_CYL 22 /* cylinder */
#define GUS_RCTS 24 /* RCT size */
#define GUS_RBSC 25 /* RBNs, copies */
#define GUS_SHUN 18 /* shadowing */
#define GUS_SHST 19
#define GUS_TRK 20 /* track */
#define GUS_GRP 21 /* group */
#define GUS_CYL 22 /* cylinder */
#define GUS_RCTS 24 /* RCT size */
#define GUS_RBSC 25 /* RBNs, copies */
/* Tape specific status */
#define GUS_FMT 18 /* format */
#define GUS_SPEED 19 /* speed */
#define GUS_MENU 20 /* menu */
#define GUS_CAP 21 /* capacity */
#define GUS_FVER 22 /* fmtr version */
#define GUS_FMT 18 /* format */
#define GUS_SPEED 19 /* speed */
#define GUS_MENU 20 /* menu */
#define GUS_CAP 21 /* capacity */
#define GUS_FVER 22 /* fmtr version */
#define GUS_UIDD_V_MOD 0 /* unit model */
#define GUS_UIDD_V_CLS 8 /* unit class */
#define GUS_RB_V_RBNS 0 /* RBNs/track */
#define GUS_RB_V_RCTC 8 /* RCT copies */
#define GUS_UIDD_V_MOD 0 /* unit model */
#define GUS_UIDD_V_CLS 8 /* unit class */
#define GUS_RB_V_RBNS 0 /* RBNs/track */
#define GUS_RB_V_RCTC 8 /* RCT copies */
/* Unit online - 2 W parameter, 16 W status (disk or tape) */
#define ONL_LNT 44
#define ONL_MLUN 8 /* mlun */
#define ONL_UFL 9 /* flags */
#define ONL_RSVL 10 /* reserved */
#define ONL_RSVH 11
#define ONL_UIDA 12 /* unit ID */
#define ONL_UIDB 13
#define ONL_UIDC 14
#define ONL_UIDD 15
#define ONL_MEDL 16 /* media ID */
#define ONL_MEDH 17
#define ONL_LNT 44
#define ONL_MLUN 8 /* mlun */
#define ONL_UFL 9 /* flags */
#define ONL_RSVL 10 /* reserved */
#define ONL_RSVH 11
#define ONL_UIDA 12 /* unit ID */
#define ONL_UIDB 13
#define ONL_UIDC 14
#define ONL_UIDD 15
#define ONL_MEDL 16 /* media ID */
#define ONL_MEDH 17
/* Disk specific status */
#define ONL_SHUN 18 /* shadowing */
#define ONL_SHST 19
#define ONL_SIZL 20 /* size */
#define ONL_SIZH 21
#define ONL_VSNL 22 /* vol ser # */
#define ONL_VSNH 23
#define ONL_SHUN 18 /* shadowing */
#define ONL_SHST 19
#define ONL_SIZL 20 /* size */
#define ONL_SIZH 21
#define ONL_VSNL 22 /* vol ser # */
#define ONL_VSNH 23
/* Tape specific status */
#define ONL_FMT 18 /* format */
#define ONL_SPD 19 /* speed */
#define ONL_MAXL 20 /* max rec size */
#define ONL_MAXH 21
#define ONL_NREC 22 /* noise rec */
#define ONL_RSVE 23 /* reserved */
#define ONL_FMT 18 /* format */
#define ONL_SPD 19 /* speed */
#define ONL_MAXL 20 /* max rec size */
#define ONL_MAXH 21
#define ONL_NREC 22 /* noise rec */
#define ONL_RSVE 23 /* reserved */
#define ONL_UIDD_V_MOD 0 /* unit model */
#define ONL_UIDD_V_CLS 8 /* unit class */
#define ONL_UIDD_V_MOD 0 /* unit model */
#define ONL_UIDD_V_CLS 8 /* unit class */
/* Set controller characteristics packet - 8 W parameters, 10 W status */
#define SCC_LNT 32
#define SCC_MSV 8 /* MSCP version */
#define SCC_CFL 9 /* flags */
#define SCC_TMO 10 /* timeout */
#define SCC_VER 11 /* ctrl version */
#define SCC_CIDA 12 /* ctrl ID */
#define SCC_CIDB 13
#define SCC_CIDC 14
#define SCC_CIDD 15
#define SCC_MBCL 16 /* max byte count */
#define SCC_MBCH 17
#define SCC_LNT 32
#define SCC_MSV 8 /* MSCP version */
#define SCC_CFL 9 /* flags */
#define SCC_TMO 10 /* timeout */
#define SCC_VER 11 /* ctrl version */
#define SCC_CIDA 12 /* ctrl ID */
#define SCC_CIDB 13
#define SCC_CIDC 14
#define SCC_CIDD 15
#define SCC_MBCL 16 /* max byte count */
#define SCC_MBCH 17
#define SCC_VER_V_SVER 0 /* swre vrsn */
#define SCC_VER_V_HVER 8 /* hwre vrsn */
#define SCC_CIDD_V_MOD 0 /* ctrl model */
#define SCC_CIDD_V_CLS 8 /* ctrl class */
#define SCC_VER_V_SVER 0 /* swre vrsn */
#define SCC_VER_V_HVER 8 /* hwre vrsn */
#define SCC_CIDD_V_MOD 0 /* ctrl model */
#define SCC_CIDD_V_CLS 8 /* ctrl class */
/* Set unit characteristics - 2 W parameter, 16 W status - same as ONL */
#define SUC_LNT 44
#define SUC_LNT 44
/* Reposition - 4 W parameters, 10 W status */
#define POS_LNT 32
#define POS_RCL 8 /* record cnt */
#define POS_RCH 9
#define POS_TMCL 10 /* tape mk cnt */
#define POS_TMCH 11
/* reserved 12 - 15 */
#define POS_POSL 16 /* position */
#define POS_POSH 17
#define POS_LNT 32
#define POS_RCL 8 /* record cnt */
#define POS_RCH 9
#define POS_TMCL 10 /* tape mk cnt */
#define POS_TMCH 11
/* reserved 12 - 15 */
#define POS_POSL 16 /* position */
#define POS_POSH 17
/* Data transfer packet - 10 W parameters (disk), 6W parameters (tape),
10 W status (disk), 12W status (tape) */
#define RW_LNT_D 32
#define RW_LNT_T 36
#define RW_BCL 8 /* byte count */
#define RW_BCH 9
#define RW_BAL 10 /* buff desc */
#define RW_BAH 11
#define RW_MAPL 12 /* map table */
#define RW_MAPH 13
/* 14 /* reserved */
/* 15 /* reserved */
#define RW_LNT_D 32
#define RW_LNT_T 36
#define RW_BCL 8 /* byte count */
#define RW_BCH 9
#define RW_BAL 10 /* buff desc */
#define RW_BAH 11
#define RW_MAPL 12 /* map table */
#define RW_MAPH 13
/* 14 /* reserved */
/* 15 /* reserved */
/* Disk specific parameters */
#define RW_LBNL 16 /* LBN */
#define RW_LBNH 17
#define RW_WBCL 18 /* working bc */
#define RW_WBCH 19
#define RW_WBAL 20 /* working ba */
#define RW_WBAH 21
#define RW_WBLL 22 /* working lbn */
#define RW_WBLH 23
#define RW_LBNL 16 /* LBN */
#define RW_LBNH 17
#define RW_WBCL 18 /* working bc */
#define RW_WBCH 19
#define RW_WBAL 20 /* working ba */
#define RW_WBAH 21
#define RW_WBLL 22 /* working lbn */
#define RW_WBLH 23
/* Tape specific status */
#define RW_POSL 16 /* position */
#define RW_POSH 17
#define RW_RSZL 18 /* record size */
#define RW_RSZH 19
#define RW_POSL 16 /* position */
#define RW_POSH 17
#define RW_RSZL 18 /* record size */
#define RW_RSZH 19
/* Error log packet header */
#define ELP_REFL 2 /* ref # */
#define ELP_REFH 3
#define ELP_UN 4 /* unit */
#define ELP_SEQ 5
#define ELP_FF 6 /* fmt,flg */
#define ELP_EVT 7 /* event */
#define ELP_REFL 2 /* ref # */
#define ELP_REFH 3
#define ELP_UN 4 /* unit */
#define ELP_SEQ 5
#define ELP_FF 6 /* fmt,flg */
#define ELP_EVT 7 /* event */
#define ELP_EV_V_FMT 0 /* format */
#define ELP_EV_V_FLG 8 /* flag */
#define ELP_EV_V_FMT 0 /* format */
#define ELP_EV_V_FLG 8 /* flag */
/* Port last failure error log packet - 6 W status */
#define PLF_LNT 24 /* length */
#define PLF_CIDA 8 /* ctrl ID */
#define PLF_CIDB 9
#define PLF_CIDC 10
#define PLF_CIDD 11
#define PLF_VER 12 /* ctrl version */
#define PLF_ERR 13 /* err */
#define PLF_LNT 24 /* length */
#define PLF_CIDA 8 /* ctrl ID */
#define PLF_CIDB 9
#define PLF_CIDC 10
#define PLF_CIDD 11
#define PLF_VER 12 /* ctrl version */
#define PLF_ERR 13 /* err */
#define PLF_CIDD_V_MOD 0 /* ctrl model */
#define PLF_CIDD_V_CLS 8 /* ctrl class */
#define PLF_VER_V_SVER 0 /* swre ver */
#define PLF_VER_V_HVER 8 /* hwre ver */
#define PLF_CIDD_V_MOD 0 /* ctrl model */
#define PLF_CIDD_V_CLS 8 /* ctrl class */
#define PLF_VER_V_SVER 0 /* swre ver */
#define PLF_VER_V_HVER 8 /* hwre ver */
/* Disk transfer error log packet - 18 W status */
#define DTE_LNT 48
#define DTE_CIDA 8 /* ctrl ID */
#define DTE_CIDB 9
#define DTE_CIDC 10
#define DTE_CIDD 11
#define DTE_VER 12 /* version */
#define DTE_MLUN 13 /* mlun */
#define DTE_UIDA 14 /* unit ID */
#define DTE_UIDB 15
#define DTE_UIDC 16
#define DTE_UIDD 17
#define DTE_UVER 18
#define DTE_D2 23
#define DTE_D3 24
#define DTE_D4 25
#define DTE_LNT 48
#define DTE_CIDA 8 /* ctrl ID */
#define DTE_CIDB 9
#define DTE_CIDC 10
#define DTE_CIDD 11
#define DTE_VER 12 /* version */
#define DTE_MLUN 13 /* mlun */
#define DTE_UIDA 14 /* unit ID */
#define DTE_UIDB 15
#define DTE_UIDC 16
#define DTE_UIDD 17
#define DTE_UVER 18
#define DTE_D2 23
#define DTE_D3 24
#define DTE_D4 25
/* Disk specific status */
#define DTE_SCYL 19 /* cylinder */
#define DTE_VSNL 20 /* vol ser # */
#define DTE_VSNH 21
#define DTE_D1 22 /* dev params */
#define DTE_SCYL 19 /* cylinder */
#define DTE_VSNL 20 /* vol ser # */
#define DTE_VSNH 21
#define DTE_D1 22 /* dev params */
/* Tape specific status */
#define DTE_RETR 19 /* retry */
#define DTE_POSL 20 /* position */
#define DTE_POSH 21
#define DTE_FVER 22 /* formatter ver */
#define DTE_RETR 19 /* retry */
#define DTE_POSL 20 /* position */
#define DTE_POSH 21
#define DTE_FVER 22 /* formatter ver */
#define DTE_CIDD_V_MOD 0 /* ctrl model */
#define DTE_CIDD_V_CLS 8 /* ctrl class */
#define DTE_VER_V_SVER 0 /* ctrl swre ver */
#define DTE_VER_V_HVER 8 /* ctrl hwre ver */
#define DTE_UIDD_V_MOD 0 /* unit model */
#define DTE_UIDD_V_CLS 8 /* unit class */
#define DTE_D2_V_SECT 8
#define DTE_D3_V_SURF 0
#define DTE_D3_V_CYL 8
#define DTE_CIDD_V_MOD 0 /* ctrl model */
#define DTE_CIDD_V_CLS 8 /* ctrl class */
#define DTE_VER_V_SVER 0 /* ctrl swre ver */
#define DTE_VER_V_HVER 8 /* ctrl hwre ver */
#define DTE_UIDD_V_MOD 0 /* unit model */
#define DTE_UIDD_V_CLS 8 /* unit class */
#define DTE_D2_V_SECT 8
#define DTE_D3_V_SURF 0
#define DTE_D3_V_CYL 8
/* Host bus error log packet - 8 W status */
#define HBE_LNT 28
#define HBE_CIDA 8 /* ctrl ID */
#define HBE_CIDB 9
#define HBE_CIDC 10
#define HBE_CIDD 11
#define HBE_VER 12 /* ctrl version */
#define HBE_RSV 13 /* reserved */
#define HBE_BADL 14 /* bad address */
#define HBE_BADH 15
#define HBE_LNT 28
#define HBE_CIDA 8 /* ctrl ID */
#define HBE_CIDB 9
#define HBE_CIDC 10
#define HBE_CIDD 11
#define HBE_VER 12 /* ctrl version */
#define HBE_RSV 13 /* reserved */
#define HBE_BADL 14 /* bad address */
#define HBE_BADH 15
#define HBE_CIDD_V_MOD 0 /* ctrl model */
#define HBE_CIDD_V_CLS 8 /* ctrl class */
#define HBE_VER_V_SVER 0 /* ctrl swre ver */
#define HBE_VER_V_HVER 8 /* ctrl hwre ver */
#define HBE_CIDD_V_MOD 0 /* ctrl model */
#define HBE_CIDD_V_CLS 8 /* ctrl class */
#define HBE_VER_V_SVER 0 /* ctrl swre ver */
#define HBE_VER_V_HVER 8 /* ctrl hwre ver */
/* Unit now available attention message - 10 W status, same as
first 10 W of status from get unit status
*/
#define UNA_LNT 32
#define UNA_LNT 32
#endif

View File

@@ -1,6 +1,6 @@
/* pdp11_pclk.c: KW11P programmable clock simulator
Copyright (c) 1993-2004, Robert M Supnik
Copyright (c) 1993-2005, Robert M Supnik
Written by John Dundas, used with his gracious permission
Permission is hereby granted, free of charge, to any person obtaining a
@@ -20,24 +20,25 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not 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.
pclk KW11P line frequency clock
*/
pclk KW11P line frequency clock
/* KW11-P Programmable Clock
07-Jul-05 RMS Removed extraneous externs
KW11-P Programmable Clock
I/O Page Registers:
CSR 17 772 540
CSB 17 772 542
CNT 17 772 544
CSR 17 772 540
CSB 17 772 542
CNT 17 772 544
Vector: 0104
Vector: 0104
Priority: BR6
Priority: BR6
** Theory of Operation **
@@ -59,11 +60,11 @@
as well as the desired clock ticking rate. Possible rates are
given in the table below.
Rate Bit 2 Bit 1
100 kHz 0 0
10 kHz 0 1
Line frequency 1 0
External 1 1
Rate Bit 2 Bit 1
100 kHz 0 0
10 kHz 0 1
Line frequency 1 0
External 1 1
I think SIMH would have a hard time actually keeping up with a 100
kHz ticking rate. I haven't tried this to verify, though.
@@ -107,32 +108,31 @@
#include "pdp11_defs.h"
#define PCLKCSR_RDMASK 0100377 /* readable */
#define PCLKCSR_WRMASK 0000137 /* writeable */
#define PCLKCSR_RDMASK 0100377 /* readable */
#define PCLKCSR_WRMASK 0000137 /* writeable */
#define UNIT_V_LINE50HZ (UNIT_V_UF + 0)
#define UNIT_LINE50HZ (1 << UNIT_V_LINE50HZ)
#define UNIT_V_LINE50HZ (UNIT_V_UF + 0)
#define UNIT_LINE50HZ (1 << UNIT_V_LINE50HZ)
/* CSR - 17772540 */
#define CSR_V_FIX 5 /* single tick */
#define CSR_V_UPDN 4 /* down/up */
#define CSR_V_MODE 3 /* single/repeat */
#define CSR_FIX (1u << CSR_V_FIX)
#define CSR_UPDN (1u << CSR_V_UPDN)
#define CSR_MODE (1u << CSR_V_MODE)
#define CSR_V_RATE 1 /* rate */
#define CSR_M_RATE 03
#define CSR_GETRATE(x) (((x) >> CSR_V_RATE) & CSR_M_RATE)
#define CSR_V_FIX 5 /* single tick */
#define CSR_V_UPDN 4 /* down/up */
#define CSR_V_MODE 3 /* single/repeat */
#define CSR_FIX (1u << CSR_V_FIX)
#define CSR_UPDN (1u << CSR_V_UPDN)
#define CSR_MODE (1u << CSR_V_MODE)
#define CSR_V_RATE 1 /* rate */
#define CSR_M_RATE 03
#define CSR_GETRATE(x) (((x) >> CSR_V_RATE) & CSR_M_RATE)
extern int32 int_req[IPL_HLVL];
extern int32 int_vec[IPL_HLVL][32];
uint32 pclk_csr = 0; /* control/status */
uint32 pclk_csb = 0; /* count set buffer */
uint32 pclk_ctr = 0; /* counter */
static uint32 rate[4] = { 100000, 10000, 60, 10 }; /* ticks per second */
static uint32 xtim[4] = { 10, 100, 16000, 100000 }; /* nominal time delay */
uint32 pclk_csr = 0; /* control/status */
uint32 pclk_csb = 0; /* count set buffer */
uint32 pclk_ctr = 0; /* counter */
static uint32 rate[4] = { 100000, 10000, 60, 10 }; /* ticks per second */
static uint32 xtim[4] = { 10, 100, 16000, 100000 }; /* nominal time delay */
DEVICE pclk_dev;
t_stat pclk_rd (int32 *data, int32 PA, int32 access);
@@ -141,69 +141,79 @@ t_stat pclk_svc (UNIT *uptr);
t_stat pclk_reset (DEVICE *dptr);
t_stat pclk_set_line (UNIT *uptr, int32 val, char *cptr, void *desc);
void pclk_tick (void);
/* PCLK data structures
pclk_dev PCLK device descriptor
pclk_unit PCLK unit descriptor
pclk_reg PCLK register list
pclk_dev PCLK device descriptor
pclk_unit PCLK unit descriptor
pclk_reg PCLK register list
*/
DIB pclk_dib = { IOBA_PCLK, IOLN_PCLK, &pclk_rd, &pclk_wr,
1, IVCL (PCLK), VEC_PCLK, { NULL } };
DIB pclk_dib = {
IOBA_PCLK, IOLN_PCLK, &pclk_rd, &pclk_wr,
1, IVCL (PCLK), VEC_PCLK, { NULL }
};
UNIT pclk_unit = { UDATA (&pclk_svc, 0, 0) };
REG pclk_reg[] = {
{ ORDATA (CSR, pclk_csr, 16) },
{ ORDATA (CSB, pclk_csb, 16) },
{ ORDATA (CNT, pclk_ctr, 16) },
{ FLDATA (INT, IREQ (PCLK), INT_V_PCLK) },
{ FLDATA (OVFL, pclk_csr, CSR_V_ERR) },
{ FLDATA (DONE, pclk_csr, CSR_V_DONE) },
{ FLDATA (IE, pclk_csr, CSR_V_IE) },
{ FLDATA (UPDN, pclk_csr, CSR_V_UPDN) },
{ FLDATA (MODE, pclk_csr, CSR_V_MODE) },
{ FLDATA (RUN, pclk_csr, CSR_V_GO) },
{ BRDATA (TIME, xtim, 10, 32, 4), REG_NZ + PV_LEFT },
{ BRDATA (TPS, rate, 10, 32, 4), REG_NZ + PV_LEFT },
{ DRDATA (CURTIM, pclk_unit.wait, 32), REG_HRO },
{ ORDATA (DEVADDR, pclk_dib.ba, 32), REG_HRO },
{ ORDATA (DEVVEC, pclk_dib.vec, 16), REG_HRO },
{ NULL } };
{ ORDATA (CSR, pclk_csr, 16) },
{ ORDATA (CSB, pclk_csb, 16) },
{ ORDATA (CNT, pclk_ctr, 16) },
{ FLDATA (INT, IREQ (PCLK), INT_V_PCLK) },
{ FLDATA (OVFL, pclk_csr, CSR_V_ERR) },
{ FLDATA (DONE, pclk_csr, CSR_V_DONE) },
{ FLDATA (IE, pclk_csr, CSR_V_IE) },
{ FLDATA (UPDN, pclk_csr, CSR_V_UPDN) },
{ FLDATA (MODE, pclk_csr, CSR_V_MODE) },
{ FLDATA (RUN, pclk_csr, CSR_V_GO) },
{ BRDATA (TIME, xtim, 10, 32, 4), REG_NZ + PV_LEFT },
{ BRDATA (TPS, rate, 10, 32, 4), REG_NZ + PV_LEFT },
{ DRDATA (CURTIM, pclk_unit.wait, 32), REG_HRO },
{ ORDATA (DEVADDR, pclk_dib.ba, 32), REG_HRO },
{ ORDATA (DEVVEC, pclk_dib.vec, 16), REG_HRO },
{ NULL }
};
MTAB pclk_mod[] = {
{ UNIT_LINE50HZ, UNIT_LINE50HZ, "50 Hz", "50HZ", &pclk_set_line },
{ UNIT_LINE50HZ, 0, "60 Hz", "60HZ", &pclk_set_line },
{ MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL,
NULL, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR",
&set_vec, &show_vec, NULL },
{ 0 } };
{ UNIT_LINE50HZ, UNIT_LINE50HZ, "50 Hz", "50HZ", &pclk_set_line },
{ UNIT_LINE50HZ, 0, "60 Hz", "60HZ", &pclk_set_line },
{ MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL,
NULL, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR",
&set_vec, &show_vec, NULL },
{ 0 }
};
DEVICE pclk_dev = {
"PCLK", &pclk_unit, pclk_reg, pclk_mod,
1, 0, 0, 0, 0, 0,
NULL, NULL, &pclk_reset,
NULL, NULL, NULL,
&pclk_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS };
"PCLK", &pclk_unit, pclk_reg, pclk_mod,
1, 0, 0, 0, 0, 0,
NULL, NULL, &pclk_reset,
NULL, NULL, NULL,
&pclk_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS
};
/* Clock I/O address routines */
t_stat pclk_rd (int32 *data, int32 PA, int32 access)
{
switch ((PA >> 1) & 03) {
case 00: /* CSR */
*data = pclk_csr & PCLKCSR_RDMASK; /* return CSR */
pclk_csr = pclk_csr & ~(CSR_ERR | CSR_DONE); /* clr err, done */
CLR_INT (PCLK); /* clr intr */
break;
case 01: /* buffer */
*data = 0; /* read only */
break;
case 02: /* counter */
*data = pclk_ctr & DMASK; /* return counter */
break; }
case 00: /* CSR */
*data = pclk_csr & PCLKCSR_RDMASK; /* return CSR */
pclk_csr = pclk_csr & ~(CSR_ERR | CSR_DONE); /* clr err, done */
CLR_INT (PCLK); /* clr intr */
break;
case 01: /* buffer */
*data = 0; /* read only */
break;
case 02: /* counter */
*data = pclk_ctr & DMASK; /* return counter */
break;
}
return SCPE_OK;
}
@@ -213,28 +223,34 @@ int32 old_csr = pclk_csr;
int32 rv;
switch ((PA >> 1) & 03) {
case 00: /* CSR */
pclk_csr = data & PCLKCSR_WRMASK; /* clear and write */
CLR_INT (PCLK); /* clr intr */
rv = CSR_GETRATE (pclk_csr); /* new rate */
pclk_unit.wait = xtim[rv]; /* new delay */
if ((pclk_csr & CSR_GO) == 0) { /* stopped? */
sim_cancel (&pclk_unit); /* cancel */
if (data & CSR_FIX) pclk_tick (); } /* fix? tick */
else if (((old_csr & CSR_GO) == 0) || /* run 0 -> 1? */
(rv != CSR_GETRATE (old_csr))) { /* rate change? */
sim_cancel (&pclk_unit); /* cancel */
sim_activate (&pclk_unit, /* start clock */
sim_rtcn_init (pclk_unit.wait, TMR_PCLK));
}
break;
case 01: /* buffer */
pclk_csb = pclk_ctr = data; /* store ctr */
pclk_csr = pclk_csr & ~(CSR_ERR | CSR_DONE); /* clr err, done */
CLR_INT (PCLK); /* clr intr */
break;
case 02: /* counter */
break; } /* read only */
case 00: /* CSR */
pclk_csr = data & PCLKCSR_WRMASK; /* clear and write */
CLR_INT (PCLK); /* clr intr */
rv = CSR_GETRATE (pclk_csr); /* new rate */
pclk_unit.wait = xtim[rv]; /* new delay */
if ((pclk_csr & CSR_GO) == 0) { /* stopped? */
sim_cancel (&pclk_unit); /* cancel */
if (data & CSR_FIX) pclk_tick (); /* fix? tick */
}
else if (((old_csr & CSR_GO) == 0) || /* run 0 -> 1? */
(rv != CSR_GETRATE (old_csr))) { /* rate change? */
sim_cancel (&pclk_unit); /* cancel */
sim_activate (&pclk_unit, /* start clock */
sim_rtcn_init (pclk_unit.wait, TMR_PCLK));
}
break;
case 01: /* buffer */
pclk_csb = pclk_ctr = data; /* store ctr */
pclk_csr = pclk_csr & ~(CSR_ERR | CSR_DONE); /* clr err, done */
CLR_INT (PCLK); /* clr intr */
break;
case 02: /* counter */
break; /* read only */
}
return SCPE_OK;
}
@@ -242,18 +258,20 @@ return SCPE_OK;
void pclk_tick (void)
{
if (pclk_csr & CSR_UPDN) /* up or down? */
pclk_ctr = (pclk_ctr + 1) & DMASK; /* 1 = up */
else pclk_ctr = (pclk_ctr - 1) & DMASK; /* 0 = down */
if (pclk_ctr == 0) { /* reached zero? */
if (pclk_csr & CSR_DONE) /* done already set? */
pclk_csr = pclk_csr | CSR_ERR; /* set error */
else pclk_csr = pclk_csr | CSR_DONE; /* else set done */
if (pclk_csr & CSR_IE) SET_INT (PCLK); /* if IE, set int */
if (pclk_csr & CSR_MODE) pclk_ctr = pclk_csb; /* if rpt, reload */
else {
pclk_csb = 0; /* else clr ctr */
pclk_csr = pclk_csr & ~CSR_GO; } } /* and clr go */
if (pclk_csr & CSR_UPDN) /* up or down? */
pclk_ctr = (pclk_ctr + 1) & DMASK; /* 1 = up */
else pclk_ctr = (pclk_ctr - 1) & DMASK; /* 0 = down */
if (pclk_ctr == 0) { /* reached zero? */
if (pclk_csr & CSR_DONE) /* done already set? */
pclk_csr = pclk_csr | CSR_ERR; /* set error */
else pclk_csr = pclk_csr | CSR_DONE; /* else set done */
if (pclk_csr & CSR_IE) SET_INT (PCLK); /* if IE, set int */
if (pclk_csr & CSR_MODE) pclk_ctr = pclk_csb; /* if rpt, reload */
else {
pclk_csb = 0; /* else clr ctr */
pclk_csr = pclk_csr & ~CSR_GO; /* and clr go */
}
}
return;
}
@@ -263,9 +281,9 @@ t_stat pclk_svc (UNIT *uptr)
{
int32 rv;
pclk_tick (); /* tick clock */
if ((pclk_csr & CSR_GO) == 0) return SCPE_OK; /* done? */
rv = CSR_GETRATE (pclk_csr); /* get rate */
pclk_tick (); /* tick clock */
if ((pclk_csr & CSR_GO) == 0) return SCPE_OK; /* done? */
rv = CSR_GETRATE (pclk_csr); /* get rate */
sim_activate (&pclk_unit, sim_rtcn_calb (rate[rv], TMR_PCLK));
return SCPE_OK;
}
@@ -274,12 +292,12 @@ return SCPE_OK;
t_stat pclk_reset (DEVICE *dptr)
{
pclk_csr = 0; /* clear reg */
pclk_csr = 0; /* clear reg */
pclk_csb = 0;
pclk_ctr = 0;
CLR_INT (PCLK); /* clear int */
sim_cancel (&pclk_unit); /* cancel */
pclk_unit.wait = xtim[0]; /* reset delay */
CLR_INT (PCLK); /* clear int */
sim_cancel (&pclk_unit); /* cancel */
pclk_unit.wait = xtim[0]; /* reset delay */
return SCPE_OK;
}

View File

@@ -1,6 +1,6 @@
/* pdp11_pt.c: PC11 paper tape reader/punch simulator
Copyright (c) 1993-2004, Robert M Supnik
Copyright (c) 1993-2005, 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"),
@@ -19,46 +19,44 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not 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.
ptr paper tape reader
ptp paper tape punch
ptr paper tape reader
ptp paper tape punch
19-May-03 RMS Revised for new conditional compilation scheme
25-Apr-03 RMS Revised for extended file support
12-Sep-02 RMS Split off from pdp11_stddev.c
07-Jul-05 RMS Removed extraneous externs
19-May-03 RMS Revised for new conditional compilation scheme
25-Apr-03 RMS Revised for extended file support
12-Sep-02 RMS Split off from pdp11_stddev.c
*/
#if defined (VM_PDP10) /* PDP10 version */
#if defined (VM_PDP10) /* PDP10 version */
#include "pdp10_defs.h"
#define PT_DIS DEV_DIS
#define PT_DIS DEV_DIS
extern int32 int_req;
extern int32 int_vec[32];
#elif defined (VM_VAX) /* VAX version */
#elif defined (VM_VAX) /* VAX version */
#include "vax_defs.h"
#define PT_DIS DEV_DIS
#define PT_DIS DEV_DIS
extern int32 int_req[IPL_HLVL];
extern int32 int_vec[IPL_HLVL][32];
#else /* PDP-11 version */
#else /* PDP-11 version */
#include "pdp11_defs.h"
#define PT_DIS 0
#define PT_DIS 0
extern int32 int_req[IPL_HLVL];
extern int32 int_vec[IPL_HLVL][32];
#endif
#define PTRCSR_IMP (CSR_ERR+CSR_BUSY+CSR_DONE+CSR_IE) /* paper tape reader */
#define PTRCSR_RW (CSR_IE)
#define PTPCSR_IMP (CSR_ERR + CSR_DONE + CSR_IE) /* paper tape punch */
#define PTPCSR_RW (CSR_IE)
#define PTRCSR_IMP (CSR_ERR+CSR_BUSY+CSR_DONE+CSR_IE) /* paper tape reader */
#define PTRCSR_RW (CSR_IE)
#define PTPCSR_IMP (CSR_ERR + CSR_DONE + CSR_IE) /* paper tape punch */
#define PTPCSR_RW (CSR_IE)
int32 ptr_csr = 0; /* control/status */
int32 ptr_stopioe = 0; /* stop on error */
int32 ptp_csr = 0; /* control/status */
int32 ptp_stopioe = 0; /* stop on error */
int32 ptr_csr = 0; /* control/status */
int32 ptr_stopioe = 0; /* stop on error */
int32 ptp_csr = 0; /* control/status */
int32 ptp_stopioe = 0; /* stop on error */
DEVICE ptr_dev, ptp_dev;
t_stat ptr_rd (int32 *data, int32 PA, int32 access);
@@ -73,123 +71,144 @@ t_stat ptp_svc (UNIT *uptr);
t_stat ptp_reset (DEVICE *dptr);
t_stat ptp_attach (UNIT *uptr, char *ptr);
t_stat ptp_detach (UNIT *uptr);
/* PTR data structures
ptr_dev PTR device descriptor
ptr_unit PTR unit descriptor
ptr_reg PTR register list
ptr_dev PTR device descriptor
ptr_unit PTR unit descriptor
ptr_reg PTR register list
*/
DIB ptr_dib = { IOBA_PTR, IOLN_PTR, &ptr_rd, &ptr_wr,
1, IVCL (PTR), VEC_PTR, { NULL } };
DIB ptr_dib = {
IOBA_PTR, IOLN_PTR, &ptr_rd, &ptr_wr,
1, IVCL (PTR), VEC_PTR, { NULL }
};
UNIT ptr_unit = {
UDATA (&ptr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0),
SERIAL_IN_WAIT };
UDATA (&ptr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0),
SERIAL_IN_WAIT
};
REG ptr_reg[] = {
{ GRDATA (BUF, ptr_unit.buf, DEV_RDX, 8, 0) },
{ GRDATA (CSR, ptr_csr, DEV_RDX, 16, 0) },
{ FLDATA (INT, int_req, INT_V_PTR) },
{ FLDATA (ERR, ptr_csr, CSR_V_ERR) },
{ FLDATA (BUSY, ptr_csr, CSR_V_BUSY) },
{ FLDATA (DONE, ptr_csr, CSR_V_DONE) },
{ FLDATA (IE, ptr_csr, CSR_V_IE) },
{ DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, ptr_stopioe, 0) },
{ FLDATA (DEVDIS, ptr_dev.flags, DEV_V_DIS), REG_HRO },
{ NULL } };
{ GRDATA (BUF, ptr_unit.buf, DEV_RDX, 8, 0) },
{ GRDATA (CSR, ptr_csr, DEV_RDX, 16, 0) },
{ FLDATA (INT, int_req, INT_V_PTR) },
{ FLDATA (ERR, ptr_csr, CSR_V_ERR) },
{ FLDATA (BUSY, ptr_csr, CSR_V_BUSY) },
{ FLDATA (DONE, ptr_csr, CSR_V_DONE) },
{ FLDATA (IE, ptr_csr, CSR_V_IE) },
{ DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, ptr_stopioe, 0) },
{ FLDATA (DEVDIS, ptr_dev.flags, DEV_V_DIS), REG_HRO },
{ NULL }
};
MTAB ptr_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL,
NULL, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL,
NULL, &show_vec, NULL },
{ 0 } };
{ MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL,
NULL, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL,
NULL, &show_vec, NULL },
{ 0 }
};
DEVICE ptr_dev = {
"PTR", &ptr_unit, ptr_reg, ptr_mod,
1, 10, 31, 1, DEV_RDX, 8,
NULL, NULL, &ptr_reset,
NULL, &ptr_attach, &ptr_detach,
&ptr_dib, DEV_DISABLE | PT_DIS | DEV_UBUS | DEV_QBUS };
"PTR", &ptr_unit, ptr_reg, ptr_mod,
1, 10, 31, 1, DEV_RDX, 8,
NULL, NULL, &ptr_reset,
NULL, &ptr_attach, &ptr_detach,
&ptr_dib, DEV_DISABLE | PT_DIS | DEV_UBUS | DEV_QBUS
};
/* PTP data structures
ptp_dev PTP device descriptor
ptp_unit PTP unit descriptor
ptp_reg PTP register list
ptp_dev PTP device descriptor
ptp_unit PTP unit descriptor
ptp_reg PTP register list
*/
DIB ptp_dib = { IOBA_PTP, IOLN_PTP, &ptp_rd, &ptp_wr,
1, IVCL (PTP), VEC_PTP, { NULL } };
DIB ptp_dib = {
IOBA_PTP, IOLN_PTP, &ptp_rd, &ptp_wr,
1, IVCL (PTP), VEC_PTP, { NULL }
};
UNIT ptp_unit = {
UDATA (&ptp_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT };
UDATA (&ptp_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT
};
REG ptp_reg[] = {
{ GRDATA (BUF, ptp_unit.buf, DEV_RDX, 8, 0) },
{ GRDATA (CSR, ptp_csr, DEV_RDX, 16, 0) },
{ FLDATA (INT, int_req, INT_V_PTP) },
{ FLDATA (ERR, ptp_csr, CSR_V_ERR) },
{ FLDATA (DONE, ptp_csr, CSR_V_DONE) },
{ FLDATA (IE, ptp_csr, CSR_V_IE) },
{ DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, ptp_stopioe, 0) },
{ NULL } };
{ GRDATA (BUF, ptp_unit.buf, DEV_RDX, 8, 0) },
{ GRDATA (CSR, ptp_csr, DEV_RDX, 16, 0) },
{ FLDATA (INT, int_req, INT_V_PTP) },
{ FLDATA (ERR, ptp_csr, CSR_V_ERR) },
{ FLDATA (DONE, ptp_csr, CSR_V_DONE) },
{ FLDATA (IE, ptp_csr, CSR_V_IE) },
{ DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, ptp_stopioe, 0) },
{ NULL }
};
MTAB ptp_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL,
NULL, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL,
NULL, &show_vec, NULL },
{ 0 } };
{ MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL,
NULL, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL,
NULL, &show_vec, NULL },
{ 0 }
};
DEVICE ptp_dev = {
"PTP", &ptp_unit, ptp_reg, ptp_mod,
1, 10, 31, 1, DEV_RDX, 8,
NULL, NULL, &ptp_reset,
NULL, &ptp_attach, &ptp_detach,
&ptp_dib, DEV_DISABLE | PT_DIS | DEV_UBUS | DEV_QBUS };
"PTP", &ptp_unit, ptp_reg, ptp_mod,
1, 10, 31, 1, DEV_RDX, 8,
NULL, NULL, &ptp_reset,
NULL, &ptp_attach, &ptp_detach,
&ptp_dib, DEV_DISABLE | PT_DIS | DEV_UBUS | DEV_QBUS
};
/* Paper tape reader I/O address routines */
t_stat ptr_rd (int32 *data, int32 PA, int32 access)
{
switch ((PA >> 1) & 01) { /* decode PA<1> */
case 0: /* ptr csr */
*data = ptr_csr & PTRCSR_IMP;
return SCPE_OK;
case 1: /* ptr buf */
ptr_csr = ptr_csr & ~CSR_DONE;
CLR_INT (PTR);
*data = ptr_unit.buf & 0377;
return SCPE_OK; }
return SCPE_NXM; /* can't get here */
switch ((PA >> 1) & 01) { /* decode PA<1> */
case 0: /* ptr csr */
*data = ptr_csr & PTRCSR_IMP;
return SCPE_OK;
case 1: /* ptr buf */
ptr_csr = ptr_csr & ~CSR_DONE;
CLR_INT (PTR);
*data = ptr_unit.buf & 0377;
return SCPE_OK;
}
return SCPE_NXM; /* can't get here */
}
t_stat ptr_wr (int32 data, int32 PA, int32 access)
{
switch ((PA >> 1) & 01) { /* decode PA<1> */
case 0: /* ptr csr */
if (PA & 1) return SCPE_OK;
if ((data & CSR_IE) == 0) CLR_INT (PTR);
else if (((ptr_csr & CSR_IE) == 0) && (ptr_csr & (CSR_ERR | CSR_DONE)))
SET_INT (PTR);
if (data & CSR_GO) {
ptr_csr = (ptr_csr & ~CSR_DONE) | CSR_BUSY;
CLR_INT (PTR);
if (ptr_unit.flags & UNIT_ATT) /* data to read? */
sim_activate (&ptr_unit, ptr_unit.wait);
else sim_activate (&ptr_unit, 0); } /* error if not */
ptr_csr = (ptr_csr & ~PTRCSR_RW) | (data & PTRCSR_RW);
return SCPE_OK;
case 1: /* ptr buf */
return SCPE_OK; } /* end switch PA */
return SCPE_NXM; /* can't get here */
switch ((PA >> 1) & 01) { /* decode PA<1> */
case 0: /* ptr csr */
if (PA & 1) return SCPE_OK;
if ((data & CSR_IE) == 0) CLR_INT (PTR);
else if (((ptr_csr & CSR_IE) == 0) && (ptr_csr & (CSR_ERR | CSR_DONE)))
SET_INT (PTR);
if (data & CSR_GO) {
ptr_csr = (ptr_csr & ~CSR_DONE) | CSR_BUSY;
CLR_INT (PTR);
if (ptr_unit.flags & UNIT_ATT) /* data to read? */
sim_activate (&ptr_unit, ptr_unit.wait);
else sim_activate (&ptr_unit, 0); /* error if not */
}
ptr_csr = (ptr_csr & ~PTRCSR_RW) | (data & PTRCSR_RW);
return SCPE_OK;
case 1: /* ptr buf */
return SCPE_OK;
} /* end switch PA */
return SCPE_NXM; /* can't get here */
}
/* Paper tape reader service */
@@ -201,20 +220,22 @@ int32 temp;
ptr_csr = (ptr_csr | CSR_ERR) & ~CSR_BUSY;
if (ptr_csr & CSR_IE) SET_INT (PTR);
if ((ptr_unit.flags & UNIT_ATT) == 0)
return IORETURN (ptr_stopioe, SCPE_UNATT);
return IORETURN (ptr_stopioe, SCPE_UNATT);
if ((temp = getc (ptr_unit.fileref)) == EOF) {
if (feof (ptr_unit.fileref)) {
if (ptr_stopioe) printf ("PTR end of file\n");
else return SCPE_OK; }
else perror ("PTR I/O error");
clearerr (ptr_unit.fileref);
return SCPE_IOERR; }
if (feof (ptr_unit.fileref)) {
if (ptr_stopioe) printf ("PTR end of file\n");
else return SCPE_OK;
}
else perror ("PTR I/O error");
clearerr (ptr_unit.fileref);
return SCPE_IOERR;
}
ptr_csr = (ptr_csr | CSR_DONE) & ~CSR_ERR;
ptr_unit.buf = temp & 0377;
ptr_unit.pos = ptr_unit.pos + 1;
return SCPE_OK;
}
/* Paper tape reader support routines */
t_stat ptr_reset (DEVICE *dptr)
@@ -242,40 +263,48 @@ t_stat ptr_detach (UNIT *uptr)
ptr_csr = ptr_csr | CSR_ERR;
return detach_unit (uptr);
}
/* Paper tape punch I/O address routines */
t_stat ptp_rd (int32 *data, int32 PA, int32 access)
{
switch ((PA >> 1) & 01) { /* decode PA<1> */
case 0: /* ptp csr */
*data = ptp_csr & PTPCSR_IMP;
return SCPE_OK;
case 1: /* ptp buf */
*data = ptp_unit.buf;
return SCPE_OK; }
return SCPE_NXM; /* can't get here */
switch ((PA >> 1) & 01) { /* decode PA<1> */
case 0: /* ptp csr */
*data = ptp_csr & PTPCSR_IMP;
return SCPE_OK;
case 1: /* ptp buf */
*data = ptp_unit.buf;
return SCPE_OK;
}
return SCPE_NXM; /* can't get here */
}
t_stat ptp_wr (int32 data, int32 PA, int32 access)
{
switch ((PA >> 1) & 01) { /* decode PA<1> */
case 0: /* ptp csr */
if (PA & 1) return SCPE_OK;
if ((data & CSR_IE) == 0) CLR_INT (PTP);
else if (((ptp_csr & CSR_IE) == 0) && (ptp_csr & (CSR_ERR | CSR_DONE)))
SET_INT (PTP);
ptp_csr = (ptp_csr & ~PTPCSR_RW) | (data & PTPCSR_RW);
return SCPE_OK;
case 1: /* ptp buf */
if ((PA & 1) == 0) ptp_unit.buf = data & 0377;
ptp_csr = ptp_csr & ~CSR_DONE;
CLR_INT (PTP);
if (ptp_unit.flags & UNIT_ATT) /* file to write? */
sim_activate (&ptp_unit, ptp_unit.wait);
else sim_activate (&ptp_unit, 0); /* error if not */
return SCPE_OK; } /* end switch PA */
return SCPE_NXM; /* can't get here */
switch ((PA >> 1) & 01) { /* decode PA<1> */
case 0: /* ptp csr */
if (PA & 1) return SCPE_OK;
if ((data & CSR_IE) == 0) CLR_INT (PTP);
else if (((ptp_csr & CSR_IE) == 0) && (ptp_csr & (CSR_ERR | CSR_DONE)))
SET_INT (PTP);
ptp_csr = (ptp_csr & ~PTPCSR_RW) | (data & PTPCSR_RW);
return SCPE_OK;
case 1: /* ptp buf */
if ((PA & 1) == 0) ptp_unit.buf = data & 0377;
ptp_csr = ptp_csr & ~CSR_DONE;
CLR_INT (PTP);
if (ptp_unit.flags & UNIT_ATT) /* file to write? */
sim_activate (&ptp_unit, ptp_unit.wait);
else sim_activate (&ptp_unit, 0); /* error if not */
return SCPE_OK;
} /* end switch PA */
return SCPE_NXM; /* can't get here */
}
/* Paper tape punch service */
@@ -285,16 +314,17 @@ t_stat ptp_svc (UNIT *uptr)
ptp_csr = ptp_csr | CSR_ERR | CSR_DONE;
if (ptp_csr & CSR_IE) SET_INT (PTP);
if ((ptp_unit.flags & UNIT_ATT) == 0)
return IORETURN (ptp_stopioe, SCPE_UNATT);
return IORETURN (ptp_stopioe, SCPE_UNATT);
if (putc (ptp_unit.buf, ptp_unit.fileref) == EOF) {
perror ("PTP I/O error");
clearerr (ptp_unit.fileref);
return SCPE_IOERR; }
perror ("PTP I/O error");
clearerr (ptp_unit.fileref);
return SCPE_IOERR;
}
ptp_csr = ptp_csr & ~CSR_ERR;
ptp_unit.pos = ptp_unit.pos + 1;
return SCPE_OK;
}
/* Paper tape punch support routines */
t_stat ptp_reset (DEVICE *dptr)
@@ -303,7 +333,7 @@ ptp_unit.buf = 0;
ptp_csr = CSR_DONE;
if ((ptp_unit.flags & UNIT_ATT) == 0) ptp_csr = ptp_csr | CSR_ERR;
CLR_INT (PTP);
sim_cancel (&ptp_unit); /* deactivate unit */
sim_cancel (&ptp_unit); /* deactivate unit */
return SCPE_OK;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/* pdp11_rx.c: RX11/RX01 floppy disk simulator
Copyright (c) 1993-2004, Robert M Supnik
Copyright (c) 1993-2005, 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"),
@@ -19,28 +19,29 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not 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.
rx RX11/RX01 floppy disk
rx RX11/RX01 floppy disk
12-Oct-02 RMS Added autoconfigure support
08-Oct-02 RMS Added variable address support to bootstrap
Added vector change/display support
Revised state machine based on RX211
New data structures
Fixed reset of disabled device
26-Jan-02 RMS Revised bootstrap to conform to M9312
06-Jan-02 RMS Revised enable/disable support
30-Nov-01 RMS Added read only unit, extended SET/SHOW support
24-Nov-01 RMS Converted FLG to array
07-Sep-01 RMS Revised device disable and interrupt mechanisms
17-Jul-01 RMS Fixed warning from VC++ 6.0
26-Apr-01 RMS Added device enable/disable support
13-Apr-01 RMS Revised for register arrays
15-Feb-01 RMS Corrected bootstrap string
14-Apr-99 RMS Changed t_addr to unsigned
07-Jul-05 RMS Removed extraneous externs
12-Oct-02 RMS Added autoconfigure support
08-Oct-02 RMS Added variable address support to bootstrap
Added vector change/display support
Revised state machine based on RX211
New data structures
Fixed reset of disabled device
26-Jan-02 RMS Revised bootstrap to conform to M9312
06-Jan-02 RMS Revised enable/disable support
30-Nov-01 RMS Added read only unit, extended SET/SHOW support
24-Nov-01 RMS Converted FLG to array
07-Sep-01 RMS Revised device disable and interrupt mechanisms
17-Jul-01 RMS Fixed warning from VC++ 6.0
26-Apr-01 RMS Added device enable/disable support
13-Apr-01 RMS Revised for register arrays
15-Feb-01 RMS Corrected bootstrap string
14-Apr-99 RMS Changed t_addr to unsigned
An RX01 diskette consists of 77 tracks, each with 26 sectors of 128B.
Tracks are numbered 0-76, sectors 1-26.
@@ -48,81 +49,80 @@
#include "pdp11_defs.h"
#define RX_NUMTR 77 /* tracks/disk */
#define RX_M_TRACK 0377
#define RX_NUMSC 26 /* sectors/track */
#define RX_M_SECTOR 0177
#define RX_NUMBY 128 /* bytes/sector */
#define RX_SIZE (RX_NUMTR * RX_NUMSC * RX_NUMBY) /* bytes/disk */
#define RX_NUMDR 2 /* drives/controller */
#define RX_M_NUMDR 01
#define UNIT_V_WLK (UNIT_V_UF) /* write locked */
#define UNIT_WLK (1u << UNIT_V_UF)
#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write protect */
#define RX_NUMTR 77 /* tracks/disk */
#define RX_M_TRACK 0377
#define RX_NUMSC 26 /* sectors/track */
#define RX_M_SECTOR 0177
#define RX_NUMBY 128 /* bytes/sector */
#define RX_SIZE (RX_NUMTR * RX_NUMSC * RX_NUMBY) /* bytes/disk */
#define RX_NUMDR 2 /* drives/controller */
#define RX_M_NUMDR 01
#define UNIT_V_WLK (UNIT_V_UF) /* write locked */
#define UNIT_WLK (1u << UNIT_V_UF)
#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write protect */
#define IDLE 0 /* idle state */
#define RWDS 1 /* rw, sect next */
#define RWDT 2 /* rw, track next */
#define RWXFR 3 /* rw, transfer */
#define FILL 4 /* fill buffer */
#define EMPTY 5 /* empty buffer */
#define CMD_COMPLETE 6 /* set done next */
#define INIT_COMPLETE 7 /* init compl next */
#define IDLE 0 /* idle state */
#define RWDS 1 /* rw, sect next */
#define RWDT 2 /* rw, track next */
#define RWXFR 3 /* rw, transfer */
#define FILL 4 /* fill buffer */
#define EMPTY 5 /* empty buffer */
#define CMD_COMPLETE 6 /* set done next */
#define INIT_COMPLETE 7 /* init compl next */
#define RXCS_V_FUNC 1 /* function */
#define RXCS_M_FUNC 7
#define RXCS_FILL 0 /* fill buffer */
#define RXCS_EMPTY 1 /* empty buffer */
#define RXCS_WRITE 2 /* write sector */
#define RXCS_READ 3 /* read sector */
#define RXCS_RXES 5 /* read status */
#define RXCS_WRDEL 6 /* write del data */
#define RXCS_ECODE 7 /* read error code */
#define RXCS_V_DRV 4 /* drive select */
#define RXCS_V_DONE 5 /* done */
#define RXCS_V_IE 6 /* intr enable */
#define RXCS_V_TR 7 /* xfer request */
#define RXCS_V_INIT 14 /* init */
#define RXCS_V_ERR 15 /* error */
#define RXCS_FUNC (RXCS_M_FUNC << RXCS_V_FUNC)
#define RXCS_DRV (1u << RXCS_V_DRV)
#define RXCS_DONE (1u << RXCS_V_DONE)
#define RXCS_IE (1u << RXCS_V_IE)
#define RXCS_TR (1u << RXCS_V_TR)
#define RXCS_INIT (1u << RXCS_V_INIT)
#define RXCS_ERR (1u << RXCS_V_ERR)
#define RXCS_ROUT (RXCS_ERR+RXCS_TR+RXCS_IE+RXCS_DONE)
#define RXCS_IMP (RXCS_ROUT+RXCS_DRV+RXCS_FUNC)
#define RXCS_RW (RXCS_IE) /* read/write */
#define RXCS_GETFNC(x) (((x) >> RXCS_V_FUNC) & RXCS_M_FUNC)
#define RXCS_V_FUNC 1 /* function */
#define RXCS_M_FUNC 7
#define RXCS_FILL 0 /* fill buffer */
#define RXCS_EMPTY 1 /* empty buffer */
#define RXCS_WRITE 2 /* write sector */
#define RXCS_READ 3 /* read sector */
#define RXCS_RXES 5 /* read status */
#define RXCS_WRDEL 6 /* write del data */
#define RXCS_ECODE 7 /* read error code */
#define RXCS_V_DRV 4 /* drive select */
#define RXCS_V_DONE 5 /* done */
#define RXCS_V_IE 6 /* intr enable */
#define RXCS_V_TR 7 /* xfer request */
#define RXCS_V_INIT 14 /* init */
#define RXCS_V_ERR 15 /* error */
#define RXCS_FUNC (RXCS_M_FUNC << RXCS_V_FUNC)
#define RXCS_DRV (1u << RXCS_V_DRV)
#define RXCS_DONE (1u << RXCS_V_DONE)
#define RXCS_IE (1u << RXCS_V_IE)
#define RXCS_TR (1u << RXCS_V_TR)
#define RXCS_INIT (1u << RXCS_V_INIT)
#define RXCS_ERR (1u << RXCS_V_ERR)
#define RXCS_ROUT (RXCS_ERR+RXCS_TR+RXCS_IE+RXCS_DONE)
#define RXCS_IMP (RXCS_ROUT+RXCS_DRV+RXCS_FUNC)
#define RXCS_RW (RXCS_IE) /* read/write */
#define RXCS_GETFNC(x) (((x) >> RXCS_V_FUNC) & RXCS_M_FUNC)
#define RXES_CRC 0001 /* CRC error */
#define RXES_PAR 0002 /* parity error */
#define RXES_ID 0004 /* init done */
#define RXES_WLK 0010 /* write protect */
#define RXES_DD 0100 /* deleted data */
#define RXES_DRDY 0200 /* drive ready */
#define RXES_CRC 0001 /* CRC error */
#define RXES_PAR 0002 /* parity error */
#define RXES_ID 0004 /* init done */
#define RXES_WLK 0010 /* write protect */
#define RXES_DD 0100 /* deleted data */
#define RXES_DRDY 0200 /* drive ready */
#define TRACK u3 /* current track */
#define TRACK u3 /* current track */
#define CALC_DA(t,s) (((t) * RX_NUMSC) + ((s) - 1)) * RX_NUMBY
extern int32 int_req[IPL_HLVL];
extern int32 int_vec[IPL_HLVL][32];
int32 rx_csr = 0; /* control/status */
int32 rx_dbr = 0; /* data buffer */
int32 rx_esr = 0; /* error status */
int32 rx_ecode = 0; /* error code */
int32 rx_track = 0; /* desired track */
int32 rx_sector = 0; /* desired sector */
int32 rx_state = IDLE; /* controller state */
int32 rx_stopioe = 1; /* stop on error */
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 */
int32 rx_bptr = 0; /* buffer pointer */
int32 rx_enb = 1; /* device enable */
extern int32 int_req[IPL_HLVL];
int32 rx_csr = 0; /* control/status */
int32 rx_dbr = 0; /* data buffer */
int32 rx_esr = 0; /* error status */
int32 rx_ecode = 0; /* error code */
int32 rx_track = 0; /* desired track */
int32 rx_sector = 0; /* desired sector */
int32 rx_state = IDLE; /* controller state */
int32 rx_stopioe = 1; /* stop on error */
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 */
int32 rx_bptr = 0; /* buffer pointer */
int32 rx_enb = 1; /* device enable */
DEVICE rx_dev;
t_stat rx_rd (int32 *data, int32 PA, int32 access);
@@ -134,164 +134,184 @@ void rx_done (int esr_flags, int new_ecode);
/* RX11 data structures
rx_dev RX device descriptor
rx_unit RX unit list
rx_reg RX register list
rx_mod RX modifier list
rx_dev RX device descriptor
rx_unit RX unit list
rx_reg RX register list
rx_mod RX modifier list
*/
DIB rx_dib = { IOBA_RX, IOLN_RX, &rx_rd, &rx_wr,
1, IVCL (RX), VEC_RX, { NULL } };
DIB rx_dib = {
IOBA_RX, IOLN_RX, &rx_rd, &rx_wr,
1, IVCL (RX), VEC_RX, { NULL }
};
UNIT rx_unit[] = {
{ UDATA (&rx_svc,
UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF, RX_SIZE) },
{ UDATA (&rx_svc,
UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF, RX_SIZE) } };
{ UDATA (&rx_svc,
UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF, RX_SIZE) },
{ UDATA (&rx_svc,
UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF, RX_SIZE) }
};
REG rx_reg[] = {
{ ORDATA (RXCS, rx_csr, 16) },
{ ORDATA (RXDB, rx_dbr, 8) },
{ ORDATA (RXES, rx_esr, 8) },
{ ORDATA (RXERR, rx_ecode, 8) },
{ ORDATA (RXTA, rx_track, 8) },
{ ORDATA (RXSA, rx_sector, 8) },
{ DRDATA (STAPTR, rx_state, 3), REG_RO },
{ 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) },
{ FLDATA (IE, rx_csr, RXCS_V_IE) },
{ FLDATA (DONE, rx_csr, RXCS_V_DONE) },
{ DRDATA (CTIME, rx_cwait, 24), PV_LEFT },
{ DRDATA (STIME, rx_swait, 24), PV_LEFT },
{ DRDATA (XTIME, rx_xwait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, rx_stopioe, 0) },
{ BRDATA (SBUF, rx_buf, 8, 8, RX_NUMBY) },
{ ORDATA (DEVADDR, rx_dib.ba, 32), REG_HRO },
{ ORDATA (DEVVEC, rx_dib.vec, 16), REG_HRO },
{ NULL } };
{ ORDATA (RXCS, rx_csr, 16) },
{ ORDATA (RXDB, rx_dbr, 8) },
{ ORDATA (RXES, rx_esr, 8) },
{ ORDATA (RXERR, rx_ecode, 8) },
{ ORDATA (RXTA, rx_track, 8) },
{ ORDATA (RXSA, rx_sector, 8) },
{ DRDATA (STAPTR, rx_state, 3), REG_RO },
{ 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) },
{ FLDATA (IE, rx_csr, RXCS_V_IE) },
{ FLDATA (DONE, rx_csr, RXCS_V_DONE) },
{ DRDATA (CTIME, rx_cwait, 24), PV_LEFT },
{ DRDATA (STIME, rx_swait, 24), PV_LEFT },
{ DRDATA (XTIME, rx_xwait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, rx_stopioe, 0) },
{ BRDATA (SBUF, rx_buf, 8, 8, RX_NUMBY) },
{ ORDATA (DEVADDR, rx_dib.ba, 32), REG_HRO },
{ ORDATA (DEVVEC, rx_dib.vec, 16), REG_HRO },
{ NULL }
};
MTAB rx_mod[] = {
{ UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL },
{ UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL },
{ MTAB_XTD|MTAB_VDV, 004, "ADDRESS", "ADDRESS",
&set_addr, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR",
&set_vec, &show_vec, NULL },
{ MTAB_XTD | MTAB_VDV, 0, NULL, "AUTOCONFIGURE",
&set_addr_flt, NULL, NULL },
{ 0 } };
{ UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL },
{ UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL },
{ MTAB_XTD|MTAB_VDV, 004, "ADDRESS", "ADDRESS",
&set_addr, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR",
&set_vec, &show_vec, NULL },
{ MTAB_XTD | MTAB_VDV, 0, NULL, "AUTOCONFIGURE",
&set_addr_flt, NULL, NULL },
{ 0 }
};
DEVICE rx_dev = {
"RX", rx_unit, rx_reg, rx_mod,
RX_NUMDR, 8, 20, 1, 8, 8,
NULL, NULL, &rx_reset,
&rx_boot, NULL, NULL,
&rx_dib, DEV_FLTA | DEV_DISABLE | DEV_UBUS | DEV_QBUS };
"RX", rx_unit, rx_reg, rx_mod,
RX_NUMDR, 8, 20, 1, 8, 8,
NULL, NULL, &rx_reset,
&rx_boot, NULL, NULL,
&rx_dib, DEV_FLTA | DEV_DISABLE | DEV_UBUS | DEV_QBUS
};
/* I/O dispatch routine, I/O addresses 17777170 - 17777172
17777170 floppy CSR
17777172 floppy data register
17777170 floppy CSR
17777172 floppy data register
*/
t_stat rx_rd (int32 *data, int32 PA, int32 access)
{
switch ((PA >> 1) & 1) { /* decode PA<1> */
case 0: /* RXCS */
rx_csr = rx_csr & RXCS_IMP; /* clear junk */
*data = rx_csr & RXCS_ROUT;
break;
case 1: /* RXDB */
if ((rx_state == EMPTY) && (rx_csr & RXCS_TR)) {/* empty? */
sim_activate (&rx_unit[0], rx_xwait);
rx_csr = rx_csr & ~RXCS_TR; } /* clear xfer */
*data = rx_dbr; /* return data */
break; } /* end switch PA */
switch ((PA >> 1) & 1) { /* decode PA<1> */
case 0: /* RXCS */
rx_csr = rx_csr & RXCS_IMP; /* clear junk */
*data = rx_csr & RXCS_ROUT;
break;
case 1: /* RXDB */
if ((rx_state == EMPTY) && (rx_csr & RXCS_TR)) {/* empty? */
sim_activate (&rx_unit[0], rx_xwait);
rx_csr = rx_csr & ~RXCS_TR; /* clear xfer */
}
*data = rx_dbr; /* return data */
break;
} /* end switch PA */
return SCPE_OK;
}
t_stat rx_wr (int32 data, int32 PA, int32 access)
{
int32 drv;
switch ((PA >> 1) & 1) { /* decode PA<1> */
switch ((PA >> 1) & 1) { /* decode PA<1> */
/* Writing RXCS, three cases:
1. Writing INIT, reset device
2. Idle and writing new function
- clear error, done, transfer ready, int req
- save int enable, function, drive
- start new function
- clear error, done, transfer ready, int req
- save int enable, function, drive
- start new function
3. Otherwise, write IE and update interrupts
*/
case 0: /* RXCS */
rx_csr = rx_csr & RXCS_IMP; /* clear junk */
if (access == WRITEB) data = (PA & 1)? /* write byte? */
(rx_csr & 0377) | (data << 8): (rx_csr & ~0377) | data;
if (data & RXCS_INIT) { /* initialize? */
rx_reset (&rx_dev); /* reset device */
return SCPE_OK; } /* end if init */
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 */
rx_bptr = 0; /* clear buf pointer */
switch (RXCS_GETFNC (data)) { /* case on func */
case RXCS_FILL:
rx_state = FILL; /* state = fill */
rx_csr = rx_csr | RXCS_TR; /* xfer is ready */
break;
case RXCS_EMPTY:
rx_state = EMPTY; /* state = empty */
sim_activate (&rx_unit[drv], rx_xwait);
break;
case RXCS_READ: case RXCS_WRITE: case RXCS_WRDEL:
rx_state = RWDS; /* state = get sector */
rx_csr = rx_csr | RXCS_TR; /* xfer is ready */
rx_esr = rx_esr & RXES_ID; /* clear errors */
break;
default:
rx_state = CMD_COMPLETE; /* state = cmd compl */
sim_activate (&rx_unit[drv], rx_cwait);
break; } /* end switch func */
return SCPE_OK; } /* end if GO */
if ((data & RXCS_IE) == 0) CLR_INT (RX);
else if ((rx_csr & (RXCS_DONE + RXCS_IE)) == RXCS_DONE)
SET_INT (RX);
rx_csr = (rx_csr & ~RXCS_RW) | (data & RXCS_RW);
break; /* end case RXCS */
case 0: /* RXCS */
rx_csr = rx_csr & RXCS_IMP; /* clear junk */
if (access == WRITEB) data = (PA & 1)? /* write byte? */
(rx_csr & 0377) | (data << 8): (rx_csr & ~0377) | data;
if (data & RXCS_INIT) { /* initialize? */
rx_reset (&rx_dev); /* reset device */
return SCPE_OK; /* end if init */
}
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 */
rx_bptr = 0; /* clear buf pointer */
switch (RXCS_GETFNC (data)) { /* case on func */
case RXCS_FILL:
rx_state = FILL; /* state = fill */
rx_csr = rx_csr | RXCS_TR; /* xfer is ready */
break;
case RXCS_EMPTY:
rx_state = EMPTY; /* state = empty */
sim_activate (&rx_unit[drv], rx_xwait);
break;
case RXCS_READ: case RXCS_WRITE: case RXCS_WRDEL:
rx_state = RWDS; /* state = get sector */
rx_csr = rx_csr | RXCS_TR; /* xfer is ready */
rx_esr = rx_esr & RXES_ID; /* clear errors */
break;
default:
rx_state = CMD_COMPLETE; /* state = cmd compl */
sim_activate (&rx_unit[drv], rx_cwait);
break;
} /* end switch func */
return SCPE_OK;
} /* end if GO */
if ((data & RXCS_IE) == 0) CLR_INT (RX);
else if ((rx_csr & (RXCS_DONE + RXCS_IE)) == RXCS_DONE)
SET_INT (RX);
rx_csr = (rx_csr & ~RXCS_RW) | (data & RXCS_RW);
break; /* end case RXCS */
/* Accessing RXDB, two cases:
1. Write idle, write
2. Write not idle and TR set, state dependent
*/
case 1: /* RXDB */
if ((PA & 1) || ((rx_state != IDLE) && ((rx_csr & RXCS_TR) == 0)))
return SCPE_OK; /* if ~IDLE, need tr */
rx_dbr = data & 0377; /* save data */
if ((rx_state != IDLE) && (rx_state != EMPTY)) {
drv = ((rx_csr & RXCS_DRV)? 1: 0); /* select drive */
sim_activate (&rx_unit[drv], rx_xwait); /* sched event */
rx_csr = rx_csr & ~RXCS_TR; } /* clear xfer */
break; /* end case RXDB */
} /* end switch PA */
case 1: /* RXDB */
if ((PA & 1) || ((rx_state != IDLE) && ((rx_csr & RXCS_TR) == 0)))
return SCPE_OK; /* if ~IDLE, need tr */
rx_dbr = data & 0377; /* save data */
if ((rx_state != IDLE) && (rx_state != EMPTY)) {
drv = ((rx_csr & RXCS_DRV)? 1: 0); /* select drive */
sim_activate (&rx_unit[drv], rx_xwait); /* sched event */
rx_csr = rx_csr & ~RXCS_TR; /* clear xfer */
}
break; /* end case RXDB */
} /* end switch PA */
return SCPE_OK;
}
/* Unit service; the action to be taken depends on the transfer state:
IDLE Should never get here
RWDS Save sector, set TR, set RWDT
RWDT Save track, set RWXFR
RWXFR Read/write buffer
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
IDLE Should never get here
RWDS Save sector, set TR, set RWDT
RWDT Save track, set RWXFR
RWXFR Read/write buffer
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
For RWDT and CMD_COMPLETE, the input argument is the selected drive;
@@ -304,87 +324,100 @@ int32 i, func;
uint32 da;
int8 *fbuf = uptr->filebuf;
func = RXCS_GETFNC (rx_csr); /* get function */
switch (rx_state) { /* case on state */
func = RXCS_GETFNC (rx_csr); /* get function */
switch (rx_state) { /* case on state */
case IDLE: /* idle */
return SCPE_IERR; /* done */
case IDLE: /* idle */
return SCPE_IERR; /* done */
case EMPTY: /* empty buffer */
if (rx_bptr >= RX_NUMBY) rx_done (0, 0); /* done all? */
else {
rx_dbr = rx_buf[rx_bptr]; /* get next */
rx_bptr = rx_bptr + 1;
rx_csr = rx_csr | RXCS_TR; } /* set xfer */
break;
case EMPTY: /* empty buffer */
if (rx_bptr >= RX_NUMBY) rx_done (0, 0); /* done all? */
else {
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[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;
case FILL: /* fill buffer */
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;
case RWDS: /* wait for sector */
rx_sector = rx_dbr & RX_M_SECTOR; /* save sector */
rx_csr = rx_csr | RXCS_TR; /* set xfer */
rx_state = RWDT; /* advance state */
return SCPE_OK;
case RWDT: /* wait for track */
rx_track = rx_dbr & RX_M_TRACK; /* save track */
rx_state = RWXFR;
sim_activate (uptr, /* sched done */
rx_swait * abs (rx_track - uptr->TRACK));
return SCPE_OK;
case RWXFR:
if ((uptr->flags & UNIT_BUF) == 0) { /* not buffered? */
rx_done (0, 0110); /* done, error */
return IORETURN (rx_stopioe, SCPE_UNATT); }
if (rx_track >= RX_NUMTR) { /* bad track? */
rx_done (0, 0040); /* done, error */
break; }
uptr->TRACK = rx_track; /* now on track */
if ((rx_sector == 0) || (rx_sector > RX_NUMSC)) { /* bad sect? */
rx_done (0, 0070); /* done, error */
break; }
da = CALC_DA (rx_track, rx_sector); /* get disk address */
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] = 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 */
fbuf[da + i] = rx_buf[i];
da = da + RX_NUMBY;
if (da > uptr->hwmark) uptr->hwmark = da; }
rx_done (0, 0); /* done */
break;
case RWDS: /* wait for sector */
rx_sector = rx_dbr & RX_M_SECTOR; /* save sector */
rx_csr = rx_csr | RXCS_TR; /* set xfer */
rx_state = RWDT; /* advance state */
return SCPE_OK;
case CMD_COMPLETE: /* command complete */
if (func == RXCS_ECODE) { /* read ecode? */
rx_dbr = rx_ecode; /* set dbr */
rx_done (0, -1); } /* don't update */
else rx_done (0, 0);
break;
case RWDT: /* wait for track */
rx_track = rx_dbr & RX_M_TRACK; /* save track */
rx_state = RWXFR;
sim_activate (uptr, /* sched done */
rx_swait * abs (rx_track - uptr->TRACK));
return SCPE_OK;
case RWXFR:
if ((uptr->flags & UNIT_BUF) == 0) { /* not buffered? */
rx_done (0, 0110); /* done, error */
return IORETURN (rx_stopioe, SCPE_UNATT);
}
if (rx_track >= RX_NUMTR) { /* bad track? */
rx_done (0, 0040); /* done, error */
break;
}
uptr->TRACK = rx_track; /* now on track */
if ((rx_sector == 0) || (rx_sector > RX_NUMSC)) { /* bad sect? */
rx_done (0, 0070); /* done, error */
break;
}
da = CALC_DA (rx_track, rx_sector); /* get disk address */
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] = 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 */
fbuf[da + i] = rx_buf[i];
da = da + RX_NUMBY;
if (da > uptr->hwmark) uptr->hwmark = da;
}
rx_done (0, 0); /* done */
break;
case CMD_COMPLETE: /* command complete */
if (func == RXCS_ECODE) { /* read ecode? */
rx_dbr = rx_ecode; /* set dbr */
rx_done (0, -1); /* don't update */
}
else rx_done (0, 0);
break;
case INIT_COMPLETE: /* init complete */
rx_unit[0].TRACK = 1; /* drive 0 to trk 1 */
rx_unit[1].TRACK = 0; /* drive 1 to trk 0 */
if ((rx_unit[0].flags & UNIT_BUF) == 0) { /* not buffered? */
rx_done (RXES_ID, 0010); /* init done, error */
break;
}
da = CALC_DA (1, 1); /* track 1, sector 1 */
for (i = 0; i < RX_NUMBY; i++) /* read sector */
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 */
case INIT_COMPLETE: /* init complete */
rx_unit[0].TRACK = 1; /* drive 0 to trk 1 */
rx_unit[1].TRACK = 0; /* drive 1 to trk 0 */
if ((rx_unit[0].flags & UNIT_BUF) == 0) { /* not buffered? */
rx_done (RXES_ID, 0010); /* init done, error */
break; }
da = CALC_DA (1, 1); /* track 1, sector 1 */
for (i = 0; i < RX_NUMBY; i++) /* read sector */
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 */
return SCPE_OK;
}
/* Command complete. Set done and put final value in interface register,
request interrupt if needed, return to IDLE state.
*/
@@ -393,16 +426,16 @@ void rx_done (int32 esr_flags, int32 new_ecode)
{
int32 drv = (rx_csr & RXCS_DRV)? 1: 0;
rx_state = IDLE; /* now idle */
rx_csr = rx_csr | RXCS_DONE; /* set done */
if (rx_csr & RXCS_IE) SET_INT (RX); /* if ie, intr */
rx_state = IDLE; /* now idle */
rx_csr = rx_csr | RXCS_DONE; /* set done */
if (rx_csr & RXCS_IE) SET_INT (RX); /* if ie, intr */
rx_esr = (rx_esr | esr_flags) & ~RXES_DRDY;
if (rx_unit[drv].flags & UNIT_ATT)
rx_esr = rx_esr | RXES_DRDY;
if (new_ecode > 0) rx_csr = rx_csr | RXCS_ERR; /* test for error */
if (new_ecode < 0) return; /* don't update? */
rx_ecode = new_ecode; /* update ecode */
rx_dbr = rx_esr; /* update RXDB */
rx_esr = rx_esr | RXES_DRDY;
if (new_ecode > 0) rx_csr = rx_csr | RXCS_ERR; /* test for error */
if (new_ecode < 0) return; /* don't update? */
rx_ecode = new_ecode; /* update ecode */
rx_dbr = rx_esr; /* update RXDB */
return;
}
@@ -412,63 +445,64 @@ return;
t_stat rx_reset (DEVICE *dptr)
{
rx_csr = rx_dbr = 0; /* clear regs */
rx_esr = rx_ecode = 0; /* clear error */
rx_track = rx_sector = 0; /* clear addr */
rx_state = IDLE; /* ctrl idle */
CLR_INT (RX); /* clear int req */
sim_cancel (&rx_unit[1]); /* cancel drive 1 */
if (dptr->flags & DEV_DIS) sim_cancel (&rx_unit[0]); /* disabled? */
else if (rx_unit[0].flags & UNIT_BUF) { /* attached? */
rx_state = INIT_COMPLETE; /* yes, sched init */
sim_activate (&rx_unit[0], rx_swait * abs (1 - rx_unit[0].TRACK)); }
else rx_done (0, 0010); /* no, error */
return auto_config (0, 0); /* run autoconfig */
rx_csr = rx_dbr = 0; /* clear regs */
rx_esr = rx_ecode = 0; /* clear error */
rx_track = rx_sector = 0; /* clear addr */
rx_state = IDLE; /* ctrl idle */
CLR_INT (RX); /* clear int req */
sim_cancel (&rx_unit[1]); /* cancel drive 1 */
if (dptr->flags & DEV_DIS) sim_cancel (&rx_unit[0]); /* disabled? */
else if (rx_unit[0].flags & UNIT_BUF) { /* attached? */
rx_state = INIT_COMPLETE; /* yes, sched init */
sim_activate (&rx_unit[0], rx_swait * abs (1 - rx_unit[0].TRACK));
}
else rx_done (0, 0010); /* no, error */
return auto_config (0, 0); /* run autoconfig */
}
/* Device bootstrap */
#define BOOT_START 02000 /* start */
#define BOOT_ENTRY (BOOT_START + 002) /* entry */
#define BOOT_UNIT (BOOT_START + 010) /* unit number */
#define BOOT_CSR (BOOT_START + 026) /* CSR */
#define BOOT_LEN (sizeof (boot_rom) / sizeof (int16))
#define BOOT_START 02000 /* start */
#define BOOT_ENTRY (BOOT_START + 002) /* entry */
#define BOOT_UNIT (BOOT_START + 010) /* unit number */
#define BOOT_CSR (BOOT_START + 026) /* CSR */
#define BOOT_LEN (sizeof (boot_rom) / sizeof (int16))
static const uint16 boot_rom[] = {
042130, /* "XD" */
0012706, BOOT_START, /* MOV #boot_start, SP */
0012700, 0000000, /* MOV #unit, R0 ; unit number */
0010003, /* MOV R0, R3 */
0006303, /* ASL R3 */
0006303, /* ASL R3 */
0006303, /* ASL R3 */
0006303, /* ASL R3 */
0012701, 0177170, /* MOV #RXCS, R1 ; csr */
0032711, 0000040, /* BITB #40, (R1) ; ready? */
0001775, /* BEQ .-4 */
0052703, 0000007, /* BIS #READ+GO, R3 */
0010311, /* MOV R3, (R1) ; read & go */
0105711, /* TSTB (R1) ; xfr ready? */
0100376, /* BPL .-2 */
0012761, 0000001, 0000002, /* MOV #1, 2(R1) ; sector */
0105711, /* TSTB (R1) ; xfr ready? */
0100376, /* BPL .-2 */
0012761, 0000001, 0000002, /* MOV #1, 2(R1) ; track */
0005003, /* CLR R3 */
0032711, 0000040, /* BITB #40, (R1) ; ready? */
0001775, /* BEQ .-4 */
0012711, 0000003, /* MOV #EMPTY+GO, (R1) ; empty & go */
0105711, /* TSTB (R1) ; xfr, done? */
0001776, /* BEQ .-2 */
0100003, /* BPL .+010 */
0116123, 0000002, /* MOVB 2(R1), (R3)+ ; move byte */
0000772, /* BR .-012 */
0005002, /* CLR R2 */
0005003, /* CLR R3 */
0012704, BOOT_START+020, /* MOV #START+20, R4 */
0005005, /* CLR R5 */
0005007 /* CLR R7 */
};
042130, /* "XD" */
0012706, BOOT_START, /* MOV #boot_start, SP */
0012700, 0000000, /* MOV #unit, R0 ; unit number */
0010003, /* MOV R0, R3 */
0006303, /* ASL R3 */
0006303, /* ASL R3 */
0006303, /* ASL R3 */
0006303, /* ASL R3 */
0012701, 0177170, /* MOV #RXCS, R1 ; csr */
0032711, 0000040, /* BITB #40, (R1) ; ready? */
0001775, /* BEQ .-4 */
0052703, 0000007, /* BIS #READ+GO, R3 */
0010311, /* MOV R3, (R1) ; read & go */
0105711, /* TSTB (R1) ; xfr ready? */
0100376, /* BPL .-2 */
0012761, 0000001, 0000002, /* MOV #1, 2(R1) ; sector */
0105711, /* TSTB (R1) ; xfr ready? */
0100376, /* BPL .-2 */
0012761, 0000001, 0000002, /* MOV #1, 2(R1) ; track */
0005003, /* CLR R3 */
0032711, 0000040, /* BITB #40, (R1) ; ready? */
0001775, /* BEQ .-4 */
0012711, 0000003, /* MOV #EMPTY+GO, (R1) ; empty & go */
0105711, /* TSTB (R1) ; xfr, done? */
0001776, /* BEQ .-2 */
0100003, /* BPL .+010 */
0116123, 0000002, /* MOVB 2(R1), (R3)+ ; move byte */
0000772, /* BR .-012 */
0005002, /* CLR R2 */
0005003, /* CLR R3 */
0012704, BOOT_START+020, /* MOV #START+20, R4 */
0005005, /* CLR R5 */
0005007 /* CLR R7 */
};
t_stat rx_boot (int32 unitno, DEVICE *dptr)
{

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/* pdp11_stddev.c: PDP-11 standard I/O devices simulator
Copyright (c) 1993-2004, Robert M Supnik
Copyright (c) 1993-2005, 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"),
@@ -19,64 +19,64 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not 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.
tti,tto DL11 terminal input/output
clk KW11L (and other) line frequency clock
tti,tto DL11 terminal input/output
clk KW11L (and other) line frequency clock
11-Oct-04 RMS Added clock model dependencies
28-May-04 RMS Removed SET TTI CTRL-C
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
01-Nov-02 RMS Added 7B/8B support to terminal
29-Sep-02 RMS Added vector display support
Split out paper tape
Split DL11 dibs
30-May-02 RMS Widened POS to 32b
26-Jan-02 RMS Revised for multiple timers
09-Jan-02 RMS Fixed bugs in KW11L (found by John Dundas)
06-Jan-02 RMS Split I/O address routines, revised enable/disable support
29-Nov-01 RMS Added read only unit support
09-Nov-01 RMS Added RQDX3 support
07-Oct-01 RMS Upgraded clock to full KW11L for RSTS/E autoconfigure
07-Sep-01 RMS Moved function prototypes, revised interrupt mechanism
17-Jul-01 RMS Moved function prototype
04-Jul-01 RMS Added DZ11 support
05-Mar-01 RMS Added clock calibration support
30-Oct-00 RMS Standardized register order
25-Jun-98 RMS Fixed bugs in paper tape error handling
07-Jul-05 RMS Removed extraneous externs
11-Oct-04 RMS Added clock model dependencies
28-May-04 RMS Removed SET TTI CTRL-C
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
01-Nov-02 RMS Added 7B/8B support to terminal
29-Sep-02 RMS Added vector display support
Split out paper tape
Split DL11 dibs
30-May-02 RMS Widened POS to 32b
26-Jan-02 RMS Revised for multiple timers
09-Jan-02 RMS Fixed bugs in KW11L (found by John Dundas)
06-Jan-02 RMS Split I/O address routines, revised enable/disable support
29-Nov-01 RMS Added read only unit support
09-Nov-01 RMS Added RQDX3 support
07-Oct-01 RMS Upgraded clock to full KW11L for RSTS/E autoconfigure
07-Sep-01 RMS Moved function prototypes, revised interrupt mechanism
17-Jul-01 RMS Moved function prototype
04-Jul-01 RMS Added DZ11 support
05-Mar-01 RMS Added clock calibration support
30-Oct-00 RMS Standardized register order
25-Jun-98 RMS Fixed bugs in paper tape error handling
*/
#include "pdp11_defs.h"
#define TTICSR_IMP (CSR_DONE + CSR_IE) /* terminal input */
#define TTICSR_RW (CSR_IE)
#define TTOCSR_IMP (CSR_DONE + CSR_IE) /* terminal output */
#define TTOCSR_RW (CSR_IE)
#define CLKCSR_IMP (CSR_DONE + CSR_IE) /* real-time clock */
#define CLKCSR_RW (CSR_IE)
#define CLK_DELAY 8000
#define TTICSR_IMP (CSR_DONE + CSR_IE) /* terminal input */
#define TTICSR_RW (CSR_IE)
#define TTOCSR_IMP (CSR_DONE + CSR_IE) /* terminal output */
#define TTOCSR_RW (CSR_IE)
#define CLKCSR_IMP (CSR_DONE + CSR_IE) /* real-time clock */
#define CLKCSR_RW (CSR_IE)
#define CLK_DELAY 8000
#define UNIT_V_8B (UNIT_V_UF + 0) /* 8B */
#define UNIT_8B (1 << UNIT_V_8B)
#define UNIT_V_8B (UNIT_V_UF + 0) /* 8B */
#define UNIT_8B (1 << UNIT_V_8B)
extern int32 int_req[IPL_HLVL];
extern int32 int_vec[IPL_HLVL][32];
extern int32 cpu_type;
int32 tti_csr = 0; /* control/status */
int32 tto_csr = 0; /* control/status */
int32 clk_csr = 0; /* control/status */
int32 clk_tps = 60; /* ticks/second */
int32 clk_default = 60; /* default ticks/second */
int32 clk_fie = 0; /* force IE = 1 */
int32 clk_fnxm = 0; /* force NXM on reg */
int32 tmxr_poll = CLK_DELAY; /* term mux poll */
int32 tmr_poll = CLK_DELAY; /* timer poll */
int32 tti_csr = 0; /* control/status */
int32 tto_csr = 0; /* control/status */
int32 clk_csr = 0; /* control/status */
int32 clk_tps = 60; /* ticks/second */
int32 clk_default = 60; /* default ticks/second */
int32 clk_fie = 0; /* force IE = 1 */
int32 clk_fnxm = 0; /* force NXM on reg */
int32 tmxr_poll = CLK_DELAY; /* term mux poll */
int32 tmr_poll = CLK_DELAY; /* timer poll */
t_stat tti_rd (int32 *data, int32 PA, int32 access);
t_stat tti_wr (int32 data, int32 PA, int32 access);
@@ -94,157 +94,180 @@ int32 clk_inta (void);
t_stat clk_reset (DEVICE *dptr);
t_stat clk_set_freq (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat clk_show_freq (FILE *st, UNIT *uptr, int32 val, void *desc);
/* TTI data structures
tti_dev TTI device descriptor
tti_unit TTI unit descriptor
tti_reg TTI register list
tti_dev TTI device descriptor
tti_unit TTI unit descriptor
tti_reg TTI register list
*/
DIB tti_dib = { IOBA_TTI, IOLN_TTI, &tti_rd, &tti_wr,
1, IVCL (TTI), VEC_TTI, { NULL } };
DIB tti_dib = {
IOBA_TTI, IOLN_TTI, &tti_rd, &tti_wr,
1, IVCL (TTI), VEC_TTI, { NULL }
};
UNIT tti_unit = { UDATA (&tti_svc, 0, 0), KBD_POLL_WAIT };
REG tti_reg[] = {
{ ORDATA (BUF, tti_unit.buf, 8) },
{ ORDATA (CSR, tti_csr, 16) },
{ FLDATA (INT, IREQ (TTI), INT_V_TTI) },
{ FLDATA (ERR, tti_csr, CSR_V_ERR) },
{ FLDATA (DONE, tti_csr, CSR_V_DONE) },
{ FLDATA (IE, tti_csr, CSR_V_IE) },
{ DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
{ NULL } };
{ ORDATA (BUF, tti_unit.buf, 8) },
{ ORDATA (CSR, tti_csr, 16) },
{ FLDATA (INT, IREQ (TTI), INT_V_TTI) },
{ FLDATA (ERR, tti_csr, CSR_V_ERR) },
{ FLDATA (DONE, tti_csr, CSR_V_DONE) },
{ FLDATA (IE, tti_csr, CSR_V_IE) },
{ DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
{ NULL }
};
MTAB tti_mod[] = {
{ UNIT_8B, 0 , "7b" , "7B" , &tty_set_mode },
{ UNIT_8B, UNIT_8B , "8b" , "8B" , &tty_set_mode },
{ MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL,
NULL, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL,
NULL, &show_vec, NULL },
{ 0 } };
{ UNIT_8B, 0 , "7b" , "7B" , &tty_set_mode },
{ UNIT_8B, UNIT_8B , "8b" , "8B" , &tty_set_mode },
{ MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL,
NULL, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL,
NULL, &show_vec, NULL },
{ 0 }
};
DEVICE tti_dev = {
"TTI", &tti_unit, tti_reg, tti_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &tti_reset,
NULL, NULL, NULL,
&tti_dib, DEV_UBUS | DEV_QBUS };
"TTI", &tti_unit, tti_reg, tti_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &tti_reset,
NULL, NULL, NULL,
&tti_dib, DEV_UBUS | DEV_QBUS
};
/* TTO data structures
tto_dev TTO device descriptor
tto_unit TTO unit descriptor
tto_reg TTO register list
tto_dev TTO device descriptor
tto_unit TTO unit descriptor
tto_reg TTO register list
*/
DIB tto_dib = { IOBA_TTO, IOLN_TTO, &tto_rd, &tto_wr,
1, IVCL (TTO), VEC_TTO, { NULL } };
DIB tto_dib = {
IOBA_TTO, IOLN_TTO, &tto_rd, &tto_wr,
1, IVCL (TTO), VEC_TTO, { NULL }
};
UNIT tto_unit = { UDATA (&tto_svc, 0, 0), SERIAL_OUT_WAIT };
REG tto_reg[] = {
{ ORDATA (BUF, tto_unit.buf, 8) },
{ ORDATA (CSR, tto_csr, 16) },
{ FLDATA (INT, IREQ (TTO), INT_V_TTO) },
{ FLDATA (ERR, tto_csr, CSR_V_ERR) },
{ FLDATA (DONE, tto_csr, CSR_V_DONE) },
{ FLDATA (IE, tto_csr, CSR_V_IE) },
{ DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
{ NULL } };
{ ORDATA (BUF, tto_unit.buf, 8) },
{ ORDATA (CSR, tto_csr, 16) },
{ FLDATA (INT, IREQ (TTO), INT_V_TTO) },
{ FLDATA (ERR, tto_csr, CSR_V_ERR) },
{ FLDATA (DONE, tto_csr, CSR_V_DONE) },
{ FLDATA (IE, tto_csr, CSR_V_IE) },
{ DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
{ NULL }
};
MTAB tto_mod[] = {
{ UNIT_8B, 0 , "7b" , "7B" , &tty_set_mode },
{ UNIT_8B, UNIT_8B , "8b" , "8B" , &tty_set_mode },
{ MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL,
NULL, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL,
NULL, &show_vec, NULL },
{ 0 } };
{ UNIT_8B, 0 , "7b" , "7B" , &tty_set_mode },
{ UNIT_8B, UNIT_8B , "8b" , "8B" , &tty_set_mode },
{ MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL,
NULL, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL,
NULL, &show_vec, NULL },
{ 0 }
};
DEVICE tto_dev = {
"TTO", &tto_unit, tto_reg, tto_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &tto_reset,
NULL, NULL, NULL,
&tto_dib, DEV_UBUS | DEV_QBUS };
"TTO", &tto_unit, tto_reg, tto_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &tto_reset,
NULL, NULL, NULL,
&tto_dib, DEV_UBUS | DEV_QBUS
};
/* CLK data structures
clk_dev CLK device descriptor
clk_unit CLK unit descriptor
clk_reg CLK register list
clk_dev CLK device descriptor
clk_unit CLK unit descriptor
clk_reg CLK register list
*/
DIB clk_dib = { IOBA_CLK, IOLN_CLK, &clk_rd, &clk_wr,
1, IVCL (CLK), VEC_CLK, { &clk_inta } };
DIB clk_dib = {
IOBA_CLK, IOLN_CLK, &clk_rd, &clk_wr,
1, IVCL (CLK), VEC_CLK, { &clk_inta }
};
UNIT clk_unit = { UDATA (&clk_svc, 0, 0), 8000 };
REG clk_reg[] = {
{ ORDATA (CSR, clk_csr, 16) },
{ FLDATA (INT, IREQ (CLK), INT_V_CLK) },
{ FLDATA (DONE, clk_csr, CSR_V_DONE) },
{ FLDATA (IE, clk_csr, CSR_V_IE) },
{ DRDATA (TIME, clk_unit.wait, 24), REG_NZ + PV_LEFT },
{ DRDATA (TPS, clk_tps, 16), PV_LEFT + REG_HRO },
{ DRDATA (DEFTPS, clk_default, 16), PV_LEFT + REG_HRO },
{ FLDATA (FIE, clk_fie, 0), REG_HIDDEN },
{ FLDATA (FNXM, clk_fnxm, 0), REG_HIDDEN },
{ NULL } };
{ ORDATA (CSR, clk_csr, 16) },
{ FLDATA (INT, IREQ (CLK), INT_V_CLK) },
{ FLDATA (DONE, clk_csr, CSR_V_DONE) },
{ FLDATA (IE, clk_csr, CSR_V_IE) },
{ DRDATA (TIME, clk_unit.wait, 24), REG_NZ + PV_LEFT },
{ DRDATA (TPS, clk_tps, 16), PV_LEFT + REG_HRO },
{ DRDATA (DEFTPS, clk_default, 16), PV_LEFT + REG_HRO },
{ FLDATA (FIE, clk_fie, 0), REG_HIDDEN },
{ FLDATA (FNXM, clk_fnxm, 0), REG_HIDDEN },
{ NULL }
};
MTAB clk_mod[] = {
{ MTAB_XTD|MTAB_VDV, 50, NULL, "50HZ",
&clk_set_freq, NULL, NULL },
{ MTAB_XTD|MTAB_VDV, 60, NULL, "60HZ",
&clk_set_freq, NULL, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "FREQUENCY", NULL,
NULL, &clk_show_freq, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL,
NULL, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL,
NULL, &show_vec, NULL },
{ 0 } };
{ MTAB_XTD|MTAB_VDV, 50, NULL, "50HZ",
&clk_set_freq, NULL, NULL },
{ MTAB_XTD|MTAB_VDV, 60, NULL, "60HZ",
&clk_set_freq, NULL, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "FREQUENCY", NULL,
NULL, &clk_show_freq, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL,
NULL, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL,
NULL, &show_vec, NULL },
{ 0 }
};
DEVICE clk_dev = {
"CLK", &clk_unit, clk_reg, clk_mod,
1, 0, 0, 0, 0, 0,
NULL, NULL, &clk_reset,
NULL, NULL, NULL,
&clk_dib, DEV_UBUS | DEV_QBUS };
"CLK", &clk_unit, clk_reg, clk_mod,
1, 0, 0, 0, 0, 0,
NULL, NULL, &clk_reset,
NULL, NULL, NULL,
&clk_dib, DEV_UBUS | DEV_QBUS
};
/* Terminal input address routines */
t_stat tti_rd (int32 *data, int32 PA, int32 access)
{
switch ((PA >> 1) & 01) { /* decode PA<1> */
case 00: /* tti csr */
*data = tti_csr & TTICSR_IMP;
return SCPE_OK;
case 01: /* tti buf */
tti_csr = tti_csr & ~CSR_DONE;
CLR_INT (TTI);
*data = tti_unit.buf & 0377;
return SCPE_OK; } /* end switch PA */
switch ((PA >> 1) & 01) { /* decode PA<1> */
case 00: /* tti csr */
*data = tti_csr & TTICSR_IMP;
return SCPE_OK;
case 01: /* tti buf */
tti_csr = tti_csr & ~CSR_DONE;
CLR_INT (TTI);
*data = tti_unit.buf & 0377;
return SCPE_OK;
} /* end switch PA */
return SCPE_NXM;
}
t_stat tti_wr (int32 data, int32 PA, int32 access)
{
switch ((PA >> 1) & 01) { /* decode PA<1> */
case 00: /* tti csr */
if (PA & 1) return SCPE_OK;
if ((data & CSR_IE) == 0) CLR_INT (TTI);
else if ((tti_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
SET_INT (TTI);
tti_csr = (tti_csr & ~TTICSR_RW) | (data & TTICSR_RW);
return SCPE_OK;
case 01: /* tti buf */
return SCPE_OK; } /* end switch PA */
switch ((PA >> 1) & 01) { /* decode PA<1> */
case 00: /* tti csr */
if (PA & 1) return SCPE_OK;
if ((data & CSR_IE) == 0) CLR_INT (TTI);
else if ((tti_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
SET_INT (TTI);
tti_csr = (tti_csr & ~TTICSR_RW) | (data & TTICSR_RW);
return SCPE_OK;
case 01: /* tti buf */
return SCPE_OK;
} /* end switch PA */
return SCPE_NXM;
}
@@ -254,9 +277,9 @@ t_stat tti_svc (UNIT *uptr)
{
int32 c;
sim_activate (&tti_unit, tti_unit.wait); /* continue poll */
if ((c = sim_poll_kbd ()) < SCPE_KFLAG) return c; /* no char or error? */
if (c & SCPE_BREAK) tti_unit.buf = 0; /* break? */
sim_activate (&tti_unit, tti_unit.wait); /* continue poll */
if ((c = sim_poll_kbd ()) < SCPE_KFLAG) return c; /* no char or error? */
if (c & SCPE_BREAK) tti_unit.buf = 0; /* break? */
else tti_unit.buf = c & ((tti_unit.flags & UNIT_8B)? 0377: 0177);
tti_unit.pos = tti_unit.pos + 1;
tti_csr = tti_csr | CSR_DONE;
@@ -271,40 +294,48 @@ t_stat tti_reset (DEVICE *dptr)
tti_unit.buf = 0;
tti_csr = 0;
CLR_INT (TTI);
sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
return SCPE_OK;
}
/* Terminal output address routines */
t_stat tto_rd (int32 *data, int32 PA, int32 access)
{
switch ((PA >> 1) & 01) { /* decode PA<1> */
case 00: /* tto csr */
*data = tto_csr & TTOCSR_IMP;
return SCPE_OK;
case 01: /* tto buf */
*data = tto_unit.buf;
return SCPE_OK; } /* end switch PA */
switch ((PA >> 1) & 01) { /* decode PA<1> */
case 00: /* tto csr */
*data = tto_csr & TTOCSR_IMP;
return SCPE_OK;
case 01: /* tto buf */
*data = tto_unit.buf;
return SCPE_OK;
} /* end switch PA */
return SCPE_NXM;
}
t_stat tto_wr (int32 data, int32 PA, int32 access)
{
switch ((PA >> 1) & 01) { /* decode PA<1> */
case 00: /* tto csr */
if (PA & 1) return SCPE_OK;
if ((data & CSR_IE) == 0) CLR_INT (TTO);
else if ((tto_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
SET_INT (TTO);
tto_csr = (tto_csr & ~TTOCSR_RW) | (data & TTOCSR_RW);
return SCPE_OK;
case 01: /* tto buf */
if ((PA & 1) == 0) tto_unit.buf = data & 0377;
tto_csr = tto_csr & ~CSR_DONE;
CLR_INT (TTO);
sim_activate (&tto_unit, tto_unit.wait);
return SCPE_OK; } /* end switch PA */
switch ((PA >> 1) & 01) { /* decode PA<1> */
case 00: /* tto csr */
if (PA & 1) return SCPE_OK;
if ((data & CSR_IE) == 0) CLR_INT (TTO);
else if ((tto_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
SET_INT (TTO);
tto_csr = (tto_csr & ~TTOCSR_RW) | (data & TTOCSR_RW);
return SCPE_OK;
case 01: /* tto buf */
if ((PA & 1) == 0) tto_unit.buf = data & 0377;
tto_csr = tto_csr & ~CSR_DONE;
CLR_INT (TTO);
sim_activate (&tto_unit, tto_unit.wait);
return SCPE_OK;
} /* end switch PA */
return SCPE_NXM;
}
@@ -316,9 +347,10 @@ 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 */
if ((r = sim_putchar_s (c)) != SCPE_OK) { /* output; error? */
sim_activate (uptr, uptr->wait); /* try again */
return ((r == SCPE_STALL)? SCPE_OK: r); /* !stall? report */
}
tto_csr = tto_csr | CSR_DONE;
if (tto_csr & CSR_IE) SET_INT (TTO);
tto_unit.pos = tto_unit.pos + 1;
@@ -332,7 +364,7 @@ t_stat tto_reset (DEVICE *dptr)
tto_unit.buf = 0;
tto_csr = CSR_DONE;
CLR_INT (TTO);
sim_cancel (&tto_unit); /* deactivate unit */
sim_cancel (&tto_unit); /* deactivate unit */
return SCPE_OK;
}
@@ -342,34 +374,34 @@ tti_unit.flags = (tti_unit.flags & ~UNIT_8B) | val;
tto_unit.flags = (tto_unit.flags & ~UNIT_8B) | val;
return SCPE_OK;
}
/* The line time clock has a few twists and turns through the history of 11's
LSI-11 no CSR
LSI-11/23 (KDF11A) no CSR
PDP-11/23+ (KDF11B) no monitor bit
PDP-11/24 (KDF11U) monitor bit clears on IAK
LSI-11 no CSR
LSI-11/23 (KDF11A) no CSR
PDP-11/23+ (KDF11B) no monitor bit
PDP-11/24 (KDF11U) monitor bit clears on IAK
*/
/* Clock I/O address routines */
t_stat clk_rd (int32 *data, int32 PA, int32 access)
{
if (clk_fnxm) return SCPE_NXM; /* not there??? */
if (CPUT (HAS_LTCM)) *data = clk_csr & CLKCSR_IMP; /* monitor bit? */
else *data = clk_csr & (CLKCSR_IMP & ~CSR_DONE); /* no, just IE */
if (clk_fnxm) return SCPE_NXM; /* not there??? */
if (CPUT (HAS_LTCM)) *data = clk_csr & CLKCSR_IMP; /* monitor bit? */
else *data = clk_csr & (CLKCSR_IMP & ~CSR_DONE); /* no, just IE */
return SCPE_OK;
}
t_stat clk_wr (int32 data, int32 PA, int32 access)
{
if (clk_fnxm) return SCPE_NXM; /* not there??? */
if (clk_fnxm) return SCPE_NXM; /* not there??? */
if (PA & 1) return SCPE_OK;
clk_csr = (clk_csr & ~CLKCSR_RW) | (data & CLKCSR_RW);
if (CPUT (HAS_LTCM) && ((data & CSR_DONE) == 0)) /* monitor bit? */
clk_csr = clk_csr & ~CSR_DONE; /* clr if zero */
if ((((clk_csr & CSR_IE) == 0) && !clk_fie) || /* unless IE+DONE */
((clk_csr & CSR_DONE) == 0)) CLR_INT (CLK); /* clr intr */
if (CPUT (HAS_LTCM) && ((data & CSR_DONE) == 0)) /* monitor bit? */
clk_csr = clk_csr & ~CSR_DONE; /* clr if zero */
if ((((clk_csr & CSR_IE) == 0) && !clk_fie) || /* unless IE+DONE */
((clk_csr & CSR_DONE) == 0)) CLR_INT (CLK); /* clr intr */
return SCPE_OK;
}
@@ -379,12 +411,12 @@ t_stat clk_svc (UNIT *uptr)
{
int32 t;
clk_csr = clk_csr | CSR_DONE; /* set done */
clk_csr = clk_csr | CSR_DONE; /* set done */
if ((clk_csr & CSR_IE) || clk_fie) SET_INT (CLK);
t = sim_rtcn_calb (clk_tps, TMR_CLK); /* calibrate clock */
sim_activate (&clk_unit, t); /* reactivate unit */
tmr_poll = t; /* set timer poll */
tmxr_poll = t; /* set mux poll */
t = sim_rtcn_calb (clk_tps, TMR_CLK); /* calibrate clock */
sim_activate (&clk_unit, t); /* reactivate unit */
tmr_poll = t; /* set timer poll */
tmxr_poll = t; /* set mux poll */
return SCPE_OK;
}
@@ -400,14 +432,14 @@ return clk_dib.vec;
t_stat clk_reset (DEVICE *dptr)
{
if (CPUT (HAS_LTCR)) clk_fie = clk_fnxm = 0; /* reg there? */
else clk_fie = clk_fnxm = 1; /* no, BEVENT */
clk_tps = clk_default; /* set default tps */
clk_csr = CSR_DONE; /* set done */
if (CPUT (HAS_LTCR)) clk_fie = clk_fnxm = 0; /* reg there? */
else clk_fie = clk_fnxm = 1; /* no, BEVENT */
clk_tps = clk_default; /* set default tps */
clk_csr = CSR_DONE; /* set done */
CLR_INT (CLK);
sim_activate (&clk_unit, clk_unit.wait); /* activate unit */
tmr_poll = clk_unit.wait; /* set timer poll */
tmxr_poll = clk_unit.wait; /* set mux poll */
sim_activate (&clk_unit, clk_unit.wait); /* activate unit */
tmr_poll = clk_unit.wait; /* set timer poll */
tmxr_poll = clk_unit.wait; /* set mux poll */
return SCPE_OK;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/* pdp11_uqssp.h: Unibus/Qbus storage systems port definitions file
Copyright (c) 2001-2004, Robert M Supnik
Copyright (c) 2001-2005, Robert M Supnik
Derived from work by Stephen F. Shirron
Permission is hereby granted, free of charge, to any person obtaining a
@@ -20,15 +20,15 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not 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.
30-Aug-02 RMS Added TMSCP support
30-Aug-02 RMS Added TMSCP support
*/
#ifndef _PDP11_UQSSP_H_
#define _PDP11_UQSSP_H_ 0
#define _PDP11_UQSSP_H_ 0
/* IP register - initialization and polling
@@ -42,128 +42,128 @@
write - host startup information, purge complete
*/
#define SA_ER 0x8000 /* error */
#define SA_S4 0x4000 /* init step 4 */
#define SA_S3 0x2000 /* init step 3 */
#define SA_S2 0x1000 /* init step 2 */
#define SA_S1 0x0800 /* init step 1 */
#define SA_ER 0x8000 /* error */
#define SA_S4 0x4000 /* init step 4 */
#define SA_S3 0x2000 /* init step 3 */
#define SA_S2 0x1000 /* init step 2 */
#define SA_S1 0x0800 /* init step 1 */
/* Init step 1, controller to host */
#define SA_S1C_NV 0x0400 /* fixed vec NI */
#define SA_S1C_Q22 0x0200 /* Q22 device */
#define SA_S1C_DI 0x0100 /* ext diags */
#define SA_S1C_OD 0x0080 /* odd addrs NI */
#define SA_S1C_MP 0x0040 /* mapping */
#define SA_S1C_SM 0x0020 /* spec fncs NI */
#define SA_S1C_CN 0x0010 /* node name NI */
#define SA_S1C_NV 0x0400 /* fixed vec NI */
#define SA_S1C_Q22 0x0200 /* Q22 device */
#define SA_S1C_DI 0x0100 /* ext diags */
#define SA_S1C_OD 0x0080 /* odd addrs NI */
#define SA_S1C_MP 0x0040 /* mapping */
#define SA_S1C_SM 0x0020 /* spec fncs NI */
#define SA_S1C_CN 0x0010 /* node name NI */
/* Init step 1, host to controller */
#define SA_S1H_VL 0x8000 /* valid */
#define SA_S1H_WR 0x4000 /* wrap mode */
#define SA_S1H_V_CQ 11 /* cmd q len */
#define SA_S1H_M_CQ 0x7
#define SA_S1H_V_RQ 8 /* resp q len */
#define SA_S1H_M_RQ 0x7
#define SA_S1H_IE 0x0080 /* int enb */
#define SA_S1H_VEC 0x007F /* vector */
#define SA_S1H_CQ(x) (1 << (((x) >> SA_S1H_V_CQ) & SA_S1H_M_CQ))
#define SA_S1H_RQ(x) (1 << (((x) >> SA_S1H_V_RQ) & SA_S1H_M_RQ))
#define SA_S1H_VL 0x8000 /* valid */
#define SA_S1H_WR 0x4000 /* wrap mode */
#define SA_S1H_V_CQ 11 /* cmd q len */
#define SA_S1H_M_CQ 0x7
#define SA_S1H_V_RQ 8 /* resp q len */
#define SA_S1H_M_RQ 0x7
#define SA_S1H_IE 0x0080 /* int enb */
#define SA_S1H_VEC 0x007F /* vector */
#define SA_S1H_CQ(x) (1 << (((x) >> SA_S1H_V_CQ) & SA_S1H_M_CQ))
#define SA_S1H_RQ(x) (1 << (((x) >> SA_S1H_V_RQ) & SA_S1H_M_RQ))
/* Init step 2, controller to host */
#define SA_S2C_PT 0x0000 /* port type */
#define SA_S2C_V_EC 8 /* info to echo */
#define SA_S2C_M_EC 0xFF
#define SA_S2C_EC(x) (((x) >> SA_S2C_V_EC) & SA_S2C_M_EC)
#define SA_S2C_PT 0x0000 /* port type */
#define SA_S2C_V_EC 8 /* info to echo */
#define SA_S2C_M_EC 0xFF
#define SA_S2C_EC(x) (((x) >> SA_S2C_V_EC) & SA_S2C_M_EC)
/* Init step 2, host to controller */
#define SA_S2H_CLO 0xFFFE /* comm addr lo */
#define SA_S2H_PI 0x0001 /* adp prg int */
#define SA_S2H_CLO 0xFFFE /* comm addr lo */
#define SA_S2H_PI 0x0001 /* adp prg int */
/* Init step 3, controller to host */
#define SA_S3C_V_EC 0 /* info to echo */
#define SA_S3C_M_EC 0xFF
#define SA_S3C_EC(x) (((x) >> SA_S3C_V_EC) & SA_S3C_M_EC)
#define SA_S3C_V_EC 0 /* info to echo */
#define SA_S3C_M_EC 0xFF
#define SA_S3C_EC(x) (((x) >> SA_S3C_V_EC) & SA_S3C_M_EC)
/* Init step 3, host to controller */
#define SA_S3H_PP 0x8000 /* purge, poll test */
#define SA_S3H_CHI 0x7FFF /* comm addr hi */
#define SA_S3H_PP 0x8000 /* purge, poll test */
#define SA_S3H_CHI 0x7FFF /* comm addr hi */
/* Init step 4, controller to host */
#define SA_S4C_V_MOD 4 /* adapter # */
#define SA_S4C_V_VER 0 /* version # */
#define SA_S4C_V_MOD 4 /* adapter # */
#define SA_S4C_V_VER 0 /* version # */
/* Init step 4, host to controller */
#define SA_S4H_CS 0x0400 /* host scrpad NI */
#define SA_S4H_NN 0x0200 /* snd node name NI */
#define SA_S4H_SF 0x0100 /* spec fnc NI */
#define SA_S4H_LF 0x0002 /* send last fail */
#define SA_S4H_GO 0x0001 /* go */
#define SA_S4H_CS 0x0400 /* host scrpad NI */
#define SA_S4H_NN 0x0200 /* snd node name NI */
#define SA_S4H_SF 0x0100 /* spec fnc NI */
#define SA_S4H_LF 0x0002 /* send last fail */
#define SA_S4H_GO 0x0001 /* go */
/* Fatal error codes (generic through 32) */
#define PE_PRE 1 /* packet read err */
#define PE_PWE 2 /* packet write err */
#define PE_QRE 6 /* queue read err */
#define PE_QWE 7 /* queue write err */
#define PE_HAT 9 /* host access tmo */
#define PE_ICI 14 /* inv conn ident */
#define PE_PIE 20 /* prot incompat */
#define PE_PPF 21 /* prg/poll err */
#define PE_MRE 22 /* map reg rd err */
#define PE_T11 475 /* T11 err NI */
#define PE_SND 476 /* SND err NI */
#define PE_RCV 477 /* RCV err NI */
#define PE_NSR 478 /* no such rsrc */
#define PE_PRE 1 /* packet read err */
#define PE_PWE 2 /* packet write err */
#define PE_QRE 6 /* queue read err */
#define PE_QWE 7 /* queue write err */
#define PE_HAT 9 /* host access tmo */
#define PE_ICI 14 /* inv conn ident */
#define PE_PIE 20 /* prot incompat */
#define PE_PPF 21 /* prg/poll err */
#define PE_MRE 22 /* map reg rd err */
#define PE_T11 475 /* T11 err NI */
#define PE_SND 476 /* SND err NI */
#define PE_RCV 477 /* RCV err NI */
#define PE_NSR 478 /* no such rsrc */
/* Comm region offsets */
#define SA_COMM_QQ -8 /* unused */
#define SA_COMM_PI -6 /* purge int */
#define SA_COMM_CI -4 /* cmd int */
#define SA_COMM_RI -2 /* resp int */
#define SA_COMM_MAX ((4 << SA_S1H_M_CQ) + (4 << SA_S1H_M_RQ) - SA_COMM_QQ)
#define SA_COMM_QQ -8 /* unused */
#define SA_COMM_PI -6 /* purge int */
#define SA_COMM_CI -4 /* cmd int */
#define SA_COMM_RI -2 /* resp int */
#define SA_COMM_MAX ((4 << SA_S1H_M_CQ) + (4 << SA_S1H_M_RQ) - SA_COMM_QQ)
/* Command/response rings */
struct uq_ring {
int32 ioff; /* intr offset */
uint32 ba; /* base addr */
uint32 lnt; /* size in bytes */
uint32 idx; /* current index */
};
int32 ioff; /* intr offset */
uint32 ba; /* base addr */
uint32 lnt; /* size in bytes */
uint32 idx; /* current index */
};
/* Ring descriptor entry */
#define UQ_DESC_OWN 0x80000000 /* ownership */
#define UQ_DESC_F 0x40000000 /* flag */
#define UQ_ADDR 0x003FFFFE /* addr, word aligned */
#define UQ_DESC_OWN 0x80000000 /* ownership */
#define UQ_DESC_F 0x40000000 /* flag */
#define UQ_ADDR 0x003FFFFE /* addr, word aligned */
/* Packet header */
#define UQ_HDR_OFF -4 /* offset */
#define UQ_HDR_OFF -4 /* offset */
#define UQ_HLNT 0 /* length */
#define UQ_HCTC 1 /* credits, type, CID */
#define UQ_HLNT 0 /* length */
#define UQ_HCTC 1 /* credits, type, CID */
#define UQ_HCTC_V_CR 0 /* credits */
#define UQ_HCTC_M_CR 0xF
#define UQ_HCTC_V_TYP 4 /* type */
#define UQ_HCTC_M_TYP 0xF
#define UQ_TYP_SEQ 0 /* sequential */
#define UQ_TYP_DAT 1 /* datagram */
#define UQ_HCTC_V_CID 8 /* conn ID */
#define UQ_HCTC_M_CID 0xFF
#define UQ_CID_MSCP 0 /* MSCP */
#define UQ_CID_TMSCP 1 /* TMSCP */
#define UQ_CID_DUP 2 /* DUP */
#define UQ_CID_DIAG 0xFF /* diagnostic */
#define UQ_HCTC_V_CR 0 /* credits */
#define UQ_HCTC_M_CR 0xF
#define UQ_HCTC_V_TYP 4 /* type */
#define UQ_HCTC_M_TYP 0xF
#define UQ_TYP_SEQ 0 /* sequential */
#define UQ_TYP_DAT 1 /* datagram */
#define UQ_HCTC_V_CID 8 /* conn ID */
#define UQ_HCTC_M_CID 0xFF
#define UQ_CID_MSCP 0 /* MSCP */
#define UQ_CID_TMSCP 1 /* TMSCP */
#define UQ_CID_DUP 2 /* DUP */
#define UQ_CID_DIAG 0xFF /* diagnostic */
#endif

View File

@@ -1,6 +1,6 @@
/* pdp11_vh.c: DHQ11 asynchronous terminal multiplexor simulator
Copyright (c) 2004, John A. Dundas III
Copyright (c) 2004-2005, John A. Dundas III
Portions derived from work by Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
@@ -20,31 +20,32 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of the Author shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of the Author shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the Author.
vh DHQ11 asynch multiplexor for SIMH
vh DHQ11 asynch multiplexor for SIMH
12-Jun-04 RMS Repair MS2SIMH macro to avoid possible divide by
0 bug.
8-Jun-04 JAD Repair vh_dev initialization; remove unused
variables, cast to avoid conversion confusion.
7-Jun-04 JAD Complete function prototypes of forward declarations.
Repair broken prototypes of vh_rd() and vh_wr().
Explicitly size integer declarations.
07-Jul-05 RMS Removed extraneous externs
15-Jun-05 RMS Revised for new autoconfigure interface
Fixed bug in vector display routine
12-Jun-04 RMS Repair MS2SIMH macro to avoid divide by 0 bug
08-Jun-04 JAD Repair vh_dev initialization; remove unused
variables, cast to avoid conversion confusion
07-Jun-04 JAD Complete function prototypes of forward declarations.
Repair broken prototypes of vh_rd() and vh_wr()
Explicitly size integer declarations
4-Jun-04 JAD Preliminary code: If operating in a PDP-11 Unibus
environment, force DHU mode.
29-May-04 JAD Make certain RX.TIMER is within allowable range.
25-May-04 JAD All time-based operations are scaled by tmxr_poll
units.
23-May-04 JAD Change to fifo_get() and dq_tx_report() to avoid
gratuitous stack manipulation.
20-May-04 JAD Made modem control and auto-hangup unit flags
19-May-04 JAD Fix problem with modem status where the line number
environment, force DHU mode
29-May-04 JAD Make certain RX.TIMER is within allowable range
25-May-04 JAD All time-based operations are scaled by tmxr_poll units
23-May-04 JAD Change to fifo_get() and dq_tx_report() to avoid
gratuitous stack manipulation
20-May-04 JAD Made modem control and auto-hangup unit flags
19-May-04 JAD Fix problem with modem status where the line number
was not being included
12-May-04 JAD Revised for updated tmxr interfaces
28-Jan-04 JAD Original creation and testing
12-May-04 JAD Revised for updated tmxr interfaces
28-Jan-04 JAD Original creation and testing
I/O Page Registers
@@ -57,18 +58,16 @@ Priority: BR4
Rank: 32
*/
/* MANY constants needed! */
/* MANY constants needed! */
#if defined (VM_VAX)
#include "vax_defs.h"
extern int32 int_req[IPL_HLVL];
extern int32 int_vec[IPL_HLVL][32];
#endif
#if defined (VM_PDP11)
#include "pdp11_defs.h"
extern int32 int_req[IPL_HLVL];
extern int32 int_vec[IPL_HLVL][32];
extern int32 cpu_opt;
#endif
@@ -235,7 +234,7 @@ extern FILE *sim_log;
#define LOOP_NONE (0)
#define LOOP_H325 (1)
#define LOOP_H3101 (2) /* p.2-13 DHQ manual */
/* Local storage */
/* Local storage */
static uint16 vh_csr[VH_MUXES] = { 0 }; /* CSRs */
static uint16 vh_timer[VH_MUXES] = { 1 }; /* controller timeout */
@@ -281,7 +280,7 @@ static TMLN vh_ldsc[VH_MUXES * VH_LINES] = { 0 };
static TMXR vh_desc = { VH_MUXES * VH_LINES, 0, 0, vh_ldsc };
static TMLX vh_parm[VH_MUXES * VH_LINES] = { 0 };
/* Forward references */
/* Forward references */
static t_stat vh_rd (int32 *data, int32 PA, int32 access);
static t_stat vh_wr (int32 data, int32 PA, int32 access);
static t_stat vh_svc (UNIT *uptr);
@@ -302,7 +301,7 @@ static t_stat vh_summ (FILE *st, UNIT *uptr, int32 val, void *desc);
int32 tmxr_send_buffered_data (TMLN *lp);
/* SIMH I/O Structures */
/* SIMH I/O Structures */
static DIB vh_dib = {
IOBA_VH,
@@ -386,7 +385,7 @@ DEVICE vh_dev = {
DEV_FLTA | DEV_DISABLE | DEV_NET | DEV_QBUS | DEV_UBUS, /* flags */
};
/* Interrupt routines */
/* Interrupt routines */
static void vh_clr_rxint ( int32 vh )
{
@@ -447,7 +446,7 @@ static int32 vh_txinta (void)
}
return (0);
}
/* RX FIFO get/put routines */
/* RX FIFO get/put routines */
/* return 0 on success, -1 on FIFO overflow */
@@ -574,7 +573,7 @@ static int32 fifo_get ( int32 vh )
}
return (data & 0177777);
}
/* TX Q manipulation */
/* TX Q manipulation */
static int32 dq_tx_report ( int32 vh )
{
@@ -603,7 +602,7 @@ static void q_tx_report ( int32 vh,
vh_txq[vh][txq_idx[vh]] = CSR_TX_ACTION | data;
txq_idx[vh] += 1;
}
/* Channel get/put routines */
/* Channel get/put routines */
static void HangupModem ( int32 vh,
TMLX *lp,
@@ -692,7 +691,7 @@ static void vh_getc ( int32 vh )
}
}
/* I/O dispatch routines */
/* I/O dispatch routines */
static t_stat vh_rd ( int32 *data,
int32 PA,
@@ -775,7 +774,7 @@ fprintf (stderr, "\rtqln %d\n", 64 - tmxr_tqln (lp->tmln));
}
return (SCPE_OK);
}
static t_stat vh_wr ( int32 data,
int32 PA,
int32 access )
@@ -1039,7 +1038,7 @@ static t_stat vh_wr ( int32 data,
}
return (SCPE_OK);
}
static void doDMA ( int32 vh,
int32 chan )
{
@@ -1133,7 +1132,7 @@ static t_stat vh_svc ( UNIT *uptr )
return (SCPE_OK);
}
/* init a channel on a controller */
/* init a channel on a controller */
/* set for:
send/receive 9600
@@ -1250,10 +1249,10 @@ static t_stat vh_reset ( DEVICE *dptr )
CLR_INT (VHTX);
for (i = 0; i < VH_MUXES; i++)
sim_cancel (&vh_unit[i]);
return (auto_config (RANK_VH, (dptr->flags & DEV_DIS) ? 0 : VH_MUXES));
return (auto_config (dptr->name, (dptr->flags & DEV_DIS) ? 0 : VH_MUXES));
}
static t_stat vh_attach ( UNIT *uptr,
char *cptr )
{
@@ -1298,7 +1297,7 @@ static t_stat vh_show_vec ( FILE *st,
int32 val,
void *desc )
{
return (show_vec (st, uptr, val, desc));
return (show_vec (st, uptr, ((vh_desc.lines * 2) / VH_LINES), desc));
}
static void debug_line ( FILE *st,

View File

@@ -1,7 +1,7 @@
/* pdp11_xq.c: DEQNA/DELQA ethernet controller simulator
------------------------------------------------------------------------------
Copyright (c) 2002-2004, David T. Hittner
Copyright (c) 2002-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"),
@@ -66,6 +66,9 @@
Modification history:
07-Sep-05 DTH Removed unused variable
16-Aug-05 RMS Fixed C++ declaration and cast problems
01-Dec-04 DTH Added runtime attach prompt
27-Feb-04 DTH Removed struct timeb deuggers
31-Jan-04 DTH Replaced #ifdef debuggers with inline debugging
19-Jan-04 DTH Combined service timers into one for efficiency
@@ -206,6 +209,7 @@
extern int32 tmr_poll, clk_tps;
extern FILE* sim_deb;
extern char* read_line (char *ptr, int32 size, FILE *stream);
/* forward declarations */
t_stat xq_rd(int32* data, int32 PA, int32 access);
@@ -1869,14 +1873,25 @@ t_stat xq_attach(UNIT* uptr, char* cptr)
t_stat status;
char* tptr;
CTLR* xq = xq_unit2ctlr(uptr);
char buffer[80]; /* buffer for runtime input */
sim_debug(DBG_TRC, xq->dev, "xq_attach(cptr=%s)\n", cptr);
tptr = malloc(strlen(cptr) + 1);
/* runtime selection of ethernet port? */
if (*cptr == '?') { /* I/O style derived from main() */
memset (buffer, 0, sizeof(buffer)); /* clear read buffer */
eth_show (stdout, uptr, 0, NULL); /* show ETH devices */
printf ("Select device (ethX or <device_name>)? "); /* prompt for device */
cptr = read_line (buffer, sizeof(buffer), stdin); /* read command line */
if (cptr == NULL) return SCPE_ARG; /* ignore EOF */
if (*cptr == 0) return SCPE_ARG; /* ignore blank */
} /* resume attaching */
tptr = (char *) malloc(strlen(cptr) + 1);
if (tptr == NULL) return SCPE_MEM;
strcpy(tptr, cptr);
xq->var->etherface = malloc(sizeof(ETH_DEV));
xq->var->etherface = (ETH_DEV *) malloc(sizeof(ETH_DEV));
if (!xq->var->etherface) return SCPE_MEM;
status = eth_open(xq->var->etherface, cptr, xq->dev, DBG_ETH);
@@ -1906,7 +1921,7 @@ t_stat xq_detach(UNIT* uptr)
sim_debug(DBG_TRC, xq->dev, "xq_detach()\n");
if (uptr->flags & UNIT_ATT) {
t_stat status = eth_close (xq->var->etherface);
eth_close (xq->var->etherface);
free(xq->var->etherface);
xq->var->etherface = 0;
free(uptr->filename);

View File

@@ -1,7 +1,7 @@
/* pdp11_xq.h: DEQNA/DELQA ethernet controller information
------------------------------------------------------------------------------
Copyright (c) 2002-2004, David T. Hittner
Copyright (c) 2002-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:
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
09-Jan-04 DTH Added Boot PDP diagnostic definition, XI/RI combination
@@ -56,67 +57,65 @@
#ifndef _PDP11_XQ_H
#define _PDP11_XQ_H
#if defined (VM_PDP10) /* PDP10 version */
#if defined (VM_PDP10) /* PDP10 version */
#error "DEQNA/DELQA not supported on PDP10!"
#elif defined (VM_VAX) /* VAX version */
#elif defined (VM_VAX) /* VAX version */
#include "vax_defs.h"
#define XQ_RDX 16
#define XQ_WID 32
extern int32 PSL; /* PSL */
extern int32 fault_PC; /* fault PC */
#define XQ_RDX 16
#define XQ_WID 32
extern int32 PSL; /* PSL */
extern int32 fault_PC; /* fault PC */
extern int32 int_req[IPL_HLVL];
extern int32 int_vec[IPL_HLVL][32];
#else /* PDP-11 version */
#else /* PDP-11 version */
#include "pdp11_defs.h"
#define XQ_RDX 8
#define XQ_WID 16
#define XQ_RDX 8
#define XQ_WID 16
extern int32 int_req[IPL_HLVL];
extern int32 int_vec[IPL_HLVL][32];
#endif
#include "sim_ether.h"
#define XQ_QUE_MAX 500 /* read queue size in packets */
#define XQ_FILTER_MAX 14 /* number of filters allowed */
#define XQ_SERVICE_INTERVAL 100 /* polling interval - X per second */
#define XQ_SYSTEM_ID_SECS 540 /* seconds before system ID timer expires */
#define XQ_HW_SANITY_SECS 240 /* seconds before HW sanity timer expires */
#define XQ_MAX_CONTROLLERS 2 /* maximum controllers allowed */
#define XQ_QUE_MAX 500 /* read queue size in packets */
#define XQ_FILTER_MAX 14 /* number of filters allowed */
#define XQ_SERVICE_INTERVAL 100 /* polling interval - X per second */
#define XQ_SYSTEM_ID_SECS 540 /* seconds before system ID timer expires */
#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};
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 */
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 */
};
struct xq_setup {
int valid; /* is the setup block valid? */
int promiscuous; /* promiscuous mode enabled */
int multicast; /* enable all multicast addresses */
int l1; /* first diagnostic led state */
int l2; /* second diagnostic led state */
int l3; /* third diagnostic led state */
int sanity_timer; /* sanity timer value (encoded) */
ETH_MAC macs[XQ_FILTER_MAX]; /* MAC addresses to respond to */
int valid; /* is the setup block valid? */
int promiscuous; /* promiscuous mode enabled */
int multicast; /* enable all multicast addresses */
int l1; /* first diagnostic led state */
int l2; /* second diagnostic led state */
int l3; /* third diagnostic led state */
int sanity_timer; /* sanity timer value (encoded) */
ETH_MAC macs[XQ_FILTER_MAX]; /* MAC addresses to respond to */
};
struct xq_stats {
int recv; /* received packets */
int filter; /* filtered packets */
int xmit; /* transmitted packets */
int fail; /* transmit failed */
int runt; /* runts */
int giant; /* oversize packets */
int setup; /* setup packets */
int loop; /* loopback packets */
int recv; /* received packets */
int filter; /* filtered packets */
int xmit; /* transmitted packets */
int fail; /* transmit failed */
int runt; /* runts */
int giant; /* oversize packets */
int setup; /* setup packets */
int loop; /* loopback packets */
};
struct xq_meb { /* MEB block */
struct xq_meb { /* MEB block */
uint8 type;
uint8 add_lo;
uint8 add_mi;
@@ -126,24 +125,24 @@ struct xq_meb { /* MEB block */
};
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 */
enum xq_type type; /* controller type */
int poll; /* poll ethernet times/sec */
struct xq_sanity sanity; /* sanity timer information */
/*- initialized values - DO NOT MOVE */
/*+ initialized values - DO NOT MOVE */
ETH_PCALLBACK rcallback; /* read callback routine */
ETH_PCALLBACK wcallback; /* write callback routine */
ETH_MAC mac; /* MAC address */
enum xq_type type; /* controller type */
int poll; /* poll ethernet times/sec */
struct xq_sanity sanity; /* sanity timer information */
/*- initialized values - DO NOT MOVE */
/* I/O register storage */
/* I/O register storage */
uint16 addr[6];
uint16 rbdl[2];
uint16 xbdl[2];
uint16 var;
uint16 csr;
uint32 irq; /* interrupt request flag */
uint32 irq; /* interrupt request flag */
/* buffers, etc. */
/* buffers, etc. */
struct xq_setup setup;
struct xq_stats stats;
uint8 mac_checksum[2];
@@ -156,79 +155,79 @@ struct xq_device {
ETH_PACK read_buffer;
ETH_PACK write_buffer;
ETH_QUE ReadQ;
int idtmr; /* countdown for ID Timer */
int idtmr; /* countdown for ID Timer */
};
struct xq_controller {
DEVICE* dev; /* device block */
UNIT* unit; /* unit block */
DIB* dib; /* device interface block */
struct xq_device* var; /* controller-specific variables */
DEVICE* dev; /* device block */
UNIT* unit; /* unit block */
DIB* dib; /* device interface block */
struct xq_device* var; /* controller-specific variables */
};
typedef struct xq_controller CTLR;
#define XQ_CSR_RI 0x8000 /* Receive Interrupt Request (RI) [RO/W1] */
#define XQ_CSR_PE 0x4000 /* Parity Error in Host Memory (PE) [RO] */
#define XQ_CSR_CA 0x2000 /* Carrier from Receiver Enabled (CA) [RO] */
#define XQ_CSR_OK 0x1000 /* Ethernet Transceiver Power (OK) [RO] */
#define XQ_CSR_RR 0x0800 /* Reserved : Set to Zero (RR) [RO] */
#define XQ_CSR_SE 0x0400 /* Sanity Timer Enable (SE) [RW] */
#define XQ_CSR_EL 0x0200 /* External Loopback (EL) [RW] */
#define XQ_CSR_IL 0x0100 /* Internal Loopback (IL) [RW] */
#define XQ_CSR_XI 0x0080 /* Transmit Interrupt Request (XI) [RO/W1] */
#define XQ_CSR_IE 0x0040 /* Interrupt Enable (IE) [RW] */
#define XQ_CSR_RL 0x0020 /* Receive List Invalid/Empty (RL) [RO] */
#define XQ_CSR_XL 0x0010 /* Transmit List Invalid/Empty (XL) [RO] */
#define XQ_CSR_BD 0x0008 /* Boot/Diagnostic ROM Load (BD) [RW] */
#define XQ_CSR_NI 0x0004 /* NonExistant Memory Timeout (NXM) [RO] */
#define XQ_CSR_SR 0x0002 /* Software Reset (SR) [RW] */
#define XQ_CSR_RE 0x0001 /* Receiver Enable (RE) [RW] */
#define XQ_CSR_RI 0x8000 /* Receive Interrupt Request (RI) [RO/W1] */
#define XQ_CSR_PE 0x4000 /* Parity Error in Host Memory (PE) [RO] */
#define XQ_CSR_CA 0x2000 /* Carrier from Receiver Enabled (CA) [RO] */
#define XQ_CSR_OK 0x1000 /* Ethernet Transceiver Power (OK) [RO] */
#define XQ_CSR_RR 0x0800 /* Reserved : Set to Zero (RR) [RO] */
#define XQ_CSR_SE 0x0400 /* Sanity Timer Enable (SE) [RW] */
#define XQ_CSR_EL 0x0200 /* External Loopback (EL) [RW] */
#define XQ_CSR_IL 0x0100 /* Internal Loopback (IL) [RW] */
#define XQ_CSR_XI 0x0080 /* Transmit Interrupt Request (XI) [RO/W1] */
#define XQ_CSR_IE 0x0040 /* Interrupt Enable (IE) [RW] */
#define XQ_CSR_RL 0x0020 /* Receive List Invalid/Empty (RL) [RO] */
#define XQ_CSR_XL 0x0010 /* Transmit List Invalid/Empty (XL) [RO] */
#define XQ_CSR_BD 0x0008 /* Boot/Diagnostic ROM Load (BD) [RW] */
#define XQ_CSR_NI 0x0004 /* NonExistant Memory Timeout (NXM) [RO] */
#define XQ_CSR_SR 0x0002 /* Software Reset (SR) [RW] */
#define XQ_CSR_RE 0x0001 /* Receiver Enable (RE) [RW] */
/* special access bitmaps */
#define XQ_CSR_RO 0xF8B4 /* Read-Only bits */
#define XQ_CSR_RW 0x074B /* Read/Write bits */
#define XQ_CSR_W1 0x8080 /* Write-one-to-clear bits */
#define XQ_CSR_BP 0x0208 /* Boot PDP diagnostic ROM */
#define XQ_CSR_XIRI 0X8080 /* Transmit & Receive Interrupts */
#define XQ_CSR_RO 0xF8B4 /* Read-Only bits */
#define XQ_CSR_RW 0x074B /* Read/Write bits */
#define XQ_CSR_W1 0x8080 /* Write-one-to-clear bits */
#define XQ_CSR_BP 0x0208 /* Boot PDP diagnostic ROM */
#define XQ_CSR_XIRI 0X8080 /* Transmit & Receive Interrupts */
#define XQ_VEC_MS 0x8000 /* Mode Select (MO) [RW] */
#define XQ_VEC_OS 0x4000 /* Option Switch Setting (OS) [RO] */
#define XQ_VEC_RS 0x2000 /* Request Self-Test (RS) [RW] */
#define XQ_VEC_S3 0x1000 /* Self-Test Status (S3) [RO] */
#define XQ_VEC_S2 0x0800 /* Self-Test Status (S2) [RO] */
#define XQ_VEC_S1 0x0400 /* Self-Test Status (S1) [RO] */
#define XQ_VEC_ST 0x1C00 /* Self-Test (S1 + S2 + S3) [RO] */
#define XQ_VEC_IV 0x03FC /* Interrupt Vector (IV) [RW] */
#define XQ_VEC_RR 0x0002 /* Reserved (RR) [RO] */
#define XQ_VEC_ID 0x0001 /* Identity Test Bit (ID) [RW] */
#define XQ_VEC_MS 0x8000 /* Mode Select (MO) [RW] */
#define XQ_VEC_OS 0x4000 /* Option Switch Setting (OS) [RO] */
#define XQ_VEC_RS 0x2000 /* Request Self-Test (RS) [RW] */
#define XQ_VEC_S3 0x1000 /* Self-Test Status (S3) [RO] */
#define XQ_VEC_S2 0x0800 /* Self-Test Status (S2) [RO] */
#define XQ_VEC_S1 0x0400 /* Self-Test Status (S1) [RO] */
#define XQ_VEC_ST 0x1C00 /* Self-Test (S1 + S2 + S3) [RO] */
#define XQ_VEC_IV 0x03FC /* Interrupt Vector (IV) [RW] */
#define XQ_VEC_RR 0x0002 /* Reserved (RR) [RO] */
#define XQ_VEC_ID 0x0001 /* Identity Test Bit (ID) [RW] */
/* special access bitmaps */
#define XQ_VEC_RO 0x5C02 /* Read-Only bits */
#define XQ_VEC_RW 0xA3FD /* Read/Write bits */
#define XQ_VEC_RO 0x5C02 /* Read-Only bits */
#define XQ_VEC_RW 0xA3FD /* Read/Write bits */
#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] */
#define XQ_DSC_S 0x1000 /* Setup bit [Transmit only] */
#define XQ_DSC_L 0x0080 /* Low Byte Termination bit [Transmit only] */
#define XQ_DSC_H 0x0040 /* High Byte Start bit [Transmit only] */
#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] */
#define XQ_DSC_S 0x1000 /* Setup bit [Transmit only] */
#define XQ_DSC_L 0x0080 /* Low Byte Termination bit [Transmit only] */
#define XQ_DSC_H 0x0040 /* High Byte Start bit [Transmit only] */
#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 */
#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 */
/* debugging bitmaps */
#define DBG_TRC 0x0001 /* trace routine calls */
#define DBG_REG 0x0002 /* trace read/write registers */
#define DBG_CSR 0x0004 /* watch CSR */
#define DBG_VAR 0x0008 /* watch VAR */
#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_ETH 0x8000 /* debug ethernet device */
#define DBG_TRC 0x0001 /* trace routine calls */
#define DBG_REG 0x0002 /* trace read/write registers */
#define DBG_CSR 0x0004 /* watch CSR */
#define DBG_VAR 0x0008 /* watch VAR */
#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_ETH 0x8000 /* debug ethernet device */
#endif /* _PDP11_XQ_H */
#endif /* _PDP11_XQ_H */

View File

@@ -1,7 +1,7 @@
/* pdp11_xq_bootrom.h: DEQNA/DELQA bootrom data
------------------------------------------------------------------------------
Copyright (c) 2003, 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"),
@@ -307,6 +307,6 @@
0000000,0000000,0000000,0000000,0000000,0000000,0000000,0000000,
0000000,0000000,0000000,0000000,0000000,0000000,0000000,0102206
};
#endif /* VM_PDP11 */
#endif /* VM_PDP11 */
#endif /* _PDP11_XQ_BOOTROM_H */
#endif /* _PDP11_XQ_BOOTROM_H */

View File

@@ -52,6 +52,9 @@
Modification history:
07-Sep-05 DTH Corrected runt packet processing (found by Tim Chapman),
Removed unused variable
16-Aug-05 RMS Fixed C++ declaration and cast problems
10-Mar-05 RMS Fixed equality test in RCSTAT (from Mark Hittinger)
16-Jan-04 DTH Added more info to SHOW MOD commands
09-Jan-04 DTH Made XU floating address so that XUB will float correctly
@@ -971,7 +974,6 @@ void xu_process_transmit(CTLR* xu)
uint32 segb, ba;
int slen, wlen, i, off, giant, runt;
t_stat rstatus, wstatus;
const ETH_MAC zeros = {0, 0, 0, 0, 0, 0};
sim_debug(DBG_TRC, xu->dev, "xu_process_transmit()\n");
@@ -1023,9 +1025,10 @@ void xu_process_transmit(CTLR* xu)
if (xu->var->txhdr[2] & TXR_ENF) {
/* make sure packet is minimum length */
if ((xu->var->write_buffer.len < ETH_MIN_PACKET) && (xu->var->mode & MODE_TPAD)) {
xu->var->write_buffer.len = ETH_MIN_PACKET;
runt = 1;
if (xu->var->write_buffer.len < ETH_MIN_PACKET) {
xu->var->write_buffer.len = ETH_MIN_PACKET; /* pad packet to minimum length */
if ((xu->var->mode & MODE_TPAD) == 0) /* if pad mode is NOT on, set runt error flag */
runt = 1;
}
/* are we in internal loopback mode ? */
@@ -1297,11 +1300,11 @@ t_stat xu_attach(UNIT* uptr, char* cptr)
CTLR* xu = xu_unit2ctlr(uptr);
sim_debug(DBG_TRC, xu->dev, "xu_attach(cptr=%s)\n", cptr);
tptr = malloc(strlen(cptr) + 1);
tptr = (char *) malloc(strlen(cptr) + 1);
if (tptr == NULL) return SCPE_MEM;
strcpy(tptr, cptr);
xu->var->etherface = malloc(sizeof(ETH_DEV));
xu->var->etherface = (ETH_DEV *) malloc(sizeof(ETH_DEV));
if (!xu->var->etherface) return SCPE_MEM;
status = eth_open(xu->var->etherface, cptr, xu->dev, DBG_ETH);

View File

@@ -1,7 +1,7 @@
/* pdp11_xu.h: DEUNA/DELUA ethernet controller information
------------------------------------------------------------------------------
Copyright (c) 2003-2004, 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:
07-Jul-05 RMS Removed extraneous externs
05-Jan-04 DTH Added network statistics
31-Dec-03 DTH Added reserved states
28-Dec-03 DTH Corrected MODE bitmasks
@@ -42,43 +43,40 @@
#define _PDP11_XU_H
#if defined (VM_PDP10) /* PDP10 version */
#if defined (VM_PDP10) /* PDP10 version */
#include "pdp10_defs.h"
#define XU_RDX 8
#define XU_WID 16
#define XU_RDX 8
#define XU_WID 16
extern int32 int_req;
extern int32 int_vec[32];
#elif defined (VM_VAX) /* VAX version */
#elif defined (VM_VAX) /* VAX version */
#include "vax_defs.h"
#define XU_RDX 8
#define XU_WID 16
#define XU_RDX 8
#define XU_WID 16
extern int32 int_req[IPL_HLVL];
extern int32 int_vec[IPL_HLVL][32];
#else /* PDP-11 version */
#else /* PDP-11 version */
#include "pdp11_defs.h"
#define XU_RDX 8
#define XU_WID 16
#define XU_RDX 8
#define XU_WID 16
extern int32 int_req[IPL_HLVL];
extern int32 int_vec[IPL_HLVL][32];
#endif /* VM_PDP10 */
#endif /* VM_PDP10 */
#include "sim_ether.h"
#define XU_QUE_MAX 500 /* message queue array */
#define XU_FILTER_MAX 11 /* mac + 10 multicast addrs */
#define XU_SERVICE_INTERVAL 100 /* times per second */
#define XU_ID_TIMER_VAL 540 /* 9 min * 60 sec */
#define UDBSIZE 100 /* max size of UDB (in words) */
#define XU_QUE_MAX 500 /* message queue array */
#define XU_FILTER_MAX 11 /* mac + 10 multicast addrs */
#define XU_SERVICE_INTERVAL 100 /* times per second */
#define XU_ID_TIMER_VAL 540 /* 9 min * 60 sec */
#define UDBSIZE 100 /* max size of UDB (in words) */
enum xu_type {XU_T_DEUNA, XU_T_DELUA};
struct xu_setup {
int promiscuous; /* promiscuous mode enabled */
int multicast; /* enable all multicast addresses */
int mac_count; /* number of multicast mac addresses */
ETH_MAC macs[XU_FILTER_MAX]; /* MAC addresses to respond to */
int promiscuous; /* promiscuous mode enabled */
int multicast; /* enable all multicast addresses */
int mac_count; /* number of multicast mac addresses */
ETH_MAC macs[XU_FILTER_MAX]; /* MAC addresses to respond to */
};
/* Network Statistics -
@@ -87,219 +85,219 @@ struct xu_setup {
things like incoming runts, collision tests, babbling, etc.
*/
struct xu_stats {
uint16 secs; /* seconds since last clear */
uint32 frecv; /* frames received */
uint32 mfrecv; /* multicast frames received */
uint16 rxerf; /* receive error flags */
uint32 frecve; /* frames received with errors */
uint32 rbytes; /* data bytes received */
uint32 mrbytes; /* multicast data bytes received */
uint16 rlossi; /* received frames lost - internal err */
uint16 rlossl; /* received frames lost - local buffers */
uint32 ftrans; /* frames transmitted */
uint32 mftrans; /* multicast frames transmitted */
uint32 ftrans3; /* frames transmitted with 3+ tries */
uint32 ftrans2; /* frames transmitted - two tries */
uint32 ftransd; /* frames transmitted - deferred */
uint32 tbytes; /* data bytes transmitted */
uint32 mtbytes; /* multicast data bytes transmitted */
uint16 txerf; /* transmit error flags summary */
uint16 ftransa; /* transmit frames aborted */
uint16 txccf; /* transmit collision test failure */
uint16 porterr; /* port driver errors */
uint16 bablcnt; /* babble counter */
uint16 secs; /* seconds since last clear */
uint32 frecv; /* frames received */
uint32 mfrecv; /* multicast frames received */
uint16 rxerf; /* receive error flags */
uint32 frecve; /* frames received with errors */
uint32 rbytes; /* data bytes received */
uint32 mrbytes; /* multicast data bytes received */
uint16 rlossi; /* received frames lost - internal err */
uint16 rlossl; /* received frames lost - local buffers */
uint32 ftrans; /* frames transmitted */
uint32 mftrans; /* multicast frames transmitted */
uint32 ftrans3; /* frames transmitted with 3+ tries */
uint32 ftrans2; /* frames transmitted - two tries */
uint32 ftransd; /* frames transmitted - deferred */
uint32 tbytes; /* data bytes transmitted */
uint32 mtbytes; /* multicast data bytes transmitted */
uint16 txerf; /* transmit error flags summary */
uint16 ftransa; /* transmit frames aborted */
uint16 txccf; /* transmit collision test failure */
uint16 porterr; /* port driver errors */
uint16 bablcnt; /* babble counter */
};
struct xu_device {
/*+ initialized values - DO NOT MOVE */
ETH_PCALLBACK rcallback; /* read callback routine */
ETH_PCALLBACK wcallback; /* write callback routine */
ETH_MAC mac; /* MAC address */
enum xu_type type; /* controller type */
/*- initialized values - DO NOT MOVE */
/*+ initialized values - DO NOT MOVE */
ETH_PCALLBACK rcallback; /* read callback routine */
ETH_PCALLBACK wcallback; /* write callback routine */
ETH_MAC mac; /* MAC address */
enum xu_type type; /* controller type */
/*- initialized values - DO NOT MOVE */
/* I/O register storage */
uint32 irq; /* interrupt request flag */
/* I/O register storage */
uint32 irq; /* interrupt request flag */
/* buffers, etc. */
/* buffers, etc. */
ETH_DEV* etherface;
ETH_PACK read_buffer;
ETH_PACK write_buffer;
ETH_QUE ReadQ;
int idtmr; /* countdown for ID Timer */
int sectmr; /* countup for one second timer */
int idtmr; /* countdown for ID Timer */
int sectmr; /* countup for one second timer */
struct xu_setup setup;
struct xu_stats stats; /* reportable network statistics */
struct xu_stats stats; /* reportable network statistics */
/* copied from dec_deuna.h */
uint16 pcsr0; /* primary DEUNA registers */
/* copied from dec_deuna.h */
uint16 pcsr0; /* primary DEUNA registers */
uint16 pcsr1;
uint16 pcsr2;
uint16 pcsr3;
uint32 mode; /* mode register */
uint32 pcbb; /* port command block base */
uint32 stat; /* extended port status */
uint32 mode; /* mode register */
uint32 pcbb; /* port command block base */
uint32 stat; /* extended port status */
uint32 tdrb; /* transmit desc ring base */
uint32 telen; /* transmit desc ring entry len */
uint32 trlen; /* transmit desc ring length */
uint32 txnext; /* transmit buffer pointer */
uint32 rdrb; /* receive desc ring base */
uint32 relen; /* receive desc ring entry len */
uint32 rrlen; /* receive desc ring length */
uint32 rxnext; /* receive buffer pointer */
uint32 tdrb; /* transmit desc ring base */
uint32 telen; /* transmit desc ring entry len */
uint32 trlen; /* transmit desc ring length */
uint32 txnext; /* transmit buffer pointer */
uint32 rdrb; /* receive desc ring base */
uint32 relen; /* receive desc ring entry len */
uint32 rrlen; /* receive desc ring length */
uint32 rxnext; /* receive buffer pointer */
uint16 pcb[4]; /* copy of Port Command Block */
uint16 udb[UDBSIZE]; /* copy of Unibus Data Block */
uint16 rxhdr[4]; /* content of RX ring entry, during wait */
uint16 txhdr[4]; /* content of TX ring entry, during xmit */
uint16 pcb[4]; /* copy of Port Command Block */
uint16 udb[UDBSIZE]; /* copy of Unibus Data Block */
uint16 rxhdr[4]; /* content of RX ring entry, during wait */
uint16 txhdr[4]; /* content of TX ring entry, during xmit */
};
struct xu_controller {
DEVICE* dev; /* device block */
UNIT* unit; /* unit block */
DIB* dib; /* device interface block */
struct xu_device* var; /* controller-specific variables */
DEVICE* dev; /* device block */
UNIT* unit; /* unit block */
DIB* dib; /* device interface block */
struct xu_device* var; /* controller-specific variables */
};
typedef struct xu_controller CTLR;
/* PCSR0 register definitions */
#define PCSR0_SERI 0100000 /* <15> Status Error Intr */
#define PCSR0_PCEI 0040000 /* <14> Port Command Error Intr */
#define PCSR0_RXI 0020000 /* <13> Receive Interrupt */
#define PCSR0_TXI 0010000 /* <12> Transmit Interrupt */
#define PCSR0_DNI 0004000 /* <11> Done Interrupt */
#define PCSR0_RCBI 0002000 /* <10> Recv Buffer Unavail Intr */
#define PCSR0_USCI 0000400 /* <08> Unsolicited State Chg Inter */
#define PCSR0_INTR 0000200 /* <07> Interrupt Summary */
#define PCSR0_INTE 0000100 /* <06> Interrupt Enable */
#define PCSR0_RSET 0000040 /* <05> Reset */
#define PCSR0_PCMD 0000017 /* <03:00> Port Command field */
#define PCSR0_SERI 0100000 /* <15> Status Error Intr */
#define PCSR0_PCEI 0040000 /* <14> Port Command Error Intr */
#define PCSR0_RXI 0020000 /* <13> Receive Interrupt */
#define PCSR0_TXI 0010000 /* <12> Transmit Interrupt */
#define PCSR0_DNI 0004000 /* <11> Done Interrupt */
#define PCSR0_RCBI 0002000 /* <10> Recv Buffer Unavail Intr */
#define PCSR0_USCI 0000400 /* <08> Unsolicited State Chg Inter */
#define PCSR0_INTR 0000200 /* <07> Interrupt Summary */
#define PCSR0_INTE 0000100 /* <06> Interrupt Enable */
#define PCSR0_RSET 0000040 /* <05> Reset */
#define PCSR0_PCMD 0000017 /* <03:00> Port Command field */
/* PCSR0 Port Commands */
#define CMD_NOOP 000 /* No-op */
#define CMD_GETPCBB 001 /* Get PCB base */
#define CMD_GETCMD 002 /* Get Command */
#define CMD_SELFTEST 003 /* Self-test init */
#define CMD_START 004 /* Start xmit/recv */
#define CMD_BOOT 005 /* Boot */
#define CMD_RSV06 006 /* Reserved */
#define CMD_RSV07 007 /* Reserved */
#define CMD_PDMD 010 /* Polling Demand */
#define CMD_RSV11 011 /* Reserved */
#define CMD_RSV12 012 /* Reserved */
#define CMD_RSV13 013 /* Reserved */
#define CMD_RSV14 014 /* Reserved */
#define CMD_RSV15 015 /* Reserved */
#define CMD_HALT 016 /* Halt */
#define CMD_STOP 017 /* Stop */
#define CMD_NOOP 000 /* No-op */
#define CMD_GETPCBB 001 /* Get PCB base */
#define CMD_GETCMD 002 /* Get Command */
#define CMD_SELFTEST 003 /* Self-test init */
#define CMD_START 004 /* Start xmit/recv */
#define CMD_BOOT 005 /* Boot */
#define CMD_RSV06 006 /* Reserved */
#define CMD_RSV07 007 /* Reserved */
#define CMD_PDMD 010 /* Polling Demand */
#define CMD_RSV11 011 /* Reserved */
#define CMD_RSV12 012 /* Reserved */
#define CMD_RSV13 013 /* Reserved */
#define CMD_RSV14 014 /* Reserved */
#define CMD_RSV15 015 /* Reserved */
#define CMD_HALT 016 /* Halt */
#define CMD_STOP 017 /* Stop */
/* PCSR1 register definitions */
#define PCSR1_XPWR 0100000 /* <15> Tranceiver power failure */
#define PCSR1_ICAB 0040000 /* <14> Port/Link cable failure */
#define PCSR1_ECOD 0037400 /* <13:08> Self-test error code */
#define PCSR1_PCTO 0000200 /* <07> Port Command Timeout */
#define PCSR1_TYPE 0000160 /* <06:04> Interface type */
#define PCSR1_STATE 0000017 /* <03:00> State: */
#define PCSR1_XPWR 0100000 /* <15> Tranceiver power failure */
#define PCSR1_ICAB 0040000 /* <14> Port/Link cable failure */
#define PCSR1_ECOD 0037400 /* <13:08> Self-test error code */
#define PCSR1_PCTO 0000200 /* <07> Port Command Timeout */
#define PCSR1_TYPE 0000160 /* <06:04> Interface type */
#define PCSR1_STATE 0000017 /* <03:00> State: */
/* PCSR1 Types */
#define TYPE_DEUNA (0 << 4) /* Controller is a DEUNA */
#define TYPE_DELUA (1 << 4) /* Controller is a DELUA */
#define TYPE_DEUNA (0 << 4) /* Controller is a DEUNA */
#define TYPE_DELUA (1 << 4) /* Controller is a DELUA */
/* PCSR1 States */
#define STATE_RESET 000 /* Reset */
#define STATE_PLOAD 001 /* Primary Load */
#define STATE_READY 002 /* Ready */
#define STATE_RUNNING 003 /* Running */
#define STATE_UHALT 005 /* UNIBUS Halted */
#define STATE_NHALT 006 /* NI Halted */
#define STATE_NUHALT 007 /* NI and UNIBUS Halted */
#define STATE_HALT 010 /* Halted */
#define STATE_SLOAD 017 /* Secondary Load */
#define STATE_RESET 000 /* Reset */
#define STATE_PLOAD 001 /* Primary Load */
#define STATE_READY 002 /* Ready */
#define STATE_RUNNING 003 /* Running */
#define STATE_UHALT 005 /* UNIBUS Halted */
#define STATE_NHALT 006 /* NI Halted */
#define STATE_NUHALT 007 /* NI and UNIBUS Halted */
#define STATE_HALT 010 /* Halted */
#define STATE_SLOAD 017 /* Secondary Load */
/* Status register definitions */
#define STAT_ERRS 0100000 /* <15> error summary */
#define STAT_MERR 0040000 /* <14> multiple errors */
#define STAT_BABL 0020000 /* <13> Transmitter on too long [DELUA only] */
#define STAT_CERR 0010000 /* <12> collision test error */
#define STAT_TMOT 0004000 /* <11> UNIBUS timeout */
#define STAT_RRNG 0001000 /* <09> receive ring error */
#define STAT_TRNG 0000400 /* <08> transmit ring error */
#define STAT_PTCH 0000200 /* <07> ROM patch */
#define STAT_RRAM 0000100 /* <06> running from RAM */
#define STAT_RREV 0000077 /* <05:00> ROM version */
#define STAT_ERRS 0100000 /* <15> error summary */
#define STAT_MERR 0040000 /* <14> multiple errors */
#define STAT_BABL 0020000 /* <13> Transmitter on too long [DELUA only] */
#define STAT_CERR 0010000 /* <12> collision test error */
#define STAT_TMOT 0004000 /* <11> UNIBUS timeout */
#define STAT_RRNG 0001000 /* <09> receive ring error */
#define STAT_TRNG 0000400 /* <08> transmit ring error */
#define STAT_PTCH 0000200 /* <07> ROM patch */
#define STAT_RRAM 0000100 /* <06> running from RAM */
#define STAT_RREV 0000077 /* <05:00> ROM version */
/* Mode definitions */
#define MODE_PROM 0100000 /* <15> Promiscuous Mode */
#define MODE_ENAL 0040000 /* <14> Enable All Multicasts */
#define MODE_DRDC 0020000 /* <13> Disable Data Chaining */
#define MODE_TPAD 0010000 /* <12> Transmit Msg Pad Enable */
#define MODE_ECT 0004000 /* <11> Enable Collision Test */
#define MODE_DMNT 0001000 /* <09> Disable Maint Message */
#define MODE_INTL 0000200 /* <07> Internal Loopback [DELUA only] */
#define MODE_DTCR 0000010 /* <03> Disable Transmit CRC */
#define MODE_LOOP 0000004 /* <02> Internal Loopback Mode */
#define MODE_HDPX 0000001 /* <00> Half-Duplex Mode */
#define MODE_PROM 0100000 /* <15> Promiscuous Mode */
#define MODE_ENAL 0040000 /* <14> Enable All Multicasts */
#define MODE_DRDC 0020000 /* <13> Disable Data Chaining */
#define MODE_TPAD 0010000 /* <12> Transmit Msg Pad Enable */
#define MODE_ECT 0004000 /* <11> Enable Collision Test */
#define MODE_DMNT 0001000 /* <09> Disable Maint Message */
#define MODE_INTL 0000200 /* <07> Internal Loopback [DELUA only] */
#define MODE_DTCR 0000010 /* <03> Disable Transmit CRC */
#define MODE_LOOP 0000004 /* <02> Internal Loopback Mode */
#define MODE_HDPX 0000001 /* <00> Half-Duplex Mode */
/* Function Code definitions */
#define FC_NOOP 0000000 /* no-op */
#define FC_LSM 0000001 /* Load and Start Microaddress */
#define FC_RDPA 0000002 /* Read Default Physical Address */
#define FC_RPA 0000004 /* Read Physical Address */
#define FC_WPA 0000005 /* Write Physical Address */
#define FC_RMAL 0000006 /* Read Multicast Address List */
#define FC_WMAL 0000007 /* Write Multicast Address List */
#define FC_RRF 0000010 /* Read Ring Format */
#define FC_WRF 0000011 /* Write Ring Format */
#define FC_RDCTR 0000012 /* Read Counters */
#define FC_RDCLCTR 0000013 /* Read and Clear Counters */
#define FC_RMODE 0000014 /* Read Mode */
#define FC_WMODE 0000015 /* Write Mode */
#define FC_RSTAT 0000016 /* Read Status */
#define FC_RCSTAT 0000017 /* Read and Clear Status */
#define FC_DIM 0000020 /* Dump Internal Memory */
#define FC_LIM 0000021 /* Load Internal Memory */
#define FC_RSID 0000022 /* Read System ID parameters */
#define FC_WSID 0000023 /* Write System ID parameters */
#define FC_RLSA 0000024 /* Read Load Server Address */
#define FC_WLSA 0000025 /* Write Load Server Address */
#define FC_NOOP 0000000 /* no-op */
#define FC_LSM 0000001 /* Load and Start Microaddress */
#define FC_RDPA 0000002 /* Read Default Physical Address */
#define FC_RPA 0000004 /* Read Physical Address */
#define FC_WPA 0000005 /* Write Physical Address */
#define FC_RMAL 0000006 /* Read Multicast Address List */
#define FC_WMAL 0000007 /* Write Multicast Address List */
#define FC_RRF 0000010 /* Read Ring Format */
#define FC_WRF 0000011 /* Write Ring Format */
#define FC_RDCTR 0000012 /* Read Counters */
#define FC_RDCLCTR 0000013 /* Read and Clear Counters */
#define FC_RMODE 0000014 /* Read Mode */
#define FC_WMODE 0000015 /* Write Mode */
#define FC_RSTAT 0000016 /* Read Status */
#define FC_RCSTAT 0000017 /* Read and Clear Status */
#define FC_DIM 0000020 /* Dump Internal Memory */
#define FC_LIM 0000021 /* Load Internal Memory */
#define FC_RSID 0000022 /* Read System ID parameters */
#define FC_WSID 0000023 /* Write System ID parameters */
#define FC_RLSA 0000024 /* Read Load Server Address */
#define FC_WLSA 0000025 /* Write Load Server Address */
/* Transmitter Ring definitions */
#define TXR_OWN 0100000 /* <15> we own it (1) */
#define TXR_ERRS 0040000 /* <14> error summary */
#define TXR_MTCH 0020000 /* <13> Station Match */
#define TXR_MORE 0010000 /* <12> Mult Retries Needed */
#define TXR_ONE 0004000 /* <11> One Collision */
#define TXR_DEF 0002000 /* <10> Deferred */
#define TXR_STF 0001000 /* <09> Start Of Frame */
#define TXR_ENF 0000400 /* <08> End Of Frame */
#define TXR_BUFL 0100000 /* <15> Buffer Length Error */
#define TXR_UBTO 0040000 /* <14> UNIBUS TimeOut */
#define TXR_UFLO 0020000 /* <13> Underflow Error */
#define TXR_LCOL 0010000 /* <12> Late Collision */
#define TXR_LCAR 0004000 /* <11> Lost Carrier */
#define TXR_RTRY 0002000 /* <10> Retry Failure (16x) */
#define TXR_TDR 0001777 /* <9:0> TDR value if RTRY=1 */
#define TXR_OWN 0100000 /* <15> we own it (1) */
#define TXR_ERRS 0040000 /* <14> error summary */
#define TXR_MTCH 0020000 /* <13> Station Match */
#define TXR_MORE 0010000 /* <12> Mult Retries Needed */
#define TXR_ONE 0004000 /* <11> One Collision */
#define TXR_DEF 0002000 /* <10> Deferred */
#define TXR_STF 0001000 /* <09> Start Of Frame */
#define TXR_ENF 0000400 /* <08> End Of Frame */
#define TXR_BUFL 0100000 /* <15> Buffer Length Error */
#define TXR_UBTO 0040000 /* <14> UNIBUS TimeOut */
#define TXR_UFLO 0020000 /* <13> Underflow Error */
#define TXR_LCOL 0010000 /* <12> Late Collision */
#define TXR_LCAR 0004000 /* <11> Lost Carrier */
#define TXR_RTRY 0002000 /* <10> Retry Failure (16x) */
#define TXR_TDR 0001777 /* <9:0> TDR value if RTRY=1 */
/* Receiver Ring definitions */
#define RXR_OWN 0100000 /* <15> we own it (1) */
#define RXR_ERRS 0040000 /* <14> Error Summary */
#define RXR_FRAM 0020000 /* <13> Frame Error */
#define RXR_OFLO 0010000 /* <12> Message Overflow */
#define RXR_CRC 0004000 /* <11> CRC Check Error */
#define RXR_STF 0001000 /* <09> Start Of Frame */
#define RXR_ENF 0000400 /* <08> End Of Frame */
#define RXR_BUFL 0100000 /* <15> Buffer Length error */
#define RXR_UBTO 0040000 /* <14> UNIBUS TimeOut */
#define RXR_NCHN 0020000 /* <13> No Data Chaining */
#define RXR_OVRN 0010000 /* <12> Overrun Error [DELUA only] */
#define RXR_MLEN 0007777 /* <11:0> Message Length */
#define RXR_OWN 0100000 /* <15> we own it (1) */
#define RXR_ERRS 0040000 /* <14> Error Summary */
#define RXR_FRAM 0020000 /* <13> Frame Error */
#define RXR_OFLO 0010000 /* <12> Message Overflow */
#define RXR_CRC 0004000 /* <11> CRC Check Error */
#define RXR_STF 0001000 /* <09> Start Of Frame */
#define RXR_ENF 0000400 /* <08> End Of Frame */
#define RXR_BUFL 0100000 /* <15> Buffer Length error */
#define RXR_UBTO 0040000 /* <14> UNIBUS TimeOut */
#define RXR_NCHN 0020000 /* <13> No Data Chaining */
#define RXR_OVRN 0010000 /* <12> Overrun Error [DELUA only] */
#define RXR_MLEN 0007777 /* <11:0> Message Length */
/* debugging bitmaps */
#define DBG_TRC 0x0001 /* trace routine calls */
#define DBG_REG 0x0002 /* trace read/write registers */
#define DBG_WRN 0x0004 /* display warnings */
#define DBG_ETH 0x8000 /* debug ethernet device */
#define DBG_TRC 0x0001 /* trace routine calls */
#define DBG_REG 0x0002 /* trace read/write registers */
#define DBG_WRN 0x0004 /* display warnings */
#define DBG_ETH 0x8000 /* debug ethernet device */
#endif /* _PDP11_XU_H */
#endif /* _PDP11_XU_H */