Notes For V3.4-0
The memory layout for the Interdata simulators has been changed. Do not use Interdata SAVE files from prior revisions with V3.4. 1. New Features in 3.4 1.1 SCP and Libraries - Revised interpretation of fprint_sym, fparse_sym returns - Revised syntax for SET DEBUG - DO command nesting allowed to ten levels 1.2 Interdata - Revised memory model to be 16b instead of 8b 1.3 HP2100 - Added Fast FORTRAN Processor instructions - Added SET OFFLINE/ONLINE and SET UNLOAD/LOAD commands to tapes and disks 2. Bugs Fixed in 3.4-0 2.1 Interdata - Fixed bug in show history routine (from Mark Hittinger) - Fixed bug in initial memory allocation 2.2 PDP-10 - Fixed TU bug, ERASE and WREOF should not clear done (reported by Rich Alderson) - Fixed TU error reporting 2.3 PDP-11 - Fixed TU error reporting
This commit is contained in:
parent
098200a126
commit
ec60bbf329
62 changed files with 4332 additions and 7632 deletions
|
@ -1,47 +0,0 @@
|
||||||
Notes For V3.3-2
|
|
||||||
|
|
||||||
1. New Features in 3.3-2
|
|
||||||
|
|
||||||
1.1 SCP and Libraries
|
|
||||||
|
|
||||||
- Added ASSERT command (from Dave Bryan)
|
|
||||||
|
|
||||||
1.2 PDP-11, VAX
|
|
||||||
|
|
||||||
- Added RA60, RA71, RA81 disks
|
|
||||||
|
|
||||||
2. Bugs Fixed in 3.3-2
|
|
||||||
|
|
||||||
2.1 H316
|
|
||||||
|
|
||||||
- Fixed IORETURN macro
|
|
||||||
- PT: fixed bug in OCP '0001 (found by Philipp Hachtmann)
|
|
||||||
- MT: fixed error reporting from OCP (found by Philipp Hachtmann)
|
|
||||||
|
|
||||||
2.2 Interdata 32b
|
|
||||||
|
|
||||||
- Fixed branches to mask new PC (from Greg Johnson)
|
|
||||||
|
|
||||||
2.3 PDP-11
|
|
||||||
|
|
||||||
- Fixed bugs in RESET for 11/70 (reported by Tim Chapman)
|
|
||||||
- Fixed bug in SHOW MODEL (from Sergey Okhapkin)
|
|
||||||
- Made SYSID variable for 11/70 (from Tim Chapman)
|
|
||||||
- Fixed MBRK write case for 11/70 (from Tim Chapman)
|
|
||||||
- RY: fixed bug in boot code (reported by Graham Toal)
|
|
||||||
|
|
||||||
2.4 VAX
|
|
||||||
|
|
||||||
- Fixed initial state of cpu_extmem
|
|
||||||
|
|
||||||
2.5 HP2100 (from Dave Bryan)
|
|
||||||
|
|
||||||
- Fixed missing MPCK on JRS target
|
|
||||||
- Removed EXECUTE instruction (is NOP in actual microcode)
|
|
||||||
- Fixed missing negative overflow renorm in StoreFP
|
|
||||||
|
|
||||||
2.6 I1401
|
|
||||||
|
|
||||||
- Fixed bug in line printer write line (reported by Van Snyder)
|
|
||||||
|
|
||||||
|
|
38
0readme_34.txt
Normal file
38
0readme_34.txt
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
Notes For V3.4-0
|
||||||
|
|
||||||
|
The memory layout for the Interdata simulators has been changed.
|
||||||
|
Do not use Interdata SAVE files from prior revisions with V3.4.
|
||||||
|
|
||||||
|
1. New Features in 3.4
|
||||||
|
|
||||||
|
1.1 SCP and Libraries
|
||||||
|
|
||||||
|
- Revised interpretation of fprint_sym, fparse_sym returns
|
||||||
|
- Revised syntax for SET DEBUG
|
||||||
|
- DO command nesting allowed to ten levels
|
||||||
|
|
||||||
|
1.2 Interdata
|
||||||
|
|
||||||
|
- Revised memory model to be 16b instead of 8b
|
||||||
|
|
||||||
|
1.3 HP2100
|
||||||
|
|
||||||
|
- Added Fast FORTRAN Processor instructions
|
||||||
|
- Added SET OFFLINE/ONLINE and SET UNLOAD/LOAD commands to tapes and disks
|
||||||
|
|
||||||
|
2. Bugs Fixed in 3.4-0
|
||||||
|
|
||||||
|
2.1 Interdata
|
||||||
|
|
||||||
|
- Fixed bug in show history routine (from Mark Hittinger)
|
||||||
|
- Fixed bug in initial memory allocation
|
||||||
|
|
||||||
|
2.2 PDP-10
|
||||||
|
|
||||||
|
- Fixed TU bug, ERASE and WREOF should not clear done (reported by
|
||||||
|
Rich Alderson)
|
||||||
|
- Fixed TU error reporting
|
||||||
|
|
||||||
|
2.3 PDP-11
|
||||||
|
|
||||||
|
- Fixed TU error reporting
|
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
||||||
/* altairz80_defs.h: MITS Altair simulator definitions
|
/* altairz80_defs.h: MITS Altair simulator definitions
|
||||||
|
|
||||||
Copyright (c) 2002-2004, Peter Schorn
|
Copyright (c) 2002-2005, Peter Schorn
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -36,15 +36,15 @@
|
||||||
#define BANKMASK (MAXBANKS-1) /* bank mask */
|
#define BANKMASK (MAXBANKS-1) /* bank mask */
|
||||||
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
|
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
|
||||||
#define KB 1024 /* kilo byte */
|
#define KB 1024 /* kilo byte */
|
||||||
#define defaultROMLow 0xff00 /* default for lowest addres of ROM */
|
#define defaultROMLow 0xff00 /* default for lowest address of ROM */
|
||||||
#define defaultROMHigh 0xffff /* default for highest addres of ROM */
|
#define defaultROMHigh 0xffff /* default for highest address of ROM */
|
||||||
|
|
||||||
#define NUM_OF_DSK 8 /* NUM_OF_DSK must be power of two */
|
#define NUM_OF_DSK 8 /* NUM_OF_DSK must be power of two */
|
||||||
#define LDAInstruction 0x3e /* op-code for LD A,<8-bit value> instruction */
|
#define LDAInstruction 0x3e /* op-code for LD A,<8-bit value> instruction */
|
||||||
#define unitNoOffset1 0x37 /* LD A,<unitno> */
|
#define unitNoOffset1 0x37 /* LD A,<unitno> */
|
||||||
#define unitNoOffset2 0xb4 /* LD a,80h | <unitno> */
|
#define unitNoOffset2 0xb4 /* LD a,80h | <unitno> */
|
||||||
|
|
||||||
#define UNIT_V_OPSTOP (UNIT_V_UF+0) /* stop on nvalid operation */
|
#define UNIT_V_OPSTOP (UNIT_V_UF+0) /* stop on invalid operation */
|
||||||
#define UNIT_OPSTOP (1 << UNIT_V_OPSTOP)
|
#define UNIT_OPSTOP (1 << UNIT_V_OPSTOP)
|
||||||
#define UNIT_V_CHIP (UNIT_V_UF+1) /* 8080 or Z80 CPU */
|
#define UNIT_V_CHIP (UNIT_V_UF+1) /* 8080 or Z80 CPU */
|
||||||
#define UNIT_CHIP (1 << UNIT_V_CHIP)
|
#define UNIT_CHIP (1 << UNIT_V_CHIP)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* altairz80_dsk.c: MITS Altair 88-DISK Simulator
|
/* altairz80_dsk.c: MITS Altair 88-DISK Simulator
|
||||||
|
|
||||||
Copyright (c) 2002-2004, Peter Schorn
|
Copyright (c) 2002-2005, Peter Schorn
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
Each diskette has physically 77 tracks of 32 137-byte sectors
|
Each diskette has physically 77 tracks of 32 137-byte sectors
|
||||||
each.
|
each.
|
||||||
|
|
||||||
The controller is interfaced to the CPU by use of 3 I/O addreses,
|
The controller is interfaced to the CPU by use of 3 I/O addresses,
|
||||||
standardly, these are device numbers 10, 11, and 12 (octal).
|
standardly, these are device numbers 10, 11, and 12 (octal).
|
||||||
|
|
||||||
Address Mode Function
|
Address Mode Function
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* altairz80_sio: MITS Altair serial I/O card
|
/* altairz80_sio: MITS Altair serial I/O card
|
||||||
|
|
||||||
Copyright (c) 2002-2004, Peter Schorn
|
Copyright (c) 2002-2005, Peter Schorn
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -58,7 +58,7 @@
|
||||||
|
|
||||||
#define UNIT_V_ANSI (UNIT_V_UF + 0) /* ANSI mode, strip bit 8 on output */
|
#define UNIT_V_ANSI (UNIT_V_UF + 0) /* ANSI mode, strip bit 8 on output */
|
||||||
#define UNIT_ANSI (1 << UNIT_V_ANSI)
|
#define UNIT_ANSI (1 << UNIT_V_ANSI)
|
||||||
#define UNIT_V_UPPER (UNIT_V_UF + 1) /* uppper case mode */
|
#define UNIT_V_UPPER (UNIT_V_UF + 1) /* upper case mode */
|
||||||
#define UNIT_UPPER (1 << UNIT_V_UPPER)
|
#define UNIT_UPPER (1 << UNIT_V_UPPER)
|
||||||
#define UNIT_V_BS (UNIT_V_UF + 2) /* map delete to backspace */
|
#define UNIT_V_BS (UNIT_V_UF + 2) /* map delete to backspace */
|
||||||
#define UNIT_BS (1 << UNIT_V_BS)
|
#define UNIT_BS (1 << UNIT_V_BS)
|
||||||
|
@ -170,7 +170,7 @@ static int32 warnUnattachedPTR = 0; /* display a warning message if < warnLe
|
||||||
static int32 warnPTREOF = 0; /* display a warning message if < warnLevel and SIO set to
|
static int32 warnPTREOF = 0; /* display a warning message if < warnLevel and SIO set to
|
||||||
VERBOSE and attempt to read from PTR past EOF */
|
VERBOSE and attempt to read from PTR past EOF */
|
||||||
static int32 warnUnassignedPort = 0; /* display a warning message if < warnLevel and SIO set to
|
static int32 warnUnassignedPort = 0; /* display a warning message if < warnLevel and SIO set to
|
||||||
VERBOSE andattempt to perform IN or OUT on an unassigned PORT */
|
VERBOSE and attempt to perform IN or OUT on an unassigned PORT */
|
||||||
struct sio_terminal {
|
struct sio_terminal {
|
||||||
int32 data; /* data for this terminal */
|
int32 data; /* data for this terminal */
|
||||||
int32 status; /* status information for this terminal */
|
int32 status; /* status information for this terminal */
|
||||||
|
@ -743,10 +743,10 @@ static t_stat simh_svc(UNIT *uptr) {
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The CP/M commandline is used as the name of a file and UNIT* uptr is attached to it. */
|
/* The CP/M command line is used as the name of a file and UNIT* uptr is attached to it. */
|
||||||
static void attachCPM(UNIT *uptr) {
|
static void attachCPM(UNIT *uptr) {
|
||||||
char cpmCommandLine[cpmCommandLineLength];
|
char cpmCommandLine[cpmCommandLineLength];
|
||||||
uint32 i, len = (GetBYTEWrapper(0x80) & 0x7f) - 1; /* 0x80 contains length of commandline, discard first char */
|
uint32 i, len = (GetBYTEWrapper(0x80) & 0x7f) - 1; /* 0x80 contains length of command line, discard first char */
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
cpmCommandLine[i] = (char)GetBYTEWrapper(0x82 + i); /* the first char, typically ' ', is discarded */
|
cpmCommandLine[i] = (char)GetBYTEWrapper(0x82 + i); /* the first char, typically ' ', is discarded */
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* altairz80_sys.c: MITS Altair system interface
|
/* altairz80_sys.c: MITS Altair system interface
|
||||||
|
|
||||||
Copyright (c) 2002-2004, Peter Schorn
|
Copyright (c) 2002-2005, Peter Schorn
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -425,7 +425,7 @@ int32 fprint_sym(FILE *of, int32 addr, uint32 *val, UNIT *uptr, int32 sw) {
|
||||||
return 1 - ch; /* need to return additional bytes */
|
return 1 - ch; /* need to return additional bytes */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* numString checks determines the base of the number (ch, *numString)
|
/* checkbase determines the base of the number (ch, *numString)
|
||||||
and returns FALSE if the number is bad */
|
and returns FALSE if the number is bad */
|
||||||
static int32 checkbase(char ch, const char *numString) {
|
static int32 checkbase(char ch, const char *numString) {
|
||||||
int32 decimal = (ch <= '9');
|
int32 decimal = (ch <= '9');
|
||||||
|
@ -475,7 +475,7 @@ static int32 match(const char *pattern, const char *input, char *xyFirst, char *
|
||||||
char inp = *input++;
|
char inp = *input++;
|
||||||
while ((pat) && (inp)) {
|
while ((pat) && (inp)) {
|
||||||
switch(pat) {
|
switch(pat) {
|
||||||
case '_': /* patterns containting '_' should never match */
|
case '_': /* patterns containing '_' should never match */
|
||||||
return FALSE;
|
return FALSE;
|
||||||
case ',':
|
case ',':
|
||||||
if (inp == ' ') {
|
if (inp == ' ') {
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
To: Users
|
To: Users
|
||||||
From: Peter Schorn
|
From: Peter Schorn
|
||||||
Subj: AltairZ80 Simulator Usage
|
Subj: AltairZ80 Simulator Usage
|
||||||
Date: 12-Apr-2004
|
Date: 05-Apr-2005
|
||||||
|
|
||||||
COPYRIGHT NOTICE
|
COPYRIGHT NOTICE
|
||||||
|
|
||||||
The following copyright notice applies to both the SIMH source and binary:
|
The following copyright notice applies to both the SIMH source and binary:
|
||||||
|
|
||||||
Copyright (c) 2002-2004, Peter Schorn
|
Copyright (c) 2002-2005, Peter Schorn
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -61,7 +61,10 @@ sim/AltairZ80/altairz80_defs.h
|
||||||
|
|
||||||
2. Revision History
|
2. Revision History
|
||||||
|
|
||||||
- 12-Apr-2004, Peter Schorn (added MAP/NOMAP capability to switch off key mapping)
|
- 05-Apr-2005, removed bogus t-state stepping support
|
||||||
|
- 24-Jul-2004, Peter Schorn (updated CP/M 2 and SPL packages)
|
||||||
|
- 12-Apr-2004, Peter Schorn (added MAP/NOMAP capability to switch off
|
||||||
|
key mapping)
|
||||||
- 26-Jan-2004, Peter Schorn (added support for t-state stepping)
|
- 26-Jan-2004, Peter Schorn (added support for t-state stepping)
|
||||||
- 25-Feb-2003, Peter Schorn (added support for real time simulation)
|
- 25-Feb-2003, Peter Schorn (added support for real time simulation)
|
||||||
- 9-Oct-2002, Peter Schorn (added support for simulated hard disk)
|
- 9-Oct-2002, Peter Schorn (added support for simulated hard disk)
|
||||||
|
@ -169,7 +172,7 @@ the MITS Disk Basic and Altair DOS require about a minimum of 24K.
|
||||||
a warning message if the CPU attempts to read from non-existing
|
a warning message if the CPU attempts to read from non-existing
|
||||||
memory.
|
memory.
|
||||||
|
|
||||||
SET CPU NOWARNROM Suppreses all warning message of "WARNROM". Note that
|
SET CPU NOWARNROM Suppresses all warning message of "WARNROM". Note that
|
||||||
some software tries on purpose to write to ROM in order to detect
|
some software tries on purpose to write to ROM in order to detect
|
||||||
the available RAM.
|
the available RAM.
|
||||||
|
|
||||||
|
@ -181,7 +184,7 @@ crashes. This is historically accurate behavior.
|
||||||
|
|
||||||
The real 8080, on receiving a HLT (Halt) instruction, freezes the
|
The real 8080, on receiving a HLT (Halt) instruction, freezes the
|
||||||
processor and only an interrupt or CPU hardware reset will restore it. The
|
processor and only an interrupt or CPU hardware reset will restore it. The
|
||||||
simulator is alot nicer, it will halt but send you back to the simulator
|
simulator is a lot nicer, it will halt but send you back to the simulator
|
||||||
command line.
|
command line.
|
||||||
|
|
||||||
CPU Registers include the following:
|
CPU Registers include the following:
|
||||||
|
@ -193,7 +196,7 @@ CPU Registers include the following:
|
||||||
F = S Z - AC - P/V N C
|
F = S Z - AC - P/V N C
|
||||||
S = Sign flag.
|
S = Sign flag.
|
||||||
Z = Zero Flag.
|
Z = Zero Flag.
|
||||||
AC = Auxillary Carry flag.
|
AC = Auxiliary Carry flag.
|
||||||
P/V = Parity flag on 8080
|
P/V = Parity flag on 8080
|
||||||
Parity / Overflow flag on Z80
|
Parity / Overflow flag on Z80
|
||||||
- = not used (undefined)
|
- = not used (undefined)
|
||||||
|
@ -307,10 +310,10 @@ for debugging purposes.
|
||||||
|
|
||||||
The MITS 88-DISK is a simple programmed I/O interface to the MITS 8-inch
|
The MITS 88-DISK is a simple programmed I/O interface to the MITS 8-inch
|
||||||
floppy drive, which was basically a Pertec FD-400 with a power supply and
|
floppy drive, which was basically a Pertec FD-400 with a power supply and
|
||||||
buffer board builtin. The controller supports neither interrupts nor DMA,
|
buffer board built-in. The controller supports neither interrupts nor DMA,
|
||||||
so floppy access required the sustained attention of the CPU. The standard
|
so floppy access required the sustained attention of the CPU. The standard
|
||||||
I/O addresses were 8, 9, and 0A (hex), and we follow the standard. Details
|
I/O addresses were 8, 9, and 0A (hex), and we follow the standard. Details
|
||||||
on controlling this hardware are in the altair_dsk.c source file.
|
on controlling this hardware are in the altairz80_dsk.c source file.
|
||||||
|
|
||||||
The only difference is that the simulated disks may be larger than the
|
The only difference is that the simulated disks may be larger than the
|
||||||
original ones: The original disk had 77 tracks while the simulated disks
|
original ones: The original disk had 77 tracks while the simulated disks
|
||||||
|
@ -438,10 +441,10 @@ DUMP .COM 2K ; hex dump a file
|
||||||
ED .COM 8K ; line editor
|
ED .COM 8K ; line editor
|
||||||
ELIZA .BAS 10K ; Eliza game in Basic
|
ELIZA .BAS 10K ; Eliza game in Basic
|
||||||
EX8080 .COM 12K ; exercise 8080 instruction set
|
EX8080 .COM 12K ; exercise 8080 instruction set
|
||||||
EXZ80N .COM 12K ; exercise Z80 instruction set, No undefined status bits
|
EXZ80DOC.COM 12K ; exercise Z80 instruction set, No undefined status bits
|
||||||
EXZ80U .COM 12K ; exercise Z80 instruction set, Undefined status bits
|
EXZ80ALL.COM 12K ; exercise Z80 instruction set, Undefined status bits
|
||||||
EXZ80 .MAC 54K ; source for EX8080.COM, EXZ80N.COM, EXZ80U.COM
|
EX .MAC 54K ; source for EX8080.COM, EXZ80DOC.COM, EXZ80ALL.COM
|
||||||
EX .SUB 2K ; benchmark execution of EX8080.COM, EXZ80N.COM, EXZ80U.COM
|
EX .SUB 2K ; benchmark execution of EX8080.COM,EXZ80DOC.COM,EXZ80ALL.COM
|
||||||
FORMAT .COM 2K ; format disks
|
FORMAT .COM 2K ; format disks
|
||||||
GO .COM 0K ; start the currently loaded program at 100H
|
GO .COM 0K ; start the currently loaded program at 100H
|
||||||
HDSKBOOT.MAC 6K ; boot code for hard disk
|
HDSKBOOT.MAC 6K ; boot code for hard disk
|
||||||
|
@ -484,7 +487,7 @@ W .COM 4K ; write files to SIMH environment
|
||||||
WM .COM 12K ; word master screen editor
|
WM .COM 12K ; word master screen editor
|
||||||
WM .HLP 3K ; help file for WM.COM
|
WM .HLP 3K ; help file for WM.COM
|
||||||
WORM .COM 4K ; worm game for VT100 terminal
|
WORM .COM 4K ; worm game for VT100 terminal
|
||||||
XFORMAT .COM 2K ; initialise a drive (floppy or hard disk)
|
XFORMAT .COM 2K ; initialize a drive (floppy or hard disk)
|
||||||
XSUB .COM 2K ; support for DO.COM
|
XSUB .COM 2K ; support for DO.COM
|
||||||
ZAP .COM 10K ; SuperZap 5.2 disk editor configured for VT100
|
ZAP .COM 10K ; SuperZap 5.2 disk editor configured for VT100
|
||||||
ZSID .COM 10K ; debugger for Z80
|
ZSID .COM 10K ; debugger for Z80
|
||||||
|
@ -493,7 +496,7 @@ ZTRAN4 .COM 4K ; translate 8080 mnemonics into Z80 equivalents
|
||||||
|
|
||||||
5.2 CP/M Version 3 with banked memory
|
5.2 CP/M Version 3 with banked memory
|
||||||
|
|
||||||
CP/M 3 is the successor to CP/M 2.2. A customised BIOS (BIOS3.MAC) is
|
CP/M 3 is the successor to CP/M 2.2. A customized BIOS (BIOS3.MAC) is
|
||||||
included to facilitate modification if so desired. The defaults supplied in
|
included to facilitate modification if so desired. The defaults supplied in
|
||||||
GENCPM.DAT for system generation can be used. BOOTGEN.COM is used to place
|
GENCPM.DAT for system generation can be used. BOOTGEN.COM is used to place
|
||||||
the CP/M loader (LDR.COM) on the boot tracks of a disk.
|
the CP/M loader (LDR.COM) on the boot tracks of a disk.
|
||||||
|
@ -545,13 +548,13 @@ HEXCOM .CPM 2K
|
||||||
HIST .UTL 2K
|
HIST .UTL 2K
|
||||||
INITDIR .COM 32K
|
INITDIR .COM 32K
|
||||||
L80 .COM 12K ; Microsoft linker
|
L80 .COM 12K ; Microsoft linker
|
||||||
LDR .COM 4K ; CP/M loader with optimised loader BIOS
|
LDR .COM 4K ; CP/M loader with optimized loader BIOS
|
||||||
LDRBIOS3.MAC 14K ; optimised (for space) loader BIOS
|
LDRBIOS3.MAC 14K ; optimized (for space) loader BIOS
|
||||||
LIB .COM 8K ; Digital Research librarian
|
LIB .COM 8K ; Digital Research librarian
|
||||||
LINK .COM 16K ; Digital Research linker
|
LINK .COM 16K ; Digital Research linker
|
||||||
LOAD .COM 2K
|
LOAD .COM 2K
|
||||||
M80 .COM 20K ; Microsoft macro assembler
|
M80 .COM 20K ; Microsoft macro assembler
|
||||||
MC .SUB 2K ; assemble and link an assmbler program
|
MC .SUB 2K ; assemble and link an assembler program
|
||||||
MCC .SUB 2K ; read, assemble and link an assembler program
|
MCC .SUB 2K ; read, assemble and link an assembler program
|
||||||
PATCH .COM 4K
|
PATCH .COM 4K
|
||||||
PIP .COM 10K ; Peripheral Interchange Program
|
PIP .COM 10K ; Peripheral Interchange Program
|
||||||
|
@ -626,7 +629,7 @@ DUMP .MAC 6K ; source for DUMP.PRL
|
||||||
DUMP .PRL 2K ; dump command
|
DUMP .PRL 2K ; dump command
|
||||||
ED .PRL 10K ; MP/M line editor
|
ED .PRL 10K ; MP/M line editor
|
||||||
ERA .PRL 2K ; erase command
|
ERA .PRL 2K ; erase command
|
||||||
ERAQ .PRL 4K ; erase comand (verbose)
|
ERAQ .PRL 4K ; erase command (verbose)
|
||||||
GENHEX .COM 2K
|
GENHEX .COM 2K
|
||||||
GENMOD .COM 2K
|
GENMOD .COM 2K
|
||||||
GENSYS .COM 10K
|
GENSYS .COM 10K
|
||||||
|
@ -636,7 +639,7 @@ LIB .COM 8K ; library utility
|
||||||
LINK .COM 16K ; linker
|
LINK .COM 16K ; linker
|
||||||
LOAD .COM 2K ; loader
|
LOAD .COM 2K ; loader
|
||||||
M80 .COM 20K ; Microsoft macro assembler
|
M80 .COM 20K ; Microsoft macro assembler
|
||||||
MC .SUB 2K ; assemble and link an assmbler program
|
MC .SUB 2K ; assemble and link an assembler program
|
||||||
MCC .SUB 2K ; read, assemble and link an assembler program
|
MCC .SUB 2K ; read, assemble and link an assembler program
|
||||||
MPM .COM 8K ; start MP/M II
|
MPM .COM 8K ; start MP/M II
|
||||||
MPM .SYS 26K ; MP/M system file
|
MPM .SYS 26K ; MP/M system file
|
||||||
|
@ -703,21 +706,22 @@ before booting CP/M.
|
||||||
|
|
||||||
The disk "app.dsk" contains the following files:
|
The disk "app.dsk" contains the following files:
|
||||||
Name Ext Size Comment
|
Name Ext Size Comment
|
||||||
|
ACKER .SPL 4K ; compute the Ackermann function
|
||||||
|
ACKER .COM 2K ; compute the Ackermann function, SPL source
|
||||||
BOOTGEN .COM 2K
|
BOOTGEN .COM 2K
|
||||||
BOOTGEN .SPL 6K ; SPL source for BOOTGEN.COM
|
BOOTGEN .SPL 6K ; SPL source for BOOTGEN.COM
|
||||||
C .SUB 2K ; batch file for compiling an SPL source file
|
C .SUB 2K ; batch file for compiling an SPL source file
|
||||||
CALC .PRO 4K ; Prolog demo program: Calculator
|
CALC .PRO 4K ; Prolog demo program: Calculator
|
||||||
CC .SUB 2K ; compile an SPL source which is on the underlying
|
|
||||||
file system
|
|
||||||
DECLARAT. 12K ; common include file, SPL source
|
|
||||||
DIF .COM 4K
|
DIF .COM 4K
|
||||||
DIF .SPL 10K ; SPL source for DIF.COM
|
DIF .SPL 10K ; SPL source for DIF.COM
|
||||||
EDIT .SPL 10K ; screen editor for PROLOGZ, SPL source
|
FAC .COM 4K ; compute the factorial
|
||||||
|
FAC .SPL 4K ; compute the factorial, SPL source
|
||||||
FAMILY .PRO 4K ; Prolog demo program: Family relations
|
FAMILY .PRO 4K ; Prolog demo program: Family relations
|
||||||
|
FORMEL .COM 4K ; calculator
|
||||||
|
FORMEL .SPL 6K ; calculator, SPL source
|
||||||
INTEGER .PRO 2K ; Prolog demo program: Integer arithmetic
|
INTEGER .PRO 2K ; Prolog demo program: Integer arithmetic
|
||||||
KNAKE .PRO 2K ; Prolog demo program: Logic puzzle
|
KNAKE .PRO 2K ; Prolog demo program: Logic puzzle
|
||||||
LINKMT .COM 12K ; Pascal MT+ 5.5 linker
|
LINKMT .COM 12K ; Pascal MT+ 5.5 linker
|
||||||
MAIN .SPL 14K ; main module for PROLOGZ, SPL source
|
|
||||||
MOVE .MAC 4K ; helper functions for PROLOGZ in assembler
|
MOVE .MAC 4K ; helper functions for PROLOGZ in assembler
|
||||||
MTERRS .TXT 6K ; Pascal MT+ error messages
|
MTERRS .TXT 6K ; Pascal MT+ error messages
|
||||||
MTPLUS .000 14K ; Pascal MT+ 5.5 compiler file
|
MTPLUS .000 14K ; Pascal MT+ 5.5 compiler file
|
||||||
|
@ -733,34 +737,31 @@ PASCFORM.PAS 54K ; Pascal formatter source code
|
||||||
PASCFORM.SUB 2K ; create Pascal formatter
|
PASCFORM.SUB 2K ; create Pascal formatter
|
||||||
PASLIB .ERL 24K ; Pascal MT+ 5.5 run time library
|
PASLIB .ERL 24K ; Pascal MT+ 5.5 run time library
|
||||||
PINST .COM 4K ; terminal installation program for PROLOGZ
|
PINST .COM 4K ; terminal installation program for PROLOGZ
|
||||||
PINST .SPL 16K ; terminal installation program for PROLOGZ,
|
PINST .SPL 16K ; terminal installation program for PROLOGZ, SPL source
|
||||||
SPL source
|
PRIM .COM 2K ; compute prime numbers
|
||||||
|
PRIM .SPL 2K ; compute prime numbers, SPL source
|
||||||
PROLOGZ .COM 18K ; PROLOGZ interpreter and screen editor
|
PROLOGZ .COM 18K ; PROLOGZ interpreter and screen editor
|
||||||
PROLOGZ .SPL 2K ; PROLOGZ main program, SPL source
|
PROLOGZ .SPL 2K ; SPL source for PROLOGZ
|
||||||
PROLOGZ .TXT 40K ; PROLOGZ documentation in German
|
PROLOGZ .TXT 40K ; PROLOGZ documentation in German
|
||||||
PROVE .SPL 16K ; backtrack theorem prover for PROLOGZ, SPL source
|
|
||||||
PZCLEAN .SUB 2K ; PROLOGZ: remove all created ".rel" and ".lst" files
|
|
||||||
PZLINK .SUB 2K ; PROLOGZ: create PINST, PROLOGZ and personalise the
|
|
||||||
serial number
|
|
||||||
PZMAKE .SUB 2K ; PROLOGZ: compiles the sources (you can ignore
|
|
||||||
any compiler errors)
|
|
||||||
QUEEN .PRO 2K ; Prolog demo program: N-queens problem
|
QUEEN .PRO 2K ; Prolog demo program: N-queens problem
|
||||||
READ .COM 4K
|
READ .COM 4K
|
||||||
READ .SPL 10K ; SPL source for R.COM
|
READ .SPL 10K ; SPL source for R.COM
|
||||||
SHOWSEC .COM 4K
|
RELDUMP .COM 4K ; dump a .REL file to the console
|
||||||
|
RELDUMP .SPL 10K ; dump a .REL file to the console, SPL source
|
||||||
|
SHOWSEC .COM 2K
|
||||||
SHOWSEC .SPL 6K ; SPL source for SHOWSEC.COM
|
SHOWSEC .SPL 6K ; SPL source for SHOWSEC.COM
|
||||||
|
SIEVE .COM 2K ; compute prime numbers with a sieve
|
||||||
|
SIEVE .SPL 6K ; compute prime numbers with a sieve, SPL source
|
||||||
SPEED .COM 2K ; utility to measure the clock speed of the simulated CPU
|
SPEED .COM 2K ; utility to measure the clock speed of the simulated CPU
|
||||||
SPEED .SPL 2K ; SPL source for SPEED.COM, requires SWLIB.MAC
|
SPEED .SPL 4K ; SPL source for SPEED.COM
|
||||||
SPL .COM 38K ; the SPL compiler itself
|
SPL .COM 28K ; the SPL compiler itself
|
||||||
SPL .TXT 56K ; SPL language and compiler documentation in German
|
SPL .TXT 50K ; SPL language and compiler documentation
|
||||||
SPLERROR.DAT 12K ; error messages of the compiler (in German)
|
SPLERROR.DAT 8K ; error messages of the compiler
|
||||||
SPLIB .REL 6K ; SPL runtime library
|
SPLRTLB .REL 2K ; SPL runtime library
|
||||||
STDIO . 2K ; include file for SPL programs
|
|
||||||
SWLIB .MAC 2K ; assembler utility routines needed by SPEED.SPL
|
|
||||||
SYSCOPY .COM 2K
|
SYSCOPY .COM 2K
|
||||||
SYSCOPY .SPL 6K ; SPL source for SYSCOPY.COM
|
SYSCOPY .SPL 6K ; SPL source for SYSCOPY.COM
|
||||||
TERMBDOS.SPL 2K ; terminal interface to CP/M for PROLOGZ, SPL source
|
WC .COM 6K ; word count and query facility
|
||||||
UTIL .SPL 18K ; utility functions for PROLOGZ, SPL source
|
WC .SPL 14K ; word count and query facility, SPL source
|
||||||
WRITE .COM 4K
|
WRITE .COM 4K
|
||||||
WRITE .SPL 8K ; SPL source for W.COM
|
WRITE .SPL 8K ; SPL source for W.COM
|
||||||
XFORMAT .COM 2K
|
XFORMAT .COM 2K
|
||||||
|
@ -828,7 +829,7 @@ trick is to get the Switch Register right).
|
||||||
|
|
||||||
sim> set cpu 8080 ;note 4k Basic will not run on a Z80 CPU
|
sim> set cpu 8080 ;note 4k Basic will not run on a Z80 CPU
|
||||||
sim> set sio upper ;4k Basic does not like lower case letters as input
|
sim> set sio upper ;4k Basic does not like lower case letters as input
|
||||||
sim> set cpu noitrap ;4k Basic likes to execute non 8080 instructions - ignore
|
sim> set cpu noitrap ;4k Basic likes to execute non 8080 instructions-ignore
|
||||||
sim> set sio ansi ;4k Basic produces 8-bit output, strip to seven bits
|
sim> set sio ansi ;4k Basic produces 8-bit output, strip to seven bits
|
||||||
sim> d sr 8 ;good setting for the Switch Register
|
sim> d sr 8 ;good setting for the Switch Register
|
||||||
sim> load 4kbas.bin 0 ;load it at 0
|
sim> load 4kbas.bin 0 ;load it at 0
|
||||||
|
@ -873,8 +874,8 @@ trick is to get the Switch Register right).
|
||||||
|
|
||||||
Execute the following commands to run Altair Extended Basic:
|
Execute the following commands to run Altair Extended Basic:
|
||||||
|
|
||||||
sim> set sio upper ;Extended Basic does not like lower case letters as input
|
sim> set sio upper ;Extended Basic requires upper case input
|
||||||
sim> set sio ansi ;Extended Basic produces 8-bit output, strip to seven bits
|
sim> set sio ansi ;Extended Basic produces 8-bit output, strip to 7 bits
|
||||||
sim> d sr 8 ;good setting for the Switch Register
|
sim> d sr 8 ;good setting for the Switch Register
|
||||||
sim> load exbas.bin 0 ;load it at 0
|
sim> load exbas.bin 0 ;load it at 0
|
||||||
sim> go 0 ;and start it
|
sim> go 0 ;and start it
|
||||||
|
@ -914,10 +915,7 @@ following commands:
|
||||||
OK
|
OK
|
||||||
|
|
||||||
|
|
||||||
6. Special simulator features
|
6. Special simulator feature: Memory access breakpoints
|
||||||
|
|
||||||
|
|
||||||
6.1 Memory access breakpoints
|
|
||||||
|
|
||||||
In addition to the regular SIMH features such as PC queue, breakpoints
|
In addition to the regular SIMH features such as PC queue, breakpoints
|
||||||
etc., this simulator supports memory access breakpoints. A memory access
|
etc., this simulator supports memory access breakpoints. A memory access
|
||||||
|
@ -932,21 +930,6 @@ a memory access breakpoint is not triggered by fetching code from memory
|
||||||
by using the typing facility of the SIMH breakpoints.
|
by using the typing facility of the SIMH breakpoints.
|
||||||
|
|
||||||
|
|
||||||
6.2 T-state stepping
|
|
||||||
|
|
||||||
The SIMH step command supports the "-t" modifier to allow steppping for
|
|
||||||
a predefined number of t-states. For example
|
|
||||||
|
|
||||||
sim> step -t 1000
|
|
||||||
|
|
||||||
will cause the simulated CPU to execute 1000 t-states (note that the shortest
|
|
||||||
instruction will have 4 t-states). On the other hand, the command
|
|
||||||
|
|
||||||
sim> step 1000
|
|
||||||
|
|
||||||
will cause the simulated CPU to execute 1000 instructions.
|
|
||||||
|
|
||||||
|
|
||||||
7. Brief summary of all major changes to the original Altair simulator
|
7. Brief summary of all major changes to the original Altair simulator
|
||||||
- Full support for Z80. CP/M software requiring a Z80 CPU now runs
|
- Full support for Z80. CP/M software requiring a Z80 CPU now runs
|
||||||
properly. DDTZ and PROLOGZ are included for demonstration purposes.
|
properly. DDTZ and PROLOGZ are included for demonstration purposes.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* altairz80_hdsk.c: simulated hard disk device to increase capacity
|
/* altairz80_hdsk.c: simulated hard disk device to increase capacity
|
||||||
|
|
||||||
Copyright (c) 2002-2004, Peter Schorn
|
Copyright (c) 2002-2005, Peter Schorn
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
MP 12892B memory protect
|
MP 12892B memory protect
|
||||||
DMA0,DMA1 12895A/12897B direct memory access/dual channel port controller
|
DMA0,DMA1 12895A/12897B direct memory access/dual channel port controller
|
||||||
|
|
||||||
|
21-Jan-05 JDB Reorganized CPU option flags
|
||||||
15-Jan-05 RMS Split out EAU and MAC instructions
|
15-Jan-05 RMS Split out EAU and MAC instructions
|
||||||
26-Dec-04 RMS DMA reset doesn't clear alternate CTL flop (from Dave Bryan)
|
26-Dec-04 RMS DMA reset doesn't clear alternate CTL flop (from Dave Bryan)
|
||||||
DMA reset shouldn't clear control words (from Dave Bryan)
|
DMA reset shouldn't clear control words (from Dave Bryan)
|
||||||
|
@ -340,9 +341,16 @@
|
||||||
#define UNIT_MP_INT (1 << UNIT_V_MP_INT)
|
#define UNIT_MP_INT (1 << UNIT_V_MP_INT)
|
||||||
#define UNIT_MP_SEL1 (1 << UNIT_V_MP_SEL1)
|
#define UNIT_MP_SEL1 (1 << UNIT_V_MP_SEL1)
|
||||||
|
|
||||||
#define MOD_2116 1
|
#define MOD_211X (1 << TYPE_211X)
|
||||||
#define MOD_2100 2
|
#define MOD_2100 (1 << TYPE_2100)
|
||||||
#define MOD_21MX 4
|
#define MOD_21MX (1 << TYPE_21MX)
|
||||||
|
#define MOD_CURRENT (1 << CPU_TYPE)
|
||||||
|
|
||||||
|
#define UNIT_SYSTEM (UNIT_CPU_MASK | UNIT_OPTS)
|
||||||
|
#define UNIT_SYS_2116 (UNIT_2116)
|
||||||
|
#define UNIT_SYS_2100 (UNIT_2100 | UNIT_EAU)
|
||||||
|
#define UNIT_SYS_21MX_M (UNIT_21MX_M | UNIT_EAU | UNIT_FP | UNIT_DMS)
|
||||||
|
#define UNIT_SYS_21MX_E (UNIT_21MX_E | UNIT_EAU | UNIT_FP | UNIT_DMS)
|
||||||
|
|
||||||
#define ABORT(val) longjmp (save_env, (val))
|
#define ABORT(val) longjmp (save_env, (val))
|
||||||
|
|
||||||
|
@ -396,13 +404,14 @@ struct opt_table { /* options table */
|
||||||
int32 cpuf; };
|
int32 cpuf; };
|
||||||
|
|
||||||
static struct opt_table opt_val[] = {
|
static struct opt_table opt_val[] = {
|
||||||
{ UNIT_EAU, MOD_2116 },
|
{ UNIT_EAU, MOD_211X },
|
||||||
{ UNIT_FP, MOD_2100 },
|
{ UNIT_FP, MOD_2100 },
|
||||||
{ UNIT_DMS, MOD_21MX },
|
{ UNIT_DMS, MOD_21MX },
|
||||||
{ UNIT_IOP, MOD_2100 | MOD_21MX },
|
{ UNIT_IOP, MOD_2100 | MOD_21MX },
|
||||||
{ UNIT_2116, MOD_2116 | MOD_2100 | MOD_21MX },
|
{ UNIT_FFP, MOD_2100 | MOD_21MX },
|
||||||
{ UNIT_2100, MOD_2116 | MOD_2100 | MOD_21MX },
|
{ TYPE_211X, MOD_211X | MOD_2100 | MOD_21MX },
|
||||||
{ UNIT_21MX, MOD_2116 | MOD_2100 | MOD_21MX },
|
{ TYPE_2100, MOD_211X | MOD_2100 | MOD_21MX },
|
||||||
|
{ TYPE_21MX, MOD_211X | MOD_2100 | MOD_21MX },
|
||||||
{ 0, 0 } };
|
{ 0, 0 } };
|
||||||
|
|
||||||
extern int32 sim_interval;
|
extern int32 sim_interval;
|
||||||
|
@ -415,7 +424,7 @@ extern DEVICE *sim_devices[];
|
||||||
extern int32 sim_switches;
|
extern int32 sim_switches;
|
||||||
extern char halt_msg[];
|
extern char halt_msg[];
|
||||||
|
|
||||||
t_stat Ea1 (uint32 *addr, uint32 irq);
|
t_stat Ea (uint32 IR, uint32 *addr, uint32 irq);
|
||||||
uint16 ReadIO (uint32 addr, uint32 map);
|
uint16 ReadIO (uint32 addr, uint32 map);
|
||||||
uint16 ReadPW (uint32 addr);
|
uint16 ReadPW (uint32 addr);
|
||||||
uint16 ReadTAB (uint32 addr);
|
uint16 ReadTAB (uint32 addr);
|
||||||
|
@ -440,7 +449,8 @@ t_bool dev_conflict (void);
|
||||||
void hp_post_cmd (t_bool from_scp);
|
void hp_post_cmd (t_bool from_scp);
|
||||||
|
|
||||||
extern t_stat cpu_eau (uint32 IR, uint32 intrq);
|
extern t_stat cpu_eau (uint32 IR, uint32 intrq);
|
||||||
extern t_stat cpu_mac (uint32 IR, uint32 intrq);
|
extern t_stat cpu_uig_0 (uint32 IR, uint32 intrq);
|
||||||
|
extern t_stat cpu_uig_1 (uint32 IR, uint32 intrq);
|
||||||
extern int32 clk_delay (int32 flg);
|
extern int32 clk_delay (int32 flg);
|
||||||
extern void (*sim_vm_post) (t_bool from_scp);
|
extern void (*sim_vm_post) (t_bool from_scp);
|
||||||
|
|
||||||
|
@ -495,49 +505,50 @@ REG cpu_reg[] = {
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
MTAB cpu_mod[] = {
|
MTAB cpu_mod[] = {
|
||||||
{ UNIT_2116+UNIT_2100+UNIT_21MX+UNIT_EAU+UNIT_FP+UNIT_DMS+UNIT_IOP+UNIT_IOPX,
|
{ UNIT_SYSTEM, UNIT_SYS_2116, NULL, "2116", &cpu_set_opt, NULL,
|
||||||
UNIT_2116, NULL, "2116", &cpu_set_opt,
|
(void *) TYPE_211X },
|
||||||
NULL, (void *) UNIT_2116 },
|
{ UNIT_SYSTEM, UNIT_SYS_2100, NULL, "2100", &cpu_set_opt, NULL,
|
||||||
{ UNIT_2116+UNIT_2100+UNIT_21MX+UNIT_EAU+UNIT_FP+UNIT_DMS+UNIT_IOP+UNIT_IOPX,
|
(void *) TYPE_2100 },
|
||||||
UNIT_2100+UNIT_EAU, NULL, "2100", &cpu_set_opt,
|
{ UNIT_SYSTEM, UNIT_SYS_21MX_E, NULL, "21MX-E", &cpu_set_opt, NULL,
|
||||||
NULL, (void *) UNIT_2100 },
|
(void *) TYPE_21MX },
|
||||||
{ UNIT_2116+UNIT_2100+UNIT_21MX+UNIT_MXM+UNIT_EAU+UNIT_FP+UNIT_DMS+UNIT_IOP+UNIT_IOPX,
|
{ UNIT_SYSTEM, UNIT_SYS_21MX_M, NULL, "21MX-M", &cpu_set_opt, NULL,
|
||||||
UNIT_21MX+UNIT_EAU+UNIT_FP+UNIT_DMS, NULL, "21MX-E", &cpu_set_opt,
|
(void *) TYPE_21MX },
|
||||||
NULL, (void *) UNIT_21MX },
|
|
||||||
{ UNIT_2116+UNIT_2100+UNIT_21MX+UNIT_MXM+UNIT_EAU+UNIT_FP+UNIT_DMS+UNIT_IOP+UNIT_IOPX,
|
{ UNIT_CPU_MASK, UNIT_2116, "2116", NULL, NULL },
|
||||||
UNIT_21MX+UNIT_MXM+UNIT_EAU+UNIT_FP+UNIT_DMS, NULL, "21MX-M", &cpu_set_opt,
|
{ UNIT_CPU_MASK, UNIT_2100, "2100", NULL, NULL },
|
||||||
NULL, (void *) UNIT_21MX },
|
{ UNIT_CPU_MASK, UNIT_21MX_E, "21MX-E", NULL, NULL },
|
||||||
{ UNIT_2116+UNIT_2100+UNIT_21MX, UNIT_2116, "2116", NULL, NULL },
|
{ UNIT_CPU_MASK, UNIT_21MX_M, "21MX-M", NULL, NULL },
|
||||||
{ UNIT_2116+UNIT_2100+UNIT_21MX, UNIT_2100, "2100", NULL, NULL },
|
|
||||||
{ UNIT_2116+UNIT_2100+UNIT_21MX+UNIT_MXM, UNIT_21MX, "21MX-E", NULL, NULL },
|
{ UNIT_EAU, UNIT_EAU, "EAU", "EAU", &cpu_set_opt, NULL,
|
||||||
{ UNIT_2116+UNIT_2100+UNIT_21MX+UNIT_MXM, UNIT_21MX+UNIT_MXM, "21MX-M", NULL, NULL },
|
(void *) UNIT_EAU },
|
||||||
{ UNIT_EAU, UNIT_EAU, "EAU", "EAU", &cpu_set_opt,
|
{ UNIT_EAU, 0, "no EAU", "NOEAU", &cpu_set_opt, NULL,
|
||||||
NULL, (void *) UNIT_EAU },
|
(void *) UNIT_EAU },
|
||||||
{ UNIT_EAU, 0, "no EAU", "NOEAU", &cpu_set_opt,
|
{ UNIT_FP, UNIT_FP, "FP", "FP", &cpu_set_opt, NULL,
|
||||||
NULL, (void *) UNIT_EAU },
|
(void *) UNIT_FP },
|
||||||
{ UNIT_FP, UNIT_FP, "FP", "FP", &cpu_set_opt,
|
{ UNIT_FP, 0, "no FP", "NOFP", &cpu_set_opt, NULL,
|
||||||
NULL, (void *) UNIT_FP },
|
(void *) UNIT_FP },
|
||||||
{ UNIT_FP, 0, "no FP", "NOFP", &cpu_set_opt,
|
{ UNIT_IOP, UNIT_IOP, "IOP", "IOP", &cpu_set_opt, NULL,
|
||||||
NULL, (void *) UNIT_FP },
|
(void *) UNIT_IOP },
|
||||||
{ UNIT_DMS, UNIT_DMS, "DMS", "DMS", &cpu_set_opt,
|
{ UNIT_IOP, 0, "no IOP", "NOIOP", &cpu_set_opt, NULL,
|
||||||
NULL, (void *) UNIT_DMS },
|
(void *) UNIT_IOP },
|
||||||
{ UNIT_DMS, 0, "no DMS", "NODMS", &cpu_set_opt,
|
{ UNIT_DMS, UNIT_DMS, "DMS", "DMS", &cpu_set_opt, NULL,
|
||||||
NULL, (void *) UNIT_DMS },
|
(void *) UNIT_DMS },
|
||||||
{ UNIT_MSIZE, 2, NULL, "IOP", &cpu_set_opt,
|
{ UNIT_DMS, 0, "no DMS", "NODMS", &cpu_set_opt, NULL,
|
||||||
NULL, (void *) UNIT_IOP },
|
(void *) UNIT_DMS },
|
||||||
{ UNIT_IOP+UNIT_IOPX, UNIT_IOP, "IOP", NULL, NULL },
|
{ UNIT_FFP, UNIT_FFP, "FFP", "FFP", &cpu_set_opt, NULL,
|
||||||
{ UNIT_IOP+UNIT_IOPX, UNIT_IOPX,"IOP", NULL, NULL },
|
(void *) UNIT_FFP },
|
||||||
{ UNIT_IOP+UNIT_IOPX, 0, "no IOP", "NOIOP", &cpu_set_opt,
|
{ UNIT_FFP, 0, "no FFP", "NOFFP", &cpu_set_opt, NULL,
|
||||||
NULL, (void *) UNIT_IOP },
|
(void *) UNIT_FFP },
|
||||||
{ UNIT_MSIZE, 4096, NULL, "4K", &cpu_set_size },
|
|
||||||
{ UNIT_MSIZE, 8192, NULL, "8K", &cpu_set_size },
|
{ MTAB_XTD | MTAB_VDV, 4096, NULL, "4K", &cpu_set_size },
|
||||||
{ UNIT_MSIZE, 16384, NULL, "16K", &cpu_set_size },
|
{ MTAB_XTD | MTAB_VDV, 8192, NULL, "8K", &cpu_set_size },
|
||||||
{ UNIT_MSIZE, 32768, NULL, "32K", &cpu_set_size },
|
{ MTAB_XTD | MTAB_VDV, 16384, NULL, "16K", &cpu_set_size },
|
||||||
{ UNIT_MSIZE, 65536, NULL, "64K", &cpu_set_size },
|
{ MTAB_XTD | MTAB_VDV, 32768, NULL, "32K", &cpu_set_size },
|
||||||
{ UNIT_MSIZE, 131072, NULL, "128K", &cpu_set_size },
|
{ MTAB_XTD | MTAB_VDV, 65536, NULL, "64K", &cpu_set_size },
|
||||||
{ UNIT_MSIZE, 262144, NULL, "256K", &cpu_set_size },
|
{ MTAB_XTD | MTAB_VDV, 131072, NULL, "128K", &cpu_set_size },
|
||||||
{ UNIT_MSIZE, 524288, NULL, "512K", &cpu_set_size },
|
{ MTAB_XTD | MTAB_VDV, 262144, NULL, "256K", &cpu_set_size },
|
||||||
{ UNIT_MSIZE, 1048576, NULL, "1024K", &cpu_set_size },
|
{ MTAB_XTD | MTAB_VDV, 524288, NULL, "512K", &cpu_set_size },
|
||||||
|
{ MTAB_XTD | MTAB_VDV, 1048576, NULL, "1024K", &cpu_set_size },
|
||||||
{ 0 } };
|
{ 0 } };
|
||||||
|
|
||||||
DEVICE cpu_dev = {
|
DEVICE cpu_dev = {
|
||||||
|
@ -1006,10 +1017,15 @@ case 0211: /* DST */
|
||||||
|
|
||||||
/* Extended instructions */
|
/* Extended instructions */
|
||||||
|
|
||||||
case 0212: /* MAC0 ext */
|
case 0212: /* UIG 0 extension */
|
||||||
case 0203: /* MAC1 ext */
|
reason = cpu_uig_0 (IR, intrq); /* extended opcode */
|
||||||
|
dmarq = calc_dma (); /* recalc DMA masks */
|
||||||
|
intrq = calc_int (); /* recalc interrupts */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0203: /* UIG 1 extension */
|
||||||
case 0213:
|
case 0213:
|
||||||
reason = cpu_mac (IR, intrq); /* extended opcode */
|
reason = cpu_uig_1 (IR, intrq); /* extended opcode */
|
||||||
dmarq = calc_dma (); /* recalc DMA masks */
|
dmarq = calc_dma (); /* recalc DMA masks */
|
||||||
intrq = calc_int (); /* recalc interrupts */
|
intrq = calc_int (); /* recalc interrupts */
|
||||||
break; } /* end case IR */
|
break; } /* end case IR */
|
||||||
|
@ -1043,14 +1059,12 @@ pcq_r->qptr = pcq_p; /* update pc q ptr */
|
||||||
return reason;
|
return reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Effective address calculation */
|
/* Resolve indirect addresses */
|
||||||
|
|
||||||
t_stat Ea (uint32 IR, uint32 *addr, uint32 irq)
|
t_stat resolve (uint32 MA, uint32 *addr, uint32 irq)
|
||||||
{
|
{
|
||||||
uint32 i, MA;
|
uint32 i;
|
||||||
|
|
||||||
MA = IR & (I_IA | I_DISP); /* ind + disp */
|
|
||||||
if (IR & I_CP) MA = ((PC - 1) & I_PAGENO) | MA; /* current page? */
|
|
||||||
for (i = 0; (i < ind_max) && (MA & I_IA); i++) { /* resolve multilevel */
|
for (i = 0; (i < ind_max) && (MA & I_IA); i++) { /* resolve multilevel */
|
||||||
if (irq && /* int req? */
|
if (irq && /* int req? */
|
||||||
((i >= 2) || (mp_unit.flags & UNIT_MP_INT)) && /* ind > 3 or W6 out? */
|
((i >= 2) || (mp_unit.flags & UNIT_MP_INT)) && /* ind > 3 or W6 out? */
|
||||||
|
@ -1062,23 +1076,15 @@ if (i >= ind_max) return STOP_IND; /* indirect loop? */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Effective address, two words */
|
/* Get effective address from IR */
|
||||||
|
|
||||||
t_stat Ea1 (uint32 *addr, uint32 irq)
|
t_stat Ea (uint32 IR, uint32 *addr, uint32 irq)
|
||||||
{
|
{
|
||||||
uint32 i, MA;
|
uint32 MA;
|
||||||
|
|
||||||
MA = ReadW (PC); /* get next address */
|
MA = IR & (I_IA | I_DISP); /* ind + disp */
|
||||||
PC = (PC + 1) & VAMASK;
|
if (IR & I_CP) MA = ((PC - 1) & I_PAGENO) | MA; /* current page? */
|
||||||
for (i = 0; (i < ind_max) && (MA & I_IA); i++) { /* resolve multilevel */
|
return resolve (MA, addr, irq); /* resolve indirects */
|
||||||
if (irq && /* int req? */
|
|
||||||
((i >= 2) || (mp_unit.flags & UNIT_MP_INT)) && /* ind > 3 or W6 out? */
|
|
||||||
!(mp_unit.flags & DEV_DIS)) /* MP installed? */
|
|
||||||
return STOP_INDINT; /* break out */
|
|
||||||
MA = ReadW (MA & VAMASK); }
|
|
||||||
if (i >= ind_max) return STOP_IND; /* indirect loop? */
|
|
||||||
*addr = MA;
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Shift micro operation */
|
/* Shift micro operation */
|
||||||
|
@ -1181,7 +1187,7 @@ return r;
|
||||||
to request an interrupt. This is the masked under the
|
to request an interrupt. This is the masked under the
|
||||||
result from #1 to determine the highest priority interrupt,
|
result from #1 to determine the highest priority interrupt,
|
||||||
if any.
|
if any.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint32 calc_int (void)
|
uint32 calc_int (void)
|
||||||
{
|
{
|
||||||
|
@ -1550,7 +1556,7 @@ case ioLIX: /* load */
|
||||||
dat = SR;
|
dat = SR;
|
||||||
break;
|
break;
|
||||||
case ioOTX: /* output */
|
case ioOTX: /* output */
|
||||||
if (cpu_unit.flags & (UNIT_2100 | UNIT_21MX)) SR = dat;
|
if (UNIT_CPU_TYPE != UNIT_TYPE_211X) SR = dat;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break; }
|
break; }
|
||||||
|
@ -1663,7 +1669,7 @@ case ioSFS: /* skip flag set */
|
||||||
case ioLIX: /* load */
|
case ioLIX: /* load */
|
||||||
dat = 0;
|
dat = 0;
|
||||||
case ioMIX: /* merge */
|
case ioMIX: /* merge */
|
||||||
if (cpu_unit.flags & UNIT_21MX) dat = DMASK;
|
if (UNIT_CPU_TYPE == UNIT_TYPE_21MX) dat = DMASK;
|
||||||
break;
|
break;
|
||||||
case ioOTX: /* output */
|
case ioOTX: /* output */
|
||||||
dmac[ch].cw1 = dat;
|
dmac[ch].cw1 = dat;
|
||||||
|
@ -1748,7 +1754,8 @@ case ioSFC: /* skip flag clear */
|
||||||
case ioLIX: /* load */
|
case ioLIX: /* load */
|
||||||
dat = 0;
|
dat = 0;
|
||||||
case ioMIX: /* merge */
|
case ioMIX: /* merge */
|
||||||
if ((devd < VARDEV) && (cpu_unit.flags & UNIT_21MX)) dat = DMASK;
|
if ((devd < VARDEV) && (UNIT_CPU_TYPE == UNIT_TYPE_21MX))
|
||||||
|
dat = DMASK;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break; }
|
break; }
|
||||||
|
@ -1854,7 +1861,7 @@ int32 mc = 0;
|
||||||
uint32 i;
|
uint32 i;
|
||||||
|
|
||||||
if ((val <= 0) || (val > PASIZE) || ((val & 07777) != 0) ||
|
if ((val <= 0) || (val > PASIZE) || ((val & 07777) != 0) ||
|
||||||
(!(uptr->flags & UNIT_21MX) && (val > VASIZE)))
|
((UNIT_CPU_TYPE != UNIT_TYPE_21MX) && (val > VASIZE)))
|
||||||
return SCPE_ARG;
|
return SCPE_ARG;
|
||||||
if (!(sim_switches & SWMASK ('F'))) { /* force truncation? */
|
if (!(sim_switches & SWMASK ('F'))) { /* force truncation? */
|
||||||
for (i = val; i < MEMSIZE; i++) mc = mc | M[i];
|
for (i = val; i < MEMSIZE; i++) mc = mc | M[i];
|
||||||
|
@ -1947,33 +1954,35 @@ return FALSE;
|
||||||
|
|
||||||
/* Configuration validation
|
/* Configuration validation
|
||||||
|
|
||||||
Memory is trimmed to 32K if 2116 or 2100 is selected.
|
- Checks that the current CPU type supports the option selected.
|
||||||
Memory protect is enabled if 2100 or 21MX or DMS is selected.
|
- Ensures that FP/FFP and IOP are mutually exclusive if CPU is 2100.
|
||||||
DMA is enabled if 2116 or 2100 or 21MX is selected. */
|
- Disables memory protect if 2116 is selected.
|
||||||
|
- Enables memory protect if 2100 or 21MX or DMS is selected.
|
||||||
|
- Enables DMA if 2116 or 2100 or 21MX is selected.
|
||||||
|
- Memory is trimmed to 32K if 2116 or 2100 is selected. */
|
||||||
|
|
||||||
t_bool cpu_set_opt (UNIT *uptr, int32 val, char *cptr, void *desc)
|
t_bool cpu_set_opt (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||||
{
|
{
|
||||||
int32 opt = (int32) desc;
|
int32 opt = (int32) desc;
|
||||||
int32 mod, i;
|
int32 i;
|
||||||
|
uint32 mod;
|
||||||
|
|
||||||
mod = MOD_2116;
|
mod = MOD_CURRENT;
|
||||||
if (uptr->flags & UNIT_2100) mod = MOD_2100;
|
|
||||||
else if (uptr->flags & UNIT_21MX) mod = MOD_21MX;
|
|
||||||
for (i = 0; opt_val[i].cpuf != 0; i++) {
|
for (i = 0; opt_val[i].cpuf != 0; i++) {
|
||||||
if ((opt == opt_val[i].optf) && (mod & opt_val[i].cpuf)) {
|
if ((opt == opt_val[i].optf) && (mod & opt_val[i].cpuf)) {
|
||||||
if ((mod == MOD_2100) && (val == UNIT_FP))
|
|
||||||
uptr->flags = uptr->flags & ~UNIT_IOP;
|
|
||||||
if ((opt == UNIT_IOP) && val) {
|
|
||||||
if (mod == MOD_2100)
|
if (mod == MOD_2100)
|
||||||
uptr->flags = (uptr->flags & ~UNIT_FP) | UNIT_IOP;
|
if ((opt == UNIT_FP) || (opt == UNIT_FFP))
|
||||||
if (mod == MOD_21MX) uptr->flags |= UNIT_IOPX; }
|
uptr->flags = uptr->flags & ~UNIT_IOP;
|
||||||
if (opt == UNIT_2116) mp_dev.flags = mp_dev.flags | DEV_DIS;
|
else if (opt == UNIT_IOP)
|
||||||
else if ((val == UNIT_DMS) || (opt == UNIT_2100) || (opt == UNIT_21MX))
|
uptr->flags = uptr->flags & ~(UNIT_FP | UNIT_FFP);
|
||||||
|
if (opt == TYPE_211X)
|
||||||
|
mp_dev.flags = mp_dev.flags | DEV_DIS;
|
||||||
|
else if ((opt == UNIT_DMS) || (opt == TYPE_2100) || (opt == TYPE_21MX))
|
||||||
mp_dev.flags = mp_dev.flags & ~DEV_DIS;
|
mp_dev.flags = mp_dev.flags & ~DEV_DIS;
|
||||||
if ((opt == UNIT_2116) || (opt == UNIT_2100) || (opt == UNIT_21MX)) {
|
if ((opt == TYPE_211X) || (opt == TYPE_2100) || (opt == TYPE_21MX)) {
|
||||||
dma0_dev.flags = dma0_dev.flags & ~DEV_DIS;
|
dma0_dev.flags = dma0_dev.flags & ~DEV_DIS;
|
||||||
dma1_dev.flags = dma1_dev.flags & ~DEV_DIS; }
|
dma1_dev.flags = dma1_dev.flags & ~DEV_DIS; }
|
||||||
if (((opt == UNIT_2116) || (opt == UNIT_2100)) && (MEMSIZE > VASIZE))
|
if (((opt == TYPE_211X) || (opt == TYPE_2100)) && (MEMSIZE > VASIZE))
|
||||||
return cpu_set_size (uptr, VASIZE, cptr, desc);
|
return cpu_set_size (uptr, VASIZE, cptr, desc);
|
||||||
return SCPE_OK; } }
|
return SCPE_OK; } }
|
||||||
return SCPE_NOFNC;
|
return SCPE_NOFNC;
|
||||||
|
|
|
@ -23,37 +23,67 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
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.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
21-Jan-05 JDB Reorganized CPU option flags
|
||||||
14-Jan-05 RMS Cloned from hp2100_cpu.c
|
14-Jan-05 RMS Cloned from hp2100_cpu.c
|
||||||
|
|
||||||
|
CPU models are broken down into type and series to facilitate option
|
||||||
|
validation. Bits 3:2 encode the type, and bits 1:0 encode the series
|
||||||
|
within the type.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _HP2100_CPU_H_
|
#ifndef _HP2100_CPU_H_
|
||||||
#define _HP2100_CPU_H_ 0
|
#define _HP2100_CPU_H_ 0
|
||||||
|
|
||||||
|
#define CPU_V_SERIES 0
|
||||||
|
#define CPU_V_TYPE 2
|
||||||
|
|
||||||
|
#define TYPE_211X 0 /* 2114, 2115, 2116 */
|
||||||
|
#define TYPE_2100 1 /* 2100A, 2100S */
|
||||||
|
#define TYPE_21MX 2 /* 21MX-M, 21MX-E, 21MX-F */
|
||||||
|
#define TYPE_1000A 3 /* A600, A700, A900, A990 */
|
||||||
|
|
||||||
|
#define CPU_2116 (TYPE_211X << CPU_V_TYPE | 0)
|
||||||
|
#define CPU_2100 (TYPE_2100 << CPU_V_TYPE | 0)
|
||||||
|
#define CPU_21MX_M (TYPE_21MX << CPU_V_TYPE | 0)
|
||||||
|
#define CPU_21MX_E (TYPE_21MX << CPU_V_TYPE | 1)
|
||||||
|
|
||||||
|
#define UNIT_V_CPU (UNIT_V_UF + 0) /* CPU model bits 0-3 */
|
||||||
|
#define UNIT_M_CPU 017 /* CPU model mask */
|
||||||
|
#define UNIT_M_TYPE 014 /* CPU type mask */
|
||||||
|
#define UNIT_V_EAU (UNIT_V_UF + 4) /* EAU installed */
|
||||||
|
#define UNIT_V_FP (UNIT_V_UF + 5) /* FP installed */
|
||||||
|
#define UNIT_V_IOP (UNIT_V_UF + 6) /* IOP installed */
|
||||||
|
#define UNIT_V_DMS (UNIT_V_UF + 7) /* DMS installed */
|
||||||
|
#define UNIT_V_FFP (UNIT_V_UF + 8) /* FFP installed */
|
||||||
|
|
||||||
|
#define UNIT_CPU_MASK (UNIT_M_CPU << UNIT_V_CPU)
|
||||||
|
#define UNIT_2116 (CPU_2116 << UNIT_V_CPU)
|
||||||
|
#define UNIT_2100 (CPU_2100 << UNIT_V_CPU)
|
||||||
|
#define UNIT_21MX_M (CPU_21MX_M << UNIT_V_CPU)
|
||||||
|
#define UNIT_21MX_E (CPU_21MX_E << UNIT_V_CPU)
|
||||||
|
|
||||||
|
#define UNIT_TYPE_MASK (UNIT_M_TYPE << UNIT_V_CPU)
|
||||||
|
#define UNIT_TYPE_211X ((TYPE_211X << CPU_V_TYPE) << UNIT_V_CPU)
|
||||||
|
#define UNIT_TYPE_2100 ((TYPE_2100 << CPU_V_TYPE) << UNIT_V_CPU)
|
||||||
|
#define UNIT_TYPE_21MX ((TYPE_21MX << CPU_V_TYPE) << UNIT_V_CPU)
|
||||||
|
|
||||||
|
#define UNIT_CPU_MODEL (cpu_unit.flags & UNIT_CPU_MASK)
|
||||||
|
#define UNIT_CPU_TYPE (cpu_unit.flags & UNIT_TYPE_MASK)
|
||||||
|
#define CPU_TYPE (UNIT_CPU_TYPE >> (UNIT_V_CPU + CPU_V_TYPE))
|
||||||
|
|
||||||
|
#define UNIT_EAU (1 << UNIT_V_EAU)
|
||||||
|
#define UNIT_FP (1 << UNIT_V_FP)
|
||||||
|
#define UNIT_IOP (1 << UNIT_V_IOP)
|
||||||
|
#define UNIT_DMS (1 << UNIT_V_DMS)
|
||||||
|
#define UNIT_FFP (1 << UNIT_V_FFP)
|
||||||
|
|
||||||
|
#define UNIT_OPTS (UNIT_EAU | UNIT_FP | UNIT_IOP | UNIT_DMS | UNIT_FFP)
|
||||||
|
|
||||||
#define PCQ_SIZE 64 /* must be 2**n */
|
#define PCQ_SIZE 64 /* must be 2**n */
|
||||||
#define PCQ_MASK (PCQ_SIZE - 1)
|
#define PCQ_MASK (PCQ_SIZE - 1)
|
||||||
#define PCQ_ENTRY pcq[pcq_p = (pcq_p - 1) & PCQ_MASK] = err_PC
|
#define PCQ_ENTRY pcq[pcq_p = (pcq_p - 1) & PCQ_MASK] = err_PC
|
||||||
|
|
||||||
#define UNIT_V_2100 (UNIT_V_UF + 0) /* 2100 */
|
t_stat resolve (uint32 MA, uint32 *addr, uint32 irq);
|
||||||
#define UNIT_V_21MX (UNIT_V_UF + 1) /* 21MX-E or 21MX-M */
|
|
||||||
#define UNIT_V_EAU (UNIT_V_UF + 2) /* EAU */
|
|
||||||
#define UNIT_V_FP (UNIT_V_UF + 3) /* FP */
|
|
||||||
#define UNIT_V_DMS (UNIT_V_UF + 4) /* DMS */
|
|
||||||
#define UNIT_V_IOP (UNIT_V_UF + 5) /* 2100 IOP */
|
|
||||||
#define UNIT_V_IOPX (UNIT_V_UF + 6) /* 21MX IOP */
|
|
||||||
#define UNIT_V_MSIZE (UNIT_V_UF + 7) /* dummy mask */
|
|
||||||
#define UNIT_V_MXM (UNIT_V_UF + 8) /* 21MX is M-series */
|
|
||||||
#define UNIT_2116 (0)
|
|
||||||
#define UNIT_2100 (1 << UNIT_V_2100)
|
|
||||||
#define UNIT_21MX (1 << UNIT_V_21MX)
|
|
||||||
#define UNIT_EAU (1 << UNIT_V_EAU)
|
|
||||||
#define UNIT_FP (1 << UNIT_V_FP)
|
|
||||||
#define UNIT_DMS (1 << UNIT_V_DMS)
|
|
||||||
#define UNIT_IOP (1 << UNIT_V_IOP)
|
|
||||||
#define UNIT_IOPX (1 << UNIT_V_IOPX)
|
|
||||||
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
|
|
||||||
#define UNIT_MXM (1 << UNIT_V_MXM)
|
|
||||||
|
|
||||||
t_stat Ea (uint32 IR, uint32 *addr, uint32 irq);
|
|
||||||
uint8 ReadB (uint32 addr);
|
uint8 ReadB (uint32 addr);
|
||||||
uint8 ReadBA (uint32 addr);
|
uint8 ReadBA (uint32 addr);
|
||||||
uint16 ReadW (uint32 addr);
|
uint16 ReadW (uint32 addr);
|
||||||
|
|
1956
HP2100/hp2100_cpu1.c
1956
HP2100/hp2100_cpu1.c
File diff suppressed because it is too large
Load diff
|
@ -63,7 +63,7 @@
|
||||||
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
|
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
|
||||||
#define VA_N_SIZE 15 /* virtual addr size */
|
#define VA_N_SIZE 15 /* virtual addr size */
|
||||||
#define VASIZE (1 << VA_N_SIZE)
|
#define VASIZE (1 << VA_N_SIZE)
|
||||||
#define VAMASK (VASIZE - 1) /* virt addr mask */
|
#define VAMASK 077777 /* virt addr mask */
|
||||||
#define PA_N_SIZE 20 /* phys addr size */
|
#define PA_N_SIZE 20 /* phys addr size */
|
||||||
#define PASIZE (1 << PA_N_SIZE)
|
#define PASIZE (1 << PA_N_SIZE)
|
||||||
#define PAMASK (PASIZE - 1) /* phys addr mask */
|
#define PAMASK (PASIZE - 1) /* phys addr mask */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
SIMH/HP 21XX DIAGNOSTICS PERFORMANCE
|
SIMH/HP 21XX DIAGNOSTICS PERFORMANCE
|
||||||
====================================
|
====================================
|
||||||
Last update: 2004-12-29
|
Last update: 2005-03-22
|
||||||
|
|
||||||
|
|
||||||
The HP 24396 diagnostic suite has been run against the SIMH HP 21xx simulation.
|
The HP 24396 diagnostic suite has been run against the SIMH HP 21xx simulation.
|
||||||
|
@ -12,7 +12,7 @@ The test system configuration is the default SIMH configuration with these
|
||||||
alterations (except where noted in the individual diagnostic reports):
|
alterations (except where noted in the individual diagnostic reports):
|
||||||
|
|
||||||
* All I/O devices are enabled.
|
* All I/O devices are enabled.
|
||||||
* The CPU is configured as a 21MX with 128KW of memory.
|
* The CPU is configured as a 21MX-E with 128KW of memory.
|
||||||
|
|
||||||
Detailed diagnostic configuration, operation, and results are given after the
|
Detailed diagnostic configuration, operation, and results are given after the
|
||||||
summary table. These may be used to duplicate the diagnostic results.
|
summary table. These may be used to duplicate the diagnostic results.
|
||||||
|
@ -42,9 +42,9 @@ The results of the diagnostic runs are summarized below:
|
||||||
|
|
||||||
101011 Extended Instruction Group (Index) 1432 3.2-3 Passed
|
101011 Extended Instruction Group (Index) 1432 3.2-3 Passed
|
||||||
101112 Extended Instruction Group (Word, Byte) 1728 3.2-3 Passed
|
101112 Extended Instruction Group (Word, Byte) 1728 3.2-3 Passed
|
||||||
101110 2100 Fast FORTRAN Package 1632 - No simulation
|
101110 2100 Fast FORTRAN Package 1632 3.4-0 Partial
|
||||||
101213 M/E-Series Fast FORTRAN Package 1 1822 - No simulation
|
101213 M/E-Series Fast FORTRAN Package 1 1822 3.4-0 Passed
|
||||||
101115 M/E-Series Fast FORTRAN Package 2 1632 - No simulation
|
101114 M/E-Series Fast FORTRAN Package 2 1632 3.4-0 Passed
|
||||||
101121 F-Series FPP/SIS/FFP 1926 - No simulation
|
101121 F-Series FPP/SIS/FFP 1926 - No simulation
|
||||||
|
|
||||||
102103 Memory Expansion Unit 1830 3.2-3 Passed
|
102103 Memory Expansion Unit 1830 3.2-3 Passed
|
||||||
|
@ -492,7 +492,7 @@ TEST RESULT: Passed.
|
||||||
DSN 101011 - Extended Instruction Group (Index)
|
DSN 101011 - Extended Instruction Group (Index)
|
||||||
-----------------------------------------------
|
-----------------------------------------------
|
||||||
|
|
||||||
TESTED DEVICE: CPU (hp2100_cpu.c)
|
TESTED DEVICE: CPU (hp2100_cpu1.c)
|
||||||
|
|
||||||
CONFIGURATION: sim> deposit S 000000
|
CONFIGURATION: sim> deposit S 000000
|
||||||
sim> reset
|
sim> reset
|
||||||
|
@ -511,7 +511,7 @@ TEST RESULT: Passed.
|
||||||
DSN 101112 - Extended Instruction Group (Word, Byte, Bit)
|
DSN 101112 - Extended Instruction Group (Word, Byte, Bit)
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
|
|
||||||
TESTED DEVICE: CPU (hp2100_cpu.c)
|
TESTED DEVICE: CPU (hp2100_cpu1.c)
|
||||||
|
|
||||||
CONFIGURATION: sim> set LPS diag
|
CONFIGURATION: sim> set LPS diag
|
||||||
sim> deposit S 000014
|
sim> deposit S 000014
|
||||||
|
@ -533,6 +533,148 @@ TEST RESULT: Passed.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------
|
||||||
|
DSN 101110 - 2100 Fast FORTRAN Package
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
TESTED DEVICE: CPU (hp2100_cpu1.c)
|
||||||
|
|
||||||
|
CONFIGURATION: sim> set CPU 2100
|
||||||
|
sim> set CPU 32K
|
||||||
|
sim> set CPU FFP
|
||||||
|
|
||||||
|
sim> deposit S 000013
|
||||||
|
sim> reset
|
||||||
|
sim> go 100
|
||||||
|
|
||||||
|
HALT instruction 102074
|
||||||
|
|
||||||
|
sim> deposit S 000000
|
||||||
|
sim> reset
|
||||||
|
sim> go
|
||||||
|
|
||||||
|
TEST REPORT: START 2100A-S FFP DIAGNOSTIC
|
||||||
|
H030 .GOTO TEST
|
||||||
|
H050 .ENTR TEST
|
||||||
|
H060 .ENTP TEST
|
||||||
|
H100 .SETP TEST
|
||||||
|
H110 ..MAP TEST
|
||||||
|
H120 SNGL TEST
|
||||||
|
H130 DBLE TEST
|
||||||
|
H140 .XADD TEST
|
||||||
|
|
||||||
|
TEST 07
|
||||||
|
E142 NOT INTERRUPTIBLE
|
||||||
|
|
||||||
|
HALT instruction 106042
|
||||||
|
|
||||||
|
sim> go
|
||||||
|
|
||||||
|
H150 .XSUB TEST
|
||||||
|
H160 .XMPY TEST
|
||||||
|
|
||||||
|
TEST 11
|
||||||
|
E162 NOT INTERRUPTIBLE
|
||||||
|
|
||||||
|
HALT instruction 106062
|
||||||
|
|
||||||
|
sim> go
|
||||||
|
|
||||||
|
H200 .XDIV TEST
|
||||||
|
H210 .DFER TEST
|
||||||
|
H220 .XFER TEST
|
||||||
|
PASS 000001
|
||||||
|
|
||||||
|
HALT instruction 102077
|
||||||
|
|
||||||
|
TEST RESULT: Partially passed.
|
||||||
|
|
||||||
|
TEST NOTES: Tests 07 and 11 test the interruptibility of the .XADD and .XMPY
|
||||||
|
instructions. These features are not simulated.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------------------------
|
||||||
|
DSN 101213 - M/E-Series Fast FORTRAN Package 1
|
||||||
|
----------------------------------------------
|
||||||
|
|
||||||
|
TESTED DEVICE: CPU (hp2100_cpu1.c)
|
||||||
|
|
||||||
|
CONFIGURATION: sim> set CPU FFP
|
||||||
|
sim> set LPS diag
|
||||||
|
|
||||||
|
sim> deposit S 000014
|
||||||
|
sim> reset
|
||||||
|
sim> go 100
|
||||||
|
|
||||||
|
HALT instruction 102074
|
||||||
|
|
||||||
|
sim> deposit S 000000
|
||||||
|
sim> reset
|
||||||
|
sim> go
|
||||||
|
|
||||||
|
TEST REPORT: START 21MX FFP DIAGNOSTIC 1
|
||||||
|
H110 ..MAP TEST
|
||||||
|
H120 SNGL TEST
|
||||||
|
H130 DBLE TEST
|
||||||
|
H210 .DFER TEST
|
||||||
|
H220 .XFER TEST
|
||||||
|
H230 PWR2 TEST
|
||||||
|
H240 .PACK TEST
|
||||||
|
H250 FLUN TEST
|
||||||
|
H260 .XPAK TEST
|
||||||
|
H300 .XCOM TEST
|
||||||
|
H310 ..DCM TEST
|
||||||
|
H320 DDINT TEST
|
||||||
|
H330 .CFER TEST
|
||||||
|
PASS 000001
|
||||||
|
|
||||||
|
HALT instruction 102077
|
||||||
|
|
||||||
|
TEST RESULT: Passed.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------------------------
|
||||||
|
DSN 101115 - M/E-Series Fast FORTRAN Package 2
|
||||||
|
----------------------------------------------
|
||||||
|
|
||||||
|
TESTED DEVICE: CPU (hp2100_cpu1.c)
|
||||||
|
|
||||||
|
CONFIGURATION: sim> set CPU FFP
|
||||||
|
sim> set LPS diag
|
||||||
|
|
||||||
|
sim> deposit S 000014
|
||||||
|
sim> reset
|
||||||
|
sim> go 100
|
||||||
|
|
||||||
|
HALT instruction 102074
|
||||||
|
|
||||||
|
sim> deposit S 000000
|
||||||
|
sim> reset
|
||||||
|
sim> go
|
||||||
|
|
||||||
|
TEST REPORT: START 21MX FFP DIAGNOSTIC 2
|
||||||
|
H030 .GOTO TEST
|
||||||
|
H050 .ENTR TEST
|
||||||
|
H060 .ENTP TEST
|
||||||
|
H100 .SETP TEST
|
||||||
|
H115 XADD TEST
|
||||||
|
H125 XSUB TEST
|
||||||
|
H135 XMPY TEST
|
||||||
|
H140 .XADD TEST
|
||||||
|
H150 .XSUB TEST
|
||||||
|
H160 .XMPY TEST
|
||||||
|
H200 .XDIV TEST
|
||||||
|
H215 XDIV TEST
|
||||||
|
PASS 000001
|
||||||
|
|
||||||
|
HALT instruction 102077
|
||||||
|
|
||||||
|
TEST RESULT: Passed.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------
|
----------------------------------
|
||||||
DSN 102103 - Memory Expansion Unit
|
DSN 102103 - Memory Expansion Unit
|
||||||
----------------------------------
|
----------------------------------
|
||||||
|
@ -933,7 +1075,7 @@ TEST REPORT: H0 7900/7901 CARTRIDGE DISC MEMORY DIAGNOSTIC
|
||||||
|
|
||||||
HALT instruction 102002
|
HALT instruction 102002
|
||||||
|
|
||||||
sim> detach DPC0
|
sim> set DPC0 unloaded
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H40 PROTECT U/D THEN READY UNIT 0
|
H40 PROTECT U/D THEN READY UNIT 0
|
||||||
|
@ -942,7 +1084,7 @@ TEST REPORT: H0 7900/7901 CARTRIDGE DISC MEMORY DIAGNOSTIC
|
||||||
Simulation stopped
|
Simulation stopped
|
||||||
|
|
||||||
sim> set DPC0 locked
|
sim> set DPC0 locked
|
||||||
sim> attach DPC0 scratch.U0.7900.disc
|
sim> set DPC0 loaded
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H41 CLEAR U/D PROTECT,LOAD,PUSH RUN
|
H41 CLEAR U/D PROTECT,LOAD,PUSH RUN
|
||||||
|
@ -1113,7 +1255,7 @@ TEST REPORT: H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN
|
||||||
|
|
||||||
HALT instruction 102002
|
HALT instruction 102002
|
||||||
|
|
||||||
sim> set DS0 FORMAT
|
sim> set DS0 format
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H46 READ IN STEP 04
|
H46 READ IN STEP 04
|
||||||
|
@ -1142,7 +1284,7 @@ TEST REPORT: H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN
|
||||||
|
|
||||||
HALT instruction 102002
|
HALT instruction 102002
|
||||||
|
|
||||||
sim> set DS0 NOFORMAT
|
sim> set DS0 noformat
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H46 READ IN STEP 07
|
H46 READ IN STEP 07
|
||||||
|
@ -1171,7 +1313,7 @@ TEST REPORT: H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN
|
||||||
|
|
||||||
HALT instruction 102002
|
HALT instruction 102002
|
||||||
|
|
||||||
sim> set DS0 FORMAT
|
sim> set DS0 format
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H45 WRITE IN STEP 10
|
H45 WRITE IN STEP 10
|
||||||
|
@ -1189,7 +1331,7 @@ TEST REPORT: H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN
|
||||||
|
|
||||||
HALT instruction 102002
|
HALT instruction 102002
|
||||||
|
|
||||||
sim> detach DS0
|
sim> set DS0 unloaded
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H107 READY UNIT 0
|
H107 READY UNIT 0
|
||||||
|
@ -1197,21 +1339,21 @@ TEST REPORT: H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN
|
||||||
[CTRL+E]
|
[CTRL+E]
|
||||||
Simulation stopped
|
Simulation stopped
|
||||||
|
|
||||||
sim> attach DS0 scratch.U0.7905.disc
|
sim> set DS0 loaded
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H142 PROTECT U/D,PUSH RUN
|
H142 PROTECT U/D,PUSH RUN
|
||||||
|
|
||||||
HALT instruction 102002
|
HALT instruction 102002
|
||||||
|
|
||||||
sim> set DS0 LOCKED
|
sim> set DS0 locked
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H143 CLEAR U/D PROTECT,PUSH RUN
|
H143 CLEAR U/D PROTECT,PUSH RUN
|
||||||
|
|
||||||
HALT instruction 102002
|
HALT instruction 102002
|
||||||
|
|
||||||
sim> set DS0 WRITEENABLED
|
sim> set DS0 writeenabled
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H110 PRESS PRESET(S),PRESS RUN
|
H110 PRESS PRESET(S),PRESS RUN
|
||||||
|
@ -1323,12 +1465,14 @@ TEST REPORT: H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H46 READ IN STEP 43
|
H46 READ IN STEP 43
|
||||||
|
E47 DATA WORD 0000 IS 156164 SHOULD BE 144300
|
||||||
|
E47 DATA WORD 0001 IS 023302 SHOULD BE 117306
|
||||||
|
E47 DATA WORD 0002 IS 114642 SHOULD BE 045322
|
||||||
H135 S P D TSTAT XXXX UNIT / E DRTYPE X A P F DF FS SC NR B
|
H135 S P D TSTAT XXXX UNIT / E DRTYPE X A P F DF FS SC NR B
|
||||||
E64 STATUS IS 0 0 0 00111 0000 0000 / 0 000010 0 0 0 1 0 0 0 0 0
|
E64 STATUS IS 0 0 0 00000 0000 0000 / 0 000010 0 0 0 1 0 0 0 0 0
|
||||||
SHOULD BE 1 0 0 00000 XXXX XXXX / 0 000010 0 0 0 X 0 0 0 0 0
|
SHOULD BE 1 0 0 00000 XXXX XXXX / 0 000010 0 0 0 X 0 0 0 0 0
|
||||||
H137 TERMINATION STATUS IS "CYL CMP ERROR " SHOULD BE "NORMAL COMPLET"
|
H137 TERMINATION STATUS IS "NORMAL COMPLET"
|
||||||
E13 0000 WORDS TRANSFERRED 0128 EXPECTED
|
START 0016/00/33-LAST 0016/00/34 WORD COUNT 00128,OLD CYL 0016,UNIT 00
|
||||||
START 0016/00/33-LAST 0016/00/33 WORD COUNT 00128,OLD CYL 0016,UNIT 00
|
|
||||||
|
|
||||||
HALT instruction 102001
|
HALT instruction 102001
|
||||||
|
|
||||||
|
@ -1462,28 +1606,28 @@ TEST REPORT: 7970-13181 DIAG.
|
||||||
|
|
||||||
HALT instruction 106037
|
HALT instruction 106037
|
||||||
|
|
||||||
sim> attach MSC0 scratch.U0.7970.tape
|
sim> set MSC0 online
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H137 PUT TAPE UNIT ON-LINE
|
H137 PUT TAPE UNIT ON-LINE
|
||||||
|
|
||||||
HALT instruction 106037
|
HALT instruction 106037
|
||||||
|
|
||||||
sim> attach MSC1 scratch.U1.7970.tape
|
sim> set MSC1 online
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H137 PUT TAPE UNIT ON-LINE
|
H137 PUT TAPE UNIT ON-LINE
|
||||||
|
|
||||||
HALT instruction 106037
|
HALT instruction 106037
|
||||||
|
|
||||||
sim> attach MSC2 scratch.U2.7970.tape
|
sim> set MSC2 online
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H137 PUT TAPE UNIT ON-LINE
|
H137 PUT TAPE UNIT ON-LINE
|
||||||
|
|
||||||
HALT instruction 106037
|
HALT instruction 106037
|
||||||
|
|
||||||
sim> attach MSC3 scratch.U3.7970.tape
|
sim> set MSC3 online
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
PASS 000001
|
PASS 000001
|
||||||
|
@ -1599,28 +1743,28 @@ TEST REPORT: 7970-13183 DIAG.
|
||||||
|
|
||||||
HALT instruction 106037
|
HALT instruction 106037
|
||||||
|
|
||||||
sim> attach MSC0 scratch.U0.7970.tape
|
sim> set MSC0 online
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H137 PUT TAPE UNIT ON-LINE
|
H137 PUT TAPE UNIT ON-LINE
|
||||||
|
|
||||||
HALT instruction 106037
|
HALT instruction 106037
|
||||||
|
|
||||||
sim> attach MSC1 scratch.U1.7970.tape
|
sim> set MSC1 online
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H137 PUT TAPE UNIT ON-LINE
|
H137 PUT TAPE UNIT ON-LINE
|
||||||
|
|
||||||
HALT instruction 106037
|
HALT instruction 106037
|
||||||
|
|
||||||
sim> attach MSC2 scratch.U2.7970.tape
|
sim> set MSC2 online
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H137 PUT TAPE UNIT ON-LINE
|
H137 PUT TAPE UNIT ON-LINE
|
||||||
|
|
||||||
HALT instruction 106037
|
HALT instruction 106037
|
||||||
|
|
||||||
sim> attach MSC3 scratch.U3.7970.tape
|
sim> set MSC3 online
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
PASS 000001
|
PASS 000001
|
||||||
|
@ -2257,7 +2401,7 @@ TEST REPORT: H0 HP2100A CARTRIDGE DISC MEMORY DIAGNOSTIC
|
||||||
|
|
||||||
HALT instruction 102002
|
HALT instruction 102002
|
||||||
|
|
||||||
sim> detach DPC0
|
sim> set DPC0 unloaded
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H40 READY UNIT 0
|
H40 READY UNIT 0
|
||||||
|
@ -2265,7 +2409,7 @@ TEST REPORT: H0 HP2100A CARTRIDGE DISC MEMORY DIAGNOSTIC
|
||||||
[CTRL+E]
|
[CTRL+E]
|
||||||
Simulation stopped
|
Simulation stopped
|
||||||
|
|
||||||
sim> attach DPC0 scratch.U0.2871.disc
|
sim> set DPC0 loaded
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H71 PRESS PRESET THEN PRESS RUN
|
H71 PRESS PRESET THEN PRESS RUN
|
||||||
|
@ -2446,7 +2590,7 @@ TEST REPORT: H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN
|
||||||
|
|
||||||
HALT instruction 102002
|
HALT instruction 102002
|
||||||
|
|
||||||
sim> detach DQC0
|
sim> set DQC0 unloaded
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H40 ENABLE UNIT 0
|
H40 ENABLE UNIT 0
|
||||||
|
@ -2454,7 +2598,7 @@ TEST REPORT: H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN
|
||||||
[CTRL+E]
|
[CTRL+E]
|
||||||
Simulation stopped
|
Simulation stopped
|
||||||
|
|
||||||
sim> attach DQC0 scratch.U0.2883.disc
|
sim> set DQC0 loaded
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H71 PRESS PRESET THEN PRESS RUN
|
H71 PRESS PRESET THEN PRESS RUN
|
||||||
|
@ -2497,7 +2641,7 @@ CONFIGURATION: sim> reset
|
||||||
HALT instruction 107001
|
HALT instruction 107001
|
||||||
|
|
||||||
sim> set DRC 180K
|
sim> set DRC 180K
|
||||||
sim> set DRC TRACKPROT=8
|
sim> set DRC trackprot=8
|
||||||
sim> attach DRC0 scratch.U0.2770.disc
|
sim> attach DRC0 scratch.U0.2770.disc
|
||||||
sim> deposit S 002611
|
sim> deposit S 002611
|
||||||
sim> go
|
sim> go
|
||||||
|
@ -2516,14 +2660,14 @@ TEST REPORT: H12 DEVICE HAS 90 SECTORS
|
||||||
|
|
||||||
HALT instruction 102002
|
HALT instruction 102002
|
||||||
|
|
||||||
sim> set DRC UNPROTECTED
|
sim> set DRC unprotected
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H10 SET TRACK PROTECT SWITCH TO PROTECTED,PRESS RUN
|
H10 SET TRACK PROTECT SWITCH TO PROTECTED,PRESS RUN
|
||||||
|
|
||||||
HALT instruction 102002
|
HALT instruction 102002
|
||||||
|
|
||||||
sim> set DRC PROTECTED
|
sim> set DRC protected
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H14 DEVICE HAS 0032 TRACKS,THE FOLLOWING ARE PROTECTED:
|
H14 DEVICE HAS 0032 TRACKS,THE FOLLOWING ARE PROTECTED:
|
||||||
|
@ -2532,7 +2676,7 @@ TEST REPORT: H12 DEVICE HAS 90 SECTORS
|
||||||
|
|
||||||
HALT instruction 102002
|
HALT instruction 102002
|
||||||
|
|
||||||
sim> set DRC UNPROTECTED
|
sim> set DRC unprotected
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H36 PASS 0001
|
H36 PASS 0001
|
||||||
|
@ -2560,7 +2704,7 @@ CONFIGURATION: sim> reset
|
||||||
HALT instruction 107001
|
HALT instruction 107001
|
||||||
|
|
||||||
sim> set DRC 720K
|
sim> set DRC 720K
|
||||||
sim> set DRC TRACKPROT=32
|
sim> set DRC trackprot=32
|
||||||
sim> attach DRC0 scratch.U0.2771.disc
|
sim> attach DRC0 scratch.U0.2771.disc
|
||||||
sim> deposit S 002611
|
sim> deposit S 002611
|
||||||
sim> go
|
sim> go
|
||||||
|
@ -2579,14 +2723,14 @@ TEST REPORT: H12 DEVICE HAS 90 SECTORS
|
||||||
|
|
||||||
HALT instruction 102002
|
HALT instruction 102002
|
||||||
|
|
||||||
sim> set DRC UNPROTECTED
|
sim> set DRC unprotected
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H10 SET TRACK PROTECT SWITCH TO PROTECTED,PRESS RUN
|
H10 SET TRACK PROTECT SWITCH TO PROTECTED,PRESS RUN
|
||||||
|
|
||||||
HALT instruction 102002
|
HALT instruction 102002
|
||||||
|
|
||||||
sim> set DRC PROTECTED
|
sim> set DRC protected
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H14 DEVICE HAS 0128 TRACKS,THE FOLLOWING ARE PROTECTED:
|
H14 DEVICE HAS 0128 TRACKS,THE FOLLOWING ARE PROTECTED:
|
||||||
|
@ -2595,7 +2739,7 @@ TEST REPORT: H12 DEVICE HAS 90 SECTORS
|
||||||
|
|
||||||
HALT instruction 102002
|
HALT instruction 102002
|
||||||
|
|
||||||
sim> set DRC UNPROTECTED
|
sim> set DRC unprotected
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H36 PASS 0001
|
H36 PASS 0001
|
||||||
|
@ -2623,7 +2767,7 @@ CONFIGURATION: sim> reset
|
||||||
HALT instruction 107001
|
HALT instruction 107001
|
||||||
|
|
||||||
sim> set DRC 384K
|
sim> set DRC 384K
|
||||||
sim> set DRC TRACKPROT=16
|
sim> set DRC trackprot=16
|
||||||
sim> attach DRC0 scratch.U0.2773.disc
|
sim> attach DRC0 scratch.U0.2773.disc
|
||||||
sim> deposit S 002611
|
sim> deposit S 002611
|
||||||
sim> go
|
sim> go
|
||||||
|
@ -2642,14 +2786,14 @@ TEST REPORT: H12 DEVICE HAS 32 SECTORS
|
||||||
|
|
||||||
HALT instruction 102002
|
HALT instruction 102002
|
||||||
|
|
||||||
sim> set DRC UNPROTECTED
|
sim> set DRC unprotected
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H10 SET TRACK PROTECT SWITCH TO PROTECTED,PRESS RUN
|
H10 SET TRACK PROTECT SWITCH TO PROTECTED,PRESS RUN
|
||||||
|
|
||||||
HALT instruction 102002
|
HALT instruction 102002
|
||||||
|
|
||||||
sim> set DRC PROTECTED
|
sim> set DRC protected
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H14 DEVICE HAS 0192 TRACKS,THE FOLLOWING ARE PROTECTED:
|
H14 DEVICE HAS 0192 TRACKS,THE FOLLOWING ARE PROTECTED:
|
||||||
|
@ -2658,7 +2802,7 @@ TEST REPORT: H12 DEVICE HAS 32 SECTORS
|
||||||
|
|
||||||
HALT instruction 102002
|
HALT instruction 102002
|
||||||
|
|
||||||
sim> set DRC UNPROTECTED
|
sim> set DRC unprotected
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H36 PASS 0001
|
H36 PASS 0001
|
||||||
|
@ -2686,7 +2830,7 @@ CONFIGURATION: sim> reset
|
||||||
HALT instruction 107001
|
HALT instruction 107001
|
||||||
|
|
||||||
sim> set DRC 1536K
|
sim> set DRC 1536K
|
||||||
sim> set DRC TRACKPROT=64
|
sim> set DRC trackprot=64
|
||||||
sim> attach DRC0 scratch.U0.2775.disc
|
sim> attach DRC0 scratch.U0.2775.disc
|
||||||
sim> deposit S 002611
|
sim> deposit S 002611
|
||||||
sim> go
|
sim> go
|
||||||
|
@ -2705,14 +2849,14 @@ TEST REPORT: H12 DEVICE HAS 32 SECTORS
|
||||||
|
|
||||||
HALT instruction 102002
|
HALT instruction 102002
|
||||||
|
|
||||||
sim> set DRC UNPROTECTED
|
sim> set DRC unprotected
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H10 SET TRACK PROTECT SWITCH TO PROTECTED,PRESS RUN
|
H10 SET TRACK PROTECT SWITCH TO PROTECTED,PRESS RUN
|
||||||
|
|
||||||
HALT instruction 102002
|
HALT instruction 102002
|
||||||
|
|
||||||
sim> set DRC PROTECTED
|
sim> set DRC protected
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H14 DEVICE HAS 0768 TRACKS,THE FOLLOWING ARE PROTECTED:
|
H14 DEVICE HAS 0768 TRACKS,THE FOLLOWING ARE PROTECTED:
|
||||||
|
@ -2721,7 +2865,7 @@ TEST REPORT: H12 DEVICE HAS 32 SECTORS
|
||||||
|
|
||||||
HALT instruction 102002
|
HALT instruction 102002
|
||||||
|
|
||||||
sim> set DRC UNPROTECTED
|
sim> set DRC unprotected
|
||||||
sim> go
|
sim> go
|
||||||
|
|
||||||
H36 PASS 0001
|
H36 PASS 0001
|
||||||
|
|
|
@ -55,9 +55,11 @@ sim/ scp.h
|
||||||
|
|
||||||
sim/hp2100/ hp2100_cpu.h
|
sim/hp2100/ hp2100_cpu.h
|
||||||
hp2100_defs.h
|
hp2100_defs.h
|
||||||
|
hp2100_fp1.h
|
||||||
hp2100_cpu.c
|
hp2100_cpu.c
|
||||||
hp2100_cpu1.c
|
hp2100_cpu1.c
|
||||||
hp2100_fp.c
|
hp2100_fp.c
|
||||||
|
hp2100_fp1.c
|
||||||
hp2100_dp.c
|
hp2100_dp.c
|
||||||
hp2100_dq.c
|
hp2100_dq.c
|
||||||
hp2100_dr.c
|
hp2100_dr.c
|
||||||
|
@ -78,9 +80,10 @@ The HP2100 simulator is configured as follows:
|
||||||
device simulates
|
device simulates
|
||||||
name(s)
|
name(s)
|
||||||
|
|
||||||
CPU 2116 CPU with 32KW memory
|
CPU 2116 CPU with up to 32KW of memory
|
||||||
2100 CPU with 32KW memory, FP or IOP instructions
|
2100 CPU with up to 32KW of memory
|
||||||
21MX-M/E CPU with 1024KW memory, FP, DMS, and/or IOP instructions
|
21MX-M or -E CPU with up to 1024KW of memory
|
||||||
|
EAU, FP, FFP, IOP, and/or DMS microcode extensions
|
||||||
MP 12892B memory protect
|
MP 12892B memory protect
|
||||||
DMA0, DMA1 12895A/12897B direct memory access/dual channel port controller
|
DMA0, DMA1 12895A/12897B direct memory access/dual channel port controller
|
||||||
PTR 12597A duplex register interface with 2748 paper tape reader
|
PTR 12597A duplex register interface with 2748 paper tape reader
|
||||||
|
@ -110,13 +113,21 @@ The HP2100 simulator implements several unique stop conditions:
|
||||||
- more than INDMAX indirect references are detected during
|
- more than INDMAX indirect references are detected during
|
||||||
memory reference address decoding
|
memory reference address decoding
|
||||||
|
|
||||||
The HP2100 loader supports standard absolute binary format. The DUMP
|
The HP2100 LOAD command supports standard absolute binary format. The DUMP
|
||||||
command is not implemented.
|
command is not implemented.
|
||||||
|
|
||||||
2.1 CPU
|
2.1 CPU
|
||||||
|
|
||||||
CPU options include choice of instruction set and memory size. The
|
CPU options include choice of model, memory size, and instruction sets.
|
||||||
general command form is:
|
Several microcode options are simulated:
|
||||||
|
|
||||||
|
EAU Extended Arithmetic Unit
|
||||||
|
FP Single-Precision Floating Point
|
||||||
|
FFP Fast FORTRAN Processor
|
||||||
|
IOP 2000/Access I/O Processor
|
||||||
|
DMS Dynamic Mapping System
|
||||||
|
|
||||||
|
The general command form is:
|
||||||
|
|
||||||
SET {-F} CPU <option>
|
SET {-F} CPU <option>
|
||||||
|
|
||||||
|
@ -132,6 +143,8 @@ Options that may be specified are:
|
||||||
SET CPU NOFP no FP instructions (2100 only)
|
SET CPU NOFP no FP instructions (2100 only)
|
||||||
SET CPU IOP IOP instructions (2100, 21MX only)
|
SET CPU IOP IOP instructions (2100, 21MX only)
|
||||||
SET CPU NOIOP no IOP instructions (2100, 21MX only)
|
SET CPU NOIOP no IOP instructions (2100, 21MX only)
|
||||||
|
SET CPU FFP FFP instructions (2100, 21MX only)
|
||||||
|
SET CPU NOFFP no FFP instructions (2100, 21MX only)
|
||||||
SET CPU DMS DMS instructions (21MX only)
|
SET CPU DMS DMS instructions (21MX only)
|
||||||
SET CPU NODMS no DMS instructions (21MX only)
|
SET CPU NODMS no DMS instructions (21MX only)
|
||||||
SET CPU 4K set memory size = 4K
|
SET CPU 4K set memory size = 4K
|
||||||
|
@ -144,11 +157,10 @@ Options that may be specified are:
|
||||||
SET CPU 512K set memory size = 512K (21MX only)
|
SET CPU 512K set memory size = 512K (21MX only)
|
||||||
SET CPU 1024K set memory size = 1024K (21MX only)
|
SET CPU 1024K set memory size = 1024K (21MX only)
|
||||||
|
|
||||||
On the 2100, EAU is standard, and the FP and IOP options are mutually
|
On the 2100, EAU is standard, and the FP or FFP and IOP options are mutually
|
||||||
exclusive. On the 21MX, EAU and FP are standard. The 21MX optionally
|
exclusive. On the 21MX, EAU and FP are standard. The DMS, FFP, and IOP
|
||||||
includes DMS (dynamic mapping system) and IOP instructions. The 21MX-E
|
instructions are optional. The 21MX-E supports the TIMER instruction; on
|
||||||
supports the TIMER instruction; on the 21MX-M, this instruction decodes
|
the 21MX-M, this instruction decodes as MPY.
|
||||||
as MPY.
|
|
||||||
|
|
||||||
Setting the CPU type to 2116, 2100, or 21MX establishes a consistent set
|
Setting the CPU type to 2116, 2100, or 21MX establishes a consistent set
|
||||||
of common options. Additional SET CPU commands may follow to fine-tune
|
of common options. Additional SET CPU commands may follow to fine-tune
|
||||||
|
@ -813,6 +825,14 @@ Separate protection for the upper and lower platters of the 7900 drive
|
||||||
is not supported. Also, the drive Protect/Override switch is not
|
is not supported. Also, the drive Protect/Override switch is not
|
||||||
supported; drive protection is permanently overridden.
|
supported; drive protection is permanently overridden.
|
||||||
|
|
||||||
|
Drives may also have their heads unloaded and loaded:
|
||||||
|
|
||||||
|
SET DPCn UNLOADED unload heads on unit n
|
||||||
|
SET DPCn LOADED load heads on unit n
|
||||||
|
|
||||||
|
This provides a convenient method of setting a drive "down" without
|
||||||
|
detaching the associated disk image file.
|
||||||
|
|
||||||
The 12557A/13210A supports the BOOT command. BOOT DPC copies the IBL
|
The 12557A/13210A supports the BOOT command. BOOT DPC copies the IBL
|
||||||
for 7900 class disks into memory and starts it running. BOOT -R DPC
|
for 7900 class disks into memory and starts it running. BOOT -R DPC
|
||||||
boots from the removable platter (head 0). The switch register (S) is
|
boots from the removable platter (head 0). The switch register (S) is
|
||||||
|
@ -869,7 +889,7 @@ Error handling is as follows:
|
||||||
|
|
||||||
error processed as
|
error processed as
|
||||||
|
|
||||||
not attached disk not ready (drive unloaded)
|
not attached disk not ready (heads unloaded)
|
||||||
|
|
||||||
end of file assume rest of disk is zero
|
end of file assume rest of disk is zero
|
||||||
|
|
||||||
|
@ -887,6 +907,14 @@ Individual drives may be protected against writing:
|
||||||
SET DQCn LOCKED set unit n write locked
|
SET DQCn LOCKED set unit n write locked
|
||||||
SET DQCn WRITEENABLED set unit n write enabled
|
SET DQCn WRITEENABLED set unit n write enabled
|
||||||
|
|
||||||
|
Drives may also have their heads unloaded and loaded:
|
||||||
|
|
||||||
|
SET DQCn UNLOADED unload heads on unit n
|
||||||
|
SET DQCn LOADED load heads on unit n
|
||||||
|
|
||||||
|
This provides a convenient method of setting a drive "down" without
|
||||||
|
detaching the associated disk image file.
|
||||||
|
|
||||||
The 12565A supports the BOOT command. BOOT DQC copies the IBL for 2883
|
The 12565A supports the BOOT command. BOOT DQC copies the IBL for 2883
|
||||||
class disks into memory and starts it running. The switch register (S)
|
class disks into memory and starts it running. The switch register (S)
|
||||||
is set automatically to the value expected by the IBL loader:
|
is set automatically to the value expected by the IBL loader:
|
||||||
|
@ -939,7 +967,7 @@ Error handling is as follows:
|
||||||
|
|
||||||
error processed as
|
error processed as
|
||||||
|
|
||||||
not attached disk not ready
|
not attached disk not ready (heads unloaded)
|
||||||
|
|
||||||
end of file assume rest of disk is zero
|
end of file assume rest of disk is zero
|
||||||
|
|
||||||
|
@ -1052,6 +1080,14 @@ Separate protection for the upper and lower platters of the 7905 and
|
||||||
7906 drives is not supported. Protecting a 7905 or 7906 drive behaves
|
7906 drives is not supported. Protecting a 7905 or 7906 drive behaves
|
||||||
as though both of the Disc Protect switches were on.
|
as though both of the Disc Protect switches were on.
|
||||||
|
|
||||||
|
Drives may also have their heads unloaded and loaded:
|
||||||
|
|
||||||
|
SET DSn UNLOADED unload heads on unit n
|
||||||
|
SET DSn LOADED load heads on unit n
|
||||||
|
|
||||||
|
This provides a convenient method of setting a drive "down" without
|
||||||
|
detaching the associated disk image file.
|
||||||
|
|
||||||
The setting of the drive Format switch may be changed with:
|
The setting of the drive Format switch may be changed with:
|
||||||
|
|
||||||
SET DSn FORMAT set format enabled
|
SET DSn FORMAT set format enabled
|
||||||
|
@ -1105,7 +1141,7 @@ Error handling is as follows:
|
||||||
|
|
||||||
error processed as
|
error processed as
|
||||||
|
|
||||||
not attached disk not ready
|
not attached disk not ready (heads unloaded)
|
||||||
|
|
||||||
end of file assume rest of disk is zero
|
end of file assume rest of disk is zero
|
||||||
|
|
||||||
|
@ -1171,10 +1207,12 @@ Error handling is as follows:
|
||||||
2.7.2 13181A Magnetic Tape Controller (MSC, MSD) with Four 7970B Drives
|
2.7.2 13181A Magnetic Tape Controller (MSC, MSD) with Four 7970B Drives
|
||||||
18183A Magnetic Tape Controller (MSC, MSD) with Four 7970E Drives
|
18183A Magnetic Tape Controller (MSC, MSD) with Four 7970E Drives
|
||||||
|
|
||||||
Magnetic tape options include the ability to make the unit write enabled
|
Magnetic tape options include the ability to set a drive offline and
|
||||||
or write locked, and the ability to select the 13181A (800 bpi) controller
|
online, write enabled or write locked, and the ability to select the
|
||||||
or the 13183A (1600 bpi) controller.
|
13181A (800 bpi) controller or the 13183A (1600 bpi) controller.
|
||||||
|
|
||||||
|
SET MSCn OFFLINE set unit n offline
|
||||||
|
SET MSCn ONLINE set unit n online
|
||||||
SET MSCn LOCKED set unit n write locked
|
SET MSCn LOCKED set unit n write locked
|
||||||
SET MSCn WRITEENABLED set unit n write enabled
|
SET MSCn WRITEENABLED set unit n write enabled
|
||||||
SET MSC 13181A set controller to 13181A
|
SET MSC 13181A set controller to 13181A
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
dp 12557A 2871 disk subsystem
|
dp 12557A 2871 disk subsystem
|
||||||
13210A 7900 disk subsystem
|
13210A 7900 disk subsystem
|
||||||
|
|
||||||
|
01-Mar-05 JDB Added SET UNLOAD/LOAD
|
||||||
07-Oct-04 JDB Fixed enable/disable from either device
|
07-Oct-04 JDB Fixed enable/disable from either device
|
||||||
Fixed ANY ERROR status for 12557A interface
|
Fixed ANY ERROR status for 12557A interface
|
||||||
Fixed unattached drive status for 12557A interface
|
Fixed unattached drive status for 12557A interface
|
||||||
|
@ -113,7 +114,9 @@
|
||||||
#include "hp2100_defs.h"
|
#include "hp2100_defs.h"
|
||||||
|
|
||||||
#define UNIT_V_WLK (UNIT_V_UF + 0) /* write locked */
|
#define UNIT_V_WLK (UNIT_V_UF + 0) /* write locked */
|
||||||
|
#define UNIT_V_UNLOAD (UNIT_V_UF + 1) /* heads unloaded */
|
||||||
#define UNIT_WLK (1 << UNIT_V_WLK)
|
#define UNIT_WLK (1 << UNIT_V_WLK)
|
||||||
|
#define UNIT_UNLOAD (1 << UNIT_V_UNLOAD)
|
||||||
#define FNC u3 /* saved function */
|
#define FNC u3 /* saved function */
|
||||||
#define DRV u4 /* drive number (DC) */
|
#define DRV u4 /* drive number (DC) */
|
||||||
#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write prot */
|
#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write prot */
|
||||||
|
@ -231,11 +234,12 @@ int32 dpcio (int32 inst, int32 IR, int32 dat);
|
||||||
t_stat dpc_svc (UNIT *uptr);
|
t_stat dpc_svc (UNIT *uptr);
|
||||||
t_stat dpd_svc (UNIT *uptr);
|
t_stat dpd_svc (UNIT *uptr);
|
||||||
t_stat dpc_reset (DEVICE *dptr);
|
t_stat dpc_reset (DEVICE *dptr);
|
||||||
t_stat dpc_vlock (UNIT *uptr, int32 val);
|
|
||||||
t_stat dpc_attach (UNIT *uptr, char *cptr);
|
t_stat dpc_attach (UNIT *uptr, char *cptr);
|
||||||
|
t_stat dpc_detach (UNIT* uptr);
|
||||||
t_stat dpc_boot (int32 unitno, DEVICE *dptr);
|
t_stat dpc_boot (int32 unitno, DEVICE *dptr);
|
||||||
void dp_god (int32 fnc, int32 drv, int32 time);
|
void dp_god (int32 fnc, int32 drv, int32 time);
|
||||||
void dp_goc (int32 fnc, int32 drv, int32 time);
|
void dp_goc (int32 fnc, int32 drv, int32 time);
|
||||||
|
t_stat dpc_load_unload (UNIT *uptr, int32 value, char *cptr, void *desc);
|
||||||
t_stat dp_settype (UNIT *uptr, int32 val, char *cptr, void *desc);
|
t_stat dp_settype (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||||
t_stat dp_showtype (FILE *st, UNIT *uptr, int32 val, void *desc);
|
t_stat dp_showtype (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||||
|
|
||||||
|
@ -291,14 +295,14 @@ DEVICE dpd_dev = {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
UNIT dpc_unit[] = {
|
UNIT dpc_unit[] = {
|
||||||
{ UDATA (&dpc_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
{ UDATA (&dpc_svc, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||||
UNIT_ROABLE, DP_SIZE3) },
|
UNIT_DISABLE | UNIT_UNLOAD, DP_SIZE3) },
|
||||||
{ UDATA (&dpc_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
{ UDATA (&dpc_svc, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||||
UNIT_ROABLE, DP_SIZE3) },
|
UNIT_DISABLE | UNIT_UNLOAD, DP_SIZE3) },
|
||||||
{ UDATA (&dpc_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
{ UDATA (&dpc_svc, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||||
UNIT_ROABLE, DP_SIZE3) },
|
UNIT_DISABLE | UNIT_UNLOAD, DP_SIZE3) },
|
||||||
{ UDATA (&dpc_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
{ UDATA (&dpc_svc, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||||
UNIT_ROABLE, DP_SIZE3) } };
|
UNIT_DISABLE | UNIT_UNLOAD, DP_SIZE3) } };
|
||||||
|
|
||||||
REG dpc_reg[] = {
|
REG dpc_reg[] = {
|
||||||
{ ORDATA (OBUF, dpc_obuf, 16) },
|
{ ORDATA (OBUF, dpc_obuf, 16) },
|
||||||
|
@ -329,6 +333,8 @@ REG dpc_reg[] = {
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
MTAB dpc_mod[] = {
|
MTAB dpc_mod[] = {
|
||||||
|
{ UNIT_UNLOAD, UNIT_UNLOAD, "heads unloaded", "UNLOADED", dpc_load_unload },
|
||||||
|
{ UNIT_UNLOAD, 0, "heads loaded", "LOADED", dpc_load_unload },
|
||||||
{ UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL },
|
{ UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL },
|
||||||
{ UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL },
|
{ UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL },
|
||||||
{ MTAB_XTD | MTAB_VDV, 1, NULL, "13210A",
|
{ MTAB_XTD | MTAB_VDV, 1, NULL, "13210A",
|
||||||
|
@ -345,7 +351,7 @@ DEVICE dpc_dev = {
|
||||||
"DPC", dpc_unit, dpc_reg, dpc_mod,
|
"DPC", dpc_unit, dpc_reg, dpc_mod,
|
||||||
DP_NUMDRV, 8, 24, 1, 8, 16,
|
DP_NUMDRV, 8, 24, 1, 8, 16,
|
||||||
NULL, NULL, &dpc_reset,
|
NULL, NULL, &dpc_reset,
|
||||||
&dpc_boot, &dpc_attach, NULL,
|
&dpc_boot, &dpc_attach, &dpc_detach,
|
||||||
&dpc_dib, DEV_DISABLE };
|
&dpc_dib, DEV_DISABLE };
|
||||||
|
|
||||||
/* IOT routines */
|
/* IOT routines */
|
||||||
|
@ -561,7 +567,7 @@ case FNC_SEEK1: /* seek, need hd/sec */
|
||||||
|
|
||||||
case FNC_STA: /* read status */
|
case FNC_STA: /* read status */
|
||||||
if (CMD (devd) || dp_ctype) { /* dch act or 13210? */
|
if (CMD (devd) || dp_ctype) { /* dch act or 13210? */
|
||||||
if (dpc_unit[drv].flags & UNIT_ATT) { /* attached? */
|
if ((dpc_unit[drv].flags & UNIT_UNLOAD) == 0) { /* drive up? */
|
||||||
dpd_ibuf = dpc_sta[drv] & ~STA_ERR; /* clear err */
|
dpd_ibuf = dpc_sta[drv] & ~STA_ERR; /* clear err */
|
||||||
if (dp_ctype) dpd_ibuf = /* 13210? */
|
if (dp_ctype) dpd_ibuf = /* 13210? */
|
||||||
(dpd_ibuf & ~(STA_MBZ13 | STA_PROT)) |
|
(dpd_ibuf & ~(STA_MBZ13 | STA_PROT)) |
|
||||||
|
@ -621,7 +627,7 @@ err = 0; /* assume no err */
|
||||||
drv = uptr - dpc_dev.units; /* get drive no */
|
drv = uptr - dpc_dev.units; /* get drive no */
|
||||||
devc = dpc_dib.devno; /* get cch devno */
|
devc = dpc_dib.devno; /* get cch devno */
|
||||||
devd = dpd_dib.devno; /* get dch devno */
|
devd = dpd_dib.devno; /* get dch devno */
|
||||||
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
|
if (uptr->flags & UNIT_UNLOAD) { /* drive down? */
|
||||||
setFSR (devc); /* set cch flg */
|
setFSR (devc); /* set cch flg */
|
||||||
clrCMD (devc); /* clr cch cmd */
|
clrCMD (devc); /* clr cch cmd */
|
||||||
dpc_sta[drv] = 0; /* clr status */
|
dpc_sta[drv] = 0; /* clr status */
|
||||||
|
@ -760,18 +766,40 @@ return SCPE_OK;
|
||||||
|
|
||||||
t_stat dpc_attach (UNIT *uptr, char *cptr)
|
t_stat dpc_attach (UNIT *uptr, char *cptr)
|
||||||
{
|
{
|
||||||
int32 drv;
|
|
||||||
t_stat r;
|
t_stat r;
|
||||||
|
|
||||||
drv = uptr - dpc_dev.units; /* get drive no */
|
|
||||||
r = attach_unit (uptr, cptr); /* attach unit */
|
r = attach_unit (uptr, cptr); /* attach unit */
|
||||||
if (r != SCPE_OK) return r;
|
if (r == SCPE_OK) dpc_load_unload (uptr, 0, NULL, NULL);/* if OK, load heads */
|
||||||
dpc_sta[drv] = dpc_sta[drv] | STA_ATN | STA_1ST; /* update status */
|
return r;
|
||||||
if (dpc_poll) { /* polling enabled? */
|
}
|
||||||
|
|
||||||
|
/* Detach routine */
|
||||||
|
|
||||||
|
t_stat dpc_detach (UNIT* uptr)
|
||||||
|
{
|
||||||
|
dpc_load_unload (uptr, UNIT_UNLOAD, NULL, NULL); /* unload heads */
|
||||||
|
return detach_unit (uptr); /* detach unit */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load and unload heads */
|
||||||
|
|
||||||
|
t_stat dpc_load_unload (UNIT *uptr, int32 value, char *cptr, void *desc)
|
||||||
|
{
|
||||||
|
uint32 drv;
|
||||||
|
|
||||||
|
if ((uptr->flags & UNIT_ATT) == 0) return SCPE_UNATT; /* must be attached to load */
|
||||||
|
|
||||||
|
if (value == UNIT_UNLOAD) /* unload heads? */
|
||||||
|
uptr->flags = uptr->flags | UNIT_UNLOAD; /* indicate unload */
|
||||||
|
else { /* load heads */
|
||||||
|
uptr->flags = uptr->flags & ~UNIT_UNLOAD; /* indicate load */
|
||||||
|
drv = uptr - dpc_dev.units; /* get drive no */
|
||||||
|
dpc_sta[drv] = dpc_sta[drv] | STA_ATN | STA_1ST;/* update status */
|
||||||
|
if (dpc_poll) { /* polling enabled? */
|
||||||
dpc_dib.fbf = 1; /* set fbf */
|
dpc_dib.fbf = 1; /* set fbf */
|
||||||
dpc_dib.flg = 1; /* set flg */
|
dpc_dib.flg = 1; /* set flg */
|
||||||
dpc_dib.srq = 1; } /* srq follows flg */
|
dpc_dib.srq = 1; } } /* srq follows flg */
|
||||||
return r;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set controller type */
|
/* Set controller type */
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
dq 12565A 2883 disk system
|
dq 12565A 2883 disk system
|
||||||
|
|
||||||
|
01-Mar-05 JDB Added SET UNLOAD/LOAD
|
||||||
07-Oct-04 JDB Fixed enable/disable from either device
|
07-Oct-04 JDB Fixed enable/disable from either device
|
||||||
Shortened xtime from 5 to 3 (drive avg 156KW/second)
|
Shortened xtime from 5 to 3 (drive avg 156KW/second)
|
||||||
Fixed not ready/any error status
|
Fixed not ready/any error status
|
||||||
|
@ -71,7 +72,9 @@
|
||||||
#include "hp2100_defs.h"
|
#include "hp2100_defs.h"
|
||||||
|
|
||||||
#define UNIT_V_WLK (UNIT_V_UF + 0) /* write locked */
|
#define UNIT_V_WLK (UNIT_V_UF + 0) /* write locked */
|
||||||
|
#define UNIT_V_UNLOAD (UNIT_V_UF + 1) /* heads unloaded */
|
||||||
#define UNIT_WLK (1 << UNIT_V_WLK)
|
#define UNIT_WLK (1 << UNIT_V_WLK)
|
||||||
|
#define UNIT_UNLOAD (1 << UNIT_V_UNLOAD)
|
||||||
#define FNC u3 /* saved function */
|
#define FNC u3 /* saved function */
|
||||||
#define DRV u4 /* drive number (DC) */
|
#define DRV u4 /* drive number (DC) */
|
||||||
#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write prot */
|
#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write prot */
|
||||||
|
@ -166,6 +169,9 @@ int32 dqcio (int32 inst, int32 IR, int32 dat);
|
||||||
t_stat dqc_svc (UNIT *uptr);
|
t_stat dqc_svc (UNIT *uptr);
|
||||||
t_stat dqd_svc (UNIT *uptr);
|
t_stat dqd_svc (UNIT *uptr);
|
||||||
t_stat dqc_reset (DEVICE *dptr);
|
t_stat dqc_reset (DEVICE *dptr);
|
||||||
|
t_stat dqc_attach (UNIT *uptr, char *cptr);
|
||||||
|
t_stat dqc_detach (UNIT* uptr);
|
||||||
|
t_stat dqc_load_unload (UNIT *uptr, int32 value, char *cptr, void *desc);
|
||||||
t_stat dqc_boot (int32 unitno, DEVICE *dptr);
|
t_stat dqc_boot (int32 unitno, DEVICE *dptr);
|
||||||
void dq_god (int32 fnc, int32 drv, int32 time);
|
void dq_god (int32 fnc, int32 drv, int32 time);
|
||||||
void dq_goc (int32 fnc, int32 drv, int32 time);
|
void dq_goc (int32 fnc, int32 drv, int32 time);
|
||||||
|
@ -222,10 +228,10 @@ DEVICE dqd_dev = {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
UNIT dqc_unit[] = {
|
UNIT dqc_unit[] = {
|
||||||
{ UDATA (&dqc_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
{ UDATA (&dqc_svc, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||||
UNIT_ROABLE, DQ_SIZE) },
|
UNIT_DISABLE | UNIT_UNLOAD, DQ_SIZE) },
|
||||||
{ UDATA (&dqc_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
{ UDATA (&dqc_svc, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||||
UNIT_ROABLE, DQ_SIZE) } };
|
UNIT_DISABLE | UNIT_UNLOAD, DQ_SIZE) } };
|
||||||
|
|
||||||
REG dqc_reg[] = {
|
REG dqc_reg[] = {
|
||||||
{ ORDATA (OBUF, dqc_obuf, 16) },
|
{ ORDATA (OBUF, dqc_obuf, 16) },
|
||||||
|
@ -252,6 +258,8 @@ REG dqc_reg[] = {
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
MTAB dqc_mod[] = {
|
MTAB dqc_mod[] = {
|
||||||
|
{ UNIT_UNLOAD, UNIT_UNLOAD, "heads unloaded", "UNLOADED", dqc_load_unload },
|
||||||
|
{ UNIT_UNLOAD, 0, "heads loaded", "LOADED", dqc_load_unload },
|
||||||
{ UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL },
|
{ UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL },
|
||||||
{ UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL },
|
{ UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL },
|
||||||
{ MTAB_XTD | MTAB_VDV, 1, "DEVNO", "DEVNO",
|
{ MTAB_XTD | MTAB_VDV, 1, "DEVNO", "DEVNO",
|
||||||
|
@ -262,7 +270,7 @@ DEVICE dqc_dev = {
|
||||||
"DQC", dqc_unit, dqc_reg, dqc_mod,
|
"DQC", dqc_unit, dqc_reg, dqc_mod,
|
||||||
DQ_NUMDRV, 8, 24, 1, 8, 16,
|
DQ_NUMDRV, 8, 24, 1, 8, 16,
|
||||||
NULL, NULL, &dqc_reset,
|
NULL, NULL, &dqc_reset,
|
||||||
&dqc_boot, NULL, NULL,
|
&dqc_boot, &dqc_attach, &dqc_detach,
|
||||||
&dqc_dib, DEV_DISABLE };
|
&dqc_dib, DEV_DISABLE };
|
||||||
|
|
||||||
/* IOT routines */
|
/* IOT routines */
|
||||||
|
@ -472,7 +480,7 @@ case FNC_RCL: /* recalibrate */
|
||||||
|
|
||||||
case FNC_STA: /* read status */
|
case FNC_STA: /* read status */
|
||||||
if (CMD (devd)) { /* dch active? */
|
if (CMD (devd)) { /* dch active? */
|
||||||
if (dqc_unit[drv].flags & UNIT_ATT) /* attached? */
|
if ((dqc_unit[drv].flags & UNIT_UNLOAD) == 0) /* drive up? */
|
||||||
dqd_ibuf = dqc_sta[drv] & ~STA_DID;
|
dqd_ibuf = dqc_sta[drv] & ~STA_DID;
|
||||||
else dqd_ibuf = STA_NRDY;
|
else dqd_ibuf = STA_NRDY;
|
||||||
if (dqd_ibuf & STA_ANYERR) /* errors? set flg */
|
if (dqd_ibuf & STA_ANYERR) /* errors? set flg */
|
||||||
|
@ -527,7 +535,7 @@ err = 0; /* assume no err */
|
||||||
drv = uptr - dqc_dev.units; /* get drive no */
|
drv = uptr - dqc_dev.units; /* get drive no */
|
||||||
devc = dqc_dib.devno; /* get cch devno */
|
devc = dqc_dib.devno; /* get cch devno */
|
||||||
devd = dqd_dib.devno; /* get dch devno */
|
devd = dqd_dib.devno; /* get dch devno */
|
||||||
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
|
if (uptr->flags & UNIT_UNLOAD) { /* drive down? */
|
||||||
setFSR (devc); /* set cch flg */
|
setFSR (devc); /* set cch flg */
|
||||||
clrCMD (devc); /* clr cch cmd */
|
clrCMD (devc); /* clr cch cmd */
|
||||||
dqc_sta[drv] = 0; /* clr status */
|
dqc_sta[drv] = 0; /* clr status */
|
||||||
|
@ -671,11 +679,33 @@ for (drv = 0; drv < DQ_NUMDRV; drv++) { /* loop thru drives */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write lock/enable routine */
|
/* Attach routine */
|
||||||
|
|
||||||
t_stat dqc_vlock (UNIT *uptr, int32 val)
|
t_stat dqc_attach (UNIT *uptr, char *cptr)
|
||||||
{
|
{
|
||||||
if (uptr->flags & UNIT_ATT) return SCPE_ARG;
|
t_stat r;
|
||||||
|
|
||||||
|
r = attach_unit (uptr, cptr); /* attach unit */
|
||||||
|
if (r == SCPE_OK) dqc_load_unload (uptr, 0, NULL, NULL);/* if OK, load heads */
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Detach routine */
|
||||||
|
|
||||||
|
t_stat dqc_detach (UNIT* uptr)
|
||||||
|
{
|
||||||
|
dqc_load_unload (uptr, UNIT_UNLOAD, NULL, NULL); /* unload heads */
|
||||||
|
return detach_unit (uptr); /* detach unit */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load and unload heads */
|
||||||
|
|
||||||
|
t_stat dqc_load_unload (UNIT *uptr, int32 value, char *cptr, void *desc)
|
||||||
|
{
|
||||||
|
if ((uptr->flags & UNIT_ATT) == 0) return SCPE_UNATT; /* must be attached to load */
|
||||||
|
if (value == UNIT_UNLOAD) /* unload heads? */
|
||||||
|
uptr->flags = uptr->flags | UNIT_UNLOAD; /* indicate unload */
|
||||||
|
else uptr->flags = uptr->flags & ~UNIT_UNLOAD; /* indicate load */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp2100_ds.c: HP 2100 13037 disk controller simulator
|
/* hp2100_ds.c: HP 2100 13037 disk controller simulator
|
||||||
|
|
||||||
Copyright (c) 2004, Robert M. Supnik
|
Copyright (c) 2004-2005, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -25,6 +25,9 @@
|
||||||
|
|
||||||
ds 13037 disk controller
|
ds 13037 disk controller
|
||||||
|
|
||||||
|
18-Mar-05 RMS Added attached test to detach routine
|
||||||
|
01-Mar-05 JDB Added SET UNLOAD/LOAD
|
||||||
|
|
||||||
States of the controller: the controller uP runs all the time, but most of
|
States of the controller: the controller uP runs all the time, but most of
|
||||||
the time it is waiting for an event. The simulator only 'runs' the controller
|
the time it is waiting for an event. The simulator only 'runs' the controller
|
||||||
when there's an event to process: change in CPU interface state, change in
|
when there's an event to process: change in CPU interface state, change in
|
||||||
|
@ -77,14 +80,16 @@
|
||||||
/* Flags in the unit flags word */
|
/* Flags in the unit flags word */
|
||||||
|
|
||||||
#define UNIT_V_WLK (UNIT_V_UF + 0) /* write locked */
|
#define UNIT_V_WLK (UNIT_V_UF + 0) /* write locked */
|
||||||
#define UNIT_V_FMT (UNIT_V_UF + 1) /* format enabled */
|
#define UNIT_V_UNLOAD (UNIT_V_UF + 1) /* heads unloaded */
|
||||||
#define UNIT_V_DTYPE (UNIT_V_UF + 2) /* disk type */
|
#define UNIT_V_DTYPE (UNIT_V_UF + 2) /* disk type */
|
||||||
#define UNIT_M_DTYPE 3
|
#define UNIT_M_DTYPE 3
|
||||||
#define UNIT_V_AUTO (UNIT_V_UF + 4) /* autosize */
|
#define UNIT_V_AUTO (UNIT_V_UF + 4) /* autosize */
|
||||||
|
#define UNIT_V_FMT (UNIT_V_UF + 5) /* format enabled */
|
||||||
#define UNIT_WLK (1 << UNIT_V_WLK)
|
#define UNIT_WLK (1 << UNIT_V_WLK)
|
||||||
#define UNIT_FMT (1 << UNIT_V_FMT)
|
#define UNIT_FMT (1 << UNIT_V_FMT)
|
||||||
#define UNIT_DTYPE (UNIT_M_DTYPE << UNIT_V_DTYPE)
|
#define UNIT_DTYPE (UNIT_M_DTYPE << UNIT_V_DTYPE)
|
||||||
#define UNIT_AUTO (1 << UNIT_V_AUTO)
|
#define UNIT_AUTO (1 << UNIT_V_AUTO)
|
||||||
|
#define UNIT_UNLOAD (1 << UNIT_V_UNLOAD)
|
||||||
#define GET_DTYPE(x) (((x) >> UNIT_V_DTYPE) & UNIT_M_DTYPE)
|
#define GET_DTYPE(x) (((x) >> UNIT_V_DTYPE) & UNIT_M_DTYPE)
|
||||||
#define UNIT_WPR (UNIT_WLK | UNIT_RO) /* write prot */
|
#define UNIT_WPR (UNIT_WLK | UNIT_RO) /* write prot */
|
||||||
|
|
||||||
|
@ -406,6 +411,7 @@ t_stat ds_reset (DEVICE *dptr);
|
||||||
t_stat ds_attach (UNIT *uptr, char *cptr);
|
t_stat ds_attach (UNIT *uptr, char *cptr);
|
||||||
t_stat ds_detach (UNIT *uptr);
|
t_stat ds_detach (UNIT *uptr);
|
||||||
t_stat ds_boot (int32 unitno, DEVICE *dptr);
|
t_stat ds_boot (int32 unitno, DEVICE *dptr);
|
||||||
|
t_stat ds_load_unload (UNIT *uptr, int32 value, char *cptr, void *desc);
|
||||||
t_stat ds_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
|
t_stat ds_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||||
void ds_poll (void);
|
void ds_poll (void);
|
||||||
void ds_docmd (uint32 cmd);
|
void ds_docmd (uint32 cmd);
|
||||||
|
@ -443,22 +449,22 @@ void ds_fifo_reset (void);
|
||||||
DIB ds_dib = { DS, 0, 0, 0, 0, 0, &dsio };
|
DIB ds_dib = { DS, 0, 0, 0, 0, 0, &dsio };
|
||||||
|
|
||||||
UNIT ds_unit[] = {
|
UNIT ds_unit[] = {
|
||||||
{ UDATA (&ds_svc_u, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
{ UDATA (&ds_svc_u, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||||
UNIT_ROABLE, D7905_SIZE) },
|
UNIT_DISABLE | UNIT_UNLOAD, D7905_SIZE) },
|
||||||
{ UDATA (&ds_svc_u, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
{ UDATA (&ds_svc_u, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||||
UNIT_ROABLE, D7905_SIZE) },
|
UNIT_DISABLE | UNIT_UNLOAD, D7905_SIZE) },
|
||||||
{ UDATA (&ds_svc_u, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
{ UDATA (&ds_svc_u, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||||
UNIT_ROABLE, D7905_SIZE) },
|
UNIT_DISABLE | UNIT_UNLOAD, D7905_SIZE) },
|
||||||
{ UDATA (&ds_svc_u, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
{ UDATA (&ds_svc_u, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||||
UNIT_ROABLE, D7905_SIZE) },
|
UNIT_DISABLE | UNIT_UNLOAD, D7905_SIZE) },
|
||||||
{ UDATA (&ds_svc_u, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
{ UDATA (&ds_svc_u, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||||
UNIT_ROABLE, D7905_SIZE) },
|
UNIT_DISABLE | UNIT_UNLOAD, D7905_SIZE) },
|
||||||
{ UDATA (&ds_svc_u, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
{ UDATA (&ds_svc_u, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||||
UNIT_ROABLE, D7905_SIZE) },
|
UNIT_DISABLE | UNIT_UNLOAD, D7905_SIZE) },
|
||||||
{ UDATA (&ds_svc_u, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
{ UDATA (&ds_svc_u, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||||
UNIT_ROABLE, D7905_SIZE) },
|
UNIT_DISABLE | UNIT_UNLOAD, D7905_SIZE) },
|
||||||
{ UDATA (&ds_svc_u, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
{ UDATA (&ds_svc_u, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||||
UNIT_ROABLE, D7905_SIZE) },
|
UNIT_DISABLE | UNIT_UNLOAD, D7905_SIZE) },
|
||||||
{ UDATA (&ds_svc_c, UNIT_DIS, 0) },
|
{ UDATA (&ds_svc_c, UNIT_DIS, 0) },
|
||||||
{ UDATA (&ds_svc_t, UNIT_DIS, 0) } };
|
{ UDATA (&ds_svc_t, UNIT_DIS, 0) } };
|
||||||
|
|
||||||
|
@ -504,6 +510,8 @@ REG ds_reg[] = {
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
MTAB ds_mod[] = {
|
MTAB ds_mod[] = {
|
||||||
|
{ UNIT_UNLOAD, UNIT_UNLOAD, "heads unloaded", "UNLOADED", ds_load_unload },
|
||||||
|
{ UNIT_UNLOAD, 0, "heads loaded", "LOADED", ds_load_unload },
|
||||||
{ UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL },
|
{ UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL },
|
||||||
{ UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL },
|
{ UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL },
|
||||||
{ UNIT_FMT, 0, "format disabled", "NOFORMAT", NULL },
|
{ UNIT_FMT, 0, "format disabled", "NOFORMAT", NULL },
|
||||||
|
@ -850,7 +858,7 @@ switch (op) { /* case on function */
|
||||||
/* Seek and recalibrate */
|
/* Seek and recalibrate */
|
||||||
|
|
||||||
case DSC_RECAL: /* recalibrate */
|
case DSC_RECAL: /* recalibrate */
|
||||||
if (uptr->flags & UNIT_ATT) { /* attached? */
|
if ((uptr->flags & UNIT_UNLOAD) == 0) { /* drive up? */
|
||||||
ds_start_seek (uptr, 0, DSC_RECAL|DSC_2ND); /* set up seek */
|
ds_start_seek (uptr, 0, DSC_RECAL|DSC_2ND); /* set up seek */
|
||||||
ds_set_idle (); /* ctrl is idle */
|
ds_set_idle (); /* ctrl is idle */
|
||||||
}
|
}
|
||||||
|
@ -873,7 +881,7 @@ case DSC_SEEK | DSC_2ND: /* waiting for word 1 */
|
||||||
case DSC_SEEK | DSC_3RD: /* waiting for word 2 */
|
case DSC_SEEK | DSC_3RD: /* waiting for word 2 */
|
||||||
if (!DS_FIFO_EMPTY) { /* OTA ds? */
|
if (!DS_FIFO_EMPTY) { /* OTA ds? */
|
||||||
ds_hs = ds_fifo_read (); /* save head/sector */
|
ds_hs = ds_fifo_read (); /* save head/sector */
|
||||||
if (uptr->flags & UNIT_ATT) { /* attached? */
|
if ((uptr->flags & UNIT_UNLOAD) == 0) { /* drive up? */
|
||||||
ds_start_seek (uptr, ds_cyl, DSC_SEEK|DSC_4TH); /* set up seek */
|
ds_start_seek (uptr, ds_cyl, DSC_SEEK|DSC_4TH); /* set up seek */
|
||||||
ds_set_idle (); /* ctrl is idle */
|
ds_set_idle (); /* ctrl is idle */
|
||||||
}
|
}
|
||||||
|
@ -900,7 +908,7 @@ case DSC_ROFF | DSC_2ND: /* poll done */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DSC_COLD: /* cold load read */
|
case DSC_COLD: /* cold load read */
|
||||||
if (uptr->flags & UNIT_ATT) /* attached? */
|
if ((uptr->flags & UNIT_UNLOAD) == 0) /* drive up? */
|
||||||
ds_start_seek (uptr, 0, DSC_READ); /* set up seek */
|
ds_start_seek (uptr, 0, DSC_READ); /* set up seek */
|
||||||
else ds_cmd_done (1, DS1_S2ERR); /* no, not ready error */
|
else ds_cmd_done (1, DS1_S2ERR); /* no, not ready error */
|
||||||
break;
|
break;
|
||||||
|
@ -1065,7 +1073,7 @@ sta = drv_tab[dtyp].id | /* form status */
|
||||||
uptr->STA | /* static bits */
|
uptr->STA | /* static bits */
|
||||||
((uptr->flags & UNIT_WPR)? DS2_RO: 0) | /* dynamic bits */
|
((uptr->flags & UNIT_WPR)? DS2_RO: 0) | /* dynamic bits */
|
||||||
((uptr->flags & UNIT_FMT)? DS2_FRM: 0) |
|
((uptr->flags & UNIT_FMT)? DS2_FRM: 0) |
|
||||||
((uptr->flags & UNIT_ATT)? 0: DS2_NR | DS2_BS) |
|
((uptr->flags & UNIT_UNLOAD)? DS2_NR | DS2_BS: 0) |
|
||||||
(sim_is_active (uptr)? DS2_BS: 0);
|
(sim_is_active (uptr)? DS2_BS: 0);
|
||||||
if (sta & DS2_ALLERR) sta = sta | DS2_ERR; /* set error */
|
if (sta & DS2_ALLERR) sta = sta | DS2_ERR; /* set error */
|
||||||
return sta;
|
return sta;
|
||||||
|
@ -1133,7 +1141,7 @@ uint32 dtyp = GET_DTYPE (uptr->flags);
|
||||||
|
|
||||||
ds_eod = 0; /* init eod */
|
ds_eod = 0; /* init eod */
|
||||||
ds_ptr = 0; /* init buffer ptr */
|
ds_ptr = 0; /* init buffer ptr */
|
||||||
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
|
if (uptr->flags & UNIT_UNLOAD) { /* drive down? */
|
||||||
ds_cmd_done (1, DS1_S2ERR);
|
ds_cmd_done (1, DS1_S2ERR);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1410,7 +1418,7 @@ t_stat r;
|
||||||
uptr->capac = drv_tab[GET_DTYPE (uptr->flags)].size;
|
uptr->capac = drv_tab[GET_DTYPE (uptr->flags)].size;
|
||||||
r = attach_unit (uptr, cptr); /* attach unit */
|
r = attach_unit (uptr, cptr); /* attach unit */
|
||||||
if (r != SCPE_OK) return r; /* error? */
|
if (r != SCPE_OK) return r; /* error? */
|
||||||
uptr->STA = DS2_ATN | DS2_FS; /* update drive status */
|
ds_load_unload (uptr, 0, NULL, NULL); /* if OK, load heads */
|
||||||
ds_sched_atn (uptr); /* schedule attention */
|
ds_sched_atn (uptr); /* schedule attention */
|
||||||
if (((uptr->flags & UNIT_AUTO) == 0) || /* static size? */
|
if (((uptr->flags & UNIT_AUTO) == 0) || /* static size? */
|
||||||
((p = sim_fsize (uptr->fileref)) == 0)) return SCPE_OK; /* new file? */
|
((p = sim_fsize (uptr->fileref)) == 0)) return SCPE_OK; /* new file? */
|
||||||
|
@ -1428,11 +1436,26 @@ return SCPE_OK;
|
||||||
|
|
||||||
t_stat ds_detach (UNIT *uptr)
|
t_stat ds_detach (UNIT *uptr)
|
||||||
{
|
{
|
||||||
uptr->STA = DS2_ATN; /* update drive status */
|
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; /* attached? */
|
||||||
ds_sched_atn (uptr); /* schedule attention */
|
ds_load_unload (uptr, UNIT_UNLOAD, NULL, NULL); /* unload heads */
|
||||||
return detach_unit (uptr);
|
return detach_unit (uptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Load and unload heads */
|
||||||
|
|
||||||
|
t_stat ds_load_unload (UNIT *uptr, int32 value, char *cptr, void *desc)
|
||||||
|
{
|
||||||
|
if ((uptr->flags & UNIT_ATT) == 0) return SCPE_UNATT; /* must be attached to [un]load */
|
||||||
|
if (value == UNIT_UNLOAD) { /* unload heads? */
|
||||||
|
uptr->flags = uptr->flags | UNIT_UNLOAD; /* indicate unload */
|
||||||
|
uptr->STA = DS2_ATN; /* update drive status */
|
||||||
|
ds_sched_atn (uptr); } /* schedule attention */
|
||||||
|
else { /* load heads */
|
||||||
|
uptr->flags = uptr->flags & ~UNIT_UNLOAD; /* indicate load */
|
||||||
|
uptr->STA = DS2_ATN | DS2_FS; } /* update drive status */
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/* Schedule attention interrupt if CTL set, not restore, and controller idle */
|
/* Schedule attention interrupt if CTL set, not restore, and controller idle */
|
||||||
|
|
||||||
void ds_sched_atn (UNIT *uptr)
|
void ds_sched_atn (UNIT *uptr)
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
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.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
25-Feb-05 JDB Added FFP helpers f_pack, f_unpack, f_pwr2
|
||||||
11-Feb-05 JDB Fixed missing negative overflow renorm in StoreFP
|
11-Feb-05 JDB Fixed missing negative overflow renorm in StoreFP
|
||||||
26-Dec-04 RMS Separated A/B from M[0/1] for DMA IO (from Dave Bryan)
|
26-Dec-04 RMS Separated A/B from M[0/1] for DMA IO (from Dave Bryan)
|
||||||
15-Jul-03 RMS Fixed signed/unsigned warning
|
15-Jul-03 RMS Fixed signed/unsigned warning
|
||||||
|
@ -105,6 +106,7 @@ struct ufp { /* unpacked fp */
|
||||||
#define FR_NEG(v) ((~(v) + 1) & DMASK32)
|
#define FR_NEG(v) ((~(v) + 1) & DMASK32)
|
||||||
|
|
||||||
extern uint16 ABREG[2];
|
extern uint16 ABREG[2];
|
||||||
|
|
||||||
uint32 UnpackFP (struct ufp *fop, uint32 opnd);
|
uint32 UnpackFP (struct ufp *fop, uint32 opnd);
|
||||||
void NegFP (struct ufp *fop);
|
void NegFP (struct ufp *fop);
|
||||||
void NormFP (struct ufp *fop);
|
void NormFP (struct ufp *fop);
|
||||||
|
@ -260,6 +262,46 @@ if (fop1.fr) { /* dvd != 0? */
|
||||||
return StoreFP (&quo); /* store result */
|
return StoreFP (&quo); /* store result */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fast FORTRAN Processor helpers. */
|
||||||
|
|
||||||
|
/* Pack mantissa in A/B and exponent and return fp in A/B */
|
||||||
|
|
||||||
|
uint32 f_pack (int32 expon)
|
||||||
|
{
|
||||||
|
struct ufp fop;
|
||||||
|
|
||||||
|
fop.fr = FPAB;
|
||||||
|
fop.exp = expon;
|
||||||
|
return StoreFP (&fop);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unpack fp number in A/B into A (exponent) and B (lower mantissa) */
|
||||||
|
|
||||||
|
void f_unpack (void)
|
||||||
|
{
|
||||||
|
AR = FP_GETEXP (BR); /* get exponent */
|
||||||
|
if (FP_GETEXPS (BR)) AR = (AR | ~FP_M_EXP) & DMASK; /* < 0? sext */
|
||||||
|
BR = BR & (uint16) ~(FP_EXP | FP_EXPS); /* clear exp */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Multiply fp number in A/B by 2**n and return in A/B.
|
||||||
|
Exponent overflow or underflow wraps around. */
|
||||||
|
|
||||||
|
void f_pwr2 (int32 n)
|
||||||
|
{
|
||||||
|
uint32 save_a;
|
||||||
|
|
||||||
|
if (AR | BR) { /* microcode test */
|
||||||
|
save_a = AR;
|
||||||
|
f_unpack (); /* unpack exponent */
|
||||||
|
AR = AR + n; /* multiply */
|
||||||
|
BR = BR | ((AR & FP_M_EXP) << FP_V_EXP) | /* merge exponent */
|
||||||
|
((AR & SIGN)? (1 << FP_V_EXPS): 0); /* and exponent sign */
|
||||||
|
AR = save_a; }
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Utility routines */
|
/* Utility routines */
|
||||||
|
|
||||||
/* Unpack operand */
|
/* Unpack operand */
|
||||||
|
|
508
HP2100/hp2100_fp1.c
Normal file
508
HP2100/hp2100_fp1.c
Normal file
|
@ -0,0 +1,508 @@
|
||||||
|
/* hp2100_fp1.c: HP 2100/21MX extended-precision floating point routines
|
||||||
|
|
||||||
|
Copyright (c) 2005, J. David Bryan
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
Except as contained in this notice, the name of the author shall not
|
||||||
|
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
|
in this Software without prior written authorization from the author.
|
||||||
|
|
||||||
|
Primary references:
|
||||||
|
- HP 1000 M/E/F-Series Computers Technical Reference Handbook
|
||||||
|
(5955-0282, Mar-1980)
|
||||||
|
- DOS/RTE Relocatable Library Reference Manual
|
||||||
|
(24998-90001, Oct-1981)
|
||||||
|
|
||||||
|
The extended-precision floating-point format is a 48-bit extension of the
|
||||||
|
32-bit format used for single precision. A packed "XP" number consists of a
|
||||||
|
40-bit twos-complement mantissa and an 8-bit twos-complement exponent. The
|
||||||
|
exponent is rotated left so that the sign is in the LSB. Pictorially, an XP
|
||||||
|
number appears in memory as follows:
|
||||||
|
|
||||||
|
15 14 0
|
||||||
|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||||
|
|S | mantissa high | : M
|
||||||
|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||||
|
| mantissa middle | : M + 1
|
||||||
|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||||
|
| mantissa low | exponent |XS| : M + 2
|
||||||
|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||||
|
15 8 7 1 0
|
||||||
|
|
||||||
|
In a normalized value, the sign and MSB of the mantissa differ. Zero is
|
||||||
|
represented by all three words = 0.
|
||||||
|
|
||||||
|
Internally, an unpacked XP number is contained in a structure having a signed
|
||||||
|
64-bit mantissa and a signed 32-bit exponent. The mantissa is masked to 48
|
||||||
|
bits and left-justified, while the exponent is right-justified.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "hp2100_defs.h"
|
||||||
|
#include "hp2100_cpu.h"
|
||||||
|
#include "hp2100_fp1.h"
|
||||||
|
|
||||||
|
#if defined (HAVE_INT64) /* we need int64 support */
|
||||||
|
|
||||||
|
/* packed starting bit numbers */
|
||||||
|
|
||||||
|
#define XP_PAD 16 /* padding LSBs */
|
||||||
|
|
||||||
|
#define XP_V_MSIGN (47 + XP_PAD) /* mantissa sign */
|
||||||
|
#define XP_V_MANT ( 8 + XP_PAD) /* mantissa */
|
||||||
|
#define XP_V_EXP ( 1 + XP_PAD) /* exponent */
|
||||||
|
#define XP_V_ESIGN ( 0 + XP_PAD) /* exponent sign */
|
||||||
|
|
||||||
|
/* packed bit widths */
|
||||||
|
|
||||||
|
#define XP_W_MSIGN 1 /* mantissa sign */
|
||||||
|
#define XP_W_MANT 39 /* mantissa */
|
||||||
|
#define XP_W_EXP 7 /* exponent */
|
||||||
|
#define XP_W_ESIGN 1 /* exponent sign */
|
||||||
|
|
||||||
|
/* packed bit masks */
|
||||||
|
|
||||||
|
#define XP_M_MSIGN (((t_uint64) 1 << XP_W_MSIGN) - 1) /* mantissa sign */
|
||||||
|
#define XP_M_MANT (((t_uint64) 1 << XP_W_MANT) - 1) /* mantissa */
|
||||||
|
#define XP_M_EXP (((t_uint64) 1 << XP_W_EXP) - 1) /* exponent */
|
||||||
|
#define XP_M_ESIGN (((t_uint64) 1 << XP_W_ESIGN) - 1) /* exponent sign */
|
||||||
|
|
||||||
|
/* packed field masks */
|
||||||
|
|
||||||
|
#define XP_MSIGN (XP_M_MSIGN << XP_V_MSIGN) /* mantissa sign */
|
||||||
|
#define XP_MANT (XP_M_MANT << XP_V_MANT) /* mantissa */
|
||||||
|
#define XP_SMANT (XP_MSIGN | XP_MANT) /* signed mantissa */
|
||||||
|
|
||||||
|
/* unpacked starting bit numbers */
|
||||||
|
|
||||||
|
#define XP_V_UMANT (0 + XP_PAD) /* signed mantissa */
|
||||||
|
|
||||||
|
/* unpacked bit widths */
|
||||||
|
|
||||||
|
#define XP_W_USMANT 48 /* signed mantissa */
|
||||||
|
|
||||||
|
/* unpacked bit masks */
|
||||||
|
|
||||||
|
#define XP_M_USMANT (((t_uint64) 1 << XP_W_USMANT) - 1) /* mantissa */
|
||||||
|
|
||||||
|
/* unpacked field masks */
|
||||||
|
|
||||||
|
#define XP_USMANT (XP_M_USMANT << XP_V_UMANT) /* signed mantissa */
|
||||||
|
|
||||||
|
/* values */
|
||||||
|
|
||||||
|
#define XP_ONEHALF ((t_int64) 1 << (XP_V_MSIGN - 1)) /* mantissa = 0.5 */
|
||||||
|
#define XP_HALSBPOS ((t_int64) 1 << (XP_V_MANT - 1)) /* + 1/2 LSB */
|
||||||
|
#define XP_HALSBNEG ((t_int64) XP_HALSBPOS - 1) /* - 1/2 LSB */
|
||||||
|
#define XP_MAXPOS ((t_int64) XP_MANT) /* maximum pos mantissa */
|
||||||
|
#define XP_MAXNEG ((t_int64) XP_MSIGN) /* maximum neg mantissa */
|
||||||
|
#define XP_MAXEXP ((t_int64) XP_M_EXP) /* maximum pos exponent */
|
||||||
|
|
||||||
|
/* helpers */
|
||||||
|
|
||||||
|
#define DENORM(x) ((((x) ^ (x) << 1) & XP_MSIGN) == 0)
|
||||||
|
|
||||||
|
#define TO_INT64(xpn) ((t_int64) ((t_uint64) (xpn).high << 32 | (xpn).low))
|
||||||
|
|
||||||
|
/* internal unpacked extended-precision representation */
|
||||||
|
|
||||||
|
typedef struct { t_int64 mantissa;
|
||||||
|
int32 exponent; } XPU;
|
||||||
|
|
||||||
|
/* Private routines */
|
||||||
|
|
||||||
|
|
||||||
|
/* Pack an unpacked mantissa and exponent */
|
||||||
|
|
||||||
|
static XPN to_xpn (t_uint64 m, int32 e)
|
||||||
|
{
|
||||||
|
XPN packed;
|
||||||
|
|
||||||
|
packed.high = (uint32) (m >> 32);
|
||||||
|
packed.low = (uint32) (m | ((e & XP_M_EXP) << XP_V_EXP) | ((e < 0) << XP_V_ESIGN));
|
||||||
|
return packed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Unpack a packed number */
|
||||||
|
|
||||||
|
static XPU unpack (XPN packed)
|
||||||
|
{
|
||||||
|
XPU unpacked;
|
||||||
|
|
||||||
|
unpacked.mantissa = TO_INT64 (packed) & XP_SMANT; /* left-justify mantissa */
|
||||||
|
unpacked.exponent = (int8) ((packed.low >> XP_V_EXP & XP_M_EXP) | /* sign-extend exponent */
|
||||||
|
packed.low >> (XP_V_ESIGN - XP_W_EXP));
|
||||||
|
|
||||||
|
return unpacked;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Normalize an unpacked number */
|
||||||
|
|
||||||
|
static void normalize (XPU *unpacked)
|
||||||
|
{
|
||||||
|
if (unpacked->mantissa) { /* non-zero? */
|
||||||
|
while (DENORM (unpacked->mantissa)) { /* normal form? */
|
||||||
|
unpacked->exponent = unpacked->exponent - 1; /* no, so shift */
|
||||||
|
unpacked->mantissa = unpacked->mantissa << 1; } }
|
||||||
|
else unpacked->exponent = 0; /* clean for zero */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Round and pack an unpacked number */
|
||||||
|
|
||||||
|
static uint32 pack (XPN *packed, XPU unpacked)
|
||||||
|
{
|
||||||
|
int32 sign, overflow = 0;
|
||||||
|
|
||||||
|
normalize (&unpacked); /* normalize */
|
||||||
|
sign = (unpacked.mantissa < 0); /* save sign */
|
||||||
|
unpacked.mantissa = (unpacked.mantissa + /* round the number */
|
||||||
|
(sign? XP_HALSBNEG: XP_HALSBPOS)) & XP_SMANT; /* mask off rounding bits */
|
||||||
|
if (sign != (unpacked.mantissa < 0)) { /* pos overflow? */
|
||||||
|
unpacked.mantissa = /* renormalize */
|
||||||
|
(t_uint64) unpacked.mantissa >> 1 & XP_SMANT; /* and remask */
|
||||||
|
unpacked.exponent = unpacked.exponent + 1; }
|
||||||
|
else normalize (&unpacked); /* neg overflow? renorm */
|
||||||
|
unpacked.mantissa = unpacked.mantissa & XP_SMANT;
|
||||||
|
if (unpacked.mantissa == 0) /* result 0? */
|
||||||
|
packed->high = packed->low = 0; /* return 0 */
|
||||||
|
else if (unpacked.exponent < -(XP_MAXEXP + 1)) { /* underflow? */
|
||||||
|
packed->high = packed->low = 0; /* return 0 */
|
||||||
|
overflow = 1; } /* and set overflow */
|
||||||
|
else if (unpacked.exponent > XP_MAXEXP) { /* overflow? */
|
||||||
|
if (sign) *packed = to_xpn (XP_MAXNEG, XP_MAXEXP); /* return neg infinity */
|
||||||
|
else *packed = to_xpn (XP_MAXPOS, XP_MAXEXP); /* or pos infinity */
|
||||||
|
overflow = 1; } /* with overflow */
|
||||||
|
else *packed = to_xpn (unpacked.mantissa, unpacked.exponent);
|
||||||
|
return overflow;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Complement an unpacked number */
|
||||||
|
|
||||||
|
static void complement (XPU *result)
|
||||||
|
{
|
||||||
|
result->mantissa = -result->mantissa; /* negate mantissa */
|
||||||
|
if (result->mantissa == XP_MAXNEG) { /* maximum negative? */
|
||||||
|
result->mantissa = (t_uint64) result->mantissa >> 1; /* renormalize to pos */
|
||||||
|
result->exponent = result->exponent + 1; } /* correct exponent */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Add two unpacked numbers
|
||||||
|
|
||||||
|
The mantissas are first aligned (if necessary) by scaling the smaller of the
|
||||||
|
two operands. If the magnitude of the difference between the exponents is
|
||||||
|
greater than the number of significant bits, then the smaller number has been
|
||||||
|
scaled to zero, and so the sum is simply the larger operand. Otherwise, the
|
||||||
|
sum is computed and checked for overflow, which has occured if the signs of
|
||||||
|
the operands are the same but differ from that of the result. Scaling and
|
||||||
|
renormalization is perfomed if overflow occurred. */
|
||||||
|
|
||||||
|
static void add (XPU *sum, XPU augend, XPU addend)
|
||||||
|
{
|
||||||
|
int32 magn;
|
||||||
|
|
||||||
|
if (augend.mantissa == 0) *sum = addend; /* x + 0 = x */
|
||||||
|
else if (addend.mantissa == 0) *sum = augend; /* 0 + x = x */
|
||||||
|
else {
|
||||||
|
magn = augend.exponent - addend.exponent; /* difference exponents */
|
||||||
|
if (magn > 0) { /* addend smaller? */
|
||||||
|
*sum = augend; /* preset augend */
|
||||||
|
addend.mantissa = addend.mantissa >> magn; } /* align addend */
|
||||||
|
else { /* augend smaller? */
|
||||||
|
*sum = addend; /* preset addend */
|
||||||
|
magn = -magn; /* make difference positive */
|
||||||
|
augend.mantissa = augend.mantissa >> magn; } /* align augend */
|
||||||
|
if (magn <= XP_W_MANT + 1) { /* check mangitude */
|
||||||
|
sum->mantissa = addend.mantissa + augend.mantissa; /* add mantissas */
|
||||||
|
if (((addend.mantissa < 0) == (augend.mantissa < 0)) && /* chk overflow */
|
||||||
|
((addend.mantissa < 0) != (sum->mantissa < 0))) {
|
||||||
|
sum->mantissa = (addend.mantissa & XP_MSIGN) | /* restore sign */
|
||||||
|
(t_uint64) sum->mantissa >> 1; /* renormalize */
|
||||||
|
sum->exponent = sum->exponent + 1; } } } /* adjust exponent */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Multiply two unpacked numbers
|
||||||
|
|
||||||
|
The firmware first negates the operands as necessary so that the values are
|
||||||
|
positive. Then it performs six of the nine 16-bit x 16-bit = 32-bit unsigned
|
||||||
|
multiplications required for a full 96-bit product. Given a 48-bit
|
||||||
|
multiplicand "a1a2a3" and a 48-bit multiplier "b1b2b3", the firmware performs
|
||||||
|
these calculations to develop a 48-bit product:
|
||||||
|
|
||||||
|
a1 a2 a3
|
||||||
|
+-------+-------+-------+
|
||||||
|
b1 b2 b3
|
||||||
|
+-------+-------+-------+
|
||||||
|
_________________________
|
||||||
|
|
||||||
|
a1 * b3 [m1]
|
||||||
|
+-------+-------+
|
||||||
|
a2 * b2 [m2]
|
||||||
|
+-------+-------+
|
||||||
|
a1 * b2 [m3]
|
||||||
|
+-------+-------+
|
||||||
|
a3 * b1 [m4]
|
||||||
|
+-------+-------+
|
||||||
|
a2 * b1 [m5]
|
||||||
|
+-------+-------+
|
||||||
|
a1 * b1 [m6]
|
||||||
|
+-------+-------+
|
||||||
|
_________________________________
|
||||||
|
|
||||||
|
product
|
||||||
|
+-------+-------+-------+
|
||||||
|
|
||||||
|
The least-significant words of intermediate multiplications [m1], [m2], and
|
||||||
|
[m4] are used only to develop a carry bit into the 48-bit sum. The product
|
||||||
|
is complemented if necessary to restore the sign.
|
||||||
|
|
||||||
|
Instead of implementing this algorithm directly, it is more efficient under
|
||||||
|
simulation to use 32 x 32 = 64-bit multiplications, thereby reducing the
|
||||||
|
number required from six to four. */
|
||||||
|
|
||||||
|
static void multiply (XPU *product, XPU multiplicand, XPU multiplier)
|
||||||
|
{
|
||||||
|
uint32 ah, al, bh, bl, carry, sign = 0;
|
||||||
|
t_uint64 hi, m1, m2, m3;
|
||||||
|
|
||||||
|
if ((multiplicand.mantissa == 0) || (multiplier.mantissa == 0)) /* x * 0 = 0 */
|
||||||
|
product->mantissa = product->exponent = 0;
|
||||||
|
else {
|
||||||
|
if (multiplicand.mantissa < 0) { /* negative? */
|
||||||
|
complement (&multiplicand); /* complement operand */
|
||||||
|
sign = ~sign; } /* track sign */
|
||||||
|
if (multiplier.mantissa < 0) { /* negative? */
|
||||||
|
complement (&multiplier); /* complement operand */
|
||||||
|
sign = ~sign; } /* track sign */
|
||||||
|
|
||||||
|
product->exponent = multiplicand.exponent + /* compute exponent */
|
||||||
|
multiplier.exponent + 1;
|
||||||
|
|
||||||
|
ah = (uint32) (multiplicand.mantissa >> 32); /* split multiplicand */
|
||||||
|
al = (uint32) multiplicand.mantissa; /* into high and low parts */
|
||||||
|
bh = (uint32) (multiplier.mantissa >> 32); /* split multiplier */
|
||||||
|
bl = (uint32) multiplier.mantissa; /* into high and low parts */
|
||||||
|
|
||||||
|
hi = ((t_uint64) ah * bh); /* form four cross products */
|
||||||
|
m1 = ((t_uint64) ah * bl); /* using 32 x 32 = 64-bit */
|
||||||
|
m2 = ((t_uint64) al * bh); /* hardware multiplies */
|
||||||
|
m3 = ((t_uint64) al * bl);
|
||||||
|
|
||||||
|
carry = ((uint32) m1 + (uint32) m2 + /* form a carry bit */
|
||||||
|
(uint32) (m3 >> 32)) >> (31 - XP_V_UMANT); /* and align to LSB - 1 */
|
||||||
|
|
||||||
|
product->mantissa = (hi + (m1 >> 32) + /* align, sum, and mask */
|
||||||
|
(m2 >> 32) + carry) & XP_USMANT;
|
||||||
|
if (sign) complement (product); } /* negate if required */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Divide two unpacked numbers
|
||||||
|
|
||||||
|
The firmware performs division by calculating (1.0 / divisor) and then
|
||||||
|
multiplying by the dividend. The simulator uses 64-bit division and uses a
|
||||||
|
"divide-and-correct" algorithm similar to the one employed by the base set
|
||||||
|
single-precision floating-point division routine. */
|
||||||
|
|
||||||
|
static void divide (XPU *quotient, XPU dividend, XPU divisor)
|
||||||
|
{
|
||||||
|
t_int64 bh, bl, m1, m2, m3, m4;
|
||||||
|
|
||||||
|
if (divisor.mantissa == 0) { /* division by zero? */
|
||||||
|
if (dividend.mantissa < 0)
|
||||||
|
quotient->mantissa = XP_MSIGN; /* return minus infinity */
|
||||||
|
else quotient->mantissa = XP_MANT; /* or plus infinity */
|
||||||
|
quotient->exponent = XP_MAXEXP + 1; }
|
||||||
|
else if (dividend.mantissa == 0) /* dividend zero? */
|
||||||
|
quotient->mantissa = quotient->exponent = 0; /* yes; result is zero */
|
||||||
|
else {
|
||||||
|
quotient->exponent = dividend.exponent - /* division subtracts exponents */
|
||||||
|
divisor.exponent + 1;
|
||||||
|
|
||||||
|
bh = divisor.mantissa >> 32; /* split divisor */
|
||||||
|
bl = divisor.mantissa & 0xFFFFFFFF;
|
||||||
|
|
||||||
|
m1 = (dividend.mantissa >> 2) / bh; /* form 1st partial quotient */
|
||||||
|
m2 = (dividend.mantissa >> 2) % bh; /* obtain remainder */
|
||||||
|
m3 = bl * m1; /* calculate correction */
|
||||||
|
m4 = ((m2 - (m3 >> 32)) << 32) / bh; /* form 2nd partial quotient */
|
||||||
|
|
||||||
|
quotient->mantissa = (m1 << 32) + m4; /* merge quotients */
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Global routines */
|
||||||
|
|
||||||
|
/* Extended-precision memory read */
|
||||||
|
|
||||||
|
XPN ReadX (uint32 va)
|
||||||
|
{
|
||||||
|
XPN packed;
|
||||||
|
|
||||||
|
packed.high = ReadW (va) << 16 | ReadW ((va + 1) & VAMASK);
|
||||||
|
packed.low = ReadW ((va + 2) & VAMASK) << 16; /* read and pack */
|
||||||
|
return packed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Extended-precision memory write */
|
||||||
|
|
||||||
|
void WriteX (uint32 va, XPN packed)
|
||||||
|
{
|
||||||
|
WriteW (va, (packed.high >> 16) & DMASK); /* write high word */
|
||||||
|
WriteW ((va + 1) & VAMASK, packed.high & DMASK); /* write middle word */
|
||||||
|
WriteW ((va + 2) & VAMASK, (packed.low >> 16) & DMASK); /* write low word */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined (HAVE_INT64)
|
||||||
|
|
||||||
|
/* Extended-precision add */
|
||||||
|
|
||||||
|
uint32 x_add (XPN *sum, XPN augend, XPN addend)
|
||||||
|
{
|
||||||
|
XPU usum, uaddend, uaugend;
|
||||||
|
|
||||||
|
uaugend = unpack (augend); /* unpack augend */
|
||||||
|
uaddend = unpack (addend); /* unpack addend */
|
||||||
|
add (&usum, uaugend, uaddend); /* calculate sum */
|
||||||
|
return pack (sum, usum); /* pack sum */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Extended-precision subtract */
|
||||||
|
|
||||||
|
uint32 x_sub (XPN *difference, XPN minuend, XPN subtrahend)
|
||||||
|
{
|
||||||
|
XPU udifference, uminuend, usubtrahend;
|
||||||
|
|
||||||
|
uminuend = unpack (minuend); /* unpack minuend */
|
||||||
|
usubtrahend = unpack (subtrahend); /* unpack subtrahend */
|
||||||
|
complement (&usubtrahend); /* calculate difference */
|
||||||
|
add (&udifference, uminuend, usubtrahend); /* pack difference */
|
||||||
|
return pack (difference, udifference);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Extended-precision multiply */
|
||||||
|
|
||||||
|
uint32 x_mpy (XPN *product, XPN multiplicand, XPN multiplier)
|
||||||
|
{
|
||||||
|
XPU uproduct, umultiplicand, umultiplier;
|
||||||
|
|
||||||
|
umultiplicand = unpack (multiplicand); /* unpack multiplicand */
|
||||||
|
umultiplier = unpack (multiplier); /* unpack multiplier */
|
||||||
|
multiply (&uproduct, umultiplicand, umultiplier); /* calculate product */
|
||||||
|
return pack (product, uproduct); /* pack product */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Extended-precision divide */
|
||||||
|
|
||||||
|
uint32 x_div (XPN *quotient, XPN dividend, XPN divisor)
|
||||||
|
{
|
||||||
|
XPU uquotient, udividend, udivisor;
|
||||||
|
|
||||||
|
udividend = unpack (dividend); /* unpack dividend */
|
||||||
|
udivisor = unpack (divisor); /* unpack divisor */
|
||||||
|
divide (&uquotient, udividend, udivisor); /* calculate quotient */
|
||||||
|
return pack (quotient, uquotient); /* pack quotient */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Pack an extended-precision number
|
||||||
|
|
||||||
|
An unpacked mantissa is passed as a "packed" number with an unused exponent.
|
||||||
|
*/
|
||||||
|
uint32 x_pak (XPN *result, XPN mantissa, int32 exponent)
|
||||||
|
{
|
||||||
|
XPU unpacked;
|
||||||
|
|
||||||
|
unpacked.mantissa = TO_INT64 (mantissa); /* retrieve mantissa */
|
||||||
|
unpacked.exponent = exponent; /* and exponent */
|
||||||
|
return pack (result, unpacked); /* pack them */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Complement an extended-precision mantissa
|
||||||
|
|
||||||
|
An unpacked mantissa is passed as a "packed" number with an unused exponent.
|
||||||
|
We return the exponent increment, i.e., either zero or one, depending on
|
||||||
|
whether a renormalization was required. */
|
||||||
|
|
||||||
|
uint32 x_com (XPN *mantissa)
|
||||||
|
{
|
||||||
|
XPU unpacked;
|
||||||
|
|
||||||
|
unpacked.mantissa = TO_INT64 (*mantissa); /* retrieve mantissa */
|
||||||
|
unpacked.exponent = 0; /* exponent is irrelevant */
|
||||||
|
complement (&unpacked); /* negate it */
|
||||||
|
*mantissa = to_xpn (unpacked.mantissa, 0); /* replace mantissa */
|
||||||
|
return (uint32) unpacked.exponent; /* return exponent increment */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Complement an extended-precision number */
|
||||||
|
|
||||||
|
uint32 x_dcm (XPN *packed)
|
||||||
|
{
|
||||||
|
XPU unpacked;
|
||||||
|
|
||||||
|
unpacked = unpack (*packed); /* unpack the number */
|
||||||
|
complement (&unpacked); /* negate it */
|
||||||
|
return pack (packed, unpacked); /* and repack */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Truncate an extended-precision number */
|
||||||
|
|
||||||
|
void x_trun (XPN *result, XPN source)
|
||||||
|
{
|
||||||
|
t_uint64 mask;
|
||||||
|
uint32 bitslost;
|
||||||
|
XPU unpacked;
|
||||||
|
const XPU one = { XP_ONEHALF, 1 }; /* 0.5 * 2 ** 1 = 1.0 */
|
||||||
|
|
||||||
|
unpacked = unpack (source);
|
||||||
|
if (unpacked.exponent < 0) /* number < 0.5? */
|
||||||
|
result->high = result->low = 0; /* return 0 */
|
||||||
|
else if (unpacked.exponent > XP_W_MANT) /* no fractional bits? */
|
||||||
|
*result = source; /* already integer */
|
||||||
|
else {
|
||||||
|
mask = (XP_MANT >> unpacked.exponent) & XP_MANT;/* mask fractional bits */
|
||||||
|
bitslost = (uint32) (unpacked.mantissa & mask); /* flag if bits lost */
|
||||||
|
unpacked.mantissa = unpacked.mantissa & ~mask; /* mask off fraction */
|
||||||
|
if ((unpacked.mantissa < 0) && bitslost) /* negative? */
|
||||||
|
add (&unpacked, unpacked, one); /* truncate toward zero */
|
||||||
|
pack (result, unpacked); } /* (overflow cannot occur) */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* defined (HAVE_INT64) */
|
52
HP2100/hp2100_fp1.h
Normal file
52
HP2100/hp2100_fp1.h
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/* hp2100_fp1.h: HP 2100/21MX extended-precision floating point definitions
|
||||||
|
|
||||||
|
Copyright (c) 2005, J. David Bryan
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
Except as contained in this notice, the name of the author shall not
|
||||||
|
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
|
in this Software without prior written authorization from the author.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _HP2100_FP1_H_
|
||||||
|
#define _HP2100_FP1_H_ 0
|
||||||
|
|
||||||
|
|
||||||
|
/* HP memory representation of an extended-precision number */
|
||||||
|
|
||||||
|
typedef struct { uint32 high;
|
||||||
|
uint32 low; } XPN;
|
||||||
|
|
||||||
|
|
||||||
|
#define AS_XPN(x) (*(XPN *) &(x)) /* view as XPN */
|
||||||
|
|
||||||
|
|
||||||
|
XPN ReadX (uint32 va);
|
||||||
|
void WriteX (uint32 va, XPN packed);
|
||||||
|
|
||||||
|
uint32 x_add (XPN *sum, XPN augend, XPN addend);
|
||||||
|
uint32 x_sub (XPN *difference, XPN minuend, XPN subtrahend);
|
||||||
|
uint32 x_mpy (XPN *product, XPN multiplicand, XPN multiplier);
|
||||||
|
uint32 x_div (XPN *quotient, XPN dividend, XPN divisor);
|
||||||
|
uint32 x_pak (XPN *result, XPN mantissa, int32 exponent);
|
||||||
|
uint32 x_com (XPN *mantissa);
|
||||||
|
uint32 x_dcm (XPN *packed);
|
||||||
|
void x_trun (XPN *result, XPN source);
|
||||||
|
|
||||||
|
#endif
|
|
@ -26,6 +26,7 @@
|
||||||
ms 13181A 7970B 800bpi nine track magnetic tape
|
ms 13181A 7970B 800bpi nine track magnetic tape
|
||||||
13183A 7970E 1600bpi nine track magnetic tape
|
13183A 7970E 1600bpi nine track magnetic tape
|
||||||
|
|
||||||
|
01-Mar-05 JDB Added SET OFFLINE; rewind/offline now does not detach
|
||||||
07-Oct-04 JDB Fixed enable/disable from either device
|
07-Oct-04 JDB Fixed enable/disable from either device
|
||||||
14-Aug-04 JDB Fixed many functional and timing problems (from Dave Bryan)
|
14-Aug-04 JDB Fixed many functional and timing problems (from Dave Bryan)
|
||||||
- fixed erroneous execution of rejected command
|
- fixed erroneous execution of rejected command
|
||||||
|
@ -75,6 +76,9 @@
|
||||||
#include "hp2100_defs.h"
|
#include "hp2100_defs.h"
|
||||||
#include "sim_tape.h"
|
#include "sim_tape.h"
|
||||||
|
|
||||||
|
#define UNIT_V_OFFLINE (MTUF_V_UF + 0) /* unit offline */
|
||||||
|
#define UNIT_OFFLINE (1 << UNIT_V_OFFLINE)
|
||||||
|
|
||||||
#define MS_NUMDR 4 /* number of drives */
|
#define MS_NUMDR 4 /* number of drives */
|
||||||
#define DB_N_SIZE 16 /* max data buf */
|
#define DB_N_SIZE 16 /* max data buf */
|
||||||
#define DBSIZE (1 << DB_N_SIZE) /* max data cmd */
|
#define DBSIZE (1 << DB_N_SIZE) /* max data cmd */
|
||||||
|
@ -190,6 +194,7 @@ t_stat msc_svc (UNIT *uptr);
|
||||||
t_stat msc_reset (DEVICE *dptr);
|
t_stat msc_reset (DEVICE *dptr);
|
||||||
t_stat msc_attach (UNIT *uptr, char *cptr);
|
t_stat msc_attach (UNIT *uptr, char *cptr);
|
||||||
t_stat msc_detach (UNIT *uptr);
|
t_stat msc_detach (UNIT *uptr);
|
||||||
|
t_stat msc_online (UNIT *uptr, int32 value, char *cptr, void *desc);
|
||||||
t_stat msc_boot (int32 unitno, DEVICE *dptr);
|
t_stat msc_boot (int32 unitno, DEVICE *dptr);
|
||||||
t_stat ms_map_err (UNIT *uptr, t_stat st);
|
t_stat ms_map_err (UNIT *uptr, t_stat st);
|
||||||
t_stat ms_settype (UNIT *uptr, int32 val, char *cptr, void *desc);
|
t_stat ms_settype (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||||
|
@ -250,10 +255,14 @@ DEVICE msd_dev = {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
UNIT msc_unit[] = {
|
UNIT msc_unit[] = {
|
||||||
{ UDATA (&msc_svc, UNIT_ATTABLE + UNIT_ROABLE + UNIT_DISABLE, 0) },
|
{ UDATA (&msc_svc, UNIT_ATTABLE | UNIT_ROABLE |
|
||||||
{ UDATA (&msc_svc, UNIT_ATTABLE + UNIT_ROABLE + UNIT_DISABLE, 0) },
|
UNIT_DISABLE | UNIT_OFFLINE, 0) },
|
||||||
{ UDATA (&msc_svc, UNIT_ATTABLE + UNIT_ROABLE + UNIT_DISABLE, 0) },
|
{ UDATA (&msc_svc, UNIT_ATTABLE | UNIT_ROABLE |
|
||||||
{ UDATA (&msc_svc, UNIT_ATTABLE + UNIT_ROABLE + UNIT_DISABLE, 0) } };
|
UNIT_DISABLE | UNIT_OFFLINE, 0) },
|
||||||
|
{ UDATA (&msc_svc, UNIT_ATTABLE | UNIT_ROABLE |
|
||||||
|
UNIT_DISABLE | UNIT_OFFLINE, 0) },
|
||||||
|
{ UDATA (&msc_svc, UNIT_ATTABLE | UNIT_ROABLE |
|
||||||
|
UNIT_DISABLE | UNIT_OFFLINE, 0) } };
|
||||||
|
|
||||||
REG msc_reg[] = {
|
REG msc_reg[] = {
|
||||||
{ ORDATA (STA, msc_sta, 12) },
|
{ ORDATA (STA, msc_sta, 12) },
|
||||||
|
@ -282,6 +291,8 @@ REG msc_reg[] = {
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
MTAB msc_mod[] = {
|
MTAB msc_mod[] = {
|
||||||
|
{ UNIT_OFFLINE, UNIT_OFFLINE, "offline", "OFFLINE", NULL },
|
||||||
|
{ UNIT_OFFLINE, 0, "online", "ONLINE", msc_online },
|
||||||
{ MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL },
|
{ MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL },
|
||||||
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL },
|
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL },
|
||||||
{ MTAB_XTD|MTAB_VUN, 0, "REEL", "REEL",
|
{ MTAB_XTD|MTAB_VUN, 0, "REEL", "REEL",
|
||||||
|
@ -396,7 +407,7 @@ case ioLIX: /* load */
|
||||||
dat = 0;
|
dat = 0;
|
||||||
case ioMIX: /* merge */
|
case ioMIX: /* merge */
|
||||||
dat = dat | (msc_sta & ~STA_DYN); /* get card status */
|
dat = dat | (msc_sta & ~STA_DYN); /* get card status */
|
||||||
if (uptr->flags & UNIT_ATT) { /* online? */
|
if ((uptr->flags & UNIT_OFFLINE) == 0) { /* online? */
|
||||||
dat = dat | uptr->UST; /* add unit status */
|
dat = dat | uptr->UST; /* add unit status */
|
||||||
if (sim_is_active (uptr) && /* TBSY unless RWD at BOT */
|
if (sim_is_active (uptr) && /* TBSY unless RWD at BOT */
|
||||||
!((uptr->FNC & FNF_RWD) && (uptr->UST & STA_BOT)))
|
!((uptr->FNC & FNF_RWD) && (uptr->UST & STA_BOT)))
|
||||||
|
@ -482,14 +493,17 @@ devc = msc_dib.devno; /* get device nos */
|
||||||
devd = msd_dib.devno;
|
devd = msd_dib.devno;
|
||||||
unum = uptr - msc_dev.units; /* get unit number */
|
unum = uptr - msc_dev.units; /* get unit number */
|
||||||
|
|
||||||
if ((uptr->FNC != FNC_RWS) && !(uptr->flags & UNIT_ATT)) { /* offline? */
|
if ((uptr->FNC != FNC_RWS) && (uptr->flags & UNIT_OFFLINE)) { /* offline? */
|
||||||
msc_sta = (msc_sta | STA_REJ) & ~STA_BUSY; /* reject */
|
msc_sta = (msc_sta | STA_REJ) & ~STA_BUSY; /* reject */
|
||||||
setFSR (devc); /* set cch flg */
|
setFSR (devc); /* set cch flg */
|
||||||
return IORETURN (msc_stopioe, SCPE_UNATT); }
|
return IORETURN (msc_stopioe, SCPE_UNATT); }
|
||||||
|
|
||||||
switch (uptr->FNC) { /* case on function */
|
switch (uptr->FNC) { /* case on function */
|
||||||
|
|
||||||
case FNC_RWS: /* rewind offline */
|
case FNC_RWS: /* rewind offline */
|
||||||
detach_unit (uptr); /* detach == offline */
|
sim_tape_rewind (uptr); /* rewind tape */
|
||||||
|
uptr->flags = uptr->flags | UNIT_OFFLINE; /* set offline */
|
||||||
|
uptr->UST = STA_BOT; /* BOT when online again */
|
||||||
break; /* we're done */
|
break; /* we're done */
|
||||||
|
|
||||||
case FNC_REW: /* rewind */
|
case FNC_REW: /* rewind */
|
||||||
|
@ -680,7 +694,9 @@ t_stat msc_attach (UNIT *uptr, char *cptr)
|
||||||
t_stat r;
|
t_stat r;
|
||||||
|
|
||||||
r = sim_tape_attach (uptr, cptr); /* attach unit */
|
r = sim_tape_attach (uptr, cptr); /* attach unit */
|
||||||
if (r == SCPE_OK) uptr->UST = STA_BOT; /* tape starts at BOT */
|
if (r == SCPE_OK) {
|
||||||
|
uptr->flags = uptr->flags & ~UNIT_OFFLINE; /* set online */
|
||||||
|
uptr->UST = STA_BOT; } /* tape starts at BOT */
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -689,9 +705,18 @@ return r;
|
||||||
t_stat msc_detach (UNIT* uptr)
|
t_stat msc_detach (UNIT* uptr)
|
||||||
{
|
{
|
||||||
uptr->UST = 0; /* update status */
|
uptr->UST = 0; /* update status */
|
||||||
|
uptr->flags = uptr->flags | UNIT_OFFLINE; /* set offline */
|
||||||
return sim_tape_detach (uptr); /* detach unit */
|
return sim_tape_detach (uptr); /* detach unit */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Online routine */
|
||||||
|
|
||||||
|
t_stat msc_online (UNIT *uptr, int32 value, char *cptr, void *desc)
|
||||||
|
{
|
||||||
|
if (uptr->flags & UNIT_ATT) return SCPE_OK;
|
||||||
|
else return SCPE_UNATT;
|
||||||
|
}
|
||||||
|
|
||||||
/* Configure timing */
|
/* Configure timing */
|
||||||
|
|
||||||
void ms_config_timing (void)
|
void ms_config_timing (void)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* id16_cpu.c: Interdata 16b CPU simulator
|
/* id16_cpu.c: Interdata 16b CPU simulator
|
||||||
|
|
||||||
Copyright (c) 2000-2004, Robert M. Supnik
|
Copyright (c) 2000-2005, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
cpu Interdata 16b CPU
|
cpu Interdata 16b CPU
|
||||||
|
|
||||||
|
10-Mar-05 RMS Fixed bug in show history routine (from Mark Hittinger)
|
||||||
|
Revised examine/deposit to do words rather than bytes
|
||||||
07-Nov-04 RMS Added instruction history
|
07-Nov-04 RMS Added instruction history
|
||||||
22-Sep-03 RMS Added additional instruction decode types
|
22-Sep-03 RMS Added additional instruction decode types
|
||||||
07-Feb-03 RMS Fixed bug in SETM, SETMR (found by Mark Pizzolato)
|
07-Feb-03 RMS Fixed bug in SETM, SETMR (found by Mark Pizzolato)
|
||||||
|
@ -521,7 +523,7 @@ MTAB cpu_mod[] = {
|
||||||
|
|
||||||
DEVICE cpu_dev = {
|
DEVICE cpu_dev = {
|
||||||
"CPU", &cpu_unit, cpu_reg, cpu_mod,
|
"CPU", &cpu_unit, cpu_reg, cpu_mod,
|
||||||
1, 16, 18, 1, 16, 8,
|
1, 16, 18, 2, 16, 16,
|
||||||
&cpu_ex, &cpu_dep, &cpu_reset,
|
&cpu_ex, &cpu_dep, &cpu_reset,
|
||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
&cpu_dib, 0 };
|
&cpu_dib, 0 };
|
||||||
|
@ -1681,6 +1683,17 @@ M[loc >> 1] = ((loc & 1)?
|
||||||
((M[loc >> 1] & DMASK8) | (val << 8)));
|
((M[loc >> 1] & DMASK8) | (val << 8)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 IOReadH (uint32 loc)
|
||||||
|
{
|
||||||
|
return (M[loc >> 1] & DMASK16);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOWriteH (uint32 loc, uint32 val)
|
||||||
|
{
|
||||||
|
M[loc >> 1] = val & DMASK16;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Reset routine */
|
/* Reset routine */
|
||||||
|
|
||||||
|
@ -1708,7 +1721,7 @@ if (sw & SWMASK ('V')) {
|
||||||
if (addr > VAMASK) return SCPE_NXM;
|
if (addr > VAMASK) return SCPE_NXM;
|
||||||
addr = (addr + ((addr & VA_S1)? s1_rel: s0_rel)) & PAMASK16E; }
|
addr = (addr + ((addr & VA_S1)? s1_rel: s0_rel)) & PAMASK16E; }
|
||||||
if (addr >= MEMSIZE) return SCPE_NXM;
|
if (addr >= MEMSIZE) return SCPE_NXM;
|
||||||
if (vptr != NULL) *vptr = IOReadB (addr);
|
if (vptr != NULL) *vptr = IOReadH (addr);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1720,7 +1733,7 @@ if (sw & SWMASK ('V')) {
|
||||||
if (addr > VAMASK) return SCPE_NXM;
|
if (addr > VAMASK) return SCPE_NXM;
|
||||||
addr = (addr + ((addr & VA_S1)? s1_rel: s0_rel)) & PAMASK16E; }
|
addr = (addr + ((addr & VA_S1)? s1_rel: s0_rel)) & PAMASK16E; }
|
||||||
if (addr >= MEMSIZE) return SCPE_NXM;
|
if (addr >= MEMSIZE) return SCPE_NXM;
|
||||||
IOWriteB (addr, val & 0xFF);
|
IOWriteH (addr, val);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1794,9 +1807,9 @@ return SCPE_OK;
|
||||||
|
|
||||||
t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, void *desc)
|
t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, void *desc)
|
||||||
{
|
{
|
||||||
uint32 op, k, di, lnt;
|
int32 op, k, di, lnt;
|
||||||
char *cptr = (char *) desc;
|
char *cptr = (char *) desc;
|
||||||
t_value sim_eval[4];
|
t_value sim_eval[2];
|
||||||
t_stat r;
|
t_stat r;
|
||||||
struct InstHistory *h;
|
struct InstHistory *h;
|
||||||
extern t_stat fprint_sym (FILE *ofile, t_addr addr, t_value *val,
|
extern t_stat fprint_sym (FILE *ofile, t_addr addr, t_value *val,
|
||||||
|
@ -1814,12 +1827,11 @@ for (k = 0; k < lnt; k++) { /* print specified */
|
||||||
h = &hst[(di++) % hst_lnt]; /* entry pointer */
|
h = &hst[(di++) % hst_lnt]; /* entry pointer */
|
||||||
if (h->vld) { /* instruction? */
|
if (h->vld) { /* instruction? */
|
||||||
fprintf (st, "%04X %04X %04X ", h->pc, h->r1, h->opnd);
|
fprintf (st, "%04X %04X %04X ", h->pc, h->r1, h->opnd);
|
||||||
sim_eval[0] = op = (h->ir1 >> 8) & 0xFF;
|
op = (h->ir1 >> 8) & 0xFF;
|
||||||
sim_eval[1] = h->ir1 & 0xFF;
|
|
||||||
sim_eval[2] = (h->ir2 >> 8) & 0xFF;
|
|
||||||
sim_eval[3] = h->ir2 & 0xFF;
|
|
||||||
if (OP_TYPE (op) >= OP_RX) fprintf (st, "%04X ", h->ea);
|
if (OP_TYPE (op) >= OP_RX) fprintf (st, "%04X ", h->ea);
|
||||||
else fprintf (st, " ");
|
else fprintf (st, " ");
|
||||||
|
sim_eval[0] = h->ir1;
|
||||||
|
sim_eval[1] = h->ir2;
|
||||||
if ((fprint_sym (st, h->pc, sim_eval, &cpu_unit, SWMASK ('M'))) > 0)
|
if ((fprint_sym (st, h->pc, sim_eval, &cpu_unit, SWMASK ('M'))) > 0)
|
||||||
fprintf (st, "(undefined) %04X", h->ir1);
|
fprintf (st, "(undefined) %04X", h->ir1);
|
||||||
fputc ('\n', st); /* end line */
|
fputc ('\n', st); /* end line */
|
||||||
|
|
|
@ -45,8 +45,8 @@ extern UNIT cpu_unit;
|
||||||
extern REG cpu_reg[];
|
extern REG cpu_reg[];
|
||||||
extern uint16 *M;
|
extern uint16 *M;
|
||||||
|
|
||||||
t_stat fprint_sym_m (FILE *of, t_addr addr, t_value *val, t_bool cf);
|
t_stat fprint_sym_m (FILE *of, t_addr addr, t_value *val);
|
||||||
t_stat parse_sym_m (char *cptr, t_addr addr, t_value *val, t_bool cf);
|
t_stat parse_sym_m (char *cptr, t_addr addr, t_value *val);
|
||||||
extern t_stat lp_load (FILE *fileref, char *cptr, char *fnam);
|
extern t_stat lp_load (FILE *fileref, char *cptr, char *fnam);
|
||||||
extern t_stat pt_dump (FILE *of, char *cptr, char *fnam);
|
extern t_stat pt_dump (FILE *of, char *cptr, char *fnam);
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ char sim_name[] = "Interdata 16b";
|
||||||
|
|
||||||
REG *sim_PC = &cpu_reg[0];
|
REG *sim_PC = &cpu_reg[0];
|
||||||
|
|
||||||
int32 sim_emax = 8;
|
int32 sim_emax = 2;
|
||||||
|
|
||||||
DEVICE *sim_devices[] = {
|
DEVICE *sim_devices[] = {
|
||||||
&cpu_dev,
|
&cpu_dev,
|
||||||
|
@ -255,9 +255,6 @@ static const uint32 opc_val[] = {
|
||||||
0xEC00+I_RX, 0xED00+I_RX, 0xEE00+I_RX, 0xEF00+I_RX,
|
0xEC00+I_RX, 0xED00+I_RX, 0xEE00+I_RX, 0xEF00+I_RX,
|
||||||
0xFFFF };
|
0xFFFF };
|
||||||
|
|
||||||
#define GETNUM(d,n) for (k = d = 0; k < n; k++) \
|
|
||||||
d = (d << 8) | (((uint32) val[vp++]) & 0xFF)
|
|
||||||
|
|
||||||
/* Symbolic decode
|
/* Symbolic decode
|
||||||
|
|
||||||
Inputs:
|
Inputs:
|
||||||
|
@ -274,38 +271,42 @@ static const uint32 opc_val[] = {
|
||||||
t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,
|
t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,
|
||||||
UNIT *uptr, int32 sw)
|
UNIT *uptr, int32 sw)
|
||||||
{
|
{
|
||||||
int32 c, k, num, rdx, vp, lnt;
|
int32 c1, c2, rdx;
|
||||||
t_stat r;
|
t_stat r;
|
||||||
DEVICE *dptr;
|
DEVICE *dptr;
|
||||||
|
|
||||||
if (uptr == NULL) uptr = &cpu_unit; /* anon = CPU */
|
if (uptr == NULL) uptr = &cpu_unit; /* anon = CPU */
|
||||||
|
else if (uptr != &cpu_unit) return SCPE_ARG; /* CPU only */
|
||||||
dptr = find_dev_from_unit (uptr); /* find dev */
|
dptr = find_dev_from_unit (uptr); /* find dev */
|
||||||
if (dptr == NULL) return SCPE_IERR;
|
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 if (sw & SWMASK ('F')) lnt = 4;
|
|
||||||
else lnt = (uptr == &cpu_unit)? 2: 1;
|
|
||||||
if (sw & SWMASK ('D')) rdx = 10; /* get radix */
|
if (sw & SWMASK ('D')) rdx = 10; /* get radix */
|
||||||
else if (sw & SWMASK ('O')) rdx = 8;
|
else if (sw & SWMASK ('O')) rdx = 8;
|
||||||
else if (sw & SWMASK ('H')) rdx = 16;
|
else if (sw & SWMASK ('H')) rdx = 16;
|
||||||
else rdx = dptr->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] & 0x7F) == 0) return SCPE_ARG;
|
|
||||||
while (vp < lnt) { /* print string */
|
|
||||||
if ((c = (uint32) val[vp++] & 0x7F) == 0) break;
|
|
||||||
fprintf (of, (c < 0x20)? "<%02X>": "%c", c); }
|
|
||||||
return -(vp - 1); } /* return # chars */
|
|
||||||
|
|
||||||
|
if (sw & SWMASK ('A')) { /* ASCII char? */
|
||||||
|
c1 = (val[0] >> ((addr & 1)? 0: 8)) & 0x7F; /* get byte */
|
||||||
|
fprintf (of, (c1 < 0x20)? "<%02X>": "%c", c1);
|
||||||
|
return 0; }
|
||||||
|
if (sw & SWMASK ('B')) { /* byte? */
|
||||||
|
c1 = (val[0] >> ((addr & 1)? 0: 8)) & 0xFF; /* get byte */
|
||||||
|
fprint_val (of, c1, rdx, 8, PV_RZRO);
|
||||||
|
return 0; }
|
||||||
|
if (sw & SWMASK ('C')) { /* string? */
|
||||||
|
c1 = (val[0] >> 8) & 0x7F;
|
||||||
|
c2 = val[0] & 0x7F;
|
||||||
|
fprintf (of, (c1 < 0x20)? "<%02X>": "%c", c1);
|
||||||
|
fprintf (of, (c2 < 0x20)? "<%02X>": "%c", c2);
|
||||||
|
return -1; }
|
||||||
|
if (sw & SWMASK ('F')) { /* fullword? */
|
||||||
|
fprint_val (of, (val[0] << 16) | val[1], rdx, 32, PV_RZRO);
|
||||||
|
return -3; }
|
||||||
if (sw & SWMASK ('M')) { /* inst format? */
|
if (sw & SWMASK ('M')) { /* inst format? */
|
||||||
r = fprint_sym_m (of, addr, val, uptr == &cpu_unit); /* decode inst */
|
r = fprint_sym_m (of, addr, val); /* decode inst */
|
||||||
if (r <= 0) return r; }
|
if (r <= 0) return r; }
|
||||||
|
|
||||||
GETNUM (num, lnt); /* get number */
|
fprint_val (of, val[0], rdx, 16, PV_RZRO);
|
||||||
fprint_val (of, num, rdx, lnt * 8, PV_RZRO);
|
return -1;
|
||||||
return -(vp - 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Symbolic decode for -m
|
/* Symbolic decode for -m
|
||||||
|
@ -314,19 +315,18 @@ return -(vp - 1);
|
||||||
of = output stream
|
of = output stream
|
||||||
addr = current PC
|
addr = current PC
|
||||||
*val = values to decode
|
*val = values to decode
|
||||||
cf = true if decoding for CPU
|
|
||||||
Outputs:
|
Outputs:
|
||||||
return = if >= 0, error code
|
return = if >= 0, error code
|
||||||
if < 0, number of extra bytes retired
|
if < 0, number of extra bytes retired
|
||||||
*/
|
*/
|
||||||
|
|
||||||
t_stat fprint_sym_m (FILE *of, t_addr addr, t_value *val, t_bool cf)
|
t_stat fprint_sym_m (FILE *of, t_addr addr, t_value *val)
|
||||||
{
|
{
|
||||||
uint32 i, j, k, inst, r1, r2, ea, vp;
|
uint32 i, j, inst, r1, r2, ea, vp;
|
||||||
|
|
||||||
vp = 0;
|
vp = 0;
|
||||||
GETNUM (inst, 2); /* first 16b */
|
inst = val[0]; /* first 16b */
|
||||||
GETNUM (ea, 2); /* second 16b */
|
ea = val[1]; /* second 16b */
|
||||||
for (i = 0; opcode[i] != NULL; i++) { /* loop thru ops */
|
for (i = 0; opcode[i] != NULL; i++) { /* loop thru ops */
|
||||||
j = (opc_val[i] >> I_V_FL) & I_M_FL; /* get class */
|
j = (opc_val[i] >> I_V_FL) & I_M_FL; /* get class */
|
||||||
if ((opc_val[i] & 0xFFFF) == (inst & masks[j])) { /* match? */
|
if ((opc_val[i] & 0xFFFF) == (inst & masks[j])) { /* match? */
|
||||||
|
@ -347,10 +347,8 @@ for (i = 0; opcode[i] != NULL; i++) { /* loop thru ops */
|
||||||
case I_V_SB: /* short branch */
|
case I_V_SB: /* short branch */
|
||||||
fprintf (of, "%-X,", r1);
|
fprintf (of, "%-X,", r1);
|
||||||
case I_V_SX: /* ext short branch */
|
case I_V_SX: /* ext short branch */
|
||||||
if (cf) fprintf (of, "%-X", ((inst & MSK_SBF)?
|
fprintf (of, "%-X", ((inst & MSK_SBF)?
|
||||||
(addr + r2 + r2): (addr - r2 - r2)));
|
(addr + r2 + r2): (addr - r2 - r2)));
|
||||||
else fprintf (of, ((inst & MSK_SBF)?
|
|
||||||
".+%-X": ".-%X"), r2 + r2);
|
|
||||||
return -1;
|
return -1;
|
||||||
case I_V_R: /* register */
|
case I_V_R: /* register */
|
||||||
fprintf (of, "R%d", r2);
|
fprintf (of, "R%d", r2);
|
||||||
|
@ -408,74 +406,74 @@ return reg;
|
||||||
*cptr = pointer to input string
|
*cptr = pointer to input string
|
||||||
**tptr = pointer to moved pointer
|
**tptr = pointer to moved pointer
|
||||||
*ea = effective address
|
*ea = effective address
|
||||||
*rel = relative flag
|
|
||||||
addr = base address
|
addr = base address
|
||||||
cf = true if parsing for CPU
|
|
||||||
Outputs:
|
Outputs:
|
||||||
status = SCPE_OK if ok, else error code
|
status = SCPE_OK if ok, else error code
|
||||||
*/
|
*/
|
||||||
|
|
||||||
t_stat get_addr (char *cptr, char **tptr, t_addr *ea, t_bool *rel,
|
t_stat get_addr (char *cptr, char **tptr, t_addr *ea, t_addr addr)
|
||||||
t_addr addr, t_bool cf)
|
|
||||||
{
|
{
|
||||||
int32 sign = 1;
|
int32 sign = 1;
|
||||||
|
|
||||||
*ea = 0;
|
|
||||||
if (*cptr == '.') { /* relative? */
|
if (*cptr == '.') { /* relative? */
|
||||||
*rel = TRUE;
|
|
||||||
cptr++;
|
cptr++;
|
||||||
if (cf) *ea = addr;
|
*ea = addr;
|
||||||
if (*cptr == '+') cptr++; /* .+? */
|
if (*cptr == '+') cptr++; /* .+? */
|
||||||
else if (*cptr == '-') { /* .-? */
|
else if (*cptr == '-') { /* .-? */
|
||||||
sign = -1;
|
sign = -1;
|
||||||
cptr++; }
|
cptr++; }
|
||||||
else return SCPE_OK; }
|
else return SCPE_OK; }
|
||||||
else *rel = FALSE;
|
else *ea = 0;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
*ea = *ea + (sign * ((int32) strtoul (cptr, tptr, 16)));
|
*ea = *ea + (sign * ((int32) strtoul (cptr, tptr, 16)));
|
||||||
if (errno || (cptr == *tptr)) return SCPE_ARG;
|
if (errno || (cptr == *tptr)) return SCPE_ARG;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PUTNUM(d,n) for (k = n; k > 0; k--) \
|
|
||||||
val[vp++] = (d >> ((k - 1) * 8)) & 0xFF
|
|
||||||
|
|
||||||
/* Symbolic input */
|
/* Symbolic input */
|
||||||
|
|
||||||
t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw)
|
t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw)
|
||||||
{
|
{
|
||||||
int32 k, rdx, lnt, num, vp;
|
int32 by, rdx, num;
|
||||||
t_stat r;
|
t_stat r;
|
||||||
DEVICE *dptr;
|
DEVICE *dptr;
|
||||||
static const uint32 maxv[5] = { 0, 0xFF, 0xFFFF, 0, 0xFFFFFFFF };
|
|
||||||
|
|
||||||
if (uptr == NULL) uptr = &cpu_unit; /* anon = CPU */
|
if (uptr == NULL) uptr = &cpu_unit; /* anon = CPU */
|
||||||
|
else if (uptr != &cpu_unit) return SCPE_ARG; /* CPU only */
|
||||||
dptr = find_dev_from_unit (uptr); /* find dev */
|
dptr = find_dev_from_unit (uptr); /* find dev */
|
||||||
if (dptr == NULL) return SCPE_IERR;
|
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 if (sw & SWMASK ('F')) lnt = 4;
|
|
||||||
else lnt = (uptr == &cpu_unit)? 2: 1;
|
|
||||||
if (sw & SWMASK ('D')) rdx = 10; /* get radix */
|
if (sw & SWMASK ('D')) rdx = 10; /* get radix */
|
||||||
else if (sw & SWMASK ('O')) rdx = 8;
|
else if (sw & SWMASK ('O')) rdx = 8;
|
||||||
else if (sw & SWMASK ('H')) rdx = 16;
|
else if (sw & SWMASK ('H')) rdx = 16;
|
||||||
else rdx = dptr->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) && *cptr) { /* get chars */
|
|
||||||
val[vp++] = *cptr++; }
|
|
||||||
return -(vp - 1); } /* return # chars */
|
|
||||||
|
|
||||||
r = parse_sym_m (cptr, addr, val, uptr == &cpu_unit); /* try to parse inst */
|
if ((sw & SWMASK ('A')) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */
|
||||||
|
if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */
|
||||||
|
if (addr & 1) val[0] = (val[0] & ~0xFF) | ((t_value) cptr[0]);
|
||||||
|
else val[0] = (val[0] & 0xFF) | (((t_value) cptr[0]) << 8);
|
||||||
|
return 0; }
|
||||||
|
if (sw & SWMASK ('B')) { /* byte? */
|
||||||
|
by = get_uint (cptr, rdx, DMASK8, &r); /* get byte */
|
||||||
|
if (r != SCPE_OK) return SCPE_ARG;
|
||||||
|
if (addr & 1) val[0] = (val[0] & ~0xFF) | by;
|
||||||
|
else val[0] = (val[0] & 0xFF) | (by << 8);
|
||||||
|
return 0; }
|
||||||
|
if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* ASCII chars? */
|
||||||
|
if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */
|
||||||
|
val[0] = ((t_value) cptr[0] << 8) | (t_value) cptr[1];
|
||||||
|
return -1; }
|
||||||
|
if (sw & SWMASK ('F')) {
|
||||||
|
num = (int32) get_uint (cptr, rdx, DMASK32, &r);/* get number */
|
||||||
|
if (r != SCPE_OK) return r;
|
||||||
|
val[0] = (num >> 16) & DMASK16;
|
||||||
|
val[1] = num & DMASK16;
|
||||||
|
return -3; }
|
||||||
|
|
||||||
|
r = parse_sym_m (cptr, addr, val); /* try to parse inst */
|
||||||
if (r <= 0) return r;
|
if (r <= 0) return r;
|
||||||
|
val[0] = (int32) get_uint (cptr, rdx, DMASK16, &r); /* get number */
|
||||||
num = (int32) get_uint (cptr, rdx, maxv[lnt], &r); /* get number */
|
|
||||||
if (r != SCPE_OK) return r;
|
if (r != SCPE_OK) return r;
|
||||||
PUTNUM (num, lnt); /* store */
|
return -1;
|
||||||
return -(lnt - 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Symbolic input for -m
|
/* Symbolic input for -m
|
||||||
|
@ -490,15 +488,13 @@ return -(lnt - 1);
|
||||||
<= 0 -number of extra words
|
<= 0 -number of extra words
|
||||||
*/
|
*/
|
||||||
|
|
||||||
t_stat parse_sym_m (char *cptr, t_addr addr, t_value *val, t_bool cf)
|
t_stat parse_sym_m (char *cptr, t_addr addr, t_value *val)
|
||||||
{
|
{
|
||||||
uint32 i, j, k, t, df, db, inst, vp;
|
uint32 i, j, t, df, db, inst;
|
||||||
int32 st, r1, r2;
|
int32 st, r1, r2;
|
||||||
t_bool rel;
|
|
||||||
t_stat r;
|
t_stat r;
|
||||||
char *tptr, gbuf[CBUFSIZE];
|
char *tptr, gbuf[CBUFSIZE];
|
||||||
|
|
||||||
vp = 0;
|
|
||||||
cptr = get_glyph (cptr, gbuf, 0); /* get opcode */
|
cptr = get_glyph (cptr, gbuf, 0); /* get opcode */
|
||||||
for (i = 0; (opcode[i] != NULL) && (strcmp (opcode[i], gbuf) != 0) ; i++) ;
|
for (i = 0; (opcode[i] != NULL) && (strcmp (opcode[i], gbuf) != 0) ; i++) ;
|
||||||
if (opcode[i] == NULL) return SCPE_ARG;
|
if (opcode[i] == NULL) return SCPE_ARG;
|
||||||
|
@ -527,25 +523,23 @@ case I_V_R: /* register */
|
||||||
case I_V_FX: /* float-memory */
|
case I_V_FX: /* float-memory */
|
||||||
case I_V_MX: case I_V_RX: /* mask/reg-mem */
|
case I_V_MX: case I_V_RX: /* mask/reg-mem */
|
||||||
case I_V_X: /* memory */
|
case I_V_X: /* memory */
|
||||||
r = get_addr (gbuf, &tptr, &t, &rel, addr, cf); /* get addr */
|
r = get_addr (gbuf, &tptr, &t, addr); /* get addr */
|
||||||
if ((r != SCPE_OK) || (t > PAMASK16) ||
|
if ((r != SCPE_OK) || (t > PAMASK16)) return SCPE_ARG;
|
||||||
(!cf && rel)) return SCPE_ARG;
|
|
||||||
if (*tptr == '(') { /* index? */
|
if (*tptr == '(') { /* index? */
|
||||||
if ((r2 = get_reg (tptr + 1, &tptr, R_R)) < 0)
|
if ((r2 = get_reg (tptr + 1, &tptr, R_R)) < 0)
|
||||||
return SCPE_ARG;
|
return SCPE_ARG;
|
||||||
if (*tptr++ != ')') return SCPE_ARG;
|
if (*tptr++ != ')') return SCPE_ARG;
|
||||||
inst = inst | r2; } /* or in R2 */
|
inst = inst | r2; } /* or in R2 */
|
||||||
if (*tptr != 0) return SCPE_ARG;
|
if (*tptr != 0) return SCPE_ARG;
|
||||||
PUTNUM (inst, 2);
|
val[0] = inst;
|
||||||
PUTNUM (t, 2);
|
val[1] = t;
|
||||||
return -3;
|
return -3;
|
||||||
|
|
||||||
case I_V_SB: case I_V_SX: /* short branches */
|
case I_V_SB: case I_V_SX: /* short branches */
|
||||||
r = get_addr (gbuf, &tptr, &t, &rel, addr, cf); /* get addr */
|
r = get_addr (gbuf, &tptr, &t, addr); /* get addr */
|
||||||
if ((r != SCPE_OK) || (t & 1) || *tptr) /* error if odd */
|
if ((r != SCPE_OK) || (t & 1) || *tptr) /* error if odd */
|
||||||
return SCPE_ARG;
|
return SCPE_ARG;
|
||||||
st = t; /* signed version */
|
st = t; /* signed version */
|
||||||
if (cf) { /* for CPU? */
|
|
||||||
db = (addr - t) & 0x1F; /* back displ */
|
db = (addr - t) & 0x1F; /* back displ */
|
||||||
df = (t - addr) & 0x1F; /* fwd displ */
|
df = (t - addr) & 0x1F; /* fwd displ */
|
||||||
if ((t == ((addr - db) & VAMASK16)) && /* back work and */
|
if ((t == ((addr - db) & VAMASK16)) && /* back work and */
|
||||||
|
@ -554,18 +548,10 @@ case I_V_SB: case I_V_SX: /* short branches */
|
||||||
else if ((t == ((addr + df) & VAMASK16)) && /* fwd work and */
|
else if ((t == ((addr + df) & VAMASK16)) && /* fwd work and */
|
||||||
((j == I_V_SX) || (inst & MSK_SBF))) /* ext or fwd br? */
|
((j == I_V_SX) || (inst & MSK_SBF))) /* ext or fwd br? */
|
||||||
inst = inst | (df >> 1) | MSK_SBF; /* or in fwd displ */
|
inst = inst | (df >> 1) | MSK_SBF; /* or in fwd displ */
|
||||||
else return SCPE_ARG; }
|
else return SCPE_ARG;
|
||||||
else if (rel) { /* periph, must be rel */
|
break;
|
||||||
if ((st <= 0) && (st >= -0x1F) && /* relative back? */
|
|
||||||
((j == I_V_SX) || !(inst & MSK_SBF)))
|
|
||||||
inst = inst | ((-st & 0x1F) >> 1);
|
|
||||||
else if ((st >= 0) && (st < 0x1F) && /* relative fwd? */
|
|
||||||
((j == I_V_SX) || (inst & MSK_SBF)))
|
|
||||||
inst = inst | ((t & 0x1F) >> 1);
|
|
||||||
else return SCPE_ARG; }
|
|
||||||
else return SCPE_ARG; /* periph & ~rel, err */
|
|
||||||
} /* end case */
|
} /* end case */
|
||||||
|
|
||||||
PUTNUM (inst, 2);
|
val[0] = inst;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,9 @@
|
||||||
|
|
||||||
cpu Interdata 32b CPU
|
cpu Interdata 32b CPU
|
||||||
|
|
||||||
|
10-Mar-05 RMS Fixed bug in initial memory allocation
|
||||||
|
RMS Fixed bug in show history routine (from Mark Hittinger)
|
||||||
|
RMS Revised examine/deposit to do words rather than bytes
|
||||||
18-Feb-05 RMS Fixed branches to mask new PC (from Greg Johnson)
|
18-Feb-05 RMS Fixed branches to mask new PC (from Greg Johnson)
|
||||||
06-Nov-04 RMS Added =n to SHOW HISTORY
|
06-Nov-04 RMS Added =n to SHOW HISTORY
|
||||||
25-Jan-04 RMS Revised for device debug support
|
25-Jan-04 RMS Revised for device debug support
|
||||||
|
@ -574,7 +577,7 @@ DEBTAB cpu_deb[] = {
|
||||||
|
|
||||||
DEVICE cpu_dev = {
|
DEVICE cpu_dev = {
|
||||||
"CPU", &cpu_unit, cpu_reg, cpu_mod,
|
"CPU", &cpu_unit, cpu_reg, cpu_mod,
|
||||||
1, 16, 20, 1, 16, 8,
|
1, 16, 20, 2, 16, 16,
|
||||||
&cpu_ex, &cpu_dep, &cpu_reset,
|
&cpu_ex, &cpu_dep, &cpu_reset,
|
||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
&cpu_dib, DEV_DEBUG, 0,
|
&cpu_dib, DEV_DEBUG, 0,
|
||||||
|
@ -1870,6 +1873,8 @@ return 0; /* ok */
|
||||||
WriteF write fullword (processor)
|
WriteF write fullword (processor)
|
||||||
IOReadB read byte (IO)
|
IOReadB read byte (IO)
|
||||||
IOWriteB write byte (IO)
|
IOWriteB write byte (IO)
|
||||||
|
IOReadH read halfword (IO)
|
||||||
|
IOWriteH write halfword (IO)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint32 ReadB (uint32 loc, uint32 rel)
|
uint32 ReadB (uint32 loc, uint32 rel)
|
||||||
|
@ -1987,6 +1992,11 @@ uint32 sc = (3 - (loc & 3)) << 3;
|
||||||
return (M[loc >> 2] >> sc) & DMASK8;
|
return (M[loc >> 2] >> sc) & DMASK8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 IOReadH (uint32 loc)
|
||||||
|
{
|
||||||
|
return (M[loc >> 2] >> ((loc & 2)? 0: 16)) & DMASK16;
|
||||||
|
}
|
||||||
|
|
||||||
void IOWriteB (uint32 loc, uint32 val)
|
void IOWriteB (uint32 loc, uint32 val)
|
||||||
{
|
{
|
||||||
uint32 sc = (3 - (loc & 3)) << 3;
|
uint32 sc = (3 - (loc & 3)) << 3;
|
||||||
|
@ -1995,6 +2005,15 @@ val = val & DMASK8;
|
||||||
M[loc >> 2] = (M[loc >> 2] & ~(DMASK8 << sc)) | (val << sc);
|
M[loc >> 2] = (M[loc >> 2] & ~(DMASK8 << sc)) | (val << sc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IOWriteH (uint32 loc, uint32 val)
|
||||||
|
{
|
||||||
|
uint32 sc = (loc & 2)? 0: 16;
|
||||||
|
|
||||||
|
val = val & DMASK16;
|
||||||
|
M[loc >> 2] = (M[loc >> 2] & ~(DMASK16 << sc)) | (val << sc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Reset routine */
|
/* Reset routine */
|
||||||
|
|
||||||
|
@ -2008,7 +2027,7 @@ DR = 0; /* clear display */
|
||||||
drmod = 0;
|
drmod = 0;
|
||||||
blk_io.dfl = blk_io.cur = blk_io.end = 0; /* no block I/O */
|
blk_io.dfl = blk_io.cur = blk_io.end = 0; /* no block I/O */
|
||||||
sim_brk_types = sim_brk_dflt = SWMASK ('E'); /* init bkpts */
|
sim_brk_types = sim_brk_dflt = SWMASK ('E'); /* init bkpts */
|
||||||
if (M == NULL) M = calloc (MAXMEMSIZE32 >> 1, sizeof (uint16));
|
if (M == NULL) M = calloc (MAXMEMSIZE32 >> 2, sizeof (uint32));
|
||||||
if (M == NULL) return SCPE_MEM;
|
if (M == NULL) return SCPE_MEM;
|
||||||
pcq_r = find_reg ("PCQ", NULL, dptr); /* init PCQ */
|
pcq_r = find_reg ("PCQ", NULL, dptr); /* init PCQ */
|
||||||
if (pcq_r) pcq_r->qptr = 0;
|
if (pcq_r) pcq_r->qptr = 0;
|
||||||
|
@ -2024,7 +2043,7 @@ if ((sw & SWMASK ('V')) && (PSW & PSW_REL)) {
|
||||||
int32 cc = RelocT (addr, MAC_BASE, P, &addr);
|
int32 cc = RelocT (addr, MAC_BASE, P, &addr);
|
||||||
if (cc & (CC_C | CC_V)) return SCPE_NXM; }
|
if (cc & (CC_C | CC_V)) return SCPE_NXM; }
|
||||||
if (addr >= MEMSIZE) return SCPE_NXM;
|
if (addr >= MEMSIZE) return SCPE_NXM;
|
||||||
if (vptr != NULL) *vptr = IOReadB (addr);
|
if (vptr != NULL) *vptr = IOReadH (addr);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2036,7 +2055,7 @@ if ((sw & SWMASK ('V')) && (PSW & PSW_REL)) {
|
||||||
int32 cc = RelocT (addr, MAC_BASE, P, &addr);
|
int32 cc = RelocT (addr, MAC_BASE, P, &addr);
|
||||||
if (cc & (CC_C | CC_V)) return SCPE_NXM; }
|
if (cc & (CC_C | CC_V)) return SCPE_NXM; }
|
||||||
if (addr >= MEMSIZE) return SCPE_NXM;
|
if (addr >= MEMSIZE) return SCPE_NXM;
|
||||||
IOWriteB (addr, val & 0xFF);
|
IOWriteH (addr, val);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2108,9 +2127,9 @@ return SCPE_OK;
|
||||||
|
|
||||||
t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, void *desc)
|
t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, void *desc)
|
||||||
{
|
{
|
||||||
uint32 op, k, di, lnt;
|
int32 op, k, di, lnt;
|
||||||
char *cptr = (char *) desc;
|
char *cptr = (char *) desc;
|
||||||
t_value sim_eval[6];
|
t_value sim_eval[3];
|
||||||
t_stat r;
|
t_stat r;
|
||||||
struct InstHistory *h;
|
struct InstHistory *h;
|
||||||
extern t_stat fprint_sym (FILE *ofile, t_addr addr, t_value *val,
|
extern t_stat fprint_sym (FILE *ofile, t_addr addr, t_value *val,
|
||||||
|
@ -2128,14 +2147,12 @@ for (k = 0; k < lnt; k++) { /* print specified */
|
||||||
h = &hst[(di++) % hst_lnt]; /* entry pointer */
|
h = &hst[(di++) % hst_lnt]; /* entry pointer */
|
||||||
if (h->pc & HIST_PC) { /* instruction? */
|
if (h->pc & HIST_PC) { /* instruction? */
|
||||||
fprintf (st, "%06X %08X %08X ", h->pc & VAMASK32, h->r1, h->opnd);
|
fprintf (st, "%06X %08X %08X ", h->pc & VAMASK32, h->r1, h->opnd);
|
||||||
sim_eval[0] = op = (h->ir1 >> 8) & 0xFF;
|
op = (h->ir1 >> 8) & 0xFF;
|
||||||
sim_eval[1] = h->ir1 & 0xFF;
|
|
||||||
sim_eval[2] = (h->ir2 >> 8) & 0xFF;
|
|
||||||
sim_eval[3] = h->ir2 & 0xFF;
|
|
||||||
sim_eval[4] = (h->ir3 >> 8) & 0xFF;
|
|
||||||
sim_eval[5] = h->ir3 & 0xFF;
|
|
||||||
if (OP_TYPE (op) >= OP_RX) fprintf (st, "%06X ", h->ea);
|
if (OP_TYPE (op) >= OP_RX) fprintf (st, "%06X ", h->ea);
|
||||||
else fprintf (st, " ");
|
else fprintf (st, " ");
|
||||||
|
sim_eval[0] = h->ir1;
|
||||||
|
sim_eval[1] = h->ir2;
|
||||||
|
sim_eval[2] = h->ir3;
|
||||||
if ((fprint_sym (st, h->pc & VAMASK32, sim_eval, &cpu_unit, SWMASK ('M'))) > 0)
|
if ((fprint_sym (st, h->pc & VAMASK32, sim_eval, &cpu_unit, SWMASK ('M'))) > 0)
|
||||||
fprintf (st, "(undefined) %04X", h->ir1);
|
fprintf (st, "(undefined) %04X", h->ir1);
|
||||||
fputc ('\n', st); /* end line */
|
fputc ('\n', st); /* end line */
|
||||||
|
|
|
@ -48,8 +48,8 @@ extern UNIT cpu_unit;
|
||||||
extern REG cpu_reg[];
|
extern REG cpu_reg[];
|
||||||
extern uint32 *M;
|
extern uint32 *M;
|
||||||
|
|
||||||
t_stat fprint_sym_m (FILE *of, t_addr addr, t_value *val, t_bool cf);
|
t_stat fprint_sym_m (FILE *of, t_addr addr, t_value *val);
|
||||||
t_stat parse_sym_m (char *cptr, t_addr addr, t_value *val, t_bool cf);
|
t_stat parse_sym_m (char *cptr, t_addr addr, t_value *val);
|
||||||
extern t_stat lp_load (FILE *fileref, char *cptr, char *fnam);
|
extern t_stat lp_load (FILE *fileref, char *cptr, char *fnam);
|
||||||
extern t_stat pt_dump (FILE *of, char *cptr, char *fnam);
|
extern t_stat pt_dump (FILE *of, char *cptr, char *fnam);
|
||||||
|
|
||||||
|
@ -290,7 +290,7 @@ static const uint32 opc_val[] = {
|
||||||
/* Print an RX specifier */
|
/* Print an RX specifier */
|
||||||
|
|
||||||
t_stat fprint_addr (FILE *of, t_addr addr, uint32 rx, uint32 ea1,
|
t_stat fprint_addr (FILE *of, t_addr addr, uint32 rx, uint32 ea1,
|
||||||
uint32 ea2, t_bool cf)
|
uint32 ea2)
|
||||||
{
|
{
|
||||||
uint32 rx2;
|
uint32 rx2;
|
||||||
|
|
||||||
|
@ -299,25 +299,17 @@ if ((ea1 & 0xC000) == 0) { /* RX1 */
|
||||||
if (rx) fprintf (of, "(R%d)", rx);
|
if (rx) fprintf (of, "(R%d)", rx);
|
||||||
return -3; }
|
return -3; }
|
||||||
if (ea1 & 0x8000) { /* RX2 */
|
if (ea1 & 0x8000) { /* RX2 */
|
||||||
if (cf) { /* for CPU? */
|
|
||||||
ea1 = addr + 4 + SEXT15 (ea1);
|
ea1 = addr + 4 + SEXT15 (ea1);
|
||||||
fprintf (of, "%-X", ea1 & VAMASK32); }
|
fprintf (of, "%-X", ea1 & VAMASK32);
|
||||||
else { /* for dev */
|
|
||||||
int32 disp = SEXT15 (ea1); /* get disp */
|
|
||||||
if (disp >= -4) fprintf (of, ".+%-X", disp + 4);
|
|
||||||
else fprintf (of, ".-%-X", -4 - disp); }
|
|
||||||
if (rx) fprintf (of, "(R%d)", rx);
|
if (rx) fprintf (of, "(R%d)", rx);
|
||||||
return -3; }
|
return -3; }
|
||||||
rx2 = (ea1 >> 8) & 0xF;
|
rx2 = (ea1 >> 8) & 0xF; /* RX3 */
|
||||||
fprintf (of, "%-X", ((ea1 << 16) | ea2) & VAMASK32);
|
fprintf (of, "%-X", ((ea1 << 16) | ea2) & VAMASK32);
|
||||||
if (rx && !rx2) fprintf (of, "(R%d)", rx);
|
if (rx && !rx2) fprintf (of, "(R%d)", rx);
|
||||||
if (rx2) fprintf (of, "(R%d,R%d)", rx, rx2);
|
if (rx2) fprintf (of, "(R%d,R%d)", rx, rx2);
|
||||||
return -5;
|
return -5;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GETNUM(d,n) for (k = d = 0; k < n; k++) \
|
|
||||||
d = (d << 8) | (((uint32) val[vp++]) & 0xFF)
|
|
||||||
|
|
||||||
/* Symbolic decode
|
/* Symbolic decode
|
||||||
|
|
||||||
Inputs:
|
Inputs:
|
||||||
|
@ -334,39 +326,42 @@ return -5;
|
||||||
t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,
|
t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,
|
||||||
UNIT *uptr, int32 sw)
|
UNIT *uptr, int32 sw)
|
||||||
{
|
{
|
||||||
int32 c, k, num, rdx, vp, lnt;
|
int32 c1, c2, rdx;
|
||||||
t_stat r;
|
t_stat r;
|
||||||
DEVICE *dptr;
|
DEVICE *dptr;
|
||||||
|
|
||||||
if (uptr == NULL) uptr = &cpu_unit; /* anon = CPU */
|
if (uptr == NULL) uptr = &cpu_unit; /* anon = CPU */
|
||||||
|
else if (uptr != &cpu_unit) return SCPE_ARG; /* only for CPU */
|
||||||
dptr = find_dev_from_unit (uptr); /* find dev */
|
dptr = find_dev_from_unit (uptr); /* find dev */
|
||||||
if (dptr == NULL) return SCPE_IERR;
|
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 if (sw & SWMASK ('F')) lnt = 4;
|
|
||||||
else lnt = (uptr == &cpu_unit)? 4: 1;
|
|
||||||
if (sw & SWMASK ('D')) rdx = 10; /* get radix */
|
if (sw & SWMASK ('D')) rdx = 10; /* get radix */
|
||||||
else if (sw & SWMASK ('O')) rdx = 8;
|
else if (sw & SWMASK ('O')) rdx = 8;
|
||||||
else if (sw & SWMASK ('H')) rdx = 16;
|
else if (sw & SWMASK ('H')) rdx = 16;
|
||||||
else rdx = dptr->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] & 0x7F) == 0) return SCPE_ARG;
|
|
||||||
while (vp < lnt) { /* print string */
|
|
||||||
if ((c = (uint32) val[vp++] & 0x7F) == 0) break;
|
|
||||||
fprintf (of, (c < 0x20)? "<%02X>": "%c", c); }
|
|
||||||
return -(vp - 1); } /* return # chars */
|
|
||||||
|
|
||||||
|
if (sw & SWMASK ('A')) { /* ASCII char? */
|
||||||
|
c1 = (val[0] >> ((addr & 1)? 0: 8)) & 0x7F; /* get byte */
|
||||||
|
fprintf (of, (c1 < 0x20)? "<%02X>": "%c", c1);
|
||||||
|
return 0; }
|
||||||
|
if (sw & SWMASK ('B')) { /* byte? */
|
||||||
|
c1 = (val[0] >> ((addr & 1)? 0: 8)) & 0xFF; /* get byte */
|
||||||
|
fprint_val (of, c1, rdx, 8, PV_RZRO);
|
||||||
|
return 0; }
|
||||||
|
if (sw & SWMASK ('C')) { /* string? */
|
||||||
|
c1 = (val[0] >> 8) & 0x7F;
|
||||||
|
c2 = val[0] & 0x7F;
|
||||||
|
fprintf (of, (c1 < 0x20)? "<%02X>": "%c", c1);
|
||||||
|
fprintf (of, (c2 < 0x20)? "<%02X>": "%c", c2);
|
||||||
|
return -1; }
|
||||||
|
if (sw & SWMASK ('H')) { /* halfword? */
|
||||||
|
fprint_val (of, val[0], rdx, 16, PV_RZRO);
|
||||||
|
return -1; }
|
||||||
if (sw & SWMASK ('M')) { /* inst format? */
|
if (sw & SWMASK ('M')) { /* inst format? */
|
||||||
r = fprint_sym_m (of, addr, val, uptr == &cpu_unit); /* decode inst */
|
r = fprint_sym_m (of, addr, val); /* decode inst */
|
||||||
if (r <= 0) return r; /* success? */
|
if (r <= 0) return r; }
|
||||||
lnt = 2; } /* no, skip 16b */
|
|
||||||
|
|
||||||
GETNUM (num, lnt); /* get number */
|
fprint_val (of, (val[0] << 16) | val[1], rdx, 32, PV_RZRO);
|
||||||
fprint_val (of, num, rdx, lnt * 8, PV_RZRO);
|
return -3;
|
||||||
return -(vp - 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Symbolic decode for -m
|
/* Symbolic decode for -m
|
||||||
|
@ -381,14 +376,13 @@ return -(vp - 1);
|
||||||
if < 0, number of extra bytes retired
|
if < 0, number of extra bytes retired
|
||||||
*/
|
*/
|
||||||
|
|
||||||
t_stat fprint_sym_m (FILE *of, t_addr addr, t_value *val, t_bool cf)
|
t_stat fprint_sym_m (FILE *of, t_addr addr, t_value *val)
|
||||||
{
|
{
|
||||||
uint32 i, j, k, inst, r1, r2, ea1, ea2, vp;
|
uint32 i, j, inst, r1, r2, ea1, ea2;
|
||||||
|
|
||||||
vp = 0;
|
inst = val[0];
|
||||||
GETNUM (inst,2); /* high 16b */
|
ea1 = val[1];
|
||||||
GETNUM (ea1, 2); /* next 16b */
|
ea2 = val[2];
|
||||||
GETNUM (ea2, 2); /* next 16b */
|
|
||||||
for (i = 0; opc_val[i] != 0xFFFF; i++) { /* loop thru ops */
|
for (i = 0; opc_val[i] != 0xFFFF; i++) { /* loop thru ops */
|
||||||
j = (opc_val[i] >> I_V_FL) & I_M_FL; /* get class */
|
j = (opc_val[i] >> I_V_FL) & I_M_FL; /* get class */
|
||||||
if ((opc_val[i] & 0xFFFF) == (inst & masks[j])) { /* match? */
|
if ((opc_val[i] & 0xFFFF) == (inst & masks[j])) { /* match? */
|
||||||
|
@ -409,10 +403,8 @@ for (i = 0; opc_val[i] != 0xFFFF; i++) { /* loop thru ops */
|
||||||
case I_V_SB: /* short branch */
|
case I_V_SB: /* short branch */
|
||||||
fprintf (of, "%-X,", r1);
|
fprintf (of, "%-X,", r1);
|
||||||
case I_V_SX: /* ext short branch */
|
case I_V_SX: /* ext short branch */
|
||||||
if (cf) fprintf (of, "%-X", ((inst & MSK_SBF)?
|
fprintf (of, "%-X", ((inst & MSK_SBF)?
|
||||||
(addr + r2 + r2): (addr - r2 - r2)));
|
(addr + r2 + r2): (addr - r2 - r2)));
|
||||||
else fprintf (of, ((inst & MSK_SBF)?
|
|
||||||
".+%-X": ".-%X"), r2 + r2);
|
|
||||||
return -1;
|
return -1;
|
||||||
case I_V_R: /* register */
|
case I_V_R: /* register */
|
||||||
fprintf (of, "R%d", r2);
|
fprintf (of, "R%d", r2);
|
||||||
|
@ -427,13 +419,15 @@ for (i = 0; opc_val[i] != 0xFFFF; i++) { /* loop thru ops */
|
||||||
return -5;
|
return -5;
|
||||||
case I_V_MX: /* mask-memory */
|
case I_V_MX: /* mask-memory */
|
||||||
fprintf (of, "%-X,", r1);
|
fprintf (of, "%-X,", r1);
|
||||||
return fprint_addr (of, addr, r2, ea1, ea2, cf);
|
return fprint_addr (of, addr, r2, ea1, ea2);
|
||||||
case I_V_RX: /* register-memory */
|
case I_V_RX: /* register-memory */
|
||||||
case I_V_FX: /* floating-memory */
|
case I_V_FX: /* floating-memory */
|
||||||
fprintf (of, "R%d,", r1);
|
fprintf (of, "R%d,", r1);
|
||||||
case I_V_X: /* memory */
|
case I_V_X: /* memory */
|
||||||
return fprint_addr (of, addr, r2, ea1, ea2, cf); }
|
return fprint_addr (of, addr, r2, ea1, ea2);
|
||||||
return SCPE_IERR; } /* end if */
|
} /* end case */
|
||||||
|
return SCPE_IERR;
|
||||||
|
} /* end if */
|
||||||
} /* end for */
|
} /* end for */
|
||||||
return SCPE_ARG; /* no match */
|
return SCPE_ARG; /* no match */
|
||||||
}
|
}
|
||||||
|
@ -503,74 +497,74 @@ return SCPE_OK;
|
||||||
*cptr = pointer to input string
|
*cptr = pointer to input string
|
||||||
**tptr = pointer to moved pointer
|
**tptr = pointer to moved pointer
|
||||||
*ea = effective address
|
*ea = effective address
|
||||||
*rel = relative flag
|
|
||||||
addr = base address
|
addr = base address
|
||||||
cf = true if parsing for CPU
|
|
||||||
Outputs:
|
Outputs:
|
||||||
status = SCPE_OK if ok, else error code
|
status = SCPE_OK if ok, else error code
|
||||||
*/
|
*/
|
||||||
|
|
||||||
t_stat get_addr (char *cptr, char **tptr, t_addr *ea, t_bool *rel,
|
t_stat get_addr (char *cptr, char **tptr, t_addr *ea, t_addr addr)
|
||||||
t_addr addr, t_bool cf)
|
|
||||||
{
|
{
|
||||||
int32 sign = 1;
|
int32 sign = 1;
|
||||||
|
|
||||||
*ea = 0;
|
|
||||||
if (*cptr == '.') { /* relative? */
|
if (*cptr == '.') { /* relative? */
|
||||||
*rel = TRUE;
|
|
||||||
cptr++;
|
cptr++;
|
||||||
if (cf) *ea = addr;
|
*ea = addr;
|
||||||
if (*cptr == '+') cptr++; /* .+? */
|
if (*cptr == '+') cptr++; /* .+? */
|
||||||
else if (*cptr == '-') { /* .-? */
|
else if (*cptr == '-') { /* .-? */
|
||||||
sign = -1;
|
sign = -1;
|
||||||
cptr++; }
|
cptr++; }
|
||||||
else return SCPE_OK; }
|
else return SCPE_OK; }
|
||||||
else *rel = FALSE;
|
else *ea = 0;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
*ea = *ea + (sign * ((int32) strtoul (cptr, tptr, 16)));
|
*ea = *ea + (sign * ((int32) strtoul (cptr, tptr, 16)));
|
||||||
if (errno || (cptr == *tptr)) return SCPE_ARG;
|
if (errno || (cptr == *tptr)) return SCPE_ARG;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PUTNUM(d,n) for (k = n; k > 0; k--) \
|
|
||||||
val[vp++] = (d >> ((k - 1) * 8)) & 0xFF
|
|
||||||
|
|
||||||
/* Symbolic input */
|
/* Symbolic input */
|
||||||
|
|
||||||
t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw)
|
t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw)
|
||||||
{
|
{
|
||||||
int32 k, rdx, lnt, num, vp;
|
int32 by, rdx, num;
|
||||||
t_stat r;
|
t_stat r;
|
||||||
DEVICE *dptr;
|
DEVICE *dptr;
|
||||||
static const uint32 maxv[5] = { 0, 0xFF, 0xFFFF, 0, 0xFFFFFFFF };
|
|
||||||
|
|
||||||
if (uptr == NULL) uptr = &cpu_unit; /* anon = CPU */
|
if (uptr == NULL) uptr = &cpu_unit; /* anon = CPU */
|
||||||
|
else if (uptr != &cpu_unit) return SCPE_ARG; /* CPU only */
|
||||||
dptr = find_dev_from_unit (uptr); /* find dev */
|
dptr = find_dev_from_unit (uptr); /* find dev */
|
||||||
if (dptr == NULL) return SCPE_IERR;
|
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 if (sw & SWMASK ('F')) lnt = 4;
|
|
||||||
else lnt = (uptr == &cpu_unit)? 4: 1;
|
|
||||||
if (sw & SWMASK ('D')) rdx = 10; /* get radix */
|
if (sw & SWMASK ('D')) rdx = 10; /* get radix */
|
||||||
else if (sw & SWMASK ('O')) rdx = 8;
|
else if (sw & SWMASK ('O')) rdx = 8;
|
||||||
else if (sw & SWMASK ('H')) rdx = 16;
|
else if (sw & SWMASK ('H')) rdx = 16;
|
||||||
else rdx = dptr->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) && *cptr) { /* get chars */
|
|
||||||
val[vp++] = *cptr++; }
|
|
||||||
return -(vp - 1); } /* return # chars */
|
|
||||||
|
|
||||||
r = parse_sym_m (cptr, addr, val, uptr == &cpu_unit); /* try to parse */
|
if ((sw & SWMASK ('A')) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */
|
||||||
|
if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */
|
||||||
|
if (addr & 1) val[0] = (val[0] & ~0xFF) | ((t_value) cptr[0]);
|
||||||
|
else val[0] = (val[0] & 0xFF) | (((t_value) cptr[0]) << 8);
|
||||||
|
return 0; }
|
||||||
|
if (sw & SWMASK ('B')) { /* byte? */
|
||||||
|
by = get_uint (cptr, rdx, DMASK8, &r); /* get byte */
|
||||||
|
if (r != SCPE_OK) return SCPE_ARG;
|
||||||
|
if (addr & 1) val[0] = (val[0] & ~0xFF) | by;
|
||||||
|
else val[0] = (val[0] & 0xFF) | (by << 8);
|
||||||
|
return 0; }
|
||||||
|
if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* ASCII chars? */
|
||||||
|
if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */
|
||||||
|
val[0] = ((t_value) cptr[0] << 8) | (t_value) cptr[1];
|
||||||
|
return -1; }
|
||||||
|
if (sw & SWMASK ('H')) { /* halfword? */
|
||||||
|
val[0] = (int32) get_uint (cptr, rdx, DMASK16, &r); /* get number */
|
||||||
|
if (r != SCPE_OK) return r;
|
||||||
|
return -1; }
|
||||||
|
|
||||||
|
r = parse_sym_m (cptr, addr, val); /* try to parse inst */
|
||||||
if (r <= 0) return r;
|
if (r <= 0) return r;
|
||||||
|
num = (int32) get_uint (cptr, rdx, DMASK32, &r); /* get number */
|
||||||
num = (int32) get_uint (cptr, rdx, maxv[lnt], &r); /* get number */
|
|
||||||
if (r != SCPE_OK) return r;
|
if (r != SCPE_OK) return r;
|
||||||
PUTNUM (num, lnt); /* store */
|
val[0] = (num >> 16) & DMASK16;
|
||||||
return -(lnt - 1);
|
val[1] = num & DMASK16;
|
||||||
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Symbolic input for -m
|
/* Symbolic input for -m
|
||||||
|
@ -585,12 +579,11 @@ return -(lnt - 1);
|
||||||
<= 0 -number of extra words
|
<= 0 -number of extra words
|
||||||
*/
|
*/
|
||||||
|
|
||||||
t_stat parse_sym_m (char *cptr, t_addr addr, t_value *val, t_bool cf)
|
t_stat parse_sym_m (char *cptr, t_addr addr, t_value *val)
|
||||||
{
|
{
|
||||||
uint32 i, j, k, df, db, t, inst, vp;
|
uint32 i, j, df, db, t, inst, vp;
|
||||||
int32 st, r1, r2, rx2;
|
int32 st, r1, r2, rx2;
|
||||||
t_stat r;
|
t_stat r;
|
||||||
t_bool rel;
|
|
||||||
char *tptr, gbuf[CBUFSIZE];
|
char *tptr, gbuf[CBUFSIZE];
|
||||||
|
|
||||||
vp = 0;
|
vp = 0;
|
||||||
|
@ -622,7 +615,7 @@ case I_V_R: /* register */
|
||||||
case I_V_FX: /* float-memory */
|
case I_V_FX: /* float-memory */
|
||||||
case I_V_MX: case I_V_RX: /* mask/reg-memory */
|
case I_V_MX: case I_V_RX: /* mask/reg-memory */
|
||||||
case I_V_X: /* memory */
|
case I_V_X: /* memory */
|
||||||
r = get_addr (gbuf, &tptr, &t, &rel, addr, cf); /* get addr */
|
r = get_addr (gbuf, &tptr, &t, addr); /* get addr */
|
||||||
if (r != SCPE_OK) return SCPE_ARG; /* error? */
|
if (r != SCPE_OK) return SCPE_ARG; /* error? */
|
||||||
rx2 = 0; /* assume no 2nd */
|
rx2 = 0; /* assume no 2nd */
|
||||||
if (*tptr == '(') { /* index? */
|
if (*tptr == '(') { /* index? */
|
||||||
|
@ -634,47 +627,41 @@ case I_V_X: /* memory */
|
||||||
return SCPE_ARG; }
|
return SCPE_ARG; }
|
||||||
if (*tptr++ != ')') return SCPE_ARG; } /* all done? */
|
if (*tptr++ != ')') return SCPE_ARG; } /* all done? */
|
||||||
if (*tptr != 0) return SCPE_ARG;
|
if (*tptr != 0) return SCPE_ARG;
|
||||||
PUTNUM (inst, 2); /* store inst */
|
val[0] = inst; /* store inst */
|
||||||
if (!cf && rel) { /* periph, rel */
|
|
||||||
st = t - 4; /* displ */
|
|
||||||
if (rx2 || (st > 0x3FFF) || (st < -0x4000)) /* rx2 or too big? */
|
|
||||||
return SCPE_ARG;
|
|
||||||
t = (st & 0x7FFF) | 0x8000;
|
|
||||||
PUTNUM (t, 2); /* store displ */
|
|
||||||
return -3; }
|
|
||||||
if (rx2 == 0) { /* no 2nd? */
|
if (rx2 == 0) { /* no 2nd? */
|
||||||
if (t < 0x4000) { /* RX1? */
|
if (t < 0x4000) { /* RX1? */
|
||||||
PUTNUM (t, 2); /* store ea */
|
val[1] = t; /* store ea */
|
||||||
return -3; }
|
return -3; }
|
||||||
st = (t - (addr + 4)); /* displ */
|
st = (t - (addr + 4)); /* displ */
|
||||||
if (cf && (st <= 0x3FFF) && (st >= -0x4000)) { /* RX2? CPU only */
|
if ((st <= 0x3FFF) && (st >= -0x4000)) { /* RX2? CPU only */
|
||||||
t = (st & 0x7FFF) | 0x8000;
|
t = (st & 0x7FFF) | 0x8000;
|
||||||
PUTNUM (t, 2); /* store displ */
|
val[1] = t; /* store displ */
|
||||||
return -3; } }
|
return -3; } }
|
||||||
t = (t & VAMASK32) | 0x40000000 | (rx2 << 24);
|
t = (t & VAMASK32) | 0x40000000 | (rx2 << 24);
|
||||||
PUTNUM (t, 4); /* RX3 */
|
val[1] = (t >> 16) & DMASK16;
|
||||||
|
val[2] = t & DMASK16;
|
||||||
return -5;
|
return -5;
|
||||||
|
|
||||||
case I_V_RI: /* 16b immediate */
|
case I_V_RI: /* 16b immediate */
|
||||||
r = get_imm (gbuf, &t, &inst, DMASK16); /* process imm */
|
r = get_imm (gbuf, &t, &inst, DMASK16); /* process imm */
|
||||||
if (r != SCPE_OK) return r;
|
if (r != SCPE_OK) return r;
|
||||||
PUTNUM (inst, 2); /* store inst */
|
val[0] = inst;
|
||||||
PUTNUM (t, 2); /* store 16b imm */
|
val[1] = t;
|
||||||
return -3;
|
return -3;
|
||||||
|
|
||||||
case I_V_RF:
|
case I_V_RF:
|
||||||
r = get_imm (gbuf, &t, &inst, DMASK32); /* process imm */
|
r = get_imm (gbuf, &t, &inst, DMASK32); /* process imm */
|
||||||
if (r != SCPE_OK) return r;
|
if (r != SCPE_OK) return r;
|
||||||
PUTNUM (inst, 2); /* store inst */
|
val[0] = inst;
|
||||||
PUTNUM (t, 4); /* store 32b imm */
|
val[1] = (t >> 16) & DMASK16;
|
||||||
|
val[2] = t & DMASK16;
|
||||||
return -5;
|
return -5;
|
||||||
|
|
||||||
case I_V_SB: case I_V_SX: /* short branches */
|
case I_V_SB: case I_V_SX: /* short branches */
|
||||||
r = get_addr (gbuf, &tptr, &t, &rel, addr, cf); /* get addr */
|
r = get_addr (gbuf, &tptr, &t, addr); /* get addr */
|
||||||
if ((r != SCPE_OK) || (t & 1) || *tptr) /* error if odd */
|
if ((r != SCPE_OK) || (t & 1) || *tptr) /* error if odd */
|
||||||
return SCPE_ARG;
|
return SCPE_ARG;
|
||||||
st = t; /* signed version */
|
st = t; /* signed version */
|
||||||
if (cf) { /* for CPU? */
|
|
||||||
db = (addr - t) & 0x1F; /* back displ */
|
db = (addr - t) & 0x1F; /* back displ */
|
||||||
df = (t - addr) & 0x1F; /* fwd displ */
|
df = (t - addr) & 0x1F; /* fwd displ */
|
||||||
if ((t == ((addr - db) & VAMASK16)) && /* back work and */
|
if ((t == ((addr - db) & VAMASK16)) && /* back work and */
|
||||||
|
@ -683,18 +670,9 @@ case I_V_SB: case I_V_SX: /* short branches */
|
||||||
else if ((t == ((addr + df) & VAMASK16)) && /* fwd work and */
|
else if ((t == ((addr + df) & VAMASK16)) && /* fwd work and */
|
||||||
((j == I_V_SX) || (inst & MSK_SBF))) /* ext or fwd br? */
|
((j == I_V_SX) || (inst & MSK_SBF))) /* ext or fwd br? */
|
||||||
inst = inst | (df >> 1) | MSK_SBF; /* or in fwd displ */
|
inst = inst | (df >> 1) | MSK_SBF; /* or in fwd displ */
|
||||||
else return SCPE_ARG; }
|
else return SCPE_ARG;
|
||||||
else if (rel) { /* periph, must be rel */
|
|
||||||
if ((st <= 0) && (st >= -0x1F) && /* relative back? */
|
|
||||||
((j == I_V_SX) || !(inst & MSK_SBF)))
|
|
||||||
inst = inst | ((-st & 0x1F) >> 1);
|
|
||||||
else if ((st >= 0) && (st < 0x1F) && /* relative fwd? */
|
|
||||||
((j == I_V_SX) || (inst & MSK_SBF)))
|
|
||||||
inst = inst | ((t & 0x1F) >> 1);
|
|
||||||
else return SCPE_ARG; }
|
|
||||||
else return SCPE_ARG; /* periph & ~rel, err */
|
|
||||||
} /* end case */
|
} /* end case */
|
||||||
|
|
||||||
PUTNUM (inst, 2);
|
val[0] = inst;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -464,6 +464,8 @@ int32 int_chg (uint32 irq, int32 dat, int32 armdis);
|
||||||
int32 io_2b (int32 val, int32 pos, int32 old);
|
int32 io_2b (int32 val, int32 pos, int32 old);
|
||||||
uint32 IOReadB (uint32 loc);
|
uint32 IOReadB (uint32 loc);
|
||||||
void IOWriteB (uint32 loc, uint32 val);
|
void IOWriteB (uint32 loc, uint32 val);
|
||||||
|
uint32 IOReadH (uint32 loc);
|
||||||
|
void IOWriteH (uint32 loc, uint32 val);
|
||||||
uint32 ReadF (uint32 loc, uint32 rel);
|
uint32 ReadF (uint32 loc, uint32 rel);
|
||||||
void WriteF (uint32 loc, uint32 val, uint32 rel);
|
void WriteF (uint32 loc, uint32 val, uint32 rel);
|
||||||
uint32 IOReadBlk (uint32 loc, uint32 cnt, uint8 *buf);
|
uint32 IOReadBlk (uint32 loc, uint32 cnt, uint8 *buf);
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
To: Users
|
To: Users
|
||||||
From: Bob Supnik
|
From: Bob Supnik
|
||||||
Subj: Interdata 16b/32b Simulator Usage
|
Subj: Interdata 16b/32b Simulator Usage
|
||||||
Date: 15-Nov-2004
|
Date: 15-Mar-2005
|
||||||
|
|
||||||
COPYRIGHT NOTICE
|
COPYRIGHT NOTICE
|
||||||
|
|
||||||
The following copyright notice applies to both the SIMH source and binary:
|
The following copyright notice applies to both the SIMH source and binary:
|
||||||
|
|
||||||
Original code published in 1993-2004, written by Robert M Supnik
|
Original code published in 1993-2005, written by Robert M Supnik
|
||||||
Copyright (c) 1993-2004, Robert M Supnik
|
Copyright (c) 1993-2005, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -166,17 +166,23 @@ If memory size is being reduced, and the memory being truncated contains
|
||||||
non-zero data, the simulator asks for confirmation. Data in the truncated
|
non-zero data, the simulator asks for confirmation. Data in the truncated
|
||||||
portion of memory is lost. Initial memory size is 64KB.
|
portion of memory is lost. Initial memory size is 64KB.
|
||||||
|
|
||||||
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):
|
|
||||||
|
|
||||||
|
-a examine/deposit ASCII characters
|
||||||
-b examine/deposit bytes
|
-b examine/deposit bytes
|
||||||
|
-c examine/deposit packed ASCII characters
|
||||||
-w examine/deposit halfwords (CPU default)
|
-w examine/deposit halfwords (CPU default)
|
||||||
-f examine/deposit fullwords
|
-f examine/deposit fullwords
|
||||||
-d data radix is decimal
|
-d data radix is decimal
|
||||||
-o data radix is octal
|
-o data radix is octal
|
||||||
-h data radix is hexadecimal
|
-h data radix is hexadecimal
|
||||||
|
-m examine as instruction mnemonics
|
||||||
-v interpret address as virtual
|
-v interpret address as virtual
|
||||||
|
|
||||||
|
Packed characters, halfwords, fullwords, and instructions must be aligned
|
||||||
|
on a halfword (16b) boundary. If an odd address is specified, the low
|
||||||
|
order bit is ignored.
|
||||||
|
|
||||||
CPU registers include the visible state of the processor as well as the
|
CPU registers include the visible state of the processor as well as the
|
||||||
control registers for the interrupt system.
|
control registers for the interrupt system.
|
||||||
|
|
||||||
|
@ -234,17 +240,22 @@ If memory size is being reduced, and the memory being truncated contains
|
||||||
non-zero data, the simulator asks for confirmation. Data in the truncated
|
non-zero data, the simulator asks for confirmation. Data in the truncated
|
||||||
portion of memory is lost. Initial memory size is 1024KB.
|
portion of memory is lost. Initial memory size is 1024KB.
|
||||||
|
|
||||||
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):
|
|
||||||
|
|
||||||
|
-a examine/deposit ASCII characters
|
||||||
-b examine/deposit bytes
|
-b examine/deposit bytes
|
||||||
-w examine/deposit halfwords
|
-c examine/deposit packed ASCII characters
|
||||||
-f examine/deposit fullwords (CPU default)
|
-f examine/deposit fullwords (CPU default)
|
||||||
-d data radix is decimal
|
-d data radix is decimal
|
||||||
-o data radix is octal
|
-o data radix is octal
|
||||||
-h data radix is hexadecimal
|
-h data radix is hexadecimal
|
||||||
|
-m examine as instruction mnemonics
|
||||||
-v interpret address as virtual
|
-v interpret address as virtual
|
||||||
|
|
||||||
|
Packed characters, halfwords, fullwords, and instructions must be aligned
|
||||||
|
on a halfword (16b) boundary. If an odd address is specified, the low
|
||||||
|
order bit is ignored.
|
||||||
|
|
||||||
CPU registers include the visible state of the processor as well as the
|
CPU registers include the visible state of the processor as well as the
|
||||||
control registers for the interrupt system.
|
control registers for the interrupt system.
|
||||||
|
|
||||||
|
@ -845,8 +856,8 @@ Error handling is as follows:
|
||||||
The Interdata simulator implements symbolic display and input. Display is
|
The Interdata simulator implements symbolic display and input. Display is
|
||||||
controlled by command line switches:
|
controlled by command line switches:
|
||||||
|
|
||||||
-a display as ASCII character
|
-a display byte as ASCII character
|
||||||
-c display as two character string
|
-c display halfword as two packed ASCII characters
|
||||||
-m display instruction mnemonics
|
-m display instruction mnemonics
|
||||||
|
|
||||||
Input parsing is controlled by the first character typed in or by command
|
Input parsing is controlled by the first character typed in or by command
|
||||||
|
@ -855,7 +866,7 @@ line switches:
|
||||||
' or -a ASCII character
|
' or -a ASCII character
|
||||||
" or -c two character sixbit string
|
" or -c two character sixbit string
|
||||||
alphabetic instruction mnemonic
|
alphabetic instruction mnemonic
|
||||||
numeric octal number
|
numeric hexadecimal number
|
||||||
|
|
||||||
2.8.1 16b Instruction Input
|
2.8.1 16b Instruction Input
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* id_dp.c: Interdata 2.5MB/10MB cartridge disk simulator
|
/* id_dp.c: Interdata 2.5MB/10MB cartridge disk simulator
|
||||||
|
|
||||||
Copyright (c) 2001-2004, Robert M. Supnik
|
Copyright (c) 2001-2005, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
dp M46-421 2.5MB/10MB cartridge disk
|
dp M46-421 2.5MB/10MB cartridge disk
|
||||||
|
|
||||||
|
18-Mar-05 RMS Added attached test to detach routine
|
||||||
25-Jan-04 RMS Revised for device debug support
|
25-Jan-04 RMS Revised for device debug support
|
||||||
25-Apr-03 RMS Revised for extended file support
|
25-Apr-03 RMS Revised for extended file support
|
||||||
16-Feb-03 RMS Fixed read to test transfer ok before selch operation
|
16-Feb-03 RMS Fixed read to test transfer ok before selch operation
|
||||||
|
@ -532,6 +533,7 @@ t_stat dp_detach (UNIT *uptr)
|
||||||
{
|
{
|
||||||
uint32 u = uptr - dp_dev.units;
|
uint32 u = uptr - dp_dev.units;
|
||||||
|
|
||||||
|
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; /* attached? */
|
||||||
if (dpd_arm[u]) SET_INT (v_DPC + u + 1); /* if arm, intr */
|
if (dpd_arm[u]) SET_INT (v_DPC + u + 1); /* if arm, intr */
|
||||||
return detach_unit (uptr);
|
return detach_unit (uptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* id_mt.c: Interdata magnetic tape simulator
|
/* id_mt.c: Interdata magnetic tape simulator
|
||||||
|
|
||||||
Copyright (c) 2001-2004, Robert M Supnik
|
Copyright (c) 2001-2005, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
mt M46-494 dual density 9-track magtape controller
|
mt M46-494 dual density 9-track magtape controller
|
||||||
|
|
||||||
|
18-Mar-05 RMS Added attached test to detach routine
|
||||||
07-Dec-04 RMS Added read-only file support
|
07-Dec-04 RMS Added read-only file support
|
||||||
25-Apr-03 RMS Revised for extended file support
|
25-Apr-03 RMS Revised for extended file support
|
||||||
28-Mar-03 RMS Added multiformat support
|
28-Mar-03 RMS Added multiformat support
|
||||||
|
@ -445,6 +446,7 @@ t_stat mt_detach (UNIT* uptr)
|
||||||
int32 u = uptr - mt_dev.units;
|
int32 u = uptr - mt_dev.units;
|
||||||
t_stat r;
|
t_stat r;
|
||||||
|
|
||||||
|
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK;
|
||||||
r = sim_tape_detach (uptr);
|
r = sim_tape_detach (uptr);
|
||||||
if (r != SCPE_OK) return r;
|
if (r != SCPE_OK) return r;
|
||||||
if (mt_arm[u]) SET_INT (v_MT + u);
|
if (mt_arm[u]) SET_INT (v_MT + u);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* nova_mta.c: NOVA magnetic tape simulator
|
/* nova_mta.c: NOVA magnetic tape simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2004, Robert M. Supnik
|
Copyright (c) 1993-2005, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
mta magnetic tape
|
mta magnetic tape
|
||||||
|
|
||||||
|
18-Mar-05 RMS Added attached test to detach routine
|
||||||
22-Nov-03 CEO DIB returns # records skipped after space fwd
|
22-Nov-03 CEO DIB returns # records skipped after space fwd
|
||||||
22-Nov-03 CEO Removed cancel of tape events in IORST
|
22-Nov-03 CEO Removed cancel of tape events in IORST
|
||||||
25-Apr-03 RMS Revised for extended file support
|
25-Apr-03 RMS Revised for extended file support
|
||||||
|
@ -546,6 +547,7 @@ return r;
|
||||||
|
|
||||||
t_stat mta_detach (UNIT* uptr)
|
t_stat mta_detach (UNIT* uptr)
|
||||||
{
|
{
|
||||||
|
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; /* attached? */
|
||||||
if (!sim_is_active (uptr)) mta_upddsta (uptr, 0);
|
if (!sim_is_active (uptr)) mta_upddsta (uptr, 0);
|
||||||
return sim_tape_detach (uptr);
|
return sim_tape_detach (uptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* pdp10_lp20.c: PDP-10 LP20 line printer simulator
|
/* pdp10_lp20.c: PDP-10 LP20 line printer simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2004, Robert M Supnik
|
Copyright (c) 1993-2005, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
lp20 line printer
|
lp20 line printer
|
||||||
|
|
||||||
|
18-Mar-05 RMS Added attached test to detach routine
|
||||||
29-Dec-03 RMS Fixed bug in scheduling
|
29-Dec-03 RMS Fixed bug in scheduling
|
||||||
25-Apr-03 RMS Revised for extended file support
|
25-Apr-03 RMS Revised for extended file support
|
||||||
29-Sep-02 RMS Added variable vector support
|
29-Sep-02 RMS Added variable vector support
|
||||||
|
@ -581,6 +582,7 @@ t_stat lp20_detach (UNIT *uptr)
|
||||||
{
|
{
|
||||||
t_stat reason;
|
t_stat reason;
|
||||||
|
|
||||||
|
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; /* attached? */
|
||||||
reason = detach_unit (uptr);
|
reason = detach_unit (uptr);
|
||||||
sim_cancel (&lp20_unit);
|
sim_cancel (&lp20_unit);
|
||||||
lpcsa = lpcsa & ~CSA_GO;
|
lpcsa = lpcsa & ~CSA_GO;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* pdp10_rp.c - RH11/RP04/05/06/07 RM02/03/05/80 "Massbus" disk controller
|
/* pdp10_rp.c - RH11/RP04/05/06/07 RM02/03/05/80 "Massbus" disk controller
|
||||||
|
|
||||||
Copyright (c) 1993-2004, Robert M Supnik
|
Copyright (c) 1993-2005, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
rp RH/RP/RM moving head disks
|
rp RH/RP/RM moving head disks
|
||||||
|
|
||||||
|
18-Mar-05 RMS Added attached test to detach routine
|
||||||
20-Sep-04 RMS Fixed bugs in replicated state, RP vs RM accuracy
|
20-Sep-04 RMS Fixed bugs in replicated state, RP vs RM accuracy
|
||||||
04-Jan-04 RMS Changed sim_fsize calling sequence
|
04-Jan-04 RMS Changed sim_fsize calling sequence
|
||||||
23-Jul-03 RMS Fixed bug in read header stub
|
23-Jul-03 RMS Fixed bug in read header stub
|
||||||
|
@ -1036,6 +1037,7 @@ t_stat rp_detach (UNIT *uptr)
|
||||||
{
|
{
|
||||||
int32 drv;
|
int32 drv;
|
||||||
|
|
||||||
|
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; /* attached? */
|
||||||
drv = uptr - rp_dev.units; /* get drv number */
|
drv = uptr - rp_dev.units; /* get drv number */
|
||||||
rpds[drv] = (rpds[drv] & ~(DS_MOL | DS_RDY | DS_WRL | DS_VV | DS_OF)) |
|
rpds[drv] = (rpds[drv] & ~(DS_MOL | DS_RDY | DS_WRL | DS_VV | DS_OF)) |
|
||||||
DS_ATA;
|
DS_ATA;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* pdp10_tu.c - PDP-10 RH11/TM03/TU45 magnetic tape simulator
|
/* pdp10_tu.c - PDP-10 RH11/TM03/TU45 magnetic tape simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2004, Robert M Supnik
|
Copyright (c) 1993-2005, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -25,6 +25,9 @@
|
||||||
|
|
||||||
tu RH11/TM03/TU45 magtape
|
tu RH11/TM03/TU45 magtape
|
||||||
|
|
||||||
|
31-Mar-05 RMS Fixed bug, ERASE/WREOF incorrectly clear CS1<done>
|
||||||
|
Fixed inaccuracies in error reporting
|
||||||
|
18-Mar-05 RMS Added attached test to detach routine
|
||||||
23-Oct-04 RMS Fixed setting done on non data transfers
|
23-Oct-04 RMS Fixed setting done on non data transfers
|
||||||
01-Oct-04 RMS Modified to set FCE on read short record, eof
|
01-Oct-04 RMS Modified to set FCE on read short record, eof
|
||||||
Implemented write check
|
Implemented write check
|
||||||
|
@ -333,7 +336,7 @@ t_stat tu_boot (int32 unitno, DEVICE *dptr);
|
||||||
void tu_go (int32 drv);
|
void tu_go (int32 drv);
|
||||||
void set_tuer (int32 flag);
|
void set_tuer (int32 flag);
|
||||||
void update_tucs (int32 flag, int32 drv);
|
void update_tucs (int32 flag, int32 drv);
|
||||||
t_stat tu_map_err (UNIT *uptr, t_stat st);
|
t_stat tu_map_err (UNIT *uptr, t_stat st, t_bool qdt);
|
||||||
|
|
||||||
/* TU data structures
|
/* TU data structures
|
||||||
|
|
||||||
|
@ -637,6 +640,21 @@ case FNC_SPACER:
|
||||||
uptr->USTAT = FS_PIP;
|
uptr->USTAT = FS_PIP;
|
||||||
goto GO_XFER;
|
goto GO_XFER;
|
||||||
|
|
||||||
|
case FNC_WREOF: /* write tape mark */
|
||||||
|
case FNC_ERASE: /* erase */
|
||||||
|
if ((uptr->flags & UNIT_ATT) == 0) { /* unattached? */
|
||||||
|
set_tuer (ER_UNS);
|
||||||
|
break; }
|
||||||
|
if (sim_tape_wrp (uptr)) { /* write locked? */
|
||||||
|
set_tuer (ER_NXF);
|
||||||
|
break; }
|
||||||
|
if (fmt_test[GET_FMT (tutc)] == 0) { /* invalid format? */
|
||||||
|
set_tuer (ER_FER);
|
||||||
|
break; }
|
||||||
|
if (uptr->UDENS == UD_UNK) uptr->UDENS = den; /* set dens */
|
||||||
|
uptr->USTAT = 0;
|
||||||
|
goto GO_XFER;
|
||||||
|
|
||||||
case FNC_WCHKR: /* wchk = read */
|
case FNC_WCHKR: /* wchk = read */
|
||||||
case FNC_READR: /* read rev */
|
case FNC_READR: /* read rev */
|
||||||
if (tufs & FS_BOT) { /* beginning of tape? */
|
if (tufs & FS_BOT) { /* beginning of tape? */
|
||||||
|
@ -649,11 +667,6 @@ case FNC_WRITE: /* write */
|
||||||
((den == TC_800) && (tufc > 0777765))) { /* NRZI, fc < 13? */
|
((den == TC_800) && (tufc > 0777765))) { /* NRZI, fc < 13? */
|
||||||
set_tuer (ER_NXF);
|
set_tuer (ER_NXF);
|
||||||
break; }
|
break; }
|
||||||
case FNC_WREOF: /* write tape mark */
|
|
||||||
case FNC_ERASE: /* erase */
|
|
||||||
if (sim_tape_wrp (uptr)) { /* write locked? */
|
|
||||||
set_tuer (ER_NXF);
|
|
||||||
break; }
|
|
||||||
case FNC_WCHKF: /* wchk = read */
|
case FNC_WCHKF: /* wchk = read */
|
||||||
case FNC_READF: /* read */
|
case FNC_READF: /* read */
|
||||||
DATA_XFER:
|
DATA_XFER:
|
||||||
|
@ -721,7 +734,7 @@ case FNC_SPACEF: /* space forward */
|
||||||
do {
|
do {
|
||||||
tufc = (tufc + 1) & 0177777; /* incr fc */
|
tufc = (tufc + 1) & 0177777; /* incr fc */
|
||||||
if (st = sim_tape_sprecf (uptr, &tbc)) { /* space rec fwd, err? */
|
if (st = sim_tape_sprecf (uptr, &tbc)) { /* space rec fwd, err? */
|
||||||
r = tu_map_err (uptr, st); /* map error */
|
r = tu_map_err (uptr, st, 0); /* map error */
|
||||||
break; }
|
break; }
|
||||||
}
|
}
|
||||||
while (tufc != 0);
|
while (tufc != 0);
|
||||||
|
@ -734,7 +747,7 @@ case FNC_SPACER: /* space reverse */
|
||||||
do {
|
do {
|
||||||
tufc = (tufc + 1) & 0177777; /* incr wc */
|
tufc = (tufc + 1) & 0177777; /* incr wc */
|
||||||
if (st = sim_tape_sprecr (uptr, &tbc)) { /* space rec rev, err? */
|
if (st = sim_tape_sprecr (uptr, &tbc)) { /* space rec rev, err? */
|
||||||
r = tu_map_err (uptr, st); /* map error */
|
r = tu_map_err (uptr, st, 0); /* map error */
|
||||||
break; }
|
break; }
|
||||||
}
|
}
|
||||||
while (tufc != 0);
|
while (tufc != 0);
|
||||||
|
@ -745,13 +758,13 @@ case FNC_SPACER: /* space reverse */
|
||||||
|
|
||||||
case FNC_WREOF: /* write end of file */
|
case FNC_WREOF: /* write end of file */
|
||||||
if (st = sim_tape_wrtmk (uptr)) /* write tmk, err? */
|
if (st = sim_tape_wrtmk (uptr)) /* write tmk, err? */
|
||||||
r = tu_map_err (uptr, st); /* map error */
|
r = tu_map_err (uptr, st, 0); /* map error */
|
||||||
tufs = tufs | FS_ATA;
|
tufs = tufs | FS_ATA;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FNC_ERASE:
|
case FNC_ERASE:
|
||||||
if (sim_tape_wrp (uptr)) /* write protected? */
|
if (sim_tape_wrp (uptr)) /* write protected? */
|
||||||
r = tu_map_err (uptr, MTSE_WRP); /* map error */
|
r = tu_map_err (uptr, MTSE_WRP, 0); /* map error */
|
||||||
tufs = tufs | FS_ATA;
|
tufs = tufs | FS_ATA;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -775,7 +788,7 @@ case FNC_WCHKF: /* wcheck = read */
|
||||||
tufs = tufs | FS_ID; /* PE BOT? ID burst */
|
tufs = tufs | FS_ID; /* PE BOT? ID burst */
|
||||||
TXFR (ba, wc, 0); /* validate transfer */
|
TXFR (ba, wc, 0); /* validate transfer */
|
||||||
if (st = sim_tape_rdrecf (uptr, xbuf, &tbc, MT_MAXFR)) { /* read fwd */
|
if (st = sim_tape_rdrecf (uptr, xbuf, &tbc, MT_MAXFR)) { /* read fwd */
|
||||||
r = tu_map_err (uptr, st); /* map error */
|
r = tu_map_err (uptr, st, 1); /* map error */
|
||||||
break; } /* done */
|
break; } /* done */
|
||||||
for (i = j = 0; (i < wc10) && (j < ((int32) tbc)); i++) {
|
for (i = j = 0; (i < wc10) && (j < ((int32) tbc)); i++) {
|
||||||
if ((i == 0) || NEWPAGE (ba10 + i, 0)) { /* map new page */
|
if ((i == 0) || NEWPAGE (ba10 + i, 0)) { /* map new page */
|
||||||
|
@ -808,7 +821,7 @@ case FNC_WRITE: /* write */
|
||||||
mpa10 = mpa10 + 1; } /* end for */
|
mpa10 = mpa10 + 1; } /* end for */
|
||||||
if (j < fc) fc = j; /* short record? */
|
if (j < fc) fc = j; /* short record? */
|
||||||
if (st = sim_tape_wrrecf (uptr, xbuf, fc)) /* write rec, err? */
|
if (st = sim_tape_wrrecf (uptr, xbuf, fc)) /* write rec, err? */
|
||||||
r = tu_map_err (uptr, st); /* map error */
|
r = tu_map_err (uptr, st, 1); /* map error */
|
||||||
else {
|
else {
|
||||||
tufc = (tufc + fc) & 0177777;
|
tufc = (tufc + fc) & 0177777;
|
||||||
if (tufc == 0) tutc = tutc & ~TC_FCS;
|
if (tufc == 0) tutc = tutc & ~TC_FCS;
|
||||||
|
@ -821,7 +834,7 @@ case FNC_WCHKR: /* wcheck = read */
|
||||||
tufc = 0; /* clear frame count */
|
tufc = 0; /* clear frame count */
|
||||||
TXFR (ba, wc, 1); /* validate xfer rev */
|
TXFR (ba, wc, 1); /* validate xfer rev */
|
||||||
if (st = sim_tape_rdrecr (uptr, xbuf + 4, &tbc, MT_MAXFR)) { /* read rev */
|
if (st = sim_tape_rdrecr (uptr, xbuf + 4, &tbc, MT_MAXFR)) { /* read rev */
|
||||||
r = tu_map_err (uptr, st); /* map error */
|
r = tu_map_err (uptr, st, 1); /* map error */
|
||||||
break; } /* done */
|
break; } /* done */
|
||||||
for (i = 0; i < 4; i++) xbuf[i] = 0;
|
for (i = 0; i < 4; i++) xbuf[i] = 0;
|
||||||
for (i = 0, j = tbc + 4; (i < wc10) && (j >= 4); i++) {
|
for (i = 0, j = tbc + 4; (i < wc10) && (j >= 4); i++) {
|
||||||
|
@ -907,35 +920,41 @@ return VEC_TU; /* acknowledge */
|
||||||
|
|
||||||
/* Map tape error status */
|
/* Map tape error status */
|
||||||
|
|
||||||
t_stat tu_map_err (UNIT *uptr, t_stat st)
|
t_stat tu_map_err (UNIT *uptr, t_stat st, t_bool qdt)
|
||||||
{
|
{
|
||||||
switch (st) {
|
switch (st) {
|
||||||
case MTSE_FMT: /* illegal fmt */
|
case MTSE_FMT: /* illegal fmt */
|
||||||
case MTSE_UNATT: /* not attached */
|
case MTSE_UNATT: /* not attached */
|
||||||
set_tuer (ER_NXF); /* can't execute */
|
set_tuer (ER_NXF); /* can't execute */
|
||||||
|
if (qdt) tucs1 = tucs1 | CS1_TRE; /* data xfr? set TRE */
|
||||||
case MTSE_OK: /* no error */
|
case MTSE_OK: /* no error */
|
||||||
return SCPE_IERR;
|
return SCPE_IERR;
|
||||||
case MTSE_TMK: /* end of file */
|
case MTSE_TMK: /* end of file */
|
||||||
tufs = tufs | FS_TMK;
|
|
||||||
set_tuer (ER_FCE); /* also sets FCE */
|
set_tuer (ER_FCE); /* also sets FCE */
|
||||||
|
tufs = tufs | FS_TMK;
|
||||||
break;
|
break;
|
||||||
case MTSE_IOERR: /* IO error */
|
case MTSE_IOERR: /* IO error */
|
||||||
set_tuer (ER_VPE); /* flag error */
|
set_tuer (ER_VPE); /* flag error */
|
||||||
|
if (qdt) tucs1 = tucs1 | CS1_TRE; /* data xfr? set TRE */
|
||||||
if (tu_stopioe) return SCPE_IOERR;
|
if (tu_stopioe) return SCPE_IOERR;
|
||||||
break;
|
break;
|
||||||
case MTSE_INVRL: /* invalid rec lnt */
|
case MTSE_INVRL: /* invalid rec lnt */
|
||||||
set_tuer (ER_VPE); /* flag error */
|
set_tuer (ER_VPE); /* flag error */
|
||||||
|
if (qdt) tucs1 = tucs1 | CS1_TRE; /* data xfr? set TRE */
|
||||||
return SCPE_MTRLNT;
|
return SCPE_MTRLNT;
|
||||||
case MTSE_RECE: /* record in error */
|
case MTSE_RECE: /* record in error */
|
||||||
set_tuer (ER_CRC); /* set crc err */
|
set_tuer (ER_CRC); /* set crc err */
|
||||||
|
if (qdt) tucs1 = tucs1 | CS1_TRE; /* data xfr? set TRE */
|
||||||
break;
|
break;
|
||||||
case MTSE_EOM: /* end of medium */
|
case MTSE_EOM: /* end of medium */
|
||||||
set_tuer (ER_OPI); /* incomplete */
|
set_tuer (ER_OPI); /* incomplete */
|
||||||
|
if (qdt) tucs1 = tucs1 | CS1_TRE; /* data xfr? set TRE */
|
||||||
break;
|
break;
|
||||||
case MTSE_BOT: /* reverse into BOT */
|
case MTSE_BOT: /* reverse into BOT */
|
||||||
break;
|
break;
|
||||||
case MTSE_WRP: /* write protect */
|
case MTSE_WRP: /* write protect */
|
||||||
set_tuer (ER_NXF); /* can't execute */
|
set_tuer (ER_NXF); /* can't execute */
|
||||||
|
if (qdt) tucs1 = tucs1 | CS1_TRE; /* data xfr? set TRE */
|
||||||
break; }
|
break; }
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -992,6 +1011,7 @@ t_stat tu_detach (UNIT* uptr)
|
||||||
{
|
{
|
||||||
int32 drv = uptr - tu_dev.units;
|
int32 drv = uptr - tu_dev.units;
|
||||||
|
|
||||||
|
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; /* attached? */
|
||||||
if (sim_is_active (uptr)) { /* unit active? */
|
if (sim_is_active (uptr)) { /* unit active? */
|
||||||
sim_cancel (uptr); /* cancel operation */
|
sim_cancel (uptr); /* cancel operation */
|
||||||
tuer = tuer | ER_UNS; /* set formatter error */
|
tuer = tuer | ER_UNS; /* set formatter error */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* pdp11_hk.c - RK611/RK06/RK07 disk controller
|
/* pdp11_hk.c - RK611/RK06/RK07 disk controller
|
||||||
|
|
||||||
Copyright (c) 1993-2004, Robert M Supnik
|
Copyright (c) 1993-2005, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
hk RK611/RK06/RK07 disk
|
hk RK611/RK06/RK07 disk
|
||||||
|
|
||||||
|
18-Mar-05 RMS Added attached test to detach routine
|
||||||
03-Oct-04 RMS Revised Unibus interface
|
03-Oct-04 RMS Revised Unibus interface
|
||||||
RMS Fixed state of output ready for M+
|
RMS Fixed state of output ready for M+
|
||||||
26-Mar-04 RMS Fixed warnings with -std=c99
|
26-Mar-04 RMS Fixed warnings with -std=c99
|
||||||
|
@ -1062,6 +1063,7 @@ t_stat hk_detach (UNIT *uptr)
|
||||||
{
|
{
|
||||||
int32 drv;
|
int32 drv;
|
||||||
|
|
||||||
|
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; /* attached? */
|
||||||
drv = uptr - hk_dev.units; /* get drv number */
|
drv = uptr - hk_dev.units; /* get drv number */
|
||||||
hkds[drv] = (hkds[drv] & ~(DS_RDY | DS_WRL | DS_VV | DS_OF)) | DS_ATA;
|
hkds[drv] = (hkds[drv] & ~(DS_RDY | DS_WRL | DS_VV | DS_OF)) | DS_ATA;
|
||||||
if (sim_is_active (uptr)) { /* unit active? */
|
if (sim_is_active (uptr)) { /* unit active? */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* pdp11_rp.c - RP04/05/06/07 RM02/03/05/80 Massbus disk controller
|
/* pdp11_rp.c - RP04/05/06/07 RM02/03/05/80 Massbus disk controller
|
||||||
|
|
||||||
Copyright (c) 1993-2004, Robert M Supnik
|
Copyright (c) 1993-2005, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
rp RH/RP/RM moving head disks
|
rp RH/RP/RM moving head disks
|
||||||
|
|
||||||
|
18-Mar-05 RMS Added attached test to detach routine
|
||||||
12-Sep-04 RMS Cloned from pdp11_rp.c
|
12-Sep-04 RMS Cloned from pdp11_rp.c
|
||||||
|
|
||||||
Note: The VMS driver and the RP controller documentation state that
|
Note: The VMS driver and the RP controller documentation state that
|
||||||
|
@ -922,6 +923,7 @@ t_stat rp_detach (UNIT *uptr)
|
||||||
{
|
{
|
||||||
int32 drv;
|
int32 drv;
|
||||||
|
|
||||||
|
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; /* attached? */
|
||||||
drv = uptr - rp_dev.units; /* get drv number */
|
drv = uptr - rp_dev.units; /* get drv number */
|
||||||
rpds[drv] = rpds[drv] & ~(DS_MOL | DS_RDY | DS_WRL | DS_VV | DS_OFM);
|
rpds[drv] = rpds[drv] & ~(DS_MOL | DS_RDY | DS_WRL | DS_VV | DS_OFM);
|
||||||
rp_update_ds (DS_ATA, drv); /* request intr */
|
rp_update_ds (DS_ATA, drv); /* request intr */
|
||||||
|
|
|
@ -537,15 +537,20 @@ int32 l8b, brdisp, wd1, wd2;
|
||||||
extern int32 FPS;
|
extern int32 FPS;
|
||||||
|
|
||||||
cflag = (uptr == NULL) || (uptr == &cpu_unit);
|
cflag = (uptr == NULL) || (uptr == &cpu_unit);
|
||||||
c1 = val[0] & 0177;
|
|
||||||
c2 = (val[0] >> 8) & 0177;
|
|
||||||
if (sw & SWMASK ('A')) { /* ASCII? */
|
if (sw & SWMASK ('A')) { /* ASCII? */
|
||||||
|
c1 = (val[0] >> ((addr & 1)? 8: 0)) & 0177;
|
||||||
fprintf (of, (c1 < 040)? "<%03o>": "%c", c1);
|
fprintf (of, (c1 < 040)? "<%03o>": "%c", c1);
|
||||||
return SCPE_OK; }
|
return 0; }
|
||||||
|
if (sw & SWMASK ('B')) { /* byte? */
|
||||||
|
c1 = (val[0] >> ((addr & 1)? 8: 0)) & 0377;
|
||||||
|
fprintf (of, "%o", c1);
|
||||||
|
return 0; }
|
||||||
if (sw & SWMASK ('C')) { /* character? */
|
if (sw & SWMASK ('C')) { /* character? */
|
||||||
|
c1 = val[0] & 0177;
|
||||||
|
c2 = (val[0] >> 8) & 0177;
|
||||||
fprintf (of, (c1 < 040)? "<%03o>": "%c", c1);
|
fprintf (of, (c1 < 040)? "<%03o>": "%c", c1);
|
||||||
fprintf (of, (c2 < 040)? "<%03o>": "%c", c2);
|
fprintf (of, (c2 < 040)? "<%03o>": "%c", c2);
|
||||||
return SCPE_OK; }
|
return -1; }
|
||||||
if (sw & SWMASK ('R')) { /* radix 50? */
|
if (sw & SWMASK ('R')) { /* radix 50? */
|
||||||
if (val[0] > 0174777) return SCPE_ARG; /* max value */
|
if (val[0] > 0174777) return SCPE_ARG; /* max value */
|
||||||
c3 = val[0] % 050;
|
c3 = val[0] % 050;
|
||||||
|
@ -553,7 +558,7 @@ if (sw & SWMASK ('R')) { /* radix 50? */
|
||||||
c1 = val[0] / (050 * 050);
|
c1 = val[0] / (050 * 050);
|
||||||
fprintf (of, "%c%c%c", r50_to_asc[c1],
|
fprintf (of, "%c%c%c", r50_to_asc[c1],
|
||||||
r50_to_asc[c2], r50_to_asc[c3]);
|
r50_to_asc[c2], r50_to_asc[c3]);
|
||||||
return SCPE_OK; }
|
return -1; }
|
||||||
if (!(sw & SWMASK ('M'))) return SCPE_ARG;
|
if (!(sw & SWMASK ('M'))) return SCPE_ARG;
|
||||||
|
|
||||||
inst = val[0] | ((FPS << (I_V_L - FPS_V_L)) & I_L) |
|
inst = val[0] | ((FPS << (I_V_L - FPS_V_L)) & I_L) |
|
||||||
|
@ -567,61 +572,69 @@ for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
|
||||||
dstm = inst & 077;
|
dstm = inst & 077;
|
||||||
dstr = dstm & 07;
|
dstr = dstm & 07;
|
||||||
l8b = inst & 0377;
|
l8b = inst & 0377;
|
||||||
|
wd1 = wd2 = 0;
|
||||||
|
|
||||||
/* Instruction decode */
|
/* Instruction decode */
|
||||||
|
|
||||||
switch (j) { /* case on class */
|
switch (j) { /* case on class */
|
||||||
case I_V_NPN: case I_V_CCC: case I_V_CCS: /* no operands */
|
case I_V_NPN: case I_V_CCC: case I_V_CCS: /* no operands */
|
||||||
fprintf (of, "%s", opcode[i]);
|
fprintf (of, "%s", opcode[i]);
|
||||||
return SCPE_OK;
|
break;
|
||||||
case I_V_REG: /* reg */
|
case I_V_REG: /* reg */
|
||||||
fprintf (of, "%s %-s", opcode[i], rname[dstr]);
|
fprintf (of, "%s %-s", opcode[i], rname[dstr]);
|
||||||
return SCPE_OK;
|
break;
|
||||||
case I_V_SOP: /* sop */
|
case I_V_SOP: /* sop */
|
||||||
fprintf (of, "%s ", opcode[i]);
|
fprintf (of, "%s ", opcode[i]);
|
||||||
return fprint_spec (of, addr, dstm, val[1], cflag, TRUE);
|
wd1 = fprint_spec (of, addr, dstm, val[1], cflag, TRUE);
|
||||||
|
break;
|
||||||
case I_V_3B: /* 3b */
|
case I_V_3B: /* 3b */
|
||||||
fprintf (of, "%s %-o", opcode[i], dstr);
|
fprintf (of, "%s %-o", opcode[i], dstr);
|
||||||
return SCPE_OK;
|
break;
|
||||||
case I_V_FOP: /* fop */
|
case I_V_FOP: /* fop */
|
||||||
fprintf (of, "%s ", opcode[i]);
|
fprintf (of, "%s ", opcode[i]);
|
||||||
return fprint_spec (of, addr, dstm, val[1], cflag, FALSE);
|
wd1 = fprint_spec (of, addr, dstm, val[1], cflag, FALSE);
|
||||||
|
break;
|
||||||
case I_V_AFOP: /* afop */
|
case I_V_AFOP: /* afop */
|
||||||
fprintf (of, "%s %s,", opcode[i], fname[fac]);
|
fprintf (of, "%s %s,", opcode[i], fname[fac]);
|
||||||
return fprint_spec (of, addr, dstm, val[1], cflag, FALSE);
|
wd1 = fprint_spec (of, addr, dstm, val[1], cflag, FALSE);
|
||||||
|
break;
|
||||||
case I_V_6B: /* 6b */
|
case I_V_6B: /* 6b */
|
||||||
fprintf (of, "%s %-o", opcode[i], dstm);
|
fprintf (of, "%s %-o", opcode[i], dstm);
|
||||||
return SCPE_OK;
|
break;
|
||||||
case I_V_BR: /* cond branch */
|
case I_V_BR: /* cond branch */
|
||||||
fprintf (of, "%s ", opcode[i]);
|
fprintf (of, "%s ", opcode[i]);
|
||||||
brdisp = (l8b + l8b + ((l8b & 0200)? 0177002: 2)) & 0177777;
|
brdisp = (l8b + l8b + ((l8b & 0200)? 0177002: 2)) & 0177777;
|
||||||
if (cflag) fprintf (of, "%-o", (addr + brdisp) & 0177777);
|
if (cflag) fprintf (of, "%-o", (addr + brdisp) & 0177777);
|
||||||
else if (brdisp < 01000) fprintf (of, ".+%-o", brdisp);
|
else if (brdisp < 01000) fprintf (of, ".+%-o", brdisp);
|
||||||
else fprintf (of, ".-%-o", 0200000 - brdisp);
|
else fprintf (of, ".-%-o", 0200000 - brdisp);
|
||||||
return SCPE_OK;
|
break;
|
||||||
case I_V_8B: /* 8b */
|
case I_V_8B: /* 8b */
|
||||||
fprintf (of, "%s %-o", opcode[i], l8b);
|
fprintf (of, "%s %-o", opcode[i], l8b);
|
||||||
return SCPE_OK;
|
break;
|
||||||
case I_V_SOB: /* sob */
|
case I_V_SOB: /* sob */
|
||||||
fprintf (of, "%s %s,", opcode[i], rname[srcr]);
|
fprintf (of, "%s %s,", opcode[i], rname[srcr]);
|
||||||
brdisp = (dstm * 2) - 2;
|
brdisp = (dstm * 2) - 2;
|
||||||
if (cflag) fprintf (of, "%-o", (addr - brdisp) & 0177777);
|
if (cflag) fprintf (of, "%-o", (addr - brdisp) & 0177777);
|
||||||
else if (brdisp <= 0) fprintf (of, ".+%-o", -brdisp);
|
else if (brdisp <= 0) fprintf (of, ".+%-o", -brdisp);
|
||||||
else fprintf (of, ".-%-o", brdisp);
|
else fprintf (of, ".-%-o", brdisp);
|
||||||
return SCPE_OK;
|
break;
|
||||||
case I_V_RSOP: /* rsop */
|
case I_V_RSOP: /* rsop */
|
||||||
fprintf (of, "%s %s,", opcode[i], rname[srcr]);
|
fprintf (of, "%s %s,", opcode[i], rname[srcr]);
|
||||||
return fprint_spec (of, addr, dstm, val[1], cflag, TRUE);
|
wd1 = fprint_spec (of, addr, dstm, val[1], cflag, TRUE);
|
||||||
|
break;
|
||||||
case I_V_ASOP: case I_V_ASMD: /* asop, asmd */
|
case I_V_ASOP: case I_V_ASMD: /* asop, asmd */
|
||||||
fprintf (of, "%s %s,", opcode[i], fname[fac]);
|
fprintf (of, "%s %s,", opcode[i], fname[fac]);
|
||||||
return fprint_spec (of, addr, dstm, val[1], cflag, TRUE);
|
wd1 = fprint_spec (of, addr, dstm, val[1], cflag, TRUE);
|
||||||
|
break;
|
||||||
case I_V_DOP: /* dop */
|
case I_V_DOP: /* dop */
|
||||||
fprintf (of, "%s ", opcode[i]);
|
fprintf (of, "%s ", opcode[i]);
|
||||||
wd1 = fprint_spec (of, addr, srcm, val[1], cflag, TRUE);
|
wd1 = fprint_spec (of, addr, srcm, val[1], cflag, TRUE);
|
||||||
fprintf (of, ",");
|
fprintf (of, ",");
|
||||||
wd2 = fprint_spec (of, addr - wd1 - wd1, dstm,
|
wd2 = fprint_spec (of, addr - wd1 - wd1, dstm,
|
||||||
val[1 - wd1], cflag, TRUE);
|
val[1 - wd1], cflag, TRUE);
|
||||||
return wd1 + wd2; } /* end case */
|
break;
|
||||||
|
} /* end case */
|
||||||
|
return ((wd1 + wd2) * 2) - 1;
|
||||||
} /* end if */
|
} /* end if */
|
||||||
} /* end for */
|
} /* end for */
|
||||||
return SCPE_ARG; /* no match */
|
return SCPE_ARG; /* no match */
|
||||||
|
@ -807,6 +820,7 @@ default:
|
||||||
t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw)
|
t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw)
|
||||||
{
|
{
|
||||||
int32 cflag, d, i, j, reg, spec, n1, n2, disp, pflag;
|
int32 cflag, d, i, j, reg, spec, n1, n2, disp, pflag;
|
||||||
|
t_value by;
|
||||||
t_stat r;
|
t_stat r;
|
||||||
char *tptr, gbuf[CBUFSIZE];
|
char *tptr, gbuf[CBUFSIZE];
|
||||||
|
|
||||||
|
@ -814,12 +828,19 @@ cflag = (uptr == NULL) || (uptr == &cpu_unit);
|
||||||
while (isspace (*cptr)) cptr++; /* absorb spaces */
|
while (isspace (*cptr)) cptr++; /* absorb spaces */
|
||||||
if ((sw & SWMASK ('A')) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */
|
if ((sw & SWMASK ('A')) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */
|
||||||
if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */
|
if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */
|
||||||
val[0] = (t_value) cptr[0];
|
if (addr & 1) val[0] = (val[0] & 0377) | (((t_value) cptr[0]) << 8);
|
||||||
return SCPE_OK; }
|
else val[0] = (val[0] & ~0377) | ((t_value) cptr[0]);
|
||||||
|
return 0; }
|
||||||
|
if (sw & SWMASK ('B')) { /* byte? */
|
||||||
|
by = get_uint (cptr, 8, 0377, &r); /* get byte */
|
||||||
|
if (r != SCPE_OK) return SCPE_ARG;
|
||||||
|
if (addr & 1) val[0] = (val[0] & 0377) | (by << 8);
|
||||||
|
else val[0] = (val[0] & ~0377) | by;
|
||||||
|
return 0; }
|
||||||
if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* ASCII string? */
|
if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* ASCII string? */
|
||||||
if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */
|
if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */
|
||||||
val[0] = ((t_value) cptr[1] << 8) + (t_value) cptr[0];
|
val[0] = ((t_value) cptr[1] << 8) | (t_value) cptr[0];
|
||||||
return SCPE_OK; }
|
return -1; }
|
||||||
if (sw & SWMASK ('R')) return SCPE_ARG; /* radix 50 */
|
if (sw & SWMASK ('R')) return SCPE_ARG; /* radix 50 */
|
||||||
|
|
||||||
cptr = get_glyph (cptr, gbuf, 0); /* get opcode */
|
cptr = get_glyph (cptr, gbuf, 0); /* get opcode */
|
||||||
|
@ -909,5 +930,5 @@ case I_V_CCC: case I_V_CCS: /* cond code oper */
|
||||||
default:
|
default:
|
||||||
return SCPE_ARG; }
|
return SCPE_ARG; }
|
||||||
if (*cptr != 0) return SCPE_ARG; /* junk at end? */
|
if (*cptr != 0) return SCPE_ARG; /* junk at end? */
|
||||||
return n1 + n2;
|
return ((n1 + n2) * 2) - 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* pdp11_tm.c: PDP-11 magnetic tape simulator
|
/* pdp11_tm.c: PDP-11 magnetic tape simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2004, Robert M Supnik
|
Copyright (c) 1993-2005, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
tm TM11/TU10 magtape
|
tm TM11/TU10 magtape
|
||||||
|
|
||||||
|
18-Mar-05 RMS Added attached test to detach routine
|
||||||
07-Dec-04 RMS Added read-only file support
|
07-Dec-04 RMS Added read-only file support
|
||||||
30-Sep-04 RMS Revised Unibus interface
|
30-Sep-04 RMS Revised Unibus interface
|
||||||
25-Jan-04 RMS Revised for device debug support
|
25-Jan-04 RMS Revised for device debug support
|
||||||
|
@ -557,6 +558,7 @@ t_stat tm_detach (UNIT* uptr)
|
||||||
{
|
{
|
||||||
int32 u = uptr - tm_dev.units;
|
int32 u = uptr - tm_dev.units;
|
||||||
|
|
||||||
|
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK;
|
||||||
if (!sim_is_active (uptr)) uptr->USTAT = 0;
|
if (!sim_is_active (uptr)) uptr->USTAT = 0;
|
||||||
if (u == GET_UNIT (tm_cmd)) tm_updcsta (uptr);
|
if (u == GET_UNIT (tm_cmd)) tm_updcsta (uptr);
|
||||||
return sim_tape_detach (uptr);
|
return sim_tape_detach (uptr);
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
#elif defined (VM_VAX) /* VAX version */
|
#elif defined (VM_VAX) /* VAX version */
|
||||||
#include "vax_defs.h"
|
#include "vax_defs.h"
|
||||||
#if (UNIBUS)
|
#if (UNIBUS)
|
||||||
#define INIT_TYPE TQU_TYPE
|
#define INIT_TYPE TQ8_TYPE
|
||||||
#else
|
#else
|
||||||
#define INIT_TYPE TQ5_TYPE
|
#define INIT_TYPE TQ5_TYPE
|
||||||
#endif
|
#endif
|
||||||
|
@ -1755,7 +1755,6 @@ return SCPE_OK;
|
||||||
#define BOOT_CSR (BOOT_START + 014) /* CSR */
|
#define BOOT_CSR (BOOT_START + 014) /* CSR */
|
||||||
#define BOOT_LEN (sizeof (boot_rom) / sizeof (int16))
|
#define BOOT_LEN (sizeof (boot_rom) / sizeof (int16))
|
||||||
|
|
||||||
|
|
||||||
/* Data structure definitions */
|
/* Data structure definitions */
|
||||||
|
|
||||||
#define B_CMDINT (BOOT_START - 01000) /* cmd int */
|
#define B_CMDINT (BOOT_START - 01000) /* cmd int */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* pdp11_ts.c: TS11/TSV05 magnetic tape simulator
|
/* pdp11_ts.c: TS11/TSV05 magnetic tape simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2004, Robert M Supnik
|
Copyright (c) 1993-2005, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
ts TS11/TSV05 magtape
|
ts TS11/TSV05 magtape
|
||||||
|
|
||||||
|
18-Mar-05 RMS Added attached test to detach routine
|
||||||
07-Dec-04 RMS Added read-only file support
|
07-Dec-04 RMS Added read-only file support
|
||||||
30-Sep-04 RMS Revised Unibus interface
|
30-Sep-04 RMS Revised Unibus interface
|
||||||
25-Jan-04 RMS Revised for device debug support
|
25-Jan-04 RMS Revised for device debug support
|
||||||
|
@ -935,6 +936,7 @@ t_stat ts_detach (UNIT* uptr)
|
||||||
{
|
{
|
||||||
t_stat r;
|
t_stat r;
|
||||||
|
|
||||||
|
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; /* attached? */
|
||||||
r = sim_tape_detach (uptr); /* detach unit */
|
r = sim_tape_detach (uptr); /* detach unit */
|
||||||
if (r != SCPE_OK) return r; /* error? */
|
if (r != SCPE_OK) return r; /* error? */
|
||||||
tssr = tssr | TSSR_OFL; /* set offline */
|
tssr = tssr | TSSR_OFL; /* set offline */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* pdp11_tu.c - PDP-11 TM02/TU16 TM03/TU45/TU77 Massbus magnetic tape controller
|
/* pdp11_tu.c - PDP-11 TM02/TU16 TM03/TU45/TU77 Massbus magnetic tape controller
|
||||||
|
|
||||||
Copyright (c) 1993-2004, Robert M Supnik
|
Copyright (c) 1993-2005, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
tu TM02/TM03 magtape
|
tu TM02/TM03 magtape
|
||||||
|
|
||||||
|
31-Mar-05 RMS Fixed inaccuracies in error reporting
|
||||||
|
18-Mar-05 RMS Added attached test to detach routine
|
||||||
10-Sep-04 RMS Cloned from pdp10_tu.c
|
10-Sep-04 RMS Cloned from pdp10_tu.c
|
||||||
|
|
||||||
Magnetic tapes are represented as a series of variable 8b records
|
Magnetic tapes are represented as a series of variable 8b records
|
||||||
|
@ -246,7 +248,7 @@ int32 tu_abort (void);
|
||||||
void tu_set_er (int32 flg);
|
void tu_set_er (int32 flg);
|
||||||
void tu_clr_as (int32 mask);
|
void tu_clr_as (int32 mask);
|
||||||
void tu_update_fs (int32 flg, int32 drv);
|
void tu_update_fs (int32 flg, int32 drv);
|
||||||
t_stat tu_map_err (int32 drv, t_stat st);
|
t_stat tu_map_err (int32 drv, t_stat st, t_bool qdt);
|
||||||
|
|
||||||
/* TU data structures
|
/* TU data structures
|
||||||
|
|
||||||
|
@ -569,7 +571,7 @@ case FNC_SPACEF: /* space forward */
|
||||||
do {
|
do {
|
||||||
tufc = (tufc + 1) & 0177777; /* incr fc */
|
tufc = (tufc + 1) & 0177777; /* incr fc */
|
||||||
if (st = sim_tape_sprecf (uptr, &tbc)) { /* space rec fwd, err? */
|
if (st = sim_tape_sprecf (uptr, &tbc)) { /* space rec fwd, err? */
|
||||||
r = tu_map_err (drv, st); /* map error */
|
r = tu_map_err (drv, st, 0); /* map error */
|
||||||
break; }
|
break; }
|
||||||
}
|
}
|
||||||
while (tufc != 0);
|
while (tufc != 0);
|
||||||
|
@ -581,7 +583,7 @@ case FNC_SPACER: /* space reverse */
|
||||||
do {
|
do {
|
||||||
tufc = (tufc + 1) & 0177777; /* incr wc */
|
tufc = (tufc + 1) & 0177777; /* incr wc */
|
||||||
if (st = sim_tape_sprecr (uptr, &tbc)) { /* space rec rev, err? */
|
if (st = sim_tape_sprecr (uptr, &tbc)) { /* space rec rev, err? */
|
||||||
r = tu_map_err (drv, st); /* map error */
|
r = tu_map_err (drv, st, 0); /* map error */
|
||||||
break; }
|
break; }
|
||||||
}
|
}
|
||||||
while (tufc != 0);
|
while (tufc != 0);
|
||||||
|
@ -591,12 +593,12 @@ case FNC_SPACER: /* space reverse */
|
||||||
|
|
||||||
case FNC_WREOF: /* write end of file */
|
case FNC_WREOF: /* write end of file */
|
||||||
if (st = sim_tape_wrtmk (uptr)) /* write tmk, err? */
|
if (st = sim_tape_wrtmk (uptr)) /* write tmk, err? */
|
||||||
r = tu_map_err (drv, st); /* map error */
|
r = tu_map_err (drv, st, 0); /* map error */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FNC_ERASE:
|
case FNC_ERASE:
|
||||||
if (sim_tape_wrp (uptr)) /* write protected? */
|
if (sim_tape_wrp (uptr)) /* write protected? */
|
||||||
r = tu_map_err (drv, MTSE_WRP); /* map error */
|
r = tu_map_err (drv, MTSE_WRP, 0); /* map error */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Unit service - data transfer commands */
|
/* Unit service - data transfer commands */
|
||||||
|
@ -607,7 +609,7 @@ case FNC_WCHKF: /* wcheck = read */
|
||||||
if ((uptr->UDENS == TC_1600) && sim_tape_bot (uptr))
|
if ((uptr->UDENS == TC_1600) && sim_tape_bot (uptr))
|
||||||
tufs = tufs | FS_ID; /* PE BOT? ID burst */
|
tufs = tufs | FS_ID; /* PE BOT? ID burst */
|
||||||
if (st = sim_tape_rdrecf (uptr, xbuf, &tbc, MT_MAXFR)) { /* read fwd */
|
if (st = sim_tape_rdrecf (uptr, xbuf, &tbc, MT_MAXFR)) { /* read fwd */
|
||||||
r = tu_map_err (drv, st); /* map error */
|
r = tu_map_err (drv, st, 1); /* map error */
|
||||||
break; } /* done */
|
break; } /* done */
|
||||||
for (i = tbc; i < tbc + 4; i++) xbuf[i] = 0; /* pad with 0's */
|
for (i = tbc; i < tbc + 4; i++) xbuf[i] = 0; /* pad with 0's */
|
||||||
if (fmt == TC_CDUMP) { /* core dump? */
|
if (fmt == TC_CDUMP) { /* core dump? */
|
||||||
|
@ -652,7 +654,7 @@ case FNC_WRITE: /* write */
|
||||||
tbc = xbc;
|
tbc = xbc;
|
||||||
}
|
}
|
||||||
if (st = sim_tape_wrrecf (uptr, xbuf, tbc)) /* write rec, err? */
|
if (st = sim_tape_wrrecf (uptr, xbuf, tbc)) /* write rec, err? */
|
||||||
r = tu_map_err (drv, st); /* map error */
|
r = tu_map_err (drv, st, 1); /* map error */
|
||||||
else {
|
else {
|
||||||
tufc = (tufc + tbc) & 0177777;
|
tufc = (tufc + tbc) & 0177777;
|
||||||
if (tufc == 0) tutc = tutc & ~TC_FCS;
|
if (tufc == 0) tutc = tutc & ~TC_FCS;
|
||||||
|
@ -663,7 +665,7 @@ case FNC_READR: /* read reverse */
|
||||||
case FNC_WCHKR: /* wcheck = read */
|
case FNC_WCHKR: /* wcheck = read */
|
||||||
tufc = 0; /* clear frame count */
|
tufc = 0; /* clear frame count */
|
||||||
if (st = sim_tape_rdrecr (uptr, xbuf + 4, &tbc, MT_MAXFR)) { /* read rev */
|
if (st = sim_tape_rdrecr (uptr, xbuf + 4, &tbc, MT_MAXFR)) { /* read rev */
|
||||||
r = tu_map_err (drv, st); /* map error */
|
r = tu_map_err (drv, st, 1); /* map error */
|
||||||
break; } /* done */
|
break; } /* done */
|
||||||
for (i = 0; i < 4; i++) xbuf[i] = 0; /* pad with 0's */
|
for (i = 0; i < 4; i++) xbuf[i] = 0; /* pad with 0's */
|
||||||
if (fmt == TC_CDUMP) { /* core dump? */
|
if (fmt == TC_CDUMP) { /* core dump? */
|
||||||
|
@ -740,12 +742,13 @@ return;
|
||||||
|
|
||||||
/* Map tape error status */
|
/* Map tape error status */
|
||||||
|
|
||||||
t_stat tu_map_err (int32 drv, t_stat st)
|
t_stat tu_map_err (int32 drv, t_stat st, t_bool qdt)
|
||||||
{
|
{
|
||||||
switch (st) {
|
switch (st) {
|
||||||
case MTSE_FMT: /* illegal fmt */
|
case MTSE_FMT: /* illegal fmt */
|
||||||
case MTSE_UNATT: /* not attached */
|
case MTSE_UNATT: /* not attached */
|
||||||
tu_set_er (ER_NXF); /* can't execute */
|
tu_set_er (ER_NXF); /* can't execute */
|
||||||
|
if (qdt) mba_set_exc (tu_dib.ba); /* set exception */
|
||||||
break;
|
break;
|
||||||
case MTSE_TMK: /* end of file */
|
case MTSE_TMK: /* end of file */
|
||||||
tufs = tufs | FS_TMK;
|
tufs = tufs | FS_TMK;
|
||||||
|
@ -753,21 +756,25 @@ case MTSE_TMK: /* end of file */
|
||||||
break;
|
break;
|
||||||
case MTSE_IOERR: /* IO error */
|
case MTSE_IOERR: /* IO error */
|
||||||
tu_set_er (ER_VPE); /* flag error */
|
tu_set_er (ER_VPE); /* flag error */
|
||||||
mba_set_exc (tu_dib.ba); /* set exception */
|
if (qdt) mba_set_exc (tu_dib.ba); /* set exception */
|
||||||
return (tu_stopioe? SCPE_IOERR: SCPE_OK);
|
return (tu_stopioe? SCPE_IOERR: SCPE_OK);
|
||||||
case MTSE_INVRL: /* invalid rec lnt */
|
case MTSE_INVRL: /* invalid rec lnt */
|
||||||
tu_set_er (ER_VPE); /* flag error */
|
tu_set_er (ER_VPE); /* flag error */
|
||||||
|
if (qdt) mba_set_exc (tu_dib.ba); /* set exception */
|
||||||
return SCPE_MTRLNT;
|
return SCPE_MTRLNT;
|
||||||
case MTSE_RECE: /* record in error */
|
case MTSE_RECE: /* record in error */
|
||||||
tu_set_er (ER_CRC); /* set crc err */
|
tu_set_er (ER_CRC); /* set crc err */
|
||||||
|
if (qdt) mba_set_exc (tu_dib.ba); /* set exception */
|
||||||
break;
|
break;
|
||||||
case MTSE_EOM: /* end of medium */
|
case MTSE_EOM: /* end of medium */
|
||||||
tu_set_er (ER_OPI); /* incomplete */
|
tu_set_er (ER_OPI); /* incomplete */
|
||||||
|
if (qdt) mba_set_exc (tu_dib.ba); /* set exception */
|
||||||
break;
|
break;
|
||||||
case MTSE_BOT: /* reverse into BOT */
|
case MTSE_BOT: /* reverse into BOT */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
case MTSE_WRP: /* write protect */
|
case MTSE_WRP: /* write protect */
|
||||||
tu_set_er (ER_NXF); /* can't execute */
|
tu_set_er (ER_NXF); /* can't execute */
|
||||||
|
if (qdt) mba_set_exc (tu_dib.ba); /* set exception */
|
||||||
break;
|
break;
|
||||||
default: /* unknown error */
|
default: /* unknown error */
|
||||||
return SCPE_IERR; }
|
return SCPE_IERR; }
|
||||||
|
@ -822,6 +829,7 @@ t_stat tu_detach (UNIT* uptr)
|
||||||
{
|
{
|
||||||
int32 drv = uptr - tu_dev.units;
|
int32 drv = uptr - tu_dev.units;
|
||||||
|
|
||||||
|
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; /* attached? */
|
||||||
uptr->USTAT = 0; /* clear status flags */
|
uptr->USTAT = 0; /* clear status flags */
|
||||||
tu_update_fs (FS_ATA | FS_SSC, drv); /* update status */
|
tu_update_fs (FS_ATA | FS_SSC, drv); /* update status */
|
||||||
return sim_tape_detach (uptr);
|
return sim_tape_detach (uptr);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* pdp11_xu.c: DEUNA/DELUA ethernet controller simulator
|
/* pdp11_xu.c: DEUNA/DELUA ethernet controller simulator
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2003-2004, David T. Hittner
|
Copyright (c) 2003-2005, David T. Hittner
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -52,6 +52,7 @@
|
||||||
|
|
||||||
Modification history:
|
Modification history:
|
||||||
|
|
||||||
|
10-Mar-05 RMS Fixed equality test in RCSTAT (from Mark Hittinger)
|
||||||
16-Jan-04 DTH Added more info to SHOW MOD commands
|
16-Jan-04 DTH Added more info to SHOW MOD commands
|
||||||
09-Jan-04 DTH Made XU floating address so that XUB will float correctly
|
09-Jan-04 DTH Made XU floating address so that XUB will float correctly
|
||||||
08-Jan-04 DTH Added system_id message
|
08-Jan-04 DTH Added system_id message
|
||||||
|
@ -783,7 +784,7 @@ int32 xu_command(CTLR* xu)
|
||||||
if ((wstatus != SCPE_OK) || (wstatus2 != SCPE_OK) || (wstatus3 != SCPE_OK))
|
if ((wstatus != SCPE_OK) || (wstatus2 != SCPE_OK) || (wstatus3 != SCPE_OK))
|
||||||
return PCSR0_PCEI + 1;
|
return PCSR0_PCEI + 1;
|
||||||
|
|
||||||
if (fnc = FC_RCSTAT)
|
if (fnc == FC_RCSTAT)
|
||||||
xu->var->stat &= 0377; /* clear high byte */
|
xu->var->stat &= 0377; /* clear high byte */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* pdp18b_mt.c: 18b PDP magnetic tape simulator
|
/* pdp18b_mt.c: 18b PDP magnetic tape simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2004, Robert M Supnik
|
Copyright (c) 1993-2005, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -26,6 +26,7 @@
|
||||||
mt (PDP-9) TC59 magtape
|
mt (PDP-9) TC59 magtape
|
||||||
(PDP-15) TC59D magtape
|
(PDP-15) TC59D magtape
|
||||||
|
|
||||||
|
18-Mar-05 RMS Added attached test to detach routine
|
||||||
14-Jan-04 RMS Revised IO device call interface
|
14-Jan-04 RMS Revised IO device call interface
|
||||||
25-Apr-03 RMS Revised for extended file support
|
25-Apr-03 RMS Revised for extended file support
|
||||||
28-Mar-03 RMS Added multiformat support
|
28-Mar-03 RMS Added multiformat support
|
||||||
|
@ -471,6 +472,7 @@ return r;
|
||||||
|
|
||||||
t_stat mt_detach (UNIT* uptr)
|
t_stat mt_detach (UNIT* uptr)
|
||||||
{
|
{
|
||||||
|
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; /* attached? */
|
||||||
if (!sim_is_active (uptr)) uptr->USTAT = 0;
|
if (!sim_is_active (uptr)) uptr->USTAT = 0;
|
||||||
mt_updcsta (mt_dev.units + GET_UNIT (mt_cu), 0); /* update status */
|
mt_updcsta (mt_dev.units + GET_UNIT (mt_cu), 0); /* update status */
|
||||||
return sim_tape_detach (uptr);
|
return sim_tape_detach (uptr);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* pdp8_mt.c: PDP-8 magnetic tape simulator
|
/* pdp8_mt.c: PDP-8 magnetic tape simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2004, Robert M Supnik
|
Copyright (c) 1993-2005, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
mt TM8E/TU10 magtape
|
mt TM8E/TU10 magtape
|
||||||
|
|
||||||
|
18-Mar-05 RMS Added attached test to detach routine
|
||||||
25-Apr-03 RMS Revised for extended file support
|
25-Apr-03 RMS Revised for extended file support
|
||||||
29-Mar-03 RMS Added multiformat support
|
29-Mar-03 RMS Added multiformat support
|
||||||
04-Mar-03 RMS Fixed bug in SKTR
|
04-Mar-03 RMS Fixed bug in SKTR
|
||||||
|
@ -563,6 +564,7 @@ t_stat mt_detach (UNIT* uptr)
|
||||||
{
|
{
|
||||||
int32 u = uptr - mt_dev.units; /* get unit number */
|
int32 u = uptr - mt_dev.units; /* get unit number */
|
||||||
|
|
||||||
|
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; /* check for attached */
|
||||||
if (!sim_is_active (uptr)) uptr->USTAT = STA_REM;
|
if (!sim_is_active (uptr)) uptr->USTAT = STA_REM;
|
||||||
if (u == GET_UNIT (mt_cu)) mt_updcsta (uptr);
|
if (u == GET_UNIT (mt_cu)) mt_updcsta (uptr);
|
||||||
return sim_tape_detach (uptr);
|
return sim_tape_detach (uptr);
|
||||||
|
|
|
@ -1,403 +0,0 @@
|
||||||
/* vax780_defs.h: VAX 780 model-specific definitions file
|
|
||||||
|
|
||||||
Copyright (c) 2004, Robert M Supnik
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
copy of this software and associated documentation files (the "Software"),
|
|
||||||
to deal in the Software without restriction, including without limitation
|
|
||||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
Software is furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
||||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
Except as contained in this notice, the name of Robert M Supnik shall not
|
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
|
||||||
in this Software without prior written authorization from Robert M Supnik.
|
|
||||||
|
|
||||||
This file covers the VAX 11/780, the first VAX.
|
|
||||||
|
|
||||||
System memory map
|
|
||||||
|
|
||||||
0000 0000 - 1FFF FFFF main memory
|
|
||||||
|
|
||||||
2000 0000 - 2001 FFFF nexus register space
|
|
||||||
2002 0000 - 200F FFFF reserved
|
|
||||||
2010 0000 - 2013 FFFF Unibus address space, Unibus 0
|
|
||||||
2014 0000 - 2017 FFFF Unibus address space, Unibus 1
|
|
||||||
2018 0000 - 201B FFFF Unibus address space, Unibus 2
|
|
||||||
201C 0000 - 201F FFFF Unibus address space, Unibus 3
|
|
||||||
2020 0000 - 3FFF FFFF reserved
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Microcode constructs */
|
|
||||||
|
|
||||||
#ifndef FULL_VAX
|
|
||||||
#define FULL_VAX 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _VAX_780_DEFS_H_
|
|
||||||
#define _VAX_780_DEFS_H_ 1
|
|
||||||
|
|
||||||
#define VAX780_SID (1 << 24) /* system ID */
|
|
||||||
#define VAX780_ECO (7 << 19) /* ucode revision */
|
|
||||||
#define VAX780_PLANT (0 << 12) /* plant (Salem NH) */
|
|
||||||
#define VAX780_SN (1234)
|
|
||||||
#define CON_HLTPIN 0x0200 /* external CPU halt */
|
|
||||||
#define CON_HLTINS 0x0600 /* HALT instruction */
|
|
||||||
#define MCHK_RD_F 0x00 /* read fault */
|
|
||||||
#define MCHK_RD_A 0xF4 /* read abort */
|
|
||||||
#define MCHK_IBUF 0x0D /* read istream */
|
|
||||||
|
|
||||||
/* Interrupts */
|
|
||||||
|
|
||||||
#define IPL_HMAX 0x17 /* highest hwre level */
|
|
||||||
#define IPL_HMIN 0x14 /* lowest hwre level */
|
|
||||||
#define IPL_HLVL (IPL_HMAX - IPL_HMIN + 1) /* # hardware levels */
|
|
||||||
#define IPL_SMAX 0xF /* highest swre level */
|
|
||||||
|
|
||||||
/* Nexus constants */
|
|
||||||
|
|
||||||
#define NEXUS_NUM 16 /* number of nexus */
|
|
||||||
#define MCTL_NUM 2 /* number of mem ctrl */
|
|
||||||
#define MBA_NUM 2 /* number of MBA's */
|
|
||||||
#define TR_MCTL0 1 /* nexus assignments */
|
|
||||||
#define TR_MCTL1 2
|
|
||||||
#define TR_UBA 3
|
|
||||||
#define TR_MBA0 8
|
|
||||||
#define TR_MBA1 9
|
|
||||||
#define NEXUS_HLVL (IPL_HMAX - IPL_HMIN + 1)
|
|
||||||
#define SCB_NEXUS 0x100 /* nexus intr base */
|
|
||||||
#define SBI_FAULTS 0xFC000000 /* SBI fault flags */
|
|
||||||
|
|
||||||
/* Internal I/O interrupts - relative except for clock and console */
|
|
||||||
|
|
||||||
#define IPL_CLKINT 0x18 /* clock IPL */
|
|
||||||
#define IPL_TTINT 0x14 /* console IPL */
|
|
||||||
|
|
||||||
#define IPL_MCTL0 (0x15 - IPL_HMIN)
|
|
||||||
#define IPL_MCTL1 (0x15 - IPL_HMIN)
|
|
||||||
#define IPL_UBA (0x15 - IPL_HMIN)
|
|
||||||
#define IPL_MBA0 (0x15 - IPL_HMIN)
|
|
||||||
#define IPL_MBA1 (0x15 - IPL_HMIN)
|
|
||||||
|
|
||||||
/* Nexus interrupt macros */
|
|
||||||
|
|
||||||
#define SET_NEXUS_INT(dv) nexus_req[IPL_##dv] |= (1 << TR_##dv)
|
|
||||||
#define CLR_NEXUS_INT(dv) nexus_req[IPL_##dv] &= ~(1 << TR_##dv)
|
|
||||||
|
|
||||||
/* Machine specific IPRs */
|
|
||||||
|
|
||||||
#define MT_ACCS 40 /* FPA control */
|
|
||||||
#define MT_ACCR 41 /* FPA maint */
|
|
||||||
#define MT_WCSA 44 /* WCS address */
|
|
||||||
#define MT_WCSD 45 /* WCS data */
|
|
||||||
#define MT_SBIFS 48 /* SBI fault status */
|
|
||||||
#define MT_SBIS 49 /* SBI silo */
|
|
||||||
#define MT_SBISC 50 /* SBI silo comparator */
|
|
||||||
#define MT_SBIMT 51 /* SBI maint */
|
|
||||||
#define MT_SBIER 52 /* SBI error */
|
|
||||||
#define MT_SBITA 53 /* SBI timeout addr */
|
|
||||||
#define MT_SBIQC 54 /* SBI timeout clear */
|
|
||||||
#define MT_MBRK 60 /* microbreak */
|
|
||||||
|
|
||||||
/* Memory */
|
|
||||||
|
|
||||||
#define MAXMEMWIDTH 23 /* max mem, MS780C */
|
|
||||||
#define MAXMEMSIZE (1 << MAXMEMWIDTH)
|
|
||||||
#define MAXMEMWIDTH_X 27 /* max mem, MS780E */
|
|
||||||
#define MAXMEMSIZE_X (1 << MAXMEMWIDTH_X)
|
|
||||||
#define INITMEMSIZE (1 << MAXMEMWIDTH) /* initial memory size */
|
|
||||||
#define MEMSIZE (cpu_unit.capac)
|
|
||||||
#define ADDR_IS_MEM(x) (((uint32) (x)) < MEMSIZE)
|
|
||||||
|
|
||||||
/* Unibus I/O registers */
|
|
||||||
|
|
||||||
#define UBADDRWIDTH 18 /* Unibus addr width */
|
|
||||||
#define UBADDRSIZE (1u << UBADDRWIDTH) /* Unibus addr length */
|
|
||||||
#define UBADDRMASK (UBADDRSIZE - 1) /* Unibus addr mask */
|
|
||||||
#define IOPAGEAWIDTH 13 /* IO addr width */
|
|
||||||
#define IOPAGESIZE (1u << IOPAGEAWIDTH) /* IO page length */
|
|
||||||
#define IOPAGEMASK (IOPAGESIZE - 1) /* IO addr mask */
|
|
||||||
#define UBADDRBASE 0x20100000 /* Unibus addr base */
|
|
||||||
#define IOPAGEBASE 0x2013E000 /* IO page base */
|
|
||||||
#define ADDR_IS_IO(x) ((((uint32) (x)) >= UBADDRBASE) && \
|
|
||||||
(((uint32) (x)) < (UBADDRBASE + UBADDRSIZE)))
|
|
||||||
#define ADDR_IS_IOP(x) (((uint32) (x)) >= IOPAGEBASE)
|
|
||||||
|
|
||||||
/* Nexus register space */
|
|
||||||
|
|
||||||
#define REGAWIDTH 17 /* REG addr width */
|
|
||||||
#define REG_V_NEXUS 13 /* nexus number */
|
|
||||||
#define REG_M_NEXUS 0xF
|
|
||||||
#define REG_V_OFS 2 /* register number */
|
|
||||||
#define REG_M_OFS 0x7FF
|
|
||||||
#define REGSIZE (1u << REGAWIDTH) /* REG length */
|
|
||||||
#define REGBASE 0x20000000 /* REG addr base */
|
|
||||||
#define ADDR_IS_REG(x) ((((uint32) (x)) >= REGBASE) && \
|
|
||||||
(((uint32) (x)) < (REGBASE + REGSIZE)))
|
|
||||||
#define NEXUS_GETNEX(x) (((x) >> REG_V_NEXUS) & REG_M_NEXUS)
|
|
||||||
#define NEXUS_GETOFS(x) (((x) >> REG_V_OFS) & REG_M_OFS)
|
|
||||||
|
|
||||||
/* ROM address space in memory controllers */
|
|
||||||
|
|
||||||
#define ROMAWIDTH 12 /* ROM addr width */
|
|
||||||
#define ROMSIZE (1u << ROMAWIDTH) /* ROM size */
|
|
||||||
#define ROM0BASE (REGBASE + (TR_MCTL0 << REG_V_NEXUS) + 0x1000)
|
|
||||||
#define ROM1BASE (REGBASE + (TR_MCTL1 << REG_V_NEXUS) + 0x1000)
|
|
||||||
#define ADDR_IS_ROM0(x) ((((uint32) (x)) >= ROM0BASE) && \
|
|
||||||
(((uint32) (x)) < (ROM0BASE + ROMSIZE)))
|
|
||||||
#define ADDR_IS_ROM1(x) ((((uint32) (x)) >= ROM1BASE) && \
|
|
||||||
(((uint32) (x)) < (ROM1BASE + ROMSIZE)))
|
|
||||||
#define ADDR_IS_ROM(x) (ADDR_IS_ROM0 (x) || ADDR_IS_ROM1 (x))
|
|
||||||
|
|
||||||
/* Other address spaces */
|
|
||||||
|
|
||||||
#define ADDR_IS_CDG(x) (0)
|
|
||||||
#define ADDR_IS_NVR(x) (0)
|
|
||||||
|
|
||||||
/* Unibus I/O modes */
|
|
||||||
|
|
||||||
#define READ 0 /* PDP-11 compatibility */
|
|
||||||
#define WRITE (L_WORD)
|
|
||||||
#define WRITEB (L_BYTE)
|
|
||||||
|
|
||||||
/* Common CSI flags */
|
|
||||||
|
|
||||||
#define CSR_V_GO 0 /* go */
|
|
||||||
#define CSR_V_IE 6 /* interrupt enable */
|
|
||||||
#define CSR_V_DONE 7 /* done */
|
|
||||||
#define CSR_V_BUSY 11 /* busy */
|
|
||||||
#define CSR_V_ERR 15 /* error */
|
|
||||||
#define CSR_GO (1u << CSR_V_GO)
|
|
||||||
#define CSR_IE (1u << CSR_V_IE)
|
|
||||||
#define CSR_DONE (1u << CSR_V_DONE)
|
|
||||||
#define CSR_BUSY (1u << CSR_V_BUSY)
|
|
||||||
#define CSR_ERR (1u << CSR_V_ERR)
|
|
||||||
|
|
||||||
/* Timers */
|
|
||||||
|
|
||||||
#define TMR_CLK 0 /* 100Hz clock */
|
|
||||||
|
|
||||||
/* I/O system definitions */
|
|
||||||
|
|
||||||
#define DZ_MUXES 4 /* max # of DZV muxes */
|
|
||||||
#define DZ_LINES 8 /* lines per DZV mux */
|
|
||||||
#define VH_MUXES 4 /* max # of DHQ muxes */
|
|
||||||
#define MT_MAXFR (1 << 16) /* magtape max rec */
|
|
||||||
#define AUTO_LNT 34 /* autoconfig ranks */
|
|
||||||
|
|
||||||
#define DEV_V_UBUS (DEV_V_UF + 0) /* Unibus */
|
|
||||||
#define DEV_V_MBUS (DEV_V_UF + 1) /* Massbus */
|
|
||||||
#define DEV_V_NEXUS (DEV_V_UF + 2) /* Nexus */
|
|
||||||
#define DEV_V_FLTA (DEV_V_UF + 3) /* flt addr */
|
|
||||||
#define DEV_V_FFUF (DEV_V_UF + 4) /* first free flag */
|
|
||||||
#define DEV_UBUS (1u << DEV_V_UBUS)
|
|
||||||
#define DEV_MBUS (1u << DEV_V_MBUS)
|
|
||||||
#define DEV_NEXUS (1u << DEV_V_NEXUS)
|
|
||||||
#define DEV_FLTA (1u << DEV_V_FLTA)
|
|
||||||
#define DEV_QBUS (0)
|
|
||||||
#define DEV_Q18 (0)
|
|
||||||
|
|
||||||
#define UNIBUS TRUE /* Unibus only */
|
|
||||||
|
|
||||||
#define DEV_RDX 16 /* default device radix */
|
|
||||||
|
|
||||||
/* Device information block
|
|
||||||
|
|
||||||
For Massbus devices,
|
|
||||||
ba = Massbus number
|
|
||||||
lnt = Massbus ctrl type
|
|
||||||
ack[0] = abort routine
|
|
||||||
|
|
||||||
For Nexus devices,
|
|
||||||
ba = Nexus number
|
|
||||||
lnt = number of consecutive nexi */
|
|
||||||
|
|
||||||
#define VEC_DEVMAX 4 /* max device vec */
|
|
||||||
|
|
||||||
struct pdp_dib {
|
|
||||||
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);
|
|
||||||
int32 vnum; /* vectors: number */
|
|
||||||
int32 vloc; /* locator */
|
|
||||||
int32 vec; /* value */
|
|
||||||
int32 (*ack[VEC_DEVMAX])(void); /* ack routine */
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct pdp_dib DIB;
|
|
||||||
|
|
||||||
/* Unibus I/O page layout - XUB,RQB,RQC,RQD float based on number of DZ's
|
|
||||||
Massbus devices (RP, TU) do not appear in the Unibus IO page */
|
|
||||||
|
|
||||||
#define IOBA_DZ (IOPAGEBASE + 000100) /* DZ11 */
|
|
||||||
#define IOLN_DZ 010
|
|
||||||
#define IOBA_XUB (IOPAGEBASE + 000330 + (020 * (DZ_MUXES / 2)))
|
|
||||||
#define IOLN_XUB 010
|
|
||||||
#define IOBA_RQB (IOPAGEBASE + 000334 + (020 * (DZ_MUXES / 2)))
|
|
||||||
#define IOLN_RQB 004
|
|
||||||
#define IOBA_RQC (IOPAGEBASE + IOBA_RQB + IOLN_RQB)
|
|
||||||
#define IOLN_RQC 004
|
|
||||||
#define IOBA_RQD (IOPAGEBASE + IOBA_RQC + IOLN_RQC)
|
|
||||||
#define IOLN_RQD 004
|
|
||||||
#define IOBA_RQ (IOPAGEBASE + 012150) /* UDA50 */
|
|
||||||
#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_TQ (IOPAGEBASE + 014500) /* TMSCP */
|
|
||||||
#define IOLN_TQ 004
|
|
||||||
#define IOBA_XU (IOPAGEBASE + 014510) /* DEUNA/DELUA */
|
|
||||||
#define IOLN_XU 010
|
|
||||||
#define IOBA_RX (IOPAGEBASE + 017170) /* RX11 */
|
|
||||||
#define IOLN_RX 004
|
|
||||||
#define IOBA_RY (IOPAGEBASE + 017170) /* RXV21 */
|
|
||||||
#define IOLN_RY 004
|
|
||||||
#define IOBA_HK (IOPAGEBASE + 017440) /* RK611 */
|
|
||||||
#define IOLN_HK 040
|
|
||||||
#define IOBA_LPT (IOPAGEBASE + 017514) /* LP11 */
|
|
||||||
#define IOLN_LPT 004
|
|
||||||
#define IOBA_PTR (IOPAGEBASE + 017550) /* PC11 reader */
|
|
||||||
#define IOLN_PTR 004
|
|
||||||
#define IOBA_PTP (IOPAGEBASE + 017554) /* PC11 punch */
|
|
||||||
#define IOLN_PTP 004
|
|
||||||
|
|
||||||
/* Interrupt assignments; within each level, priority is right to left */
|
|
||||||
|
|
||||||
#define INT_V_DZRX 0 /* BR5 */
|
|
||||||
#define INT_V_DZTX 1
|
|
||||||
#define INT_V_HK 2
|
|
||||||
#define INT_V_RL 3
|
|
||||||
#define INT_V_RQ 4
|
|
||||||
#define INT_V_TQ 5
|
|
||||||
#define INT_V_TS 6
|
|
||||||
#define INT_V_RY 7
|
|
||||||
#define INT_V_XU 8
|
|
||||||
|
|
||||||
#define INT_V_LPT 0 /* BR4 */
|
|
||||||
#define INT_V_PTR 1
|
|
||||||
#define INT_V_PTP 2
|
|
||||||
|
|
||||||
#define INT_DZRX (1u << INT_V_DZRX)
|
|
||||||
#define INT_DZTX (1u << INT_V_DZTX)
|
|
||||||
#define INT_HK (1u << INT_V_HK)
|
|
||||||
#define INT_RL (1u << INT_V_RL)
|
|
||||||
#define INT_RQ (1u << INT_V_RQ)
|
|
||||||
#define INT_TQ (1u << INT_V_TQ)
|
|
||||||
#define INT_TS (1u << INT_V_TS)
|
|
||||||
#define INT_RY (1u << INT_V_RY)
|
|
||||||
#define INT_XU (1u << INT_V_XU)
|
|
||||||
#define INT_PTR (1u << INT_V_PTR)
|
|
||||||
#define INT_PTP (1u << INT_V_PTP)
|
|
||||||
#define INT_LPT (1u << INT_V_LPT)
|
|
||||||
|
|
||||||
#define IPL_DZRX (0x15 - IPL_HMIN)
|
|
||||||
#define IPL_DZTX (0x15 - IPL_HMIN)
|
|
||||||
#define IPL_HK (0x15 - IPL_HMIN)
|
|
||||||
#define IPL_RL (0x15 - IPL_HMIN)
|
|
||||||
#define IPL_RQ (0x15 - IPL_HMIN)
|
|
||||||
#define IPL_TQ (0x15 - IPL_HMIN)
|
|
||||||
#define IPL_TS (0x15 - IPL_HMIN)
|
|
||||||
#define IPL_RY (0x15 - IPL_HMIN)
|
|
||||||
#define IPL_XU (0x15 - IPL_HMIN)
|
|
||||||
#define IPL_PTR (0x14 - IPL_HMIN)
|
|
||||||
#define IPL_PTP (0x14 - IPL_HMIN)
|
|
||||||
#define IPL_LPT (0x14 - IPL_HMIN)
|
|
||||||
|
|
||||||
/* Device vectors */
|
|
||||||
|
|
||||||
#define VEC_Q 0000
|
|
||||||
#define VEC_PTR 0070
|
|
||||||
#define VEC_PTP 0074
|
|
||||||
#define VEC_XU 0120
|
|
||||||
#define VEC_RQ 0154
|
|
||||||
#define VEC_RL 0160
|
|
||||||
#define VEC_LPT 0200
|
|
||||||
#define VEC_HK 0210
|
|
||||||
#define VEC_TS 0224
|
|
||||||
#define VEC_TQ 0260
|
|
||||||
#define VEC_RX 0264
|
|
||||||
#define VEC_RY 0264
|
|
||||||
#define VEC_DZRX 0300
|
|
||||||
#define VEC_DZTX 0304
|
|
||||||
|
|
||||||
/* Autoconfigure ranks */
|
|
||||||
|
|
||||||
#define RANK_DZ 8
|
|
||||||
#define RANK_RL 14
|
|
||||||
#define RANK_RX 18
|
|
||||||
#define RANK_XU 25
|
|
||||||
#define RANK_RQ 26
|
|
||||||
#define RANK_TQ 30
|
|
||||||
#define RANK_VH 32
|
|
||||||
|
|
||||||
/* Interrupt macros */
|
|
||||||
|
|
||||||
#define IVCL(dv) ((IPL_##dv * 32) + INT_V_##dv)
|
|
||||||
#define NVCL(dv) ((IPL_##dv * 32) + TR_##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)
|
|
||||||
#define IORETURN(f,v) ((f)? (v): SCPE_OK) /* cond error return */
|
|
||||||
|
|
||||||
/* Logging */
|
|
||||||
|
|
||||||
#define LOG_CPU_I 0x1 /* intexc */
|
|
||||||
#define LOG_CPU_R 0x2 /* REI */
|
|
||||||
#define LOG_CPU_P 0x4 /* context */
|
|
||||||
|
|
||||||
/* Massbus definitions */
|
|
||||||
|
|
||||||
#define MBA_RP (TR_MBA0 - TR_MBA0) /* MBA for RP */
|
|
||||||
#define MBA_TU (TR_MBA1 - TR_MBA0) /* MBA for TU */
|
|
||||||
#define MBA_RMASK 0x1F /* max 32 reg */
|
|
||||||
#define MBE_NXD 1 /* nx drive */
|
|
||||||
#define MBE_NXR 2 /* nx reg */
|
|
||||||
#define MBE_GOE 3 /* err on GO */
|
|
||||||
|
|
||||||
/* Boot definitions */
|
|
||||||
|
|
||||||
#define BOOT_MB 0 /* device codes */
|
|
||||||
#define BOOT_HK 1 /* for VMB */
|
|
||||||
#define BOOT_RL 2
|
|
||||||
#define BOOT_UDA 17
|
|
||||||
#define BOOT_TK 18
|
|
||||||
|
|
||||||
/* Function prototypes for I/O */
|
|
||||||
|
|
||||||
t_bool map_addr (uint32 qa, uint32 *ma);
|
|
||||||
int32 Map_ReadB (uint32 ba, int32 bc, uint8 *buf);
|
|
||||||
int32 Map_ReadW (uint32 ba, int32 bc, uint16 *buf);
|
|
||||||
int32 Map_WriteB (uint32 ba, int32 bc, uint8 *buf);
|
|
||||||
int32 Map_WriteW (uint32 ba, int32 bc, uint16 *buf);
|
|
||||||
|
|
||||||
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_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);
|
|
||||||
|
|
||||||
int32 mba_rdbufW (uint32 mbus, int32 bc, uint16 *buf);
|
|
||||||
int32 mba_wrbufW (uint32 mbus, int32 bc, uint16 *buf);
|
|
||||||
int32 mba_chbufW (uint32 mbus, int32 bc, uint16 *buf);
|
|
||||||
int32 mba_get_bc (uint32 mbus);
|
|
||||||
void mba_upd_ata (uint32 mbus, uint32 val);
|
|
||||||
void mba_set_exc (uint32 mbus);
|
|
||||||
void mba_set_don (uint32 mbus);
|
|
||||||
t_stat mba_show_num (FILE *st, UNIT *uptr, int32 val, void *desc);
|
|
||||||
|
|
||||||
t_stat show_nexus (FILE *st, UNIT *uptr, int32 val, void *desc);
|
|
||||||
|
|
||||||
#endif
|
|
1079
VAX/vax780_doc.txt
1079
VAX/vax780_doc.txt
File diff suppressed because it is too large
Load diff
696
VAX/vax780_mba.c
696
VAX/vax780_mba.c
|
@ -1,696 +0,0 @@
|
||||||
/* vax780_mba.c: VAX 11/780 Massbus adapter
|
|
||||||
|
|
||||||
Copyright (c) 2004, Robert M Supnik
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
copy of this software and associated documentation files (the "Software"),
|
|
||||||
to deal in the Software without restriction, including without limitation
|
|
||||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
Software is furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
||||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
Except as contained in this notice, the name of Robert M Supnik shall not
|
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
|
||||||
in this Software without prior written authorization from Robert M Supnik.
|
|
||||||
|
|
||||||
mba0, mba1 RH780 Massbus adapter
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "vax_defs.h"
|
|
||||||
|
|
||||||
/* Massbus */
|
|
||||||
|
|
||||||
#define MBA_NMAPR 256 /* number of map reg */
|
|
||||||
#define MBA_V_RTYPE 10 /* nexus addr: reg type */
|
|
||||||
#define MBA_M_RTYPE 0x3
|
|
||||||
#define MBART_INT 0x0 /* internal */
|
|
||||||
#define MBART_EXT 0x1 /* external */
|
|
||||||
#define MBART_MAP 0x2 /* map */
|
|
||||||
#define MBA_V_INTOFS 2 /* int reg: reg ofs */
|
|
||||||
#define MBA_M_INTOFS 0xFF
|
|
||||||
#define MBA_V_DRV 7 /* ext reg: drive num */
|
|
||||||
#define MBA_M_DRV 0x7
|
|
||||||
#define MBA_V_DEVOFS 2 /* ext reg: reg ofs */
|
|
||||||
#define MBA_M_DEVOFS 0x1F
|
|
||||||
#define MBA_RTYPE(x) (((x) >> MBA_V_RTYPE) & MBA_M_RTYPE)
|
|
||||||
#define MBA_INTOFS(x) (((x) >> MBA_V_INTOFS) & MBA_M_INTOFS)
|
|
||||||
#define MBA_EXTDRV(x) (((x) >> MBA_V_DRV) & MBA_M_DRV)
|
|
||||||
#define MBA_EXTOFS(x) (((x) >> MBA_V_DEVOFS) & MBA_M_DEVOFS)
|
|
||||||
|
|
||||||
/* Massbus configuration register */
|
|
||||||
|
|
||||||
#define MBACNF_OF 0x0
|
|
||||||
#define MBACNF_ADPDN 0x00800000 /* adap pdn - ni */
|
|
||||||
#define MBACNF_ADPUP 0x00400000 /* adap pup - ni */
|
|
||||||
#define MBACNF_CODE 0x00000020
|
|
||||||
#define MBACNF_RD (SBI_FAULTS|MBACNF_W1C)
|
|
||||||
#define MBACNF_W1C 0x00C00000
|
|
||||||
|
|
||||||
/* Control register */
|
|
||||||
|
|
||||||
#define MBACR_OF 0x1
|
|
||||||
#define MBACR_MNT 0x00000008 /* maint */
|
|
||||||
#define MBACR_IE 0x00000004 /* int enable */
|
|
||||||
#define MBACR_ABORT 0x00000002 /* abort */
|
|
||||||
#define MBACR_INIT 0x00000001
|
|
||||||
#define MBACR_RD 0x0000000E
|
|
||||||
#define MBACR_WR 0x0000000E
|
|
||||||
|
|
||||||
/* Status register */
|
|
||||||
|
|
||||||
#define MBASR_OF 0x2
|
|
||||||
#define MBASR_DTBUSY 0x80000000 /* DT busy RO */
|
|
||||||
#define MBASR_NRCONF 0x40000000 /* no conf - ni W1C */
|
|
||||||
#define MBASR_CRD 0x20000000 /* CRD - ni W1C */
|
|
||||||
#define MBASR_CBH 0x00800000 /* CBHUNG - ni W1C */
|
|
||||||
#define MBASR_PGE 0x00080000 /* prog err - W1C int */
|
|
||||||
#define MBASR_NFD 0x00040000 /* nx drive - W1C int */
|
|
||||||
#define MBASR_MCPE 0x00020000 /* ctl perr - ni W1C int */
|
|
||||||
#define MBASR_ATA 0x00010000 /* attn - W1C int */
|
|
||||||
#define MBASR_SPE 0x00004000 /* silo perr - ni W1C int */
|
|
||||||
#define MBASR_DTCMP 0x00002000 /* xfr done - W1C int */
|
|
||||||
#define MBASR_DTABT 0x00001000 /* abort - W1C int */
|
|
||||||
#define MBASR_DLT 0x00000800 /* dat late - ni W1C abt */
|
|
||||||
#define MBASR_WCEU 0x00000400 /* wrchk upper - W1C abt */
|
|
||||||
#define MBASR_WCEL 0x00000200 /* wrchk lower - W1C abt */
|
|
||||||
#define MBASR_MXF 0x00000100 /* miss xfr - ni W1C abt */
|
|
||||||
#define MBASR_MBEXC 0x00000080 /* except - ni W1C abt */
|
|
||||||
#define MBASR_MBDPE 0x00000040 /* dat perr - ni W1C abt */
|
|
||||||
#define MBASR_MAPPE 0x00000020 /* map perr - ni W1C abt */
|
|
||||||
#define MBASR_INVM 0x00000010 /* inv map - W1C abt */
|
|
||||||
#define MBASR_ERCONF 0x00000008 /* err conf - ni W1C abt */
|
|
||||||
#define MBASR_RDS 0x00000004 /* RDS - ni W1C abt */
|
|
||||||
#define MBASR_ITMO 0x00000002 /* timeout - W1C abt */
|
|
||||||
#define MBASR_RTMO 0x00000001 /* rd timeout - W1C abt */
|
|
||||||
#define MBASR_RD 0xE08F7FFF
|
|
||||||
#define MBASR_W1C 0x608F7FFF
|
|
||||||
#define MBASR_ABORTS 0x00000FFF
|
|
||||||
#define MBASR_INTR 0x000F7000
|
|
||||||
|
|
||||||
/* Virtual address register */
|
|
||||||
|
|
||||||
#define MBAVA_OF 0x3
|
|
||||||
#define MBAVA_RD 0x0001FFFF
|
|
||||||
#define MBAVA_WR (MBAVA_RD)
|
|
||||||
|
|
||||||
/* Byte count */
|
|
||||||
|
|
||||||
#define MBABC_OF 0x4
|
|
||||||
#define MBABC_RD 0xFFFFFFFF
|
|
||||||
#define MBABC_WR 0x0000FFFF
|
|
||||||
#define MBABC_V_CNT 16 /* active count */
|
|
||||||
|
|
||||||
/* Diagnostic register */
|
|
||||||
|
|
||||||
#define MBADR_OF 0x5
|
|
||||||
#define MBADR_RD 0xFFFFFFFF
|
|
||||||
#define MBADR_WR 0xFFC00000
|
|
||||||
|
|
||||||
/* Selected map entry - read only */
|
|
||||||
|
|
||||||
#define MBASMR_OF 0x6
|
|
||||||
#define MBASMR_RD (MBAMAP_RD)
|
|
||||||
|
|
||||||
/* Command register (SBI) - read only */
|
|
||||||
|
|
||||||
#define MBACMD_OF 0x7
|
|
||||||
|
|
||||||
/* External registers */
|
|
||||||
|
|
||||||
#define MBA_CS1 0x00 /* device CSR1 */
|
|
||||||
#define MBA_CS1_WR 0x3F /* writeable bits */
|
|
||||||
#define MBA_CS1_DT 0x28 /* >= for data xfr */
|
|
||||||
|
|
||||||
/* Map registers */
|
|
||||||
|
|
||||||
#define MBAMAP_VLD 0x80000000 /* valid */
|
|
||||||
#define MBAMAP_PAG 0x001FFFFF
|
|
||||||
#define MBAMAP_RD (MBAMAP_VLD | MBAMAP_PAG)
|
|
||||||
#define MBAMAP_WR (MBAMAP_RD)
|
|
||||||
|
|
||||||
struct mbctx {
|
|
||||||
uint32 cnf; /* config reg */
|
|
||||||
uint32 cr; /* control reg */
|
|
||||||
uint32 sr; /* status reg */
|
|
||||||
uint32 va; /* virt addr */
|
|
||||||
uint32 bc; /* byte count */
|
|
||||||
uint32 dr; /* diag reg */
|
|
||||||
uint32 smr; /* sel map reg */
|
|
||||||
uint32 map[MBA_NMAPR]; /* map */
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct mbctx MBACTX;
|
|
||||||
MBACTX massbus[MBA_NUM];
|
|
||||||
|
|
||||||
extern uint32 nexus_req[NEXUS_HLVL];
|
|
||||||
extern UNIT cpu_unit;
|
|
||||||
extern FILE *sim_log;
|
|
||||||
extern int32 sim_switches;
|
|
||||||
|
|
||||||
t_stat mba_reset (DEVICE *dptr);
|
|
||||||
t_stat mba_rdreg (int32 *val, int32 pa, int32 mode);
|
|
||||||
t_stat mba_wrreg (int32 val, int32 pa, int32 lnt);
|
|
||||||
t_bool mba_map_addr (uint32 va, uint32 *ma, uint32 mb);
|
|
||||||
void mba_set_int (uint32 mb);
|
|
||||||
void mba_clr_int (uint32 mb);
|
|
||||||
void mba_upd_sr (uint32 set, uint32 clr, uint32 mb);
|
|
||||||
DEVICE mba0_dev, mba1_dev;
|
|
||||||
DIB mba0_dib, mba1_dib;
|
|
||||||
|
|
||||||
extern int32 ReadB (uint32 pa);
|
|
||||||
extern int32 ReadW (uint32 pa);
|
|
||||||
extern int32 ReadL (uint32 pa);
|
|
||||||
extern void WriteB (uint32 pa, int32 val);
|
|
||||||
extern void WriteW (uint32 pa, int32 val);
|
|
||||||
extern void WriteL (uint32 pa, int32 val);
|
|
||||||
|
|
||||||
/* Maps */
|
|
||||||
|
|
||||||
static MBACTX *ctxmap[MBA_NUM] = { &massbus[0], &massbus[1] };
|
|
||||||
static DEVICE *devmap[MBA_NUM] = { &mba0_dev, &mba1_dev };
|
|
||||||
|
|
||||||
/* Massbus register dispatches */
|
|
||||||
|
|
||||||
static t_stat (*mbregR[MBA_NUM])(int32 *dat, int32 ad, int32 md);
|
|
||||||
static t_stat (*mbregW[MBA_NUM])(int32 dat, int32 ad, int32 md);
|
|
||||||
static int32 (*mbabort[MBA_NUM])(void);
|
|
||||||
|
|
||||||
/* Massbus adapter data structures
|
|
||||||
|
|
||||||
mba_dev UBA device descriptor
|
|
||||||
mba_unit UBA units
|
|
||||||
mba_reg UBA register list
|
|
||||||
*/
|
|
||||||
|
|
||||||
DIB mba0_dib = { TR_MBA0, 0, &mba_rdreg, &mba_wrreg, 0, NVCL (MBA0) };
|
|
||||||
|
|
||||||
UNIT mba0_unit = { UDATA (NULL, 0, 0) };
|
|
||||||
|
|
||||||
REG mba0_reg[] = {
|
|
||||||
{ HRDATA (CNFR, massbus[0].cnf, 32) },
|
|
||||||
{ HRDATA (CR, massbus[0].cr, 4) },
|
|
||||||
{ HRDATA (SR, massbus[0].sr, 32) },
|
|
||||||
{ HRDATA (VA, massbus[0].va, 17) },
|
|
||||||
{ HRDATA (BC, massbus[0].bc, 32) },
|
|
||||||
{ HRDATA (DR, massbus[0].dr, 32) },
|
|
||||||
{ HRDATA (SMR, massbus[0].dr, 32) },
|
|
||||||
{ BRDATA (MAP, massbus[0].map, 16, 32, MBA_NMAPR) },
|
|
||||||
{ FLDATA (NEXINT, nexus_req[IPL_MBA0], TR_MBA0) },
|
|
||||||
{ NULL } };
|
|
||||||
|
|
||||||
MTAB mba0_mod[] = {
|
|
||||||
{ MTAB_XTD|MTAB_VDV, TR_MBA0, "NEXUS", NULL,
|
|
||||||
NULL, &show_nexus },
|
|
||||||
{ 0 } };
|
|
||||||
|
|
||||||
DEVICE mba0_dev = {
|
|
||||||
"MBA0", &mba0_unit, mba0_reg, mba0_mod,
|
|
||||||
1, 0, 0, 0, 0, 0,
|
|
||||||
NULL, NULL, &mba_reset,
|
|
||||||
NULL, NULL, NULL,
|
|
||||||
&mba0_dib, DEV_NEXUS };
|
|
||||||
|
|
||||||
DIB mba1_dib = { TR_MBA1, 0, &mba_rdreg, &mba_wrreg, 0, NVCL (MBA0) };
|
|
||||||
|
|
||||||
UNIT mba1_unit = { UDATA (NULL, 0, 0) };
|
|
||||||
|
|
||||||
MTAB mba1_mod[] = {
|
|
||||||
{ MTAB_XTD|MTAB_VDV, TR_MBA1, "NEXUS", NULL,
|
|
||||||
NULL, &show_nexus },
|
|
||||||
{ 0 } };
|
|
||||||
|
|
||||||
REG mba1_reg[] = {
|
|
||||||
{ HRDATA (CNFR, massbus[1].cnf, 32) },
|
|
||||||
{ HRDATA (CR, massbus[1].cr, 4) },
|
|
||||||
{ HRDATA (SR, massbus[1].sr, 32) },
|
|
||||||
{ HRDATA (VA, massbus[1].va, 17) },
|
|
||||||
{ HRDATA (BC, massbus[1].bc, 32) },
|
|
||||||
{ HRDATA (DR, massbus[1].dr, 32) },
|
|
||||||
{ HRDATA (SMR, massbus[1].dr, 32) },
|
|
||||||
{ BRDATA (MAP, massbus[1].map, 16, 32, MBA_NMAPR) },
|
|
||||||
{ FLDATA (NEXINT, nexus_req[IPL_MBA1], TR_MBA1) },
|
|
||||||
{ NULL } };
|
|
||||||
|
|
||||||
DEVICE mba1_dev = {
|
|
||||||
"MBA1", &mba1_unit, mba1_reg, mba1_mod,
|
|
||||||
1, 0, 0, 0, 0, 0,
|
|
||||||
NULL, NULL, &mba_reset,
|
|
||||||
NULL, NULL, NULL,
|
|
||||||
&mba1_dib, DEV_NEXUS };
|
|
||||||
|
|
||||||
/* Read Massbus adapter register */
|
|
||||||
|
|
||||||
t_stat mba_rdreg (int32 *val, int32 pa, int32 mode)
|
|
||||||
{
|
|
||||||
int32 mb, ofs, drv, rtype;
|
|
||||||
t_stat r;
|
|
||||||
MBACTX *mbp;
|
|
||||||
|
|
||||||
mb = NEXUS_GETNEX (pa) - TR_MBA0; /* get MBA */
|
|
||||||
if (mb >= MBA_NUM) return SCPE_NXM; /* valid? */
|
|
||||||
mbp = ctxmap[mb]; /* get context */
|
|
||||||
rtype = MBA_RTYPE (pa); /* get reg type */
|
|
||||||
|
|
||||||
switch (rtype) { /* case on type */
|
|
||||||
|
|
||||||
case MBART_INT: /* internal */
|
|
||||||
ofs = MBA_INTOFS (pa); /* check range */
|
|
||||||
switch (ofs) {
|
|
||||||
case MBACNF_OF: /* CNF */
|
|
||||||
*val = (mbp->cnf & MBACNF_RD) | MBACNF_CODE;
|
|
||||||
break;
|
|
||||||
case MBACR_OF: /* CR */
|
|
||||||
*val = mbp->cr & MBACR_RD;
|
|
||||||
break;
|
|
||||||
case MBASR_OF: /* SR */
|
|
||||||
*val = mbp->sr & MBASR_RD;
|
|
||||||
break;
|
|
||||||
case MBAVA_OF: /* VA */
|
|
||||||
*val = mbp->va & MBAVA_RD;
|
|
||||||
break;
|
|
||||||
case MBABC_OF: /* BC */
|
|
||||||
*val = mbp->bc & MBABC_RD;
|
|
||||||
break;
|
|
||||||
case MBADR_OF: /* DR */
|
|
||||||
*val = mbp->dr & MBADR_RD;
|
|
||||||
break;
|
|
||||||
case MBASMR_OF: /* SMR */
|
|
||||||
*val = mbp->smr & MBASMR_RD;
|
|
||||||
break;
|
|
||||||
case MBACMD_OF: /* CMD */
|
|
||||||
*val = 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return SCPE_NXM;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MBART_EXT: /* external */
|
|
||||||
if (!mbregR[mb]) return SCPE_NXM; /* device there? */
|
|
||||||
drv = MBA_EXTDRV (pa); /* get dev num */
|
|
||||||
ofs = MBA_EXTOFS (pa); /* get reg offs */
|
|
||||||
r = mbregR[mb] (val, ofs, drv); /* call device */
|
|
||||||
if (r == MBE_NXD) mba_upd_sr (MBASR_NFD, 0, mb);/* nx drive? */
|
|
||||||
else if (r == MBE_NXR) return SCPE_NXM; /* nx reg? */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MBART_MAP: /* map */
|
|
||||||
ofs = MBA_INTOFS (pa);
|
|
||||||
*val = mbp->map[ofs] & MBAMAP_RD;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return SCPE_NXM; }
|
|
||||||
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write Massbus adapter register */
|
|
||||||
|
|
||||||
t_stat mba_wrreg (int32 val, int32 pa, int32 lnt)
|
|
||||||
{
|
|
||||||
int32 mb, ofs, drv, rtype;
|
|
||||||
t_stat r;
|
|
||||||
t_bool cs1dt;
|
|
||||||
MBACTX *mbp;
|
|
||||||
|
|
||||||
mb = NEXUS_GETNEX (pa) - TR_MBA0; /* get MBA */
|
|
||||||
if (mb >= MBA_NUM) return SCPE_NXM; /* valid? */
|
|
||||||
mbp = ctxmap[mb]; /* get context */
|
|
||||||
rtype = MBA_RTYPE (pa); /* get reg type */
|
|
||||||
|
|
||||||
switch (rtype) { /* case on type */
|
|
||||||
|
|
||||||
case MBART_INT: /* internal */
|
|
||||||
ofs = MBA_INTOFS (pa); /* check range */
|
|
||||||
switch (ofs) {
|
|
||||||
case MBACNF_OF: /* CNF */
|
|
||||||
mbp->cnf = mbp->cnf & ~(val & MBACNF_W1C);
|
|
||||||
break;
|
|
||||||
case MBACR_OF: /* CR */
|
|
||||||
if (val & MBACR_INIT) /* init? */
|
|
||||||
mba_reset (devmap[mb]); /* reset MBA */
|
|
||||||
if ((val & MBACR_ABORT) && (mbp->sr & MBASR_DTBUSY)) {
|
|
||||||
if (mbabort[mb]) mbabort[mb] (); /* abort? */
|
|
||||||
mba_upd_sr (MBASR_DTABT, 0, mb); }
|
|
||||||
if ((val & MBACR_MNT) && (mbp->sr & MBASR_DTBUSY)) {
|
|
||||||
mba_upd_sr (MBASR_PGE, 0, mb); /* mnt & xfer? */
|
|
||||||
val = val & ~MBACR_MNT; }
|
|
||||||
if ((val & MBACR_IE) == 0) mba_clr_int (mb);
|
|
||||||
mbp->cr = (mbp->cr & ~MBACR_WR) | (val & MBACR_WR);
|
|
||||||
break;
|
|
||||||
case MBASR_OF: /* SR */
|
|
||||||
mbp->sr = mbp->sr & ~(val & MBASR_W1C);
|
|
||||||
break;
|
|
||||||
case MBAVA_OF: /* VA */
|
|
||||||
if (mbp->sr & MBASR_DTBUSY) /* err if xfr */
|
|
||||||
mba_upd_sr (MBASR_PGE, 0, mb);
|
|
||||||
else mbp->va = val & MBAVA_WR;
|
|
||||||
break;
|
|
||||||
case MBABC_OF: /* BC */
|
|
||||||
if (mbp->sr & MBASR_DTBUSY) /* err if xfr */
|
|
||||||
mba_upd_sr (MBASR_PGE, 0, mb);
|
|
||||||
else {
|
|
||||||
val = val & MBABC_WR;
|
|
||||||
mbp->bc = (val << MBABC_V_CNT) | val;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MBADR_OF: /* DR */
|
|
||||||
mbp->dr = (mbp->dr & ~MBADR_WR) | (val & MBADR_WR);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return SCPE_NXM;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MBART_EXT: /* external */
|
|
||||||
if (!mbregW[mb]) return SCPE_NXM; /* device there? */
|
|
||||||
drv = MBA_EXTDRV (pa); /* get dev num */
|
|
||||||
ofs = MBA_EXTOFS (pa); /* get reg offs */
|
|
||||||
cs1dt = (ofs == MBA_CS1) && (val & CSR_GO) && /* starting xfr? */
|
|
||||||
((val & MBA_CS1_WR) >= MBA_CS1_DT);
|
|
||||||
if (cs1dt && (mbp->sr & MBASR_DTBUSY)) { /* xfr while busy? */
|
|
||||||
mba_upd_sr (MBASR_PGE, 0, mb); /* prog error */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
r = mbregW[mb] (val, ofs, drv); /* write dev reg */
|
|
||||||
if (r == MBE_NXD) mba_upd_sr (MBASR_NFD, 0, mb);/* nx drive? */
|
|
||||||
else if (r == MBE_NXR) return SCPE_NXM; /* nx reg? */
|
|
||||||
if (cs1dt && (r == SCPE_OK)) /* did dt start? */
|
|
||||||
mbp->sr = (mbp->sr | MBASR_DTBUSY) & ~MBASR_W1C;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MBART_MAP: /* map */
|
|
||||||
ofs = MBA_INTOFS (pa);
|
|
||||||
mbp->map[ofs] = val & MBAMAP_WR;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return SCPE_NXM; }
|
|
||||||
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Massbus I/O routine
|
|
||||||
|
|
||||||
mb_rdbufW - fetch word buffer from memory
|
|
||||||
mb_wrbufW - store word buffer into memory
|
|
||||||
mb_chbufW - compare word buffer with memory
|
|
||||||
|
|
||||||
Returns number of bytes successfully transferred/checked
|
|
||||||
*/
|
|
||||||
|
|
||||||
int32 mba_rdbufW (uint32 mb, int32 bc, uint16 *buf)
|
|
||||||
{
|
|
||||||
MBACTX *mbp;
|
|
||||||
int32 i, j, ba, mbc, pbc;
|
|
||||||
uint32 pa, dat;
|
|
||||||
|
|
||||||
if (mb >= MBA_NUM) return 0; /* valid MBA? */
|
|
||||||
mbp = ctxmap[mb]; /* get context */
|
|
||||||
ba = mbp->va; /* get virt addr */
|
|
||||||
mbc = ((MBABC_WR + 1) - (mbp->bc >> MBABC_V_CNT)) & MBABC_WR; /* get Mbus bc */
|
|
||||||
if (bc > mbc) bc = mbc; /* use smaller */
|
|
||||||
for (i = 0; i < bc; i = i + pbc) { /* loop by pages */
|
|
||||||
if (!mba_map_addr (ba + i, &pa, mb)) break; /* page inv? */
|
|
||||||
if (!ADDR_IS_MEM (pa)) { /* NXM? */
|
|
||||||
mba_upd_sr (MBASR_RTMO, 0, mb);
|
|
||||||
break; }
|
|
||||||
pbc = VA_PAGSIZE - VA_GETOFF (pa); /* left in page */
|
|
||||||
if (pbc > (bc - i)) pbc = bc - i; /* limit to rem xfr */
|
|
||||||
if ((pa | pbc) & 1) { /* aligned word? */
|
|
||||||
for (j = 0; j < pbc; pa++, j++) { /* no, bytes */
|
|
||||||
if ((i + j) & 1) { /* odd byte? */
|
|
||||||
*buf = (*buf & BMASK) | (ReadB (pa) << 8);
|
|
||||||
buf++;
|
|
||||||
}
|
|
||||||
else *buf = (*buf & ~BMASK) | ReadB (pa);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ((pa | pbc) & 3) { /* aligned LW? */
|
|
||||||
for (j = 0; j < pbc; pa = pa + 2, j = j + 2) { /* no, words */
|
|
||||||
*buf++ = ReadW (pa); /* get word */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else { /* yes, do by LW */
|
|
||||||
for (j = 0; j < pbc; pa = pa + 4, j = j + 4) {
|
|
||||||
dat = ReadL (pa); /* get lw */
|
|
||||||
*buf++ = dat & WMASK; /* low 16b */
|
|
||||||
*buf++ = (dat >> 16) & WMASK; /* high 16b */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 mba_wrbufW (uint32 mb, int32 bc, uint16 *buf)
|
|
||||||
{
|
|
||||||
MBACTX *mbp;
|
|
||||||
int32 i, j, ba, mbc, pbc;
|
|
||||||
uint32 pa, dat;
|
|
||||||
|
|
||||||
if (mb >= MBA_NUM) return 0; /* valid MBA? */
|
|
||||||
mbp = ctxmap[mb]; /* get context */
|
|
||||||
ba = mbp->va; /* get virt addr */
|
|
||||||
mbc = ((MBABC_WR + 1) - (mbp->bc >> MBABC_V_CNT)) & MBABC_WR; /* get Mbus bc */
|
|
||||||
if (bc > mbc) bc = mbc; /* use smaller */
|
|
||||||
for (i = 0; i < bc; i = i + pbc) { /* loop by pages */
|
|
||||||
if (!mba_map_addr (ba + i, &pa, mb)) break; /* page inv? */
|
|
||||||
if (!ADDR_IS_MEM (pa)) { /* NXM? */
|
|
||||||
mba_upd_sr (MBASR_RTMO, 0, mb);
|
|
||||||
break; }
|
|
||||||
pbc = VA_PAGSIZE - VA_GETOFF (pa); /* left in page */
|
|
||||||
if (pbc > (bc - i)) pbc = bc - i; /* limit to rem xfr */
|
|
||||||
if ((pa | pbc) & 1) { /* aligned word? */
|
|
||||||
for (j = 0; j < pbc; pa++, j++) { /* no, bytes */
|
|
||||||
if ((i + j) & 1) {
|
|
||||||
WriteB (pa, (*buf >> 8) & BMASK);
|
|
||||||
buf++; }
|
|
||||||
else WriteB (pa, *buf & BMASK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ((pa | pbc) & 3) { /* aligned LW? */
|
|
||||||
for (j = 0; j < pbc; pa = pa + 2, j = j + 2) { /* no, words */
|
|
||||||
WriteW (pa, *buf); /* write word */
|
|
||||||
buf++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else { /* yes, do by LW */
|
|
||||||
for (j = 0; j < pbc; pa = pa + 4, j = j + 4) {
|
|
||||||
dat = (uint32) *buf++; /* get low 16b */
|
|
||||||
dat = dat | (((uint32) *buf++) << 16); /* merge hi 16b */
|
|
||||||
WriteL (pa, dat); /* store LW */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 mba_chbufW (uint32 mb, int32 bc, uint16 *buf)
|
|
||||||
{
|
|
||||||
MBACTX *mbp;
|
|
||||||
int32 i, j, ba, mbc, pbc;
|
|
||||||
uint32 pa, dat, cmp;
|
|
||||||
|
|
||||||
if (mb >= MBA_NUM) return 0; /* valid MBA? */
|
|
||||||
mbp = ctxmap[mb]; /* get context */
|
|
||||||
ba = mbp->va; /* get virt addr */
|
|
||||||
mbc = ((MBABC_WR + 1) - (mbp->bc >> MBABC_V_CNT)) & MBABC_WR; /* get Mbus bc */
|
|
||||||
if (bc > mbc) bc = mbc; /* use smaller */
|
|
||||||
for (i = 0; i < bc; i = i + pbc) { /* loop by pages */
|
|
||||||
if (!mba_map_addr (ba + i, &pa, mb)) break; /* page inv? */
|
|
||||||
if (!ADDR_IS_MEM (pa)) { /* NXM? */
|
|
||||||
mba_upd_sr (MBASR_RTMO, 0, mb);
|
|
||||||
break; }
|
|
||||||
pbc = VA_PAGSIZE - VA_GETOFF (pa); /* left in page */
|
|
||||||
if (pbc > (bc - i)) pbc = bc - i; /* limit to rem xfr */
|
|
||||||
for (j = 0; j < pbc; j++, pa++) { /* byte by byte */
|
|
||||||
cmp = ReadB (pa);
|
|
||||||
if ((i + j) & 1) dat = (*buf++ >> 8) & BMASK;
|
|
||||||
else dat = *buf & BMASK;
|
|
||||||
if (cmp != dat) {
|
|
||||||
mba_upd_sr ((j & 1)? MBASR_WCEU: MBASR_WCEL, 0, mb);
|
|
||||||
break;
|
|
||||||
} /* end if */
|
|
||||||
} /* end for j */
|
|
||||||
} /* end for i */
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Map an address via the translation map */
|
|
||||||
|
|
||||||
t_bool mba_map_addr (uint32 va, uint32 *ma, uint32 mb)
|
|
||||||
{
|
|
||||||
MBACTX *mbp = ctxmap[mb];
|
|
||||||
uint32 vblk = (va >> VA_V_VPN); /* map index */
|
|
||||||
uint32 mmap = mbp->map[vblk]; /* get map */
|
|
||||||
|
|
||||||
mbp->smr = mmap; /* save map reg */
|
|
||||||
if (mmap & MBAMAP_VLD) { /* valid? */
|
|
||||||
*ma = ((mmap & MBAMAP_PAG) << VA_V_VPN) + VA_GETOFF (va);
|
|
||||||
return 1; } /* legit addr */
|
|
||||||
mba_upd_sr (MBASR_INVM, 0, mb); /* invalid map */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Device access, status, and interrupt routines */
|
|
||||||
|
|
||||||
void mba_set_don (uint32 mb)
|
|
||||||
{
|
|
||||||
mba_upd_sr (MBASR_DTCMP, 0, mb);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mba_upd_ata (uint32 mb, uint32 val)
|
|
||||||
{
|
|
||||||
if (val) mba_upd_sr (MBASR_ATA, 0, mb);
|
|
||||||
else mba_upd_sr (0, MBASR_ATA, mb);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mba_set_exc (uint32 mb)
|
|
||||||
{
|
|
||||||
mba_upd_sr (MBASR_MBEXC, 0, mb);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 mba_get_bc (uint32 mb)
|
|
||||||
{
|
|
||||||
MBACTX *mbp;
|
|
||||||
|
|
||||||
if (mb >= MBA_NUM) return 0;
|
|
||||||
mbp = ctxmap[mb];
|
|
||||||
return (((MBABC_WR + 1) - (mbp->bc >> MBABC_V_CNT)) & MBABC_WR);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mba_set_int (uint32 mb)
|
|
||||||
{
|
|
||||||
DEVICE *dptr;
|
|
||||||
DIB *dibp;
|
|
||||||
|
|
||||||
if (mb >= MBA_NUM) return;
|
|
||||||
dptr = devmap[mb];
|
|
||||||
dibp = (DIB *) dptr->ctxt;
|
|
||||||
nexus_req[dibp->vloc >> 5] |= (1u << (dibp->vloc & 0x1F));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mba_clr_int (uint32 mb)
|
|
||||||
{
|
|
||||||
DEVICE *dptr;
|
|
||||||
DIB *dibp;
|
|
||||||
|
|
||||||
if (mb >= MBA_NUM) return;
|
|
||||||
dptr = devmap[mb];
|
|
||||||
dibp = (DIB *) dptr->ctxt;
|
|
||||||
nexus_req[dibp->vloc >> 5] &= ~(1u << (dibp->vloc & 0x1F));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mba_upd_sr (uint32 set, uint32 clr, uint32 mb)
|
|
||||||
{
|
|
||||||
MBACTX *mbp;
|
|
||||||
|
|
||||||
if (mb >= MBA_NUM) return;
|
|
||||||
mbp = ctxmap[mb];
|
|
||||||
if (set & MBASR_ABORTS) set |= (MBASR_DTCMP|MBASR_DTABT);
|
|
||||||
if (set & (MBASR_DTCMP|MBASR_DTABT)) mbp->sr &= ~MBASR_DTBUSY;
|
|
||||||
mbp->sr = (mbp->sr | set) & ~clr;
|
|
||||||
if ((set & MBASR_INTR) && (mbp->cr & MBACR_IE))
|
|
||||||
mba_set_int (mb);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset Massbus adapter */
|
|
||||||
|
|
||||||
t_stat mba_reset (DEVICE *dptr)
|
|
||||||
{
|
|
||||||
int32 i, mb;
|
|
||||||
DIB *dibp;
|
|
||||||
MBACTX *mbp;
|
|
||||||
|
|
||||||
dibp = (DIB *) dptr->ctxt;
|
|
||||||
if (dibp == NULL) return SCPE_IERR;
|
|
||||||
mb = dibp->ba - TR_MBA0;
|
|
||||||
if ((mb < 0) || (mb >= MBA_NUM)) return SCPE_IERR;
|
|
||||||
mbp = ctxmap[mb];
|
|
||||||
mbp->cnf = 0;
|
|
||||||
mbp->cr = mbp->cr & MBACR_MNT;
|
|
||||||
mbp->sr = 0;
|
|
||||||
mbp->bc = 0;
|
|
||||||
mbp->va = 0;
|
|
||||||
mbp->dr = 0;
|
|
||||||
mbp->smr = 0;
|
|
||||||
if (sim_switches & SWMASK ('P')) {
|
|
||||||
for (i = 0; i < MBA_NMAPR; i++) mbp->map[i] = 0;
|
|
||||||
}
|
|
||||||
if (mbabort[mb]) mbabort[mb] (); /* reset device */
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Show Massbus adapter number */
|
|
||||||
|
|
||||||
t_stat mba_show_num (FILE *st, UNIT *uptr, int32 val, void *desc)
|
|
||||||
{
|
|
||||||
DEVICE *dptr = find_dev_from_unit (uptr);
|
|
||||||
DIB *dibp;
|
|
||||||
|
|
||||||
if (dptr == NULL) return SCPE_IERR;
|
|
||||||
dibp = (DIB *) dptr->ctxt;
|
|
||||||
if (dibp == NULL) return SCPE_IERR;
|
|
||||||
fprintf (st, "Massbus adapter %d", dibp->ba);
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Init Mbus tables */
|
|
||||||
|
|
||||||
void init_mbus_tab (void)
|
|
||||||
{
|
|
||||||
uint32 i;
|
|
||||||
|
|
||||||
for (i = 0; i < MBA_NUM; i++) {
|
|
||||||
mbregR[i] = NULL;
|
|
||||||
mbregW[i] = NULL;
|
|
||||||
mbabort[i] = NULL;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build dispatch tables */
|
|
||||||
|
|
||||||
t_stat build_mbus_tab (DEVICE *dptr, DIB *dibp)
|
|
||||||
{
|
|
||||||
uint32 idx;
|
|
||||||
|
|
||||||
if ((dptr == NULL) || (dibp == NULL)) return SCPE_IERR; /* validate args */
|
|
||||||
idx = dibp->ba; /* Mbus # */
|
|
||||||
if (idx >= MBA_NUM) return SCPE_STOP;
|
|
||||||
if ((mbregR[idx] && dibp->rd && /* conflict? */
|
|
||||||
(mbregR[idx] != dibp->rd)) ||
|
|
||||||
(mbregW[idx] && dibp->wr &&
|
|
||||||
(mbregW[idx] != dibp->wr)) ||
|
|
||||||
(mbabort[idx] && dibp->ack[0] &&
|
|
||||||
(mbabort[idx] != dibp->ack[0]))) {
|
|
||||||
printf ("Massbus %s assignment conflict at %d\n",
|
|
||||||
sim_dname (dptr), dibp->ba);
|
|
||||||
if (sim_log) fprintf (sim_log,
|
|
||||||
"Massbus %s assignment conflict at %d\n",
|
|
||||||
sim_dname (dptr), dibp->ba);
|
|
||||||
return SCPE_STOP;
|
|
||||||
}
|
|
||||||
if (dibp->rd) mbregR[idx] = dibp->rd; /* set rd dispatch */
|
|
||||||
if (dibp->wr) mbregW[idx] = dibp->wr; /* set wr dispatch */
|
|
||||||
if (dibp->ack[0]) mbabort[idx] = dibp->ack[0]; /* set abort dispatch */
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,901 +0,0 @@
|
||||||
/* vax780_sbimem.c: VAX 11/780 SBI and memory controller
|
|
||||||
|
|
||||||
Copyright (c) 2004, Robert M Supnik
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
copy of this software and associated documentation files (the "Software"),
|
|
||||||
to deal in the Software without restriction, including without limitation
|
|
||||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
Software is furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
||||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
Except as contained in this notice, the name of Robert M Supnik shall not
|
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
|
||||||
in this Software without prior written authorization from Robert M Supnik.
|
|
||||||
|
|
||||||
This module contains the VAX 11/780 system-specific registers and devices.
|
|
||||||
|
|
||||||
mctl0, mctl1 MS780C/E memory controllers
|
|
||||||
sbi bus controller
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "vax_defs.h"
|
|
||||||
|
|
||||||
/* 11/780 specific IPRs */
|
|
||||||
|
|
||||||
/* Writeable control store */
|
|
||||||
|
|
||||||
#define WCSA_RW 0xFFFF /* writeable */
|
|
||||||
#define WCSA_ADDR 0x1FFF /* addr */
|
|
||||||
#define WCSA_CTR 0x6000 /* counter */
|
|
||||||
#define WCSA_CTR_INC 0x2000 /* increment */
|
|
||||||
#define WCSA_CTR_MAX 0x6000 /* max value */
|
|
||||||
#define WCSD_RD_VAL 0xFF /* fixed read val */
|
|
||||||
#define WCSD_WR 0xFFFFFFFF /* write */
|
|
||||||
#define MBRK_RW 0x1FFF /* microbreak */
|
|
||||||
|
|
||||||
/* System registers */
|
|
||||||
|
|
||||||
#define SBIFS_RD (0x031F0000|SBI_FAULTS) /* SBI faults */
|
|
||||||
#define SBIFS_WR 0x03140000
|
|
||||||
#define SBIFS_W1C 0x00080000
|
|
||||||
|
|
||||||
#define SBISC_RD 0xFFFF0000 /* SBI silo comp */
|
|
||||||
#define SBISC_WR 0x7FFF0000
|
|
||||||
#define SBISC_LOCK 0x80000000 /* lock */
|
|
||||||
|
|
||||||
#define SBIMT_RD 0xFFFFFF00 /* SBI maint */
|
|
||||||
#define SBIMT_WR 0xFFFFF900
|
|
||||||
|
|
||||||
#define SBIER_CRDIE 0x00008000 /* SBI error, CRD IE */
|
|
||||||
#define SBIER_CRD 0x00004000 /* CRD */
|
|
||||||
#define SBIER_RDS 0x00002000 /* RDS */
|
|
||||||
#define SBIER_TMO 0x00001000 /* timeout */
|
|
||||||
#define SBIER_STA 0x00000C00 /* timeout status (0) */
|
|
||||||
#define SBIER_CNF 0x00000100 /* error confirm */
|
|
||||||
#define SBIER_IBRDS 0x00000080
|
|
||||||
#define SBIER_IBTMO 0x00000040
|
|
||||||
#define SBIER_IBSTA 0x00000030
|
|
||||||
#define SBIER_IBCNF 0x00000008
|
|
||||||
#define SBIER_MULT 0x00000004 /* multiple errors */
|
|
||||||
#define SBIER_FREE 0x00000002 /* SBI free */
|
|
||||||
#define SBIER_RD 0x0000FDFE
|
|
||||||
#define SBIER_WR 0x00008000
|
|
||||||
#define SBIER_W1C 0x000070C0
|
|
||||||
#define SBIER_TMOW1C (SBIER_TMO|SBIER_STA|SBIER_CNF|SBIER_MULT)
|
|
||||||
#define SBIER_IBTW1C (SBIER_IBTMO|SBIER_STA|SBIER_IBCNF)
|
|
||||||
|
|
||||||
#define SBITMO_V_MODE 30 /* mode */
|
|
||||||
#define SBITMO_VIRT 0x20000000 /* physical */
|
|
||||||
|
|
||||||
/* Memory controller register A */
|
|
||||||
|
|
||||||
#define MCRA_OF 0x0
|
|
||||||
#define MCRA_SUMM 0x00100000 /* err summ (MS780E) */
|
|
||||||
#define MCRA_C_SIZE 0x00007C00 /* array size - fixed */
|
|
||||||
#define MCRA_V_SIZE 9
|
|
||||||
#define MCRA_ILVE 0x00000100 /* interleave wr enab */
|
|
||||||
#define MCRA_TYPE 0x000000F8 /* type */
|
|
||||||
#define MCRA_C_TYPE 0x00000010 /* 16k uninterleaved */
|
|
||||||
#define MCRA_E_TYPE 0x0000006A /* 256k upper + lower */
|
|
||||||
#define MCRA_ILV 0x00000007 /* interleave */
|
|
||||||
#define MCRA_RD (0x00107FFF|SBI_FAULTS)
|
|
||||||
#define MCRA_WR 0x00000100
|
|
||||||
|
|
||||||
/* Memory controller register B */
|
|
||||||
|
|
||||||
#define MCRB_OF 0x1
|
|
||||||
#define MCRB_FP 0xF0000000 /* file pointers */
|
|
||||||
#define MCRB_V_SA 15 /* start addr */
|
|
||||||
#define MCRB_M_SA 0x1FFF
|
|
||||||
#define MCRB_SA (MCRB_M_SA << MCRB_V_SA)
|
|
||||||
#define MCRB_SAE 0x00004000 /* start addr wr enab */
|
|
||||||
#define MCRB_INIT 0x00003000 /* init state */
|
|
||||||
#define MCRB_REF 0x00000400 /* refresh */
|
|
||||||
#define MCRB_ECC 0x000003FF /* ECC for diags */
|
|
||||||
#define MCRB_RD 0xFFFFF7FF
|
|
||||||
#define MCRB_WR 0x000043FF
|
|
||||||
|
|
||||||
/* Memory controller register C,D */
|
|
||||||
|
|
||||||
#define MCRC_OF 0x2
|
|
||||||
#define MCRD_OF 0x3
|
|
||||||
#define MCRC_DCRD 0x40000000 /* disable CRD */
|
|
||||||
#define MCRC_HER 0x20000000 /* high error rate */
|
|
||||||
#define MCRC_ERL 0x10000000 /* log error */
|
|
||||||
#define MCRC_C_ER 0x0FFFFFFF /* MS780C error */
|
|
||||||
#define MCRC_E_PE1 0x00080000 /* MS780E par ctl 1 */
|
|
||||||
#define MCRC_E_PE0 0x00040000 /* MS780E par ctl 0 */
|
|
||||||
#define MCRC_E_CRD 0x00000200 /* MS780E CRD */
|
|
||||||
#define MCRC_E_PEW 0x00000100 /* MS780E par err wr */
|
|
||||||
#define MCRC_E_USEQ 0x00000080 /* MS780E seq err */
|
|
||||||
#define MCRC_C_RD 0x7FFFFFFF
|
|
||||||
#define MCRC_E_RD 0x700C0380
|
|
||||||
#define MCRC_WR 0x40000000
|
|
||||||
#define MCRC_C_W1C 0x30000000
|
|
||||||
#define MCRC_E_W1C 0x300C0380
|
|
||||||
|
|
||||||
#define MCRMAX_OF 0x4
|
|
||||||
|
|
||||||
#define MCRROM_OF 0x400
|
|
||||||
|
|
||||||
/* VAX-11/780 boot device definitions */
|
|
||||||
|
|
||||||
struct boot_dev {
|
|
||||||
char *name;
|
|
||||||
int32 code;
|
|
||||||
int32 let;
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32 wcs_addr = 0;
|
|
||||||
uint32 wcs_data = 0;
|
|
||||||
uint32 wcs_mbrk = 0;
|
|
||||||
uint32 nexus_req[NEXUS_HLVL]; /* nexus int req */
|
|
||||||
uint32 sbi_fs = 0; /* SBI fault status */
|
|
||||||
uint32 sbi_sc = 0; /* SBI silo comparator */
|
|
||||||
uint32 sbi_mt = 0; /* SBI maintenance */
|
|
||||||
uint32 sbi_er = 0; /* SBI error status */
|
|
||||||
uint32 sbi_tmo = 0; /* SBI timeout addr */
|
|
||||||
uint32 mcr_a[MCTL_NUM];
|
|
||||||
uint32 mcr_b[MCTL_NUM];
|
|
||||||
uint32 mcr_c[MCTL_NUM];
|
|
||||||
uint32 mcr_d[MCTL_NUM];
|
|
||||||
uint32 rom_lw[MCTL_NUM][ROMSIZE >> 2];
|
|
||||||
|
|
||||||
static t_stat (*nexusR[NEXUS_NUM])(int32 *dat, int32 ad, int32 md);
|
|
||||||
static t_stat (*nexusW[NEXUS_NUM])(int32 dat, int32 ad, int32 md);
|
|
||||||
|
|
||||||
static struct boot_dev boot_tab[] = {
|
|
||||||
{ "RP", BOOT_MB, 0 },
|
|
||||||
{ "HK", BOOT_HK, 0 },
|
|
||||||
{ "RL", BOOT_RL, 0 },
|
|
||||||
{ "RQ", BOOT_UDA, 'A' << 24 },
|
|
||||||
{ "TQ", BOOT_TK, 'A' << 24 },
|
|
||||||
{ NULL } };
|
|
||||||
|
|
||||||
extern int32 R[16];
|
|
||||||
extern int32 PSL;
|
|
||||||
extern int32 ASTLVL, SISR;
|
|
||||||
extern int32 mapen, pme, trpirq;
|
|
||||||
extern int32 in_ie;
|
|
||||||
extern int32 mchk_va, mchk_ref;
|
|
||||||
extern int32 cpu_extmem;
|
|
||||||
extern int32 crd_err, mem_err, hlt_pin;
|
|
||||||
extern int32 tmr_int, tti_int, tto_int;
|
|
||||||
extern jmp_buf save_env;
|
|
||||||
extern int32 p1;
|
|
||||||
extern int32 sim_switches;
|
|
||||||
extern UNIT cpu_unit;
|
|
||||||
extern DEVICE *sim_devices[];
|
|
||||||
extern FILE *sim_log;
|
|
||||||
extern CTAB *sim_vm_cmd;
|
|
||||||
|
|
||||||
t_stat sbi_reset (DEVICE *dptr);
|
|
||||||
t_stat mctl_reset (DEVICE *dptr);
|
|
||||||
t_stat mctl_rdreg (int32 *val, int32 pa, int32 mode);
|
|
||||||
t_stat mctl_wrreg (int32 val, int32 pa, int32 mode);
|
|
||||||
void sbi_set_tmo (int32 pa);
|
|
||||||
t_stat vax780_boot (int32 flag, char *ptr);
|
|
||||||
|
|
||||||
void uba_eval_int (void);
|
|
||||||
extern void Write (uint32 va, int32 val, int32 lnt, int32 acc);
|
|
||||||
extern int32 intexc (int32 vec, int32 cc, int32 ipl, int ei);
|
|
||||||
extern int32 iccs_rd (void);
|
|
||||||
extern int32 nicr_rd (void);
|
|
||||||
extern int32 icr_rd (void);
|
|
||||||
extern int32 todr_rd (void);
|
|
||||||
extern int32 rxcs_rd (void);
|
|
||||||
extern int32 rxdb_rd (void);
|
|
||||||
extern int32 txcs_rd (void);
|
|
||||||
extern void iccs_wr (int32 dat);
|
|
||||||
extern void nicr_wr (int32 dat);
|
|
||||||
extern void todr_wr (int32 dat);
|
|
||||||
extern void rxcs_wr (int32 dat);
|
|
||||||
extern void txcs_wr (int32 dat);
|
|
||||||
extern void txdb_wr (int32 dat);
|
|
||||||
extern void init_mbus_tab (void);
|
|
||||||
extern void init_ubus_tab (void);
|
|
||||||
extern t_stat build_mbus_tab (DEVICE *dptr, DIB *dibp);
|
|
||||||
extern t_stat build_ubus_tab (DEVICE *dptr, DIB *dibp);
|
|
||||||
|
|
||||||
/* SBI data structures
|
|
||||||
|
|
||||||
sbi_dev SBI device descriptor
|
|
||||||
sbi_unit SBI unit
|
|
||||||
sbi_reg SBI register list
|
|
||||||
*/
|
|
||||||
|
|
||||||
UNIT sbi_unit = { UDATA (NULL, 0, 0) };
|
|
||||||
|
|
||||||
REG sbi_reg[] = {
|
|
||||||
{ HRDATA (NREQ14, nexus_req[0], 16) },
|
|
||||||
{ HRDATA (NREQ15, nexus_req[1], 16) },
|
|
||||||
{ HRDATA (NREQ16, nexus_req[2], 16) },
|
|
||||||
{ HRDATA (NREQ17, nexus_req[3], 16) },
|
|
||||||
{ HRDATA (WCSA, wcs_addr, 16) },
|
|
||||||
{ HRDATA (WCSD, wcs_data, 32) },
|
|
||||||
{ HRDATA (MBRK, wcs_mbrk, 13) },
|
|
||||||
{ HRDATA (SBIFS, sbi_fs, 32) },
|
|
||||||
{ HRDATA (SBISC, sbi_sc, 32) },
|
|
||||||
{ HRDATA (SBIMT, sbi_mt, 32) },
|
|
||||||
{ HRDATA (SBIER, sbi_er, 32) },
|
|
||||||
{ HRDATA (SBITMO, sbi_tmo, 32) },
|
|
||||||
{ NULL } };
|
|
||||||
|
|
||||||
DEVICE sbi_dev = {
|
|
||||||
"SBI", &sbi_unit, sbi_reg, NULL,
|
|
||||||
1, 16, 16, 1, 16, 8,
|
|
||||||
NULL, NULL, &sbi_reset,
|
|
||||||
NULL, NULL, NULL,
|
|
||||||
NULL, 0 };
|
|
||||||
|
|
||||||
/* MCTLx data structures
|
|
||||||
|
|
||||||
mctlx_dev MCTLx device descriptor
|
|
||||||
mctlx_unit MCTLx unit
|
|
||||||
mctlx_reg MCTLx register list
|
|
||||||
*/
|
|
||||||
|
|
||||||
DIB mctl0_dib[] = { TR_MCTL0, 0, &mctl_rdreg, &mctl_wrreg, 0 };
|
|
||||||
|
|
||||||
UNIT mctl0_unit = { UDATA (NULL, 0, 0) };
|
|
||||||
|
|
||||||
REG mctl0_reg[] = {
|
|
||||||
{ HRDATA (CRA, mcr_a[0], 32) },
|
|
||||||
{ HRDATA (CRB, mcr_b[0], 32) },
|
|
||||||
{ HRDATA (CRC, mcr_c[0], 32) },
|
|
||||||
{ HRDATA (CRD, mcr_d[0], 32) },
|
|
||||||
{ BRDATA (ROM, rom_lw[0], 16, 32, ROMSIZE >> 2) },
|
|
||||||
{ NULL } };
|
|
||||||
|
|
||||||
MTAB mctl0_mod[] = {
|
|
||||||
{ MTAB_XTD|MTAB_VDV, TR_MCTL0, "NEXUS", NULL,
|
|
||||||
NULL, &show_nexus },
|
|
||||||
{ 0 } };
|
|
||||||
|
|
||||||
DEVICE mctl0_dev = {
|
|
||||||
"MCTL0", &mctl0_unit, mctl0_reg, mctl0_mod,
|
|
||||||
1, 16, 16, 1, 16, 8,
|
|
||||||
NULL, NULL, &mctl_reset,
|
|
||||||
NULL, NULL, NULL,
|
|
||||||
&mctl0_dib, DEV_NEXUS };
|
|
||||||
|
|
||||||
DIB mctl1_dib[] = { TR_MCTL1, 0, &mctl_rdreg, &mctl_wrreg, 0 };
|
|
||||||
|
|
||||||
UNIT mctl1_unit = { UDATA (NULL, 0, 0) };
|
|
||||||
|
|
||||||
MTAB mctl1_mod[] = {
|
|
||||||
{ MTAB_XTD|MTAB_VDV, TR_MCTL1, "NEXUS", NULL,
|
|
||||||
NULL, &show_nexus },
|
|
||||||
{ 0 } };
|
|
||||||
|
|
||||||
REG mctl1_reg[] = {
|
|
||||||
{ HRDATA (CRA, mcr_a[1], 32) },
|
|
||||||
{ HRDATA (CRB, mcr_b[1], 32) },
|
|
||||||
{ HRDATA (CRC, mcr_c[1], 32) },
|
|
||||||
{ HRDATA (CRD, mcr_d[1], 32) },
|
|
||||||
{ BRDATA (ROM, rom_lw[1], 16, 32, ROMSIZE >> 2) },
|
|
||||||
{ NULL } };
|
|
||||||
|
|
||||||
DEVICE mctl1_dev = {
|
|
||||||
"MCTL1", &mctl1_unit, mctl1_reg, mctl1_mod,
|
|
||||||
1, 16, 16, 1, 16, 8,
|
|
||||||
NULL, NULL, &mctl_reset,
|
|
||||||
NULL, NULL, NULL,
|
|
||||||
&mctl1_dib, DEV_NEXUS };
|
|
||||||
|
|
||||||
DIB mctl_dib[] = { TR_MCTL0, 2, &mctl_rdreg, &mctl_wrreg, 0 };
|
|
||||||
|
|
||||||
/* Special boot command, overrides regular boot */
|
|
||||||
|
|
||||||
CTAB vax780_cmd[] = {
|
|
||||||
{ "BOOT", &vax780_boot, RU_BOOT,
|
|
||||||
"bo{ot} <device>{/R5:flg} boot device\n" },
|
|
||||||
{ NULL } };
|
|
||||||
|
|
||||||
/* The VAX 11/780 has three sources of interrupts
|
|
||||||
|
|
||||||
- internal device interrupts (CPU, console, clock)
|
|
||||||
- nexus interupts (e.g., memory controller, MBA, UBA)
|
|
||||||
- external device interrupts (Unibus)
|
|
||||||
|
|
||||||
Internal devices vector to fixed SCB locations.
|
|
||||||
|
|
||||||
Nexus interrupts vector to an SCB location based on this
|
|
||||||
formula: SCB_NEXUS + ((IPL - 0x14) * 0x40) + (TR# * 0x4)
|
|
||||||
|
|
||||||
External device interrupts do not vector directly.
|
|
||||||
Instead, the interrupt handler for a given UBA IPL
|
|
||||||
reads a vector register that contains the Unibus vector
|
|
||||||
for that IPL.
|
|
||||||
|
|
||||||
/* Find highest priority vectorable interrupt */
|
|
||||||
|
|
||||||
int32 eval_int (void)
|
|
||||||
{
|
|
||||||
int32 ipl = PSL_GETIPL (PSL);
|
|
||||||
int32 i, t;
|
|
||||||
|
|
||||||
static const int32 sw_int_mask[IPL_SMAX] = {
|
|
||||||
0xFFFE, 0xFFFC, 0xFFF8, 0xFFF0, /* 0 - 3 */
|
|
||||||
0xFFE0, 0xFFC0, 0xFF80, 0xFF00, /* 4 - 7 */
|
|
||||||
0xFE00, 0xFC00, 0xF800, 0xF000, /* 8 - B */
|
|
||||||
0xE000, 0xC000, 0x8000 }; /* C - E */
|
|
||||||
|
|
||||||
if (hlt_pin) return IPL_HLTPIN; /* hlt pin int */
|
|
||||||
if ((ipl < IPL_MEMERR) && mem_err) return IPL_MEMERR; /* mem err int */
|
|
||||||
if ((ipl < IPL_CRDERR) && crd_err) return IPL_CRDERR; /* crd err int */
|
|
||||||
if ((ipl < IPL_CLKINT) && tmr_int) return IPL_CLKINT; /* clock int */
|
|
||||||
uba_eval_int (); /* update UBA */
|
|
||||||
for (i = IPL_HMAX; i >= IPL_HMIN; i--) { /* chk hwre int */
|
|
||||||
if (i <= ipl) return 0; /* at ipl? no int */
|
|
||||||
if (nexus_req[i - IPL_HMIN]) return i; } /* req != 0? int */
|
|
||||||
if ((ipl < IPL_TTINT) && (tti_int || tto_int)) /* console int */
|
|
||||||
return IPL_TTINT;
|
|
||||||
if (ipl >= IPL_SMAX) return 0; /* ipl >= sw max? */
|
|
||||||
if ((t = SISR & sw_int_mask[ipl]) == 0) return 0; /* eligible req */
|
|
||||||
for (i = IPL_SMAX; i > ipl; i--) { /* check swre int */
|
|
||||||
if ((t >> i) & 1) return i; } /* req != 0? int */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return vector for highest priority hardware interrupt at IPL lvl */
|
|
||||||
|
|
||||||
int32 get_vector (int32 lvl)
|
|
||||||
{
|
|
||||||
int32 i;
|
|
||||||
int32 l = lvl - IPL_HMIN;
|
|
||||||
|
|
||||||
if (lvl == IPL_MEMERR) { /* mem error? */
|
|
||||||
mem_err = 0;
|
|
||||||
return SCB_MEMERR; }
|
|
||||||
if (lvl == IPL_CRDERR) { /* CRD error? */
|
|
||||||
crd_err = 0;
|
|
||||||
return SCB_CRDERR; }
|
|
||||||
if ((lvl == IPL_CLKINT) && tmr_int) { /* clock? */
|
|
||||||
tmr_int = 0; /* clear req */
|
|
||||||
return SCB_INTTIM; } /* return vector */
|
|
||||||
if (lvl > IPL_HMAX) { /* error req lvl? */
|
|
||||||
ABORT (STOP_UIPL); } /* unknown intr */
|
|
||||||
if ((lvl <= IPL_HMAX) && (lvl >= IPL_HMIN)) { /* nexus? */
|
|
||||||
for (i = 0; nexus_req[l] && (i < NEXUS_NUM); i++) {
|
|
||||||
if ((nexus_req[l] >> i) & 1) {
|
|
||||||
nexus_req[l] = nexus_req[l] & ~(1u << i);
|
|
||||||
return SCB_NEXUS + (l << 6) + (i << 2); /* return vector */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lvl == IPL_TTINT) { /* console? */
|
|
||||||
if (tti_int) { /* input? */
|
|
||||||
tti_int = 0; /* clear req */
|
|
||||||
return SCB_TTI; } /* return vector */
|
|
||||||
if (tto_int) { /* output? */
|
|
||||||
tto_int = 0; /* clear req */
|
|
||||||
return SCB_TTO; } /* return vector */
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read 780-specific IPR's */
|
|
||||||
|
|
||||||
int32 ReadIPR (int32 rg)
|
|
||||||
{
|
|
||||||
int32 val;
|
|
||||||
|
|
||||||
switch (rg) {
|
|
||||||
case MT_ICCS: /* ICCS */
|
|
||||||
val = iccs_rd ();
|
|
||||||
break;
|
|
||||||
case MT_NICR: /* NICR */
|
|
||||||
val = nicr_rd ();
|
|
||||||
break;
|
|
||||||
case MT_ICR: /* ICR */
|
|
||||||
val = icr_rd ();
|
|
||||||
break;
|
|
||||||
case MT_TODR: /* TODR */
|
|
||||||
val = todr_rd ();
|
|
||||||
break;
|
|
||||||
case MT_ACCS: /* ACCS (not impl) */
|
|
||||||
val = 0;
|
|
||||||
break;
|
|
||||||
case MT_WCSA: /* WCSA */
|
|
||||||
val = wcs_addr & WCSA_RW;
|
|
||||||
break;
|
|
||||||
case MT_WCSD: /* WCSD */
|
|
||||||
val = WCSD_RD_VAL;
|
|
||||||
break;
|
|
||||||
case MT_RXCS: /* RXCS */
|
|
||||||
val = rxcs_rd ();
|
|
||||||
break;
|
|
||||||
case MT_RXDB: /* RXDB */
|
|
||||||
val = rxdb_rd ();
|
|
||||||
break;
|
|
||||||
case MT_TXCS: /* TXCS */
|
|
||||||
val = txcs_rd ();
|
|
||||||
break;
|
|
||||||
case MT_TXDB: /* TXDB */
|
|
||||||
val = 0;
|
|
||||||
break;
|
|
||||||
case MT_SBIFS: /* SBIFS */
|
|
||||||
val = sbi_fs & SBIFS_RD;
|
|
||||||
break;
|
|
||||||
case MT_SBIS: /* SBIS */
|
|
||||||
val = 0;
|
|
||||||
break;
|
|
||||||
case MT_SBISC: /* SBISC */
|
|
||||||
val = sbi_sc & SBISC_RD;
|
|
||||||
break;
|
|
||||||
case MT_SBIMT: /* SBIMT */
|
|
||||||
val = sbi_mt & SBIMT_RD;
|
|
||||||
break;
|
|
||||||
case MT_SBIER: /* SBIER */
|
|
||||||
val = sbi_er & SBIER_RD;
|
|
||||||
break;
|
|
||||||
case MT_SBITA: /* SBITA */
|
|
||||||
val = sbi_tmo;
|
|
||||||
break;
|
|
||||||
case MT_MBRK: /* MBRK */
|
|
||||||
val = wcs_mbrk & MBRK_RW;
|
|
||||||
break;
|
|
||||||
case MT_SID: /* SID */
|
|
||||||
val = VAX780_SID | VAX780_ECO | VAX780_PLANT | VAX780_SN;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
RSVD_OPND_FAULT;
|
|
||||||
}
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write 780-specific IPR's */
|
|
||||||
|
|
||||||
void WriteIPR (int32 rg, int32 val)
|
|
||||||
{
|
|
||||||
switch (rg) {
|
|
||||||
case MT_ICCS: /* ICCS */
|
|
||||||
iccs_wr (val);
|
|
||||||
break;
|
|
||||||
case MT_NICR: /* NICR */
|
|
||||||
nicr_wr (val);
|
|
||||||
break;
|
|
||||||
case MT_TODR: /* TODR */
|
|
||||||
todr_wr (val);
|
|
||||||
break;
|
|
||||||
case MT_WCSA: /* WCSA */
|
|
||||||
wcs_addr = val & WCSA_RW;
|
|
||||||
break;
|
|
||||||
case MT_WCSD: /* WCSD */
|
|
||||||
wcs_data = val & WCSD_WR;
|
|
||||||
wcs_addr = (wcs_addr & ~WCSA_CTR) |
|
|
||||||
((wcs_addr + WCSA_CTR_INC) & WCSA_CTR);
|
|
||||||
if ((wcs_addr & WCSA_CTR) == WCSA_CTR_MAX)
|
|
||||||
wcs_addr = (wcs_addr & ~WCSA_ADDR) |
|
|
||||||
((wcs_addr + 1) & WCSA_ADDR);
|
|
||||||
break;
|
|
||||||
case MT_RXCS: /* RXCS */
|
|
||||||
rxcs_wr (val);
|
|
||||||
break;
|
|
||||||
case MT_RXDB: /* RXDB */
|
|
||||||
break;
|
|
||||||
case MT_TXCS: /* TXCS */
|
|
||||||
txcs_wr (val);
|
|
||||||
break;
|
|
||||||
case MT_TXDB: /* TXDB */
|
|
||||||
txdb_wr (val);
|
|
||||||
break;
|
|
||||||
case MT_SBIFS: /* SBIFS */
|
|
||||||
sbi_fs = (sbi_fs & ~SBIFS_WR) | (val & SBIFS_WR);
|
|
||||||
sbi_fs = sbi_fs & ~(val & SBIFS_W1C);
|
|
||||||
break;
|
|
||||||
case MT_SBISC: /* SBISC */
|
|
||||||
sbi_sc = (sbi_sc & ~(SBISC_LOCK|SBISC_WR)) | (val & SBISC_WR);
|
|
||||||
break;
|
|
||||||
case MT_SBIMT: /* SBIMT */
|
|
||||||
sbi_mt = (sbi_mt & ~SBIMT_WR) | (val & SBIMT_WR);
|
|
||||||
break;
|
|
||||||
case MT_SBIER: /* SBIER */
|
|
||||||
sbi_er = (sbi_er & ~SBIER_WR) | (val & SBIER_WR);
|
|
||||||
sbi_er = sbi_er & ~(val & SBIER_W1C);
|
|
||||||
if (val & SBIER_TMO) sbi_er = sbi_er & ~SBIER_TMOW1C;
|
|
||||||
if (val & SBIER_IBTMO) sbi_er = sbi_er & ~SBIER_IBTW1C;
|
|
||||||
if ((sbi_er & SBIER_CRDIE) && (sbi_er & SBIER_CRD))
|
|
||||||
crd_err = 1;
|
|
||||||
else crd_err = 0;
|
|
||||||
break;
|
|
||||||
case MT_SBIQC:
|
|
||||||
// tbd /* SBIQC */
|
|
||||||
break;
|
|
||||||
case MT_MBRK: /* MBRK */
|
|
||||||
wcs_mbrk = val & MBRK_RW;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
RSVD_OPND_FAULT;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ReadReg - read register space
|
|
||||||
|
|
||||||
Inputs:
|
|
||||||
pa = physical address
|
|
||||||
lnt = length (BWLQ) - ignored
|
|
||||||
Output:
|
|
||||||
longword of data
|
|
||||||
*/
|
|
||||||
|
|
||||||
int32 ReadReg (int32 pa, int32 lnt)
|
|
||||||
{
|
|
||||||
int32 nexus, val;
|
|
||||||
|
|
||||||
if (ADDR_IS_REG (pa)) { /* reg space? */
|
|
||||||
nexus = NEXUS_GETNEX (pa); /* get nexus */
|
|
||||||
if (nexusR[nexus] && /* valid? */
|
|
||||||
(nexusR[nexus] (&val, pa, lnt) == SCPE_OK)) {
|
|
||||||
SET_IRQL;
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sbi_set_tmo (pa); /* timeout */
|
|
||||||
MACH_CHECK (MCHK_RD_F); /* machine check */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* WriteReg - write register space
|
|
||||||
|
|
||||||
Inputs:
|
|
||||||
pa = physical address
|
|
||||||
val = data to write, right justified in 32b longword
|
|
||||||
lnt = length (BWLQ)
|
|
||||||
Outputs:
|
|
||||||
none
|
|
||||||
*/
|
|
||||||
|
|
||||||
void WriteReg (int32 pa, int32 val, int32 lnt)
|
|
||||||
{
|
|
||||||
int32 nexus;
|
|
||||||
|
|
||||||
if (ADDR_IS_REG (pa)) { /* reg space? */
|
|
||||||
nexus = NEXUS_GETNEX (pa); /* get nexus */
|
|
||||||
if (nexusW[nexus] && /* valid? */
|
|
||||||
(nexusW[nexus] (val, pa, lnt) == SCPE_OK)) {
|
|
||||||
SET_IRQL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sbi_set_tmo (pa); /* timeout */
|
|
||||||
mem_err = 1; /* interrupt */
|
|
||||||
eval_int ();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set SBI timeout */
|
|
||||||
|
|
||||||
void sbi_set_tmo (int32 pa)
|
|
||||||
{
|
|
||||||
if ((sbi_er & SBIER_TMO) == 0) { /* not yet set? */
|
|
||||||
sbi_tmo = pa >> 2; /* save addr */
|
|
||||||
if (mchk_ref == REF_V) sbi_tmo |= SBITMO_VIRT | /* virt? add mode */
|
|
||||||
(PSL_GETCUR (PSL) << SBITMO_V_MODE);
|
|
||||||
sbi_er |= SBIER_TMO; } /* set tmo flag */
|
|
||||||
else sbi_er |= SBIER_MULT; /* yes, multiple */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Memory controller register read */
|
|
||||||
|
|
||||||
t_stat mctl_rdreg (int32 *val, int32 pa, int32 mode)
|
|
||||||
{
|
|
||||||
int32 mctl, ofs;
|
|
||||||
|
|
||||||
mctl = NEXUS_GETNEX (pa) - TR_MCTL0; /* get mctl num */
|
|
||||||
ofs = NEXUS_GETOFS (pa); /* get offset */
|
|
||||||
if (ofs >= MCRROM_OF) { /* ROM? */
|
|
||||||
*val = rom_lw[mctl][ofs - MCRROM_OF]; /* get lw */
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
if (ofs >= MCRMAX_OF) return SCPE_NXM; /* in range? */
|
|
||||||
switch (ofs) {
|
|
||||||
|
|
||||||
case MCRA_OF: /* CR A */
|
|
||||||
*val = mcr_a[mctl] & MCRA_RD;
|
|
||||||
break;
|
|
||||||
case MCRB_OF: /* CR B */
|
|
||||||
*val = (mcr_b[mctl] & MCRB_RD) | MCRB_INIT;
|
|
||||||
break;
|
|
||||||
case MCRC_OF: /* CR C */
|
|
||||||
*val = mcr_c[mctl] & (cpu_extmem? MCRC_E_RD: MCRC_C_RD);
|
|
||||||
break;
|
|
||||||
case MCRD_OF: /* CR D */
|
|
||||||
if (!cpu_extmem) return SCPE_NXM; /* MS780E only */
|
|
||||||
*val = mcr_d[mctl] & MCRC_E_RD;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Memory controller register write */
|
|
||||||
|
|
||||||
t_stat mctl_wrreg (int32 val, int32 pa, int32 mode)
|
|
||||||
{
|
|
||||||
int32 mctl, ofs, mask;
|
|
||||||
|
|
||||||
mctl = NEXUS_GETNEX (pa) - TR_MCTL0; /* get mctl num */
|
|
||||||
ofs = NEXUS_GETOFS (pa); /* get offset */
|
|
||||||
if (ofs >= MCRMAX_OF) return SCPE_NXM; /* in range? */
|
|
||||||
switch (ofs) {
|
|
||||||
|
|
||||||
case MCRA_OF: /* CR A */
|
|
||||||
mask = MCRA_WR | ((val & MCRA_ILVE)? MCRA_ILV: 0);
|
|
||||||
mcr_a[mctl] = (mcr_a[mctl] & ~mask) | (val & mask);
|
|
||||||
break;
|
|
||||||
case MCRB_OF: /* CR B */
|
|
||||||
mask = MCRB_WR | ((val & MCRB_SAE)? MCRB_SA: 0);
|
|
||||||
mcr_b[mctl] = (mcr_b[mctl] & ~mask) | (val & mask);
|
|
||||||
break;
|
|
||||||
case MCRC_OF: /* CR C */
|
|
||||||
mcr_c[mctl] = ((mcr_c[mctl] & MCRC_WR) | (val & MCRC_WR)) &
|
|
||||||
~(val & (cpu_extmem? MCRC_E_W1C: MCRC_C_W1C));
|
|
||||||
break;
|
|
||||||
case MCRD_OF: /* CR D */
|
|
||||||
if (!cpu_extmem) return SCPE_NXM; /* MS780E only */
|
|
||||||
mcr_d[mctl] = ((mcr_d[mctl] & MCRC_WR) | (val & MCRC_WR)) &
|
|
||||||
~(val & MCRC_E_W1C);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Used by CPU and loader */
|
|
||||||
|
|
||||||
void rom_wr_B (int32 pa, int32 val)
|
|
||||||
{
|
|
||||||
uint32 mctl = NEXUS_GETNEX (pa) - TR_MCTL0; /* get mctl num */
|
|
||||||
uint32 ofs = NEXUS_GETOFS (pa) - MCRROM_OF; /* get offset */
|
|
||||||
int32 sc = (pa & 3) << 3;
|
|
||||||
|
|
||||||
rom_lw[mctl][ofs] = ((val & 0xFF) << sc) | (rom_lw[mctl][ofs] & ~(0xFF << sc));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Machine check
|
|
||||||
|
|
||||||
Error status word format
|
|
||||||
<2:0> = ASTLVL
|
|
||||||
<3> = PME
|
|
||||||
<6:4> = arith trap code
|
|
||||||
Rest will be zero
|
|
||||||
*/
|
|
||||||
|
|
||||||
int32 machine_check (int32 p1, int32 opc, int32 cc)
|
|
||||||
{
|
|
||||||
int32 acc, err;
|
|
||||||
|
|
||||||
err = (GET_TRAP (trpirq) << 4) | (pme << 3) | ASTLVL; /* error word */
|
|
||||||
cc = intexc (SCB_MCHK, cc, 0, IE_SVE); /* take exception */
|
|
||||||
acc = ACC_MASK (KERN); /* in kernel mode */
|
|
||||||
in_ie = 1;
|
|
||||||
SP = SP - 44; /* push 11 words */
|
|
||||||
Write (SP, 40, L_LONG, WA); /* # bytes */
|
|
||||||
Write (SP + 4, p1, L_LONG, WA); /* mcheck type */
|
|
||||||
Write (SP + 8, err, L_LONG, WA); /* CPU error status */
|
|
||||||
Write (SP + 12, 0, L_LONG, WA); /* uPC */
|
|
||||||
Write (SP + 16, mchk_va, L_LONG, WA); /* VA */
|
|
||||||
Write (SP + 20, 0, L_LONG, WA); /* D register */
|
|
||||||
Write (SP + 24, mapen, L_LONG, WA); /* TB status 1 */
|
|
||||||
Write (SP + 28, 0, L_LONG, WA); /* TB status 2 */
|
|
||||||
Write (SP + 32, sbi_tmo, L_LONG, WA); /* SBI timeout addr */
|
|
||||||
Write (SP + 36, 0, L_LONG, WA); /* cache status */
|
|
||||||
Write (SP + 40, sbi_er, L_LONG, WA); /* SBI error */
|
|
||||||
in_ie = 0;
|
|
||||||
return cc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Console entry */
|
|
||||||
|
|
||||||
int32 con_halt (int32 code, int32 cc)
|
|
||||||
{
|
|
||||||
ABORT (STOP_HALT);
|
|
||||||
return cc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Special boot command - linked into SCP by initial reset
|
|
||||||
|
|
||||||
Syntax: BOOT <device>{/R5:val}
|
|
||||||
|
|
||||||
Sets up R0-R5, calls SCP boot processor with effective BOOT CPU
|
|
||||||
*/
|
|
||||||
|
|
||||||
t_stat vax780_boot (int32 flag, char *ptr)
|
|
||||||
{
|
|
||||||
char gbuf[CBUFSIZE];
|
|
||||||
char *slptr, *regptr;
|
|
||||||
int32 i, r5v, unitno;
|
|
||||||
DEVICE *dptr;
|
|
||||||
UNIT *uptr;
|
|
||||||
DIB *dibp;
|
|
||||||
t_stat r;
|
|
||||||
|
|
||||||
regptr = get_glyph (ptr, gbuf, 0); /* get glyph */
|
|
||||||
if (slptr = strchr (gbuf, '/')) { /* found slash? */
|
|
||||||
regptr = strchr (ptr, '/'); /* locate orig */
|
|
||||||
*slptr = 0; } /* zero in string */
|
|
||||||
dptr = find_unit (gbuf, &uptr); /* find device */
|
|
||||||
if ((dptr == NULL) || (uptr == NULL)) return SCPE_ARG;
|
|
||||||
dibp = (DIB *) dptr->ctxt; /* get DIB */
|
|
||||||
if (dibp == NULL) return SCPE_ARG;
|
|
||||||
unitno = uptr - dptr->units;
|
|
||||||
r5v = 0;
|
|
||||||
if ((strncmp (regptr, "/R5:", 4) == 0) ||
|
|
||||||
(strncmp (regptr, "/R5=", 4) == 0) ||
|
|
||||||
(strncmp (regptr, "/r5:", 4) == 0) ||
|
|
||||||
(strncmp (regptr, "/r5=", 4) == 0)) {
|
|
||||||
r5v = (int32) get_uint (regptr + 4, 16, LMASK, &r);
|
|
||||||
if (r != SCPE_OK) return r; }
|
|
||||||
else if (*regptr != 0) return SCPE_ARG;
|
|
||||||
for (i = 0; boot_tab[i].name != NULL; i++) {
|
|
||||||
if (strcmp (dptr->name, boot_tab[i].name) == 0) {
|
|
||||||
R[0] = boot_tab[i].code;
|
|
||||||
if (dptr->flags & DEV_MBUS) {
|
|
||||||
R[1] = dibp->ba + TR_MBA0;
|
|
||||||
R[2] = unitno;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
R[1] = TR_UBA;
|
|
||||||
R[2] = boot_tab[i].let | (dibp->ba & UBADDRMASK);
|
|
||||||
}
|
|
||||||
R[3] = unitno;
|
|
||||||
R[4] = 0;
|
|
||||||
R[5] = r5v;
|
|
||||||
return run_cmd (flag, "CPU");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return SCPE_NOFNC;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bootstrap - finish up bootstrap process */
|
|
||||||
|
|
||||||
t_stat cpu_boot (int32 unitno, DEVICE *dptr)
|
|
||||||
{
|
|
||||||
t_stat r;
|
|
||||||
|
|
||||||
printf ("Loading boot code from vmb780.bin\n");
|
|
||||||
if (sim_log) fprintf (sim_log,
|
|
||||||
"Loading boot code from vmb780.bin\n");
|
|
||||||
r = load_cmd (0, "-O vmb780.bin 200");
|
|
||||||
if (r != SCPE_OK) return r;
|
|
||||||
SP = PC = 512;
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* SBI reset */
|
|
||||||
|
|
||||||
t_stat sbi_reset (DEVICE *dptr)
|
|
||||||
{
|
|
||||||
wcs_addr = 0;
|
|
||||||
wcs_data = 0;
|
|
||||||
wcs_mbrk = 0;
|
|
||||||
sbi_fs = 0;
|
|
||||||
sbi_sc = 0;
|
|
||||||
sbi_mt = 0;
|
|
||||||
sbi_er = 0;
|
|
||||||
sbi_tmo = 0;
|
|
||||||
sim_vm_cmd = vax780_cmd;
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* MEMCTL reset */
|
|
||||||
|
|
||||||
t_stat mctl_reset (DEVICE *dptr)
|
|
||||||
{
|
|
||||||
int32 i, amb;
|
|
||||||
|
|
||||||
amb = (MEMSIZE / 2) >> 20; /* array size MB */
|
|
||||||
for (i = 0; i < MCTL_NUM; i++) { /* init for MS780C */
|
|
||||||
if (cpu_extmem) { /* extended memory? */
|
|
||||||
mcr_a[i] = (amb << MCRA_V_SIZE) | MCRA_E_TYPE;
|
|
||||||
mcr_b[i] = MCRB_INIT | ((i * amb) << MCRB_V_SA);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
mcr_a[i] = MCRA_C_SIZE | MCRA_C_TYPE;
|
|
||||||
mcr_b[i] = MCRB_INIT | (i << 21);
|
|
||||||
}
|
|
||||||
mcr_c[i] = 0;
|
|
||||||
mcr_d[i] = 0;
|
|
||||||
}
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Show nexus */
|
|
||||||
|
|
||||||
t_stat show_nexus (FILE *st, UNIT *uptr, int32 val, void *desc)
|
|
||||||
{
|
|
||||||
fprintf (st, "nexus=%d", val);
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Init nexus tables */
|
|
||||||
|
|
||||||
void init_nexus_tab (void)
|
|
||||||
{
|
|
||||||
uint32 i;
|
|
||||||
|
|
||||||
for (i = 0; i < NEXUS_NUM; i++) {
|
|
||||||
nexusR[i] = NULL;
|
|
||||||
nexusW[i] = NULL;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build nexus tables
|
|
||||||
|
|
||||||
Inputs:
|
|
||||||
dptr = pointer to device
|
|
||||||
dibp = pointer to DIB
|
|
||||||
Outputs:
|
|
||||||
status
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
t_stat build_nexus_tab (DEVICE *dptr, DIB *dibp)
|
|
||||||
{
|
|
||||||
uint32 idx;
|
|
||||||
|
|
||||||
if ((dptr == NULL) || (dibp == NULL)) return SCPE_IERR;
|
|
||||||
idx = dibp->ba;
|
|
||||||
if (idx >= NEXUS_NUM) return SCPE_IERR;
|
|
||||||
if ((nexusR[idx] && dibp->rd && /* conflict? */
|
|
||||||
(nexusR[idx] != dibp->rd)) ||
|
|
||||||
(nexusW[idx] && dibp->wr &&
|
|
||||||
(nexusW[idx] != dibp->wr))) {
|
|
||||||
printf ("Nexus %s conflict at %d\n",
|
|
||||||
sim_dname (dptr), dibp->ba);
|
|
||||||
if (sim_log) fprintf (sim_log,
|
|
||||||
"Nexus %s conflict at %d\n",
|
|
||||||
sim_dname (dptr), dibp->ba);
|
|
||||||
return SCPE_STOP;
|
|
||||||
}
|
|
||||||
if (dibp->rd) nexusR[idx] = dibp->rd; /* set rd dispatch */
|
|
||||||
if (dibp->wr) nexusW[idx] = dibp->wr; /* set wr dispatch */
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build dib_tab from device list */
|
|
||||||
|
|
||||||
t_stat build_dib_tab (void)
|
|
||||||
{
|
|
||||||
uint32 i;
|
|
||||||
DEVICE *dptr;
|
|
||||||
DIB *dibp;
|
|
||||||
t_stat r;
|
|
||||||
|
|
||||||
init_nexus_tab ();
|
|
||||||
init_ubus_tab ();
|
|
||||||
init_mbus_tab ();
|
|
||||||
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */
|
|
||||||
dibp = (DIB *) dptr->ctxt; /* get DIB */
|
|
||||||
if (dibp && !(dptr->flags & DEV_DIS)) { /* defined, enabled? */
|
|
||||||
if (dptr->flags & DEV_NEXUS) { /* Nexus? */
|
|
||||||
if (r = build_nexus_tab (dptr, dibp)) /* add to dispatch table */
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
else if (dptr->flags & DEV_MBUS) { /* Massbus? */
|
|
||||||
if (r = build_mbus_tab (dptr, dibp))
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
else { /* no, Unibus device */
|
|
||||||
if (r = build_ubus_tab (dptr, dibp)) /* add to dispatch tab */
|
|
||||||
return r;
|
|
||||||
} /* end else */
|
|
||||||
} /* end if enabled */
|
|
||||||
} /* end for */
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
|
@ -1,851 +0,0 @@
|
||||||
/* vax780_stddev.c: VAX 11/780 standard I/O devices
|
|
||||||
|
|
||||||
Copyright (c) 1998-2004, Robert M Supnik
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
copy of this software and associated documentation files (the "Software"),
|
|
||||||
to deal in the Software without restriction, including without limitation
|
|
||||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
Software is furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
||||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
Except as contained in this notice, the name of Robert M Supnik shall not
|
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
|
||||||
in this Software without prior written authorization from Robert M Supnik.
|
|
||||||
|
|
||||||
tti console input
|
|
||||||
tto console output
|
|
||||||
rx console floppy
|
|
||||||
todr TODR clock
|
|
||||||
tmr interval timer
|
|
||||||
|
|
||||||
08-Sep-04 RMS Cloned from vax_stddev.c, vax_sysdev.c, and pdp11_rx.c
|
|
||||||
|
|
||||||
The console floppy protocol is based on the description in the 1982 VAX
|
|
||||||
Architecture Reference Manual:
|
|
||||||
|
|
||||||
TXDB<11:8> = 0 -> normal console output
|
|
||||||
TXDB<11:8> = 1 -> data output to floppy
|
|
||||||
TXDB<11:8> = 9 -> command output to floppy
|
|
||||||
TXDB<11:8> = F -> flag output (e.g., reboot)
|
|
||||||
|
|
||||||
RXDB<11:8> = 0 -> normal terminal input
|
|
||||||
RXDB<11:8> = 1 -> data input from floppy
|
|
||||||
RXDB<11:8> = 2 -> status input from floppy
|
|
||||||
RXDB<11:8> = 9 -> "command" input from floppy (protocol error)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "vax_defs.h"
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
/* Terminal definitions */
|
|
||||||
|
|
||||||
#define RXCS_RD (CSR_DONE + CSR_IE) /* terminal input */
|
|
||||||
#define RXCS_WR (CSR_IE)
|
|
||||||
#define RXDB_ERR 0x8000 /* error */
|
|
||||||
#define RXDB_OVR 0x4000 /* overrun */
|
|
||||||
#define RXDB_FRM 0x2000 /* framing error */
|
|
||||||
#define RXDB_RBR 0x0400 /* receive break */
|
|
||||||
#define TXCS_RD (CSR_DONE + CSR_IE) /* terminal output */
|
|
||||||
#define TXCS_WR (CSR_IE)
|
|
||||||
#define TXDB_V_SEL 8 /* unit select */
|
|
||||||
#define TXDB_M_SEL 0xF
|
|
||||||
#define TXDB_FDAT 0x1 /* floppy data */
|
|
||||||
#define TXDB_FCMD 0x9 /* floppy cmd */
|
|
||||||
#define TXDB_MISC 0xF /* console misc */
|
|
||||||
#define TXDB_SEL (TXDB_M_SEL << TXDB_V_SEL) /* non-terminal */
|
|
||||||
#define TXDB_GETSEL(x) (((x) >> TXDB_V_SEL) & TXDB_M_SEL)
|
|
||||||
#define UNIT_V_8B (UNIT_V_UF + 0) /* 8B mode */
|
|
||||||
#define UNIT_8B (1 << UNIT_V_8B)
|
|
||||||
|
|
||||||
/* Clock definitions */
|
|
||||||
|
|
||||||
#define TMR_CSR_ERR 0x80000000 /* error W1C */
|
|
||||||
#define TMR_CSR_DON 0x00000080 /* done W1C */
|
|
||||||
#define TMR_CSR_IE 0x00000040 /* int enb RW */
|
|
||||||
#define TMR_CSR_SGL 0x00000020 /* single WO */
|
|
||||||
#define TMR_CSR_XFR 0x00000010 /* xfer WO */
|
|
||||||
#define TMR_CSR_RUN 0x00000001 /* run RW */
|
|
||||||
#define TMR_CSR_RD (TMR_CSR_W1C | TMR_CSR_WR)
|
|
||||||
#define TMR_CSR_W1C (TMR_CSR_ERR | TMR_CSR_DON)
|
|
||||||
#define TMR_CSR_WR (TMR_CSR_IE | TMR_CSR_RUN)
|
|
||||||
#define TMR_INC 10000 /* usec/interval */
|
|
||||||
#define CLK_DELAY 5000 /* 100 Hz */
|
|
||||||
#define TMXR_MULT 2 /* 50 Hz */
|
|
||||||
|
|
||||||
/* Floppy definitions */
|
|
||||||
|
|
||||||
#define FL_NUMTR 77 /* tracks/disk */
|
|
||||||
#define FL_M_TRACK 0377
|
|
||||||
#define FL_NUMSC 26 /* sectors/track */
|
|
||||||
#define FL_M_SECTOR 0177
|
|
||||||
#define FL_NUMBY 128 /* bytes/sector */
|
|
||||||
#define FL_SIZE (FL_NUMTR * FL_NUMSC * FL_NUMBY) /* bytes/disk */
|
|
||||||
#define UNIT_V_WLK (UNIT_V_UF) /* write locked */
|
|
||||||
#define UNIT_WLK (1u << UNIT_V_UF)
|
|
||||||
#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write protect */
|
|
||||||
|
|
||||||
#define FL_IDLE 0 /* idle state */
|
|
||||||
#define FL_RWDS 1 /* rw, sect next */
|
|
||||||
#define FL_RWDT 2 /* rw, track next */
|
|
||||||
#define FL_READ 3 /* read */
|
|
||||||
#define FL_READ1 4
|
|
||||||
#define FL_WRITE 5 /* write */
|
|
||||||
#define FL_WRITE1 6
|
|
||||||
#define FL_FILL 7 /* fill buffer */
|
|
||||||
#define FL_EMPTY 8 /* empty buffer */
|
|
||||||
#define FL_READSTA 9 /* read status */
|
|
||||||
#define FL_DONE 10 /* cmd done */
|
|
||||||
|
|
||||||
#define FL_V_FNC 0 /* floppy function */
|
|
||||||
#define FL_M_FNC 0xFF
|
|
||||||
#define FL_FNCRD 0x0 /* read */
|
|
||||||
#define FL_FNCWR 0x1 /* write */
|
|
||||||
#define FL_FNCRS 0x2 /* read status */
|
|
||||||
#define FL_FNCWD 0x3 /* write del data */
|
|
||||||
#define FL_FNCCA 0x4 /* cancel */
|
|
||||||
#define FL_CDATA 0x100 /* returned data */
|
|
||||||
#define FL_CDONE 0x200 /* completion code */
|
|
||||||
#define FL_STACRC 0x001 /* status bits */
|
|
||||||
#define FL_STAPAR 0x002
|
|
||||||
#define FL_STAINC 0x004
|
|
||||||
#define FL_STADDA 0x040
|
|
||||||
#define FL_STAERR 0x080
|
|
||||||
#define FL_CPROT 0x905 /* protocol error */
|
|
||||||
#define FL_MISC 0xF00 /* misc communications */
|
|
||||||
#define FL_SWDN 0x1 /* software done */
|
|
||||||
#define FL_BOOT 0x2 /* reboot */
|
|
||||||
#define FL_CLWS 0x3 /* clear warm start */
|
|
||||||
#define FL_CLCS 0x4 /* clear cold start */
|
|
||||||
#define FL_GETFNC(x) (((x) >> FL_V_FNC) & FL_M_FNC)
|
|
||||||
|
|
||||||
#define TRACK u3 /* current track */
|
|
||||||
#define CALC_DA(t,s) (((t) * FL_NUMSC) + ((s) - 1)) * FL_NUMBY
|
|
||||||
|
|
||||||
int32 tti_csr = 0; /* control/status */
|
|
||||||
int32 tti_buf = 0; /* buffer */
|
|
||||||
int32 tti_int = 0; /* interrupt */
|
|
||||||
int32 tto_csr = 0; /* control/status */
|
|
||||||
int32 tto_buf = 0; /* buffer */
|
|
||||||
int32 tto_int = 0; /* interrupt */
|
|
||||||
|
|
||||||
int32 tmr_iccs = 0; /* interval timer csr */
|
|
||||||
uint32 tmr_icr = 0; /* curr interval */
|
|
||||||
uint32 tmr_nicr = 0; /* next interval */
|
|
||||||
uint32 tmr_inc = 0; /* timer increment */
|
|
||||||
int32 tmr_sav = 0; /* timer save */
|
|
||||||
int32 tmr_int = 0; /* interrupt */
|
|
||||||
int32 clk_tps = 100; /* ticks/second */
|
|
||||||
int32 tmxr_poll = CLK_DELAY * TMXR_MULT; /* term mux poll */
|
|
||||||
int32 tmr_poll = CLK_DELAY; /* pgm timer poll */
|
|
||||||
int32 todr_reg = 0; /* TODR register */
|
|
||||||
|
|
||||||
int32 fl_fnc = 0; /* function */
|
|
||||||
int32 fl_esr = 0; /* error status */
|
|
||||||
int32 fl_ecode = 0; /* error code */
|
|
||||||
int32 fl_track = 0; /* desired track */
|
|
||||||
int32 fl_sector = 0; /* desired sector */
|
|
||||||
int32 fl_state = FL_IDLE; /* controller state */
|
|
||||||
int32 fl_stopioe = 1; /* stop on error */
|
|
||||||
int32 fl_swait = 100; /* seek, per track */
|
|
||||||
int32 fl_cwait = 50; /* command time */
|
|
||||||
int32 fl_xwait = 20; /* tr set time */
|
|
||||||
uint8 fl_buf[FL_NUMBY] = { 0 }; /* sector buffer */
|
|
||||||
int32 fl_bptr = 0; /* buffer pointer */
|
|
||||||
|
|
||||||
extern int32 sim_switches;
|
|
||||||
|
|
||||||
t_stat tti_svc (UNIT *uptr);
|
|
||||||
t_stat tto_svc (UNIT *uptr);
|
|
||||||
t_stat clk_svc (UNIT *uptr);
|
|
||||||
t_stat tmr_svc (UNIT *uptr);
|
|
||||||
t_stat tti_reset (DEVICE *dptr);
|
|
||||||
t_stat tto_reset (DEVICE *dptr);
|
|
||||||
t_stat clk_reset (DEVICE *dptr);
|
|
||||||
t_stat tmr_reset (DEVICE *dptr);
|
|
||||||
t_stat fl_svc (UNIT *uptr);
|
|
||||||
t_stat fl_reset (DEVICE *dptr);
|
|
||||||
int32 icr_rd (t_bool interp);
|
|
||||||
void tmr_incr (uint32 inc);
|
|
||||||
void tmr_sched (void);
|
|
||||||
t_stat todr_powerup (void);
|
|
||||||
t_stat fl_wr_txdb (int32 data);
|
|
||||||
t_bool fl_test_xfr (UNIT *uptr, t_bool wr);
|
|
||||||
void fl_protocol_error (void);
|
|
||||||
|
|
||||||
/* TTI data structures
|
|
||||||
|
|
||||||
tti_dev TTI device descriptor
|
|
||||||
tti_unit TTI unit descriptor
|
|
||||||
tti_reg TTI register list
|
|
||||||
*/
|
|
||||||
|
|
||||||
UNIT tti_unit = { UDATA (&tti_svc, UNIT_8B, 0), KBD_POLL_WAIT };
|
|
||||||
|
|
||||||
REG tti_reg[] = {
|
|
||||||
{ HRDATA (RXDB, tti_buf, 16) },
|
|
||||||
{ HRDATA (RXCS, tti_csr, 16) },
|
|
||||||
{ FLDATA (INT, tti_int, 0) },
|
|
||||||
{ FLDATA (DONE, tti_csr, CSR_V_DONE) },
|
|
||||||
{ FLDATA (IE, tti_csr, CSR_V_IE) },
|
|
||||||
{ DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT },
|
|
||||||
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
|
|
||||||
{ NULL } };
|
|
||||||
|
|
||||||
MTAB tti_mod[] = {
|
|
||||||
{ UNIT_8B, UNIT_8B, "8b", "8B", NULL },
|
|
||||||
{ UNIT_8B, 0 , "7b", "7B", NULL },
|
|
||||||
{ 0 } };
|
|
||||||
|
|
||||||
DEVICE tti_dev = {
|
|
||||||
"TTI", &tti_unit, tti_reg, tti_mod,
|
|
||||||
1, 10, 31, 1, 16, 8,
|
|
||||||
NULL, NULL, &tti_reset,
|
|
||||||
NULL, NULL, NULL,
|
|
||||||
NULL, 0 };
|
|
||||||
|
|
||||||
/* TTO data structures
|
|
||||||
|
|
||||||
tto_dev TTO device descriptor
|
|
||||||
tto_unit TTO unit descriptor
|
|
||||||
tto_reg TTO register list
|
|
||||||
*/
|
|
||||||
|
|
||||||
UNIT tto_unit = { UDATA (&tto_svc, UNIT_8B, 0), SERIAL_OUT_WAIT };
|
|
||||||
|
|
||||||
REG tto_reg[] = {
|
|
||||||
{ HRDATA (TXDB, tto_buf, 16) },
|
|
||||||
{ HRDATA (TXCS, tto_csr, 16) },
|
|
||||||
{ FLDATA (INT, tto_int, 0) },
|
|
||||||
{ FLDATA (DONE, tto_csr, CSR_V_DONE) },
|
|
||||||
{ FLDATA (IE, tto_csr, CSR_V_IE) },
|
|
||||||
{ DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT },
|
|
||||||
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
|
|
||||||
{ NULL } };
|
|
||||||
|
|
||||||
MTAB tto_mod[] = {
|
|
||||||
{ UNIT_8B, UNIT_8B, "8b", "8B", NULL },
|
|
||||||
{ UNIT_8B, 0 , "7b", "7B", NULL },
|
|
||||||
{ 0 } };
|
|
||||||
|
|
||||||
DEVICE tto_dev = {
|
|
||||||
"TTO", &tto_unit, tto_reg, tto_mod,
|
|
||||||
1, 10, 31, 1, 16, 8,
|
|
||||||
NULL, NULL, &tto_reset,
|
|
||||||
NULL, NULL, NULL,
|
|
||||||
NULL, 0 };
|
|
||||||
|
|
||||||
/* TODR and TMR data structures */
|
|
||||||
|
|
||||||
UNIT clk_unit = { UDATA (&clk_svc, 0, 0), CLK_DELAY }; /* 100Hz */
|
|
||||||
|
|
||||||
REG clk_reg[] = {
|
|
||||||
{ DRDATA (TODR, todr_reg, 32), PV_LEFT },
|
|
||||||
{ DRDATA (TIME, clk_unit.wait, 24), REG_NZ + PV_LEFT },
|
|
||||||
{ DRDATA (TPS, clk_tps, 8), REG_HIDDEN + REG_NZ + PV_LEFT },
|
|
||||||
{ NULL } };
|
|
||||||
|
|
||||||
DEVICE clk_dev = {
|
|
||||||
"TODR", &clk_unit, clk_reg, NULL,
|
|
||||||
1, 0, 0, 0, 0, 0,
|
|
||||||
NULL, NULL, &clk_reset,
|
|
||||||
NULL, NULL, NULL,
|
|
||||||
NULL, 0 };
|
|
||||||
|
|
||||||
UNIT tmr_unit = { UDATA (&tmr_svc, 0, 0) }; /* timer */
|
|
||||||
|
|
||||||
REG tmr_reg[] = {
|
|
||||||
{ HRDATA (ICCS, tmr_iccs, 32) },
|
|
||||||
{ HRDATA (ICR, tmr_icr, 32) },
|
|
||||||
{ HRDATA (NICR, tmr_nicr, 32) },
|
|
||||||
{ HRDATA (INCR, tmr_inc, 32), REG_HIDDEN },
|
|
||||||
{ HRDATA (SAVE, tmr_sav, 32), REG_HIDDEN },
|
|
||||||
{ FLDATA (INT, tmr_int, 0) },
|
|
||||||
{ NULL } };
|
|
||||||
|
|
||||||
DEVICE tmr_dev = {
|
|
||||||
"TMR", &tmr_unit, tmr_reg, NULL,
|
|
||||||
1, 0, 0, 0, 0, 0,
|
|
||||||
NULL, NULL, &tmr_reset,
|
|
||||||
NULL, NULL, NULL,
|
|
||||||
NULL, 0 };
|
|
||||||
|
|
||||||
/* RX01 data structures
|
|
||||||
|
|
||||||
fl_dev RX device descriptor
|
|
||||||
fl_unit RX unit list
|
|
||||||
fl_reg RX register list
|
|
||||||
fl_mod RX modifier list
|
|
||||||
*/
|
|
||||||
|
|
||||||
UNIT fl_unit = { UDATA (&fl_svc,
|
|
||||||
UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF, FL_SIZE) };
|
|
||||||
|
|
||||||
REG fl_reg[] = {
|
|
||||||
{ HRDATA (FNC, fl_fnc, 8) },
|
|
||||||
{ HRDATA (ES, fl_esr, 8) },
|
|
||||||
{ HRDATA (ECODE, fl_ecode, 8) },
|
|
||||||
{ HRDATA (TA, fl_track, 8) },
|
|
||||||
{ HRDATA (SA, fl_sector, 8) },
|
|
||||||
{ DRDATA (STATE, fl_state, 4), REG_RO },
|
|
||||||
{ DRDATA (BPTR, fl_bptr, 7) },
|
|
||||||
{ DRDATA (CTIME, fl_cwait, 24), PV_LEFT },
|
|
||||||
{ DRDATA (STIME, fl_swait, 24), PV_LEFT },
|
|
||||||
{ DRDATA (XTIME, fl_xwait, 24), PV_LEFT },
|
|
||||||
{ FLDATA (STOP_IOE, fl_stopioe, 0) },
|
|
||||||
{ BRDATA (DBUF, fl_buf, 16, 8, FL_NUMBY) },
|
|
||||||
{ NULL } };
|
|
||||||
|
|
||||||
MTAB fl_mod[] = {
|
|
||||||
{ UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL },
|
|
||||||
{ UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL },
|
|
||||||
{ 0 } };
|
|
||||||
|
|
||||||
DEVICE fl_dev = {
|
|
||||||
"RX", &fl_unit, fl_reg, fl_mod,
|
|
||||||
1, DEV_RDX, 20, 1, DEV_RDX, 8,
|
|
||||||
NULL, NULL, &fl_reset,
|
|
||||||
NULL, NULL, NULL,
|
|
||||||
NULL, 0 };
|
|
||||||
|
|
||||||
/* Terminal MxPR routines
|
|
||||||
|
|
||||||
rxcs_rd/wr input control/status
|
|
||||||
rxdb_rd input buffer
|
|
||||||
txcs_rd/wr output control/status
|
|
||||||
txdb_wr output buffer
|
|
||||||
*/
|
|
||||||
|
|
||||||
int32 rxcs_rd (void)
|
|
||||||
{
|
|
||||||
return (tti_csr & RXCS_RD);
|
|
||||||
}
|
|
||||||
|
|
||||||
void rxcs_wr (int32 data)
|
|
||||||
{
|
|
||||||
if ((data & CSR_IE) == 0) tto_int = 0;
|
|
||||||
else if ((tti_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
|
|
||||||
tti_int = 1;
|
|
||||||
tti_csr = (tti_csr & ~RXCS_WR) | (data & RXCS_WR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 rxdb_rd (void)
|
|
||||||
{
|
|
||||||
int32 t = tti_buf; /* char + error */
|
|
||||||
|
|
||||||
tti_csr = tti_csr & ~CSR_DONE; /* clr done */
|
|
||||||
tti_buf = tti_buf & BMASK; /* clr errors */
|
|
||||||
tti_int = 0;
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 txcs_rd (void)
|
|
||||||
{
|
|
||||||
return (tto_csr & TXCS_RD);
|
|
||||||
}
|
|
||||||
|
|
||||||
void txcs_wr (int32 data)
|
|
||||||
{
|
|
||||||
if ((data & CSR_IE) == 0) tto_int = 0;
|
|
||||||
else if ((tto_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
|
|
||||||
tto_int = 1;
|
|
||||||
tto_csr = (tto_csr & ~TXCS_WR) | (data & TXCS_WR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void txdb_wr (int32 data)
|
|
||||||
{
|
|
||||||
tto_buf = data & WMASK; /* save data */
|
|
||||||
tto_csr = tto_csr & ~CSR_DONE; /* clear flag */
|
|
||||||
tto_int = 0; /* clear int */
|
|
||||||
if (tto_buf & TXDB_SEL) fl_wr_txdb (tto_buf); /* floppy? */
|
|
||||||
else sim_activate (&tto_unit, tto_unit.wait); /* no, console */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Terminal input service (poll for character */
|
|
||||||
|
|
||||||
t_stat tti_svc (UNIT *uptr)
|
|
||||||
{
|
|
||||||
int32 c;
|
|
||||||
|
|
||||||
sim_activate (&tti_unit, tti_unit.wait); /* continue poll */
|
|
||||||
if ((c = sim_poll_kbd ()) < SCPE_KFLAG) return c; /* no char or error? */
|
|
||||||
if (c & SCPE_BREAK) /* break? */
|
|
||||||
tti_buf = RXDB_ERR | RXDB_FRM | RXDB_RBR;
|
|
||||||
else tti_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) tti_int = 1;
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Terminal input reset */
|
|
||||||
|
|
||||||
t_stat tti_reset (DEVICE *dptr)
|
|
||||||
{
|
|
||||||
tti_buf = 0;
|
|
||||||
tti_csr = 0;
|
|
||||||
tti_int = 0;
|
|
||||||
sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Terminal output service (output character) */
|
|
||||||
|
|
||||||
t_stat tto_svc (UNIT *uptr)
|
|
||||||
{
|
|
||||||
int32 c;
|
|
||||||
t_stat r;
|
|
||||||
|
|
||||||
if ((tto_buf & TXDB_SEL) == 0) { /* for console? */
|
|
||||||
c = tto_buf & ((tto_unit.flags & UNIT_8B)? 0377: 0177);
|
|
||||||
if ((r = sim_putchar_s (c)) != SCPE_OK) { /* output; error? */
|
|
||||||
sim_activate (uptr, uptr->wait); /* retry */
|
|
||||||
return ((r == SCPE_STALL)? SCPE_OK: r); } /* !stall? report */
|
|
||||||
tto_unit.pos = tto_unit.pos + 1; }
|
|
||||||
tto_csr = tto_csr | CSR_DONE;
|
|
||||||
if (tto_csr & CSR_IE) tto_int = 1;
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Terminal output reset */
|
|
||||||
|
|
||||||
t_stat tto_reset (DEVICE *dptr)
|
|
||||||
{
|
|
||||||
tto_buf = 0;
|
|
||||||
tto_csr = CSR_DONE;
|
|
||||||
tto_int = 0;
|
|
||||||
sim_cancel (&tto_unit); /* deactivate unit */
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Programmable timer
|
|
||||||
|
|
||||||
The architected VAX timer, which increments at 1Mhz, cannot be
|
|
||||||
accurately simulated due to the overhead that would be required
|
|
||||||
for 1M clock events per second. Instead, a hidden calibrated
|
|
||||||
100Hz timer is run (because that's what VMS expects), and a
|
|
||||||
gross hack is used for the interval timer.
|
|
||||||
|
|
||||||
When the timer is started, the timer interval is inspected.
|
|
||||||
|
|
||||||
if (int < 0 and small) then testing timer, count instructions.
|
|
||||||
Small is determined by when the requested interval is less
|
|
||||||
than the size of a 100Hz system clock tick.
|
|
||||||
if (int >= 0 or large) then counting a real interval, schedule
|
|
||||||
clock events at 100Hz using calibrated clock delay. When
|
|
||||||
the remaining time value gets small enough, behave like
|
|
||||||
the small case above.
|
|
||||||
|
|
||||||
If the interval register is read, then its value between events
|
|
||||||
is interpolated using the current instruction count versus the
|
|
||||||
count when the most recent event started, the result is scaled
|
|
||||||
to the calibrated system clock, unless the interval being timed
|
|
||||||
is less than a calibrated system clock tick (or the calibrated
|
|
||||||
clock is running very slowly) at which time the result will be
|
|
||||||
the elapsed instruction count.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int32 iccs_rd (void)
|
|
||||||
{
|
|
||||||
return tmr_iccs & TMR_CSR_RD;
|
|
||||||
}
|
|
||||||
|
|
||||||
void iccs_wr (int32 val)
|
|
||||||
{
|
|
||||||
if ((val & TMR_CSR_RUN) == 0) { /* clearing run? */
|
|
||||||
sim_cancel (&tmr_unit); /* cancel timer */
|
|
||||||
if (tmr_iccs & TMR_CSR_RUN) /* run 1 -> 0? */
|
|
||||||
tmr_icr = icr_rd (TRUE); } /* update itr */
|
|
||||||
tmr_iccs = tmr_iccs & ~(val & TMR_CSR_W1C); /* W1C csr */
|
|
||||||
tmr_iccs = (tmr_iccs & ~TMR_CSR_WR) | /* new r/w */
|
|
||||||
(val & TMR_CSR_WR);
|
|
||||||
if (val & TMR_CSR_XFR) tmr_icr = tmr_nicr; /* xfr set? */
|
|
||||||
if (val & TMR_CSR_RUN) { /* run? */
|
|
||||||
if (val & TMR_CSR_XFR) /* new tir? */
|
|
||||||
sim_cancel (&tmr_unit); /* stop prev */
|
|
||||||
if (!sim_is_active (&tmr_unit)) /* not running? */
|
|
||||||
tmr_sched (); } /* activate */
|
|
||||||
else if (val & TMR_CSR_SGL) { /* single step? */
|
|
||||||
tmr_incr (1); /* incr tmr */
|
|
||||||
if (tmr_icr == 0) /* if ovflo, */
|
|
||||||
tmr_icr = tmr_nicr; } /* reload tir */
|
|
||||||
if ((tmr_iccs & (TMR_CSR_DON | TMR_CSR_IE)) != /* update int */
|
|
||||||
(TMR_CSR_DON | TMR_CSR_IE)) tmr_int = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 icr_rd (t_bool interp)
|
|
||||||
{
|
|
||||||
uint32 delta;
|
|
||||||
|
|
||||||
if (interp || (tmr_iccs & TMR_CSR_RUN)) { /* interp, running? */
|
|
||||||
delta = sim_grtime () - tmr_sav; /* delta inst */
|
|
||||||
if ((tmr_inc == TMR_INC) && /* scale large int */
|
|
||||||
(tmr_poll > TMR_INC))
|
|
||||||
delta = (uint32) ((((double) delta) * TMR_INC) / tmr_poll);
|
|
||||||
if (delta >= tmr_inc) delta = tmr_inc - 1;
|
|
||||||
return tmr_icr + delta; }
|
|
||||||
return tmr_icr;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 nicr_rd ()
|
|
||||||
{
|
|
||||||
return tmr_nicr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nicr_wr (int32 val)
|
|
||||||
{
|
|
||||||
tmr_nicr = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 100Hz base clock unit service */
|
|
||||||
|
|
||||||
t_stat clk_svc (UNIT *uptr)
|
|
||||||
{
|
|
||||||
int32 t;
|
|
||||||
|
|
||||||
t = sim_rtcn_calb (clk_tps, TMR_CLK); /* calibrate clock */
|
|
||||||
sim_activate (&clk_unit, t); /* reactivate unit */
|
|
||||||
tmr_poll = t; /* set tmr poll */
|
|
||||||
tmxr_poll = t * TMXR_MULT; /* set mux poll */
|
|
||||||
todr_reg = todr_reg + 1; /* incr TODR */
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Interval timer unit service */
|
|
||||||
|
|
||||||
t_stat tmr_svc (UNIT *uptr)
|
|
||||||
{
|
|
||||||
tmr_incr (tmr_inc); /* incr timer */
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Timer increment */
|
|
||||||
|
|
||||||
void tmr_incr (uint32 inc)
|
|
||||||
{
|
|
||||||
uint32 new_icr = (tmr_icr + inc) & LMASK; /* add incr */
|
|
||||||
|
|
||||||
if (new_icr < tmr_icr) { /* ovflo? */
|
|
||||||
tmr_icr = 0; /* now 0 */
|
|
||||||
if (tmr_iccs & TMR_CSR_DON) /* done? set err */
|
|
||||||
tmr_iccs = tmr_iccs | TMR_CSR_ERR;
|
|
||||||
else tmr_iccs = tmr_iccs | TMR_CSR_DON; /* set done */
|
|
||||||
if (tmr_iccs & TMR_CSR_RUN) { /* run? */
|
|
||||||
tmr_icr = tmr_nicr; /* reload */
|
|
||||||
tmr_sched (); } /* reactivate */
|
|
||||||
if (tmr_iccs & TMR_CSR_IE) tmr_int = 1; /* ie? set int req */
|
|
||||||
else tmr_int = 0; }
|
|
||||||
else { tmr_icr = new_icr; /* no, update icr */
|
|
||||||
if (tmr_iccs & TMR_CSR_RUN) /* still running? */
|
|
||||||
tmr_sched (); } /* reactivate */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Timer scheduling */
|
|
||||||
|
|
||||||
void tmr_sched (void)
|
|
||||||
{
|
|
||||||
int32 clk_time = sim_is_active (&clk_unit) - 1;
|
|
||||||
int32 tmr_time;
|
|
||||||
|
|
||||||
tmr_sav = sim_grtime (); /* save intvl base */
|
|
||||||
if (tmr_icr > (0xFFFFFFFFu - TMR_INC)) { /* short interval? */
|
|
||||||
tmr_inc = (~tmr_icr + 1); /* inc = interval */
|
|
||||||
tmr_time = tmr_inc; }
|
|
||||||
else { tmr_inc = TMR_INC; /* usec/interval */
|
|
||||||
tmr_time = tmr_poll; }
|
|
||||||
if (tmr_time == 0) tmr_time = 1;
|
|
||||||
if ((tmr_inc = TMR_INC) && (tmr_time > clk_time)) {
|
|
||||||
|
|
||||||
/* Align scheduled event to be identical to the event for the next clock
|
|
||||||
tick. This lets us always see a consistent calibrated value, both for
|
|
||||||
this scheduling, AND for any query of the current timer register that
|
|
||||||
may happen in tmr_icr_rd (). This presumes that sim_activate will
|
|
||||||
queue the interval timer behind the event for the 100Hz clock tick. */
|
|
||||||
|
|
||||||
tmr_inc = (uint32) (((double) clk_time * TMR_INC) / tmr_poll);
|
|
||||||
tmr_time = clk_time; }
|
|
||||||
sim_activate (&tmr_unit, tmr_time);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 100Hz clock reset */
|
|
||||||
|
|
||||||
t_stat clk_reset (DEVICE *dptr)
|
|
||||||
{
|
|
||||||
int32 t;
|
|
||||||
|
|
||||||
t = sim_rtcn_init (clk_unit.wait, TMR_CLK); /* init 100Hz timer */
|
|
||||||
sim_activate (&clk_unit, t); /* activate 100Hz unit */
|
|
||||||
tmr_poll = t; /* set tmr poll */
|
|
||||||
tmxr_poll = t * TMXR_MULT; /* set mux poll */
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Interval timer reset */
|
|
||||||
|
|
||||||
t_stat tmr_reset (DEVICE *dptr)
|
|
||||||
{
|
|
||||||
tmr_iccs = 0;
|
|
||||||
tmr_icr = 0;
|
|
||||||
tmr_nicr = 0;
|
|
||||||
tmr_int = 0;
|
|
||||||
sim_cancel (&tmr_unit); /* cancel timer */
|
|
||||||
if (sim_switches & SWMASK ('P')) todr_powerup (); /* powerup? set TODR */
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODR routines */
|
|
||||||
|
|
||||||
int32 todr_rd (void)
|
|
||||||
{
|
|
||||||
return todr_reg;
|
|
||||||
}
|
|
||||||
|
|
||||||
void todr_wr (int32 data)
|
|
||||||
{
|
|
||||||
todr_reg = data;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
t_stat todr_powerup (void)
|
|
||||||
{
|
|
||||||
uint32 base;
|
|
||||||
time_t curr;
|
|
||||||
struct tm *ctm;
|
|
||||||
|
|
||||||
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;
|
|
||||||
todr_reg = (base * 100) + 0x10000000; /* cvt to VAX form */
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Console write, txdb<11:8> != 0 (console unit) */
|
|
||||||
|
|
||||||
t_stat fl_wr_txdb (int32 data)
|
|
||||||
{
|
|
||||||
int32 sel = TXDB_GETSEL (data); /* get selection */
|
|
||||||
|
|
||||||
if (sel == TXDB_FCMD) { /* floppy command? */
|
|
||||||
fl_fnc = FL_GETFNC (data); /* get function */
|
|
||||||
if (fl_state != FL_IDLE) switch (fl_fnc) { /* cmd in prog? */
|
|
||||||
case FL_FNCCA: /* cancel? */
|
|
||||||
sim_cancel (&fl_unit); /* stop op */
|
|
||||||
fl_state = FL_DONE;
|
|
||||||
break;
|
|
||||||
default: /* all others */
|
|
||||||
fl_protocol_error ();
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
else switch (fl_fnc) { /* idle, case */
|
|
||||||
case FL_FNCRS: /* read status */
|
|
||||||
fl_state = FL_READSTA;
|
|
||||||
break;
|
|
||||||
case FL_FNCCA: /* cancel, nop */
|
|
||||||
fl_state = FL_DONE;
|
|
||||||
break;
|
|
||||||
case FL_FNCRD: case FL_FNCWR: /* data xfer */
|
|
||||||
case FL_FNCWD:
|
|
||||||
fl_esr = 0; /* clear errors */
|
|
||||||
fl_ecode = 0;
|
|
||||||
fl_bptr = 0; /* init buffer */
|
|
||||||
fl_state = FL_RWDS; /* sector next */
|
|
||||||
break;
|
|
||||||
default: /* all others */
|
|
||||||
fl_protocol_error ();
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
sim_activate (&fl_unit, fl_cwait); /* sched command */
|
|
||||||
} /* end command */
|
|
||||||
else if (sel == TXDB_FDAT) { /* floppy data? */
|
|
||||||
switch (fl_state) { /* data */
|
|
||||||
case FL_RWDS: /* expecting sector */
|
|
||||||
fl_sector = data & FL_M_SECTOR;
|
|
||||||
fl_state = FL_RWDT;
|
|
||||||
break;
|
|
||||||
case FL_RWDT: /* expecting track */
|
|
||||||
fl_track = data & FL_M_TRACK;
|
|
||||||
if (fl_fnc == FL_FNCRD) fl_state = FL_READ;
|
|
||||||
else fl_state = FL_FILL;
|
|
||||||
break;
|
|
||||||
case FL_FILL: /* expecting wr data */
|
|
||||||
fl_buf[fl_bptr++] = data & BMASK;
|
|
||||||
if (fl_bptr >= FL_NUMBY) fl_state = FL_WRITE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fl_protocol_error ();
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
sim_activate (&fl_unit, fl_xwait); /* schedule xfer */
|
|
||||||
} /* end else data */
|
|
||||||
else sim_activate (&tto_unit, tto_unit.wait); /* discard for now */
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unit service; the action to be taken depends on the transfer state:
|
|
||||||
|
|
||||||
FL_IDLE Should never get here
|
|
||||||
FL_RWDS Set TXCS<done> (driver sends sector, sets FL_RWDT)
|
|
||||||
FL_RWDT Set TXCS<done> (driver sends track, sets FL_READ/FL_FILL)
|
|
||||||
FL_READ Set TXCS<done>, schedule FL_READ1
|
|
||||||
FL_READ1 Read sector, schedule FL_EMPTY
|
|
||||||
FL_EMPTY Copy data to RXDB, set RXCS<done>
|
|
||||||
if fl_bptr >= max, schedule completion, else continue
|
|
||||||
FL_FILL Set TXCS<done> (driver sends next byte, sets FL_WRITE)
|
|
||||||
FL_WRITE Set TXCS<done>, schedule FL_WRITE1
|
|
||||||
FL_WRITE1 Write sector, schedule FL_DONE
|
|
||||||
FL_DONE Copy requested data to TXDB, set FL_IDLE
|
|
||||||
*/
|
|
||||||
|
|
||||||
t_stat fl_svc (UNIT *uptr)
|
|
||||||
{
|
|
||||||
int32 i, t;
|
|
||||||
uint32 da;
|
|
||||||
int8 *fbuf = uptr->filebuf;
|
|
||||||
|
|
||||||
switch (fl_state) { /* case on state */
|
|
||||||
|
|
||||||
case FL_IDLE: /* idle */
|
|
||||||
return SCPE_IERR; /* done */
|
|
||||||
|
|
||||||
case FL_READ: case FL_WRITE: /* read, write */
|
|
||||||
fl_state = fl_state + 1; /* set next state */
|
|
||||||
t = abs (fl_track - uptr->TRACK); /* # tracks to seek */
|
|
||||||
if (t == 0) t = 1; /* minimum 1 */
|
|
||||||
sim_activate (uptr, fl_swait * t); /* schedule seek */
|
|
||||||
/* fall thru, set flag */
|
|
||||||
case FL_RWDS: case FL_RWDT: case FL_FILL: /* rwds, rwdt, fill */
|
|
||||||
tto_csr = tto_csr | CSR_DONE; /* set output done */
|
|
||||||
if (tto_csr & CSR_IE) tto_int = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FL_READ1: /* read, seek done */
|
|
||||||
if (fl_test_xfr (uptr, FALSE)) { /* transfer ok? */
|
|
||||||
da = CALC_DA (fl_track, fl_sector); /* get disk address */
|
|
||||||
for (i = 0; i < FL_NUMBY; i++) /* copy sector to buf */
|
|
||||||
fl_buf[i] = fbuf[da + i];
|
|
||||||
tti_buf = fl_esr | FL_CDONE; /* completion code */
|
|
||||||
tti_csr = tti_csr | CSR_DONE; /* set input flag */
|
|
||||||
if (tti_csr & CSR_IE) tti_int = 1;
|
|
||||||
fl_state = FL_EMPTY; } /* go empty */
|
|
||||||
else fl_state = FL_DONE; /* error? cmd done */
|
|
||||||
sim_activate (uptr, fl_xwait); /* schedule next */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FL_EMPTY: /* empty buffer */
|
|
||||||
if ((tti_csr & CSR_DONE) == 0) { /* prev data taken? */
|
|
||||||
tti_buf = FL_CDATA | fl_buf[fl_bptr++]; /* get next byte */
|
|
||||||
tti_csr = tti_csr | CSR_DONE; /* set input flag */
|
|
||||||
if (tti_csr & CSR_IE) tti_int = 1;
|
|
||||||
if (fl_bptr >= FL_NUMBY) { /* buffer empty? */
|
|
||||||
fl_state = FL_IDLE; /* cmd done */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sim_activate (uptr, fl_xwait); /* schedule next */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FL_WRITE1: /* write, seek done */
|
|
||||||
if (fl_test_xfr (uptr, TRUE)) { /* transfer ok? */
|
|
||||||
da = CALC_DA (fl_track, fl_sector); /* get disk address */
|
|
||||||
for (i = 0; i < FL_NUMBY; i++) /* copy buf to sector */
|
|
||||||
fbuf[da + i] = fl_buf[i];
|
|
||||||
da = da + FL_NUMBY;
|
|
||||||
if (da > uptr->hwmark) uptr->hwmark = da; /* update hwmark */
|
|
||||||
}
|
|
||||||
if (fl_fnc == FL_FNCWD) fl_esr |= FL_STADDA; /* wrdel? set status*/
|
|
||||||
fl_state = FL_DONE; /* command done */
|
|
||||||
sim_activate (uptr, fl_xwait); /* schedule */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FL_DONE: /* command done */
|
|
||||||
if (tti_csr & CSR_DONE) /* input buf empty? */
|
|
||||||
sim_activate (uptr, fl_xwait); /* no, wait */
|
|
||||||
else { /* yes */
|
|
||||||
tti_buf = fl_esr | FL_CDONE; /* completion code */
|
|
||||||
tti_csr = tti_csr | CSR_DONE; /* set input flag */
|
|
||||||
if (tti_csr & CSR_IE) tti_int = 1;
|
|
||||||
fl_state = FL_IDLE; /* floppy idle */
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FL_READSTA: /* read status */
|
|
||||||
if ((tti_csr & CSR_DONE) == 0) { /* input buf empty? */
|
|
||||||
tti_buf = fl_ecode; /* return err code */
|
|
||||||
tti_csr = tti_csr | CSR_DONE; /* set input flag */
|
|
||||||
if (tti_csr & CSR_IE) tti_int = 1;
|
|
||||||
fl_state = FL_DONE; /* command done */
|
|
||||||
}
|
|
||||||
sim_activate (uptr, fl_xwait);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Test for data transfer okay */
|
|
||||||
|
|
||||||
t_bool fl_test_xfr (UNIT *uptr, t_bool wr)
|
|
||||||
{
|
|
||||||
if ((uptr->flags & UNIT_BUF) == 0) /* not buffered? */
|
|
||||||
fl_ecode = 0110;
|
|
||||||
else if (fl_track >= FL_NUMTR) /* bad track? */
|
|
||||||
fl_ecode = 0040; /* done, error */
|
|
||||||
else if ((fl_sector == 0) || (fl_sector > FL_NUMSC)) /* bad sect? */
|
|
||||||
fl_ecode = 0070; /* done, error */
|
|
||||||
else if (wr && (uptr->flags & UNIT_WPRT)) /* write and locked? */
|
|
||||||
fl_ecode = 0100; /* done, error */
|
|
||||||
else { uptr->TRACK = fl_track; /* now on track */
|
|
||||||
return TRUE; }
|
|
||||||
fl_esr = fl_esr | FL_STAERR; /* set error */
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set protocol error */
|
|
||||||
|
|
||||||
void fl_protocol_error (void)
|
|
||||||
{
|
|
||||||
if ((tto_csr & CSR_DONE) == 0) { /* output busy? */
|
|
||||||
tto_csr = tto_csr | CSR_DONE; /* set done */
|
|
||||||
if (tto_csr & CSR_IE) tto_int = 1; }
|
|
||||||
if ((tti_csr & CSR_DONE) == 0) { /* input idle? */
|
|
||||||
tti_csr = tti_csr | CSR_DONE; /* set done */
|
|
||||||
if (tti_csr & CSR_IE) tti_int = 1; }
|
|
||||||
tti_buf = FL_CPROT; /* status */
|
|
||||||
fl_state = FL_IDLE; /* floppy idle */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset */
|
|
||||||
|
|
||||||
t_stat fl_reset (DEVICE *dptr)
|
|
||||||
{
|
|
||||||
fl_esr = FL_STAINC;
|
|
||||||
fl_ecode = 0; /* clear error */
|
|
||||||
fl_sector = 0; /* clear addr */
|
|
||||||
fl_track = 0;
|
|
||||||
fl_state = FL_IDLE; /* ctrl idle */
|
|
||||||
fl_bptr = 0;
|
|
||||||
sim_cancel (&fl_unit); /* cancel drive */
|
|
||||||
fl_unit.TRACK = 0;
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
|
@ -1,130 +0,0 @@
|
||||||
/* vax_syslist.c: VAX device list
|
|
||||||
|
|
||||||
Copyright (c) 1998-2004, Robert M Supnik
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
copy of this software and associated documentation files (the "Software"),
|
|
||||||
to deal in the Software without restriction, including without limitation
|
|
||||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
Software is furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
||||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
Except as contained in this notice, the name of Robert M Supnik shall not
|
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
|
||||||
in this Software without prior written authorization from Robert M Supnik.
|
|
||||||
|
|
||||||
01-Oct-2004 RMS Cloned from vax_sys.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "vax_defs.h"
|
|
||||||
|
|
||||||
char sim_name[] = "VAX780 (pre-Beta developers preview)";
|
|
||||||
|
|
||||||
extern DEVICE cpu_dev;
|
|
||||||
extern DEVICE tlb_dev;
|
|
||||||
extern DEVICE sbi_dev;
|
|
||||||
extern DEVICE mctl0_dev, mctl1_dev;
|
|
||||||
extern DEVICE uba_dev;
|
|
||||||
extern DEVICE mba0_dev, mba1_dev;
|
|
||||||
extern DEVICE clk_dev;
|
|
||||||
extern DEVICE tmr_dev;
|
|
||||||
extern DEVICE tti_dev, tto_dev;
|
|
||||||
extern DEVICE fl_dev;
|
|
||||||
extern DEVICE lpt_dev;
|
|
||||||
extern DEVICE rq_dev, rqb_dev, rqc_dev, rqd_dev;
|
|
||||||
extern DEVICE rl_dev;
|
|
||||||
extern DEVICE hk_dev;
|
|
||||||
extern DEVICE rp_dev;
|
|
||||||
extern DEVICE ry_dev;
|
|
||||||
extern DEVICE ts_dev;
|
|
||||||
extern DEVICE tq_dev;
|
|
||||||
extern DEVICE tu_dev;
|
|
||||||
extern DEVICE dz_dev;
|
|
||||||
extern DEVICE xu_dev, xub_dev;
|
|
||||||
|
|
||||||
extern int32 sim_switches;
|
|
||||||
extern UNIT cpu_unit;
|
|
||||||
extern void WriteB (int32 pa, int32 val);
|
|
||||||
extern void rom_wr_B (int32 pa, int32 val);
|
|
||||||
|
|
||||||
DEVICE *sim_devices[] = {
|
|
||||||
&cpu_dev,
|
|
||||||
&tlb_dev,
|
|
||||||
&sbi_dev,
|
|
||||||
&mctl0_dev,
|
|
||||||
&mctl1_dev,
|
|
||||||
&uba_dev,
|
|
||||||
&mba0_dev,
|
|
||||||
&mba1_dev,
|
|
||||||
&clk_dev,
|
|
||||||
&tmr_dev,
|
|
||||||
&tti_dev,
|
|
||||||
&tto_dev,
|
|
||||||
&fl_dev,
|
|
||||||
&dz_dev,
|
|
||||||
&lpt_dev,
|
|
||||||
&rp_dev,
|
|
||||||
&rl_dev,
|
|
||||||
&hk_dev,
|
|
||||||
&rq_dev,
|
|
||||||
&rqb_dev,
|
|
||||||
&rqc_dev,
|
|
||||||
&rqd_dev,
|
|
||||||
&ry_dev,
|
|
||||||
&tu_dev,
|
|
||||||
&ts_dev,
|
|
||||||
&tq_dev,
|
|
||||||
&xu_dev,
|
|
||||||
&xub_dev,
|
|
||||||
NULL };
|
|
||||||
|
|
||||||
|
|
||||||
/* Binary loader
|
|
||||||
|
|
||||||
The binary loader handles absolute system images, that is, system
|
|
||||||
images linked /SYSTEM. These are simply a byte stream, with no
|
|
||||||
origin or relocation information.
|
|
||||||
|
|
||||||
-r load ROM0
|
|
||||||
-s load ROM1
|
|
||||||
-o for memory, specify origin
|
|
||||||
*/
|
|
||||||
|
|
||||||
t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag)
|
|
||||||
{
|
|
||||||
t_stat r;
|
|
||||||
int32 val;
|
|
||||||
uint32 origin, limit;
|
|
||||||
|
|
||||||
if (flag) return SCPE_ARG; /* dump? */
|
|
||||||
origin = 0; /* memory */
|
|
||||||
limit = (uint32) cpu_unit.capac;
|
|
||||||
if (sim_switches & SWMASK ('O')) { /* origin? */
|
|
||||||
origin = (int32) get_uint (cptr, 16, 0xFFFFFFFF, &r);
|
|
||||||
if (r != SCPE_OK) return SCPE_ARG; }
|
|
||||||
|
|
||||||
while ((val = getc (fileref)) != EOF) { /* read byte stream */
|
|
||||||
if (sim_switches & SWMASK ('R')) { /* ROM0? */
|
|
||||||
if (origin >= ROMSIZE) return SCPE_NXM;
|
|
||||||
rom_wr_B (ROM0BASE + origin, val); }
|
|
||||||
else if (sim_switches & SWMASK ('S')) { /* ROM1? */
|
|
||||||
if (origin >= ROMSIZE) return SCPE_NXM;
|
|
||||||
rom_wr_B (ROM1BASE + origin, val); }
|
|
||||||
else {
|
|
||||||
if (origin >= limit) return SCPE_NXM; /* NXM? */
|
|
||||||
WriteB (origin, val); } /* memory */
|
|
||||||
origin = origin + 1; }
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
1104
VAX/vax780_uba.c
1104
VAX/vax780_uba.c
File diff suppressed because it is too large
Load diff
|
@ -408,8 +408,8 @@ case CRC:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case MOVP:
|
case MOVP:
|
||||||
if (PSL & PSL_FPD) RSVD_INST_FAULT;
|
if ((PSL & PSL_FPD) || (op[0] > 31))
|
||||||
if (op[0] > 31) RSVD_OPND_FAULT;
|
RSVD_OPND_FAULT;
|
||||||
ReadDstr (op[0], op[1], &dst, acc); /* read source */
|
ReadDstr (op[0], op[1], &dst, acc); /* read source */
|
||||||
cc = WriteDstr (op[0], op[2], &dst, 0, acc) | /* write dest */
|
cc = WriteDstr (op[0], op[2], &dst, 0, acc) | /* write dest */
|
||||||
(cc & CC_C); /* preserve C */
|
(cc & CC_C); /* preserve C */
|
||||||
|
@ -445,8 +445,8 @@ case ADDP4: case SUBP4:
|
||||||
op[4] = op[2]; /* copy dst */
|
op[4] = op[2]; /* copy dst */
|
||||||
op[5] = op[3];
|
op[5] = op[3];
|
||||||
case ADDP6: case SUBP6:
|
case ADDP6: case SUBP6:
|
||||||
if (PSL & PSL_FPD) RSVD_INST_FAULT;
|
if ((PSL & PSL_FPD) || (op[0] > 31) ||
|
||||||
if ((op[0] > 31) || (op[2] > 31) || (op[4] > 31))
|
(op[2] > 31) || (op[4] > 31))
|
||||||
RSVD_OPND_FAULT;
|
RSVD_OPND_FAULT;
|
||||||
ReadDstr (op[0], op[1], &src1, acc); /* get src1 */
|
ReadDstr (op[0], op[1], &src1, acc); /* get src1 */
|
||||||
ReadDstr (op[2], op[3], &src2, acc); /* get src2 */
|
ReadDstr (op[2], op[3], &src2, acc); /* get src2 */
|
||||||
|
@ -498,8 +498,8 @@ case ADDP6: case SUBP6:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case MULP:
|
case MULP:
|
||||||
if (PSL & PSL_FPD) RSVD_INST_FAULT;
|
if ((PSL & PSL_FPD) || (op[0] > 31) ||
|
||||||
if ((op[0] > 31) || (op[2] > 31) || (op[4] > 31))
|
(op[2] > 31) || (op[4] > 31))
|
||||||
RSVD_OPND_FAULT;
|
RSVD_OPND_FAULT;
|
||||||
dst = Dstr_zero; /* clear result */
|
dst = Dstr_zero; /* clear result */
|
||||||
if (ReadDstr (op[0], op[1], &src1, acc) && /* read src1, src2 */
|
if (ReadDstr (op[0], op[1], &src1, acc) && /* read src1, src2 */
|
||||||
|
@ -548,8 +548,8 @@ case MULP:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case DIVP:
|
case DIVP:
|
||||||
if (PSL & PSL_FPD) RSVD_INST_FAULT;
|
if ((PSL & PSL_FPD) || (op[0] > 31) ||
|
||||||
if ((op[0] > 31) || (op[2] > 31) || (op[4] > 31))
|
(op[2] > 31) || (op[4] > 31))
|
||||||
RSVD_OPND_FAULT;
|
RSVD_OPND_FAULT;
|
||||||
ldivr = ReadDstr (op[0], op[1], &src1, acc); /* get divisor */
|
ldivr = ReadDstr (op[0], op[1], &src1, acc); /* get divisor */
|
||||||
if (ldivr == 0) { /* divisor = 0? */
|
if (ldivr == 0) { /* divisor = 0? */
|
||||||
|
@ -613,8 +613,8 @@ case CMPP3:
|
||||||
op[3] = op[2]; /* reposition ops */
|
op[3] = op[2]; /* reposition ops */
|
||||||
op[2] = op[0];
|
op[2] = op[0];
|
||||||
case CMPP4:
|
case CMPP4:
|
||||||
if (PSL & PSL_FPD) RSVD_INST_FAULT;
|
if ((PSL & PSL_FPD) || (op[0] > 31) || (op[2] > 31))
|
||||||
if ((op[0] > 31) || (op[2] > 31)) RSVD_OPND_FAULT;
|
RSVD_OPND_FAULT;
|
||||||
ReadDstr (op[0], op[1], &src1, acc); /* get src1 */
|
ReadDstr (op[0], op[1], &src1, acc); /* get src1 */
|
||||||
ReadDstr (op[1], op[2], &src2, acc); /* get src2 */
|
ReadDstr (op[1], op[2], &src2, acc); /* get src2 */
|
||||||
cc = 0;
|
cc = 0;
|
||||||
|
@ -651,8 +651,8 @@ case CMPP4:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case ASHP:
|
case ASHP:
|
||||||
if (PSL & PSL_FPD) RSVD_INST_FAULT;
|
if ((PSL & PSL_FPD) || (op[1] > 31) || (op[4] > 31))
|
||||||
if ((op[1] > 31) || (op[4] > 31)) RSVD_OPND_FAULT;
|
RSVD_OPND_FAULT;
|
||||||
ReadDstr (op[1], op[2], &src1, acc); /* get source */
|
ReadDstr (op[1], op[2], &src1, acc); /* get source */
|
||||||
V = 0; /* init V */
|
V = 0; /* init V */
|
||||||
shift = op[0]; /* get shift count */
|
shift = op[0]; /* get shift count */
|
||||||
|
@ -695,8 +695,8 @@ case ASHP:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case CVTPL:
|
case CVTPL:
|
||||||
if (PSL & PSL_FPD) RSVD_INST_FAULT;
|
if ((PSL & PSL_FPD) || (op[0] > 31))
|
||||||
if (op[0] > 31) RSVD_OPND_FAULT;
|
RSVD_OPND_FAULT;
|
||||||
ReadDstr (op[0], op[1], &src1, acc); /* get source */
|
ReadDstr (op[0], op[1], &src1, acc); /* get source */
|
||||||
V = result = 0; /* clear V, result */
|
V = result = 0; /* clear V, result */
|
||||||
for (i = (DSTRLNT * 8) - 1; i > 0; i--) { /* loop thru digits */
|
for (i = (DSTRLNT * 8) - 1; i > 0; i--) { /* loop thru digits */
|
||||||
|
@ -737,8 +737,8 @@ case CVTPL:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case CVTLP:
|
case CVTLP:
|
||||||
if (PSL & PSL_FPD) RSVD_INST_FAULT;
|
if ((PSL & PSL_FPD) || (op[1] > 31))
|
||||||
if (op[1] > 31) RSVD_OPND_FAULT;
|
RSVD_OPND_FAULT;
|
||||||
dst = Dstr_zero; /* clear result */
|
dst = Dstr_zero; /* clear result */
|
||||||
result = op[0];
|
result = op[0];
|
||||||
if ((result & LSIGN) != 0) {
|
if ((result & LSIGN) != 0) {
|
||||||
|
@ -775,8 +775,8 @@ case CVTLP:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case CVTSP:
|
case CVTSP:
|
||||||
if (PSL & PSL_FPD) RSVD_INST_FAULT;
|
if ((PSL & PSL_FPD) || (op[0] > 31) || (op[2] > 31))
|
||||||
if ((op[0] > 31) || (op[2] > 31)) RSVD_OPND_FAULT;
|
RSVD_OPND_FAULT;
|
||||||
dst = Dstr_zero; /* clear result */
|
dst = Dstr_zero; /* clear result */
|
||||||
t = Read (op[1], L_BYTE, RA); /* read source sign */
|
t = Read (op[1], L_BYTE, RA); /* read source sign */
|
||||||
if (t == C_MINUS) dst.sign = 1; /* sign -, */
|
if (t == C_MINUS) dst.sign = 1; /* sign -, */
|
||||||
|
@ -815,8 +815,8 @@ case CVTSP:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case CVTPS:
|
case CVTPS:
|
||||||
if (PSL & PSL_FPD) RSVD_INST_FAULT;
|
if ((PSL & PSL_FPD) || (op[0] > 31) || (op[2] > 31))
|
||||||
if ((op[0] > 31) || (op[2] > 31)) RSVD_OPND_FAULT;
|
RSVD_OPND_FAULT;
|
||||||
ReadDstr (op[0], op[1], &dst, acc); /* get src */
|
ReadDstr (op[0], op[1], &dst, acc); /* get src */
|
||||||
ProbeDstr (op[2], op[3], WA); /* test dst write */
|
ProbeDstr (op[2], op[3], WA); /* test dst write */
|
||||||
Write (op[3], dst.sign? C_MINUS: C_PLUS, L_BYTE, WA);
|
Write (op[3], dst.sign? C_MINUS: C_PLUS, L_BYTE, WA);
|
||||||
|
@ -851,8 +851,8 @@ case CVTPS:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case CVTTP:
|
case CVTTP:
|
||||||
if (PSL & PSL_FPD) RSVD_INST_FAULT;
|
if ((PSL & PSL_FPD) || (op[0] > 31) || (op[3] > 31))
|
||||||
if ((op[0] > 31) || (op[3] > 31)) RSVD_OPND_FAULT;
|
RSVD_OPND_FAULT;
|
||||||
dst = Dstr_zero; /* clear result */
|
dst = Dstr_zero; /* clear result */
|
||||||
for (i = 1; i <= op[0]; i++) { /* loop thru char */
|
for (i = 1; i <= op[0]; i++) { /* loop thru char */
|
||||||
c = Read ((op[1] + op[0] - i) & LMASK, L_BYTE, RA); /* read char */
|
c = Read ((op[1] + op[0] - i) & LMASK, L_BYTE, RA); /* read char */
|
||||||
|
@ -897,17 +897,17 @@ case CVTTP:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case CVTPT:
|
case CVTPT:
|
||||||
if (PSL & PSL_FPD) RSVD_INST_FAULT;
|
if ((PSL & PSL_FPD) || (op[0] > 31) || (op[3] > 31))
|
||||||
if ((op[0] > 31) || (op[3] > 31)) RSVD_OPND_FAULT;
|
RSVD_OPND_FAULT;
|
||||||
ReadDstr (op[0], op[1], &dst, acc); /* get source */
|
ReadDstr (op[0], op[1], &dst, acc); /* get source */
|
||||||
ProbeDstr (op[3], op[4], WA); /* test writeability */
|
ProbeDstr (op[3], op[4], WA); /* test writeability */
|
||||||
for (i = 1; i <= op[3]; i++) { /* loop thru chars */
|
for (i = 1; i <= op[3]; i++) { /* loop thru chars */
|
||||||
if (i != op[3]) { /* not last? */
|
if (i != 1) { /* not last? */
|
||||||
d = (dst.val[i / 8] >> ((i % 8) * 4)) & 0xF; /* get digit */
|
d = (dst.val[i / 8] >> ((i % 8) * 4)) & 0xF; /* get digit */
|
||||||
c = d + C_ZERO; /* convert */
|
c = d + C_ZERO; /* convert */
|
||||||
}
|
}
|
||||||
else { /* translate last */
|
else { /* translate last */
|
||||||
t = Read ((op[1] + op[0]) & LMASK, L_BYTE, RA);
|
t = Read ((op[1] + (op[0] / 2)) & LMASK, L_BYTE, RA);
|
||||||
c = Read ((op[2] + t) & LMASK, L_BYTE, RA);
|
c = Read ((op[2] + t) & LMASK, L_BYTE, RA);
|
||||||
}
|
}
|
||||||
Write ((op[4] + op[3] - i) & LMASK, c, L_BYTE, WA);
|
Write ((op[4] + op[3] - i) & LMASK, c, L_BYTE, WA);
|
||||||
|
@ -971,8 +971,8 @@ case EDITPC:
|
||||||
}
|
}
|
||||||
else { /* new instr */
|
else { /* new instr */
|
||||||
if (op[0] > 31) RSVD_OPND_FAULT; /* lnt > 31? */
|
if (op[0] > 31) RSVD_OPND_FAULT; /* lnt > 31? */
|
||||||
d = Read ((op[1] + (op[0] / 2)) & LMASK, L_BYTE, RA) & 0xF;
|
t = Read ((op[1] + (op[0] / 2)) & LMASK, L_BYTE, RA) & 0xF;
|
||||||
if ((d == 0xB) || (d == 0xD)) {
|
if ((t == 0xB) || (t == 0xD)) {
|
||||||
cc = CC_N | CC_Z;
|
cc = CC_N | CC_Z;
|
||||||
sign = C_MINUS;
|
sign = C_MINUS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,8 @@ int32 op_mulh (int32 *opnd, int32 *hf);
|
||||||
int32 op_divh (int32 *opnd, int32 *hf);
|
int32 op_divh (int32 *opnd, int32 *hf);
|
||||||
int32 op_emodh (int32 *opnd, int32 *hflt, int32 *intgr, int32 *flg);
|
int32 op_emodh (int32 *opnd, int32 *hflt, int32 *intgr, int32 *flg);
|
||||||
void op_polyh (int32 *opnd, int32 acc);
|
void op_polyh (int32 *opnd, int32 acc);
|
||||||
|
void h_write_b (int32 spec, int32 va, int32 val, int32 acc);
|
||||||
|
void h_write_w (int32 spec, int32 va, int32 val, int32 acc);
|
||||||
void h_write_l (int32 spec, int32 va, int32 val, int32 acc);
|
void h_write_l (int32 spec, int32 va, int32 val, int32 acc);
|
||||||
void h_write_q (int32 spec, int32 va, int32 vl, int32 vh, int32 acc);
|
void h_write_q (int32 spec, int32 va, int32 vl, int32 vh, int32 acc);
|
||||||
void h_write_o (int32 spec, int32 va, int32 *val, int32 acc);
|
void h_write_o (int32 spec, int32 va, int32 *val, int32 acc);
|
||||||
|
@ -90,7 +92,6 @@ void vax_hmod (UFPH *a, int32 *intgr, int32 *flg);
|
||||||
void vax_hdiv (UFPH *a, UFPH *b);
|
void vax_hdiv (UFPH *a, UFPH *b);
|
||||||
void qp_add (UQP *a, UQP *b);
|
void qp_add (UQP *a, UQP *b);
|
||||||
void qp_inc (UQP *a);
|
void qp_inc (UQP *a);
|
||||||
void qp_sub (UQP *a, UQP *b);
|
|
||||||
void qp_lsh (UQP *a, uint32 sc);
|
void qp_lsh (UQP *a, uint32 sc);
|
||||||
void qp_rsh (UQP *a, uint32 sc);
|
void qp_rsh (UQP *a, uint32 sc);
|
||||||
void qp_rsh_s (UQP *a, uint32 sc, uint32 neg);
|
void qp_rsh_s (UQP *a, uint32 sc, uint32 neg);
|
||||||
|
@ -110,7 +111,7 @@ static int32 z_octa[4] = { 0, 0, 0, 0 };
|
||||||
|
|
||||||
int32 op_octa (int32 *opnd, int32 cc, int32 opc, int32 acc, int32 spec, int32 va)
|
int32 op_octa (int32 *opnd, int32 cc, int32 opc, int32 acc, int32 spec, int32 va)
|
||||||
{
|
{
|
||||||
int32 r, rh, temp, flg, rn;
|
int32 r, rh, temp, flg;
|
||||||
int32 r_octa[4];
|
int32 r_octa[4];
|
||||||
|
|
||||||
switch (opc) {
|
switch (opc) {
|
||||||
|
@ -173,12 +174,14 @@ case MOVO:
|
||||||
h_write_o (spec, va, opnd, acc); /* write src */
|
h_write_o (spec, va, opnd, acc); /* write src */
|
||||||
CC_IIZP_O (opnd[0], opnd[1], opnd[2], opnd[3]); /* set cc's */
|
CC_IIZP_O (opnd[0], opnd[1], opnd[2], opnd[3]); /* set cc's */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MOVH:
|
case MOVH:
|
||||||
if (r = op_tsth (opnd[0])) /* test for 0 */
|
if (r = op_tsth (opnd[0])) /* test for 0 */
|
||||||
h_write_o (spec, va, opnd, acc); /* nz, write result */
|
h_write_o (spec, va, opnd, acc); /* nz, write result */
|
||||||
else h_write_o (spec, va, z_octa, acc); /* zero, write 0 */
|
else h_write_o (spec, va, z_octa, acc); /* zero, write 0 */
|
||||||
CC_IIZP_FP (r); /* set cc's */
|
CC_IIZP_FP (r); /* set cc's */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MNEGH:
|
case MNEGH:
|
||||||
if (r = op_tsth (opnd[0])) { /* test for 0 */
|
if (r = op_tsth (opnd[0])) { /* test for 0 */
|
||||||
opnd[0] = opnd[0] ^ FPSIGN; /* nz, invert sign */
|
opnd[0] = opnd[0] ^ FPSIGN; /* nz, invert sign */
|
||||||
|
@ -211,11 +214,13 @@ case CVTBH:
|
||||||
h_write_o (spec, va, r_octa, acc); /* write reslt */
|
h_write_o (spec, va, r_octa, acc); /* write reslt */
|
||||||
CC_IIZZ_FP (r); /* set cc's */
|
CC_IIZZ_FP (r); /* set cc's */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CVTWH:
|
case CVTWH:
|
||||||
r = op_cvtih (SXTW (opnd[0]), r_octa); /* convert */
|
r = op_cvtih (SXTW (opnd[0]), r_octa); /* convert */
|
||||||
h_write_o (spec, va, r_octa, acc); /* write result */
|
h_write_o (spec, va, r_octa, acc); /* write result */
|
||||||
CC_IIZZ_FP (r); /* set cc's */
|
CC_IIZZ_FP (r); /* set cc's */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CVTLH:
|
case CVTLH:
|
||||||
r = op_cvtih (opnd[0], r_octa); /* convert */
|
r = op_cvtih (opnd[0], r_octa); /* convert */
|
||||||
h_write_o (spec, va, r_octa, acc); /* write result */
|
h_write_o (spec, va, r_octa, acc); /* write result */
|
||||||
|
@ -232,22 +237,18 @@ case CVTLH:
|
||||||
|
|
||||||
case CVTHB:
|
case CVTHB:
|
||||||
r = op_cvthi (opnd, &temp, opc) & BMASK; /* convert */
|
r = op_cvthi (opnd, &temp, opc) & BMASK; /* convert */
|
||||||
if (spec > (GRN | nPC)) Write (va, r, L_BYTE, WA);
|
h_write_b (spec, va, r, acc); /* write result */
|
||||||
else {
|
|
||||||
rn = spec & 0xF;
|
|
||||||
R[rn] = (R[rn] & ~BMASK) | r; }
|
|
||||||
CC_IIZZ_B (r); /* set cc's */
|
CC_IIZZ_B (r); /* set cc's */
|
||||||
cc = cc | temp; /* or in V */
|
cc = cc | temp; /* or in V */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CVTHW:
|
case CVTHW:
|
||||||
r = op_cvthi (opnd, &temp, opc) & WMASK; /* convert */
|
r = op_cvthi (opnd, &temp, opc) & WMASK; /* convert */
|
||||||
if (spec > (GRN | nPC)) Write (va, r, L_WORD, WA);
|
h_write_w (spec, va, r, acc); /* write result */
|
||||||
else {
|
|
||||||
rn = spec & 0xF;
|
|
||||||
R[rn] = (R[rn] & ~WMASK) | r; }
|
|
||||||
CC_IIZZ_W (r); /* set cc's */
|
CC_IIZZ_W (r); /* set cc's */
|
||||||
cc = cc | temp; /* or in V */
|
cc = cc | temp; /* or in V */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CVTHL: case CVTRHL:
|
case CVTHL: case CVTRHL:
|
||||||
r = op_cvthi (opnd, &temp, opc) & LMASK; /* convert */
|
r = op_cvthi (opnd, &temp, opc) & LMASK; /* convert */
|
||||||
h_write_l (spec, va, r, acc); /* write result */
|
h_write_l (spec, va, r, acc); /* write result */
|
||||||
|
@ -282,6 +283,7 @@ case CVTDH:
|
||||||
h_write_o (spec, va, r_octa, acc); /* write result */
|
h_write_o (spec, va, r_octa, acc); /* write result */
|
||||||
CC_IIZZ_FP (r); /* set cc's */
|
CC_IIZZ_FP (r); /* set cc's */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CVTGH:
|
case CVTGH:
|
||||||
r = op_cvtgh (opnd[0], opnd[1], r_octa); /* convert */
|
r = op_cvtgh (opnd[0], opnd[1], r_octa); /* convert */
|
||||||
h_write_o (spec, va, r_octa, acc); /* write result */
|
h_write_o (spec, va, r_octa, acc); /* write result */
|
||||||
|
@ -301,11 +303,13 @@ case CVTHF:
|
||||||
h_write_l (spec, va, r, acc); /* write result */
|
h_write_l (spec, va, r, acc); /* write result */
|
||||||
CC_IIZZ_FP (r); /* set cc's */
|
CC_IIZZ_FP (r); /* set cc's */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CVTHD:
|
case CVTHD:
|
||||||
r = op_cvthfd (opnd, &rh); /* convert */
|
r = op_cvthfd (opnd, &rh); /* convert */
|
||||||
h_write_q (spec, va, r, rh, acc); /* write result */
|
h_write_q (spec, va, r, rh, acc); /* write result */
|
||||||
CC_IIZZ_FP (r); /* set cc's */
|
CC_IIZZ_FP (r); /* set cc's */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CVTHG:
|
case CVTHG:
|
||||||
r = op_cvthg (opnd, &rh); /* convert */
|
r = op_cvthg (opnd, &rh); /* convert */
|
||||||
h_write_q (spec, va, r, rh, acc); /* write result */
|
h_write_q (spec, va, r, rh, acc); /* write result */
|
||||||
|
@ -334,16 +338,19 @@ case ADDH2: case ADDH3:
|
||||||
h_write_o (spec, va, r_octa, acc); /* write result */
|
h_write_o (spec, va, r_octa, acc); /* write result */
|
||||||
CC_IIZZ_FP (r); /* set cc's */
|
CC_IIZZ_FP (r); /* set cc's */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBH2: case SUBH3:
|
case SUBH2: case SUBH3:
|
||||||
r = op_addh (opnd, r_octa, TRUE); /* subtract */
|
r = op_addh (opnd, r_octa, TRUE); /* subtract */
|
||||||
h_write_o (spec, va, r_octa, acc); /* write result */
|
h_write_o (spec, va, r_octa, acc); /* write result */
|
||||||
CC_IIZZ_FP (r); /* set cc's */
|
CC_IIZZ_FP (r); /* set cc's */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MULH2: case MULH3:
|
case MULH2: case MULH3:
|
||||||
r = op_mulh (opnd, r_octa); /* multiply */
|
r = op_mulh (opnd, r_octa); /* multiply */
|
||||||
h_write_o (spec, va, r_octa, acc); /* write result */
|
h_write_o (spec, va, r_octa, acc); /* write result */
|
||||||
CC_IIZZ_FP (r); /* set cc's */
|
CC_IIZZ_FP (r); /* set cc's */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DIVH2: case DIVH3:
|
case DIVH2: case DIVH3:
|
||||||
r = op_divh (opnd, r_octa); /* divide */
|
r = op_divh (opnd, r_octa); /* divide */
|
||||||
h_write_o (spec, va, r_octa, acc); /* write result */
|
h_write_o (spec, va, r_octa, acc); /* write result */
|
||||||
|
@ -649,12 +656,9 @@ if ((a->exp < b->exp) || /* |s1| < |s2|? */
|
||||||
}
|
}
|
||||||
ediff = a->exp - b->exp; /* exp diff */
|
ediff = a->exp - b->exp; /* exp diff */
|
||||||
if (a->sign ^ b->sign) { /* eff sub? */
|
if (a->sign ^ b->sign) { /* eff sub? */
|
||||||
if (ediff) { /* exp diff? */
|
|
||||||
qp_neg (&b->frac); /* negate fraction */
|
qp_neg (&b->frac); /* negate fraction */
|
||||||
qp_rsh_s (&b->frac, ediff, 1); /* signed right */
|
if (ediff) qp_rsh_s (&b->frac, ediff, 1); /* denormalize */
|
||||||
qp_add (&a->frac, &b->frac); /* "add" frac */
|
qp_add (&a->frac, &b->frac); /* "add" frac */
|
||||||
}
|
|
||||||
else qp_sub (&a->frac, &b->frac); /* a >= b */
|
|
||||||
h_normh (a); /* normalize */
|
h_normh (a); /* normalize */
|
||||||
}
|
}
|
||||||
else { if (ediff) qp_rsh (&b->frac, ediff); /* add, denormalize */
|
else { if (ediff) qp_rsh (&b->frac, ediff); /* add, denormalize */
|
||||||
|
@ -738,7 +742,7 @@ return;
|
||||||
void vax_hdiv (UFPH *a, UFPH *b)
|
void vax_hdiv (UFPH *a, UFPH *b)
|
||||||
{
|
{
|
||||||
int32 i;
|
int32 i;
|
||||||
UQP quo = { 0, 0, 0, 0 };
|
UQP ndvr, quo = { 0, 0, 0, 0 };
|
||||||
|
|
||||||
if (a->exp == 0) FLT_DZRO_FAULT; /* divr = 0? */
|
if (a->exp == 0) FLT_DZRO_FAULT; /* divr = 0? */
|
||||||
if (b->exp == 0) return; /* divd = 0? */
|
if (b->exp == 0) return; /* divd = 0? */
|
||||||
|
@ -746,11 +750,14 @@ b->sign = b->sign ^ a->sign; /* result sign */
|
||||||
b->exp = b->exp - a->exp + H_BIAS + 1; /* unbiased exp */
|
b->exp = b->exp - a->exp + H_BIAS + 1; /* unbiased exp */
|
||||||
qp_rsh (&a->frac, 1); /* allow 1 bit left */
|
qp_rsh (&a->frac, 1); /* allow 1 bit left */
|
||||||
qp_rsh (&b->frac, 1);
|
qp_rsh (&b->frac, 1);
|
||||||
|
ndvr = a->frac; /* copy divisor */
|
||||||
|
qp_neg (&ndvr); /* and negate */
|
||||||
for (i = 0; i < 128; i++) { /* divide loop */
|
for (i = 0; i < 128; i++) { /* divide loop */
|
||||||
qp_lsh (&quo, 1); /* shift quo */
|
qp_lsh (&quo, 1); /* shift quo */
|
||||||
if (qp_cmp (&b->frac, &a->frac) >= 0) { /* div step ok? */
|
if (qp_cmp (&b->frac, &a->frac) >= 0) { /* div step ok? */
|
||||||
qp_sub (&b->frac, &a->frac); /* subtract */
|
qp_add (&b->frac, &ndvr); /* "subtract" */
|
||||||
quo.f0 = quo.f0 + 1; } /* quo bit = 1 */
|
quo.f0 = quo.f0 + 1; /* quo bit = 1 */
|
||||||
|
}
|
||||||
qp_lsh (&b->frac, 1); /* shift divd */
|
qp_lsh (&b->frac, 1); /* shift divd */
|
||||||
}
|
}
|
||||||
b->frac = quo;
|
b->frac = quo;
|
||||||
|
@ -803,15 +810,6 @@ r->f3 = (~r->f3 + (r->f2 == 0)) & LMASK;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void qp_sub (UQP *a, UQP *b)
|
|
||||||
{
|
|
||||||
UQP nb = *b;
|
|
||||||
|
|
||||||
qp_neg (&nb);
|
|
||||||
qp_add (a, &nb);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void qp_lsh (UQP *r, uint32 sc)
|
void qp_lsh (UQP *r, uint32 sc)
|
||||||
{
|
{
|
||||||
if (sc >= 128) r->f3 = r->f2 = r->f1 = r->f0 = 0; /* > 127? result 0 */
|
if (sc >= 128) r->f3 = r->f2 = r->f1 = r->f0 = 0; /* > 127? result 0 */
|
||||||
|
@ -1050,6 +1048,28 @@ hflt[3] = WORDSWAP (r->frac.f0);
|
||||||
return hflt[0];
|
return hflt[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void h_write_b (int32 spec, int32 va, int32 val, int32 acc)
|
||||||
|
{
|
||||||
|
int32 rn;
|
||||||
|
|
||||||
|
if (spec > (GRN | nPC)) Write (va, val, L_BYTE, WA);
|
||||||
|
else { rn = spec & 0xF;
|
||||||
|
R[rn] = (R[rn] & ~BMASK) | val;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void h_write_w (int32 spec, int32 va, int32 val, int32 acc)
|
||||||
|
{
|
||||||
|
int32 rn;
|
||||||
|
|
||||||
|
if (spec > (GRN | nPC)) Write (va, val, L_WORD, WA);
|
||||||
|
else { rn = spec & 0xF;
|
||||||
|
R[rn] = (R[rn] & ~WMASK) | val;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void h_write_l (int32 spec, int32 va, int32 val, int32 acc)
|
void h_write_l (int32 spec, int32 va, int32 val, int32 acc)
|
||||||
{
|
{
|
||||||
if (spec > (GRN | nPC)) Write (va, val, L_LONG, WA);
|
if (spec > (GRN | nPC)) Write (va, val, L_LONG, WA);
|
||||||
|
@ -1064,11 +1084,13 @@ int32 rn, mstat;
|
||||||
if (spec > (GRN | nPC)) {
|
if (spec > (GRN | nPC)) {
|
||||||
if (Test (va + 7, WA, &mstat) >= 0)
|
if (Test (va + 7, WA, &mstat) >= 0)
|
||||||
Write (va, vl, L_LONG, WA);
|
Write (va, vl, L_LONG, WA);
|
||||||
Write (va + 4, vh, L_LONG, WA); }
|
Write (va + 4, vh, L_LONG, WA);
|
||||||
|
}
|
||||||
else { rn = spec & 0xF;
|
else { rn = spec & 0xF;
|
||||||
if (rn >= nSP) RSVD_ADDR_FAULT;
|
if (rn >= nSP) RSVD_ADDR_FAULT;
|
||||||
R[rn] = vl;
|
R[rn] = vl;
|
||||||
R[rn + 1] = vh; }
|
R[rn + 1] = vh;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1081,13 +1103,15 @@ if (spec > (GRN | nPC)) {
|
||||||
Write (va, val[0], L_LONG, WA);
|
Write (va, val[0], L_LONG, WA);
|
||||||
Write (va + 4, val[1], L_LONG, WA);
|
Write (va + 4, val[1], L_LONG, WA);
|
||||||
Write (va + 8, val[2], L_LONG, WA);
|
Write (va + 8, val[2], L_LONG, WA);
|
||||||
Write (va + 12, val[3], L_LONG, WA); }
|
Write (va + 12, val[3], L_LONG, WA);
|
||||||
|
}
|
||||||
else { rn = spec & 0xF;
|
else { rn = spec & 0xF;
|
||||||
if (rn >= nAP) RSVD_ADDR_FAULT;
|
if (rn >= nAP) RSVD_ADDR_FAULT;
|
||||||
R[rn] = val[0];
|
R[rn] = val[0];
|
||||||
R[rn + 1] = val[1];
|
R[rn + 1] = val[1];
|
||||||
R[rn + 2] = val[2];
|
R[rn + 2] = val[2];
|
||||||
R[rn + 3] = val[3]; }
|
R[rn + 3] = val[3];
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* vax_sysdev.c: VAX 3900 system-specific logic
|
/* vax_sysdev.c: VAX 3900 system-specific logic
|
||||||
|
|
||||||
Copyright (c) 1998-2004, Robert M Supnik
|
Copyright (c) 1998-2005, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -32,6 +32,7 @@
|
||||||
cso console storage output
|
cso console storage output
|
||||||
sysd system devices (SSC miscellany)
|
sysd system devices (SSC miscellany)
|
||||||
|
|
||||||
|
10-Mar-05 RMS Fixed bug in timer schedule routine (from Mark Hittinger)
|
||||||
30-Sep-04 RMS Moved CADR, MSER, CONPC, CONPSL, machine_check, cpu_boot,
|
30-Sep-04 RMS Moved CADR, MSER, CONPC, CONPSL, machine_check, cpu_boot,
|
||||||
con_halt here from vax_cpu.c
|
con_halt here from vax_cpu.c
|
||||||
Moved model-specific IPR's here from vax_cpu1.c
|
Moved model-specific IPR's here from vax_cpu1.c
|
||||||
|
@ -1283,7 +1284,7 @@ if (tmr_tir[tmr] > (0xFFFFFFFFu - TMR_INC)) { /* short interval? */
|
||||||
else { tmr_inc[tmr] = TMR_INC; /* usec/interval */
|
else { tmr_inc[tmr] = TMR_INC; /* usec/interval */
|
||||||
tmr_time = tmr_poll; }
|
tmr_time = tmr_poll; }
|
||||||
if (tmr_time == 0) tmr_time = 1;
|
if (tmr_time == 0) tmr_time = 1;
|
||||||
if ((tmr_inc[tmr] = TMR_INC) && (tmr_time > clk_time)) {
|
if ((tmr_inc[tmr] == TMR_INC) && (tmr_time > clk_time)) {
|
||||||
|
|
||||||
/* Align scheduled event to be identical to the event for the next clock
|
/* Align scheduled event to be identical to the event for the next clock
|
||||||
tick. This lets us always see a consistent calibrated value, both for
|
tick. This lets us always see a consistent calibrated value, both for
|
||||||
|
|
|
@ -246,8 +246,14 @@ HP2100_SOURCE = $(HP2100_DIR)HP2100_STDDEV.C,$(HP2100_DIR)HP2100_DP.C,\
|
||||||
$(HP2100_DIR)HP2100_MT.C,$(HP2100_DIR)HP2100_MUX.C,\
|
$(HP2100_DIR)HP2100_MT.C,$(HP2100_DIR)HP2100_MUX.C,\
|
||||||
$(HP2100_DIR)HP2100_CPU.C,$(HP2100_DIR)HP2100_FP.C,\
|
$(HP2100_DIR)HP2100_CPU.C,$(HP2100_DIR)HP2100_FP.C,\
|
||||||
$(HP2100_DIR)HP2100_SYS.C,$(HP2100_DIR)HP2100_LPT.C,\
|
$(HP2100_DIR)HP2100_SYS.C,$(HP2100_DIR)HP2100_LPT.C,\
|
||||||
$(HP2100_DIR)HP2100_IPL.C,$(HP2100_DIR)HP2100_CPU1.C
|
$(HP2100_DIR)HP2100_IPL.C,$(HP2100_DIR)HP2100_CPU1.C,\
|
||||||
|
$(HP2100_DIR)HP2100_FP1.C
|
||||||
|
.IFDEF MMSALPHA
|
||||||
|
HP2100_OPTIONS = /INCLUDE=($(SIMH_DIR),$(HP2100_DIR))\
|
||||||
|
/DEFINE=($(CC_DEFS),"HAVE_INT64=1")
|
||||||
|
.ELSE
|
||||||
HP2100_OPTIONS = /INCLUDE=($(SIMH_DIR),$(HP2100_DIR))/DEFINE=($(CC_DEFS))
|
HP2100_OPTIONS = /INCLUDE=($(SIMH_DIR),$(HP2100_DIR))/DEFINE=($(CC_DEFS))
|
||||||
|
.ENDIF
|
||||||
|
|
||||||
#
|
#
|
||||||
# Interdata 16-bit CPU.
|
# Interdata 16-bit CPU.
|
||||||
|
|
5
makefile
5
makefile
|
@ -147,8 +147,9 @@ HP2100 = ${HP2100D}hp2100_stddev.c ${HP2100D}hp2100_dp.c ${HP2100D}hp2100_dq.c \
|
||||||
${HP2100D}hp2100_dr.c ${HP2100D}hp2100_lps.c ${HP2100D}hp2100_ms.c \
|
${HP2100D}hp2100_dr.c ${HP2100D}hp2100_lps.c ${HP2100D}hp2100_ms.c \
|
||||||
${HP2100D}hp2100_mt.c ${HP2100D}hp2100_mux.c ${HP2100D}hp2100_cpu.c \
|
${HP2100D}hp2100_mt.c ${HP2100D}hp2100_mux.c ${HP2100D}hp2100_cpu.c \
|
||||||
${HP2100D}hp2100_fp.c ${HP2100D}hp2100_sys.c ${HP2100D}hp2100_lpt.c \
|
${HP2100D}hp2100_fp.c ${HP2100D}hp2100_sys.c ${HP2100D}hp2100_lpt.c \
|
||||||
${HP2100D}hp2100_ipl.c ${HP2100D}hp2100_ds.c ${HP2100D}hp2100_cpu1.c
|
${HP2100D}hp2100_ipl.c ${HP2100D}hp2100_ds.c ${HP2100D}hp2100_cpu1.c \
|
||||||
HP2100_OPT = -I ${HP2100D}
|
${HP2100D}hp2100_fp1.c
|
||||||
|
HP2100_OPT = -DHAVE_INT64 -I ${HP2100D}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
152
scp.c
152
scp.c
|
@ -23,6 +23,10 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
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.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
01-May-05 RMS Revised syntax for SET DEBUG (from Dave Bryan)
|
||||||
|
22-Mar-05 JDB Modified DO command to allow ten-level nesting
|
||||||
|
18-Mar-05 RMS Moved DETACH tests into detach_unit (from Dave Bryan)
|
||||||
|
Revised interface to fprint_sym, fparse_sym
|
||||||
07-Feb-05 RMS Added ASSERT command (from Dave Bryan)
|
07-Feb-05 RMS Added ASSERT command (from Dave Bryan)
|
||||||
02-Feb-05 RMS Fixed bug in global register search
|
02-Feb-05 RMS Fixed bug in global register search
|
||||||
26-Dec-04 RMS Qualified SAVE examine, RESTORE deposit with SIM_SW_REST
|
26-Dec-04 RMS Qualified SAVE examine, RESTORE deposit with SIM_SW_REST
|
||||||
|
@ -45,16 +49,14 @@
|
||||||
RMS Split out libraries
|
RMS Split out libraries
|
||||||
RMS Moved logging function to SCP
|
RMS Moved logging function to SCP
|
||||||
RMS Exposed step counter interface(s)
|
RMS Exposed step counter interface(s)
|
||||||
RMS Fixed double logging of SHOW BREAK
|
RMS Fixed double logging of SHOW BREAK (found by Mark Pizzolato)
|
||||||
(found by Mark Pizzolato)
|
|
||||||
RMS Fixed implementation of REG_VMIO
|
RMS Fixed implementation of REG_VMIO
|
||||||
RMS Added SET/SHOW DEBUG, SET/SHOW <device> DEBUG,
|
RMS Added SET/SHOW DEBUG, SET/SHOW <device> DEBUG,
|
||||||
SHOW <device> MODIFIERS, SHOW <device> RADIX
|
SHOW <device> MODIFIERS, SHOW <device> RADIX
|
||||||
RMS Changed sim_fsize to take uptr argument
|
RMS Changed sim_fsize to take uptr argument
|
||||||
29-Dec-03 RMS Added Telnet console output stall support
|
29-Dec-03 RMS Added Telnet console output stall support
|
||||||
01-Nov-03 RMS Cleaned up implicit detach on attach/restore
|
01-Nov-03 RMS Cleaned up implicit detach on attach/restore
|
||||||
Fixed bug in command line read while logging
|
Fixed bug in command line read while logging (found by Mark Pizzolato)
|
||||||
(found by Mark Pizzolato)
|
|
||||||
01-Sep-03 RMS Fixed end-of-file problem in dep, idep
|
01-Sep-03 RMS Fixed end-of-file problem in dep, idep
|
||||||
Fixed error on trailing spaces in dep, idep
|
Fixed error on trailing spaces in dep, idep
|
||||||
15-Jul-03 RMS Removed unnecessary test in reset_all
|
15-Jul-03 RMS Removed unnecessary test in reset_all
|
||||||
|
@ -169,6 +171,7 @@
|
||||||
#define SSH_SH 1 /* show */
|
#define SSH_SH 1 /* show */
|
||||||
#define SSH_CL 2 /* clear */
|
#define SSH_CL 2 /* clear */
|
||||||
|
|
||||||
|
#define DO_NEST_LVL 10 /* DO cmd nesting level */
|
||||||
#define SRBSIZ 1024 /* save/restore buffer */
|
#define SRBSIZ 1024 /* save/restore buffer */
|
||||||
#define SIM_BRK_INILNT 4096 /* bpt tbl length */
|
#define SIM_BRK_INILNT 4096 /* bpt tbl length */
|
||||||
#define SIM_BRK_ALLTYP 0xFFFFFFFF
|
#define SIM_BRK_ALLTYP 0xFFFFFFFF
|
||||||
|
@ -388,7 +391,7 @@ const char *scp_error_messages[] = {
|
||||||
"Non-existent unit",
|
"Non-existent unit",
|
||||||
"Non-existent register",
|
"Non-existent register",
|
||||||
"Non-existent parameter",
|
"Non-existent parameter",
|
||||||
"Nested DO commands",
|
"Nested DO command limit exceeded",
|
||||||
"Internal error",
|
"Internal error",
|
||||||
"Invalid magtape record length",
|
"Invalid magtape record length",
|
||||||
"Console Telnet connection lost",
|
"Console Telnet connection lost",
|
||||||
|
@ -503,7 +506,7 @@ static CTAB cmd_table[] = {
|
||||||
"sh{ow} <dev} NAMES show device logical name\n"
|
"sh{ow} <dev} NAMES show device logical name\n"
|
||||||
"sh{ow} <dev> {arg,...} show device parameters\n"
|
"sh{ow} <dev> {arg,...} show device parameters\n"
|
||||||
"sh{ow} <unit> {arg,...} show unit parameters\n" },
|
"sh{ow} <unit> {arg,...} show unit parameters\n" },
|
||||||
{ "DO", &do_cmd, 0,
|
{ "DO", &do_cmd, 1,
|
||||||
"do <file> {arg,arg...} process command file\n" },
|
"do <file> {arg,arg...} process command file\n" },
|
||||||
{ "ECHO", &echo_cmd, 0,
|
{ "ECHO", &echo_cmd, 0,
|
||||||
"echo <string> display <string>\n" },
|
"echo <string> display <string>\n" },
|
||||||
|
@ -581,7 +584,7 @@ if (!sim_quiet) {
|
||||||
show_version (stdout, NULL, NULL, 0, NULL); }
|
show_version (stdout, NULL, NULL, 0, NULL); }
|
||||||
|
|
||||||
if (*cbuf) { /* cmd file arg? */
|
if (*cbuf) { /* cmd file arg? */
|
||||||
stat = do_cmd (1, cbuf); /* proc cmd file */
|
stat = do_cmd (0, cbuf); /* proc cmd file */
|
||||||
if (stat == SCPE_OPENERR) /* error? */
|
if (stat == SCPE_OPENERR) /* error? */
|
||||||
fprintf (stderr, "Can't open file %s\n", cbuf); }
|
fprintf (stderr, "Can't open file %s\n", cbuf); }
|
||||||
else if (*argv[0]) { /* sim name arg? */
|
else if (*argv[0]) { /* sim name arg? */
|
||||||
|
@ -590,7 +593,7 @@ else if (*argv[0]) { /* sim name arg? */
|
||||||
strncpy (nbuf + 1, argv[0], PATH_MAX + 1); /* copy sim name */
|
strncpy (nbuf + 1, argv[0], PATH_MAX + 1); /* copy sim name */
|
||||||
if (np = match_ext (nbuf, "EXE")) *np = 0; /* remove .exe */
|
if (np = match_ext (nbuf, "EXE")) *np = 0; /* remove .exe */
|
||||||
strcat (nbuf, ".ini\""); /* add .ini" */
|
strcat (nbuf, ".ini\""); /* add .ini" */
|
||||||
stat = do_cmd (1, nbuf); } /* proc cmd file */
|
stat = do_cmd (0, nbuf); } /* proc cmd file */
|
||||||
|
|
||||||
while (stat != SCPE_EXIT) { /* in case exit */
|
while (stat != SCPE_EXIT) { /* in case exit */
|
||||||
printf ("sim> "); /* prompt */
|
printf ("sim> "); /* prompt */
|
||||||
|
@ -710,7 +713,8 @@ CTAB *cmdp;
|
||||||
int32 echo, nargs;
|
int32 echo, nargs;
|
||||||
t_stat stat = SCPE_OK;
|
t_stat stat = SCPE_OK;
|
||||||
|
|
||||||
if (flag == 0) { GET_SWITCHES (fcptr); } /* get switches */
|
if (flag > 0) { GET_SWITCHES (fcptr); } /* get switches */
|
||||||
|
else flag = 1; /* start at level 1 */
|
||||||
echo = sim_switches & SWMASK ('V'); /* -v means echo */
|
echo = sim_switches & SWMASK ('V'); /* -v means echo */
|
||||||
|
|
||||||
c = fcptr;
|
c = fcptr;
|
||||||
|
@ -735,12 +739,13 @@ do { cptr = read_line (cbuf, CBUFSIZE, fpin); /* get cmd line */
|
||||||
if (echo && sim_log) fprintf (sim_log, "do> %s\n", cptr);
|
if (echo && sim_log) fprintf (sim_log, "do> %s\n", cptr);
|
||||||
cptr = get_glyph (cptr, gbuf, 0); /* get command glyph */
|
cptr = get_glyph (cptr, gbuf, 0); /* get command glyph */
|
||||||
sim_switches = 0; /* init switches */
|
sim_switches = 0; /* init switches */
|
||||||
if (strcmp (gbuf, "DO") == 0) { /* don't recurse */
|
if (cmdp = find_cmd (gbuf)) { /* lookup command */
|
||||||
fclose (fpin);
|
if (cmdp->action == &do_cmd) /* DO command? */
|
||||||
return SCPE_NEST; }
|
if (flag >= DO_NEST_LVL) /* nest too deep? */
|
||||||
if (cmdp = find_cmd (gbuf)) /* lookup command */
|
stat = SCPE_NEST;
|
||||||
stat = cmdp->action (cmdp->arg, cptr); /* if found, exec */
|
else stat = do_cmd (flag + 1, cptr); /* exec DO cmd */
|
||||||
else stat = SCPE_UNK;
|
else stat = cmdp->action (cmdp->arg, cptr); } /* exec other cmd */
|
||||||
|
else stat = SCPE_UNK; /* bad cmd given */
|
||||||
if (stat >= SCPE_BASE) { /* error? */
|
if (stat >= SCPE_BASE) { /* error? */
|
||||||
printf ("%s\n", scp_error_messages[stat - SCPE_BASE]);
|
printf ("%s\n", scp_error_messages[stat - SCPE_BASE]);
|
||||||
if (sim_log) fprintf (sim_log, "%s\n",
|
if (sim_log) fprintf (sim_log, "%s\n",
|
||||||
|
@ -791,7 +796,7 @@ return;
|
||||||
|
|
||||||
t_stat assert_cmd (int32 flag, char *cptr)
|
t_stat assert_cmd (int32 flag, char *cptr)
|
||||||
{
|
{
|
||||||
char gbuf[CBUFSIZE], *gptr, *aptr;
|
char gbuf[CBUFSIZE], *gptr, *aptr, *tptr;
|
||||||
REG *rptr;
|
REG *rptr;
|
||||||
uint32 idx;
|
uint32 idx;
|
||||||
t_value val;
|
t_value val;
|
||||||
|
@ -805,13 +810,16 @@ rptr = find_reg (gbuf, &gptr, sim_dfdev); /* parse register */
|
||||||
if (!rptr) return SCPE_NXREG; /* not there */
|
if (!rptr) return SCPE_NXREG; /* not there */
|
||||||
if (*gptr == '[') { /* subscript? */
|
if (*gptr == '[') { /* subscript? */
|
||||||
if (rptr->depth <= 1) return SCPE_ARG; /* array register? */
|
if (rptr->depth <= 1) return SCPE_ARG; /* array register? */
|
||||||
idx = (uint32) strtotv (++gptr, &cptr, 10); /* convert index */
|
idx = (uint32) strtotv (++gptr, &tptr, 10); /* convert index */
|
||||||
if ((gptr == cptr) || (*cptr++ != ']')) return SCPE_ARG;
|
if ((gptr == tptr) || (*tptr++ != ']')) return SCPE_ARG;
|
||||||
|
gptr = tptr; /* update */
|
||||||
}
|
}
|
||||||
else idx = 0; /* not array */
|
else idx = 0; /* not array */
|
||||||
if (idx >= rptr->depth) return SCPE_SUB; /* validate subscript */
|
if (idx >= rptr->depth) return SCPE_SUB; /* validate subscript */
|
||||||
if (*cptr == 0) return SCPE_2FARG; /* must be more */
|
if (*gptr != 0) get_glyph (gptr, gbuf, 0); /* more? must be search */
|
||||||
cptr = get_glyph (cptr, gbuf, 0); /* get search cond */
|
else { if (*cptr == 0) return SCPE_2FARG; /* must be more */
|
||||||
|
cptr = get_glyph (cptr, gbuf, 0); /* get search cond */
|
||||||
|
}
|
||||||
if (*cptr != 0) return SCPE_2MARG; /* must be done */
|
if (*cptr != 0) return SCPE_2MARG; /* must be done */
|
||||||
if (!get_search (gbuf, rptr->radix, &sim_stab)) /* parse condition */
|
if (!get_search (gbuf, rptr->radix, &sim_stab)) /* parse condition */
|
||||||
return SCPE_MISVAL;
|
return SCPE_MISVAL;
|
||||||
|
@ -994,12 +1002,14 @@ DEBTAB *dep;
|
||||||
|
|
||||||
if ((dptr->flags & DEV_DEBUG) == 0) return SCPE_NOFNC;
|
if ((dptr->flags & DEV_DEBUG) == 0) return SCPE_NOFNC;
|
||||||
if (cptr == NULL) { /* no arguments? */
|
if (cptr == NULL) { /* no arguments? */
|
||||||
if (dptr->debflags && flag) return SCPE_ARG; /* table or enable? */
|
dptr->dctrl = flag; /* disable/enable w/o table */
|
||||||
dptr->dctrl = flag; /* no table or disable */
|
if (flag && dptr->debflags) { /* enable with table? */
|
||||||
|
for (dep = dptr->debflags; dep->name != NULL; dep++)
|
||||||
|
dptr->dctrl = dptr->dctrl | dep->mask; } /* set all */
|
||||||
return SCPE_OK; }
|
return SCPE_OK; }
|
||||||
if (dptr->debflags == NULL) return SCPE_ARG; /* must have table */
|
if (dptr->debflags == NULL) return SCPE_ARG; /* must have table */
|
||||||
while (*cptr) {
|
while (*cptr) {
|
||||||
cptr = get_glyph (cptr, gbuf, ','); /* get debug flag */
|
cptr = get_glyph (cptr, gbuf, ';'); /* get debug flag */
|
||||||
for (dep = dptr->debflags; dep->name != NULL; dep++) {
|
for (dep = dptr->debflags; dep->name != NULL; dep++) {
|
||||||
if (strcmp (dep->name, gbuf) == 0) { /* match? */
|
if (strcmp (dep->name, gbuf) == 0) { /* match? */
|
||||||
if (flag) dptr->dctrl = dptr->dctrl | dep->mask;
|
if (flag) dptr->dctrl = dptr->dctrl | dep->mask;
|
||||||
|
@ -1302,7 +1312,7 @@ if (dptr->flags & DEV_DEBUG) {
|
||||||
fputs ("Debug=", st);
|
fputs ("Debug=", st);
|
||||||
for (dep = dptr->debflags; dep->name != NULL; dep++) {
|
for (dep = dptr->debflags; dep->name != NULL; dep++) {
|
||||||
if (dptr->dctrl & dep->mask) {
|
if (dptr->dctrl & dep->mask) {
|
||||||
if (any) fputc (',', st);
|
if (any) fputc (';', st);
|
||||||
fputs (dep->name, st);
|
fputs (dep->name, st);
|
||||||
any = 1; }
|
any = 1; }
|
||||||
}
|
}
|
||||||
|
@ -1400,7 +1410,7 @@ char gbuf[CBUFSIZE], *tptr, *t1ptr, *aptr;
|
||||||
DEVICE *dptr = sim_devices[0];
|
DEVICE *dptr = sim_devices[0];
|
||||||
UNIT *uptr = dptr->units;
|
UNIT *uptr = dptr->units;
|
||||||
t_stat r;
|
t_stat r;
|
||||||
t_addr lo, hi, max = uptr->capac - dptr->aincr;
|
t_addr lo, hi, max = uptr->capac - 1;
|
||||||
int32 cnt;
|
int32 cnt;
|
||||||
|
|
||||||
if (*cptr == 0) return SCPE_2FARG;
|
if (*cptr == 0) return SCPE_2FARG;
|
||||||
|
@ -1425,11 +1435,20 @@ while (*cptr) {
|
||||||
else if (flg == SSH_SH) sim_brk_showall (st, sim_switches);
|
else if (flg == SSH_SH) sim_brk_showall (st, sim_switches);
|
||||||
else return SCPE_ARG; }
|
else return SCPE_ARG; }
|
||||||
else {
|
else {
|
||||||
for ( ; lo <= hi; lo = lo + dptr->aincr) {
|
for ( ; lo <= hi; lo = lo + 1) {
|
||||||
if (flg == SSH_ST) r = sim_brk_set (lo, sim_switches, cnt, aptr);
|
switch (flg) {
|
||||||
else if (flg == SSH_CL) r = sim_brk_clr (lo, sim_switches);
|
case SSH_ST:
|
||||||
else if (flg == SSH_SH) r = sim_brk_show (st, lo, sim_switches);
|
r = sim_brk_set (lo, sim_switches, cnt, aptr);
|
||||||
else return SCPE_ARG;
|
break;
|
||||||
|
case SSH_CL:
|
||||||
|
r = sim_brk_clr (lo, sim_switches);
|
||||||
|
break;
|
||||||
|
case SSH_SH:
|
||||||
|
r = sim_brk_show (st, lo, sim_switches);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return SCPE_ARG;
|
||||||
|
}
|
||||||
if (r != SCPE_OK) return r;
|
if (r != SCPE_OK) return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1643,8 +1662,6 @@ if (strcmp (gbuf, "ALL") == 0) return (detach_all (0, FALSE));
|
||||||
dptr = find_unit (gbuf, &uptr); /* locate unit */
|
dptr = find_unit (gbuf, &uptr); /* locate unit */
|
||||||
if (dptr == NULL) return SCPE_NXDEV; /* found dev? */
|
if (dptr == NULL) return SCPE_NXDEV; /* found dev? */
|
||||||
if (uptr == NULL) return SCPE_NXUN; /* valid unit? */
|
if (uptr == NULL) return SCPE_NXUN; /* valid unit? */
|
||||||
if (!(uptr->flags & UNIT_ATTABLE)) return SCPE_NOATT; /* attachable? */
|
|
||||||
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; /* attached? */
|
|
||||||
return scp_detach_unit (dptr, uptr); /* detach */
|
return scp_detach_unit (dptr, uptr); /* detach */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1694,7 +1711,8 @@ t_stat detach_unit (UNIT *uptr)
|
||||||
DEVICE *dptr;
|
DEVICE *dptr;
|
||||||
|
|
||||||
if (uptr == NULL) return SCPE_IERR;
|
if (uptr == NULL) return SCPE_IERR;
|
||||||
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK;
|
if (!(uptr->flags & UNIT_ATTABLE)) return SCPE_NOATT; /* attachable? */
|
||||||
|
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; /* attached? */
|
||||||
if ((dptr = find_dev_from_unit (uptr)) == NULL) return SCPE_OK;
|
if ((dptr = find_dev_from_unit (uptr)) == NULL) return SCPE_OK;
|
||||||
if (uptr->flags & UNIT_BUF) {
|
if (uptr->flags & UNIT_BUF) {
|
||||||
uint32 cap = (uptr->hwmark + dptr->aincr - 1) / dptr->aincr;
|
uint32 cap = (uptr->hwmark + dptr->aincr - 1) / dptr->aincr;
|
||||||
|
@ -1710,7 +1728,8 @@ if (uptr->flags & UNIT_BUF) {
|
||||||
uptr->flags = uptr->flags & ~(UNIT_ATT | UNIT_RO);
|
uptr->flags = uptr->flags & ~(UNIT_ATT | UNIT_RO);
|
||||||
free (uptr->filename);
|
free (uptr->filename);
|
||||||
uptr->filename = NULL;
|
uptr->filename = NULL;
|
||||||
return (fclose (uptr->fileref) == EOF)? SCPE_IOERR: SCPE_OK;
|
if (fclose (uptr->fileref) == EOF) return SCPE_IOERR;
|
||||||
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assign command
|
/* Assign command
|
||||||
|
@ -1973,9 +1992,10 @@ for ( ;; ) { /* device loop */
|
||||||
uptr->flags = (uptr->flags & ~UNIT_RFLAGS) |
|
uptr->flags = (uptr->flags & ~UNIT_RFLAGS) |
|
||||||
(flg & UNIT_RFLAGS); /* restore */
|
(flg & UNIT_RFLAGS); /* restore */
|
||||||
READ_S (buf); /* attached file */
|
READ_S (buf); /* attached file */
|
||||||
if (!(dptr->flags & DEV_NET) || /* if not net dev or */
|
if ((uptr->flags & UNIT_ATTABLE) && /* if attachable and */
|
||||||
|
(!(dptr->flags & DEV_NET) || /* not net dev or */
|
||||||
!(uptr->flags & UNIT_ATT) || /* not currently att */
|
!(uptr->flags & UNIT_ATT) || /* not currently att */
|
||||||
(buf[0] == 0)) { /* or will not be att */
|
(buf[0] == 0))) { /* or will not be att */
|
||||||
sim_switches = SIM_SW_REST; /* att-det/rest */
|
sim_switches = SIM_SW_REST; /* att-det/rest */
|
||||||
r = scp_detach_unit (dptr, uptr); /* detach old */
|
r = scp_detach_unit (dptr, uptr); /* detach old */
|
||||||
if (r != SCPE_OK) return r;
|
if (r != SCPE_OK) return r;
|
||||||
|
@ -2328,20 +2348,26 @@ t_stat reason;
|
||||||
if (uptr->flags & UNIT_DIS) return SCPE_UDIS; /* disabled? */
|
if (uptr->flags & UNIT_DIS) return SCPE_UDIS; /* disabled? */
|
||||||
mask = (t_addr) width_mask[dptr->awidth];
|
mask = (t_addr) width_mask[dptr->awidth];
|
||||||
if ((low > mask) || (high > mask) || (low > high)) return SCPE_ARG;
|
if ((low > mask) || (high > mask) || (low > high)) return SCPE_ARG;
|
||||||
for (i = low; i <= high; i = i + (dptr->aincr)) {
|
for (i = low; i <= high; ) { /* all paths must incr!! */
|
||||||
if ((flag & EX_E) || schptr) { /* examine or search? */
|
|
||||||
reason = get_aval (i, dptr, uptr); /* get data */
|
reason = get_aval (i, dptr, uptr); /* get data */
|
||||||
if (reason != SCPE_OK) return reason; /* return if error */
|
if (reason != SCPE_OK) return reason; /* return if error */
|
||||||
if (schptr && !test_search (sim_eval[0], schptr)) continue; }
|
if (schptr && !test_search (sim_eval[0], schptr))
|
||||||
if (flag != EX_D) {
|
i = i + dptr->aincr; /* sch fails, incr */
|
||||||
|
else { /* no sch or success */
|
||||||
|
if (flag != EX_D) { /* ex, ie, or id? */
|
||||||
reason = ex_addr (ofile, flag, i, dptr, uptr);
|
reason = ex_addr (ofile, flag, i, dptr, uptr);
|
||||||
if (reason > SCPE_OK) return reason;
|
if (reason > SCPE_OK) return reason;
|
||||||
if (sim_log && (ofile == stdout))
|
if (sim_log && (ofile == stdout))
|
||||||
ex_addr (sim_log, flag, i, dptr, uptr); }
|
ex_addr (sim_log, flag, i, dptr, uptr);
|
||||||
if (flag != EX_E) {
|
}
|
||||||
|
else reason = 1 - dptr->aincr; /* no, dflt incr */
|
||||||
|
if (flag != EX_E) { /* ie, id, or d? */
|
||||||
reason = dep_addr (flag, cptr, i, dptr, uptr, reason);
|
reason = dep_addr (flag, cptr, i, dptr, uptr, reason);
|
||||||
if (reason > SCPE_OK) return reason; }
|
if (reason > SCPE_OK) return reason;
|
||||||
if (reason < SCPE_OK) i = i + ((-reason) * dptr->aincr); }
|
}
|
||||||
|
i = i + (1 - reason); /* incr */
|
||||||
|
}
|
||||||
|
}
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2523,8 +2549,8 @@ return;
|
||||||
dptr = pointer to device
|
dptr = pointer to device
|
||||||
uptr = pointer to unit
|
uptr = pointer to unit
|
||||||
Outputs:
|
Outputs:
|
||||||
return = if >= 0, error status
|
return = if > 0, error status
|
||||||
if < 0, number of extra words retired
|
if <= 0,-number of extra addr units retired
|
||||||
*/
|
*/
|
||||||
|
|
||||||
t_stat ex_addr (FILE *ofile, int32 flag, t_addr addr, DEVICE *dptr, UNIT *uptr)
|
t_stat ex_addr (FILE *ofile, int32 flag, t_addr addr, DEVICE *dptr, UNIT *uptr)
|
||||||
|
@ -2535,11 +2561,13 @@ int32 rdx;
|
||||||
if (sim_vm_fprint_addr) sim_vm_fprint_addr (ofile, dptr, addr);
|
if (sim_vm_fprint_addr) sim_vm_fprint_addr (ofile, dptr, addr);
|
||||||
else fprint_val (ofile, addr, dptr->aradix, dptr->awidth, PV_LEFT);
|
else fprint_val (ofile, addr, dptr->aradix, dptr->awidth, PV_LEFT);
|
||||||
fprintf (ofile, ": ");
|
fprintf (ofile, ": ");
|
||||||
if (!(flag & EX_E)) return SCPE_OK;
|
if (!(flag & EX_E)) return (1 - dptr->aincr);
|
||||||
|
|
||||||
GET_RADIX (rdx, dptr->dradix);
|
GET_RADIX (rdx, dptr->dradix);
|
||||||
if ((reason = fprint_sym (ofile, addr, sim_eval, uptr, sim_switches)) > 0)
|
if ((reason = fprint_sym (ofile, addr, sim_eval, uptr, sim_switches)) > 0) {
|
||||||
reason = fprint_val (ofile, sim_eval[0], rdx, dptr->dwidth, PV_RZRO);
|
fprint_val (ofile, sim_eval[0], rdx, dptr->dwidth, PV_RZRO);
|
||||||
|
reason = 1 - dptr->aincr;
|
||||||
|
}
|
||||||
if (flag & EX_I) fprintf (ofile, " ");
|
if (flag & EX_I) fprintf (ofile, " ");
|
||||||
else fprintf (ofile, "\n");
|
else fprintf (ofile, "\n");
|
||||||
return reason;
|
return reason;
|
||||||
|
@ -2607,8 +2635,8 @@ return SCPE_OK;
|
||||||
uptr = pointer to unit
|
uptr = pointer to unit
|
||||||
dfltinc = value to return on cr input
|
dfltinc = value to return on cr input
|
||||||
Outputs:
|
Outputs:
|
||||||
return = if >= 0, error status
|
return = if > 0, error status
|
||||||
if < 0, number of extra words retired
|
if <= 0, -number of extra address units retired
|
||||||
*/
|
*/
|
||||||
|
|
||||||
t_stat dep_addr (int32 flag, char *cptr, t_addr addr, DEVICE *dptr,
|
t_stat dep_addr (int32 flag, char *cptr, t_addr addr, DEVICE *dptr,
|
||||||
|
@ -2624,8 +2652,8 @@ char gbuf[CBUFSIZE];
|
||||||
if (dptr == NULL) return SCPE_IERR;
|
if (dptr == NULL) return SCPE_IERR;
|
||||||
if (flag & EX_I) {
|
if (flag & EX_I) {
|
||||||
cptr = read_line (gbuf, CBUFSIZE, stdin);
|
cptr = read_line (gbuf, CBUFSIZE, stdin);
|
||||||
if (cptr == NULL) return 1; /* force exit */
|
|
||||||
if (sim_log) fprintf (sim_log, (cptr? "%s\n": "\n"), cptr);
|
if (sim_log) fprintf (sim_log, (cptr? "%s\n": "\n"), cptr);
|
||||||
|
if (cptr == NULL) return 1; /* force exit */
|
||||||
if (*cptr == 0) return dfltinc; } /* success */
|
if (*cptr == 0) return dfltinc; } /* success */
|
||||||
if (uptr->flags & UNIT_RO) return SCPE_RO; /* read only? */
|
if (uptr->flags & UNIT_RO) return SCPE_RO; /* read only? */
|
||||||
mask = width_mask[dptr->dwidth];
|
mask = width_mask[dptr->dwidth];
|
||||||
|
@ -2634,7 +2662,7 @@ GET_RADIX (rdx, dptr->dradix);
|
||||||
if ((reason = parse_sym (cptr, addr, uptr, sim_eval, sim_switches)) > 0) {
|
if ((reason = parse_sym (cptr, addr, uptr, sim_eval, sim_switches)) > 0) {
|
||||||
sim_eval[0] = get_uint (cptr, rdx, mask, &reason);
|
sim_eval[0] = get_uint (cptr, rdx, mask, &reason);
|
||||||
if (reason != SCPE_OK) return reason; }
|
if (reason != SCPE_OK) return reason; }
|
||||||
count = 1 - reason;
|
count = (1 - reason + (dptr->aincr - 1)) / dptr->aincr;
|
||||||
|
|
||||||
for (i = 0, j = addr; i < count; i++, j = j + dptr->aincr) {
|
for (i = 0, j = addr; i < count; i++, j = j + dptr->aincr) {
|
||||||
sim_eval[i] = sim_eval[i] & mask;
|
sim_eval[i] = sim_eval[i] & mask;
|
||||||
|
@ -2665,7 +2693,7 @@ return reason;
|
||||||
t_stat eval_cmd (int32 flg, char *cptr)
|
t_stat eval_cmd (int32 flg, char *cptr)
|
||||||
{
|
{
|
||||||
DEVICE *dptr = sim_devices[0];
|
DEVICE *dptr = sim_devices[0];
|
||||||
int32 i, count, rdx;
|
int32 i, rdx, a, lim;
|
||||||
t_stat r;
|
t_stat r;
|
||||||
|
|
||||||
GET_SWITCHES (cptr);
|
GET_SWITCHES (cptr);
|
||||||
|
@ -2675,20 +2703,20 @@ if (*cptr == 0) return SCPE_2FARG;
|
||||||
if ((r = parse_sym (cptr, 0, dptr->units, sim_eval, sim_switches)) > 0) {
|
if ((r = parse_sym (cptr, 0, dptr->units, sim_eval, sim_switches)) > 0) {
|
||||||
sim_eval[0] = get_uint (cptr, rdx, width_mask[dptr->dwidth], &r);
|
sim_eval[0] = get_uint (cptr, rdx, width_mask[dptr->dwidth], &r);
|
||||||
if (r != SCPE_OK) return r; }
|
if (r != SCPE_OK) return r; }
|
||||||
count = 1 - r;
|
lim = 1 - r;
|
||||||
for (i = 0; count > 0; i++, count = count - dptr->aincr) {
|
for (i = a = 0; a < lim; ) {
|
||||||
printf ("%d:\t", i);
|
printf ("%d:\t", a);
|
||||||
if ((r = fprint_sym (stdout, 0, &sim_eval[i], dptr->units, sim_switches)) > 0)
|
if ((r = fprint_sym (stdout, a, &sim_eval[i], dptr->units, sim_switches)) > 0)
|
||||||
r = fprint_val (stdout, sim_eval[i], rdx, dptr->dwidth, PV_RZRO);
|
r = fprint_val (stdout, sim_eval[i], rdx, dptr->dwidth, PV_RZRO);
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
if (sim_log) {
|
if (sim_log) {
|
||||||
fprintf (sim_log, "%d\t", i);
|
fprintf (sim_log, "%d\t", i);
|
||||||
if ((r = fprint_sym (sim_log, 0, &sim_eval[i], dptr->units, sim_switches)) > 0)
|
if ((r = fprint_sym (sim_log, a, &sim_eval[i], dptr->units, sim_switches)) > 0)
|
||||||
r = fprint_val (sim_log, sim_eval[i], rdx, dptr->dwidth, PV_RZRO);
|
r = fprint_val (sim_log, sim_eval[i], rdx, dptr->dwidth, PV_RZRO);
|
||||||
fprintf (sim_log, "\n"); }
|
fprintf (sim_log, "\n"); }
|
||||||
if (r < 0) {
|
if (r < 0) a = a + 1 - r;
|
||||||
i = i - r;
|
else a = a + dptr->aincr;
|
||||||
count = count + (r * dptr->aincr); }
|
i = a / dptr->aincr;
|
||||||
}
|
}
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
19
sim_defs.h
19
sim_defs.h
|
@ -23,6 +23,7 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
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.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
11-Mar-05 RMS Moved 64b data type definitions outside USE_INT64
|
||||||
07-Feb-05 RMS Added assertion fail stop
|
07-Feb-05 RMS Added assertion fail stop
|
||||||
05-Nov-04 RMS Added support for SHOW opt=val
|
05-Nov-04 RMS Added support for SHOW opt=val
|
||||||
20-Oct-04 RMS Converted all base types to typedefs
|
20-Oct-04 RMS Converted all base types to typedefs
|
||||||
|
@ -115,8 +116,12 @@ typedef unsigned int uint32;
|
||||||
typedef int t_stat; /* status */
|
typedef int t_stat; /* status */
|
||||||
typedef int t_bool; /* boolean */
|
typedef int t_bool; /* boolean */
|
||||||
|
|
||||||
#if defined (USE_INT64) /* 64b data */
|
/* 64b integers */
|
||||||
#if defined (_WIN32) /* Windows */
|
|
||||||
|
#if defined (__GNUC__) /* GCC */
|
||||||
|
typedef signed long long t_int64;
|
||||||
|
typedef unsigned long long t_uint64;
|
||||||
|
#elif defined (_WIN32) /* Windows */
|
||||||
typedef signed __int64 t_int64;
|
typedef signed __int64 t_int64;
|
||||||
typedef unsigned __int64 t_uint64;
|
typedef unsigned __int64 t_uint64;
|
||||||
#elif defined (__ALPHA) && defined (VMS) /* Alpha VMS */
|
#elif defined (__ALPHA) && defined (VMS) /* Alpha VMS */
|
||||||
|
@ -125,10 +130,12 @@ typedef unsigned __int64 t_uint64;
|
||||||
#elif defined (__ALPHA) && defined (__unix__) /* Alpha UNIX */
|
#elif defined (__ALPHA) && defined (__unix__) /* Alpha UNIX */
|
||||||
typedef signed long t_int64;
|
typedef signed long t_int64;
|
||||||
typedef unsigned long t_uint64;
|
typedef unsigned long t_uint64;
|
||||||
#else /* default GCC */
|
#else /* default */
|
||||||
typedef signed long long t_int64;
|
#define t_int64 signed long long
|
||||||
typedef unsigned long long t_uint64;
|
#define t_uint64 unsigned long long
|
||||||
#endif /* end OS's */
|
#endif /* end 64b */
|
||||||
|
|
||||||
|
#if defined (USE_INT64) /* 64b data */
|
||||||
typedef t_int64 t_svalue; /* signed value */
|
typedef t_int64 t_svalue; /* signed value */
|
||||||
typedef t_uint64 t_value; /* value */
|
typedef t_uint64 t_value; /* value */
|
||||||
#else /* 32b data */
|
#else /* 32b data */
|
||||||
|
|
44
sim_rev.h
44
sim_rev.h
|
@ -28,13 +28,51 @@
|
||||||
#define _SIM_REV_H_ 0
|
#define _SIM_REV_H_ 0
|
||||||
|
|
||||||
#define SIM_MAJOR 3
|
#define SIM_MAJOR 3
|
||||||
#define SIM_MINOR 3
|
#define SIM_MINOR 4
|
||||||
#define SIM_PATCH 2
|
#define SIM_PATCH 0
|
||||||
|
|
||||||
/* V3.3 revision history
|
/* V3.4 revision history
|
||||||
|
|
||||||
patch date module(s) and fix(es)
|
patch date module(s) and fix(es)
|
||||||
|
|
||||||
|
0 01-May-04 scp.c:
|
||||||
|
- fixed ASSERT code
|
||||||
|
- revised syntax for SET DEBUG (from Dave Bryan)
|
||||||
|
- revised interpretation of fprint_sym, fparse_sym returns
|
||||||
|
- moved DETACH sanity tests into detach_unit
|
||||||
|
|
||||||
|
sim_sock.h and sim_sock.c:
|
||||||
|
- added test for WSAEINPROGRESS (from Tim Riker)
|
||||||
|
|
||||||
|
many: revised detach routines to test for attached state
|
||||||
|
|
||||||
|
hp2100_cpu.c: reorganized CPU options (from Dave Bryan)
|
||||||
|
|
||||||
|
hp2100_cpu1.c: reorganized EIG routines (from Dave Bryan)
|
||||||
|
|
||||||
|
hp2100_fp1.c: added FFP support (from Dave Bryan)
|
||||||
|
|
||||||
|
id16_cpu.c:
|
||||||
|
- fixed bug in show history routine (from Mark Hittinger)
|
||||||
|
- revised examine/deposit to do words rather than bytes
|
||||||
|
|
||||||
|
id32_cpu.c:
|
||||||
|
- fixed bug in initial memory allocation
|
||||||
|
- fixed bug in show history routine (from Mark Hittinger)
|
||||||
|
- revised examine/deposit to do words rather than bytes
|
||||||
|
|
||||||
|
id16_sys.c, id32_sys:
|
||||||
|
- revised examine/deposit to do words rather than bytes
|
||||||
|
|
||||||
|
pdp10_tu.c:
|
||||||
|
- fixed bug, ERASE and WREOF should not clear done (reported
|
||||||
|
by Rich Alderson)
|
||||||
|
- fixed error reporting
|
||||||
|
|
||||||
|
pdp11_tu.c: fixed error reporting
|
||||||
|
|
||||||
|
/* V3.3 revision history
|
||||||
|
|
||||||
2 08-Mar-05 scp.c: added ASSERT command (from Dave Bryan)
|
2 08-Mar-05 scp.c: added ASSERT command (from Dave Bryan)
|
||||||
|
|
||||||
h316_defs.h: fixed IORETURN macro
|
h316_defs.h: fixed IORETURN macro
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* sim_sock.c: OS-dependent socket routines
|
/* sim_sock.c: OS-dependent socket routines
|
||||||
|
|
||||||
Copyright (c) 2001-2004, Robert M Supnik
|
Copyright (c) 2001-2005, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -23,6 +23,7 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
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.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
14-Apr-05 RMS Added WSAEINPROGRESS test (from Tim Riker)
|
||||||
09-Jan-04 RMS Fixed typing problem in Alpha Unix (found by Tim Chapman)
|
09-Jan-04 RMS Fixed typing problem in Alpha Unix (found by Tim Chapman)
|
||||||
17-Apr-03 RMS Fixed non-implemented version of sim_close_sock
|
17-Apr-03 RMS Fixed non-implemented version of sim_close_sock
|
||||||
(found by Mark Pizzolato)
|
(found by Mark Pizzolato)
|
||||||
|
@ -172,7 +173,9 @@ sta = sim_setnonblock (newsock); /* set nonblocking */
|
||||||
if (sta == SOCKET_ERROR) /* fcntl error? */
|
if (sta == SOCKET_ERROR) /* fcntl error? */
|
||||||
return sim_err_sock (newsock, "fcntl", 1);
|
return sim_err_sock (newsock, "fcntl", 1);
|
||||||
sta = connect (newsock, (struct sockaddr *) &name, sizeof (name));
|
sta = connect (newsock, (struct sockaddr *) &name, sizeof (name));
|
||||||
if ((sta == SOCKET_ERROR) && (WSAGetLastError () != WSAEWOULDBLOCK))
|
if ((sta == SOCKET_ERROR) &&
|
||||||
|
(WSAGetLastError () != WSAEWOULDBLOCK) &&
|
||||||
|
(WSAGetLastError () != WSAEINPROGRESS))
|
||||||
return sim_err_sock (newsock, "connect", 1);
|
return sim_err_sock (newsock, "connect", 1);
|
||||||
|
|
||||||
return newsock; /* got it! */
|
return newsock; /* got it! */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* sim_sock.h: OS-dependent socket routines header file
|
/* sim_sock.h: OS-dependent socket routines header file
|
||||||
|
|
||||||
Copyright (c) 2001-2004, Robert M Supnik
|
Copyright (c) 2001-2005, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -23,6 +23,7 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
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.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
14-Apr-05 RMS Added WSAEINPROGRESS (from Tim Riker)
|
||||||
20-Aug-04 HV Added missing definition for OS/2 (from Holger Veit)
|
20-Aug-04 HV Added missing definition for OS/2 (from Holger Veit)
|
||||||
22-Oct-03 MP Changed WIN32 winsock include to use winsock2.h to
|
22-Oct-03 MP Changed WIN32 winsock include to use winsock2.h to
|
||||||
avoid a conflict if sim_sock.h and sim_ether.h get
|
avoid a conflict if sim_sock.h and sim_ether.h get
|
||||||
|
@ -49,6 +50,7 @@
|
||||||
#define WSAGetLastError() errno /* Windows macros */
|
#define WSAGetLastError() errno /* Windows macros */
|
||||||
#define SOCKET int32
|
#define SOCKET int32
|
||||||
#define WSAEWOULDBLOCK EWOULDBLOCK
|
#define WSAEWOULDBLOCK EWOULDBLOCK
|
||||||
|
#define WSAEINPROGRESS EINPROGRESS
|
||||||
#define INVALID_SOCKET -1
|
#define INVALID_SOCKET -1
|
||||||
#define SOCKET_ERROR -1
|
#define SOCKET_ERROR -1
|
||||||
#include <sys/types.h> /* for fcntl, getpid */
|
#include <sys/types.h> /* for fcntl, getpid */
|
||||||
|
|
70
simh_doc.txt
70
simh_doc.txt
|
@ -1,7 +1,7 @@
|
||||||
To: Users
|
To: Users
|
||||||
From: Bob Supnik
|
From: Bob Supnik
|
||||||
Subj: Simulator Usage, V3.3
|
Subj: Simulator Usage, V3.4
|
||||||
Date: 25-Jan-2005
|
Date: 01-May-2005
|
||||||
|
|
||||||
COPYRIGHT NOTICE
|
COPYRIGHT NOTICE
|
||||||
|
|
||||||
|
@ -89,6 +89,13 @@ The simulators recognize or require a few compile-time #defines:
|
||||||
both USE_INT64 and USE_ADDR64 must be defined as part of the
|
both USE_INT64 and USE_ADDR64 must be defined as part of the
|
||||||
compilation command line.
|
compilation command line.
|
||||||
|
|
||||||
|
- The HP2100 Fast FORTRAN Processor (FFP) option requires 64b integer
|
||||||
|
support. Define HAVE_INT64 (not USE_INT64) as part of the compilation
|
||||||
|
command line if your host compiler supports 64b integers. On systems
|
||||||
|
without 64b support, the extended-precision instructions (e.g., XADD)
|
||||||
|
will be disabled; the remainder of the FFP instructions will work
|
||||||
|
normally. There may be some compilation warnings.
|
||||||
|
|
||||||
To start the simulator, simply type its name. (On version of VMS
|
To start the simulator, simply type its name. (On version of VMS
|
||||||
prior to 6.2, the simulators must then be defined as foreign commands
|
prior to 6.2, the simulators must then be defined as foreign commands
|
||||||
in order to be be started by name.) The simulator recognizes one
|
in order to be be started by name.) The simulator recognizes one
|
||||||
|
@ -725,15 +732,60 @@ the next character is interpreted literally, even if it is % or \.
|
||||||
Arguments with spaces can be enclosed in matching single or double
|
Arguments with spaces can be enclosed in matching single or double
|
||||||
quotation marks.
|
quotation marks.
|
||||||
|
|
||||||
If the switch -V is specified, the commands in the file are echoed
|
If the switch -V is specified, the commands in the file are echoed before
|
||||||
before they are executed.
|
they are executed. DO commands may be nested up to ten invocations deep.
|
||||||
|
|
||||||
|
Several commands are particularly useful within command files. While they
|
||||||
|
may be executed interactively, they have only limited functionality when so
|
||||||
|
used.
|
||||||
|
|
||||||
|
3.13.1 Displaying Arbitrary Text
|
||||||
|
|
||||||
The ECHO command is a useful way of annotating command files. ECHO
|
The ECHO command is a useful way of annotating command files. ECHO
|
||||||
prints out its argument on the console:
|
prints out its argument on the console:
|
||||||
|
|
||||||
sim> ECHO <string> -- output string to console
|
sim> ECHO <string> -- output string to console
|
||||||
|
|
||||||
If there is no argument, ECHO prints a blank line on the console.
|
If there is no argument, ECHO prints a blank line on the console. This may
|
||||||
|
be used to provide spacing in the console display or log.
|
||||||
|
|
||||||
|
3.13.2 Testing Simulator State
|
||||||
|
|
||||||
|
The ASSERT command tests a simulator state condition and halts command file
|
||||||
|
execution if the condition is false:
|
||||||
|
|
||||||
|
sim> ASSERT {<dev>} <reg>{<logical-op><value>}<conditional-op><value>
|
||||||
|
|
||||||
|
If <dev> is not specified, CPU is assumed. <reg> is a register (scalar or
|
||||||
|
subscripted) belonging to the indicated device. The <conditional-op> and
|
||||||
|
optional <logical-op> are the same as those used for "search specifiers" by
|
||||||
|
the EXAMINE and DEPOSIT commands (see above). The <value>s are expressed in
|
||||||
|
the radix specified for <reg>, not in the radix for the device.
|
||||||
|
|
||||||
|
If the <logical-op> and <value> are specified, the target register value is
|
||||||
|
first altered as indicated. The result is then compared to the <value> via
|
||||||
|
the <conditional-op>. If the result is false, an "Assertion failed" message
|
||||||
|
is printed, and any running command file is aborted. Otherwise, the command
|
||||||
|
has no effect.
|
||||||
|
|
||||||
|
For example, a command file might be used to bootstrap an operating system
|
||||||
|
that halts after the initial load from disk. The ASSERT command is then
|
||||||
|
used to confirm that the load completed successfully by examining the CPU's
|
||||||
|
"A" register for the expected value:
|
||||||
|
|
||||||
|
; OS bootstrap command file
|
||||||
|
;
|
||||||
|
ATTACH DS0 os.disk
|
||||||
|
BOOT DS
|
||||||
|
; A register contains error code; 0 = good boot
|
||||||
|
ASSERT A=0
|
||||||
|
ATTACH MT0 sys.tape
|
||||||
|
ATTACH MT1 user.tape
|
||||||
|
RUN
|
||||||
|
|
||||||
|
In the example, if the A register is not 0, the command file will be aborted
|
||||||
|
with an "Assertion failed (A=0)" message. Otherwise, the command file will
|
||||||
|
continue to bring up the operating system.
|
||||||
|
|
||||||
3.14 Executing System Commands
|
3.14 Executing System Commands
|
||||||
|
|
||||||
|
@ -773,8 +825,9 @@ SET command. If a device has only a single debug flag:
|
||||||
|
|
||||||
If the device has individual, named debug flags:
|
If the device has individual, named debug flags:
|
||||||
|
|
||||||
sim> SET <device> DEBUG=n1,n2,... -- enable device debug flags n1, n2, ...
|
sim> SET <device> DEBUG -- enable all device debug flags
|
||||||
sim> SET <device> NODEBUG=n1,n2,... -- disable device debug flags n1, n2, ...
|
sim> SET <device> DEBUG=n1;n2;... -- enable device debug flags n1, n2, ...
|
||||||
|
sim> SET <device> NODEBUG=n1;n2;... -- disable device debug flags n1, n2, ...
|
||||||
sim> SET <device> NODEBUG -- disable all device debug flags
|
sim> SET <device> NODEBUG -- disable all device debug flags
|
||||||
|
|
||||||
If debug output is directed to stdout, it will be intermixed with normal
|
If debug output is directed to stdout, it will be intermixed with normal
|
||||||
|
@ -957,6 +1010,9 @@ Revision History (covering Rev 2.0 to present)
|
||||||
Starting with Rev 2.7, detailed revision histories can be found
|
Starting with Rev 2.7, detailed revision histories can be found
|
||||||
in file sim_rev.c.
|
in file sim_rev.c.
|
||||||
|
|
||||||
|
Rev 3.4, May, 05
|
||||||
|
Revised memory interaction model
|
||||||
|
|
||||||
Rev 3.3, Nov, 04
|
Rev 3.3, Nov, 04
|
||||||
Added PDP-11/VAX DHQ11 support
|
Added PDP-11/VAX DHQ11 support
|
||||||
Added PDP-11/VAX TM02/TM03 support
|
Added PDP-11/VAX TM02/TM03 support
|
||||||
|
|
Loading…
Add table
Reference in a new issue