mirror of
https://github.com/simh/simh.git
synced 2026-04-13 15:34:35 +00:00
Notes For V2.10-0
WARNING: V2.10 has reorganized and renamed some of the definition files for the PDP-10, PDP-11, and VAX. Be sure to delete all previous source files before you unpack the Zip archive, or unpack it into a new directory structure. WARNING: V2.10 has a new, more comprehensive save file format. Restoring save files from previous releases will cause 'invalid register' errors and loss of CPU option flags, device enable/ disable flags, unit online/offline flags, and unit writelock flags. WARNING: If you are using Visual Studio .NET through the IDE, be sure to turn off the /Wp64 flag in the project settings, or dozens of spurious errors will be generated. WARNING: Compiling Ethernet support under Windows requires extra steps; see the Ethernet readme file. Ethernet support is currently available only for Windows, Linux, NetBSD, and OpenBSD. 1. New Features 1.1 SCP and Libraries - The VT emulation package has been replaced by the capability to remote the console to a Telnet session. Telnet clients typically have more complete and robust VT100 emulation. - Simulated devices may now have statically allocated buffers, in addition to dynamically allocated buffers or disk-based data stores. - The DO command now takes substitutable arguments (max 9). In command files, %n represents substitutable argument n. - The initial command line is now interpreted as the command name and substitutable arguments for a DO command. This is backward compatible to prior versions. - The initial command line parses switches. -Q is interpreted as quiet mode; informational messages are suppressed. - The HELP command now takes an optional argument. HELP <cmd> types help on the specified command. - Hooks have been added for implementing GUI-based consoles, as well as simulator-specific command extensions. A few internal data structures and definitions have changed. - Two new routines (tmxr_open_master, tmxr_close_master) have been added to sim_tmxr.c. The calling sequence for sim_accept_conn has been changed in sim_sock.c. - The calling sequence for the VM boot routine has been modified to add an additional parameter. - SAVE now saves, and GET now restores, controller and unit flags. - Library sim_ether.c has been added for Ethernet support. 1.2 VAX - Non-volatile RAM (NVR) can behave either like a memory or like a disk-based peripheral. If unattached, it behaves like memory and is saved and restored by SAVE and RESTORE, respectively. If attached, its contents are loaded from disk by ATTACH and written back to disk at DETACH and EXIT. - SHOW <device> VECTOR displays the device's interrupt vector. A few devices allow the vector to be changed with SET <device> VECTOR=nnn. - SHOW CPU IOSPACE displays the I/O space address map. - The TK50 (TMSCP tape) has been added. - The DEQNA/DELQA (Qbus Ethernet controllers) have been added. - Autoconfiguration support has been added. - The paper tape reader has been removed from vax_stddev.c and now references a common implementation file, dec_pt.h. - Examine and deposit switches now work on all devices, not just the CPU. - Device address conflicts are not detected until simulation starts. 1.3 PDP-11 - SHOW <device> VECTOR displays the device's interrupt vector. Most devices allow the vector to be changed with SET <device> VECTOR=nnn. - SHOW CPU IOSPACE displays the I/O space address map. - The TK50 (TMSCP tape), RK611/RK06/RK07 (cartridge disk), RX211 (double density floppy), and KW11P programmable clock have been added. - The DEQNA/DELQA (Qbus Ethernet controllers) have been added. - Autoconfiguration support has been added. - The paper tape reader has been removed from pdp11_stddev.c and now references a common implementation file, dec_pt.h. - Device bootstraps now use the actual CSR specified by the SET ADDRESS command, rather than just the default CSR. Note that PDP-11 operating systems may NOT support booting with non-standard addresses. - Specifying more than 256KB of memory, or changing the bus configuration, causes all peripherals that are not compatible with the current bus configuration to be disabled. - Device address conflicts are not detected until simulation starts. 1.4 PDP-10 - SHOW <device> VECTOR displays the device's interrupt vector. A few devices allow the vector to be changed with SET <device> VECTOR=nnn. - SHOW CPU IOSPACE displays the I/O space address map. - The RX211 (double density floppy) has been added; it is off by default. - The paper tape now references a common implementation file, dec_pt.h. - Device address conflicts are not detected until simulation starts. 1.5 PDP-1 - DECtape (then known as MicroTape) support has been added. - The line printer and DECtape can be disabled and enabled. 1.6 PDP-8 - The RX28 (double density floppy) has been added as an option to the existing RX8E controller. - SHOW <device> DEVNO displays the device's device number. Most devices allow the device number to be changed with SET <device> DEVNO=nnn. - Device number conflicts are not detected until simulation starts. 1.7 IBM 1620 - The IBM 1620 simulator has been released. 1.8 AltairZ80 - A hard drive has been added for increased storage. - Several bugs have been fixed. 1.9 HP 2100 - The 12845A has been added and made the default line printer (LPT). The 12653A has been renamed LPS and is off by default. It also supports the diagnostic functions needed to run the DCPC and DMS diagnostics. - The 12557A/13210A disk defaults to the 13210A (7900/7901). - The 12559A magtape is off by default. - New CPU options (EAU/NOEAU) enable/disable the extended arithmetic instructions for the 2116. These instructions are standard on the 2100 and 21MX. - New CPU options (MPR/NOMPR) enable/disable memory protect for the 2100 and 21MX. - New CPU options (DMS/NODMS) enable/disable the dynamic mapping instructions for the 21MX. - The 12539 timebase generator autocalibrates. 1.10 Simulated Magtapes - Simulated magtapes recognize end of file and the marker 0xFFFFFFFF as end of medium. Only the TMSCP tape simulator can generate an end of medium marker. - The error handling in simulated magtapes was overhauled to be consistent through all simulators. 1.11 Simulated DECtapes - Added support for RT11 image file format (256 x 16b) to DECtapes. 2. Release Notes 2.1 Bugs Fixed - TS11/TSV05 was not simulating the XS0_MOT bit, causing failures under VMS. In addition, two of the CTL options were coded interchanged. - IBM 1401 tape was not setting a word mark under group mark for load mode reads. This caused the diagnostics to crash. - SCP bugs in ssh_break and set_logon were fixed (found by Dave Hittner). - Numerous bugs in the HP 2100 extended arithmetic, floating point, 21MX, DMS, and IOP instructions were fixed. Bugs were also fixed in the memory protect and DMS functions. The moving head disks (DP, DQ) were revised to simulate the hardware more accurately. Missing functions in DQ (address skip, read address) were added. 2.2 HP 2100 Debugging - The HP 2100 CPU nows runs all of the CPU diagnostics. - The peripherals run most of the peripheral diagnostics. There is still a problem in overlapped seek operation on the disks. See the file hp2100_diag.txt for details. 3. In Progress These simulators are not finished and are available in a separate Zip archive distribution. - Interdata 16b/32b: coded, partially tested. See the file id_diag.txt for details. - SDS 940: coded, partially tested.
This commit is contained in:
committed by
Mark Pizzolato
parent
df6475181c
commit
2c2dd5ea33
@@ -25,6 +25,7 @@
|
||||
|
||||
cpu CVAX central processor
|
||||
|
||||
29-Sep-02 RMS Revised to build dib_tab dynamically
|
||||
14-Jul-02 RMS Added halt to console, infinite loop detection
|
||||
(from Mark Pizzolato)
|
||||
02-May-02 RMS Fixed bug in indexed autoincrement register logging
|
||||
@@ -125,11 +126,10 @@
|
||||
2. Interrupt requests are maintained in the int_req array, one word per
|
||||
interrupt level, one bit per device.
|
||||
|
||||
3. Adding I/O devices. This requires modifications to three modules:
|
||||
3. Adding I/O devices. These modules must be modified:
|
||||
|
||||
vax_defs.h add interrupt request definitions
|
||||
vax_mm.c add I/O page linkages
|
||||
vax_sys.c add to sim_devices
|
||||
vax_defs.h add device address and interrupt definitions
|
||||
vax_sys.c add sim_devices table entry
|
||||
*/
|
||||
|
||||
/* Definitions */
|
||||
@@ -231,6 +231,7 @@ extern int32 sim_int_char;
|
||||
extern int32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
|
||||
extern UNIT clk_unit;
|
||||
|
||||
extern t_stat build_dib_tab (void);
|
||||
extern UNIT rom_unit, nvr_unit;
|
||||
extern int32 op_ashq (int32 *opnd, int32 *rh, int32 *flg);
|
||||
extern int32 op_emul (int32 mpy, int32 mpc, int32 *rh);
|
||||
@@ -300,8 +301,10 @@ extern int32 get_vector (int32 lvl);
|
||||
extern void set_map_reg (void);
|
||||
extern void rom_wr (int32 pa, int32 val, int32 lnt);
|
||||
extern uint16 drom[NUM_INST][MAX_SPEC + 1];
|
||||
extern t_stat show_iospace (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||
|
||||
t_stat cpu_reset (DEVICE *dptr);
|
||||
t_stat cpu_boot (int32 unitno);
|
||||
t_stat cpu_boot (int32 unitno, DEVICE *dptr);
|
||||
t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
|
||||
t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);
|
||||
t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
@@ -376,6 +379,8 @@ MTAB cpu_mod[] = {
|
||||
{ UNIT_MSIZE, (1u << 26), NULL, "64M", &cpu_set_size },
|
||||
{ UNIT_CONH, 0, "HALT to SIMH", "SIMHALT", NULL },
|
||||
{ UNIT_CONH, UNIT_CONH, "HALT to console", "CONHALT", NULL },
|
||||
{ MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "IOSPACE", NULL,
|
||||
NULL, &show_iospace },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, NULL, "VIRTUAL", &cpu_show_virt },
|
||||
{ 0 } };
|
||||
|
||||
@@ -383,14 +388,17 @@ DEVICE cpu_dev = {
|
||||
"CPU", &cpu_unit, cpu_reg, cpu_mod,
|
||||
1, 16, 32, 1, 16, 8,
|
||||
&cpu_ex, &cpu_dep, &cpu_reset,
|
||||
&cpu_boot, NULL, NULL };
|
||||
&cpu_boot, NULL, NULL,
|
||||
NULL, 0 };
|
||||
|
||||
t_stat sim_instr (void)
|
||||
{
|
||||
volatile int32 opc, cc; /* used by setjmp */
|
||||
int32 acc; /* set by setjmp */
|
||||
int abortval;
|
||||
t_stat r;
|
||||
|
||||
if ((r = build_dib_tab ()) != SCPE_OK) return r; /* build, chk dib_tab */
|
||||
cc = PSL & CC_MASK; /* split PSL */
|
||||
PSL = PSL & ~CC_MASK;
|
||||
in_ie = 0; /* not in exc */
|
||||
@@ -403,7 +411,7 @@ sim_rtcn_init (clk_unit.wait, TMR_CLK); /* init clock */
|
||||
abortval = setjmp (save_env); /* set abort hdlr */
|
||||
if (abortval > 0) { /* sim stop? */
|
||||
PSL = PSL | cc; /* put PSL together */
|
||||
pcq_r -> qptr = pcq_p; /* update pc q ptr */
|
||||
pcq_r->qptr = pcq_p; /* update pc q ptr */
|
||||
return abortval; } /* return to SCP */
|
||||
else if (abortval < 0) { /* mm or rsrv or int */
|
||||
int32 i, temp, st1, st2, hsir;
|
||||
@@ -2237,7 +2245,7 @@ mapen = 0;
|
||||
if (M == NULL) M = calloc (MEMSIZE >> 2, sizeof (int32));
|
||||
if (M == NULL) return SCPE_MEM;
|
||||
pcq_r = find_reg ("PCQ", NULL, dptr);
|
||||
if (pcq_r) pcq_r -> qptr = 0;
|
||||
if (pcq_r) pcq_r->qptr = 0;
|
||||
else return SCPE_IERR;
|
||||
sim_brk_types = sim_brk_dflt = SWMASK ('E');
|
||||
return SCPE_OK;
|
||||
@@ -2245,12 +2253,16 @@ return SCPE_OK;
|
||||
|
||||
/* Bootstrap */
|
||||
|
||||
t_stat cpu_boot (int32 unitno)
|
||||
t_stat cpu_boot (int32 unitno, DEVICE *dptr)
|
||||
{
|
||||
extern int32 clk_csr;
|
||||
extern t_stat qba_powerup (void);
|
||||
extern t_stat sysd_powerup (void);
|
||||
extern t_stat todr_powerup (void);
|
||||
extern uint32 *rom;
|
||||
extern t_stat load_cmd (int32 flag, char *cptr);
|
||||
extern FILE *sim_log;
|
||||
t_stat r;
|
||||
|
||||
qba_powerup ();
|
||||
sysd_powerup ();
|
||||
@@ -2259,6 +2271,13 @@ PC = ROMBASE;
|
||||
PSL = PSL_IS | PSL_IPL1F;
|
||||
conpc = 0;
|
||||
conpsl = PSL_IS | PSL_IPL1F | CON_PWRUP;
|
||||
if (rom == NULL) return SCPE_IERR;
|
||||
if (*rom == 0) { /* no boot? */
|
||||
printf ("Loading boot code from ka655.bin\n");
|
||||
if (sim_log) fprintf (sim_log,
|
||||
"Loading boot code from ka655.bin\n");
|
||||
r = load_cmd (0, "-R ka655.bin");
|
||||
if (r != SCPE_OK) return r; }
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -174,7 +174,7 @@ int32 pos = opnd[0];
|
||||
int32 size = opnd[1];
|
||||
int32 rn = opnd[2];
|
||||
uint32 wd = opnd[3];
|
||||
int32 ba, wd1;
|
||||
int32 ba, wd1 = 0;
|
||||
|
||||
if (size == 0) return 0; /* size 0? field = 0 */
|
||||
if (size > 32) RSVD_OPND_FAULT; /* size > 32? fault */
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#define STOP_RQ 9 /* fatal RQ err */
|
||||
#define STOP_LOOP 10 /* infinite loop */
|
||||
#define STOP_UNKABO 11 /* unknown abort */
|
||||
#define STOP_SANITY 12 /* sanity timer exp */
|
||||
#define ABORT_INTR -1 /* interrupt */
|
||||
#define ABORT_MCHK (-SCB_MCHK) /* machine check */
|
||||
#define ABORT_RESIN (-SCB_RESIN) /* rsvd instruction */
|
||||
@@ -65,9 +66,10 @@
|
||||
|
||||
/* Address space */
|
||||
|
||||
#define VAMASK 0xFFFFFFFF /* virt addr mask */
|
||||
#define PAWIDTH 30 /* phys addr width */
|
||||
#define PASIZE (1 << PAWIDTH) /* phys addr size */
|
||||
#define PAMASK (PASIZE - 1) /* phys mem mask */
|
||||
#define PAMASK (PASIZE - 1) /* phys addr mask */
|
||||
#define IOPAGE (1 << (PAWIDTH - 1)) /* start of I/O page */
|
||||
|
||||
/* Architectural constants */
|
||||
@@ -430,9 +432,10 @@ enum opcodes {
|
||||
#define SXTB(x) (((x) & BSIGN)? ((x) | ~BMASK): ((x) & BMASK))
|
||||
#define SXTW(x) (((x) & WSIGN)? ((x) | ~WMASK): ((x) & WMASK))
|
||||
#define SXTBW(x) (((x) & BSIGN)? ((x) | (WMASK - BMASK)): ((x) & BMASK))
|
||||
#define SXTL(x) (((x) & LSIGN)? ((x) | ~LMASK): ((x) & LMASK))
|
||||
#define INTOV if (PSL & PSW_IV) SET_TRAP (TRAP_INTOV)
|
||||
#define V_INTOV cc = cc | CC_V; INTOV
|
||||
#define NEG(x) (-((int32) (x)))
|
||||
#define NEG(x) ((~(x) + 1) & LMASK)
|
||||
|
||||
/* Istream access */
|
||||
|
||||
|
||||
262
VAX/vax_doc.txt
262
VAX/vax_doc.txt
@@ -1,7 +1,7 @@
|
||||
To: Users
|
||||
From: Bob Supnik
|
||||
Subj: VAX Simulator Usage
|
||||
Date: 15-Jun-2002
|
||||
Date: 15-Nov-2002
|
||||
|
||||
COPYRIGHT NOTICE
|
||||
|
||||
@@ -39,15 +39,16 @@ This memorandum documents the VAX simulator.
|
||||
To compile the VAX, you must define USE_INT64 as part of the compilation
|
||||
command line.
|
||||
|
||||
sim/ sim_defs.h
|
||||
sim/ dec_dz.h
|
||||
dec_pt.h
|
||||
sim_defs.h
|
||||
sim_ether.h
|
||||
sim_rev.h
|
||||
sim_sock.h
|
||||
sim_tmxr.h
|
||||
dec_dz.h
|
||||
dec_mscp.h
|
||||
dec_uqssp.h
|
||||
scp.c
|
||||
scp_tty.c
|
||||
sim_rev.c
|
||||
sim_ether.c
|
||||
sim_sock.c
|
||||
sim_tmxr.c
|
||||
|
||||
@@ -61,11 +62,17 @@ sim/vax/ vax_defs.h
|
||||
vax_stddev.c
|
||||
vax_sys.c
|
||||
|
||||
sim/pdp11/ pdp11_dz.c
|
||||
sim/pdp11/ pdp11_mscp.h
|
||||
pdp11_uqssp.h
|
||||
pdp11_xq.h
|
||||
pdp11_dz.c
|
||||
pdp11_lp.c
|
||||
pdp11_pt.c
|
||||
pdp11_rl.c
|
||||
pdp11_rq.c
|
||||
pdp11_tq.c
|
||||
pdp11_ts.c
|
||||
pdp11_xp.c
|
||||
|
||||
2. VAX Features
|
||||
|
||||
@@ -87,11 +94,15 @@ CLK real-time clock
|
||||
DZ DZV11 8-line terminal multiplexor (up to 4)
|
||||
RL RLV12/RL01(2) cartridge disk controller with four drives
|
||||
RQ RQDX3 MSCP controller with four drives
|
||||
RQB second RQDX3 MSCP controller with four drives
|
||||
RQC third RQDX3 MSCP controller with four drives
|
||||
RQD fourth RQDX3 MSCP controller with four drives
|
||||
TS TSV11/TSV05 magnetic tape controller with one drive
|
||||
TQ TQK50 TMSCP magnetic tape controller with four drives
|
||||
XQ DELQA/DEQNA Ethernet controller
|
||||
|
||||
The PTR, PTP, LPT, DZ, RL, and TS devices can be set DISABLED. In addition,
|
||||
most devices support the SET ADDRESS command, which allows the I/O page
|
||||
address of the device to be changed.
|
||||
The PTR, PTP, LPT, DZ, RL, RQ, RQB, RQC, RQD, TS, TQ, and XQ devices can
|
||||
be set DISABLED. RQB, RQC, and RQD are disabled by default.
|
||||
|
||||
The VAX simulator implements several unique stop conditions:
|
||||
|
||||
@@ -119,10 +130,13 @@ HALT instruction.
|
||||
SET CPU 64M set memory size = 64MB
|
||||
SET CPU SIMHALT kernel HALT returns to simulator
|
||||
SET CPU CONHALT kernel HALT returns to boot ROM console
|
||||
SHOW CPU IOSPACE show I/O space address map
|
||||
|
||||
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 16MB.
|
||||
portion of memory is lost. Initial memory size is 16MB. If the simulator
|
||||
is running VMS, the operating system will not recognize memory size changes
|
||||
until AUTOGEN is run.
|
||||
|
||||
Memory can be loaded with a binary byte stream using the LOAD command.
|
||||
The LOAD command recognizes one switch:
|
||||
@@ -131,10 +145,12 @@ The LOAD command recognizes one switch:
|
||||
|
||||
The CPU supports the BOOT command and is the only VAX device to do so.
|
||||
|
||||
These switches are recognized when examining or depositing in CPU memory:
|
||||
These switches are recognized when examining or depositing in CPU memory
|
||||
(or any other byte oriented device):
|
||||
|
||||
-b examine/deposit bytes
|
||||
-w examine/deposit words
|
||||
-l examine/deposit longwords
|
||||
-d data radix is decimal
|
||||
-o data radix is octal
|
||||
-h data radix is hexadecimal
|
||||
@@ -200,10 +216,10 @@ using the LOAD -r command:
|
||||
|
||||
The NVR consists of a single unit, representing 1KB of battery-backed up
|
||||
memory. When the simulator starts, NVR is cleared to 0, and the SSC
|
||||
battery-low indicator is set. The NVR can be loaded with a binary byte
|
||||
stream using the LOAD -n command:
|
||||
|
||||
LOAD -n NVR.BIN -- load NVR image NVR.BIN
|
||||
battery-low indicator is set. Normally, NVR is saved and restored like
|
||||
other memory in the system. Alternately, NVR can be attached to a file.
|
||||
This allows its contents to be saved and restored independently of
|
||||
other memories, so that NVR state can be preserved across simulator runs.
|
||||
|
||||
Successfully loading an NVR image clears the SSC battery-low indicator.
|
||||
|
||||
@@ -253,9 +269,43 @@ The QBA represents the CQBIC Qbus adapter chip. The QBA registers are:
|
||||
IPL15 32 IPL 15 interrupt flags
|
||||
IPL14 32 IPL 14 interrupt flags
|
||||
|
||||
2.2 Programmed I/O Devices
|
||||
2.2 I/O Device Addressing
|
||||
|
||||
2.2.1 PC11 Paper Tape Reader (PTR)
|
||||
Qbus 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:
|
||||
|
||||
DZ11 all instances have floating addresses
|
||||
RL11 first instance has fixed address, rest floating
|
||||
MSCP disk first instance has fixed address, rest floating
|
||||
TMSCP tape first instance has fixed address, rest floating
|
||||
|
||||
To maintain addressing consistency as the configuration changes, the
|
||||
simulator implements DEC's standard I/O address and vector autoconfiguration
|
||||
algorithms for devices DZ, RL, RQ, and TQ. This allows the user to
|
||||
enable or disable devices without needing to manage I/O addresses
|
||||
and vectors.
|
||||
|
||||
In addition to autoconfiguration, most devices support the SET ADDRESS
|
||||
command, which allows the I/O page address of the device to be changed,
|
||||
and the SET VECTOR command, which allows the vector of the device to be
|
||||
changed. Explicitly setting the I/O address of a device which normally
|
||||
uses autoconfiguration DISABLES autoconfiguration for that device. As
|
||||
a consequence, the user may have to manually configure all other
|
||||
autoconfigured devices, because the autoconfiguration algorithm no
|
||||
longer recognizes the explicitly configured device. A device can be
|
||||
reset to autoconfigure with the SET <device> AUTOCONFIGURE command.
|
||||
|
||||
The current I/O map can be displayed with the SHOW CPU IOSPACE command.
|
||||
Address that have set by autoconfiguration are marked with an asterisk (*).
|
||||
|
||||
All devices support the SHOW ADDRESS and SHOW VECTOR commands, which display
|
||||
the device address and vector, respectively.
|
||||
|
||||
2.3 Programmed I/O Devices
|
||||
|
||||
2.3.1 PC11 Paper Tape Reader (PTR)
|
||||
|
||||
The paper tape reader (PTR) reads data from a disk file. The POS
|
||||
register specifies the number of the next data item to be read. Thus,
|
||||
@@ -288,7 +338,7 @@ Error handling is as follows:
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.2.2 PC11 Paper Tape Punch (PTP)
|
||||
2.3.2 PC11 Paper Tape Punch (PTP)
|
||||
|
||||
The paper tape punch (PTP) writes data to a disk file. The POS
|
||||
register specifies the number of the next data item to be written.
|
||||
@@ -317,7 +367,12 @@ Error handling is as follows:
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.2.3 Terminal Input (TTI)
|
||||
2.3.3 Terminal Input (TTI)
|
||||
|
||||
The terminal interfaces (TTI, TTO) can be set to one of two modes:
|
||||
7B or 8B. In 7B mode, input and output characters are masked to 7
|
||||
bits. In 8B mode, characters are not modified. Changing the mode
|
||||
of either interface changes both. The default mode is 8B.
|
||||
|
||||
The terminal input (TTI) polls the console keyboard for input. It
|
||||
implements these registers:
|
||||
@@ -333,7 +388,7 @@ implements these registers:
|
||||
POS 32 number of characters input
|
||||
TIME 24 keyboard polling interval
|
||||
|
||||
2.2.4 Terminal Output (TTO)
|
||||
2.3.4 Terminal Output (TTO)
|
||||
|
||||
The terminal output (TTO) writes to the simulator console window. It
|
||||
implements these registers:
|
||||
@@ -349,7 +404,7 @@ implements these registers:
|
||||
POS 32 number of characters input
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
|
||||
2.2.5 Line Printer (LPT)
|
||||
2.3.5 Line Printer (LPT)
|
||||
|
||||
The line printer (LPT) writes data to a disk file. The POS register
|
||||
specifies the number of the next data item to be written. Thus,
|
||||
@@ -378,7 +433,7 @@ Error handling is as follows:
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.2.6 Real-Time Clock (CLK)
|
||||
2.3.6 Real-Time Clock (CLK)
|
||||
|
||||
The clock (CLK) implements these registers:
|
||||
|
||||
@@ -395,14 +450,21 @@ The clock (CLK) implements these registers:
|
||||
The real-time clock autocalibrates; the clock interval is adjusted up or
|
||||
down so that the clock tracks actual elapsed time.
|
||||
|
||||
2.2.7 DZ11 Terminal Multiplexor (DZ)
|
||||
2.3.7 DZ11 Terminal Multiplexor (DZ)
|
||||
|
||||
The DZ11 is an 8-line terminal multiplexor. Up to 4 DZ11's (32 lines)
|
||||
are supported. The number of lines can be changed with the command
|
||||
|
||||
SET DZ LINES=n set line count to n
|
||||
|
||||
The line count must be a multiple of 8, with a maximum of 32.
|
||||
The line count must be a multiple of 4, with a maximum of 16.
|
||||
|
||||
The DZ11 supports 8-bit input and output of characters. 8-bit output
|
||||
may be incompatible with certain operating systems. The command
|
||||
|
||||
SET DZ 7B
|
||||
|
||||
forces output characters to be masked to 7 bits.
|
||||
|
||||
The terminal lines perform input and output through Telnet sessions
|
||||
connected to a user-specified port. The ATTACH command specifies
|
||||
@@ -444,7 +506,7 @@ The DZ11 implements these registers:
|
||||
The DZ11 does not support save and restore. All open connections are
|
||||
lost when the simulator shuts down or the DZ is detached.
|
||||
|
||||
2.3 RLV12/RL01,RL02 Cartridge Disk (RL)
|
||||
2.4 RLV12/RL01,RL02 Cartridge Disk (RL)
|
||||
|
||||
RLV12 options include the ability to set units write enabled or write locked,
|
||||
to set the drive size to RL01, RL02, or autosize, and to write a DEC standard
|
||||
@@ -489,11 +551,13 @@ Error handling is as follows:
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.4 RQDX3 MSCP Disk Controller (RQ)
|
||||
2.5 RQDX3 MSCP Disk Controllers (RQ, RQB, RQC, RQD)
|
||||
|
||||
The RQ controller simulates the RQDX3 MSCP disk controller. RQ options
|
||||
include the ability to set units write enabled or write locked, and to
|
||||
set the drive type to one of eleven disk types:
|
||||
The simulator implements four MSCP disk controllers, RQ, RQB, RQC, RQD.
|
||||
Initially, RQB, RQC, and RQD are disabled. Each RQ controller simulates
|
||||
an RQDX3 MSCP disk controller. RQ options include the ability to set
|
||||
units write enabled or write locked, and to set the drive type to one
|
||||
of eleven disk types:
|
||||
|
||||
SET RQn LOCKED set unit n write locked
|
||||
SET RQn WRITEENABLED set unit n write enabled
|
||||
@@ -512,7 +576,7 @@ set the drive type to one of eleven disk types:
|
||||
The type options can be used only when a unit is not attached to a file.
|
||||
Units can also be set ONLINE or OFFLINE.
|
||||
|
||||
The RQ controller implements the following special SHOW commands:
|
||||
Each RQ controller implements the following special SHOW commands:
|
||||
|
||||
SHOW RQ RINGS show command and response rings
|
||||
SHOW RQ FREEQ show packet free queue
|
||||
@@ -521,7 +585,7 @@ The RQ controller implements the following special SHOW commands:
|
||||
SHOW RQ ALL show all ring and queue state
|
||||
SHOW RQn UNITQ show unit queues for unit n
|
||||
|
||||
The RQ controller implements these registers:
|
||||
Each RQ controller implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
@@ -563,7 +627,7 @@ Error handling is as follows:
|
||||
|
||||
OS I/O error report error and stop
|
||||
|
||||
2.5 TSV11/TSV05 Magnetic Tape (TS)
|
||||
2.6 TSV11/TSV05 Magnetic Tape (TS)
|
||||
|
||||
TS options include the ability to make the unit write enabled or write locked.
|
||||
|
||||
@@ -611,7 +675,137 @@ Error handling is as follows:
|
||||
|
||||
OS I/O error fatal tape error
|
||||
|
||||
2.6 Symbolic Display and Input
|
||||
2.7 TQK50 TMSCP Disk Controller (TQ)
|
||||
|
||||
The TQ controller simulates the TQK50 TMSCP disk controller. TQ options
|
||||
include the ability to set units write enabled or write locked:
|
||||
|
||||
SET TQn LOCKED set unit n write locked
|
||||
SET TQn WRITEENABLED set unit n write enabled
|
||||
|
||||
The TQ controller implements the following special SHOW commands:
|
||||
|
||||
SHOW TQ RINGS show command and response rings
|
||||
SHOW TQ FREEQ show packet free queue
|
||||
SHOW TQ RESPQ show packet response queue
|
||||
SHOW TQ UNITQ show unit queues
|
||||
SHOW TQ ALL show all ring and queue state
|
||||
SHOW TQn UNITQ show unit queues for unit n
|
||||
|
||||
The TQ controller implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
SA 16 status/address register
|
||||
S1DAT 16 step 1 init host data
|
||||
CQBA 22 command queue base address
|
||||
CQLNT 8 command queue length
|
||||
CQIDX 8 command queue index
|
||||
RQBA 22 request queue base address
|
||||
RQLNT 8 request queue length
|
||||
RQIDX 8 request queue index
|
||||
FREE 5 head of free packet list
|
||||
RESP 5 head of response packet list
|
||||
PBSY 5 number of busy packets
|
||||
CFLGS 16 controller flags
|
||||
CSTA 4 controller state
|
||||
PERR 9 port error number
|
||||
CRED 5 host credits
|
||||
HAT 17 host available timer
|
||||
HTMO 17 host timeout value
|
||||
CPKT[0:3] 5 current packet, units 0-3
|
||||
PKTQ[0:3] 5 packet queue, units 0-3
|
||||
UFLG[0:3] 16 unit flags, units 0-3
|
||||
POS[0:3] 32 tape position, units 0-3
|
||||
OBJP[0:3] 32 object position, units 0-3
|
||||
INT 1 interrupt request
|
||||
ITIME 1 response time for initialization steps
|
||||
(except for step 4)
|
||||
QTIME 24 response time for 'immediate' packets
|
||||
XTIME 24 response time for data transfers
|
||||
PKTS[33*32] 16 packet buffers, 33W each,
|
||||
32 entries
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error processed as
|
||||
|
||||
not attached tape not ready
|
||||
|
||||
end of file end of medium
|
||||
|
||||
OS I/O error report error and stop
|
||||
|
||||
2.8 DELQA/DEQNA Ethernet Controller (XQ)
|
||||
|
||||
XQ simulates the DELQA/DEQNA 10Mbps Ethernet controller. Options allow
|
||||
control of the MAC address, the controller mode, and the sanity timer.
|
||||
|
||||
SET XQ MAC=<mac-address> ex. 08-00-2B-AA-BB-CC
|
||||
SHOW XQ MAC
|
||||
|
||||
These commands are used to change or display the MAC address. <mac-address>
|
||||
is a valid ethernet MAC, delimited by dashes or periods. The controller
|
||||
defaults to 08-00-2B-AA-BB-CC, which should be sufficient if there is
|
||||
only one SIMH controller on your LAN. Two cards with the same MAC address
|
||||
will see each other's packets, resulting in a serious mess.
|
||||
|
||||
SET XQ TYPE={DEQNA|[DELQA]}
|
||||
SHOW XQ TYPE
|
||||
|
||||
These commands are used to change or display the controller mode. DELQA
|
||||
mode is better and faster but may not be usable by older or non-DEC OS's.
|
||||
Also, be aware that DEQNA mode is not supported by many modern OS's. The
|
||||
DEQNA-LOCK mode of the DELQA card is emulated by setting the the controller
|
||||
to DEQNA - there is no need for a separate mode. DEQNA-LOCK mode behaves
|
||||
exactly like a DEQNA, except for the operation of the VAR and MOP processing.
|
||||
|
||||
SET XQ SANITY={ON|[OFF]}
|
||||
SHOW XQ SANITY
|
||||
|
||||
These commands change or display the INITIALIZATION sanity timer (DEQNA
|
||||
jumper W3/DELQA switch S4). The INITIALIZATION sanity timer has a default
|
||||
timeout of 4 minutes, and cannot be turned off, just reset. The normal
|
||||
sanity timer can be set by operating system software regardless of the
|
||||
state of this switch. Note that only the DEQNA (or the DELQA in DEQNA-
|
||||
LOCK mode (=DEQNA)) supports the sanity timer - it is ignored by a DELQA
|
||||
in Normal mode, which uses switch S4 for a different purpose.
|
||||
|
||||
To access the network, the simulated Ethernet controller must be attached
|
||||
to a real Ethernet interface:
|
||||
|
||||
ATTACH XQ0 {ethX|<device_name>} ex. eth0 or /dev/era0
|
||||
SHOW XQ ETH
|
||||
|
||||
where X in 'ethX' is the number of the ethernet controller to attach, or
|
||||
the real device name. The X number is system dependant. If you only have
|
||||
one ethernet controller, the number will probably be 0. To find out what
|
||||
your system thinks the ethernet numbers are, use the SHOW XQ ETH command.
|
||||
The device list can be quite cryptic, depending on the host system, but
|
||||
is probably better than guessing. If you do not attach the device, the
|
||||
controller will behave as though the ethernet cable were unplugged.
|
||||
|
||||
XQ has the following registers:
|
||||
|
||||
name size comments
|
||||
|
||||
SA0 16 station address word 0
|
||||
SA1 16 station address word 1
|
||||
SA2 16 station address word 2
|
||||
SA3 16 station address word 3
|
||||
SA4 16 station address word 4
|
||||
SA5 16 station address word 5
|
||||
CSR 16 control status register
|
||||
VAR 16 vector address register
|
||||
RBDL 32 receive buffer descriptor list
|
||||
XBDL 32 trans(X)mit buffer descriptorlList
|
||||
|
||||
One final note: because of it's 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!" :-)
|
||||
|
||||
2.9 Symbolic Display and Input
|
||||
|
||||
The VAX simulator implements symbolic display and input. Display is
|
||||
controlled by command line switches:
|
||||
|
||||
178
VAX/vax_fpa.c
178
VAX/vax_fpa.c
@@ -366,34 +366,34 @@ void vax_fadd (UFP *a, UFP *b, t_int64 mask)
|
||||
int32 ediff;
|
||||
UFP t;
|
||||
|
||||
if (a -> exp == 0) { /* s1 = 0? */
|
||||
if (a->exp == 0) { /* s1 = 0? */
|
||||
*a = *b;
|
||||
return; }
|
||||
if (b -> exp == 0) return; /* s2 = 0? */
|
||||
if (a -> exp < b -> exp) { /* s1 < s2? swap */
|
||||
if (b->exp == 0) return; /* s2 = 0? */
|
||||
if (a->exp < b->exp) { /* s1 < s2? swap */
|
||||
t = *a;
|
||||
*a = *b;
|
||||
*b = t; }
|
||||
ediff = a -> exp - b -> exp; /* exp diff */
|
||||
if (a -> sign ^ b -> sign) { /* eff sub? */
|
||||
ediff = a->exp - b->exp; /* exp diff */
|
||||
if (a->sign ^ b->sign) { /* eff sub? */
|
||||
if (ediff) { /* exp diff? */
|
||||
b -> frac = (ediff > 63)? ONES: /* shift b */
|
||||
((-((t_int64) b -> frac) >> ediff) |
|
||||
b->frac = (ediff > 63)? ONES: /* shift b */
|
||||
((-((t_int64) b->frac) >> ediff) |
|
||||
(ONES << (64 - ediff))); /* preserve sign */
|
||||
a -> frac = a -> frac + b -> frac; } /* add frac */
|
||||
else { if (a -> frac < b -> frac) { /* same, check magn */
|
||||
a -> frac = b -> frac - a -> frac; /* b > a */
|
||||
a -> sign = b -> sign; }
|
||||
else a -> frac = a -> frac - b -> frac; } /* a >= b */
|
||||
a -> frac = a -> frac & ~mask;
|
||||
a->frac = a->frac + b->frac; } /* add frac */
|
||||
else { if (a->frac < b->frac) { /* same, check magn */
|
||||
a->frac = b->frac - a->frac; /* b > a */
|
||||
a->sign = b->sign; }
|
||||
else a->frac = a->frac - b->frac; } /* a >= b */
|
||||
a->frac = a->frac & ~mask;
|
||||
norm (a); } /* normalize */
|
||||
else { if (ediff >= 64) b -> frac = 0;
|
||||
else b -> frac = b -> frac >> ediff; /* add, denorm */
|
||||
a -> frac = a -> frac + b -> frac; /* add frac */
|
||||
if (a -> frac < b -> frac) { /* chk for carry */
|
||||
a -> frac = UF_NM | (a -> frac >> 1); /* shift in carry */
|
||||
a -> exp = a -> exp + 1; } /* skip norm */
|
||||
a -> frac = a -> frac & ~mask; }
|
||||
else { if (ediff >= 64) b->frac = 0;
|
||||
else b->frac = b->frac >> ediff; /* add, denorm */
|
||||
a->frac = a->frac + b->frac; /* add frac */
|
||||
if (a->frac < b->frac) { /* chk for carry */
|
||||
a->frac = UF_NM | (a->frac >> 1); /* shift in carry */
|
||||
a->exp = a->exp + 1; } /* skip norm */
|
||||
a->frac = a->frac & ~mask; }
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -419,7 +419,7 @@ UFP a, b;
|
||||
|
||||
unpackd (opnd[0], opnd[1], &a);
|
||||
unpackd (opnd[2], opnd[3], &b);
|
||||
vax_fmul (&a, &b, 56, FD_BIAS, 0); /* do multiply */
|
||||
vax_fmul (&a, &b, 56, FD_BIAS, 0); /* do multiply */
|
||||
return rpackfd (&a, rh); /* round and pack */
|
||||
}
|
||||
|
||||
@@ -441,17 +441,17 @@ void vax_fmul (UFP *a, UFP *b, int32 prec, int32 bias, t_int64 mask)
|
||||
{
|
||||
t_uint64 ah, bh, al, bl, rhi, rlo, rmid1, rmid2;
|
||||
|
||||
if ((a -> exp == 0) || (b -> exp == 0)) { /* zero argument? */
|
||||
a -> frac = a -> sign = a -> exp = 0; /* result is zero */
|
||||
if ((a->exp == 0) || (b->exp == 0)) { /* zero argument? */
|
||||
a->frac = a->sign = a->exp = 0; /* result is zero */
|
||||
return; }
|
||||
a -> sign = a -> sign ^ b -> sign; /* sign of result */
|
||||
a -> exp = a -> exp + b -> exp - bias; /* add exponents */
|
||||
ah = (a -> frac >> 32) & M32; /* split operands */
|
||||
bh = (b -> frac >> 32) & M32; /* into 32b chunks */
|
||||
a->sign = a->sign ^ b->sign; /* sign of result */
|
||||
a->exp = a->exp + b->exp - bias; /* add exponents */
|
||||
ah = (a->frac >> 32) & M32; /* split operands */
|
||||
bh = (b->frac >> 32) & M32; /* into 32b chunks */
|
||||
rhi = ah * bh; /* high result */
|
||||
if (prec > 32) { /* 64b needed? */
|
||||
al = a -> frac & M32;
|
||||
bl = b -> frac & M32;
|
||||
al = a->frac & M32;
|
||||
bl = b->frac & M32;
|
||||
rmid1 = ah * bl;
|
||||
rmid2 = al * bh;
|
||||
rlo = al * bl;
|
||||
@@ -460,7 +460,7 @@ if (prec > 32) { /* 64b needed? */
|
||||
if (rmid1 < rlo) rhi = rhi + 1; /* carry? incr hi */
|
||||
rmid2 = rmid1 + (rmid2 << 32); /* add mid2 to to */
|
||||
if (rmid2 < rmid1) rhi = rhi + 1; } /* carry? incr hi */
|
||||
a -> frac = rhi & ~mask; /* mask out */
|
||||
a->frac = rhi & ~mask; /* mask out */
|
||||
norm (a); /* normalize */
|
||||
return;
|
||||
}
|
||||
@@ -508,19 +508,19 @@ void vax_fdiv (UFP *a, UFP *b, int32 prec, int32 bias)
|
||||
int32 i;
|
||||
t_uint64 quo = 0;
|
||||
|
||||
if (a -> exp == 0) FLT_DZRO_FAULT; /* divr = 0? */
|
||||
if (b -> exp == 0) return; /* divd = 0? */
|
||||
b -> sign = b -> sign ^ a -> sign; /* result sign */
|
||||
b -> exp = b -> exp - a -> exp + bias + 1; /* unbiased exp */
|
||||
a -> frac = a -> frac >> 1; /* allow 1 bit left */
|
||||
b -> frac = b -> frac >> 1;
|
||||
for (i = 0; (i < prec) && b -> frac; i++) { /* divide loop */
|
||||
if (a->exp == 0) FLT_DZRO_FAULT; /* divr = 0? */
|
||||
if (b->exp == 0) return; /* divd = 0? */
|
||||
b->sign = b->sign ^ a->sign; /* result sign */
|
||||
b->exp = b->exp - a->exp + bias + 1; /* unbiased exp */
|
||||
a->frac = a->frac >> 1; /* allow 1 bit left */
|
||||
b->frac = b->frac >> 1;
|
||||
for (i = 0; (i < prec) && b->frac; i++) { /* divide loop */
|
||||
quo = quo << 1; /* shift quo */
|
||||
if (b -> frac >= a -> frac) { /* div step ok? */
|
||||
b -> frac = b -> frac - a -> frac; /* subtract */
|
||||
if (b->frac >= a->frac) { /* div step ok? */
|
||||
b->frac = b->frac - a->frac; /* subtract */
|
||||
quo = quo + 1; } /* quo bit = 1 */
|
||||
b -> frac = b -> frac << 1; } /* shift divd */
|
||||
b -> frac = quo << (UF_V_NM - i + 1); /* shift quo */
|
||||
b->frac = b->frac << 1; } /* shift divd */
|
||||
b->frac = quo << (UF_V_NM - i + 1); /* shift quo */
|
||||
norm (b); /* normalize */
|
||||
return;
|
||||
}
|
||||
@@ -572,13 +572,13 @@ return rpackg (&a, flo); /* return frac */
|
||||
|
||||
void vax_fmod (UFP *a, int32 bias, int32 *intgr, int32 *flg)
|
||||
{
|
||||
if (a -> exp <= bias) *intgr = 0; /* 0 or <1? int = 0 */
|
||||
else if (a -> exp <= (bias + 64)) { /* in range? */
|
||||
*intgr = (int32) (a -> frac >> (64 - (a -> exp - bias)));
|
||||
a -> frac = a -> frac << (a -> exp - bias); }
|
||||
if (a->exp <= bias) *intgr = 0; /* 0 or <1? int = 0 */
|
||||
else if (a->exp <= (bias + 64)) { /* in range? */
|
||||
*intgr = (int32) (a->frac >> (64 - (a->exp - bias)));
|
||||
a->frac = a->frac << (a->exp - bias); }
|
||||
else *intgr = 0; /* out of range */
|
||||
if (a -> sign) *intgr = -*intgr; /* -? comp int */
|
||||
if ((a -> exp >= (bias + 32)) || (((a -> sign) != 0) && (*intgr < 0)))
|
||||
if (a->sign) *intgr = -*intgr; /* -? comp int */
|
||||
if ((a->exp >= (bias + 32)) || (((a->sign) != 0) && (*intgr < 0)))
|
||||
*flg = CC_V; /* test ovflo */
|
||||
else *flg = 0;
|
||||
norm (a); /* normalize */
|
||||
@@ -684,40 +684,40 @@ return;
|
||||
|
||||
void unpackf (int32 hi, UFP *r)
|
||||
{
|
||||
r -> sign = hi & FPSIGN; /* get sign */
|
||||
r -> exp = FD_GETEXP (hi); /* get exponent */
|
||||
if (r -> exp == 0) { /* exp = 0? */
|
||||
if (r -> sign) RSVD_OPND_FAULT; /* if -, rsvd op */
|
||||
r -> frac = 0; /* else 0 */
|
||||
r->sign = hi & FPSIGN; /* get sign */
|
||||
r->exp = FD_GETEXP (hi); /* get exponent */
|
||||
if (r->exp == 0) { /* exp = 0? */
|
||||
if (r->sign) RSVD_OPND_FAULT; /* if -, rsvd op */
|
||||
r->frac = 0; /* else 0 */
|
||||
return; }
|
||||
hi = (((hi & FD_FRACW) | FD_HB) << 16) | ((hi >> 16) & 0xFFFF);
|
||||
r -> frac = ((t_uint64) hi) << (32 + UF_V_FDLO);
|
||||
r->frac = ((t_uint64) hi) << (32 + UF_V_FDLO);
|
||||
return;
|
||||
}
|
||||
|
||||
void unpackd (int32 hi, int32 lo, UFP *r)
|
||||
{
|
||||
r -> sign = hi & FPSIGN; /* get sign */
|
||||
r -> exp = FD_GETEXP (hi); /* get exponent */
|
||||
if (r -> exp == 0) { /* exp = 0? */
|
||||
if (r -> sign) RSVD_OPND_FAULT; /* if -, rsvd op */
|
||||
r -> frac = 0; /* else 0 */
|
||||
r->sign = hi & FPSIGN; /* get sign */
|
||||
r->exp = FD_GETEXP (hi); /* get exponent */
|
||||
if (r->exp == 0) { /* exp = 0? */
|
||||
if (r->sign) RSVD_OPND_FAULT; /* if -, rsvd op */
|
||||
r->frac = 0; /* else 0 */
|
||||
return; }
|
||||
hi = (hi & FD_FRACL) | FD_HB; /* canonical form */
|
||||
r -> frac = UNSCRAM (hi, lo) << UF_V_FDLO; /* guard bits */
|
||||
r->frac = UNSCRAM (hi, lo) << UF_V_FDLO; /* guard bits */
|
||||
return;
|
||||
}
|
||||
|
||||
void unpackg (int32 hi, int32 lo, UFP *r)
|
||||
{
|
||||
r -> sign = hi & FPSIGN; /* get sign */
|
||||
r -> exp = G_GETEXP (hi); /* get exponent */
|
||||
if (r -> exp == 0) { /* exp = 0? */
|
||||
if (r -> sign) RSVD_OPND_FAULT; /* if -, rsvd op */
|
||||
r -> frac = 0; /* else 0 */
|
||||
r->sign = hi & FPSIGN; /* get sign */
|
||||
r->exp = G_GETEXP (hi); /* get exponent */
|
||||
if (r->exp == 0) { /* exp = 0? */
|
||||
if (r->sign) RSVD_OPND_FAULT; /* if -, rsvd op */
|
||||
r->frac = 0; /* else 0 */
|
||||
return; }
|
||||
hi = (hi & G_FRACL) | G_HB; /* canonical form */
|
||||
r -> frac = UNSCRAM (hi, lo) << UF_V_GLO; /* guard bits */
|
||||
r->frac = UNSCRAM (hi, lo) << UF_V_GLO; /* guard bits */
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -729,45 +729,45 @@ static t_uint64 normmask[5] = {
|
||||
0xffff000000000000, 0xffffffff00000000 };
|
||||
static int32 normtab[6] = { 1, 2, 4, 8, 16, 32};
|
||||
|
||||
if (r -> frac == 0) { /* if fraction = 0 */
|
||||
r -> sign = r -> exp = 0; /* result is 0 */
|
||||
if (r->frac == 0) { /* if fraction = 0 */
|
||||
r->sign = r->exp = 0; /* result is 0 */
|
||||
return; }
|
||||
while ((r -> frac & UF_NM) == 0) { /* normalized? */
|
||||
while ((r->frac & UF_NM) == 0) { /* normalized? */
|
||||
for (i = 0; i < 5; i++) { /* find first 1 */
|
||||
if (r -> frac & normmask[i]) break; }
|
||||
r -> frac = r -> frac << normtab[i]; /* shift frac */
|
||||
r -> exp = r -> exp - normtab[i]; } /* decr exp */
|
||||
if (r->frac & normmask[i]) break; }
|
||||
r->frac = r->frac << normtab[i]; /* shift frac */
|
||||
r->exp = r->exp - normtab[i]; } /* decr exp */
|
||||
return;
|
||||
}
|
||||
|
||||
int32 rpackfd (UFP *r, int32 *rh)
|
||||
{
|
||||
if (rh) *rh = 0; /* assume 0 */
|
||||
if (r -> frac == 0) return 0; /* result 0? */
|
||||
r -> frac = r -> frac + (rh? UF_DRND: UF_FRND); /* round */
|
||||
if ((r -> frac & UF_NM) == 0) { /* carry out? */
|
||||
r -> frac = r -> frac >> 1; /* renormalize */
|
||||
r -> exp = r -> exp + 1; }
|
||||
if (r -> exp > (int32) FD_M_EXP) FLT_OVFL_FAULT; /* ovflo? fault */
|
||||
if (r -> exp <= 0) { /* underflow? */
|
||||
if (r->frac == 0) return 0; /* result 0? */
|
||||
r->frac = r->frac + (rh? UF_DRND: UF_FRND); /* round */
|
||||
if ((r->frac & UF_NM) == 0) { /* carry out? */
|
||||
r->frac = r->frac >> 1; /* renormalize */
|
||||
r->exp = r->exp + 1; }
|
||||
if (r->exp > (int32) FD_M_EXP) FLT_OVFL_FAULT; /* ovflo? fault */
|
||||
if (r->exp <= 0) { /* underflow? */
|
||||
if (PSL & PSW_FU) FLT_UNFL_FAULT; /* fault if fu */
|
||||
return 0; } /* else 0 */
|
||||
if (rh) *rh = UF_GETFDLO (r -> frac); /* get low */
|
||||
return r -> sign | (r -> exp << FD_V_EXP) | UF_GETFDHI (r -> frac);
|
||||
if (rh) *rh = UF_GETFDLO (r->frac); /* get low */
|
||||
return r->sign | (r->exp << FD_V_EXP) | UF_GETFDHI (r->frac);
|
||||
}
|
||||
|
||||
int32 rpackg (UFP *r, int32 *rh)
|
||||
{
|
||||
*rh = 0; /* assume 0 */
|
||||
if (r -> frac == 0) return 0; /* result 0? */
|
||||
r -> frac = r -> frac + UF_GRND; /* round */
|
||||
if ((r -> frac & UF_NM) == 0) { /* carry out? */
|
||||
r -> frac = r -> frac >> 1; /* renormalize */
|
||||
r -> exp = r -> exp + 1; }
|
||||
if (r -> exp > (int32) G_M_EXP) FLT_OVFL_FAULT; /* ovflo? fault */
|
||||
if (r -> exp <= 0) { /* underflow? */
|
||||
if (r->frac == 0) return 0; /* result 0? */
|
||||
r->frac = r->frac + UF_GRND; /* round */
|
||||
if ((r->frac & UF_NM) == 0) { /* carry out? */
|
||||
r->frac = r->frac >> 1; /* renormalize */
|
||||
r->exp = r->exp + 1; }
|
||||
if (r->exp > (int32) G_M_EXP) FLT_OVFL_FAULT; /* ovflo? fault */
|
||||
if (r->exp <= 0) { /* underflow? */
|
||||
if (PSL & PSW_FU) FLT_UNFL_FAULT; /* fault if fu */
|
||||
return 0; } /* else 0 */
|
||||
if (rh) *rh = UF_GETGLO (r -> frac); /* get low */
|
||||
return r -> sign | (r -> exp << G_V_EXP) | UF_GETGHI (r -> frac);
|
||||
if (rh) *rh = UF_GETGLO (r->frac); /* get low */
|
||||
return r->sign | (r->exp << G_V_EXP) | UF_GETGHI (r->frac);
|
||||
}
|
||||
|
||||
373
VAX/vax_io.c
373
VAX/vax_io.c
@@ -24,6 +24,11 @@
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
qba Qbus adapter
|
||||
|
||||
12-Oct-02 RMS Added autoconfigure support
|
||||
Added SHOW IO space routine
|
||||
29-Sep-02 RMS Added dynamic table support
|
||||
07-Sep-02 RMS Added TMSCP and variable vector support
|
||||
*/
|
||||
|
||||
#include "vax_defs.h"
|
||||
@@ -86,7 +91,6 @@ int32 cq_mear = 0; /* MEAR */
|
||||
int32 cq_sear = 0; /* SEAR */
|
||||
int32 cq_mbr = 0; /* MBR */
|
||||
int32 cq_ipc = 0; /* IPC */
|
||||
static int_dummy = 0; /* keep save/restore working */
|
||||
|
||||
extern uint32 *M;
|
||||
extern UNIT cpu_unit;
|
||||
@@ -94,6 +98,7 @@ extern int32 PSL, SISR, trpirq, mem_err;
|
||||
extern int32 p1;
|
||||
extern int32 ssc_bto;
|
||||
extern jmp_buf save_env;
|
||||
extern DEVICE *sim_devices[];
|
||||
|
||||
extern int32 ReadB (t_addr pa);
|
||||
extern int32 ReadW (t_addr pa);
|
||||
@@ -101,10 +106,6 @@ extern int32 ReadL (t_addr pa);
|
||||
extern int32 WriteB (t_addr pa, int32 val);
|
||||
extern int32 WriteW (t_addr pa, int32 val);
|
||||
extern int32 WriteL (t_addr pa, int32 val);
|
||||
extern DIB pt_dib;
|
||||
extern DIB lpt_dib, dz_dib;
|
||||
extern DIB rl_dib, rq_dib;
|
||||
extern DIB ts_dib;
|
||||
extern FILE *sim_log;
|
||||
|
||||
t_stat dbl_rd (int32 *data, int32 addr, int32 access);
|
||||
@@ -112,13 +113,7 @@ t_stat dbl_wr (int32 data, int32 addr, int32 access);
|
||||
int32 eval_int (void);
|
||||
void cq_merr (int32 pa);
|
||||
void cq_serr (int32 pa);
|
||||
t_bool dev_conflict (uint32 nba, DIB *curr);
|
||||
t_stat qba_reset (DEVICE *dptr);
|
||||
extern int32 rq_inta (void);
|
||||
extern int32 tmr0_inta (void);
|
||||
extern int32 tmr1_inta (void);
|
||||
extern dz_rxinta (void);
|
||||
extern dz_txinta (void);
|
||||
|
||||
/* Qbus adapter data structures
|
||||
|
||||
@@ -127,7 +122,7 @@ extern dz_txinta (void);
|
||||
qba_reg QBA register list
|
||||
*/
|
||||
|
||||
DIB qba_dib = { 1, IOBA_DBL, IOLN_DBL, &dbl_rd, &dbl_wr };
|
||||
DIB qba_dib = { IOBA_DBL, IOLN_DBL, &dbl_rd, &dbl_wr, 0 };
|
||||
|
||||
UNIT qba_unit = { UDATA (NULL, 0, 0) };
|
||||
|
||||
@@ -138,7 +133,6 @@ REG qba_reg[] = {
|
||||
{ HRDATA (SEAR, cq_sear, 20) },
|
||||
{ HRDATA (MBR, cq_mbr, 29) },
|
||||
{ HRDATA (IPC, cq_ipc, 16) },
|
||||
{ HRDATA (IPL18, int_dummy, 32), REG_HRO },
|
||||
{ HRDATA (IPL17, int_req[3], 32), REG_RO },
|
||||
{ HRDATA (IPL16, int_req[2], 32), REG_RO },
|
||||
{ HRDATA (IPL15, int_req[1], 32), REG_RO },
|
||||
@@ -149,48 +143,20 @@ DEVICE qba_dev = {
|
||||
"QBA", &qba_unit, qba_reg, NULL,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
NULL, NULL, &qba_reset,
|
||||
NULL, NULL, NULL };
|
||||
|
||||
struct iolink { /* I/O page linkage */
|
||||
int32 low; /* low I/O addr */
|
||||
int32 high; /* high I/O addr */
|
||||
int32 *enb; /* enable flag */
|
||||
t_stat (*read)(); /* read routine */
|
||||
t_stat (*write)(); }; /* write routine */
|
||||
NULL, NULL, NULL,
|
||||
&qba_dib, DEV_QBUS };
|
||||
|
||||
/* IO page addresses */
|
||||
|
||||
DIB *dib_tab[] = {
|
||||
&dz_dib,
|
||||
&rq_dib,
|
||||
&rl_dib,
|
||||
&pt_dib,
|
||||
&lpt_dib,
|
||||
&ts_dib,
|
||||
&qba_dib,
|
||||
NULL };
|
||||
DIB *dib_tab[DIB_MAX]; /* DIB table */
|
||||
|
||||
/* Interrupt request to interrupt action map */
|
||||
|
||||
int32 (*int_ack[IPL_HLVL][32])() = { /* int ack routines */
|
||||
{ NULL, NULL, NULL, NULL, /* IPL 14 */
|
||||
NULL, NULL, NULL, &tmr0_inta,
|
||||
&tmr1_inta },
|
||||
{ &rq_inta, NULL, &dz_rxinta, &dz_txinta, /* IPL 15 */
|
||||
NULL, NULL },
|
||||
{ NULL }, /* IPL 16 */
|
||||
{ NULL } }; /* IPL 17 */
|
||||
int32 (*int_ack[IPL_HLVL][32])(); /* int ack routines */
|
||||
|
||||
/* Interrupt request to vector map */
|
||||
|
||||
int32 int_vec[IPL_HLVL][32] = { /* int req to vector */
|
||||
{ SCB_TTI, SCB_TTO, VEC_PTR, VEC_PTP, /* IPL 14 */
|
||||
VEC_LPT, SCB_CSI, SCB_CSO, 0,
|
||||
0 },
|
||||
{ VEC_RQ, VEC_RL, VEC_DZRX, VEC_DZTX, /* IPL 15 */
|
||||
VEC_RP, VEC_TS },
|
||||
{ SCB_INTTIM }, /* IPL 16 */
|
||||
{ 0 } }; /* IPL 17 */
|
||||
int32 int_vec[IPL_HLVL][32]; /* int req to vector */
|
||||
|
||||
/* The KA65x handles errors in I/O space as follows
|
||||
|
||||
@@ -204,9 +170,9 @@ int32 i, val;
|
||||
DIB *dibp;
|
||||
|
||||
for (i = 0; dibp = dib_tab[i]; i++ ) {
|
||||
if (dibp -> enb && (pa >= dibp -> ba) &&
|
||||
(pa < (dibp -> ba + dibp -> lnt))) {
|
||||
dibp -> rd (&val, pa, READ);
|
||||
if ((pa >= dibp->ba) &&
|
||||
(pa < (dibp->ba + dibp->lnt))) {
|
||||
dibp->rd (&val, pa, READ);
|
||||
return val; } }
|
||||
cq_merr (pa);
|
||||
MACH_CHECK (MCHK_READ);
|
||||
@@ -219,9 +185,9 @@ int32 i;
|
||||
DIB *dibp;
|
||||
|
||||
for (i = 0; dibp = dib_tab[i]; i++ ) {
|
||||
if (dibp -> enb && (pa >= dibp -> ba) &&
|
||||
(pa < (dibp -> ba + dibp -> lnt))) {
|
||||
dibp -> wr (val, pa, mode);
|
||||
if ((pa >= dibp->ba) &&
|
||||
(pa < (dibp->ba + dibp->lnt))) {
|
||||
dibp->wr (val, pa, mode);
|
||||
return; } }
|
||||
cq_merr (pa);
|
||||
mem_err = 1;
|
||||
@@ -292,7 +258,7 @@ for (i = IPL_SMAX; i > ipl; i--) { /* check swre int */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return vector for highest priority hardware interrupt at IPL lvl*/
|
||||
/* Return vector for highest priority hardware interrupt at IPL lvl */
|
||||
|
||||
int32 get_vector (int32 lvl)
|
||||
{
|
||||
@@ -635,85 +601,296 @@ for (i = ma = 0; i < bc; i = i + 4, buf++) { /* by lw */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Change device number for a device */
|
||||
/* Change device address */
|
||||
|
||||
t_stat set_addr (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
DIB *dibp;
|
||||
uint32 newba;
|
||||
t_stat r;
|
||||
|
||||
if (cptr == NULL) return SCPE_ARG;
|
||||
if ((val == 0) || (desc == NULL)) return SCPE_IERR;
|
||||
dibp = (DIB *) desc;
|
||||
if ((val == 0) || (uptr == NULL)) return SCPE_IERR;
|
||||
dptr = find_dev_from_unit (uptr);
|
||||
if (dptr == NULL) return SCPE_IERR;
|
||||
dibp = (DIB *) dptr->ctxt;
|
||||
if (dibp == NULL) return SCPE_IERR;
|
||||
newba = (uint32) get_uint (cptr, 16, IOPAGEBASE+IOPAGEMASK, &r); /* get new */
|
||||
if ((r != SCPE_OK) || (newba == dibp -> ba)) return r;
|
||||
if (newba <= IOPAGEBASE) return SCPE_ARG; /* must be > 0 */
|
||||
if (newba % ((uint32) val)) return SCPE_ARG; /* check modulus */
|
||||
if (dev_conflict (newba, dibp)) return SCPE_OK;
|
||||
dibp -> ba = newba; /* store */
|
||||
return SCPE_OK;
|
||||
if (r != SCPE_OK) return r;
|
||||
if ((newba <= IOPAGEBASE) || /* must be > 0 */
|
||||
(newba % ((uint32) val))) return SCPE_ARG; /* check modulus */
|
||||
dibp->ba = newba; /* store */
|
||||
dptr->flags = dptr->flags & ~DEV_FLTA; /* not floating */
|
||||
return auto_config (0, 0); /* autoconfigure */
|
||||
}
|
||||
|
||||
/* Show device address */
|
||||
|
||||
t_stat show_addr (FILE *st, UNIT *uptr, int32 val, void *desc)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
DIB *dibp;
|
||||
|
||||
if (desc == NULL) return SCPE_IERR;
|
||||
dibp = (DIB *) desc;
|
||||
if (dibp -> ba <= IOPAGEBASE) return SCPE_IERR;
|
||||
fprintf (st, "address=%08X", dibp -> ba);
|
||||
if (dibp -> lnt > 1)
|
||||
fprintf (st, "-%08X", dibp -> ba + dibp -> lnt - 1);
|
||||
if (uptr == NULL) return SCPE_IERR;
|
||||
dptr = find_dev_from_unit (uptr);
|
||||
if (dptr == NULL) return SCPE_IERR;
|
||||
dibp = (DIB *) dptr->ctxt;
|
||||
if ((dibp == NULL) || (dibp->ba <= IOPAGEBASE)) return SCPE_IERR;
|
||||
fprintf (st, "address=%08X", dibp->ba);
|
||||
if (dibp->lnt > 1)
|
||||
fprintf (st, "-%08X", dibp->ba + dibp->lnt - 1);
|
||||
if (dptr->flags & DEV_FLTA) fprintf (st, "*");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Enable or disable a device */
|
||||
/* Set address floating */
|
||||
|
||||
t_stat set_enbdis (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
t_stat set_addr_flt (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
int32 i;
|
||||
DEVICE *dptr;
|
||||
DIB *dibp;
|
||||
UNIT *up;
|
||||
|
||||
if (cptr != NULL) return SCPE_ARG;
|
||||
if ((uptr == NULL) || (desc == NULL)) return SCPE_IERR;
|
||||
dptr = find_dev_from_unit (uptr); /* find device */
|
||||
if (cptr == NULL) return SCPE_ARG;
|
||||
if ((val == 0) || (uptr == NULL)) return SCPE_IERR;
|
||||
dptr = find_dev_from_unit (uptr);
|
||||
if (dptr == NULL) return SCPE_IERR;
|
||||
dibp = (DIB *) desc;
|
||||
if ((val ^ dibp -> enb) == 0) return SCPE_OK; /* enable chg? */
|
||||
if (val) { /* enable? */
|
||||
if (dev_conflict (dibp -> ba, dibp)) return SCPE_OK; }
|
||||
else { /* disable */
|
||||
for (i = 0; i < dptr -> numunits; i++) { /* check units */
|
||||
up = (dptr -> units) + i;
|
||||
if ((up -> flags & UNIT_ATT) || sim_is_active (up))
|
||||
return SCPE_NOFNC; } }
|
||||
dibp -> enb = val;
|
||||
if (dptr -> reset) return dptr -> reset (dptr);
|
||||
else return SCPE_OK;
|
||||
dptr->flags = dptr->flags | DEV_FLTA; /* floating */
|
||||
return auto_config (0, 0); /* autoconfigure */
|
||||
}
|
||||
|
||||
/* Change device vector */
|
||||
|
||||
t_stat set_vec (UNIT *uptr, int32 arg, char *cptr, void *desc)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
DIB *dibp;
|
||||
uint32 newvec;
|
||||
t_stat r;
|
||||
|
||||
if (cptr == NULL) return SCPE_ARG;
|
||||
if (uptr == NULL) return SCPE_IERR;
|
||||
dptr = find_dev_from_unit (uptr);
|
||||
if (dptr == NULL) return SCPE_IERR;
|
||||
dibp = (DIB *) dptr->ctxt;
|
||||
if (dibp == NULL) return SCPE_IERR;
|
||||
newvec = (uint32) get_uint (cptr, 16, VEC_Q + 01000, &r);
|
||||
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;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Show device vector */
|
||||
|
||||
t_stat show_vec (FILE *st, UNIT *uptr, int32 arg, void *desc)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
DIB *dibp;
|
||||
uint32 vec, numvec;
|
||||
|
||||
if (uptr == NULL) return SCPE_IERR;
|
||||
dptr = find_dev_from_unit (uptr);
|
||||
if (dptr == NULL) return SCPE_IERR;
|
||||
dibp = (DIB *) dptr->ctxt;
|
||||
if (dibp == NULL) return SCPE_IERR;
|
||||
vec = dibp->vec;
|
||||
if (arg) numvec = arg;
|
||||
else numvec = dibp->vnum;
|
||||
if (vec == 0) fprintf (st, "no vector");
|
||||
else { fprintf (st, "vector=%X", vec);
|
||||
if (numvec > 1) fprintf (st, "-%X", vec + (4 * (numvec - 1))); }
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Test for conflict in device addresses */
|
||||
|
||||
t_bool dev_conflict (uint32 nba, DIB *curr)
|
||||
t_bool dev_conflict (DIB *curr)
|
||||
{
|
||||
uint32 i, end;
|
||||
DEVICE *dptr;
|
||||
DIB *dibp;
|
||||
|
||||
end = nba + curr -> lnt - 1; /* get end */
|
||||
for (i = 0; dibp = dib_tab[i]; i++) { /* loop thru dev */
|
||||
if (!dibp -> enb || (dibp == curr)) continue; /* skip disabled */
|
||||
if (((nba >= dibp -> ba) &&
|
||||
(nba < (dibp -> ba + dibp -> lnt))) ||
|
||||
((end >= dibp -> ba) &&
|
||||
(end < (dibp -> ba + dibp -> lnt)))) {
|
||||
printf ("Device address conflict at %08X\n", dibp -> ba);
|
||||
end = curr->ba + curr->lnt - 1; /* get end */
|
||||
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */
|
||||
dibp = (DIB *) dptr->ctxt; /* get DIB */
|
||||
if ((dibp == NULL) || (dibp == curr) ||
|
||||
(dptr->flags & DEV_DIS)) continue;
|
||||
if (((curr->ba >= dibp->ba) && /* overlap start? */
|
||||
(curr->ba < (dibp->ba + dibp->lnt))) ||
|
||||
((end >= dibp->ba) && /* overlap end? */
|
||||
(end < (dibp->ba + dibp->lnt)))) {
|
||||
printf ("Device %s address conflict at %08X\n", dptr->name, dibp->ba);
|
||||
if (sim_log) fprintf (sim_log,
|
||||
"Device number conflict at %08X\n", dibp -> ba);
|
||||
"Device %s address conflict at %08X\n", dptr->name, dibp->ba);
|
||||
return TRUE; } }
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Build interrupt tables */
|
||||
|
||||
void build_int_vec (int32 vloc, int32 ivec, int32 (*iack)(void) )
|
||||
{
|
||||
int32 ilvl = vloc / 32;
|
||||
int32 ibit = vloc % 32;
|
||||
|
||||
if (iack != NULL) int_ack[ilvl][ibit] = iack;
|
||||
else int_vec[ilvl][ibit] = ivec;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Build dib_tab from device list */
|
||||
|
||||
t_stat build_dib_tab (void)
|
||||
{
|
||||
int32 i, j, k;
|
||||
DEVICE *dptr;
|
||||
DIB *dibp;
|
||||
|
||||
for (i = 0; i < IPL_HLVL; i++) { /* clear int tables */
|
||||
for (j = 0; j < 32; j++) {
|
||||
int_vec[i][j] = 0;
|
||||
int_ack[i][j] = NULL; } }
|
||||
for (i = j = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */
|
||||
dibp = (DIB *) dptr->ctxt; /* get DIB */
|
||||
if (dibp && !(dptr->flags & DEV_DIS)) { /* defined, enabled? */
|
||||
if (dibp->vnum > VEC_DEVMAX) return SCPE_IERR;
|
||||
for (k = 0; k < dibp->vnum; k++) /* loop thru vec */
|
||||
build_int_vec (dibp->vloc + k, /* add vector */
|
||||
dibp->vec + (k * 4), dibp->ack[k]);
|
||||
if (dibp->lnt != 0) { /* I/O addresses? */
|
||||
dib_tab[j++] = dibp; /* add DIB to dib_tab */
|
||||
if (j >= DIB_MAX) return SCPE_IERR; } /* too many? */
|
||||
} /* end if enabled */
|
||||
} /* end for */
|
||||
dib_tab[j] = NULL; /* end with NULL */
|
||||
for (i = 0; (dibp = dib_tab[i]) != NULL; i++) { /* test built dib_tab */
|
||||
if (dev_conflict (dibp)) return SCPE_STOP; } /* for conflicts */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Show dib_tab */
|
||||
|
||||
t_stat show_iospace (FILE *st, UNIT *uptr, int32 val, void *desc)
|
||||
{
|
||||
int32 i, j, done = 0;
|
||||
DEVICE *dptr;
|
||||
DIB *dibt;
|
||||
|
||||
build_dib_tab (); /* build table */
|
||||
while (done == 0) { /* sort ascending */
|
||||
done = 1; /* assume done */
|
||||
for (i = 0; dib_tab[i + 1] != NULL; i++) { /* check table */
|
||||
if (dib_tab[i]->ba > dib_tab[i + 1]->ba) { /* out of order? */
|
||||
dibt = dib_tab[i]; /* interchange */
|
||||
dib_tab[i] = dib_tab[i + 1];
|
||||
dib_tab[i + 1] = dibt;
|
||||
done = 0; } } /* not done */
|
||||
} /* end while */
|
||||
for (i = 0; dib_tab[i] != NULL; i++) { /* print table */
|
||||
for (j = 0, dptr = NULL; sim_devices[j] != NULL; j++) {
|
||||
if (((DIB*) sim_devices[j]->ctxt) == dib_tab[i]) {
|
||||
dptr = sim_devices[j];
|
||||
break; } }
|
||||
fprintf (st, "%08X - %08X%c\t%s\n", dib_tab[i]->ba,
|
||||
dib_tab[i]->ba + dib_tab[i]->lnt - 1,
|
||||
(dptr && (dptr->flags & DEV_FLTA))? '*': ' ',
|
||||
dptr? dptr->name: "CPU");
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Autoconfiguration */
|
||||
|
||||
#define AUTO_DYN 0001
|
||||
#define AUTO_VEC 0002
|
||||
#define AUTO_MAXC 4
|
||||
#define AUTO_CSRBASE 0010
|
||||
#define AUTO_VECBASE 0300
|
||||
|
||||
struct auto_con {
|
||||
uint32 amod;
|
||||
uint32 vmod;
|
||||
uint32 flags;
|
||||
uint32 num;
|
||||
uint32 fix;
|
||||
char *dnam[AUTO_MAXC]; };
|
||||
|
||||
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" } },
|
||||
|
||||
{ 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 */
|
||||
|
||||
{ 0x7, 0 }, /* reserved */
|
||||
{ 0x7, 0x3 }, /* RX11/RX211 */
|
||||
{ 0x7, 0x3 }, /* DR11W */
|
||||
{ 0x7, 0x3 }, /* DR11B */
|
||||
{ 0x7, 0x7 }, /* DMP11 */
|
||||
{ 0x7, 0x7 }, /* DPV11 */
|
||||
{ 0x7, 0x7 }, /* ISB11 */
|
||||
{ 0xf, 0x7 }, /* DMV11 */
|
||||
|
||||
{ 0x7, 0x3 }, /* DEUNA/DELUA */
|
||||
{ 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 */
|
||||
{ 0xf, 0x7 }, /* DHU11/DHQ11 */
|
||||
|
||||
{ 0x1f, 0x7 }, /* DMZ32 */
|
||||
{ 0x1f, 0x7 }, /* CP132 */
|
||||
{ 0 }, /* padding */
|
||||
};
|
||||
|
||||
t_stat auto_config (uint32 rank, uint32 nctrl)
|
||||
{
|
||||
uint32 csr = IOPAGEBASE + AUTO_CSRBASE;
|
||||
uint32 vec = VEC_Q + AUTO_VECBASE;
|
||||
struct auto_con *autp;
|
||||
DEVICE *dptr;
|
||||
DIB *dibp;
|
||||
int32 i, j, k;
|
||||
extern DEVICE *find_dev (char *ptr);
|
||||
|
||||
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 */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
338
VAX/vax_stddev.c
338
VAX/vax_stddev.c
@@ -23,12 +23,12 @@
|
||||
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
|
||||
tti terminal input
|
||||
tto terminal output
|
||||
clk line frequency clock
|
||||
clk 100Hz and TODR clock
|
||||
|
||||
01-Nov-02 RMS Added 7B/8B capability to terminal
|
||||
12-Sep-02 RMS Removed paper tape, added variable vector support
|
||||
30-May-02 RMS Widened POS to 32b
|
||||
30-Apr-02 RMS Automatically set TODR to VMS-correct value during boot
|
||||
*/
|
||||
@@ -36,10 +36,6 @@
|
||||
#include "vax_defs.h"
|
||||
#include <time.h>
|
||||
|
||||
#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 TTICSR_IMP (CSR_DONE + CSR_IE) /* terminal input */
|
||||
#define TTICSR_RW (CSR_IE)
|
||||
#define TTOCSR_IMP (CSR_DONE + CSR_IE) /* terminal output */
|
||||
@@ -49,11 +45,11 @@
|
||||
#define CLK_DELAY 5000 /* 100 Hz */
|
||||
#define TMXR_MULT 2 /* 50 Hz */
|
||||
|
||||
#define UNIT_V_8B (UNIT_V_UF + 0) /* 8B mode */
|
||||
#define UNIT_8B (1 << UNIT_V_8B)
|
||||
|
||||
extern int32 int_req[IPL_HLVL];
|
||||
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 tti_csr = 0; /* control/status */
|
||||
int32 tto_csr = 0; /* control/status */
|
||||
int32 clk_csr = 0; /* control/status */
|
||||
@@ -63,100 +59,12 @@ int32 todr_blow = 1; /* TODR battery low */
|
||||
int32 tmxr_poll = CLK_DELAY * TMXR_MULT; /* term mux poll */
|
||||
int32 tmr_poll = CLK_DELAY; /* pgm timer poll */
|
||||
|
||||
t_stat pt_rd (int32 *data, int32 PA, int32 access);
|
||||
t_stat pt_wr (int32 data, int32 PA, int32 access);
|
||||
t_stat ptr_svc (UNIT *uptr);
|
||||
t_stat ptp_svc (UNIT *uptr);
|
||||
t_stat tti_svc (UNIT *uptr);
|
||||
t_stat tto_svc (UNIT *uptr);
|
||||
t_stat clk_svc (UNIT *uptr);
|
||||
t_stat ptr_reset (DEVICE *dptr);
|
||||
t_stat ptp_reset (DEVICE *dptr);
|
||||
t_stat tti_reset (DEVICE *dptr);
|
||||
t_stat tto_reset (DEVICE *dptr);
|
||||
t_stat clk_reset (DEVICE *dptr);
|
||||
t_stat ptr_attach (UNIT *uptr, char *ptr);
|
||||
t_stat ptr_detach (UNIT *uptr);
|
||||
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
|
||||
*/
|
||||
|
||||
DIB pt_dib = { 1, IOBA_PT, IOLN_PT, &pt_rd, &pt_wr };
|
||||
|
||||
UNIT ptr_unit = {
|
||||
UDATA (&ptr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0),
|
||||
SERIAL_IN_WAIT };
|
||||
|
||||
REG ptr_reg[] = {
|
||||
{ HRDATA (BUF, ptr_unit.buf, 8) },
|
||||
{ HRDATA (CSR, ptr_csr, 16) },
|
||||
{ FLDATA (INT, int_req[IPL_PTR], 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, 32), PV_LEFT },
|
||||
{ DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT },
|
||||
{ FLDATA (STOP_IOE, ptr_stopioe, 0) },
|
||||
{ NULL } };
|
||||
|
||||
MTAB ptr_mod[] = {
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL,
|
||||
NULL, &show_addr, &pt_dib },
|
||||
{ MTAB_XTD|MTAB_VDV, 1, NULL, "ENABLED",
|
||||
&set_enbdis, NULL, &pt_dib },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, NULL, "DISABLED",
|
||||
&set_enbdis, NULL, &pt_dib },
|
||||
{ 0 } };
|
||||
|
||||
DEVICE ptr_dev = {
|
||||
"PTR", &ptr_unit, ptr_reg, ptr_mod,
|
||||
1, 10, 31, 1, 16, 8,
|
||||
NULL, NULL, &ptr_reset,
|
||||
NULL, &ptr_attach, &ptr_detach };
|
||||
|
||||
/* PTP data structures
|
||||
|
||||
ptp_dev PTP device descriptor
|
||||
ptp_unit PTP unit descriptor
|
||||
ptp_reg PTP register list
|
||||
*/
|
||||
|
||||
UNIT ptp_unit = {
|
||||
UDATA (&ptp_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT };
|
||||
|
||||
REG ptp_reg[] = {
|
||||
{ HRDATA (BUF, ptp_unit.buf, 8) },
|
||||
{ HRDATA (CSR, ptp_csr, 16) },
|
||||
{ FLDATA (INT, int_req[IPL_PTP], 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, 32), 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, &pt_dib },
|
||||
{ MTAB_XTD|MTAB_VDV, 1, NULL, "ENABLED",
|
||||
&set_enbdis, NULL, &pt_dib },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, NULL, "DISABLED",
|
||||
&set_enbdis, NULL, &pt_dib },
|
||||
{ 0 } };
|
||||
|
||||
DEVICE ptp_dev = {
|
||||
"PTP", &ptp_unit, ptp_reg, ptp_mod,
|
||||
1, 10, 31, 1, 16, 8,
|
||||
NULL, NULL, &ptp_reset,
|
||||
NULL, &ptp_attach, &ptp_detach };
|
||||
|
||||
/* TTI data structures
|
||||
|
||||
@@ -165,7 +73,9 @@ DEVICE ptp_dev = {
|
||||
tti_reg TTI register list
|
||||
*/
|
||||
|
||||
UNIT tti_unit = { UDATA (&tti_svc, 0, 0), KBD_POLL_WAIT };
|
||||
DIB tti_dib = { 0, 0, NULL, NULL, 1, IVCL (TTI), SCB_TTI, { NULL } };
|
||||
|
||||
UNIT tti_unit = { UDATA (&tti_svc, UNIT_8B, 0), KBD_POLL_WAIT };
|
||||
|
||||
REG tti_reg[] = {
|
||||
{ HRDATA (BUF, tti_unit.buf, 8) },
|
||||
@@ -177,11 +87,18 @@ REG tti_reg[] = {
|
||||
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||
{ NULL } };
|
||||
|
||||
MTAB tti_mod[] = {
|
||||
{ UNIT_8B, UNIT_8B, "8b", "8B", NULL },
|
||||
{ UNIT_8B, 0 , "7b", "7B", NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL, NULL, &show_vec },
|
||||
{ 0 } };
|
||||
|
||||
DEVICE tti_dev = {
|
||||
"TTI", &tti_unit, tti_reg, NULL,
|
||||
"TTI", &tti_unit, tti_reg, tti_mod,
|
||||
1, 10, 31, 1, 16, 8,
|
||||
NULL, NULL, &tti_reset,
|
||||
NULL, NULL, NULL };
|
||||
NULL, NULL, NULL,
|
||||
&tti_dib, 0 };
|
||||
|
||||
/* TTO data structures
|
||||
|
||||
@@ -190,7 +107,9 @@ DEVICE tti_dev = {
|
||||
tto_reg TTO register list
|
||||
*/
|
||||
|
||||
UNIT tto_unit = { UDATA (&tto_svc, 0, 0), SERIAL_OUT_WAIT };
|
||||
DIB tto_dib = { 0, 0, NULL, NULL, 1, IVCL (TTO), SCB_TTO, { NULL } };
|
||||
|
||||
UNIT tto_unit = { UDATA (&tto_svc, UNIT_8B, 0), SERIAL_OUT_WAIT };
|
||||
|
||||
REG tto_reg[] = {
|
||||
{ HRDATA (BUF, tto_unit.buf, 8) },
|
||||
@@ -202,11 +121,18 @@ REG tto_reg[] = {
|
||||
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
|
||||
{ NULL } };
|
||||
|
||||
MTAB tto_mod[] = {
|
||||
{ UNIT_8B, UNIT_8B, "8b", "8B", NULL },
|
||||
{ UNIT_8B, 0 , "7b", "7B", NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL, NULL, &show_vec },
|
||||
{ 0 } };
|
||||
|
||||
DEVICE tto_dev = {
|
||||
"TTO", &tto_unit, tto_reg, NULL,
|
||||
"TTO", &tto_unit, tto_reg, tto_mod,
|
||||
1, 10, 31, 1, 16, 8,
|
||||
NULL, NULL, &tto_reset,
|
||||
NULL, NULL, NULL };
|
||||
NULL, NULL, NULL,
|
||||
&tto_dib, 0 };
|
||||
|
||||
/* CLK data structures
|
||||
|
||||
@@ -215,6 +141,8 @@ DEVICE tto_dev = {
|
||||
clk_reg CLK register list
|
||||
*/
|
||||
|
||||
DIB clk_dib = { 0, 0, NULL, NULL, 1, IVCL (CLK), SCB_INTTIM, { NULL } };
|
||||
|
||||
UNIT clk_unit = { UDATA (&clk_svc, 0, 0), CLK_DELAY };
|
||||
|
||||
REG clk_reg[] = {
|
||||
@@ -227,78 +155,16 @@ REG clk_reg[] = {
|
||||
{ DRDATA (TPS, clk_tps, 8), REG_NZ + PV_LEFT },
|
||||
{ NULL } };
|
||||
|
||||
MTAB clk_mod[] = {
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL, NULL, &show_vec },
|
||||
{ 0 } };
|
||||
|
||||
DEVICE clk_dev = {
|
||||
"CLK", &clk_unit, clk_reg, NULL,
|
||||
"CLK", &clk_unit, clk_reg, clk_mod,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
NULL, NULL, &clk_reset,
|
||||
NULL, NULL, NULL };
|
||||
|
||||
/* Paper tape I/O dispatch routine, I/O addresses 17777550-17777577
|
||||
|
||||
17777550 ptr CSR
|
||||
17777552 ptr buffer
|
||||
17777554 ptp CSR
|
||||
17777556 ptp buffer
|
||||
|
||||
Note: Word access routines filter out odd addresses. Thus,
|
||||
an odd address implies an (odd) byte access.
|
||||
*/
|
||||
|
||||
t_stat pt_rd (int32 *data, int32 PA, int32 access)
|
||||
{
|
||||
switch ((PA >> 1) & 03) { /* decode PA<2:1> */
|
||||
case 00: /* ptr csr */
|
||||
*data = ptr_csr & PTRCSR_IMP;
|
||||
break;
|
||||
case 01: /* ptr buf */
|
||||
ptr_csr = ptr_csr & ~CSR_DONE;
|
||||
CLR_INT (PTR);
|
||||
*data = ptr_unit.buf & 0377;
|
||||
break;
|
||||
case 02: /* ptp csr */
|
||||
*data = ptp_csr & PTPCSR_IMP;
|
||||
break;
|
||||
case 03: /* ptp buf */
|
||||
*data = ptp_unit.buf;
|
||||
break; }
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat pt_wr (int32 data, int32 PA, int32 access)
|
||||
{
|
||||
switch ((PA >> 1) & 03) { /* decode PA<2:1> */
|
||||
case 00: /* 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);
|
||||
break;
|
||||
case 01: /* ptr buf */
|
||||
break;
|
||||
case 02: /* 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);
|
||||
break;
|
||||
case 03: /* 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 */
|
||||
break; } /* end switch PA */
|
||||
return SCPE_OK;
|
||||
}
|
||||
NULL, NULL, NULL,
|
||||
&clk_dib, 0 };
|
||||
|
||||
/* Clock and terminal MxPR routines
|
||||
|
||||
@@ -378,110 +244,6 @@ sim_activate (&tto_unit, tto_unit.wait);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Paper tape reader routines
|
||||
|
||||
ptr_svc process event (character ready)
|
||||
ptr_reset process reset
|
||||
ptr_attach process attach
|
||||
ptr_detach process detach
|
||||
*/
|
||||
|
||||
t_stat ptr_svc (UNIT *uptr)
|
||||
{
|
||||
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);
|
||||
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; }
|
||||
ptr_csr = (ptr_csr | CSR_DONE) & ~CSR_ERR;
|
||||
ptr_unit.buf = temp & 0377;
|
||||
ptr_unit.pos = ptr_unit.pos + 1;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat ptr_reset (DEVICE *dptr)
|
||||
{
|
||||
ptr_unit.buf = 0;
|
||||
ptr_csr = 0;
|
||||
if ((ptr_unit.flags & UNIT_ATT) == 0) ptr_csr = ptr_csr | CSR_ERR;
|
||||
CLR_INT (PTR);
|
||||
sim_cancel (&ptr_unit);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat ptr_attach (UNIT *uptr, char *cptr)
|
||||
{
|
||||
t_stat reason;
|
||||
|
||||
reason = attach_unit (uptr, cptr);
|
||||
if ((ptr_unit.flags & UNIT_ATT) == 0) ptr_csr = ptr_csr | CSR_ERR;
|
||||
else ptr_csr = ptr_csr & ~CSR_ERR;
|
||||
return reason;
|
||||
}
|
||||
|
||||
t_stat ptr_detach (UNIT *uptr)
|
||||
{
|
||||
ptr_csr = ptr_csr | CSR_ERR;
|
||||
return detach_unit (uptr);
|
||||
}
|
||||
|
||||
/* Paper tape punch routines
|
||||
|
||||
ptp_svc process event (character punched)
|
||||
ptp_reset process reset
|
||||
ptp_attach process attach
|
||||
ptp_detach process detach
|
||||
*/
|
||||
|
||||
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);
|
||||
if (putc (ptp_unit.buf, ptp_unit.fileref) == EOF) {
|
||||
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;
|
||||
}
|
||||
|
||||
t_stat ptp_reset (DEVICE *dptr)
|
||||
{
|
||||
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 */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat ptp_attach (UNIT *uptr, char *cptr)
|
||||
{
|
||||
t_stat reason;
|
||||
|
||||
reason = attach_unit (uptr, cptr);
|
||||
if ((ptp_unit.flags & UNIT_ATT) == 0) ptp_csr = ptp_csr | CSR_ERR;
|
||||
else ptp_csr = ptp_csr & ~CSR_ERR;
|
||||
return reason;
|
||||
}
|
||||
|
||||
t_stat ptp_detach (UNIT *uptr)
|
||||
{
|
||||
ptp_csr = ptp_csr | CSR_ERR;
|
||||
return detach_unit (uptr);
|
||||
}
|
||||
|
||||
/* Terminal input routines
|
||||
|
||||
tti_svc process event (character ready)
|
||||
@@ -490,11 +252,11 @@ return detach_unit (uptr);
|
||||
|
||||
t_stat tti_svc (UNIT *uptr)
|
||||
{
|
||||
int32 temp;
|
||||
int32 c;
|
||||
|
||||
sim_activate (&tti_unit, tti_unit.wait); /* continue poll */
|
||||
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG) return temp; /* no char or error? */
|
||||
tti_unit.buf = temp & 0377;
|
||||
if ((c = sim_poll_kbd ()) < SCPE_KFLAG) return c; /* no char or error? */
|
||||
tti_unit.buf = c & ((tti_unit.flags & UNIT_8B)? 0377: 0177);
|
||||
tti_unit.pos = tti_unit.pos + 1;
|
||||
tti_csr = tti_csr | CSR_DONE;
|
||||
if (tti_csr & CSR_IE) SET_INT (TTI);
|
||||
@@ -518,11 +280,13 @@ return SCPE_OK;
|
||||
|
||||
t_stat tto_svc (UNIT *uptr)
|
||||
{
|
||||
int32 temp;
|
||||
int32 c;
|
||||
t_stat r;
|
||||
|
||||
tto_csr = tto_csr | CSR_DONE;
|
||||
if (tto_csr & CSR_IE) SET_INT (TTO);
|
||||
if ((temp = sim_putchar (tto_unit.buf & 0177)) != SCPE_OK) return temp;
|
||||
c = tto_unit.buf & ((tto_unit.flags & UNIT_8B)? 0377: 0177);
|
||||
if ((r = sim_putchar (c)) != SCPE_OK) return r;
|
||||
tto_unit.pos = tto_unit.pos + 1;
|
||||
return SCPE_OK;
|
||||
}
|
||||
@@ -579,10 +343,10 @@ curr = time (NULL); /* get curr time */
|
||||
if (curr == (time_t) -1) return SCPE_NOFNC; /* error? */
|
||||
ctm = localtime (&curr); /* decompose */
|
||||
if (ctm == NULL) return SCPE_NOFNC; /* error? */
|
||||
base = (((((ctm -> tm_yday * 24) + /* sec since 1-Jan */
|
||||
ctm -> tm_hour) * 60) +
|
||||
ctm -> tm_min) * 60) +
|
||||
ctm -> tm_sec;
|
||||
base = (((((ctm->tm_yday * 24) + /* sec since 1-Jan */
|
||||
ctm->tm_hour) * 60) +
|
||||
ctm->tm_min) * 60) +
|
||||
ctm->tm_sec;
|
||||
todr_reg = (base * 100) + 0x10000000; /* cvt to VAX form */
|
||||
todr_blow = 0;
|
||||
return SCPE_OK;
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
12-Oct-02 RMS Added multiple RQ controller support
|
||||
10-Oct-02 RMS Added DELQA support
|
||||
21-Sep-02 RMS Extended symbolic ex/mod to all byte devices
|
||||
06-Sep-02 RMS Added TMSCP support
|
||||
14-Jul-02 RMS Added infinite loop message
|
||||
*/
|
||||
|
||||
@@ -36,17 +40,16 @@ extern DEVICE ptr_dev, ptp_dev;
|
||||
extern DEVICE tti_dev, tto_dev;
|
||||
extern DEVICE csi_dev, cso_dev;
|
||||
extern DEVICE lpt_dev, clk_dev;
|
||||
extern DEVICE rq_dev, rl_dev;
|
||||
extern DEVICE ts_dev;
|
||||
extern DEVICE dz_dev;
|
||||
extern DEVICE rq_dev, rqb_dev, rqc_dev, rqd_dev;
|
||||
extern DEVICE rl_dev;
|
||||
extern DEVICE ts_dev, tq_dev;
|
||||
extern DEVICE dz_dev, xq_dev;
|
||||
extern UNIT cpu_unit;
|
||||
extern REG cpu_reg[];
|
||||
extern uint32 *M;
|
||||
extern int32 saved_PC;
|
||||
extern int32 sim_switches;
|
||||
|
||||
extern t_stat fprint_val (FILE *stream, t_value val, int radix,
|
||||
int width, int format);
|
||||
extern void WriteB (int32 pa, int32 val);
|
||||
extern void rom_wr (int32 pa, int32 val, int32 lnt);
|
||||
t_stat fprint_sym_m (FILE *of, t_addr addr, t_value *val);
|
||||
@@ -91,10 +94,15 @@ DEVICE *sim_devices[] = {
|
||||
&ptr_dev,
|
||||
&ptp_dev,
|
||||
&lpt_dev,
|
||||
&rq_dev,
|
||||
&rl_dev,
|
||||
&ts_dev,
|
||||
&dz_dev,
|
||||
&rl_dev,
|
||||
&rq_dev,
|
||||
&rqb_dev,
|
||||
&rqc_dev,
|
||||
&rqd_dev,
|
||||
&ts_dev,
|
||||
&tq_dev,
|
||||
&xq_dev,
|
||||
NULL };
|
||||
|
||||
const char *sim_stop_messages[] = {
|
||||
@@ -109,7 +117,8 @@ const char *sim_stop_messages[] = {
|
||||
"Unknown error",
|
||||
"Fatal RQDX3 error",
|
||||
"Infinite loop",
|
||||
"Unknown abort code" };
|
||||
"Unknown abort code",
|
||||
"Sanity timer expired" };
|
||||
|
||||
/* Binary loader
|
||||
|
||||
@@ -178,18 +187,18 @@ int32 i, da;
|
||||
int32 *buf;
|
||||
|
||||
if ((sec < 2) || (wds < 16)) return SCPE_ARG;
|
||||
if ((uptr -> flags & UNIT_ATT) == 0) return SCPE_UNATT;
|
||||
if ((uptr->flags & UNIT_ATT) == 0) return SCPE_UNATT;
|
||||
if (!get_yn ("Overwrite last track? [N]", FALSE)) return SCPE_OK;
|
||||
da = (uptr -> capac - (sec * wds)) * sizeof (int16);
|
||||
if (fseek (uptr -> fileref, da, SEEK_SET)) return SCPE_IOERR;
|
||||
da = (uptr->capac - (sec * wds)) * sizeof (int16);
|
||||
if (fseek (uptr->fileref, da, SEEK_SET)) return SCPE_IOERR;
|
||||
if ((buf = malloc (wds * sizeof (int32))) == NULL) return SCPE_MEM;
|
||||
buf[0] = 0x12345678;
|
||||
buf[1] = 0;
|
||||
for (i = 2; i < wds; i++) buf[i] = 0xFFFFFFFF;
|
||||
for (i = 0; (i < sec) && (i < 10); i++)
|
||||
fxwrite (buf, sizeof (int32), wds, uptr -> fileref);
|
||||
fxwrite (buf, sizeof (int32), wds, uptr->fileref);
|
||||
free (buf);
|
||||
if (ferror (uptr -> fileref)) return SCPE_IOERR;
|
||||
if (ferror (uptr->fileref)) return SCPE_IOERR;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -817,25 +826,30 @@ t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,
|
||||
{
|
||||
int32 c, k, num, vp, lnt, rdx;
|
||||
t_stat r;
|
||||
DEVICE *dptr;
|
||||
|
||||
if (uptr && uptr != &cpu_unit) return SCPE_ARG; /* only for CPU */
|
||||
vp = 0; /* init ptr */
|
||||
if (uptr == NULL) uptr = &cpu_unit; /* anon = CPU */
|
||||
dptr = find_dev_from_unit (uptr); /* find dev */
|
||||
if (dptr == NULL) return SCPE_IERR;
|
||||
if (dptr->dwidth != 8) return SCPE_ARG; /* byte dev only */
|
||||
if (sw & SWMASK ('B')) lnt = 1; /* get length */
|
||||
else if (sw & SWMASK ('W')) lnt = 2;
|
||||
else lnt = 4;
|
||||
else if (sw & SWMASK ('L')) lnt = 4;
|
||||
else lnt = (uptr == &cpu_unit)? 4: 1;
|
||||
if (sw & SWMASK ('D')) rdx = 10; /* get radix */
|
||||
else if (sw & SWMASK ('O')) rdx = 8;
|
||||
else if (sw & SWMASK ('H')) rdx = 16;
|
||||
else rdx = cpu_dev.dradix;
|
||||
else rdx = dptr->dradix;
|
||||
vp = 0; /* init ptr */
|
||||
if ((sw & SWMASK ('A')) || (sw & SWMASK ('C'))) { /* char format? */
|
||||
if (sw & SWMASK ('C')) lnt = sim_emax; /* -c -> string */
|
||||
if ((val[0] & 0177) == 0) return SCPE_ARG;
|
||||
if ((val[0] & 0x7F) == 0) return SCPE_ARG;
|
||||
while (vp < lnt) { /* print string */
|
||||
if ((c = (int32) val[vp++] & 0177) == 0) break;
|
||||
fprintf (of, (c < 040)? "<%03o>": "%c", c); }
|
||||
if ((c = (int32) val[vp++] & 0x7F) == 0) break;
|
||||
fprintf (of, (c < 0x20)? "<%02X>": "%c", c); }
|
||||
return -(vp - 1); } /* return # chars */
|
||||
|
||||
if (sw & SWMASK ('M')) { /* inst format? */
|
||||
if (sw & SWMASK ('M') && (uptr == &cpu_unit)) { /* inst format? */
|
||||
r = fprint_sym_m (of, addr, val); /* decode inst */
|
||||
if (r <= 0) return r; }
|
||||
|
||||
@@ -985,27 +999,32 @@ t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw)
|
||||
{
|
||||
int32 k, rdx, lnt, num, vp;
|
||||
t_stat r;
|
||||
DEVICE *dptr;
|
||||
static const uint32 maxv[5] = { 0, 0xFF, 0xFFFF, 0, 0xFFFFFFFF };
|
||||
|
||||
if (uptr != &cpu_unit) return SCPE_ARG; /* only for CPU */
|
||||
vp = 0; /* init ptr */
|
||||
if (sw & SWMASK ('B')) lnt = 1; /* set length */
|
||||
if (uptr == NULL) uptr = &cpu_unit; /* anon = CPU */
|
||||
dptr = find_dev_from_unit (uptr); /* find dev */
|
||||
if (dptr == NULL) return SCPE_IERR;
|
||||
if (dptr->dwidth != 8) return SCPE_ARG; /* byte dev only */
|
||||
if (sw & SWMASK ('B')) lnt = 1; /* get length */
|
||||
else if (sw & SWMASK ('W')) lnt = 2;
|
||||
else lnt = 4;
|
||||
if (sw & SWMASK ('D')) rdx = 10; /* set radix */
|
||||
else if (sw & SWMASK ('L')) lnt = 4;
|
||||
else lnt = (uptr == &cpu_unit)? 4: 1;
|
||||
if (sw & SWMASK ('D')) rdx = 10; /* get radix */
|
||||
else if (sw & SWMASK ('O')) rdx = 8;
|
||||
else if (sw & SWMASK ('H')) rdx = 16;
|
||||
else rdx = cpu_dev.dradix;
|
||||
else rdx = dptr->dradix;
|
||||
vp = 0;
|
||||
if ((sw & SWMASK ('A')) || (sw & SWMASK ('C'))) { /* char format? */
|
||||
if (sw & SWMASK ('C')) lnt = sim_emax; /* -c -> string */
|
||||
if (*cptr == 0) return SCPE_ARG;
|
||||
while (vp < lnt) { /* get chars */
|
||||
if (*cptr == 0) break;
|
||||
while ((vp < lnt) && *cptr) { /* get chars */
|
||||
val[vp++] = *cptr++; }
|
||||
return -(vp - 1); } /* return # chars */
|
||||
|
||||
r = parse_sym_m (cptr, addr, val); /* try to parse inst */
|
||||
if (r <= 0) return r;
|
||||
if (uptr == &cpu_unit) { /* cpu only */
|
||||
r = parse_sym_m (cptr, addr, val); /* try to parse inst */
|
||||
if (r <= 0) return r; }
|
||||
|
||||
num = (int32) get_uint (cptr, rdx, maxv[lnt], &r); /* get number */
|
||||
if (r != SCPE_OK) return r;
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
cso console storage output
|
||||
sysd system devices (SSC miscellany)
|
||||
|
||||
19-Aug-02 RMS Removed unused variables (found by David Hittner)
|
||||
Allowed NVR to be attached to file
|
||||
30-May-02 RMS Widened POS to 32b
|
||||
28-Feb-02 RMS Fixed bug, missing end of table (found by Lars Brinkhoff)
|
||||
*/
|
||||
@@ -183,6 +185,8 @@ t_stat rom_reset (DEVICE *dptr);
|
||||
t_stat nvr_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
|
||||
t_stat nvr_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);
|
||||
t_stat nvr_reset (DEVICE *dptr);
|
||||
t_stat nvr_attach (UNIT *uptr, char *cptr);
|
||||
t_stat nvr_detach (UNIT *uptr);
|
||||
t_stat csi_reset (DEVICE *dptr);
|
||||
t_stat cso_reset (DEVICE *dptr);
|
||||
t_stat cso_svc (UNIT *uptr);
|
||||
@@ -210,6 +214,8 @@ int32 tmr_tir_rd (int32 tmr, t_bool interp);
|
||||
void tmr_csr_wr (int32 tmr, int32 val);
|
||||
void tmr_sched (int32 tmr);
|
||||
void tmr_incr (int32 tmr, uint32 inc);
|
||||
int32 tmr0_inta (void);
|
||||
int32 tmr1_inta (void);
|
||||
int32 parity (int32 val, int32 odd);
|
||||
|
||||
extern int32 cqmap_rd (int32 pa);
|
||||
@@ -248,7 +254,8 @@ DEVICE rom_dev = {
|
||||
"ROM", &rom_unit, rom_reg, NULL,
|
||||
1, 16, ROMAWIDTH, 4, 16, 32,
|
||||
&rom_ex, &rom_dep, &rom_reset,
|
||||
NULL, NULL, NULL };
|
||||
NULL, NULL, NULL,
|
||||
NULL, 0 };
|
||||
|
||||
/* NVR data structures
|
||||
|
||||
@@ -267,7 +274,8 @@ DEVICE nvr_dev = {
|
||||
"NVR", &nvr_unit, nvr_reg, NULL,
|
||||
1, 16, NVRAWIDTH, 4, 16, 32,
|
||||
&nvr_ex, &nvr_dep, &nvr_reset,
|
||||
NULL, NULL, NULL };
|
||||
NULL, &nvr_attach, &nvr_detach,
|
||||
NULL, 0 };
|
||||
|
||||
/* CSI data structures
|
||||
|
||||
@@ -276,6 +284,8 @@ DEVICE nvr_dev = {
|
||||
csi_reg CSI register list
|
||||
*/
|
||||
|
||||
DIB csi_dib = { 0, 0, NULL, NULL, 1, IVCL (CSI), SCB_CSI, { NULL } };
|
||||
|
||||
UNIT csi_unit = { UDATA (NULL, 0, 0), KBD_POLL_WAIT };
|
||||
|
||||
REG csi_reg[] = {
|
||||
@@ -288,11 +298,16 @@ REG csi_reg[] = {
|
||||
{ DRDATA (TIME, csi_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||
{ NULL } };
|
||||
|
||||
MTAB csi_mod[] = {
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL, NULL, &show_vec },
|
||||
{ 0 } };
|
||||
|
||||
DEVICE csi_dev = {
|
||||
"CSI", &csi_unit, csi_reg, NULL,
|
||||
"CSI", &csi_unit, csi_reg, csi_mod,
|
||||
1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &csi_reset,
|
||||
NULL, NULL, NULL };
|
||||
NULL, NULL, NULL,
|
||||
&csi_dib, 0 };
|
||||
|
||||
/* CSO data structures
|
||||
|
||||
@@ -301,6 +316,8 @@ DEVICE csi_dev = {
|
||||
cso_reg CSO register list
|
||||
*/
|
||||
|
||||
DIB cso_dib = { 0, 0, NULL, NULL, 1, IVCL (CSO), SCB_CSO, { NULL } };
|
||||
|
||||
UNIT cso_unit = { UDATA (&cso_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT };
|
||||
|
||||
REG cso_reg[] = {
|
||||
@@ -313,11 +330,16 @@ REG cso_reg[] = {
|
||||
{ DRDATA (TIME, cso_unit.wait, 24), PV_LEFT },
|
||||
{ NULL } };
|
||||
|
||||
MTAB cso_mod[] = {
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL, NULL, &show_vec },
|
||||
{ 0 } };
|
||||
|
||||
DEVICE cso_dev = {
|
||||
"CSO", &cso_unit, cso_reg, NULL,
|
||||
"CSO", &cso_unit, cso_reg, cso_mod,
|
||||
1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &cso_reset,
|
||||
NULL, NULL, NULL };
|
||||
NULL, NULL, NULL,
|
||||
&cso_dib, 0 };
|
||||
|
||||
/* SYSD data structures
|
||||
|
||||
@@ -326,6 +348,9 @@ DEVICE cso_dev = {
|
||||
sysd_reg SYSD register list
|
||||
*/
|
||||
|
||||
DIB sysd_dib[] = { 0, 0, NULL, NULL,
|
||||
2, IVCL (TMR0), 0, { &tmr0_inta, &tmr1_inta } };
|
||||
|
||||
UNIT sysd_unit[] = {
|
||||
{ UDATA (&tmr_svc, 0, 0) },
|
||||
{ UDATA (&tmr_svc, 0, 0) } };
|
||||
@@ -361,7 +386,8 @@ DEVICE sysd_dev = {
|
||||
"SYSD", sysd_unit, sysd_reg, NULL,
|
||||
2, 16, 16, 1, 16, 8,
|
||||
NULL, NULL, &sysd_reset,
|
||||
NULL, NULL, NULL };
|
||||
NULL, NULL, NULL,
|
||||
&sysd_dib, 0 };
|
||||
|
||||
/* ROM: read only memory - stored in a buffered file
|
||||
Register space access routines see ROM twice
|
||||
@@ -462,10 +488,38 @@ t_stat nvr_reset (DEVICE *dptr)
|
||||
{
|
||||
if (nvr == NULL) {
|
||||
nvr = calloc (NVRSIZE >> 2, sizeof (int32));
|
||||
nvr_unit.filebuf = nvr;
|
||||
ssc_cnf = ssc_cnf | SSCCNF_BLO; }
|
||||
if (nvr == NULL) return SCPE_MEM;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* NVR attach */
|
||||
|
||||
t_stat nvr_attach (UNIT *uptr, char *cptr)
|
||||
{
|
||||
t_stat r;
|
||||
|
||||
uptr->flags = uptr->flags | (UNIT_ATTABLE | UNIT_BUFABLE);
|
||||
r = attach_unit (uptr, cptr);
|
||||
if (r != SCPE_OK)
|
||||
uptr->flags = uptr->flags & ~(UNIT_ATTABLE | UNIT_BUFABLE);
|
||||
else { uptr->hwmark = uptr->capac;
|
||||
ssc_cnf = ssc_cnf & ~SSCCNF_BLO; }
|
||||
return r;
|
||||
}
|
||||
|
||||
/* NVR detach */
|
||||
|
||||
t_stat nvr_detach (UNIT *uptr)
|
||||
{
|
||||
t_stat r;
|
||||
|
||||
r = detach_unit (uptr);
|
||||
if ((uptr->flags & UNIT_ATT) == 0)
|
||||
uptr->flags = uptr->flags & ~(UNIT_ATTABLE | UNIT_BUFABLE);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* CSI: console storage input */
|
||||
|
||||
@@ -485,7 +539,7 @@ void csrs_wr (int32 data)
|
||||
{
|
||||
if ((data & CSR_IE) == 0) CLR_INT (CSI);
|
||||
else if ((csi_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
|
||||
SET_INT (CSI);
|
||||
SET_INT (CSI);
|
||||
csi_csr = (csi_csr & ~CSICSR_RW) | (data & CSICSR_RW);
|
||||
return;
|
||||
}
|
||||
@@ -682,9 +736,9 @@ int32 ReadReg (int32 pa, int32 lnt)
|
||||
{
|
||||
struct reglink *p;
|
||||
|
||||
for (p = ®table[0]; p -> low != 0; p++) {
|
||||
if ((pa >= p -> low) && (pa < p -> high) && p -> read)
|
||||
return p -> read (pa); }
|
||||
for (p = ®table[0]; p->low != 0; p++) {
|
||||
if ((pa >= p->low) && (pa < p->high) && p->read)
|
||||
return p->read (pa); }
|
||||
ssc_bto = ssc_bto | SSCBTO_BTO | SSCBTO_RWT;
|
||||
MACH_CHECK (MCHK_READ);
|
||||
return 0;
|
||||
@@ -704,9 +758,9 @@ void WriteReg (int32 pa, int32 val, int32 lnt)
|
||||
{
|
||||
struct reglink *p;
|
||||
|
||||
for (p = ®table[0]; p -> low != 0; p++) {
|
||||
if ((pa >= p -> low) && (pa < p -> high) && p -> write) {
|
||||
p -> write (pa, val, lnt);
|
||||
for (p = ®table[0]; p->low != 0; p++) {
|
||||
if ((pa >= p->low) && (pa < p->high) && p->write) {
|
||||
p->write (pa, val, lnt);
|
||||
return; } }
|
||||
ssc_bto = ssc_bto | SSCBTO_BTO | SSCBTO_RWT;
|
||||
MACH_CHECK (MCHK_WRITE);
|
||||
@@ -795,8 +849,6 @@ return;
|
||||
int32 cdg_rd (int32 pa)
|
||||
{
|
||||
int32 t, row = CDG_GETROW (pa);
|
||||
int32 tag = CDG_GETTAG (pa);
|
||||
int32 tidx = row >> 1;
|
||||
|
||||
t = cdg_dat[row];
|
||||
ka_cacr = ka_cacr & ~CACR_DRO; /* clear diag */
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
11-Nov-02 RMS Added log bits for XQ
|
||||
10-Oct-02 RMS Added DEQNA/DELQA, multiple RQ, autoconfigure support
|
||||
29-Sep-02 RMS Revamped bus support macros
|
||||
06-Sep-02 RMS Added TMSCP support
|
||||
14-Jul-02 RMS Added additional console halt codes
|
||||
28-Apr-02 RMS Fixed DZV vector base and number of lines
|
||||
|
||||
@@ -185,47 +189,76 @@
|
||||
#define CSR_BUSY (1u << CSR_V_BUSY)
|
||||
#define CSR_ERR (1u << CSR_V_ERR)
|
||||
|
||||
/* IO parameters */
|
||||
|
||||
#define DZ_MUXES 4 /* max # of muxes */
|
||||
#define DZ_LINES 4 /* (DZV) lines per mux */
|
||||
#define MT_MAXFR (1 << 16) /* magtape max rec */
|
||||
|
||||
/* Timers */
|
||||
|
||||
#define TMR_CLK 0 /* 100Hz clock */
|
||||
|
||||
/* I/O system definitions */
|
||||
|
||||
#define DZ_MUXES 4 /* max # of muxes */
|
||||
#define DZ_LINES 4 /* (DZV) lines per mux */
|
||||
#define MT_MAXFR (1 << 16) /* magtape max rec */
|
||||
#define AUTO_LNT 34 /* autoconfig ranks */
|
||||
#define DIB_MAX 100 /* max DIBs */
|
||||
|
||||
#define DEV_V_UBUS (DEV_V_UF + 0) /* Unibus */
|
||||
#define DEV_V_QBUS (DEV_V_UF + 1) /* Qbus */
|
||||
#define DEV_V_FLTA (DEV_V_UF + 2) /* flt addr */
|
||||
#define DEV_UBUS (1u << DEV_V_UBUS)
|
||||
#define DEV_QBUS (1u << DEV_V_QBUS)
|
||||
#define DEV_FLTA (1u << DEV_V_FLTA)
|
||||
|
||||
#define UNIBUS FALSE /* 22b only */
|
||||
|
||||
/* Device information block */
|
||||
|
||||
#define VEC_DEVMAX 4 /* max device vec */
|
||||
|
||||
struct pdp_dib {
|
||||
uint32 enb; /* enabled */
|
||||
uint32 ba; /* base addr */
|
||||
uint32 lnt; /* length */
|
||||
t_stat (*rd)(int32 *dat, int32 ad, int32 md);
|
||||
t_stat (*wr)(int32 dat, int32 ad, int32 md); };
|
||||
t_stat (*wr)(int32 dat, int32 ad, int32 md);
|
||||
int32 vnum; /* vectors: number */
|
||||
int32 vloc; /* locator */
|
||||
int32 vec; /* value */
|
||||
int32 (*ack[VEC_DEVMAX])(void); /* ack routines */
|
||||
};
|
||||
|
||||
typedef struct pdp_dib DIB;
|
||||
|
||||
/* I/O page layout */
|
||||
/* I/O page layout - RQB,RQC,RQD float based on number of DZ's */
|
||||
|
||||
#define IOBA_DZ (IOPAGEBASE + 000100) /* DZ11 */
|
||||
#define IOLN_DZ 010
|
||||
#define IOBA_RQB (IOPAGEBASE + 000334 + (020 * (DZ_MUXES / 2)))
|
||||
#define IOLN_RQB 004
|
||||
#define IOBA_RQC (IOPAGEBASE + IOBA_RQB + IOLN_RQB)
|
||||
#define IOLN_RQC 004
|
||||
#define IOBA_RQD (IOPAGEBASE + IOBA_RQC + IOLN_RQC)
|
||||
#define IOLN_RQD 004
|
||||
#define IOBA_RQ (IOPAGEBASE + 012150) /* RQDX3 */
|
||||
#define IOLN_RQ 004
|
||||
#define IOBA_TS (IOPAGEBASE + 012520) /* TS11 */
|
||||
#define IOLN_TS 004
|
||||
#define IOBA_RL (IOPAGEBASE + 014400) /* RL11 */
|
||||
#define IOLN_RL 012
|
||||
#define IOBA_XQ (IOPAGEBASE + 014440) /* DEQNA/DELQA */
|
||||
#define IOLN_XQ 020
|
||||
#define IOBA_XQB (IOPAGEBASE + 014460) /* 2nd DEQNA/DELQA */
|
||||
#define IOLN_XQB 020
|
||||
#define IOBA_TQ (IOPAGEBASE + 014500) /* TMSCP */
|
||||
#define IOLN_TQ 004
|
||||
#define IOBA_RP (IOPAGEBASE + 016700) /* RP/RM */
|
||||
#define IOLN_RP 054
|
||||
#define IOBA_DBL (IOPAGEBASE + 017500) /* doorbell */
|
||||
#define IOLN_DBL 002
|
||||
#define IOBA_LPT (IOPAGEBASE + 017514) /* LP11 */
|
||||
#define IOLN_LPT 004
|
||||
#define IOBA_PT (IOPAGEBASE + 017550) /* PC11 */
|
||||
#define IOLN_PT 010
|
||||
#define IOBA_PTR (IOPAGEBASE + 017550) /* PC11 reader */
|
||||
#define IOLN_PTR 004
|
||||
#define IOBA_PTP (IOPAGEBASE + 017554) /* PC11 punch */
|
||||
#define IOLN_PTP 004
|
||||
|
||||
/* The KA65x maintains 4 separate hardware IPL levels, IPL 17 to IPL 14
|
||||
Within each IPL, priority is right to left
|
||||
@@ -245,6 +278,8 @@ typedef struct pdp_dib DIB;
|
||||
#define INT_V_DZTX 3
|
||||
#define INT_V_RP 4 /* RP,RM drives */
|
||||
#define INT_V_TS 5 /* TS11/TSV05 */
|
||||
#define INT_V_TQ 6 /* TMSCP */
|
||||
#define INT_V_XQ 7 /* DEQNA/DELQA */
|
||||
|
||||
/* IPL 14 */
|
||||
|
||||
@@ -265,6 +300,8 @@ typedef struct pdp_dib DIB;
|
||||
#define INT_DZTX (1u << INT_V_DZTX)
|
||||
#define INT_RP (1u << INT_V_RP)
|
||||
#define INT_TS (1u << INT_V_TS)
|
||||
#define INT_TQ (1u << INT_V_TQ)
|
||||
#define INT_XQ (1u << INT_V_XQ)
|
||||
#define INT_TTI (1u << INT_V_TTI)
|
||||
#define INT_TTO (1u << INT_V_TTO)
|
||||
#define INT_PTR (1u << INT_V_PTR)
|
||||
@@ -282,6 +319,8 @@ typedef struct pdp_dib DIB;
|
||||
#define IPL_DZTX (0x15 - IPL_HMIN)
|
||||
#define IPL_RP (0x15 - IPL_HMIN)
|
||||
#define IPL_TS (0x15 - IPL_HMIN)
|
||||
#define IPL_TQ (0x15 - IPL_HMIN)
|
||||
#define IPL_XQ (0x15 - IPL_HMIN)
|
||||
#define IPL_TTI (0x14 - IPL_HMIN)
|
||||
#define IPL_TTO (0x14 - IPL_HMIN)
|
||||
#define IPL_PTR (0x14 - IPL_HMIN)
|
||||
@@ -297,17 +336,31 @@ typedef struct pdp_dib DIB;
|
||||
#define IPL_HLVL (IPL_HMAX - IPL_HMIN + 1) /* # hardware levels */
|
||||
#define IPL_SMAX 0xF /* highest swre level */
|
||||
|
||||
/* Device vectors */
|
||||
|
||||
#define VEC_Q 0x200 /* Qbus vector offset */
|
||||
#define VEC_PTR (VEC_Q + 0070) /* Qbus vectors */
|
||||
#define VEC_PTR (VEC_Q + 0070)
|
||||
#define VEC_PTP (VEC_Q + 0074)
|
||||
#define VEC_XQ (VEC_Q + 0120)
|
||||
#define VEC_RQ (VEC_Q + 0154)
|
||||
#define VEC_RL (VEC_Q + 0160)
|
||||
#define VEC_LPT (VEC_Q + 0200)
|
||||
#define VEC_TS (VEC_Q + 0224)
|
||||
#define VEC_RP (VEC_Q + 0254)
|
||||
#define VEC_TQ (VEC_Q + 0260)
|
||||
#define VEC_DZRX (VEC_Q + 0300)
|
||||
#define VEC_DZTX (VEC_Q + 0304)
|
||||
|
||||
/* Autoconfigure ranks */
|
||||
|
||||
#define RANK_DZ 8
|
||||
#define RANK_RL 14
|
||||
#define RANK_RQ 26
|
||||
#define RANK_TQ 30
|
||||
|
||||
/* Interrupt macros */
|
||||
|
||||
#define IVCL(dv) ((IPL_##dv * 32) + INT_V_##dv)
|
||||
#define IREQ(dv) int_req[IPL_##dv]
|
||||
#define SET_INT(dv) int_req[IPL_##dv] = int_req[IPL_##dv] | (INT_##dv)
|
||||
#define CLR_INT(dv) int_req[IPL_##dv] = int_req[IPL_##dv] & ~(INT_##dv)
|
||||
@@ -315,13 +368,18 @@ typedef struct pdp_dib DIB;
|
||||
|
||||
/* Logging */
|
||||
|
||||
#define LOG_CPU_I 0x001 /* intexc */
|
||||
#define LOG_CPU_R 0x002 /* REI */
|
||||
#define LOG_CPU_P 0x004 /* context */
|
||||
#define LOG_CPU_A 0x008
|
||||
#define LOG_RP 0x010
|
||||
#define LOG_TS 0x020
|
||||
#define LOG_RQ 0x040
|
||||
#define LOG_CPU_I 0x0001 /* intexc */
|
||||
#define LOG_CPU_R 0x0002 /* REI */
|
||||
#define LOG_CPU_P 0x0004 /* context */
|
||||
#define LOG_CPU_A 0x0008
|
||||
#define LOG_RP 0x0010
|
||||
#define LOG_TS 0x0020
|
||||
#define LOG_RQ 0x0040
|
||||
#define LOG_TQ 0x0080
|
||||
#define LOG_XQ0 0x0100
|
||||
#define LOG_XQ1 0x0200
|
||||
#define LOG_XQ2 0x0400
|
||||
#define LOG_XQ3 0x0800
|
||||
|
||||
#define DBG_LOG(x) (sim_log && (cpu_log & (x)))
|
||||
|
||||
@@ -335,17 +393,15 @@ int32 map_writeB (t_addr ba, int32 bc, uint8 *buf);
|
||||
int32 map_writeW (t_addr ba, int32 bc, uint16 *buf);
|
||||
int32 map_writeL (t_addr ba, int32 bc, uint32 *buf);
|
||||
|
||||
/* Macros for PDP-11 compatibility */
|
||||
|
||||
#define QB 0 /* Q22 native */
|
||||
#define UB 1 /* Unibus */
|
||||
|
||||
#define Map_Addr(a,b) map_addr (a, b)
|
||||
#define Map_ReadB(a,b,c,d) map_readB (a, b, c)
|
||||
#define Map_ReadW(a,b,c,d) map_readW (a, b, c)
|
||||
#define Map_WriteB(a,b,c,d) map_writeB (a, b, c)
|
||||
#define Map_WriteW(a,b,c,d) map_writeW (a, b, c)
|
||||
|
||||
t_stat set_addr (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
t_stat show_addr (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||
t_stat set_enbdis (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
t_bool dev_conflict (uint32 nba, DIB *curr);
|
||||
t_stat set_addr_flt (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
t_stat set_vec (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
t_stat show_vec (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||
t_stat auto_config (uint32 rank, uint32 num);
|
||||
|
||||
Reference in New Issue
Block a user