Notes For V3.6-0
The save/restore format has been updated to improve its reliability. As a result, save files prior to release 3.0 are no longer supported. The text documentation files are obsolete and are no longer included with the distribution. Up-to-date PDF documentation files are available on the SimH web site. 1. New Features 1.1 3.6-0 1.1.1 Most magnetic tapes - Added support for limiting tape capacity to a particular size in MB 1.1.2 IBM 7090/7094 - First release 1.1.3 VAX-11/780 - Added FLOAD command, loads system file from console floppy disk 1.1.4 VAX, VAX-11/780, and PDP-11 - Added card reader support (from John Dundas) 1.1.5 PDP-11 - Added instruction history 2. Bugs Fixed Please see the revision history on http://simh.trailing-edge.com or in the source module sim_rev.h.
This commit is contained in:
parent
a12e4a1c39
commit
dc871fa631
106 changed files with 15439 additions and 17517 deletions
148
0readme_35.txt
148
0readme_35.txt
|
@ -1,148 +0,0 @@
|
|||
Notes For V3.5-1
|
||||
|
||||
The source set has been extensively overhauled. For correct
|
||||
viewing, set Visual C++ or Emacs to have tab stops every 4
|
||||
characters.
|
||||
|
||||
1. New Features
|
||||
|
||||
1.1 3.5-0
|
||||
|
||||
1.1.1 All Ethernet devices
|
||||
|
||||
- Added Windows user-defined adapter names (from Timothe Litt)
|
||||
|
||||
1.1.2 Interdata, SDS, HP, PDP-8, PDP-18b terminal multiplexors
|
||||
|
||||
- Added support for SET <unit>n DISCONNECT
|
||||
|
||||
1.1.3 VAX
|
||||
|
||||
- Added latent QDSS support
|
||||
- Revised autoconfigure to handle QDSS
|
||||
|
||||
1.1.4 PDP-11
|
||||
|
||||
- Revised autoconfigure to handle more cases
|
||||
|
||||
1.2 3.5-1
|
||||
|
||||
No new features
|
||||
|
||||
1.3 3.5-2
|
||||
|
||||
1.3.1 All ASCII terminals
|
||||
|
||||
- Most ASCII terminal emulators have supported 7-bit and 8-bit
|
||||
operation; where required, they have also supported an upper-
|
||||
case only or KSR-emulation mode. This release adds a new mode,
|
||||
7P, for 7-bit printing characters. In 7P mode, non-printing
|
||||
characters in the range 0-31 (decimal), and 127 (decimal), are
|
||||
automatically suppressed. This prevents printing of fill
|
||||
characters under Windows.
|
||||
|
||||
The printable character set for ASCII code values 0-31 can be
|
||||
changed with the SET CONSOLE PCHAR command. Code value 127
|
||||
(DELETE) is always suppressed.
|
||||
|
||||
1.3.2 VAX-11/780
|
||||
|
||||
- First release. The VAX-11/780 has successfully run VMS V7.2. The
|
||||
commercial instructions and compatability mode have not been
|
||||
extensively tested. The Ethernet controller is not working yet
|
||||
and is disabled.
|
||||
|
||||
2. Bugs Fixed
|
||||
|
||||
2.1 3.5-0
|
||||
|
||||
2.1.1 SCP and libraries
|
||||
|
||||
- Trim trailing spaces on all input (for example, attach file names)
|
||||
- Fixed sim_sock spurious SIGPIPE error in Unix/Linux
|
||||
- Fixed sim_tape misallocation of TPC map array for 64b simulators
|
||||
|
||||
2.1.2 1401
|
||||
|
||||
- Fixed bug, CPU reset was clearing SSB through SSG
|
||||
|
||||
2.1.3 PDP-11
|
||||
|
||||
- Fixed bug in VH vector display routine
|
||||
- Fixed XU runt packet processing (found by Tim Chapman)
|
||||
|
||||
2.1.4 Interdata
|
||||
|
||||
- Fixed bug in SHOW PAS CONN/STATS
|
||||
- Fixed potential integer overflow exception in divide
|
||||
|
||||
2.1.5 SDS
|
||||
|
||||
- Fixed bug in SHOW MUX CONN/STATS
|
||||
|
||||
2.1.6 HP
|
||||
|
||||
- Fixed bug in SHOW MUX CONN/STATS
|
||||
|
||||
2.1.7 PDP-8
|
||||
|
||||
- Fixed bug in SHOW TTIX CONN/STATS
|
||||
- Fixed bug in SET/SHOW TTOXn LOG
|
||||
|
||||
2.1.8 PDP-18b
|
||||
|
||||
- Fixed bug in SHOW TTIX CONN/STATS
|
||||
- Fixed bug in SET/SHOW TTOXn LOG
|
||||
|
||||
2.1.9 Nova, Eclipse
|
||||
|
||||
- Fixed potential integer overflow exception in divide
|
||||
|
||||
2.2 3.5-1
|
||||
|
||||
2.2.1 1401
|
||||
|
||||
- Changed character encodings to be compatible with Pierce 709X simulator
|
||||
- Added mode for old/new character encodings
|
||||
|
||||
2.2.2 1620
|
||||
|
||||
- Changed character encodings to be compatible with Pierce 709X simulator
|
||||
|
||||
2.2.3 PDP-10
|
||||
|
||||
- Changed MOVNI to eliminate GCC warning
|
||||
|
||||
2.2.4 VAX
|
||||
|
||||
- Fixed bug in structure definitions with 32b compilation options
|
||||
- Fixed bug in autoconfiguration table
|
||||
|
||||
2.2.5 PDP-11
|
||||
|
||||
- Fixed bug in autoconfiguration table
|
||||
|
||||
2.3 3.5-2
|
||||
|
||||
2.3.1 PDP-10
|
||||
|
||||
- RP: fixed drive clear not to clear disk address
|
||||
|
||||
2.3.2 PDP-11 (VAX, VAX-11/780, for shared peripherals)
|
||||
|
||||
- HK: fixed overlap seek interaction with drive select, drive clear, etc
|
||||
- RQ, TM, TQ, TS, TU: widened address display to 64b when USE_ADDR64 option selected
|
||||
- TU: changed default adapter from TM02 to TM03 (required by VMS)
|
||||
- RP: fixed drive clear not to clear disk address
|
||||
- RP, TU: fixed device enable/disable to enabled/disable Massbus adapter as well
|
||||
- XQ: fixed register access alignment bug (found by Doug Carman)
|
||||
|
||||
2.3.3 PDP-8
|
||||
|
||||
- RL: fixed IOT 61 decoding bug (found by David Gesswein)
|
||||
- DF, DT, RF: fixed register access alignment bug (found by Doug Carman)
|
||||
|
||||
2.3.4 VAX
|
||||
|
||||
- Fixed CVTfi to trap on integer overflow if PSW<iv> is set
|
||||
- Fixed breakpoint detection when USE_ADDR64 option selected
|
39
0readme_36.txt
Normal file
39
0readme_36.txt
Normal file
|
@ -0,0 +1,39 @@
|
|||
Notes For V3.6-0
|
||||
|
||||
The save/restore format has been updated to improve its reliability.
|
||||
As a result, save files prior to release 3.0 are no longer supported.
|
||||
|
||||
The text documentation files are obsolete and are no longer included
|
||||
with the distribution. Up-to-date PDF documentation files are
|
||||
available on the SimH web site.
|
||||
|
||||
|
||||
1. New Features
|
||||
|
||||
1.1 3.6-0
|
||||
|
||||
1.1.1 Most magnetic tapes
|
||||
|
||||
- Added support for limiting tape capacity to a particular size in MB
|
||||
|
||||
1.1.2 IBM 7090/7094
|
||||
|
||||
- First release
|
||||
|
||||
1.1.3 VAX-11/780
|
||||
|
||||
- Added FLOAD command, loads system file from console floppy disk
|
||||
|
||||
1.1.4 VAX, VAX-11/780, and PDP-11
|
||||
|
||||
- Added card reader support (from John Dundas)
|
||||
|
||||
1.1.5 PDP-11
|
||||
|
||||
- Added instruction history
|
||||
|
||||
|
||||
2. Bugs Fixed
|
||||
|
||||
Please see the revision history on http://simh.trailing-edge.com or
|
||||
in the source module sim_rev.h.
|
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
|||
/* altairz80_defs.h: MITS Altair simulator definitions
|
||||
|
||||
Copyright (c) 2002-2005, Peter Schorn
|
||||
Copyright (c) 2002-2006, Peter Schorn
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -73,14 +73,3 @@
|
|||
sprintf(messageBuffer,PCformat p1,PCX,p2,p3,p4,p5); printMessage()
|
||||
#define message6(p1,p2,p3,p4,p5,p6) \
|
||||
sprintf(messageBuffer,PCformat p1,PCX,p2,p3,p4,p5,p6); printMessage()
|
||||
|
||||
/* The default is to use "inline". */
|
||||
#if defined(NO_INLINE)
|
||||
#define INLINE
|
||||
#else
|
||||
#if defined(__DECC) && defined(VMS)
|
||||
#define INLINE __inline
|
||||
#else
|
||||
#define INLINE inline
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* altairz80_dsk.c: MITS Altair 88-DISK Simulator
|
||||
|
||||
Copyright (c) 2002-2005, Peter Schorn
|
||||
Copyright (c) 2002-2006, Peter Schorn
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -494,7 +494,7 @@ int32 dsk11(const int32 port, const int32 io, const int32 data) {
|
|||
|
||||
/* Disk Data In/Out */
|
||||
|
||||
static INLINE int32 dskseek(const UNIT *xptr) {
|
||||
static int32 dskseek(const UNIT *xptr) {
|
||||
return fseek(xptr -> fileref, DSK_TRACSIZE * current_track[current_disk] +
|
||||
DSK_SECTSIZE * current_sector[current_disk], SEEK_SET);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* altairz80_sio: MITS Altair serial I/O card
|
||||
/* altairz80_sio.c: MITS Altair serial I/O card
|
||||
|
||||
Copyright (c) 2002-2005, Peter Schorn
|
||||
Copyright (c) 2002-2006, Peter Schorn
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -115,7 +115,7 @@ extern t_stat sim_poll_kbd(void);
|
|||
extern t_stat sim_putchar(int32 out);
|
||||
extern t_stat attach_unit(UNIT *uptr, char *cptr);
|
||||
extern int32 getBankSelect(void);
|
||||
extern void setBankSelect(int32 b);
|
||||
extern void setBankSelect(const int32 b);
|
||||
extern uint32 getCommon(void);
|
||||
extern t_bool rtc_avail;
|
||||
extern FILE *sim_log;
|
||||
|
@ -124,7 +124,7 @@ extern int32 sim_switches;
|
|||
extern uint32 sim_os_msec(void);
|
||||
extern const char *scp_error_messages[];
|
||||
extern int32 SR;
|
||||
extern uint8 GetBYTEWrapper(register uint32 Addr);
|
||||
extern uint8 GetBYTEWrapper(const uint32 Addr);
|
||||
extern UNIT cpu_unit;
|
||||
|
||||
/* SIMH pseudo device status registers */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* altairz80_sys.c: MITS Altair system interface
|
||||
|
||||
Copyright (c) 2002-2005, Peter Schorn
|
||||
Copyright (c) 2002-2006, Peter Schorn
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -584,7 +584,7 @@ static int32 match(const char *pattern, const char *input, char *xyFirst, char *
|
|||
return (pat == 0) && (inp == 0);
|
||||
}
|
||||
|
||||
static INLINE int32 checkXY(const char xy) {
|
||||
static int32 checkXY(const char xy) {
|
||||
return xy == 'X' ? 0xdd : 0xfd; /* else is 'Y' */
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* altairz80_hdsk.c: simulated hard disk device to increase capacity
|
||||
|
||||
Copyright (c) 2002-2005, Peter Schorn
|
||||
Copyright (c) 2002-2006, Peter Schorn
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -54,9 +54,9 @@ extern int32 saved_PC;
|
|||
extern int32 install_bootrom(void);
|
||||
extern void printMessage(void);
|
||||
extern void PutBYTEBasic(const uint32 Addr, const uint32 Bank, const uint32 Value);
|
||||
extern void PutBYTEWrapper(register uint32 Addr, register uint32 Value);
|
||||
extern void PutBYTEWrapper(const uint32 Addr, const uint32 Value);
|
||||
extern void protect(const int32 l, const int32 h);
|
||||
extern uint8 GetBYTEWrapper(register uint32 Addr);
|
||||
extern uint8 GetBYTEWrapper(const uint32 Addr);
|
||||
extern int32 bootrom[bootrom_size];
|
||||
|
||||
static t_stat hdsk_svc(UNIT *uptr);
|
||||
|
|
338
GRI/gri_doc.txt
338
GRI/gri_doc.txt
|
@ -1,338 +0,0 @@
|
|||
To: Users
|
||||
From: Bob Supnik
|
||||
Subj: GRI-909 Simulator Usage
|
||||
Date: 01-Dec-2005
|
||||
|
||||
COPYRIGHT NOTICE
|
||||
|
||||
The following copyright notice applies to both the SIMH source and binary:
|
||||
|
||||
Original code published in 1993-2005, written by Robert M Supnik
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
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 memorandum documents the GRI-909 simulator.
|
||||
|
||||
|
||||
1. Simulator Files
|
||||
|
||||
sim/ scp.h
|
||||
sim_console.h
|
||||
sim_defs.h
|
||||
sim_fio.h
|
||||
sim_rev.h
|
||||
sim_sock.h
|
||||
sim_timer.h
|
||||
sim_tmxr.h
|
||||
scp.c
|
||||
sim_console.c
|
||||
sim_fio.c
|
||||
sim_sock.c
|
||||
sim_timer.c
|
||||
sim_tmxr.c
|
||||
|
||||
sim/gri/ gri_defs.h
|
||||
gri_cpu.c
|
||||
gri_stddev.c
|
||||
gri_sys.c
|
||||
|
||||
2. GRI-909 Features
|
||||
|
||||
The GRI-909 is configured as follows:
|
||||
|
||||
device simulates
|
||||
name(s)
|
||||
|
||||
CPU GRI-909 CPU with up to 32KW of memory
|
||||
HSR S42-004 high speed reader
|
||||
HSP S42-004 high speed punch
|
||||
TTI S42-001 Teletype input
|
||||
TTO S42-002 Teletype output
|
||||
RTC real-time clock
|
||||
|
||||
The GRI-909 simulator implements the following unique stop conditions:
|
||||
|
||||
- an unimplemented operator is referenced, and register
|
||||
STOP_OPR is set
|
||||
- an invalid interrupt request is made
|
||||
|
||||
The LOAD commands has an optional argument to specify the load address:
|
||||
|
||||
LOAD <filename> {<starting address>}
|
||||
|
||||
The LOAD command loads a paper-tape bootstrap format file at the specified
|
||||
address. If no address is specified, loading starts at location 200. The
|
||||
DUMP command is not supported.
|
||||
|
||||
2.1 CPU
|
||||
|
||||
The only CPU options are the presence of the extended arithmetic operator
|
||||
and the size of main memory.
|
||||
|
||||
SET CPU EAO enable extended arithmetic operator
|
||||
SET CPU NOEAO disable extended arithmetic operator
|
||||
SET CPU 4K set memory size = 4K
|
||||
SET CPU 8K set memory size = 8K
|
||||
SET CPU 12K set memory size = 12K
|
||||
SET CPU 16K set memory size = 16K
|
||||
SET CPU 20K set memory size = 20K
|
||||
SET CPU 24K set memory size = 24K
|
||||
SET CPU 28K set memory size = 28K
|
||||
SET CPU 32K set memory size = 32K
|
||||
|
||||
If memory size is being reduced, and the memory being truncated contains
|
||||
non-zero data, the simulator asks for confirmation. Data in the truncated
|
||||
portion of memory is lost. Initial memory size is 32K.
|
||||
|
||||
CPU registers include the visible state of the processor as well as the
|
||||
control registers for the interrupt system.
|
||||
|
||||
name size comments
|
||||
|
||||
SC 15 sequence counter
|
||||
AX 16 arithmetic operator input register 1
|
||||
AY 16 arithmetic operator input register 2
|
||||
AO 16 arithmetic operator output register
|
||||
TRP 16 TRP register
|
||||
MSR 16 machine status register
|
||||
ISR 16 interrupt status register
|
||||
BSW 16 byte swapper buffer
|
||||
BPK 16 byte packer buffer
|
||||
GR1..GR6 16 general registers 1 to 6
|
||||
BOV 1 bus overflow (MSR<15>)
|
||||
L 1 link (MSR<14>)
|
||||
FOA 2 arithmetic operator function (MSR<9:8>)
|
||||
AOV 1 arithmetic overflow (MSR<0>)
|
||||
IR 16 instruction register (read only)
|
||||
MA 16 memory address register (read only)
|
||||
SWR 16 switch register
|
||||
DR 16 display register
|
||||
THW 6 thumbwheels (selects operator displayed in DR)
|
||||
IREQ 16 interrupt requests
|
||||
ION 1 interrupts enabled
|
||||
INODEF 1 interrupts not deferred
|
||||
BKP 1 breakpoint request
|
||||
SCQ[0:63] 15 SC prior to last jump or interrupt;
|
||||
most recent SC change first
|
||||
STOP_OPR 1 stop on undefined operator
|
||||
WRU 8 interrupt character
|
||||
|
||||
2.2 Programmed I/O Devices
|
||||
|
||||
2.2.1 S42-004 High Speed Reader (HSR)
|
||||
|
||||
The paper tape reader (HSR) reads data from or a disk file. The POS
|
||||
register specifies the number of the next data item to be read.
|
||||
Thus, by changing POS, the user can backspace or advance the reader.
|
||||
|
||||
The paper tape reader implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
IRDY 1 device ready flag
|
||||
IENB 1 device interrupt enable flag
|
||||
POS 32 position in the input file
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of tape
|
||||
|
||||
end of file 1 report error and stop
|
||||
0 out of tape
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.2.2 S42-006 High Speed Punch (HSP)
|
||||
|
||||
The paper tape punch (HSP) writes data to a disk file. The POS
|
||||
register specifies the number of the next data item to be written.
|
||||
Thus, by changing POS, the user can backspace or advance the punch.
|
||||
|
||||
The paper tape punch implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
ORDY 1 device ready flag
|
||||
IENB 1 device interrupt enable flag
|
||||
POS 32 position in the output file
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of tape
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.2.3 S42-001 Teletype Input (TTI)
|
||||
|
||||
The Teletype interfaces (TTI, TTO) can be set to one of four modes,
|
||||
KSR, 7P, 7B, or 8B:
|
||||
|
||||
mode input characters output characters
|
||||
|
||||
KSR lower case converted lower case converted
|
||||
to upper case, to upper case,
|
||||
high-order bit set high-order bit cleared,
|
||||
non-printing characters
|
||||
suppressed
|
||||
7P high-order bit cleared high-order bit cleared,
|
||||
non-printing characters
|
||||
suppressed
|
||||
7B high-order bit cleared high-order bit cleared
|
||||
8B no changes no changes
|
||||
|
||||
The default mode is KSR.
|
||||
|
||||
The Teletype input (TTI) polls the console keyboard for input. It
|
||||
implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
IRDY 1 device ready flag
|
||||
IENB 1 device interrupt enable flag
|
||||
POS 32 position in the output file
|
||||
TIME 24 keyboard polling interval
|
||||
|
||||
2.2.4 S42-002 Teletype Output (TTO)
|
||||
|
||||
The Teletype output (TTO) writes to the simulator console window. It
|
||||
implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
ORDY 1 device ready flag
|
||||
IENB 1 device interrupt enable flag
|
||||
POS 32 number of characters output
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
|
||||
2.2.5 Real-Time Clock (RTC)
|
||||
|
||||
The real-time clock (CLK) implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
RDY 1 device ready flag
|
||||
IENB 1 interrupt enable flag
|
||||
TIME 24 clock interval
|
||||
|
||||
The real-time clock autocalibrates; the clock interval is adjusted up or
|
||||
down so that the clock tracks actual elapsed time.
|
||||
|
||||
2.3 Symbolic Display and Input
|
||||
|
||||
The GRI-909 simulator implements symbolic display and input. Display is
|
||||
controlled by command line switches:
|
||||
|
||||
-a display as ASCII character
|
||||
-c display as packed ASCII characters
|
||||
-m display instruction mnemonics
|
||||
|
||||
Input parsing is controlled by the first character typed in or by command
|
||||
line switches:
|
||||
|
||||
' or -a ASCII character
|
||||
" or -c two packed ASCII characters
|
||||
alphabetic instruction mnemonic
|
||||
numeric octal number
|
||||
|
||||
Instruction input uses modified GRI-909 basic assembler syntax. There are
|
||||
thirteen different instruction formats. Operators, functions, and tests may
|
||||
be octal or symbolic; jump conditions and bus operators are always symbolic.
|
||||
|
||||
Function out, general
|
||||
Syntax: FO function,operator
|
||||
Function symbols: INP, IRDY, ORDY, STRT
|
||||
Example: FO ORDY,TTO
|
||||
|
||||
Function out, named
|
||||
Syntax: FO{M|I|A} function
|
||||
Function symbols: M: CLL, CML, STL, HLT; I: ICF, ICO;
|
||||
A: ADD, AND, XOR, OR
|
||||
Example: FOA XOR
|
||||
|
||||
Sense function, general
|
||||
Syntax: SF operator,{NOT} tests
|
||||
Test symbols: IRDY, ORDY
|
||||
Example: SF HSR,IRDY
|
||||
|
||||
Sense function, named
|
||||
Syntax: SF{M|A} {NOT} tests
|
||||
Test symbols: M: POK BOV LNK; A: SOV AOV
|
||||
Example: SFM NOT BOV
|
||||
|
||||
Register to register
|
||||
Syntax: RR{C} src,{bus op,}dst
|
||||
Bus op symbols: P1, L1, R1
|
||||
Example: RRC AX,P1,AY
|
||||
|
||||
Zero to register
|
||||
Syntax: ZR{C} {bus op,}dst
|
||||
Bus op symbols: P1, L1, R1
|
||||
Example: ZR P1,GR1
|
||||
|
||||
Register to self
|
||||
Syntax: RS{C} dst{,bus op}
|
||||
Bus op symbols: P1, L1, R1
|
||||
Example: RS AX,L1
|
||||
|
||||
Jump unconditional or named condition
|
||||
Syntax: J{U|O|N}{D} address
|
||||
Example: JUD 1400
|
||||
|
||||
Jump conditional
|
||||
Syntax: JC{D} src,cond,address
|
||||
Cond symbols: NEVER,ALWAYS,ETZ,NEZ,LTZ,GEZ,LEZ,GTZ
|
||||
Example: JC AX,LEZ,200
|
||||
|
||||
Register to memory
|
||||
syntax: RM{I|D|ID} src,{bus op,}address
|
||||
Bus op symbols: P1, L1, R1
|
||||
Example: RMD AX,P1,1315
|
||||
|
||||
Zero to memory
|
||||
Syntax: ZM{I|D|ID} {bus op,}address
|
||||
Bus op symbols: P1, L1, R1
|
||||
Example: ZM P1,5502
|
||||
|
||||
Memory to register
|
||||
Syntax: MR{I|D|ID} address,{bus op,}dst
|
||||
Bus op symbols: P1, L1, R1
|
||||
Example: MRI 1405,GR6
|
||||
|
||||
Memory to self:
|
||||
Syntax: MS{I|D|ID} address{,bus op}
|
||||
Bus op symbols: P1, L1, R1
|
||||
Example: MS 3333,P1
|
|
@ -1,6 +1,6 @@
|
|||
/* h316_cpu.c: Honeywell 316/516 CPU simulator
|
||||
|
||||
Copyright (c) 1999-2005, Robert M. Supnik
|
||||
Copyright (c) 1999-2006, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
cpu H316/H516 CPU
|
||||
|
||||
03-Apr-06 RMS Fixed bugs in LLL, LRL (from Theo Engel)
|
||||
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
15-Feb-05 RMS Added start button interrupt
|
||||
|
@ -427,7 +428,7 @@ if (chan_req) { /* channel request? */
|
|||
if (st & DMA_IN) { /* input? */
|
||||
t = iotab[dev] (ioINA, 0, 0, dev); /* input word */
|
||||
if ((t & IOT_SKIP) == 0) return STOP_DMAER;
|
||||
if (r = (t >> IOT_V_REASON)) return r;
|
||||
if ((r = t >> IOT_V_REASON) != 0) return r;
|
||||
Write (ad, t & DMASK); /* write to mem */
|
||||
}
|
||||
else { /* no, output */
|
||||
|
@ -441,7 +442,7 @@ if (chan_req) { /* channel request? */
|
|||
if (dma_wc[i] == 0) { /* done? */
|
||||
dma_eor[i] = 1; /* set end of range */
|
||||
t = iotab[dev] (ioEND, 0, 0, dev); /* send end range */
|
||||
if (r = (t >> IOT_V_REASON)) return r;
|
||||
if ((r = t >> IOT_V_REASON) != 0) return r;
|
||||
}
|
||||
}
|
||||
else { /* DMC */
|
||||
|
@ -450,7 +451,7 @@ if (chan_req) { /* channel request? */
|
|||
end = Read (dmcad + 1); /* get end */
|
||||
if (((ad ^ end) & X_AMASK) == 0) { /* start == end? */
|
||||
t = iotab[dev] (ioEND, 0, 0, dev); /* send end range */
|
||||
if (r = (t >> IOT_V_REASON)) return r;
|
||||
if ((r = t >> IOT_V_REASON) != 0) return r;
|
||||
} /* end if end range */
|
||||
} /* end else DMC */
|
||||
} /* end if chan i */
|
||||
|
@ -659,6 +660,7 @@ switch (I_GETOP (MB)) { /* case on <1:6> */
|
|||
|
||||
case 000:
|
||||
if ((MB & 1) == 0) { /* HLT */
|
||||
if ((reason = sim_process_event ()) != SCPE_OK) break;
|
||||
reason = STOP_HALT;
|
||||
break;
|
||||
}
|
||||
|
@ -739,7 +741,8 @@ switch (I_GETOP (MB)) { /* case on <1:6> */
|
|||
else {
|
||||
ut = GETDBL_U (AR, BR); /* get A'B */
|
||||
C = (ut >> (t1 - 1)) & 1; /* C = last out */
|
||||
ut = ut >> t1; /* log right */
|
||||
if (t1 == 32) ut = 0; /* =32? all 0 */
|
||||
else ut = ut >> t1; /* log right */
|
||||
}
|
||||
PUTDBL_U (ut); /* store A,B */
|
||||
break;
|
||||
|
@ -803,7 +806,8 @@ switch (I_GETOP (MB)) { /* case on <1:6> */
|
|||
else {
|
||||
ut = GETDBL_U (AR, BR); /* get A'B */
|
||||
C = (ut >> (32 - t1)) & 1; /* C = last out */
|
||||
ut = ut << t1; /* log left */
|
||||
if (t1 == 32) ut = 0; /* =32? all 0 */
|
||||
else ut = ut << t1; /* log left */
|
||||
}
|
||||
PUTDBL_U (ut); /* store A,B */
|
||||
break;
|
||||
|
@ -1369,9 +1373,11 @@ for (i = 0; dptr = sim_devices[i]; i++) { /* loop thru devices */
|
|||
dno = dibp->dev; /* device number */
|
||||
for (j = 0; j < dibp->num; j++) { /* repeat for slots */
|
||||
if (iotab[dno + j]) { /* conflict? */
|
||||
printf ("%s device number conflict, devno = %02o\n", sim_dname (dptr), dno + j);
|
||||
printf ("%s device number conflict, devno = %02o\n",
|
||||
sim_dname (dptr), dno + j);
|
||||
if (sim_log) fprintf (sim_log,
|
||||
"%s device number conflict, devno = %02o\n", sim_dname (dptr), dno + j);
|
||||
"%s device number conflict, devno = %02o\n",
|
||||
sim_dname (dptr), dno + j);
|
||||
return TRUE;
|
||||
}
|
||||
iotab[dno + j] = dibp->io; /* set I/O routine */
|
||||
|
@ -1379,21 +1385,27 @@ for (i = 0; dptr = sim_devices[i]; i++) { /* loop thru devices */
|
|||
if (dibp->chan) { /* DMA/DMC? */
|
||||
chan = dibp->chan - 1;
|
||||
if ((chan < DMC_V_DMC1) && (chan >= dma_nch)) {
|
||||
printf ("%s configured for DMA channel %d\n", sim_dname (dptr), chan + 1);
|
||||
printf ("%s configured for DMA channel %d\n",
|
||||
sim_dname (dptr), chan + 1);
|
||||
if (sim_log) fprintf (sim_log,
|
||||
"%s configured for DMA channel %d\n", sim_dname (dptr), chan + 1);
|
||||
"%s configured for DMA channel %d\n",
|
||||
sim_dname (dptr), chan + 1);
|
||||
return TRUE;
|
||||
}
|
||||
if ((chan >= DMC_V_DMC1) && !(cpu_unit.flags & UNIT_DMC)) {
|
||||
printf ("%s configured for DMC, option disabled\n", sim_dname (dptr));
|
||||
printf ("%s configured for DMC, option disabled\n",
|
||||
sim_dname (dptr));
|
||||
if (sim_log) fprintf (sim_log,
|
||||
"%s configured for DMC, option disabled\n", sim_dname (dptr));
|
||||
"%s configured for DMC, option disabled\n",
|
||||
sim_dname (dptr));
|
||||
return TRUE;
|
||||
}
|
||||
if (chan_map[chan]) { /* channel conflict? */
|
||||
printf ("%s DMA/DMC channel conflict, devno = %02o\n", sim_dname (dptr), dno);
|
||||
printf ("%s DMA/DMC channel conflict, devno = %02o\n",
|
||||
sim_dname (dptr), dno);
|
||||
if (sim_log) fprintf (sim_log,
|
||||
"%s DMA/DMC channel conflict, devno = %02o\n", sim_dname (dptr), dno);
|
||||
"%s DMA/DMC channel conflict, devno = %02o\n",
|
||||
sim_dname (dptr), dno);
|
||||
return TRUE;
|
||||
}
|
||||
chan_map[chan] = dno; /* channel back map */
|
||||
|
@ -1466,7 +1478,8 @@ for (k = 0; k < lnt; k++) { /* print specified */
|
|||
if (h->pc & HIST_EA) fprintf (st, "%05o ", h->ea);
|
||||
else fprintf (st, " ");
|
||||
sim_eval = h->ir;
|
||||
if ((fprint_sym (st, h->pc & X_AMASK, &sim_eval, &cpu_unit, SWMASK ('M'))) > 0)
|
||||
if ((fprint_sym (st, h->pc & X_AMASK, &sim_eval,
|
||||
&cpu_unit, SWMASK ('M'))) > 0)
|
||||
fprintf (st, "(undefined) %06o", h->ir);
|
||||
op = I_GETOP (h->ir) & 017; /* base op */
|
||||
if (has_opnd[op]) fprintf (st, " [%06o]", h->opnd);
|
||||
|
|
|
@ -1,672 +0,0 @@
|
|||
To: Users
|
||||
From: Bob Supnik
|
||||
Subj: H316 Simulator Usage
|
||||
Date: 01-Dec-2005
|
||||
|
||||
COPYRIGHT NOTICE
|
||||
|
||||
The following copyright notice applies to both the SIMH source and binary:
|
||||
|
||||
Original code published in 1993-2005, written by Robert M Supnik
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
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 memorandum documents the Honeywell 316/516 simulator.
|
||||
|
||||
|
||||
1. Simulator Files
|
||||
|
||||
The H316 requires the following files:
|
||||
|
||||
sim/ scp.h
|
||||
sim_console.h
|
||||
sim_defs.h
|
||||
sim_fio.h
|
||||
sim_rev.h
|
||||
sim_sock.h
|
||||
sim_tape.h
|
||||
sim_timer.h
|
||||
sim_tmxr.h
|
||||
scp.c
|
||||
sim_console.c
|
||||
sim_fio.c
|
||||
sim_sock.c
|
||||
sim_tape.c
|
||||
sim_timer.c
|
||||
sim_tmxr.c
|
||||
|
||||
sim/h316/ h316_defs.h
|
||||
h316_cpu.c
|
||||
h316_fhd.c
|
||||
h316_lp.c
|
||||
h316_mt.c
|
||||
h316_dp.c
|
||||
h316_stddev.c
|
||||
h316_sys.c
|
||||
|
||||
2. H316/H516 Features
|
||||
|
||||
The Honeywell 316/516 simulator is configured as follows:
|
||||
|
||||
device simulates
|
||||
name(s)
|
||||
|
||||
CPU H316/H516 CPU with 16/32KW memory
|
||||
PTR 316/516-50 paper tape reader
|
||||
PTP 316/516-52 paper tape punch
|
||||
TTY 316/516-33 console terminal
|
||||
CLK 316/516-12 real time clock
|
||||
LPT 316/516 line printer
|
||||
FHD 4400 fixed head disk
|
||||
DP 4623/4653/4720 disk pack controller with eight drives
|
||||
MT 4100 seven track magtape with four drives
|
||||
|
||||
The H316/H516 simulator implements several unique stop conditions:
|
||||
|
||||
- decode of an undefined instruction, and STOP_INST is et
|
||||
- reference to an undefined I/O device, and STOP_DEV is set
|
||||
- more than INDMAX indirect references are detected during
|
||||
memory reference address decoding
|
||||
- DMA/DMC direction does not agree with I/O device operation
|
||||
- a write operation is initiated on a write locked magtape
|
||||
unit (hangs the real system)
|
||||
- a disk write overruns the specified record size (destroys
|
||||
the rest of the track on the real system)
|
||||
- a disk track has an illegal format
|
||||
|
||||
The H316/H516 loader is not implemented.
|
||||
|
||||
2.1 CPU
|
||||
|
||||
CPU options include choice of instruction set, memory size, DMC option,
|
||||
and number of DMA channels.
|
||||
|
||||
SET CPU HSA high speed arithmetic instructions
|
||||
SET CPU NOHSA no high speed arithmetic instructions
|
||||
SET CPU 4K set memory size = 4K
|
||||
SET CPU 8K set memory size = 8K
|
||||
SET CPU 12K set memory size = 12K
|
||||
SET CPU 16K set memory size = 16K
|
||||
SET CPU 24K set memory size = 24K
|
||||
SET CPU 32K set memory size = 32K
|
||||
SET CPU DMC enable DMC option
|
||||
SET CPU NODMC disable DMC option
|
||||
SET CPU DMA=n set number of DMA channels to n (0-4)
|
||||
|
||||
If memory size is being reduced, and the memory being truncated contains
|
||||
non-zero data, the simulator asks for confirmation. Data in the truncated
|
||||
portion of memory is lost. Initial memory size is 32K. The HSA and DMC
|
||||
options are enabled, and four DMA channels are configured.
|
||||
|
||||
The CPU includes special show commands to display the state of the DMA
|
||||
channels:
|
||||
|
||||
SHOW CPU DMAn show DMA channel n
|
||||
|
||||
CPU registers include the visible state of the processor as well as the
|
||||
control registers for the interrupt system.
|
||||
|
||||
name size comments
|
||||
|
||||
P 15 program counter
|
||||
A 16 A register
|
||||
B 16 B register
|
||||
X 16 index register
|
||||
SC 16 shift count
|
||||
C 1 carry flag
|
||||
EXT 1 extend flag
|
||||
PME 1 previous mode extend flag
|
||||
EXT_OFF 1 extend off pending flag
|
||||
DP 1 double precision flag
|
||||
SS1..4 1 sense switches 1..4
|
||||
ION 1 interrupts enabled
|
||||
INODEF 1 interrupts not deferred
|
||||
INTREQ 16 interrupt requests
|
||||
DEVRDY 16 device ready flags (read only)
|
||||
DEVENB 16 device interrupt enable flags (read only)
|
||||
CHREQ 20 DMA/DMC channel requests
|
||||
DMAAD[0:3] 16 DMA channel current address, channels 1-4
|
||||
DMAWC[0:3] 15 DMA channel word count, channels 1-4
|
||||
DMAEOR[0:3] 1 DMA end of range flag, channels 1-4
|
||||
STOP_INST 1 stop on undefined instruction
|
||||
STOP_DEV 1 stop on undefined device
|
||||
INDMAX 1 indirect address limit
|
||||
PCQ[0:63] 15 PC prior to last JMP, JSB, or interrupt;
|
||||
most recent PC change first
|
||||
WRU 8 interrupt character
|
||||
|
||||
The CPU can maintain a history of the most recently executed instructions.
|
||||
This is controlled by the SET CPU HISTORY and SHOW CPU HISTORY commands:
|
||||
|
||||
SET CPU HISTORY clear history buffer
|
||||
SET CPU HISTORY=0 disable history
|
||||
SET CPU HISTORY=n enable history, length = n
|
||||
SHOW CPU HISTORY print CPU history
|
||||
SHOW CPU HISTORY=n print first n entries of CPU history
|
||||
|
||||
The maximum length for the history is 65536 entries.
|
||||
|
||||
2.2 Programmed I/O Devices
|
||||
|
||||
2.2.1 316/516-50 Paper Tape Reader (PTR)
|
||||
|
||||
The paper tape reader (PTR) reads data from a disk file. The POS
|
||||
register specifies the number of the next data item to be read.
|
||||
Thus, by changing POS, the user can backspace or advance the reader.
|
||||
|
||||
The paper tape reader can bet set to operate in binary, ASCII, or
|
||||
Unix ASCII mode:
|
||||
|
||||
sim> set ptr binary -- binary mode
|
||||
sim> set ptr ascii -- ASCII mode
|
||||
sim> set ptr uascii -- Unix ASCII mode
|
||||
|
||||
The mode can also be set by a switch setting in the attach command:
|
||||
|
||||
sim> att -b ptr <file> -- binary mode
|
||||
sim> att -a ptr <file> -- ASCII mode
|
||||
sim> att -u ptr <file> -- Unix ASCII mode
|
||||
|
||||
In ASCII or Unix ASCII mode, all non-zero characters have the high
|
||||
order bit forced on. In Unix ASCII mode, newline is converted to
|
||||
CR, and LF in inserted as the following character.
|
||||
|
||||
The paper tape reader supports the BOOT command. BOOT PTR copies the
|
||||
absolute binary loader into memory and starts it running.
|
||||
|
||||
The paper tape reader implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
INTREQ 1 device interrupt request
|
||||
READY 1 device ready
|
||||
ENABLE 1 device interrupts enabled
|
||||
POS 32 position in the input or output file
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of tape
|
||||
|
||||
end of file 1 report error and stop
|
||||
0 out of tape or paper
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.2.2 316/516-52 Paper Tape Punch (PTP)
|
||||
|
||||
The paper tape punch (PTP) writes data to a disk file. The POS
|
||||
register specifies the number of the next data item to be written.
|
||||
Thus, by changing POS, the user can backspace or advance the punch.
|
||||
|
||||
The paper tape punch can bet set to operate in binary, ASCII, or
|
||||
Unix ASCII mode:
|
||||
|
||||
sim> set ptp binary -- binary mode
|
||||
sim> set ptp ascii -- ASCII mode
|
||||
sim> set ptp uascii -- Unix ASCII mode
|
||||
|
||||
The mode can also be set by a switch setting in the attach command:
|
||||
|
||||
sim> att -b ptp <file> -- binary mode
|
||||
sim> att -a ptp <file> -- ASCII mode
|
||||
sim> att -u ptp <file> -- Unix ASCII mode
|
||||
|
||||
In ASCII or Unix ASCII mode, all characters are masked to 7b
|
||||
before being written to the output file. In Unix ASCII mode, LF
|
||||
is converted to newline, and CR is discarded.
|
||||
|
||||
The paper tape punch implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
INTREQ 1 device interrupt request
|
||||
READY 1 device ready
|
||||
ENABLE 1 device interrupts enabled
|
||||
POWER 1 device powered up
|
||||
POS 32 position in the input or output file
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
PWRTIME 24 time from I/O request to power up
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of tape
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.2.3 316/516-33 Console Teletype (TTY)
|
||||
|
||||
The console Teletype (TTY) consists of four separate units:
|
||||
|
||||
TTY0 keyboard
|
||||
TTY1 printer
|
||||
TTY2 paper tape reader
|
||||
TTY3 paper tape punch
|
||||
|
||||
The keyboard and printer (TTY0, TTY1) can be set to one of four modes,
|
||||
KSR, 7P, 7B, or 8B:
|
||||
|
||||
mode input characters output characters
|
||||
|
||||
KSR lower case converted lower case converted
|
||||
to upper case, to upper case,
|
||||
high-order bit set high-order bit cleared,
|
||||
non-printing characters
|
||||
suppressed
|
||||
7P high-order bit cleared high-order bit cleared,
|
||||
non-printing characters
|
||||
suppressed
|
||||
7B high-order bit cleared high-order bit cleared
|
||||
8B no changes no changes
|
||||
|
||||
The default mode is KSR. The Teletype keyboard reads from the console
|
||||
keyboard, and the printer writes to the simulator console window.
|
||||
|
||||
The paper tape reader (TTY2) can bet set to operate in binary, ASCII, or
|
||||
Unix ASCII mode:
|
||||
|
||||
sim> set tty2 binary -- binary mode
|
||||
sim> set tty2 ascii -- ASCII mode
|
||||
sim> set tty2 uascii -- Unix ASCII mode
|
||||
|
||||
The mode can also be set by a switch setting in the attach command:
|
||||
|
||||
sim> att -b tty2 <file> -- binary mode
|
||||
sim> att -a tty2 <file> -- ASCII mode
|
||||
sim> att -u tty2 <file> -- Unix ASCII mode
|
||||
|
||||
In ASCII or Unix ASCII mode, all non-zero characters have the high
|
||||
order bit forced on. In Unix ASCII mode, newline is converted to
|
||||
CR, and LF in inserted as the following character.
|
||||
|
||||
The paper tape reader is started by program output of XON or by
|
||||
the command SET TTY2 START. The paper tape reader is stopped by
|
||||
reader input of XOFF or by the command SET TTY2 STOP.
|
||||
|
||||
The paper tape punch (TTY3) can bet set to operate in binary, ASCII, or
|
||||
Unix ASCII mode:
|
||||
|
||||
sim> set tty3 binary -- binary mode
|
||||
sim> set tty3 ascii -- ASCII mode
|
||||
sim> set tty3 uascii -- Unix ASCII mode
|
||||
|
||||
The mode can also be set by a switch setting in the attach command:
|
||||
|
||||
sim> att -b tty3 <file> -- binary mode
|
||||
sim> att -a tty3 <file> -- ASCII mode
|
||||
sim> att -u tty3 <file> -- Unix ASCII mode
|
||||
|
||||
In ASCII or Unix ASCII mode, all characters are masked to 7b
|
||||
before being written to the output file. In Unix ASCII mode, LF
|
||||
is converted to newline, and CR is discarded.
|
||||
|
||||
The paper tape punch is started by program output of TAPE or by
|
||||
the command SET TTY3 START. The paper tape punch is stopped by
|
||||
program output of XOFF or by the command SET TTY3 STOP.
|
||||
|
||||
It implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
MODE 1 read/write mode
|
||||
INTREQ 1 device interrupt request
|
||||
READY 1 device ready
|
||||
ENABLE 1 device interrupts enabled
|
||||
KPOS 32 number of keyboard characters input
|
||||
KTIME 24 keyboard polling interval
|
||||
TPOS 32 number of printer characters output
|
||||
TTIME 24 time from I/O initiation to interrupt
|
||||
RPOS 32 current reader character position
|
||||
PPOS 32 current punch character position
|
||||
|
||||
2.2.4 316/516-12 Real Time Clock (CLK)
|
||||
|
||||
The real time clock (CLK) frequency can be adjusted as follows:
|
||||
|
||||
SET CLK 60HZ set frequency to 60Hz
|
||||
SET CLK 50HZ set frequency to 50Hz
|
||||
|
||||
The default is 60Hz.
|
||||
|
||||
The clock implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
INTREQ 1 device interrupt request
|
||||
READY 1 device ready
|
||||
ENABLE 1 device interrupts enabled
|
||||
TIME 24 clock interval
|
||||
|
||||
The real-time clock autocalibrates; the clock interval is adjusted up or
|
||||
down so that the clock tracks actual elapsed time.
|
||||
|
||||
2.3 316/516 Line Printer (LPT)
|
||||
|
||||
The line printer (LPT) writes data to a disk file. The POS register
|
||||
specifies the number of the next data item to be written. Thus,
|
||||
by changing POS, the user can backspace or advance the printer.
|
||||
|
||||
The line printer can be connected to the IO bus, a DMC channel, or
|
||||
a DMA channel:
|
||||
|
||||
SET LPT IOBUS connect to IO bus
|
||||
SET LPT DMC=n connect to DMC channel n (1-16)
|
||||
SET LPT DMA=n connect to DMA channel n (1-4)
|
||||
|
||||
By default, the line printer is connected to the IO bus.
|
||||
|
||||
The line printer implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
WDPOS 6 word position in current scan
|
||||
DRPOS 6 drum position
|
||||
CRPOS 1 carriage position
|
||||
PRDN 1 print done flag
|
||||
RDY 1 ready flag
|
||||
EOR 1 (DMA/DMC) end of range flag
|
||||
DMA 1 transfer using DMA/DMC
|
||||
INTREQ 1 device interrupt request
|
||||
ENABLE 1 device interrupt enable
|
||||
SVCST 2 service state
|
||||
SVCCH 2 service channel
|
||||
BUF 8 buffer
|
||||
POS 32 number of characters output
|
||||
XTIME 24 delay between transfers
|
||||
ETIME 24 delay at end of scan
|
||||
PTIME 24 delay for shuttle/line advance
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of paper
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.4 4400 Fixed Head Disk (FHD)
|
||||
|
||||
Fixed head disk options include the ability to set the number of
|
||||
surfaces to a fixed value between 1 and 16, or to autosize the number
|
||||
of surfaces from the attached file:
|
||||
|
||||
SET FHD 1S one surface (98K)
|
||||
SET FHD 2S two platters (196K)
|
||||
:
|
||||
SET FHD 16S sixteen surfaces (1568K)
|
||||
SET FHD AUTOSIZE autosized on attach
|
||||
|
||||
The default is one surface.
|
||||
|
||||
The fixed head disk can be connected to the IO bus, a DMC channel, or
|
||||
a DMA channel:
|
||||
|
||||
SET FHD IOBUS connect to IO bus
|
||||
SET FHD DMC=n connect to DMC channel n (1-16)
|
||||
SET FHD DMA=n connect to DMA channel n (1-4)
|
||||
|
||||
By default, the fixed head disk is connected to the IO bus.
|
||||
|
||||
|
||||
The fixed head disk implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
CW1 16 control word 1 (read write, surface, track)
|
||||
CW2 16 control word 2 (character address)
|
||||
BUF 16 data buffer
|
||||
BUSY 1 controller busy flag
|
||||
RDY 1 transfer ready flag
|
||||
DTE 1 data transfer error flag
|
||||
ACE 1 access error flag
|
||||
EOR 1 (DMA/DMC) end of range
|
||||
DMA 1 transfer using DMA/DMC
|
||||
CSUM 1 transfer parity checksum
|
||||
INTREQ 1 device interrupt request
|
||||
ENABLE 1 device interrupt enable
|
||||
TIME 24 delay between words
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
The fixed head disk does not support the BOOT command.
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 disk not ready
|
||||
|
||||
Fixed head disk data files are buffered in memory; therefore, end of file
|
||||
and OS I/O errors cannot occur.
|
||||
|
||||
2.5 4100 7-track Magnetic Tape (MT)
|
||||
|
||||
Magnetic tape options include the ability to make units write enabled or
|
||||
or write locked.
|
||||
|
||||
SET MTn LOCKED set unit n write locked
|
||||
SET MTn WRITEENABLED set unit n write enabled
|
||||
|
||||
Units can also be set ENABLED or DISABLED.
|
||||
|
||||
The magtape controller can be connected to the IO bus, a DMC channel, or
|
||||
a DMA channel:
|
||||
|
||||
SET MT IOBUS connect to IO bus
|
||||
SET MT DMC=n connect to DMC channel n (1-16)
|
||||
SET MT DMA=n connect to DMA channel n (1-4)
|
||||
|
||||
By default, the magtape controller is connected to the IO bus.
|
||||
|
||||
The magnetic tape controller implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 16 data buffer
|
||||
USEL 2 unit select
|
||||
BUSY 1 controller busy flag
|
||||
RDY 1 transfer ready flag
|
||||
ERR 1 error flag
|
||||
EOF 1 end of file flag
|
||||
EOR 1 (DMA/DMC) end of range
|
||||
DMA 1 transfer using DMA/DMC
|
||||
MDIRQ 1 motion done interrupt request
|
||||
INTREQ 1 device interrupt request
|
||||
ENABLE 1 device interrupt enable
|
||||
DBUF[0:65535] 8 transfer buffer
|
||||
BPTR 17 transfer buffer pointer
|
||||
BMAX 17 transfer size (reads)
|
||||
CTIME 24 start/stop time
|
||||
XTIME 24 delay between words
|
||||
POS[0:3] 32 position, units 0-3
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error processed as
|
||||
|
||||
not attached tape not ready; if STOP_IOE, stop
|
||||
|
||||
end of file bad tape
|
||||
|
||||
OS I/O error parity error; if STOP_IOE, stop
|
||||
|
||||
2.6 4623/4651/4720 Disk Packs (DP)
|
||||
|
||||
The disk controller can be configured as a 4623, supporting 10 surface
|
||||
disk packs; a 4651, supporting 2 surface disk packs; or a 4720, supporting
|
||||
20 surface disk packs:
|
||||
|
||||
SET DP 4623 controller is 4623
|
||||
SET DP 4651 controller is 4651
|
||||
SET DP 4720 controller is 4720
|
||||
|
||||
The default is 4651. All disk packs on the controller must be of the
|
||||
same type. Units can be set ENABLED or DISABLED, and WRITEENABLED or
|
||||
write LOCKED.
|
||||
|
||||
The disk pack controller can be connected to a DMC channel or a DMA
|
||||
channel; it cannot be connected to the IO bus:
|
||||
|
||||
SET DP DMC=n connect to DMC channel n (1-16)
|
||||
SET DP DMA=n connect to DMA channel n (1-4)
|
||||
|
||||
The disk pack controller supports variable track formatting. Each track
|
||||
can contain between 1 and 103 records, with a minimum size of 1 word and
|
||||
a maximum size of 1893 words. Record addresses are unconstrained. The
|
||||
simulator provides a command to perform a simple, fixed record size format
|
||||
of a new disk:
|
||||
|
||||
SET DPn FORMAT=k format unit n with k words per record
|
||||
SET -R DPn FORMAT=k format unit n with k records per track
|
||||
|
||||
Record addresses can either be geometric (cylinder/track/sector) or simple
|
||||
sequential starting from 0:
|
||||
|
||||
SET DPn FORMAT=k format with geometric record addresses
|
||||
SET -S DPn FORMAT=k format with sequential record addresses
|
||||
|
||||
Geometric address have the cylinder number in bits<1:8>, the head number in
|
||||
bits<9:13>, and the sector number in bits <14:16>.
|
||||
|
||||
A summary of the current format, and its validity, can be obtained with
|
||||
the command:
|
||||
|
||||
SHOW DPn FORMAT display format of unit n
|
||||
|
||||
To accomodate the variable formatting, each track is allocated 2048 words
|
||||
in the data file. A record consists of a three word header, the data, and
|
||||
a five word trailer:
|
||||
|
||||
word 0 record length in words, not including header/trailer
|
||||
word 1 record address
|
||||
word 2 number of extension words used (0-4)
|
||||
word 3 start of data record
|
||||
word 3+n-1 end of data record
|
||||
word 3+n..7+n record trailer: up to four extension words,
|
||||
plus checksum
|
||||
|
||||
A record can "grow" by up to four words without disrupting the track formatting;
|
||||
writing more than four extra words destroys the formatting of the rest of the
|
||||
track and causes a simulator error.
|
||||
|
||||
The disk pack controller implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
STA 16 status
|
||||
BUF 16 data buffer
|
||||
FNC 4 controller function
|
||||
CW1 16 command word 1
|
||||
CW2 16 command word 2
|
||||
CSUM 16 record checksum
|
||||
BUSY 1 controller busy
|
||||
RDY 1 transfer ready
|
||||
EOR 1 (DMA/DMC) end of range
|
||||
DEFINT 1 seek deferred interrupt pending
|
||||
INTREQ 1 interrupt request
|
||||
ENABLE 1 interrupt enable
|
||||
TBUF[0:2047] 16 track buffer
|
||||
RPTR 11 pointer to start of record in track buffer
|
||||
WPTR 11 pointer to current word in record
|
||||
BCTR 15 bit counter for formatting
|
||||
STIME 24 seek time, per cylinder
|
||||
XTIME 24 transfer time, per word
|
||||
BTIME 24 controller busy time
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error processed as
|
||||
|
||||
not attached pack off line; if STOP_IOE, stop
|
||||
|
||||
end of file ignored
|
||||
|
||||
OS I/O error data error; if STOP_IOE, stop
|
||||
|
||||
2.7 Symbolic Display and Input
|
||||
|
||||
The H316/H516 simulator implements symbolic display and input. Display is
|
||||
controlled by command line switches:
|
||||
|
||||
-a display as ASCII character
|
||||
-c display as two character string
|
||||
-m display instruction mnemonics
|
||||
|
||||
Input parsing is controlled by the first character typed in or by command
|
||||
line switches:
|
||||
|
||||
' or -a ASCII character
|
||||
" or -c two character sixbit string
|
||||
alphabetic instruction mnemonic
|
||||
numeric octal number
|
||||
|
||||
Instruction input uses standard H316/H516 assembler syntax. There are six
|
||||
instruction classes: memory reference, I/O, control, shift, skip, and
|
||||
operate.
|
||||
|
||||
Memory reference instructions have the format
|
||||
|
||||
memref{*} {C/Z} address{,1}
|
||||
|
||||
where * signifies indirect, C a current sector reference, Z a sector zero
|
||||
reference, and 1 indexed. The address is an octal number in the range 0 -
|
||||
077777; if C or Z is specified, the address is a page offset in the range
|
||||
0 - 0777. Normally, C is not needed; the simulator figures out from the
|
||||
address what mode to use. However, when referencing memory outside the CPU,
|
||||
there is no valid PC, and C must be used to specify current sector addressing.
|
||||
|
||||
I/O instructions have the format
|
||||
|
||||
io pulse+device
|
||||
|
||||
The pulse+device is an octal number in the range 0 - 01777.
|
||||
|
||||
Control and operate instructions consist of a single opcode
|
||||
|
||||
opcode
|
||||
|
||||
Shift instructions have the format
|
||||
|
||||
shift n
|
||||
|
||||
where n is an octal number in the range 0-77.
|
||||
|
||||
Skip instructions have the format
|
||||
|
||||
sub-op sub-op sub-op...
|
||||
|
||||
The simulator checks that the combination of sub-opcodes is legal.
|
|
@ -1,6 +1,6 @@
|
|||
/* h316_fhd.c: H316/516 fixed head simulator
|
||||
|
||||
Copyright (c) 2003-2005, Robert M. Supnik
|
||||
Copyright (c) 2003-2006, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
fhd 516-4400 fixed head disk
|
||||
|
||||
15-May-06 RMS Fixed bug in autosize attach (reported by David Gesswein)
|
||||
04-Jan-04 RMS Changed sim_fsize calling sequence
|
||||
|
||||
These head-per-track devices are buffered in memory, to minimize overhead.
|
||||
|
@ -93,7 +94,6 @@ int32 fhdio (int32 inst, int32 fnc, int32 dat, int32 dev);
|
|||
t_stat fhd_svc (UNIT *uptr);
|
||||
t_stat fhd_reset (DEVICE *dptr);
|
||||
t_stat fhd_attach (UNIT *uptr, char *cptr);
|
||||
t_stat fhd_boot (int32 unitno, DEVICE *dptr);
|
||||
t_stat fhd_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
void fhd_go (uint32 dma);
|
||||
void fhd_go1 (uint32 dat);
|
||||
|
@ -433,18 +433,15 @@ t_stat fhd_attach (UNIT *uptr, char *cptr)
|
|||
{
|
||||
uint32 sz, sf;
|
||||
uint32 ds_bytes = FH_WDPSF * sizeof (int16);
|
||||
t_stat r;
|
||||
|
||||
r = attach_unit (uptr, cptr);
|
||||
if (r != SCPE_OK) return r;
|
||||
if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize (uptr->fileref))) {
|
||||
if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize_name (cptr))) {
|
||||
sf = (sz + ds_bytes - 1) / ds_bytes;
|
||||
if (sf >= FH_NUMSF) sf = FH_NUMSF - 1;
|
||||
uptr->flags = (uptr->flags & ~UNIT_SF) |
|
||||
(sf << UNIT_V_SF);
|
||||
}
|
||||
uptr->capac = UNIT_GETSF (uptr->flags) * FH_WDPSF;
|
||||
return SCPE_OK;
|
||||
return attach_unit (uptr, cptr);
|
||||
}
|
||||
|
||||
/* Set size routine */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* h316_lp.c: Honeywell 316/516 line printer
|
||||
|
||||
Copyright (c) 1999-2005, Robert M. Supnik
|
||||
Copyright (c) 1999-2006, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
lpt line printer
|
||||
|
||||
03-Apr-06 RMS Fixed bug in blanks backscanning (from Theo Engel)
|
||||
01-Dec-04 RMS Fixed bug in DMA/DMC support
|
||||
24-Oct-03 RMS Added DMA/DMC support
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
|
@ -298,7 +299,7 @@ if (lpt_svcst & LPT_SVCSH) { /* shuttling */
|
|||
}
|
||||
if (lpt_svcst & LPT_SVCPA) { /* paper advance */
|
||||
SET_INT (INT_LPT); /* interrupt */
|
||||
for (i = LPT_WIDTH - 1; i >= 0; i++) {
|
||||
for (i = LPT_WIDTH - 1; i >= 0; i--) { /* backscan for blanks */
|
||||
if (lpt_buf[i] != ' ') break;
|
||||
}
|
||||
lpt_buf[i + 1] = 0;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* h316_mt.c: H316/516 magnetic tape simulator
|
||||
|
||||
Copyright (c) 2003-2005, Robert M. Supnik
|
||||
Copyright (c) 2003-2006, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
mt 516-4100 seven track magnetic tape
|
||||
|
||||
16-Feb-06 RMS Added tape capacity checking
|
||||
26-Aug-05 RMS Revised to use API for write lock check
|
||||
08-Feb-05 RMS Fixed error reporting from OCP (found by Philipp Hachtmann)
|
||||
01-Dec-04 RMS Fixed bug in DMA/DMC support
|
||||
|
@ -154,6 +155,8 @@ MTAB mt_mod[] = {
|
|||
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "CAPACITY", "CAPACITY",
|
||||
&sim_tape_set_capac, &sim_tape_show_capac, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, NULL, "IOBUS",
|
||||
&io_set_iobus, NULL, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, NULL, "DMC",
|
||||
|
@ -177,7 +180,7 @@ DEVICE mt_dev = {
|
|||
|
||||
int32 mtio (int32 inst, int32 fnc, int32 dat, int32 dev)
|
||||
{
|
||||
uint32 u = dev & 03;
|
||||
uint32 i, u = dev & 03;
|
||||
UNIT *uptr = mt_dev.units + u;
|
||||
static uint8 wrt_fnc[16] = { /* >0 = wr, 1 = chan op */
|
||||
0, 0, 0, 0, 1, 1, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0
|
||||
|
@ -222,6 +225,8 @@ switch (inst) { /* case on opcode */
|
|||
uptr->FNC = fnc;
|
||||
uptr->UST = 0;
|
||||
mt_busy = 1;
|
||||
for (i = 0; i < MT_NUMDR; i++) /* clear all EOT flags */
|
||||
mt_unit[i].UST = mt_unit[i].UST & ~STA_EOT;
|
||||
sim_activate (uptr, mt_ctime); /* schedule */
|
||||
break;
|
||||
}
|
||||
|
@ -319,6 +324,7 @@ t_stat mt_svc (UNIT *uptr)
|
|||
int32 ch = mt_dib.chan - 1; /* DMA/DMC ch */
|
||||
uint32 i, c1, c2, c3;
|
||||
t_mtrlnt tbc;
|
||||
t_bool passed_eot;
|
||||
t_stat st, r = SCPE_OK;
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) == 0) { /* offline? */
|
||||
|
@ -328,6 +334,7 @@ if ((uptr->flags & UNIT_ATT) == 0) { /* offline? */
|
|||
return IORETURN (mt_stopioe, SCPE_UNATT);
|
||||
}
|
||||
|
||||
passed_eot = sim_tape_eot (uptr); /* passed EOT? */
|
||||
switch (uptr->FNC) { /* case on function */
|
||||
|
||||
case FNC_REW: /* rewind (initial) */
|
||||
|
@ -442,6 +449,8 @@ switch (uptr->FNC) { /* case on function */
|
|||
|
||||
/* End of command, process error or schedule end of motion */
|
||||
|
||||
if (!passed_eot && sim_tape_eot (uptr)) /* just passed EOT? */
|
||||
uptr->UST = uptr->UST | STA_EOT;
|
||||
if (r != SCPE_OK) {
|
||||
uptr->FNC = FNC_NOP; /* nop function */
|
||||
mt_busy = 0; /* not busy */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* h316_stddev.c: Honeywell 316/516 standard devices
|
||||
|
||||
Copyright (c) 1999-2005, Robert M. Supnik
|
||||
Copyright (c) 1999-2006, 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"),
|
||||
|
@ -28,6 +28,7 @@
|
|||
tty 316/516-33 teleprinter
|
||||
clk/options 316/516-12 real time clocks/internal options
|
||||
|
||||
03-Apr-06 RMS Fixed bugs in punch state handling (from Theo Engel)
|
||||
22-Nov-05 RMS Revised for new terminal processing routines
|
||||
05-Feb-05 RMS Fixed bug in OCP '0001 (found by Philipp Hachtmann)
|
||||
31-Jan-05 RMS Fixed bug in TTY print (found by Philipp Hachtmann)
|
||||
|
@ -608,7 +609,7 @@ else if ((ruptr->flags & UNIT_ATT) && /* TTR attached */
|
|||
(ruptr->STA & RUNNING)) { /* and running? */
|
||||
if (ruptr->STA & LF_PEND) { /* lf pending? */
|
||||
c = 0212; /* char is lf */
|
||||
ruptr->STA &= LF_PEND; /* clear flag */
|
||||
ruptr->STA &= ~LF_PEND; /* clear flag */
|
||||
}
|
||||
else { /* normal read */
|
||||
if ((c = getc (ruptr->fileref)) == EOF) { /* read byte */
|
||||
|
@ -665,7 +666,7 @@ if (ttp_tape_rcvd != 0) { /* prev = tape? */
|
|||
else if (c7b == TAPE) ttp_tape_rcvd = 2; /* char = TAPE? */
|
||||
if (ttp_xoff_rcvd != 0) { /* prev = XOFF? */
|
||||
ttp_xoff_rcvd--; /* decrement state */
|
||||
if (ttp_xoff_rcvd == 0) puptr->STA &= RUNNING; /* stop after delay */
|
||||
if (ttp_xoff_rcvd == 0) puptr->STA &= ~RUNNING; /* stop after delay */
|
||||
}
|
||||
else if (c7b == XOFF) ttp_xoff_rcvd = 2; /* char = XOFF? */
|
||||
if ((c7b == XON) && (ruptr->flags & UNIT_ATT)) { /* char = XON? */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
|||
/* hp2100_ms.c: HP 2100 13181A/13183A magnetic tape simulator
|
||||
|
||||
Copyright (c) 1993-2005, Robert M. Supnik
|
||||
Copyright (c) 1993-2006, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -26,6 +26,7 @@
|
|||
ms 13181A 7970B 800bpi nine track magnetic tape
|
||||
13183A 7970E 1600bpi nine track magnetic tape
|
||||
|
||||
16-Feb-06 RMS Revised for new EOT test
|
||||
22-Jul-05 RMS Fixed compiler warning on Solaris (from Doug Glyn)
|
||||
01-Mar-05 JDB Added SET OFFLINE; rewind/offline now does not detach
|
||||
07-Oct-04 JDB Fixed enable/disable from either device
|
||||
|
@ -445,8 +446,8 @@ switch (inst) { /* case on opcode */
|
|||
dat = dat | STA_TBSY;
|
||||
if (sim_tape_wrp (uptr)) /* write prot? */
|
||||
dat = dat | STA_WLK;
|
||||
if (uptr->REEL &&
|
||||
sim_tape_eot (uptr, (TCAP << uptr->REEL) << ms_ctype))
|
||||
uptr->capac = (TCAP << uptr->REEL) << ms_ctype;
|
||||
if (sim_tape_eot (uptr))
|
||||
dat = dat | STA_EOT;
|
||||
}
|
||||
else dat = dat | STA_TBSY | STA_LOCAL;
|
||||
|
@ -529,7 +530,7 @@ return dat;
|
|||
|
||||
t_stat msc_svc (UNIT *uptr)
|
||||
{
|
||||
int32 devc, devd, unum, cap;
|
||||
int32 devc, devd, unum;
|
||||
t_mtrlnt tbc;
|
||||
t_stat st, r = SCPE_OK;
|
||||
|
||||
|
@ -588,10 +589,9 @@ switch (uptr->FNC) { /* case on function */
|
|||
break;
|
||||
|
||||
case FNC_FSF: /* space fwd file */
|
||||
cap = (TCAP << uptr->REEL) << ms_ctype;
|
||||
uptr->capac = (TCAP << uptr->REEL) << ms_ctype;
|
||||
while ((st = sim_tape_sprecf (uptr, &tbc)) == MTSE_OK) {
|
||||
if (uptr->REEL && sim_tape_eot (uptr, cap))
|
||||
break; /* EOT stops */
|
||||
if (sim_tape_eot (uptr)) break; /* EOT stops */
|
||||
}
|
||||
r = ms_map_err (uptr, st); /* map error */
|
||||
break;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* i1401_cpu.c: IBM 1401 CPU simulator
|
||||
|
||||
Copyright (c) 1993-2005, Robert M. Supnik
|
||||
Copyright (c) 1993-2006, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -23,6 +23,8 @@
|
|||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
22-May-06 RMS Fixed format error in CPU history (found by Peter Schorn)
|
||||
06-Mar-06 RMS Fixed bug in divide (found by Van Snyder)
|
||||
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
|
||||
01-Sep-05 RMS Removed error stops in MCE
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
|
@ -1333,7 +1335,8 @@ CHECK_LENGTH:
|
|||
*/
|
||||
|
||||
case OP_DIV:
|
||||
asave = AS; ahigh = -1;
|
||||
asave = AS;
|
||||
ahigh = -1;
|
||||
do {
|
||||
a = M[AS]; /* get dvr char */
|
||||
if ((a & CHAR) != BCD_ZERO) ahigh = AS; /* mark non-zero */
|
||||
|
@ -1379,9 +1382,11 @@ CHECK_LENGTH:
|
|||
t = div_sub (asave, bsave, ahigh); /* subtract */
|
||||
quo++; /* incr quo digit */
|
||||
} while (t == 0); /* until borrow */
|
||||
div_add (asave, bsave, ahigh); quo--; /* restore */
|
||||
div_add (asave, bsave, ahigh); /* restore */
|
||||
quo--;
|
||||
M[qs] = (M[qs] & WM) | sum_table[quo]; /* store quo digit */
|
||||
bsave++; qs++; /* adv divd, quo */
|
||||
bsave++; /* adv divd, quo */
|
||||
qs++;
|
||||
} while ((b & ZONE) == 0); /* until B sign */
|
||||
if (reason) break; /* address err? */
|
||||
|
||||
|
@ -1583,7 +1588,8 @@ int32 a, b, c, r;
|
|||
|
||||
c = 0; /* init borrow */
|
||||
do {
|
||||
a = M[ap]; b = M[bp]; /* get operands */
|
||||
a = M[ap]; /* get operands */
|
||||
b = M[bp];
|
||||
r = bcd_to_bin[b & DIGIT] - /* a - b - borrow */
|
||||
bcd_to_bin[a & DIGIT] - c;
|
||||
c = (r < 0); /* set borrow out */
|
||||
|
@ -1592,7 +1598,7 @@ do {
|
|||
bp--;
|
||||
} while (ap >= aend);
|
||||
b = M[bp] & CHAR; /* borrow position */
|
||||
if (b != BCD_ZERO) { /* non-zero? */
|
||||
if (b && (b != BCD_ZERO)) { /* non-zero? */
|
||||
r = bcd_to_bin[b & DIGIT] - c; /* subtract borrow */
|
||||
M[bp] = sum_table[r]; /* store result */
|
||||
return 0; /* subtract worked */
|
||||
|
|
|
@ -1,579 +0,0 @@
|
|||
To: Users
|
||||
From: Bob Supnik
|
||||
Subj: IBM 1401 Simulator Usage
|
||||
Date: 01-Nov-05
|
||||
|
||||
COPYRIGHT NOTICE
|
||||
|
||||
The following copyright notice applies to both the SIMH source and binary:
|
||||
|
||||
Original code published in 1993-2005, written by Robert M Supnik
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
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 memorandum documents the IBM 1401 simulator.
|
||||
|
||||
|
||||
1. Simulator Files
|
||||
|
||||
sim/ scp.h
|
||||
sim_console.h
|
||||
sim_defs.h
|
||||
sim_fio.h
|
||||
sim_rev.h
|
||||
sim_sock.h
|
||||
sim_tape.h
|
||||
sim_timer.h
|
||||
sim_tmxr.h
|
||||
scp.c
|
||||
sim_console.c
|
||||
sim_fio.c
|
||||
sim_sock.c
|
||||
sim_tape.c
|
||||
sim_timer.c
|
||||
sim_tmxr.c
|
||||
|
||||
sim/i1401/ i1401_defs.h
|
||||
i1401_dat.h
|
||||
i1401_cpu.c
|
||||
i1401_cd.c
|
||||
i1401_iq.c
|
||||
i1401_lp.c
|
||||
i1401_dp.c
|
||||
i1401_mt.c
|
||||
i1401_sys.c
|
||||
|
||||
2. IBM 1401 Features
|
||||
|
||||
The IBM 1401 simulator is configured as follows:
|
||||
|
||||
device simulates
|
||||
name(s)
|
||||
|
||||
CPU IBM 1401 CPU with 16K of memory
|
||||
CDR,CDP IBM 1402 card reader/punch
|
||||
LPT IBM 1403 line printer
|
||||
INQ IBM 1407 inquiry terminal
|
||||
DP IBM 1311 disk pack with five drives
|
||||
MT IBM 729 7-track magnetic tape controller with six drives
|
||||
|
||||
The IBM 1401 simulator implements many unique stop conditions. On almost
|
||||
any kind of error the simulator stops:
|
||||
|
||||
unimplemented opcode
|
||||
reference to non-existent memory
|
||||
reference to non-existent device
|
||||
no word mark under opcode
|
||||
invalid A address
|
||||
invalid B address
|
||||
invalid instruction length
|
||||
invalid modifier character
|
||||
invalid branch address
|
||||
invalid magtape unit number
|
||||
invalid magtape record length
|
||||
write to locked magtape drive
|
||||
skip to unpunched carriage control tape channel
|
||||
card reader hopper empty
|
||||
address register wrap-around
|
||||
I/O check with I/O stop switch set
|
||||
invalid disk drive
|
||||
invalid disk sector address
|
||||
invalid disk sector count
|
||||
invalid disk address compare
|
||||
|
||||
The LOAD command is used to load a line printer carriage-control tape.
|
||||
The DUMP command is not implemented.
|
||||
|
||||
2.1 CPU
|
||||
|
||||
The CPU options include a number of special features and the size of main
|
||||
memory. Note that the Modify Address special feature is always included
|
||||
when memory size is greater than 4K.
|
||||
|
||||
SET CPU XSA enable advanced programming special feature
|
||||
SET CPU NOXSA disable advanced programming
|
||||
SET CPU HLE enable high/low/equal special feature
|
||||
SET CPU NOHLE disable high/low/equal
|
||||
SET CPU BBE enable branch on bit equal special feature
|
||||
SET CPU NOBBE disable branch on bit equal
|
||||
SET CPU MR enable move record special feature
|
||||
SET CPU NOMR disable move record
|
||||
SET CPU EPE enable extended print edit special feature
|
||||
SET CPU NOEPE disable extended print edit
|
||||
SET CPU MDV enable multiply/divide special feature
|
||||
SET CPU NOMDV disable multiply/divide
|
||||
SET CPU 4K set memory size = 4K
|
||||
SET CPU 8K set memory size = 8K
|
||||
SET CPU 12K set memory size = 12K
|
||||
SET CPU 16K set memory size = 16K
|
||||
|
||||
If memory size is being reduced, and the memory being truncated contains
|
||||
non-zero data, the simulator asks for confirmation. Data in the truncated
|
||||
portion of memory is lost. Initially, memory size is 16K, and all special
|
||||
features are enabled.
|
||||
|
||||
Memory is implemented as 7 bit BCD characters, as follows:
|
||||
|
||||
6 5 4 3 2 1 0
|
||||
|
||||
word B bit A bit 8 4 2 1
|
||||
mark <-- zone --> <-------- digit -------->
|
||||
|
||||
In BCD, the decimal digits 0-9 are (octal) values 012, 001, 002, 003, 004,
|
||||
005, 006, 007, 010, 011, respectively. Signs are encoded in the zone bits,
|
||||
with 00, 01, and 11 being positive, and 10 being negative.
|
||||
|
||||
CPU registers include the visible state of the processor. The 1401 has no
|
||||
interrupt system.
|
||||
|
||||
name size comments
|
||||
|
||||
IS 14 instruction storage address register (PC)
|
||||
AS 14 A storage address register
|
||||
BS 14 B storage address register
|
||||
ASERR 1 AS invalid flag
|
||||
BSERR 1 BS invalid flag
|
||||
SSA 1 sense switch A
|
||||
SSB 1 sense switch B
|
||||
SSC 1 sense switch C
|
||||
SSD 1 sense switch D
|
||||
SSE 1 sense switch E
|
||||
SSF 1 sense switch F
|
||||
SSG 1 sense switch G
|
||||
EQU 1 equal compare indicator
|
||||
UNEQ 1 unequal compare indicator
|
||||
HIGH 1 high compare indicator
|
||||
LOW 1 low compare indicator
|
||||
OVF 1 overflow indicator
|
||||
IOCHK 1 I/O check switch
|
||||
PRCHK 1 process check switch
|
||||
ISQ[0:63] 14 IS prior to last branch;
|
||||
most recent IS change first
|
||||
WRU 8 interrupt character
|
||||
|
||||
The CPU can maintain a history of the most recently executed instructions.
|
||||
This is controlled by the SET CPU HISTORY and SHOW CPU HISTORY commands:
|
||||
|
||||
SET CPU HISTORY clear history buffer
|
||||
SET CPU HISTORY=0 disable history
|
||||
SET CPU HISTORY=n enable history, length = n
|
||||
SHOW CPU HISTORY print CPU history
|
||||
SHOW CPU HISTORY=n print first n entries of CPU history
|
||||
|
||||
The maximum length for the history is 65536 entries.
|
||||
|
||||
The original character encoding used by the 1401 simulator was revised to be
|
||||
compatible with the coding used by Paul Pierce's 709X and 1401 simulators.
|
||||
The user can select between the original (old) and compatible (new) encodings,
|
||||
as follows:
|
||||
|
||||
SET CPU OLDCONVERSIONS use original character encoding
|
||||
SET CPU NEWCONVERSIONS use compatible character encoding
|
||||
|
||||
NEWCONVERSIONS is the default.
|
||||
|
||||
2.2 1402 Card Reader/Punch (CDR, CDP, STKR)
|
||||
|
||||
The IBM 1402 card/reader punch is simulated as three independent devices:
|
||||
the card reader (CDR), the card punch (CDP), and the reader and punch
|
||||
stackers (STKR). STRK units 0, 1, 2, and 4 correspond to the reader
|
||||
normal stacker, reader stacker 1, shared stacker 2/8, and punch stacker
|
||||
4, respectively.
|
||||
|
||||
Card punch and stacker units support both the business (1403 print chain
|
||||
A) and Fortran (1403 H chain) character sets:
|
||||
|
||||
SET CDP BUSINESS business character set
|
||||
SET CDP FORTRAN Fortran character set
|
||||
|
||||
The business character set is the default.
|
||||
|
||||
The card reader supports the BOOT command. BOOT CDR reads a card image
|
||||
into locations 1-80, sets a word mark under location 1, clears storage,
|
||||
and then transfers control to location 1.
|
||||
|
||||
The card reader reads data from disk files, while the punch and stackers
|
||||
write data to disk files. Cards are simulated as ASCII text lines with
|
||||
terminating newlines; column binary is not supported. For each unit,
|
||||
the POS register specifies the number of the next data item to be read or
|
||||
written. Thus, by changing POS, the user can backspace or advance these
|
||||
devices.
|
||||
|
||||
The card reader registers are:
|
||||
|
||||
name size comments
|
||||
|
||||
LAST 1 last card indicator
|
||||
ERR 1 error indicator
|
||||
S1 1 stacker 1 select flag
|
||||
S2 1 stacker 2 select flag
|
||||
POS 32 position
|
||||
TIME 24 delay window for stacker select
|
||||
BUF[0:79] 8 reader buffer
|
||||
|
||||
The card punch registers are:
|
||||
|
||||
ERR 1 error indicator
|
||||
S4 1 stacker 4 select flag
|
||||
S8 1 stacker 8 select flag
|
||||
|
||||
The stacker registers are:
|
||||
|
||||
POS0 32 position, normal reader stack
|
||||
POS1 32 position, reader stacker 1
|
||||
POS2 32 position, shared stacker 2/8
|
||||
POS4 32 position, punch stacker 4
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
device error processed as
|
||||
|
||||
reader end of file if SSA set, set LAST indicator
|
||||
on next Read, report error and stop
|
||||
|
||||
reader,punch not attached report error and stop
|
||||
OS I/O error print error message
|
||||
if IOCHK set, report error and stop
|
||||
otherwise, set ERR indicator
|
||||
|
||||
stacker not attached ignored
|
||||
OS I/O error print error message
|
||||
if IOCHK set, report error and stop
|
||||
|
||||
2.3 1403 Line Printer (LPT)
|
||||
|
||||
The IBM 1403 line printer (LPT) writes its data, converted to ASCII, to
|
||||
a disk file. The line printer implements both 48- and 64-character print
|
||||
chains:
|
||||
|
||||
SET LPT 64 64-character print chain
|
||||
SET LPT 48 48-character print chain
|
||||
|
||||
The line printer also implements both the business (1403 print chain
|
||||
A) and Fortran (1403 H chain) character sets:
|
||||
|
||||
SET LPT BUSINESS business print character set
|
||||
SET LPT FORTRAN Fortran character set
|
||||
|
||||
The default is the 64 character print chain with the business set.
|
||||
|
||||
In addition, the line printer can be programmed with a carriage control
|
||||
tape. The LOAD command loads a new carriage control tape:
|
||||
|
||||
LOAD <file> load carriage control tape file
|
||||
|
||||
The format of a carriage control tape consists of multiple lines. Each
|
||||
line contains an optional repeat count, enclosed in parentheses, optionally
|
||||
followed by a series of column numbers separated by commas. Column numbers
|
||||
must be between 1 and 12; a column number of zero denotes top of form. The
|
||||
following are all legal carriage control specifications:
|
||||
|
||||
<blank line> no punch
|
||||
(5) 5 lines with no punches
|
||||
1,5,7,8 columns 1, 5, 7, 8 punched
|
||||
(10)2 10 lines with column 2 punched
|
||||
1,0 column 1 punched; top of form
|
||||
|
||||
The default form is 66 lines long, with column 1 and the top of form mark
|
||||
on line 1, and the rest blank.
|
||||
|
||||
The line printer registers are:
|
||||
|
||||
name size comments
|
||||
|
||||
LINES 8 number of newlines after next print
|
||||
LFLAG 1 carriage control flag (1 = skip, 0 = space)
|
||||
CCTP 8 carriage control tape pointer
|
||||
CCTL 8 carriage control tape length (read only)
|
||||
ERR 1 error indicator
|
||||
POS 32 position
|
||||
CCT[0:131] 32 carriage control tape array
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error processed as
|
||||
|
||||
not attached report error and stop
|
||||
|
||||
OS I/O error print error message
|
||||
if IOCHK set, report error and stop
|
||||
otherwise, set ERR indicator
|
||||
|
||||
2.4 1407 Inquiry Terminal (INQ)
|
||||
|
||||
The IBM 1407 inquiry terminal (INQ) is a half-duplex console. It polls
|
||||
the console keyboard periodically for inquiry requests.
|
||||
|
||||
The inquiry terminal supports both the business (1403 print chain A)
|
||||
and Fortran (1403 H chain) character sets for output:
|
||||
|
||||
SET INQ BUSINESS business character set
|
||||
SET INQ FORTRAN Fortran character set
|
||||
|
||||
The business character set is the default.
|
||||
|
||||
The inquiry terminal registers are:
|
||||
|
||||
name size comments
|
||||
|
||||
INQC 7 inquiry request character (initially ESC)
|
||||
INR 1 inquiry request indicator
|
||||
INC 1 inquiry cleared indicator
|
||||
TIME 24 polling interval
|
||||
|
||||
When the 1401 CPU requests input from the keyboard, the message [Enter]
|
||||
is printed out, followed by a new line. The CPU hangs waiting for input
|
||||
until either the return/enter key is pressed, or the inquiry request
|
||||
character is typed in. The latter cancels the type-in and sets INC.
|
||||
|
||||
The inquiry terminal has no errors.
|
||||
|
||||
2.5 1311 Disk Pack (DP)
|
||||
|
||||
The disk pack controller supports 5 drives, numbered 0 through 4. Disk
|
||||
pack options include the ability to enable address writing (formatting).
|
||||
|
||||
SET DPn ADDROFF set unit n address enable off
|
||||
SET DPn ADDRON set unit n address enable on
|
||||
|
||||
Units can also be set ENABLED or DISABLED.
|
||||
|
||||
Unlike most simulated disks, the 1311 includes explicit representation
|
||||
for sector addresses. This is to support non-standard formats, such as
|
||||
the inclusion of the drive number in the sector address. As a result,
|
||||
1311 sectors are 106 characters long: 6 address characters and 100
|
||||
data characters. If the 1311 has not been formatted, the addresses
|
||||
are blanks and are synthesized, if needed, based on the sector number.
|
||||
|
||||
The 1311 also supports two modes of operation: move mode and load mode.
|
||||
In move mode, word marks are ignored on writes and left untouched on reads,
|
||||
and sectors hold 100 characters. In load mode, word marks are included
|
||||
on writes and stored on reads, and sectors hold 90 characters. No attempt
|
||||
is made to deal with sectors written in load mode and read in move mode,
|
||||
or vice versa; on a real 1401, this causes a fatal parity error.
|
||||
|
||||
The disk pack controller implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
ACC 1 access error indicator
|
||||
PWC 1 parity or write check error indicator
|
||||
WLR 1 wrong length record error indicator
|
||||
UNA 1 unequal address compare error indicator
|
||||
DSK 1 any disk error indicator
|
||||
BSY 1 disk access busy indicator
|
||||
LASTF 3 most recent function
|
||||
TIME 24 seek time
|
||||
|
||||
The 1311 has a primative overlapped seek capability. If TIME is set
|
||||
non-zero, the 1311 will report itself busy for the specified amount
|
||||
of time following a seek. This allows programs to utilize the seek
|
||||
time for processing.
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error processed as
|
||||
|
||||
not attached set DSK indicator
|
||||
if IOCHK set, report error and stop
|
||||
|
||||
1311 data files are buffered in memory; therefore, end of file and OS
|
||||
I/O errors cannot occur.
|
||||
|
||||
2.6 729 Magnetic Tape (MT)
|
||||
|
||||
The magnetic tape controller supports six drives, numbered 1 through 6.
|
||||
Magnetic tape options include the ability to make units write enabled or
|
||||
or write locked.
|
||||
|
||||
SET MTn LOCKED set unit n write locked
|
||||
SET MTn WRITEENABLED set unit n write enabled
|
||||
|
||||
Units can also be set ENABLED or DISABLED. The magnetic tape simulator
|
||||
supports the BOOT command. BOOT MT reads the first record off tape,
|
||||
starting at location 1, and then branches to it.
|
||||
|
||||
The magnetic tape controller implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
END 1 end of file indicator
|
||||
ERR 1 error indicator
|
||||
PAR 1 parity error indicator
|
||||
POS1..6 32 position, drives 1..6
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error processed as
|
||||
|
||||
not attached report error and stop
|
||||
|
||||
end of file set error indicator
|
||||
|
||||
OS I/O error print error message
|
||||
set error indicator
|
||||
if IOCHK set, report error and stop
|
||||
|
||||
2.7 Symbolic Display and Input
|
||||
|
||||
The IBM 1401 simulator implements symbolic display and input. Display is
|
||||
controlled by command line switches:
|
||||
|
||||
-c display as single character
|
||||
(BCD for CPU and MT, ASCII for others)
|
||||
-s display as wordmark terminated BCD string
|
||||
(CPU only)
|
||||
-m display instruction mnemonics
|
||||
(CPU only)
|
||||
-d display 50 characters per line, with word
|
||||
marks denoted by "1" on the line below
|
||||
|
||||
In a CPU character display, word marks are denoted by `.
|
||||
|
||||
Input parsing is controlled by the first character typed in or by command
|
||||
line switches:
|
||||
|
||||
' or " or -c or -s characters (BCD for CPU and MT, ASCII
|
||||
for others)
|
||||
alphabetic instruction mnemonic
|
||||
numeric octal number
|
||||
|
||||
Instruction input is free format, with spaces separating fields. There
|
||||
are six instruction formats: 1, 2, 4, 5, 7, and 8 characters:
|
||||
|
||||
1 character opcode
|
||||
2 character opcode 'modifier
|
||||
4 character opcode address
|
||||
5 character opcode address 'modifier
|
||||
7 character opcode address address
|
||||
8 character opcode address address 'modifier
|
||||
|
||||
Addresses are always decimal, except for special I/O addresses in the A
|
||||
field, which may be specified as %xy, where x denotes the device and y
|
||||
the unit number.
|
||||
|
||||
For the CPU, string input may encompass multiple characters. A word mark
|
||||
is denoted by ~ and must precede the character to be marked. All other
|
||||
devices can only accept single character input, without word marks.
|
||||
|
||||
2.7 Character Sets
|
||||
|
||||
The IBM 1401 uses a 6b character code called BCD (binary coded decimal).
|
||||
Some of the characters have no equivalent in ASCII and require different
|
||||
representations:
|
||||
|
||||
BCD ASCII IBM 1401 print
|
||||
code representation character chains
|
||||
|
||||
00 space
|
||||
01 1
|
||||
02 2
|
||||
03 3
|
||||
04 4
|
||||
05 5
|
||||
06 6
|
||||
07 7
|
||||
10 8
|
||||
11 9
|
||||
12 0
|
||||
13 # or = = in H chain
|
||||
14 @ or ' ' in H chain
|
||||
15 : blank in A, H chains
|
||||
16 > blank in A, H chains
|
||||
17 { tape mark blank in A, H chains
|
||||
20 ^ alternate blank blank in A, H chains
|
||||
21 /
|
||||
22 S
|
||||
23 T
|
||||
24 U
|
||||
25 V
|
||||
26 W
|
||||
27 X
|
||||
30 Y
|
||||
31 Z
|
||||
32 | record mark
|
||||
33 ,
|
||||
34 % or ( ( in H chain
|
||||
35 ~ word mark blank in A, H chains
|
||||
36 \ blank in A, H chains
|
||||
37 " blank in A, H chains
|
||||
40 -
|
||||
41 J
|
||||
42 K
|
||||
43 L
|
||||
44 M
|
||||
45 N
|
||||
46 O
|
||||
47 P
|
||||
50 Q
|
||||
51 R
|
||||
52 !
|
||||
53 $
|
||||
54 *
|
||||
55 ] blank in A, H chains
|
||||
56 ; blank in A, H chains
|
||||
57 _ delta blank in A, H chains
|
||||
60 &
|
||||
61 A
|
||||
62 B
|
||||
63 C
|
||||
64 D
|
||||
65 E
|
||||
66 F
|
||||
67 G
|
||||
70 H
|
||||
71 I
|
||||
72 ?
|
||||
73 .
|
||||
74 ) lozenge
|
||||
75 [ blank in A, H chains
|
||||
76 < blank in A, H chains
|
||||
77 } group mark blank in A, H chains
|
||||
|
||||
2.8 Old Conversions
|
||||
|
||||
Starting with V3.5-1, the 1401 simulator was changed to use the same character
|
||||
set as the 7094 (and other 7094 simulators). This involved the following changes
|
||||
|
||||
code V3.5-0 or earlier V3.5-1 or later
|
||||
|
||||
13 # # or = on input
|
||||
14 @ @ or ' on input
|
||||
17 ( {
|
||||
32 ' |
|
||||
34 % % or ( on input
|
||||
35 = ~
|
||||
37 + "
|
||||
60 & & or + on input
|
||||
77 " }
|
||||
|
||||
In addition, the word mark indicator was changed from ~ to `.
|
||||
|
||||
The 1401 simulator can be set to operate with either set of conventions:
|
||||
|
||||
SET CPU OLDCONVERSIONS
|
||||
SET CPU NEWCONVERSIONS
|
||||
|
||||
The default is NEWCONVERSIONS.
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/* i1401_mt.c: IBM 1401 magnetic tape simulator
|
||||
|
||||
Copyright (c) 1993-2005, Robert M. Supnik
|
||||
Copyright (c) 1993-2006, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
mt 7-track magtape
|
||||
|
||||
16-Feb-06 RMS Added tape capacity checking
|
||||
15-Sep-05 RMS Yet another fix to load read group mark plus word mark
|
||||
Added debug printouts (from Van Snyder)
|
||||
26-Aug-05 RMS Revised to use API for write lock check
|
||||
|
@ -128,6 +129,8 @@ MTAB mt_mod[] = {
|
|||
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "CAPACITY", "CAPACITY",
|
||||
&sim_tape_set_capac, &sim_tape_show_capac, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
@ -224,6 +227,7 @@ t_stat mt_io (int32 unit, int32 flag, int32 mod)
|
|||
int32 t, wm_seen;
|
||||
t_mtrlnt i, tbc;
|
||||
t_stat st;
|
||||
t_bool passed_eot;
|
||||
UNIT *uptr;
|
||||
|
||||
if ((uptr = get_unit (unit)) == NULL) return STOP_INVMTU; /* valid unit? */
|
||||
|
@ -300,7 +304,10 @@ switch (mod) {
|
|||
}
|
||||
}
|
||||
if (DEBUG_PRS (mt_dev)) fprintf (sim_deb, " to %d\n", BS - 1);
|
||||
passed_eot = sim_tape_eot (uptr); /* passed EOT? */
|
||||
st = sim_tape_wrrecf (uptr, dbuf, tbc); /* write record */
|
||||
if (!passed_eot && sim_tape_eot (uptr)) /* just passed EOT? */
|
||||
ind[IN_END] = 1;
|
||||
if (ADDR_ERR (BS)) { /* check final BS */
|
||||
BS = BA | (BS % MAXMEMSIZE);
|
||||
return STOP_WRAP;
|
||||
|
|
|
@ -1,533 +0,0 @@
|
|||
To: Users
|
||||
From: Bob Supnik
|
||||
Subj: IBM 1620 Simulator Usage
|
||||
Date: 15-Sep-2005
|
||||
|
||||
COPYRIGHT NOTICE
|
||||
|
||||
The following copyright notice applies to both the SIMH source and binary:
|
||||
|
||||
Original code published in 1993-2005, written by Robert M Supnik
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
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 memorandum documents the IBM 1620 simulator. This simulator is based on
|
||||
Geoff Kuenning's 1620 simulator, which is used by permission.
|
||||
|
||||
1. Simulator Files
|
||||
|
||||
sim/ scp.h
|
||||
sim_console.h
|
||||
sim_defs.h
|
||||
sim_fio.h
|
||||
sim_rev.h
|
||||
sim_sock.h
|
||||
sim_timer.h
|
||||
sim_tmxr.h
|
||||
scp.c
|
||||
sim_console.c
|
||||
sim_fio.c
|
||||
sim_sock.c
|
||||
sim_timer.c
|
||||
sim_tmxr.c
|
||||
|
||||
sim/i1620/ i1620_defs.h
|
||||
i1620_cpu.c
|
||||
i1620_fp.c
|
||||
i1620_tty.c
|
||||
i1620_pt.c
|
||||
i1620_cd.c
|
||||
i1620_lp.c
|
||||
i1620_dp.c
|
||||
i1620_sys.c
|
||||
|
||||
2. IBM 1620 Features
|
||||
|
||||
The IBM 1620 simulator is configured as follows:
|
||||
|
||||
device simulates
|
||||
name(s)
|
||||
|
||||
CPU IBM 1620 Model 1 or Model 2 CPU with 20K to 60K of memory
|
||||
Model 1 options: indirect addressing, automatic divide,
|
||||
edit instructions, floating point
|
||||
Model 2 options: indexing, binary capability, floating point
|
||||
TTY IBM console terminal
|
||||
PTR IBM 1621 paper tape reader
|
||||
PTP IBM 1624 paper tape punch
|
||||
CDR,CDP IBM 1622 card reader/punch
|
||||
LPT IBM 1443 line printer
|
||||
DP IBM 1311 disk pack with four drives
|
||||
|
||||
The IBM 1620 simulator implements many unique stop conditions. On almost
|
||||
any kind of error the simulator stops:
|
||||
|
||||
unimplemented opcode
|
||||
reference to non-existent device
|
||||
invalid digit
|
||||
invalid alphameric character
|
||||
invalid P address digit
|
||||
invalid Q address digit
|
||||
indirect address limit exceeded
|
||||
invalid odd address
|
||||
invalid even address
|
||||
invalid function
|
||||
invalid indicator
|
||||
invalid return address register
|
||||
skip to unpunched carriage control tape channel
|
||||
card reader hopper empty
|
||||
overflow with arithmetic stop switch set
|
||||
I/O error with I/O stop switch set
|
||||
invalid disk drive
|
||||
invalid disk sector address
|
||||
invalid disk sector count
|
||||
invalid disk buffer address
|
||||
disk address compare error
|
||||
disk cylinder overflow error
|
||||
disk write check error
|
||||
field exceeds memory
|
||||
record exceeds memory
|
||||
floating point mantissa exceeds maximum length
|
||||
floating point mantissas not the same length
|
||||
floating point exponent check with arithmetic stop switch set
|
||||
floating point exponent missing high flag
|
||||
|
||||
The LOAD command is used to load a line printer carriage-control tape.
|
||||
The DUMP command is not implemented.
|
||||
|
||||
2.1 CPU
|
||||
|
||||
The CPU options include the CPU model (Model 1 or Model 2), a number of
|
||||
special features, and the size of main memory.
|
||||
|
||||
SET CPU IA enable indirect addressing
|
||||
SET CPU NOIA disable indirect addressing
|
||||
SET CPU EDT enable extra editing instructions
|
||||
SET CPU NOEDT disable extra editing instructions
|
||||
SET CPU DIV enable divide instructions
|
||||
SET CPU NODIV disable divide instructions
|
||||
SET CPU IDX enable indexing
|
||||
SET CPU NOIDX disable indexing
|
||||
SET CPU BIN enable binary instructions
|
||||
SET CPU NOBIN disable binary instructions
|
||||
SET CPU FP enable floating point instructions
|
||||
SET CPU NOFP disable floating point instructions
|
||||
SET CPU MOD1 set Model 1
|
||||
SET CPU MOD2 set Model 2
|
||||
SET CPU 20K set memory size = 20K
|
||||
SET CPU 40K set memory size = 40K
|
||||
SET CPU 60K set memory size = 60K
|
||||
|
||||
Model 1 options include IA, EDT, DIV, and FP; the first three are on by
|
||||
default. Model 2 options include IDX, BIN, and FP; IA, EDT, and DIV are
|
||||
standard on the Model 2.
|
||||
|
||||
If memory size is being reduced, and the memory being truncated contains
|
||||
non-zero data, the simulator asks for confirmation. Data in the truncated
|
||||
portion of memory is lost. Initially, the CPU is a Model 1, memory size is
|
||||
20K, and indirect addressing, editing instructions, and divide are enabled.
|
||||
|
||||
Memory is implemented as 5 bit BCD digits, as follows:
|
||||
|
||||
4 3 2 1 0
|
||||
|
||||
flag 8 4 2 1
|
||||
<-------- digit -------->
|
||||
|
||||
In BCD, the decimal digits 0-9 are (hex) values 0x0, 0x1, 0x2, 0x3, 0x4,
|
||||
0x5, 0x6, 0x7, 0x8, 0x9, respectively. 0xA is record mark, 0xC non-
|
||||
punching blank, and 0xF group mark, respectively.
|
||||
|
||||
CPU registers include the visible state of the processor. The 1620 has no
|
||||
interrupt system.
|
||||
|
||||
name size comments
|
||||
|
||||
IR1 16 instruction storage address register (PC)
|
||||
IR2 16 return register
|
||||
PR1 16 processor register 1
|
||||
PAR 16 P address register (OR2)
|
||||
QAR 16 Q address register (OR1)
|
||||
SS1 1 sense switch 1
|
||||
SS2 1 sense switch 2
|
||||
SS3 1 sense switch 3
|
||||
SS4 1 sense switch 4
|
||||
HP 1 high/positive indicator
|
||||
EZ 1 equal/zero indicator
|
||||
ARCHK 1 arithmetic check (overflow) indicator
|
||||
EXPCHK 1 exponent check indicator
|
||||
RDCHK 1 read check indicator
|
||||
WRCHK 1 write check indicator
|
||||
ARSTOP 1 arithmetic check stop switch
|
||||
IOSTOP 1 I/O check stop switch
|
||||
IND[0:99] 1 indicator array
|
||||
IAE 1 indirect address enable (Model 2 only)
|
||||
IDXE 1 indexing enable (Model 2 only)
|
||||
IDXB 1 indexing band select (Model 2 only)
|
||||
IR1Q[0:63] 16 IR1 prior to last branch;
|
||||
most recent IR1 change first
|
||||
WRU 8 interrupt character
|
||||
|
||||
The CPU can maintain a history of the most recently executed instructions.
|
||||
This is controlled by the SET CPU HISTORY and SHOW CPU HISTORY commands:
|
||||
|
||||
SET CPU HISTORY clear history buffer
|
||||
SET CPU HISTORY=0 disable history
|
||||
SET CPU HISTORY=n enable history, length = n
|
||||
SHOW CPU HISTORY print CPU history
|
||||
SHOW CPU HISTORY=n print first n entries of CPU history
|
||||
|
||||
The maximum length for the history is 65536 entries.
|
||||
|
||||
2.2 Console Typewriter (TTY)
|
||||
|
||||
The console typewriter (TTY) is a half-duplex console. The typewriter
|
||||
registers are:
|
||||
|
||||
name size comments
|
||||
|
||||
COL 7 current column
|
||||
TIME 24 polling interval
|
||||
|
||||
When the 1620 CPU requests input from the keyboard, a greater than sign
|
||||
(>) is printed. The CPU hangs waiting for input until the return/enter
|
||||
key is pressed. The typewriter has no errors.
|
||||
|
||||
2.3 1621 Paper Tape Reader (PTR)
|
||||
|
||||
The paper tape reader (PTR) reads data from a disk file. The POS register
|
||||
specifies the number of the next data item to be read. Thus, by changing
|
||||
POS, the user can backspace or advance the reader.
|
||||
|
||||
The paper tape reader supports the BOOT command. BOOT PTR starts the
|
||||
standard paper tape boot sequence at location 0.
|
||||
|
||||
The paper tape reader implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
POS 32 position in the input file
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error IOCHK processed as
|
||||
|
||||
not attached x set RDCHK indicator, report error, stop
|
||||
|
||||
end of file x set RDCHK indicator, report error, stop
|
||||
|
||||
OS I/O error x set RDCHK indicator, report error, stop
|
||||
|
||||
parity error 1 set RDCHK indicator, report error, stop
|
||||
0 set RDCHK indicator
|
||||
|
||||
2.4 1624 Paper Tape Punch (PTP)
|
||||
|
||||
The paper tape punch (PTP) writes data to a disk file. The POS register
|
||||
specifies the number of the next data item to be written. Thus, by
|
||||
changing POS, the user can backspace or advance the punch.
|
||||
|
||||
The paper tape punch implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
POS 32 position in the output file
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error IOCHK processed as
|
||||
|
||||
not attached x set WRCHK indicator, report error, stop
|
||||
|
||||
OS I/O error x set WRCHK indicator, report error, stop
|
||||
|
||||
invalid char 1 set WRCHK indicator, report error, stop
|
||||
0 set WRCHK indicator
|
||||
|
||||
2.5 1622 Card Reader/Punch (CDR, CDP)
|
||||
|
||||
The IBM 1402 card/reader punch is simulated as two independent devices:
|
||||
the card reader (CDR) and the card punch (CDP).
|
||||
|
||||
The card reader supports the BOOT command. BOOT CDR starts the standard
|
||||
card boot sequence at location 0.
|
||||
|
||||
The card reader reads data from a disk file, while the punch writes data
|
||||
to a disk file. Cards are simulated as ASCII text lines with terminating
|
||||
newlines. For each unit, the POS register specifies the number of the
|
||||
next data item to be read or written. Thus, by changing POS, the user
|
||||
can backspace or advance these devices.
|
||||
|
||||
The card reader registers are:
|
||||
|
||||
name size comments
|
||||
|
||||
LAST 1 last card indicator
|
||||
POS 32 position
|
||||
|
||||
The card punch registes are:
|
||||
|
||||
name size comments
|
||||
|
||||
POS 32 position
|
||||
|
||||
Card reader error handling is as follows:
|
||||
|
||||
error IOCHK processed as
|
||||
|
||||
end of file x set RDCHK indicator, report error, stop
|
||||
|
||||
not attached x set RDCHK indicator, report error, stop
|
||||
|
||||
OS I/O error x set RDCHK indicator, report error, stop
|
||||
|
||||
invalid char 1 set RDCHK indicator, report error, stop
|
||||
0 set RDCHK indicator
|
||||
|
||||
Card punch error handling is as follows:
|
||||
|
||||
error IOCHK processed as
|
||||
|
||||
not attached x set WRCHK indicator, report error, stop
|
||||
|
||||
OS I/O error x set WRCHK indicator, report error, stop
|
||||
|
||||
invalid char 1 set WRCHK indicator, report error, stop
|
||||
0 set WRCHK indicator
|
||||
|
||||
2.6 1443 Line Printer (LPT)
|
||||
|
||||
The IBM 1443 line printer (LPT) writes its data, converted to ASCII, to
|
||||
a disk file. The line printer can be programmed with a carriage control
|
||||
tape. The LOAD command loads a new carriage control tape:
|
||||
|
||||
LOAD <file> load carriage control tape file
|
||||
|
||||
The format of a carriage control tape consists of multiple lines. Each
|
||||
line contains an optional repeat count, enclosed in parentheses, optionally
|
||||
followed by a series of column numbers separated by commas. Column numbers
|
||||
must be between 1 and 12; a column number of zero denotes top of form. The
|
||||
following are all legal carriage control specifications:
|
||||
|
||||
<blank line> no punch
|
||||
(5) 5 lines with no punches
|
||||
1,5,7,8 columns 1, 5, 7, 8 punched
|
||||
(10)2 10 lines with column 2 punched
|
||||
1,0 column 1 punched; top of form
|
||||
|
||||
The default form is 66 lines long, with column 1 and the top of form mark
|
||||
on line 1, and the rest blank.
|
||||
|
||||
The line printer registers are:
|
||||
|
||||
name size comments
|
||||
|
||||
LBUF[0:119] 7 line buffer
|
||||
BPTR 7 buffer pointer
|
||||
PCTL 8 saved print control directive
|
||||
PRCHK 1 print check indicator
|
||||
PRCH9 1 channel 9 indicator
|
||||
PRCH12 1 channel 12 indicator
|
||||
POS 32 position
|
||||
CCT[0:131] 32 carriage control tape array
|
||||
CCTP 8 carriage control tape pointer
|
||||
CCTL 8 carriage control tape length (read only)
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error IOCHK processed as
|
||||
|
||||
not attached x set PRCHK, WRCHK indicators, report error, stop
|
||||
|
||||
OS I/O error x set PRCHK, WRCHK indicators, report error, stop
|
||||
|
||||
invalid char 1 set PRCHK, WRCHK indicator, report error, stop
|
||||
0 set PRCHK, WRCHK indicator
|
||||
|
||||
2.7 1311 Disk Pack (DP)
|
||||
|
||||
The disk pack controller supports 4 drives, numbered 0 through 3. Disk
|
||||
pack options include the ability to enable address writing (formatting).
|
||||
|
||||
SET DPn ADDROFF set unit n address enable off
|
||||
SET DPn ADDRON set unit n address enable on
|
||||
|
||||
Units can also be set ENABLED or DISABLED.
|
||||
|
||||
Unlike most simulated disks, the 1311 includes explicit representation
|
||||
for sector addresses. This is to support non-standard formats, such as
|
||||
the inclusion of the drive number in the sector address. As a result,
|
||||
1311 sectors are 105 digits long: 5 address digits and 100 data digits.
|
||||
If the 1311 has not been formatted, the addresses are zeroes and are
|
||||
synthesized, if needed, based on the sector number.
|
||||
|
||||
The disk pack controller implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
ADCHK 1 address check (compare error) indicator
|
||||
WLRC 1 wrong length record check indicator
|
||||
CYLO 1 cylinder overflow check indicator
|
||||
ERR 1 disk error indicator
|
||||
DPSTOP 1 disk check stop
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error DPCHK processed as
|
||||
|
||||
not attached x set ERR indicator, report error, stop
|
||||
|
||||
1311 data files are buffered in memory; therefore, end of file and OS
|
||||
I/O errors cannot occur.
|
||||
|
||||
2.8 Symbolic Display and Input
|
||||
|
||||
The IBM 1620 simulator implements symbolic display and input. Display is
|
||||
controlled by command line switches:
|
||||
|
||||
-c display as single character (alphameric
|
||||
for CPU and DP, ASCII for others)
|
||||
-s display as flag terminated alphameric string
|
||||
(CPU and DP only)
|
||||
-m display instruction mnemonics
|
||||
(CPU and DP only)
|
||||
-d display 50 characters per line, with word
|
||||
marks denoted by "_" on the line above
|
||||
|
||||
Input parsing is controlled by the first character typed in or by command
|
||||
line switches:
|
||||
|
||||
' or -c character (alphameric for CPU and DP, ASCII
|
||||
for others)
|
||||
" or -s alphameric string (CPU and DP only)
|
||||
alphabetic instruction mnemonic (CPU and DP only)
|
||||
numeric octal number
|
||||
|
||||
Instruction input is free format and consists of an opcode and up to
|
||||
three operands:
|
||||
|
||||
op {+/-}ppppp{(idx)},{+-}qqqqq{(idx)},flags
|
||||
|
||||
The p address and, if present, the q address, are always decimal. A
|
||||
plus sign is ignored; a minus sign denotes indirect addressing (or a
|
||||
negative immediate operand). If indexing is enabled, addresses may
|
||||
be indexed; index registers are decimal numbers between 1 and 7. The
|
||||
flags field is used to set extra flags on the instruction. It consists
|
||||
of digit numbers in ascending order, with no separators. For example,
|
||||
|
||||
AM -12345(5),67890,110
|
||||
|
||||
translates into
|
||||
_ _ ___ _
|
||||
111234567890
|
||||
|
||||
The flag over digits 3 and 5 specify the P index register; the flag
|
||||
over digit 6 specifies the P indirect address; the flag over digit 7
|
||||
marks the end of the immediate Q operand; and the flags over digits
|
||||
1 and 10 are specified by the third field.
|
||||
|
||||
2.9 Character Sets
|
||||
|
||||
The IBM 1620 uses single digits to represent numbers, and pairs of
|
||||
digits to represent characters (alphameric coding). Only a small
|
||||
number of the 256 possible alphameric codings have legitimate values.
|
||||
Further, the translation between alphameric and devices varied from
|
||||
device to device. The simulator implements a code called 1620 ASCII,
|
||||
which allows all 64 possible card codes to be represented by upper
|
||||
case ASCII characters. In addition, lower case alphabetic characters
|
||||
are accepted on input as equivalent to upper case.
|
||||
|
||||
Card code PT code RA RN LPT WA ASCII representation
|
||||
|
||||
<blank> C 0 0 blank blank
|
||||
1 1 71 1 1 1
|
||||
2 2 72 2 2 2
|
||||
3 C21 73 3 3 3
|
||||
4 4 74 4 4 4
|
||||
5 C41 75 5 5 5
|
||||
6 C42 76 6 6 6
|
||||
7 421 77 7 7 7
|
||||
8 8 78 8 8 8
|
||||
9 C81 79 9 9 9
|
||||
2 + 8 C82 ? 0A A na ^
|
||||
3 + 8 821 33 B = = (or #)
|
||||
4 + 8 C84 34 C @ @ (or ')
|
||||
5 + 8 841 70 0 0 :
|
||||
6 + 8 842 ? 0E E na >
|
||||
7 + 8 C8421 ? 0F F na {
|
||||
12 XOC 10 0 + + (or &)
|
||||
12 + 1 XO1 41 1 A A
|
||||
12 + 2 XO2 42 2 B B
|
||||
12 + 3 XOC21 43 3 C C
|
||||
12 + 4 XO4 44 4 D D
|
||||
12 + 5 XOC41 45 5 E E
|
||||
12 + 6 XOC42 46 6 F F
|
||||
12 + 7 XO421 47 7 G G
|
||||
12 + 8 XO8 48 8 H H
|
||||
12 + 9 XOC81 49 9 I I
|
||||
12 + 2 + 8 XOC82 ? 5A ? F+A na ?
|
||||
12 + 3 + 8 XO821 3 ? F+B . .
|
||||
12 + 4 + 8 XOC84 4 C ) )
|
||||
12 + 5 + 8 XO841 40 0 na [
|
||||
12 + 6 + 8 XO842 ? 5E ? F+E na <
|
||||
12 + 7 + 8 XOC8421 5F F+F na }
|
||||
11 X 20 F+0 - -
|
||||
11 + 1 XC1 51 F+1 J J
|
||||
11 + 2 XC2 52 F+2 K K
|
||||
11 + 3 X21 53 F+3 L L
|
||||
11 + 4 XC4 54 F+4 M M
|
||||
11 + 5 X41 55 F+5 N N
|
||||
11 + 6 X42 56 F+6 O O
|
||||
11 + 7 XC421 57 F+7 P P
|
||||
11 + 8 XC8 58 F+8 Q Q
|
||||
11 + 9 X81 59 F+9 R R
|
||||
11 + 2 + 8 X82 5A F+A na !
|
||||
11 + 3 + 8 XC821 13 F+B $ $
|
||||
11 + 4 + 8 X84 14 F+C * *
|
||||
11 + 5 + 8 XC841 50 F+0 - ]
|
||||
11 + 6 + 8 XC842 ? 5E ? F+E na ;
|
||||
11 + 7 + 8 X8421 5F F+F na _
|
||||
0 O 70 0 0 0
|
||||
0 + 1 OC1 21 1 / /
|
||||
0 + 2 OC2 62 2 S S
|
||||
0 + 3 O21 63 3 T T
|
||||
0 + 4 OC4 64 4 U U
|
||||
0 + 5 O41 65 5 V V
|
||||
0 + 6 O42 66 6 W W
|
||||
0 + 7 OC421 67 7 X X
|
||||
0 + 8 OC8 68 8 Y Y
|
||||
0 + 9 O81 69 9 Z Z
|
||||
0 + 2 + 8 O82 0A A na |
|
||||
0 + 3 + 8 OC821 23 B , ,
|
||||
0 + 4 + 8 O84 24 C ( ( (or %)
|
||||
0 + 5 + 8 OC841 60 0 na ~
|
||||
0 + 6 + 8 OC842 0E E na \
|
||||
0 + 7 + 8 O8421 0F F na "
|
||||
|
||||
2 ?
|
||||
12 !
|
||||
22 |
|
||||
32 0
|
||||
35 :
|
||||
36 blank
|
||||
11 + 0 50 - `
|
72
I7094/i7094_bugs.txt
Normal file
72
I7094/i7094_bugs.txt
Normal file
|
@ -0,0 +1,72 @@
|
|||
Bugs found
|
||||
|
||||
1. CPU: MPY tested sign of AC instead of sign of MQ.
|
||||
2. CPU: VLM, VDP, VDH need alternate opcode decode points for large counts.
|
||||
3. CPU: STL not in decode table.
|
||||
4. CPU: Partial stores lacked initial read in decode table.
|
||||
5. CPU: PXD, PCD needed (t_uint64) cast.
|
||||
6. CPU: SXD, SCD needed (t_uint64) cast.
|
||||
7. CPU: SBM at wrong case offset.
|
||||
8. CPU: All transfers used IR<21:35> instead of calculated effective address.
|
||||
9. CPU: HPR, TRA need alternate negative opcodes.
|
||||
10. CPU: STT missing final write to memory.
|
||||
11. IO: Channel output process model incorrect, extensive revision required.
|
||||
12. IO: Channel connect test should not test channel state, only connection.
|
||||
13. IO: Channel opcode with nostore doesn't increment channel address.
|
||||
14. CDR: Card reader missing activate at end of state 2.
|
||||
15. SYS: Zero operand instructions printed with trailing space.
|
||||
16. CPU: Convert class count bit field start definition incorrect.
|
||||
17. CPU: CAQ cut and paste error from CVR.
|
||||
18. CPU: Shift count is 8b wide, not 9b.
|
||||
19. SYS: Mnemonic is LDQ not LMQ.
|
||||
20. SYS: RQL opcode incorrect in symbolic decode table.
|
||||
21. CPU: Multi-tag mode stores OR'd value of tags on any index read except
|
||||
normal effective address.
|
||||
22. CPU: Floating point trap does not write location 0 if trap suppressed.
|
||||
23. SYS: TRA instructions should have symbolic class MXN not MXR.
|
||||
24. CPU: Floating add instructions test for zero result only if normalization enabled.
|
||||
25. CPU: Floating add with unlike signs and equal magnitudes, result sign is sign
|
||||
of SR rather than sign of AC.
|
||||
26. CPU: Floating multiply does not test spill prior to normalization step.
|
||||
27. CPU: Channel activity proceeds under HALT.
|
||||
28. MT: Any read error should stop the channel and the tape controller.
|
||||
29. MT: EOR write flag cleared before testing.
|
||||
39. IO: EOR write flag set after data sent to device.
|
||||
40. IO: EOR write flag incorrect set on IOCP, IOCT, IOSP, IOST.
|
||||
41. MT: End of file errors not masked on backspace operations.
|
||||
42. CPU: LCHx, RCHx miscoded in decode table.
|
||||
43. IO: Only 7607 error completions (IOxT without new command) set trap.
|
||||
44. CPU: 7067 channel trap flags misdefined with extraneous decrement shift.
|
||||
45. CPU: pcq array misdeclared as uint32 instead of uint16.
|
||||
46. IO: SDC and SCD tested chan_flags instead of chan_dev.flags.
|
||||
47. SYS: 7907 opcodes defined incorrectly.
|
||||
48. SYS: TCH not decoding bit<19>.
|
||||
49. IO: CTL not clearing EOR after device end.
|
||||
50. DSK: Format code not incrementing track in writing all tracks in cylinder.
|
||||
51. DSK: THA mode overwrites record structure of first record.
|
||||
52. DSK: Write doesn't set channel request for initial word.
|
||||
53. DSK: Saved record number was command digits 3..8 instead of 5..10.
|
||||
54. CLK: Compute 60th's from location 5, so Chrono clock is in sync with interval clock.
|
||||
55. CPU: Enable Chronolog clock if CTSS.
|
||||
56. CPU: Read/write protection error not setting protection trap.
|
||||
57. CPU: SCHx not setting protection trap in user mode.
|
||||
58: CPU: Protection trap overwriting wrong location.
|
||||
59. CPU: Stop message reporting physical, not virtual, PC.
|
||||
60. IO: Test for "request another cycle" in channel processor was inverted.
|
||||
61. IO: Valid bit handling incorrect across multiple transfers.
|
||||
62. IO: BSR doesn't set EOF indicator.
|
||||
63. IO: 7607 channel modeled incorrectly, could stall.
|
||||
64. IO: All 7607 "effective NOP" conditions must be tested when a new command is
|
||||
decoded (wc == 0 for IOCx and IOSx, EOR set for IOSx and IORx).
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
495
I7094/i7094_cd.c
Normal file
495
I7094/i7094_cd.c
Normal file
|
@ -0,0 +1,495 @@
|
|||
/* i7094_cd.c: IBM 711/721 card reader/punch
|
||||
|
||||
Copyright (c) 2003-2006, 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.
|
||||
|
||||
cdr 711 card reader
|
||||
cdp 721 card punch
|
||||
|
||||
Cards are represented as ASCII text streams terminated by newlines.
|
||||
This allows cards to be created and edited as normal files. Two
|
||||
formats are supported:
|
||||
|
||||
column binary each character represents 6b of a 12b column
|
||||
text each character represents all 12b of a column
|
||||
|
||||
Internally, the 7094 works only with column binary and is limited
|
||||
to 72 columns of data. Each row of the card is represented by 72b
|
||||
of data (two 36b words). A complete card image consists of 12 rows
|
||||
(24 36b words).
|
||||
*/
|
||||
|
||||
#include "i7094_defs.h"
|
||||
|
||||
#define CD_BINLNT 24 /* bin buf length */
|
||||
#define CD_CHRLNT 80 /* char buf length */
|
||||
|
||||
#define CDS_INIT 0 /* card in motion */
|
||||
#define CDS_DATA 1 /* data transfer */
|
||||
#define CDS_END 2 /* card complete */
|
||||
|
||||
#define UNIT_V_CBN (UNIT_V_UF + 0) /* column binary file */
|
||||
#define UNIT_V_PCA (UNIT_V_UF + 1) /* A vs H punch flag */
|
||||
#define UNIT_CBN (1 << UNIT_V_CBN)
|
||||
#define UNIT_PCA (1 << UNIT_V_PCA)
|
||||
|
||||
uint32 cdr_sta = 0; /* state */
|
||||
uint32 cdr_bptr = 0; /* buffer ptr */
|
||||
uint32 cdr_tstart = 27500; /* timing */
|
||||
uint32 cdr_tstop = 27500;
|
||||
uint32 cdr_tleft = 150;
|
||||
uint32 cdr_tright = 4000;
|
||||
t_uint64 cdr_bbuf[CD_BINLNT]; /* col binary buf */
|
||||
|
||||
uint32 cdp_sta = 0; /* state */
|
||||
uint32 cdp_bptr = 0; /* buffer ptr */
|
||||
uint32 cdp_tstart = 35000; /* timing */
|
||||
uint32 cdp_tstop = 35000;
|
||||
uint32 cdp_tleft = 150;
|
||||
uint32 cdp_tright = 15500;
|
||||
t_uint64 cdp_chob = 0;
|
||||
uint32 cdp_chob_v = 0;
|
||||
t_uint64 cdp_bbuf[CD_BINLNT]; /* col binary buf */
|
||||
|
||||
t_stat cdr_chsel (uint32 ch, uint32 sel, uint32 unit);
|
||||
t_stat cdr_reset (DEVICE *dptr);
|
||||
t_stat cdr_svc (UNIT *uptr);
|
||||
t_stat cdr_boot (int32 unitno, DEVICE *dptr);
|
||||
t_stat cdp_chsel (uint32 ch, uint32 sel, uint32 unit);
|
||||
t_stat cdp_chwr (uint32 ch, t_uint64 val, uint32 flags);
|
||||
t_stat cdp_reset (DEVICE *dptr);
|
||||
t_stat cdp_svc (UNIT *uptr);
|
||||
t_stat cdp_card_end (UNIT *uptr);
|
||||
t_stat cd_attach (UNIT *uptr, char *cptr);
|
||||
t_stat cd_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
char colbin_to_bcd (uint32 cb);
|
||||
|
||||
extern uint32 sim_switches;
|
||||
extern uint32 PC;
|
||||
extern uint32 ind_ioc;
|
||||
extern char bcd_to_ascii_a[64];
|
||||
extern char bcd_to_ascii_h[64];
|
||||
extern uint32 bcd_to_colbin[64];
|
||||
extern char ascii_to_bcd[128];
|
||||
extern t_uint64 bit_masks[36];
|
||||
extern uint32 col_masks[12];
|
||||
|
||||
/* Card reader data structures
|
||||
|
||||
cdr_dev CDR descriptor
|
||||
cdr_unit CDR unit descriptor
|
||||
cdr_reg CDR register list
|
||||
*/
|
||||
|
||||
DIB cdr_dib = { &cdr_chsel, NULL };
|
||||
|
||||
UNIT cdr_unit = {
|
||||
UDATA (&cdr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0)
|
||||
};
|
||||
|
||||
REG cdr_reg[] = {
|
||||
{ ORDATA (STATE, cdr_sta, 2) },
|
||||
{ DRDATA (BPTR, cdr_bptr, 5), PV_LEFT },
|
||||
{ BRDATA (BUF, cdr_bbuf, 8, 36, CD_BINLNT) },
|
||||
{ DRDATA (POS, cdr_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TSTART, cdr_tstart, 24), PV_LEFT + REG_NZ },
|
||||
{ DRDATA (TSTOP, cdr_tstop, 24), PV_LEFT + REG_NZ },
|
||||
{ DRDATA (TLEFT, cdr_tleft, 24), PV_LEFT + REG_NZ },
|
||||
{ DRDATA (TRIGHT, cdr_tright, 24), PV_LEFT + REG_NZ },
|
||||
{ NULL } };
|
||||
|
||||
MTAB cdr_mod[] = {
|
||||
{ UNIT_CBN, UNIT_CBN, "column binary", "BINARY", &cd_set_mode },
|
||||
{ UNIT_CBN, UNIT_CBN, "text", "TEXT", &cd_set_mode },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEVICE cdr_dev = {
|
||||
"CDR", &cdr_unit, cdr_reg, cdr_mod,
|
||||
1, 10, 31, 1, 8, 7,
|
||||
NULL, NULL, &cdr_reset,
|
||||
&cdr_boot, &cd_attach, NULL,
|
||||
&cdr_dib, DEV_DISABLE
|
||||
};
|
||||
|
||||
/* CDP data structures
|
||||
|
||||
cdp_dev CDP device descriptor
|
||||
cdp_unit CDP unit descriptor
|
||||
cdp_reg CDP register list
|
||||
*/
|
||||
|
||||
DIB cdp_dib = { &cdp_chsel, &cdp_chwr };
|
||||
|
||||
UNIT cdp_unit = {
|
||||
UDATA (&cdp_svc, UNIT_SEQ+UNIT_ATTABLE, 0)
|
||||
};
|
||||
|
||||
REG cdp_reg[] = {
|
||||
{ ORDATA (STATE, cdp_sta, 2) },
|
||||
{ ORDATA (CHOB, cdp_chob, 36) },
|
||||
{ FLDATA (CHOBV, cdp_chob_v, 0) },
|
||||
{ DRDATA (BPTR, cdp_bptr, 5), PV_LEFT },
|
||||
{ BRDATA (BUF, cdp_bbuf, 8, 36, CD_BINLNT) },
|
||||
{ DRDATA (POS, cdp_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TSTART, cdp_tstart, 24), PV_LEFT + REG_NZ },
|
||||
{ DRDATA (TSTOP, cdp_tstop, 24), PV_LEFT + REG_NZ },
|
||||
{ DRDATA (TLEFT, cdp_tleft, 24), PV_LEFT + REG_NZ },
|
||||
{ DRDATA (TRIGHT, cdp_tright, 24), PV_LEFT + REG_NZ },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
MTAB cdp_mod[] = {
|
||||
{ UNIT_CBN, UNIT_CBN, "column binary", "BINARY", &cd_set_mode },
|
||||
{ UNIT_CBN, UNIT_CBN, "text", "TEXT", &cd_set_mode },
|
||||
{ UNIT_PCA, UNIT_PCA, "business set", "BUSINESS", NULL },
|
||||
{ UNIT_PCA, 0, "Fortran set", "FORTRAN", NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEVICE cdp_dev = {
|
||||
"CDP", &cdp_unit, cdp_reg, cdp_mod,
|
||||
1, 10, 31, 1, 8, 7,
|
||||
NULL, NULL, &cdp_reset,
|
||||
NULL, &cd_attach, NULL,
|
||||
&cdp_dib, DEV_DISABLE
|
||||
};
|
||||
|
||||
/* Card reader select */
|
||||
|
||||
t_stat cdr_chsel (uint32 ch, uint32 sel, uint32 unit)
|
||||
{
|
||||
if (sel & CHSL_NDS) return ch6_end_nds (ch); /* nds? nop */
|
||||
|
||||
switch (sel) { /* case on data sel */
|
||||
|
||||
case CHSL_RDS: /* read */
|
||||
if ((cdr_unit.flags & UNIT_ATT) == 0) /* not attached? */
|
||||
return SCPE_UNATT;
|
||||
if (sim_is_active (&cdr_unit)) /* busy? */
|
||||
return ERR_STALL;
|
||||
cdr_sta = CDS_INIT; /* initial state */
|
||||
sim_activate (&cdr_unit, cdp_tstart); /* start reader */
|
||||
break;
|
||||
|
||||
default: /* other */
|
||||
return STOP_ILLIOP; /* not allowed */
|
||||
}
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Unit timeout */
|
||||
|
||||
t_stat cdr_svc (UNIT *uptr)
|
||||
{
|
||||
uint32 i, col, row, bufw, colbin;
|
||||
char cdr_cbuf[2 * CD_CHRLNT + 1];
|
||||
t_uint64 dat = 0;
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) == 0) return SCPE_UNATT; /* not attached? */
|
||||
switch (cdr_sta) { /* case on state */
|
||||
|
||||
case CDS_INIT: /* initial state */
|
||||
for (i = 0; i < CD_BINLNT; i++) /* clear bin buf */
|
||||
cdr_bbuf[i] = 0;
|
||||
for (i = 0; i < ((2 * CD_CHRLNT) + 1); i++) /* clear char buf */
|
||||
cdr_cbuf[i] = ' ';
|
||||
cdr_sta = CDS_DATA; /* data state */
|
||||
cdr_bptr = 0; /* init buf ptr */
|
||||
fgets (cdr_cbuf, (uptr->flags & UNIT_CBN)? (2 * CD_CHRLNT): CD_CHRLNT,
|
||||
uptr->fileref); /* read card */
|
||||
if (feof (uptr->fileref)) /* eof? */
|
||||
return ch6_err_disc (CH_A, U_CDR, CHF_EOF); /* set EOF, disc */
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
perror ("CDR I/O error");
|
||||
clearerr (uptr->fileref);
|
||||
return SCPE_IOERR; /* stop */
|
||||
}
|
||||
uptr->pos = ftell (uptr->fileref); /* update position */
|
||||
for (i = 0; i < (2 * CD_CHRLNT); i++) /* convert to BCD */
|
||||
cdr_cbuf[i] = ascii_to_bcd[cdr_cbuf[i] & 0177] & 077;
|
||||
for (col = 0; col < 72; col++) { /* process 72 columns */
|
||||
if (uptr->flags & UNIT_CBN) /* column binary? */
|
||||
colbin = (((uint32) cdr_cbuf[2 * col]) << 6) |
|
||||
((uint32) cdr_cbuf[(2 * col) + 1]); /* 2 chars -> col bin */
|
||||
else colbin = bcd_to_colbin[cdr_cbuf[col]]; /* cvt to col binary */
|
||||
dat = bit_masks[35 - (col % 36)]; /* mask for column */
|
||||
for (row = 0; row < 12; row++) { /* rows 9..0, 11, 12 */
|
||||
bufw = (row * 2) + (col / 36); /* index to buffer */
|
||||
if (colbin & col_masks[row]) /* row bit set? */
|
||||
cdr_bbuf[bufw] |= dat;
|
||||
}
|
||||
}
|
||||
|
||||
case CDS_DATA: /* data state */
|
||||
dat = cdr_bbuf[cdr_bptr++]; /* get next word */
|
||||
if (cdr_bptr >= CD_BINLNT) { /* last word? */
|
||||
cdr_sta = CDS_END; /* end state */
|
||||
ch6_req_rd (CH_A, U_CDR, dat, CH6DF_EOR); /* req chan, dat, EOR */
|
||||
sim_activate (uptr, cdr_tstop);
|
||||
}
|
||||
else {
|
||||
ch6_req_rd (CH_A, U_CDR, dat, 0); /* req chan, dat */
|
||||
sim_activate (uptr, (cdr_bptr & 1)? cdr_tleft: cdr_tright);
|
||||
}
|
||||
break;
|
||||
|
||||
case CDS_END: /* end state */
|
||||
if (ch6_qconn (CH_A, U_CDR)) { /* if cdr still conn */
|
||||
cdr_sta = CDS_INIT; /* return to init */
|
||||
sim_activate (uptr, 1); /* next card */
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Card reader reset */
|
||||
|
||||
t_stat cdr_reset (DEVICE *dptr)
|
||||
{
|
||||
uint32 i;
|
||||
|
||||
for (i = 0; i < CD_BINLNT; i++) cdr_bbuf[i] = 0; /* clear buffer */
|
||||
cdr_sta = 0; /* clear state */
|
||||
cdr_bptr = 0; /* clear buf ptr */
|
||||
sim_cancel (&cdr_unit); /* stop reader */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Card reader bootstrap */
|
||||
|
||||
#define BOOT_START 01000
|
||||
#define BOOT_SIZE (sizeof (boot_rom) / sizeof (t_uint64))
|
||||
|
||||
static const t_uint64 boot_rom[] = {
|
||||
00762000001000 + U_CDR, /* RDSA CDR */
|
||||
00544000000000 + BOOT_START + 4, /* LCHA *+3 */
|
||||
00544000000000, /* LCHA 0 */
|
||||
00021000000001, /* TTR 1 */
|
||||
05000030000000, /* IOCT 3,,0 */
|
||||
};
|
||||
|
||||
t_stat cdr_boot (int32 unitno, DEVICE *dptr)
|
||||
{
|
||||
uint32 i;
|
||||
extern t_uint64 *M;
|
||||
|
||||
for (i = 0; i < BOOT_SIZE; i++)
|
||||
WriteP (BOOT_START + i, boot_rom[i]);
|
||||
PC = BOOT_START;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Reader/punch attach */
|
||||
|
||||
t_stat cd_attach (UNIT *uptr, char *cptr)
|
||||
{
|
||||
t_stat r = attach_unit (uptr, cptr);
|
||||
|
||||
if (r != SCPE_OK) return r; /* attach */
|
||||
if (sim_switches & SWMASK ('T')) /* text? */
|
||||
uptr->flags = uptr->flags & ~UNIT_CBN;
|
||||
else if (sim_switches & SWMASK ('C')) /* column binary? */
|
||||
uptr->flags = uptr->flags | UNIT_CBN;
|
||||
else if (match_ext (cptr, "TXT")) /* .txt? */
|
||||
uptr->flags = uptr->flags & ~UNIT_CBN;
|
||||
else if (match_ext (cptr, "CBN")) /* .cbn? */
|
||||
uptr->flags = uptr->flags | UNIT_CBN;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Reader/punch set mode - valid only if not attached */
|
||||
|
||||
t_stat cd_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
return (uptr->flags & UNIT_ATT)? SCPE_NOFNC: SCPE_OK;
|
||||
}
|
||||
|
||||
/* Card punch select */
|
||||
|
||||
t_stat cdp_chsel (uint32 ch, uint32 sel, uint32 unit)
|
||||
{
|
||||
if (sel & CHSL_NDS) return ch6_end_nds (ch); /* nds? nop */
|
||||
|
||||
switch (sel) { /* case on cmd */
|
||||
|
||||
case CHSL_WRS: /* write */
|
||||
if ((cdp_unit.flags & UNIT_ATT) == 0) /* not attached? */
|
||||
return SCPE_UNATT;
|
||||
if (sim_is_active (&cdp_unit)) /* busy? */
|
||||
return ERR_STALL;
|
||||
cdp_sta = CDS_INIT; /* initial state */
|
||||
sim_activate (&cdp_unit, cdp_tstart); /* start punch */
|
||||
break;
|
||||
|
||||
default: /* other */
|
||||
return STOP_ILLIOP; /* not allowed */
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Channel write routine - write word to buffer, write card when full */
|
||||
|
||||
t_stat cdp_chwr (uint32 ch, t_uint64 val, uint32 eorfl)
|
||||
{
|
||||
cdp_chob = val & DMASK; /* store data */
|
||||
cdp_chob_v = 1; /* buffer valid */
|
||||
if (cdp_sta == CDS_DATA) {
|
||||
cdp_bbuf[cdp_bptr++] = cdp_chob; /* store data */
|
||||
if ((cdp_bptr >= CD_BINLNT) || eorfl) { /* end card or end rec? */
|
||||
ch6_set_flags (CH_A, U_CDP, CHF_EOR); /* set eor */
|
||||
return cdp_card_end (&cdp_unit); /* write card */
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
return SCPE_IERR;
|
||||
}
|
||||
|
||||
/* Unit timeout */
|
||||
|
||||
t_stat cdp_svc (UNIT *uptr)
|
||||
{
|
||||
uint32 i;
|
||||
|
||||
switch (cdp_sta) { /* case on state */
|
||||
|
||||
case CDS_INIT: /* initial state */
|
||||
for (i = 0; i < CD_BINLNT; i++) /* clear bin buffer */
|
||||
cdp_bbuf[i] = 0;
|
||||
cdp_sta = CDS_DATA; /* data state */
|
||||
cdp_bptr = 0; /* init pointer */
|
||||
ch6_req_wr (CH_A, U_CDP); /* request channel */
|
||||
cdp_chob = 0; /* clr, inval buffer */
|
||||
cdp_chob_v = 0;
|
||||
sim_activate (uptr, cdp_tleft); /* go again */
|
||||
break;
|
||||
|
||||
case CDS_DATA: /* data state */
|
||||
if (!ch6_qconn (CH_A, U_CDP)) /* chan disconnect? */
|
||||
return cdp_card_end (uptr); /* write card */
|
||||
if (cdp_chob_v) cdp_chob_v = 0; /* valid? clear */
|
||||
else ind_ioc = 1; /* no, io check */
|
||||
ch6_req_wr (CH_A, U_CDP); /* req channel */
|
||||
sim_activate (uptr, (cdp_bptr & 1)? cdp_tleft: cdp_tright);
|
||||
break;
|
||||
|
||||
case CDS_END: /* end state */
|
||||
if (ch6_qconn (CH_A, U_CDP)) { /* if cdp still conn */
|
||||
cdp_sta = CDS_INIT; /* return to init */
|
||||
sim_activate (uptr, 1); /* next card */
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Card end - write card image to file, transition to end state */
|
||||
|
||||
t_stat cdp_card_end (UNIT *uptr)
|
||||
{
|
||||
uint32 i, col, row, bufw, colbin;
|
||||
char *pch, bcd, cdp_cbuf[(2 * CD_CHRLNT) + 1];
|
||||
t_uint64 dat;
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) == 0) return SCPE_UNATT; /* not attached? */
|
||||
if (uptr->flags & UNIT_PCA) pch = bcd_to_ascii_a;
|
||||
else pch = bcd_to_ascii_h;
|
||||
for (col = 0; col < ((2 * CD_CHRLNT) + 1); col++)
|
||||
cdp_cbuf[col] = ' '; /* clear char buf */
|
||||
for (col = 0; col < 72; col++) { /* process 72 columns */
|
||||
colbin = 0;
|
||||
dat = bit_masks[35 - (col % 36)]; /* mask for column */
|
||||
for (row = 0; row < 12; row++) { /* proc 12 rows */
|
||||
bufw = (row * 2) + (col / 36); /* index to buffer */
|
||||
if (cdp_bbuf[bufw] & dat) colbin |= col_masks[row];
|
||||
}
|
||||
if (cdp_unit.flags & UNIT_CBN) { /* column binary? */
|
||||
cdp_cbuf[2 * col] = pch[(colbin >> 6) & 077];
|
||||
cdp_cbuf[(2 * col) + 1] = pch[colbin & 077];
|
||||
}
|
||||
else { /* text */
|
||||
bcd = colbin_to_bcd (colbin); /* column bin -> BCD */
|
||||
cdp_cbuf[col] = pch[bcd]; /* -> ASCII */
|
||||
}
|
||||
}
|
||||
for (i = ((2 * CD_CHRLNT) + 1); (i > 0) &&
|
||||
(cdp_cbuf[i - 1] == ' '); --i) ; /* trim spaces */
|
||||
cdp_cbuf[i++] = '\n'; /* append nl */
|
||||
fxwrite (cdp_cbuf, 1, i, uptr->fileref); /* write card */
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
perror ("CDP I/O error");
|
||||
clearerr (uptr->fileref);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
uptr->pos = ftell (uptr->fileref); /* update position */
|
||||
cdp_sta = CDS_END; /* end state */
|
||||
sim_cancel (uptr); /* cancel current */
|
||||
sim_activate (uptr, cdp_tstop); /* long timer */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Card punch reset */
|
||||
|
||||
t_stat cdp_reset (DEVICE *dptr)
|
||||
{
|
||||
uint32 i;
|
||||
|
||||
for (i = 0; i < 24; i++) cdp_bbuf[i] = 0; /* clear buffer */
|
||||
cdp_sta = 0; /* clear state */
|
||||
cdp_bptr = 0; /* clear buf ptr */
|
||||
cdp_chob = 0;
|
||||
cdp_chob_v = 0;
|
||||
sim_cancel (&cdp_unit); /* stop punch */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Column binary to BCD
|
||||
|
||||
This is based on documentation in the IBM 1620 manual and may not be
|
||||
accurate for the 7094. Each row (12,11,0,1..9) is interpreted as a bit
|
||||
pattern, and the appropriate bits are set. (Double punches inclusive
|
||||
OR, eg, 1,8,9 is 9.) On the 1620, double punch errors are detected;
|
||||
since the 7094 only reads column binary, double punches are ignored.
|
||||
|
||||
Bit order, left to right, is 12, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
|
||||
The for loop works right to left, so the table is reversed. */
|
||||
|
||||
static const char row_val[12] = {
|
||||
011, 010, 007, 006, 005, 004,
|
||||
003, 002, 001, 020, 040, 060
|
||||
};
|
||||
|
||||
char colbin_to_bcd (uint32 cb)
|
||||
{
|
||||
uint32 i;
|
||||
char bcd;
|
||||
|
||||
for (i = 0, bcd = 0; i < 12; i++) { /* 'sum' rows */
|
||||
if (cb & (1 << i)) bcd |= row_val[i];
|
||||
}
|
||||
return bcd;
|
||||
}
|
124
I7094/i7094_clk.c
Normal file
124
I7094/i7094_clk.c
Normal file
|
@ -0,0 +1,124 @@
|
|||
/* i7094_clk.c: IBM 7094 clock
|
||||
|
||||
Copyright (c) 2003-2006, 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.
|
||||
|
||||
clk RPQ F89349 interval timer
|
||||
Chronolog calendar clock
|
||||
*/
|
||||
|
||||
#include "i7094_defs.h"
|
||||
#include <time.h>
|
||||
|
||||
uint32 chtr_clk = 0;
|
||||
extern t_uint64 *M;
|
||||
|
||||
t_stat clk_svc (UNIT *uptr);
|
||||
t_stat clk_reset (DEVICE *dptr);
|
||||
uint8 bcd_2d (uint32 n, uint8 *b2);
|
||||
|
||||
/* CLK data structures
|
||||
|
||||
clk_dev CLK device descriptor
|
||||
clk_unit CLK unit
|
||||
clk_reg CLK register list
|
||||
*/
|
||||
|
||||
UNIT clk_unit = { UDATA (&clk_svc, 0, 0), 16000 };
|
||||
|
||||
REG clk_reg[] = {
|
||||
{ FLDATA (TRAP, chtr_clk, 0) },
|
||||
{ DRDATA (TIME, clk_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
DEVICE clk_dev = {
|
||||
"CLK", &clk_unit, clk_reg, NULL,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
NULL, NULL, &clk_reset,
|
||||
NULL, NULL, NULL,
|
||||
NULL, DEV_DISABLE+DEV_DIS
|
||||
};
|
||||
|
||||
/* Clock unit service */
|
||||
|
||||
t_stat clk_svc (UNIT *uptr)
|
||||
{
|
||||
t_uint64 ctr;
|
||||
|
||||
if ((clk_dev.flags & DEV_DIS) == 0) { /* clock enabled? */
|
||||
ctr = ReadP (CLK_CTR);
|
||||
ctr = (ctr + 1) & DMASK; /* increment */
|
||||
WriteP (CLK_CTR, ctr);
|
||||
if ((ctr & MMASK) == 0) chtr_clk = 1; /* overflow? req trap */
|
||||
sim_activate (uptr, sim_rtcn_calb (CLK_TPS, TMR_CLK)); /* reactivate unit */
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Chronolog clock */
|
||||
|
||||
uint32 chrono_rd (uint8 *buf, uint32 bufsiz)
|
||||
{
|
||||
time_t curtim;
|
||||
t_uint64 ctr;
|
||||
struct tm *tptr;
|
||||
|
||||
if (bufsiz < 12) return 0;
|
||||
curtim = time (NULL); /* get time */
|
||||
tptr = localtime (&curtim); /* decompose */
|
||||
if (tptr == NULL) return 0; /* error? */
|
||||
|
||||
buf[0] = bcd_2d (tptr->tm_mon + 1, buf + 1);
|
||||
buf[2] = bcd_2d (tptr->tm_mday, buf + 3);
|
||||
buf[4] = bcd_2d (tptr->tm_hour, buf + 5);
|
||||
buf[6] = bcd_2d (tptr->tm_min, buf + 7);
|
||||
buf[8] = bcd_2d (tptr->tm_sec, buf + 9);
|
||||
ctr = ReadP (CLK_CTR);
|
||||
buf[10] = bcd_2d ((uint32) (ctr % 60), buf + 11);
|
||||
return 12;
|
||||
}
|
||||
|
||||
/* Convert number (0-99) to BCD */
|
||||
|
||||
uint8 bcd_2d (uint32 n, uint8 *b2)
|
||||
{
|
||||
uint8 d1, d2;
|
||||
|
||||
d1 = n / 10;
|
||||
d2 = n % 10;
|
||||
if (d1 == 0) d1 = BCD_ZERO;
|
||||
if (d2 == 0) d2 = BCD_ZERO;
|
||||
if (b2 != NULL) *b2 = d2;
|
||||
return d1;
|
||||
}
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat clk_reset (DEVICE *dptr)
|
||||
{
|
||||
chtr_clk = 0;
|
||||
if (clk_dev.flags & DEV_DIS) sim_cancel (&clk_unit);
|
||||
else sim_activate (&clk_unit, sim_rtcn_init (clk_unit.wait, TMR_CLK));
|
||||
return SCPE_OK;
|
||||
}
|
1149
I7094/i7094_com.c
Normal file
1149
I7094/i7094_com.c
Normal file
File diff suppressed because it is too large
Load diff
2239
I7094/i7094_cpu.c
Normal file
2239
I7094/i7094_cpu.c
Normal file
File diff suppressed because it is too large
Load diff
837
I7094/i7094_cpu1.c
Normal file
837
I7094/i7094_cpu1.c
Normal file
|
@ -0,0 +1,837 @@
|
|||
/* i7094_cpu1.c: IBM 7094 CPU complex instructions
|
||||
|
||||
Copyright (c) 2003-2006, 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.
|
||||
*/
|
||||
|
||||
#include "i7094_defs.h"
|
||||
|
||||
#define FP_HIFRAC(x) ((uint32) ((x) >> FP_N_FR) & FP_FMASK)
|
||||
#define FP_LOFRAC(x) ((uint32) (x) & FP_FMASK)
|
||||
|
||||
#define FP_PACK38(s,e,f) (((s)? AC_S: 0) | ((t_uint64) (f)) | \
|
||||
(((t_uint64) ((e) & FP_M_ACCH)) << FP_V_CH))
|
||||
#define FP_PACK36(s,e,f) (((s)? SIGN: 0) | ((t_uint64) (f)) | \
|
||||
(((t_uint64) ((e) & FP_M_CH)) << FP_V_CH))
|
||||
|
||||
extern t_uint64 AC, MQ, SI, KEYS;
|
||||
extern uint32 PC;
|
||||
extern uint32 SLT, SSW;
|
||||
extern uint32 cpu_model, stop_illop;
|
||||
extern uint32 ind_ovf, ind_dvc, ind_ioc, ind_mqo;
|
||||
extern uint32 mode_ttrap, mode_strap, mode_ctrap, mode_ftrap;
|
||||
extern uint32 mode_storn, mode_multi;
|
||||
extern uint32 chtr_pend, chtr_inht, chtr_inhi;
|
||||
extern uint32 ch_flags[NUM_CHAN];
|
||||
|
||||
typedef struct { /* unpacked fp */
|
||||
uint32 s; /* sign: 0 +, 1 - */
|
||||
int32 ch; /* exponent */
|
||||
t_uint64 fr; /* fraction (54b) */
|
||||
} UFP;
|
||||
|
||||
uint32 op_frnd (void);
|
||||
t_uint64 fp_fracdiv (t_uint64 dvd, t_uint64 dvr, t_uint64 *rem);
|
||||
void fp_norm (UFP *op);
|
||||
void fp_unpack (t_uint64 h, t_uint64 l, t_bool q_ac, UFP *op);
|
||||
uint32 fp_pack (UFP *op, uint32 mqs, int32 mqch);
|
||||
|
||||
extern t_bool fp_trap (uint32 spill);
|
||||
extern t_bool sel_trap (uint32 va);
|
||||
extern t_stat ch_op_reset (uint32 ch, t_bool ch7909);
|
||||
|
||||
/* Integer add
|
||||
|
||||
Sherman: "As the result of an addition or subtraction, if the C(AC) is
|
||||
zero, the sign of AC is unchanged." */
|
||||
|
||||
void op_add (t_uint64 op)
|
||||
{
|
||||
t_uint64 mac = AC & AC_MMASK; /* get magnitudes */
|
||||
t_uint64 mop = op & MMASK;
|
||||
|
||||
AC = AC & AC_S; /* isolate AC sign */
|
||||
if ((AC? 1: 0) ^ ((op & SIGN)? 1: 0)) { /* signs diff? sub */
|
||||
if (mac >= mop) AC = AC | (mac - mop); /* AC >= MQ */
|
||||
else AC = (AC ^ AC_S) | (mop - mac); /* <, sign change */
|
||||
}
|
||||
else {
|
||||
AC = AC | ((mac + mop) & AC_MMASK); /* signs same, add */
|
||||
if ((AC ^ mac) & AC_P) ind_ovf = 1; /* P change? overflow */
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Multiply */
|
||||
|
||||
void op_mpy (t_uint64 ac, t_uint64 sr, uint32 sc)
|
||||
{
|
||||
uint32 sign;
|
||||
|
||||
if (sc == 0) return; /* sc = 0? nop */
|
||||
sign = ((MQ & SIGN)? 1: 0) ^ ((sr & SIGN)? 1: 0); /* result sign */
|
||||
ac = ac & AC_MMASK; /* clear AC sign */
|
||||
sr = sr & MMASK; /* mpy magnitude */
|
||||
MQ = MQ & MMASK; /* MQ magnitude */
|
||||
if (sr && MQ) { /* mpy != 0? */
|
||||
while (sc--) { /* for sc */
|
||||
if (MQ & 1) ac = (ac + sr) & AC_MMASK; /* MQ35? AC += mpy */
|
||||
MQ = (MQ >> 1) | ((ac & 1) << 34); /* AC'MQ >> 1 */
|
||||
ac = ac >> 1;
|
||||
}
|
||||
}
|
||||
else ac = MQ = 0; /* result = 0 */
|
||||
if (sign) { /* negative? */
|
||||
ac = ac | AC_S; /* insert signs */
|
||||
MQ = MQ | SIGN;
|
||||
}
|
||||
AC = ac; /* update AC */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Divide */
|
||||
|
||||
t_bool op_div (t_uint64 sr, uint32 sc)
|
||||
{
|
||||
uint32 signa, signm;
|
||||
|
||||
if (sc == 0) return FALSE; /* sc = 0? nop */
|
||||
signa = (AC & AC_S)? 1: 0; /* get signs */
|
||||
signm = (sr & SIGN)? 1: 0;
|
||||
sr = sr & MMASK; /* get dvr magn */
|
||||
if ((AC & AC_MMASK) >= sr) return TRUE; /* |AC| >= |sr|? */
|
||||
AC = AC & AC_MMASK; /* AC, MQ magn */
|
||||
MQ = MQ & MMASK;
|
||||
while (sc--) { /* for sc */
|
||||
AC = ((AC << 1) & AC_MMASK) | (MQ >> 34); /* AC'MQ << 1 */
|
||||
MQ = (MQ << 1) & MMASK;
|
||||
if (AC >= sr) { /* AC >= dvr? */
|
||||
AC = AC - sr; /* AC -= dvr */
|
||||
MQ = MQ | 1; /* set quo bit */
|
||||
}
|
||||
}
|
||||
if (signa ^ signm) MQ = MQ | SIGN; /* quo neg? */
|
||||
if (signa) AC = AC | AC_S; /* rem neg? */
|
||||
return FALSE; /* div ok */
|
||||
}
|
||||
|
||||
/* Shifts */
|
||||
|
||||
void op_als (uint32 addr)
|
||||
{
|
||||
uint32 sc = addr & SCMASK;
|
||||
|
||||
if ((sc >= 35)? /* shift >= 35? */
|
||||
((AC & MMASK) != 0): /* test all bits for ovf */
|
||||
(((AC & MMASK) >> (35 - sc)) != 0)) /* test only 35-sc bits */
|
||||
ind_ovf = 1;
|
||||
if (sc >= 37) AC = AC & AC_S; /* sc >= 37? result 0 */
|
||||
else AC = (AC & AC_S) | ((AC << sc) & AC_MMASK); /* shift, save sign */
|
||||
return;
|
||||
}
|
||||
|
||||
void op_ars (uint32 addr)
|
||||
{
|
||||
uint32 sc = addr & SCMASK;
|
||||
|
||||
if (sc >= 37) AC = AC & AC_S; /* sc >= 37? result 0 */
|
||||
else AC = (AC & AC_S) | ((AC & AC_MMASK) >> sc); /* shift, save sign */
|
||||
return;
|
||||
}
|
||||
|
||||
void op_lls (uint32 addr)
|
||||
{
|
||||
uint32 sc; /* get sc */
|
||||
|
||||
AC = AC & AC_MMASK; /* clear AC sign */
|
||||
for (sc = addr & SCMASK; sc != 0; sc--) { /* for SC */
|
||||
AC = ((AC << 1) & AC_MMASK) | ((MQ >> 34) & 1); /* AC'MQ << 1 */
|
||||
MQ = (MQ & SIGN) | ((MQ << 1) & MMASK); /* preserve MQ sign */
|
||||
if (AC & AC_P) ind_ovf = 1; /* if P, overflow */
|
||||
}
|
||||
if (MQ & SIGN) AC = AC | AC_S; /* set ACS from MQS */
|
||||
return;
|
||||
}
|
||||
|
||||
void op_lrs (uint32 addr)
|
||||
{
|
||||
uint32 sc = addr & SCMASK;
|
||||
t_uint64 mac;
|
||||
|
||||
MQ = MQ & MMASK; /* get MQ magnitude */
|
||||
if (sc != 0) {
|
||||
mac = AC & AC_MMASK; /* get AC magnitude, */
|
||||
AC = AC & AC_S; /* sign */
|
||||
if (sc < 35) { /* sc [1,34]? */
|
||||
MQ = ((MQ >> sc) | (mac << (35 - sc))) & MMASK; /* MQ has AC'MQ */
|
||||
AC = AC | (mac >> sc); /* AC has AC only */
|
||||
}
|
||||
else if (sc < 37) { /* sc [35:36]? */
|
||||
MQ = (mac >> (sc - 35)) & MMASK; /* MQ has AC only */
|
||||
AC = AC | (mac >> sc); /* AC has <QP> */
|
||||
}
|
||||
else if (sc < 72) /* sc [37:71]? */
|
||||
MQ = (mac >> (sc - 35)) & MMASK; /* MQ has AC only */
|
||||
else MQ = 0; /* >72? MQ = 0 */
|
||||
}
|
||||
if (AC & AC_S) MQ = MQ | SIGN; /* set MQS from ACS */
|
||||
return;
|
||||
}
|
||||
|
||||
void op_lgl (uint32 addr)
|
||||
{
|
||||
uint32 sc; /* get sc */
|
||||
|
||||
for (sc = addr & SCMASK; sc != 0; sc--) { /* for SC */
|
||||
AC = (AC & AC_S) | ((AC << 1) & AC_MMASK) | /* AC'MQ << 1 */
|
||||
((MQ >> 35) & 1); /* preserve AC sign */
|
||||
MQ = (MQ << 1) & DMASK;
|
||||
if (AC & AC_P) ind_ovf = 1; /* if P, overflow */
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void op_lgr (uint32 addr)
|
||||
{
|
||||
uint32 sc = addr & SCMASK;
|
||||
t_uint64 mac;
|
||||
|
||||
if (sc != 0) {
|
||||
mac = AC & AC_MMASK; /* get AC magnitude, */
|
||||
AC = AC & AC_S; /* sign */
|
||||
if (sc < 36) { /* sc [1,35]? */
|
||||
MQ = ((MQ >> sc) | (mac << (36 - sc))) & DMASK; /* MQ has AC'MQ */
|
||||
AC = AC | (mac >> sc); /* AC has AC only */
|
||||
}
|
||||
else if (sc == 36) { /* sc [36]? */
|
||||
MQ = mac & DMASK; /* MQ = AC<P,1:35> */
|
||||
AC = AC | (mac >> 36); /* AC = AC<Q> */
|
||||
}
|
||||
else if (sc < 73) /* sc [37, 72]? */
|
||||
MQ = (mac >> (sc - 36)) & DMASK; /* MQ has AC only */
|
||||
else MQ = 0; /* >72, AC,MQ = 0 */
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Plus sense - undefined operations are NOPs */
|
||||
|
||||
t_stat op_pse (uint32 addr)
|
||||
{
|
||||
uint32 ch, spill;
|
||||
|
||||
switch (addr) {
|
||||
|
||||
case 00000: /* CLM */
|
||||
if (cpu_model & I_9X) AC = AC & AC_S; /* 709X only */
|
||||
break;
|
||||
|
||||
case 00001: /* LBT */
|
||||
if ((AC & 1) != 0) PC = (PC + 1) & AMASK;
|
||||
break;
|
||||
|
||||
case 00002: /* CHS */
|
||||
AC = AC ^ AC_S;
|
||||
break;
|
||||
|
||||
case 00003: /* SSP */
|
||||
AC = AC & ~AC_S;
|
||||
break;
|
||||
|
||||
case 00004: /* ENK */
|
||||
MQ = KEYS;
|
||||
break;
|
||||
|
||||
case 00005: /* IOT */
|
||||
if (ind_ioc) ind_ioc = 0;
|
||||
else PC = (PC + 1) & AMASK;
|
||||
break;
|
||||
|
||||
case 00006: /* COM */
|
||||
AC = AC ^ AC_MMASK;
|
||||
break;
|
||||
|
||||
case 00007: /* ETM */
|
||||
if (cpu_model & I_9X) mode_ttrap = 1; /* 709X only */
|
||||
break;
|
||||
|
||||
case 00010: /* RND */
|
||||
if ((cpu_model & I_9X) && (MQ & B1)) /* 709X only, MQ1 set? */
|
||||
op_add ((t_uint64) 1); /* incr AC */
|
||||
break;
|
||||
|
||||
case 00011: /* FRN */
|
||||
if (cpu_model & I_9X) { /* 709X only */
|
||||
spill = op_frnd ();
|
||||
if (spill) fp_trap (spill);
|
||||
}
|
||||
break;
|
||||
|
||||
case 00012: /* DCT */
|
||||
if (ind_dvc) ind_dvc = 0;
|
||||
else PC = (PC + 1) & AMASK;
|
||||
break;
|
||||
|
||||
case 00014: /* RCT */
|
||||
chtr_inhi = 1; /* 1 cycle delay */
|
||||
chtr_inht = 0; /* clr inhibit trap */
|
||||
chtr_pend = 0; /* no trap now */
|
||||
break;
|
||||
|
||||
case 00016: /* LMTM */
|
||||
if (cpu_model & I_94) mode_multi = 0; /* 709X only */
|
||||
break;
|
||||
|
||||
case 00140: /* SLF */
|
||||
if (cpu_model & I_9X) SLT = 0; /* 709X only */
|
||||
break;
|
||||
|
||||
case 00141: case 00142: case 00143: case 00144: /* SLN */
|
||||
if (cpu_model & I_9X) /* 709X only */
|
||||
SLT = SLT | (1u << (00144 - addr));
|
||||
break;
|
||||
|
||||
case 00161: case 00162: case 00163: /* SWT */
|
||||
case 00164: case 00165: case 00166:
|
||||
if ((SSW & (1u << (00166 - addr))) != 0)
|
||||
PC = (PC + 1) & AMASK;
|
||||
break;
|
||||
|
||||
case 01000: case 02000: case 03000: case 04000: /* BTT */
|
||||
case 05000: case 06000: case 07000: case 10000:
|
||||
if (cpu_model & I_9X) { /* 709X only */
|
||||
if (sel_trap (PC)) break; /* sel trap? */
|
||||
ch = GET_U_CH (addr); /* get channel */
|
||||
if (ch_flags[ch] & CHF_BOT) /* BOT? */
|
||||
ch_flags[ch] &= ~CHF_BOT; /* clear */
|
||||
else PC = (PC + 1) & AMASK; /* else skip */
|
||||
}
|
||||
break;
|
||||
|
||||
case 001350: case 002350: case 003350: case 004350: /* RICx */
|
||||
case 005350: case 006350: case 007350: case 010350:
|
||||
ch = GET_U_CH (addr); /* get channel */
|
||||
return ch_op_reset (ch, 1);
|
||||
|
||||
case 001352: case 002352: case 003352: case 004352: /* RDCx */
|
||||
case 005352: case 006352: case 007352: case 010352:
|
||||
ch = GET_U_CH (addr); /* get channel */
|
||||
return ch_op_reset (ch, 0);
|
||||
} /* end case */
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Minus sense */
|
||||
|
||||
t_stat op_mse (uint32 addr)
|
||||
{
|
||||
uint32 t, ch;
|
||||
|
||||
switch (addr) {
|
||||
|
||||
case 00000: /* CLM */
|
||||
if (cpu_model & I_9X) AC = AC & AC_S; /* 709X only */
|
||||
break;
|
||||
|
||||
case 00001: /* PBT */
|
||||
if ((AC & AC_P) != 0) PC = (PC + 1) & AMASK;
|
||||
break;
|
||||
|
||||
case 00002: /* EFTM */
|
||||
if (cpu_model & I_9X) { /* 709X only */
|
||||
mode_ftrap = 1;
|
||||
ind_mqo = 0; /* clears MQ ovf */
|
||||
}
|
||||
break;
|
||||
|
||||
case 00003: /* SSM */
|
||||
if (cpu_model & I_9X) AC = AC | AC_S; /* 709X only */
|
||||
break;
|
||||
|
||||
case 00004: /* LFTM */
|
||||
if (cpu_model & I_9X) mode_ftrap = 0; /* 709X only */
|
||||
break;
|
||||
|
||||
case 00005: /* ESTM */
|
||||
if (cpu_model & I_9X) mode_strap = 1; /* 709X only */
|
||||
break;
|
||||
|
||||
case 00006: /* ECTM */
|
||||
if (cpu_model & I_9X) mode_ctrap = 1; /* 709X only */
|
||||
break;
|
||||
|
||||
case 00007: /* LTM */
|
||||
if (cpu_model & I_9X) mode_ttrap = 0; /* 709X only */
|
||||
break;
|
||||
|
||||
case 00010: /* LSNM */
|
||||
if (cpu_model & I_9X) mode_storn = 0; /* 709X only */
|
||||
break;
|
||||
|
||||
case 00012: /* RTT (704) */
|
||||
if (cpu_model & I_9X) sel_trap (PC); /* 709X only */
|
||||
break;
|
||||
|
||||
case 00016: /* EMTM */
|
||||
mode_multi = 1;
|
||||
break;
|
||||
|
||||
case 00140: /* SLF */
|
||||
if (cpu_model & I_9X) SLT = 0; /* 709X only */
|
||||
break;
|
||||
|
||||
case 00141: case 00142: case 00143: case 00144: /* SLT */
|
||||
if (cpu_model & I_9X) { /* 709X only */
|
||||
t = SLT & (1u << (00144 - addr));
|
||||
SLT = SLT & ~t;
|
||||
if (t != 0) PC = (PC + 1) & AMASK;
|
||||
}
|
||||
break;
|
||||
|
||||
case 00161: case 00162: case 00163: /* SWT */
|
||||
case 00164: case 00165: case 00166:
|
||||
if ((cpu_model & I_9X) && /* 709X only */
|
||||
((SSW & (1u << (00166 - addr))) != 0))
|
||||
PC = (PC + 1) & AMASK;
|
||||
break;
|
||||
|
||||
case 001000: case 002000: case 003000: case 004000: /* ETT */
|
||||
case 005000: case 006000: case 007000: case 010000:
|
||||
if (sel_trap (PC)) break; /* sel trap? */
|
||||
ch = GET_U_CH (addr); /* get channel */
|
||||
if (ch_flags[ch] & CHF_EOT) /* EOT? */
|
||||
ch_flags[ch] = ch_flags[ch] & ~CHF_EOT; /* clear */
|
||||
else PC = (PC + 1) & AMASK; /* else skip */
|
||||
break;
|
||||
}
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Floating add
|
||||
|
||||
Notes:
|
||||
- AC<Q,P> enter into the initial exponent comparison. If either is set,
|
||||
the numbers are always swapped. AC<P> gets OR'd into AC<S> during the
|
||||
swap, and AC<Q,P> are cleared afterwards
|
||||
- The early end test is actually > 077 if AC <= SR and > 100 if
|
||||
AC > SR. However, any shift >= 54 will produce a zero fraction,
|
||||
so the difference can be ignored */
|
||||
|
||||
uint32 op_fad (t_uint64 sr, t_bool norm)
|
||||
{
|
||||
UFP op1, op2, t;
|
||||
int32 mqch, diff;
|
||||
|
||||
MQ = 0; /* clear MQ */
|
||||
fp_unpack (AC, 0, 1, &op1); /* unpack AC */
|
||||
fp_unpack (sr, 0, 0, &op2); /* unpack sr */
|
||||
if (op1.ch > op2.ch) { /* AC exp > SR exp? */
|
||||
if (AC & AC_P) op1.s = 1; /* AC P or's with S */
|
||||
t = op1; /* swap operands */
|
||||
op1 = op2;
|
||||
op2 = t;
|
||||
op2.ch = op2.ch & FP_M_CH; /* clear P,Q */
|
||||
}
|
||||
diff = op2.ch - op1.ch; /* exp diff */
|
||||
if (diff) { /* any shift? */
|
||||
if ((diff < 0) || (diff > 077)) op1.fr = 0; /* diff > 63? */
|
||||
else op1.fr = op1.fr >> diff; /* no, denormalize */
|
||||
}
|
||||
if (op1.s ^ op2.s) { /* subtract? */
|
||||
if (op1.fr >= op2.fr) { /* op1 > op2? */
|
||||
op2.fr = op1.fr - op2.fr; /* op1 - op2 */
|
||||
op2.s = op1.s; /* op2 sign is result */
|
||||
}
|
||||
else op2.fr = op2.fr - op1.fr; /* else op2 - op1 */
|
||||
}
|
||||
else {
|
||||
op2.fr = op2.fr + op1.fr; /* op2 + op1 */
|
||||
if (op2.fr & FP_FCRY) { /* carry? */
|
||||
op2.fr = op2.fr >> 1; /* renormalize */
|
||||
op2.ch++; /* incr exp */
|
||||
}
|
||||
}
|
||||
if (norm) { /* normalize? */
|
||||
if (op2.fr) { /* non-zero frac? */
|
||||
fp_norm (&op2);
|
||||
mqch = op2.ch - FP_N_FR;
|
||||
}
|
||||
else op2.ch = mqch = 0; /* else true zero */
|
||||
}
|
||||
else mqch = op2.ch - FP_N_FR;
|
||||
return fp_pack (&op2, op2.s, mqch); /* pack AC, MQ */
|
||||
}
|
||||
|
||||
/* Floating multiply */
|
||||
|
||||
uint32 op_fmp (t_uint64 sr, t_bool norm)
|
||||
{
|
||||
UFP op1, op2;
|
||||
int32 mqch;
|
||||
uint32 f1h, f2h;
|
||||
|
||||
fp_unpack (MQ, 0, 0, &op1); /* unpack MQ */
|
||||
fp_unpack (sr, 0, 0, &op2); /* unpack sr */
|
||||
op1.s = op1.s ^ op2.s; /* result sign */
|
||||
if ((op2.ch == 0) && (op2.fr == 0)) { /* sr a normal 0? */
|
||||
AC = op1.s? AC_S: 0; /* result is 0 */
|
||||
MQ = op1.s? SIGN: 0;
|
||||
return 0;
|
||||
}
|
||||
f1h = FP_HIFRAC (op1.fr); /* get hi fracs */
|
||||
f2h = FP_HIFRAC (op2.fr);
|
||||
op1.fr = ((t_uint64) f1h) * ((t_uint64) f2h); /* f1h * f2h */
|
||||
op1.ch = (op1.ch & FP_M_CH) + op2.ch - FP_BIAS; /* result exponent */
|
||||
if (norm) { /* normalize? */
|
||||
if (!(op1.fr & FP_FNORM)) { /* not normalized? */
|
||||
op1.fr = op1.fr << 1; /* shift frac left 1 */
|
||||
op1.ch--; /* decr exp */
|
||||
}
|
||||
if (FP_HIFRAC (op1.fr)) /* hi result non-zero? */
|
||||
mqch = op1.ch - FP_N_FR; /* set MQ exp */
|
||||
else op1.ch = mqch = 0; /* clear AC, MQ exp */
|
||||
}
|
||||
else mqch = op1.ch - FP_N_FR; /* set MQ exp */
|
||||
return fp_pack (&op1, op1.s, mqch); /* pack AC, MQ */
|
||||
}
|
||||
|
||||
/* Floating divide */
|
||||
|
||||
uint32 op_fdv (t_uint64 sr)
|
||||
{
|
||||
UFP op1, op2;
|
||||
int32 mqch;
|
||||
uint32 spill, quos;
|
||||
t_uint64 rem;
|
||||
|
||||
fp_unpack (AC, 0, 1, &op1); /* unpack AC */
|
||||
fp_unpack (sr, 0, 0, &op2); /* unpack sr */
|
||||
quos = op1.s ^ op2.s; /* quotient sign */
|
||||
if (op1.fr >= (2 * op2.fr)) { /* |AC| >= 2*|sr|? */
|
||||
MQ = quos? SIGN: 0; /* MQ = sign only */
|
||||
return TRAP_F_DVC; /* divide check */
|
||||
}
|
||||
if (op1.fr == 0) { /* |AC| == 0? */
|
||||
MQ = quos? SIGN: 0; /* MQ = sign only */
|
||||
AC = 0; /* AC = +0 */
|
||||
return 0; /* done */
|
||||
}
|
||||
op1.ch = op1.ch & FP_M_CH; /* remove AC<Q,P> */
|
||||
if (op1.fr >= op2.fr) { /* |AC| >= |sr|? */
|
||||
op1.fr = op1.fr >> 1; /* denorm AC */
|
||||
op1.ch++;
|
||||
}
|
||||
op1.fr = fp_fracdiv (op1.fr, op2.fr, &rem); /* fraction divide */
|
||||
op1.fr = op1.fr | (rem << FP_N_FR); /* rem'quo */
|
||||
mqch = op1.ch - op2.ch + FP_BIAS; /* quotient exp */
|
||||
op1.ch = op1.ch - FP_N_FR; /* remainder exp */
|
||||
spill = fp_pack (&op1, quos, mqch); /* pack up */
|
||||
return (spill? (spill | TRAP_F_SGL): 0); /* if spill, set SGL */
|
||||
}
|
||||
|
||||
/* Double floating add
|
||||
|
||||
Notes:
|
||||
- AC<Q,P> enter into the initial exponent comparison. If either is set,
|
||||
the numbers are always swapped. AC<P> gets OR'd into AC<S> during the
|
||||
swap, and AC<Q,P> are cleared afterwards
|
||||
- For most cases, SI ends up with the high order part of the larger number
|
||||
- The 'early end' cases (smaller number is shifted away) must be tracked
|
||||
exactly for SI impacts. The early end cases are:
|
||||
|
||||
(a) AC > SR, diff > 0100, and AC normalized
|
||||
(b) AC <= SR, diff > 077, and SR normalized
|
||||
|
||||
In case (a), SI is unchanged. In case (b), SI ends up with the SR sign
|
||||
and characteristic but the MQ (!) fraction */
|
||||
|
||||
uint32 op_dfad (t_uint64 sr, t_uint64 sr1, t_bool norm)
|
||||
{
|
||||
UFP op1, op2, t;
|
||||
int32 mqch, diff;
|
||||
|
||||
fp_unpack (AC, MQ, 1, &op1); /* unpack AC'MQ */
|
||||
fp_unpack (sr, sr1, 0, &op2); /* unpack sr'sr1 */
|
||||
if (op1.ch > op2.ch) { /* AC exp > SR exp? */
|
||||
if (((op1.ch - op2.ch) > 0100) && (AC & B9)) ; /* early out */
|
||||
else SI = FP_PACK36 (op1.s, op1.ch, FP_HIFRAC (op1.fr));
|
||||
if (AC & AC_P) op1.s = 1; /* AC P or's with S */
|
||||
t = op1; /* swap operands */
|
||||
op1 = op2;
|
||||
op2 = t;
|
||||
op2.ch = op2.ch & FP_M_CH; /* clear P,Q */
|
||||
}
|
||||
else { /* AC <= SR */
|
||||
if (((op2.ch - op1.ch) > 077) && (sr & B9)) /* early out */
|
||||
SI = FP_PACK36 (op2.s, op2.ch, FP_LOFRAC (MQ));
|
||||
else SI = FP_PACK36 (op2.s, op2.ch, FP_HIFRAC (op2.fr));
|
||||
}
|
||||
diff = op2.ch - op1.ch; /* exp diff */
|
||||
if (diff) { /* any shift? */
|
||||
if ((diff < 0) || (diff > 077)) op1.fr = 0; /* diff > 63? */
|
||||
else op1.fr = op1.fr >> diff; /* no, denormalize */
|
||||
}
|
||||
if (op1.s ^ op2.s) { /* subtract? */
|
||||
if (op1.fr >= op2.fr) { /* op1 > op2? */
|
||||
op2.fr = op1.fr - op2.fr; /* op1 - op2 */
|
||||
op2.s = op1.s; /* op2 sign is result */
|
||||
}
|
||||
else op2.fr = op2.fr - op1.fr; /* op2 - op1 */
|
||||
}
|
||||
else {
|
||||
op2.fr = op2.fr + op1.fr; /* op2 + op1 */
|
||||
if (op2.fr & FP_FCRY) { /* carry? */
|
||||
op2.fr = op2.fr >> 1; /* renormalize */
|
||||
op2.ch++; /* incr exp */
|
||||
}
|
||||
}
|
||||
if (norm) { /* normalize? */
|
||||
if (op2.fr) { /* non-zero frac? */
|
||||
fp_norm (&op2);
|
||||
mqch = op2.ch - FP_N_FR;
|
||||
}
|
||||
else op2.ch = mqch = 0; /* else true zero */
|
||||
}
|
||||
else mqch = op2.ch - FP_N_FR;
|
||||
return fp_pack (&op2, op2.s, mqch); /* pack AC, MQ */
|
||||
}
|
||||
|
||||
/* Double floating multiply
|
||||
|
||||
Notes (notation is A+B' * C+D', where ' denotes 2^-27):
|
||||
- The instruction returns 0 if A and C are both zero, because B*D is never
|
||||
done as part of the algorithm
|
||||
- For most cases, SI ends up with B*C, with a zero sign and exponent
|
||||
- For the A+B' both zero 'early end' case SI ends up with A or C,
|
||||
depending on whether the operation is normalized or not */
|
||||
|
||||
uint32 op_dfmp (t_uint64 sr, t_uint64 sr1, t_bool norm)
|
||||
{
|
||||
UFP op1, op2;
|
||||
int32 mqch;
|
||||
uint32 f1h, f2h, f1l, f2l;
|
||||
t_uint64 tx;
|
||||
|
||||
fp_unpack (AC, MQ, 1, &op1); /* unpack AC'MQ */
|
||||
fp_unpack (sr, sr1, 0, &op2); /* unpack sr'sr1 */
|
||||
op1.s = op1.s ^ op2.s; /* result sign */
|
||||
f1h = FP_HIFRAC (op1.fr); /* A */
|
||||
f1l = FP_LOFRAC (op1.fr); /* B */
|
||||
f2h = FP_HIFRAC (op2.fr); /* C */
|
||||
f2l = FP_LOFRAC (op2.fr); /* D */
|
||||
if (((op1.ch == 0) && (op1.fr == 0)) || /* AC'MQ normal 0? */
|
||||
((op2.ch == 0) && (op2.fr == 0)) || /* sr'sr1 normal 0? */
|
||||
((f1h == 0) && (f2h == 0))) { /* both hi frac zero? */
|
||||
AC = op1.s? AC_S: 0; /* result is 0 */
|
||||
MQ = op1.s? SIGN: 0;
|
||||
SI = sr; /* SI has C */
|
||||
return 0;
|
||||
}
|
||||
op1.ch = (op1.ch & FP_M_CH) + op2.ch - FP_BIAS; /* result exponent */
|
||||
if (op1.fr) { /* A'B != 0? */
|
||||
op1.fr = ((t_uint64) f1h) * ((t_uint64) f2h); /* A * C */
|
||||
tx = ((t_uint64) f1h) * ((t_uint64) f2l); /* A * D */
|
||||
op1.fr = op1.fr + (tx >> FP_N_FR); /* add in hi 27b */
|
||||
tx = ((t_uint64) f1l) * ((t_uint64) f2h); /* B * C */
|
||||
op1.fr = op1.fr + (tx >> FP_N_FR); /* add in hi 27b */
|
||||
SI = tx >> FP_N_FR; /* SI keeps B * C */
|
||||
}
|
||||
else {
|
||||
if (norm) SI = sr; /* early out */
|
||||
else SI = FP_PACK36 (op2.s, op2.ch, 0);
|
||||
}
|
||||
if (norm) { /* normalize? */
|
||||
if (!(op1.fr & FP_FNORM)) { /* not normalized? */
|
||||
op1.fr = op1.fr << 1; /* shift frac left 1 */
|
||||
op1.ch--; /* decr exp */
|
||||
}
|
||||
if (FP_HIFRAC (op1.fr)) { /* non-zero? */
|
||||
mqch = op1.ch - FP_N_FR; /* set MQ exp */
|
||||
}
|
||||
else op1.ch = mqch = 0; /* clear AC, MQ exp */
|
||||
}
|
||||
else mqch = op1.ch - FP_N_FR; /* set MQ exp */
|
||||
return fp_pack (&op1, op1.s, mqch); /* pack AC, MQ */
|
||||
}
|
||||
|
||||
/* Double floating divide
|
||||
|
||||
|
||||
Notes:
|
||||
- This is a Taylor series expansion (where ' denotes >> 27):
|
||||
|
||||
(A+B') * (C+D')^-1 = (A+B') * C^-1 - (A+B') * D'* C^-2 +...
|
||||
|
||||
to two terms, which can be rewritten as terms Q1, Q2:
|
||||
|
||||
Q1 = (A+B')/C
|
||||
Q2' = (R - Q1*D)'/C
|
||||
|
||||
- Tracking the sign of Q2' is complicated:
|
||||
|
||||
Q1 has the sign of the quotient, s_AC ^ s_SR
|
||||
D has the sign of the divisor, s_SR
|
||||
R has the sign of the dividend, s_AC
|
||||
Q1*D sign is s_AC ^ s_SR ^ s^SR = s^AC
|
||||
Therefore, R and Q1*D have the same sign, s_AC
|
||||
Q2' sign is s^AC ^ s_SR, which is the sign of the quotient
|
||||
|
||||
- For first divide check, SI is 0
|
||||
- For other cases, including second divide check, SI ends up with Q1
|
||||
- R-Q1*D is only calculated to the high 27b; using the full 54b
|
||||
throws off the result
|
||||
- The second divide must check for divd >= divr, otherwise an extra
|
||||
bit of quotient would be devloped, throwing off the result
|
||||
- A late ECO added full post-normalization; single precision divide
|
||||
does no normalization */
|
||||
|
||||
uint32 op_dfdv (t_uint64 sr, t_uint64 sr1)
|
||||
{
|
||||
UFP op1, op2;
|
||||
int32 mqch;
|
||||
uint32 csign, ac_s;
|
||||
t_uint64 f1h, f2h, tr, tq1, tq1d, trmq1d, tq2;
|
||||
|
||||
fp_unpack (AC, MQ, 1, &op1); /* unpack AC'MQ */
|
||||
fp_unpack (sr, 0, 0, &op2); /* unpack sr only */
|
||||
ac_s = op1.s; /* save AC sign */
|
||||
op1.s = op1.s ^ op2.s; /* sign of result */
|
||||
f1h = FP_HIFRAC (op1.fr);
|
||||
f2h = FP_HIFRAC (op2.fr);
|
||||
if (f1h >= (2 * f2h)) { /* |A| >= 2*|C|? */
|
||||
SI = 0; /* clear SI */
|
||||
return TRAP_F_DVC; /* divide check */
|
||||
}
|
||||
if (f1h == 0) { /* |AC| == 0? */
|
||||
SI = MQ = op1.s? SIGN: 0; /* MQ, SI = sign only */
|
||||
AC = op1.s? AC_S: 0; /* AC = sign only */
|
||||
return 0; /* done */
|
||||
}
|
||||
op1.ch = op1.ch & FP_M_CH; /* remove AC<Q,P> */
|
||||
if (f1h >= f2h) { /* |A| >= |C|? */
|
||||
op1.fr = op1.fr >> 1; /* denorm AC */
|
||||
op1.ch++;
|
||||
}
|
||||
op1.ch = op1.ch - op2.ch + FP_BIAS; /* exp of quotient */
|
||||
tq1 = fp_fracdiv (op1.fr, op2.fr, &tr); /* |A+B| / |C| */
|
||||
tr = tr << FP_N_FR; /* R << 27 */
|
||||
tq1d = (tq1 * ((t_uint64) FP_LOFRAC (sr1))) & /* Q1 * D */
|
||||
~((t_uint64) FP_FMASK); /* top 27 bits */
|
||||
csign = (tr < tq1d); /* correction sign */
|
||||
if (csign) trmq1d = tq1d - tr; /* |R|<|Q1*D|? compl */
|
||||
else trmq1d = tr - tq1d; /* no, subtr ok */
|
||||
SI = FP_PACK36 (op1.s, op1.ch, tq1); /* SI has Q1 */
|
||||
if (trmq1d >= (2 * op2.fr)) { /* |R-Q1*D| >= 2*|C|? */
|
||||
AC = FP_PACK38 (csign ^ ac_s, 0, FP_HIFRAC (trmq1d)); /* AC has R-Q1*D */
|
||||
MQ = (csign ^ ac_s)? SIGN: 0; /* MQ = sign only */
|
||||
return TRAP_F_DVC; /* divide check */
|
||||
}
|
||||
tq2 = fp_fracdiv (trmq1d, op2.fr, NULL); /* |R-Q1*D| / |C| */
|
||||
if (trmq1d >= op2.fr) tq2 &= ~((t_uint64) 1); /* can only gen 27b quo */
|
||||
op1.fr = tq1 << FP_N_FR; /* shift Q1 into place */
|
||||
if (csign) op1.fr = op1.fr - tq2; /* sub or add Q2 */
|
||||
else op1.fr = op1.fr + tq2;
|
||||
fp_norm (&op1); /* normalize */
|
||||
if (op1.fr) mqch = op1.ch - FP_N_FR; /* non-zero? */
|
||||
else op1.ch = mqch = 0; /* clear AC, MQ exp */
|
||||
return fp_pack (&op1, op1.s, mqch); /* pack AC, MQ */
|
||||
}
|
||||
|
||||
/* Floating round */
|
||||
|
||||
uint32 op_frnd (void)
|
||||
{
|
||||
UFP op;
|
||||
uint32 spill;
|
||||
|
||||
spill = 0; /* no error */
|
||||
if (MQ & B9) { /* MQ9 set? */
|
||||
fp_unpack (AC, 0, 1, &op); /* unpack AC */
|
||||
op.fr = op.fr + ((t_uint64) (1 << FP_N_FR)); /* round up */
|
||||
if (op.fr & FP_FCRY) { /* carry out? */
|
||||
op.fr = op.fr >> 1; /* renormalize */
|
||||
op.ch++; /* incr exp */
|
||||
if (op.ch == (FP_M_CH + 1)) /* ovf with QP = 0? */
|
||||
spill = TRAP_F_OVF | TRAP_F_AC;
|
||||
}
|
||||
AC = FP_PACK38 (op.s, op.ch, FP_HIFRAC (op.fr)); /* pack AC */
|
||||
}
|
||||
return spill;
|
||||
}
|
||||
|
||||
/* Fraction divide - 54/27'0 yielding quotient and remainder */
|
||||
|
||||
t_uint64 fp_fracdiv (t_uint64 dvd, t_uint64 dvr, t_uint64 *rem)
|
||||
{
|
||||
dvr = dvr >> FP_N_FR;
|
||||
if (rem) *rem = dvd % dvr;
|
||||
return (dvd / dvr);
|
||||
}
|
||||
|
||||
/* Floating point normalize */
|
||||
|
||||
void fp_norm (UFP *op)
|
||||
{
|
||||
op->fr = op->fr & FP_DFMASK; /* mask fraction */
|
||||
if (op->fr == 0) return; /* zero? */
|
||||
while ((op->fr & FP_FNORM) == 0) { /* until norm */
|
||||
op->fr = op->fr << 1; /* lsh 1 */
|
||||
op->ch--; /* decr exp */
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Floating point unpack */
|
||||
|
||||
void fp_unpack (t_uint64 h, t_uint64 l, t_bool q_ac, UFP *op)
|
||||
{
|
||||
if (q_ac) { /* AC? */
|
||||
op->s = (h & AC_S)? 1: 0; /* get sign */
|
||||
op->ch = (uint32) ((h >> FP_V_CH) & FP_M_ACCH); /* get exp */
|
||||
}
|
||||
else {
|
||||
op->s = (h & SIGN)? 1: 0; /* no, mem */
|
||||
op->ch = (uint32) ((h >> FP_V_CH) & FP_M_CH);
|
||||
}
|
||||
op->fr = (((t_uint64) FP_LOFRAC (h)) << FP_N_FR) | /* get frac hi */
|
||||
((t_uint64) FP_LOFRAC (l)); /* get frac lo */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Floating point pack */
|
||||
|
||||
uint32 fp_pack (UFP *op, uint32 mqs, int32 mqch)
|
||||
{
|
||||
uint32 spill;
|
||||
|
||||
AC = FP_PACK38 (op->s, op->ch, FP_HIFRAC (op->fr)); /* pack AC */
|
||||
MQ = FP_PACK36 (mqs, mqch, FP_LOFRAC (op->fr)); /* pack MQ */
|
||||
if (op->ch > FP_M_CH) spill = TRAP_F_OVF | TRAP_F_AC; /* check AC exp */
|
||||
else if (op->ch < 0) spill = TRAP_F_AC;
|
||||
else spill = 0;
|
||||
if (mqch > FP_M_CH) spill |= (TRAP_F_OVF | TRAP_F_MQ); /* check MQ exp */
|
||||
else if (mqch < 0) spill |= TRAP_F_MQ;
|
||||
return spill;
|
||||
}
|
152
I7094/i7094_dat.h
Normal file
152
I7094/i7094_dat.h
Normal file
|
@ -0,0 +1,152 @@
|
|||
/* i7094_dat.h: IBM 7094 data conversion tables
|
||||
|
||||
Copyright (c) 2003-2006, 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.
|
||||
*/
|
||||
|
||||
/* Nine-code to ASCII conversion */
|
||||
|
||||
const char nine_to_ascii_a[64] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', '^', '#', '@', ':', '>', '{',
|
||||
'&', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
||||
'H', 'I', '?', '.', ')', '[', '<', '}',
|
||||
'-', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', '!', '$', '*', ']', ';', '_',
|
||||
' ', '/', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z', '|', ',', '%', '~', '\\', '"',
|
||||
};
|
||||
|
||||
const char nine_to_ascii_h[64] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', '^', '=', '\'', ':', '>', '{',
|
||||
'+', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
||||
'H', 'I', '?', '.', ')', '[', '<', '}',
|
||||
'-', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', '!', '$', '*', ']', ';', '_',
|
||||
' ', '/', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z', '|', ',', '(', '~', '\\', '"',
|
||||
};
|
||||
|
||||
/* ASCII to nine-code conversion */
|
||||
|
||||
const char ascii_to_nine[128] = {
|
||||
060, 060, 060, 060, 060, 060, 060, 060, /* 000 - 037 */
|
||||
060, 060, 060, 060, 060, 060, 060, 060,
|
||||
060, 060, 060, 060, 060, 060, 060, 060,
|
||||
060, 060, 060, 060, 060, 060, 060, 060,
|
||||
060, 052, 077, 013, 053, 074, 020, 014, /* 040 - 077 */
|
||||
074, 034, 054, 020, 073, 040, 033, 061,
|
||||
000, 001, 002, 003, 004, 005, 006, 007,
|
||||
010, 011, 015, 056, 036, 013, 016, 032,
|
||||
014, 021, 022, 023, 024, 025, 026, 027, /* 100 - 137 */
|
||||
030, 031, 041, 042, 043, 044, 045, 046,
|
||||
047, 050, 051, 062, 063, 064, 065, 066,
|
||||
067, 070, 071, 035, 076, 055, 012, 057,
|
||||
060, 021, 022, 023, 024, 025, 026, 027, /* 140 - 177 */
|
||||
030, 031, 041, 042, 043, 044, 045, 046,
|
||||
047, 050, 051, 062, 063, 064, 065, 066,
|
||||
067, 070, 071, 017, 072, 037, 075, 060
|
||||
};
|
||||
|
||||
/* ASCII to BCD conversion */
|
||||
|
||||
const char ascii_to_bcd[128] = {
|
||||
000, 000, 000, 000, 000, 000, 000, 000, /* 000 - 037 */
|
||||
000, 000, 000, 000, 000, 000, 000, 000,
|
||||
000, 000, 000, 000, 000, 000, 000, 000,
|
||||
000, 000, 000, 000, 000, 000, 000, 000,
|
||||
000, 052, 037, 013, 053, 074, 060, 014, /* 040 - 077 */
|
||||
034, 074, 054, 060, 033, 040, 073, 021,
|
||||
020, 001, 002, 003, 004, 005, 006, 007,
|
||||
010, 011, 015, 056, 076, 013, 016, 072,
|
||||
014, 061, 062, 063, 064, 065, 066, 067, /* 100 - 137 */
|
||||
070, 071, 041, 042, 043, 044, 045, 046,
|
||||
047, 050, 051, 022, 023, 024, 025, 026,
|
||||
027, 030, 031, 075, 036, 055, 012, 057,
|
||||
000, 061, 062, 063, 064, 065, 066, 067, /* 140 - 177 */
|
||||
070, 071, 041, 042, 043, 044, 045, 046,
|
||||
047, 050, 051, 022, 023, 024, 025, 026,
|
||||
027, 030, 031, 017, 032, 077, 035, 000
|
||||
};
|
||||
|
||||
/* BCD to ASCII conversion */
|
||||
|
||||
const char bcd_to_ascii_a[64] = {
|
||||
' ', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', '^', '#', '@', ':', '>', '{',
|
||||
'0', '/', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z', '|', ',', '%', '~', '\\', '"',
|
||||
'-', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', '!', '$', '*', ']', ';', '_',
|
||||
'&', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
||||
'H', 'I', '?', '.', ')', '[', '<', '}'
|
||||
};
|
||||
|
||||
const char bcd_to_ascii_h[64] = {
|
||||
' ', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', '^', '=', '\'', ':', '>', '{',
|
||||
'0', '/', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z', '|', ',', '(', '~', '\\', '"',
|
||||
'-', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', '!', '$', '*', ']', ';', '_',
|
||||
'+', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
||||
'H', 'I', '?', '.', ')', '[', '<', '}'
|
||||
};
|
||||
|
||||
/* BCD to ASCII 48 character print chains */
|
||||
|
||||
const char bcd_to_pca[64] = {
|
||||
' ', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', ' ', '#', '@', ' ', ' ', ' ',
|
||||
'0', '/', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z', ' ', ',', '%', ' ', ' ', ' ',
|
||||
'-', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', '-', '$', '*', ' ', ' ', ' ',
|
||||
'&', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
||||
'H', 'I', '&', '.', ')', ' ', ' ', ' '
|
||||
};
|
||||
|
||||
const char bcd_to_pch[64] = {
|
||||
' ', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', ' ', '=', '\'', ' ', ' ', ' ',
|
||||
'0', '/', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z', ' ', ',', '(', ' ', ' ', ' ',
|
||||
'-', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', '-', '$', '*', ' ', ' ', ' ',
|
||||
'&', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
||||
'H', 'I', '&', '.', ')', ' ', ' ', ' '
|
||||
};
|
||||
|
||||
/* BCD to column binary conversion */
|
||||
|
||||
const uint32 bcd_to_colbin[64] = {
|
||||
00000, 00400, 00200, 00100, 00040, 00020, 00010, 00004,
|
||||
00002, 00001, 00202, 00102, 00042, 00022, 00012, 00006,
|
||||
01000, 01400, 01200, 01100, 01040, 01020, 01010, 01004,
|
||||
01002, 01001, 01202, 01102, 01042, 01022, 01012, 01006,
|
||||
02000, 02400, 02200, 02100, 02040, 02020, 02010, 02004,
|
||||
02002, 02001, 02202, 02102, 02042, 02022, 02012, 02006,
|
||||
04000, 04400, 04200, 04100, 04040, 04020, 04010, 04004,
|
||||
04002, 04001, 04202, 04102, 04042, 04022, 04012, 04006
|
||||
};
|
474
I7094/i7094_defs.h
Normal file
474
I7094/i7094_defs.h
Normal file
|
@ -0,0 +1,474 @@
|
|||
/* i7094_defs.h: IBM 7094 simulator definitions
|
||||
|
||||
Copyright (c) 2003-2006, 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 simulator incorporates prior work by Paul Pierce, Dave Pitts, and Rob
|
||||
Storey. Tom Van Vleck, Stan Dunten, Jerry Saltzer, and other CTSS veterans
|
||||
helped to reconstruct the CTSS hardware RPQ's. Dave Pitts gets special
|
||||
thanks for patiently coaching me through IBSYS debug. */
|
||||
|
||||
#ifndef _I7094_DEFS_H_
|
||||
#define _I7094_DEFS_H_ 0
|
||||
|
||||
#include "sim_defs.h" /* simulator defns */
|
||||
|
||||
/* Simulator stop codes */
|
||||
|
||||
#define STOP_HALT 1 /* halted */
|
||||
#define STOP_IBKPT 2 /* breakpoint */
|
||||
#define STOP_ILLEG 3 /* illegal instr */
|
||||
#define STOP_DIVCHK 4 /* divide check */
|
||||
#define STOP_XEC 5 /* XCT loop */
|
||||
#define STOP_ASTOP 6 /* address stop */
|
||||
#define STOP_NXCHN 7 /* nx channel */
|
||||
#define STOP_7909 8 /* ill inst to 7909 */
|
||||
#define STOP_NT7909 9 /* ill inst to !7909 */
|
||||
#define STOP_NXDEV 10 /* nx device */
|
||||
#define STOP_ILLCHI 11 /* illegal channel op */
|
||||
#define STOP_WRP 12 /* write protect */
|
||||
#define STOP_ILLIOP 13 /* illegal I/O op */
|
||||
#define STOP_INVFMT 14 /* invalid disk format */
|
||||
#define STOP_NOIFREE 15 /* 7750: no buf for inp */
|
||||
#define STOP_NOOFREE 16 /* 7750: no buf for out */
|
||||
#define STOP_INVLIN 17 /* 7750: invalid line# */
|
||||
#define STOP_INVMSG 18 /* 7750: invalid message */
|
||||
#define STOP_CHBKPT 19 /* channel breakpoint */
|
||||
|
||||
/* Simulator error codes */
|
||||
|
||||
#define ERR_STALL 40 /* stall */
|
||||
#define ERR_ENDRC 41 /* end rec */
|
||||
#define ERR_NRCF 42 /* no record found */
|
||||
|
||||
/* Instruction history - flags in left half of pc entry */
|
||||
|
||||
#define HIST_PC 0x04000000 /* CPU */
|
||||
#define HIST_V_CH 28 /* chan + 1 */
|
||||
#define HIST_M_CH 0xF
|
||||
#define HIST_CH(x) (((x) >> HIST_V_CH) & HIST_M_CH)
|
||||
|
||||
typedef struct {
|
||||
uint32 pc;
|
||||
uint32 ea;
|
||||
uint32 rpt;
|
||||
t_uint64 ir;
|
||||
t_uint64 ac;
|
||||
t_uint64 mq;
|
||||
t_uint64 si;
|
||||
t_uint64 opnd;
|
||||
} InstHistory;
|
||||
|
||||
/* Architectural constants */
|
||||
|
||||
#define A704_SIZE 14 /* addr width, 704 mode */
|
||||
#define ASIZE 15 /* inst addr width */
|
||||
#define PASIZE 16 /* phys addr width */
|
||||
#define STDMEMSIZE (1u << ASIZE) /* standard memory */
|
||||
#define MAXMEMSIZE (1u << PASIZE) /* maximum memory */
|
||||
#define A704_MASK ((1u << A704_SIZE) - 1)
|
||||
#define PAMASK ((1u << PASIZE) - 1)
|
||||
#define MEMSIZE (cpu_unit.capac)
|
||||
#define BCORE_V (ASIZE) /* (CTSS) A/B core sel */
|
||||
#define BCORE_BASE (1u << BCORE_V) /* (CTSS) B core base */
|
||||
|
||||
/* Traps */
|
||||
|
||||
#define TRAP_STD_SAV 000000 /* trap save location */
|
||||
#define TRAP_TRA_PC 000001 /* trap PC: transfer */
|
||||
#define TRAP_STR_PC 000002 /* trap PC: STR */
|
||||
#define TRAP_FP_PC 000010 /* trap PC: flt point */
|
||||
#define TRAP_PROT_SAV 000032 /* protection trap save */
|
||||
#define TRAP_PROT_PC 000033 /* protection trap PC */
|
||||
#define TRAP_704_SAV 040000 /* 704 compat trap */
|
||||
#define TRAP_SEL_PC 040001 /* 704 trap PC: select */
|
||||
#define TRAP_CPY_PC 040002 /* 704 trap PC: copy */
|
||||
|
||||
#define TRAP_F_MQ 000001 /* MQ error */
|
||||
#define TRAP_F_AC 000002 /* AC error */
|
||||
#define TRAP_F_OVF 000004 /* overflow */
|
||||
#define TRAP_F_SGL 000010 /* single precision */
|
||||
#define TRAP_F_DVC 000020 /* fake: divide check */
|
||||
#define TRAP_F_ODD 000040 /* odd address */
|
||||
#define TRAP_F_BDATA 020000 /* (CTSS) data B core */
|
||||
#define TRAP_F_BINST 040000 /* (CTSS) inst B core */
|
||||
|
||||
/* Integer */
|
||||
|
||||
#define DMASK 0777777777777 /* data mask */
|
||||
#define SIGN 0400000000000 /* sign */
|
||||
#define MMASK 0377777777777 /* magnitude mask */
|
||||
#define LMASK 0777777000000 /* left mask */
|
||||
#define RMASK 0000000777777 /* right mask */
|
||||
#define PMASK 0700000000000 /* prefix */
|
||||
#define XMASK 0077777000000 /* decrement */
|
||||
#define TMASK 0000000700000 /* tag */
|
||||
#define AMASK 0000000077777 /* address */
|
||||
#define SCMASK 0000000000377 /* shift count mask */
|
||||
#define B1 0200000000000 /* bit 1 */
|
||||
#define B9 0000400000000 /* bit 9 */
|
||||
|
||||
/* Accumulator is actually 38b wide */
|
||||
|
||||
#define AC_S 02000000000000 /* sign */
|
||||
#define AC_Q 01000000000000 /* Q */
|
||||
#define AC_P 00400000000000 /* P */
|
||||
#define AC_MMASK 01777777777777 /* Q+P+magnitude */
|
||||
|
||||
/* Floating point */
|
||||
|
||||
#define FP_N_FR 27 /* fraction bits */
|
||||
#define FP_FMASK ((1u << FP_N_FR) - 1)
|
||||
#define FP_N_DFR 54 /* double fraction bits */
|
||||
#define FP_DFMASK ((((t_uint64) 1) << FP_N_DFR) - 1)
|
||||
#define FP_FNORM (((t_uint64) 1u) << (FP_N_DFR - 1)) /* normalized bit */
|
||||
#define FP_FCRY (((t_uint64) 1u) << FP_N_DFR) /* fraction carry */
|
||||
#define FP_BIAS 0200 /* exponent bias */
|
||||
#define FP_V_CH (FP_N_FR) /* exponent */
|
||||
#define FP_M_CH 0377 /* SR char mask */
|
||||
#define FP_M_ACCH 01777 /* AC char mask incl Q,P */
|
||||
|
||||
/* Instruction format */
|
||||
|
||||
#define INST_T_DEC 0300000000000 /* if nz, takes decr */
|
||||
#define INST_T_CXR1 0000000100000 /* if nz, update XR1 */
|
||||
#define INST_V_OPD 33 /* decrement opcode */
|
||||
#define INST_M_OPD 07
|
||||
#define INST_V_DEC 18 /* decrement */
|
||||
#define INST_M_DEC 077777
|
||||
#define INST_V_OPC 24 /* normal opcode */
|
||||
#define INST_M_OPC 0777
|
||||
#define INST_V_IND 22 /* indirect */
|
||||
#define INST_IND (3 << INST_V_IND)
|
||||
#define INST_V_CCNT 18 /* convert count */
|
||||
#define INST_M_CCNT 0377
|
||||
#define INST_V_VCNT 18 /* vlm/vdh count */
|
||||
#define INST_M_VCNT 077
|
||||
#define INST_V_TAG 15 /* index */
|
||||
#define INST_M_TAG 07
|
||||
#define INST_V_ADDR 0
|
||||
#define INST_M_ADDR 077777
|
||||
|
||||
#define GET_OPD(x) ((uint32) (((x) >> INST_V_OPD) & INST_M_OPD))
|
||||
#define GET_DEC(x) ((uint32) (((x) >> INST_V_DEC) & INST_M_DEC))
|
||||
#define GET_OPC(x) (((uint32) (((x) >> INST_V_OPC) & INST_M_OPC)) | \
|
||||
(((x) & SIGN)? 01000: 0))
|
||||
#define TST_IND(x) (((x) & INST_IND) == INST_IND)
|
||||
#define GET_CCNT(x) ((uint32) (((x) >> INST_V_CCNT) & INST_M_CCNT))
|
||||
#define GET_VCNT(x) ((uint32) (((x) >> INST_V_VCNT) & INST_M_VCNT))
|
||||
#define GET_TAG(x) ((uint32) (((x) >> INST_V_TAG) & INST_M_TAG))
|
||||
|
||||
/* Instruction decode flags */
|
||||
|
||||
#define I_4X 0x01 /* 7040, 7044 */
|
||||
#define I_9X 0x02 /* 7090, 7094, CTSS */
|
||||
#define I_94 0x04 /* 7094, CTSS */
|
||||
#define I_CT 0x08 /* CTSS */
|
||||
#define I_MODEL 0x0F /* option mask */
|
||||
#define I_X 0x10 /* indexed */
|
||||
#define I_N 0x20 /* indirect */
|
||||
#define I_R 0x40 /* read */
|
||||
#define I_D 0x80 /* double read */
|
||||
|
||||
#define I_XN (I_X|I_N)
|
||||
#define I_XNR (I_X|I_N|I_R)
|
||||
#define I_XND (I_X|I_N|I_D)
|
||||
|
||||
/* Memory protection (CTSS) */
|
||||
|
||||
#define VA_V_OFF 0 /* offset in block */
|
||||
#define VA_N_OFF 8 /* width of offset */
|
||||
#define VA_M_OFF ((1u << VA_N_OFF) - 1)
|
||||
#define VA_OFF (VA_M_OFF << VA_V_OFF)
|
||||
#define VA_V_BLK (VA_N_OFF) /* block */
|
||||
#define VA_N_BLK (ASIZE - VA_N_OFF) /* width of block */
|
||||
#define VA_M_BLK ((1u << VA_N_BLK) - 1)
|
||||
#define VA_BLK (VA_M_BLK << VA_V_BLK)
|
||||
|
||||
/* Unsigned operations */
|
||||
|
||||
#define NEG(x) (~(x) + 1)
|
||||
#define BIT_TST(w,b) (((w) >> (b)) & 1)
|
||||
|
||||
/* Device information block */
|
||||
|
||||
typedef struct {
|
||||
t_stat (*chsel)(uint32 ch, uint32 sel, uint32 u);
|
||||
t_stat (*write)(uint32 ch, t_uint64 val, uint32 flags);
|
||||
} DIB;
|
||||
|
||||
/* BCD digits */
|
||||
|
||||
#define BCD_MASK 017
|
||||
#define BCD_ZERO 012
|
||||
#define BCD_ONE 001
|
||||
#define BCD_TWO 002
|
||||
#define BCD_AT 014
|
||||
|
||||
/* Channels */
|
||||
|
||||
#define NUM_CHAN 8 /* # channels */
|
||||
#define CH_A 0 /* channel A */
|
||||
#define CH_B 1
|
||||
#define CH_C 2
|
||||
#define CH_D 3
|
||||
#define CH_E 4
|
||||
#define CH_F 5
|
||||
#define CH_G 6
|
||||
#define CH_H 7
|
||||
|
||||
#define REQ_CH(x) (1u << (x))
|
||||
|
||||
/* All channel commands */
|
||||
|
||||
#define CHI_IND 0000000400000 /* ch inst indirect */
|
||||
|
||||
/* Channel selects - all channels */
|
||||
|
||||
#define CHSL_RDS 0001 /* data selects */
|
||||
#define CHSL_WRS 0002
|
||||
#define CHSL_SNS 0003
|
||||
#define CHSL_CTL 0004
|
||||
#define CHSL_FMT 0005
|
||||
#define CHSL_WEF 0010 /* non-data selects */
|
||||
#define CHSL_WBT 0011 /* 704X only */
|
||||
#define CHSL_BSR 0012
|
||||
#define CHSL_BSF 0013
|
||||
#define CHSL_REW 0014
|
||||
#define CHSL_RUN 0015
|
||||
#define CHSL_SDN 0016
|
||||
#define CHSL_2ND 0020 /* second state */
|
||||
#define CHSL_3RD 0040 /* etc */
|
||||
#define CHSL_4TH 0060
|
||||
#define CHSL_5TH 0100
|
||||
#define CHSL_NDS 0010 /* non-data sel flag */
|
||||
#define CHSL_NUM 16
|
||||
|
||||
/* Channel commands - 7607/7289 - S12'19 */
|
||||
|
||||
#define CH6I_NST 0000000200000 /* ch inst no store */
|
||||
|
||||
#define CH6_IOCD 000
|
||||
#define CH6_TCH 002
|
||||
#define CH6_IORP 004
|
||||
#define CH6_IORT 006
|
||||
#define CH6_IOCP 010
|
||||
#define CH6_IOCT 012
|
||||
#define CH6_IOSP 014
|
||||
#define CH6_IOST 016
|
||||
#define CH6_OPMASK 016 /* without nostore */
|
||||
#define TCH_LIMIT 5 /* TCH autoresolve limit */
|
||||
|
||||
/* Channel data flags - 7607 */
|
||||
|
||||
#define CH6DF_EOR 1 /* end of record */
|
||||
#define CH6DF_VLD 2 /* input valid */
|
||||
|
||||
/* Channel commands - 7909 - S123'19 */
|
||||
|
||||
#define CH9_WTR 000
|
||||
#define CH9_XMT 001
|
||||
#define CH9_TCH 004
|
||||
#define CH9_LIPT 005
|
||||
#define CH9_CTL 010
|
||||
#define CH9_CTLR 011
|
||||
#define CH9_CTLW 012
|
||||
#define CH9_SNS 013
|
||||
#define CH9_LAR 014
|
||||
#define CH9_SAR 015
|
||||
#define CH9_TWT 016
|
||||
#define CH9_CPYP 020
|
||||
#define CH9_CPYD 024
|
||||
#define CH9_TCM 025
|
||||
#define CH9_LIP 031
|
||||
#define CH9_TDC 032
|
||||
#define CH9_LCC 033
|
||||
#define CH9_SMS 034
|
||||
#define CH9_ICC 035
|
||||
#define CH9_ICCA 037 /* ignores bit <3> */
|
||||
#define CH9_OPMASK 037
|
||||
|
||||
/* Channel data flags - 7909 */
|
||||
|
||||
#define CH9DF_STOP 1 /* stop */
|
||||
#define CH9DF_VLD 2 /* input valid */
|
||||
|
||||
/* Extended parts of the command come from the decrement, stored in ch_wc */
|
||||
|
||||
#define CH9D_V_MASK 0 /* condition mask */
|
||||
#define CH9D_M_MASK 077
|
||||
#define CH9D_V_COND 12 /* condition select */
|
||||
#define CH9D_M_COND 07
|
||||
#define CH9D_MASK(x) (((x) >> CH9D_V_MASK) & CH9D_M_MASK)
|
||||
#define CH9D_COND(x) (((x) >> CH9D_V_COND) & CH9D_M_COND)
|
||||
|
||||
#define CH9D_NST 020000 /* no store */
|
||||
#define CH9D_B11 000100
|
||||
|
||||
/* Or from the effective address, stored in ch_ca */
|
||||
|
||||
#define CH9A_V_LCC 0 /* counter */
|
||||
#define CH9A_M_LCC 077
|
||||
#define CH9A_V_SMS 0 /* system mask */
|
||||
#define CH9A_M_SMS 0177
|
||||
#define CH9A_LCC(x) (((x) >> CH9A_V_LCC) & CH9A_M_LCC)
|
||||
#define CH9A_SMS(x) (((x) >> CH9A_V_SMS) & CH9A_M_SMS)
|
||||
|
||||
/* Channel states - common */
|
||||
|
||||
#define CHXS_IDLE 0 /* idle */
|
||||
#define CHXS_DSX 1 /* executing */
|
||||
|
||||
/* Channel states - 7607/7289 */
|
||||
|
||||
#define CH6S_PNDS 2 /* polling NDS */
|
||||
#define CH6S_PDS 3 /* polling DS */
|
||||
#define CH6S_NDS 4 /* nds, executing */
|
||||
#define CH6S_DSW 5 /* ds, chan wait */
|
||||
|
||||
/* Channel traps - 7909 has only CMD (== TWT) */
|
||||
|
||||
#define CHTR_V_CME 0 /* cmd/eof enable */
|
||||
#define CHTR_V_CLK 17 /* clock */
|
||||
#define CHTR_V_TRC 18 /* tape check */
|
||||
#define CHTR_V_TWT (CHTR_V_CME)
|
||||
#define CHTR_CLK_SAV 006 /* clock */
|
||||
#define CHTR_CHA_SAV 012 /* start of chan block */
|
||||
#define CHTR_F_CMD 1 /* CMD flag (in decr) */
|
||||
#define CHTR_F_TRC 2 /* TRC flag (in decr) */
|
||||
#define CHTR_F_EOF 4 /* EOF flag (in decr) */
|
||||
|
||||
/* Channel interrupts - 7909 only */
|
||||
|
||||
#define CHINT_CHA_SAV 042 /* start of chan block */
|
||||
|
||||
/* Channel interrupt conditions - 7909 only */
|
||||
|
||||
#define CHINT_ADPC 001 /* adapter check */
|
||||
#define CHINT_ATN2 002 /* attention 2 - ni */
|
||||
#define CHINT_ATN1 004 /* attention 1 */
|
||||
#define CHINT_UEND 010 /* unusual end */
|
||||
#define CHINT_SEQC 020 /* sequence check */
|
||||
#define CHINT_IOC 040 /* IO check */
|
||||
|
||||
/* Channel SMS flags - 7909 only */
|
||||
|
||||
#define CHSMS_SEL2 0001 /* select 2nd - ni */
|
||||
#define CHSMS_IATN2 0002 /* inhibit atn2 - ni */
|
||||
#define CHSMS_IATN1 0004 /* inhibit atn1 */
|
||||
#define CHSMS_IUEND 0010 /* inhibit uend */
|
||||
#define CHSMS_BCD 0020 /* BCD conversion - ni */
|
||||
#define CHSMS_RBCK 0040 /* read backwards - ni */
|
||||
#define CHSMS_ENCI 0100 /* enable noncon - ni */
|
||||
|
||||
/* Channel flags (7607 in right half, 7909 in left half) */
|
||||
|
||||
#define CHF_CMD 00000000001 /* cmd done */
|
||||
#define CHF_TWT (CHF_CMD)
|
||||
#define CHF_TRC 00000000002 /* tape check */
|
||||
#define CHF_EOF 00000000004 /* end of file */
|
||||
#define CHF_BOT 00000000010 /* beginning of tape */
|
||||
#define CHF_EOT 00000000020 /* end of tape */
|
||||
#define CHF_LDW 00000000040 /* LCH waiting */
|
||||
#define CHF_EOR 00000000100 /* end of record */
|
||||
#define CHF_IRQ 00001000000 /* intr request */
|
||||
#define CHF_INT 00002000000 /* intr in prog */
|
||||
#define CHF_WRS 00004000000 /* write */
|
||||
#define CHF_RDS 00010000000 /* read */
|
||||
#define CHF_PWR 00020000000 /* prepare to write */
|
||||
#define CHF_PRD 00040000000 /* prepare to read */
|
||||
#define CHF_V_COND 24 /* cond register */
|
||||
#define CHF_M_COND 077
|
||||
#define CHF_ADPC (CHINT_ADPC << CHF_V_COND) /* adapter check */
|
||||
#define CHF_ATN2 (CHINT_ATN2 << CHF_V_COND) /* attention 2 */
|
||||
#define CHF_ATN1 (CHINT_ATN1 << CHF_V_COND) /* attention 1 */
|
||||
#define CHF_UEND (CHINT_UEND << CHF_V_COND) /* unusual end */
|
||||
#define CHF_SEQC (CHINT_SEQC << CHF_V_COND) /* sequence check */
|
||||
#define CHF_IOC (CHINT_IOC << CHF_V_COND) /* IO check */
|
||||
#define CHF_V_LCC 30 /* loop ctrl counter */
|
||||
#define CHF_M_LCC 077
|
||||
|
||||
#define CHF_CLR_7909 07775000177 /* 7909 clear flags */
|
||||
#define CHF_SDC_7909 07776000000 /* 7909 SDC flags */
|
||||
|
||||
/* Channel characteristics (in dev.flags) */
|
||||
|
||||
#define DEV_7909 (1u << (DEV_V_UF + 0))
|
||||
#define DEV_7289 (1u << (DEV_V_UF + 1))
|
||||
#define DEV_CDLP (1u << (DEV_V_UF + 2))
|
||||
#define DEV_7750 (1u << (DEV_V_UF + 3))
|
||||
#define DEV_7631 (1u << (DEV_V_UF + 4))
|
||||
|
||||
/* Unit addresses - 7607/7289 only */
|
||||
|
||||
#define U_V_CH 9 /* channel number */
|
||||
#define U_M_CH 077
|
||||
#define U_V_UNIT 0
|
||||
#define U_M_UNIT 0777
|
||||
#define GET_U_CH(x) (((((uint32) (x)) >> U_V_CH) & U_M_CH) - 1)
|
||||
#define GET_U_UNIT(x) ((((uint32) (x)) >> U_V_UNIT) & U_M_UNIT)
|
||||
|
||||
#define U_MTBCD 0201 /* BCD tape */
|
||||
#define U_MTBIN 0221 /* binary tape */
|
||||
#define U_CDR 0321 /* card reader */
|
||||
#define U_CDP 0341 /* card punch */
|
||||
#define U_LPBCD 0361 /* BCD print */
|
||||
#define U_LPBIN 0362 /* binary print */
|
||||
#define U_DRM 0330 /* 7320A drum */
|
||||
|
||||
#define MT_NUMDR 10
|
||||
|
||||
/* CTSS Chronolog clock */
|
||||
|
||||
#define CHRONO_CH (CH_A) /* channel A */
|
||||
#define CHRONO_UNIT (7) /* unit 7 */
|
||||
|
||||
/* Interval timer */
|
||||
|
||||
#define CLK_CTR 05 /* counter */
|
||||
#define CLK_TPS 60 /* 60Hz */
|
||||
#define TMR_CLK 0 /* use timer 0 */
|
||||
#define TMR_COM 1 /* 7750 timer */
|
||||
|
||||
/* Function prototypes and macros */
|
||||
|
||||
#define ReadP(p) M[p]
|
||||
#define WriteP(p,d) M[p] = d
|
||||
|
||||
void cpu_ent_hist (uint32 pc, uint32 ea, t_uint64 ir, t_uint64 opnd);
|
||||
t_stat ch_show_chan (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||
t_stat ch6_end_nds (uint32 ch);
|
||||
uint32 ch6_set_flags (uint32 ch, uint32 unit, uint32 flags);
|
||||
t_stat ch6_err_disc (uint32 ch, uint32 unit, uint32 flags);
|
||||
t_stat ch6_req_rd (uint32 ch, uint32 unit, t_uint64 val, uint32 flags);
|
||||
t_stat ch6_req_wr (uint32 ch, uint32 unit);
|
||||
t_bool ch6_qconn (uint32 ch, uint32 unit);
|
||||
t_stat ch9_req_rd (uint32 ch, t_uint64 val);
|
||||
void ch9_set_atn (uint32 ch);
|
||||
void ch9_set_ioc (uint32 ch);
|
||||
void ch9_set_end (uint32 ch, uint32 ireq);
|
||||
t_bool ch9_qconn (uint32 ch);
|
||||
void ch_set_map (void);
|
||||
t_bool ch_qidle (void);
|
||||
|
||||
#endif
|
286
I7094/i7094_drm.c
Normal file
286
I7094/i7094_drm.c
Normal file
|
@ -0,0 +1,286 @@
|
|||
/* i7094_drm.c: 7289/7320A drum simulator
|
||||
|
||||
Copyright (c) 2005-2006, 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.
|
||||
|
||||
drm 7289/7320A "fast" drum
|
||||
|
||||
Very little is known about this device; the behavior simulated here is
|
||||
what is used by CTSS.
|
||||
|
||||
- The drum channel/controller behaves like a hybrid of the 7607 and the 7909.
|
||||
It responds to SCD (like the 7909), gets its address from the channel
|
||||
program (like the 7909), but responds to IOCD/IOCP (like the 7607) and
|
||||
sets channel flags (like the 7607).
|
||||
- The drum channel supports at least 2 drums. The maximum is 8 or less.
|
||||
Physical drums are numbered from 0.
|
||||
- Each drum has a capacity of 192K 36b words. This is divided into 6
|
||||
"logical" drum of 32KW each. Each "logical" drum has 16 2048W "sectors".
|
||||
Logical drums are numbered from 1.
|
||||
- The drum's behavior if a sector boundary is crossed in mid-transfer is
|
||||
unknown. CTSS never does this.
|
||||
- The drum's behavior with record operations is unknown. CTSS only uses
|
||||
IOCD and IOCP.
|
||||
- The drum's error indicators are unknown. CTSS regards bits <0:2,13> of
|
||||
the returned SCD data as errors, as well as the normal 7607 trap flags.
|
||||
- The drum's rotational speed is unknown.
|
||||
|
||||
Assumptions in this simulator:
|
||||
|
||||
- Transfers may not cross a sector boundary. An attempt to do so sets
|
||||
the EOF flag and causes an immediate disconnect.
|
||||
- The hardware never sets end of record.
|
||||
|
||||
For speed, the entire drum is buffered in memory.
|
||||
*/
|
||||
|
||||
#include "i7094_defs.h"
|
||||
#include <math.h>
|
||||
|
||||
#define DRM_NUMDR 8 /* drums/controller */
|
||||
|
||||
/* Drum geometry */
|
||||
|
||||
#define DRM_NUMWDS 2048 /* words/sector */
|
||||
#define DRM_SCMASK (DRM_NUMWDS - 1) /* sector mask */
|
||||
#define DRM_NUMSC 16 /* sectors/log drum */
|
||||
#define DRM_NUMWDL (DRM_NUMWDS * DRM_NUMSC) /* words/log drum */
|
||||
#define DRM_NUMLD 6 /* log drums/phys drum */
|
||||
#define DRM_SIZE (DRM_NUMLD * DRM_NUMWDL) /* words/phys drum */
|
||||
#define GET_POS(x) ((int) fmod (sim_gtime() / ((double) (x)), \
|
||||
((double) DRM_NUMWDS)))
|
||||
|
||||
/* Drum address from channel */
|
||||
|
||||
#define DRM_V_PHY 30 /* physical drum sel */
|
||||
#define DRM_M_PHY 07
|
||||
#define DRM_V_LOG 18 /* logical drum sel */
|
||||
#define DRM_M_LOG 07
|
||||
#define DRM_V_WDA 0 /* word address */
|
||||
#define DRM_M_WDA (DRM_NUMWDL - 1)
|
||||
#define DRM_GETPHY(x) (((uint32) ((x) >> DRM_V_PHY)) & DRM_M_PHY)
|
||||
#define DRM_GETLOG(x) ((((uint32) (x)) >> DRM_V_LOG) & DRM_M_LOG)
|
||||
#define DRM_GETWDA(x) ((((uint32) (x)) >> DRM_V_WDA) & DRM_M_WDA)
|
||||
#define DRM_GETDA(x) (((DRM_GETLOG(x) - 1) * DRM_NUMWDL) + DRM_GETWDA(x))
|
||||
|
||||
/* Drum controller states */
|
||||
|
||||
#define DRM_IDLE 0
|
||||
#define DRM_1ST 1
|
||||
#define DRM_DATA 2
|
||||
#define DRM_EOS 3
|
||||
|
||||
uint32 drm_ch = CH_G; /* drum channel */
|
||||
uint32 drm_da = 0; /* drum address */
|
||||
uint32 drm_sta = 0; /* state */
|
||||
uint32 drm_op = 0; /* operation */
|
||||
t_uint64 drm_chob = 0; /* output buf */
|
||||
uint32 drm_chob_v = 0; /* valid */
|
||||
int32 drm_time = 10; /* inter-word time */
|
||||
|
||||
extern uint32 ind_ioc;
|
||||
|
||||
t_stat drm_svc (UNIT *uptr);
|
||||
t_stat drm_reset (DEVICE *dptr);
|
||||
t_stat drm_chsel (uint32 ch, uint32 sel, uint32 unit);
|
||||
t_stat drm_chwr (uint32 ch, t_uint64 val, uint32 flags);
|
||||
t_bool drm_da_incr (void);
|
||||
|
||||
/* DRM data structures
|
||||
|
||||
drm_dev DRM device descriptor
|
||||
drm_unit DRM unit descriptor
|
||||
drm_reg DRM register list
|
||||
*/
|
||||
|
||||
DIB drm_dib = { &drm_chsel, &drm_chwr };
|
||||
|
||||
UNIT drm_unit[] = {
|
||||
{ UDATA (&drm_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+
|
||||
UNIT_MUSTBUF+UNIT_DISABLE, DRM_SIZE) },
|
||||
{ UDATA (&drm_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+
|
||||
UNIT_MUSTBUF+UNIT_DISABLE, DRM_SIZE) },
|
||||
{ UDATA (&drm_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+
|
||||
UNIT_MUSTBUF+UNIT_DISABLE+UNIT_DIS, DRM_SIZE) },
|
||||
{ UDATA (&drm_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+
|
||||
UNIT_MUSTBUF+UNIT_DISABLE+UNIT_DIS, DRM_SIZE) },
|
||||
{ UDATA (&drm_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+
|
||||
UNIT_MUSTBUF+UNIT_DISABLE+UNIT_DIS, DRM_SIZE) },
|
||||
{ UDATA (&drm_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+
|
||||
UNIT_MUSTBUF+UNIT_DISABLE+UNIT_DIS, DRM_SIZE) },
|
||||
{ UDATA (&drm_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+
|
||||
UNIT_MUSTBUF+UNIT_DISABLE+UNIT_DIS, DRM_SIZE) },
|
||||
{ UDATA (&drm_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+
|
||||
UNIT_MUSTBUF+UNIT_DISABLE+UNIT_DIS, DRM_SIZE) }
|
||||
};
|
||||
|
||||
REG drm_reg[] = {
|
||||
{ ORDATA (STATE, drm_sta, 2) },
|
||||
{ ORDATA (DA, drm_da, 18) },
|
||||
{ FLDATA (OP, drm_op, 0) },
|
||||
{ ORDATA (CHOB, drm_chob, 36) },
|
||||
{ FLDATA (CHOBV, drm_chob_v, 0) },
|
||||
{ DRDATA (TIME, drm_time, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (CHAN, drm_ch, 3), REG_HRO },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
MTAB drm_mtab[] = {
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "CHANNEL", NULL, NULL, &ch_show_chan },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEVICE drm_dev = {
|
||||
"DRM", drm_unit, drm_reg, drm_mtab,
|
||||
DRM_NUMDR, 8, 18, 1, 8, 36,
|
||||
NULL, NULL, &drm_reset,
|
||||
NULL, NULL, NULL,
|
||||
&drm_dib, DEV_DIS
|
||||
};
|
||||
|
||||
/* Channel select routine */
|
||||
|
||||
t_stat drm_chsel (uint32 ch, uint32 sel, uint32 unit)
|
||||
{
|
||||
drm_ch = ch; /* save channel */
|
||||
if (sel & CHSL_NDS) return ch6_end_nds (ch); /* nds? nop */
|
||||
|
||||
switch (sel) { /* case on cmd */
|
||||
|
||||
case CHSL_RDS: /* read */
|
||||
case CHSL_WRS: /* write */
|
||||
if (drm_sta != DRM_IDLE) return ERR_STALL; /* busy? */
|
||||
drm_sta = DRM_1ST; /* initial state */
|
||||
if (sel == CHSL_WRS) drm_op = 1; /* set read/write */
|
||||
else drm_op = 0; /* LCHx sends addr */
|
||||
break; /* wait for addr */
|
||||
|
||||
default: /* other */
|
||||
return STOP_ILLIOP;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Channel write routine */
|
||||
|
||||
t_stat drm_chwr (uint32 ch, t_uint64 val, uint32 flags)
|
||||
{
|
||||
uint32 u, l;
|
||||
int32 cp, dp;
|
||||
|
||||
if (drm_sta == DRM_1ST) {
|
||||
u = DRM_GETPHY (val); /* get unit */
|
||||
l = DRM_GETLOG (val); /* get logical address */
|
||||
if ((u >= DRM_NUMDR) || /* invalid unit? */
|
||||
(drm_unit[u].flags & UNIT_DIS) || /* disabled unit? */
|
||||
(l == 0) || (l > DRM_NUMLD)) { /* invalid log drum? */
|
||||
ch6_err_disc (ch, U_DRM, CHF_TRC); /* disconnect */
|
||||
drm_sta = DRM_IDLE;
|
||||
return SCPE_OK;
|
||||
}
|
||||
drm_da = DRM_GETDA (val); /* get drum addr */
|
||||
cp = GET_POS (drm_time); /* current pos in sec */
|
||||
dp = (drm_da & DRM_SCMASK) - cp; /* delta to desired pos */
|
||||
if (dp <= 0) dp = dp + DRM_NUMWDS; /* if neg, add rev */
|
||||
sim_activate (&drm_unit[u], dp * drm_time); /* schedule */
|
||||
if (drm_op) ch6_req_wr (ch, U_DRM); /* if write, get word */
|
||||
drm_sta = DRM_DATA;
|
||||
drm_chob = 0; /* clr, inval buffer */
|
||||
drm_chob_v = 0;
|
||||
}
|
||||
else {
|
||||
drm_chob = val & DMASK;
|
||||
drm_chob_v = 1;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Unit service - this code assumes the entire drum is buffered */
|
||||
|
||||
t_stat drm_svc (UNIT *uptr)
|
||||
{
|
||||
t_uint64 *fbuf = (t_uint64 *) uptr->filebuf;
|
||||
|
||||
if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? */
|
||||
ch6_err_disc (drm_ch, U_DRM, CHF_TRC); /* set TRC, disc */
|
||||
drm_sta = DRM_IDLE; /* drum is idle */
|
||||
return SCPE_UNATT;
|
||||
}
|
||||
if (drm_da >= DRM_SIZE) { /* nx logical drum? */
|
||||
ch6_err_disc (drm_ch, U_DRM, CHF_EOF); /* set EOF, disc */
|
||||
drm_sta = DRM_IDLE; /* drum is idle */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
switch (drm_sta) { /* case on state */
|
||||
|
||||
case DRM_DATA: /* data */
|
||||
if (drm_op) { /* write? */
|
||||
if (drm_chob_v) drm_chob_v = 0; /* valid? clear */
|
||||
else if (ch6_qconn (drm_ch, U_DRM)) /* no, chan conn? */
|
||||
ind_ioc = 1; /* io check */
|
||||
fbuf[drm_da] = drm_chob; /* get data */
|
||||
if (drm_da >= uptr->hwmark) uptr->hwmark = drm_da + 1;
|
||||
if (!drm_da_incr ()) ch6_req_wr (drm_ch, U_DRM);
|
||||
}
|
||||
else{ /* read */
|
||||
ch6_req_rd (drm_ch, U_DRM, fbuf[drm_da], 0); /* send word to channel */
|
||||
drm_da_incr ();
|
||||
}
|
||||
sim_activate (uptr, drm_time); /* next word */
|
||||
break;
|
||||
|
||||
case DRM_EOS: /* end sector */
|
||||
if (ch6_qconn (drm_ch, U_DRM)) /* drum still conn? */
|
||||
ch6_err_disc (drm_ch, U_DRM, CHF_EOF); /* set EOF, disc */
|
||||
drm_sta = DRM_IDLE; /* drum is idle */
|
||||
break;
|
||||
} /* end case */
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Increment drum address - return true, set new state if end of sector */
|
||||
|
||||
t_bool drm_da_incr (void)
|
||||
{
|
||||
drm_da = drm_da + 1;
|
||||
if (drm_da & DRM_SCMASK) return FALSE;
|
||||
drm_sta = DRM_EOS;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat drm_reset (DEVICE *dptr)
|
||||
{
|
||||
uint32 i;
|
||||
|
||||
drm_da = 0;
|
||||
drm_op = 0;
|
||||
drm_sta = DRM_IDLE;
|
||||
drm_chob = 0;
|
||||
drm_chob_v = 0;
|
||||
for (i = 0; i < dptr->numunits; i++) sim_cancel (dptr->units + i);
|
||||
return SCPE_OK;
|
||||
}
|
1172
I7094/i7094_dsk.c
Normal file
1172
I7094/i7094_dsk.c
Normal file
File diff suppressed because it is too large
Load diff
1789
I7094/i7094_io.c
Normal file
1789
I7094/i7094_io.c
Normal file
File diff suppressed because it is too large
Load diff
365
I7094/i7094_lp.c
Normal file
365
I7094/i7094_lp.c
Normal file
|
@ -0,0 +1,365 @@
|
|||
/* i7094_lp.c: IBM 716 line printer simulator
|
||||
|
||||
Copyright (c) 2003-2006, 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.
|
||||
|
||||
lpt 716 line printer
|
||||
|
||||
Internally, the 7094 works only with column binary and is limited to
|
||||
72 columns of data. Each row of the printed line is represented by
|
||||
72b of data (two 36b words). A complete print line consists of 12 rows
|
||||
(24 36b words).
|
||||
|
||||
The printer can also echo part of what it prints, namely, the digit rows
|
||||
plus the 8+3 and 8+4 combinations. This was intended for verification of
|
||||
check printing. Echoed data is interspersed with output data in the
|
||||
following order:
|
||||
|
||||
output row 9 to row 1
|
||||
echo row "8+4"
|
||||
output row 0
|
||||
echo row "8+3"
|
||||
output row 11
|
||||
echo row 9
|
||||
output row 12
|
||||
echo row 8 to row 1
|
||||
*/
|
||||
|
||||
#include "i7094_defs.h"
|
||||
|
||||
#define UNIT_V_CONS (UNIT_V_UF + 0) /* print to console */
|
||||
#define UNIT_CONS (1u << UNIT_V_CONS)
|
||||
#define UNIT_V_BZ (UNIT_V_UF + 1)
|
||||
#define UNIT_V_48 (UNIT_V_UF + 2)
|
||||
#define UNIT_BZ (1 << UNIT_V_BZ)
|
||||
#define UNIT_48 (1 << UNIT_V_48)
|
||||
#define GET_PCHAIN(x) (((x) >> UNIT_V_BZ) & (UNIT_BZ|UNIT_48))
|
||||
|
||||
#define LPT_BINLNT 24 /* bin buffer length */
|
||||
#define LPT_ECHLNT 22 /* echo buffer length */
|
||||
#define LPT_CHRLNT 80 /* char buffer length */
|
||||
|
||||
#define LPS_INIT 0 /* init state */
|
||||
#define LPS_DATA 1 /* print data state */
|
||||
#define ECS_DATA 2 /* echo data state */
|
||||
#define LPS_END 3 /* end state */
|
||||
|
||||
#define LPB_9ROW 0 /* bin buf: 9 row */
|
||||
#define LPB_8ROW 2 /* 8 row */
|
||||
#define LPB_4ROW 10 /* 4 row */
|
||||
#define LPB_3ROW 12 /* 3 row */
|
||||
#define LPB_1ROW 16 /* 1 row */
|
||||
#define LPB_12ROW 22 /* 12 row */
|
||||
|
||||
#define ECB_84ROW 0 /* echo buf: 8-4 row */
|
||||
#define ECB_83ROW 2 /* 8-3 row */
|
||||
#define ECB_9ROW 4 /* 9 row */
|
||||
|
||||
#define ECHO_F 0100 /* echo map: flag */
|
||||
#define ECHO_MASK 0037 /* mask */
|
||||
|
||||
#define CMD_BIN 1 /* cmd: bcd/bin */
|
||||
#define CMD_ECHO 2 /* cmd: wrs/rds */
|
||||
|
||||
uint32 lpt_sta = 0; /* state */
|
||||
uint32 lpt_bptr = 0; /* buffer ptr */
|
||||
uint32 lpt_cmd = 0; /* modes */
|
||||
uint32 lpt_tstart = 27500; /* timing */
|
||||
uint32 lpt_tstop = 27500;
|
||||
uint32 lpt_tleft = 150;
|
||||
uint32 lpt_tright = 4000;
|
||||
t_uint64 lpt_chob = 0;
|
||||
uint32 lpt_chob_v = 0;
|
||||
t_uint64 lpt_bbuf[LPT_BINLNT]; /* binary buffer */
|
||||
t_uint64 lpt_ebuf[LPT_ECHLNT]; /* echo buffer */
|
||||
|
||||
|
||||
/* Echo ordering map */
|
||||
|
||||
static const uint8 echo_map[LPT_BINLNT + LPT_ECHLNT] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, /* write 9 to 1 */
|
||||
8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17,
|
||||
0+ECHO_F, 1+ECHO_F, /* echo 8+4 */
|
||||
18, 19, /* write 0 */
|
||||
2+ECHO_F, 3+ECHO_F, /* echo 8+3 */
|
||||
20, 21, /* write 11 */
|
||||
4+ECHO_F, 5+ECHO_F, /* echo 9 */
|
||||
22, 23, /* write 12 */
|
||||
6+ECHO_F, 7+ECHO_F, 8+ECHO_F, 9+ECHO_F, /* echo 8 to 1 */
|
||||
10+ECHO_F, 11+ECHO_F, 12+ECHO_F, 13+ECHO_F,
|
||||
14+ECHO_F, 15+ECHO_F, 16+ECHO_F, 17+ECHO_F,
|
||||
18+ECHO_F, 19+ECHO_F, 20+ECHO_F, 21+ECHO_F
|
||||
};
|
||||
|
||||
extern uint32 ind_ioc;
|
||||
extern t_uint64 bit_masks[36];
|
||||
extern uint32 col_masks[12];
|
||||
extern char bcd_to_ascii_a[64];
|
||||
extern char bcd_to_ascii_h[64];
|
||||
extern char bcd_to_pca[64];
|
||||
extern char bcd_to_pch[64];
|
||||
|
||||
char *pch_table[4] = {
|
||||
bcd_to_ascii_h, bcd_to_ascii_a, bcd_to_pch, bcd_to_pca,
|
||||
};
|
||||
|
||||
t_stat lpt_reset (DEVICE *dptr);
|
||||
t_stat lpt_svc (UNIT *uptr);
|
||||
t_stat lpt_chsel (uint32 ch, uint32 sel, uint32 unit);
|
||||
t_stat lpt_chwr (uint32 ch, t_uint64 val, uint32 flags);
|
||||
t_stat lpt_end_line (UNIT *uptr);
|
||||
|
||||
extern char colbin_to_bcd (uint32 colbin);
|
||||
|
||||
/* LPT data structures
|
||||
|
||||
lpt_dev LPT device descriptor
|
||||
lpt_unit LPT unit descriptor
|
||||
lpt_reg LPT register list
|
||||
*/
|
||||
|
||||
DIB lpt_dib = { &lpt_chsel, &lpt_chwr };
|
||||
|
||||
UNIT lpt_unit = {
|
||||
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_CONS, 0)
|
||||
};
|
||||
|
||||
REG lpt_reg[] = {
|
||||
{ ORDATA (STATE, lpt_sta, 2) },
|
||||
{ ORDATA (CMD, lpt_cmd, 2) },
|
||||
{ ORDATA (CHOB, lpt_chob, 36) },
|
||||
{ FLDATA (CHOBV, lpt_chob_v, 0) },
|
||||
{ DRDATA (BPTR, lpt_bptr, 6), PV_LEFT },
|
||||
{ BRDATA (BUF, lpt_bbuf, 8, 36, LPT_BINLNT) },
|
||||
{ BRDATA (EBUF, lpt_ebuf, 8, 36, LPT_ECHLNT) },
|
||||
{ DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TSTART, lpt_tstart, 24), PV_LEFT + REG_NZ },
|
||||
{ DRDATA (TSTOP, lpt_tstop, 24), PV_LEFT + REG_NZ },
|
||||
{ DRDATA (TLEFT, lpt_tleft, 24), PV_LEFT + REG_NZ },
|
||||
{ DRDATA (TRIGHT, lpt_tright, 24), PV_LEFT + REG_NZ },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
MTAB lpt_mod[] = {
|
||||
{ UNIT_CONS, UNIT_CONS, "default to console", "DEFAULT" },
|
||||
{ UNIT_CONS, 0 , "no default device", "NODEFAULT" },
|
||||
{ UNIT_48, UNIT_48, "48 character chain", "48" },
|
||||
{ UNIT_48, 0, "64 character chain", "64" },
|
||||
{ UNIT_BZ, UNIT_BZ, "business set", "BUSINESS" },
|
||||
{ UNIT_BZ, 0, "Fortran set", "FORTRAN" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEVICE lpt_dev = {
|
||||
"LPT", &lpt_unit, lpt_reg, lpt_mod,
|
||||
1, 10, 31, 1, 8, 7,
|
||||
NULL, NULL, &lpt_reset,
|
||||
NULL, NULL, NULL,
|
||||
&lpt_dib, DEV_DISABLE
|
||||
};
|
||||
|
||||
/* Channel select routine */
|
||||
|
||||
t_stat lpt_chsel (uint32 ch, uint32 sel, uint32 unit)
|
||||
{
|
||||
if (sel & CHSL_NDS) return ch6_end_nds (ch); /* nds? nop */
|
||||
|
||||
switch (sel) { /* case on cmd */
|
||||
|
||||
case CHSL_RDS: /* read */
|
||||
case CHSL_WRS: /* write */
|
||||
if (!(lpt_unit.flags & (UNIT_ATT|UNIT_CONS))) /* not attached? */
|
||||
return SCPE_UNATT;
|
||||
if (sim_is_active (&lpt_unit)) /* busy? */
|
||||
return ERR_STALL;
|
||||
lpt_cmd = ((unit & 02)? CMD_BIN: 0) | /* save modes */
|
||||
((sel == CHSL_RDS)? CMD_ECHO: 0);
|
||||
lpt_sta = LPS_INIT; /* initial state */
|
||||
sim_activate (&lpt_unit, lpt_tstart); /* start reader */
|
||||
break;
|
||||
|
||||
default: /* other */
|
||||
return STOP_ILLIOP;
|
||||
}
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Channel write routine
|
||||
|
||||
- Normal mode is processed here
|
||||
- Echo mode is processed in the service routine (like a read) */
|
||||
|
||||
t_stat lpt_chwr (uint32 ch, t_uint64 val, uint32 eorfl)
|
||||
{
|
||||
uint32 u = (lpt_cmd & CMD_BIN)? U_LPBIN: U_LPBCD; /* reconstruct unit */
|
||||
|
||||
lpt_chob = val & DMASK; /* store data */
|
||||
lpt_chob_v = 1; /* set valid */
|
||||
if (lpt_sta == ECS_DATA) return SCPE_OK;
|
||||
if (lpt_sta == LPS_DATA) {
|
||||
lpt_bbuf[lpt_bptr++] = lpt_chob; /* store data */
|
||||
if (eorfl || /* end record, or */
|
||||
((lpt_cmd & CMD_BIN)? /* last word in buffer? */
|
||||
(lpt_bptr > (LPB_1ROW + 1)): /* (binary mode) */
|
||||
(lpt_bptr > (LPB_12ROW + 1)))) { /* (normal mode) */
|
||||
ch6_set_flags (CH_A, u, CHF_EOR); /* set eor */
|
||||
return lpt_end_line (&lpt_unit);
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
return SCPE_IERR;
|
||||
}
|
||||
|
||||
/* Unit timeout */
|
||||
|
||||
t_stat lpt_svc (UNIT *uptr)
|
||||
{
|
||||
uint32 u = (lpt_cmd & CMD_BIN)? U_LPBIN: U_LPBCD; /* reconstruct unit */
|
||||
uint32 i, map;
|
||||
|
||||
switch (lpt_sta) { /* case on state */
|
||||
|
||||
case LPS_INIT: /* initial state */
|
||||
for (i = 0; i < LPT_BINLNT; i++) /* clear data buffer */
|
||||
lpt_bbuf[i] = 0;
|
||||
for (i = 0; i < LPT_ECHLNT; i++) /* clear echo buffer */
|
||||
lpt_ebuf[i] = 0;
|
||||
if (lpt_cmd & CMD_BIN) lpt_bptr = LPB_1ROW; /* set buffer ptr */
|
||||
else lpt_bptr = LPB_9ROW;
|
||||
if (lpt_cmd & CMD_ECHO) lpt_sta = ECS_DATA; /* set data state */
|
||||
else lpt_sta = LPS_DATA;
|
||||
ch6_req_wr (CH_A, u); /* request channel */
|
||||
lpt_chob = 0; /* clr, inval buffer */
|
||||
lpt_chob_v = 0;
|
||||
sim_activate (uptr, lpt_tleft); /* go again */
|
||||
break;
|
||||
|
||||
case LPS_DATA: /* print data state */
|
||||
if (!ch6_qconn (CH_A, u)) /* disconnect? */
|
||||
return lpt_end_line (uptr); /* line is done */
|
||||
if (lpt_chob_v) lpt_chob_v = 0; /* valid? clear */
|
||||
else ind_ioc = 1; /* no, io check */
|
||||
ch6_req_wr (CH_A, u); /* request chan again */
|
||||
sim_activate (uptr, (lpt_bptr & 1)? lpt_tleft: lpt_tright);
|
||||
break;
|
||||
|
||||
case ECS_DATA: /* echo data state */
|
||||
map = echo_map[lpt_bptr++]; /* map column */
|
||||
if (map == ECHO_F) { /* first echo? */
|
||||
lpt_ebuf[ECB_84ROW] = lpt_bbuf[LPB_8ROW] & lpt_bbuf[LPB_4ROW];
|
||||
lpt_ebuf[ECB_84ROW + 1] = lpt_bbuf[LPB_8ROW + 1] & lpt_bbuf[LPB_4ROW + 1];
|
||||
lpt_ebuf[ECB_83ROW] = lpt_bbuf[LPB_8ROW] & lpt_bbuf[LPB_3ROW];
|
||||
lpt_ebuf[ECB_83ROW + 1] = lpt_bbuf[LPB_8ROW + 1] & lpt_bbuf[LPB_3ROW + 1];
|
||||
for (i = 0; i < 18; i++) /* copy rows 9.. 1 */
|
||||
lpt_ebuf[ECB_9ROW + i] = lpt_bbuf[LPB_9ROW + i];
|
||||
}
|
||||
if (map & ECHO_F) { /* echo cycle */
|
||||
ch6_req_rd (CH_A, u, lpt_ebuf[map & ECHO_MASK], 0);
|
||||
if (lpt_bptr >= (LPT_BINLNT + LPT_ECHLNT))
|
||||
return lpt_end_line (uptr); /* done? */
|
||||
sim_activate (uptr, lpt_tleft); /* short timer */
|
||||
}
|
||||
else { /* print cycle */
|
||||
if (lpt_chob_v) lpt_chob_v = 0; /* valid? clear */
|
||||
else ind_ioc = 1; /* no, io check */
|
||||
lpt_bbuf[map] = lpt_chob; /* store in buffer */
|
||||
sim_activate (uptr, (lpt_bptr & 1)? lpt_tleft: lpt_tright);
|
||||
}
|
||||
if (!(echo_map[lpt_bptr] & ECHO_F)) /* print word next? */
|
||||
ch6_req_wr (CH_A, u); /* req channel */
|
||||
break;
|
||||
|
||||
case LPS_END: /* end state */
|
||||
if (ch6_qconn (CH_A, u)) { /* lpt still conn? */
|
||||
lpt_sta = LPS_INIT; /* initial state */
|
||||
sim_activate (uptr, 1); /* next line */
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* End line routine */
|
||||
|
||||
t_stat lpt_end_line (UNIT *uptr)
|
||||
{
|
||||
uint32 i, j, col, row, bufw, colbin;
|
||||
char *pch, bcd, lpt_cbuf[LPT_CHRLNT + 1];
|
||||
t_uint64 dat;
|
||||
|
||||
pch = pch_table[GET_PCHAIN (lpt_unit.flags)]; /* get print chain */
|
||||
for (col = 0; col < (LPT_CHRLNT + 1); col++) /* clear ascii buf */
|
||||
lpt_cbuf[col] = ' ';
|
||||
for (col = 0; col < 72; col++) { /* proc 72 columns */
|
||||
colbin = 0;
|
||||
dat = bit_masks[35 - (col % 36)]; /* mask for column */
|
||||
for (row = 0; row < 12; row++) { /* proc 12 rows */
|
||||
bufw = (row * 2) + (col / 36); /* index to buffer */
|
||||
if (lpt_bbuf[bufw] & dat) colbin |= col_masks[row];
|
||||
}
|
||||
bcd = colbin_to_bcd (colbin); /* column bin -> BCD */
|
||||
lpt_cbuf[col] = pch[bcd]; /* -> ASCII */
|
||||
}
|
||||
for (i = LPT_CHRLNT; (i > 0) &&
|
||||
(lpt_cbuf[i - 1] == ' '); --i) ; /* trim spaces */
|
||||
lpt_cbuf[i++] = '\n'; /* append nl */
|
||||
if (uptr->flags & UNIT_ATT) { /* file? */
|
||||
fxwrite (lpt_cbuf, 1, i, uptr->fileref); /* write line */
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
perror ("LPT I/O error");
|
||||
clearerr (uptr->fileref);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
uptr->pos = ftell (uptr->fileref); /* update position */
|
||||
}
|
||||
else if (uptr->flags & UNIT_CONS) { /* print to console? */
|
||||
for (j = 0; j < i; j++) sim_putchar (lpt_cbuf[j]);
|
||||
sim_putchar ('\r');
|
||||
}
|
||||
else return SCPE_UNATT; /* otherwise error */
|
||||
uptr->pos = uptr->pos + strlen (lpt_cbuf); /* count char */
|
||||
lpt_sta = LPS_END; /* end line state */
|
||||
sim_cancel (uptr); /* cancel current */
|
||||
sim_activate (uptr, lpt_tstop); /* long timer */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat lpt_reset (DEVICE *dptr)
|
||||
{
|
||||
uint32 i;
|
||||
|
||||
for (i = 0; i < LPT_BINLNT; i++) lpt_bbuf[i] = 0; /* clear bin buf */
|
||||
for (i = 0; i < LPT_ECHLNT; i++) lpt_ebuf[i] = 0; /* clear echo buf */
|
||||
lpt_sta = 0; /* clear state */
|
||||
lpt_cmd = 0; /* clear modes */
|
||||
lpt_bptr = 0; /* clear buf ptr */
|
||||
lpt_chob = 0;
|
||||
lpt_chob_v = 0;
|
||||
sim_cancel (&lpt_unit); /* stop printer */
|
||||
return SCPE_OK;
|
||||
}
|
826
I7094/i7094_mt.c
Normal file
826
I7094/i7094_mt.c
Normal file
|
@ -0,0 +1,826 @@
|
|||
/* i7094_mt.c: IBM 7094 magnetic tape simulator
|
||||
|
||||
Copyright (c) 2003-2006, 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.
|
||||
|
||||
mt magtape simulator
|
||||
*/
|
||||
|
||||
#include "i7094_defs.h"
|
||||
#include "sim_tape.h"
|
||||
|
||||
#define UST u3 /* unit state */
|
||||
#define UCH u4 /* channel number */
|
||||
#define MTUF_V_LDN (MTUF_V_UF + 0)
|
||||
#define MTUF_LDN (1 << MTUF_V_LDN)
|
||||
#define MT_MAXFR ((1 << 18) + 2)
|
||||
|
||||
#define QCHRONO(c,u) ((cpu_model & I_CT) && \
|
||||
((c) == CHRONO_CH) && ((u) == CHRONO_UNIT))
|
||||
|
||||
uint8 *mtxb[NUM_CHAN] = { NULL }; /* xfer buffer */
|
||||
uint32 mt_unit[NUM_CHAN]; /* unit */
|
||||
uint32 mt_bptr[NUM_CHAN];
|
||||
uint32 mt_blnt[NUM_CHAN];
|
||||
t_uint64 mt_chob[NUM_CHAN];
|
||||
uint32 mt_chob_v[NUM_CHAN];
|
||||
uint32 mt_tshort = 2;
|
||||
uint32 mt_twef = 25000; /* 50 msec */
|
||||
uint32 mt_tstart = 29000; /* 58 msec */
|
||||
uint32 mt_tstop = 10000; /* 20 msec */
|
||||
uint32 mt_tword = 50; /* 125 usec */
|
||||
|
||||
static const uint8 odd_par[64] = {
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1
|
||||
};
|
||||
|
||||
static const char *tape_stat[] = {
|
||||
"OK", "TMK", "UNATT", "IOERR", "INVRECLNT",
|
||||
"FMT", "BOT", "EOM", "RECERR", "WRPROT"
|
||||
};
|
||||
|
||||
extern uint32 PC;
|
||||
extern uint32 cpu_model;
|
||||
extern uint32 ind_ioc;
|
||||
extern FILE *sim_deb;
|
||||
extern char *sel_name[];
|
||||
|
||||
t_stat mt_chsel (uint32 ch, uint32 sel, uint32 unit);
|
||||
t_stat mt_chwr (uint32 ch, t_uint64 val, uint32 flags);
|
||||
t_stat mt_rec_end (UNIT *uptr);
|
||||
t_stat mt_svc (UNIT *uptr);
|
||||
t_stat mt_reset (DEVICE *dptr);
|
||||
t_stat mt_attach (UNIT *uptr, char *cptr);
|
||||
t_stat mt_boot (int32 unitno, DEVICE *dptr);
|
||||
t_stat mt_map_err (UNIT *uptr, t_stat st);
|
||||
|
||||
extern uint32 chrono_rd (uint8 *buf, uint32 bufsiz);
|
||||
|
||||
/* MT data structures
|
||||
|
||||
mt_dev MT device descriptor
|
||||
mt_unit MT unit list
|
||||
mt_reg MT register list
|
||||
mt_mod MT modifier list
|
||||
*/
|
||||
|
||||
DIB mt_dib = { &mt_chsel, &mt_chwr };
|
||||
|
||||
MTAB mt_mod[] = {
|
||||
{ MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL },
|
||||
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL },
|
||||
{ MTUF_LDN, 0, "high density", "HIGH", NULL },
|
||||
{ MTUF_LDN, MTUF_LDN, "low density", "LOW", NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
UNIT mta_unit[] = {
|
||||
{ UDATA (NULL, UNIT_DIS, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) }
|
||||
};
|
||||
|
||||
REG mta_reg[] = {
|
||||
{ ORDATA (UNIT, mt_unit[0], 5) },
|
||||
{ ORDATA (CHOB, mt_chob[0], 36) },
|
||||
{ FLDATA (CHOBV, mt_chob_v[0], 0) },
|
||||
{ DRDATA (BPTR, mt_bptr[0], 16), PV_LEFT },
|
||||
{ DRDATA (BLNT, mt_blnt[0], 16), PV_LEFT },
|
||||
{ BRDATA (BUF, NULL, 8, 7, MT_MAXFR) },
|
||||
{ DRDATA (TWEF, mt_twef, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TSHORT, mt_tshort, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TSTART, mt_tstart, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TSTOP, mt_tstop, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TWORD, mt_tword, 24), REG_NZ + PV_LEFT },
|
||||
{ URDATA (UST, mta_unit[0].UST, 8, 5, 0, MT_NUMDR + 1, 0) },
|
||||
{ URDATA (POS, mta_unit[0].pos, 10, T_ADDR_W, 0,
|
||||
MT_NUMDR + 1, PV_LEFT | REG_RO) },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
UNIT mtb_unit[] = {
|
||||
{ UDATA (NULL, UNIT_DIS, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) }
|
||||
};
|
||||
|
||||
REG mtb_reg[] = {
|
||||
{ ORDATA (UNIT, mt_unit[1], 5) },
|
||||
{ ORDATA (CHOB, mt_chob[1], 36) },
|
||||
{ FLDATA (CHOBV, mt_chob_v[1], 0) },
|
||||
{ DRDATA (BPTR, mt_bptr[1], 16), PV_LEFT },
|
||||
{ DRDATA (BLNT, mt_blnt[1], 16), PV_LEFT },
|
||||
{ BRDATA (BUF, NULL, 8, 7, MT_MAXFR) },
|
||||
{ DRDATA (TWEF, mt_twef, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TSHORT, mt_tshort, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TSTART, mt_tstart, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TSTOP, mt_tstop, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TWORD, mt_tword, 24), REG_NZ + PV_LEFT },
|
||||
{ URDATA (UST, mtb_unit[0].UST, 8, 5, 0, MT_NUMDR + 1, 0) },
|
||||
{ URDATA (POS, mtb_unit[0].pos, 10, T_ADDR_W, 0,
|
||||
MT_NUMDR + 1, PV_LEFT | REG_RO) },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
UNIT mtc_unit[] = {
|
||||
{ UDATA (NULL, UNIT_DIS, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) }
|
||||
};
|
||||
|
||||
REG mtc_reg[] = {
|
||||
{ ORDATA (UNIT, mt_unit[2], 5) },
|
||||
{ ORDATA (CHOB, mt_chob[2], 36) },
|
||||
{ FLDATA (CHOBV, mt_chob_v[2], 0) },
|
||||
{ DRDATA (BPTR, mt_bptr[2], 16), PV_LEFT },
|
||||
{ DRDATA (BLNT, mt_blnt[2], 16), PV_LEFT },
|
||||
{ BRDATA (BUF, NULL, 8, 7, MT_MAXFR) },
|
||||
{ DRDATA (TWEF, mt_twef, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TSHORT, mt_tshort, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TSTART, mt_tstart, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TSTOP, mt_tstop, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TWORD, mt_tword, 24), REG_NZ + PV_LEFT },
|
||||
{ URDATA (UST, mtc_unit[0].UST, 8, 5, 0, MT_NUMDR + 1, 0) },
|
||||
{ URDATA (POS, mtc_unit[0].pos, 10, T_ADDR_W, 0,
|
||||
MT_NUMDR + 1, PV_LEFT | REG_RO) },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
UNIT mtd_unit[] = {
|
||||
{ UDATA (NULL, UNIT_DIS, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) }
|
||||
};
|
||||
|
||||
REG mtd_reg[] = {
|
||||
{ ORDATA (UNIT, mt_unit[3], 5) },
|
||||
{ ORDATA (CHOB, mt_chob[3], 36) },
|
||||
{ FLDATA (CHOBV, mt_chob_v[3], 0) },
|
||||
{ DRDATA (BPTR, mt_bptr[3], 16), PV_LEFT },
|
||||
{ DRDATA (BLNT, mt_blnt[3], 16), PV_LEFT },
|
||||
{ BRDATA (BUF, NULL, 8, 7, MT_MAXFR) },
|
||||
{ DRDATA (TWEF, mt_twef, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TSHORT, mt_tshort, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TSTART, mt_tstart, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TSTOP, mt_tstop, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TWORD, mt_tword, 24), REG_NZ + PV_LEFT },
|
||||
{ URDATA (UST, mtd_unit[0].UST, 8, 5, 0, MT_NUMDR + 1, 0) },
|
||||
{ URDATA (POS, mtd_unit[0].pos, 10, T_ADDR_W, 0,
|
||||
MT_NUMDR + 1, PV_LEFT | REG_RO) },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
UNIT mte_unit[] = {
|
||||
{ UDATA (NULL, UNIT_DIS, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) }
|
||||
};
|
||||
|
||||
REG mte_reg[] = {
|
||||
{ ORDATA (UNIT, mt_unit[4], 5) },
|
||||
{ ORDATA (CHOB, mt_chob[4], 36) },
|
||||
{ FLDATA (CHOBV, mt_chob_v[4], 0) },
|
||||
{ DRDATA (BPTR, mt_bptr[4], 16), PV_LEFT },
|
||||
{ DRDATA (BLNT, mt_blnt[4], 16), PV_LEFT },
|
||||
{ BRDATA (BUF, NULL, 8, 7, MT_MAXFR) },
|
||||
{ DRDATA (TWEF, mt_twef, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TSHORT, mt_tshort, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TSTART, mt_tstart, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TSTOP, mt_tstop, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TWORD, mt_tword, 24), REG_NZ + PV_LEFT },
|
||||
{ URDATA (UST, mte_unit[0].UST, 8, 5, 0, MT_NUMDR + 1, 0) },
|
||||
{ URDATA (POS, mte_unit[0].pos, 10, T_ADDR_W, 0,
|
||||
MT_NUMDR + 1, PV_LEFT | REG_RO) },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
UNIT mtf_unit[] = {
|
||||
{ UDATA (NULL, UNIT_DIS, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) }
|
||||
};
|
||||
|
||||
REG mtf_reg[] = {
|
||||
{ ORDATA (UNIT, mt_unit[5], 5) },
|
||||
{ ORDATA (CHOB, mt_chob[5], 36) },
|
||||
{ FLDATA (CHOBV, mt_chob_v[5], 0) },
|
||||
{ DRDATA (BPTR, mt_bptr[5], 16), PV_LEFT },
|
||||
{ DRDATA (BLNT, mt_blnt[5], 16), PV_LEFT },
|
||||
{ BRDATA (BUF, NULL, 8, 7, MT_MAXFR) },
|
||||
{ DRDATA (TWEF, mt_twef, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TSHORT, mt_tshort, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TSTART, mt_tstart, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TSTOP, mt_tstop, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TWORD, mt_tword, 24), REG_NZ + PV_LEFT },
|
||||
{ URDATA (UST, mtf_unit[0].UST, 8, 5, 0, MT_NUMDR + 1, 0) },
|
||||
{ URDATA (POS, mtf_unit[0].pos, 10, T_ADDR_W, 0,
|
||||
MT_NUMDR + 1, PV_LEFT | REG_RO) },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
UNIT mtg_unit[] = {
|
||||
{ UDATA (NULL, UNIT_DIS, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) }
|
||||
};
|
||||
|
||||
REG mtg_reg[] = {
|
||||
{ ORDATA (UNIT, mt_unit[6], 5) },
|
||||
{ ORDATA (CHOB, mt_chob[6], 36) },
|
||||
{ FLDATA (CHOBV, mt_chob_v[6], 0) },
|
||||
{ DRDATA (BPTR, mt_bptr[6], 16), PV_LEFT },
|
||||
{ DRDATA (BLNT, mt_blnt[6], 16), PV_LEFT },
|
||||
{ BRDATA (BUF, NULL, 8, 7, MT_MAXFR) },
|
||||
{ DRDATA (TWEF, mt_twef, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TSHORT, mt_tshort, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TSTART, mt_tstart, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TSTOP, mt_tstop, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TWORD, mt_tword, 24), REG_NZ + PV_LEFT },
|
||||
{ URDATA (UST, mtg_unit[0].UST, 8, 5, 0, MT_NUMDR + 1, 0) },
|
||||
{ URDATA (POS, mtg_unit[0].pos, 10, T_ADDR_W, 0,
|
||||
MT_NUMDR + 1, PV_LEFT | REG_RO) },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
UNIT mth_unit[] = {
|
||||
{ UDATA (NULL, UNIT_DIS, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
|
||||
{ UDATA (&mt_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) }
|
||||
};
|
||||
|
||||
REG mth_reg[] = {
|
||||
{ ORDATA (UNIT, mt_unit[7], 5) },
|
||||
{ ORDATA (CHOB, mt_chob[7], 36) },
|
||||
{ FLDATA (CHOBV, mt_chob_v[7], 0) },
|
||||
{ DRDATA (BPTR, mt_bptr[7], 16), PV_LEFT },
|
||||
{ DRDATA (BLNT, mt_blnt[7], 16), PV_LEFT },
|
||||
{ BRDATA (BUF, NULL, 8, 7, MT_MAXFR) },
|
||||
{ DRDATA (TWEF, mt_twef, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TSHORT, mt_tshort, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TSTART, mt_tstart, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TSTOP, mt_tstop, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TWORD, mt_tword, 24), REG_NZ + PV_LEFT },
|
||||
{ URDATA (UST, mth_unit[0].UST, 8, 5, 0, MT_NUMDR + 1, 0) },
|
||||
{ URDATA (POS, mth_unit[0].pos, 10, T_ADDR_W, 0,
|
||||
MT_NUMDR + 1, PV_LEFT | REG_RO) },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
DEVICE mt_dev[NUM_CHAN] = {
|
||||
{
|
||||
"MTA", mta_unit, mta_reg, mt_mod,
|
||||
MT_NUMDR + 1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &mt_reset,
|
||||
&mt_boot, &mt_attach, &sim_tape_detach,
|
||||
&mt_dib, DEV_DEBUG
|
||||
},
|
||||
{
|
||||
"MTB", mtb_unit, mtb_reg, mt_mod,
|
||||
MT_NUMDR + 1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &mt_reset,
|
||||
NULL, &mt_attach, &sim_tape_detach,
|
||||
&mt_dib, DEV_DIS|DEV_DEBUG
|
||||
},
|
||||
{
|
||||
"MTC", mtc_unit, mtc_reg, mt_mod,
|
||||
MT_NUMDR + 1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &mt_reset,
|
||||
NULL, &mt_attach, &sim_tape_detach,
|
||||
&mt_dib, DEV_DIS|DEV_DEBUG
|
||||
},
|
||||
{
|
||||
"MTD", mtd_unit, mtd_reg, mt_mod,
|
||||
MT_NUMDR + 1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &mt_reset,
|
||||
NULL, &mt_attach, &sim_tape_detach,
|
||||
&mt_dib, DEV_DIS|DEV_DEBUG
|
||||
},
|
||||
{
|
||||
"MTE", mte_unit, mte_reg, mt_mod,
|
||||
MT_NUMDR + 1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &mt_reset,
|
||||
NULL, &mt_attach, &sim_tape_detach,
|
||||
&mt_dib, DEV_DIS|DEV_DEBUG
|
||||
},
|
||||
{
|
||||
"MTF", mtf_unit, mtf_reg, mt_mod,
|
||||
MT_NUMDR + 1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &mt_reset,
|
||||
NULL, &mt_attach, &sim_tape_detach,
|
||||
&mt_dib, DEV_DIS|DEV_DEBUG
|
||||
},
|
||||
{
|
||||
"MTG", mtg_unit, mtg_reg, mt_mod,
|
||||
MT_NUMDR + 1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &mt_reset,
|
||||
NULL, &mt_attach, &sim_tape_detach,
|
||||
&mt_dib, DEV_DIS|DEV_DEBUG
|
||||
},
|
||||
{
|
||||
"MTH", mth_unit, mth_reg, mt_mod,
|
||||
MT_NUMDR + 1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &mt_reset,
|
||||
NULL, &mt_attach, &sim_tape_detach,
|
||||
&mt_dib, DEV_DIS|DEV_DEBUG
|
||||
}
|
||||
};
|
||||
|
||||
/* Select controller
|
||||
|
||||
Inputs:
|
||||
ch = channel
|
||||
cmd = select command
|
||||
unit = unit
|
||||
Outputs:
|
||||
status = SCPE_OK if ok
|
||||
STOP_STALL if busy
|
||||
error code if error
|
||||
*/
|
||||
|
||||
static const int mt_must_att[CHSL_NUM] = {
|
||||
0, 1, 1, 0, 1, 1, 0, 0,
|
||||
1, 1, 1, 1, 1, 1, 0, 0
|
||||
};
|
||||
|
||||
static const int mt_will_wrt[CHSL_NUM] = {
|
||||
0, 0, 1, 0, 0, 1, 0, 0,
|
||||
1, 1, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
t_stat mt_chsel (uint32 ch, uint32 cmd, uint32 unit)
|
||||
{
|
||||
UNIT *uptr;
|
||||
uint32 u = unit & 017;
|
||||
|
||||
if ((ch >= NUM_CHAN) || (cmd == 0) || (cmd >= CHSL_NUM))
|
||||
return SCPE_IERR; /* invalid arg? */
|
||||
if (mt_dev[ch].flags & DEV_DIS) return STOP_NXDEV; /* disabled? */
|
||||
if ((u == 0) || (u > MT_NUMDR)) return STOP_NXDEV; /* valid unit? */
|
||||
uptr = mt_dev[ch].units + u; /* get unit ptr */
|
||||
if (uptr->flags & UNIT_DIS) return STOP_NXDEV; /* disabled? */
|
||||
if (mt_unit[ch] || sim_is_active (uptr)) /* ctrl or unit busy? */
|
||||
return ERR_STALL; /* stall */
|
||||
if (QCHRONO (ch, u)) { /* Chronolog clock? */
|
||||
if (cmd != CHSL_RDS) return STOP_ILLIOP; /* only reads */
|
||||
sim_activate (uptr, mt_tword); /* responds quickly */
|
||||
}
|
||||
else { /* real tape */
|
||||
if (!(uptr->flags & UNIT_ATT) && mt_must_att[cmd]) /* unit unatt? */
|
||||
return SCPE_UNATT;
|
||||
if (sim_tape_wrp (uptr) && mt_will_wrt[cmd]) /* unit wrp && write? */
|
||||
return STOP_WRP;
|
||||
if (DEBUG_PRS (mt_dev[ch])) fprintf (sim_deb,
|
||||
">>%s%d %s, pos = %d\n", mt_dev[ch].name, u, sel_name[cmd], uptr->pos);
|
||||
|
||||
switch (cmd) { /* case on cmd */
|
||||
|
||||
case CHSL_RDS:
|
||||
case CHSL_WRS:
|
||||
case CHSL_BSR:
|
||||
case CHSL_BSF: /* rd, wr, backspace */
|
||||
sim_activate (uptr, mt_tstart); /* schedule op */
|
||||
break;
|
||||
|
||||
case CHSL_WEF: /* write eof? */
|
||||
sim_activate (uptr, mt_twef); /* schedule op */
|
||||
break;
|
||||
|
||||
case CHSL_RUN:
|
||||
sim_activate (uptr, mt_tshort); /* schedule quick event */
|
||||
break;
|
||||
case CHSL_REW:
|
||||
case CHSL_SDN: /* rew, rew/unl, set det */
|
||||
sim_activate (uptr, mt_tshort); /* schedule quick event */
|
||||
break;
|
||||
|
||||
default:
|
||||
return SCPE_IERR;
|
||||
} /* end switch */
|
||||
} /* end else */
|
||||
|
||||
uptr->UST = cmd; /* set cmd */
|
||||
mt_unit[ch] = unit & 0777; /* save unit */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Channel write routine */
|
||||
|
||||
t_stat mt_chwr (uint32 ch, t_uint64 val, uint32 eorfl)
|
||||
{
|
||||
int32 k, u;
|
||||
uint8 by, *xb;
|
||||
UNIT *uptr;
|
||||
|
||||
if (ch >= NUM_CHAN) return SCPE_IERR; /* invalid chan? */
|
||||
xb = mtxb[ch]; /* get xfer buf */
|
||||
u = mt_unit[ch] & 017;
|
||||
if ((xb == NULL) || (u > MT_NUMDR)) return SCPE_IERR; /* invalid args? */
|
||||
uptr = mt_dev[ch].units + u; /* get unit */
|
||||
mt_chob[ch] = val & DMASK; /* save word from chan */
|
||||
mt_chob_v[ch] = 1; /* set valid */
|
||||
|
||||
if (uptr->UST == (CHSL_WRS|CHSL_2ND)) { /* data write? */
|
||||
for (k = 30; /* proc 6 bytes */
|
||||
(k >= 0) && (mt_bptr[ch] < MT_MAXFR);
|
||||
k = k - 6) {
|
||||
by = (uint8) ((val >> k) & 077); /* get byte */
|
||||
if ((mt_unit[ch] & 020) == 0) { /* BCD? */
|
||||
if (by == 0) by = BCD_ZERO; /* cvt bin 0 */
|
||||
else if (by & 020) by = by ^ 040; /* invert zones */
|
||||
if (!odd_par[by]) by = by | 0100; /* even parity */
|
||||
}
|
||||
else if (odd_par[by]) by = by | 0100; /* bin, odd par */
|
||||
xb[mt_bptr[ch]++] = by; /* put in buffer */
|
||||
}
|
||||
if (eorfl) return mt_rec_end (uptr); /* EOR? write rec */
|
||||
return SCPE_OK;
|
||||
}
|
||||
return SCPE_IERR;
|
||||
}
|
||||
|
||||
/* Unit timeout */
|
||||
|
||||
t_stat mt_svc (UNIT *uptr)
|
||||
{
|
||||
uint32 i, u, ch = uptr->UCH; /* get channel number */
|
||||
uint8 by, *xb = mtxb[ch]; /* get xfer buffer */
|
||||
t_uint64 dat;
|
||||
t_mtrlnt bc;
|
||||
t_stat r;
|
||||
|
||||
if (xb == NULL) return SCPE_IERR; /* valid buffer? */
|
||||
u = uptr - mt_dev[ch].units;
|
||||
switch (uptr->UST) { /* case on state */
|
||||
|
||||
case CHSL_RDS: /* read start */
|
||||
if (QCHRONO (ch, mt_unit[ch] & 017)) /* Chronolog clock? */
|
||||
bc = chrono_rd (xb, MT_MAXFR); /* read clock */
|
||||
else { /* real tape */
|
||||
r = sim_tape_rdrecf (uptr, xb, &bc, MT_MAXFR); /* read record */
|
||||
if (r = mt_map_err (uptr, r)) return r; /* map status */
|
||||
if (mt_unit[ch] == 0) return SCPE_OK; /* disconnected? */
|
||||
} /* end else Chrono */
|
||||
if (!ch6_qconn (ch, mt_unit[ch])) { /* chan disconnected? */
|
||||
mt_unit[ch] = 0; /* clr ctrl busy */
|
||||
return SCPE_OK;
|
||||
}
|
||||
for (i = bc; i < (bc + 6); i++) xb[i] = 0; /* extra 0's */
|
||||
mt_bptr[ch] = 0; /* set ptr, lnt */
|
||||
mt_blnt[ch] = bc;
|
||||
uptr->UST = CHSL_RDS|CHSL_2ND; /* next state */
|
||||
sim_activate (uptr, mt_tword);
|
||||
break;
|
||||
|
||||
case CHSL_RDS|CHSL_2ND: /* read word */
|
||||
for (i = 0, dat = 0; i < 6; i++) { /* proc 6 bytes */
|
||||
by = xb[mt_bptr[ch]++] & 077; /* get next byte */
|
||||
if ((mt_unit[ch] & 020) == 0) { /* BCD? */
|
||||
if (by == BCD_ZERO) by = 0; /* cvt BCD 0 */
|
||||
else if (by & 020) by = by ^ 040; /* invert zones */
|
||||
}
|
||||
dat = (dat << 6) | ((t_uint64) by);
|
||||
}
|
||||
if (mt_bptr[ch] >= mt_blnt[ch]) { /* end of record? */
|
||||
ch6_req_rd (ch, mt_unit[ch], dat, CH6DF_EOR);
|
||||
uptr->UST = CHSL_RDS|CHSL_3RD; /* next state */
|
||||
sim_activate (uptr, mt_tstop); /* long timing */
|
||||
}
|
||||
else {
|
||||
ch6_req_rd (ch, mt_unit[ch], dat, 0); /* send to channel */
|
||||
sim_activate (uptr, mt_tword); /* next word */
|
||||
}
|
||||
break;
|
||||
|
||||
case CHSL_RDS|CHSL_3RD: /* end record */
|
||||
if (ch6_qconn (ch, mt_unit[ch])) { /* ch still conn? */
|
||||
uptr->UST = CHSL_RDS; /* initial state */
|
||||
sim_activate (uptr, mt_tshort); /* sched next record */
|
||||
}
|
||||
else mt_unit[ch] = 0; /* clr ctrl busy */
|
||||
if (DEBUG_PRS (mt_dev[ch])) fprintf (sim_deb,
|
||||
">>%s%d RDS complete, pos = %d, %s\n",
|
||||
mt_dev[ch].name, u, uptr->pos, mt_unit[ch]? "continuing": "disconnecting");
|
||||
return SCPE_OK;
|
||||
|
||||
case CHSL_WRS: /* write start */
|
||||
if (!ch6_qconn (ch, mt_unit[ch])) { /* chan disconnected? */
|
||||
mt_unit[ch] = 0; /* clr ctrl busy */
|
||||
return SCPE_OK; /* (writes blank tape) */
|
||||
}
|
||||
mt_bptr[ch] = 0; /* init buffer */
|
||||
uptr->UST = CHSL_WRS|CHSL_2ND; /* next state */
|
||||
ch6_req_wr (ch, mt_unit[ch]); /* request channel */
|
||||
mt_chob[ch] = 0; /* clr, inval buffer */
|
||||
mt_chob_v[ch] = 0;
|
||||
sim_activate (uptr, mt_tword); /* wait for word */
|
||||
break;
|
||||
|
||||
case CHSL_WRS|CHSL_2ND: /* write word */
|
||||
if (!ch6_qconn (ch, mt_unit[ch])) /* disconnected? */
|
||||
return mt_rec_end (uptr); /* write record */
|
||||
if (mt_chob_v[ch]) mt_chob_v[ch] = 0; /* valid? clear */
|
||||
else ind_ioc = 1; /* no, io check */
|
||||
ch6_req_wr (ch, mt_unit[ch]); /* request channel */
|
||||
sim_activate (uptr, mt_tword); /* next word */
|
||||
break;
|
||||
|
||||
case CHSL_WRS|CHSL_3RD: /* write stop */
|
||||
if (ch6_qconn (ch, mt_unit[ch])) { /* chan active? */
|
||||
uptr->UST = CHSL_WRS; /* initial state */
|
||||
sim_activate (uptr, mt_tshort); /* sched next record */
|
||||
}
|
||||
else mt_unit[ch] = 0; /* clr ctrl busy */
|
||||
if (DEBUG_PRS (mt_dev[ch])) fprintf (sim_deb,
|
||||
">>%s%d WRS complete, pos = %d, %s\n",
|
||||
mt_dev[ch].name, u, uptr->pos, mt_unit[ch]? "continuing": "disconnecting");
|
||||
return SCPE_OK;
|
||||
|
||||
case CHSL_BSR: /* backspace rec */
|
||||
r = sim_tape_sprecr (uptr, &bc); /* space backwards */
|
||||
mt_unit[ch] = 0; /* clr ctrl busy */
|
||||
ch6_end_nds (ch); /* disconnect */
|
||||
if (DEBUG_PRS (mt_dev[ch])) fprintf (sim_deb,
|
||||
">>%s%d BSR complete, pos = %d\n", mt_dev[ch].name, u, uptr->pos);
|
||||
if (r == MTSE_TMK) return SCPE_OK; /* allow tape mark */
|
||||
return mt_map_err (uptr, r);
|
||||
|
||||
case CHSL_BSF: /* backspace file */
|
||||
while ((r = sim_tape_sprecr (uptr, &bc)) == MTSE_OK) ;
|
||||
mt_unit[ch] = 0; /* clr ctrl busy */
|
||||
ch6_end_nds (ch); /* disconnect */
|
||||
if (DEBUG_PRS (mt_dev[ch])) fprintf (sim_deb,
|
||||
">>%s%d BSF complete, pos = %d\n", mt_dev[ch].name, u, uptr->pos);
|
||||
if (r == MTSE_TMK) return SCPE_OK; /* allow tape mark */
|
||||
return mt_map_err (uptr, r); /* map others */
|
||||
|
||||
case CHSL_WEF: /* write eof */
|
||||
r = sim_tape_wrtmk (uptr); /* write tape mark */
|
||||
mt_unit[ch] = 0; /* clr ctrl busy */
|
||||
ch6_end_nds (ch); /* disconnect */
|
||||
if (DEBUG_PRS (mt_dev[ch])) fprintf (sim_deb,
|
||||
">>%s%d WEF complete, pos = %d\n", mt_dev[ch].name, u, uptr->pos);
|
||||
return mt_map_err (uptr, r);
|
||||
|
||||
case CHSL_REW: case CHSL_RUN: /* rewind, unload */
|
||||
uptr->UST = uptr->UST | CHSL_2ND; /* set 2nd state */
|
||||
sim_activate (uptr, mt_tstart); /* reactivate */
|
||||
mt_unit[ch] = 0; /* clr ctrl busy */
|
||||
ch6_end_nds (ch); /* disconnect */
|
||||
return SCPE_OK;
|
||||
|
||||
case CHSL_REW | CHSL_2ND:
|
||||
sim_tape_rewind (uptr);
|
||||
if (DEBUG_PRS (mt_dev[ch])) fprintf (sim_deb,
|
||||
">>%s%d REW complete, pos = %d\n", mt_dev[ch].name, u, uptr->pos);
|
||||
return SCPE_OK;
|
||||
|
||||
case CHSL_RUN | CHSL_2ND:
|
||||
sim_tape_detach (uptr);
|
||||
if (DEBUG_PRS (mt_dev[ch])) fprintf (sim_deb,
|
||||
">>%s%d RUN complete, pos = %d\n", mt_dev[ch].name, u, uptr->pos);
|
||||
return SCPE_OK;
|
||||
|
||||
case CHSL_SDN:
|
||||
if (mt_unit[ch] & 020) /* set density flag */
|
||||
uptr->flags = uptr-> flags & ~MTUF_LDN;
|
||||
else uptr->flags = uptr->flags | MTUF_LDN;
|
||||
mt_unit[ch] = 0; /* clr ctrl busy */
|
||||
ch6_end_nds (ch); /* disconnect */
|
||||
if (DEBUG_PRS (mt_dev[ch])) fprintf (sim_deb,
|
||||
">>%s%d SDN complete, pos = %d\n", mt_dev[ch].name, u, uptr->pos);
|
||||
return SCPE_OK;
|
||||
|
||||
default:
|
||||
return SCPE_IERR;
|
||||
}
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* End record routine */
|
||||
|
||||
t_stat mt_rec_end (UNIT *uptr)
|
||||
{
|
||||
uint32 ch = uptr->UCH;
|
||||
uint8 *xb = mtxb[ch];
|
||||
t_stat r;
|
||||
|
||||
if (mt_bptr[ch]) { /* any data? */
|
||||
if (xb == NULL) return SCPE_IERR;
|
||||
r = sim_tape_wrrecf (uptr, xb, mt_bptr[ch]); /* write record */
|
||||
if (r = mt_map_err (uptr, r)) return r; /* map error */
|
||||
}
|
||||
uptr->UST = CHSL_WRS|CHSL_3RD; /* next state */
|
||||
sim_cancel (uptr); /* cancel current */
|
||||
sim_activate (uptr, mt_tstop); /* long timing */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Map tape error status */
|
||||
|
||||
t_stat mt_map_err (UNIT *uptr, t_stat st)
|
||||
{
|
||||
uint32 ch = uptr->UCH;
|
||||
uint32 u = mt_unit[ch];
|
||||
uint32 up = uptr - mt_dev[ch].units;
|
||||
|
||||
if ((st != MTSE_OK) && DEBUG_PRS (mt_dev[ch])) fprintf (sim_deb,
|
||||
">>%s%d status = %s, pos = %d\n", mt_dev[ch].name, up, tape_stat[st], uptr->pos);
|
||||
|
||||
switch (st) {
|
||||
|
||||
case MTSE_FMT: /* illegal fmt */
|
||||
case MTSE_UNATT: /* not attached */
|
||||
ch6_err_disc (ch, u, CHF_TRC);
|
||||
mt_unit[ch] = 0; /* disconnect */
|
||||
return SCPE_IERR;
|
||||
|
||||
case MTSE_IOERR: /* IO error */
|
||||
ch6_err_disc (ch, u, CHF_TRC);
|
||||
mt_unit[ch] = 0; /* disconnect */
|
||||
return SCPE_IOERR;
|
||||
|
||||
case MTSE_INVRL: /* invalid rec lnt */
|
||||
ch6_err_disc (ch, u, CHF_TRC);
|
||||
mt_unit[ch] = 0; /* disconnect */
|
||||
return SCPE_MTRLNT;
|
||||
|
||||
case MTSE_WRP: /* write protect */
|
||||
ch6_err_disc (ch, u, 0);
|
||||
mt_unit[ch] = 0; /* disconnect */
|
||||
return STOP_WRP;
|
||||
|
||||
case MTSE_EOM: /* end of medium */
|
||||
case MTSE_TMK: /* tape mark */
|
||||
ch6_err_disc (ch, u, CHF_EOF);
|
||||
mt_unit[ch] = 0; /* disconnect */
|
||||
break;
|
||||
|
||||
case MTSE_RECE: /* record in error */
|
||||
ch6_set_flags (ch, u, CHF_TRC);
|
||||
break;
|
||||
|
||||
case MTSE_BOT: /* reverse into BOT */
|
||||
ch6_set_flags (ch, u, CHF_BOT);
|
||||
break;
|
||||
|
||||
case MTSE_OK: /* no error */
|
||||
break;
|
||||
}
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Magtape reset */
|
||||
|
||||
t_stat mt_reset (DEVICE *dptr)
|
||||
{
|
||||
uint32 ch = dptr - &mt_dev[0];
|
||||
uint32 j;
|
||||
REG *rptr;
|
||||
UNIT *uptr;
|
||||
|
||||
if (mtxb[ch] == NULL) mtxb[ch] = (uint8 *) calloc (MT_MAXFR + 6, sizeof (uint8));
|
||||
if (mtxb[ch] == NULL) return SCPE_MEM; /* allocate buffer */
|
||||
rptr = find_reg ("BUF", NULL, dptr); /* update reg ptr */
|
||||
if (rptr == NULL) return SCPE_IERR;
|
||||
rptr->loc = (void *) mtxb[ch];
|
||||
mt_unit[ch] = 0; /* clear busy */
|
||||
mt_bptr[ch] = 0; /* clear buf ptrs */
|
||||
mt_blnt[ch] = 0;
|
||||
mt_chob[ch] = 0;
|
||||
mt_chob_v[ch] = 0;
|
||||
for (j = 1; j <= MT_NUMDR; j++) { /* for all units */
|
||||
uptr = dptr->units + j;
|
||||
uptr->UST = 0; /* clear state */
|
||||
uptr->UCH = ch;
|
||||
sim_cancel (uptr); /* stop activity */
|
||||
} /* end for */
|
||||
return SCPE_OK; /* done */
|
||||
}
|
||||
|
||||
/* Magtape attach */
|
||||
|
||||
t_stat mt_attach (UNIT *uptr, char *cptr)
|
||||
{
|
||||
uptr->flags = uptr->flags & ~MTUF_LDN; /* start as hi den */
|
||||
return sim_tape_attach (uptr, cptr);
|
||||
}
|
||||
|
||||
/* Magtape boot */
|
||||
|
||||
#define BOOT_START 01000
|
||||
|
||||
static const t_uint64 boot_rom[5] = {
|
||||
0076200000000 + U_MTBIN - 1, /* RDS MT_binary */
|
||||
0054000000000 + BOOT_START + 4, /* RCHA *+3 */
|
||||
0054400000000, /* LCHA 0 */
|
||||
0002100000001, /* TTR 1 */
|
||||
0500003000000, /* IOCT 0,,3 */
|
||||
};
|
||||
|
||||
t_stat mt_boot (int32 unitno, DEVICE *dptr)
|
||||
{
|
||||
uint32 i, chan;
|
||||
extern t_uint64 *M;
|
||||
|
||||
chan = dptr - &mt_dev[0] + 1;
|
||||
WriteP (BOOT_START, boot_rom[0] + unitno + (chan << 9));
|
||||
for (i = 1; i < 5; i++)
|
||||
WriteP (BOOT_START + i, boot_rom[i]);
|
||||
PC = BOOT_START;
|
||||
return SCPE_OK;
|
||||
}
|
718
I7094/i7094_sys.c
Normal file
718
I7094/i7094_sys.c
Normal file
|
@ -0,0 +1,718 @@
|
|||
/* i7094_sys.c: IBM 7094 simulator interface
|
||||
|
||||
Copyright (c) 2003-2006, 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.
|
||||
*/
|
||||
|
||||
#include "i7094_defs.h"
|
||||
#include <ctype.h>
|
||||
#include "i7094_dat.h"
|
||||
|
||||
extern DEVICE cpu_dev;
|
||||
extern DEVICE ch_dev[NUM_CHAN];
|
||||
extern DEVICE mt_dev[NUM_CHAN];
|
||||
extern DEVICE drm_dev;
|
||||
extern DEVICE dsk_dev;
|
||||
extern DEVICE com_dev, coml_dev;
|
||||
extern DEVICE cdr_dev, cdp_dev;
|
||||
extern DEVICE lpt_dev;
|
||||
extern DEVICE clk_dev;
|
||||
extern UNIT cpu_unit;
|
||||
extern REG cpu_reg[];
|
||||
|
||||
uint32 cvt_code_to_ascii (uint32 c, int32 sw);
|
||||
uint32 cvt_ascii_to_code (uint32 c, int32 sw);
|
||||
|
||||
/* SCP data structures and interface routines
|
||||
|
||||
sim_name simulator name string
|
||||
sim_PC pointer to saved PC register descriptor
|
||||
sim_emax number of words for examine
|
||||
sim_devices array of pointers to simulated devices
|
||||
sim_stop_messages array of pointers to stop messages
|
||||
sim_load binary loader
|
||||
*/
|
||||
|
||||
char sim_name[] = "IBM 7094";
|
||||
|
||||
REG *sim_PC = &cpu_reg[0];
|
||||
|
||||
int32 sim_emax = 1;
|
||||
|
||||
DEVICE *sim_devices[] = {
|
||||
&cpu_dev,
|
||||
&clk_dev,
|
||||
&ch_dev[0],
|
||||
&ch_dev[1],
|
||||
&ch_dev[2],
|
||||
&ch_dev[3],
|
||||
&ch_dev[4],
|
||||
&ch_dev[5],
|
||||
&ch_dev[6],
|
||||
&ch_dev[7],
|
||||
&mt_dev[0],
|
||||
&mt_dev[1],
|
||||
&mt_dev[2],
|
||||
&mt_dev[3],
|
||||
&mt_dev[4],
|
||||
&mt_dev[5],
|
||||
&mt_dev[6],
|
||||
&mt_dev[7],
|
||||
&cdr_dev,
|
||||
&cdp_dev,
|
||||
&lpt_dev,
|
||||
&dsk_dev,
|
||||
&drm_dev,
|
||||
&com_dev,
|
||||
&coml_dev,
|
||||
NULL
|
||||
};
|
||||
|
||||
char ch_bkpt_msg[] = "Channel A breakpoint, CLC: xxxxxx";
|
||||
|
||||
const char *sim_stop_messages[] = {
|
||||
"Unknown error",
|
||||
"HALT instruction",
|
||||
"Breakpoint",
|
||||
"Undefined instruction",
|
||||
"Divide check",
|
||||
"Nested XEC limit exceeded",
|
||||
"Address stop",
|
||||
"Non-existent channel",
|
||||
"Illegal instruction for 7909 channel",
|
||||
"Illegal instruction for non-7909 channel",
|
||||
"Non-existent device",
|
||||
"Undefined channel instruction",
|
||||
"Write to protected device",
|
||||
"Illegal instruction for device",
|
||||
"Invalid 7631 track format",
|
||||
"7750 buffer pool empty on input",
|
||||
"7750 buffer pool empty on output",
|
||||
"7750 invalid line number",
|
||||
"7750 invalid message",
|
||||
ch_bkpt_msg
|
||||
};
|
||||
|
||||
/* Modify channel breakpoint message */
|
||||
|
||||
t_stat ch_bkpt (uint32 ch, uint32 clc)
|
||||
{
|
||||
ch_bkpt_msg[8] = 'A' + ch;
|
||||
sprintf (&ch_bkpt_msg[27], "%06o", clc);
|
||||
return STOP_CHBKPT;
|
||||
}
|
||||
|
||||
/* Binary loader, not implemented */
|
||||
|
||||
t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag)
|
||||
{
|
||||
return SCPE_NOFNC;
|
||||
}
|
||||
|
||||
/* Symbol tables */
|
||||
|
||||
#define I_V_FL 39 /* inst class */
|
||||
#define I_M_FL 017 /* class mask */
|
||||
#define I_NOP 0000000000000000 /* no operand */
|
||||
#define I_MXR 0010000000000000 /* addr(tag) */
|
||||
#define I_MXN 0020000000000000 /* *addr(tag) */
|
||||
#define I_MXV 0030000000000000 /* var mul/div */
|
||||
#define I_MXC 0040000000000000 /* convert */
|
||||
#define I_DNP 0050000000000000 /* decr, no oper */
|
||||
#define I_DEC 0060000000000000 /* decrement */
|
||||
#define I_SNS 0070000000000000 /* sense */
|
||||
#define I_IMM 0100000000000000 /* 18b immediate */
|
||||
#define I_TAG 0110000000000000 /* tag only */
|
||||
#define I_IOX 0120000000000000 /* IO channel */
|
||||
#define I_TCH 0130000000000000 /* transfer channel */
|
||||
#define I_I9N 0140000000000000 /* 7909 with nostore */
|
||||
#define I_I9S 0150000000000000 /* 7909 */
|
||||
#define IFAKE_7607 0001000000000000 /* fake op extensions */
|
||||
#define IFAKE_7909 0002000000000000
|
||||
#define DFAKE (DMASK|IFAKE_7607|IFAKE_7909)
|
||||
#define I_N_NOP 000
|
||||
#define I_N_MXR 001
|
||||
#define I_N_MXN 002
|
||||
#define I_N_MXV 003
|
||||
#define I_N_MXC 004
|
||||
#define I_N_DNP 005
|
||||
#define I_N_DEC 006
|
||||
#define I_N_SNS 007
|
||||
#define I_N_IMM 010
|
||||
#define I_N_TAG 011
|
||||
#define I_N_IOX 012
|
||||
#define I_N_TCH 013
|
||||
#define I_N_I9N 014
|
||||
#define I_N_I9S 015
|
||||
|
||||
#define INST_P_XIT 0 /* exit */
|
||||
#define INST_P_SKP 1 /* do not print */
|
||||
#define INST_P_PRA 2 /* print always */
|
||||
#define INST_P_PNZ 3 /* print if nz */
|
||||
#define INST_P_PNT 4 /* print if nz, term */
|
||||
|
||||
static const t_uint64 masks[14] = {
|
||||
03777700000000, 03777700000000,
|
||||
03777700000000, 03777700000000,
|
||||
03777400000000, 03700000000000,
|
||||
03700000000000, 03777700077777,
|
||||
03777700000000, 03777700000000,
|
||||
03700000200000, 03700000200000,
|
||||
03760000200000, 03740000200000 };
|
||||
|
||||
static const uint32 fld_max[14][3] = { /* addr,tag,decr limit */
|
||||
{ INST_M_ADDR, INST_M_TAG, 0 },
|
||||
{ INST_M_ADDR, INST_M_TAG, 0 },
|
||||
{ INST_M_ADDR, INST_M_TAG, 0 },
|
||||
{ INST_M_ADDR, INST_M_TAG, INST_M_VCNT },
|
||||
{ INST_M_ADDR, INST_M_TAG, INST_M_CCNT },
|
||||
{ INST_M_ADDR, INST_M_TAG, INST_M_DEC },
|
||||
{ INST_M_ADDR, INST_M_TAG, INST_M_DEC },
|
||||
{ 0, INST_M_TAG, 0 },
|
||||
{ RMASK, 0, 0 },
|
||||
{ INST_M_ADDR, INST_M_TAG, 0 },
|
||||
{ INST_M_ADDR, 1, INST_M_DEC },
|
||||
{ INST_M_ADDR, 1, 0 },
|
||||
{ INST_M_ADDR, 1, 0 },
|
||||
{ INST_M_ADDR, 1, 0 }
|
||||
};
|
||||
|
||||
static const uint32 fld_fmt[14][3] = { /* addr,tag,decr print */
|
||||
{ INST_P_PNT, INST_P_PNT, INST_P_XIT }, /* nop: all optional */
|
||||
{ INST_P_PRA, INST_P_PNT, INST_P_XIT }, /* mxr: tag optional */
|
||||
{ INST_P_PRA, INST_P_PNT, INST_P_XIT }, /* mxn: tag optional */
|
||||
{ INST_P_PRA, INST_P_PNZ, INST_P_PRA }, /* mxv: tag optional */
|
||||
{ INST_P_PRA, INST_P_PNZ, INST_P_PRA }, /* cvt: tag optional */
|
||||
{ INST_P_PNT, INST_P_PNT, INST_P_PNT }, /* dnp: all optional */
|
||||
{ INST_P_PRA, INST_P_PRA, INST_P_PRA }, /* dec: print all */
|
||||
{ INST_P_SKP, INST_P_PNT, INST_P_XIT }, /* sns: skip addr, tag opt */
|
||||
{ INST_P_PRA, INST_P_XIT, INST_P_XIT }, /* immediate: addr only */
|
||||
{ INST_P_PNZ, INST_P_PRA, INST_P_XIT }, /* tag: addr optional */
|
||||
{ INST_P_PRA, INST_P_PNZ, INST_P_PRA }, /* iox: tag optional */
|
||||
{ INST_P_PRA, INST_P_PNT, INST_P_XIT }, /* tch: tag optional */
|
||||
{ INST_P_PRA, INST_P_PNT, INST_P_XIT }, /* i9n: tag optional */
|
||||
{ INST_P_PRA, INST_P_PNT, INST_P_XIT } /* i9s: tag optional */
|
||||
};
|
||||
|
||||
static const t_uint64 ind_test[14] = {
|
||||
0, 0, INST_IND, 0, 0, 0, 0,
|
||||
0, 0, 0, CHI_IND, CHI_IND, CHI_IND, CHI_IND
|
||||
};
|
||||
|
||||
static const char *opcode[] = {
|
||||
"TXI", "TIX", "TXH",
|
||||
"STR", "TNX", "TXL",
|
||||
"HTR", "TRA", "TTR",
|
||||
|
||||
"CLM", "LBT", "CHS",
|
||||
"SSP", "ENK", "IOT",
|
||||
"COM", "ETM", "RND",
|
||||
"FRN", "DCT", "RCT",
|
||||
"LMTM", "SLF", "SLN1",
|
||||
"SLN2", "SLN3", "SLN4",
|
||||
"SWT1", "SWT2", "SWT3",
|
||||
"SWT4", "SWT5", "SWT6",
|
||||
"BTTA", "BTTB", "BTTC",
|
||||
"BTTD", "BTTE", "BTTF",
|
||||
"BTTG", "BTTH",
|
||||
"RICA", "RICB", "RICC",
|
||||
"RICD", "RICE", "RICF",
|
||||
"RICG", "RICH",
|
||||
"RDCA", "RDCB", "RDCC",
|
||||
"RDCD", "RDCE", "RDCF",
|
||||
"RDCG", "RDCH",
|
||||
|
||||
"TRCA", "TRCC",
|
||||
"TRCE", "TRCG",
|
||||
"TEFA", "TEFC",
|
||||
"TEFE", "TEFG",
|
||||
"TLQ", "IIA", "TIO",
|
||||
"OAI", "PAI", "TIF",
|
||||
"IIR", "RFT", "SIR",
|
||||
"RNT", "RIR",
|
||||
"TCOA", "TCOB", "TCOC",
|
||||
"TCOD", "TCOE", "TCOF",
|
||||
"TCOG", "TCOH", "TSX",
|
||||
"TZE", "CVR", "TPL",
|
||||
"XCA", "TOV",
|
||||
"TQO", "TQP",
|
||||
"MPY", "VLM", "VLM1",
|
||||
"DVH", "DVP",
|
||||
"VDH", "VDP",
|
||||
"VDH2", "VDP2",
|
||||
"FDH", "FDP",
|
||||
"FMP", "DFMP",
|
||||
"FAD", "DFAD",
|
||||
"FSB", "DFSB",
|
||||
"FAM", "DFAM",
|
||||
"FSM", "DFSM",
|
||||
"ANS", "ERA",
|
||||
"CAS", "ACL",
|
||||
"ADD", "ADM",
|
||||
"SUB", "SBM",
|
||||
"HPR", "IIS", "LDI",
|
||||
"OSI", "DLD", "OFT",
|
||||
"RIS", "ONT",
|
||||
"CLA", "CLS",
|
||||
"ZET", "XEC",
|
||||
"LXA", "LAC",
|
||||
"RCHA", "RCHC",
|
||||
"RCHE", "RCHG",
|
||||
"LCHA", "LCHC",
|
||||
"LCHE", "LCHG",
|
||||
"RSCA", "RSCC",
|
||||
"RSCE", "RSCG",
|
||||
"STCA", "STCC",
|
||||
"STCE", "STCG",
|
||||
"LDQ", "ENB",
|
||||
"STZ", "STO", "SLW",
|
||||
"STI", "STA", "STD",
|
||||
"STT", "STP",
|
||||
"SXA", "SCA",
|
||||
"SCHA", "SCHC",
|
||||
"SCHE", "SCHG",
|
||||
"SCDA", "SCDC",
|
||||
"SCDE", "SCDG",
|
||||
"PAX", "PAC",
|
||||
"PXA", "PCA",
|
||||
"PSE", "NOP", "RDS",
|
||||
"LLS", "BSR", "LRS",
|
||||
"WRS", "ALS", "WEF",
|
||||
"ARS", "REW", "AXT",
|
||||
"SDN",
|
||||
|
||||
"CLM", "PBT", "EFTM",
|
||||
"SSM", "LFTM", "ESTM",
|
||||
"ECTM", "LTM", "LSNM",
|
||||
"EMTM", "SLT1", "SLT2",
|
||||
"SLT3", "SLT4",
|
||||
"ETTA", "ETTB", "ETTC",
|
||||
"ETTD", "ETTE", "ETTF",
|
||||
"ETTG", "ETTH",
|
||||
|
||||
"ESNT",
|
||||
"TRCB", "TRCD",
|
||||
"TRCF", "TRCH",
|
||||
"TEFB", "TEFD",
|
||||
"TEFF", "TEFH",
|
||||
"RIA", "PIA",
|
||||
"IIL", "LFT", "SIL",
|
||||
"LNT", "RIL",
|
||||
"TCNA", "TCNB", "TCNC",
|
||||
"TCND", "TCNE", "TCNF",
|
||||
"TCNG", "TCNH",
|
||||
"TNZ", "CVR", "TMI",
|
||||
"XCL", "TNO", "CRQ",
|
||||
"MPR", "DFDH", "DFDP",
|
||||
"UFM", "DUFM",
|
||||
"UFA", "DUFA",
|
||||
"UFS", "DUFS",
|
||||
"UAM", "DUAM",
|
||||
"USM", "DUSM",
|
||||
"ANA", "LAS",
|
||||
"CAL", "ORA", "NZT",
|
||||
"LXD", "LXC",
|
||||
"RCHB", "RCHD",
|
||||
"RCHF", "RCHH",
|
||||
"LCHB", "LCHD",
|
||||
"LCHF", "LCHH",
|
||||
"RSCB", "RSCD",
|
||||
"RSCF", "RSCH",
|
||||
"STCB", "STCD",
|
||||
"STCF", "STCH",
|
||||
"STQ", "ORS", "DST",
|
||||
"SLQ", "STL",
|
||||
"SXD", "SCD",
|
||||
"SCHB", "SCHD",
|
||||
"SCHF", "SCHH",
|
||||
"SCDB", "SCDD",
|
||||
"SCDF", "SCDH",
|
||||
"PDX", "PDC",
|
||||
"PXD", "PCD",
|
||||
"MSE", "LGL", "BSF",
|
||||
"LGR", "RQL", "RUN",
|
||||
"AXC",
|
||||
|
||||
"TIA", "TIB",
|
||||
"LRI", "LPI",
|
||||
"SEA", "SEB",
|
||||
|
||||
"IOCD", "IOCDN", "TCH",
|
||||
"IORP", "IORPN",
|
||||
"IORT", "IORTN",
|
||||
"IOCP", "IOCPN",
|
||||
"IOCT", "IOCTN",
|
||||
"IOSP", "IOSPN",
|
||||
"IOST", "IOSTN",
|
||||
|
||||
"WTR", "XMT",
|
||||
"TCH", "LIPT",
|
||||
"CTL", "CTLN",
|
||||
"CTLR", "CTLRN",
|
||||
"CTLW", "CTLWN",
|
||||
"SNS",
|
||||
"LAR", "SAR", "TWT",
|
||||
"CPYP",
|
||||
"CPYD", "TCM",
|
||||
"LIP", "TDC", "LCC",
|
||||
"SMS", "ICC",
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
static const t_uint64 opc_v[] = {
|
||||
0100000000000+I_DEC, 0200000000000+I_DEC, 0300000000000+I_DEC,
|
||||
0500000000000+I_DNP, 0600000000000+I_DEC, 0700000000000+I_DEC,
|
||||
0000000000000+I_MXN, 0002000000000+I_MXN, 0002100000000+I_MXN,
|
||||
|
||||
0076000000000+I_SNS, 0076000000001+I_SNS, 0076000000002+I_SNS,
|
||||
0076000000003+I_SNS, 0076000000004+I_SNS, 0076000000005+I_SNS,
|
||||
0076000000006+I_SNS, 0076000000007+I_SNS, 0076000000010+I_SNS,
|
||||
0076000000011+I_SNS, 0076000000012+I_SNS, 0076000000014+I_SNS,
|
||||
0076000000016+I_SNS, 0076000000140+I_SNS, 0076000000141+I_SNS,
|
||||
0076000000142+I_SNS, 0076000000143+I_SNS, 0076000000144+I_SNS,
|
||||
0076000000161+I_SNS, 0076000000162+I_SNS, 0076000000163+I_SNS,
|
||||
0076000000164+I_SNS, 0076000000165+I_SNS, 0076000000166+I_SNS,
|
||||
0076000001000+I_SNS, 0076000002000+I_SNS, 0076000003000+I_SNS,
|
||||
0076000004000+I_SNS, 0076000005000+I_SNS, 0076000006000+I_SNS,
|
||||
0076000007000+I_SNS, 0076000010000+I_SNS,
|
||||
0076000001350+I_SNS, 0076000002350+I_SNS, 0076000003350+I_SNS,
|
||||
0076000004350+I_SNS, 0076000005350+I_SNS, 0076000006350+I_SNS,
|
||||
0076000007350+I_SNS, 0076000010350+I_SNS,
|
||||
0076000001352+I_SNS, 0076000002352+I_SNS, 0076000003352+I_SNS,
|
||||
0076000004352+I_SNS, 0076000005352+I_SNS, 0076000006352+I_SNS,
|
||||
0076000007352+I_SNS, 0076000010352+I_SNS,
|
||||
|
||||
0002200000000+I_MXN, 0002400000000+I_MXN,
|
||||
0002600000000+I_MXN, 0002700000000+I_MXN,
|
||||
0003000000000+I_MXN, 0003100000000+I_MXN,
|
||||
0003200000000+I_MXN, 0003300000000+I_MXN,
|
||||
0004000000000+I_MXN, 0004100000000+I_NOP, 0004200000000+I_MXR,
|
||||
0004300000000+I_NOP, 0004400000000+I_NOP, 0004600000000+I_MXR,
|
||||
0005100000000+I_IMM, 0005400000000+I_IMM, 0005500000000+I_IMM,
|
||||
0005600000000+I_IMM, 0005700000000+I_IMM,
|
||||
0006000000000+I_MXN, 0006100000000+I_MXN, 0006200000000+I_MXN,
|
||||
0006300000000+I_MXN, 0006400000000+I_MXN, 0006500000000+I_MXN,
|
||||
0006600000000+I_MXN, 0006700000000+I_MXN, 0007400000000+I_MXR,
|
||||
0010000000000+I_MXN, 0011400000000+I_MXC, 0012000000000+I_MXN,
|
||||
0013100000000+I_NOP, 0014000000000+I_MXN,
|
||||
0016100000000+I_MXN, 0016200000000+I_MXN,
|
||||
0020000000000+I_MXN, 0020400000000+I_MXV, 0020500000000+I_MXV,
|
||||
0022000000000+I_MXN, 0022100000000+I_MXN,
|
||||
0022400000000+I_MXV, 0022500000000+I_MXV,
|
||||
0022600000000+I_MXV, 0022700000000+I_MXV,
|
||||
0024000000000+I_MXN, 0024100000000+I_MXN,
|
||||
0026000000000+I_MXN, 0026100000000+I_MXN,
|
||||
0030000000000+I_MXN, 0030100000000+I_MXN,
|
||||
0030200000000+I_MXN, 0030300000000+I_MXN,
|
||||
0030400000000+I_MXN, 0030500000000+I_MXN,
|
||||
0030600000000+I_MXN, 0030700000000+I_MXN,
|
||||
0032000000000+I_MXN, 0032200000000+I_MXN,
|
||||
0034000000000+I_MXN, 0036100000000+I_MXN,
|
||||
0040000000000+I_MXN, 0040100000000+I_MXN,
|
||||
0040200000000+I_MXN, 0440000000000+I_MXN,
|
||||
0042000000000+I_NOP, 0044000000000+I_MXN, 0044100000000+I_MXN,
|
||||
0044200000000+I_MXN, 0044300000000+I_MXN, 0044400000000+I_MXN,
|
||||
0044500000000+I_MXN, 0044600000000+I_MXN,
|
||||
0050000000000+I_MXN, 0050200000000+I_MXN,
|
||||
0052000000000+I_MXN, 0052200000000+I_MXN,
|
||||
0053400000000+I_MXR, 0053500000000+I_MXR,
|
||||
0054000000000+I_MXN, 0054100000000+I_MXN,
|
||||
0054200000000+I_MXN, 0054300000000+I_MXN,
|
||||
0054400000000+I_MXN, 0054500000000+I_MXN,
|
||||
0054600000000+I_MXN, 0054700000000+I_MXN,
|
||||
0054000000000+I_MXN, 0054100000000+I_MXN,
|
||||
0054200000000+I_MXN, 0054300000000+I_MXN,
|
||||
0054400000000+I_MXN, 0054500000000+I_MXN,
|
||||
0054600000000+I_MXN, 0054700000000+I_MXN,
|
||||
0056000000000+I_MXN, 0056400000000+I_MXN,
|
||||
0060000000000+I_MXN, 0060100000000+I_MXN, 0060200000000+I_MXN,
|
||||
0060400000000+I_MXN, 0062100000000+I_MXN, 0062200000000+I_MXN,
|
||||
0062500000000+I_MXN, 0063000000000+I_MXN,
|
||||
0063400000000+I_MXR, 0063600000000+I_MXR,
|
||||
0064000000000+I_MXN, 0064000000000+I_MXN,
|
||||
0064200000000+I_MXN, 0064300000000+I_MXN,
|
||||
0064400000000+I_MXN, 0064500000000+I_MXN,
|
||||
0064600000000+I_MXN, 0064700000000+I_MXN,
|
||||
0073400000000+I_TAG, 0073700000000+I_TAG,
|
||||
0075400000000+I_TAG, 0075600000000+I_TAG,
|
||||
0076000000000+I_MXR, 0076100000000+I_NOP, 0076200000000+I_MXR,
|
||||
0076300000000+I_MXR, 0076400000000+I_MXR, 0076500000000+I_MXR,
|
||||
0076600000000+I_MXR, 0076700000000+I_MXR, 0077000000000+I_MXR,
|
||||
0077100000000+I_MXR, 0077200000000+I_MXR, 0077400000000+I_MXR,
|
||||
0077600000000+I_MXR,
|
||||
|
||||
0476000000000+I_SNS, 0476000000001+I_SNS, 0476000000002+I_SNS,
|
||||
0476000000003+I_SNS, 0476000000004+I_SNS, 0476000000005+I_SNS,
|
||||
0476000000006+I_SNS, 0476000000007+I_SNS, 0476000000010+I_SNS,
|
||||
0476000000016+I_SNS, 0476000000141+I_SNS, 0476000000142+I_SNS,
|
||||
0476000000143+I_SNS, 0476000000144+I_SNS,
|
||||
0476000001000+I_SNS, 0476000002000+I_SNS, 0476000003000+I_SNS,
|
||||
0476000004000+I_SNS, 0476000005000+I_SNS, 0476000006000+I_SNS,
|
||||
0476000007000+I_SNS, 0476000010000+I_SNS,
|
||||
|
||||
0402100000000+I_MXN,
|
||||
0402200000000+I_MXN, 0402400000000+I_MXN,
|
||||
0402600000000+I_MXN, 0402700000000+I_MXN,
|
||||
0403000000000+I_MXN, 0403100000000+I_MXN,
|
||||
0403200000000+I_MXN, 0403300000000+I_MXN,
|
||||
0404200000000+I_NOP, 0404600000000+I_NOP,
|
||||
0405100000000+I_IMM, 0405400000000+I_IMM, 0405500000000+I_IMM,
|
||||
0405600000000+I_IMM, 0405700000000+I_IMM,
|
||||
0406000000000+I_MXN, 0406100000000+I_MXN, 0406200000000+I_MXN,
|
||||
0406300000000+I_MXN, 0406400000000+I_MXN, 0406500000000+I_MXN,
|
||||
0406600000000+I_MXN, 0406700000000+I_MXN,
|
||||
0410000000000+I_MXN, 0411400000000+I_MXC, 0412000000000+I_MXN,
|
||||
0413000000000+I_NOP, 0414000000000+I_MXN, 0415400000000+I_MXC,
|
||||
0420000000000+I_MXN, 0424000000000+I_MXN, 0424100000000+I_MXN,
|
||||
0426000000000+I_MXN, 0426100000000+I_MXN,
|
||||
0430000000000+I_MXN, 0430100000000+I_MXN,
|
||||
0430200000000+I_MXN, 0430300000000+I_MXN,
|
||||
0430400000000+I_MXN, 0430500000000+I_MXN,
|
||||
0430600000000+I_MXN, 0430700000000+I_MXN,
|
||||
0432000000000+I_MXN, 0434000000000+I_MXN,
|
||||
0450000000000+I_MXN, 0450100000000+I_MXN, 0452000000000+I_MXN,
|
||||
0453400000000+I_MXR, 0453500000000+I_MXR,
|
||||
0454000000000+I_MXN, 0454100000000+I_MXN,
|
||||
0454200000000+I_MXN, 0454300000000+I_MXN,
|
||||
0454400000000+I_MXN, 0454500000000+I_MXN,
|
||||
0454600000000+I_MXN, 0454700000000+I_MXN,
|
||||
0454000000000+I_MXN, 0454100000000+I_MXN,
|
||||
0454200000000+I_MXN, 0454300000000+I_MXN,
|
||||
0454400000000+I_MXN, 0454500000000+I_MXN,
|
||||
0454600000000+I_MXN, 0454700000000+I_MXN,
|
||||
0460000000000+I_MXN, 0460200000000+I_MXN, 0460300000000+I_MXN,
|
||||
0462000000000+I_MXN, 0462500000000+I_MXN,
|
||||
0463400000000+I_MXR, 0463600000000+I_MXR,
|
||||
0464000000000+I_MXN, 0464000000000+I_MXN,
|
||||
0464200000000+I_MXN, 0464300000000+I_MXN,
|
||||
0464400000000+I_MXN, 0464500000000+I_MXN,
|
||||
0464600000000+I_MXN, 0464700000000+I_MXN,
|
||||
0473400000000+I_TAG, 0473700000000+I_TAG,
|
||||
0475400000000+I_TAG, 0475600000000+I_TAG,
|
||||
0476000000000+I_MXR, 0476300000000+I_MXR, 0476400000000+I_MXR,
|
||||
0476500000000+I_MXR, 0477300000000+I_MXR, 0477200000000+I_MXR,
|
||||
0477400000000+I_MXR,
|
||||
|
||||
0010100000000+I_MXN, 0410100000000+I_MXN,
|
||||
0056200000000+I_MXN, 0456400000000+I_MXN,
|
||||
0476100000041+I_SNS, 0476100000042+I_SNS,
|
||||
|
||||
01000000000000+I_IOX, 01000000200000+I_IOX, 01100000000000+I_TCH,
|
||||
01200000000000+I_IOX, 01200000200000+I_IOX,
|
||||
01300000000000+I_IOX, 01300000200000+I_IOX,
|
||||
01400000000000+I_IOX, 01400000200000+I_IOX,
|
||||
01500000000000+I_IOX, 01500000200000+I_IOX,
|
||||
01600000000000+I_IOX, 01600000200000+I_IOX,
|
||||
01700000000000+I_IOX, 01700000200000+I_IOX,
|
||||
|
||||
02000000000000+I_TCH, 02000000200000+I_IOX,
|
||||
02100000000000+I_TCH, 02100000200000+I_TCH,
|
||||
02200000000000+I_I9N, 02220000000000+I_TCH,
|
||||
02200000200000+I_I9N, 02220000200000+I_TCH,
|
||||
02240000000000+I_I9N, 02260000000000+I_TCH,
|
||||
02240000200000+I_I9N,
|
||||
02300000000000+I_I9S, 02300000200000+I_I9S,
|
||||
02340000000000+I_I9S,
|
||||
02400000000000+I_IOX,
|
||||
02500000000000+I_IOX, 02500000200000+I_IOX,
|
||||
02600000200000+I_I9S, 02640000000000+I_I9S, 02640000200000+I_I9S,
|
||||
02700000000000+I_I9S, 02700000200000+I_IOX,
|
||||
|
||||
0
|
||||
};
|
||||
|
||||
/* Symbolic decode
|
||||
|
||||
Inputs:
|
||||
*of = output stream
|
||||
addr = current PC
|
||||
*val = pointer to values
|
||||
*uptr = pointer to unit
|
||||
sw = switches
|
||||
Outputs:
|
||||
return = status code
|
||||
*/
|
||||
|
||||
t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,
|
||||
UNIT *uptr, int32 sw)
|
||||
{
|
||||
uint32 i, j, k, l, fmt, c, fld[3];
|
||||
DEVICE *dptr;
|
||||
t_uint64 inst;
|
||||
|
||||
inst = val[0];
|
||||
if (uptr == NULL) uptr = &cpu_unit;
|
||||
dptr = find_dev_from_unit (uptr);
|
||||
if (dptr == NULL) return SCPE_IERR;
|
||||
|
||||
if (sw & SWMASK ('C')) { /* character? */
|
||||
c = (uint32) (inst & 077);
|
||||
fprintf (of, "%c", cvt_code_to_ascii (c, sw));
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (sw & SWMASK ('S')) { /* string? */
|
||||
for (i = 36; i > 0; i = i - 6) {
|
||||
c = (uint32) ((inst >> (i - 6)) & 077);
|
||||
fprintf (of, "%c", cvt_code_to_ascii (c, sw));
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (!(sw & (SWMASK ('M')|SWMASK ('I')|SWMASK ('N'))) || /* M, N or I? */
|
||||
(dptr->dwidth != 36)) return SCPE_ARG;
|
||||
|
||||
/* Instruction decode */
|
||||
|
||||
fld[0] = ((uint32) inst & 0777777);
|
||||
fld[1] = GET_TAG (inst); /* get 3 fields */
|
||||
fld[2] = GET_DEC (inst);
|
||||
if (sw & SWMASK ('I')) inst |= IFAKE_7607; /* decode as 7607? */
|
||||
if (sw & SWMASK ('N')) inst |= IFAKE_7909; /* decode as 7909? */
|
||||
|
||||
for (i = 0; opc_v[i] > 0; i++) { /* loop thru ops */
|
||||
j = (int32) ((opc_v[i] >> I_V_FL) & I_M_FL); /* get class */
|
||||
if ((opc_v[i] & DFAKE) == (inst & masks[j])) { /* match? */
|
||||
if (inst & ind_test[j]) /* indirect? */
|
||||
fprintf (of, "%s*", opcode[i]);
|
||||
else fprintf (of, "%s", opcode[i]); /* opcode */
|
||||
for (k = 0; k < 3; k++) fld[k] = fld[k] & fld_max[j][k];
|
||||
for (k = 0; k < 3; k++) { /* loop thru fields */
|
||||
fmt = fld_fmt[j][k]; /* get format */
|
||||
if (fmt == INST_P_XIT) return SCPE_OK;
|
||||
switch (fmt) { /* case on format */
|
||||
|
||||
case INST_P_PNT: /* print nz, else term */
|
||||
for (l = k, c = 0; l < 3; l++) c |= fld[k];
|
||||
if (c == 0) return SCPE_OK;
|
||||
case INST_P_PNZ: /* print non-zero */
|
||||
fputc (k? ',': ' ', of);
|
||||
if (fld[k]) fprintf (of, "%-o", fld[k]);
|
||||
break;
|
||||
case INST_P_PRA: /* print always */
|
||||
fputc (k? ',': ' ', of);
|
||||
fprintf (of, "%-o", fld[k]);
|
||||
break;
|
||||
case INST_P_SKP: /* skip */
|
||||
break;
|
||||
} /* end switch */
|
||||
} /* end for k */
|
||||
return SCPE_OK; /* done */
|
||||
} /* end if */
|
||||
} /* end for i */
|
||||
return SCPE_ARG;
|
||||
}
|
||||
|
||||
/* Convert character to code to ASCII
|
||||
|
||||
-b BCD
|
||||
-a business-chain */
|
||||
|
||||
uint32 cvt_code_to_ascii (uint32 c, int32 sw)
|
||||
{
|
||||
if (sw & SWMASK ('B')) {
|
||||
if (sw & SWMASK ('A')) return bcd_to_ascii_a[c];
|
||||
else return bcd_to_ascii_h[c];
|
||||
}
|
||||
else if (sw & SWMASK ('A')) return nine_to_ascii_a[c];
|
||||
else return nine_to_ascii_h[c];
|
||||
}
|
||||
|
||||
/* Symbolic input
|
||||
|
||||
Inputs:
|
||||
*cptr = pointer to input string
|
||||
addr = current PC
|
||||
uptr = pointer to unit
|
||||
*val = pointer to output values
|
||||
sw = switches
|
||||
Outputs:
|
||||
status = error status
|
||||
*/
|
||||
|
||||
t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw)
|
||||
{
|
||||
uint32 i, j, c;
|
||||
t_uint64 fld[3];
|
||||
t_bool ind;
|
||||
t_stat r;
|
||||
char gbuf[CBUFSIZE];
|
||||
|
||||
while (isspace (*cptr)) cptr++;
|
||||
if ((sw & SWMASK ('C')) || ((*cptr == '\'') && cptr++)) { /* character? */
|
||||
if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */
|
||||
val[0] = (t_value) cvt_ascii_to_code (cptr[0] & 0177, sw);
|
||||
return SCPE_OK;
|
||||
}
|
||||
if ((sw & SWMASK ('S')) || ((*cptr == '"') && cptr++)) { /* sixbit string? */
|
||||
if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */
|
||||
for (i = 0; i < 6; i++) {
|
||||
c = cptr[0] & 0177;
|
||||
if (c) val[0] = (val[0] << 6) | ((t_value) cvt_ascii_to_code (c, sw));
|
||||
else {
|
||||
val[0] = val[0] << (6 * (6 - i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
cptr = get_glyph (cptr, gbuf, 0); /* get opcode */
|
||||
j = strlen (gbuf); /* get length */
|
||||
if (gbuf[j - 1] == '*') { /* indirect? */
|
||||
ind = TRUE;
|
||||
gbuf[j - 1] = 0;
|
||||
}
|
||||
else ind = FALSE;
|
||||
for (i = 0; (opcode[i] != NULL) && (strcmp (opcode[i], gbuf) != 0) ; i++) ;
|
||||
if (opcode[i] == NULL) return SCPE_ARG;
|
||||
j = (uint32) ((opc_v[i] >> I_V_FL) & I_M_FL); /* get class */
|
||||
val[0] = opc_v[i] & DMASK;
|
||||
if (ind) {
|
||||
if (ind_test[j]) val[0] |= ind_test[j];
|
||||
else return SCPE_ARG;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) fld[i] = 0; /* clear inputs */
|
||||
for (i = 0; (i < 3) && *cptr; i++) { /* parse inputs */
|
||||
if (i < 2) cptr = get_glyph (cptr, gbuf, ','); /* get glyph */
|
||||
else cptr = get_glyph (cptr, gbuf, 0);
|
||||
if (gbuf[0]) { /* anything? */
|
||||
fld[i] = get_uint (gbuf, 8, fld_max[j][i], &r);
|
||||
if ((r != SCPE_OK) || (fld_max[j][i] == 0)) return SCPE_ARG;
|
||||
}
|
||||
}
|
||||
if (*cptr != 0) return SCPE_ARG; /* junk at end? */
|
||||
|
||||
val[0] = val[0] | fld[0] | (fld[1] << INST_V_TAG) | (fld[2] << INST_V_DEC);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Convert ASCII to character code
|
||||
|
||||
-b BCD */
|
||||
|
||||
uint32 cvt_ascii_to_code (uint32 c, int32 sw)
|
||||
{
|
||||
if (sw & SWMASK ('B')) return ascii_to_bcd[c];
|
||||
else return ascii_to_nine[c];
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/* id16_cpu.c: Interdata 16b CPU simulator
|
||||
|
||||
Copyright (c) 2000-2005, Robert M. Supnik
|
||||
Copyright (c) 2000-2006, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
cpu Interdata 16b CPU
|
||||
|
||||
06-Feb-06 RMS Fixed bug in DH (found by Mark Hittinger)
|
||||
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
|
||||
25-Aug-05 RMS Fixed DH integer overflow cases
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
|
@ -169,6 +170,7 @@ typedef struct {
|
|||
uint16 opnd;
|
||||
} InstHistory;
|
||||
|
||||
#define PSW_GETMAP(x) (((x) >> PSW_V_MAP) & PSW_M_MAP)
|
||||
#define SEXT16(x) (((x) & SIGN16)? ((int32) ((x) | 0xFFFF8000)): \
|
||||
((int32) ((x) & 0x7FFF)))
|
||||
#define CC_GL_16(x) if ((x) & SIGN16) cc = CC_L; \
|
||||
|
@ -1058,7 +1060,7 @@ while (reason == 0) { /* loop until halted */
|
|||
case 0x4D: /* DH - RXH */
|
||||
r1p1 = (r1 + 1) & 0xF; /* R1 + 1 */
|
||||
if ((opnd == 0) ||
|
||||
((R[r1] == 0x8000) && (R[r1p1] == 0) && (opnd = 0xFFFF))) {
|
||||
((R[r1] == 0x8000) && (R[r1p1] == 0) && (opnd == 0xFFFF))) {
|
||||
if (PSW & PSW_AFI) /* div fault enabled? */
|
||||
cc = swap_psw (AFIPSW, cc); /* swap PSW */
|
||||
break;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* id32_cpu.c: Interdata 32b CPU simulator
|
||||
|
||||
Copyright (c) 2000-2005, Robert M. Supnik
|
||||
Copyright (c) 2000-2006, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,8 @@
|
|||
|
||||
cpu Interdata 32b CPU
|
||||
|
||||
09-Mar-06 RMS Added 8 register bank support for 8/32
|
||||
06-Feb-06 RMS Fixed bug in DH (found by Mark Hittinger)
|
||||
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
10-Mar-05 RMS Fixed bug in initial memory allocation
|
||||
|
@ -156,7 +158,7 @@
|
|||
#define PCQ_MASK (PCQ_SIZE - 1)
|
||||
#define PCQ_ENTRY pcq[pcq_p = (pcq_p - 1) & PCQ_MASK] = oPC
|
||||
#define VAMASK VAMASK32
|
||||
#define NRSETS 2 /* 2 gen reg sets */
|
||||
#define NRSETS 8 /* up to 8 reg sets */
|
||||
#define PSW_MASK PSW_x32
|
||||
#define ABORT(val) longjmp (save_env, (val))
|
||||
#define MPRO (-1)
|
||||
|
@ -164,9 +166,11 @@
|
|||
#define UNIT_V_MSIZE (UNIT_V_UF + 0) /* dummy mask */
|
||||
#define UNIT_V_DPFP (UNIT_V_UF + 1)
|
||||
#define UNIT_V_832 (UNIT_V_UF + 2)
|
||||
#define UNIT_V_8RS (UNIT_V_UF + 3)
|
||||
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
|
||||
#define UNIT_DPFP (1 << UNIT_V_DPFP)
|
||||
#define UNIT_832 (1 << UNIT_V_832)
|
||||
#define UNIT_8RS (1 << UNIT_V_8RS)
|
||||
#define UNIT_TYPE (UNIT_DPFP | UNIT_832)
|
||||
|
||||
#define HIST_PC 0x40000000
|
||||
|
@ -183,6 +187,7 @@ typedef struct {
|
|||
uint32 opnd;
|
||||
} InstHistory;
|
||||
|
||||
#define PSW_GETREG(x) (((x) >> PSW_V_REG) & psw_reg_mask)
|
||||
#define SEXT32(x) (((x) & SIGN32)? ((int32) ((x) | ~0x7FFFFFFF)): \
|
||||
((int32) ((x) & 0x7FFFFFFF)))
|
||||
#define SEXT16(x) (((x) & SIGN16)? ((int32) ((x) | ~0x7FFF)): \
|
||||
|
@ -235,6 +240,7 @@ uint32 fp_in_hwre = 0; /* ucode vs hwre fp */
|
|||
uint32 pawidth = PAWIDTH32; /* addr mask */
|
||||
uint32 hst_p = 0; /* history pointer */
|
||||
uint32 hst_lnt = 0; /* history length */
|
||||
uint32 psw_reg_mask = 1; /* PSW reg mask */
|
||||
InstHistory *hst = NULL; /* instruction history */
|
||||
jmp_buf save_env; /* abort handler */
|
||||
struct BlockIO blk_io; /* block I/O status */
|
||||
|
@ -565,10 +571,14 @@ MTAB cpu_mod[] = {
|
|||
{ UNIT_MSIZE, 262144, NULL, "256K", &cpu_set_size },
|
||||
{ UNIT_MSIZE, 524288, NULL, "512K", &cpu_set_size },
|
||||
{ UNIT_MSIZE, 1048756, NULL, "1M", &cpu_set_size },
|
||||
{ UNIT_TYPE, 0, "7/32, single precision fp", "732", NULL },
|
||||
{ UNIT_8RS|UNIT_TYPE, 0, NULL, "732", NULL },
|
||||
{ UNIT_DPFP, UNIT_DPFP, NULL, "DPFP", NULL },
|
||||
{ UNIT_TYPE, 0, "7/32, single precision fp", "732", NULL },
|
||||
{ UNIT_TYPE, UNIT_DPFP, "7/32, double precision fp", NULL, NULL },
|
||||
{ UNIT_TYPE, UNIT_DPFP | UNIT_832, "8/32", "832", NULL },
|
||||
{ UNIT_8RS|UNIT_TYPE, UNIT_8RS|UNIT_DPFP|UNIT_832, NULL, "832", NULL },
|
||||
{ UNIT_8RS, 0, NULL, "2RS", NULL },
|
||||
{ UNIT_8RS|UNIT_TYPE, UNIT_8RS|UNIT_DPFP|UNIT_832, "832, 8 register sets", NULL, NULL },
|
||||
{ UNIT_8RS|UNIT_TYPE, UNIT_DPFP|UNIT_832, "832, 2 register sets", NULL, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, NULL, "CONSINT",
|
||||
&cpu_set_consint, NULL, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "HISTORY", "HISTORY",
|
||||
|
@ -608,6 +618,8 @@ else {
|
|||
fp_in_hwre = 0; /* fp in ucode */
|
||||
dec_flgs = OP_DPF; /* sp only */
|
||||
}
|
||||
if (cpu_unit.flags & UNIT_8RS) psw_reg_mask = 7; /* 8 register sets */
|
||||
else psw_reg_mask = 1; /* 2 register sets */
|
||||
int_eval (); /* eval interrupts */
|
||||
cc = newPSW (PSW & PSW_MASK); /* split PSW, eval wait */
|
||||
sim_rtcn_init (lfc_unit.wait, TMR_LFC); /* init clock */
|
||||
|
@ -1223,7 +1235,7 @@ while (reason == 0) { /* loop until halted */
|
|||
case 0x4D: /* DH - RXH */
|
||||
opnd = opnd & DMASK16; /* force HW opnd */
|
||||
if ((opnd == 0) || /* div by zero? */
|
||||
((R[r1] == 0x80000000) && (opnd = 0xFFFF))) {
|
||||
((R[r1] == 0x80000000) && (opnd == 0xFFFF))) {
|
||||
if (PSW & PSW_AFI) /* div fault enabled? */
|
||||
cc = exception (AFIPSW, cc, 0); /* exception */
|
||||
break;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* id_defs.h: Interdata 16b/32b simulator definitions
|
||||
|
||||
Copyright (c) 2000-2005, Robert M. Supnik
|
||||
Copyright (c) 2000-2006, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -26,6 +26,7 @@
|
|||
The author gratefully acknowledges the help of Carl Friend and Al Kossow,
|
||||
who provided key documents about the Interdata product line.
|
||||
|
||||
09-Mar-06 RMS Increased register sets to architectural limit
|
||||
25-Jan-04 RMS Removed local logging support
|
||||
22-Sep-03 RMS Added additional instruction decode types
|
||||
21-Jun-03 RMS Changed subroutine argument for ARM compiler conflict
|
||||
|
@ -114,13 +115,11 @@ typedef struct {
|
|||
#define PSW_M_MAP 0xF
|
||||
#define PSW_MAP (PSW_M_MAP << PSW_V_MAP)
|
||||
#define PSW_V_REG 4 /* reg set, 32b */
|
||||
#define PSW_M_REG 0x1
|
||||
#define PSW_M_REG 0xF
|
||||
#define PSW_ID4 0xF40F /* I3, I4 PSW */
|
||||
#define PSW_x16 0xFF0F /* 7/16, 8/16 PSW */
|
||||
#define PSW_816E 0xFFFF /* 8/16E PSW */
|
||||
#define PSW_x32 0xFFFF /* 7/32, 8/32 PSW */
|
||||
#define PSW_GETMAP(x) (((x) >> PSW_V_MAP) & PSW_M_MAP)
|
||||
#define PSW_GETREG(x) (((x) >> PSW_V_REG) & PSW_M_REG)
|
||||
|
||||
#define MCKOPSW 0x20 /* mchk old PSW, 32b */
|
||||
#define FPFPSW 0x28 /* flt fault PSW, 16b */
|
||||
|
|
|
@ -655,7 +655,7 @@ sim> boot mt0
|
|||
|
||||
Breakpoint, PC: 00A00 (B A5E)
|
||||
|
||||
sim> d -w a10 0101 ; patch for TTY console
|
||||
sim> d -h a10 0202 ; patch for TTY console
|
||||
sim> att dm0 foo.dsk
|
||||
sim> att dm1 foo1.dsk
|
||||
sim> c
|
||||
|
@ -904,4 +904,8 @@ Bugs found
|
|||
92. IDC: read with invalid head sets ACF, not DTE
|
||||
93. DP, IDC: write with cylinder overflow advanced selch pointer
|
||||
94. MT: read error must stop selector channel (if active)
|
||||
95. IDC: xx000000 to controller or drive are NOP's, not invalid commands
|
||||
96. IDC: WD/WH use standard Interdata write pointers
|
||||
97. SELCH: GO preserves EXA and SSTA
|
||||
98. CPU: DH overflow checking broken
|
||||
|
||||
|
|
1054
Interdata/id_doc.txt
1054
Interdata/id_doc.txt
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
|||
/* id_idc.c: Interdata MSM/IDC disk controller simulator
|
||||
|
||||
Copyright (c) 2001-2005, Robert M. Supnik
|
||||
Copyright (c) 2001-2006, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,8 @@
|
|||
|
||||
idc MSM/IDC disk controller
|
||||
|
||||
03-Apr-06 RMS Fixed WD/WH handling (found by Davis Johnson)
|
||||
30-Mar-06 RMS Fixed bug, nop command should be ignored (found by Davis Johnson)
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
16-Feb-03 RMS Fixed read to test transfer ok before selch operation
|
||||
|
||||
|
@ -199,14 +201,16 @@ extern uint32 int_req[INTSZ], int_enb[INTSZ];
|
|||
|
||||
uint8 idcxb[IDC_NUMBY * 3]; /* xfer buffer */
|
||||
uint32 idc_bptr = 0; /* buffer ptr */
|
||||
uint32 idc_wdptr = 0; /* ctrl write data ptr */
|
||||
uint32 idc_db = 0; /* ctrl buffer */
|
||||
uint32 idd_db = 0; /* drive buffer */
|
||||
uint32 idc_sta = 0; /* ctrl status */
|
||||
uint32 idc_sec = 0; /* sector */
|
||||
uint32 idc_hcyl = 0; /* head/cyl */
|
||||
uint32 idc_svun = 0; /* most recent unit */
|
||||
uint32 idc_1st = 0; /* first byte */
|
||||
uint32 idc_arm = 0; /* ctrl armed */
|
||||
uint32 idd_db = 0; /* drive buffer */
|
||||
uint32 idd_wdptr = 0; /* drive write data ptr */
|
||||
uint32 idd_arm[ID_NUMDR] = { 0 }; /* drives armed */
|
||||
uint16 idd_dcy[ID_NUMDR] = { 0 }; /* desired cyl */
|
||||
uint32 idd_sirq = 0; /* drive saved irq */
|
||||
|
@ -221,6 +225,7 @@ t_stat idc_svc (UNIT *uptr);
|
|||
t_stat idc_reset (DEVICE *dptr);
|
||||
t_stat idc_attach (UNIT *uptr, char *cptr);
|
||||
t_stat idc_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
void idc_wd_byte (uint32 dat);
|
||||
t_stat idc_rds (UNIT *uptr);
|
||||
t_stat idc_wds (UNIT *uptr);
|
||||
t_bool idc_dter (UNIT *uptr, uint32 first);
|
||||
|
@ -259,6 +264,8 @@ REG idc_reg[] = {
|
|||
{ BRDATA (DBUF, idcxb, 16, 8, IDC_NUMBY * 3) },
|
||||
{ HRDATA (DBPTR, idc_bptr, 10), REG_RO },
|
||||
{ FLDATA (FIRST, idc_1st, 0) },
|
||||
{ HRDATA (CWDPTR, idc_wdptr, 2) },
|
||||
{ HRDATA (DWDPTR, idc_wdptr, 1) },
|
||||
{ GRDATA (IREQ, int_req[l_IDC], 16, ID_NUMDR + 1, i_IDC) },
|
||||
{ GRDATA (IENB, int_enb[l_IDC], 16, ID_NUMDR + 1, i_IDC) },
|
||||
{ GRDATA (SIREQ, idd_sirq, 16, ID_NUMDR, i_IDC + 1), REG_RO },
|
||||
|
@ -358,11 +365,12 @@ switch (op) { /* case IO op */
|
|||
return 0; /* return data */
|
||||
|
||||
case IO_WD: /* write data */
|
||||
idc_sec = dat; /* sector */
|
||||
idc_wd_byte (dat); /* one byte only */
|
||||
break;
|
||||
|
||||
case IO_WH: /* write halfword */
|
||||
idc_hcyl = dat; /* head/cylinder */
|
||||
idc_wd_byte (dat >> 8); /* high byte */
|
||||
idc_wd_byte (dat); /* low byte */
|
||||
break;
|
||||
|
||||
case IO_SS: /* status */
|
||||
|
@ -372,15 +380,17 @@ switch (op) { /* case IO op */
|
|||
|
||||
case IO_OC: /* command */
|
||||
idc_arm = int_chg (v_IDC, dat, idc_arm); /* upd int ctrl */
|
||||
idc_wdptr = 0; /* init ptr */
|
||||
f = dat & CMC_MASK; /* get cmd */
|
||||
uptr = idc_dev.units + idc_svun; /* get unit */
|
||||
if (f & CMC_CLR) { /* clear? */
|
||||
idc_reset (&idc_dev); /* reset world */
|
||||
break;
|
||||
}
|
||||
if (!(idc_sta & STC_IDL) || /* if !idle, */
|
||||
sim_is_active (uptr) || /* unit busy, */
|
||||
(f == CMC_EXP0)) break; /* expg, ignore */
|
||||
if ((f == 0) || /* if nop, */
|
||||
(f == CMC_EXP0) || /* expg, */
|
||||
!(idc_sta & STC_IDL) || /* !idle, */
|
||||
sim_is_active (uptr)) break; /* unit busy, ignore */
|
||||
idc_sta = STA_BSY; /* bsy=1,idl,err=0 */
|
||||
idc_1st = 1; /* xfr not started */
|
||||
idc_bptr = 0; /* buffer empty */
|
||||
|
@ -394,11 +404,37 @@ switch (op) { /* case IO op */
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Process WD/WH data */
|
||||
|
||||
void idc_wd_byte (uint32 dat)
|
||||
{
|
||||
dat = dat & 0xFF;
|
||||
switch (idc_wdptr) {
|
||||
|
||||
case 0: /* byte 0 = sector */
|
||||
idc_sec = dat;
|
||||
idc_wdptr++;
|
||||
break;
|
||||
|
||||
case 1: /* byte 1 = high hd/cyl */
|
||||
idc_hcyl = (idc_hcyl & 0xFF) | (dat << 8);
|
||||
idc_wdptr++;
|
||||
break;
|
||||
|
||||
case 2: /* byte 2 = low hd/cyl */
|
||||
idc_hcyl = (idc_hcyl & 0xFF00) | dat;
|
||||
idc_wdptr = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Drives: IO routine */
|
||||
|
||||
uint32 id (uint32 dev, uint32 op, uint32 dat)
|
||||
{
|
||||
uint32 t, u;
|
||||
uint32 t, u, f;
|
||||
UNIT *uptr;
|
||||
|
||||
if (dev == idc_dib.dno) return idc (dev, op, dat); /* controller? */
|
||||
|
@ -408,15 +444,17 @@ switch (op) { /* case IO op */
|
|||
|
||||
case IO_ADR: /* select */
|
||||
if (idc_sta & STC_IDL) idc_svun = u; /* idle? save unit */
|
||||
return HW; /* byte only */
|
||||
return BY; /* byte only */
|
||||
|
||||
case IO_RD: /* read data */
|
||||
case IO_RH:
|
||||
return 0;
|
||||
|
||||
case IO_WD: /* write data */
|
||||
case IO_WH: /* write halfword */
|
||||
idd_db = dat; /* save data */
|
||||
if (idd_wdptr & 1) /* low byte? */
|
||||
idd_db = (idd_db & 0xFF00) | dat;
|
||||
else idd_db = (idd_db & 0xFF) | (dat << 8); /* no, high */
|
||||
idd_wdptr = idd_wdptr ^ 1; /* other byte */
|
||||
break;
|
||||
|
||||
case IO_SS: /* status */
|
||||
|
@ -430,12 +468,15 @@ switch (op) { /* case IO op */
|
|||
|
||||
case IO_OC: /* command */
|
||||
idd_arm[u] = int_chg (v_IDC + u + 1, dat, idd_arm[u]);
|
||||
idd_wdptr = 0; /* init ptr */
|
||||
if (idd_arm[u] == 0) /* disarmed? */
|
||||
idd_sirq &= ~(1 << (v_IDC + u + 1)); /* clr saved req */
|
||||
if (sim_is_active (uptr) || /* if busy or */
|
||||
!(idc_sta & STC_IDL)) break; /* !idle, ignore */
|
||||
if ((dat & CMC_MASK) == CMDX_MASK) break; /* ignore 0x30 */
|
||||
uptr->FNC = (dat & CMC_MASK) | CMC_DRV; /* save cmd */
|
||||
f = dat & CMC_MASK; /* get cmd */
|
||||
if ((f == 0) || /* if nop, */
|
||||
(f == CMDX_MASK) || /* 0x30, */
|
||||
!(idc_sta & STC_IDL) || /* !idle, */
|
||||
sim_is_active (uptr)) break; /* unit busy, ignore */
|
||||
uptr->FNC = f | CMC_DRV; /* save cmd */
|
||||
idc_sta = idc_sta & ~STC_IDL; /* clr idle */
|
||||
sim_activate (uptr, idc_ctime); /* schedule */
|
||||
break;
|
||||
|
@ -687,6 +728,8 @@ uint32 u;
|
|||
UNIT *uptr;
|
||||
|
||||
idc_sta = STC_IDL | STA_BSY; /* idle, busy */
|
||||
idc_wdptr = 0;
|
||||
idd_wdptr = 0;
|
||||
idc_1st = 0; /* clear flag */
|
||||
idc_svun = idc_db = 0; /* clear unit, buf */
|
||||
idc_sec = 0; /* clear addr */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* id_io.c: Interdata CPU-independent I/O routines
|
||||
|
||||
Copyright (c) 2001-2005, Robert M. Supnik
|
||||
Copyright (c) 2001-2006, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -23,6 +23,7 @@
|
|||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
30-Mar-06 RMS Fixed bug, GO preserves EXA and SSTA (found by Davis Johnson)
|
||||
21-Jun-03 RMS Changed subroutine argument for ARM compiler conflict
|
||||
|
||||
Interdata I/O devices are defined by a device information block:
|
||||
|
@ -209,7 +210,7 @@ switch (op) { /* case IO op */
|
|||
sch_wdc[ch] = 0;
|
||||
}
|
||||
else if (dat & SCHC_GO) { /* go? */
|
||||
sch_cmd[ch] = dat & (SCHC_GO | SCHC_RD);
|
||||
sch_cmd[ch] = dat & (SCHC_EXA | SCHC_SSTA| SCHC_GO | SCHC_RD);
|
||||
if (sch_wdc[ch] <= 4) { /* 4 bytes? */
|
||||
sch_sa[ch] = (sch_sa[ch] & PAMASK16) | bank; /* 16b addr */
|
||||
sch_ea[ch] = (sch_ea[ch] & PAMASK16) | bank;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* id_mt.c: Interdata magnetic tape simulator
|
||||
|
||||
Copyright (c) 2001-2005, Robert M Supnik
|
||||
Copyright (c) 2001-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
mt M46-494 dual density 9-track magtape controller
|
||||
|
||||
16-Feb-06 RMS Added tape capacity checking
|
||||
18-Mar-05 RMS Added attached test to detach routine
|
||||
07-Dec-04 RMS Added read-only file support
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
|
@ -153,6 +154,8 @@ MTAB mt_mod[] = {
|
|||
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "CAPACITY", "CAPACITY",
|
||||
&sim_tape_set_capac, &sim_tape_show_capac, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO",
|
||||
&set_dev, &show_dev, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "SELCH", "SELCH",
|
||||
|
@ -260,6 +263,7 @@ uint32 i;
|
|||
int32 u = uptr - mt_dev.units;
|
||||
uint32 dev = mt_dib.dno + (u * o_MT0);
|
||||
t_mtrlnt tbc;
|
||||
t_bool passed_eot;
|
||||
t_stat st, r = SCPE_OK;
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
|
||||
|
@ -273,7 +277,7 @@ if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
|
|||
|
||||
if (uptr->UCMD & MTC_STOP2) { /* stop, gen NMTN? */
|
||||
uptr->UCMD = 0; /* clr cmd */
|
||||
uptr->UST = STA_NMTN; /* set nmtn, not eot */
|
||||
uptr->UST = uptr->UST | STA_NMTN; /* set nmtn */
|
||||
mt_xfr = 0; /* clr xfr */
|
||||
if (mt_arm[u]) SET_INT (v_MT + u); /* set intr */
|
||||
return SCPE_OK;
|
||||
|
@ -287,6 +291,7 @@ if (uptr->UCMD & MTC_STOP1) { /* stop, gen EOM? */
|
|||
return SCPE_OK;
|
||||
}
|
||||
|
||||
passed_eot = sim_tape_eot (uptr); /* passed EOT? */
|
||||
switch (uptr->UCMD) { /* case on function */
|
||||
|
||||
case MTC_REW: /* rewind */
|
||||
|
@ -388,6 +393,8 @@ switch (uptr->UCMD) { /* case on function */
|
|||
break;
|
||||
} /* end case */
|
||||
|
||||
if (!passed_eot && sim_tape_eot (uptr)) /* just passed EOT? */
|
||||
uptr->UST = uptr->UST | STA_EOT;
|
||||
uptr->UCMD = uptr->UCMD | MTC_STOP1; /* set stop stage 1 */
|
||||
sim_activate (uptr, mt_rtime); /* schedule */
|
||||
return r;
|
||||
|
|
465
LGP/lgp_doc.txt
465
LGP/lgp_doc.txt
|
@ -1,465 +0,0 @@
|
|||
To: Users
|
||||
From: Bob Supnik
|
||||
Subj: LGP Simulator Usage
|
||||
Date: 15-Feb-2004
|
||||
|
||||
COPYRIGHT NOTICE
|
||||
|
||||
The following copyright notice applies to both the SIMH source and binary:
|
||||
|
||||
Original code published in 1993-2004, written by Robert M Supnik
|
||||
Copyright (c) 1993-2004, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
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 memorandum documents the GRI-909 simulator.
|
||||
|
||||
|
||||
1. Simulator Files
|
||||
|
||||
sim/ scp.h
|
||||
sim_console.h
|
||||
sim_defs.h
|
||||
sim_fio.h
|
||||
sim_rev.h
|
||||
sim_sock.h
|
||||
sim_timer.h
|
||||
sim_tmxr.h
|
||||
scp.c
|
||||
sim_console.c
|
||||
sim_fio.c
|
||||
sim_sock.c
|
||||
sim_timer.c
|
||||
sim_tmxr.c
|
||||
|
||||
sim/gri/ lgp_defs.h
|
||||
lgp_cpu.c
|
||||
lgp_stddev.c
|
||||
lgp_sys.c
|
||||
|
||||
2. LGP Features
|
||||
|
||||
The LGP is configured as follows:
|
||||
|
||||
device simulates
|
||||
name(s)
|
||||
|
||||
CPU LGP-30 or LGP-21 CPU with 4096 words of memory
|
||||
TTI Typewriter input (keyboard and reader)
|
||||
TTO Typewriter output (printer and punch)
|
||||
PTR high-speed paper tape reader
|
||||
PTP high-speed paper tape punch
|
||||
|
||||
The LGP simulator implements the following unique stop conditions:
|
||||
|
||||
- LGP-30 only: arithmetic overflow
|
||||
- LGP-21 only: reference to undefined I/O device.
|
||||
|
||||
The LOAD and DUMP commands are not implemented.
|
||||
|
||||
2.1 CPU
|
||||
|
||||
The CPU implements either the LGP-30 or the LGP-21:
|
||||
|
||||
SET CPU LGP30 set LGP-30
|
||||
SET CPU LGP21 set LGP-21
|
||||
|
||||
The default is the LGP-30. Memory size is fixed at 4096 words.
|
||||
|
||||
The following commands implement various front panel functions:
|
||||
|
||||
D A value equivalent to the MANUAL INPUT button
|
||||
SET CPU FILL{=value} equivalent to the FILL INSTRUCTION button;
|
||||
if no value is given, fills IR from A;
|
||||
otherwise, fills IR from the specified value
|
||||
SET CPU EXEC{=value} equivalent to the EXECUTE button;
|
||||
if no value is given, executes the instruction
|
||||
in IR; otherwise, executes the instruction
|
||||
specified by the value
|
||||
SET CPU MANUAL equivalent to setting the MANUAL INPUT switch
|
||||
on the Typewriter; Typewriter input is taken
|
||||
from the keyboard
|
||||
SET CPU TAPE equivalent to clearing the MANUAL INPUT switch
|
||||
on the Typewriter; TYpewriter input is taken
|
||||
from the Typewriter paper tape reader
|
||||
|
||||
The following commands control the display of information:
|
||||
|
||||
SET CPU LGPHEX numeric displays use LGP hexadecimal encoding
|
||||
SET CPU STANDARD numeric displays use standard hexadecimal
|
||||
SET CPU TRACK symbolic addresses are ttss, where tt = track
|
||||
(0-63) and ss = sector (0-63)
|
||||
SET CPU NORMAL symbolic addresses are normal linear addresses,
|
||||
from 0 to 4095.
|
||||
|
||||
The defaults are STANDARD hex and TRACK addresses.
|
||||
|
||||
The LGP-30 implements the following additional commands:
|
||||
|
||||
SET CPU 4B sets the CPU to 4-bit input mode
|
||||
SET CPU 6B sets the CPU to 6-bit input mode
|
||||
SET CPU INPUT=TTI sets the CPU to read from the Typewriter
|
||||
SET CPU INPUT=PTR sets the CPU to read from the high-speed reader
|
||||
SET CPU OUTPUT=TTO sets the CPU to output to the Typewriter
|
||||
SET CPU OUTPUT=PTP sets the CPU to output to the high-speed punch
|
||||
|
||||
The defaults are TAPE input, 4B input mode, input and output assigned to the
|
||||
Typewriter.
|
||||
|
||||
CPU registers include the visible state of the processor as well as the
|
||||
control registers for the interrupt system.
|
||||
|
||||
name size comments
|
||||
|
||||
PC 12 counter
|
||||
A 32 accumulator
|
||||
IR 32 instruction register
|
||||
OVF 1 overflow flag (LGP-21 only)
|
||||
TSW 1 transfer switch
|
||||
BP32 1 breakpoint 32 switch
|
||||
BP16 1 breakpoint 16 switch
|
||||
BP8 1 breakpoint 8 switch
|
||||
BP4 1 breakpoint 4 switch
|
||||
INPST 1 input pending flag
|
||||
INPDN 1 input done flag
|
||||
OUTST 1 output pending flag
|
||||
OUTDN 1 output done flag
|
||||
WRU 8 interrupt character
|
||||
|
||||
2.2 Typewriter Input (TTI)
|
||||
|
||||
The Typewriter input consists of two units: the keyboard (unit 0) and
|
||||
the paper-tape reader (unit 1). The keyboard is permanently associated
|
||||
with the console window. The paper-tape reader can be attached to a
|
||||
disk file. The RPOS register specifies the number of the next data item
|
||||
to be read. Thus, by changing RPOS, the user can backspace or advance
|
||||
the reader.
|
||||
|
||||
The Typewriter input has the following options:
|
||||
|
||||
SET TTI1 ASCII default tape file format is ASCII-encoded
|
||||
Flex
|
||||
SET TTI1 FLEX default tape file format is transposed Flex
|
||||
SET TTI1 CSTOP reader recognizes conditional stop
|
||||
SET TTI1 NOCSTOP reader ignores conditional stop
|
||||
SET TTI RSTART start the reader; equivalent to the
|
||||
START READER lever
|
||||
SET TTI RSTOP stop the reader; equivalent to the
|
||||
STOP READER lever
|
||||
SET TTI START send START signal to the CPU; equivalent
|
||||
to the START COMPUTE lever
|
||||
|
||||
Transposed Flex has the tape channels in this order: 6-1-2-3-4-5.
|
||||
|
||||
The ATTACH command recognizes two switches:
|
||||
|
||||
ATT -A TTI1 file file format is ASCII-encoded Flex
|
||||
ATT -F TTI1 file file format is transposed Flex
|
||||
|
||||
The Typewriter input implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 6 data buffer
|
||||
RDY 1 data ready flag
|
||||
KPOS 32 count of keyboard characters
|
||||
RPOS 32 position in the reader input file
|
||||
TIME 24 time between keyboard polls/reader characters
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling for the Typewriter paper-tape reader is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of tape
|
||||
|
||||
end of file 1 report error and stop
|
||||
0 out of tape
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.3 Typewriter Output (TTO)
|
||||
|
||||
The Typewriter output consists of two units: the printer (unit 0) and
|
||||
the paper-tape punch (unit 1). The printer is permanently associated
|
||||
with the console window. The paper-tape punch can be attached to a
|
||||
disk file. The PPOS register specifies the number of the next data item
|
||||
to be written. Thus, by changing PPOS, the user can backspace or advance
|
||||
the reader.
|
||||
|
||||
The Typewriter output has the following options:
|
||||
|
||||
SET TTO1 ASCII default tape file format is ASCII-encoded
|
||||
Flex
|
||||
SET TTO1 FLEX default tape file format is transposed Flex
|
||||
SET TTO1 FEED=n punch 'n' feed (0) characters
|
||||
|
||||
|
||||
Transposed Flex has the tape channels in this order: 6-1-2-3-4-5. The
|
||||
default is ASCII-encoded Flex.
|
||||
|
||||
The ATTACH command recognizes two switches:
|
||||
|
||||
ATT -A TTO1 file file format is ASCII-encoded Flex
|
||||
ATT -F TTO1 file file format is transposed Flex
|
||||
|
||||
The Typewriter output implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 6 data buffer
|
||||
UC 1 upper case flag
|
||||
TPOS 32 count of output characters
|
||||
PPOS 32 position in the punch output file
|
||||
TIME 24 time from I/O initiation to completion
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of tape
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
|
||||
2.4 High Speed Paper-Tape Reader (PTR)
|
||||
|
||||
The paper tape reader (PTR) reads data from or a disk file. The POS
|
||||
register specifies the number of the next data item to be read.
|
||||
Thus, by changing POS, the user can backspace or advance the reader.
|
||||
|
||||
The paper-tape reader has the following options:
|
||||
|
||||
SET PTR ASCII default tape file format is ASCII-encoded
|
||||
Flex
|
||||
SET PTR FLEX default tape file format is transposed Flex
|
||||
|
||||
Transposed Flex has the tape channels in this order: 6-1-2-3-4-5. The
|
||||
default is ASCII-encoded Flex.
|
||||
|
||||
The ATTACH command recognizes two switches:
|
||||
|
||||
ATT -A PTR file file format is ASCII-encoded Flex
|
||||
ATT -F PTR file file format is transposed Flex
|
||||
|
||||
The paper tape reader implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF t last data item processed
|
||||
RDY 1 data ready flag
|
||||
POS 32 position in the input file
|
||||
TIME 24 time from I/O initiation to completion
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of tape
|
||||
|
||||
end of file 1 report error and stop
|
||||
0 out of tape
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.5 High Speed Paper-Tape Punch (PTP)
|
||||
|
||||
The paper tape punch (PTP) writes data to a disk file. The POS
|
||||
register specifies the number of the next data item to be written.
|
||||
Thus, by changing POS, the user can backspace or advance the punch.
|
||||
|
||||
The paper tape punch has the following options:
|
||||
|
||||
SET PTP ASCII default tape file format is ASCII-encoded
|
||||
Flex
|
||||
SET PTP FLEX default tape file format is transposed Flex
|
||||
SET PTP FEED=n punch 'n' feed (0) characters
|
||||
|
||||
Transposed Flex has the tape channels in this order: 6-1-2-3-4-5. The
|
||||
default is ASCII-encoded Flex.
|
||||
|
||||
The ATTACH command recognizes two switches:
|
||||
|
||||
ATT -A PTP file file format is ASCII-encoded Flex
|
||||
ATT -F PTP file file format is transposed Flex
|
||||
|
||||
The paper tape punch implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 6 last data item processed
|
||||
POS 32 position in the output file
|
||||
TIME 24 time from I/O initiation to completion
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of tape
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.6 Symbolic Display and Input
|
||||
|
||||
The LGP simulator implements symbolic display and input. Display is
|
||||
controlled by command line switches:
|
||||
|
||||
-a display as character (tape files only)
|
||||
-h display as standard hexadecimal
|
||||
-l display as LGP hexadecimal
|
||||
-m display instruction mnemonics
|
||||
-n display addresses in normal format
|
||||
(overrides SET CPU TRACK)
|
||||
-t display addresses as track/sector
|
||||
(overrides SET CPU NORMAL)
|
||||
|
||||
Input parsing is controlled by the first character typed in or by command
|
||||
line switches:
|
||||
|
||||
' or -a Flex character
|
||||
- or opcode instruction mnemonic
|
||||
numeric hexadecimal number
|
||||
|
||||
LGP hexadecimal differs from standard hexadecimal in the characters used
|
||||
for digits 10-15
|
||||
|
||||
digit standard hex LPG hex
|
||||
|
||||
10 A F
|
||||
11 B G
|
||||
12 C J
|
||||
13 D K
|
||||
14 E Q
|
||||
15 F W
|
||||
|
||||
There is only instruction format:
|
||||
|
||||
{-}op address
|
||||
|
||||
'op' is always a single letter. A track/sector address (specified by
|
||||
SET CPU TRACK or switch -t) is two decimal numbers between 0 and 63,
|
||||
representing the track and sector. A linear address (specified by
|
||||
SET CPU NORMAL or switch -n) is one decimal number between 0 and 4095.
|
||||
For example:
|
||||
|
||||
sim> d -n 64 10640
|
||||
sim> ex -mn 64
|
||||
64: B 400
|
||||
sim> ex -mt 100
|
||||
0100: B 0616
|
||||
|
||||
2.7 Character Set
|
||||
|
||||
The LGP Typewriter was a Friden Flexowriter. Input was always upper case;
|
||||
output could be either upper case or lower case. The following table provides
|
||||
equivalences between LPG Typewriter coding and ASCII.
|
||||
|
||||
Typewriter Input LC output UC output
|
||||
code (hex)
|
||||
|
||||
00 illegal illegal illegal
|
||||
01 z or Z z Z
|
||||
02 0 or ) 0 )
|
||||
03 space space space
|
||||
04 illegal lower case lower case
|
||||
05 b or B b B
|
||||
06 1 or L 1 L
|
||||
07 - or _ 0 _
|
||||
10 illegal upper case upper case
|
||||
11 y or Y y Y
|
||||
12 2 or * 2 *
|
||||
13 + or = + =
|
||||
14 illegal color shift color shift
|
||||
15 r or R r R
|
||||
16 3 or " 3 "
|
||||
17 ; or : ; :
|
||||
20 newline newline newline
|
||||
21 i or I i I
|
||||
22 4 or ^ 4 ^
|
||||
23 / or ? / ?
|
||||
24 illegal backspace backspace
|
||||
25 d or D d D
|
||||
26 5 or % 5 %
|
||||
27 . or ] . ]
|
||||
30 tab tab tab
|
||||
31 n or N n N
|
||||
32 6 or $ 6 $
|
||||
33 , or [ , [
|
||||
34 illegal illegal illegal
|
||||
35 m or M m M
|
||||
36 7 or ~ 7 ~
|
||||
37 v or V v V
|
||||
40 ' (cond stop) ' '
|
||||
41 p or P p P
|
||||
42 8 or # 8 #
|
||||
43 o or O o O
|
||||
44 illegal illegal illegal
|
||||
45 e or E e E
|
||||
46 9 or ( 9 (
|
||||
47 x or X x X
|
||||
50 illegal illegal illegal
|
||||
51 u or U u U
|
||||
52 f or F f F
|
||||
53 illegal illegal illegal
|
||||
54 illegal illegal illegal
|
||||
55 t or T t T
|
||||
56 g or G g G
|
||||
57 illegal illegal illegal
|
||||
60 illegal illegal illegal
|
||||
61 h or H h H
|
||||
62 j or J j J
|
||||
63 illegal illegal illegal
|
||||
64 illegal illegal illegal
|
||||
65 c or C c C
|
||||
66 k or K k K
|
||||
67 illegal illegal illegal
|
||||
70 illegal illegal illegal
|
||||
71 a or A a A
|
||||
72 q or Q q Q
|
||||
73 illegal illegal illegal
|
||||
74 illegal illegal illegal
|
||||
75 s or S s S
|
||||
76 w or W w W
|
||||
77 illegal illegal illegal
|
||||
|
||||
Certain characters on the Flexowriter keyboard don't exist in ASCII.
|
||||
The following table provides ASCII substitution characters for the unique
|
||||
Flexowriter characters (this is compatible with the coding in the LGP30
|
||||
paper tape archive):
|
||||
|
||||
Typewriter Flex ASCII
|
||||
code
|
||||
|
||||
UC 12 delta ^
|
||||
UC 1E pi ~
|
||||
UC 22 sigma #
|
||||
|
||||
Certain Flexowriter codes have no character equivalent of any kind.
|
||||
For paper-tape reader and punch files, these are encoded as #dd, where
|
||||
dd is a decimal number between 0 and 63.
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Modified from the original NOVA simulator by Robert Supnik.
|
||||
|
||||
Copyright (c) 1998-2005, Charles E Owen
|
||||
Copyright (c) 1998-2006, Charles E Owen
|
||||
Portions Copyright (c) 1993-2002, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
|
@ -28,6 +28,7 @@
|
|||
|
||||
cpu Eclipse central processor
|
||||
|
||||
06-Feb-06 RMS Fixed bug in DIVS (found by Mark Hittinger)
|
||||
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
|
||||
25-Aug-05 RMS Fixed DIVS overflow cases
|
||||
29-Nov-03 CEO Corrected POPJ and Bit operations bugs
|
||||
|
@ -1664,7 +1665,7 @@ if ((IR & 0100017) == 0100010) { /* This pattern for all
|
|||
}
|
||||
if (IR == 0157710) { /* DIVS: Signed Divide */
|
||||
if ((AC[0] == 0) ||
|
||||
((AC[0] = 0100000) && (AC[1] == 0) && (AC[2] = 0177777)))
|
||||
((AC[0] == 0100000) && (AC[1] == 0) && (AC[2] = 0177777)))
|
||||
C = 0200000;
|
||||
else {
|
||||
sAC2 = AC[2];
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* nova_cpu.c: NOVA CPU simulator
|
||||
|
||||
Copyright (c) 1993-2005, Robert M. Supnik
|
||||
Copyright (c) 1993-2006, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
cpu Nova central processor
|
||||
|
||||
06-Feb-06 RMS Fixed bug in DIVS (found by Mark Hittinger)
|
||||
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
|
||||
25-Aug-05 RMS Fixed DIVS case 2^31 / - 1
|
||||
14-Jan-04 RMS Fixed device enable/disable support (found by Bruce Ray)
|
||||
|
@ -743,7 +744,7 @@ while (reason == 0) { /* loop until halted */
|
|||
}
|
||||
if (pulse == iopN) { /* divs */
|
||||
if ((AC[2] == 0) || /* overflow? */
|
||||
((AC[0] = 0100000) && (AC[1] == 0) && (AC[2] == 0177777)))
|
||||
((AC[0] == 0100000) && (AC[1] == 0) && (AC[2] == 0177777)))
|
||||
C = CBIT;
|
||||
else {
|
||||
mddata = (SEXT (AC[0]) << 16) | AC[1];
|
||||
|
|
|
@ -1,682 +0,0 @@
|
|||
To: Users
|
||||
From: Bob Supnik
|
||||
Subj: Nova Simulator Usage
|
||||
Date: 15-Nov-2004
|
||||
|
||||
COPYRIGHT NOTICE
|
||||
|
||||
The following copyright notice applies to both the SIMH source and binary:
|
||||
|
||||
Original code published in 1993-2005, written by Robert M Supnik
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
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 memorandum documents the Nova simulator.
|
||||
|
||||
|
||||
1. Simulator Files
|
||||
|
||||
sim/ scp.h
|
||||
sim_console.h
|
||||
sim_defs.h
|
||||
sim_fio.h
|
||||
sim_rev.h
|
||||
sim_sock.h
|
||||
sim_tape.h
|
||||
sim_timer.h
|
||||
sim_tmxr.h
|
||||
scp.c
|
||||
sim_console.c
|
||||
sim_fio.c
|
||||
sim_sock.c
|
||||
sim_tape.c
|
||||
sim_timer.c
|
||||
sim_tmxr.c
|
||||
|
||||
sim/nova/ nova_defs.h
|
||||
nova_cpu.c
|
||||
nova_clk.c
|
||||
nova_dkp.c
|
||||
nova_dsk.c
|
||||
nova_lp.c
|
||||
nova_mta.c
|
||||
nova_plt.c
|
||||
nova_qty.c
|
||||
nova_sys.c
|
||||
nova_tt.c
|
||||
nova_tt1.c
|
||||
|
||||
2. Nova Features
|
||||
|
||||
The Nova simulator is configured as follows:
|
||||
|
||||
device simulates
|
||||
name(s)
|
||||
|
||||
CPU Nova, Nova 3, or Nova 4 CPU with 32KW of memory
|
||||
- hardware multiply/divide
|
||||
PTR,PTP paper tape reader/punch
|
||||
TTI,TTO console terminal
|
||||
TTI1,TTO1 second terminal
|
||||
LPT line printer
|
||||
PLT plotter
|
||||
CLK real-time clock
|
||||
DK head-per-track disk controller
|
||||
DP moving head disk controller with four drives
|
||||
MT magnetic tape controller with eight drives
|
||||
QTY 4060 multiplexor with up to 64 lines
|
||||
ALM 4255 multiplexor with up to 64 lines
|
||||
|
||||
The Nova simulator implements these unique stop conditions:
|
||||
|
||||
- reference to undefined I/O device, and STOP_DEV is set
|
||||
- more than INDMAX indirect addresses are detected during
|
||||
an interrupt
|
||||
- more than INDMAX indirect addresses are detected during
|
||||
memory reference address decoding
|
||||
|
||||
Note that indirect address loop detection does not exist on unmapped
|
||||
Novas. Some DG diagnostics test thousands of levels of indirect
|
||||
addressing. INDMAX may have to be set to 32,000 to get diagnostics
|
||||
to run properly.
|
||||
|
||||
The Nova loader supports standard binary format tapes. The DUMP command
|
||||
is not implemented.
|
||||
|
||||
Most devices can be disabled or enabled, by the commands:
|
||||
|
||||
SET <dev> DISABLED
|
||||
SET <dev> ENABLED
|
||||
|
||||
All devices are enabled by default.
|
||||
|
||||
2.1 CPU
|
||||
|
||||
The only CPU options are the presence of the optional instructions
|
||||
and the size of main memory.
|
||||
|
||||
SET CPU MDV enable multiply/divide
|
||||
SET CPU NOVA3 enable Nova3 instructions
|
||||
SET CPU NOVA4 enable Nova4 instructions
|
||||
SET CPU NONE disable all optional instructions
|
||||
SET CPU 4K set memory size = 4K
|
||||
SET CPU 8K set memory size = 8K
|
||||
SET CPU 12K set memory size = 12K
|
||||
SET CPU 16K set memory size = 16K
|
||||
SET CPU 20K set memory size = 20K
|
||||
SET CPU 24K set memory size = 24K
|
||||
SET CPU 28K set memory size = 28K
|
||||
SET CPU 32K set memory size = 32K
|
||||
|
||||
(MDV = unsigned multiply/divide instructions)
|
||||
(Nova 3 = unsigned multiply/divide, stack, trap instructions)
|
||||
(Nova 4 = unsigned and signed multiply/divide, stack, byte, trap instructions)
|
||||
|
||||
If memory size is being reduced, and the memory being truncated contains
|
||||
non-zero data, the simulator asks for confirmation. Data in the truncated
|
||||
portion of memory is lost. Initial memory size is 32K.
|
||||
|
||||
The CPU supports the boot command. BOOT CPU simulates the Nova hardware
|
||||
APL (automatic program load) feature. The switch register (SR) bits 12:17
|
||||
must contain the device code of the device to be booted. If the device is
|
||||
a "high-speed" (channel) device, SR bit 0 should also be set.
|
||||
|
||||
CPU registers include the visible state of the processor as well as the
|
||||
control registers for the interrupt system.
|
||||
|
||||
name size comments
|
||||
|
||||
PC 15 program counter
|
||||
AC0..AC3 16 accumulators 0..3
|
||||
C 1 carry
|
||||
SR 16 front panel switches
|
||||
PI 16 priority interrupt mask
|
||||
ION 1 interrupt enable
|
||||
ION_DELAY 1 interrupt enable delay for ION
|
||||
PWR 1 power fail interrupt
|
||||
INT 15 interrupt pending flags
|
||||
BUSY 15 device busy flags
|
||||
DONE 15 device done flags
|
||||
DISABLE 15 device interrupt disable flags
|
||||
STOP_DEV 1 stop on undefined IOT
|
||||
INDMAX 15 maximum number of nested indirects
|
||||
PCQ[0:63] 15 PC prior to last JMP, JMS, or interrupt;
|
||||
most recent PC change first
|
||||
WRU 8 interrupt character
|
||||
|
||||
2.2 Programmed I/O Devices
|
||||
|
||||
2.2.1 Paper Tape Reader (PTR)
|
||||
|
||||
The paper tape reader (PTR) reads data from a disk file. The POS
|
||||
register specifies the number of the next data item to be read. Thus,
|
||||
by changing POS, the user can backspace or advance the reader.
|
||||
|
||||
The paper tape reader implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
BUSY 1 device busy flag
|
||||
DONE 1 device done flag
|
||||
DISABLE 1 interrupt disable flag
|
||||
INT 1 interrupt pending flag
|
||||
POS 32 position in the input file
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of tape or paper
|
||||
|
||||
end of file 1 report error and stop
|
||||
0 out of tape or paper
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.2.2 Paper Tape Punch (PTP)
|
||||
|
||||
The paper tape punch (PTP) writes data to a disk file. The POS
|
||||
register specifies the number of the next data item to be written.
|
||||
Thus, by changing POS, the user can backspace or advance the punch.
|
||||
|
||||
The paper tape punch implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
BUSY 1 device busy flag
|
||||
DONE 1 device done flag
|
||||
DISABLE 1 interrupt disable flag
|
||||
INT 1 interrupt pending flag
|
||||
POS 32 position in the output file
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of tape or paper
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.2.3 Terminal Input (TTI)
|
||||
|
||||
The terminal input polls the console keyboard for input. Terminal
|
||||
input options include the ability to set ANSI mode or limited Dasher
|
||||
compatibility mode:
|
||||
|
||||
SET TTI ANSI normal mode
|
||||
SET TTI DASHER Dasher mode
|
||||
|
||||
Setting either TTI or TTO changes both devices. In Dasher mode, carriage
|
||||
return is changed to newline on input, and ^X is changed to backspace.
|
||||
|
||||
The terminal input implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
BUSY 1 device busy flag
|
||||
DONE 1 device done flag
|
||||
DISABLE 1 interrupt disable flag
|
||||
INT 1 interrupt pending flag
|
||||
POS 32 number of characters input
|
||||
TIME 24 keyboard polling interval
|
||||
|
||||
2.2.4 Terminal Output (TTO)
|
||||
|
||||
The terminal output writes to the simulator console window. Terminal
|
||||
output options include the the ability to set ANSI mode or limited
|
||||
Dasher compatibility mode:
|
||||
|
||||
SET TTO ANSI normal mode
|
||||
SET TTO DASHER Dasher mode
|
||||
|
||||
Setting either TTI or TTO changes both devices. In Dasher mode, carriage
|
||||
return is changed to newline on input, and ^X is changed to backspace.
|
||||
|
||||
The terminal output implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
BUSY 1 device busy flag
|
||||
DONE 1 device done flag
|
||||
DISABLE 1 interrupt disable flag
|
||||
INT 1 interrupt pending flag
|
||||
POS 32 number of characters output
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
|
||||
2.2.5 Line Printer (LPT)
|
||||
|
||||
The line printer (LPT) writes data to a disk file. The POS register
|
||||
specifies the number of the next data item to be written. Thus,
|
||||
by changing POS, the user can backspace or advance the printer.
|
||||
|
||||
The line printer implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
BUSY 1 device busy flag
|
||||
DONE 1 device done flag
|
||||
DISABLE 1 interrupt disable flag
|
||||
INT 1 interrupt pending flag
|
||||
POS 32 position in the output file
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of paper
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.2.6 Real-Time Clock (CLK)
|
||||
|
||||
The real-time clock (CLK) line frequency can be adjusted as follows:
|
||||
|
||||
SET CLK 60HZ set line frequency to 60Hz
|
||||
SET CLK 50HZ set line frequency to 50Hz
|
||||
|
||||
The default is 60Hz.
|
||||
|
||||
The clock implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
SELECT 2 selected clock interval
|
||||
BUSY 1 device busy flag
|
||||
DONE 1 device done flag
|
||||
DISABLE 1 interrupt disable flag
|
||||
INT 1 interrupt pending flag
|
||||
TIME0 24 clock frequency, select = 0
|
||||
TIME1 24 clock frequency, select = 1
|
||||
TIME2 24 clock frequency, select = 2
|
||||
TIME3 24 clock frequency, select = 3
|
||||
|
||||
The real-time clock autocalibrates; the clock interval is adjusted up
|
||||
or down so that the clock tracks actual elapsed time.
|
||||
|
||||
2.2.7 Plotter (PTP)
|
||||
|
||||
The plotter (PLT) writes data to a disk file. The POS register
|
||||
specifies the number of the next data item to be written. Thus,
|
||||
by changing POS, the user can backspace or advance the plotter.
|
||||
|
||||
The plotter implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
BUSY 1 device busy flag
|
||||
DONE 1 device done flag
|
||||
DISABLE 1 interrupt disable flag
|
||||
INT 1 interrupt pending flag
|
||||
POS 32 position in the output file
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of tape or paper
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.2.8 Second Terminal (TTI1, TTO1)
|
||||
|
||||
The second terminal consists of two independent devices, TTI1 and TTO1.
|
||||
The additional terminal performs input and output through a Telnet session
|
||||
connecting into a user-specified port. The ATTACH command specifies the
|
||||
port to be used:
|
||||
|
||||
ATTACH TTI1 <port> set up listening port
|
||||
|
||||
where port is a decimal number between 1 and 65535 that is not being used
|
||||
for other TCP/IP activities.
|
||||
|
||||
Once TTI1 is attached and the simulator is running, the terminal listens
|
||||
for a connection on the specified port. It assumes that the incoming
|
||||
connection is a Telnet connection. The connection remain opens until
|
||||
disconnected by the Telnet client, or by a DETACH TTI1 command.
|
||||
|
||||
The second terminal has two options, recognized on both devices, for
|
||||
setting limited Dasher-compatibility mode or ANSI mode:
|
||||
|
||||
SET TTI1 ANSI normal mode
|
||||
SET TTI1 DASHER Dasher mode
|
||||
SET TTO1 ANSI normal mode
|
||||
SET TTO1 DASHER Dasher mode
|
||||
|
||||
Setting either TTI1 or TTO1 changes both devices. In Dasher mode, carriage
|
||||
return is changed to newline on input, and ^X is changed to backspace.
|
||||
TTO1 supports output logging. The SET TTO1 LOG command enables logging:
|
||||
|
||||
SET TTO1 LOG=filename log output to filename
|
||||
|
||||
The SET TTO1 NOLOG command disables logging and closes the open log
|
||||
file, if any.
|
||||
|
||||
The SHOW TTI1 CONNECTIONS command displays the current connection to TTI1.
|
||||
The SHOW TTI1 STATISTICS command displays statistics for the current connection.
|
||||
The SET TTI1 DISCONNECT{=0} disconnects the current connection.
|
||||
|
||||
The second terminal input implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
BUSY 1 device busy flag
|
||||
DONE 1 device done flag
|
||||
DISABLE 1 interrupt disable flag
|
||||
INT 1 interrupt pending flag
|
||||
TIME 24 keyboard polling interval
|
||||
|
||||
The second terminal output implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
BUSY 1 device busy flag
|
||||
DONE 1 device done flag
|
||||
DISABLE 1 interrupt disable flag
|
||||
INT 1 interrupt pending flag
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
|
||||
2.2.8 Asynchronous Multiplexors (QTY, ALM)
|
||||
|
||||
The QTY and ALM are terminal multiplexors with up to 64 lines. Either
|
||||
the QTY or ALM can be enabled, but not both; the ALM is enabled by
|
||||
default. The number of lines can be changed with the command
|
||||
|
||||
SET {QTY|ALM} LINES=n set line count to n
|
||||
|
||||
The line count maximum is 64.
|
||||
|
||||
The QTY and ALM support 8-bit input and output of characters. 8-bit I/O
|
||||
may be incompatible with certain operating systems; 7-bit is the default.
|
||||
The command
|
||||
|
||||
SET {QTY|ALM} 8B
|
||||
|
||||
enables 8-bit input and output.
|
||||
|
||||
The terminal lines perform input and output through Telnet sessions
|
||||
connected to a user-specified port. The ATTACH command specifies
|
||||
the port to be used:
|
||||
|
||||
ATTACH {-am} {QTY|ALM} <port> set up listening port
|
||||
|
||||
where port is a decimal number between 1 and 65535 that is not being used
|
||||
for other TCP/IP activities. For the ALM multiplexor, the optional switch
|
||||
-m turns on the multiplexor modem controls; the optional switch -a turns on
|
||||
active disconnects (disconnect session if computer clears Data Terminal Ready).
|
||||
The QTY multiplexor does not support modem control. Without modem control,
|
||||
the multiplexor behaves as though terminals were directly connected;
|
||||
disconnecting the Telnet session does not cause any operating system-
|
||||
visible change in line status.
|
||||
|
||||
Once the multiplexor is attached and the simulator is running, it will listen
|
||||
for connections on the specified port. It assumes that the incoming
|
||||
connections are Telnet connections. The connection remains open until
|
||||
disconnected by the simulated program, the Telnet client, a SET {QTY|ALM}
|
||||
DISCONNECT command, or a DETACH {QTY|ALM} command.
|
||||
|
||||
The SHOW {QTY|ALM} CONNECTIONS command displays the current connections to
|
||||
the multiplexor. The SHOW {QTY|ALM} STATISTICS command displays statistics
|
||||
for active connections. The SET {QTY|ALM| DISCONNECT=linenumber disconnects
|
||||
the specified line.
|
||||
|
||||
The QTY/ALM implement these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 character buffer
|
||||
BUSY 1 device busy flag
|
||||
DONE 1 device done flag
|
||||
DISABLE 1 device disable flag
|
||||
INT 1 interrupt pending flag
|
||||
MDMCTL 1 modem control flag
|
||||
AUTODS 1 autodisconnect flag
|
||||
POLLS 32 number of service polls
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
The multiplexors do not support save and restore. All open connections are
|
||||
lost when the simulator shuts down or the multiplexor is detached.
|
||||
|
||||
2.3 Fixed Head Disk (DK)
|
||||
|
||||
Fixed head disk options include the ability to set the number of platters
|
||||
to a fixed value between 1 and 8, or to autosize the number of platters
|
||||
from the attached file:
|
||||
|
||||
SET RF 1P one platter (256K)
|
||||
SET RF 2P two platters (512K)
|
||||
SET RF 3P three platters (768K)
|
||||
SET RF 4P four platters (1024K)
|
||||
SET RF 5P five platters (1280K)
|
||||
SET RF 6P six platters (1536K)
|
||||
SET RF 7P seven platters (1792K)
|
||||
SET RF 8P eight platters (2048K)
|
||||
SET RF AUTOSIZE autosized on attach
|
||||
|
||||
The default is 1P (minimum size).
|
||||
|
||||
The fixed head disk controller implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
STAT 16 status
|
||||
DA 16 disk address
|
||||
MA 16 memory address
|
||||
BUSY 1 device busy flag
|
||||
DONE 1 device done flag
|
||||
DISABLE 1 device disable flag
|
||||
INT 1 interrupt pending flag
|
||||
WLK 8 write lock switches
|
||||
TIME 24 rotational delay, per sector
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
The fixed head disk controller supports the BOOT command.
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 disk not ready
|
||||
|
||||
Fixed head disk data files are buffered in memory; therefore, end of file
|
||||
and OS I/O errors cannot occur.
|
||||
|
||||
2.4 Moving Head Disk (DP)
|
||||
|
||||
Moving head disk options include the ability to make units write enabled or
|
||||
write locked, and to select the type of drive:
|
||||
|
||||
SET DPn LOCKED set unit n write locked
|
||||
SET DPn WRITEENABLED set unit n write enabled
|
||||
SET DPn FLOPPY set unit n to floppy disk
|
||||
SET DPn D31 set unit n to Diablo 31
|
||||
SET DPn D44 set unit n to Diablo 44
|
||||
SET DPn C111 set unit n to Century 111
|
||||
SET DPn C114 set unit n to Century 114
|
||||
SET DPn 6225 set unit n to 6225
|
||||
SET DPn 6099 set unit n to 6099
|
||||
SET DPn 6227 set unit n to 6227
|
||||
SET DPn 6070 set unit n to 6070
|
||||
SET DPn 6103 set unit n to 6103
|
||||
SET DPn 4231 set unit n to 4231
|
||||
|
||||
Units can also be set ENABLED or DISABLED. The moving head disk controller
|
||||
supports the BOOT command.
|
||||
|
||||
All drives have 256 16b words per sector. The other disk parameters are:
|
||||
|
||||
drive cylinders surfaces sectors size (MW) DG models
|
||||
|
||||
floppy 77 1 8 .158 6038
|
||||
D31 203 2 12 1.247 4047, 4237, 4238
|
||||
D44 408 4 12 5.014 4234, 6045
|
||||
C111 203 10 6 3.118 4048
|
||||
C114 203 20 12 12.472 4057, 2314
|
||||
6225 245 2 20 2.508
|
||||
6099 192 4 32 6.291
|
||||
6227 245 6 20 7.526
|
||||
6070 408 4 24 10.027
|
||||
6103 192 8 32 12.583
|
||||
4231 411 19 23 45.979
|
||||
|
||||
The moving head disk controller implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
FCCY 16 flags, command, cylinder
|
||||
USSC 16 unit, surface, sector, count
|
||||
STAT 16 status
|
||||
MA 16 memory address
|
||||
BUSY 1 device busy flag
|
||||
DONE 1 device done flag
|
||||
DISABLE 1 interrupt disable flag
|
||||
INT 1 interrupt pending flag
|
||||
DIAG 1 diagnostic mode flag
|
||||
MAP 2 map select
|
||||
STIME 24 seek time, per cylinder
|
||||
RTIME 24 rotational delay
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error processed as
|
||||
|
||||
not attached disk not ready
|
||||
|
||||
end of file assume rest of disk is zero
|
||||
|
||||
OS I/O error report error and stop
|
||||
|
||||
2.5 Magnetic Tape (MT)
|
||||
|
||||
Magnetic tape options include the ability to make units write enabled or
|
||||
or write locked.
|
||||
|
||||
SET MTn LOCKED set unit n write locked
|
||||
SET MTn WRITEENABLED set unit n write enabled
|
||||
|
||||
Units can also be set ENABLED or DISABLED. The magnetic tape controller
|
||||
supports the BOOT command.
|
||||
|
||||
The magnetic tape controller implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
CU 16 command, unit
|
||||
MA 16 memory address
|
||||
WC 16 word count
|
||||
STA1 16 status word 1
|
||||
STA2 16 status word 2
|
||||
EP 1 extended polling mode (not supported)
|
||||
BUSY 1 device busy flag
|
||||
DONE 1 device done flag
|
||||
DISABLE 1 interrupt disable flag
|
||||
INT 1 interrupt pending flag
|
||||
STOP_IOE 1 stop on I/O error
|
||||
CTIME 24 controller delay
|
||||
RTIME 24 record delay
|
||||
UST[0:7] 32 unit status, units 0-7
|
||||
POS[0:7] 31 position, units 0-7
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error processed as
|
||||
|
||||
not attached tape not ready
|
||||
|
||||
end of file bad tape
|
||||
|
||||
OS I/O error report error and stop
|
||||
|
||||
2.6 Symbolic Display and Input
|
||||
|
||||
The Nova simulator implements symbolic display and input. Display is
|
||||
controlled by command line switches:
|
||||
|
||||
-a display as ASCII character
|
||||
-c display as two character ASCII string
|
||||
-m display instruction mnemonics
|
||||
|
||||
Input parsing is controlled by the first character typed in or by command
|
||||
line switches:
|
||||
|
||||
' or -a ASCII character
|
||||
" or -c two character ASCII string
|
||||
alphabetic instruction mnemonic
|
||||
numeric octal number
|
||||
|
||||
Instruction input uses standard Nova assembler syntax. There are three
|
||||
instruction classes: memory reference, IOT, and operate.
|
||||
|
||||
Memory reference instructions have the format
|
||||
|
||||
memref {ac,}{@}address{,index}
|
||||
|
||||
LDA and STA require an initial register; ISZ, DSZ, JSR, and JMP do not.
|
||||
The syntax for addresses and indices is as follows:
|
||||
|
||||
syntax mode displacement comments
|
||||
|
||||
0 <= n < 0400 0 n
|
||||
{+/-}n >= 0400 1 {+/-}n - PC must be in range [-200, 177]
|
||||
invalid on disk
|
||||
.+/-n 1 {+/-}n must be in range [-200, 177]
|
||||
{+/-}n,2 2 {+/-}n must be in range [-200, 177]
|
||||
{+/-}n,3 3 {+/-}n must be in range [-200, 177]
|
||||
|
||||
IOT instructions have one of four formats
|
||||
|
||||
syntax example
|
||||
|
||||
iot HALT
|
||||
iot reg INTA
|
||||
iot device SKPDN
|
||||
iot reg,device DOAS
|
||||
|
||||
Devices may be specified as mnemonics or as numbers in the range 0 - 077.
|
||||
|
||||
Operate instructions have the format
|
||||
|
||||
opcode{#} reg,reg{,skip}
|
||||
|
||||
In all Nova instructions, blanks may be substituted for commas as field
|
||||
delimiters.
|
|
@ -1,6 +1,6 @@
|
|||
/* nova_dsk.c: 4019 fixed head disk simulator
|
||||
|
||||
Copyright (c) 1993-2005, Robert M. Supnik
|
||||
Copyright (c) 1993-2006, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
dsk fixed head disk
|
||||
|
||||
15-May-06 RMS Fixed bug in autosize attach (reported by David Gesswein)
|
||||
04-Jan-04 RMS Changed sim_fsize calling sequence
|
||||
26-Jul-03 RMS Fixed bug in set size routine
|
||||
14-Mar-03 RMS Fixed variable capacity interaction with save/restore
|
||||
|
@ -296,17 +297,14 @@ t_stat dsk_attach (UNIT *uptr, char *cptr)
|
|||
{
|
||||
uint32 sz, p;
|
||||
uint32 ds_bytes = DSK_DKSIZE * sizeof (int16);
|
||||
t_stat r;
|
||||
|
||||
r = attach_unit (uptr, cptr);
|
||||
if (r != SCPE_OK) return r;
|
||||
if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize (uptr->fileref))) {
|
||||
if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize_name (cptr))) {
|
||||
p = (sz + ds_bytes - 1) / ds_bytes;
|
||||
if (p >= DSK_NUMDK) p = DSK_NUMDK - 1;
|
||||
uptr->flags = (uptr->flags & ~UNIT_PLAT) | (p << UNIT_V_PLAT);
|
||||
}
|
||||
uptr->capac = UNIT_GETP (uptr->flags) * DSK_DKSIZE; /* set capacity */
|
||||
return SCPE_OK;
|
||||
return attach_unit (uptr, cptr);
|
||||
}
|
||||
|
||||
/* Change disk size */
|
||||
|
|
|
@ -1,572 +0,0 @@
|
|||
To: Users
|
||||
From: Bob Supnik
|
||||
Subj: PDP-1 Simulator Usage
|
||||
Date: 15-Nov-2004
|
||||
|
||||
COPYRIGHT NOTICE
|
||||
|
||||
The following copyright notice applies to both the SIMH source and binary:
|
||||
|
||||
Original code published in 1993-2005, written by Robert M Supnik
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
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 memorandum documents the PDP-1 simulator.
|
||||
|
||||
|
||||
1. Simulator Files
|
||||
|
||||
sim/ scp.h
|
||||
sim_console.h
|
||||
sim_defs.h
|
||||
sim_fio.h
|
||||
sim_rev.h
|
||||
sim_sock.h
|
||||
sim_timer.h
|
||||
sim_tmxr.h
|
||||
scp.c
|
||||
sim_console.c
|
||||
sim_fio.c
|
||||
sim_sock.c
|
||||
sim_timer.c
|
||||
sim_tmxr.c
|
||||
|
||||
sim/pdp1/ pdp1_defs.h
|
||||
pdp1_cpu.c
|
||||
pdp1_drm.c
|
||||
pdp1_dt.c
|
||||
pdp1_lp.c
|
||||
pdp1_stddev.c
|
||||
pdp1_sys.c
|
||||
|
||||
2. PDP-1 Features
|
||||
|
||||
The PDP-1 is configured as follows:
|
||||
|
||||
device simulates
|
||||
name(s)
|
||||
|
||||
CPU PDP-1 CPU with up to 64KW of memory
|
||||
PTR,PTP integral paper tape reader/punch
|
||||
TTY console typewriter
|
||||
LPT Type 62 line printer
|
||||
DRM Type 24 serial drum
|
||||
DRP Type 23 parallel drum
|
||||
DT Type 550 Microtape (DECtape)
|
||||
|
||||
The PDP-1 simulator implements the following unique stop conditions:
|
||||
|
||||
- an unimplemented instruction is decoded, and register
|
||||
STOP_INST is set
|
||||
- more than IND_MAX indirect addresses are detected during
|
||||
memory reference address decoding
|
||||
- more than XCT_MAX nested executes are detected during
|
||||
instruction execution
|
||||
- I/O wait, and no I/O operations outstanding (i.e, no I/O
|
||||
completion will ever occur)
|
||||
- a simulated DECtape runs off the end of its reel
|
||||
|
||||
The PDP-1 loader supports RIM format tapes and BLK format tapes. If
|
||||
the file to be loaded has an extension of .BIN, or switch -B is specified,
|
||||
the file is assumed to be BLK format; otherwise, it defaults to RIM
|
||||
format. LOAD takes an optional argument which specifies the starting
|
||||
address of the field to be loaded:
|
||||
|
||||
LOAD lisp.rim -- load RIM format file lisp.rim
|
||||
LOAD ddt.rim 70000 -- load RIM format file ddt.rim into
|
||||
the field starting at 70000
|
||||
LOAD -B macro.blk -- load BLK format file macro.blk
|
||||
|
||||
The DUMP command is not implemented.
|
||||
|
||||
2.1 CPU
|
||||
|
||||
The only CPU options are the presence of hardware multiply/divide and the
|
||||
size of main memory.
|
||||
|
||||
SET CPU MDV enable multiply/divide
|
||||
SET CPU NOMDV disable multiply/divide
|
||||
SET CPU 4K set memory size = 4K
|
||||
SET CPU 8K set memory size = 8K
|
||||
SET CPU 12K set memory size = 12K
|
||||
SET CPU 16K set memory size = 16K
|
||||
SET CPU 20K set memory size = 20K
|
||||
SET CPU 24K set memory size = 24K
|
||||
SET CPU 28K set memory size = 28K
|
||||
SET CPU 32K set memory size = 32K
|
||||
SET CPU 48K set memory size = 48K
|
||||
SET CPU 64K set memory size = 64K
|
||||
|
||||
If memory size is being reduced, and the memory being truncated contains
|
||||
non-zero data, the simulator asks for confirmation. Data in the truncated
|
||||
portion of memory is lost. Initial memory size is 64K.
|
||||
|
||||
CPU registers include the visible state of the processor as well as the
|
||||
control registers for the interrupt system.
|
||||
|
||||
name size comments
|
||||
|
||||
PC 16 program counter
|
||||
AC 18 accumulator
|
||||
IO 18 IO register
|
||||
OV 1 overflow flag
|
||||
PF 6 program flags<1:6>
|
||||
SS 6 sense switches<1:6>
|
||||
TA 16 address switches
|
||||
TW 18 test word (front panel switches)
|
||||
EXTM 1 extend mode
|
||||
IOSTA 18 IO status register
|
||||
SBON 1 sequence break enable
|
||||
SBRQ 1 sequence break request
|
||||
SBIP 1 sequence break in progress
|
||||
IOH 1 I/O halt in progress
|
||||
IOS 1 I/O synchronizer (completion)
|
||||
PCQ[0:63] 16 PC prior to last jump or interrupt;
|
||||
most recent PC change first
|
||||
STOP_INST 1 stop on undefined instruction
|
||||
SBS_INIT 1 initial state of sequence break enable
|
||||
EXTM_INIT 1 initial state of extend mode
|
||||
XCT_MAX 8 maximum XCT chain
|
||||
IND_MAX 8 maximum nested indirect addresses
|
||||
WRU 8 interrupt character
|
||||
|
||||
The CPU can maintain a history of the most recently executed instructions.
|
||||
This is controlled by the SET CPU HISTORY and SHOW CPU HISTORY commands:
|
||||
|
||||
SET CPU HISTORY clear history buffer
|
||||
SET CPU HISTORY=0 disable history
|
||||
SET CPU HISTORY=n enable history, length = n
|
||||
SHOW CPU HISTORY print CPU history
|
||||
SHOW CPU HISTORY=n print first n entries of CPU history
|
||||
|
||||
The maximum length for the history is 65536 entries.
|
||||
|
||||
2.2 Programmed I/O Devices
|
||||
|
||||
2.2.1 Paper Tape Reader (PTR)
|
||||
|
||||
The paper tape reader (PTR) reads data from or a disk file. The POS
|
||||
register specifies the number of the next data item to be read. Thus,
|
||||
by changing POS, the user can backspace or advance the reader.
|
||||
|
||||
The paper tape reader supports the BOOT command. BOOT PTR copies the
|
||||
RIM loader into memory and starts it running. BOOT PTR loads into the
|
||||
field selected by TA<0:3> (the high order four bits of the address
|
||||
switches).
|
||||
|
||||
The paper tape reader implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
DONE 1 device done flag
|
||||
RPLS 1 return restart pulse flag
|
||||
POS 32 position in the input file
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of tape
|
||||
|
||||
end of file 1 report error and stop
|
||||
0 out of tape
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.2.2 Paper Tape Punch (PTP)
|
||||
|
||||
The paper tape punch (PTP) writes data to a disk file. The POS
|
||||
register specifies the number of the next data item to be written.
|
||||
Thus, by changing POS, the user can backspace or advance the punch.
|
||||
|
||||
The paper tape punch implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
DONE 1 device done flag
|
||||
RPLS 1 return restart pulse flag
|
||||
POS 32 position in the output file
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of tape
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.2.3 Console Typewriter (TTY)
|
||||
|
||||
The Typewriter is a half-duplex electric typewriter (originally a
|
||||
Friden Flexowriter, later a Sorobon-modified IBM B). It has only a
|
||||
single buffer and a single carriage state but distinct input and
|
||||
output done and interrupt flags. The typewriter input (TTY unit 0)
|
||||
polls the console keyboard for input. The typewriter output (TTY
|
||||
unit 1) writes to the simulator console window.
|
||||
|
||||
The typewriter implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 6 typewriter buffer
|
||||
UC 1 upper case/lower case state flag
|
||||
RPLS 1 return restart pulse flag
|
||||
KDONE 1 input ready flag
|
||||
KPOS 32 number of characters input
|
||||
KTIME 24 keyboard polling interval
|
||||
TDONE 1 output done flag
|
||||
TPOS 32 number of characters output
|
||||
TTIME 24 time from I/O initiation to interrupt
|
||||
|
||||
2.2.4 Type 62 Line Printer (LPT)
|
||||
|
||||
The paper line printer (LPT) writes data to a disk file. The POS
|
||||
register specifies the number of the next data item to be written.
|
||||
Thus, by changing POS, the user can backspace or advance the printer.
|
||||
|
||||
The line printer can be disabled and enabled with the SET LPT DISABLED
|
||||
and SET LPT ENABLED commands, respectively.
|
||||
|
||||
The line printer implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
PNT 1 printing done flag
|
||||
SPC 1 spacing done flag
|
||||
RPLS 1 return restart pulse flag
|
||||
BPTR 6 print buffer pointer
|
||||
POS 32 position in the output file
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
STOP_IOE 1 stop on I/O error
|
||||
LBUF[0:119] 8 line buffer
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of tape or paper
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.3 Type 550/555 Microtape (DECtape) (DT)
|
||||
|
||||
The PDP-1 uses the Type 550 Microtape (later renamed DECtape), a programmed
|
||||
I/O controller. PDP-1 DECtape format has 4 18b words in its block headers
|
||||
and trailers.
|
||||
|
||||
DECtapes drives are numbered 1-8; in the simulator, drive 8 is unit 0.
|
||||
DECtape options include the ability to make units write enabled or write
|
||||
locked.
|
||||
|
||||
SET DTn WRITEENABLED set unit n write enabled
|
||||
SET DTn LOCKED set unit n write locked
|
||||
|
||||
Units can also be set ENABLED or DISABLED.
|
||||
|
||||
The DECtape controller can be disabled and enabled with the SET DT DISABLED
|
||||
and SET DT ENABLED commands, respectively.
|
||||
|
||||
The Type 550 supports PDP-8 format, PDP-11 format, and 18b format DECtape
|
||||
images. ATTACH tries to determine the tape format from the DECtape image;
|
||||
the user can force a particular format with switches:
|
||||
|
||||
-r PDP-8 format
|
||||
-s PDP-11 format
|
||||
-t 18b format
|
||||
|
||||
The DECtape controller is a data-only simulator; the timing and mark
|
||||
track, and block header and trailer, are not stored. Thus, the WRITE
|
||||
TIMING AND MARK TRACK function is not supported; the READ ALL function
|
||||
always returns the hardware standard block header and trailer; and the
|
||||
WRITE ALL function dumps non-data words into the bit bucket.
|
||||
|
||||
The DECtape controller implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
DTSA 12 status register A
|
||||
DTSB 12 status register B
|
||||
DTDB 18 data buffer
|
||||
DTF 1 DECtape flag
|
||||
BEF 1 block end flag
|
||||
ERF 1 error flag
|
||||
LTIME 31 time between lines
|
||||
DCTIME 31 time to decelerate to a full stop
|
||||
SUBSTATE 2 read/write command substate
|
||||
POS[0:7] 32 position, in lines, units 0-7
|
||||
STATT[0:7] 18 unit state, units 0-7
|
||||
STOP_OFFR 1 stop on off-reel error
|
||||
|
||||
It is critically important to maintain certain timing relationships
|
||||
among the DECtape parameters, or the DECtape simulator will fail to
|
||||
operate correctly.
|
||||
|
||||
- LTIME must be at least 6
|
||||
- DCTIME needs to be at least 100 times LTIME
|
||||
|
||||
Acceleration time is set to 75% of deceleration time.
|
||||
|
||||
2.4 Drums
|
||||
|
||||
The PDP-1 supported two drums: the Type 23 parallel drum (DRP) and
|
||||
the Type 24 serial drum (DRM). Both use device addresses 061-064;
|
||||
accordingly, only one can be enabled at a time. By default, the
|
||||
Type 24 serial drum is enabled, and the Type 23 parallel drum is
|
||||
disabled.
|
||||
|
||||
2.4.1 Type 24 Serial Drum (DRM)
|
||||
|
||||
The serial drum (DRM) implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
DA 9 drum address (sector number)
|
||||
MA 16 current memory address
|
||||
DONE 1 device done flag
|
||||
ERR 1 error flag
|
||||
WLK 32 write lock switches
|
||||
TIME 24 rotational latency, per word
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 disk not ready
|
||||
|
||||
Drum data files are buffered in memory; therefore, end of file and OS
|
||||
I/O errors cannot occur.
|
||||
|
||||
2.4.2 Type 23 Parallel Drum (DRP)
|
||||
|
||||
The parallel drum (DRP) implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
TA 12 track address
|
||||
RDF 5 read field
|
||||
RDE 1 read enable flag
|
||||
WRF 5 write field
|
||||
WRF 1 write enable flag
|
||||
MA 16 current memory address
|
||||
WC 12 word count
|
||||
BUSY 1 device busy flag
|
||||
ERR 1 error flag
|
||||
TIME 24 rotational latency, per word
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 disk not ready
|
||||
|
||||
Drum data files are buffered in memory; therefore, end of file and OS
|
||||
I/O errors cannot occur.
|
||||
|
||||
2.5 Symbolic Display and Input
|
||||
|
||||
The PDP-1 simulator implements symbolic display and input. Display is
|
||||
controlled by command line switches:
|
||||
|
||||
-a display as ASCII character
|
||||
-c display as FIODEC character string
|
||||
-m display instruction mnemonics
|
||||
|
||||
Input parsing is controlled by the first character typed in or by command
|
||||
line switches:
|
||||
|
||||
' or -a ASCII character
|
||||
" or -c three character FIODEC string
|
||||
alphabetic instruction mnemonic
|
||||
numeric octal number
|
||||
|
||||
Instruction input uses modified PDP-1 assembler syntax. There are six
|
||||
instruction classes: memory reference, shift, skip, operate, IOT, and
|
||||
LAW.
|
||||
|
||||
Memory reference instructions have the format
|
||||
|
||||
memref {I} address
|
||||
|
||||
where I signifies indirect reference. The address is an octal number in
|
||||
the range 0 - 0177777.
|
||||
|
||||
Shift instructions have the format
|
||||
|
||||
shift shift_count
|
||||
|
||||
The shift count is an octal number in the range 0-9.
|
||||
|
||||
Skip instructions consist of single mnemonics, eg, SZA, SZS4. Skip
|
||||
instructions may be or'd together
|
||||
|
||||
skip skip skip...
|
||||
|
||||
The sense of a skip can be inverted by including the mnemonic I.
|
||||
|
||||
Operate instructions consist of single mnemonics, eg, CLA, CLI. Operate
|
||||
instructions may be or'd together
|
||||
|
||||
opr opr opr...
|
||||
|
||||
IOT instructions consist of single mnemonics, eg, TYI, TYO. IOT
|
||||
instructions may include an octal numeric modifier or the modifier I:
|
||||
|
||||
iot modifier
|
||||
|
||||
The simulator does not check the legality of skip, operate, or IOT
|
||||
combinations.
|
||||
|
||||
Finally, the LAW instruction has the format
|
||||
|
||||
LAW {I} immediate
|
||||
|
||||
where immediate is in the range 0 to 07777.
|
||||
|
||||
2.6 Character Sets
|
||||
|
||||
The PDP-1's first console was a Frieden Flexowriter; its character encoding
|
||||
was known as FIODEC. The PDP-1's line printer used a modified Hollerith
|
||||
character set. The following table provides equivalences between ASCII
|
||||
characters and the PDP-1's I/O devices. In the console table, UC stands
|
||||
for upper case.
|
||||
|
||||
PDP-1 PDP-1
|
||||
ASCII console line printer
|
||||
|
||||
000 - 007 none none
|
||||
bs 075 none
|
||||
tab 036 none
|
||||
012 - 014 none none
|
||||
cr 077 none
|
||||
016 - 037 none none
|
||||
space 000 000
|
||||
! {OR} UC+005 none
|
||||
" UC+001 none
|
||||
# {IMPLIES} UC+004 none
|
||||
$ none none
|
||||
% none none
|
||||
& {AND} UC+006 none
|
||||
' UC+002 none
|
||||
( 057 057
|
||||
) 055 055
|
||||
* {TIMES} UC+073 072
|
||||
+ UC+054 074
|
||||
, 033 033
|
||||
- 054 054
|
||||
. 073 073
|
||||
/ 021 021
|
||||
0 020 020
|
||||
1 001 001
|
||||
2 002 002
|
||||
3 003 003
|
||||
4 004 004
|
||||
5 005 005
|
||||
6 006 006
|
||||
7 007 007
|
||||
8 010 010
|
||||
9 011 011
|
||||
: none none
|
||||
; none none
|
||||
< UC+007 034
|
||||
= UC+033 053
|
||||
> UC+010 034
|
||||
? UC+021 037
|
||||
@ {MID DOT} 040 {MID DOT} 040
|
||||
A UC+061 061
|
||||
B UC+062 062
|
||||
C UC+063 063
|
||||
D UC+064 064
|
||||
E UC+065 065
|
||||
F UC+066 066
|
||||
G UC+067 067
|
||||
H UC+070 070
|
||||
I UC+071 071
|
||||
J UC+041 041
|
||||
K UC+042 042
|
||||
L UC+043 043
|
||||
M UC+044 044
|
||||
N UC+045 045
|
||||
O UC+046 046
|
||||
P UC+047 047
|
||||
Q UC+050 050
|
||||
R UC+051 051
|
||||
S UC+022 022
|
||||
T UC+023 023
|
||||
U UC+024 024
|
||||
V UC+025 025
|
||||
W UC+026 026
|
||||
X UC+027 027
|
||||
Y UC+030 030
|
||||
Z UC+031 031
|
||||
[ UC+057 none
|
||||
\ {OVERLINE} 056 {OVERLINE} 056
|
||||
] UC+055 none
|
||||
^ {UP ARROW} UC+011 {UP ARROW} 035
|
||||
_ UC+040 UC+040
|
||||
` {RT ARROW} UC+020 036
|
||||
a 061 none
|
||||
b 062 none
|
||||
c 063 none
|
||||
d 064 none
|
||||
e 065 none
|
||||
f 066 none
|
||||
g 067 none
|
||||
h 070 none
|
||||
i 071 none
|
||||
j 041 none
|
||||
k 042 none
|
||||
l 043 none
|
||||
m 044 none
|
||||
n 045 none
|
||||
o 046 none
|
||||
p 047 none
|
||||
q 050 none
|
||||
r 051 none
|
||||
s 022 none
|
||||
t 023 none
|
||||
u 024 none
|
||||
v 025 none
|
||||
w 026 none
|
||||
x 027 none
|
||||
y 030 none
|
||||
z 031 none
|
||||
{ none none
|
||||
| UC+056 076
|
||||
} none none
|
||||
~ UC+003 013
|
||||
del 075 none
|
|
@ -1,660 +0,0 @@
|
|||
To: Users
|
||||
From: Bob Supnik
|
||||
Subj: PDP-10 Simulator Usage
|
||||
Date: 01-Dec-2005
|
||||
|
||||
COPYRIGHT NOTICE
|
||||
|
||||
The following copyright notice applies to both the SIMH source and binary:
|
||||
|
||||
Original code published in 1993-2005, written by Robert M Supnik
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
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 memorandum documents the PDP-10 simulator.
|
||||
|
||||
|
||||
1. Simulator Files
|
||||
|
||||
To compile the PDP-10, you must define VM_PDP10 and USE_INT64 as part of the
|
||||
compilation command line.
|
||||
|
||||
sim/ scp.h
|
||||
sim_console.h
|
||||
sim_defs.h
|
||||
sim_ether.h
|
||||
sim_fio.h
|
||||
sim_rev.h
|
||||
sim_sock.h
|
||||
sim_tape.h
|
||||
sim_timer.h
|
||||
sim_tmxr.h
|
||||
scp.c
|
||||
sim_console.c
|
||||
sim_ether.c
|
||||
sim_fio.c
|
||||
sim_sock.c
|
||||
sim_tape.c
|
||||
sim_timer.c
|
||||
sim_tmxr.c
|
||||
|
||||
sim/pdp10/ pdp10_defs.h
|
||||
pdp10_cpu.c
|
||||
pdp10_fe.c
|
||||
pdp10_ksio.c
|
||||
pdp10_lp20.c
|
||||
pdp10_mdfp.c
|
||||
pdp10_pag.c
|
||||
pdp10_rp.c
|
||||
pdp10_sys.c
|
||||
pdp10_tu.c
|
||||
pdp10_xtnd.c
|
||||
|
||||
sim/pdp11/ pdp11_dz.c
|
||||
pdp11_pt.c
|
||||
pdp11_ry.c
|
||||
pdp11_xu.c
|
||||
|
||||
2. PDP-10 Features
|
||||
|
||||
The PDP-10 simulator is configured as follows:
|
||||
|
||||
device simulates
|
||||
name(s)
|
||||
|
||||
CPU KS10 CPU with 1MW of memory
|
||||
PAG paging unit (translation maps)
|
||||
UBA Unibus adapters (translation maps)
|
||||
FE console
|
||||
TIM timer
|
||||
PTR,PTP PC11 paper tape reader/punch
|
||||
RY RX211/RX02 floppy disk and two drives
|
||||
DZ DZ11 8-line terminal multiplexor (up to 4)
|
||||
LP20 LP20 line printer
|
||||
RP RH11/RP04/RP05/RP06/RP07/RM03/RM05/RM80 controller with
|
||||
eight drives
|
||||
TU RH11/TM02/TU45 controller with eight drives
|
||||
XU DEUNA/DELUA Ethernet controller
|
||||
|
||||
The PTR, PTP, and RX211 are initially set DISABLED. The DZ11 and LP20 can
|
||||
also be set DISABLED. Some devices support the SET ADDRESS command, which
|
||||
allows the I/O page address of the device to be changed, and the SET VECTOR
|
||||
command, which allows the vector of the device to be changed. All devices
|
||||
support the SHOW ADDRESS and SHOW VECTOR commands, which display the device
|
||||
address and vector, respectively.
|
||||
|
||||
The PDP-10 simulator implements several unique stop condition:
|
||||
|
||||
- illegal instruction (000) in kernel mode
|
||||
- indirect addressing nesting exceeds limit
|
||||
- execute chaining exceeds limit
|
||||
- page fail or other error in interrupt sequence
|
||||
- illegal instruction in interrupt sequence
|
||||
- invalid vector pointer in interrupt sequence
|
||||
- invalid Unibus adapter number
|
||||
- non-existent exec or user page table address
|
||||
|
||||
The PDP-10 loader supports RIM10B format paper tapes, SAV binary files, and
|
||||
EXE binary files. LOAD switches -r, -s, -e specify RIM10, SAV, EXE format,
|
||||
respectively. If no switch is specified, the LOAD command checks the file
|
||||
extension; .RIM, .SAV, .EXE specify RIM10, SAV, EXE format, respectively.
|
||||
If no switch is specified, and no extension matches, the LOAD command checks
|
||||
the file format to try to determine the file type.
|
||||
|
||||
2.1 CPU
|
||||
|
||||
The CPU options allow the user to specify standard microcode, standard
|
||||
microcode with a bug fix for a boostrap problem in TOPS-20 V4.1, or ITS
|
||||
microcode:
|
||||
|
||||
SET CPU STANDARD Standard microcode
|
||||
SET CPU TOPS20V41 Standard microcode with TOPS-20 V4.1 bug fix
|
||||
SET CPU ITS ITS compatible microcode
|
||||
|
||||
The CPU implements a SHOW command to display the I/O space address map:
|
||||
|
||||
SHOW CPU IOSPACE show I/O space address map
|
||||
|
||||
CPU registers include the visible state of the processor as well as the
|
||||
control registers for the interrupt system.
|
||||
|
||||
name size comments
|
||||
|
||||
PC 18 program counter
|
||||
FLAGS 18 processor flags (<13:17> unused)
|
||||
AC0..AC17 36 accumulators
|
||||
IR 36 instruction register
|
||||
EBR 18 executive base register
|
||||
PGON 1 paging enabled flag
|
||||
T20P 1 TOPS-20 paging
|
||||
UBR 18 user base register
|
||||
CURAC 3 current AC block
|
||||
PRVAC 3 previous AC block
|
||||
SPT 36 shared pointer table
|
||||
CST 36 core status table
|
||||
PUR 36 process update register
|
||||
CSTM 36 CST mask
|
||||
HSB 18 halt status block address
|
||||
DBR1 18 descriptor base register 1 (ITS)
|
||||
DBR2 18 descriptor base register 2 (ITS)
|
||||
DBR3 18 descriptor base register 3 (ITS)
|
||||
DBR4 18 descriptor base register 4 (ITS)
|
||||
PIENB 7 PI levels enabled
|
||||
PIACT 7 PI levels active
|
||||
PIPRQ 7 PI levels with program requests
|
||||
PIIOQ 7 PI levels with IO requests
|
||||
PIAPR 7 PI levels with APR requests
|
||||
APRENB 8 APR flags enabled
|
||||
APRFLG 8 APR flags active
|
||||
APRLVL 3 PI level for APR interrupt
|
||||
IND_MAX 8 indirect address nesting limit
|
||||
XCT_MAX 8 execute chaining limit
|
||||
PCQ[0:63] 18 PC prior to last jump or interrupt;
|
||||
most recent PC change first
|
||||
WRU 8 interrupt character
|
||||
REG[0:127] 36 fast memory blocks
|
||||
|
||||
The CPU can maintain a history of the most recently executed instructions.
|
||||
This is controlled by the SET CPU HISTORY and SHOW CPU HISTORY commands:
|
||||
|
||||
SET CPU HISTORY clear history buffer
|
||||
SET CPU HISTORY=0 disable history
|
||||
SET CPU HISTORY=n enable history, length = n
|
||||
SHOW CPU HISTORY print CPU history
|
||||
SHOW CPU HISTORY=n print first n entries of CPU history
|
||||
|
||||
The maximum length for the history is 65536 entries.
|
||||
|
||||
2.2 Pager
|
||||
|
||||
The pager contains the page maps for executive and user mode. The
|
||||
executive page map is the memory space for unit 0, the user page map the
|
||||
memory space for unit 1. A page map entry is 32 bits wide and has the
|
||||
following format:
|
||||
|
||||
bit content
|
||||
--- -------
|
||||
31 page is writeable
|
||||
30 entry is valid
|
||||
29:19 mbz
|
||||
18:9 physical page base address
|
||||
8:0 mbz
|
||||
|
||||
The pager has no registers.
|
||||
|
||||
2.3 Unibus Adapters
|
||||
|
||||
The Unibus adapters link the system I/O devices to the CPU. Unibus
|
||||
adapter 1 (UBA1) is unit 0, and Unibus adapter 3 is unit 1. The
|
||||
adapter's Unibus map is the memory space of the corresponding unit.
|
||||
|
||||
The Unibus adapter has the following registers:
|
||||
|
||||
name size comments
|
||||
|
||||
INTREQ 32 interrupt requests
|
||||
UB1CS 16 Unibus adapter 1 control/status
|
||||
UB3CS 16 Unibus adapter 3 control/status
|
||||
|
||||
2.4 Front End (FE)
|
||||
|
||||
The front end is the system console. The keyboard input is unit 0,
|
||||
the console output is unit 1. It supports one option:
|
||||
|
||||
SET FE STOP halts the PDP-10 operating system
|
||||
|
||||
The front end has the following registers:
|
||||
|
||||
name size comments
|
||||
|
||||
IBUF 8 input buffer
|
||||
ICOUNT 32 count of input characters
|
||||
ITIME 24 keyboard polling interval
|
||||
OBUF 8 output buffer
|
||||
OCOUNT 32 count of output characters
|
||||
OTIME 24 console output response time
|
||||
|
||||
2.5 Timer (TIM)
|
||||
|
||||
The timer (TIM) implements the system timer, the interval timer, and
|
||||
the time of day clock used to get the date and time at system startup.
|
||||
Because most PDP-10 software is not Y2K compliant, the timer implements
|
||||
one option:
|
||||
|
||||
SET TIM NOY2K software not Y2K compliant, limit time
|
||||
of day clock to 1999 (default)
|
||||
SET TIM Y2K software is Y2K compliant
|
||||
|
||||
The timer has the following registers:
|
||||
|
||||
name size comments
|
||||
|
||||
TIMBASE 59 time base (double precision)
|
||||
TTG 36 time to go (remaining time) for interval
|
||||
PERIOD 36 reset value for interval
|
||||
QUANT 36 quantum timer (ITS only)
|
||||
TIME 24 tick delay
|
||||
DIAG 1 use fixed tick delay instead of autocalibration
|
||||
|
||||
Unless the DIAG flag is set, the timer autocalibrates; the tick delay
|
||||
is adjusted up or down so that the time base tracks actual elapsed time.
|
||||
This may cause time-dependent diagnostics to report errors.
|
||||
|
||||
2.6 PC11 Paper Tape Reader (PTR)
|
||||
|
||||
The paper tape reader (PTR) reads data from a disk file. The POS
|
||||
register specifies the number of the next data item to be read. Thus,
|
||||
by changing POS, the user can backspace or advance the reader.
|
||||
|
||||
The paper tape reader requires an unsupported driver under TOPS-10
|
||||
and is not supported under TOPS-20 or ITS.
|
||||
|
||||
The paper tape reader implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
CSR 16 control/status register
|
||||
INT 1 interrupt pending flag
|
||||
ERR 1 error flag (CSR<15>)
|
||||
BUSY 1 busy flag (CSR<11>)
|
||||
DONE 1 device done flag (CSR<7>)
|
||||
IE 1 interrupt enable flag (CSR<6>)
|
||||
POS 32 position in the input file
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of tape
|
||||
|
||||
end of file 1 report error and stop
|
||||
0 out of tape
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
|
||||
2.7 PC11 Paper Tape Punch (PTP)
|
||||
|
||||
The paper tape punch (PTP) writes data to a disk file. The POS
|
||||
register specifies the number of the next data item to be written.
|
||||
Thus, by by changing POS, the user can backspace or advance the punch.
|
||||
|
||||
The paper tape punch requires an unsupported driver under TOPS-10
|
||||
and is not supported under TOPS-20 or ITS.
|
||||
|
||||
The paper tape punch implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
CSR 16 control/status register
|
||||
INT 1 interrupt pending flag
|
||||
ERR 1 error flag (CSR<15>)
|
||||
DONE 1 device done flag (CSR<7>)
|
||||
IE 1 interrupt enable flag (CSR<6>)
|
||||
POS 32 position in the input or output file
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of tape
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.8 DZ11 Terminal Multiplexor (DZ)
|
||||
|
||||
The DZ11 is an 8-line terminal multiplexor. Up to 4 DZ11's (32 lines)
|
||||
are supported. The number of lines can be changed with the command
|
||||
|
||||
SET DZ LINES=n set line count to n
|
||||
|
||||
The line count must be a multiple of 8, with a maximum of 32.
|
||||
|
||||
The DZ11 supports three character processing modes, 7P, 7B, and 8B:
|
||||
|
||||
mode input characters output characters
|
||||
|
||||
7P high-order bit cleared high-order bit cleared,
|
||||
non-printing characters
|
||||
suppressed
|
||||
7B high-order bit cleared high-order bit cleared
|
||||
8B no changes no changes
|
||||
|
||||
The default is 7B, for compatability with TOPS-20.
|
||||
|
||||
The DZ11 supports logging on a per-line basis. The command
|
||||
|
||||
SET DZ LOG=line=filename
|
||||
|
||||
enables logging for the specified line to the indicated file. The
|
||||
command
|
||||
|
||||
SET DZ NOLOG=line
|
||||
|
||||
disables logging for the specified line and closes any open log file.
|
||||
Finally, the command
|
||||
|
||||
SHOW DZ LOG
|
||||
|
||||
displays logging information for all DZ lines.
|
||||
|
||||
The terminal lines perform input and output through Telnet sessions
|
||||
connected to a user-specified port. The ATTACH command specifies
|
||||
the port to be used:
|
||||
|
||||
ATTACH {-am} DZ <port> set up listening port
|
||||
|
||||
where port is a decimal number between 1 and 65535 that is not being used
|
||||
for other TCP/IP activities. The optional switch -m turns on the DZ11's
|
||||
modem controls; the optional switch -a turns on active disconnects
|
||||
(disconnect session if computer clears Data Terminal Ready). Without
|
||||
modem control, the DZ behaves as though terminals were directly connected;
|
||||
disconnecting the Telnet session does not cause any operating system-
|
||||
visible change in line status.
|
||||
|
||||
Once the DZ is attached and the simulator is running, the DZ will listen
|
||||
for connections on the specified port. It assumes that the incoming
|
||||
connections are Telnet connections. The connection remains open until
|
||||
disconnected by the simulated program, the Telnet client, a SET DZ
|
||||
DISCONNECT command, or a DETACH DZ command.
|
||||
|
||||
The SHOW DZ CONNECTIONS command displays the current connections to the DZ.
|
||||
The SHOW DZ STATISTICS command displays statistics for active connections.
|
||||
The SET DZ DISCONNECT=linenumber command disconnects the specified line.
|
||||
|
||||
The DZ11 implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
CSR[0:3] 16 control/status register, boards 0-3
|
||||
RBUF[0:3] 16 receive buffer, boards 0-3
|
||||
LPR[0:3] 16 line parameter register, boards 0-3
|
||||
TCR[0:3] 16 transmission control register, boards 0-3
|
||||
MSR[0:3] 16 modem status register, boards 0-3
|
||||
TDR[0:3] 16 transmit data register, boards 0-3
|
||||
SAENB[0:3] 1 silo alarm enabled, boards 0-3
|
||||
RXINT 4 receive interrupts, boards 3..0
|
||||
TXINT 4 transmit interrupts, boards 3..0
|
||||
MDMTCL 1 modem control enabled
|
||||
AUTODS 1 autodisconnect enabled
|
||||
|
||||
The DZ11 does not support save and restore. All open connections are
|
||||
lost when the simulator shuts down or the DZ is detached.
|
||||
|
||||
2.9 RH11 Adapter, RM02/03/05/80, RP04/05/06/07 drives (RP)
|
||||
|
||||
The RP controller implements the Massbus 18b (RH11) direct interface for
|
||||
large disk drives. It is more abstract than other device simulators, with
|
||||
just enough detail to run operating system drivers. In addition, the RP
|
||||
controller conflates the details of the RM series controllers with the RP
|
||||
series controllers, although there were detailed differences.
|
||||
|
||||
RP options include the ability to set units write enabled or write locked,
|
||||
to set the drive type to one of six disk types, or autosize:
|
||||
|
||||
SET RPn LOCKED set unit n write locked
|
||||
SET RPn WRITEENABLED set unit n write enabled
|
||||
SET RPn RM03 set type to RM03
|
||||
SET RPn RM05 set type to RM05
|
||||
SET RPn RM80 set type to RM80
|
||||
SET RPn RP04 set type to RP04
|
||||
SET RPn RP06 set type to RP06
|
||||
SET RPn RP07 set type to RP07
|
||||
SET RPn AUTOSIZE set type based on file size at attach
|
||||
|
||||
The type options can be used only when a unit is not attached to a file.
|
||||
Note that TOPS-10 V7.03 supported only the RP06 and RM03; V7.04 added
|
||||
support for the RP07. TOPS-20 V4.1 also supported only the RP06 and
|
||||
RM03. Units can be set ENABLED or DISABLED.
|
||||
|
||||
The RP controller implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
RPCS1 16 control/status 1
|
||||
RPWC 16 word count
|
||||
RPBA 16 bus address
|
||||
RPDA 16 desired surface, sector
|
||||
RPCS2 16 control/status 2
|
||||
RPDS[0:7] 16 drive status, drives 0-7
|
||||
RPER1[0:7] 16 drive errors, drives 0-7
|
||||
RPOF 16 offset
|
||||
RPDC 8 desired cylinder
|
||||
RPER2 16 error status 2
|
||||
RPER3 16 error status 3
|
||||
RPEC1 16 ECC syndrome 1
|
||||
RPEC2 16 ECC syndrome 2
|
||||
RPMR 16 maintenance register
|
||||
RPDB 16 data buffer
|
||||
IFF 1 transfer complete interrupt request flop
|
||||
INT 1 interrupt pending flag
|
||||
SC 1 special condition (CSR1<15>)
|
||||
DONE 1 device done flag (CSR1<7>)
|
||||
IE 1 interrupt enable flag (CSR1<6>)
|
||||
STIME 24 seek time, per cylinder
|
||||
RTIME 24 rotational delay
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 disk not ready
|
||||
|
||||
end of file x assume rest of disk is zero
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.10 RH11 Adapter, TM02 Formatter, TU45 Magnetic Tape (TU)
|
||||
|
||||
The magnetic tape simulator simulates an RH11 Massbus adapter with one
|
||||
TM02 formatter and up to eight TU45 drives. Magnetic tape options include
|
||||
the ability to make units write enabled or locked.
|
||||
|
||||
SET TUn LOCKED set unit n write locked
|
||||
SET TUn WRITEENABLED set unit n write enabled
|
||||
|
||||
Units can also be set ENABLED or DISABLED.
|
||||
|
||||
The magnetic tape controller implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
MTCS1 16 control/status 1
|
||||
MTBA 16 memory address
|
||||
MTWC 16 word count
|
||||
MTFC 16 frame count
|
||||
MTCS2 16 control/status 2
|
||||
MTFS 16 formatter status
|
||||
MTER 16 error status
|
||||
MTCC 16 check character
|
||||
MTDB 16 data buffer
|
||||
MTMR 16 maintenance register
|
||||
MTTC 16 tape control register
|
||||
INT 1 interrupt pending flag
|
||||
DONE 1 device done flag
|
||||
IE 1 interrupt enable flag
|
||||
STOP_IOE 1 stop on I/O error
|
||||
TIME 24 delay
|
||||
UST[0:7] 16 unit status, units 0-7
|
||||
POS[0:7] 32 position, units 0-7
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error processed as
|
||||
|
||||
not attached tape not ready; if STOP_IOE, stop
|
||||
|
||||
end of file operation incomplete
|
||||
|
||||
OS I/O error parity error; if STOP_IOE, stop
|
||||
|
||||
2.11 LP20 DMA Line Printer (LP20)
|
||||
|
||||
The LP20 is a DMA-based line printer controller. There is one
|
||||
line printer option to clear the vertical forms unit (VFU):
|
||||
|
||||
SET LP20 VFUCLEAR clear the vertical forms unit
|
||||
|
||||
The LP20 implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
LPCSA 16 control/status register A
|
||||
LPCSB 16 control/status register B
|
||||
LPBA 16 bus address register
|
||||
LPBC 12 byte count register
|
||||
LPPAGC 12 page count register
|
||||
LPRDAT 12 RAM data register
|
||||
LPCBUF 8 character buffer register
|
||||
LPCOLC 8 column counter register
|
||||
LPPDAT 8 printer data register
|
||||
LPCSUM 8 checksum register
|
||||
DVPTR 7 vertical forms unit pointer
|
||||
DVLNT 7 vertical forms unit length
|
||||
INT 1 interrupt request
|
||||
ERR 1 error flag
|
||||
DONE 1 done flag
|
||||
IE 1 interrupt enable flag
|
||||
POS 32 position in output file
|
||||
TIME 24 response time
|
||||
STOP_IOE 1 stop on I/O error
|
||||
TXRAM[0:255] 12 translation RAM
|
||||
DAVFU[0:142] 12 vertical forms unit array
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of paper
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.12 RX211/RX02 Floppy Disk (RY)
|
||||
|
||||
RX211 options include the ability to set units write enabled or write
|
||||
locked, single or double density, or autosized:
|
||||
|
||||
SET RYn LOCKED set unit n write locked
|
||||
SET RYn WRITEENABLED set unit n write enabled
|
||||
SET RYn SINGLE set unit n single density
|
||||
SET RYn DOUBLE set unit n double density (default)
|
||||
SET RYn AUTOSIZE set unit n autosized
|
||||
|
||||
The floppy disk requires an unsupported driver under TOPS-10 and
|
||||
is not supported under TOPS-20 or ITS.
|
||||
|
||||
The RX211 implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
RYCS 16 status
|
||||
RYBA 16 buffer address
|
||||
RYWC 8 word count
|
||||
RYDB 16 data buffer
|
||||
RYES 12 error status
|
||||
RYERR 8 error code
|
||||
RYTA 8 current track
|
||||
RYSA 8 current sector
|
||||
STAPTR 4 controller state
|
||||
INT 1 interrupt pending flag
|
||||
ERR 1 error flag (CSR<15>)
|
||||
TR 1 transfer ready flag (CSR<7>)
|
||||
IE 1 interrupt enable flag (CSR<6>)
|
||||
DONE 1 device done flag (CSR<5>)
|
||||
CTIME 24 command completion time
|
||||
STIME 24 seek time, per track
|
||||
XTIME 24 transfer ready delay
|
||||
STOP_IOE 1 stop on I/O error
|
||||
SBUF[0:255] 8 sector buffer array
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 disk not ready
|
||||
|
||||
RX02 data files are buffered in memory; therefore, end of file and OS
|
||||
I/O errors cannot occur.
|
||||
|
||||
2.13 DEUNA/DELUA Ethernet Controller (XU)
|
||||
|
||||
XU simulates the DEUNA/DELUA Ethernet controller. The current implementation
|
||||
is a stub and is permanently disabled.
|
||||
|
||||
2.14 Symbolic Display and Input
|
||||
|
||||
The PDP-10 simulator implements symbolic display and input. Display is
|
||||
controlled by command line switches:
|
||||
|
||||
-a display as ASCII character
|
||||
-c display as (sixbit) character string
|
||||
-p display as packed (seven bit) string
|
||||
-m display instruction mnemonics
|
||||
-v interpret address as virtual
|
||||
-e force executive mode
|
||||
-u force user mode
|
||||
|
||||
Input parsing is controlled by the first character typed in or by command
|
||||
line switches:
|
||||
|
||||
' or -a ASCII character
|
||||
" or -c sixbit string
|
||||
# or -p packed seven bit string
|
||||
alphabetic instruction mnemonic
|
||||
numeric octal number
|
||||
|
||||
Instruction input uses standard PDP-10 assembler syntax. There are three
|
||||
instruction classes: memory reference, memory reference with AC, and I/O.
|
||||
|
||||
Memory reference instructions have the format
|
||||
|
||||
memref {@}address{(index)}
|
||||
|
||||
memory reference with AC instructions have the format
|
||||
|
||||
memac ac,{@}address{(index)}
|
||||
|
||||
and I/O instructions have the format
|
||||
|
||||
io device,{@}address{(index)}
|
||||
|
||||
where @ signifies indirect. The address is a signed octal number in the
|
||||
range 0 - 0777777. The ac and index are unsigned octal numbers in the
|
||||
range 0-17. The device is either a recognized device mnemonic (APR, PI,
|
||||
TIM) or an octal number in the range 0 - 0177.
|
||||
|
||||
The simulator recognizes the standard MACRO alternate mnemonics (CLEAR
|
||||
for SETZ, OR for IORI), the individual definitions for JRST and JFCL
|
||||
variants, and the extended instruction mnemonics.
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp10_tu.c - PDP-10 RH11/TM03/TU45 magnetic tape simulator
|
||||
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
tu RH11/TM03/TU45 magtape
|
||||
|
||||
16-Feb-06 RMS Added tape capacity checking
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
07-Jul-05 RMS Removed extraneous externs
|
||||
31-Mar-05 RMS Fixed bug, ERASE/WREOF incorrectly clear CS1<done>
|
||||
|
@ -399,6 +400,8 @@ MTAB tu_mod[] = {
|
|||
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "CAPACITY", "CAPACITY",
|
||||
&sim_tape_set_capac, &sim_tape_show_capac, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL,
|
||||
NULL, &show_addr, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL,
|
||||
|
@ -625,7 +628,7 @@ return SCPE_OK;
|
|||
|
||||
void tu_go (int32 drv)
|
||||
{
|
||||
int32 fnc, den, space_test = FS_BOT;
|
||||
int32 fnc, den;
|
||||
UNIT *uptr;
|
||||
|
||||
fnc = GET_FNC (tucs1); /* get function */
|
||||
|
@ -687,13 +690,23 @@ switch (fnc) { /* case on function */
|
|||
return;
|
||||
|
||||
case FNC_SPACEF:
|
||||
space_test = FS_EOT;
|
||||
if ((uptr->flags & UNIT_ATT) == 0) { /* unattached? */
|
||||
set_tuer (ER_UNS);
|
||||
break;
|
||||
}
|
||||
if (sim_tape_eot (uptr) || ((tutc & TC_FCS) == 0)) {
|
||||
set_tuer (ER_NXF);
|
||||
break;
|
||||
}
|
||||
uptr->USTAT = FS_PIP;
|
||||
goto GO_XFER;
|
||||
|
||||
case FNC_SPACER:
|
||||
if ((uptr->flags & UNIT_ATT) == 0) { /* unattached? */
|
||||
set_tuer (ER_UNS);
|
||||
break;
|
||||
}
|
||||
if ((tufs & space_test) || ((tutc & TC_FCS) == 0)) {
|
||||
if (sim_tape_bot (uptr) || ((tutc & TC_FCS) == 0)) {
|
||||
set_tuer (ER_NXF);
|
||||
break;
|
||||
}
|
||||
|
@ -807,7 +820,7 @@ switch (fnc) { /* case on function */
|
|||
r = tu_map_err (uptr, st, 0); /* map error */
|
||||
break;
|
||||
}
|
||||
} while (tufc != 0);
|
||||
} while ((tufc != 0) && !sim_tape_eot (uptr));
|
||||
if (tufc) set_tuer (ER_FCE);
|
||||
else tutc = tutc & ~TC_FCS;
|
||||
tufs = tufs | FS_ATA;
|
||||
|
@ -977,7 +990,10 @@ if (GET_FMTR (tucs2) == 0) { /* formatter present? */
|
|||
tufs = tufs | FS_MOL | tu_unit[drv].USTAT;
|
||||
if (tu_unit[drv].UDENS == TC_1600) tufs = tufs | FS_PE;
|
||||
if (sim_tape_wrp (&tu_unit[drv])) tufs = tufs | FS_WRL;
|
||||
if (sim_tape_bot (&tu_unit[drv]) && !act) tufs = tufs | FS_BOT;
|
||||
if (!act) {
|
||||
if (sim_tape_bot (&tu_unit[drv])) tufs = tufs | FS_BOT;
|
||||
if (sim_tape_eot (&tu_unit[drv])) tufs = tufs | FS_EOT;
|
||||
}
|
||||
}
|
||||
if (tuer) tufs = tufs | FS_ERR;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp11_cis.c: PDP-11 CIS optional instruction set simulator
|
||||
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,10 @@
|
|||
|
||||
This module simulates the PDP-11 commercial instruction set (CIS).
|
||||
|
||||
22-May-06 RMS Fixed bug in decode table (found by John Dundas)
|
||||
Fixed bug in ASHP (reported by John Dundas)
|
||||
Fixed bug in write decimal string with mmgt enabled
|
||||
Fixed bug in 0-length strings in multiply/divide
|
||||
16-Sep-04 RMS Fixed bug in CMPP/N of negative strings
|
||||
17-Oct-02 RMS Fixed compiler warning (found by Hans Pufal)
|
||||
08-Oct-02 RMS Fixed macro definitions
|
||||
|
@ -175,7 +179,7 @@ void SubDstr (DSTR *src1, DSTR *src2, DSTR *dst);
|
|||
int32 CmpDstr (DSTR *src1, DSTR *src2);
|
||||
int32 TestDstr (DSTR *dsrc);
|
||||
int32 LntDstr (DSTR *dsrc, int32 nz);
|
||||
uint32 NibbleLshift (DSTR *dsrc, int32 sc, uint32 cin);
|
||||
uint32 NibbleLshift (DSTR *dsrc, int32 sc);
|
||||
uint32 NibbleRshift (DSTR *dsrc, int32 sc, uint32 cin);
|
||||
int32 WordLshift (DSTR *dsrc, int32 sc);
|
||||
void WordRshift (DSTR *dsrc, int32 sc);
|
||||
|
@ -269,7 +273,7 @@ static int32 opntab[128][MAXOPN] = {
|
|||
IN_DESC, IN_DESC, IN_DESC, 0, /* ADDPI */
|
||||
IN_DESC, IN_DESC, IN_DESC, 0, /* SUBPI */
|
||||
IN_DESC, IN_DESC, 0, 0, /* CMPPI */
|
||||
IN_DESC, 0, 0, 0, /* CVTPLI */
|
||||
IN_DESC, IN_ARG, 0, 0, /* CVTPLI */
|
||||
IN_DESC, IN_DESC, IN_DESC, 0, /* MULPI */
|
||||
IN_DESC, IN_DESC, IN_DESC, 0, /* DIVPI */
|
||||
IN_DESC, IN_DESC, IN_ARG, 0, /* ASHPI */
|
||||
|
@ -357,8 +361,8 @@ for (i = j = 0; (i < MAXOPN) && opntab[op][i]; i++) { /* parse operands */
|
|||
R[0] = ReadW (addr | dsenable);
|
||||
R[1] = ReadW (((addr + 2) & 0177777) | dsenable);
|
||||
break;
|
||||
case IN_ARG:
|
||||
|
||||
case IN_ARG:
|
||||
arg[j++] = ReadW (PC | isenable);
|
||||
PC = (PC + 2) & 0177777;
|
||||
break;
|
||||
|
@ -729,7 +733,7 @@ switch (op) { /* case on opcode */
|
|||
NibbleRshift (&src2, 1, 0);
|
||||
if ((t = ldivd - ldivr) >= 0) { /* any divide to do? */
|
||||
WordLshift (&src1, t / 8); /* align divr to divd */
|
||||
NibbleLshift (&src1, t % 8, 0);
|
||||
NibbleLshift (&src1, t % 8);
|
||||
CreateTable (&src1, mptable); /* create *1, *2, ... */
|
||||
for (i = 0; i <= t; i++) { /* divide loop */
|
||||
for (digit = 9; digit > 0; digit--) { /* find digit */
|
||||
|
@ -739,8 +743,8 @@ switch (op) { /* case on opcode */
|
|||
break;
|
||||
} /* end if */
|
||||
} /* end for */
|
||||
NibbleLshift (&src2, 1, 0); /* shift dividend */
|
||||
NibbleLshift (&dst, 1, 0); /* shift quotient */
|
||||
NibbleLshift (&src2, 1); /* shift dividend */
|
||||
NibbleLshift (&dst, 1); /* shift quotient */
|
||||
} /* end divide loop */
|
||||
dst.sign = src1.sign ^ src2.sign; /* calculate sign */
|
||||
} /* end if */
|
||||
|
@ -810,7 +814,7 @@ switch (op) { /* case on opcode */
|
|||
} /* end right shift */
|
||||
else if (shift) { /* left shift? */
|
||||
if (WordLshift (&src1, shift / 8)) V = 1; /* do word shifts */
|
||||
if (NibbleLshift (&src1, shift % 8, 0)) V = 1;
|
||||
if (NibbleLshift (&src1, shift % 8)) V = 1;
|
||||
} /* end left shift */
|
||||
WriteDstr (A2, &src1, op); /* store result */
|
||||
if ((op & INLINE) == 0) /* if reg, clr reg */
|
||||
|
@ -1056,7 +1060,7 @@ if (flag & PACKED) { /* packed? */
|
|||
else dst->val[0] = dst->val[0] | 0xC | dst->sign;
|
||||
for (i = 0; i <= end; i++) { /* store string */
|
||||
c = (dst->val[i / 4] >> ((i % 4) * 8)) & 0xFF;
|
||||
WriteB (c, ((dscr[1] + end - i) & 0177777));
|
||||
WriteB (c, ((dscr[1] + end - i) & 0177777) | dsenable);
|
||||
} /* end for */
|
||||
} /* end packed */
|
||||
else {
|
||||
|
@ -1070,7 +1074,7 @@ else {
|
|||
((i == lnt) && (type == LO)))
|
||||
c = binover[dst->sign][c]; /* get sign and digit */
|
||||
else c = c | 0x30; /* default */
|
||||
WriteB (c, ((dscr[1] + lnt - i) & 0177777));
|
||||
WriteB (c, ((dscr[1] + lnt - i) & 0177777) |dsenable );
|
||||
} /* end for */
|
||||
} /* end numeric */
|
||||
return;
|
||||
|
@ -1201,6 +1205,7 @@ int32 LntDstr (DSTR *dsrc, int32 nz)
|
|||
{
|
||||
int32 i;
|
||||
|
||||
if (nz == 0) return 0;
|
||||
for (i = 7; i > 0; i--) {
|
||||
if ((dsrc->val[nz - 1] >> (i * 4)) & 0xF) break;
|
||||
}
|
||||
|
@ -1299,22 +1304,22 @@ return 0;
|
|||
Arguments:
|
||||
dsrc = decimal string structure
|
||||
sc = shift count
|
||||
cin = carry in
|
||||
*/
|
||||
|
||||
uint32 NibbleLshift (DSTR *dsrc, int32 sc, uint32 cin)
|
||||
uint32 NibbleLshift (DSTR *dsrc, int32 sc)
|
||||
{
|
||||
int32 i, s, rs, nc;
|
||||
int32 i, s, rs;
|
||||
uint32 sv_val, cout;
|
||||
|
||||
cout = 0;
|
||||
if (s = sc * 4) {
|
||||
rs = 32 - s;
|
||||
for (i = 0; i < DSTRLNT; i++) {
|
||||
nc = dsrc->val[i];
|
||||
dsrc->val[i] = ((dsrc->val[i] << s) |
|
||||
(cin >> rs)) & 0xFFFFFFFF;
|
||||
cin = nc;
|
||||
sv_val = dsrc->val[i];
|
||||
dsrc->val[i] = ((dsrc->val[i] << s) | cout) & 0xFFFFFFFF;
|
||||
cout = sv_val >> rs;
|
||||
}
|
||||
return cin;
|
||||
return cout;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp11_cpu.c: PDP-11 CPU simulator
|
||||
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,8 @@
|
|||
|
||||
cpu PDP-11 CPU
|
||||
|
||||
24-May-06 RMS Added instruction history
|
||||
03-May-06 RMS Fixed XOR operand fetch order for 11/70-style systems
|
||||
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
19-May-05 RMS Replaced WAIT clock queue check with API call
|
||||
|
@ -228,6 +230,19 @@
|
|||
#define UNIT_V_MSIZE (UNIT_V_UF + 0) /* dummy */
|
||||
#define UNIT_MSIZE (1u << UNIT_V_MSIZE)
|
||||
|
||||
#define HIST_MIN 64
|
||||
#define HIST_MAX (1u << 18)
|
||||
#define HIST_VLD 1 /* make PC odd */
|
||||
#define HIST_ILNT 4 /* max inst length */
|
||||
|
||||
typedef struct {
|
||||
uint16 pc;
|
||||
uint16 psw;
|
||||
uint16 src;
|
||||
uint16 dst;
|
||||
uint16 inst[HIST_ILNT];
|
||||
} InstHistory;
|
||||
|
||||
/* Global state */
|
||||
|
||||
extern FILE *sim_log;
|
||||
|
@ -274,12 +289,16 @@ uint16 pcq[PCQ_SIZE] = { 0 }; /* PC queue */
|
|||
int32 pcq_p = 0; /* PC queue ptr */
|
||||
REG *pcq_r = NULL; /* PC queue reg ptr */
|
||||
jmp_buf save_env; /* abort handler */
|
||||
int32 hst_p = 0; /* history pointer */
|
||||
int32 hst_lnt = 0; /* history length */
|
||||
InstHistory *hst = NULL; /* instruction history */
|
||||
int32 dsmask[4] = { MMR3_KDS, MMR3_SDS, 0, MMR3_UDS }; /* dspace enables */
|
||||
|
||||
extern int32 CPUERR, MAINT;
|
||||
extern int32 sim_interval;
|
||||
extern UNIT clk_unit, pclk_unit;
|
||||
extern int32 sim_int_char;
|
||||
extern uint32 sim_switches;
|
||||
extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
|
||||
extern DEVICE *sim_devices[];
|
||||
extern CPUTAB cpu_tab[];
|
||||
|
@ -289,6 +308,9 @@ extern CPUTAB cpu_tab[];
|
|||
t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
|
||||
t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);
|
||||
t_stat cpu_reset (DEVICE *dptr);
|
||||
t_stat cpu_set_hist (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||
t_stat cpu_show_virt (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||
int32 GeteaB (int32 spec);
|
||||
int32 GeteaW (int32 spec);
|
||||
int32 relocR (int32 addr);
|
||||
|
@ -586,6 +608,10 @@ MTAB cpu_mod[] = {
|
|||
&set_autocon, &show_autocon },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, NULL, "NOAUTOCONFIG",
|
||||
&set_autocon, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "HISTORY", "HISTORY",
|
||||
&cpu_set_hist, &cpu_show_hist },
|
||||
{ MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "VIRTUAL", NULL,
|
||||
NULL, &cpu_show_virt },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
@ -775,12 +801,28 @@ while (reason == 0) {
|
|||
MMR2 = PC;
|
||||
}
|
||||
IR = ReadE (PC | isenable); /* fetch instruction */
|
||||
PC = (PC + 2) & 0177777; /* incr PC, mod 65k */
|
||||
sim_interval = sim_interval - 1;
|
||||
srcspec = (IR >> 6) & 077; /* src, dst specs */
|
||||
dstspec = IR & 077;
|
||||
srcreg = (srcspec <= 07); /* src, dst = rmode? */
|
||||
dstreg = (dstspec <= 07);
|
||||
if (hst_lnt) { /* record history? */
|
||||
t_value val;
|
||||
uint32 i;
|
||||
hst[hst_p].pc = PC | HIST_VLD;
|
||||
hst[hst_p].psw = get_PSW ();
|
||||
hst[hst_p].src = R[srcspec & 07];
|
||||
hst[hst_p].dst = R[dstspec & 07];
|
||||
hst[hst_p].inst[0] = IR;
|
||||
for (i = 1; i < HIST_ILNT; i++) {
|
||||
if (cpu_ex (&val, (PC + (i << 1)) & 0177777, &cpu_unit, SWMASK ('V')))
|
||||
hst[hst_p].inst[i] = 0;
|
||||
else hst[hst_p].inst[i] = (uint16) val;
|
||||
}
|
||||
hst_p = (hst_p + 1);
|
||||
if (hst_p >= hst_lnt) hst_p = 0;
|
||||
}
|
||||
PC = (PC + 2) & 0177777; /* incr PC, mod 65k */
|
||||
switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
||||
|
||||
/* Opcode 0: no operands, specials, branches, JSR, SOPs */
|
||||
|
@ -1478,8 +1520,15 @@ while (reason == 0) {
|
|||
|
||||
case 4: /* XOR */
|
||||
if (CPUT (HAS_SXS)) {
|
||||
dst = dstreg? R[dstspec]: ReadMW (GeteaW (dstspec));
|
||||
dst = dst ^ R[srcspec];
|
||||
if (CPUT (IS_SDSD) && !dstreg) { /* R,not R */
|
||||
src2 = ReadMW (GeteaW (dstspec));
|
||||
src = R[srcspec];
|
||||
}
|
||||
else {
|
||||
src = R[srcspec];
|
||||
src2 = dstreg? R[dstspec]: ReadMW (GeteaW (dstspec));
|
||||
}
|
||||
dst = src ^ src2;
|
||||
N = GET_SIGN_W (dst);
|
||||
Z = GET_Z (dst);
|
||||
V = 0;
|
||||
|
@ -2835,3 +2884,96 @@ for (i = 0; i < 6; i++, rptr++) rptr->loc = (void *) ®FILE[i][rs];
|
|||
rptr->loc = (void *) &STACKFILE[cm];
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set history */
|
||||
|
||||
t_stat cpu_set_hist (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
int32 i, lnt;
|
||||
t_stat r;
|
||||
|
||||
if (cptr == NULL) {
|
||||
for (i = 0; i < hst_lnt; i++) hst[i].pc = 0;
|
||||
hst_p = 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
lnt = (int32) get_uint (cptr, 10, HIST_MAX, &r);
|
||||
if ((r != SCPE_OK) || (lnt && (lnt < HIST_MIN))) return SCPE_ARG;
|
||||
hst_p = 0;
|
||||
if (hst_lnt) {
|
||||
free (hst);
|
||||
hst_lnt = 0;
|
||||
hst = NULL;
|
||||
}
|
||||
if (lnt) {
|
||||
hst = (InstHistory *) calloc (lnt, sizeof (InstHistory));
|
||||
if (hst == NULL) return SCPE_MEM;
|
||||
hst_lnt = lnt;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Show history */
|
||||
|
||||
t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, void *desc)
|
||||
{
|
||||
int32 j, k, di, lnt, ir;
|
||||
char *cptr = (char *) desc;
|
||||
t_value sim_eval[HIST_ILNT];
|
||||
t_stat r;
|
||||
InstHistory *h;
|
||||
extern t_stat fprint_sym (FILE *ofile, t_addr addr, t_value *val,
|
||||
UNIT *uptr, int32 sw);
|
||||
|
||||
if (hst_lnt == 0) return SCPE_NOFNC; /* enabled? */
|
||||
if (cptr) {
|
||||
lnt = (int32) get_uint (cptr, 10, hst_lnt, &r);
|
||||
if ((r != SCPE_OK) || (lnt == 0)) return SCPE_ARG;
|
||||
}
|
||||
else lnt = hst_lnt;
|
||||
di = hst_p - lnt; /* work forward */
|
||||
if (di < 0) di = di + hst_lnt;
|
||||
fprintf (st, "PC PSW src dst IR\n\n");
|
||||
for (k = 0; k < lnt; k++) { /* print specified */
|
||||
h = &hst[(di++) % hst_lnt]; /* entry pointer */
|
||||
if (h->pc & HIST_VLD) { /* instruction? */
|
||||
ir = h->inst[0];
|
||||
fprintf (st, "%06o %06o|", h->pc & ~HIST_VLD, h->psw);
|
||||
if (((ir & 0070000) != 0) || /* dops, eis, fpp */
|
||||
((ir & 0177000) == 0004000)) /* jsr */
|
||||
fprintf (st, "%06o %06o ", h->src, h->dst);
|
||||
else if ((ir >= 0000100) && /* not no opnd */
|
||||
(((ir & 0007700) < 0000300) || /* not branch */
|
||||
((ir & 0007700) >= 0004000)))
|
||||
fprintf (st, " %06o ", h->dst);
|
||||
else fprintf (st, " ");
|
||||
for (j = 0; j < HIST_ILNT; j++) sim_eval[j] = h->inst[j];
|
||||
if ((fprint_sym (st, h->pc & ~HIST_VLD, sim_eval, &cpu_unit, SWMASK ('M'))) > 0)
|
||||
fprintf (st, "(undefined) %06o", h->inst[0]);
|
||||
fputc ('\n', st); /* end line */
|
||||
} /* end else instruction */
|
||||
} /* end for */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Virtual address translation */
|
||||
|
||||
t_stat cpu_show_virt (FILE *of, UNIT *uptr, int32 val, void *desc)
|
||||
{
|
||||
t_stat r;
|
||||
char *cptr = (char *) desc;
|
||||
uint32 va, pa;
|
||||
|
||||
if (cptr) {
|
||||
va = (uint32) get_uint (cptr, 8, VAMASK, &r);
|
||||
if (r == SCPE_OK) {
|
||||
pa = relocC (va, sim_switches); /* relocate */
|
||||
if (pa < MAXMEMSIZE)
|
||||
fprintf (of, "Virtual %-o = physical %-o\n", va, pa);
|
||||
else fprintf (of, "Virtual %-o is not valid\n", va);
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
fprintf (of, "Invalid argument\n");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
|
1272
PDP11/pdp11_cr.c
Normal file
1272
PDP11/pdp11_cr.c
Normal file
File diff suppressed because it is too large
Load diff
622
PDP11/pdp11_cr_dat.h
Normal file
622
PDP11/pdp11_cr_dat.h
Normal file
|
@ -0,0 +1,622 @@
|
|||
/* pdp11_cr_dat.h
|
||||
*
|
||||
* card code arrays are indexed by 7-bit ASCII code, and
|
||||
* give corresponding 12-bit card codes using the indicated
|
||||
* collating sequence.
|
||||
*
|
||||
* ERROR should be externally defined, either as an illegal
|
||||
* card code (on conversion from ASCII to card codes) or as
|
||||
* a code with a bit set outside the least significant 12.
|
||||
*
|
||||
* author: Douglas Jones, jones@cs.uiowa.edu
|
||||
* revisions:
|
||||
* March 5, 1996
|
||||
* Feb 18, 1997 to add 026 and EBCDIC converstion tables
|
||||
* Jan 10, 2005, (JAD) Added 'static const' to the array
|
||||
* definitions.
|
||||
* Jan 11, 2005, (JAD) Create the h2c_code array.
|
||||
* Jan 14, 2005, (JAD) Added the special DEC code for 'end of deck'
|
||||
* (12-11-0-1-6-7-8-9) to the o29_code array at position 26. (^Z).
|
||||
* Should I add this to the other arrays?
|
||||
*/
|
||||
|
||||
/* DEC's version of the IBM 029 kepunch encoding, (thus avoiding IBM's
|
||||
use of non-ASCII punctuation), based on that given in the appendix
|
||||
to Digital's "Small Computer Handbook, 1973", and augmented to
|
||||
translate lower case to upper case. As a result of this modification,
|
||||
inversion of this table should be done with care! */
|
||||
static const int o29_code[] = {
|
||||
ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR, /* control */
|
||||
ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR, /* chars */
|
||||
ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR, /* control */
|
||||
ERROR,ERROR,07417,ERROR,ERROR,ERROR,ERROR,ERROR, /* chars */
|
||||
00000,02202,00006,00102,02102,01042,04000,00022, /* !"#$%&' */
|
||||
04022,02022,02042,04012,01102,02000,04102,01400, /* ()*+,-./ */
|
||||
01000,00400,00200,00100,00040,00020,00010,00004, /* 01234567 */
|
||||
00002,00001,00202,02012,04042,00012,01012,01006, /* 89:;<=>? */
|
||||
00042,04400,04200,04100,04040,04020,04010,04004, /* @ABCDEFG */
|
||||
04002,04001,02400,02200,02100,02040,02020,02010, /* HIJKLMNO */
|
||||
02004,02002,02001,01200,01100,01040,01020,01010, /* PQRSTUVW */
|
||||
01004,01002,01001,04202,02006,01202,04006,01022, /* XYZ[\]^_ */
|
||||
ERROR,04400,04200,04100,04040,04020,04010,04004, /* `abcdefg */
|
||||
04002,04001,02400,02200,02100,02040,02020,02010, /* hijklmno */
|
||||
02004,02002,02001,01200,01100,01040,01020,01010, /* pqrstuvw */
|
||||
01004,01002,01001,ERROR,ERROR,ERROR,ERROR,ERROR /* xyz{|}~ */
|
||||
};
|
||||
|
||||
/* Bare bones 026 kepunch encodings */
|
||||
static const int o26_ftn_code[] = {
|
||||
ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR, /* control */
|
||||
ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR, /* chars */
|
||||
ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR, /* control */
|
||||
ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR, /* chars */
|
||||
00000,ERROR,ERROR,ERROR,02102,ERROR,ERROR,00042, /* !"#$%&' */
|
||||
01042,04042,02042,04000,01102,02000,04102,01400, /* ()*+,-./ */
|
||||
01000,00400,00200,00100,00040,00020,00010,00004, /* 01234567 */
|
||||
00002,00001,ERROR,ERROR,ERROR,00102,ERROR,ERROR, /* 89:;<=>? */
|
||||
ERROR,04400,04200,04100,04040,04020,04010,04004, /* @ABCDEFG */
|
||||
04002,04001,02400,02200,02100,02040,02020,02010, /* HIJKLMNO */
|
||||
02004,02002,02001,01200,01100,01040,01020,01010, /* PQRSTUVW */
|
||||
01004,01002,01001,ERROR,ERROR,ERROR,ERROR,ERROR, /* XYZ[\]^_ */
|
||||
ERROR,04400,04200,04100,04040,04020,04010,04004, /* `abcdefg */
|
||||
04002,04001,02400,02200,02100,02040,02020,02010, /* hijklmno */
|
||||
02004,02002,02001,01200,01100,01040,01020,01010, /* pqrstuvw */
|
||||
01004,01002,01001,ERROR,ERROR,ERROR,ERROR,ERROR /* xyz{|}~ */
|
||||
};
|
||||
|
||||
static const int o26_comm_code[] = {
|
||||
ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR, /* control */
|
||||
ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR, /* chars */
|
||||
ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR, /* control */
|
||||
ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR, /* chars */
|
||||
00000,ERROR,ERROR,00102,02102,01042,04000,ERROR, /* !"#$%&' */
|
||||
ERROR,ERROR,02042,ERROR,01102,02000,04102,01400, /* ()*+,-./ */
|
||||
01000,00400,00200,00100,00040,00020,00010,00004, /* 01234567 */
|
||||
00002,00001,ERROR,ERROR,04042,ERROR,ERROR,ERROR, /* 89:;<=>? */
|
||||
00042,04400,04200,04100,04040,04020,04010,04004, /* @ABCDEFG */
|
||||
04002,04001,02400,02200,02100,02040,02020,02010, /* HIJKLMNO */
|
||||
02004,02002,02001,01200,01100,01040,01020,01010, /* PQRSTUVW */
|
||||
01004,01002,01001,ERROR,ERROR,ERROR,ERROR,ERROR, /* XYZ[\]^_ */
|
||||
ERROR,04400,04200,04100,04040,04020,04010,04004, /* `abcdefg */
|
||||
04002,04001,02400,02200,02100,02040,02020,02010, /* hijklmno */
|
||||
02004,02002,02001,01200,01100,01040,01020,01010, /* pqrstuvw */
|
||||
01004,01002,01001,ERROR,ERROR,ERROR,ERROR,ERROR /* xyz{|}~ */
|
||||
};
|
||||
|
||||
/* FULL EBCDIC, from Appendix C of System 360 Programming by Alex Thomas,
|
||||
1977, Reinhart Press, San Francisco. Codes not in that table have been
|
||||
left compatable with DEC's 029 table. Some control codes have been
|
||||
left out */
|
||||
static const int EBCDIC_code[] = {
|
||||
05403,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR, /* control */
|
||||
02011,04021,01021,ERROR,04041,02021,ERROR,ERROR, /* chars */
|
||||
ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR, /* control */
|
||||
ERROR,ERROR,ERROR,ERROR,01201,ERROR,ERROR,ERROR, /* chars */
|
||||
00000,02202,00006,00102,02102,01042,04000,00022, /* !"#$%&' */
|
||||
04022,02022,02042,04012,01102,02000,04102,01400, /* ()*+,-./ */
|
||||
01000,00400,00200,00100,00040,00020,00010,00004, /* 01234567 */
|
||||
00002,00001,00202,02012,04042,00012,01012,01006, /* 89:;<=>? */
|
||||
00042,04400,04200,04100,04040,04020,04010,04004, /* @ABCDEFG */
|
||||
04002,04001,02400,02200,02100,02040,02020,02010, /* HIJKLMNO */
|
||||
02004,02002,02001,01200,01100,01040,01020,01010, /* PQRSTUVW */
|
||||
01004,01002,01001,04202,02006,01202,04006,01022, /* XYZ[\]^_ */
|
||||
ERROR,05400,05200,05100,05040,05020,05010,05004, /* `abcdefg */
|
||||
05002,05001,06400,06200,06100,06040,06020,06010, /* hijklmno */
|
||||
06004,06002,06001,03200,03100,03040,03020,03010, /* pqrstuvw */
|
||||
03004,03002,03001,ERROR,ERROR,ERROR,ERROR,ERROR /* xyz{|}~ */
|
||||
};
|
||||
|
||||
static const int h2c_code[4096] = {
|
||||
0000, 0020, 0010, 0030, 0007, 0027, 0017, 0037,
|
||||
0006, 0026, 0016, 0036, 0007, 0027, 0017, 0037,
|
||||
0005, 0025, 0015, 0035, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0004, 0024, 0014, 0034, 0007, 0027, 0017, 0037,
|
||||
0006, 0026, 0016, 0036, 0007, 0027, 0017, 0037,
|
||||
0005, 0025, 0015, 0035, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0003, 0023, 0013, 0033, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0002, 0022, 0012, 0032, 0007, 0027, 0017, 0037,
|
||||
0006, 0026, 0016, 0036, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0006, 0026, 0016, 0036, 0007, 0027, 0017, 0037,
|
||||
0006, 0026, 0016, 0036, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0003, 0023, 0013, 0033, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0001, 0021, 0011, 0031, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0005, 0025, 0015, 0035, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0005, 0025, 0015, 0035, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0005, 0025, 0015, 0035, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0003, 0023, 0013, 0033, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0003, 0023, 0013, 0033, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0003, 0023, 0013, 0033, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0007, 0027, 0017, 0037, 0007, 0027, 0017, 0037,
|
||||
0040, 0060, 0050, 0070, 0047, 0067, 0057, 0077,
|
||||
0046, 0066, 0056, 0076, 0047, 0067, 0057, 0077,
|
||||
0045, 0065, 0055, 0075, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0044, 0064, 0054, 0074, 0047, 0067, 0057, 0077,
|
||||
0046, 0066, 0056, 0076, 0047, 0067, 0057, 0077,
|
||||
0045, 0065, 0055, 0075, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0043, 0063, 0053, 0073, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0042, 0062, 0052, 0072, 0047, 0067, 0057, 0077,
|
||||
0046, 0066, 0056, 0076, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0046, 0066, 0056, 0076, 0047, 0067, 0057, 0077,
|
||||
0046, 0066, 0056, 0076, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0043, 0063, 0053, 0073, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0041, 0061, 0051, 0071, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0045, 0065, 0055, 0075, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0045, 0065, 0055, 0075, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0045, 0065, 0055, 0075, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0043, 0063, 0053, 0073, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0043, 0063, 0053, 0073, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0043, 0063, 0053, 0073, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0047, 0067, 0057, 0077, 0047, 0067, 0057, 0077,
|
||||
0100, 0120, 0110, 0130, 0107, 0127, 0117, 0137,
|
||||
0106, 0126, 0116, 0136, 0107, 0127, 0117, 0137,
|
||||
0105, 0125, 0115, 0135, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0104, 0124, 0114, 0134, 0107, 0127, 0117, 0137,
|
||||
0106, 0126, 0116, 0136, 0107, 0127, 0117, 0137,
|
||||
0105, 0125, 0115, 0135, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0103, 0123, 0113, 0133, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0102, 0122, 0112, 0132, 0107, 0127, 0117, 0137,
|
||||
0106, 0126, 0116, 0136, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0106, 0126, 0116, 0136, 0107, 0127, 0117, 0137,
|
||||
0106, 0126, 0116, 0136, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0103, 0123, 0113, 0133, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0101, 0121, 0111, 0131, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0105, 0125, 0115, 0135, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0105, 0125, 0115, 0135, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0105, 0125, 0115, 0135, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0103, 0123, 0113, 0133, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0103, 0123, 0113, 0133, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0103, 0123, 0113, 0133, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0107, 0127, 0117, 0137, 0107, 0127, 0117, 0137,
|
||||
0140, 0160, 0150, 0170, 0147, 0167, 0157, 0177,
|
||||
0146, 0166, 0156, 0176, 0147, 0167, 0157, 0177,
|
||||
0145, 0165, 0155, 0175, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0144, 0164, 0154, 0174, 0147, 0167, 0157, 0177,
|
||||
0146, 0166, 0156, 0176, 0147, 0167, 0157, 0177,
|
||||
0145, 0165, 0155, 0175, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0143, 0163, 0153, 0173, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0142, 0162, 0152, 0172, 0147, 0167, 0157, 0177,
|
||||
0146, 0166, 0156, 0176, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0146, 0166, 0156, 0176, 0147, 0167, 0157, 0177,
|
||||
0146, 0166, 0156, 0176, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0143, 0163, 0153, 0173, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0141, 0161, 0151, 0171, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0145, 0165, 0155, 0175, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0145, 0165, 0155, 0175, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0145, 0165, 0155, 0175, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0143, 0163, 0153, 0173, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0143, 0163, 0153, 0173, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0143, 0163, 0153, 0173, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0147, 0167, 0157, 0177, 0147, 0167, 0157, 0177,
|
||||
0200, 0220, 0210, 0230, 0207, 0227, 0217, 0237,
|
||||
0206, 0226, 0216, 0236, 0207, 0227, 0217, 0237,
|
||||
0205, 0225, 0215, 0235, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0204, 0224, 0214, 0234, 0207, 0227, 0217, 0237,
|
||||
0206, 0226, 0216, 0236, 0207, 0227, 0217, 0237,
|
||||
0205, 0225, 0215, 0235, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0203, 0223, 0213, 0233, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0202, 0222, 0212, 0232, 0207, 0227, 0217, 0237,
|
||||
0206, 0226, 0216, 0236, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0206, 0226, 0216, 0236, 0207, 0227, 0217, 0237,
|
||||
0206, 0226, 0216, 0236, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0203, 0223, 0213, 0233, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0201, 0221, 0211, 0231, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0205, 0225, 0215, 0235, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0205, 0225, 0215, 0235, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0205, 0225, 0215, 0235, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0203, 0223, 0213, 0233, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0203, 0223, 0213, 0233, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0203, 0223, 0213, 0233, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0207, 0227, 0217, 0237, 0207, 0227, 0217, 0237,
|
||||
0240, 0260, 0250, 0270, 0247, 0267, 0257, 0277,
|
||||
0246, 0266, 0256, 0276, 0247, 0267, 0257, 0277,
|
||||
0245, 0265, 0255, 0275, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0244, 0264, 0254, 0274, 0247, 0267, 0257, 0277,
|
||||
0246, 0266, 0256, 0276, 0247, 0267, 0257, 0277,
|
||||
0245, 0265, 0255, 0275, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0243, 0263, 0253, 0273, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0242, 0262, 0252, 0272, 0247, 0267, 0257, 0277,
|
||||
0246, 0266, 0256, 0276, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0246, 0266, 0256, 0276, 0247, 0267, 0257, 0277,
|
||||
0246, 0266, 0256, 0276, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0243, 0263, 0253, 0273, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0241, 0261, 0251, 0271, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0245, 0265, 0255, 0275, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0245, 0265, 0255, 0275, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0245, 0265, 0255, 0275, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0243, 0263, 0253, 0273, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0243, 0263, 0253, 0273, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0243, 0263, 0253, 0273, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0247, 0267, 0257, 0277, 0247, 0267, 0257, 0277,
|
||||
0300, 0320, 0310, 0330, 0307, 0327, 0317, 0337,
|
||||
0306, 0326, 0316, 0336, 0307, 0327, 0317, 0337,
|
||||
0305, 0325, 0315, 0335, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0304, 0324, 0314, 0334, 0307, 0327, 0317, 0337,
|
||||
0306, 0326, 0316, 0336, 0307, 0327, 0317, 0337,
|
||||
0305, 0325, 0315, 0335, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0303, 0323, 0313, 0333, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0302, 0322, 0312, 0332, 0307, 0327, 0317, 0337,
|
||||
0306, 0326, 0316, 0336, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0306, 0326, 0316, 0336, 0307, 0327, 0317, 0337,
|
||||
0306, 0326, 0316, 0336, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0303, 0323, 0313, 0333, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0301, 0321, 0311, 0331, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0305, 0325, 0315, 0335, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0305, 0325, 0315, 0335, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0305, 0325, 0315, 0335, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0303, 0323, 0313, 0333, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0303, 0323, 0313, 0333, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0303, 0323, 0313, 0333, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0307, 0327, 0317, 0337, 0307, 0327, 0317, 0337,
|
||||
0340, 0360, 0350, 0370, 0347, 0367, 0357, 0377,
|
||||
0346, 0366, 0356, 0376, 0347, 0367, 0357, 0377,
|
||||
0345, 0365, 0355, 0375, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0344, 0364, 0354, 0374, 0347, 0367, 0357, 0377,
|
||||
0346, 0366, 0356, 0376, 0347, 0367, 0357, 0377,
|
||||
0345, 0365, 0355, 0375, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0343, 0363, 0353, 0373, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0342, 0362, 0352, 0372, 0347, 0367, 0357, 0377,
|
||||
0346, 0366, 0356, 0376, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0346, 0366, 0356, 0376, 0347, 0367, 0357, 0377,
|
||||
0346, 0366, 0356, 0376, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0343, 0363, 0353, 0373, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0341, 0361, 0351, 0371, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0345, 0365, 0355, 0375, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0345, 0365, 0355, 0375, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0345, 0365, 0355, 0375, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0343, 0363, 0353, 0373, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0343, 0363, 0353, 0373, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0343, 0363, 0353, 0373, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
0347, 0367, 0357, 0377, 0347, 0367, 0357, 0377,
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp11_defs.h: PDP-11 simulator definitions
|
||||
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -26,6 +26,8 @@
|
|||
The author gratefully acknowledges the help of Max Burnet, Megan Gentry,
|
||||
and John Wilson in resolving questions about the PDP-11
|
||||
|
||||
24-May-06 RMS Added 11/44 DR support (from CIS diagnostic)
|
||||
17-May-06 RMS Added CR11/CD11 support (from John Dundas)
|
||||
30-Sep-04 RMS Added Massbus support
|
||||
Removed Map_Addr prototype
|
||||
Removed map argument from Unibus routines
|
||||
|
@ -162,7 +164,7 @@
|
|||
|
||||
/* Feature sets
|
||||
|
||||
SDSD source addr, source fetch, dest addr, dest fetch
|
||||
SDSD source addr, dest addr, source fetch, dest fetch
|
||||
SR switch register
|
||||
DR display register
|
||||
RTT RTT instruction
|
||||
|
@ -195,7 +197,7 @@
|
|||
#define HAS_SR (CPUT_04|CPUT_05|CPUT_20|CPUT_34|CPUT_40| \
|
||||
CPUT_44|CPUT_45|CPUT_60|CPUT_70)
|
||||
#define HAS_DR (CPUT_04|CPUT_05|CPUT_20|CPUT_24|CPUT_34| \
|
||||
CPUT_40|CPUT_45|CPUT_60|CPUT_70)
|
||||
CPUT_40|CPUT_44|CPUT_45|CPUT_60|CPUT_70)
|
||||
#define HAS_RTT (CPUT_03|CPUT_04|CPUT_F|CPUT_34|CPUT_40| \
|
||||
CPUT_44|CPUT_45|CPUT_60|CPUT_70|CPUT_J|CPUT_T)
|
||||
#define HAS_SXS (CPUT_03|CPUT_F|CPUT_34|CPUT_40|CPUT_44| \
|
||||
|
@ -548,6 +550,8 @@ typedef struct pdp_dib DIB;
|
|||
#define IOLN_XU 010
|
||||
#define IOBA_RP (IOPAGEBASE + 016700) /* RP/RM */
|
||||
#define IOLN_RP 054
|
||||
#define IOBA_CR (IOPAGEBASE + 017160) /* CD/CR/CM */
|
||||
#define IOLN_CR 010
|
||||
#define IOBA_RX (IOPAGEBASE + 017170) /* RX11 */
|
||||
#define IOLN_RX 004
|
||||
#define IOBA_RY (IOPAGEBASE + 017170) /* RY11 */
|
||||
|
@ -628,7 +632,8 @@ typedef struct pdp_dib DIB;
|
|||
#define INT_V_LPT 4
|
||||
#define INT_V_VHRX 5
|
||||
#define INT_V_VHTX 6
|
||||
#define INT_V_PIR4 7
|
||||
#define INT_V_CR 7
|
||||
#define INT_V_PIR4 8
|
||||
|
||||
#define INT_V_PIR3 0 /* BR3 */
|
||||
#define INT_V_PIR2 0 /* BR2 */
|
||||
|
@ -662,6 +667,7 @@ typedef struct pdp_dib DIB;
|
|||
#define INT_LPT (1u << INT_V_LPT)
|
||||
#define INT_VHRX (1u << INT_V_VHRX)
|
||||
#define INT_VHTX (1u << INT_V_VHTX)
|
||||
#define INT_CR (1u << INT_V_CR)
|
||||
#define INT_PIR4 (1u << INT_V_PIR4)
|
||||
#define INT_PIR3 (1u << INT_V_PIR3)
|
||||
#define INT_PIR2 (1u << INT_V_PIR2)
|
||||
|
@ -692,6 +698,7 @@ typedef struct pdp_dib DIB;
|
|||
#define IPL_LPT 4
|
||||
#define IPL_VHRX 4
|
||||
#define IPL_VHTX 4
|
||||
#define IPL_CR 4
|
||||
|
||||
#define IPL_PIR7 7
|
||||
#define IPL_PIR6 6
|
||||
|
@ -722,6 +729,7 @@ typedef struct pdp_dib DIB;
|
|||
#define VEC_TM 0224
|
||||
#define VEC_TS 0224
|
||||
#define VEC_TU 0224
|
||||
#define VEC_CR 0230
|
||||
#define VEC_RP 0254
|
||||
#define VEC_TQ 0260
|
||||
#define VEC_RX 0264
|
||||
|
|
1624
PDP11/pdp11_doc.txt
1624
PDP11/pdp11_doc.txt
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
|||
/* pdp11_ry.c: RX211/RXV21/RX02 floppy disk simulator
|
||||
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
ry RX211/RXV21/RX02 floppy disk
|
||||
|
||||
15-May-06 RMS Fixed bug in autosize attach (reported by David Gesswein)
|
||||
07-Jul-05 RMS Removed extraneous externs
|
||||
18-Feb-05 RMS Fixed bug in boot code (reported by Graham Toal)
|
||||
30-Sep-04 RMS Revised Unibus interface
|
||||
|
@ -569,16 +570,13 @@ return auto_config (0, 0); /* run autoconfig */
|
|||
t_stat ry_attach (UNIT *uptr, char *cptr)
|
||||
{
|
||||
uint32 sz;
|
||||
t_stat r;
|
||||
|
||||
r = attach_unit (uptr, cptr);
|
||||
if (r != SCPE_OK) return r;
|
||||
if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize (uptr->fileref))) {
|
||||
if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize_name (cptr))) {
|
||||
if (sz > RX_SIZE) uptr->flags = uptr->flags | UNIT_DEN;
|
||||
else uptr->flags = uptr->flags & ~UNIT_DEN;
|
||||
}
|
||||
uptr->capac = (uptr->flags & UNIT_DEN)? RY_SIZE: RX_SIZE;
|
||||
return SCPE_OK;
|
||||
return attach_unit (uptr, cptr);
|
||||
}
|
||||
|
||||
/* Set size routine */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp11_sys.c: PDP-11 simulator interface
|
||||
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -23,6 +23,7 @@
|
|||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
17-May-06 RMS Added CR11/CD11 support (from John Dundas)
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
22-Jul-05 RMS Fixed missing , in initializer (from Doug Gwyn)
|
||||
22-Dec-03 RMS Added second DEUNA/DELUA support
|
||||
|
@ -57,6 +58,7 @@ extern DEVICE cpu_dev, sys_dev;
|
|||
extern DEVICE ptr_dev, ptp_dev;
|
||||
extern DEVICE tti_dev, tto_dev;
|
||||
extern DEVICE lpt_dev;
|
||||
extern DEVICE cr_dev;
|
||||
extern DEVICE clk_dev, pclk_dev;
|
||||
extern DEVICE dz_dev;
|
||||
extern DEVICE vh_dev;
|
||||
|
@ -101,6 +103,7 @@ DEVICE *sim_devices[] = {
|
|||
&ptp_dev,
|
||||
&tti_dev,
|
||||
&tto_dev,
|
||||
&cr_dev,
|
||||
&lpt_dev,
|
||||
&clk_dev,
|
||||
&pclk_dev,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp11_tc.c: PDP-11 DECtape simulator
|
||||
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
tc TC11/TU56 DECtape
|
||||
|
||||
10-Feb-06 RMS READ sets extended data bits in TCST (found by Alan Frisbie)
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
07-Jul-05 RMS Removed extraneous externs
|
||||
30-Sep-04 RMS Revised Unibus interface
|
||||
|
@ -866,6 +867,7 @@ switch (fnc) { /* at speed, check fnc *
|
|||
ma = (CSR_GETMEX (tccm) << 16) | tcba; /* form 18b addr */
|
||||
ba = (blk * DTU_BSIZE (uptr)) + wrd; /* buffer ptr */
|
||||
tcdt = wbuf = fbuf[ba] & DMASK; /* read word */
|
||||
tcst = (tcst & ~STA_M_XD) | ((fbuf[ma] >> 16) & STA_M_XD);
|
||||
if (Map_WriteW (ma, 2, &wbuf)) { /* store, nxm? */
|
||||
dt_seterr (uptr, STA_NXM);
|
||||
break;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp11_tm.c: PDP-11 magnetic tape simulator
|
||||
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
tm TM11/TU10 magtape
|
||||
|
||||
16-Feb-06 RMS Added tape capacity checking
|
||||
31-Oct-05 RMS Fixed address width for large files
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
07-Jul-05 RMS Removed extraneous externs
|
||||
|
@ -129,7 +130,7 @@
|
|||
#define STA_CRC 0020000 /* CRC error */
|
||||
#define STA_PAR 0010000 /* parity error */
|
||||
#define STA_DLT 0004000 /* data late */
|
||||
#define STA_EOT 0002000 /* *end of tape */
|
||||
#define STA_EOT 0002000 /* +end of tape */
|
||||
#define STA_RLE 0001000 /* rec lnt error */
|
||||
#define STA_BAD 0000400 /* bad tape error */
|
||||
#define STA_NXM 0000200 /* non-existent mem */
|
||||
|
@ -143,7 +144,7 @@
|
|||
|
||||
#define STA_CLR (STA_7TK | STA_SDN) /* always clear */
|
||||
#define STA_DYN (STA_EOF | STA_EOT | STA_ONL | STA_BOT | \
|
||||
STA_WLK | STA_REW | STA_TUR) /* kept in USTAT */
|
||||
STA_WLK | STA_REW | STA_TUR) /* dynamic */
|
||||
#define STA_EFLGS (STA_ILL | STA_EOF | STA_CRC | STA_PAR | \
|
||||
STA_DLT | STA_EOT | STA_RLE | STA_BAD | STA_NXM)
|
||||
/* set error */
|
||||
|
@ -230,6 +231,8 @@ MTAB tm_mod[] = {
|
|||
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", &tm_vlock },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "CAPACITY", "CAPACITY",
|
||||
&sim_tape_set_capac, &sim_tape_show_capac, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 020, "ADDRESS", "ADDRESS",
|
||||
&set_addr, &show_addr, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR",
|
||||
|
@ -495,6 +498,7 @@ return r;
|
|||
int32 tm_updcsta (UNIT *uptr)
|
||||
{
|
||||
tm_sta = (tm_sta & ~(STA_DYN | STA_CLR)) | (uptr->USTAT & STA_DYN);
|
||||
if (sim_tape_eot (uptr)) tm_sta = tm_sta | STA_EOT;
|
||||
if (sim_is_active (uptr)) tm_sta = tm_sta & ~STA_TUR;
|
||||
else tm_sta = tm_sta | STA_TUR;
|
||||
if (tm_sta & STA_EFLGS) tm_cmd = tm_cmd | MTC_ERR;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp11_tq.c: TMSCP tape controller simulator
|
||||
|
||||
Copyright (c) 2002-2005, Robert M Supnik
|
||||
Copyright (c) 2002-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
tq TQK50 tape controller
|
||||
|
||||
16-Feb-06 RMS Revised for new magtape capacity checking
|
||||
31-Oct-05 RMS Fixed address width for large files
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
22-Jul-05 RMS Fixed warning from Solaris C (from Doug Gwyn)
|
||||
|
@ -51,13 +52,16 @@
|
|||
#include "vax_defs.h"
|
||||
#if (UNIBUS)
|
||||
#define INIT_TYPE TQ8_TYPE
|
||||
#define INIT_CAP TQ8_CAP
|
||||
#else
|
||||
#define INIT_TYPE TQ5_TYPE
|
||||
#define INIT_CAP TQ5_CAP
|
||||
#endif
|
||||
|
||||
#else /* PDP-11 version */
|
||||
#include "pdp11_defs.h"
|
||||
#define INIT_TYPE TQ5_TYPE
|
||||
#define INIT_CAP TQ5_CAP
|
||||
extern int32 cpu_opt;
|
||||
#endif
|
||||
|
||||
|
@ -192,7 +196,7 @@ struct tqpkt {
|
|||
d##_CMOD, d##_MED, d##_FMT, d##_CAP, \
|
||||
d##_UMOD, d##_CREV, d##_FREV, d##_UREV
|
||||
|
||||
#define TEST_EOT(u) (sim_tape_eot (u, drv_tab[tq_typ].cap))
|
||||
#define TEST_EOT(u) (sim_tape_eot (u))
|
||||
|
||||
struct drvtyp {
|
||||
uint32 uqpm; /* UQ port model */
|
||||
|
@ -364,10 +368,10 @@ DIB tq_dib = {
|
|||
};
|
||||
|
||||
UNIT tq_unit[] = {
|
||||
{ UDATA (&tq_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0), 0 },
|
||||
{ UDATA (&tq_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0), 0 },
|
||||
{ UDATA (&tq_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0), 0 },
|
||||
{ UDATA (&tq_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0), 0 },
|
||||
{ UDATA (&tq_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0), INIT_CAP },
|
||||
{ UDATA (&tq_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0), INIT_CAP },
|
||||
{ UDATA (&tq_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0), INIT_CAP },
|
||||
{ UDATA (&tq_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0), INIT_CAP },
|
||||
{ UDATA (&tq_tmrsvc, UNIT_DIS, 0) },
|
||||
{ UDATA (&tq_quesvc, UNIT_DIS, 0) }
|
||||
};
|
||||
|
@ -2155,14 +2159,15 @@ if (cptr) {
|
|||
drv_tab[TQU_TYPE].cap = ((t_addr) cap) << 20;
|
||||
}
|
||||
tq_typ = val;
|
||||
for (i = 0; i < TQ_NUMDR; i++)
|
||||
tq_unit[i].capac = drv_tab[tq_typ].cap;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Show controller type (and capacity for user-defined type) */
|
||||
/* Show controller type and capacity */
|
||||
|
||||
t_stat tq_show_type (FILE *st, UNIT *uptr, int32 val, void *desc)
|
||||
{
|
||||
fprintf (st, "%s", drv_tab[tq_typ].name);
|
||||
if (tq_typ == TQU_TYPE) fprintf (st, " (%dMB)", drv_tab[tq_typ].cap >> 20);
|
||||
fprintf (st, "%s (%dMB)", drv_tab[tq_typ].name, (uint32) (drv_tab[tq_typ].cap >> 20));
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp11_ts.c: TS11/TSV05 magnetic tape simulator
|
||||
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
ts TS11/TSV05 magtape
|
||||
|
||||
16-Feb-06 RMS Added tape capacity checking
|
||||
31-Oct-05 RMS Fixed address width for large files
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
07-Jul-05 RMS Removed extraneous externs
|
||||
|
@ -346,6 +347,8 @@ MTAB ts_mod[] = {
|
|||
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "CAPACITY", "CAPACITY",
|
||||
&sim_tape_set_capac, &sim_tape_show_capac, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 004, "ADDRESS", "ADDRESS",
|
||||
&set_addr, &show_addr, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR",
|
||||
|
@ -648,6 +651,8 @@ if (st = sim_tape_wrrecf (uptr, tsxb, fc)) /* write rec, err? */
|
|||
return ts_map_status (st); /* return status */
|
||||
msgxs0 = msgxs0 | XS0_MOT; /* tape has moved */
|
||||
msgrfc = 0;
|
||||
if (sim_tape_eot (&ts_unit)) /* EOT on write? */
|
||||
return XTC (XS0_EOT, TC2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -658,6 +663,8 @@ t_stat st;
|
|||
if (st = sim_tape_wrtmk (uptr)) /* write tmk, err? */
|
||||
return ts_map_status (st); /* return status */
|
||||
msgxs0 = msgxs0 | XS0_MOT; /* tape has moved */
|
||||
if (sim_tape_eot (&ts_unit)) /* EOT on write? */
|
||||
return XTC (XS0_EOT, TC2);
|
||||
return XTC (XS0_TMK, TC0);
|
||||
}
|
||||
|
||||
|
@ -903,7 +910,8 @@ switch (fnc) { /* case on func */
|
|||
break;
|
||||
|
||||
case 04: /* rewind */
|
||||
if (!sim_tape_bot (uptr)) msgxs0 = msgxs0 | XS0_MOT; /* if tape moves */
|
||||
if (!sim_tape_bot (uptr)) /* if tape moves */
|
||||
msgxs0 = msgxs0 | XS0_MOT;
|
||||
sim_tape_rewind (uptr);
|
||||
break;
|
||||
}
|
||||
|
@ -930,7 +938,10 @@ t = (t & ~(XS0_ONL | XS0_WLK | XS0_BOT | XS0_IE)) | XS0_PET;
|
|||
if (ts_unit.flags & UNIT_ATT) {
|
||||
t = t | XS0_ONL;
|
||||
if (sim_tape_wrp (&ts_unit)) t = t | XS0_WLK;
|
||||
if (sim_tape_bot (&ts_unit)) t = (t | XS0_BOT) & ~XS0_EOT;
|
||||
if (sim_tape_bot (&ts_unit))
|
||||
t = (t | XS0_BOT) & ~XS0_EOT;
|
||||
if (sim_tape_eot (&ts_unit))
|
||||
t = (t | XS0_EOT) & ~XS0_BOT;
|
||||
}
|
||||
else t = t & ~XS0_EOT;
|
||||
if (cmdhdr & CMD_IE) t = t | XS0_IE;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp11_tu.c - PDP-11 TM02/TU16 TM03/TU45/TU77 Massbus magnetic tape controller
|
||||
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
tu TM02/TM03 magtape
|
||||
|
||||
16-Feb-06 RMS Added tape capacity checking
|
||||
12-Nov-05 RMS Changed default formatter to TM03 (for VMS)
|
||||
31-Oct-05 RMS Fixed address width for large files
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
|
@ -308,6 +309,8 @@ MTAB tu_mod[] = {
|
|||
{ UNIT_TYPE, UNIT_TU77, "TU77", "TU77", NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "CAPACITY", "CAPACITY",
|
||||
&sim_tape_set_capac, &sim_tape_show_capac, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
@ -447,7 +450,7 @@ return SCPE_OK;
|
|||
|
||||
t_stat tu_go (int32 drv)
|
||||
{
|
||||
int32 fnc, den, space_test = FS_BOT;
|
||||
int32 fnc, den;
|
||||
UNIT *uptr;
|
||||
|
||||
fnc = GET_FNC (tucs1); /* get function */
|
||||
|
@ -511,13 +514,23 @@ switch (fnc) { /* case on function */
|
|||
return SCPE_OK;
|
||||
|
||||
case FNC_SPACEF:
|
||||
space_test = FS_EOT;
|
||||
if ((uptr->flags & UNIT_ATT) == 0) { /* unattached? */
|
||||
tu_set_er (ER_UNS);
|
||||
break;
|
||||
}
|
||||
if (sim_tape_eot (uptr) || ((tutc & TC_FCS) == 0)) {
|
||||
tu_set_er (ER_NXF);
|
||||
break;
|
||||
}
|
||||
uptr->USTAT = FS_PIP;
|
||||
goto GO_XFER;
|
||||
|
||||
case FNC_SPACER:
|
||||
if ((uptr->flags & UNIT_ATT) == 0) { /* unattached? */
|
||||
tu_set_er (ER_UNS);
|
||||
break;
|
||||
}
|
||||
if ((tufs & space_test) || ((tutc & TC_FCS) == 0)) {
|
||||
if (sim_tape_bot (uptr) || ((tutc & TC_FCS) == 0)) {
|
||||
tu_set_er (ER_NXF);
|
||||
break;
|
||||
}
|
||||
|
@ -623,7 +636,7 @@ switch (fnc) { /* case on function */
|
|||
r = tu_map_err (drv, st, 0); /* map error */
|
||||
break;
|
||||
}
|
||||
} while (tufc != 0);
|
||||
} while ((tufc != 0) && !sim_tape_eot (uptr));
|
||||
if (tufc) tu_set_er (ER_FCE);
|
||||
else tutc = tutc & ~TC_FCS;
|
||||
break;
|
||||
|
@ -786,7 +799,12 @@ if (tu_unit[drv].flags & UNIT_ATT) {
|
|||
tufs = tufs | FS_MOL | tu_unit[drv].USTAT;
|
||||
if (tu_unit[drv].UDENS == TC_1600) tufs = tufs | FS_PE;
|
||||
if (sim_tape_wrp (&tu_unit[drv])) tufs = tufs | FS_WRL;
|
||||
if (sim_tape_bot (&tu_unit[drv]) && !act) tufs = tufs | FS_BOT;
|
||||
if (!act) {
|
||||
if (sim_tape_bot (&tu_unit[drv]))
|
||||
tufs = tufs | FS_BOT;
|
||||
if (sim_tape_eot (&tu_unit[drv]))
|
||||
tufs = tufs | FS_EOT;
|
||||
}
|
||||
}
|
||||
if (tuer) tufs = tufs | FS_ERR;
|
||||
if (tufs && !act) tufs = tufs | FS_RDY;
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
|
||||
Modification history:
|
||||
|
||||
27-Jan-06 RMS Fixed unaligned accesses in XQB (found by Doug Carman)
|
||||
07-Jan-06 RMS Fixed unaligned access bugs (found by Doug Carman)
|
||||
07-Sep-05 DTH Removed unused variable
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
|
@ -306,16 +307,18 @@ UNIT xqb_unit[] = {
|
|||
};
|
||||
|
||||
REG xqb_reg[] = {
|
||||
{ GRDATA ( SA0, xqb.addr[0], XQ_RDX, 16, 0), REG_RO},
|
||||
{ GRDATA ( SA1, xqb.addr[1], XQ_RDX, 16, 0), REG_RO},
|
||||
{ GRDATA ( SA2, xqb.addr[2], XQ_RDX, 16, 0), REG_RO},
|
||||
{ GRDATA ( SA3, xqb.addr[3], XQ_RDX, 16, 0), REG_RO},
|
||||
{ GRDATA ( SA4, xqb.addr[4], XQ_RDX, 16, 0), REG_RO},
|
||||
{ GRDATA ( SA5, xqb.addr[5], XQ_RDX, 16, 0), REG_RO},
|
||||
{ GRDATA ( RBDL, xqb.rbdl, XQ_RDX, 32, 0) },
|
||||
{ GRDATA ( XBDL, xqb.xbdl, XQ_RDX, 32, 0) },
|
||||
{ GRDATA ( VAR, xqb.var, XQ_RDX, 16, 0) },
|
||||
{ GRDATA ( CSR, xqb.csr, XQ_RDX, 16, 0) },
|
||||
{ GRDATA ( SA0, xqb.addr[0], XQ_RDX, 8, 0), REG_RO|REG_FIT},
|
||||
{ GRDATA ( SA1, xqb.addr[1], XQ_RDX, 8, 0), REG_RO|REG_FIT},
|
||||
{ GRDATA ( SA2, xqb.addr[2], XQ_RDX, 8, 0), REG_RO|REG_FIT},
|
||||
{ GRDATA ( SA3, xqb.addr[3], XQ_RDX, 8, 0), REG_RO|REG_FIT},
|
||||
{ GRDATA ( SA4, xqb.addr[4], XQ_RDX, 8, 0), REG_RO|REG_FIT},
|
||||
{ GRDATA ( SA5, xqb.addr[5], XQ_RDX, 8, 0), REG_RO|REG_FIT},
|
||||
{ GRDATA ( RBDL, xqb.rbdl[0], XQ_RDX, 16, 0), REG_FIT },
|
||||
{ GRDATA ( RBDH, xqb.rbdl[1], XQ_RDX, 16, 0), REG_FIT },
|
||||
{ GRDATA ( XBDL, xqb.xbdl[0], XQ_RDX, 16, 0), REG_FIT },
|
||||
{ GRDATA ( XBDH, xqb.xbdl[1], XQ_RDX, 16, 0), REG_FIT },
|
||||
{ GRDATA ( VAR, xqb.var, XQ_RDX, 16, 0), REG_FIT },
|
||||
{ GRDATA ( CSR, xqb.csr, XQ_RDX, 16, 0), REG_FIT },
|
||||
{ FLDATA ( INT, xqb.irq, 0) },
|
||||
{ GRDATA ( SETUP_PRM, xqb.setup.promiscuous, XQ_RDX, 32, 0), REG_HRO},
|
||||
{ GRDATA ( SETUP_MLT, xqb.setup.multicast, XQ_RDX, 32, 0), REG_HRO},
|
||||
|
|
49
PDP11/txt2cbn.c
Normal file
49
PDP11/txt2cbn.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#define ERROR 00404
|
||||
#include "pdp11_cr_dat.h"
|
||||
|
||||
static int colStart = 1; /* starting column */
|
||||
static int colEnd = 80; /* ending column */
|
||||
|
||||
main ()
|
||||
{
|
||||
int col, c;
|
||||
|
||||
while (1) {
|
||||
for (col = colStart; col <= colEnd; ) {
|
||||
switch (c = fgetc (stdin)) {
|
||||
case EOF:
|
||||
/* fall through */
|
||||
case '\n':
|
||||
while (col <= colEnd) {
|
||||
fputc (o29_code[' '] & 077, stdout);
|
||||
fputc ((o29_code[' '] >> 6) & 077, stdout);
|
||||
col++;
|
||||
}
|
||||
break;
|
||||
case '\t':
|
||||
do {
|
||||
fputc (o29_code[' '] & 077, stdout);
|
||||
fputc ((o29_code[' '] >> 6) & 077, stdout);
|
||||
col++;
|
||||
} while (((col & 07) != 1) && (col <= colEnd));
|
||||
break;
|
||||
default:
|
||||
fputc (o29_code[c] & 077, stdout);
|
||||
fputc ((o29_code[c] >> 6) & 077, stdout);
|
||||
col++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* flush long lines, or flag over-length card */
|
||||
if (c != '\n' && c != EOF) {
|
||||
printf ("overlength line\n");
|
||||
do c = fgetc (stdin);
|
||||
while ((c != EOF) && (c != '\n'));
|
||||
}
|
||||
if (c == EOF)
|
||||
break;
|
||||
}
|
||||
exit (1);
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
|||
/* pdp18b_mt.c: 18b PDP magnetic tape simulator
|
||||
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -26,6 +26,7 @@
|
|||
mt (PDP-9) TC59 magtape
|
||||
(PDP-15) TC59D magtape
|
||||
|
||||
16-Feb-06 RMS Added tape capacity checking
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
18-Mar-05 RMS Added attached test to detach routine
|
||||
14-Jan-04 RMS Revised IO device call interface
|
||||
|
@ -186,6 +187,8 @@ MTAB mt_mod[] = {
|
|||
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "CAPACITY", "CAPACITY",
|
||||
&sim_tape_set_capac, &sim_tape_show_capac, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO",
|
||||
&set_devno, &show_devno, NULL },
|
||||
{ 0 }
|
||||
|
@ -263,6 +266,7 @@ t_stat mt_svc (UNIT *uptr)
|
|||
int32 c, c1, c2, c3, f, i, p, u;
|
||||
int32 wc, xma;
|
||||
t_mtrlnt tbc, cbc;
|
||||
t_bool passed_eot;
|
||||
t_stat st, r = SCPE_OK;
|
||||
|
||||
u = (int32) (uptr - mt_dev.units); /* get unit number */
|
||||
|
@ -283,6 +287,7 @@ if ((uptr->flags & UNIT_ATT) == 0) { /* if not attached */
|
|||
return IORETURN (mt_stopioe, SCPE_UNATT);
|
||||
}
|
||||
|
||||
passed_eot = sim_tape_eot (uptr); /* passed EOT? */
|
||||
switch (f) { /* case on function */
|
||||
|
||||
case FN_READ: /* read */
|
||||
|
@ -362,7 +367,7 @@ switch (f) { /* case on function */
|
|||
r = mt_map_err (uptr, st); /* map error */
|
||||
break;
|
||||
}
|
||||
} while (M[MT_WC] != 0);
|
||||
} while ((M[MT_WC] != 0) && (passed_eot || !sim_tape_eot (uptr)));
|
||||
break;
|
||||
|
||||
case FN_SPACER: /* space reverse */
|
||||
|
@ -376,6 +381,8 @@ switch (f) { /* case on function */
|
|||
break;
|
||||
} /* end case */
|
||||
|
||||
if (!passed_eot && sim_tape_eot (uptr)) /* just passed EOT? */
|
||||
uptr->USTAT = uptr->USTAT | STA_EOT;
|
||||
mt_updcsta (uptr, STA_DON); /* set done */
|
||||
if (mt_log) printf ("MT%d: fnc=%d done, ma=%o, wc=%o, sta=%o]\n",
|
||||
u, f, M[MT_CA], M[MT_WC], mt_sta);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp18b_rf.c: fixed head disk simulator
|
||||
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -26,6 +26,7 @@
|
|||
rf (PDP-9) RF09/RF09
|
||||
(PDP-15) RF15/RS09
|
||||
|
||||
15-May-06 RMS Fixed bug in autosize attach (reported by David Gesswein)
|
||||
14-Jan-04 RMS Revised IO device call interface
|
||||
Changed sim_fsize calling sequence
|
||||
26-Oct-03 RMS Cleaned up buffer copy code
|
||||
|
@ -329,18 +330,15 @@ t_stat rf_attach (UNIT *uptr, char *cptr)
|
|||
{
|
||||
uint32 p, sz;
|
||||
uint32 ds_bytes = RF_DKSIZE * sizeof (int32);
|
||||
t_stat r;
|
||||
|
||||
r = attach_unit (uptr, cptr);
|
||||
if (r != SCPE_OK) return r;
|
||||
if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize (uptr->fileref))) {
|
||||
if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize_name (cptr))) {
|
||||
p = (sz + ds_bytes - 1) / ds_bytes;
|
||||
if (p >= RF_NUMDK) p = RF_NUMDK - 1;
|
||||
uptr->flags = (uptr->flags & ~UNIT_PLAT) |
|
||||
(p << UNIT_V_PLAT);
|
||||
}
|
||||
uptr->capac = UNIT_GETP (uptr->flags) * RF_DKSIZE;
|
||||
return SCPE_OK;
|
||||
return attach_unit (uptr, cptr);
|
||||
}
|
||||
|
||||
/* Change disk size */
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
df DF32 fixed head disk
|
||||
|
||||
15-May-06 RMS Fixed bug in autosize attach (reported by Dave Gesswein)
|
||||
07-Jan-06 RMS Fixed unaligned register access bug (found by Doug Carman)
|
||||
04-Jan-04 RMS Changed sim_fsize calling sequence
|
||||
26-Oct-03 RMS Cleaned up buffer copy code
|
||||
|
@ -349,18 +350,15 @@ t_stat df_attach (UNIT *uptr, char *cptr)
|
|||
{
|
||||
uint32 p, sz;
|
||||
uint32 ds_bytes = DF_DKSIZE * sizeof (int16);
|
||||
t_stat r;
|
||||
|
||||
r = attach_unit (uptr, cptr);
|
||||
if (r != SCPE_OK) return r;
|
||||
if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize (uptr->fileref))) {
|
||||
if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize_name (cptr))) {
|
||||
p = (sz + ds_bytes - 1) / ds_bytes;
|
||||
if (p >= DF_NUMDK) p = DF_NUMDK - 1;
|
||||
uptr->flags = (uptr->flags & ~UNIT_PLAT) |
|
||||
(p << UNIT_V_PLAT);
|
||||
}
|
||||
uptr->capac = UNIT_GETP (uptr->flags) * DF_DKSIZE;
|
||||
return SCPE_OK;
|
||||
return attach_unit (uptr, cptr);
|
||||
}
|
||||
|
||||
/* Change disk size */
|
||||
|
|
|
@ -1,886 +0,0 @@
|
|||
To: Users
|
||||
From: Bob Supnik
|
||||
Subj: PDP-8 Simulator Usage
|
||||
Date: 01-Dec-2005
|
||||
|
||||
COPYRIGHT NOTICE
|
||||
|
||||
The following copyright notice applies to both the SIMH source and binary:
|
||||
|
||||
Original code published in 1993-2005, written by Robert M Supnik
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
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 memorandum documents the PDP-8 simulator.
|
||||
|
||||
|
||||
1. Simulator Files
|
||||
|
||||
sim/ scp.h
|
||||
sim_console.h
|
||||
sim_defs.h
|
||||
sim_fio.h
|
||||
sim_rev.h
|
||||
sim_sock.h
|
||||
sim_tape.h
|
||||
sim_timer.h
|
||||
sim_tmxr.h
|
||||
scp.c
|
||||
sim_console.c
|
||||
sim_fio.c
|
||||
sim_sock.c
|
||||
sim_tape.c
|
||||
sim_timer.c
|
||||
sim_tmxr.c
|
||||
|
||||
sim/pdp8/ pdp8_defs.h
|
||||
pdp8_cpu.c
|
||||
pdp8_df.c
|
||||
pdp8_dt.c
|
||||
pdp8_lp.c
|
||||
pdp8_mt.c
|
||||
pdp8_pt.c
|
||||
pdp8_rf.c
|
||||
pdp8_rk.c
|
||||
pdp8_rl.c
|
||||
pdp8_rx.c
|
||||
pdp8_sys.c
|
||||
pdp8_td.c
|
||||
pdp8_tsc.c
|
||||
pdp8_tt.c
|
||||
pdp8_ttx.c
|
||||
|
||||
2. PDP-8 Features
|
||||
|
||||
The PDP-8 simulator is configured as follows:
|
||||
|
||||
device simulates
|
||||
name(s)
|
||||
|
||||
CPU PDP-8/E CPU with 4KW-32KW of memory
|
||||
- KE8E extended arithmetic element (EAE)
|
||||
- KM8E memory management and timeshare control
|
||||
TSC TSC8-75 ETOS operating system timeshare control
|
||||
PTR,PTP PC8E paper tape reader/punch
|
||||
TTI,TTO KL8E console terminal
|
||||
TTIX,TTOX KL8JA additional terminals
|
||||
LPT LE8E line printer
|
||||
CLK DK8E line frequency clock (also PDP-8/A compatible)
|
||||
RK RK8E/RK05 cartridge disk controller with four drives
|
||||
RF RF08/RS08 fixed head disk controller with 1-4 platters, or
|
||||
DF DF32/DS32 fixed head disk controller with 1-4 platters
|
||||
RL RL8A/RL01 cartridge disk controller with four drives
|
||||
RX RX8E/RX01, RX28/RX02 floppy disk controller with two drives
|
||||
DT TC08/TU56 DECtape controller with eight drives
|
||||
TD TD8E/TU56 DECtape controller with two drives
|
||||
MT TM8E/TU10 magnetic tape controller with eight drives
|
||||
|
||||
Most devices can be disabled or enabled, by the commands:
|
||||
|
||||
SET <dev> DISABLED
|
||||
SET <dev> ENABLED
|
||||
|
||||
The simulator allows most device numbers to be changed, by the command:
|
||||
|
||||
SET <dev> DEV=<number>
|
||||
|
||||
The PDP-8 can support only one of the set {DF32, RF08, RL8A} using the
|
||||
default device numbers, since they all use device numbers 60-61. The
|
||||
default is the RF08. To change the disk at device numbers 60-61:
|
||||
|
||||
sim> SET RF DISABLED disable RF08
|
||||
sim> SET DF ENABLED, or enable DF32
|
||||
sim> SET RL ENABLED enable RL8A
|
||||
|
||||
The PDP-8 can only support one of the set {TC08, TD8E} using the default
|
||||
device numbers, since both use device number 77. The default is the
|
||||
TC08. To change the DECtape controller to the TD8E:
|
||||
|
||||
sim> SET DT DISABLED disable TC08
|
||||
sim> SET TD ENABLED enable TD8E
|
||||
|
||||
Alternately, the device conflict can be eliminated by changing device
|
||||
numbers:
|
||||
|
||||
sim> SET RL DEV=50
|
||||
sim> SET RL ENA
|
||||
sim> SET TD DEV=74
|
||||
sim> SET TD ENA
|
||||
|
||||
However, devices can only be BOOTed with their default device numbers.
|
||||
|
||||
The PDP-8 simulator implements several unique stop conditions:
|
||||
|
||||
- if an undefined instruction (unimplemented IOT or OPR) is
|
||||
decoded, and register STOP_INST
|
||||
- if a simulated DECtape runs off the end of its reel
|
||||
|
||||
The PDP-8 loader supports both RIM format and BIN format tapes. If the file
|
||||
extension is .RIM, or the -r switch is specified with LOAD, the file is
|
||||
assumed to be RIM format; if the file extension is not .RIM, or if the -b
|
||||
switch is specified, the file is assumed to be BIN format.
|
||||
|
||||
2.1 CPU
|
||||
|
||||
The only CPU options are the presence of the EAE and the size of main
|
||||
memory; the memory extension and time-share control is always included,
|
||||
even if memory size is 4K.
|
||||
|
||||
SET CPU EAE enable EAE
|
||||
SET CPU NOEAE disable EAE
|
||||
SET CPU 4K set memory size = 4K
|
||||
SET CPU 8K set memory size = 8K
|
||||
SET CPU 12K set memory size = 12K
|
||||
SET CPU 16K set memory size = 16K
|
||||
SET CPU 20K set memory size = 20K
|
||||
SET CPU 24K set memory size = 24K
|
||||
SET CPU 28K set memory size = 28K
|
||||
SET CPU 32K set memory size = 32K
|
||||
|
||||
If memory size is being reduced, and the memory being truncated contains
|
||||
non-zero data, the simulator asks for confirmation. Data in the truncated
|
||||
portion of memory is lost. Initial memory size is 32K.
|
||||
|
||||
CPU registers include the visible state of the processor as well as the
|
||||
control registers for the interrupt system.
|
||||
|
||||
name size comments
|
||||
|
||||
PC 15 program counter, including IF as high 3 bits
|
||||
AC 12 accumulator
|
||||
MQ 12 multiplier-quotient
|
||||
L 1 link
|
||||
SR 12 front panel switches
|
||||
IF 3 instruction field
|
||||
DF 3 data field
|
||||
IB 3 instruction field buffer
|
||||
SF 7 save field
|
||||
UF 1 user mode flag
|
||||
UB 1 user mode buffer
|
||||
SC 5 EAE shift counter
|
||||
GTF 1 EAE greater than flag
|
||||
EMODE 1 EAE mode (0 = A, 1 = B)
|
||||
ION 1 interrupt enable
|
||||
ION_DELAY 1 interrupt enable delay for ION
|
||||
CIF_DELAY 1 interrupt enable delay for CIF
|
||||
PWR_INT 1 power fail interrupt
|
||||
UF_INT 1 user mode violation interrupt
|
||||
INT 15 interrupt pending flags
|
||||
DONE 15 device done flags
|
||||
ENABLE 15 device interrupt enable flags
|
||||
PCQ[0:63] 15 PC prior to last JMP, JMS, or interrupt;
|
||||
most recent PC change first
|
||||
STOP_INST 1 stop on undefined instruction
|
||||
WRU 8 interrupt character
|
||||
|
||||
The CPU can maintain a history of the most recently executed instructions.
|
||||
This is controlled by the SET CPU HISTORY and SHOW CPU HISTORY commands:
|
||||
|
||||
SET CPU HISTORY clear history buffer
|
||||
SET CPU HISTORY=0 disable history
|
||||
SET CPU HISTORY=n enable history, length = n
|
||||
SHOW CPU HISTORY print CPU history
|
||||
SHOW CPU HISTORY=n print first n entries of CPU history
|
||||
|
||||
The maximum length for the history is 65536 entries.
|
||||
|
||||
2.2 TSC8-75 ETOS Timeshare Control (TSC)
|
||||
|
||||
ETOS is a timeshared operating system for the PDP-8, providing multiple
|
||||
virtual OS/8 environments for up to 32 users. It requires a special
|
||||
timeshare control option, the TSC8-75. The TSC8-75 is normally disabled;
|
||||
to run ETOS, it must be enabled with the command:
|
||||
|
||||
SET TSC ENABLED
|
||||
|
||||
The TSC8-75 implements these registers:
|
||||
|
||||
IR most recently trapped instruction
|
||||
PC PC of most recently trapped instruction
|
||||
CDF 1 if trapped instruction is CDF, 0 otherwise
|
||||
ENB interrupt enable flag
|
||||
INT interrupt pending flag
|
||||
|
||||
Except for operation of ETOS, the TSC8-75 should be left disabled.
|
||||
|
||||
2.3 Programmed I/O Devices
|
||||
|
||||
2.3.1 PC8E Paper Tape Reader (PTR)
|
||||
|
||||
The paper tape reader (PTR) reads data from a disk file. The POS
|
||||
register specifies the number of the next data item to be read. Thus,
|
||||
by changing POS, the user can backspace or advance the reader.
|
||||
|
||||
The paper tape reader supports the BOOT command. BOOT PTR copies the
|
||||
RIM loader into memory and starts it running.
|
||||
|
||||
The paper tape reader implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
DONE 1 device done flag
|
||||
ENABLE 1 interrupt enable flag
|
||||
INT 1 interrupt pending flag
|
||||
POS 32 position in the input file
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of tape
|
||||
|
||||
end of file 1 report error and stop
|
||||
0 out of tape
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.3.2 PC8E Paper Tape Punch (PTP)
|
||||
|
||||
The paper tape punch (PTP) writes data to a disk file. The POS register
|
||||
specifies the number of the next data item to bewritten. Thus, by
|
||||
changing POS, the user can backspace or advance the punch.
|
||||
|
||||
The paper tape punch implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
DONE 1 device done flag
|
||||
ENABLE 1 interrupt enable flag
|
||||
INT 1 interrupt pending flag
|
||||
POS 32 position in the output file
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of tape
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.3.3 KL8E Terminal Input (TTI)
|
||||
|
||||
The terminal interfaces (TTI, TTO) can be set to one of four modes,
|
||||
KSR, 7B, 7B, or 8B:
|
||||
|
||||
mode input characters output characters
|
||||
|
||||
KSR lower case converted lower case converted
|
||||
to upper case, to upper case,
|
||||
high-order bit set high-order bit cleared,
|
||||
non-printing characters
|
||||
suppressed
|
||||
7P high-order bit cleared high-order bit cleared,
|
||||
non-printing characters
|
||||
suppressed
|
||||
7B high-order bit cleared high-order bit cleared
|
||||
8B no changes no changes
|
||||
|
||||
The default mode is KSR.
|
||||
|
||||
The terminal input (TTI) polls the console keyboard for input. It
|
||||
implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
DONE 1 device done flag
|
||||
ENABLE 1 interrupt enable flag
|
||||
INT 1 interrupt pending flag
|
||||
POS 32 number of characters input
|
||||
TIME 24 keyboard polling interval
|
||||
|
||||
2.3.4 KL8E Terminal Output (TTO)
|
||||
|
||||
The terminal output (TTO) writes to the simulator console window. It
|
||||
implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
DONE 1 device done flag
|
||||
ENABLE 1 interrupt enable flag
|
||||
INT 1 interrupt pending flag
|
||||
POS 32 number of characters output
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
|
||||
2.3.5 LE8E Line Printer (LPT)
|
||||
|
||||
The line printer (LPT) writes data to a disk file. The POS register
|
||||
specifies the number of the next data item to be read or written. Thus,
|
||||
by changing POS, the user can backspace or advance the printer.
|
||||
|
||||
The line printer implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 8 last data item processed
|
||||
ERR 1 error status flag
|
||||
DONE 1 device done flag
|
||||
ENABLE 1 interrupt enable flag
|
||||
INT 1 interrupt pending flag
|
||||
POS 32 position in the output file
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 set error flag
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.3.6 DK8E Line-Frequency Clock (CLK)
|
||||
|
||||
The real-time clock (CLK) frequency can be adjusted as follows:
|
||||
|
||||
SET CLK 60HZ set frequency to 60Hz
|
||||
SET CLK 50HZ set frequency to 50Hz
|
||||
|
||||
The default is 60Hz.
|
||||
|
||||
The clock implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
DONE 1 device done flag
|
||||
ENABLE 1 interrupt enable flag
|
||||
INT 1 interrupt pending flag
|
||||
TIME 24 clock interval
|
||||
|
||||
The real-time clock autocalibrates; the clock interval is adjusted up or
|
||||
down so that the clock tracks actual elapsed time.
|
||||
|
||||
2.3.7 KL8JA Additional Terminals (TTIX, TTOX)
|
||||
|
||||
The additional terminals consist of two independent devices, TTIX and
|
||||
TTOX. The entire set is modelled as a terminal multiplexor, with TTIX
|
||||
as the master unit. The additional terminals perform input and output
|
||||
through Telnet sessions connected to a user-specified port. The ATTACH
|
||||
command specifies the port to be used:
|
||||
|
||||
ATTACH TTIX <port> set up listening port
|
||||
|
||||
where port is a decimal number between 1 and 65535 that is not being used
|
||||
for other TCP/IP activities.
|
||||
|
||||
The additional terminals can be set to one of four modes: UC, 7P, 7B,
|
||||
or 8B.
|
||||
|
||||
mode input characters output characters
|
||||
|
||||
UC lower case converted lower case converted
|
||||
to upper case, to upper case,
|
||||
high-order bit cleared high-order bit cleared,
|
||||
non-printing characters
|
||||
suppressed
|
||||
7P high-order bit cleared high-order bit cleared,
|
||||
non-printing characters
|
||||
suppressed
|
||||
7B high-order bit cleared high-order bit cleared
|
||||
8B no changes no changes
|
||||
|
||||
|
||||
The default mode is UC. Finally, each line supports output logging.
|
||||
The SET TTOXn LOG command enables logging on a line:
|
||||
|
||||
SET TTOXn LOG=filename log output of line n to filename
|
||||
|
||||
The SET TTOXLn NOLOG command disables logging and closes the open log
|
||||
file, if any.
|
||||
|
||||
Once TTIX is attached and the simulator is running, the terminals listen
|
||||
for connections on the specified port. They assume that the incoming
|
||||
connections are Telnet connections. The connections remain open until
|
||||
disconnected either by the Telnet client, a SET TTIX DISCONNECT command,
|
||||
or a DETACH TTIX command.
|
||||
|
||||
The SHOW TTIX CONNECTIONS command displays the current connections to the
|
||||
extra terminals. The SHOW TTIX STATISTICS command displays statistics for
|
||||
active connections. The SET TTIXn DISCONNECT command disconnects line n.
|
||||
|
||||
The input device (TTIX) implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF[0:3] 8 input buffer, lines 0-3
|
||||
DONE 4 device done flags (line 0 rightmost)
|
||||
ENABLE 4 interrupt enable flag
|
||||
INT 4 interrupt pending flag
|
||||
TIME 24 initial polling interval
|
||||
TPS 10 polls per second after calibration
|
||||
|
||||
The output device (TTOX) implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF[0:3] 8 last data item processed, lines 0-3
|
||||
DONE 4 device done flag (line 0 rightmost)
|
||||
ENABLE 4 interrupt enable flag
|
||||
INT 4 interrupt pending flag
|
||||
TIME[0:3] 24 time from I/O initiation to interrupt,
|
||||
lines 0-3
|
||||
|
||||
The additional terminals do not support save and restore. All open
|
||||
connections are lost when the simulator shuts down or TTIX is detached.
|
||||
|
||||
2.3.8 TD8E/TU56 DECtape (TD)
|
||||
|
||||
The TD8E is a programmed I/O, non-interrupt controller, supporting two
|
||||
DECtape drives (0 and 1). The TD8E simulator puts a high burden on the
|
||||
host processor, because tape activity is simulated a line (3b) at a time.
|
||||
Unless the PDP-8 software requires the TD8E, the TC08 should be used
|
||||
to simulate DECtapes. The TD8E is disabled by default.
|
||||
|
||||
TD8E options include the ability to make units write enabled or write
|
||||
locked.
|
||||
|
||||
SET DTn LOCKED set unit n write locked
|
||||
SET DTn WRITEENABLED set unit n write enabled
|
||||
|
||||
Units can also be set ENABLED or DISABLED. The TD8E supports the BOOT
|
||||
command, but only for unit 0.
|
||||
|
||||
The TD8E supports supports PDP-8 format, PDP-11 format, and 18b format
|
||||
DECtape images. ATTACH tries to determine the tape format from the DECtape
|
||||
image; the user can force a particular format with switches:
|
||||
|
||||
-r PDP-8 format
|
||||
-s PDP-11 format
|
||||
-t 18b format
|
||||
|
||||
The TD8E controller is a data-only simulator; the timing and mark
|
||||
track, and block header and trailer, are not stored. Thus, read always
|
||||
produces standard values for header and trailer words, and write throws
|
||||
header and trailer words into the bit bucket.
|
||||
|
||||
The TD8E controller implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
TDCMD 4 command register
|
||||
TDDAT 12 data register
|
||||
TDMTK 6 mark track register
|
||||
TDSLF 1 single line flag
|
||||
TDQLF 1 quad line flag
|
||||
TDTME 1 timing error flag
|
||||
TDQL 2 quad line counter
|
||||
LTIME 31 time between lines
|
||||
DCTIME 31 time to decelerate to a full stop
|
||||
POS[0:7] 32 position, in lines, units 0-7
|
||||
STATT[0:7] 18 unit state, units 0-7
|
||||
STOP_OFFR 1 stop on off-reel error
|
||||
|
||||
The LTIME parameter should not be changed, or OS/8 may fail to run
|
||||
correctly. The DCTIME parameter should always be at least 100 times
|
||||
greater than LTIME. Acceleration time is 75% of deceleration time.
|
||||
|
||||
2.4 Moving Head Disks
|
||||
|
||||
2.4.1 RK8E Cartridge Disk (RK)
|
||||
|
||||
RK8E options include the ability to make units write enabled or write locked:
|
||||
|
||||
SET RKn LOCKED set unit n write locked
|
||||
SET RKn WRITEENABLED set unit n write enabled
|
||||
|
||||
Units can also be set ENABLED or DISABLED. The RK8E supports the BOOT command.
|
||||
|
||||
The RK8E implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
RKSTA 12 status
|
||||
RKCMD 12 disk command
|
||||
RKDA 12 disk address
|
||||
RKMA 12 current memory address
|
||||
BUSY 1 control busy flag
|
||||
INT 1 interrupt pending flag
|
||||
STIME 24 seek time, per cylinder
|
||||
RTIME 24 rotational delay
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 disk not ready
|
||||
|
||||
end of file x assume rest of disk is zero
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.4.2 RL8A Cartridge Disk (RL)
|
||||
|
||||
RL8A options include the ability to make units write enabled or write locked:
|
||||
|
||||
SET RLn LOCKED set unit n write locked
|
||||
SET RLn WRITEENABLED set unit n write enabled
|
||||
|
||||
Units can also be set ENABLED or DISABLED. The RL8A supports the BOOT command,
|
||||
but only for unit 0.
|
||||
|
||||
The RL8A implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
RLCSA 12 control/status A
|
||||
RLCSB 12 control/status B
|
||||
RLMA 12 memory address
|
||||
RLWC 12 word count
|
||||
RLSA 6 sector address
|
||||
RLER 12 error flags
|
||||
RLSI 16 silo top word
|
||||
RLSI1 16 silo second word
|
||||
RLSI2 16 silo third word
|
||||
RLSIL 1 silo read left/right flag
|
||||
INT 1 interrupt request
|
||||
DONE 1 done flag
|
||||
ERR 1 composite error flag
|
||||
STIME 1 seek time, per cylinder
|
||||
RTIME 1 rotational delay
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 disk not ready
|
||||
|
||||
end of file x assume rest of disk is zero
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
2.5 RX8E/RX01, RX28/RX02 Floppy Disk (RX)
|
||||
|
||||
The RX can be configured as an RX8E with two RX01 drives, or an RX28 with
|
||||
two RX02 drives:
|
||||
|
||||
SET RX RX8E set controller to RX8E/RX01
|
||||
SET RX RX28 set controller to RX28/RX02
|
||||
|
||||
The controller is set to the RX8E by default. The RX28 is not backwards-
|
||||
compatible with the RX8E and will not work with the standard OS/8 V3D floppy
|
||||
disk driver.
|
||||
|
||||
RX8E options include the ability to set units write enabled or write locked:
|
||||
|
||||
SET RXn LOCKED set unit n write locked
|
||||
SET RXn WRITEENABLED set unit n write enabled
|
||||
|
||||
RX28 options include, in addition, the ability to set the unit density to
|
||||
single density, double density, or autosized; autosizing is the default:
|
||||
|
||||
SET RXn SINGLE set unit n single density
|
||||
SET RXn DOUBLE set unit n double density
|
||||
SET RXn AUTOSIZE set unit n autosize
|
||||
|
||||
The RX8E and RX28 support the BOOT command.
|
||||
|
||||
The RX8E and RX28 implement these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
RXCS 12 status
|
||||
RXDB 12 data buffer
|
||||
RXES 12 error status
|
||||
RXTA 8 current track
|
||||
RXSA 8 current sector
|
||||
STAPTR 4 controller state
|
||||
BUFPTR 8 buffer pointer
|
||||
INT 1 interrupt pending flag
|
||||
DONE 1 device done flag
|
||||
ENABLE 1 interrupt enable flag
|
||||
TR 1 transfer ready flag
|
||||
ERR 1 error flag
|
||||
CTIME 24 command completion time
|
||||
STIME 24 seek time, per track
|
||||
XTIME 24 transfer ready delay
|
||||
STOP_IOE 1 stop on I/O error
|
||||
SBUF[0:255] 8 sector buffer array
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 disk not ready
|
||||
|
||||
RX01 and RX02 data files are buffered in memory; therefore, end of file
|
||||
and OS I/O errors cannot occur.
|
||||
|
||||
2.6 Fixed Head Disks
|
||||
|
||||
Either the RF08 or the DF32 can be present in a configuration, but
|
||||
not both, with default device addressing.
|
||||
|
||||
2.6.1 RF08/RS08 Fixed Head Disk (RF)
|
||||
|
||||
RF08 options include the ability to set the number of platters to a
|
||||
fixed value between 1 and 4, or to autosize the number of platters
|
||||
from the attached file:
|
||||
|
||||
SET RF 1P one platter (256K)
|
||||
SET RF 2P two platters (512K)
|
||||
SET RF 3P three platters (768K)
|
||||
SET RF 4P four platters (1024K)
|
||||
SET RF AUTOSIZE autosized on attach
|
||||
|
||||
The default is one platter.
|
||||
|
||||
The RF08 implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
STA 12 status
|
||||
DA 20 current disk address
|
||||
MA 12 memory address (in memory)
|
||||
WC 12 word count (in memory)
|
||||
WLK 32 write lock switches
|
||||
INT 1 interrupt pending flag
|
||||
DONE 1 device done flag
|
||||
TIME 24 rotational delay, per word
|
||||
BURST 1 burst flag
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
The RF08 supports the BOOT command. The default bootstrap is for OS/8. To
|
||||
bootstrap the 4K Disk Monitor, use the BOOT -D RF command.
|
||||
|
||||
The RF08 is a three-cycle data break device. If BURST = 0, word transfers
|
||||
are scheduled individually; if BURST = 1, the entire transfer occurs in
|
||||
a single data break.
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 disk not ready
|
||||
|
||||
RF08 data files are buffered in memory; therefore, end of file and OS
|
||||
I/O errors cannot occur.
|
||||
|
||||
2.6.2 DF32/DS32 Fixed Head Disk (RF)
|
||||
|
||||
DF32 options include the ability to set the number of platters to a
|
||||
fixed value between 1 and 4, or to autosize the number of platters
|
||||
from the attached file:
|
||||
|
||||
SET DF 1P one platter (32K)
|
||||
SET DF 2P two platters (64K)
|
||||
SET DF 3P three platters (98K)
|
||||
SET DF 4P four platters (128K)
|
||||
SET DF AUTOSIZE autosized on attach
|
||||
|
||||
The default is one platter.
|
||||
|
||||
The DF32 implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
STA 12 status, disk and memory address extension
|
||||
DA 12 low order disk address
|
||||
MA 12 memory address (in memory)
|
||||
WC 12 word count (in memory)
|
||||
WLK 16 write lock switches
|
||||
INT 1 interrupt pending flag
|
||||
DONE 1 device done flag
|
||||
TIME 24 rotational delay, per word
|
||||
BURST 1 burst flag
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
The DF32 supports the BOOT command. The default bootstrap is for OS/8. To
|
||||
bootstrap the 4K Disk Monitor, use the BOOT -D DF command.
|
||||
|
||||
The DF32 is a three-cycle data break device. If BURST = 0, word transfers
|
||||
are scheduled individually; if BURST = 1, the entire transfer occurs in
|
||||
a single data break.
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 disk not ready
|
||||
|
||||
DF32 data files are buffered in memory; therefore, end of file and OS
|
||||
I/O errors cannot occur.
|
||||
|
||||
2.7 TC08/TU56 DECtape (DT)
|
||||
|
||||
DECtapes drives are numbered 1-8; in the simulator, drive 8 is unit 0.
|
||||
TC08 options include the ability to make units write enabled or write
|
||||
locked.
|
||||
|
||||
SET DTn LOCKED set unit n write locked
|
||||
SET DTn WRITEENABLED set unit n write enabled
|
||||
|
||||
Units can also be set ENABLED or DISABLED. The TC08 supports the BOOT
|
||||
command, but only for unit 0.
|
||||
|
||||
The TC08 supports supports PDP-8 format, PDP-11 format, and 18b format
|
||||
DECtape images. ATTACH tries to determine the tape format from the DECtape
|
||||
image; the user can force a particular format with switches:
|
||||
|
||||
-r PDP-8 format
|
||||
-s PDP-11 format
|
||||
-t 18b format
|
||||
|
||||
The TC08 controller is a data-only simulator; the timing and mark
|
||||
track, and block header and trailer, are not stored. Thus, the WRITE
|
||||
TIMING AND MARK TRACK function is not supported; the READ ALL function
|
||||
always returns the hardware standard block header and trailer; and the
|
||||
WRITE ALL function dumps non-data words into the bit bucket.
|
||||
|
||||
The DECtape controller implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
DTSA 12 status register A
|
||||
DTSB 12 status register B
|
||||
INT 1 interrupt pending flag
|
||||
ENB 1 interrupt enable flag
|
||||
DTF 1 DECtape flag
|
||||
ERF 1 error flag
|
||||
CA 12 current address (memory location 7754)
|
||||
WC 12 word count (memory location 7755)
|
||||
LTIME 31 time between lines
|
||||
DCTIME 31 time to decelerate to a full stop
|
||||
SUBSTATE 2 read/write command substate
|
||||
POS[0:7] 32 position, in lines, units 0-7
|
||||
STATT[0:7] 31 unit state, units 0-7
|
||||
STOP_OFFR 1 stop on off-reel error
|
||||
|
||||
It is critically important to maintain certain timing relationships
|
||||
among the DECtape parameters, or the DECtape simulator will fail to
|
||||
operate correctly.
|
||||
|
||||
- LTIME must be at least 6
|
||||
- DCTIME needs to be at least 100 times LTIME
|
||||
|
||||
Acceleration time is set to 75% of deceleration time.
|
||||
|
||||
2.8 TM8E Magnetic Tape (MT)
|
||||
|
||||
Magnetic tape options include the ability to make units write enabled or
|
||||
or write locked.
|
||||
|
||||
SET MTn LOCKED set unit n write locked
|
||||
SET MTn WRITEENABLED set unit n write enabled
|
||||
|
||||
Units can also be set ENABLED or DISABLED.
|
||||
|
||||
The magnetic tape controller implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
CMD 12 command
|
||||
FNC 12 function
|
||||
CA 12 memory address
|
||||
WC 12 word count
|
||||
DB 12 data buffer
|
||||
STA 12 main status
|
||||
STA2 6 secondary status
|
||||
DONE 1 device done flag
|
||||
INT 1 interrupt pending flag
|
||||
STOP_IOE 1 stop on I/O error
|
||||
TIME 24 record delay
|
||||
UST[0:7] 24 unit status, units 0-7
|
||||
POS[0:7] 32 position, units 0-7
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error processed as
|
||||
|
||||
not attached tape not ready; if STOP_IOE, stop
|
||||
|
||||
end of file bad tape
|
||||
|
||||
OS I/O error parity error; if STOP_IOE, stop
|
||||
|
||||
2.9 Symbolic Display and Input
|
||||
|
||||
The PDP-8 simulator implements symbolic display and input. Display is
|
||||
controlled by command line switches:
|
||||
|
||||
-a display as ASCII character
|
||||
-c display as (sixbit) character string
|
||||
-t display as (TSS/8 sixbit) character string
|
||||
-m display instruction mnemonics
|
||||
|
||||
Input parsing is controlled by the first character typed in or by command
|
||||
line switches:
|
||||
|
||||
' or -a ASCII character
|
||||
" or -c two character sixbit string
|
||||
# or -t two character TSS/8 sixbit string
|
||||
alphabetic instruction mnemonic
|
||||
numeric octal number
|
||||
|
||||
Instruction input uses standard PDP-8 assembler syntax. There are four
|
||||
instruction classes: memory reference, IOT, field change, and operate.
|
||||
|
||||
Memory reference instructions have the format
|
||||
|
||||
memref {I} {C/Z} address
|
||||
|
||||
where I signifies indirect, C a current page reference, and Z a zero page
|
||||
reference. The address is an octal number in the range 0 - 07777; if C or
|
||||
Z is specified, the address is a page offset in the range 0 - 177. Normally,
|
||||
C is not needed; the simulator figures out from the address what mode to use.
|
||||
However, when referencing memory outside the CPU (eg, disks), there is no
|
||||
valid PC, and C must be used to specify current page addressing.
|
||||
|
||||
IOT instructions consist of single mnemonics, eg, KRB, TLS. IOT instructions
|
||||
may be or'd together
|
||||
|
||||
iot iot iot...
|
||||
|
||||
The simulator does not check the legality of the proposed combination. IOT's
|
||||
for which there is no opcode may be specified as IOT n, where n is an octal
|
||||
number in the range 0 - 0777.
|
||||
|
||||
Field change instructions (CIF, CDF) have the format
|
||||
|
||||
fldchg field
|
||||
|
||||
where field is an octal number in the range 0 - 7. Field change instructions
|
||||
may be or'd together.
|
||||
|
||||
Operate instructions have the format
|
||||
|
||||
opr opr opr...
|
||||
|
||||
The simulator does not check the legality of the proposed combination. EAE
|
||||
mode A and B mnemonics may be specified regardless of the EAE mode. The
|
||||
operands for MUY and DVI must be deposited explicitly.
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp8_mt.c: PDP-8 magnetic tape simulator
|
||||
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
mt TM8E/TU10 magtape
|
||||
|
||||
16-Feb-06 RMS Added tape capacity checking
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
18-Mar-05 RMS Added attached test to detach routine
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
|
@ -204,6 +205,8 @@ MTAB mt_mod[] = {
|
|||
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", &mt_vlock },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "CAPACITY", "CAPACITY",
|
||||
&sim_tape_set_capac, &sim_tape_show_capac, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO",
|
||||
&set_dev, &show_dev, NULL },
|
||||
{ 0 }
|
||||
|
@ -369,6 +372,7 @@ t_stat mt_svc (UNIT *uptr)
|
|||
{
|
||||
int32 f, i, p, u, wc, xma;
|
||||
t_mtrlnt tbc, cbc;
|
||||
t_bool passed_eot;
|
||||
uint16 c, c1, c2;
|
||||
t_stat st, r = SCPE_OK;
|
||||
|
||||
|
@ -397,6 +401,7 @@ if ((uptr->flags & UNIT_ATT) == 0) { /* if not attached */
|
|||
return IORETURN (mt_stopioe, SCPE_UNATT);
|
||||
}
|
||||
|
||||
passed_eot = sim_tape_eot (uptr); /* passed eot? */
|
||||
switch (f) { /* case on function */
|
||||
|
||||
case FN_READ: /* read */
|
||||
|
@ -460,7 +465,7 @@ switch (f) { /* case on function */
|
|||
r = mt_map_err (uptr, st); /* map error */
|
||||
break; /* stop */
|
||||
}
|
||||
} while (mt_wc != 0);
|
||||
} while ((mt_wc != 0) && (passed_eot || !sim_tape_eot (uptr)));
|
||||
break;
|
||||
|
||||
case FN_SPACER: /* space reverse */
|
||||
|
@ -474,6 +479,8 @@ switch (f) { /* case on function */
|
|||
break;
|
||||
} /* end case */
|
||||
|
||||
if (!passed_eot && sim_tape_eot (uptr)) /* just passed EOT? */
|
||||
uptr->USTAT = uptr->USTAT | STA_EOT;
|
||||
mt_cu = (mt_cu & ~CU_EMA) | ((xma >> (12 - CU_V_EMA)) & CU_EMA);
|
||||
mt_ca = xma & 07777; /* update mem addr */
|
||||
mt_set_done (); /* set done */
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
rf RF08 fixed head disk
|
||||
|
||||
15-May-06 RMS Fixed bug in autosize attach (reported by Dave Gesswein)
|
||||
07-Jan-06 RMS Fixed unaligned register access bug (found by Doug Carman)
|
||||
04-Jan-04 RMS Changed sim_fsize calling sequence
|
||||
26-Oct-03 RMS Cleaned up buffer copy code
|
||||
|
@ -413,18 +414,15 @@ t_stat rf_attach (UNIT *uptr, char *cptr)
|
|||
{
|
||||
uint32 sz, p;
|
||||
uint32 ds_bytes = RF_DKSIZE * sizeof (int16);
|
||||
t_stat r;
|
||||
|
||||
r = attach_unit (uptr, cptr);
|
||||
if (r != SCPE_OK) return r;
|
||||
if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize (uptr->fileref))) {
|
||||
if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize_name (cptr))) {
|
||||
p = (sz + ds_bytes - 1) / ds_bytes;
|
||||
if (p >= RF_NUMDK) p = RF_NUMDK - 1;
|
||||
uptr->flags = (uptr->flags & ~UNIT_PLAT) |
|
||||
(p << UNIT_V_PLAT);
|
||||
}
|
||||
uptr->capac = UNIT_GETP (uptr->flags) * RF_DKSIZE;
|
||||
return SCPE_OK;
|
||||
return attach_unit (uptr, cptr);
|
||||
}
|
||||
|
||||
/* Change disk size */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp8_rx.c: RX8E/RX01, RX28/RX02 floppy disk simulator
|
||||
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
rx RX8E/RX01, RX28/RX02 floppy disk
|
||||
|
||||
15-May-06 RMS Fixed bug in autosize attach (reported by Dave Gesswein)
|
||||
04-Jan-04 RMS Changed sim_fsize calling sequence
|
||||
05-Nov-03 RMS Fixed bug in RX28 read status (found by Charles Dickman)
|
||||
26-Oct-03 RMS Cleaned up buffer copy code, fixed double density write
|
||||
|
@ -579,16 +580,13 @@ return SCPE_OK;
|
|||
t_stat rx_attach (UNIT *uptr, char *cptr)
|
||||
{
|
||||
uint32 sz;
|
||||
t_stat r;
|
||||
|
||||
r = attach_unit (uptr, cptr);
|
||||
if (r != SCPE_OK) return r;
|
||||
if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize (uptr->fileref))) {
|
||||
if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize_name (cptr))) {
|
||||
if (sz > RX_SIZE) uptr->flags = uptr->flags | UNIT_DEN;
|
||||
else uptr->flags = uptr->flags & ~UNIT_DEN;
|
||||
}
|
||||
uptr->capac = (uptr->flags & UNIT_DEN)? RX2_SIZE: RX_SIZE;
|
||||
return SCPE_OK;
|
||||
return attach_unit (uptr, cptr);
|
||||
}
|
||||
|
||||
/* Set size routine */
|
||||
|
@ -613,9 +611,9 @@ for (i = 0; i < RX_NUMDR; i++) {
|
|||
if (rx_unit[i].flags & UNIT_ATT) return SCPE_ALATT;
|
||||
}
|
||||
for (i = 0; i < RX_NUMDR; i++) {
|
||||
rx_unit[i].flags = rx_unit[i].flags & ~(UNIT_DEN | UNIT_AUTO);
|
||||
rx_unit[i].capac = RX_SIZE;
|
||||
if (val) rx_unit[i].flags = rx_unit[i].flags | UNIT_AUTO;
|
||||
if (val) rx_unit[i].flags = rx_unit[i].flags | UNIT_DEN | UNIT_AUTO;
|
||||
else rx_unit[i].flags = rx_unit[i].flags & ~(UNIT_DEN | UNIT_AUTO);
|
||||
rx_unit[i].capac = val? RX2_SIZE: RX_SIZE;
|
||||
}
|
||||
rx_28 = val;
|
||||
return SCPE_OK;
|
||||
|
|
559
SDS/sds_doc.txt
559
SDS/sds_doc.txt
|
@ -1,559 +0,0 @@
|
|||
To: Users
|
||||
From: Bob Supnik
|
||||
Subj: SDS 940 Simulator Usage
|
||||
Date: 01-Jul-2005
|
||||
|
||||
COPYRIGHT NOTICE
|
||||
|
||||
The following copyright notice applies to both the SIMH source and binary:
|
||||
|
||||
Original code published in 1993-2005, written by Robert M Supnik
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
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 memorandum documents the SDS 940 simulator.
|
||||
|
||||
|
||||
1. Simulator Files
|
||||
|
||||
sim/ scp.h
|
||||
sim_console.h
|
||||
sim_defs.h
|
||||
sim_fio.h
|
||||
sim_rev.h
|
||||
sim_sock.h
|
||||
sim_tape.h
|
||||
sim_timer.h
|
||||
sim_tmxr.h
|
||||
scp.c
|
||||
sim_console.c
|
||||
sim_fio.c
|
||||
sim_sock.c
|
||||
sim_tape.c
|
||||
sim_timer.c
|
||||
sim_tmxr.c
|
||||
|
||||
sim/sds/ sds_defs.h
|
||||
sds_cpu.c
|
||||
sds_drm.c
|
||||
sds_dsk.c
|
||||
sds_io.c
|
||||
sds_lp.c
|
||||
sds_mt.c
|
||||
sds_mux.c
|
||||
sds_rad.c
|
||||
sds_stddev.c
|
||||
sds_sys.c
|
||||
|
||||
2. SDS 940 Features
|
||||
|
||||
The SDS-940 simulator is configured as follows:
|
||||
|
||||
device simulates
|
||||
name(s)
|
||||
|
||||
CPU SDS-940 CPU with 16KW to 64KW of memory
|
||||
CHAN I/O channels
|
||||
PTR paper tape reader
|
||||
PTP paper tape punch
|
||||
TTI console input
|
||||
TTO console output
|
||||
LPT line printer
|
||||
RTC real-time clock
|
||||
MUX terminal multiplexor
|
||||
DRM Project Genie drum
|
||||
RAD fixed head disk
|
||||
DSK 9164/9165 rapid access (moving head) disk
|
||||
MT magnetic tape
|
||||
|
||||
Most devices can be disabled or enabled with the SET <dev> DISABLED and
|
||||
SET <dev> ENABLED commands, respectively.
|
||||
|
||||
2.1 CPU
|
||||
|
||||
The CPU options set the size of main memory and the configuration of
|
||||
peripherals.
|
||||
|
||||
SET CPU 16K set memory size = 16KW
|
||||
SET CPU 32K set memory size = 32KW
|
||||
SET CPU 48K set memory size = 48KW
|
||||
SET CPU 64K set memory size = 64KW
|
||||
SET CPU GENIE enable DRM, set terminal mux
|
||||
to GENIE mode
|
||||
SET CPU SDS disable DRM, set terminal mux
|
||||
to SDS mode
|
||||
|
||||
If memory size is being reduced, and the memory being truncated contains
|
||||
non-zero data, the simulator asks for confirmation. Data in the truncated
|
||||
portion of memory is lost. Initial memory size is 64KW.
|
||||
|
||||
CPU registers include the visible state of the processor as well as the
|
||||
control registers for the interrupt system.
|
||||
|
||||
name size comments
|
||||
|
||||
P 14 program counter
|
||||
A 24 accumulator A
|
||||
B 24 accumulator B
|
||||
X 24 index register
|
||||
OV 1 overflow indicator
|
||||
EM2 3 memory extension, quadrant 2
|
||||
EM3 3 memory extension, quadrant 3
|
||||
RL1 24 user relocation register 1
|
||||
RL2 24 user relocation register 2
|
||||
RL4 12 kernel relocation register
|
||||
NML 1 normal mode flag
|
||||
USR 1 user mode flag
|
||||
MONUSR 1 monitor-to-user trap enable
|
||||
ION 1 interrupt enable
|
||||
INTDEF 1 interrupt defer
|
||||
INTREQ 32 interrupt request flags
|
||||
APIACT 5 highest active API level
|
||||
APIREQ 5 highest requesting API level
|
||||
XFRREQ 32 device transfer request flags
|
||||
BPT 4 breakpoint switches
|
||||
ALERT 6 outstanding alert number
|
||||
STOP_INVINS 1 stop on invalid instruction
|
||||
STOP_INVDEV 1 stop on invalid device number
|
||||
STOP_INVIOP 1 stop on invalid I/O operation
|
||||
INDLIM 8 maximum indirect nesting depth
|
||||
EXULIM 8 maximum execute nesting depth
|
||||
PCQ[0:63] 14 P prior to last branch or interrupt;
|
||||
most recent P change first
|
||||
WRU 8 interrupt character
|
||||
|
||||
The CPU can maintain a history of the most recently executed instructions.
|
||||
This is controlled by the SET CPU HISTORY and SHOW CPU HISTORY commands:
|
||||
|
||||
SET CPU HISTORY clear history buffer
|
||||
SET CPU HISTORY=0 disable history
|
||||
SET CPU HISTORY=n enable history, length = n
|
||||
SHOW CPU HISTORY print CPU history
|
||||
SHOW CPU HISTORY=n print first n entries of CPU history
|
||||
|
||||
The maximum length for the history is 65536 entries.
|
||||
|
||||
2.2 Channels (CHAN)
|
||||
|
||||
The SDS 940 has up to eight I/O channels, designated W, Y, C, D, E, F, G,
|
||||
and H. W, Y, C, and D are time-multiplexed communications channels (TMCC);
|
||||
E, F, G, and H are direct access communications channels (DACC). Unlike
|
||||
real SDS 940 channels, the simulated channels handle 6b, 12b, and 24b transfers
|
||||
simultaneously. The association between a device and a channel is displayed
|
||||
by the SHOW <dev> CHAN command:
|
||||
|
||||
SIM> SHOW LPT CHAN
|
||||
channel=W
|
||||
|
||||
The user can change the association with the SET <dev> CHAN=<chan> command,
|
||||
where <chan> is a channel letter:
|
||||
|
||||
SIM> SET LPT CHAN=E
|
||||
SIM> SHOW LPT CHAN
|
||||
channel=E
|
||||
|
||||
Each channel has nine registers. The registers are arrays, with entry [0]
|
||||
for channel W, entry [1] for channel Y, etc.
|
||||
|
||||
name size comments
|
||||
|
||||
UAR[0:7] 6 unit address register
|
||||
WCR[0:7] 15 word count register
|
||||
MAR[0:7] 16 memory address register
|
||||
DCR[0:7] 6 data chaining register
|
||||
WAR[0:7] 24 word assembly register
|
||||
CPW[0:7] 2 characters per word
|
||||
CNT[0:7] 3 character count
|
||||
MODE[0:7] 12 channel mode (from EOM instruction)
|
||||
FLAG[0:7] 9 channel flags
|
||||
|
||||
The user can display all the registers in a channel with the command:
|
||||
|
||||
SHOW CHAN channel-letter
|
||||
|
||||
2.3 Console Input (TTI)
|
||||
|
||||
The console input (TTI) polls the console keyboard for input. It
|
||||
implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 6 data buffer
|
||||
XFR 1 transfer ready flag
|
||||
POS 32 number of characters input
|
||||
TIME 24 polling interval
|
||||
|
||||
By default, the console input is assigned to channel W.
|
||||
|
||||
2.4 Console Output (TTO)
|
||||
|
||||
The console output (TTO) writes to the simulator console window. It
|
||||
implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 6 data buffer
|
||||
XFR 1 transfer ready flag
|
||||
POS 32 number of characters input
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
|
||||
By default, the console output is assigned to channel W.
|
||||
|
||||
2.5 Paper Tape Reader (PTR)
|
||||
|
||||
The paper tape reader (PTR) reads data from a disk file. The POS
|
||||
register specifies the number of the next data item to be read. Thus,
|
||||
by changing POS, the user can backspace or advance the reader.
|
||||
|
||||
The paper tape reader implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 6 data buffer
|
||||
XFR 1 transfer ready flag
|
||||
SOR 1 start of record flag
|
||||
CHAN 4 active channel
|
||||
POS 32 number of characters input
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of tape
|
||||
|
||||
end of file 1 report error and stop
|
||||
0 out of tape
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
By default, the paper tape reader is assigned to channel W.
|
||||
|
||||
2.6 Paper Tape Punch (PTP)
|
||||
|
||||
The paper tape punch (PTP) writes data to a disk file. The POS
|
||||
register specifies the number of the next data item to be written.
|
||||
Thus, by by changing POS, the user can backspace or advance the punch.
|
||||
|
||||
The paper tape punch implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF 6 data buffer
|
||||
XFR 1 transfer ready flag
|
||||
LDR 1 punch leader flag
|
||||
CHAN 4 active channel
|
||||
POS 32 number of characters input
|
||||
TIME 24 time from I/O initiation to interrupt
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of tape
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
By default, the paper tape punch is assigned to channel W.
|
||||
|
||||
2.7 Line Printer (LPT)
|
||||
|
||||
The line printer (LPT) writes data to a disk file. The POS register
|
||||
specifies the number of the next data item to be written. Thus,
|
||||
by changing POS, the user can backspace or advance the printer.
|
||||
|
||||
The line printer implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF[0:131] 8 data buffer
|
||||
BPTR 8 buffer pointer
|
||||
XFR 1 transfer ready flag
|
||||
ERR 1 error flag
|
||||
CHAN 4 active channel
|
||||
CCT[0:131] 8 carriage control tape
|
||||
CCTP 8 pointer into carriage control tape
|
||||
CCTL 8 length of carriage control tape
|
||||
SPCINST 24 spacing instruction
|
||||
POS 32 number of characters input
|
||||
CTIME 24 intercharacter time
|
||||
PTIME 24 print time
|
||||
STIME 24 space time
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 out of paper
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
By default, the line printer is assigned to channel W.
|
||||
|
||||
2.8 Real-Time Clock (RTC)
|
||||
|
||||
The real-time clock (RTC) frequency can be adjusted as follows:
|
||||
|
||||
SET RTC 60HZ set frequency to 60Hz
|
||||
SET RTC 50HZ set frequency to 50Hz
|
||||
|
||||
The default is 60Hz.
|
||||
|
||||
The clock implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
PIE 1 interrupt enable
|
||||
TIME 24 tick interval
|
||||
|
||||
The real-time clock autocalibrates; the clock interval is adjusted up or
|
||||
down so that the clock tracks actual elapsed time.
|
||||
|
||||
2.9 Terminal Multiplexor (MUX)
|
||||
|
||||
The terminal multiplexor provides 32 asynchronous interfaces. In Genie
|
||||
mode, the interfaces are hard-wired; in SDS mode, they implement modem
|
||||
control. The multiplexor has two controllers: MUX for the scanner, and
|
||||
MUXL for the individual lines. The terminal multiplexor performs input
|
||||
and output through Telnet sessions connected to a user-specified port.
|
||||
The ATTACH command specifies the port to be used:
|
||||
|
||||
ATTACH MUX <port> set up listening port
|
||||
|
||||
where port is a decimal number between 1 and 65535 that is not being used
|
||||
for other TCP/IP activities.
|
||||
|
||||
Each line (each unit of MUXL) supports one option: UC, when set, causes
|
||||
lower case input characters to be automatically converted to upper case.
|
||||
In addition, each line supports output logging. The SET MUXLn LOG command
|
||||
enables logging on a line:
|
||||
|
||||
SET MUXLn filename log output of line n to filename
|
||||
|
||||
The SET MUXLn NOLOG command disables logging and closes the open log
|
||||
file, if any.
|
||||
|
||||
Once MUX is attached and the simulator is running, the multiplexor listens
|
||||
for connections on the specified port. It assumes that the incoming
|
||||
connections are Telnet connections. The connections remain open until
|
||||
disconnected either by the Telnet client, a SET MUX DISCONNECT command,
|
||||
or a DETACH MUX command.
|
||||
|
||||
The SHOW MUX CONNECTIONS command displays the current connections to the
|
||||
extra terminals. The SHOW MUX STATISTICS command displays statistics for
|
||||
active connections. The SET MUXLn DISCONNECT command disconnects line n.
|
||||
|
||||
The controller (MUX) implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
STA[0:31] 6 status, lines 0 to 31
|
||||
RBUF[0:31] 8 receive buffer, lines 0 to 31
|
||||
XBUF[0:31] 8 transmit buffer, lines 0 to 31
|
||||
FLAGS[0:127] 1 line flags, 0 to 3 for line 0,
|
||||
4 to 7 for line 1, etc
|
||||
SCAN 7 scanner current flag number
|
||||
SLCK 1 scanner locked flag
|
||||
TPS 8 character polls per second
|
||||
|
||||
The lines (MUXL) implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
TIME[0:31] 24 transmit time, lines 0 to 31
|
||||
|
||||
The terminal multiplexor does not support save and restore. All open
|
||||
connections are lost when the simulator shuts down or MUX is detached.
|
||||
|
||||
2.10 Project Genie Drum (DRM)
|
||||
|
||||
The Project Genie drum (DRM) implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
DA 19 drum address
|
||||
CA 16 core address
|
||||
WC 14 word count
|
||||
PAR 12 cumulative sector parity
|
||||
RW 1 read/write flag
|
||||
ERR 1 error flag
|
||||
STA 2 drum state
|
||||
FTIME 24 channel program fetch time
|
||||
XTIME 24 interword transfer time
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 drum not ready
|
||||
|
||||
Drum data files are buffered in memory; therefore, end of file and OS
|
||||
I/O errors cannot occur. Unlike conventional SDS 940 devices, the Project
|
||||
Genie drum does not use a channel.
|
||||
|
||||
2.11 Rapid Access (fixed head) Disk (RAD)
|
||||
|
||||
The rapid access disk (RAD) implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
DA 15 disk address
|
||||
SA 6 sector word address
|
||||
BP 1 sector byte pointer
|
||||
XFR 1 data transfer flag
|
||||
NOBD 1 inhibit increment across track
|
||||
ERR 1 error flag
|
||||
CHAN 4 active channel
|
||||
PROT 8 write protect switches
|
||||
TIME 24 interval between halfword transfers
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 disk not ready
|
||||
|
||||
The rapid access disk is buffered in memory; end of file and OS I/O errors
|
||||
cannot occur. By default, the rapid access disk is assigned to channel E.
|
||||
|
||||
2.12 Moving Head Disk (DSK)
|
||||
|
||||
DSK options include the ability to make the drive write enabled or write
|
||||
locked:
|
||||
|
||||
SET RAD LOCKED set write locked
|
||||
SET RAD WRITEENABLED set write enabled
|
||||
|
||||
The moving head disk implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF[0:63] 8 transfer buffer
|
||||
BPTR 9 buffer pointer
|
||||
BLNT 9 buffer length
|
||||
DA 21 disk address
|
||||
INST 24 disk instruction
|
||||
XFR 1 data transfer flag
|
||||
ERR 1 error flag
|
||||
CHAN 4 active channel
|
||||
WTIME 24 interval between character transfers
|
||||
STIME 24 seek interval
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error STOP_IOE processed as
|
||||
|
||||
not attached 1 report error and stop
|
||||
0 disk not ready
|
||||
|
||||
end of file x assume rest of disk is zero
|
||||
|
||||
OS I/O error x report error and stop
|
||||
|
||||
|
||||
By default, the moving head disk is assigned to channel F.
|
||||
|
||||
2.13 Magnetic Tape (MT)
|
||||
|
||||
MT options include the ability to make units write enabled or write locked.
|
||||
|
||||
SET MTn LOCKED set unit n write locked
|
||||
SET MTn WRITEENABLED set unit n write enabled
|
||||
|
||||
Units can also be set ENABLED or DISABLED.
|
||||
|
||||
The magnetic tape implements these registers:
|
||||
|
||||
name size comments
|
||||
|
||||
BUF[0:131071] 8 transfer buffer
|
||||
BPTR 18 buffer pointer
|
||||
BLNT 18 buffer length
|
||||
XFR 1 data transfer flag
|
||||
CHAN 4 active channel
|
||||
INST 24 magtape instruction
|
||||
EOF 1 end-of-file flag
|
||||
GAP 1 inter-record gap flag
|
||||
SKIP 1 skip data flag
|
||||
CTIME 24 interval between character transfers
|
||||
GTIME 24 gap interval
|
||||
POS[0:7] 32 position, drives 0:7
|
||||
STOP_IOE 1 stop on I/O error
|
||||
|
||||
Error handling is as follows:
|
||||
|
||||
error processed as
|
||||
|
||||
not attached tape not ready; if STOP_IOE, stop
|
||||
|
||||
end of file end of tape
|
||||
|
||||
OS I/O error end of tape; if STOP_IOE, stop
|
||||
|
||||
By default, the magnetic tape is assigned to channel W.
|
||||
|
||||
2.13 Symbolic Display and Input
|
||||
|
||||
The SDS 940 simulator implements symbolic display and input. Display is
|
||||
controlled by command line switches:
|
||||
|
||||
-a display as ASCII character
|
||||
-c display as four character SDS string
|
||||
-m display instruction mnemonics
|
||||
|
||||
Input parsing is controlled by the first character typed in or by command
|
||||
line switches:
|
||||
|
||||
' or -a ASCII character
|
||||
" or -c four character SDS string
|
||||
alphabetic instruction mnemonic
|
||||
numeric octal number
|
||||
|
||||
Instruction input uses (more or less) standard SDS 940 assembler syntax.
|
||||
There are eight instruction classes:
|
||||
|
||||
class operands examples comments
|
||||
|
||||
no operand none EIR
|
||||
POP (prog op) op,addr{,tag} POP 66,100
|
||||
I/O addr{,tag} EOM 1266
|
||||
mem reference addr{,tag} LDA 400,2
|
||||
STA* 300 indirect addr
|
||||
reg change op op op... CLA CLB opcodes OR
|
||||
shift cnt{,tag} LSH 10
|
||||
chan command chan ALC W
|
||||
chan test chan CAT Y
|
||||
|
||||
All numbers are octal. Channel designators can be alphabetic (W, Y, C, D, E,
|
||||
F, G, H) or numeric (0-7). Tags must be 0-7, with 2 indicating indexing.
|
15
SDS/sds_mt.c
15
SDS/sds_mt.c
|
@ -1,6 +1,6 @@
|
|||
/* sds_mt.c: SDS 940 magnetic tape simulator
|
||||
|
||||
Copyright (c) 2001-2005, Robert M. Supnik
|
||||
Copyright (c) 2001-2006, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
mt 7 track magnetic tape
|
||||
|
||||
16-Feb-06 RMS Added tape capacity checking
|
||||
07-Dec-04 RMS Added read-only file support
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
28-Mar-03 RMS Added multiformat support
|
||||
|
@ -154,6 +155,8 @@ MTAB mt_mod[] = {
|
|||
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "CAPACITY", "CAPACITY",
|
||||
&sim_tape_set_capac, &sim_tape_show_capac, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "CHANNEL", "CHANNEL",
|
||||
&set_chan, &show_chan, NULL },
|
||||
{ 0 }
|
||||
|
@ -333,7 +336,12 @@ if ((uptr->flags & UNIT_ATT) == 0) { /* attached? */
|
|||
}
|
||||
if (mt_inst & CHC_REV) /* reverse? */
|
||||
st = sim_tape_rdrecr (uptr, mtxb, &tbc, MT_MAXFR); /* read rec rev */
|
||||
else st = sim_tape_rdrecf (uptr, mtxb, &tbc, MT_MAXFR); /* no, fwd */
|
||||
else { /* no, fwd */
|
||||
t_bool passed_eot = sim_tape_eot (uptr); /* passed EOT? */
|
||||
st = sim_tape_rdrecf (uptr, mtxb, &tbc, MT_MAXFR);
|
||||
if (!passed_eot && sim_tape_eot (uptr)) /* just passed eot? */
|
||||
uptr->eotf = 1;
|
||||
}
|
||||
if (st == MTSE_TMK) { /* tape mark? */
|
||||
mt_eof = 1; /* set eof flag */
|
||||
mtxb[0] = mtxb[1] = 017; /* EOR char */
|
||||
|
@ -390,10 +398,13 @@ if (dev & DEV_MTS) { /* erase? */
|
|||
st = sim_tape_wreom (uptr); /* write eom */
|
||||
}
|
||||
else {
|
||||
t_bool passed_eot = sim_tape_eot (uptr); /* passed EOT? */
|
||||
if ((mt_bptr == 1) && (mtxb[0] == 017) && /* wr eof? */
|
||||
((mt_inst & 01670) == 00050))
|
||||
st = sim_tape_wrtmk (uptr); /* write tape mark */
|
||||
else st = sim_tape_wrrecf (uptr, mtxb, mt_bptr); /* write record */
|
||||
if (!passed_eot && sim_tape_eot (uptr)) /* just passed EOT? */
|
||||
uptr->eotf = 1;
|
||||
}
|
||||
mt_bptr = 0;
|
||||
if (st != MTSE_OK) mt_set_err (uptr); /* error? */
|
||||
|
|
|
@ -11,6 +11,49 @@
|
|||
11. CIS: CMPP3/CMPP4 using wrong arguments to ReadDstr.
|
||||
12. CPU, OCTA: CVTfi with integer overflow not setting trap if PSW<iv> = 1.
|
||||
13. STDDEV: read of ICR was missing the call parameter.
|
||||
14. ACBD/G: testing wrong operand register to get limit sign.
|
||||
15. CPU: faults not clearing PSL<tp>.
|
||||
16. ADAWI: register mode implemented incorrectly.
|
||||
17. MOVTC: condition codes not preserved through page fault.
|
||||
18. MOVTUC: condition codes not preserved through page fault.
|
||||
19. MOVTUC: escape tested against untranslated rather than translated character.
|
||||
20. CVTPT: condition code and decimal overflow calculation incorrect.
|
||||
21. CVTPS: condition code and decimal overflow calculation incorrect.
|
||||
22. CVTPL: if destination is register, result is stored after register updates.
|
||||
23. CVTPL: integer overflow set <C> rather than <V>.
|
||||
24. all decimal string: 11/780 does not validate characters in decimal strings.
|
||||
25. EDITPC: condition codes not preserved through page fault.
|
||||
26. EDITPC EO$INSERT: inserts sign instead of fill.
|
||||
27. EDITPC EO$BLANK_ZERO: address off by one.
|
||||
28. EDITPC EO$BLANK_ZERO: not testing for <C> set.
|
||||
29. EDITPC EO$LOAD_PLUS: not skipping character if test fails.
|
||||
30. EDITPC EO$LOAD_MINUS: not skipping character if test fails.
|
||||
31. Compatibility mode: SXT not implemented.
|
||||
32. Compatibility mode: XOR operands fetched in wrong order.
|
||||
33. MNEGH: condition codes set from original sign.
|
||||
34. MNEGH: <C> not cleared.
|
||||
35. H_floating quad precision integer routines (add, inc, neg): carry propagation incorrect.
|
||||
36. H_floating packup routines: test for zero used exponent not fraction.
|
||||
37. MULH: carries out of floating accumulator lost.
|
||||
38. DIVH: stores wrong operand as result.
|
||||
39. POLYF/D/G: truncation after add not needed.
|
||||
40. POLYF/D/G: early SRM requires truncation to 31b/63b, not 32b/64b.
|
||||
41. POLYF/D/G/H: exits too early if argument is zero.
|
||||
42. POLYD/G/H: calculates address of residual pointer result incorrectly.
|
||||
43. POLYD/G: performs single precision rather than double precision multiply.
|
||||
44. POLYH: fails to truncate intermediate result from 128b to 127b.
|
||||
45. POLYF/D/G/H: internal add routine must test fraction rather than exponent to
|
||||
detect zero, POLYx can create "denormalized" intermediate result.
|
||||
46. EMODH: concatenate 16b of extension operand instead of 15b.
|
||||
47. Specifier flows: modify flows testing for read access rather than write access.
|
||||
48. Quad/octa writes: wrong address reported on faulting cross-page writes.
|
||||
49. Memory management: 11/780 implements access control test on first level PTE's.
|
||||
50. LDPCTX: 11/780 implements mbz tests on PCB fields.
|
||||
51. LDPCTX/MTPR: 11/780 validity checks PCBB, SCBB, SBR, SLR, P0BR, P0LR, P1BR, P1LR.
|
||||
52. TMR: tmr_inc not updated in standard (100Hz) mode.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* vax780_defs.h: VAX 780 model-specific definitions file
|
||||
|
||||
Copyright (c) 2004-2005, Robert M Supnik
|
||||
Copyright (c) 2004-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -23,6 +23,9 @@
|
|||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
17-May-2006 RMS Added CR11/CD11 support (from John Dundas)
|
||||
10-May-2006 RMS Added model-specific reserved operand check macros
|
||||
|
||||
This file covers the VAX 11/780, the first VAX.
|
||||
|
||||
System memory map
|
||||
|
@ -113,6 +116,16 @@
|
|||
#define MT_SBIQC 54 /* SBI timeout clear */
|
||||
#define MT_MBRK 60 /* microbreak */
|
||||
|
||||
/* Machine specific reserved operand tests */
|
||||
|
||||
#define ML_PA_TEST(r) if ((r) & 0xC0000003) RSVD_OPND_FAULT
|
||||
#define ML_LR_TEST(r) if ((uint32)(r) > 0x200000) RSVD_OPND_FAULT
|
||||
#define ML_BR_TEST(r) if ((((r) & 0xC0000000) != 0x80000000) || \
|
||||
((r) & 0x00000003)) RSVD_OPND_FAULT
|
||||
#define LP_AST_TEST(r) if ((r) > AST_MAX) RSVD_OPND_FAULT
|
||||
#define LP_MBZ84_TEST(r) if ((r) & 0xF8C00000) RSVD_OPND_FAULT
|
||||
#define LP_MBZ92_TEST(r) if ((r) & 0x7FC00000) RSVD_OPND_FAULT
|
||||
|
||||
/* Memory */
|
||||
|
||||
#define MAXMEMWIDTH 23 /* max mem, MS780C */
|
||||
|
@ -265,6 +278,8 @@ typedef struct {
|
|||
#define IOLN_TQ 004
|
||||
#define IOBA_XU (IOPAGEBASE + 014510) /* DEUNA/DELUA */
|
||||
#define IOLN_XU 010
|
||||
#define IOBA_CR (IOPAGEBASE + 017160) /* CD/CR/CM */
|
||||
#define IOLN_CR 010
|
||||
#define IOBA_RX (IOPAGEBASE + 017170) /* RX11 */
|
||||
#define IOLN_RX 004
|
||||
#define IOBA_RY (IOPAGEBASE + 017170) /* RXV21 */
|
||||
|
@ -295,6 +310,7 @@ typedef struct {
|
|||
#define INT_V_LPT 0 /* BR4 */
|
||||
#define INT_V_PTR 1
|
||||
#define INT_V_PTP 2
|
||||
#define INT_V_CR 3
|
||||
|
||||
#define INT_DZRX (1u << INT_V_DZRX)
|
||||
#define INT_DZTX (1u << INT_V_DZTX)
|
||||
|
@ -305,9 +321,10 @@ typedef struct {
|
|||
#define INT_TS (1u << INT_V_TS)
|
||||
#define INT_RY (1u << INT_V_RY)
|
||||
#define INT_XU (1u << INT_V_XU)
|
||||
#define INT_LPT (1u << INT_V_LPT)
|
||||
#define INT_PTR (1u << INT_V_PTR)
|
||||
#define INT_PTP (1u << INT_V_PTP)
|
||||
#define INT_LPT (1u << INT_V_LPT)
|
||||
#define INT_CR (1u << INT_V_CR)
|
||||
|
||||
#define IPL_DZRX (0x15 - IPL_HMIN)
|
||||
#define IPL_DZTX (0x15 - IPL_HMIN)
|
||||
|
@ -318,9 +335,10 @@ typedef struct {
|
|||
#define IPL_TS (0x15 - IPL_HMIN)
|
||||
#define IPL_RY (0x15 - IPL_HMIN)
|
||||
#define IPL_XU (0x15 - IPL_HMIN)
|
||||
#define IPL_LPT (0x14 - IPL_HMIN)
|
||||
#define IPL_PTR (0x14 - IPL_HMIN)
|
||||
#define IPL_PTP (0x14 - IPL_HMIN)
|
||||
#define IPL_LPT (0x14 - IPL_HMIN)
|
||||
#define IPL_CR (0x14 - IPL_HMIN)
|
||||
|
||||
/* Device vectors */
|
||||
|
||||
|
@ -334,6 +352,7 @@ typedef struct {
|
|||
#define VEC_LPT 0200
|
||||
#define VEC_HK 0210
|
||||
#define VEC_TS 0224
|
||||
#define VEC_CR 0230
|
||||
#define VEC_TQ 0260
|
||||
#define VEC_RX 0264
|
||||
#define VEC_RY 0264
|
||||
|
|
1093
VAX/vax780_doc.txt
1093
VAX/vax780_doc.txt
File diff suppressed because it is too large
Load diff
250
VAX/vax780_fload.c
Normal file
250
VAX/vax780_fload.c
Normal file
|
@ -0,0 +1,250 @@
|
|||
/* vax780_fload.c: VAX780 FLOAD command
|
||||
|
||||
Copyright (c) 2006, 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 code is based on the CP/M RT11 utility, which bears the following
|
||||
copyrights:
|
||||
|
||||
copyright (c) 1980, William C. Colley, III
|
||||
|
||||
Rev. 1.2 -- Craig Davenport - Incitec Ltd (Feb 1984)
|
||||
P O Box 140
|
||||
Morningside,
|
||||
Qld 4170,
|
||||
Australia.
|
||||
-- Modified for Digital Research C compiler under CP/M-86
|
||||
-- Assebmbly language routines added for BIOS calls etc.
|
||||
|
||||
Thanks to Phil Budne for the original adaptation of RT11 to SimH.
|
||||
*/
|
||||
|
||||
#include "vax_defs.h"
|
||||
#include <ctype.h>
|
||||
|
||||
#define BLK_SIZE 256 /* RT11 block size */
|
||||
|
||||
/* Floppy disk parameters */
|
||||
|
||||
#define BPT 26 /* blocks/track */
|
||||
#define NTRACKS 77
|
||||
#define SECTOR_SKEW 2
|
||||
#define TRACK_SKEW 6
|
||||
#define TRACK_OFFSET 1 /* track 0 unused */
|
||||
|
||||
/* RT11 directory segment (2 blocks = 512 16b words) */
|
||||
|
||||
#define DS_TOTAL 0 /* segments available */
|
||||
#define DS_MAX 31 /* segment max */
|
||||
#define DS_NEXT 1 /* zero for last segment */
|
||||
#define DS_HIGHEST 2 /* only in 1st segment */
|
||||
#define DS_EXTRA 3 /* extra bytes/entry */
|
||||
#define DS_FIRST 4 /* first block */
|
||||
#define DS_ENTRIES 5 /* start of entries */
|
||||
#define DS_SIZE (2 * BLK_SIZE) /* segment size, words */
|
||||
|
||||
/* RT11 directory entry offsets */
|
||||
|
||||
#define DE_STATUS 0 /* status (odd byte) */
|
||||
#define TENTAT 001 /* tentative */
|
||||
#define EMPTY 002
|
||||
#define PERM 004
|
||||
#define ENDSEG 010 /* end of segment */
|
||||
#define DE_NAME 1 /* file name */
|
||||
#define DE_FLNT 4 /* file length */
|
||||
#define DE_SIZE 7 /* entry size in words */
|
||||
#define DE_GET_STAT(x) (((x) >> 8) & 0377)
|
||||
|
||||
extern UNIT cpu_unit;
|
||||
extern UNIT fl_unit;
|
||||
|
||||
t_bool rtfile_parse (char *pntr, uint16 *file_name);
|
||||
uint32 rtfile_lookup (uint16 *file_name, uint32 *start);
|
||||
uint32 rtfile_ator50 (uint32 ascii);
|
||||
t_bool rtfile_read (uint32 block, uint32 count, uint16 *buffer);
|
||||
uint32 rtfile_find (uint32 block, uint32 sector);
|
||||
|
||||
extern void WriteW (uint32 pa, int32 val);
|
||||
|
||||
/* FLOAD file_name {file_origin} */
|
||||
|
||||
t_stat vax780_fload (int flag, char *cptr)
|
||||
{
|
||||
char gbuf[CBUFSIZE];
|
||||
uint16 file_name[3], blkbuf[BLK_SIZE];
|
||||
t_stat r;
|
||||
uint32 i, j, start, size, origin;
|
||||
|
||||
if ((fl_unit.flags & UNIT_ATT) == 0) /* floppy attached? */
|
||||
return SCPE_UNATT;
|
||||
if (*cptr == 0) return SCPE_2FARG;
|
||||
cptr = get_glyph (cptr, gbuf, 0); /* get file name */
|
||||
if (!rtfile_parse (gbuf, file_name)) /* legal file name? */
|
||||
return SCPE_ARG;
|
||||
if ((size = rtfile_lookup (file_name, &start)) == 0) /* file on floppy? */
|
||||
return SCPE_ARG;
|
||||
if (*cptr) { /* origin? */
|
||||
origin = (uint32) get_uint (cptr, 16, MEMSIZE, &r);
|
||||
if ((r != SCPE_OK) || (origin & 1)) /* must be even */
|
||||
return SCPE_ARG;
|
||||
}
|
||||
else origin = 512; /* no, use default */
|
||||
|
||||
for (i = 0; i < size; i++) { /* loop thru blocks */
|
||||
if (!rtfile_read (start + i, 1, blkbuf)) /* read block */
|
||||
return SCPE_FMT;
|
||||
for (j = 0; j < BLK_SIZE; j++) { /* loop thru words */
|
||||
if (ADDR_IS_MEM (origin))
|
||||
WriteW (origin, blkbuf[j]);
|
||||
else return SCPE_NXM;
|
||||
origin = origin + 2;
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Parse an RT11 file name and convert it to radix-50 */
|
||||
|
||||
t_bool rtfile_parse (char *pntr, uint16 *file_name)
|
||||
{
|
||||
char c;
|
||||
uint16 d;
|
||||
uint32 i, j;
|
||||
|
||||
file_name[0] = file_name[1] = file_name[2] = 0; /* zero file name */
|
||||
for (i = 0; i < 2; i++) { /* 6 characters */
|
||||
for (j = 0; j < 3; j++) {
|
||||
c = *pntr;
|
||||
if ((c == '.') || (c == 0)) d = 0; /* fill if . or end */
|
||||
else {
|
||||
if ((d = rtfile_ator50 (c)) == 0) return FALSE;
|
||||
pntr++;
|
||||
}
|
||||
file_name[i] = (file_name[i] * 050) + d; /* merge into name */
|
||||
}
|
||||
}
|
||||
if (file_name[0] == 0) return FALSE; /* no name? lose */
|
||||
while ((c = *pntr++) != '.') { /* scan for . */
|
||||
if (c == 0) return TRUE; /* end? done */
|
||||
}
|
||||
for (i = 0; i < 3; i++) { /* 3 characters */
|
||||
c = *pntr;
|
||||
if (c == 0) d = 0; /* fill if end */
|
||||
else {
|
||||
if ((d = rtfile_ator50 (c)) == 0) return FALSE;
|
||||
pntr++;
|
||||
}
|
||||
file_name[2] = (file_name[2] * 050) + d; /* merge into ext */
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* ASCII to radix-50 conversion */
|
||||
|
||||
uint32 rtfile_ator50 (uint32 ascii)
|
||||
{
|
||||
static char *r50 = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$._0123456789";
|
||||
char *fptr;
|
||||
|
||||
ascii = toupper (ascii);
|
||||
if ((fptr = strchr (r50, toupper (ascii))) != NULL)
|
||||
return ((uint32) (fptr - r50));
|
||||
else return 0;
|
||||
}
|
||||
|
||||
/* Lookup an RT11 file name in the directory */
|
||||
|
||||
uint32 rtfile_lookup (uint16 *file_name, uint32 *start)
|
||||
{
|
||||
uint16 dirseg[DS_SIZE];
|
||||
uint32 segnum, dirent;
|
||||
|
||||
for (segnum = 1; /* loop thru segments */
|
||||
(segnum != 0) && (segnum <= DS_MAX);
|
||||
segnum = dirseg[DS_NEXT]) {
|
||||
if (!rtfile_read ((segnum * 2) + 4, 2, dirseg)) /* read segment */
|
||||
return 0; /* error? */
|
||||
*start = dirseg[DS_FIRST]; /* init file start */
|
||||
for (dirent = DS_ENTRIES; /* loop thru entries */
|
||||
(dirent < DS_SIZE) &&
|
||||
(DE_GET_STAT (dirseg[dirent + DE_STATUS]) != ENDSEG);
|
||||
dirent += DE_SIZE + (dirseg[DS_EXTRA] / 2)) {
|
||||
if ((DE_GET_STAT (dirseg[dirent + DE_STATUS]) == PERM) &&
|
||||
(dirseg[dirent + DE_NAME + 0] == file_name[0]) &&
|
||||
(dirseg[dirent + DE_NAME + 1] == file_name[1]) &&
|
||||
(dirseg[dirent + DE_NAME + 2] == file_name[2]))
|
||||
return dirseg[dirent + DE_FLNT];
|
||||
*start += dirseg[dirent + DE_FLNT]; /* incr file start */
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read blocks */
|
||||
|
||||
t_stat rtfile_read (uint32 block, uint32 count, uint16 *buffer)
|
||||
{
|
||||
uint32 i, j;
|
||||
uint32 pos;
|
||||
uint8 *fbuf = fl_unit.filebuf;
|
||||
|
||||
for (; count > 0; count--, block++) {
|
||||
for (i = 0; i < 4; i++) { /* 4 sectors/block */
|
||||
pos = rtfile_find (block, i); /* position */
|
||||
if ((pos + 128) >= (uint32) fl_unit.capac) /* off end of disk? */
|
||||
return FALSE;
|
||||
for (j = 0; j < 128; j = j + 2) /* copy 128 bytes */
|
||||
*buffer++ = (((uint16) fbuf[pos + j + 1]) << 8) |
|
||||
((uint16) fbuf[pos + j]);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Map an RT-11 block number to a physical byte number */
|
||||
|
||||
uint32 rtfile_find (uint32 block, uint32 sector)
|
||||
{
|
||||
uint32 ls, lt, pt, ps;
|
||||
uint32 off, bb;
|
||||
|
||||
/* get logical block, track & sector */
|
||||
|
||||
bb = (block * 4) + sector;
|
||||
|
||||
lt = bb / BPT;
|
||||
ls = bb % BPT;
|
||||
|
||||
/* logic from 4.3BSD rx.c
|
||||
* calculate phys track & sector
|
||||
* 2:1 skew, 6 sector skew for each track
|
||||
*/
|
||||
|
||||
pt = lt + TRACK_OFFSET;
|
||||
ps = ((ls * SECTOR_SKEW) + (ls / (BPT / SECTOR_SKEW)) + (TRACK_SKEW * lt)) % BPT;
|
||||
|
||||
/* byte offset in logical disk */
|
||||
|
||||
off = (pt * BPT + ps) * 128;
|
||||
return off;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/* vax780_sbi.c: VAX 11/780 SBI
|
||||
|
||||
Copyright (c) 2004-2005, Robert M Supnik
|
||||
Copyright (c) 2004-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -26,6 +26,8 @@
|
|||
This module contains the VAX 11/780 system-specific registers and devices.
|
||||
|
||||
sbi bus controller
|
||||
|
||||
03-May-2006 RMS Fixed writes to ACCS
|
||||
*/
|
||||
|
||||
#include "vax_defs.h"
|
||||
|
@ -126,9 +128,10 @@ extern CTAB *sim_vm_cmd;
|
|||
|
||||
t_stat sbi_reset (DEVICE *dptr);
|
||||
void sbi_set_tmo (int32 pa);
|
||||
void uba_eval_int (void);
|
||||
t_stat vax780_boot (int32 flag, char *ptr);
|
||||
|
||||
void uba_eval_int (void);
|
||||
extern t_stat vax780_fload (int flag, char *cptr);
|
||||
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);
|
||||
|
@ -188,6 +191,8 @@ DEVICE sbi_dev = {
|
|||
CTAB vax780_cmd[] = {
|
||||
{ "BOOT", &vax780_boot, RU_BOOT,
|
||||
"bo{ot} <device>{/R5:flg} boot device\n" },
|
||||
{ "FLOAD", &vax780_fload, 0,
|
||||
"fl{oad} <file> {<start>} load file from console floppy\n" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
@ -388,6 +393,9 @@ switch (rg) {
|
|||
todr_wr (val);
|
||||
break;
|
||||
|
||||
case MT_ACCS: /* ACCS (not impl) */
|
||||
break;
|
||||
|
||||
case MT_WCSA: /* WCSA */
|
||||
wcs_addr = val & WCSA_RW;
|
||||
break;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* vax780_stddev.c: VAX 11/780 standard I/O devices
|
||||
|
||||
Copyright (c) 1998-2005, Robert M Supnik
|
||||
Copyright (c) 1998-2006, 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"),
|
||||
|
@ -29,7 +29,7 @@
|
|||
todr TODR clock
|
||||
tmr interval timer
|
||||
|
||||
|
||||
11-May-06 RMS Revised timer logic for EVKAE
|
||||
22-Nov-05 RMS Revised for new terminal processing routines
|
||||
10-Mar-05 RMS Fixed bug in timer schedule routine (from Mark Hittinger)
|
||||
08-Sep-04 RMS Cloned from vax_stddev.c, vax_sysdev.c, and pdp11_rx.c
|
||||
|
@ -101,7 +101,6 @@
|
|||
#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 TMR_NICR_STD ((~TMR_INC + 1) & LMASK)
|
||||
#define CLK_DELAY 5000 /* 100 Hz */
|
||||
#define TMXR_MULT 2 /* 50 Hz */
|
||||
|
||||
|
@ -162,6 +161,7 @@ uint32 tmr_nicr = 0; /* next interval */
|
|||
uint32 tmr_inc = 0; /* timer increment */
|
||||
int32 tmr_sav = 0; /* timer save */
|
||||
int32 tmr_int = 0; /* interrupt */
|
||||
int32 tmr_use_100hz = 1; /* use 100Hz for timer */
|
||||
int32 clk_tps = 100; /* ticks/second */
|
||||
int32 tmxr_poll = CLK_DELAY * TMXR_MULT; /* term mux poll */
|
||||
int32 tmr_poll = CLK_DELAY; /* pgm timer poll */
|
||||
|
@ -299,6 +299,7 @@ REG tmr_reg[] = {
|
|||
{ HRDATA (NICR, tmr_nicr, 32) },
|
||||
{ HRDATA (INCR, tmr_inc, 32), REG_HIDDEN },
|
||||
{ HRDATA (SAVE, tmr_sav, 32), REG_HIDDEN },
|
||||
{ FLDATA (USE100HZ, tmr_use_100hz, 0), REG_HIDDEN },
|
||||
{ FLDATA (INT, tmr_int, 0) },
|
||||
{ NULL }
|
||||
};
|
||||
|
@ -476,13 +477,13 @@ return SCPE_OK;
|
|||
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.
|
||||
hack is used for the interval timer.
|
||||
|
||||
When the timer is started, the timer interval is inspected.
|
||||
|
||||
if the interval is the standard 10msec, then the 100Hz timer
|
||||
supplies timer interrupts
|
||||
if the interval is non-standard then count instructions
|
||||
if the interval is >= 10msec, then the 100Hz timer drives the
|
||||
next interval
|
||||
if the interval is < 10mec, then count instructions
|
||||
|
||||
If the interval register is read, then its value between events
|
||||
is interpolated using the current instruction count versus the
|
||||
|
@ -502,6 +503,7 @@ void iccs_wr (int32 val)
|
|||
{
|
||||
if ((val & TMR_CSR_RUN) == 0) { /* clearing run? */
|
||||
sim_cancel (&tmr_unit); /* cancel timer */
|
||||
tmr_use_100hz = 0;
|
||||
if (tmr_iccs & TMR_CSR_RUN) /* run 1 -> 0? */
|
||||
tmr_icr = icr_rd (TRUE); /* update itr */
|
||||
}
|
||||
|
@ -531,8 +533,7 @@ 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))
|
||||
if (tmr_use_100hz && (tmr_poll > TMR_INC)) /* scale large int */
|
||||
delta = (uint32) ((((double) delta) * TMR_INC) / tmr_poll);
|
||||
if (delta >= tmr_inc) delta = tmr_inc - 1;
|
||||
return tmr_icr + delta;
|
||||
|
@ -554,15 +555,11 @@ tmr_nicr = val;
|
|||
|
||||
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 */
|
||||
tmr_poll = sim_rtcn_calb (clk_tps, TMR_CLK); /* calibrate clock */
|
||||
sim_activate (&clk_unit, tmr_poll); /* reactivate unit */
|
||||
tmxr_poll = tmr_poll * TMXR_MULT; /* set mux poll */
|
||||
todr_reg = todr_reg + 1; /* incr TODR */
|
||||
if ((tmr_iccs & TMR_CSR_RUN) && /* timer running? */
|
||||
(tmr_nicr == TMR_NICR_STD)) /* standard interval? */
|
||||
if ((tmr_iccs & TMR_CSR_RUN) && tmr_use_100hz) /* timer on, std intvl? */
|
||||
tmr_incr (TMR_INC); /* do timer service */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
@ -606,24 +603,23 @@ return;
|
|||
void tmr_sched (void)
|
||||
{
|
||||
tmr_sav = sim_grtime (); /* save intvl base */
|
||||
if (tmr_nicr != TMR_NICR_STD) { /* non-std interval? */
|
||||
tmr_inc = (~tmr_icr + 1); /* inc = interval */
|
||||
if (tmr_inc == 0) tmr_inc = 1;
|
||||
sim_activate (&tmr_unit, tmr_inc);
|
||||
if (tmr_inc < TMR_INC) { /* 100Hz multiple? */
|
||||
sim_activate (&tmr_unit, tmr_inc); /* schedule timer */
|
||||
tmr_use_100hz = 0;
|
||||
}
|
||||
return; /* let clk handle */
|
||||
else tmr_use_100hz = 1; /* let clk handle */
|
||||
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 */
|
||||
tmr_poll = sim_rtcn_init (clk_unit.wait, TMR_CLK); /* init 100Hz timer */
|
||||
sim_activate (&clk_unit, tmr_poll); /* activate 100Hz unit */
|
||||
tmxr_poll = tmr_poll * TMXR_MULT; /* set mux poll */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
@ -635,6 +631,7 @@ tmr_iccs = 0;
|
|||
tmr_icr = 0;
|
||||
tmr_nicr = 0;
|
||||
tmr_int = 0;
|
||||
tmr_use_100hz = 1;
|
||||
sim_cancel (&tmr_unit); /* cancel timer */
|
||||
if (sim_switches & SWMASK ('P')) todr_powerup (); /* powerup? set TODR */
|
||||
return SCPE_OK;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* vax_syslist.c: VAX device list
|
||||
|
||||
Copyright (c) 1998-2005, Robert M Supnik
|
||||
Copyright (c) 1998-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -23,7 +23,8 @@
|
|||
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
|
||||
17-May-06 RMS Added CR11/CD11 support (from John Dundas)
|
||||
01-Oct-04 RMS Cloned from vax_sys.c
|
||||
*/
|
||||
|
||||
#include "vax_defs.h"
|
||||
|
@ -40,6 +41,7 @@ extern DEVICE clk_dev;
|
|||
extern DEVICE tmr_dev;
|
||||
extern DEVICE tti_dev, tto_dev;
|
||||
extern DEVICE fl_dev;
|
||||
extern DEVICE cr_dev;
|
||||
extern DEVICE lpt_dev;
|
||||
extern DEVICE rq_dev, rqb_dev, rqc_dev, rqd_dev;
|
||||
extern DEVICE rl_dev;
|
||||
|
@ -72,6 +74,7 @@ DEVICE *sim_devices[] = {
|
|||
&tto_dev,
|
||||
&fl_dev,
|
||||
&dz_dev,
|
||||
&cr_dev,
|
||||
&lpt_dev,
|
||||
&rp_dev,
|
||||
&rl_dev,
|
||||
|
|
139
VAX/vax_cis.c
139
VAX/vax_cis.c
|
@ -26,6 +26,16 @@
|
|||
On a full VAX, this module simulates the VAX commercial instruction set (CIS).
|
||||
On a subset VAX, this module implements the emulated instruction fault.
|
||||
|
||||
16-May-06 RMS Fixed bug in length calculation (found by Tim Stark)
|
||||
03-May-06 RMS Fixed MOVTC, MOVTUC to preserve cc's through page faults
|
||||
Fixed MOVTUC to stop on translated == escape
|
||||
Fixed CVTPL to set registers before destination reg write
|
||||
Fixed CVTPL to set correct cc bit on overflow
|
||||
Fixed EDITPC to preserve cc's through page faults
|
||||
Fixed EDITPC EO$BLANK_ZERO count, cc test
|
||||
Fixed EDITPC EO$INSERT to insert fill instead of blank
|
||||
Fixed EDITPC EO$LOAD_PLUS/MINUS to skip character
|
||||
(all reported by Tim Stark)
|
||||
12-Apr-04 RMS Cloned from pdp11_cis.c and vax_cpu1.c
|
||||
|
||||
Zero length decimal strings require either zero bytes (trailing) or one byte
|
||||
|
@ -98,8 +108,9 @@ extern int32 eval_int (void);
|
|||
int32 op_cis (int32 *op, int32 cc, int32 opc, int32 acc)
|
||||
{
|
||||
int32 i, j, c, t, pop, rpt, V;
|
||||
int32 match, fill, sign, shift, ncc;
|
||||
int32 match, fill, sign, shift;
|
||||
int32 ldivd, ldivr;
|
||||
int32 lenl, lenp;
|
||||
uint32 nc, d, result;
|
||||
t_stat r;
|
||||
DSTR accum, src1, src2, dst;
|
||||
|
@ -120,7 +131,7 @@ switch (opc) { /* case on opcode */
|
|||
R[1] = source string address
|
||||
R[2] = number of bytes remaining to move
|
||||
R[3] = table address
|
||||
R[4] = destination string length
|
||||
R[4] = saved cc's/destination string length
|
||||
R[5] = destination string address
|
||||
|
||||
Condition codes:
|
||||
|
@ -141,23 +152,23 @@ switch (opc) { /* case on opcode */
|
|||
SETPC (fault_PC + STR_GETDPC (R[0])); /* reset PC */
|
||||
fill = STR_GETCHR (R[0]); /* get fill */
|
||||
R[2] = R[2] & STR_LNMASK; /* remaining move */
|
||||
R[4] = R[4] & STR_LNMASK;
|
||||
cc = (R[4] >> 16) & CC_MASK; /* restore cc's */
|
||||
}
|
||||
else {
|
||||
CC_CMP_W (op[0], op[4]); /* set cc's */
|
||||
R[0] = STR_PACK (op[2], op[0]); /* src len, fill */
|
||||
R[1] = op[1]; /* src addr */
|
||||
fill = op[2]; /* set fill */
|
||||
R[3] = op[3]; /* table addr */
|
||||
R[4] = op[4]; /* dst len */
|
||||
R[4] = op[4] | ((cc & CC_MASK) << 16); /* dst len + cc's */
|
||||
R[5] = op[5]; /* dst addr */
|
||||
CC_CMP_W (op[0], op[4]); /* set cc's */
|
||||
R[2] = (op[0] < op[4])? op[0]: op[4]; /* remaining move */
|
||||
PSL = PSL | PSL_FPD; /* set FPD */
|
||||
}
|
||||
if (R[2]) { /* move to do? */
|
||||
int32 mvl;
|
||||
mvl = R[0] & STR_LNMASK; /* orig move len */
|
||||
if (mvl >= R[4]) mvl = R[4];
|
||||
if (mvl >= (R[4] & STR_LNMASK)) mvl = R[4] & STR_LNMASK;
|
||||
if (((uint32) R[1]) < ((uint32) R[5])) { /* backward? */
|
||||
while (R[2]) { /* loop thru char */
|
||||
t = Read ((R[1] + R[2] - 1) & LMASK, L_BYTE, RA);
|
||||
|
@ -177,17 +188,18 @@ switch (opc) { /* case on opcode */
|
|||
R[2] = (R[2] - 1) & STR_LNMASK;
|
||||
R[5] = (R[5] + 1) & LMASK;
|
||||
}
|
||||
}
|
||||
} /* update lengths */
|
||||
R[0] = (R[0] & ~STR_LNMASK) | ((R[0] - mvl) & STR_LNMASK);
|
||||
R[4] = (R[4] - mvl) & STR_LNMASK; /* update lengths */
|
||||
R[4] = (R[4] & ~STR_LNMASK) | ((R[4] - mvl) & STR_LNMASK);
|
||||
}
|
||||
while (R[4]) { /* fill if needed */
|
||||
while (R[4] & STR_LNMASK) { /* fill if needed */
|
||||
Write (R[5], fill, L_BYTE, WA);
|
||||
R[4] = (R[4] - 1) & STR_LNMASK;
|
||||
R[4] = (R[4] & ~STR_LNMASK) | ((R[4] - 1) & STR_LNMASK);
|
||||
R[5] = (R[5] + 1) & LMASK; /* adv dst */
|
||||
}
|
||||
R[0] = R[0] & STR_LNMASK; /* mask off state */
|
||||
PSL = PSL & ~PSL_FPD; /* all reg correct */
|
||||
R[4] = 0;
|
||||
PSL = PSL & ~PSL_FPD;
|
||||
return cc;
|
||||
|
||||
/* MOVTUC
|
||||
|
@ -201,7 +213,7 @@ switch (opc) { /* case on opcode */
|
|||
Registers if PSL<fpd> = 1:
|
||||
R[0] = delta-PC/match/source string length
|
||||
R[1] = source string address
|
||||
R[2] = not used
|
||||
R[2] = saved condition codes
|
||||
R[3] = table address
|
||||
R[4] = destination string length
|
||||
R[5] = destination string address
|
||||
|
@ -224,24 +236,26 @@ switch (opc) { /* case on opcode */
|
|||
SETPC (fault_PC + STR_GETDPC (R[0])); /* reset PC */
|
||||
fill = STR_GETCHR (R[0]); /* get match */
|
||||
R[4] = R[4] & STR_LNMASK;
|
||||
cc = R[2] & CC_MASK; /* restore cc's */
|
||||
}
|
||||
else {
|
||||
CC_CMP_W (op[0], op[4]); /* set cc's */
|
||||
R[0] = STR_PACK (op[2], op[0]); /* src len, fill */
|
||||
R[1] = op[1]; /* src addr */
|
||||
fill = op[2]; /* set match */
|
||||
R[3] = op[3]; /* table addr */
|
||||
R[4] = op[4]; /* dst len */
|
||||
R[5] = op[5]; /* dst addr */
|
||||
CC_CMP_W (op[0], op[4]); /* set cc's */
|
||||
R[2] = cc; /* save cc's */
|
||||
PSL = PSL | PSL_FPD; /* set FPD */
|
||||
}
|
||||
while ((R[0] & STR_LNMASK) && R[4]) { /* while src & dst */
|
||||
t = Read (R[1], L_BYTE, RA); /* read src */
|
||||
if (t == fill) { /* stop char? */
|
||||
c = Read ((R[3] + t) & LMASK, L_BYTE, RA); /* translate */
|
||||
if (c == fill) { /* stop char? */
|
||||
cc = cc | CC_V; /* set V, done */
|
||||
break;
|
||||
}
|
||||
c = Read ((R[3] + t) & LMASK, L_BYTE, RA); /* translate */
|
||||
Write (R[5], c, L_BYTE, WA); /* write dst */
|
||||
R[0] = (R[0] & ~STR_LNMASK) | ((R[0] - 1) & STR_LNMASK);
|
||||
R[1] = (R[1] + 1) & LMASK;
|
||||
|
@ -708,15 +722,17 @@ switch (opc) { /* case on opcode */
|
|||
} /* end for */
|
||||
if (src1.sign) result = (~result + 1) & LMASK; /* negative? */
|
||||
if (src1.sign ^ ((result & LSIGN) != 0)) V = 1; /* test for overflow */
|
||||
if (op[2] >= 0) R[op[2]] = result;
|
||||
else Write (op[3], result, L_LONG, WA);
|
||||
if (V && (PSL & PSW_IV)) SET_TRAP (TRAP_INTOV); /* ovflo and IV? trap */
|
||||
R[0] = 0;
|
||||
if (op[2] < 0) /* if mem, store result */
|
||||
Write (op[3], result, L_LONG, WA); /* before reg update */
|
||||
R[0] = 0; /* update registers */
|
||||
R[1] = op[1];
|
||||
R[2] = 0;
|
||||
R[3] = 0;
|
||||
if (op[2] >= 0) /* if reg, store result */
|
||||
R[op[2]] = result; /* after reg update */
|
||||
if (V && (PSL & PSW_IV)) SET_TRAP (TRAP_INTOV); /* ovflo and IV? trap */
|
||||
CC_IIZZ_L (result);
|
||||
return cc | V;
|
||||
return cc | (V? CC_V: 0);
|
||||
|
||||
/* CVTLP
|
||||
|
||||
|
@ -816,7 +832,8 @@ switch (opc) { /* case on opcode */
|
|||
case CVTPS:
|
||||
if ((PSL & PSL_FPD) || (op[0] > 31) || (op[2] > 31))
|
||||
RSVD_OPND_FAULT;
|
||||
ReadDstr (op[0], op[1], &dst, acc); /* get src */
|
||||
lenl = ReadDstr (op[0], op[1], &dst, acc); /* get source, lw len */
|
||||
lenp = LntDstr (&dst, lenl); /* get exact nz src len */
|
||||
ProbeDstr (op[2], op[3], WA); /* test dst write */
|
||||
Write (op[3], dst.sign? C_MINUS: C_PLUS, L_BYTE, WA);
|
||||
for (i = 1; i <= op[2]; i++) { /* loop thru chars */
|
||||
|
@ -824,7 +841,11 @@ switch (opc) { /* case on opcode */
|
|||
c = d | C_ZERO; /* cvt to ASCII */
|
||||
Write ((op[3] + op[2] + 1 - i) & LMASK, c, L_BYTE, WA);
|
||||
}
|
||||
cc = SetCCDstr (op[2], &dst, 0); /* set cc's */
|
||||
cc = SetCCDstr (op[0], &dst, 0); /* set cc's */
|
||||
if (lenp > op[2]) { /* src fit in dst? */
|
||||
cc = cc | CC_V; /* set ovflo */
|
||||
if (PSL & PSW_DV) SET_TRAP (TRAP_DECOVF); /* if enabled, trap */
|
||||
}
|
||||
R[0] = 0;
|
||||
R[1] = op[1];
|
||||
R[2] = 0;
|
||||
|
@ -898,7 +919,8 @@ switch (opc) { /* case on opcode */
|
|||
case CVTPT:
|
||||
if ((PSL & PSL_FPD) || (op[0] > 31) || (op[3] > 31))
|
||||
RSVD_OPND_FAULT;
|
||||
ReadDstr (op[0], op[1], &dst, acc); /* get source */
|
||||
lenl = ReadDstr (op[0], op[1], &dst, acc); /* get source, lw len */
|
||||
lenp = LntDstr (&dst, lenl); /* get exact src len */
|
||||
ProbeDstr (op[3], op[4], WA); /* test writeability */
|
||||
for (i = 1; i <= op[3]; i++) { /* loop thru chars */
|
||||
if (i != 1) { /* not last? */
|
||||
|
@ -911,7 +933,11 @@ switch (opc) { /* case on opcode */
|
|||
}
|
||||
Write ((op[4] + op[3] - i) & LMASK, c, L_BYTE, WA);
|
||||
}
|
||||
cc = SetCCDstr (op[3], &dst, 0); /* set cc's */
|
||||
cc = SetCCDstr (op[0], &dst, 0); /* set cc's from src */
|
||||
if (lenp > op[3]) { /* src fit in dst? */
|
||||
cc = cc | CC_V; /* set ovflo */
|
||||
if (PSL & PSW_DV) SET_TRAP (TRAP_DECOVF); /* if enabled, trap */
|
||||
}
|
||||
R[0] = 0;
|
||||
R[1] = op[1];
|
||||
R[2] = 0;
|
||||
|
@ -936,6 +962,7 @@ switch (opc) { /* case on opcode */
|
|||
R0<15:0> = remaining source length
|
||||
R1 = source address
|
||||
R2<31:24> = delta PC
|
||||
R2<19:16> = condition codes
|
||||
R2<15:8> = sign char
|
||||
R2<7:0> = fill char
|
||||
R3 = pattern string address
|
||||
|
@ -957,7 +984,7 @@ switch (opc) { /* case on opcode */
|
|||
- It is safe to take a memory management fault on a write-only
|
||||
operation, like fill. After correction of the fault, the
|
||||
pattern operator is fetched and executed again.
|
||||
- The move operators do not alter visible state (registers or cc)
|
||||
- The move operators do not alter visible state (registers or saved cc)
|
||||
until all memory operations are complete.
|
||||
*/
|
||||
|
||||
|
@ -966,6 +993,7 @@ switch (opc) { /* case on opcode */
|
|||
SETPC (fault_PC + STR_GETDPC (R[2])); /* reset PC */
|
||||
fill = ED_GETFILL (R[2]); /* get fill */
|
||||
sign = ED_GETSIGN (R[2]); /* get sign */
|
||||
cc = ED_GETCC (R[2]); /* get cc's */
|
||||
R[0] = R[0] & ~0xFFE0; /* src len <= 31 */
|
||||
}
|
||||
else { /* new instr */
|
||||
|
@ -982,12 +1010,13 @@ switch (opc) { /* case on opcode */
|
|||
fill = C_SPACE;
|
||||
R[0] = R[4] = op[0]; /* src len */
|
||||
R[1] = op[1]; /* src addr */
|
||||
R[2] = STR_PACK (0, (sign << ED_V_SIGN) | (fill << ED_V_FILL));
|
||||
/* delta PC, sign, fill */
|
||||
R[2] = STR_PACK (cc, (sign << ED_V_SIGN) | (fill << ED_V_FILL));
|
||||
/* delta PC, cc, sign, fill */
|
||||
R[3] = op[2]; /* pattern */
|
||||
R[5] = op[3]; /* dst addr */
|
||||
PSL = PSL | PSL_FPD; /* set FPD */
|
||||
}
|
||||
|
||||
for ( ;; ) { /* loop thru pattern */
|
||||
pop = Read (R[3], L_BYTE, RA); /* rd pattern op */
|
||||
if (pop == EO_END) break; /* end? */
|
||||
|
@ -997,6 +1026,7 @@ switch (opc) { /* case on opcode */
|
|||
pop = pop & ~EO_RPT_MASK; /* isolate op */
|
||||
}
|
||||
switch (pop) { /* case on op */
|
||||
|
||||
case EO_END_FLOAT: /* end float */
|
||||
if (!(cc & CC_C)) { /* not signif? */
|
||||
Write (R[5], sign, L_BYTE, WA); /* write sign */
|
||||
|
@ -1004,43 +1034,59 @@ switch (opc) { /* case on opcode */
|
|||
cc = cc | CC_C; /* set signif */
|
||||
}
|
||||
break;
|
||||
|
||||
case EO_CLR_SIGNIF: /* clear signif */
|
||||
cc = cc & ~CC_C; /* clr C */
|
||||
break;
|
||||
|
||||
case EO_SET_SIGNIF: /* set signif */
|
||||
cc = cc | CC_C; /* set C */
|
||||
break;
|
||||
|
||||
case EO_STORE_SIGN: /* store sign */
|
||||
Write (R[5], sign, L_BYTE, WA); /* write sign */
|
||||
R[5] = (R[5] + 1) & LMASK; /* now fault safe */
|
||||
break;
|
||||
|
||||
case EO_LOAD_FILL: /* load fill */
|
||||
fill = Read ((R[3] + 1) & LMASK, L_BYTE, RA);
|
||||
R[2] = ED_PUTFILL (R[2], fill); /* now fault safe */
|
||||
R[3]++;
|
||||
break;
|
||||
|
||||
case EO_LOAD_SIGN: /* load sign */
|
||||
sign = edit_read_sign (acc);
|
||||
R[3]++;
|
||||
break;
|
||||
|
||||
case EO_LOAD_PLUS: /* load sign if + */
|
||||
if (!(cc & CC_N)) sign = edit_read_sign (acc);
|
||||
R[3]++;
|
||||
break;
|
||||
|
||||
case EO_LOAD_MINUS: /* load sign if - */
|
||||
if (cc & CC_N) sign = edit_read_sign (acc);
|
||||
R[3]++;
|
||||
break;
|
||||
|
||||
case EO_INSERT: /* insert char */
|
||||
c = Read ((R[3] + 1) & LMASK, L_BYTE, RA);
|
||||
Write (R[5], ((cc & CC_C)? c: sign), L_BYTE, WA);
|
||||
Write (R[5], ((cc & CC_C)? c: fill), L_BYTE, WA);
|
||||
R[5] = (R[5] + 1) & LMASK; /* now fault safe */
|
||||
R[3]++;
|
||||
break;
|
||||
|
||||
case EO_BLANK_ZERO: /* blank zero */
|
||||
t = Read ((R[3] + 1) & LMASK, L_BYTE, RA);
|
||||
if (t == 0) RSVD_OPND_FAULT;
|
||||
while (t--) /* repeat and blank */
|
||||
if (cc & CC_Z) { /* zero? */
|
||||
do { /* repeat and blank */
|
||||
Write ((R[5] - t) & LMASK, fill, L_BYTE, WA);
|
||||
} while (--t);
|
||||
}
|
||||
R[3]++; /* now fault safe */
|
||||
break;
|
||||
|
||||
case EO_REPL_SIGN: /* replace sign */
|
||||
t = Read ((R[3] + 1) & LMASK, L_BYTE, RA);
|
||||
if (t == 0) RSVD_OPND_FAULT;
|
||||
|
@ -1048,64 +1094,67 @@ switch (opc) { /* case on opcode */
|
|||
Write ((R[5] - t) & LMASK, fill, L_BYTE, WA);
|
||||
R[3]++; /* now fault safe */
|
||||
break;
|
||||
|
||||
case EO_ADJUST_LNT: /* adjust length */
|
||||
t = Read ((R[3] + 1) & LMASK, L_BYTE, RA);
|
||||
if ((t == 0) || (t > 31)) RSVD_OPND_FAULT;
|
||||
R[0] = R[0] & WMASK; /* clr old ld zero */
|
||||
if (R[0] > t) { /* decrease */
|
||||
ncc = cc; /* copy cc's */
|
||||
for (i = 0; i < (R[0] - t); i++) { /* loop thru src */
|
||||
d = edit_read_src (i, acc); /* get nibble */
|
||||
if (d) ncc = (ncc | CC_V | CC_C) & ~CC_Z;
|
||||
if (d) cc = (cc | CC_V | CC_C) & ~CC_Z;
|
||||
} /* end for */
|
||||
cc = ncc; /* now fault safe */
|
||||
edit_adv_src (R[0] - t); /* adv src ptr */
|
||||
} /* end else */
|
||||
else R[0] = R[0] | (((R[0] - t) & WMASK) << 16);
|
||||
R[3]++;
|
||||
break;
|
||||
|
||||
case EO_FILL: /* fill */
|
||||
for (i = 0; i < rpt; i++) /* fill string */
|
||||
Write ((R[5] + i) & LMASK, fill, L_BYTE, WA);
|
||||
R[5] = (R[5] + rpt) & LMASK; /* now fault safe */
|
||||
break;
|
||||
|
||||
case EO_MOVE:
|
||||
ncc = cc; /* copy cc's */
|
||||
for (i = 0; i < rpt; i++) { /* for repeat */
|
||||
d = edit_read_src (i, acc); /* get nibble */
|
||||
if (d) ncc = (ncc | CC_C) & ~CC_Z; /* test for non-zero */
|
||||
c = (ncc & CC_C)? (d | 0x30): fill; /* test for signif */
|
||||
if (d) cc = (cc | CC_C) & ~CC_Z; /* test for non-zero */
|
||||
c = (cc & CC_C)? (d | 0x30): fill; /* test for signif */
|
||||
Write ((R[5] + i) & LMASK, c, L_BYTE, WA);
|
||||
} /* end for */
|
||||
cc = ncc; /* now fault safe */
|
||||
edit_adv_src (rpt); /* advance src */
|
||||
R[5] = (R[5] + rpt) & LMASK; /* advance dst */
|
||||
break;
|
||||
|
||||
case EO_FLOAT:
|
||||
ncc = cc; /* copy cc's */
|
||||
for (i = j = 0; i < rpt; i++, j++) { /* for repeat */
|
||||
d = edit_read_src (i, acc); /* get nibble */
|
||||
if (d && !(ncc & CC_C)) { /* nz, signif clear? */
|
||||
if (d && !(cc & CC_C)) { /* nz, signif clear? */
|
||||
Write ((R[5] + j) & LMASK, sign, L_BYTE, WA);
|
||||
ncc = (ncc | CC_C) & ~CC_Z; /* set signif */
|
||||
cc = (cc | CC_C) & ~CC_Z; /* set signif */
|
||||
j++; /* extra dst char */
|
||||
} /* end if */
|
||||
c = (ncc & CC_C)? (d | 0x30): fill; /* test for signif */
|
||||
c = (cc & CC_C)? (d | 0x30): fill; /* test for signif */
|
||||
Write ((R[5] + j) & LMASK, c, L_BYTE, WA);
|
||||
} /* end for */
|
||||
cc = ncc; /* now fault safe */
|
||||
edit_adv_src (rpt); /* advance src */
|
||||
R[5] = (R[5] + j) & LMASK; /* advance dst */
|
||||
break;
|
||||
|
||||
default: /* undefined */
|
||||
RSVD_OPND_FAULT;
|
||||
} /* end case pattern */
|
||||
|
||||
R[3] = (R[3] + 1) & LMASK; /* next pattern byte */
|
||||
R[2] = ED_PUTCC (R[2], cc); /* update cc's */
|
||||
} /* end for pattern */
|
||||
|
||||
if (R[0]) RSVD_OPND_FAULT; /* pattern too short */
|
||||
PSL = PSL & ~PSL_FPD; /* clear FPD */
|
||||
if (cc & CC_Z) cc = cc & ~CC_N; /* zero? clear n */
|
||||
if ((cc & CC_V) && (PSL & PSW_DV)) SET_TRAP (TRAP_DECOVF);
|
||||
if ((cc & CC_V) && (PSL & PSW_DV)) /* overflow & trap enabled? */
|
||||
SET_TRAP (TRAP_DECOVF);
|
||||
R[0] = R[4]; /* restore src len */
|
||||
R[1] = R[1] - (R[0] >> 1); /* restore src addr */
|
||||
R[2] = R[4] = 0;
|
||||
|
@ -1146,8 +1195,8 @@ for (i = 0; i <= end; i++) { /* loop thru string */
|
|||
c = c & 0xF0; /* erase sign */
|
||||
}
|
||||
if ((i == end) && ((lnt & 1) == 0)) c = c & 0xF;
|
||||
if (((c & 0xF0) > 0x90) || /* check hi digit */
|
||||
((c & 0x0F) > 0x09)) RSVD_OPND_FAULT; /* check lo digit */
|
||||
/* if (((c & 0xF0) > 0x90) || /* check hi digit */
|
||||
/* ((c & 0x0F) > 0x09)) RSVD_OPND_FAULT; /* check lo digit */
|
||||
src->val[i / 4] = src->val[i / 4] | (c << ((i % 4) * 8));
|
||||
} /* end for */
|
||||
if ((t == 0xB) || (t == 0xD)) src->sign = 1; /* if -, set sign */
|
||||
|
@ -1366,6 +1415,7 @@ int32 LntDstr (DSTR *dsrc, int32 nz)
|
|||
{
|
||||
int32 i;
|
||||
|
||||
if (nz == 0) return 0;
|
||||
for (i = 7; i > 0; i--) {
|
||||
if ((dsrc->val[nz - 1] >> (i * 4)) & 0xF) break;
|
||||
}
|
||||
|
@ -1545,7 +1595,6 @@ int32 sign;
|
|||
|
||||
sign = Read ((R[3] + 1) & LMASK, L_BYTE, RA); /* read */
|
||||
R[2] = ED_PUTSIGN (R[2], sign); /* now fault safe */
|
||||
R[3] = (R[3] + 1) & LMASK;
|
||||
return sign;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* vax_cmode.c: VAX compatibility mode
|
||||
|
||||
Copyright (c) 2004-2005, Robert M Supnik
|
||||
Copyright (c) 2004-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -26,6 +26,8 @@
|
|||
On a full VAX, this module implements PDP-11 compatibility mode.
|
||||
On a subset VAX, this module forces a fault if REI attempts to set PSL<cm>.
|
||||
|
||||
03-May-06 RMS Fixed omission of SXT
|
||||
Fixed order of operand fetching in XOR
|
||||
24-Aug-04 RMS Cloned from PDP-11 CPU
|
||||
|
||||
In compatibility mode, the Istream prefetch mechanism is not used. The
|
||||
|
@ -113,9 +115,11 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
case 3: /* BPT */
|
||||
CMODE_FAULT (CMODE_BPT);
|
||||
break;
|
||||
|
||||
case 4: /* IOT */
|
||||
CMODE_FAULT (CMODE_IOT);
|
||||
break;
|
||||
|
||||
case 2: /* RTI */
|
||||
case 6: /* RTT */
|
||||
src = RdMemW (R[6] & WMASK); /* new PC */
|
||||
|
@ -126,15 +130,18 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
else PSL = PSL & ~PSW_T;
|
||||
CMODE_JUMP (src); /* update PC */
|
||||
break;
|
||||
|
||||
default: /* undefined */
|
||||
CMODE_FAULT (CMODE_RSVI);
|
||||
break;
|
||||
} /* end switch IR */
|
||||
break; /* end case 0000xx */
|
||||
|
||||
case 001: /* JMP */
|
||||
if (dstreg) CMODE_FAULT (CMODE_ILLI); /* mode 0 illegal */
|
||||
else { CMODE_JUMP (GeteaW (dstspec)); }
|
||||
break;
|
||||
|
||||
case 002: /* 0002xx */
|
||||
if (IR < 000210) { /* RTS */
|
||||
dstspec = dstspec & 07;
|
||||
|
@ -153,6 +160,7 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
if (IR < 000260) cc = cc & ~(IR & CC_MASK); /* clear CC */
|
||||
else cc = cc | (IR & CC_MASK); /* set CC */
|
||||
break;
|
||||
|
||||
case 003: /* SWAB */
|
||||
if (dstreg) src = RdRegW (dstspec);
|
||||
else src = RdMemMW (ea = GeteaW (dstspec));
|
||||
|
@ -161,48 +169,63 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
else WrMemW (dst, ea);
|
||||
CC_IIZZ_B ((dst & BMASK));
|
||||
break;
|
||||
|
||||
case 004: case 005: /* BR */
|
||||
BRANCH_F (IR);
|
||||
break;
|
||||
|
||||
case 006: case 007: /* BR */
|
||||
BRANCH_B (IR);
|
||||
break;
|
||||
|
||||
case 010: case 011: /* BNE */
|
||||
if ((cc & CC_Z) == 0) { BRANCH_F (IR); }
|
||||
break;
|
||||
|
||||
case 012: case 013: /* BNE */
|
||||
if ((cc & CC_Z) == 0) { BRANCH_B (IR); }
|
||||
break;
|
||||
|
||||
case 014: case 015: /* BEQ */
|
||||
if (cc & CC_Z) { BRANCH_F (IR); }
|
||||
break;
|
||||
|
||||
case 016: case 017: /* BEQ */
|
||||
if (cc & CC_Z) { BRANCH_B (IR); }
|
||||
break;
|
||||
|
||||
case 020: case 021: /* BGE */
|
||||
if (CC_XOR_NV (cc) == 0) { BRANCH_F (IR); }
|
||||
break;
|
||||
|
||||
case 022: case 023: /* BGE */
|
||||
if (CC_XOR_NV (cc) == 0) { BRANCH_B (IR); }
|
||||
break;
|
||||
|
||||
case 024: case 025: /* BLT */
|
||||
if (CC_XOR_NV (cc)) { BRANCH_F (IR); }
|
||||
break;
|
||||
|
||||
case 026: case 027: /* BLT */
|
||||
if (CC_XOR_NV (cc)) { BRANCH_B (IR); }
|
||||
break;
|
||||
|
||||
case 030: case 031: /* BGT */
|
||||
if (((cc & CC_Z) || CC_XOR_NV (cc)) == 0) { BRANCH_F (IR); }
|
||||
break;
|
||||
|
||||
case 032: case 033: /* BGT */
|
||||
if (((cc & CC_Z) || CC_XOR_NV (cc)) == 0) { BRANCH_B (IR); }
|
||||
break;
|
||||
|
||||
case 034: case 035: /* BLE */
|
||||
if ((cc & CC_Z) || CC_XOR_NV (cc)) { BRANCH_F (IR); }
|
||||
break;
|
||||
|
||||
case 036: case 037: /* BLE */
|
||||
if ((cc & CC_Z) || CC_XOR_NV (cc)) { BRANCH_B (IR); }
|
||||
break;
|
||||
|
||||
case 040: case 041: case 042: case 043: /* JSR */
|
||||
case 044: case 045: case 046: case 047:
|
||||
if (dstreg) CMODE_FAULT (CMODE_ILLI); /* mode 0 illegal */
|
||||
|
@ -216,11 +239,13 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
CMODE_JUMP (dst); /* PC <- dst */
|
||||
}
|
||||
break; /* end JSR */
|
||||
|
||||
case 050: /* CLR */
|
||||
if (dstreg) WrRegW (0, dstspec);
|
||||
else WrMemW (0, GeteaW (dstspec));
|
||||
cc = CC_Z;
|
||||
break;
|
||||
|
||||
case 051: /* COM */
|
||||
if (dstreg) src = RdRegW (dstspec);
|
||||
else src = RdMemMW (ea = GeteaW (dstspec));
|
||||
|
@ -230,6 +255,7 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
CC_IIZZ_W (dst);
|
||||
cc = cc | CC_C;
|
||||
break;
|
||||
|
||||
case 052: /* INC */
|
||||
if (dstreg) src = RdRegW (dstspec);
|
||||
else src = RdMemMW (ea = GeteaW (dstspec));
|
||||
|
@ -239,6 +265,7 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
CC_IIZP_W (dst);
|
||||
if (dst == 0100000) cc = cc | CC_V;
|
||||
break;
|
||||
|
||||
case 053: /* DEC */
|
||||
if (dstreg) src = RdRegW (dstspec);
|
||||
else src = RdMemMW (ea = GeteaW (dstspec));
|
||||
|
@ -248,6 +275,7 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
CC_IIZP_W (dst);
|
||||
if (dst == 077777) cc = cc | CC_V;
|
||||
break;
|
||||
|
||||
case 054: /* NEG */
|
||||
if (dstreg) src = RdRegW (dstspec);
|
||||
else src = RdMemMW (ea = GeteaW (dstspec));
|
||||
|
@ -258,6 +286,7 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
if (dst == 0100000) cc = cc | CC_V;
|
||||
if (dst) cc = cc | CC_C;
|
||||
break;
|
||||
|
||||
case 055: /* ADC */
|
||||
if (dstreg) src = RdRegW (dstspec);
|
||||
else src = RdMemMW (ea = GeteaW (dstspec));
|
||||
|
@ -268,6 +297,7 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
if ((src == 077777) && (dst == 0100000)) cc = cc | CC_V;
|
||||
if ((src == 0177777) && (dst == 0)) cc = cc | CC_C;
|
||||
break;
|
||||
|
||||
case 056: /* SBC */
|
||||
if (dstreg) src = RdRegW (dstspec);
|
||||
else src = RdMemMW (ea = GeteaW (dstspec));
|
||||
|
@ -278,11 +308,13 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
if ((src == 0100000) && (dst == 077777)) cc = cc | CC_V;
|
||||
if ((src == 0) && (dst == 0177777)) cc = cc | CC_C;
|
||||
break;
|
||||
|
||||
case 057: /* TST */
|
||||
if (dstreg) src = RdRegW (dstspec);
|
||||
else src = RdMemW (GeteaW (dstspec));
|
||||
CC_IIZZ_W (src);
|
||||
break;
|
||||
|
||||
case 060: /* ROR */
|
||||
if (dstreg) src = RdRegW (dstspec);
|
||||
else src = RdMemMW (ea = GeteaW (dstspec));
|
||||
|
@ -293,6 +325,7 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
if (src & 1) cc = cc | CC_C;
|
||||
if (CC_XOR_NC (cc)) cc = cc | CC_V;
|
||||
break;
|
||||
|
||||
case 061: /* ROL */
|
||||
if (dstreg) src = RdRegW (dstspec);
|
||||
else src = RdMemMW (ea = GeteaW (dstspec));
|
||||
|
@ -303,6 +336,7 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
if (src & WSIGN) cc = cc | CC_C;
|
||||
if (CC_XOR_NC (cc)) cc = cc | CC_V;
|
||||
break;
|
||||
|
||||
case 062: /* ASR */
|
||||
if (dstreg) src = RdRegW (dstspec);
|
||||
else src = RdMemMW (ea = GeteaW (dstspec));
|
||||
|
@ -313,6 +347,7 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
if (src & 1) cc = cc | CC_C;
|
||||
if (CC_XOR_NC (cc)) cc = cc | CC_V;
|
||||
break;
|
||||
|
||||
case 063: /* ASL */
|
||||
if (dstreg) src = RdRegW (dstspec);
|
||||
else src = RdMemMW (ea = GeteaW (dstspec));
|
||||
|
@ -323,6 +358,7 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
if (src & WSIGN) cc = cc | CC_C;
|
||||
if (CC_XOR_NC (cc)) cc = cc | CC_V;
|
||||
break;
|
||||
|
||||
case 065: /* MFPI */
|
||||
if (dstreg) dst = RdRegW (dstspec); /* "mov dst,-(sp)" */
|
||||
else dst = RdMemW (GeteaW (dstspec));
|
||||
|
@ -330,6 +366,7 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
R[6] = (R[6] - 2) & WMASK;
|
||||
CC_IIZP_W (dst);
|
||||
break;
|
||||
|
||||
case 066: /* MTPI */
|
||||
dst = RdMemW (R[6] & WMASK); /* "mov (sp)+,dst" */
|
||||
R[6] = (R[6] + 2) & WMASK;
|
||||
|
@ -338,6 +375,14 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
else WrMemW (dst, (GeteaW (dstspec) & WMASK));
|
||||
CC_IIZP_W (dst);
|
||||
break;
|
||||
|
||||
case 067: /* SXT */
|
||||
dst = (cc & CC_N)? 0177777: 0;
|
||||
if (dstreg) WrRegW (dst, dstspec);
|
||||
else WrMemW (dst, GeteaW (dstspec));
|
||||
CC_IIZP_W (dst);
|
||||
break;
|
||||
|
||||
default: /* undefined */
|
||||
CMODE_FAULT (CMODE_RSVI);
|
||||
break;
|
||||
|
@ -538,9 +583,9 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
break;
|
||||
|
||||
case 4: /* XOR */
|
||||
src = RdRegW (srcspec); /* get src */
|
||||
if (dstreg) src2 = RdRegW (dstspec); /* get dst */
|
||||
else src2 = RdMemMW (ea = GeteaW (dstspec));
|
||||
src = RdRegW (srcspec); /* get src */
|
||||
dst = src2 ^ src;
|
||||
if (dstreg) WrRegW (dst, dstspec); /* result */
|
||||
else WrMemW (dst, ea);
|
||||
|
@ -567,62 +612,81 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
case 000: case 001: /* BPL */
|
||||
if ((cc & CC_N) == 0) { BRANCH_F (IR); }
|
||||
break;
|
||||
|
||||
case 002: case 003: /* BPL */
|
||||
if ((cc & CC_N) == 0) { BRANCH_B (IR); }
|
||||
break;
|
||||
|
||||
case 004: case 005: /* BMI */
|
||||
if (cc & CC_N) { BRANCH_F (IR); }
|
||||
break;
|
||||
|
||||
case 006: case 007: /* BMI */
|
||||
if (cc & CC_N) { BRANCH_B (IR); }
|
||||
break;
|
||||
|
||||
case 010: case 011: /* BHI */
|
||||
if ((cc & (CC_C | CC_Z)) == 0) { BRANCH_F (IR); }
|
||||
break;
|
||||
|
||||
case 012: case 013: /* BHI */
|
||||
if ((cc & (CC_C | CC_Z)) == 0) { BRANCH_B (IR); }
|
||||
break;
|
||||
|
||||
case 014: case 015: /* BLOS */
|
||||
if (cc & (CC_C | CC_Z)) { BRANCH_F (IR); }
|
||||
break;
|
||||
|
||||
case 016: case 017: /* BLOS */
|
||||
if (cc & (CC_C | CC_Z)) { BRANCH_B (IR); }
|
||||
break;
|
||||
|
||||
case 020: case 021: /* BVC */
|
||||
if ((cc & CC_V) == 0) { BRANCH_F (IR); }
|
||||
break;
|
||||
|
||||
case 022: case 023: /* BVC */
|
||||
if ((cc & CC_V) == 0) { BRANCH_B (IR); }
|
||||
break;
|
||||
|
||||
case 024: case 025: /* BVS */
|
||||
if (cc & CC_V) { BRANCH_F (IR); }
|
||||
break;
|
||||
|
||||
case 026: case 027: /* BVS */
|
||||
if (cc & CC_V) { BRANCH_B (IR); }
|
||||
break;
|
||||
|
||||
case 030: case 031: /* BCC */
|
||||
if ((cc & CC_C) == 0) { BRANCH_F (IR); }
|
||||
break;
|
||||
|
||||
case 032: case 033: /* BCC */
|
||||
if ((cc & CC_C) == 0) { BRANCH_B (IR); }
|
||||
break;
|
||||
|
||||
case 034: case 035: /* BCS */
|
||||
if (cc & CC_C) { BRANCH_F (IR); }
|
||||
break;
|
||||
|
||||
case 036: case 037: /* BCS */
|
||||
if (cc & CC_C) { BRANCH_B (IR); }
|
||||
break;
|
||||
|
||||
case 040: case 041: case 042: case 043: /* EMT */
|
||||
CMODE_FAULT (CMODE_EMT);
|
||||
break;
|
||||
|
||||
case 044: case 045: case 046: case 047: /* TRAP */
|
||||
CMODE_FAULT (CMODE_TRAP);
|
||||
break;
|
||||
|
||||
case 050: /* CLRB */
|
||||
if (dstreg) WrRegB (0, dstspec);
|
||||
else WrMemB (0, GeteaB (dstspec));
|
||||
cc = CC_Z;
|
||||
break;
|
||||
|
||||
case 051: /* COMB */
|
||||
if (dstreg) src = RdRegB (dstspec);
|
||||
else src = RdMemMB (ea = GeteaB (dstspec));
|
||||
|
@ -632,6 +696,7 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
CC_IIZZ_B (dst);
|
||||
cc = cc | CC_C;
|
||||
break;
|
||||
|
||||
case 052: /* INCB */
|
||||
if (dstreg) src = RdRegB (dstspec);
|
||||
else src = RdMemMB (ea = GeteaB (dstspec));
|
||||
|
@ -641,6 +706,7 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
CC_IIZP_B (dst);
|
||||
if (dst == 0200) cc = cc | CC_V;
|
||||
break;
|
||||
|
||||
case 053: /* DECB */
|
||||
if (dstreg) src = RdRegB (dstspec);
|
||||
else src = RdMemMB (ea = GeteaB (dstspec));
|
||||
|
@ -650,6 +716,7 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
CC_IIZP_B (dst);
|
||||
if (dst == 0177) cc = cc | CC_V;
|
||||
break;
|
||||
|
||||
case 054: /* NEGB */
|
||||
if (dstreg) src = RdRegB (dstspec);
|
||||
else src = RdMemMB (ea = GeteaB (dstspec));
|
||||
|
@ -660,6 +727,7 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
if (dst == 0200) cc = cc | CC_V;
|
||||
if (dst) cc = cc | CC_C;
|
||||
break;
|
||||
|
||||
case 055: /* ADCB */
|
||||
if (dstreg) src = RdRegB (dstspec);
|
||||
else src = RdMemMB (ea = GeteaB (dstspec));
|
||||
|
@ -670,6 +738,7 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
if ((src == 0177) && (dst == 0200)) cc = cc | CC_V;
|
||||
if ((src == 0377) && (dst == 0)) cc = cc | CC_C;
|
||||
break;
|
||||
|
||||
case 056: /* SBCB */
|
||||
if (dstreg) src = RdRegB (dstspec);
|
||||
else src = RdMemMB (ea = GeteaB (dstspec));
|
||||
|
@ -680,11 +749,13 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
if ((src == 0200) && (dst == 0177)) cc = cc | CC_V;
|
||||
if ((src == 0) && (dst == 0377)) cc = cc | CC_C;
|
||||
break;
|
||||
|
||||
case 057: /* TSTB */
|
||||
if (dstreg) src = RdRegB (dstspec);
|
||||
else src = RdMemB (GeteaB (dstspec));
|
||||
CC_IIZZ_B (src);
|
||||
break;
|
||||
|
||||
case 060: /* RORB */
|
||||
if (dstreg) src = RdRegB (dstspec);
|
||||
else src = RdMemMB (ea = GeteaB (dstspec));
|
||||
|
@ -695,6 +766,7 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
if (src & 1) cc = cc | CC_C;
|
||||
if (CC_XOR_NC (cc)) cc = cc | CC_V;
|
||||
break;
|
||||
|
||||
case 061: /* ROLB */
|
||||
if (dstreg) src = RdRegB (dstspec);
|
||||
else src = RdMemMB (ea = GeteaB (dstspec));
|
||||
|
@ -705,6 +777,7 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
if (src & BSIGN) cc = cc | CC_C;
|
||||
if (CC_XOR_NC (cc)) cc = cc | CC_V;
|
||||
break;
|
||||
|
||||
case 062: /* ASRB */
|
||||
if (dstreg) src = RdRegB (dstspec);
|
||||
else src = RdMemMB (ea = GeteaB (dstspec));
|
||||
|
@ -715,6 +788,7 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
if (src & 1) cc = cc | CC_C;
|
||||
if (CC_XOR_NC (cc)) cc = cc | CC_V;
|
||||
break;
|
||||
|
||||
case 063: /* ASLB */
|
||||
if (dstreg) src = RdRegB (dstspec);
|
||||
else src = RdMemMB (ea = GeteaB (dstspec));
|
||||
|
@ -725,6 +799,7 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
if (src & BSIGN) cc = cc | CC_C;
|
||||
if (CC_XOR_NC (cc)) cc = cc | CC_V;
|
||||
break;
|
||||
|
||||
case 065: /* MFPD */
|
||||
if (dstreg) dst = RdRegW (dstspec); /* "mov dst,-(sp)" */
|
||||
else dst = RdMemW (GeteaW (dstspec));
|
||||
|
@ -732,6 +807,7 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
R[6] = (R[6] - 2) & WMASK;
|
||||
CC_IIZP_W (dst);
|
||||
break;
|
||||
|
||||
case 066: /* MTPD */
|
||||
dst = RdMemW (R[6] & WMASK); /* "mov (sp)+,dst" */
|
||||
R[6] = (R[6] + 2) & WMASK;
|
||||
|
@ -740,6 +816,7 @@ switch ((IR >> 12) & 017) { /* decode IR<15:12> */
|
|||
else WrMemW (dst, (GeteaW (dstspec) & WMASK));
|
||||
CC_IIZP_W (dst);
|
||||
break;
|
||||
|
||||
default:
|
||||
CMODE_FAULT (CMODE_RSVI);
|
||||
break; } /* end switch SOPs */
|
||||
|
|
543
VAX/vax_cpu.c
543
VAX/vax_cpu.c
|
@ -1,6 +1,6 @@
|
|||
/* vax_cpu.c: VAX CPU
|
||||
|
||||
Copyright (c) 1998-2005, Robert M Supnik
|
||||
Copyright (c) 1998-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,17 @@
|
|||
|
||||
cpu VAX central processor
|
||||
|
||||
22-May-06 RMS Fixed format error in CPU history (found by Peter Schorn)
|
||||
10-May-06 RMS Added -kesu switches for virtual addressing modes
|
||||
Fixed bugs in examine virtual
|
||||
Rewrote history function for greater usability
|
||||
Fixed bug in reported VA on faulting cross-page write
|
||||
02-May-06 RMS Fixed fault cleanup to clear PSL<tp>
|
||||
Fixed ADAWI r-mode to preserve dst<31:16>
|
||||
Fixed ACBD/G to test correct operand
|
||||
Fixed access checking on modify-class specifiers
|
||||
Fixed branch displacements in history buffer
|
||||
(all reported by Tim Stark)
|
||||
17-Nov-05 RMS Fixed CVTfi with integer overflow to trap if PSW<iv> set
|
||||
13-Nov-05 RMS Fixed breakpoint test with 64b addresses
|
||||
25-Oct-05 RMS Removed cpu_extmem
|
||||
|
@ -158,7 +169,8 @@
|
|||
#define UNIT_MSIZE (1u << UNIT_V_MSIZE)
|
||||
#define GET_CUR acc = ACC_MASK (PSL_GETCUR (PSL))
|
||||
|
||||
#define OPND_SIZE 20
|
||||
#define OPND_SIZE 16
|
||||
#define INST_SIZE 52
|
||||
#define op0 opnd[0]
|
||||
#define op1 opnd[1]
|
||||
#define op2 opnd[2]
|
||||
|
@ -178,7 +190,8 @@
|
|||
#define WRITE_L(r) if (spec > (GRN | nPC)) Write (va, r, L_LONG, WA); \
|
||||
else R[rn] = (r)
|
||||
#define WRITE_Q(rl,rh) if (spec > (GRN | nPC)) { \
|
||||
if (Test (va + 7, WA, &mstat) >= 0) \
|
||||
if ((Test (va + 7, WA, &mstat) >= 0) || \
|
||||
(Test (va, WA, &mstat) < 0)) \
|
||||
Write (va, rl, L_LONG, WA); \
|
||||
Write (va + 4, rh, L_LONG, WA); \
|
||||
} \
|
||||
|
@ -195,7 +208,7 @@ typedef struct {
|
|||
int32 iPC;
|
||||
int32 PSL;
|
||||
int32 opc;
|
||||
int32 brdest;
|
||||
uint8 inst[INST_SIZE];
|
||||
int32 opnd[OPND_SIZE];
|
||||
} InstHistory;
|
||||
|
||||
|
@ -265,6 +278,7 @@ const uint32 align[4] = {
|
|||
|
||||
extern int32 sim_interval;
|
||||
extern int32 sim_int_char;
|
||||
extern int32 sim_switches;
|
||||
extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
|
||||
extern UNIT clk_unit;
|
||||
|
||||
|
@ -353,8 +367,10 @@ t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
|
|||
t_stat cpu_set_hist (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||
t_stat cpu_show_virt (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||
int32 cpu_get_vsw (int32 sw);
|
||||
int32 get_istr (int32 lnt, int32 acc);
|
||||
int32 ReadOcta (int32 va, int32 *opnd, int32 j, int32 acc);
|
||||
t_bool cpu_show_opnd (FILE *st, InstHistory *h, int32 line);
|
||||
|
||||
/* CPU data structures
|
||||
|
||||
|
@ -492,6 +508,7 @@ else if (abortval < 0) { /* mm or rsrv or int */
|
|||
else R[rrn] = R[rrn] + rlnt;
|
||||
}
|
||||
}
|
||||
PSL = PSL & ~PSL_TP; /* clear <tp> */
|
||||
recqptr = 0; /* clear queue */
|
||||
delta = PC - fault_PC; /* save delta PC */
|
||||
SETPC (fault_PC); /* restore PC */
|
||||
|
@ -681,27 +698,33 @@ for ( ;; ) {
|
|||
case SH3|RB: case SH3|RW: case SH3|RL:
|
||||
opnd[j++] = spec;
|
||||
break;
|
||||
|
||||
case SH0|RQ: case SH1|RQ: case SH2|RQ: case SH3|RQ:
|
||||
opnd[j++] = spec;
|
||||
opnd[j++] = 0;
|
||||
break;
|
||||
|
||||
case SH0|RO: case SH1|RO: case SH2|RO: case SH3|RO:
|
||||
opnd[j++] = spec;
|
||||
opnd[j++] = 0;
|
||||
opnd[j++] = 0;
|
||||
opnd[j++] = 0;
|
||||
break;
|
||||
|
||||
case SH0|RF: case SH1|RF: case SH2|RF: case SH3|RF:
|
||||
opnd[j++] = (spec << 4) | 0x4000;
|
||||
break;
|
||||
|
||||
case SH0|RD: case SH1|RD: case SH2|RD: case SH3|RD:
|
||||
opnd[j++] = (spec << 4) | 0x4000;
|
||||
opnd[j++] = 0;
|
||||
break;
|
||||
|
||||
case SH0|RG: case SH1|RG: case SH2|RG: case SH3|RG:
|
||||
opnd[j++] = (spec << 1) | 0x4000;
|
||||
opnd[j++] = 0;
|
||||
break;
|
||||
|
||||
case SH0|RH: case SH1|RH: case SH2|RH: case SH3|RH:
|
||||
opnd[j++] = ((spec & 0x7) << 29) | (0x4000 | ((spec >> 3) & 0x7));
|
||||
opnd[j++] = 0;
|
||||
|
@ -715,10 +738,12 @@ for ( ;; ) {
|
|||
CHECK_FOR_PC;
|
||||
opnd[j++] = R[rn] & BMASK;
|
||||
break;
|
||||
|
||||
case GRN|RW: case GRN|MW:
|
||||
CHECK_FOR_PC;
|
||||
opnd[j++] = R[rn] & WMASK;
|
||||
break;
|
||||
|
||||
case GRN|VB:
|
||||
vfldrp1 = R[(rn + 1) & RGMASK];
|
||||
case GRN|WB: case GRN|WW: case GRN|WL: case GRN|WQ: case GRN|WO:
|
||||
|
@ -727,11 +752,13 @@ for ( ;; ) {
|
|||
CHECK_FOR_PC;
|
||||
opnd[j++] = R[rn];
|
||||
break;
|
||||
|
||||
case GRN|RQ: case GRN|RD: case GRN|RG: case GRN|MQ:
|
||||
CHECK_FOR_SP;
|
||||
opnd[j++] = R[rn];
|
||||
opnd[j++] = R[rn + 1];
|
||||
break;
|
||||
|
||||
case GRN|RO: case GRN|RH: case GRN|MO:
|
||||
CHECK_FOR_AP;
|
||||
opnd[j++] = R[rn];
|
||||
|
@ -749,6 +776,7 @@ for ( ;; ) {
|
|||
CHECK_FOR_PC;
|
||||
va = opnd[j++] = R[rn];
|
||||
break;
|
||||
|
||||
case ADC|VB:
|
||||
case ADC|WB: case ADC|WW: case ADC|WL: case ADC|WQ: case ADC|WO:
|
||||
opnd[j++] = OP_MEM;
|
||||
|
@ -757,29 +785,55 @@ for ( ;; ) {
|
|||
va = opnd[j++] = R[rn] = R[rn] - DR_LNT (disp);
|
||||
recq[recqptr++] = RQ_REC (disp, rn);
|
||||
break;
|
||||
|
||||
case ADC|RB: case ADC|RW: case ADC|RL: case ADC|RF:
|
||||
case ADC|MB: case ADC|MW: case ADC|ML:
|
||||
R[rn] = R[rn] - (DR_LNT (disp));
|
||||
recq[recqptr++] = RQ_REC (disp, rn);
|
||||
case RGD|RB: case RGD|RW: case RGD|RL: case RGD|RF:
|
||||
case RGD|MB: case RGD|MW: case RGD|ML:
|
||||
CHECK_FOR_PC;
|
||||
opnd[j++] = Read (va = R[rn], DR_LNT (disp), RA);
|
||||
break;
|
||||
case ADC|RQ: case ADC|RD: case ADC|RG: case ADC|MQ:
|
||||
|
||||
case ADC|RQ: case ADC|RD: case ADC|RG:
|
||||
R[rn] = R[rn] - 8;
|
||||
recq[recqptr++] = RQ_REC (disp, rn);
|
||||
case RGD|RQ: case RGD|RD: case RGD|RG: case RGD|MQ:
|
||||
case RGD|RQ: case RGD|RD: case RGD|RG:
|
||||
CHECK_FOR_PC;
|
||||
opnd[j++] = Read (va = R[rn], L_LONG, RA);
|
||||
opnd[j++] = Read (R[rn] + 4, L_LONG, RA);
|
||||
break;
|
||||
case ADC|RO: case ADC|RH: case ADC|MO:
|
||||
|
||||
case ADC|RO: case ADC|RH:
|
||||
R[rn] = R[rn] - 16;
|
||||
recq[recqptr++] = RQ_REC (disp, rn);
|
||||
case RGD|RO: case RGD|RH: case RGD|MO:
|
||||
case RGD|RO: case RGD|RH:
|
||||
CHECK_FOR_PC;
|
||||
j = ReadOcta (va = R[rn], opnd, j, acc);
|
||||
j = ReadOcta (va = R[rn], opnd, j, RA);
|
||||
break;
|
||||
|
||||
case ADC|MB: case ADC|MW: case ADC|ML:
|
||||
R[rn] = R[rn] - (DR_LNT (disp));
|
||||
recq[recqptr++] = RQ_REC (disp, rn);
|
||||
case RGD|MB: case RGD|MW: case RGD|ML:
|
||||
CHECK_FOR_PC;
|
||||
opnd[j++] = Read (va = R[rn], DR_LNT (disp), WA);
|
||||
break;
|
||||
|
||||
case ADC|MQ:
|
||||
R[rn] = R[rn] - 8;
|
||||
recq[recqptr++] = RQ_REC (disp, rn);
|
||||
case RGD|MQ:
|
||||
CHECK_FOR_PC;
|
||||
opnd[j++] = Read (va = R[rn], L_LONG, WA);
|
||||
opnd[j++] = Read (R[rn] + 4, L_LONG, WA);
|
||||
break;
|
||||
|
||||
case ADC|MO:
|
||||
R[rn] = R[rn] - 16;
|
||||
recq[recqptr++] = RQ_REC (disp, rn);
|
||||
case RGD|MO:
|
||||
CHECK_FOR_PC;
|
||||
j = ReadOcta (va = R[rn], opnd, j, WA);
|
||||
break;
|
||||
|
||||
/* Autoincrement */
|
||||
|
@ -806,8 +860,7 @@ for ( ;; ) {
|
|||
recq[recqptr++] = RQ_REC (disp, rn);
|
||||
}
|
||||
break;
|
||||
case AIN|MB: case AIN|MW: case AIN|ML:
|
||||
/* CHECK_FOR_PC; */
|
||||
|
||||
case AIN|RB: case AIN|RW: case AIN|RL: case AIN|RF:
|
||||
va = R[rn];
|
||||
if (rn == nPC) {
|
||||
|
@ -819,8 +872,7 @@ for ( ;; ) {
|
|||
recq[recqptr++] = RQ_REC (disp, rn);
|
||||
}
|
||||
break;
|
||||
case AIN|MQ:
|
||||
/* CHECK_FOR_PC; */
|
||||
|
||||
case AIN|RQ: case AIN|RD: case AIN|RG:
|
||||
va = R[rn];
|
||||
if (rn == nPC) {
|
||||
|
@ -834,8 +886,7 @@ for ( ;; ) {
|
|||
recq[recqptr++] = RQ_REC (disp, rn);
|
||||
}
|
||||
break;
|
||||
case AIN|MO:
|
||||
/* CHECK_FOR_PC; */
|
||||
|
||||
case AIN|RO: case AIN|RH:
|
||||
va = R[rn];
|
||||
if (rn == nPC) {
|
||||
|
@ -845,7 +896,48 @@ for ( ;; ) {
|
|||
GET_ISTR (opnd[j++], L_LONG);
|
||||
}
|
||||
else {
|
||||
j = ReadOcta (va, opnd, j, acc);
|
||||
j = ReadOcta (va, opnd, j, RA);
|
||||
R[rn] = R[rn] + 16;
|
||||
recq[recqptr++] = RQ_REC (disp, rn);
|
||||
}
|
||||
break;
|
||||
|
||||
case AIN|MB: case AIN|MW: case AIN|ML:
|
||||
va = R[rn];
|
||||
if (rn == nPC) {
|
||||
GET_ISTR (opnd[j++], DR_LNT (disp));
|
||||
}
|
||||
else {
|
||||
opnd[j++] = Read (R[rn], DR_LNT (disp), WA);
|
||||
R[rn] = R[rn] + DR_LNT (disp);
|
||||
recq[recqptr++] = RQ_REC (disp, rn);
|
||||
}
|
||||
break;
|
||||
|
||||
case AIN|MQ:
|
||||
va = R[rn];
|
||||
if (rn == nPC) {
|
||||
GET_ISTR (opnd[j++], L_LONG);
|
||||
GET_ISTR (opnd[j++], L_LONG);
|
||||
}
|
||||
else {
|
||||
opnd[j++] = Read (va, L_LONG, WA);
|
||||
opnd[j++] = Read (va + 4, L_LONG, WA);
|
||||
R[rn] = R[rn] + 8;
|
||||
recq[recqptr++] = RQ_REC (disp, rn);
|
||||
}
|
||||
break;
|
||||
|
||||
case AIN|MO:
|
||||
va = R[rn];
|
||||
if (rn == nPC) {
|
||||
GET_ISTR (opnd[j++], L_LONG);
|
||||
GET_ISTR (opnd[j++], L_LONG);
|
||||
GET_ISTR (opnd[j++], L_LONG);
|
||||
GET_ISTR (opnd[j++], L_LONG);
|
||||
}
|
||||
else {
|
||||
j = ReadOcta (va, opnd, j, WA);
|
||||
R[rn] = R[rn] + 16;
|
||||
recq[recqptr++] = RQ_REC (disp, rn);
|
||||
}
|
||||
|
@ -864,8 +956,8 @@ for ( ;; ) {
|
|||
recq[recqptr++] = RQ_REC (AID|RL, rn);
|
||||
}
|
||||
break;
|
||||
|
||||
case AID|RB: case AID|RW: case AID|RL: case AID|RF:
|
||||
case AID|MB: case AID|MW: case AID|ML:
|
||||
if (rn == nPC) {
|
||||
GET_ISTR (va, L_LONG);
|
||||
}
|
||||
|
@ -876,7 +968,8 @@ for ( ;; ) {
|
|||
}
|
||||
opnd[j++] = Read (va, DR_LNT (disp), RA);
|
||||
break;
|
||||
case AID|RQ: case AID|RD: case AID|RG: case AID|MQ:
|
||||
|
||||
case AID|RQ: case AID|RD: case AID|RG:
|
||||
if (rn == nPC) {
|
||||
GET_ISTR (va, L_LONG);
|
||||
}
|
||||
|
@ -888,7 +981,8 @@ for ( ;; ) {
|
|||
opnd[j++] = Read (va, L_LONG, RA);
|
||||
opnd[j++] = Read (va + 4, L_LONG, RA);
|
||||
break;
|
||||
case AID|RO: case AID|RH: case AID|MO:
|
||||
|
||||
case AID|RO: case AID|RH:
|
||||
if (rn == nPC) {
|
||||
GET_ISTR (va, L_LONG);
|
||||
}
|
||||
|
@ -897,7 +991,44 @@ for ( ;; ) {
|
|||
R[rn] = R[rn] + 4;
|
||||
recq[recqptr++] = RQ_REC (AID|RL, rn);
|
||||
}
|
||||
j = ReadOcta (va, opnd, j, acc);
|
||||
j = ReadOcta (va, opnd, j, RA);
|
||||
break;
|
||||
|
||||
case AID|MB: case AID|MW: case AID|ML:
|
||||
if (rn == nPC) {
|
||||
GET_ISTR (va, L_LONG);
|
||||
}
|
||||
else {
|
||||
va = Read (R[rn], L_LONG, RA);
|
||||
R[rn] = R[rn] + 4;
|
||||
recq[recqptr++] = RQ_REC (AID|RL, rn);
|
||||
}
|
||||
opnd[j++] = Read (va, DR_LNT (disp), WA);
|
||||
break;
|
||||
|
||||
case AID|MQ:
|
||||
if (rn == nPC) {
|
||||
GET_ISTR (va, L_LONG);
|
||||
}
|
||||
else {
|
||||
va = Read (R[rn], L_LONG, RA);
|
||||
R[rn] = R[rn] + 4;
|
||||
recq[recqptr++] = RQ_REC (AID|RL, rn);
|
||||
}
|
||||
opnd[j++] = Read (va, L_LONG, WA);
|
||||
opnd[j++] = Read (va + 4, L_LONG, WA);
|
||||
break;
|
||||
|
||||
case AID|MO:
|
||||
if (rn == nPC) {
|
||||
GET_ISTR (va, L_LONG);
|
||||
}
|
||||
else {
|
||||
va = Read (R[rn], L_LONG, RA);
|
||||
R[rn] = R[rn] + 4;
|
||||
recq[recqptr++] = RQ_REC (AID|RL, rn);
|
||||
}
|
||||
j = ReadOcta (va, opnd, j, WA);
|
||||
break;
|
||||
|
||||
/* Byte displacement */
|
||||
|
@ -909,22 +1040,43 @@ for ( ;; ) {
|
|||
GET_ISTR (temp, L_BYTE);
|
||||
va = opnd[j++] = R[rn] + SXTB (temp);
|
||||
break;
|
||||
|
||||
case BDP|RB: case BDP|RW: case BDP|RL: case BDP|RF:
|
||||
case BDP|MB: case BDP|MW: case BDP|ML:
|
||||
GET_ISTR (temp, L_BYTE);
|
||||
va = R[rn] + SXTB (temp);
|
||||
opnd[j++] = Read (va, DR_LNT (disp), RA);
|
||||
break;
|
||||
case BDP|RQ: case BDP|RD: case BDP|RG: case BDP|MQ:
|
||||
|
||||
case BDP|RQ: case BDP|RD: case BDP|RG:
|
||||
GET_ISTR (temp, L_BYTE);
|
||||
va = R[rn] + SXTB (temp);
|
||||
opnd[j++] = Read (va, L_LONG, RA);
|
||||
opnd[j++] = Read (va + 4, L_LONG, RA);
|
||||
break;
|
||||
case BDP|RO: case BDP|RH: case BDP|MO:
|
||||
|
||||
case BDP|RO: case BDP|RH:
|
||||
GET_ISTR (temp, L_BYTE);
|
||||
va = R[rn] + SXTB (temp);
|
||||
j = ReadOcta (va, opnd, j, acc);
|
||||
j = ReadOcta (va, opnd, j, RA);
|
||||
break;
|
||||
|
||||
case BDP|MB: case BDP|MW: case BDP|ML:
|
||||
GET_ISTR (temp, L_BYTE);
|
||||
va = R[rn] + SXTB (temp);
|
||||
opnd[j++] = Read (va, DR_LNT (disp), WA);
|
||||
break;
|
||||
|
||||
case BDP|MQ:
|
||||
GET_ISTR (temp, L_BYTE);
|
||||
va = R[rn] + SXTB (temp);
|
||||
opnd[j++] = Read (va, L_LONG, WA);
|
||||
opnd[j++] = Read (va + 4, L_LONG, WA);
|
||||
break;
|
||||
|
||||
case BDP|MO:
|
||||
GET_ISTR (temp, L_BYTE);
|
||||
va = R[rn] + SXTB (temp);
|
||||
j = ReadOcta (va, opnd, j, WA);
|
||||
break;
|
||||
|
||||
/* Byte displacement deferred */
|
||||
|
@ -937,25 +1089,49 @@ for ( ;; ) {
|
|||
iad = R[rn] + SXTB (temp);
|
||||
va = opnd[j++] = Read (iad, L_LONG, RA);
|
||||
break;
|
||||
|
||||
case BDD|RB: case BDD|RW: case BDD|RL: case BDD|RF:
|
||||
case BDD|MB: case BDD|MW: case BDD|ML:
|
||||
GET_ISTR (temp, L_BYTE);
|
||||
iad = R[rn] + SXTB (temp);
|
||||
va = Read (iad, L_LONG, RA);
|
||||
opnd[j++] = Read (va, DR_LNT (disp), RA);
|
||||
break;
|
||||
case BDD|RQ: case BDD|RD: case BDD|RG: case BDD|MQ:
|
||||
|
||||
case BDD|RQ: case BDD|RD: case BDD|RG:
|
||||
GET_ISTR (temp, L_BYTE);
|
||||
iad = R[rn] + SXTB (temp);
|
||||
va = Read (iad, L_LONG, RA);
|
||||
opnd[j++] = Read (va, L_LONG, RA);
|
||||
opnd[j++] = Read (va + 4, L_LONG, RA);
|
||||
break;
|
||||
case BDD|RO: case BDD|RH: case BDD|MO:
|
||||
|
||||
case BDD|RO: case BDD|RH:
|
||||
GET_ISTR (temp, L_BYTE);
|
||||
iad = R[rn] + SXTB (temp);
|
||||
va = Read (iad, L_LONG, RA);
|
||||
j = ReadOcta (va, opnd, j, acc);
|
||||
j = ReadOcta (va, opnd, j, RA);
|
||||
break;
|
||||
|
||||
case BDD|MB: case BDD|MW: case BDD|ML:
|
||||
GET_ISTR (temp, L_BYTE);
|
||||
iad = R[rn] + SXTB (temp);
|
||||
va = Read (iad, L_LONG, RA);
|
||||
opnd[j++] = Read (va, DR_LNT (disp), WA);
|
||||
break;
|
||||
|
||||
case BDD|MQ:
|
||||
GET_ISTR (temp, L_BYTE);
|
||||
iad = R[rn] + SXTB (temp);
|
||||
va = Read (iad, L_LONG, RA);
|
||||
opnd[j++] = Read (va, L_LONG, WA);
|
||||
opnd[j++] = Read (va + 4, L_LONG, WA);
|
||||
break;
|
||||
|
||||
case BDD|MO:
|
||||
GET_ISTR (temp, L_BYTE);
|
||||
iad = R[rn] + SXTB (temp);
|
||||
va = Read (iad, L_LONG, RA);
|
||||
j = ReadOcta (va, opnd, j, WA);
|
||||
break;
|
||||
|
||||
/* Word displacement */
|
||||
|
@ -967,22 +1143,43 @@ for ( ;; ) {
|
|||
GET_ISTR (temp, L_WORD);
|
||||
va = opnd[j++] = R[rn] + SXTW (temp);
|
||||
break;
|
||||
case WDP|MB: case WDP|MW: case WDP|ML:
|
||||
|
||||
case WDP|RB: case WDP|RW: case WDP|RL: case WDP|RF:
|
||||
GET_ISTR (temp, L_WORD);
|
||||
va = R[rn] + SXTW (temp);
|
||||
opnd[j++] = Read (va, DR_LNT (disp), RA);
|
||||
break;
|
||||
case WDP|MQ: case WDP|RQ: case WDP|RD: case WDP|RG:
|
||||
|
||||
case WDP|RQ: case WDP|RD: case WDP|RG:
|
||||
GET_ISTR (temp, L_WORD);
|
||||
va = R[rn] + SXTW (temp);
|
||||
opnd[j++] = Read (va, L_LONG, RA);
|
||||
opnd[j++] = Read (va + 4, L_LONG, RA);
|
||||
break;
|
||||
case WDP|MO: case WDP|RO: case WDP|RH:
|
||||
|
||||
case WDP|RO: case WDP|RH:
|
||||
GET_ISTR (temp, L_WORD);
|
||||
va = R[rn] + SXTW (temp);
|
||||
j = ReadOcta (va, opnd, j, acc);
|
||||
j = ReadOcta (va, opnd, j, RA);
|
||||
break;
|
||||
|
||||
case WDP|MB: case WDP|MW: case WDP|ML:
|
||||
GET_ISTR (temp, L_WORD);
|
||||
va = R[rn] + SXTW (temp);
|
||||
opnd[j++] = Read (va, DR_LNT (disp), WA);
|
||||
break;
|
||||
|
||||
case WDP|MQ:
|
||||
GET_ISTR (temp, L_WORD);
|
||||
va = R[rn] + SXTW (temp);
|
||||
opnd[j++] = Read (va, L_LONG, WA);
|
||||
opnd[j++] = Read (va + 4, L_LONG, WA);
|
||||
break;
|
||||
|
||||
case WDP|MO:
|
||||
GET_ISTR (temp, L_WORD);
|
||||
va = R[rn] + SXTW (temp);
|
||||
j = ReadOcta (va, opnd, j, WA);
|
||||
break;
|
||||
|
||||
/* Word displacement deferred */
|
||||
|
@ -995,25 +1192,49 @@ for ( ;; ) {
|
|||
iad = R[rn] + SXTW (temp);
|
||||
va = opnd[j++] = Read (iad, L_LONG, RA);
|
||||
break;
|
||||
case WDD|MB: case WDD|MW: case WDD|ML:
|
||||
|
||||
case WDD|RB: case WDD|RW: case WDD|RL: case WDD|RF:
|
||||
GET_ISTR (temp, L_WORD);
|
||||
iad = R[rn] + SXTW (temp);
|
||||
va = Read (iad, L_LONG, RA);
|
||||
opnd[j++] = Read (va, DR_LNT (disp), RA);
|
||||
break;
|
||||
case WDD|MQ: case WDD|RQ: case WDD|RD: case WDD|RG:
|
||||
|
||||
case WDD|RQ: case WDD|RD: case WDD|RG:
|
||||
GET_ISTR (temp, L_WORD);
|
||||
iad = R[rn] + SXTW (temp);
|
||||
va = Read (iad, L_LONG, RA);
|
||||
opnd[j++] = Read (va, L_LONG, RA);
|
||||
opnd[j++] = Read (va + 4, L_LONG, RA);
|
||||
break;
|
||||
case WDD|MO: case WDD|RO: case WDD|RH:
|
||||
|
||||
case WDD|RO: case WDD|RH:
|
||||
GET_ISTR (temp, L_WORD);
|
||||
iad = R[rn] + SXTW (temp);
|
||||
va = Read (iad, L_LONG, RA);
|
||||
j = ReadOcta (va, opnd, j, acc);
|
||||
j = ReadOcta (va, opnd, j, RA);
|
||||
break;
|
||||
|
||||
case WDD|MB: case WDD|MW: case WDD|ML:
|
||||
GET_ISTR (temp, L_WORD);
|
||||
iad = R[rn] + SXTW (temp);
|
||||
va = Read (iad, L_LONG, RA);
|
||||
opnd[j++] = Read (va, DR_LNT (disp), WA);
|
||||
break;
|
||||
|
||||
case WDD|MQ:
|
||||
GET_ISTR (temp, L_WORD);
|
||||
iad = R[rn] + SXTW (temp);
|
||||
va = Read (iad, L_LONG, RA);
|
||||
opnd[j++] = Read (va, L_LONG, WA);
|
||||
opnd[j++] = Read (va + 4, L_LONG, WA);
|
||||
break;
|
||||
|
||||
case WDD|MO:
|
||||
GET_ISTR (temp, L_WORD);
|
||||
iad = R[rn] + SXTW (temp);
|
||||
va = Read (iad, L_LONG, RA);
|
||||
j = ReadOcta (va, opnd, j, WA);
|
||||
break;
|
||||
|
||||
/* Longword displacement */
|
||||
|
@ -1025,22 +1246,43 @@ for ( ;; ) {
|
|||
GET_ISTR (temp, L_LONG);
|
||||
va = opnd[j++] = R[rn] + temp;
|
||||
break;
|
||||
case LDP|MB: case LDP|MW: case LDP|ML:
|
||||
|
||||
case LDP|RB: case LDP|RW: case LDP|RL: case LDP|RF:
|
||||
GET_ISTR (temp, L_LONG);
|
||||
va = R[rn] + temp;
|
||||
opnd[j++] = Read (va, DR_LNT (disp), RA);
|
||||
break;
|
||||
case LDP|MQ: case LDP|RQ: case LDP|RD: case LDP|RG:
|
||||
|
||||
case LDP|RQ: case LDP|RD: case LDP|RG:
|
||||
GET_ISTR (temp, L_LONG);
|
||||
va = R[rn] + temp;
|
||||
opnd[j++] = Read (va, L_LONG, RA);
|
||||
opnd[j++] = Read (va + 4, L_LONG, RA);
|
||||
break;
|
||||
case LDP|MO: case LDP|RO: case LDP|RH:
|
||||
|
||||
case LDP|RO: case LDP|RH:
|
||||
GET_ISTR (temp, L_LONG);
|
||||
va = R[rn] + temp;
|
||||
j = ReadOcta (va, opnd, j, acc);
|
||||
j = ReadOcta (va, opnd, j, RA);
|
||||
break;
|
||||
|
||||
case LDP|MB: case LDP|MW: case LDP|ML:
|
||||
GET_ISTR (temp, L_LONG);
|
||||
va = R[rn] + temp;
|
||||
opnd[j++] = Read (va, DR_LNT (disp), WA);
|
||||
break;
|
||||
|
||||
case LDP|MQ:
|
||||
GET_ISTR (temp, L_LONG);
|
||||
va = R[rn] + temp;
|
||||
opnd[j++] = Read (va, L_LONG, WA);
|
||||
opnd[j++] = Read (va + 4, L_LONG, WA);
|
||||
break;
|
||||
|
||||
case LDP|MO:
|
||||
GET_ISTR (temp, L_LONG);
|
||||
va = R[rn] + temp;
|
||||
j = ReadOcta (va, opnd, j, WA);
|
||||
break;
|
||||
|
||||
/* Longword displacement deferred */
|
||||
|
@ -1053,25 +1295,49 @@ for ( ;; ) {
|
|||
iad = R[rn] + temp;
|
||||
va = opnd[j++] = Read (iad, L_LONG, RA);
|
||||
break;
|
||||
case LDD|MB: case LDD|MW: case LDD|ML:
|
||||
|
||||
case LDD|RB: case LDD|RW: case LDD|RL: case LDD|RF:
|
||||
GET_ISTR (temp, L_LONG);
|
||||
iad = R[rn] + temp;
|
||||
va = Read (iad, L_LONG, RA);
|
||||
opnd[j++] = Read (va, DR_LNT (disp), RA);
|
||||
break;
|
||||
case LDD|MQ: case LDD|RQ: case LDD|RD: case LDD|RG:
|
||||
|
||||
case LDD|RQ: case LDD|RD: case LDD|RG:
|
||||
GET_ISTR (temp, L_LONG);
|
||||
iad = R[rn] + temp;
|
||||
va = Read (iad, L_LONG, RA);
|
||||
opnd[j++] = Read (va, L_LONG, RA);
|
||||
opnd[j++] = Read (va + 4, L_LONG, RA);
|
||||
break;
|
||||
case LDD|MO: case LDD|RO: case LDD|RH:
|
||||
|
||||
case LDD|RO: case LDD|RH:
|
||||
GET_ISTR (temp, L_LONG);
|
||||
iad = R[rn] + temp;
|
||||
va = Read (iad, L_LONG, RA);
|
||||
j = ReadOcta (va, opnd, j, acc);
|
||||
j = ReadOcta (va, opnd, j, RA);
|
||||
break;
|
||||
|
||||
case LDD|MB: case LDD|MW: case LDD|ML:
|
||||
GET_ISTR (temp, L_LONG);
|
||||
iad = R[rn] + temp;
|
||||
va = Read (iad, L_LONG, RA);
|
||||
opnd[j++] = Read (va, DR_LNT (disp), WA);
|
||||
break;
|
||||
|
||||
case LDD|MQ:
|
||||
GET_ISTR (temp, L_LONG);
|
||||
iad = R[rn] + temp;
|
||||
va = Read (iad, L_LONG, RA);
|
||||
opnd[j++] = Read (va, L_LONG, WA);
|
||||
opnd[j++] = Read (va + 4, L_LONG, WA);
|
||||
break;
|
||||
|
||||
case LDD|MO:
|
||||
GET_ISTR (temp, L_LONG);
|
||||
iad = R[rn] + temp;
|
||||
va = Read (iad, L_LONG, RA);
|
||||
j = ReadOcta (va, opnd, j, WA);
|
||||
break;
|
||||
|
||||
/* Index */
|
||||
|
@ -1094,12 +1360,14 @@ for ( ;; ) {
|
|||
CHECK_FOR_PC;
|
||||
index = index + R[rn];
|
||||
break;
|
||||
|
||||
case AIN:
|
||||
CHECK_FOR_PC;
|
||||
index = index + R[rn];
|
||||
R[rn] = R[rn] + DR_LNT (disp);
|
||||
recq[recqptr++] = RQ_REC (AIN | (disp & DR_LNMASK), rn);
|
||||
break;
|
||||
|
||||
case AID:
|
||||
if (rn == nPC) {
|
||||
GET_ISTR (temp, L_LONG);
|
||||
|
@ -1111,30 +1379,37 @@ for ( ;; ) {
|
|||
}
|
||||
index = temp + index;
|
||||
break;
|
||||
|
||||
case BDP:
|
||||
GET_ISTR (temp, L_BYTE);
|
||||
index = index + R[rn] + SXTB (temp);
|
||||
break;
|
||||
|
||||
case BDD:
|
||||
GET_ISTR (temp, L_BYTE);
|
||||
index = index + Read (R[rn] + SXTB (temp), L_LONG, RA);
|
||||
break;
|
||||
|
||||
case WDP:
|
||||
GET_ISTR (temp, L_WORD);
|
||||
index = index + R[rn] + SXTW (temp);
|
||||
break;
|
||||
|
||||
case WDD:
|
||||
GET_ISTR (temp, L_WORD);
|
||||
index = index + Read (R[rn] + SXTW (temp), L_LONG, RA);
|
||||
break;
|
||||
|
||||
case LDP:
|
||||
GET_ISTR (temp, L_LONG);
|
||||
index = index + R[rn] + temp;
|
||||
break;
|
||||
|
||||
case LDD:
|
||||
GET_ISTR (temp, L_LONG);
|
||||
index = index + Read (R[rn] + temp, L_LONG, RA);
|
||||
break;
|
||||
|
||||
default:
|
||||
RSVD_ADDR_FAULT; /* end case idxspec */
|
||||
}
|
||||
|
@ -1145,16 +1420,31 @@ for ( ;; ) {
|
|||
case AB: case AW: case AL: case AQ: case AO:
|
||||
va = opnd[j++] = index;
|
||||
break;
|
||||
case MB: case MW: case ML:
|
||||
|
||||
case RB: case RW: case RL:
|
||||
opnd[j++] = Read (va = index, DR_LNT (disp), RA);
|
||||
break;
|
||||
case RQ: case MQ:
|
||||
|
||||
case RQ:
|
||||
opnd[j++] = Read (va = index, L_LONG, RA);
|
||||
opnd[j++] = Read (index + 4, L_LONG, RA);
|
||||
break;
|
||||
case RO: case MO:
|
||||
j = ReadOcta (va = index, opnd, j, acc);
|
||||
|
||||
case RO:
|
||||
j = ReadOcta (va = index, opnd, j, RA);
|
||||
break;
|
||||
|
||||
case MB: case MW: case ML:
|
||||
opnd[j++] = Read (va = index, DR_LNT (disp), WA);
|
||||
break;
|
||||
|
||||
case MQ:
|
||||
opnd[j++] = Read (va = index, L_LONG, WA);
|
||||
opnd[j++] = Read (index + 4, L_LONG, WA);
|
||||
break;
|
||||
|
||||
case MO:
|
||||
j = ReadOcta (va = index, opnd, j, WA);
|
||||
break;
|
||||
} /* end case access/lnt */
|
||||
break; /* end index */
|
||||
|
@ -1169,12 +1459,24 @@ for ( ;; ) {
|
|||
/* Optionally record instruction history */
|
||||
|
||||
if (hst_lnt) {
|
||||
int32 lim;
|
||||
t_value wd;
|
||||
|
||||
hst[hst_p].iPC = fault_PC;
|
||||
hst[hst_p].PSL = PSL | cc;
|
||||
hst[hst_p].opc = opc;
|
||||
hst[hst_p].brdest = brdisp + PC;
|
||||
for (i = 0; i < OPND_SIZE; i++)
|
||||
for (i = 0; i < j; i++)
|
||||
hst[hst_p].opnd[i] = opnd[i];
|
||||
lim = PC - fault_PC;
|
||||
if ((uint32) lim > INST_SIZE) lim = INST_SIZE;
|
||||
for (i = 0; i < lim; i++) {
|
||||
if ((cpu_ex (&wd, fault_PC + i, &cpu_unit, SWMASK ('V'))) == SCPE_OK)
|
||||
hst[hst_p].inst[i] = (uint8) wd;
|
||||
else {
|
||||
hst[hst_p].inst[0] = hst[hst_p].inst[1] = 0xFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
hst_p = hst_p + 1;
|
||||
if (hst_p >= hst_lnt) hst_p = 0;
|
||||
}
|
||||
|
@ -1384,16 +1686,13 @@ for ( ;; ) {
|
|||
break;
|
||||
|
||||
case ADAWI:
|
||||
if (op1 >= 0) { /* reg? ADDW2 */
|
||||
temp = R[op1];
|
||||
r = R[op1] = (op0 + temp) & WMASK;
|
||||
}
|
||||
if (op1 >= 0) temp = R[op1] & WMASK; /* reg? ADDW2 */
|
||||
else {
|
||||
if (op2 & 1) RSVD_OPND_FAULT; /* mem? chk align */
|
||||
temp = Read (op2, L_WORD, WA); /* ok, ADDW2 */
|
||||
}
|
||||
r = (op0 + temp) & WMASK;
|
||||
WRITE_W (r);
|
||||
}
|
||||
CC_ADD_W (r, op0, temp); /* set cc's */
|
||||
break;
|
||||
|
||||
|
@ -2423,7 +2722,7 @@ for ( ;; ) {
|
|||
temp = op_cmpfd (r, rh, op0, op1);
|
||||
WRITE_Q (r, rh);
|
||||
CC_IIZP_FP (r);
|
||||
if ((temp & CC_Z) || ((op1 & FPSIGN)? /* test br cond */
|
||||
if ((temp & CC_Z) || ((op2 & FPSIGN)? /* test br cond */
|
||||
!(temp & CC_N): (temp & CC_N))) BRANCHW (brdisp);
|
||||
break;
|
||||
|
||||
|
@ -2432,7 +2731,7 @@ for ( ;; ) {
|
|||
temp = op_cmpg (r, rh, op0, op1);
|
||||
WRITE_Q (r, rh);
|
||||
CC_IIZP_FP (r);
|
||||
if ((temp & CC_Z) || ((op1 & FPSIGN)? /* test br cond */
|
||||
if ((temp & CC_Z) || ((op2 & FPSIGN)? /* test br cond */
|
||||
!(temp & CC_N): (temp & CC_N))) BRANCHW (brdisp);
|
||||
break;
|
||||
|
||||
|
@ -2637,10 +2936,10 @@ return val;
|
|||
|
||||
int32 ReadOcta (int32 va, int32 *opnd, int32 j, int32 acc)
|
||||
{
|
||||
opnd[j++] = Read (va, L_LONG, RA);
|
||||
opnd[j++] = Read (va + 4, L_LONG, RA);
|
||||
opnd[j++] = Read (va + 8, L_LONG, RA);
|
||||
opnd[j++] = Read (va + 12, L_LONG, RA);
|
||||
opnd[j++] = Read (va, L_LONG, acc);
|
||||
opnd[j++] = Read (va + 4, L_LONG, acc);
|
||||
opnd[j++] = Read (va + 8, L_LONG, acc);
|
||||
opnd[j++] = Read (va + 12, L_LONG, acc);
|
||||
return j;
|
||||
}
|
||||
|
||||
|
@ -2672,7 +2971,10 @@ int32 st;
|
|||
uint32 addr = (uint32) exta;
|
||||
|
||||
if (vptr == NULL) return SCPE_ARG;
|
||||
if (sw & SWMASK ('V')) addr = Test (addr, RD, &st);
|
||||
if (sw & SWMASK ('V')) {
|
||||
int32 acc = cpu_get_vsw (sw);
|
||||
addr = Test (addr, acc, &st);
|
||||
}
|
||||
else addr = addr & PAMASK;
|
||||
if (ADDR_IS_MEM (addr) || ADDR_IS_CDG (addr) ||
|
||||
ADDR_IS_ROM (addr) || ADDR_IS_NVR (addr)) {
|
||||
|
@ -2689,7 +2991,10 @@ t_stat cpu_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw)
|
|||
int32 st;
|
||||
uint32 addr = (uint32) exta;
|
||||
|
||||
if (sw & SWMASK ('V')) addr = Test (addr, RD, &st);
|
||||
if (sw & SWMASK ('V')) {
|
||||
int32 acc = cpu_get_vsw (sw);
|
||||
addr = Test (addr, acc, &st);
|
||||
}
|
||||
else addr = addr & PAMASK;
|
||||
if (ADDR_IS_MEM (addr) || ADDR_IS_CDG (addr) ||
|
||||
ADDR_IS_NVR (addr)) {
|
||||
|
@ -2746,7 +3051,8 @@ static const char *mm_str[] = {
|
|||
if (cptr) {
|
||||
va = (uint32) get_uint (cptr, 16, 0xFFFFFFFF, &r);
|
||||
if (r == SCPE_OK) {
|
||||
pa = Test (va, RD, &st);
|
||||
int32 acc = cpu_get_vsw (sim_switches);
|
||||
pa = Test (va, acc, &st);
|
||||
if (st == PR_OK) fprintf (of, "Virtual %-X = physical %-X\n", va, pa);
|
||||
else fprintf (of, "Virtual %-X: %s\n", va, mm_str[st]);
|
||||
return SCPE_OK;
|
||||
|
@ -2756,6 +3062,21 @@ fprintf (of, "Invalid argument\n");
|
|||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Get access mode for examine, deposit, show virtual */
|
||||
|
||||
int32 cpu_get_vsw (int32 sw)
|
||||
{
|
||||
int32 md;
|
||||
|
||||
set_map_reg (); /* update dyn reg */
|
||||
if (sw & SWMASK ('K')) md = KERN;
|
||||
else if (sw & SWMASK ('E')) md = EXEC;
|
||||
else if (sw & SWMASK ('S')) md = SUPV;
|
||||
else if (sw & SWMASK ('U')) md = USER;
|
||||
else md = PSL_GETCUR (PSL);
|
||||
return ACC_MASK (md);
|
||||
}
|
||||
|
||||
/* Set history */
|
||||
|
||||
t_stat cpu_set_hist (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
|
@ -2788,11 +3109,14 @@ return SCPE_OK;
|
|||
|
||||
t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, void *desc)
|
||||
{
|
||||
int32 i, j, k, di, disp, numspec, lnt;
|
||||
int32 i, k, di, lnt, numspec;
|
||||
char *cptr = (char *) desc;
|
||||
t_stat r;
|
||||
InstHistory *h;
|
||||
extern const char *opcode[];
|
||||
extern t_value *sim_eval;
|
||||
extern t_stat fprint_sym (FILE *ofile, t_addr addr, t_value *val,
|
||||
UNIT *uptr, int32 sw);
|
||||
|
||||
if (hst_lnt == 0) return SCPE_NOFNC; /* enabled? */
|
||||
if (cptr) {
|
||||
|
@ -2806,43 +3130,70 @@ fprintf (st, "PC PSL IR\n\n");
|
|||
for (k = 0; k < lnt; k++) { /* print specified */
|
||||
h = &hst[(di++) % hst_lnt]; /* entry pointer */
|
||||
if (h->iPC == 0) continue; /* filled in? */
|
||||
fprintf(st, "%08X %08X ", h->iPC, h->PSL); /* PC, PSL */
|
||||
fprintf(st, "%08X %08X| ", h->iPC, h->PSL); /* PC, PSL */
|
||||
numspec = drom[h->opc][0] & DR_NSPMASK; /* #specifiers */
|
||||
if (opcode[h->opc] == NULL) /* undefined? */
|
||||
fprintf (st, "%03X (undefined)", h->opc);
|
||||
else if (h->PSL & PSL_FPD) /* FPD set? */
|
||||
fprintf (st, "%s FPD set", opcode[h->opc]);
|
||||
else { /* normal */
|
||||
fprintf (st, "%s", opcode[h->opc]); /* print opcode */
|
||||
for (i = 1, j = 0; i <= numspec; i++) { /* loop thru specs */
|
||||
fputc ((i == 1)? ' ': ',', st); /* separator */
|
||||
disp = drom[h->opc][i]; /* specifier type */
|
||||
if (disp == RG) disp = RQ; /* fix specials */
|
||||
else if (disp >= BB) fprintf (st, "%X", h->brdest);
|
||||
else switch (disp & (DR_LNMASK|DR_ACMASK)) {
|
||||
case RB: case RW: case RL: /* read */
|
||||
case AB: case AW: case AL: case AQ: case AO: /* address */
|
||||
case MB: case MW: case ML: /* modify */
|
||||
fprintf (st, "%X", h->opnd[j++]);
|
||||
break;
|
||||
case RQ: case MQ: /* read, modify quad */
|
||||
fprintf (st, "%X%08X", h->opnd[j], h->opnd[j + 1]);
|
||||
j = j + 2;
|
||||
break;
|
||||
case RO: case MO: /* read, modify octa */
|
||||
fprintf (st, "%X%08X%08X%08X", h->opnd[j],
|
||||
h->opnd[j + 1], h->opnd[j + 2], h->opnd[j + 3]);
|
||||
j = j + 4;
|
||||
break;
|
||||
case WB: case WW: case WL: case WQ: case WO: /* write */
|
||||
if (h->opnd[j] < 0) fprintf (st, "%X", h->opnd[j + 1]);
|
||||
else fprintf (st, "R%d", h->opnd[j]);
|
||||
j = j + 2;
|
||||
break;
|
||||
} /* end case */
|
||||
} /* end for */
|
||||
for (i = 0; i < INST_SIZE; i++) sim_eval[i] = h->inst[i];
|
||||
if ((fprint_sym (st, h->iPC, sim_eval, &cpu_unit, SWMASK ('M'))) > 0)
|
||||
fprintf (st, "%03X (undefined)", h->opc);
|
||||
if ((numspec > 1) ||
|
||||
((numspec == 1) && (drom[h->opc][1] < BB))) {
|
||||
if (cpu_show_opnd (st, h, 0)) { /* operands; more? */
|
||||
if (cpu_show_opnd (st, h, 1)) { /* 2nd line; more? */
|
||||
cpu_show_opnd (st, h, 2); /* octa, 3rd/4th */
|
||||
cpu_show_opnd (st, h, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* end else */
|
||||
fputc ('\n', st); /* end line */
|
||||
} /* end for */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_bool cpu_show_opnd (FILE *st, InstHistory *h, int32 line)
|
||||
{
|
||||
|
||||
int32 numspec, i, j, disp;
|
||||
t_bool more;
|
||||
|
||||
numspec = drom[h->opc][0] & DR_NSPMASK; /* #specifiers */
|
||||
fputs ("\n ", st); /* space */
|
||||
for (i = 1, j = 0, more = FALSE; i <= numspec; i++) { /* loop thru specs */
|
||||
disp = drom[h->opc][i]; /* specifier type */
|
||||
if (disp == RG) disp = RQ; /* fix specials */
|
||||
else if (disp >= BB) break; /* ignore branches */
|
||||
else switch (disp & (DR_LNMASK|DR_ACMASK)) {
|
||||
|
||||
case RB: case RW: case RL: /* read */
|
||||
case AB: case AW: case AL: case AQ: case AO: /* address */
|
||||
case MB: case MW: case ML: /* modify */
|
||||
if (line == 0) fprintf (st, " %08X", h->opnd[j]);
|
||||
else fputs (" ", st);
|
||||
j = j + 1;
|
||||
break;
|
||||
case RQ: case MQ: /* read, modify quad */
|
||||
if (line <= 1) fprintf (st, " %08X", h->opnd[j + line]);
|
||||
else fputs (" ", st);
|
||||
if (line == 0) more = TRUE;
|
||||
j = j + 2;
|
||||
break;
|
||||
case RO: case MO: /* read, modify octa */
|
||||
fprintf (st, " %08X", h->opnd[j + line]);
|
||||
more = TRUE;
|
||||
j = j + 4;
|
||||
break;
|
||||
case WB: case WW: case WL: case WQ: case WO: /* write */
|
||||
if (line == 0) fprintf (st, " %08X", h->opnd[j + 1]);
|
||||
else fputs (" ", st);
|
||||
j = j + 2;
|
||||
break;
|
||||
} /* end case */
|
||||
} /* end for */
|
||||
return more;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* vax_cpu1.c: VAX complex instructions
|
||||
|
||||
Copyright (c) 1998-2005, Robert M Supnik
|
||||
Copyright (c) 1998-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -23,7 +23,9 @@
|
|||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
|
||||
10-May-06 RMS Added access check on system PTE for 11/780
|
||||
Added mbz check in LDPCTX for 11/780
|
||||
22-Sep-06 RMS Fixed declarations (from Sterling Garwood)
|
||||
30-Sep-04 RMS Added conditionals for full VAX
|
||||
Moved emulation to vax_cis.c
|
||||
Moved model-specific IPRs to system module
|
||||
|
@ -1200,7 +1202,7 @@ return newpsl & CC_MASK; /* set new cc */
|
|||
|
||||
void op_ldpctx (int32 acc)
|
||||
{
|
||||
int32 newpc, newpsl, pcbpa;
|
||||
int32 newpc, newpsl, pcbpa, t;
|
||||
|
||||
if (PSL & PSL_CUR) RSVD_INST_FAULT; /* must be kernel */
|
||||
pcbpa = PCBB & PAMASK; /* phys address */
|
||||
|
@ -1224,16 +1226,26 @@ R[12] = ReadLP (pcbpa + 64);
|
|||
R[13] = ReadLP (pcbpa + 68);
|
||||
newpc = ReadLP (pcbpa + 72); /* get PC, PSL */
|
||||
newpsl = ReadLP (pcbpa + 76);
|
||||
P0BR = ReadLP (pcbpa + 80); /* restore mem mgt */
|
||||
P0LR = ReadLP (pcbpa + 84);
|
||||
P1BR = ReadLP (pcbpa + 88);
|
||||
P1LR = ReadLP (pcbpa + 92);
|
||||
ASTLVL = (P0LR >> 24) & AST_MASK; /* restore AST */
|
||||
pme = (P1LR >> 31) & 1; /* restore PME */
|
||||
P0BR = P0BR & BR_MASK;
|
||||
P0LR = P0LR & LR_MASK;
|
||||
P1BR = P1BR & BR_MASK;
|
||||
P1LR = P1LR & LR_MASK;
|
||||
|
||||
t = ReadLP (pcbpa + 80);
|
||||
ML_BR_TEST (t); /* validate P0BR */
|
||||
P0BR = t & BR_MASK; /* restore P0BR */
|
||||
t = ReadLP (pcbpa + 84);
|
||||
LP_MBZ84_TEST (t); /* test mbz */
|
||||
ML_LR_TEST (t & LR_MASK); /* validate P0LR */
|
||||
P0LR = t & LR_MASK; /* restore P0LR */
|
||||
t = (t >> 24) & AST_MASK;
|
||||
LP_AST_TEST (t); /* validate AST */
|
||||
ASTLVL = t; /* restore AST */
|
||||
t = ReadLP (pcbpa + 88);
|
||||
ML_BR_TEST (t + 0x800000); /* validate P1BR */
|
||||
P1BR = t & BR_MASK; /* restore P1BR */
|
||||
t = ReadLP (pcbpa + 92);
|
||||
LP_MBZ92_TEST (t); /* test MBZ */
|
||||
ML_LR_TEST (t & LR_MASK); /* validate P1LR */
|
||||
P1LR = t & LR_MASK; /* restore P1LR */
|
||||
pme = (t >> 31) & 1; /* restore PME */
|
||||
|
||||
zap_tb (0); /* clear process TB */
|
||||
set_map_reg ();
|
||||
if (DEBUG_PRI (cpu_dev, LOG_CPU_P)) fprintf (sim_deb,
|
||||
|
@ -1372,46 +1384,54 @@ switch (prn) { /* case on reg # */
|
|||
break;
|
||||
|
||||
case MT_P0BR: /* P0BR */
|
||||
ML_BR_TEST (val); /* validate */
|
||||
P0BR = val & BR_MASK; /* lw aligned */
|
||||
zap_tb (0); /* clr proc TLB */
|
||||
set_map_reg ();
|
||||
break;
|
||||
|
||||
case MT_P0LR: /* P0LR */
|
||||
ML_LR_TEST (val & LR_MASK); /* validate */
|
||||
P0LR = val & LR_MASK;
|
||||
zap_tb (0); /* clr proc TLB */
|
||||
set_map_reg ();
|
||||
break;
|
||||
|
||||
case MT_P1BR: /* P1BR */
|
||||
ML_BR_TEST (val + 0x800000); /* validate */
|
||||
P1BR = val & BR_MASK; /* lw aligned */
|
||||
zap_tb (0); /* clr proc TLB */
|
||||
set_map_reg ();
|
||||
break;
|
||||
|
||||
case MT_P1LR: /* P1LR */
|
||||
ML_LR_TEST (val & LR_MASK); /* validate */
|
||||
P1LR = val & LR_MASK;
|
||||
zap_tb (0); /* clr proc TLB */
|
||||
set_map_reg ();
|
||||
break;
|
||||
|
||||
case MT_SBR: /* SBR */
|
||||
ML_PA_TEST (val); /* validate */
|
||||
SBR = val & BR_MASK; /* lw aligned */
|
||||
zap_tb (1); /* clr entire TLB */
|
||||
set_map_reg ();
|
||||
break;
|
||||
|
||||
case MT_SLR: /* SLR */
|
||||
ML_LR_TEST (val & LR_MASK); /* validate */
|
||||
SLR = val & LR_MASK;
|
||||
zap_tb (1); /* clr entire TLB */
|
||||
set_map_reg ();
|
||||
break;
|
||||
|
||||
case MT_SCBB: /* SCBB */
|
||||
ML_PA_TEST (val); /* validate */
|
||||
SCBB = val & BR_MASK; /* lw aligned */
|
||||
break;
|
||||
|
||||
case MT_PCBB: /* PCBB */
|
||||
ML_PA_TEST (val); /* validate */
|
||||
PCBB = val & BR_MASK; /* lw aligned */
|
||||
break;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* vax_defs.h: VAX architecture definitions file
|
||||
|
||||
Copyright (c) 1998-2005, Robert M Supnik
|
||||
Copyright (c) 1998-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -26,6 +26,8 @@
|
|||
The author gratefully acknowledges the help of Stephen Shirron, Antonio
|
||||
Carlini, and Kevin Peterson in providing specifications for the Qbus VAX's
|
||||
|
||||
09-May-06 RMS Added system PTE ACV error code
|
||||
03-May-06 RMS Added EDITPC get/put cc's macros
|
||||
03-Nov-05 RMS Added 780 stop codes
|
||||
22-Jul-05 RMS Fixed warning from Solaris C (from Doug Gwyn)
|
||||
02-Sep-04 RMS Added octa specifier definitions
|
||||
|
@ -235,6 +237,7 @@
|
|||
#define PTE_V (1u << PTE_V_V)
|
||||
#define PTE_V_ACC 27 /* access */
|
||||
#define PTE_M_ACC 0xF
|
||||
#define PTE_ACC (PTE_M_ACC << PTE_V_ACC)
|
||||
#define PTE_V_M 26 /* modified */
|
||||
#define PTE_M (1u << PTE_V_M)
|
||||
#define PTE_GETACC(x) (((x) >> PTE_V_ACC) & PTE_M_ACC)
|
||||
|
@ -310,14 +313,19 @@
|
|||
|
||||
/* EDITPC R2 packup parameters */
|
||||
|
||||
#define ED_V_CC 16 /* condition codes */
|
||||
#define ED_M_CC 0xFF
|
||||
#define ED_CC (ED_M_CC << ED_V_CC)
|
||||
#define ED_V_SIGN 8 /* sign */
|
||||
#define ED_M_SIGN 0xFF
|
||||
#define ED_SIGN (ED_M_SIGN << ED_V_SIGN)
|
||||
#define ED_V_FILL 0 /* fill */
|
||||
#define ED_M_FILL 0xFF
|
||||
#define ED_FILL (ED_M_FILL << ED_V_FILL)
|
||||
#define ED_GETCC(x) (((x) >> ED_V_CC) & CC_MASK)
|
||||
#define ED_GETSIGN(x) (((x) >> ED_V_SIGN) & ED_M_SIGN)
|
||||
#define ED_GETFILL(x) (((x) >> ED_V_FILL) & ED_M_FILL)
|
||||
#define ED_PUTCC(r,x) (((r) & ~ED_CC) | (((x) << ED_V_CC) & ED_CC))
|
||||
#define ED_PUTSIGN(r,x) (((r) & ~ED_SIGN) | (((x) << ED_V_SIGN) & ED_SIGN))
|
||||
#define ED_PUTFILL(r,x) (((r) & ~ED_FILL) | (((x) << ED_V_FILL) & ED_FILL))
|
||||
|
||||
|
@ -461,7 +469,7 @@
|
|||
|
||||
#define PR_ACV 0 /* ACV */
|
||||
#define PR_LNV 1 /* length viol */
|
||||
/* #define PR_PACV 2 /* impossible */
|
||||
#define PR_PACV 2 /* pte ACV (780) */
|
||||
#define PR_PLNV 3 /* pte len viol */
|
||||
#define PR_TNV 4 /* TNV */
|
||||
/* #define PR_TB 5 /* impossible */
|
||||
|
|
1133
VAX/vax_doc.txt
1133
VAX/vax_doc.txt
File diff suppressed because it is too large
Load diff
140
VAX/vax_fpa.c
140
VAX/vax_fpa.c
|
@ -1,6 +1,6 @@
|
|||
/* vax_fpa.c - VAX f_, d_, g_floating instructions
|
||||
|
||||
Copyright (c) 1998-2005, Robert M Supnik
|
||||
Copyright (c) 1998-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -23,6 +23,17 @@
|
|||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
16-May-06 RMS Fixed bug in 32b floating multiply routine
|
||||
Fixed bug in 64b extended modulus routine
|
||||
03-May-06 RMS Fixed POLYD, POLYG to clear R4, R5
|
||||
Fixed POLYD, POLYG to set R3 correctly
|
||||
Fixed POLYD, POLYG to not exit prematurely if arg = 0
|
||||
Fixed POLYD, POLYG to do full 64b multiply
|
||||
Fixed POLYF, POLYD, POLYG to remove truncation on add
|
||||
Fixed POLYF, POLYD, POLYG to mask mul reslt to 31b/63b/63b
|
||||
Fixed fp add routine to test for zero via fraction
|
||||
to support "denormal" argument from POLYF, POLYD, POLYG
|
||||
(all reported by Tim Stark)
|
||||
27-Sep-05 RMS Fixed bug in 32b structure definitions (from Jason Stevens)
|
||||
30-Sep-04 RMS Comment and formating changes based on vax_octa.c
|
||||
18-Apr-04 RMS Moved format definitions to vax_defs.h
|
||||
|
@ -93,8 +104,8 @@ void unpackg (int32 hi, int32 lo, UFP *a);
|
|||
void norm (UFP *a);
|
||||
int32 rpackfd (UFP *a, int32 *rh);
|
||||
int32 rpackg (UFP *a, int32 *rh);
|
||||
void vax_fadd (UFP *a, UFP *b, t_int64 mask);
|
||||
void vax_fmul (UFP *a, UFP *b, int32 prec, int32 bias, t_int64 mask);
|
||||
void vax_fadd (UFP *a, UFP *b);
|
||||
void vax_fmul (UFP *a, UFP *b, t_bool qd, int32 bias, uint32 mhi, uint32 mlo);
|
||||
void vax_fdiv (UFP *b, UFP *a, int32 prec, int32 bias);
|
||||
void vax_fmod (UFP *a, int32 bias, int32 *intgr, int32 *flg);
|
||||
|
||||
|
@ -285,7 +296,7 @@ UFP a, b;
|
|||
unpackf (opnd[0], &a); /* unpack operands */
|
||||
unpackf (opnd[2], &b);
|
||||
a.frac = a.frac | (((t_uint64) opnd[1]) << 32); /* extend src1 */
|
||||
vax_fmul (&a, &b, 32, FD_BIAS, LMASK); /* multiply */
|
||||
vax_fmul (&a, &b, 0, FD_BIAS, 0, LMASK); /* multiply */
|
||||
vax_fmod (&a, FD_BIAS, intgr, flg); /* sep int & frac */
|
||||
return rpackfd (&a, NULL); /* return frac */
|
||||
}
|
||||
|
@ -297,7 +308,7 @@ UFP a, b;
|
|||
unpackd (opnd[0], opnd[1], &a); /* unpack operands */
|
||||
unpackd (opnd[3], opnd[4], &b);
|
||||
a.frac = a.frac | opnd[2]; /* extend src1 */
|
||||
vax_fmul (&a, &b, 64, FD_BIAS, 0); /* multiply */
|
||||
vax_fmul (&a, &b, 1, FD_BIAS, 0, 0); /* multiply */
|
||||
vax_fmod (&a, FD_BIAS, intgr, flg); /* sep int & frac */
|
||||
return rpackfd (&a, flo); /* return frac */
|
||||
}
|
||||
|
@ -309,23 +320,23 @@ UFP a, b;
|
|||
unpackg (opnd[0], opnd[1], &a); /* unpack operands */
|
||||
unpackg (opnd[3], opnd[4], &b);
|
||||
a.frac = a.frac | (opnd[2] >> 5); /* extend src1 */
|
||||
vax_fmul (&a, &b, 64, G_BIAS, 0); /* multiply */
|
||||
vax_fmul (&a, &b, 1, G_BIAS, 0, 0); /* multiply */
|
||||
vax_fmod (&a, G_BIAS, intgr, flg); /* sep int & frac */
|
||||
return rpackg (&a, flo); /* return frac */
|
||||
}
|
||||
|
||||
/* Unpacked floating point routines */
|
||||
|
||||
void vax_fadd (UFP *a, UFP *b, t_int64 mask)
|
||||
void vax_fadd (UFP *a, UFP *b)
|
||||
{
|
||||
int32 ediff;
|
||||
UFP t;
|
||||
|
||||
if (a->exp == 0) { /* s1 = 0? */
|
||||
if (a->frac == 0) { /* s1 = 0? */
|
||||
*a = *b;
|
||||
return;
|
||||
}
|
||||
if (b->exp == 0) return; /* s2 = 0? */
|
||||
if (b->frac == 0) return; /* s2 = 0? */
|
||||
if ((a->exp < b->exp) || /* |s1| < |s2|? swap */
|
||||
((a->exp == b->exp) && (a->frac < b->frac))) {
|
||||
t = *a;
|
||||
|
@ -341,7 +352,6 @@ if (a->sign ^ b->sign) { /* eff sub? */
|
|||
a->frac = a->frac + b->frac; /* add frac */
|
||||
}
|
||||
else a->frac = a->frac - b->frac; /* sub frac */
|
||||
a->frac = a->frac & ~mask;
|
||||
norm (a); /* normalize */
|
||||
}
|
||||
else {
|
||||
|
@ -352,16 +362,16 @@ else {
|
|||
a->frac = UF_NM | (a->frac >> 1); /* shift in carry */
|
||||
a->exp = a->exp + 1; /* skip norm */
|
||||
}
|
||||
a->frac = a->frac & ~mask;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Floating multiply - 64b * 64b with cross products */
|
||||
|
||||
void vax_fmul (UFP *a, UFP *b, int32 prec, int32 bias, t_int64 mask)
|
||||
void vax_fmul (UFP *a, UFP *b, t_bool qd, int32 bias, uint32 mhi, uint32 mlo)
|
||||
{
|
||||
t_uint64 ah, bh, al, bl, rhi, rlo, rmid1, rmid2;
|
||||
t_uint64 mask = (((t_uint64) mhi) << 32) | ((t_uint64) mlo);
|
||||
|
||||
if ((a->exp == 0) || (b->exp == 0)) { /* zero argument? */
|
||||
a->frac = a->sign = a->exp = 0; /* result is zero */
|
||||
|
@ -372,7 +382,7 @@ a->exp = a->exp + b->exp - bias; /* add exponents */
|
|||
ah = (a->frac >> 32) & LMASK; /* split operands */
|
||||
bh = (b->frac >> 32) & LMASK; /* into 32b chunks */
|
||||
rhi = ah * bh; /* high result */
|
||||
if (prec > 32) { /* 64b needed? */
|
||||
if (qd) { /* 64b needed? */
|
||||
al = a->frac & LMASK;
|
||||
bl = b->frac & LMASK;
|
||||
rmid1 = ah * bl;
|
||||
|
@ -381,10 +391,10 @@ if (prec > 32) { /* 64b needed? */
|
|||
rhi = rhi + ((rmid1 >> 32) & LMASK) + ((rmid2 >> 32) & LMASK);
|
||||
rmid1 = rlo + (rmid1 << 32); /* add mid1 to lo */
|
||||
if (rmid1 < rlo) rhi = rhi + 1; /* carry? incr hi */
|
||||
rmid2 = rmid1 + (rmid2 << 32); /* add mid2 to to */
|
||||
rmid2 = rmid1 + (rmid2 << 32); /* add mid2 to lo */
|
||||
if (rmid2 < rmid1) rhi = rhi + 1; /* carry? incr hi */
|
||||
}
|
||||
a->frac = rhi & ~mask; /* mask out */
|
||||
a->frac = rhi & ~mask;
|
||||
norm (a); /* normalize */
|
||||
return;
|
||||
}
|
||||
|
@ -402,7 +412,7 @@ return;
|
|||
void vax_fmod (UFP *a, int32 bias, int32 *intgr, int32 *flg)
|
||||
{
|
||||
if (a->exp <= bias) *intgr = *flg = 0; /* 0 or <1? int = 0 */
|
||||
else if (a->exp <= (bias + 64)) { /* in range? */
|
||||
else if (a->exp <= (bias + 64)) { /* in range [1,64]? */
|
||||
*intgr = (int32) (a->frac >> (64 - (a->exp - bias)));
|
||||
if ((a->exp > (bias + 32)) || /* test ovflo */
|
||||
((a->exp == (bias + 32)) &&
|
||||
|
@ -410,7 +420,8 @@ else if (a->exp <= (bias + 64)) { /* in range? */
|
|||
*flg = CC_V;
|
||||
else *flg = 0;
|
||||
if (a->sign) *intgr = -*intgr; /* -? comp int */
|
||||
a->frac = a->frac << (a->exp - bias);
|
||||
if (a->exp == (bias + 64)) a->frac = 0; /* special case 64 */
|
||||
else a->frac = a->frac << (a->exp - bias);
|
||||
a->exp = bias;
|
||||
}
|
||||
else {
|
||||
|
@ -585,11 +596,10 @@ void unpackg (uint32 hi, uint32 lo, UFP *a);
|
|||
void norm (UFP *a);
|
||||
int32 rpackfd (UFP *a, int32 *rh);
|
||||
int32 rpackg (UFP *a, int32 *rh);
|
||||
void vax_fadd (UFP *a, UFP *b, uint32 mask);
|
||||
void vax_fmul (UFP *a, UFP *b, int32 prec, int32 bias, uint32 mask);
|
||||
void vax_fadd (UFP *a, UFP *b);
|
||||
void vax_fmul (UFP *a, UFP *b, t_bool qd, int32 bias, uint32 mhi, uint32 mlo);
|
||||
void vax_fmod (UFP *a, int32 bias, int32 *intgr, int32 *flg);
|
||||
void vax_fdiv (UFP *b, UFP *a, int32 prec, int32 bias);
|
||||
int32 vax_fcmp (UFP *a, UFP *b);
|
||||
void dp_add (UDP *a, UDP *b);
|
||||
void dp_inc (UDP *a);
|
||||
void dp_sub (UDP *a, UDP *b);
|
||||
|
@ -787,7 +797,7 @@ UFP a, b;
|
|||
unpackf (opnd[0], &a); /* unpack operands */
|
||||
unpackf (opnd[2], &b);
|
||||
a.frac.hi = a.frac.hi | opnd[1]; /* extend src1 */
|
||||
vax_fmul (&a, &b, 32, FD_BIAS, LMASK); /* multiply */
|
||||
vax_fmul (&a, &b, 0, FD_BIAS, 0, LMASK); /* multiply */
|
||||
vax_fmod (&a, FD_BIAS, intgr, flg); /* sep int & frac */
|
||||
return rpackfd (&a, NULL); /* return frac */
|
||||
}
|
||||
|
@ -799,7 +809,7 @@ UFP a, b;
|
|||
unpackd (opnd[0], opnd[1], &a); /* unpack operands */
|
||||
unpackd (opnd[3], opnd[4], &b);
|
||||
a.frac.lo = a.frac.lo | opnd[2]; /* extend src1 */
|
||||
vax_fmul (&a, &b, 64, FD_BIAS, 0); /* multiply */
|
||||
vax_fmul (&a, &b, 1, FD_BIAS, 0, 0); /* multiply */
|
||||
vax_fmod (&a, FD_BIAS, intgr, flg); /* sep int & frac */
|
||||
return rpackfd (&a, flo); /* return frac */
|
||||
}
|
||||
|
@ -811,7 +821,7 @@ UFP a, b;
|
|||
unpackg (opnd[0], opnd[1], &a); /* unpack operands */
|
||||
unpackg (opnd[3], opnd[4], &b);
|
||||
a.frac.lo = a.frac.lo | (opnd[2] >> 5); /* extend src1 */
|
||||
vax_fmul (&a, &b, 64, G_BIAS, 0); /* multiply */
|
||||
vax_fmul (&a, &b, 1, G_BIAS, 0, 0); /* multiply */
|
||||
vax_fmod (&a, G_BIAS, intgr, flg); /* sep int & frac */
|
||||
return rpackg (&a, flo); /* return frac */
|
||||
}
|
||||
|
@ -820,16 +830,16 @@ return rpackg (&a, flo); /* return frac */
|
|||
|
||||
/* Floating add */
|
||||
|
||||
void vax_fadd (UFP *a, UFP *b, uint32 mask)
|
||||
void vax_fadd (UFP *a, UFP *b)
|
||||
{
|
||||
int32 ediff;
|
||||
UFP t;
|
||||
|
||||
if (a->exp == 0) { /* s1 = 0? */
|
||||
if ((a->frac.hi == 0) && (a->frac.lo == 0)) { /* s1 = 0? */
|
||||
*a = *b;
|
||||
return;
|
||||
}
|
||||
if (b->exp == 0) return; /* s2 = 0? */
|
||||
if ((b->frac.hi == 0) && (b->frac.lo == 0)) return; /* s2 = 0? */
|
||||
if ((a->exp < b->exp) || /* |s1| < |s2|? swap */
|
||||
((a->exp == b->exp) && (dp_cmp (&a->frac, &b->frac) < 0))) {
|
||||
t = *a;
|
||||
|
@ -844,7 +854,6 @@ if (a->sign ^ b->sign) { /* eff sub? */
|
|||
dp_add (&a->frac, &b->frac); /* "add" frac */
|
||||
}
|
||||
else dp_sub (&a->frac, &b->frac); /* a >= b */
|
||||
a->frac.lo = a->frac.lo & ~mask; /* trim low result */
|
||||
norm (a); /* normalize */
|
||||
}
|
||||
else {
|
||||
|
@ -855,28 +864,13 @@ else {
|
|||
a->frac.hi = a->frac.hi | UF_NM_H; /* add norm bit */
|
||||
a->exp = a->exp + 1; /* skip norm */
|
||||
}
|
||||
a->frac.lo = a->frac.lo & ~mask; /* trim low result */
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Floating compare */
|
||||
|
||||
int32 vax_fcmp (UFP *a, UFP *b)
|
||||
{
|
||||
int32 r;
|
||||
|
||||
if (a->sign != b->sign) return ((a->sign)? CC_N: 0);
|
||||
r = a->exp - b->exp;
|
||||
if (r == 0) r = dp_cmp (&a->frac, &b->frac);
|
||||
if (r == 0) return CC_Z;
|
||||
if (r < 0) return (a->sign? 0: CC_N);
|
||||
else return (a->sign? CC_N: 0);
|
||||
}
|
||||
|
||||
/* Floating multiply - 64b * 64b with cross products */
|
||||
|
||||
void vax_fmul (UFP *a, UFP *b, int32 prec, int32 bias, uint32 mask)
|
||||
void vax_fmul (UFP *a, UFP *b, t_bool qd, int32 bias, uint32 mhi, uint32 mlo)
|
||||
{
|
||||
UDP rhi, rlo, rmid1, rmid2;
|
||||
|
||||
|
@ -888,7 +882,7 @@ if ((a->exp == 0) || (b->exp == 0)) { /* zero argument? */
|
|||
a->sign = a->sign ^ b->sign; /* sign of result */
|
||||
a->exp = a->exp + b->exp - bias; /* add exponents */
|
||||
dp_imul (a->frac.hi, b->frac.hi, &rhi); /* high result */
|
||||
if (prec > 32) { /* 64b needed? */
|
||||
if (qd) { /* 64b needed? */
|
||||
dp_imul (a->frac.hi, b->frac.lo, &rmid1); /* cross products */
|
||||
dp_imul (a->frac.lo, b->frac.hi, &rmid2);
|
||||
dp_imul (a->frac.lo, b->frac.lo, &rlo); /* low result */
|
||||
|
@ -901,10 +895,10 @@ if (prec > 32) { /* 64b needed? */
|
|||
rlo.hi = (rlo.hi + rmid1.lo) & LMASK; /* add mid1 to low res */
|
||||
if (rlo.hi < rmid1.lo) dp_inc (&rhi); /* carry? incr high res */
|
||||
rlo.hi = (rlo.hi + rmid2.lo) & LMASK; /* add mid2 to low res */
|
||||
if (rlo.hi < rmid1.hi) dp_inc (&rhi); /* carry? incr high res */
|
||||
if (rlo.hi < rmid2.lo) dp_inc (&rhi); /* carry? incr high res */
|
||||
}
|
||||
a->frac.hi = rhi.hi; /* mask low fraction */
|
||||
a->frac.lo = rhi.lo & ~mask;
|
||||
a->frac.hi = rhi.hi & ~mhi; /* mask fraction */
|
||||
a->frac.lo = rhi.lo & ~mlo;
|
||||
norm (a); /* normalize */
|
||||
return;
|
||||
}
|
||||
|
@ -924,7 +918,7 @@ void vax_fmod (UFP *a, int32 bias, int32 *intgr, int32 *flg)
|
|||
UDP ifr;
|
||||
|
||||
if (a->exp <= bias) *intgr = *flg = 0; /* 0 or <1? int = 0 */
|
||||
else if (a->exp <= (bias + 64)) { /* in range? */
|
||||
else if (a->exp <= (bias + 64)) { /* in range [1,64]? */
|
||||
ifr = a->frac;
|
||||
dp_rsh (&ifr, 64 - (a->exp - bias)); /* separate integer */
|
||||
if ((a->exp > (bias + 32)) || /* test ovflo */
|
||||
|
@ -1277,7 +1271,7 @@ UFP a, b;
|
|||
unpackf (opnd[0], &a); /* F format */
|
||||
unpackf (opnd[1], &b);
|
||||
if (sub) a.sign = a.sign ^ FPSIGN; /* sub? -s1 */
|
||||
vax_fadd (&a, &b, 0); /* add fractions */
|
||||
vax_fadd (&a, &b); /* add fractions */
|
||||
return rpackfd (&a, NULL);
|
||||
}
|
||||
|
||||
|
@ -1288,7 +1282,7 @@ UFP a, b;
|
|||
unpackd (opnd[0], opnd[1], &a);
|
||||
unpackd (opnd[2], opnd[3], &b);
|
||||
if (sub) a.sign = a.sign ^ FPSIGN; /* sub? -s1 */
|
||||
vax_fadd (&a, &b, 0); /* add fractions */
|
||||
vax_fadd (&a, &b); /* add fractions */
|
||||
return rpackfd (&a, rh);
|
||||
}
|
||||
|
||||
|
@ -1299,7 +1293,7 @@ UFP a, b;
|
|||
unpackg (opnd[0], opnd[1], &a);
|
||||
unpackg (opnd[2], opnd[3], &b);
|
||||
if (sub) a.sign = a.sign ^ FPSIGN; /* sub? -s1 */
|
||||
vax_fadd (&a, &b, 0); /* add fractions */
|
||||
vax_fadd (&a, &b); /* add fractions */
|
||||
return rpackg (&a, rh); /* round and pack */
|
||||
}
|
||||
|
||||
|
@ -1311,7 +1305,7 @@ UFP a, b;
|
|||
|
||||
unpackf (opnd[0], &a); /* F format */
|
||||
unpackf (opnd[1], &b);
|
||||
vax_fmul (&a, &b, 24, FD_BIAS, 0); /* do multiply */
|
||||
vax_fmul (&a, &b, 0, FD_BIAS, 0, 0); /* do multiply */
|
||||
return rpackfd (&a, NULL); /* round and pack */
|
||||
}
|
||||
|
||||
|
@ -1319,9 +1313,9 @@ int32 op_muld (int32 *opnd, int32 *rh)
|
|||
{
|
||||
UFP a, b;
|
||||
|
||||
unpackd (opnd[0], opnd[1], &a);
|
||||
unpackd (opnd[0], opnd[1], &a); /* D format */
|
||||
unpackd (opnd[2], opnd[3], &b);
|
||||
vax_fmul (&a, &b, 56, FD_BIAS, 0); /* do multiply */
|
||||
vax_fmul (&a, &b, 1, FD_BIAS, 0, 0); /* do multiply */
|
||||
return rpackfd (&a, rh); /* round and pack */
|
||||
}
|
||||
|
||||
|
@ -1331,7 +1325,7 @@ UFP a, b;
|
|||
|
||||
unpackg (opnd[0], opnd[1], &a); /* G format */
|
||||
unpackg (opnd[2], opnd[3], &b);
|
||||
vax_fmul (&a, &b, 53, G_BIAS, 0); /* do multiply */
|
||||
vax_fmul (&a, &b, 1, G_BIAS, 0, 0); /* do multiply */
|
||||
return rpackg (&a, rh); /* round and pack */
|
||||
}
|
||||
|
||||
|
@ -1351,7 +1345,7 @@ int32 op_divd (int32 *opnd, int32 *rh)
|
|||
{
|
||||
UFP a, b;
|
||||
|
||||
unpackd (opnd[0], opnd[1], &a);
|
||||
unpackd (opnd[0], opnd[1], &a); /* D format */
|
||||
unpackd (opnd[2], opnd[3], &b);
|
||||
vax_fdiv (&a, &b, 58, FD_BIAS); /* do divide */
|
||||
return rpackfd (&b, rh); /* round and pack */
|
||||
|
@ -1370,9 +1364,9 @@ return rpackg (&b, rh); /* round and pack */
|
|||
/* Polynomial evaluation
|
||||
The most mis-implemented instruction in the VAX (probably here too).
|
||||
POLY requires a precise combination of masking versus normalizing
|
||||
to achieve the desired answer. In particular, both the multiply
|
||||
and add steps are masked prior to normalization. In addition,
|
||||
negative small fractions must not be treated as 0 during denorm.
|
||||
to achieve the desired answer. In particular, the multiply step
|
||||
is masked prior to normalization. In addition, negative small
|
||||
fractions must not be treated as 0 during denorm.
|
||||
*/
|
||||
|
||||
void op_polyf (int32 *opnd, int32 acc)
|
||||
|
@ -1388,18 +1382,18 @@ wd = Read (ptr, L_LONG, RD); /* get C0 */
|
|||
ptr = ptr + 4;
|
||||
unpackf (wd, &r); /* unpack C0 */
|
||||
res = rpackfd (&r, NULL); /* first result */
|
||||
for (i = 0; (i < deg) && a.exp; i++) { /* loop */
|
||||
for (i = 0; i < deg; i++) { /* loop */
|
||||
unpackf (res, &r); /* unpack result */
|
||||
vax_fmul (&r, &a, 32, FD_BIAS, LMASK); /* r = r * arg */
|
||||
vax_fmul (&r, &a, 0, FD_BIAS, 1, LMASK); /* r = r * arg, mask */
|
||||
wd = Read (ptr, L_LONG, RD); /* get Cnext */
|
||||
ptr = ptr + 4;
|
||||
unpackf (wd, &c); /* unpack Cnext */
|
||||
vax_fadd (&r, &c, LMASK); /* r = r + Cnext */
|
||||
vax_fadd (&r, &c); /* r = r + Cnext */
|
||||
res = rpackfd (&r, NULL); /* round and pack */
|
||||
}
|
||||
R[0] = res;
|
||||
R[1] = R[2] = 0;
|
||||
R[3] = opnd[2] + 4 + (opnd[1] << 2);
|
||||
R[3] = ptr;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1417,20 +1411,22 @@ wd1 = Read (ptr + 4, L_LONG, RD);
|
|||
ptr = ptr + 8;
|
||||
unpackd (wd, wd1, &r); /* unpack C0 */
|
||||
res = rpackfd (&r, &resh); /* first result */
|
||||
for (i = 0; (i < deg) && a.exp; i++) { /* loop */
|
||||
for (i = 0; i < deg; i++) { /* loop */
|
||||
unpackd (res, resh, &r); /* unpack result */
|
||||
vax_fmul (&r, &a, 32, FD_BIAS, 0); /* r = r * arg */
|
||||
vax_fmul (&r, &a, 1, FD_BIAS, 0, 1); /* r = r * arg, mask */
|
||||
wd = Read (ptr, L_LONG, RD); /* get Cnext */
|
||||
wd1 = Read (ptr + 4, L_LONG, RD);
|
||||
ptr = ptr + 8;
|
||||
unpackd (wd, wd1, &c); /* unpack Cnext */
|
||||
vax_fadd (&r, &c, 0); /* r = r + Cnext */
|
||||
vax_fadd (&r, &c); /* r = r + Cnext */
|
||||
res = rpackfd (&r, &resh); /* round and pack */
|
||||
}
|
||||
R[0] = res;
|
||||
R[1] = resh;
|
||||
R[2] = 0;
|
||||
R[3] = opnd[3] + 4 + (opnd[2] << 2);
|
||||
R[3] = ptr;
|
||||
R[4] = 0;
|
||||
R[5] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1448,19 +1444,21 @@ wd1 = Read (ptr + 4, L_LONG, RD);
|
|||
ptr = ptr + 8;
|
||||
unpackg (wd, wd1, &r); /* unpack C0 */
|
||||
res = rpackg (&r, &resh); /* first result */
|
||||
for (i = 0; (i < deg) && a.exp; i++) { /* loop */
|
||||
for (i = 0; i < deg; i++) { /* loop */
|
||||
unpackg (res, resh, &r); /* unpack result */
|
||||
vax_fmul (&r, &a, 32, G_BIAS, 0); /* r = r * arg */
|
||||
vax_fmul (&r, &a, 1, G_BIAS, 0, 1); /* r = r * arg */
|
||||
wd = Read (ptr, L_LONG, RD); /* get Cnext */
|
||||
wd1 = Read (ptr + 4, L_LONG, RD);
|
||||
ptr = ptr + 8;
|
||||
unpackg (wd, wd1, &c); /* unpack Cnext */
|
||||
vax_fadd (&r, &c, 0); /* r = r + Cnext */
|
||||
vax_fadd (&r, &c); /* r = r + Cnext */
|
||||
res = rpackg (&r, &resh); /* round and pack */
|
||||
}
|
||||
R[0] = res;
|
||||
R[1] = resh;
|
||||
R[2] = 0;
|
||||
R[3] = opnd[3] + 4 + (opnd[2] << 2);
|
||||
R[3] = ptr;
|
||||
R[4] = 0;
|
||||
R[5] = 0;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -151,13 +151,15 @@ DEVICE tlb_dev = {
|
|||
3. Using the two physical addresses, do an unaligned read or
|
||||
write, with three cases: unaligned long, unaligned word within
|
||||
a longword, unaligned word crossing a longword boundary.
|
||||
|
||||
Note that these routines do not handle quad or octa references.
|
||||
*/
|
||||
|
||||
/* Read virtual
|
||||
|
||||
Inputs:
|
||||
va = virtual address
|
||||
lnt = length code (BWLQ)
|
||||
lnt = length code (BWL)
|
||||
acc = access code (KESU)
|
||||
Output:
|
||||
returned data, right justified in 32b longword
|
||||
|
@ -216,7 +218,7 @@ else {
|
|||
Inputs:
|
||||
va = virtual address
|
||||
val = data to be written, right justified in 32b lw
|
||||
lnt = length code (BWLQ)
|
||||
lnt = length code (BWL)
|
||||
acc = access code (KESU)
|
||||
Output:
|
||||
none
|
||||
|
@ -440,7 +442,8 @@ int32 tlbpte, ptead, pte, tbi, vpn;
|
|||
static TLBENT zero_pte = { 0, 0 };
|
||||
|
||||
if (va & VA_S0) { /* system space? */
|
||||
if (ptidx >= d_slr) MM_ERR (PR_LNV); /* system */
|
||||
if (ptidx >= d_slr) /* system */
|
||||
MM_ERR (PR_LNV);
|
||||
ptead = d_sbr + ptidx;
|
||||
}
|
||||
else {
|
||||
|
@ -458,8 +461,12 @@ else {
|
|||
tbi = VA_GETTBI (vpn);
|
||||
if (stlb[tbi].tag != vpn) { /* in sys tlb? */
|
||||
ptidx = ((uint32) ptead) >> 7; /* xlate like sys */
|
||||
if (ptidx >= d_slr) MM_ERR (PR_PLNV);
|
||||
if (ptidx >= d_slr)
|
||||
MM_ERR (PR_PLNV);
|
||||
pte = ReadLP (d_sbr + ptidx); /* get system pte */
|
||||
#if defined (VAX_780)
|
||||
if ((pte & PTE_ACC) == 0) MM_ERR (PR_PACV); /* spte ACV? */
|
||||
#endif
|
||||
if ((pte & PTE_V) == 0) MM_ERR (PR_PTNV); /* spte TNV? */
|
||||
stlb[tbi].tag = vpn; /* set stlb tag */
|
||||
stlb[tbi].pte = cvtacc[PTE_GETACC (pte)] |
|
||||
|
|
160
VAX/vax_octa.c
160
VAX/vax_octa.c
|
@ -1,6 +1,6 @@
|
|||
/* vax_octa.c - VAX octaword and h_floating instructions
|
||||
|
||||
Copyright (c) 2004-2005, Robert M Supnik
|
||||
Copyright (c) 2004-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,18 @@
|
|||
|
||||
This module simulates the VAX h_floating instruction set.
|
||||
|
||||
10-May-06 RMS Fixed bug in reported VA on faulting cross-page write
|
||||
03-May-06 RMS Fixed MNEGH to test negated sign, clear C
|
||||
Fixed carry propagation in qp_inc, qp_neg, qp_add
|
||||
Fixed pack routines to test for zero via fraction
|
||||
Fixed ACBH to set cc's on result
|
||||
Fixed POLYH to set R3 correctly
|
||||
Fixed POLYH to not exit prematurely if arg = 0
|
||||
Fixed POLYH to mask mul reslt to 127b
|
||||
Fixed fp add routine to test for zero via fraction
|
||||
to support "denormal" argument from POLYH
|
||||
Fixed EMODH to concatenate 15b of 16b extension
|
||||
(all reported by Tim Stark)
|
||||
15-Jul-04 RMS Cloned from 32b VAX floating point implementation
|
||||
*/
|
||||
|
||||
|
@ -83,10 +95,11 @@ 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_o (int32 spec, int32 va, int32 *val, int32 acc);
|
||||
void vax_hadd (UFPH *a, UFPH *b);
|
||||
void vax_hmul (UFPH *a, UFPH *b);
|
||||
void vax_hmul (UFPH *a, UFPH *b, uint32 mlo);
|
||||
void vax_hmod (UFPH *a, int32 *intgr, int32 *flg);
|
||||
void vax_hdiv (UFPH *a, UFPH *b);
|
||||
void qp_add (UQP *a, UQP *b);
|
||||
uint32 qp_add (UQP *a, UQP *b);
|
||||
uint32 qp_sub (UQP *a, UQP *b);
|
||||
void qp_inc (UQP *a);
|
||||
void qp_lsh (UQP *a, uint32 sc);
|
||||
void qp_rsh (UQP *a, uint32 sc);
|
||||
|
@ -172,19 +185,26 @@ switch (opc) {
|
|||
break;
|
||||
|
||||
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 */
|
||||
else h_write_o (spec, va, z_octa, acc); /* zero, write 0 */
|
||||
CC_IIZP_FP (r); /* set cc's */
|
||||
}
|
||||
else { /* zero */
|
||||
h_write_o (spec, va, z_octa, acc); /* write 0 */
|
||||
cc = (cc & CC_C) | CC_Z; /* set cc's */
|
||||
}
|
||||
break;
|
||||
|
||||
case MNEGH:
|
||||
if (r = op_tsth (opnd[0])) { /* test for 0 */
|
||||
opnd[0] = opnd[0] ^ FPSIGN; /* nz, invert sign */
|
||||
h_write_o (spec, va, opnd, acc); /* write result */
|
||||
CC_IIZZ_FP (opnd[0]); /* set cc's */
|
||||
}
|
||||
else { /* zero */
|
||||
h_write_o (spec, va, z_octa, acc); /* write 0 */
|
||||
cc = CC_Z; /* set cc's */
|
||||
}
|
||||
else h_write_o (spec, va, z_octa, acc); /* zero, write 0 */
|
||||
CC_IIZZ_FP (r); /* set cc's */
|
||||
break;
|
||||
|
||||
/* CMPH
|
||||
|
@ -365,6 +385,7 @@ switch (opc) {
|
|||
|
||||
case ACBH:
|
||||
r = op_addh (opnd + 4, r_octa, FALSE); /* add + index */
|
||||
CC_IIZP_FP (r); /* set cc's */
|
||||
temp = op_cmph (r_octa, opnd); /* result : limit */
|
||||
h_write_o (spec, va, r_octa, acc); /* write 2nd */
|
||||
if ((temp & CC_Z) || ((opnd[4] & FPSIGN)? /* test br cond */
|
||||
|
@ -501,7 +522,7 @@ int32 op_cvtfdh (int32 vl, int32 vh, int32 *hflt)
|
|||
UFPH a;
|
||||
|
||||
h_unpackfd (vl, vh, &a); /* unpack f/d */
|
||||
a.exp = a.exp - FD_BIAS + H_BIAS; /* adjust exp */
|
||||
a.exp = a.exp - FD_BIAS + H_BIAS; /* if nz, adjust exp */
|
||||
return h_rpackh (&a, hflt); /* round and pack */
|
||||
}
|
||||
|
||||
|
@ -510,7 +531,7 @@ int32 op_cvtgh (int32 vl, int32 vh, int32 *hflt)
|
|||
UFPH a;
|
||||
|
||||
h_unpackg (vl, vh, &a); /* unpack g */
|
||||
a.exp = a.exp - G_BIAS + H_BIAS; /* adjust exp */
|
||||
a.exp = a.exp - G_BIAS + H_BIAS; /* if nz, adjust exp */
|
||||
return h_rpackh (&a, hflt); /* round and pack */
|
||||
}
|
||||
|
||||
|
@ -519,7 +540,7 @@ int32 op_cvthfd (int32 *hflt, int32 *rh)
|
|||
UFPH a;
|
||||
|
||||
h_unpackh (hflt, &a); /* unpack h */
|
||||
a.exp = a.exp - H_BIAS + FD_BIAS; /* adjust exp */
|
||||
a.exp = a.exp - H_BIAS + FD_BIAS; /* if nz, adjust exp */
|
||||
return h_rpackfd (&a, rh); /* round and pack */
|
||||
}
|
||||
|
||||
|
@ -528,7 +549,7 @@ int32 op_cvthg (int32 *hflt, int32 *rh)
|
|||
UFPH a;
|
||||
|
||||
h_unpackh (hflt, &a); /* unpack h */
|
||||
a.exp = a.exp - H_BIAS + G_BIAS; /* adjust exp */
|
||||
a.exp = a.exp - H_BIAS + G_BIAS; /* if nz, adjust exp */
|
||||
return h_rpackg (&a, rh); /* round and pack */
|
||||
}
|
||||
|
||||
|
@ -553,7 +574,7 @@ UFPH a, b;
|
|||
|
||||
h_unpackh (&opnd[0], &a); /* unpack s1, s2 */
|
||||
h_unpackh (&opnd[4], &b);
|
||||
vax_hmul (&a, &b); /* do multiply */
|
||||
vax_hmul (&a, &b, 0); /* do multiply */
|
||||
return h_rpackh (&a, hflt); /* round and pack */
|
||||
}
|
||||
|
||||
|
@ -566,7 +587,7 @@ UFPH a, b;
|
|||
h_unpackh (&opnd[0], &a); /* unpack s1, s2 */
|
||||
h_unpackh (&opnd[4], &b);
|
||||
vax_hdiv (&a, &b); /* do divide */
|
||||
return h_rpackh (&a, hflt); /* round and pack */
|
||||
return h_rpackh (&b, hflt); /* round and pack */
|
||||
}
|
||||
|
||||
/* Polynomial evaluation
|
||||
|
@ -593,9 +614,9 @@ wd[3] = Read (ptr + 12, L_LONG, RD);
|
|||
ptr = ptr + 16; /* adv ptr */
|
||||
h_unpackh (wd, &r); /* unpack C0 */
|
||||
h_rpackh (&r, res); /* first result */
|
||||
for (i = 0; (i < deg) && a.exp; i++) { /* loop */
|
||||
for (i = 0; i < deg; i++) { /* loop */
|
||||
h_unpackh (res, &r); /* unpack result */
|
||||
vax_hmul (&r, &a); /* r = r * arg */
|
||||
vax_hmul (&r, &a, 1); /* r = r * arg */
|
||||
wd[0] = Read (ptr, L_LONG, RD); /* get Cn */
|
||||
wd[1] = Read (ptr + 4, L_LONG, RD);
|
||||
wd[2] = Read (ptr + 8, L_LONG, RD);
|
||||
|
@ -610,7 +631,7 @@ R[1] = res[1];
|
|||
R[2] = res[2];
|
||||
R[3] = res[3];
|
||||
R[4] = 0;
|
||||
R[5] = opnd[5] + 4 + (opnd[4] << 2);
|
||||
R[5] = ptr;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -627,8 +648,8 @@ UFPH a, b;
|
|||
|
||||
h_unpackh (&opnd[0], &a); /* unpack operands */
|
||||
h_unpackh (&opnd[5], &b);
|
||||
a.frac.f0 = a.frac.f0 | opnd[4]; /* extend src1 */
|
||||
vax_hmul (&a, &b); /* multiply */
|
||||
a.frac.f0 = a.frac.f0 | (opnd[4] >> 1); /* extend src1 */
|
||||
vax_hmul (&a, &b, 0); /* multiply */
|
||||
vax_hmod (&a, intgr, flg); /* sep int & frac */
|
||||
return h_rpackh (&a, hflt); /* round and pack frac */
|
||||
}
|
||||
|
@ -642,11 +663,14 @@ void vax_hadd (UFPH *a, UFPH *b)
|
|||
int32 ediff;
|
||||
UFPH t;
|
||||
|
||||
if (a->exp == 0) { /* s1 = 0? */
|
||||
if ((a->frac.f3 == 0) && (a->frac.f2 == 0) && /* s1 = 0? */
|
||||
(a->frac.f1 == 0) && (a->frac.f0 == 0)) {
|
||||
*a = *b; /* result is s2 */
|
||||
return;
|
||||
}
|
||||
if (b->exp == 0) return; /* s2 = 0? */
|
||||
if ((b->frac.f3 == 0) && (b->frac.f2 == 0) && /* s2 = 0? */
|
||||
(b->frac.f1 == 0) && (b->frac.f0 == 0))
|
||||
return;
|
||||
if ((a->exp < b->exp) || /* |s1| < |s2|? */
|
||||
((a->exp == b->exp) && (qp_cmp (&a->frac, &b->frac) < 0))) {
|
||||
t = *a; /* swap */
|
||||
|
@ -662,8 +686,7 @@ if (a->sign ^ b->sign) { /* eff sub? */
|
|||
}
|
||||
else {
|
||||
if (ediff) qp_rsh (&b->frac, ediff); /* add, denormalize */
|
||||
qp_add (&a->frac, &b->frac); /* add frac */
|
||||
if (qp_cmp (&a->frac, &b->frac) < 0) { /* chk for carry */
|
||||
if (qp_add (&a->frac, &b->frac)) { /* add frac, carry? */
|
||||
qp_rsh (&a->frac, 1); /* renormalize */
|
||||
a->frac.f3 = a->frac.f3 | UH_NM_H; /* add norm bit */
|
||||
a->exp = a->exp + 1; /* incr exp */
|
||||
|
@ -674,9 +697,9 @@ return;
|
|||
|
||||
/* Floating multiply - 128b * 128b */
|
||||
|
||||
void vax_hmul (UFPH *a, UFPH *b)
|
||||
void vax_hmul (UFPH *a, UFPH *b, uint32 mlo)
|
||||
{
|
||||
int32 i;
|
||||
int32 i, c;
|
||||
UQP accum = { 0, 0, 0, 0 };
|
||||
|
||||
if ((a->exp == 0) || (b->exp == 0)) { /* zero argument? */
|
||||
|
@ -688,11 +711,14 @@ if ((a->exp == 0) || (b->exp == 0)) { /* zero argument? */
|
|||
a->sign = a->sign ^ b->sign; /* sign of result */
|
||||
a->exp = a->exp + b->exp - H_BIAS; /* add exponents */
|
||||
for (i = 0; i < 128; i++) { /* quad precision */
|
||||
if (a->frac.f0 & 1) c = qp_add (&accum, &b->frac); /* mplr low? add */
|
||||
else c = 0;
|
||||
qp_rsh (&accum, 1); /* shift result */
|
||||
if (a->frac.f0 & 1) qp_add (&accum, &b->frac); /* mplr low? add */
|
||||
if (c) accum.f3 = accum.f3 | UH_NM_H; /* add carry out */
|
||||
qp_rsh (&a->frac, 1); /* shift mplr */
|
||||
}
|
||||
a->frac = accum; /* result */
|
||||
a->frac.f0 = a->frac.f0 & ~mlo; /* mask low frac */
|
||||
h_normh (a); /* normalize */
|
||||
return;
|
||||
}
|
||||
|
@ -743,7 +769,7 @@ return;
|
|||
void vax_hdiv (UFPH *a, UFPH *b)
|
||||
{
|
||||
int32 i;
|
||||
UQP ndvr, quo = { 0, 0, 0, 0 };
|
||||
UQP quo = { 0, 0, 0, 0 };
|
||||
|
||||
if (a->exp == 0) FLT_DZRO_FAULT; /* divr = 0? */
|
||||
if (b->exp == 0) return; /* divd = 0? */
|
||||
|
@ -751,12 +777,10 @@ b->sign = b->sign ^ a->sign; /* result sign */
|
|||
b->exp = b->exp - a->exp + H_BIAS + 1; /* unbiased exp */
|
||||
qp_rsh (&a->frac, 1); /* allow 1 bit left */
|
||||
qp_rsh (&b->frac, 1);
|
||||
ndvr = a->frac; /* copy divisor */
|
||||
qp_neg (&ndvr); /* and negate */
|
||||
for (i = 0; i < 128; i++) { /* divide loop */
|
||||
qp_lsh (&quo, 1); /* shift quo */
|
||||
if (qp_cmp (&b->frac, &a->frac) >= 0) { /* div step ok? */
|
||||
qp_add (&b->frac, &ndvr); /* "subtract" */
|
||||
qp_sub (&b->frac, &a->frac); /* subtract */
|
||||
quo.f0 = quo.f0 + 1; /* quo bit = 1 */
|
||||
}
|
||||
qp_lsh (&b->frac, 1); /* shift divd */
|
||||
|
@ -781,33 +805,63 @@ if (a->f0 > b->f0) return +1;
|
|||
return 0; /* all equal */
|
||||
}
|
||||
|
||||
void qp_add (UQP *a, UQP *b)
|
||||
uint32 qp_add (UQP *a, UQP *b)
|
||||
{
|
||||
uint32 cry1, cry2, cry3, cry4;
|
||||
|
||||
a->f0 = (a->f0 + b->f0) & LMASK; /* add lo */
|
||||
if (a->f0 < b->f0) a->f1 = a->f1 + 1; /* carry? */
|
||||
a->f1 = (a->f1 + b->f1) & LMASK; /* add mid2 */
|
||||
if (a->f1 < b->f1) a->f2 = a->f2 + 1; /* carry? */
|
||||
a->f2 = (a->f2 + b->f2) & LMASK; /* add mid1 */
|
||||
if (a->f2 < b->f2) a->f3 = a->f3 + 1; /* carry? */
|
||||
a->f3 = (a->f3 + b->f3) & LMASK; /* add hi */
|
||||
return;
|
||||
cry1 = (a->f0 < b->f0); /* carry? */
|
||||
a->f1 = (a->f1 + b->f1 + cry1) & LMASK; /* add mid2 */
|
||||
cry2 = (a->f1 < b->f1) || (cry1 && (a->f1 == b->f1)); /* carry? */
|
||||
a->f2 = (a->f2 + b->f2 + cry2) & LMASK; /* add mid1 */
|
||||
cry3 = (a->f2 < b->f2) || (cry2 && (a->f2 == b->f2)); /* carry? */
|
||||
a->f3 = (a->f3 + b->f3 + cry3) & LMASK; /* add hi */
|
||||
cry4 = (a->f3 < b->f3) || (cry3 && (a->f3 == b->f3)); /* carry? */
|
||||
return cry4; /* return carry out */
|
||||
}
|
||||
|
||||
void qp_inc (UQP *a)
|
||||
{
|
||||
a->f0 = (a->f0 + 1) & LMASK; /* inc lo */
|
||||
if (a->f0 == 0) a->f1 = (a->f1 + 1) & LMASK; /* propagate carry */
|
||||
if (a->f1 == 0) a->f2 = (a->f2 + 1) & LMASK;
|
||||
if (a->f2 == 0) a->f3 = (a->f3 + 1) & LMASK;
|
||||
if (a->f0 == 0) { /* propagate carry */
|
||||
a->f1 = (a->f1 + 1) & LMASK;
|
||||
if (a->f1 == 0) {
|
||||
a->f2 = (a->f2 + 1) & LMASK;
|
||||
if (a->f2 == 0) {
|
||||
a->f3 = (a->f3 + 1) & LMASK;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void qp_neg (UQP *r)
|
||||
uint32 qp_sub (UQP *a, UQP *b)
|
||||
{
|
||||
r->f0 = NEG (r->f0); /* neg lo */
|
||||
r->f1 = (~r->f1 + (r->f0 == 0)) & LMASK; /* complement rest */
|
||||
r->f2 = (~r->f2 + (r->f1 == 0)) & LMASK; /* propagate carry */
|
||||
r->f3 = (~r->f3 + (r->f2 == 0)) & LMASK;
|
||||
uint32 brw1, brw2, brw3, brw4;
|
||||
|
||||
brw1 = (a->f0 < b->f0); /* borrow? */
|
||||
a->f0 = (a->f0 - b->f0) & LMASK; /* sub lo */
|
||||
brw2 = (a->f1 < b->f1) || (brw1 && (a->f1 == b->f1)); /* borrow? */
|
||||
a->f1 = (a->f1 - b->f1 - brw1) & LMASK; /* sub mid1 */
|
||||
brw3 = (a->f2 < b->f2) || (brw2 && (a->f2 == b->f2)); /* borrow? */
|
||||
a->f2 = (a->f2 - b->f2 - brw2) & LMASK; /* sub mid2 */
|
||||
brw4 = (a->f3 < b->f3) || (brw3 && (a->f3 == b->f3)); /* borrow? */
|
||||
a->f3 = (a->f3 - b->f3 - brw3) & LMASK; /* sub high */
|
||||
return brw4;
|
||||
}
|
||||
|
||||
void qp_neg (UQP *a)
|
||||
{
|
||||
uint32 cryin;
|
||||
|
||||
cryin = 1;
|
||||
a->f0 = (~a->f0 + cryin) & LMASK;
|
||||
if (a->f0 != 0) cryin = 0;
|
||||
a->f1 = (~a->f1 + cryin) & LMASK;
|
||||
if (a->f1 != 0) cryin = 0;
|
||||
a->f2 = (~a->f2 + cryin) & LMASK;
|
||||
if (a->f2 != 0) cryin = 0;
|
||||
a->f3 = (~a->f3 + cryin) & LMASK;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -985,7 +1039,7 @@ static UQP f_round = { 0, 0, 0, UH_FRND };
|
|||
static UQP d_round = { 0, 0, UH_DRND, 0 };
|
||||
|
||||
if (rh) *rh = 0; /* assume 0 */
|
||||
if (r->exp == 0) return 0; /* exp = 0? done */
|
||||
if ((r->frac.f3 == 0) && (r->frac.f2 == 0)) return 0; /* frac = 0? done */
|
||||
qp_add (&r->frac, rh? &d_round: &f_round);
|
||||
if ((r->frac.f3 & UH_NM_H) == 0) { /* carry out? */
|
||||
qp_rsh (&r->frac, 1); /* renormalize */
|
||||
|
@ -1007,7 +1061,7 @@ int32 h_rpackg (UFPH *r, int32 *rh)
|
|||
static UQP g_round = { 0, 0, UH_GRND, 0 };
|
||||
|
||||
*rh = 0; /* assume 0 */
|
||||
if (r->exp == 0) return 0; /* exp = 0? done */
|
||||
if ((r->frac.f3 == 0) && (r->frac.f2 == 0)) return 0; /* frac = 0? done */
|
||||
qp_add (&r->frac, &g_round); /* round */
|
||||
if ((r->frac.f3 & UH_NM_H) == 0) { /* carry out? */
|
||||
qp_rsh (&r->frac, 1); /* renormalize */
|
||||
|
@ -1029,9 +1083,9 @@ int32 h_rpackh (UFPH *r, int32 *hflt)
|
|||
static UQP h_round = { UH_HRND, 0, 0, 0 };
|
||||
|
||||
hflt[0] = hflt[1] = hflt[2] = hflt[3] = 0; /* assume 0 */
|
||||
if (r->exp == 0) return 0; /* exp = 0? done */
|
||||
qp_add (&r->frac, &h_round); /* round */
|
||||
if ((r->frac.f3 & UH_NM_H) == 0) { /* carry out? */
|
||||
if ((r->frac.f3 == 0) && (r->frac.f2 == 0) && /* frac = 0? done */
|
||||
(r->frac.f1 == 0) && (r->frac.f0 == 0)) return 0;
|
||||
if (qp_add (&r->frac, &h_round)) { /* round, carry out? */
|
||||
qp_rsh (&r->frac, 1); /* renormalize */
|
||||
r->exp = r->exp + 1;
|
||||
}
|
||||
|
@ -1085,7 +1139,8 @@ void h_write_q (int32 spec, int32 va, int32 vl, int32 vh, int32 acc)
|
|||
int32 rn, mstat;
|
||||
|
||||
if (spec > (GRN | nPC)) {
|
||||
if (Test (va + 7, WA, &mstat) >= 0)
|
||||
if ((Test (va + 7, WA, &mstat) >= 0) ||
|
||||
(Test (va, WA, &mstat) < 0))
|
||||
Write (va, vl, L_LONG, WA);
|
||||
Write (va + 4, vh, L_LONG, WA);
|
||||
}
|
||||
|
@ -1103,7 +1158,8 @@ void h_write_o (int32 spec, int32 va, int32 *val, int32 acc)
|
|||
int32 rn, mstat;
|
||||
|
||||
if (spec > (GRN | nPC)) {
|
||||
if (Test (va + 15, WA, &mstat) >= 0)
|
||||
if ((Test (va + 15, WA, &mstat) >= 0) ||
|
||||
(Test (va, WA, &mstat) < 0))
|
||||
Write (va, val[0], L_LONG, WA);
|
||||
Write (va + 4, val[1], L_LONG, WA);
|
||||
Write (va + 8, val[2], L_LONG, WA);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* vax_sys.c: VAX simulator interface
|
||||
|
||||
Copyright (c) 1998-2005, Robert M Supnik
|
||||
Copyright (c) 1998-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -23,6 +23,7 @@
|
|||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
17-May-06 RMS Added CR11/CD11 support (from John Dundas)
|
||||
01-Oct-2004 RMS Cloned from vax_sys.c
|
||||
*/
|
||||
|
||||
|
@ -37,6 +38,7 @@ extern DEVICE nvr_dev;
|
|||
extern DEVICE sysd_dev;
|
||||
extern DEVICE qba_dev;
|
||||
extern DEVICE tti_dev, tto_dev;
|
||||
extern DEVICE cr_dev;
|
||||
extern DEVICE lpt_dev;
|
||||
extern DEVICE clk_dev;
|
||||
extern DEVICE rq_dev, rqb_dev, rqc_dev, rqd_dev;
|
||||
|
@ -68,6 +70,7 @@ DEVICE *sim_devices[] = {
|
|||
&clk_dev,
|
||||
&dz_dev,
|
||||
&vh_dev,
|
||||
&cr_dev,
|
||||
&lpt_dev,
|
||||
&rl_dev,
|
||||
&rq_dev,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* vaxmod_defs.h: VAX model-specific definitions file
|
||||
|
||||
Copyright (c) 1998-2005, Robert M Supnik
|
||||
Copyright (c) 1998-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -23,6 +23,8 @@
|
|||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
17-May-06 RMS Added CR11/CD11 support
|
||||
10-May-06 RMS Added NOP'd reserved operand checking macros
|
||||
05-Oct-05 RMS Added XU definitions for autoconfigure
|
||||
15-Jun-05 RMS Added QDSS support
|
||||
12-Sep-04 RMS Removed map_address prototype
|
||||
|
@ -198,6 +200,15 @@
|
|||
#define CQMAMASK (CQMSIZE - 1) /* Qmem addr mask */
|
||||
#define CQMBASE 0x30000000 /* Qmem base */
|
||||
|
||||
/* Machine specific reserved operand tests (all NOPs) */
|
||||
|
||||
#define ML_PA_TEST(r)
|
||||
#define ML_LR_TEST(r)
|
||||
#define ML_BR_TEST(r)
|
||||
#define LP_AST_TEST(r)
|
||||
#define LP_MBZ84_TEST(r)
|
||||
#define LP_MBZ92_TEST(r)
|
||||
|
||||
/* Qbus I/O modes */
|
||||
|
||||
#define READ 0 /* PDP-11 compatibility */
|
||||
|
@ -285,6 +296,8 @@ typedef struct {
|
|||
#define IOLN_XU 010
|
||||
#define IOBA_RP (IOPAGEBASE + 016700) /* RP/RM */
|
||||
#define IOLN_RP 054
|
||||
#define IOBA_CR (IOPAGEBASE + 017160) /* CD/CR/CM */
|
||||
#define IOLN_CR 010
|
||||
#define IOBA_RX (IOPAGEBASE + 017170) /* RXV11 */
|
||||
#define IOLN_RX 004
|
||||
#define IOBA_RY (IOPAGEBASE + 017170) /* RXV21 */
|
||||
|
@ -336,6 +349,7 @@ typedef struct {
|
|||
#define INT_V_VHRX 9 /* DHQ11 */
|
||||
#define INT_V_VHTX 10
|
||||
#define INT_V_QDSS 11 /* QDSS */
|
||||
#define INT_V_CR 12
|
||||
|
||||
#define INT_CLK (1u << INT_V_CLK)
|
||||
#define INT_RQ (1u << INT_V_RQ)
|
||||
|
@ -359,6 +373,7 @@ typedef struct {
|
|||
#define INT_VHRX (1u << INT_V_VHRX)
|
||||
#define INT_VHTX (1u << INT_V_VHTX)
|
||||
#define INT_QDSS (1u << INT_V_QDSS)
|
||||
#define INT_CR (1u << INT_V_CR)
|
||||
|
||||
#define IPL_CLK (0x16 - IPL_HMIN) /* relative IPL */
|
||||
#define IPL_RQ (0x15 - IPL_HMIN)
|
||||
|
@ -382,6 +397,7 @@ typedef struct {
|
|||
#define IPL_VHRX (0x14 - IPL_HMIN)
|
||||
#define IPL_VHTX (0x14 - IPL_HMIN)
|
||||
#define IPL_QDSS (0x14 - IPL_HMIN)
|
||||
#define IPL_CR (0x14 - IPL_HMIN)
|
||||
|
||||
#define IPL_HMAX 0x17 /* highest hwre level */
|
||||
#define IPL_HMIN 0x14 /* lowest hwre level */
|
||||
|
@ -399,6 +415,7 @@ typedef struct {
|
|||
#define VEC_RL (VEC_Q + 0160)
|
||||
#define VEC_LPT (VEC_Q + 0200)
|
||||
#define VEC_TS (VEC_Q + 0224)
|
||||
#define VEC_CR (VEC_Q + 0230)
|
||||
#define VEC_RP (VEC_Q + 0254)
|
||||
#define VEC_TQ (VEC_Q + 0260)
|
||||
#define VEC_RX (VEC_Q + 0264)
|
||||
|
|
391
descrip.mms
391
descrip.mms
|
@ -1,15 +1,11 @@
|
|||
#
|
||||
# DESCRIP.MMS
|
||||
# Written By: Robert Alan Byer
|
||||
# byer@mail.ourservers.net
|
||||
#
|
||||
# Modified By: Mark Pizzolato
|
||||
# mark@infocomm.com
|
||||
# Written By: Robert Alan Byer / byer@mail.ourservers.net
|
||||
# Modified By: Mark Pizzolato / mark@infocomm.com
|
||||
# Norman Lastovica / norman.lastovica@oracle.com
|
||||
#
|
||||
# This MMS/MMK build script is used to compile the various simulators in
|
||||
# the SIMH package for OpenVMS using DEC C v6.0-001(AXP), v6.5-001(AXP)
|
||||
# and v6.4-005(VAX).
|
||||
# These compilers are available with the OpenVMS V7.3 Hobbyist CDs
|
||||
# the SIMH package for OpenVMS using DEC C v6.0-001(AXP), v6.5-001(AXP),
|
||||
# HP C V7.2-001 (IA64) and v6.4-005(VAX).
|
||||
#
|
||||
# Notes: On VAX, the PDP-10 and Eclipse simulators will not be built
|
||||
# due to the fact that INT64 is required for that simulator.
|
||||
|
@ -49,70 +45,84 @@
|
|||
#
|
||||
# MMK/MACRO=(DEBUG=1)
|
||||
#
|
||||
# This will produce an executable named {Simulator}-{VAX|AXP}-DBG.EXE
|
||||
# This will produce an executable named {Simulator}-{I64|VAX|AXP}-DBG.EXE
|
||||
#
|
||||
|
||||
#
|
||||
# Define The BIN Directory Where The Executables Will Go.
|
||||
#
|
||||
BIN_DIR = SYS$DISK:[.BIN]
|
||||
# Let's See If We Are Going To Build With DEBUG Enabled. Always compile
|
||||
# /DEBUG so that the traceback and debug information is always available
|
||||
# in the object files.
|
||||
|
||||
#
|
||||
# Define Our Library Directory.
|
||||
#
|
||||
LIB_DIR = SYS$DISK:[.LIB]
|
||||
CC_DEBUG = /DEB
|
||||
|
||||
#
|
||||
# Let's See If We Are Going To Build With DEBUG Enabled.
|
||||
#
|
||||
.IFDEF DEBUG
|
||||
CC_DEBUG = /DEBUG=ALL
|
||||
LINK_DEBUG = /DEBUG/TRACEBACK
|
||||
CC_OPTIMIZE = /NOOPTIMIZE
|
||||
|
||||
.IFDEF MMSALPHA
|
||||
CC_FLAGS = /PREFIX=ALL
|
||||
ALPHA_OR_IA64 = 1
|
||||
CC_FLAGS = /PREF=ALL
|
||||
ARCH = AXP-DBG
|
||||
CC_DEFS = _LARGEFILE
|
||||
.ELSE
|
||||
.ENDIF
|
||||
|
||||
.IFDEF MMSIA64
|
||||
ALPHA_OR_IA64 = 1
|
||||
CC_FLAGS = /PREF=ALL
|
||||
ARCH = I64-DBG
|
||||
CC_DEFS = _LARGEFILE
|
||||
.ENDIF
|
||||
|
||||
.IFDEF MMSVAX
|
||||
ALPHA_OR_IA64 = 0
|
||||
CC_FLAGS = $(CC_FLAGS)
|
||||
ARCH = VAX-DBG
|
||||
CC_DEFS = __VAX
|
||||
.ENDIF
|
||||
|
||||
.ELSE
|
||||
CC_DEBUG = /NODEBUG
|
||||
LINK_DEBUG = /NODEBUG/NOTRACEBACK
|
||||
|
||||
.IFDEF MMSALPHA
|
||||
CC_OPTIMIZE = /OPTIMIZE=(LEVEL=5,TUNE=HOST)/ARCH=HOST
|
||||
CC_FLAGS = /PREFIX=ALL
|
||||
ALPHA_OR_IA64 = 1
|
||||
CC_OPTIMIZE = /OPT=(LEV=5)/ARCH=HOST
|
||||
CC_FLAGS = /PREF=ALL
|
||||
ARCH = AXP
|
||||
CC_DEFS = _LARGEFILE
|
||||
.ELSE
|
||||
LINK_SECTION_BINDING = /SECTION_BINDING
|
||||
.ENDIF
|
||||
|
||||
.IFDEF MMSIA64
|
||||
ALPHA_OR_IA64 = 1
|
||||
CC_OPTIMIZE = /OPT=(LEV=5)
|
||||
CC_FLAGS = /PREF=ALL
|
||||
ARCH = I64
|
||||
CC_DEFS = _LARGEFILE
|
||||
.ENDIF
|
||||
|
||||
.IFDEF MMSVAX
|
||||
ALPHA_OR_IA64 = 0
|
||||
CC_OPTIMIZE = /OPTIMIZE
|
||||
CC_FLAGS = $(CC_FLAGS)
|
||||
ARCH = VAX
|
||||
CC_DEFS = __VAX
|
||||
.ENDIF
|
||||
|
||||
.ENDIF
|
||||
|
||||
#
|
||||
# Define The platform specific Build Directory Where The Objects Will Go.
|
||||
#
|
||||
BLD_DIR = SYS$DISK:[.LIB.BLD-$(ARCH)]
|
||||
|
||||
#
|
||||
# Define Our Compiler Flags
|
||||
#
|
||||
OUR_CC_FLAGS = $(CC_FLAGS)$(CC_DEBUG)$(CC_OPTIMIZE)/NEST=PRIMARY/NAME=(AS_IS,SHORTENED)
|
||||
|
||||
|
||||
#
|
||||
# Define The Compile Command.
|
||||
#
|
||||
# Define Our Compiler Flags & Define The Compile Command
|
||||
OUR_CC_FLAGS = $(CC_FLAGS)$(CC_DEBUG)$(CC_OPTIMIZE) \
|
||||
/NEST=PRIMARY/NAME=(AS_IS,SHORT)
|
||||
CC = CC/DECC$(OUR_CC_FLAGS)
|
||||
|
||||
# Define The BIN Directory Where The Executables Will Go.
|
||||
# Define Our Library Directory.
|
||||
# Define The platform specific Build Directory Where The Objects Will Go.
|
||||
#
|
||||
# First, Let's Check To Make Sure We Have A SYS$DISK:[.BIN] And
|
||||
# SYS$DISK:[.LIB] Directory.
|
||||
BIN_DIR = SYS$DISK:[.BIN]
|
||||
LIB_DIR = SYS$DISK:[.LIB]
|
||||
BLD_DIR = SYS$DISK:[.LIB.BLD-$(ARCH)]
|
||||
|
||||
# Check To Make Sure We Have SYS$DISK:[.BIN] & SYS$DISK:[.LIB] Directory.
|
||||
#
|
||||
.FIRST
|
||||
@ IF (F$SEARCH("SYS$DISK:[]BIN.DIR").EQS."") THEN CREATE/DIRECTORY $(BIN_DIR)
|
||||
|
@ -121,7 +131,6 @@ CC = CC/DECC$(OUR_CC_FLAGS)
|
|||
@ IF (F$SEARCH("$(BLD_DIR)*.*").NES."") THEN DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.*;*
|
||||
@ IF "".NES."''CC'" THEN DELETE/SYMBOL/GLOBAL CC
|
||||
|
||||
#
|
||||
# Core SIMH File Definitions.
|
||||
#
|
||||
SIMH_DIR = SYS$DISK:[]
|
||||
|
@ -131,12 +140,12 @@ SIMH_SOURCE = $(SIMH_DIR)SIM_CONSOLE.C,$(SIMH_DIR)SIM_SOCK.C,\
|
|||
$(SIMH_DIR)SIM_TAPE.C,$(SIMH_DIR)SIM_FIO.C,\
|
||||
$(SIMH_DIR)SIM_TIMER.C
|
||||
|
||||
#
|
||||
# VMS PCAP File Definitions.
|
||||
#
|
||||
PCAP_DIR = SYS$DISK:[.PCAP-VMS.PCAP-VCI]
|
||||
PCAP_LIB = $(LIB_DIR)PCAP-$(ARCH).OLB
|
||||
PCAP_SOURCE = $(PCAP_DIR)PCAPVCI.C,$(PCAP_DIR)VCMUTIL.C,\
|
||||
PCAP_SOURCE = \
|
||||
$(PCAP_DIR)PCAPVCI.C,$(PCAP_DIR)VCMUTIL.C,\
|
||||
$(PCAP_DIR)BPF_DUMP.C,$(PCAP_DIR)BPF_FILTER.C,\
|
||||
$(PCAP_DIR)BPF_IMAGE.C,$(PCAP_DIR)ETHERENT.C,\
|
||||
$(PCAP_DIR)FAD-GIFC.C,$(PCAP_DIR)GENCODE.C,\
|
||||
|
@ -150,8 +159,7 @@ PCAP_VCM_SOURCES = $(PCAP_VCMDIR)PCAPVCM.C,$(PCAP_VCMDIR)PCAPVCM_INIT.MAR,\
|
|||
$(PCAP_VCMDIR)VCI_JACKET.MAR,$(PCAP_VCMDIR)VCMUTIL.C
|
||||
PCAP_VCI = SYS$COMMON:[SYS$LDR]PCAPVCM.EXE
|
||||
|
||||
#
|
||||
# PCAP is not available on OpenVMS VAX
|
||||
# PCAP is not available on OpenVMS VAX or IA64 right now
|
||||
#
|
||||
.IFDEF MMSALPHA
|
||||
PCAP_EXECLET = $(PCAP_VCI)
|
||||
|
@ -159,17 +167,16 @@ PCAP_INC = ,$(PCAP_DIR)
|
|||
PCAP_LIBD = $(PCAP_LIB)
|
||||
PCAP_LIBR = ,$(PCAP_LIB)/LIB/SYSEXE
|
||||
PCAP_DEFS = ,"USE_NETWORK=1"
|
||||
PCAP_SIMH_INC = /include=($(PCAP_DIR))
|
||||
PCAP_SIMH_INC = /INCL=($(PCAP_DIR))
|
||||
.ENDIF
|
||||
|
||||
#
|
||||
# MITS Altair Simulator Definitions.
|
||||
#
|
||||
ALTAIR_DIR = SYS$DISK:[.ALTAIR]
|
||||
ALTAIR_LIB = $(LIB_DIR)ALTAIR-$(ARCH).OLB
|
||||
ALTAIR_SOURCE = $(ALTAIR_DIR)ALTAIR_SIO.C,$(ALTAIR_DIR)ALTAIR_CPU.C,\
|
||||
$(ALTAIR_DIR)ALTAIR_DSK.C,$(ALTAIR_DIR)ALTAIR_SYS.C
|
||||
ALTAIR_OPTIONS = /INCLUDE=($(SIMH_DIR),$(ALTAIR_DIR))/DEFINE=($(CC_DEFS))
|
||||
ALTAIR_OPTIONS = /INCL=($(SIMH_DIR),$(ALTAIR_DIR))/DEF=($(CC_DEFS))
|
||||
|
||||
#
|
||||
# MITS Altair Z80 Simulator Definitions.
|
||||
|
@ -181,7 +188,7 @@ ALTAIRZ80_SOURCE = $(ALTAIRZ80_DIR)ALTAIRZ80_CPU.C,\
|
|||
$(ALTAIRZ80_DIR)ALTAIRZ80_SIO.C,\
|
||||
$(ALTAIRZ80_DIR)ALTAIRZ80_SYS.C,\
|
||||
$(ALTAIRZ80_DIR)ALTAIRZ80_HDSK.C
|
||||
ALTAIRZ80_OPTIONS = /INCLUDE=($(SIMH_DIR),$(ALTAIRZ80_DIR))/DEFINE=($(CC_DEFS))
|
||||
ALTAIRZ80_OPTIONS = /INCL=($(SIMH_DIR),$(ALTAIRZ80_DIR))/DEF=($(CC_DEFS))
|
||||
|
||||
#
|
||||
# Data General Nova Simulator Definitions.
|
||||
|
@ -194,7 +201,7 @@ NOVA_SOURCE = $(NOVA_DIR)NOVA_SYS.C,$(NOVA_DIR)NOVA_CPU.C,\
|
|||
$(NOVA_DIR)NOVA_PLT.C,$(NOVA_DIR)NOVA_PT.C,\
|
||||
$(NOVA_DIR)NOVA_CLK.C,$(NOVA_DIR)NOVA_TT.C,\
|
||||
$(NOVA_DIR)NOVA_TT1.C,$(NOVA_DIR)NOVA_QTY.C
|
||||
NOVA_OPTIONS = /INCLUDE=($(SIMH_DIR),$(NOVA_DIR))/DEFINE=($(CC_DEFS))
|
||||
NOVA_OPTIONS = /INCL=($(SIMH_DIR),$(NOVA_DIR))/DEF=($(CC_DEFS))
|
||||
|
||||
#
|
||||
# Data General Eclipse Simulator Definitions.
|
||||
|
@ -206,8 +213,8 @@ ECLIPSE_SOURCE = $(NOVA_DIR)ECLIPSE_CPU.C,$(NOVA_DIR)ECLIPSE_TT.C,\
|
|||
$(NOVA_DIR)NOVA_MTA.C,$(NOVA_DIR)NOVA_PLT.C,\
|
||||
$(NOVA_DIR)NOVA_PT.C,$(NOVA_DIR)NOVA_CLK.C,\
|
||||
$(NOVA_DIR)NOVA_TT1.C,$(NOVA_DIR)NOVA_QTY.C
|
||||
ECLIPSE_OPTIONS = /INCLUDE=($(SIMH_DIR),$(NOVA_DIR))\
|
||||
/DEFINE=($(CC_DEFS),"USE_INT64=1","ECLIPSE=1")
|
||||
ECLIPSE_OPTIONS = /INCL=($(SIMH_DIR),$(NOVA_DIR))\
|
||||
/DEF=($(CC_DEFS),"USE_INT64=1","ECLIPSE=1")
|
||||
|
||||
#
|
||||
# GRI Corporation GRI-909 Simulator Definitions.
|
||||
|
@ -215,7 +222,7 @@ ECLIPSE_OPTIONS = /INCLUDE=($(SIMH_DIR),$(NOVA_DIR))\
|
|||
GRI_DIR = SYS$DISK:[.GRI]
|
||||
GRI_LIB = $(LIB_DIR)GRI-$(ARCH).OLB
|
||||
GRI_SOURCE = $(GRI_DIR)GRI_CPU.C,$(GRI_DIR)GRI_STDDEV.C,$(GRI_DIR)GRI_SYS.C
|
||||
GRI_OPTIONS = /INCLUDE=($(SIMH_DIR),$(GRI_DIR))/DEFINE=($(CC_DEFS))
|
||||
GRI_OPTIONS = /INCL=($(SIMH_DIR),$(GRI_DIR))/DEF=($(CC_DEFS))
|
||||
|
||||
#
|
||||
# Royal-McBee LGP-30 Simulator Definitions.
|
||||
|
@ -223,7 +230,7 @@ GRI_OPTIONS = /INCLUDE=($(SIMH_DIR),$(GRI_DIR))/DEFINE=($(CC_DEFS))
|
|||
LGP_DIR = SYS$DISK:[.LGP]
|
||||
LGP_LIB = $(LIB_DIR)LGP-$(ARCH).OLB
|
||||
LGP_SOURCE = $(LGP_DIR)LGP_CPU.C,$(LGP_DIR)LGP_STDDEV.C,$(LGP_DIR)LGP_SYS.C
|
||||
LGP_OPTIONS = /INCLUDE=($(SIMH_DIR),$(LGP_DIR))/DEFINE=($(CC_DEFS))
|
||||
LGP_OPTIONS = /INCL=($(SIMH_DIR),$(LGP_DIR))/DEF=($(CC_DEFS))
|
||||
|
||||
#
|
||||
# Honeywell 316/516 Simulator Definitions.
|
||||
|
@ -234,7 +241,7 @@ H316_SOURCE = $(H316_DIR)H316_STDDEV.C,$(H316_DIR)H316_LP.C,\
|
|||
$(H316_DIR)H316_CPU.C,$(H316_DIR)H316_SYS.C,\
|
||||
$(H316_DIR)H316_FHD.C,$(H316_DIR)H316_MT.C,\
|
||||
$(H316_DIR)H316_DP.C
|
||||
H316_OPTIONS = /INCLUDE=($(SIMH_DIR),$(H316_DIR))/DEFINE=($(CC_DEFS))
|
||||
H316_OPTIONS = /INCL=($(SIMH_DIR),$(H316_DIR))/DEF=($(CC_DEFS))
|
||||
|
||||
#
|
||||
# Hewlett-Packard HP-2100 Simulator Definitions.
|
||||
|
@ -249,11 +256,11 @@ HP2100_SOURCE = $(HP2100_DIR)HP2100_STDDEV.C,$(HP2100_DIR)HP2100_DP.C,\
|
|||
$(HP2100_DIR)HP2100_SYS.C,$(HP2100_DIR)HP2100_LPT.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")
|
||||
.IF ALPHA_OR_IA64
|
||||
HP2100_OPTIONS = /INCL=($(SIMH_DIR),$(HP2100_DIR))\
|
||||
/DEF=($(CC_DEFS),"HAVE_INT64=1")
|
||||
.ELSE
|
||||
HP2100_OPTIONS = /INCLUDE=($(SIMH_DIR),$(HP2100_DIR))/DEFINE=($(CC_DEFS))
|
||||
HP2100_OPTIONS = /INCL=($(SIMH_DIR),$(HP2100_DIR))/DEF=($(CC_DEFS))
|
||||
.ENDIF
|
||||
|
||||
#
|
||||
|
@ -266,7 +273,7 @@ ID16_SOURCE = $(ID16_DIR)ID16_CPU.C,$(ID16_DIR)ID16_SYS.C,$(ID16_DIR)ID_DP.C,\
|
|||
$(ID16_DIR)ID_IO.C,$(ID16_DIR)ID_LP.C,$(ID16_DIR)ID_MT.C,\
|
||||
$(ID16_DIR)ID_PAS.C,$(ID16_DIR)ID_PT.C,$(ID16_DIR)ID_TT.C,\
|
||||
$(ID16_DIR)ID_UVC.C,$(ID16_DIR)ID16_DBOOT.C,$(ID16_DIR)ID_TTP.C
|
||||
ID16_OPTIONS = /INCLUDE=($(SIMH_DIR),$(ID16_DIR))/DEFINE=($(CC_DEFS))
|
||||
ID16_OPTIONS = /INCL=($(SIMH_DIR),$(ID16_DIR))/DEF=($(CC_DEFS))
|
||||
|
||||
#
|
||||
# Interdata 32-bit CPU.
|
||||
|
@ -278,7 +285,7 @@ ID32_SOURCE = $(ID32_DIR)ID32_CPU.C,$(ID32_DIR)ID32_SYS.C,$(ID32_DIR)ID_DP.C,\
|
|||
$(ID32_DIR)ID_IO.C,$(ID32_DIR)ID_LP.C,$(ID32_DIR)ID_MT.C,\
|
||||
$(ID32_DIR)ID_PAS.C,$(ID32_DIR)ID_PT.C,$(ID32_DIR)ID_TT.C,\
|
||||
$(ID32_DIR)ID_UVC.C,$(ID32_DIR)ID32_DBOOT.C,$(ID32_DIR)ID_TTP.C
|
||||
ID32_OPTIONS = /INCLUDE=($(SIMH_DIR),$(ID32_DIR))/DEFINE=($(CC_DEFS))
|
||||
ID32_OPTIONS = /INCL=($(SIMH_DIR),$(ID32_DIR))/DEF=($(CC_DEFS))
|
||||
|
||||
#
|
||||
# IBM 1130 Simulator Definitions.
|
||||
|
@ -290,7 +297,7 @@ IBM1130_SOURCE = $(IBM1130_DIR)IBM1130_CPU.C,$(IBM1130_DIR)IBM1130_CR.C,\
|
|||
$(IBM1130_DIR)IBM1130_SYS.C,$(IBM1130_DIR)IBM1130_GDU.C,\
|
||||
$(IBM1130_DIR)IBM1130_GUI.C,$(IBM1130_DIR)IBM1130_PRT.C,\
|
||||
$(IBM1130_DIR)IBM1130_FMT.C,$(IBM1130_DIR)IBM1130_PTRP.C
|
||||
IBM1130_OPTIONS = /INCLUDE=($(SIMH_DIR),$(IBM1130_DIR))/DEFINE=($(CC_DEFS))
|
||||
IBM1130_OPTIONS = /INCL=($(SIMH_DIR),$(IBM1130_DIR))/DEF=($(CC_DEFS))
|
||||
|
||||
#
|
||||
# IBM 1401 Simulator Definitions.
|
||||
|
@ -301,7 +308,7 @@ I1401_SOURCE = $(I1401_DIR)I1401_LP.C,$(I1401_DIR)I1401_CPU.C,\
|
|||
$(I1401_DIR)I1401_IQ.C,$(I1401_DIR)I1401_CD.C,\
|
||||
$(I1401_DIR)I1401_MT.C,$(I1401_DIR)I1401_DP.C,\
|
||||
$(I1401_DIR)I1401_SYS.C
|
||||
I1401_OPTIONS = /INCLUDE=($(SIMH_DIR),$(I1401_DIR))/DEFINE=($(CC_DEFS))
|
||||
I1401_OPTIONS = /INCL=($(SIMH_DIR),$(I1401_DIR))/DEF=($(CC_DEFS))
|
||||
|
||||
|
||||
#
|
||||
|
@ -313,7 +320,7 @@ I1620_SOURCE = $(I1620_DIR)I1620_CD.C,$(I1620_DIR)I1620_DP.C,\
|
|||
$(I1620_DIR)I1620_PT.C,$(I1620_DIR)I1620_TTY.C,\
|
||||
$(I1620_DIR)I1620_CPU.C,$(I1620_DIR)I1620_LP.C,\
|
||||
$(I1620_DIR)I1620_FP.C,$(I1620_DIR)I1620_SYS.C
|
||||
I1620_OPTIONS = /INCLUDE=($(SIMH_DIR),$(I1620_DIR))/DEFINE=($(CC_DEFS))
|
||||
I1620_OPTIONS = /INCL=($(SIMH_DIR),$(I1620_DIR))/DEF=($(CC_DEFS))
|
||||
|
||||
#
|
||||
# PDP-1 Simulator Definitions.
|
||||
|
@ -323,7 +330,7 @@ PDP1_LIB = $(LIB_DIR)PDP1-$(ARCH).OLB
|
|||
PDP1_SOURCE = $(PDP1_DIR)PDP1_LP.C,$(PDP1_DIR)PDP1_CPU.C,\
|
||||
$(PDP1_DIR)PDP1_STDDEV.C,$(PDP1_DIR)PDP1_SYS.C,\
|
||||
$(PDP1_DIR)PDP1_DT.C,$(PDP1_DIR)PDP1_DRM.C
|
||||
PDP1_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP1_DIR))/DEFINE=($(CC_DEFS))
|
||||
PDP1_OPTIONS = /INCL=($(SIMH_DIR),$(PDP1_DIR))/DEF=($(CC_DEFS))
|
||||
|
||||
#
|
||||
# Digital Equipment PDP-8 Simulator Definitions.
|
||||
|
@ -338,7 +345,7 @@ PDP8_SOURCE = $(PDP8_DIR)PDP8_CPU.C,$(PDP8_DIR)PDP8_CLK.C,\
|
|||
$(PDP8_DIR)PDP8_SYS.C,$(PDP8_DIR)PDP8_TT.C,\
|
||||
$(PDP8_DIR)PDP8_TTX.C,$(PDP8_DIR)PDP8_RL.C,\
|
||||
$(PDP8_DIR)PDP8_TSC.C,$(PDP8_DIR)PDP8_TD.C
|
||||
PDP8_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP8_DIR))/DEFINE=($(CC_DEFS))
|
||||
PDP8_OPTIONS = /INCL=($(SIMH_DIR),$(PDP8_DIR))/DEF=($(CC_DEFS))
|
||||
|
||||
#
|
||||
# Digital Equipment PDP-4, PDP-7, PDP-9 And PDP-15 Simulator Definitions.
|
||||
|
@ -354,10 +361,10 @@ PDP18B_SOURCE = $(PDP18B_DIR)PDP18B_DT.C,$(PDP18B_DIR)PDP18B_DRM.C,\
|
|||
$(PDP18B_DIR)PDP18B_RP.C,$(PDP18B_DIR)PDP18B_STDDEV.C,\
|
||||
$(PDP18B_DIR)PDP18B_SYS.C,$(PDP18B_DIR)PDP18B_TT1.C,\
|
||||
$(PDP18B_DIR)PDP18B_RB.C,$(PDP18B_DIR)PDP18B_FPP.C
|
||||
PDP4_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP18B_DIR))/DEFINE=($(CC_DEFS),"PDP4=1")
|
||||
PDP7_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP18B_DIR))/DEFINE=($(CC_DEFS),"PDP7=1")
|
||||
PDP9_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP18B_DIR))/DEFINE=($(CC_DEFS),"PDP9=1")
|
||||
PDP15_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP18B_DIR))/DEFINE=($(CC_DEFS),"PDP15=1")
|
||||
PDP4_OPTIONS = /INCL=($(SIMH_DIR),$(PDP18B_DIR))/DEF=($(CC_DEFS),"PDP4=1")
|
||||
PDP7_OPTIONS = /INCL=($(SIMH_DIR),$(PDP18B_DIR))/DEF=($(CC_DEFS),"PDP7=1")
|
||||
PDP9_OPTIONS = /INCL=($(SIMH_DIR),$(PDP18B_DIR))/DEF=($(CC_DEFS),"PDP9=1")
|
||||
PDP15_OPTIONS = /INCL=($(SIMH_DIR),$(PDP18B_DIR))/DEF=($(CC_DEFS),"PDP15=1")
|
||||
|
||||
#
|
||||
# Digital Equipment PDP-11 Simulator Definitions.
|
||||
|
@ -370,7 +377,7 @@ PDP11_SOURCE1 = $(PDP11_DIR)PDP11_FP.C,$(PDP11_DIR)PDP11_CPU.C,\
|
|||
$(PDP11_DIR)PDP11_RL.C,$(PDP11_DIR)PDP11_RP.C,\
|
||||
$(PDP11_DIR)PDP11_RX.C,$(PDP11_DIR)PDP11_STDDEV.C,\
|
||||
$(PDP11_DIR)PDP11_SYS.C,$(PDP11_DIR)PDP11_TC.C, \
|
||||
$(PDP11_DIR)PDP11_CPUMOD.C
|
||||
$(PDP11_DIR)PDP11_CPUMOD.C,$(PDP11_DIR)PDP11_CR.C
|
||||
PDP11_LIB2 = $(LIB_DIR)PDP11L2-$(ARCH).OLB
|
||||
PDP11_SOURCE2 = $(PDP11_DIR)PDP11_TM.C,$(PDP11_DIR)PDP11_TS.C,\
|
||||
$(PDP11_DIR)PDP11_IO.C,$(PDP11_DIR)PDP11_RQ.C,\
|
||||
|
@ -379,8 +386,8 @@ PDP11_SOURCE2 = $(PDP11_DIR)PDP11_TM.C,$(PDP11_DIR)PDP11_TS.C,\
|
|||
$(PDP11_DIR)PDP11_HK.C,$(PDP11_DIR)PDP11_XQ.C,\
|
||||
$(PDP11_DIR)PDP11_VH.C,$(PDP11_DIR)PDP11_RH.C,\
|
||||
$(PDP11_DIR)PDP11_XU.C,$(PDP11_DIR)PDP11_TU.C
|
||||
PDP11_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP11_DIR)$(PCAP_INC))\
|
||||
/DEFINE=($(CC_DEFS),"VM_PDP11=1"$(PCAP_DEFS))
|
||||
PDP11_OPTIONS = /INCL=($(SIMH_DIR),$(PDP11_DIR)$(PCAP_INC))\
|
||||
/DEF=($(CC_DEFS),"VM_PDP11=1"$(PCAP_DEFS))
|
||||
|
||||
#
|
||||
# Digital Equipment PDP-10 Simulator Definitions.
|
||||
|
@ -395,8 +402,8 @@ PDP10_SOURCE = $(PDP10_DIR)PDP10_FE.C,\
|
|||
$(PDP10_DIR)PDP10_TIM.C,$(PDP10_DIR)PDP10_TU.C,\
|
||||
$(PDP11_DIR)PDP11_PT.C,$(PDP11_DIR)PDP11_DZ.C,\
|
||||
$(PDP11_DIR)PDP11_RY.C,$(PDP11_DIR)PDP11_XU.C
|
||||
PDP10_OPTIONS = /INCLUDE=($(SIMH_DIR),$(PDP10_DIR),$(PDP11_DIR))\
|
||||
/DEFINE=($(CC_DEFS),"USE_INT64=1","VM_PDP10=1"$(PCAP_DEFS))
|
||||
PDP10_OPTIONS = /INCL=($(SIMH_DIR),$(PDP10_DIR),$(PDP11_DIR))\
|
||||
/DEF=($(CC_DEFS),"USE_INT64=1","VM_PDP10=1"$(PCAP_DEFS))
|
||||
|
||||
#
|
||||
# IBM System 3 Simulator Definitions.
|
||||
|
@ -405,7 +412,7 @@ S3_DIR = SYS$DISK:[.S3]
|
|||
S3_LIB = $(LIB_DIR)S3-$(ARCH).OLB
|
||||
S3_SOURCE = $(S3_DIR)S3_CD.C,$(S3_DIR)S3_CPU.C,$(S3_DIR)S3_DISK.C,\
|
||||
$(S3_DIR)S3_LP.C,$(S3_DIR)S3_PKB.C,$(S3_DIR)S3_SYS.C
|
||||
S3_OPTIONS = /INCLUDE=($(SIMH_DIR),$(S3_DIR))/DEFINE=($(CC_DEFS))
|
||||
S3_OPTIONS = /INCL=($(SIMH_DIR),$(S3_DIR))/DEF=($(CC_DEFS))
|
||||
|
||||
#
|
||||
# SDS 940
|
||||
|
@ -416,7 +423,7 @@ SDS_SOURCE = $(SDS_DIR)SDS_CPU.C,$(SDS_DIR)SDS_DRM.C,$(SDS_DIR)SDS_DSK.C,\
|
|||
$(SDS_DIR)SDS_IO.C,$(SDS_DIR)SDS_LP.C,$(SDS_DIR)SDS_MT.C,\
|
||||
$(SDS_DIR)SDS_MUX.C,$(SDS_DIR)SDS_RAD.C,$(SDS_DIR)SDS_STDDEV.C,\
|
||||
$(SDS_DIR)SDS_SYS.C
|
||||
SDS_OPTIONS = /INCLUDE=($(SIMH_DIR),$(SDS_DIR))/DEFINE=($(CC_DEFS))
|
||||
SDS_OPTIONS = /INCL=($(SIMH_DIR),$(SDS_DIR))/DEF=($(CC_DEFS))
|
||||
|
||||
#
|
||||
# Digital Equipment VAX Simulator Definitions.
|
||||
|
@ -433,12 +440,11 @@ VAX_SOURCE = $(VAX_DIR)VAX_CIS.C,$(VAX_DIR)VAX_CMODE.C,\
|
|||
$(PDP11_DIR)PDP11_RL.C,$(PDP11_DIR)PDP11_RQ.C,\
|
||||
$(PDP11_DIR)PDP11_TS.C,$(PDP11_DIR)PDP11_DZ.C,\
|
||||
$(PDP11_DIR)PDP11_LP.C,$(PDP11_DIR)PDP11_TQ.C,\
|
||||
$(PDP11_DIR)PDP11_XQ.C,\
|
||||
$(PDP11_DIR)PDP11_XQ.C,$(PDP11_DIR)PDP11_CR.C,\
|
||||
$(PDP11_DIR)PDP11_RY.C,$(PDP11_DIR)PDP11_VH.C
|
||||
VAX_OPTIONS = /INCLUDE=($(SIMH_DIR),$(VAX_DIR),$(PDP11_DIR)$(PCAP_INC))\
|
||||
/DEFINE=($(CC_DEFS),"VM_VAX=1"$(PCAP_DEFS))
|
||||
VAX_OPTIONS = /INCL=($(SIMH_DIR),$(VAX_DIR),$(PDP11_DIR)$(PCAP_INC))\
|
||||
/DEF=($(CC_DEFS),"VM_VAX=1"$(PCAP_DEFS))
|
||||
|
||||
#
|
||||
# Digital Equipment VAX780 Simulator Definitions.
|
||||
#
|
||||
VAX780_DIR = SYS$DISK:[.VAX]
|
||||
|
@ -449,27 +455,38 @@ VAX780_SOURCE = $(VAX780_DIR)VAX_CIS.C,$(VAX780_DIR)VAX_CMODE.C,\
|
|||
$(VAX780_DIR)VAX_OCTA.C,$(VAX780_DIR)VAX_SYS.C,\
|
||||
$(VAX780_DIR)VAX_SYSCM.C,\
|
||||
$(VAX780_DIR)VAX780_MBA.C,$(VAX780_DIR)VAX780_MEM.C,\
|
||||
$(VAX780_DIR)VAX_SBI.C,$(VAX780_DIR)VAX780_STDDEV.C,\
|
||||
$(VAX780_DIR)VAX780_SBI.C,$(VAX780_DIR)VAX780_STDDEV.C,\
|
||||
$(VAX780_DIR)VAX780_SYSLIST.C,$(VAX780_DIR)VAX780_UBA.C,\
|
||||
$(PDP11_DIR)PDP11_DZ.C,$(PDP11_DIR)PDP11_HK.C,\
|
||||
$(PDP11_DIR)PDP11_LP.C,$(PDP11_DIR)PDP11_RL.C,\
|
||||
$(PDP11_DIR)PDP11_RP.C,$(PDP11_DIR)PDP11_RQ.C,\
|
||||
$(PDP11_DIR)PDP11_RY.C,$(PDP11_DIR)PDP11_TQ.C,\
|
||||
$(PDP11_DIR)PDP11_TS.C,$(PDP11_DIR)PDP11_TU.C,\
|
||||
$(PDP11_DIR)PDP11_XU.C
|
||||
VAX780_OPTIONS = /INCLUDE=($(SIMH_DIR),$(VAX780_DIR),$(PDP11_DIR)$(PCAP_INC))\
|
||||
/DEFINE=($(CC_DEFS),"VM_VAX=1"$(PCAP_DEFS))
|
||||
$(PDP11_DIR)PDP11_XU.C,$(PDP11_DIR)PDP11_CR.C
|
||||
VAX780_OPTIONS = /INCL=($(SIMH_DIR),$(VAX780_DIR),$(PDP11_DIR)$(PCAP_INC))\
|
||||
/DEF=($(CC_DEFS),"VM_VAX=1"$(PCAP_DEFS),"VAX_780=1")
|
||||
|
||||
# IBM 7094 Simulator Definitions.
|
||||
#
|
||||
I7094_DIR = SYS$DISK:[.I7094]
|
||||
I7094_LIB = $(LIB_DIR)I7094-$(ARCH).OLB
|
||||
I7094_SOURCE = $(I7094_DIR)I7094_CPU.C,$(I7094_DIR)I7094_CPU1.C,\
|
||||
$(I7094_DIR)I7094_IO.C,$(I7094_DIR)I7094_SYS.C,\
|
||||
$(I7094_DIR)I7094_CD.C,$(I7094_DIR)I7094_COM.C,\
|
||||
$(I7094_DIR)I7094_DSK.C,$(I7094_DIR)I7094_DRM.C,\
|
||||
$(I7094_DIR)I7094_MT.C,\
|
||||
$(I7094_DIR)I7094_CLK.C,$(I7094_DIR)I7094_LP.C
|
||||
I7094_OPTIONS = /INCL=($(SIMH_DIR),$(I7094_DIR))/DEF=($(CC_DEFS))
|
||||
|
||||
# If we're not a VAX, Build Everything
|
||||
#
|
||||
.IFDEF MMSALPHA
|
||||
ALL : ALTAIR ALTAIRZ80 ECLIPSE GRI LGP H316 HP2100 I1401 I1620 IBM1130 ID16 ID32 \
|
||||
NOVA PDP1 PDP4 PDP7 PDP8 PDP9 PDP10 PDP11 PDP15 S3 VAX SDS
|
||||
.IF ALPHA_OR_IA64
|
||||
ALL : ALTAIR ALTAIRZ80 ECLIPSE GRI LGP H316 HP2100 I1401 I1620 IBM1130 ID16 \
|
||||
ID32 NOVA PDP1 PDP4 PDP7 PDP8 PDP9 PDP10 PDP11 PDP15 S3 VAX VAX780 SDS \
|
||||
I7094
|
||||
.ELSE
|
||||
#
|
||||
# Else We Are On VAX And Build Everything EXCEPT The PDP-10 and the ECLIPSE
|
||||
# Since VAX Dosen't Have INT64
|
||||
# Else We Are On VAX And Build Everything EXCEPT the 64b simulators
|
||||
#
|
||||
ALL : ALTAIR ALTAIRZ80 GRI H316 HP2100 I1401 I1620 IBM1130 ID16 ID32 \
|
||||
NOVA PDP1 PDP4 PDP7 PDP8 PDP9 PDP11 PDP15 S3 VAX VAX780 SDS
|
||||
|
@ -497,8 +514,8 @@ $(SIMH_LIB) : $(SIMH_SOURCE)
|
|||
$!
|
||||
$! Building The $(SIMH_LIB) Library.
|
||||
$!
|
||||
$ $(CC)/DEFINE=($(CC_DEFS)$(PCAP_DEFS))$(PCAP_SIMH_INC) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ $(CC)/DEF=($(CC_DEFS)$(PCAP_DEFS))$(PCAP_SIMH_INC) -
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -509,7 +526,7 @@ $(ALTAIR_LIB) : $(ALTAIR_SOURCE)
|
|||
$! Building The $(ALTAIR_LIB) Library.
|
||||
$!
|
||||
$ $(CC)$(ALTAIR_OPTIONS) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -520,7 +537,7 @@ $(ALTAIRZ80_LIB) : $(ALTAIRZ80_SOURCE)
|
|||
$! Building The $(ALTAIRZ80_LIB) Library.
|
||||
$!
|
||||
$ $(CC)$(ALTAIRZ80_OPTIONS) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -529,13 +546,13 @@ $(ALTAIRZ80_LIB) : $(ALTAIRZ80_SOURCE)
|
|||
#
|
||||
# If Not On VAX, Build The Eclipse Library.
|
||||
#
|
||||
.IFDEF MMSALPHA
|
||||
.IF ALPHA_OR_IA64
|
||||
$(ECLIPSE_LIB) : $(ECLIPSE_SOURCE)
|
||||
$!
|
||||
$! Building The $(ECLIPSE_LIB) Library.
|
||||
$!
|
||||
$ $(CC)$(ECLIPSE_OPTIONS) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -556,7 +573,7 @@ $(GRI_LIB) : $(GRI_SOURCE)
|
|||
$! Building The $(GRI_LIB) Library.
|
||||
$!
|
||||
$ $(CC)$(GRI_OPTIONS) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -567,7 +584,7 @@ $(LGP_LIB) : $(LGP_SOURCE)
|
|||
$! Building The $(LGP_LIB) Library.
|
||||
$!
|
||||
$ $(CC)$(LGP_OPTIONS) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -578,7 +595,7 @@ $(H316_LIB) : $(H316_SOURCE)
|
|||
$! Building The $(H316_LIB) Library.
|
||||
$!
|
||||
$ $(CC)$(H316_OPTIONS) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -589,7 +606,7 @@ $(HP2100_LIB) : $(HP2100_SOURCE)
|
|||
$! Building The $(HP2100_LIB) Library.
|
||||
$!
|
||||
$ $(CC)$(HP2100_OPTIONS) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -600,7 +617,7 @@ $(I1401_LIB) : $(I1401_SOURCE)
|
|||
$! Building The $(I1401_LIB) Library.
|
||||
$!
|
||||
$ $(CC)$(I1401_OPTIONS) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -611,7 +628,7 @@ $(I1620_LIB) : $(I1620_SOURCE)
|
|||
$! Building The $(I1620_LIB) Library.
|
||||
$!
|
||||
$ $(CC)$(I1620_OPTIONS) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -622,7 +639,7 @@ $(IBM1130_LIB) : $(IBM1130_SOURCE)
|
|||
$! Building The $(IBM1130_LIB) Library.
|
||||
$!
|
||||
$ $(CC)$(IBM1130_OPTIONS) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -633,7 +650,7 @@ $(ID16_LIB) : $(ID16_SOURCE)
|
|||
$! Building The $(ID16_LIB) Library.
|
||||
$!
|
||||
$ $(CC)$(ID16_OPTIONS) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -644,7 +661,7 @@ $(ID32_LIB) : $(ID32_SOURCE)
|
|||
$! Building The $(ID32_LIB) Library.
|
||||
$!
|
||||
$ $(CC)$(ID32_OPTIONS) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -655,7 +672,7 @@ $(NOVA_LIB) : $(NOVA_SOURCE)
|
|||
$! Building The $(NOVA_LIB) Library.
|
||||
$!
|
||||
$ $(CC)$(NOVA_OPTIONS) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -666,7 +683,7 @@ $(PDP1_LIB) : $(PDP1_SOURCE)
|
|||
$! Building The $(PDP1_LIB) Library.
|
||||
$!
|
||||
$ $(CC)$(PDP1_OPTIONS) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -677,7 +694,7 @@ $(PDP4_LIB) : $(PDP18B_SOURCE)
|
|||
$! Building The $(PDP4_LIB) Library.
|
||||
$!
|
||||
$ $(CC)$(PDP4_OPTIONS) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -688,7 +705,7 @@ $(PDP7_LIB) : $(PDP18B_SOURCE)
|
|||
$! Building The $(PDP7_LIB) Library.
|
||||
$!
|
||||
$ $(CC)$(PDP7_OPTIONS) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -699,7 +716,7 @@ $(PDP8_LIB) : $(PDP8_SOURCE)
|
|||
$! Building The $(PDP8_LIB) Library.
|
||||
$!
|
||||
$ $(CC)$(PDP8_OPTIONS) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -710,7 +727,7 @@ $(PDP9_LIB) : $(PDP18B_SOURCE)
|
|||
$! Building The $(PDP9_LIB) Library.
|
||||
$!
|
||||
$ $(CC)$(PDP9_OPTIONS) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -719,13 +736,13 @@ $(PDP9_LIB) : $(PDP18B_SOURCE)
|
|||
#
|
||||
# If Not On VAX, Build The PDP-10 Library.
|
||||
#
|
||||
.IFDEF MMSALPHA
|
||||
.IF ALPHA_OR_IA64
|
||||
$(PDP10_LIB) : $(PDP10_SOURCE)
|
||||
$!
|
||||
$! Building The $(PDP10_LIB) Library.
|
||||
$!
|
||||
$ $(CC)$(PDP10_OPTIONS) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -735,10 +752,8 @@ $(PDP10_LIB) : $(PDP10_SOURCE)
|
|||
# We Are On VAX And Due To The Use of INT64 We Can't Build It.
|
||||
#
|
||||
$(PDP10_LIB) :
|
||||
$!
|
||||
$! Due To The Use Of INT64 We Can't Build The
|
||||
$! $(LIB_DIR)PDP10-$(ARCH).OLB Library On VAX.
|
||||
$!
|
||||
.ENDIF
|
||||
|
||||
$(PDP11_LIB1) : $(PDP11_SOURCE1)
|
||||
|
@ -746,7 +761,7 @@ $(PDP11_LIB1) : $(PDP11_SOURCE1)
|
|||
$! Building The $(PDP11_LIB1) Library.
|
||||
$!
|
||||
$(CC)$(PDP11_OPTIONS) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -757,7 +772,7 @@ $(PDP11_LIB2) : $(PDP11_SOURCE2)
|
|||
$! Building The $(PDP11_LIB2) Library.
|
||||
$!
|
||||
$(CC)$(PDP11_OPTIONS) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -768,7 +783,7 @@ $(PDP15_LIB) : $(PDP18B_SOURCE)
|
|||
$! Building The $(PDP15_LIB) Library.
|
||||
$!
|
||||
$ $(CC)$(PDP15_OPTIONS) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -779,7 +794,7 @@ $(S3_LIB) : $(S3_SOURCE)
|
|||
$! Building The $(S3_LIB) Library.
|
||||
$!
|
||||
$ $(CC)$(S3_OPTIONS) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -790,7 +805,7 @@ $(SDS_LIB) : $(SDS_SOURCE)
|
|||
$! Building The $(SDS_LIB) Library.
|
||||
$!
|
||||
$ $(CC)$(SDS_OPTIONS) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -800,8 +815,8 @@ $(VAX_LIB) : $(VAX_SOURCE)
|
|||
$!
|
||||
$! Building The $(VAX_LIB) Library.
|
||||
$!
|
||||
$ $(CC)$(VAX_OPTIONS)/OBJECT=$(VAX_DIR) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ $(CC)$(VAX_OPTIONS)/OBJ=$(VAX_DIR) -
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -811,8 +826,8 @@ $(VAX780_LIB) : $(VAX780_SOURCE)
|
|||
$!
|
||||
$! Building The $(VAX_780LIB) Library.
|
||||
$!
|
||||
$ $(CC)$(VAX780_OPTIONS)/OBJECT=$(VAX780_DIR) -
|
||||
/OBJECT=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ $(CC)$(VAX780_OPTIONS)/OBJ=$(VAX780_DIR) -
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
|
@ -830,6 +845,29 @@ $(PCAP_LIB) : $(PCAP_SOURCE)
|
|||
$ COPY $(PCAP_DIR)PCAP.OLB $(PCAP_LIB)
|
||||
$ DELETE/NOLOG/NOCONFIRM $(PCAP_DIR)*.OBJ;*,$(PCAP_DIR)*.OLB;*
|
||||
|
||||
#
|
||||
# If Not On VAX, Build The IBM 7094 Library.
|
||||
#
|
||||
.IF ALPHA_OR_IA64
|
||||
$(I7094_LIB) : $(I7094_SOURCE)
|
||||
$!
|
||||
$! Building The $(I7094_LIB) Library.
|
||||
$!
|
||||
$ $(CC)$(I7094_OPTIONS) -
|
||||
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
|
||||
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
|
||||
LIBRARY/CREATE $(MMS$TARGET)
|
||||
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
.ELSE
|
||||
#
|
||||
# We Are On VAX And Due To The Use of INT64 We Can't Build It.
|
||||
#
|
||||
$(I7094_LIB) :
|
||||
$! Due To The Use Of INT64 We Can't Build The
|
||||
$! $(LIB_DIR)I7094-$(ARCH).OLB Library On VAX.
|
||||
.ENDIF
|
||||
|
||||
#
|
||||
# Individual Simulator Builds.
|
||||
#
|
||||
|
@ -837,7 +875,7 @@ ALTAIR : $(SIMH_LIB) $(ALTAIR_LIB)
|
|||
$!
|
||||
$! Building The $(BIN_DIR)ALTAIR-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(ALTAIR_OPTIONS)/OBJECT=$(BLD_DIR) SCP.C
|
||||
$ $(CC)$(ALTAIR_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)ALTAIR-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(ALTAIR_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
|
@ -846,7 +884,7 @@ ALTAIRZ80 : $(SIMH_LIB) $(ALTAIRZ80_LIB)
|
|||
$!
|
||||
$! Building The $(BIN_DIR)ALTAIRZ80-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(ALTAIRZ80_OPTIONS)/OBJECT=$(BLD_DIR) SCP.C
|
||||
$ $(CC)$(ALTAIRZ80_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)ALTAIRZ80-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(ALTAIRZ80_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
|
@ -854,12 +892,12 @@ ALTAIRZ80 : $(SIMH_LIB) $(ALTAIRZ80_LIB)
|
|||
#
|
||||
# If Not On VAX, Build The PDP-10 Simulator.
|
||||
#
|
||||
.IFDEF MMSALPHA
|
||||
.IF ALPHA_OR_IA64
|
||||
ECLIPSE : $(SIMH_LIB) $(ECLIPSE_LIB)
|
||||
$!
|
||||
$! Building The $(BIN_DIR)ECLIPSE-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(ECLIPSE_OPTIONS)/OBJECT=$(BLD_DIR) SCP.C
|
||||
$ $(CC)$(ECLIPSE_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)ECLIPSE-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(ECLIPSE_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
|
@ -869,17 +907,15 @@ ECLIPSE : $(SIMH_LIB) $(ECLIPSE_LIB)
|
|||
# Due To The Use Of INT64.
|
||||
#
|
||||
ECLIPSE :
|
||||
$!
|
||||
$! Sorry, Can't Build $(BIN_DIR)ECLIPSE-$(ARCH).EXE Simulator
|
||||
$! Because It Requires The Use Of INT64.
|
||||
$!
|
||||
.ENDIF
|
||||
|
||||
GRI : $(SIMH_LIB) $(GRI_LIB)
|
||||
$!
|
||||
$! Building The $(BIN_DIR)GRI-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(GRI_OPTIONS)/OBJECT=$(BLD_DIR) SCP.C
|
||||
$ $(CC)$(GRI_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)GRI-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(GRI_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
|
@ -888,7 +924,7 @@ LGP : $(SIMH_LIB) $(LGP_LIB)
|
|||
$!
|
||||
$! Building The $(BIN_DIR)LGP-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(LGP_OPTIONS)/OBJECT=$(BLD_DIR) SCP.C
|
||||
$ $(CC)$(LGP_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)LGP-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(LGP_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
|
@ -897,7 +933,7 @@ H316 : $(SIMH_LIB) $(H316_LIB)
|
|||
$!
|
||||
$! Building The $(BIN_DIR)H316-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(H316_OPTIONS)/OBJECT=$(BLD_DIR) SCP.C
|
||||
$ $(CC)$(H316_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)H316-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(H316_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
|
@ -906,7 +942,7 @@ HP2100 : $(SIMH_LIB) $(HP2100_LIB)
|
|||
$!
|
||||
$! Building The $(BIN_DIR)HP2100-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(HP2100_OPTIONS)/OBJECT=$(BLD_DIR) SCP.C
|
||||
$ $(CC)$(HP2100_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)HP2100-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(HP2100_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
|
@ -915,7 +951,7 @@ I1401 : $(SIMH_LIB) $(I1401_LIB)
|
|||
$!
|
||||
$! Building The $(BIN_DIR)I1401-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(I1401_OPTIONS)/OBJECT=$(BLD_DIR) SCP.C
|
||||
$ $(CC)$(I1401_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)I1401-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(I1401_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
|
@ -924,7 +960,7 @@ I1620 : $(SIMH_LIB) $(I1620_LIB)
|
|||
$!
|
||||
$! Building The $(BIN_DIR)I1620-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(I1620_OPTIONS)/OBJECT=$(BLD_DIR) SCP.C
|
||||
$ $(CC)$(I1620_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)I1620-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(I1620_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
|
@ -933,7 +969,7 @@ IBM1130 : $(SIMH_LIB) $(IBM1130_LIB)
|
|||
$!
|
||||
$! Building The $(BIN_DIR)IBM1130-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(IBM1130_OPTIONS)/OBJECT=$(BLD_DIR) SCP.C
|
||||
$ $(CC)$(IBM1130_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)IBM1130-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(IBM1130_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
|
@ -942,7 +978,7 @@ ID16 : $(SIMH_LIB) $(ID16_LIB)
|
|||
$!
|
||||
$! Building The $(BIN_DIR)ID16-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(ID16_OPTIONS)/OBJECT=$(BLD_DIR) SCP.C
|
||||
$ $(CC)$(ID16_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)ID16-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(ID16_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
|
@ -951,7 +987,7 @@ ID32 : $(SIMH_LIB) $(ID32_LIB)
|
|||
$!
|
||||
$! Building The $(BIN_DIR)ID32-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(ID32_OPTIONS)/OBJECT=$(BLD_DIR) SCP.C
|
||||
$ $(CC)$(ID32_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)ID32-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(ID32_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
|
@ -960,7 +996,7 @@ NOVA : $(SIMH_LIB) $(NOVA_LIB)
|
|||
$!
|
||||
$! Building The $(BIN_DIR)NOVA-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(NOVA_OPTIONS)/OBJECT=$(BLD_DIR) SCP.C
|
||||
$ $(CC)$(NOVA_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)NOVA-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(NOVA_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
|
@ -969,7 +1005,7 @@ PDP1 : $(SIMH_LIB) $(PDP1_LIB)
|
|||
$!
|
||||
$! Building The $(BIN_DIR)PDP1-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(PDP1_OPTIONS)/OBJECT=$(BLD_DIR) SCP.C
|
||||
$ $(CC)$(PDP1_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)PDP1-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(PDP1_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
|
@ -978,7 +1014,7 @@ PDP4 : $(SIMH_LIB) $(PDP4_LIB)
|
|||
$!
|
||||
$! Building The $(BIN_DIR)PDP4-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(PDP4_OPTIONS)/OBJECT=$(BLD_DIR) SCP.C
|
||||
$ $(CC)$(PDP4_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)PDP4-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(PDP4_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
|
@ -987,7 +1023,7 @@ PDP7 : $(SIMH_LIB) $(PDP7_LIB)
|
|||
$!
|
||||
$! Building The $(BIN_DIR)PDP7-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(PDP7_OPTIONS)/OBJECT=$(BLD_DIR) SCP.C
|
||||
$ $(CC)$(PDP7_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)PDP7-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(PDP7_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
|
@ -996,7 +1032,7 @@ PDP8 : $(SIMH_LIB) $(PDP8_LIB)
|
|||
$!
|
||||
$! Building The $(BIN_DIR)PDP8-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(PDP8_OPTIONS)/OBJECT=$(BLD_DIR) SCP.C
|
||||
$ $(CC)$(PDP8_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)PDP8-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(PDP8_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
|
@ -1005,7 +1041,7 @@ PDP9 : $(SIMH_LIB) $(PDP9_LIB)
|
|||
$!
|
||||
$! Building The $(BIN_DIR)PDP9-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(PDP9_OPTIONS)/OBJECT=$(BLD_DIR) SCP.C
|
||||
$ $(CC)$(PDP9_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)PDP9-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(PDP9_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
|
@ -1013,12 +1049,12 @@ PDP9 : $(SIMH_LIB) $(PDP9_LIB)
|
|||
#
|
||||
# If Not On VAX, Build The PDP-10 Simulator.
|
||||
#
|
||||
.IFDEF MMSALPHA
|
||||
.IF ALPHA_OR_IA64
|
||||
PDP10 : $(SIMH_LIB) $(PCAP_LIBD) $(PDP10_LIB) $(PCAP_EXECLET)
|
||||
$!
|
||||
$! Building The $(BIN_DIR)PDP10-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(PDP10_OPTIONS)/OBJECT=$(BLD_DIR) SCP.C
|
||||
$ $(CC)$(PDP10_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)PDP10-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(PDP10_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY$(PCAP_LIBR)
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
|
@ -1028,17 +1064,15 @@ PDP10 : $(SIMH_LIB) $(PCAP_LIBD) $(PDP10_LIB) $(PCAP_EXECLET)
|
|||
# Due To The Use Of INT64.
|
||||
#
|
||||
PDP10 :
|
||||
$!
|
||||
$! Sorry, Can't Build $(BIN_DIR)PDP10-$(ARCH).EXE Simulator
|
||||
$! Because It Requires The Use Of INT64.
|
||||
$!
|
||||
.ENDIF
|
||||
|
||||
PDP11 : $(SIMH_LIB) $(PCAP_LIBD) $(PDP11_LIB1) $(PDP11_LIB2) $(PCAP_EXECLET)
|
||||
$!
|
||||
$! Building The $(BIN_DIR)PDP11-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(PDP11_OPTIONS)/OBJECT=$(BLD_DIR) SCP.C
|
||||
$ $(CC)$(PDP11_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)PDP11-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(PDP11_LIB1)/LIBRARY,$(PDP11_LIB2)/LIBRARY,$(SIMH_LIB)/LIBRARY$(PCAP_LIBR)
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
|
@ -1047,7 +1081,7 @@ PDP15 : $(SIMH_LIB) $(PDP15_LIB)
|
|||
$!
|
||||
$! Building The $(BIN_DIR)PDP15-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(PDP15_OPTIONS)/OBJECT=$(BLD_DIR) SCP.C
|
||||
$ $(CC)$(PDP15_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)PDP15-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(PDP15_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
|
@ -1056,7 +1090,7 @@ S3 : $(SIMH_LIB) $(S3_LIB)
|
|||
$!
|
||||
$! Building The $(BIN_DIR)S3-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(S3_OPTIONS)/OBJECT=$(BLD_DIR) SCP.C
|
||||
$ $(CC)$(S3_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)S3-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(S3_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
|
@ -1065,7 +1099,7 @@ SDS : $(SIMH_LIB) $(SDS_LIB)
|
|||
$!
|
||||
$! Building The $(BIN_DIR)SDS-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(SDS_OPTIONS)/OBJECT=$(BLD_DIR) SCP.C
|
||||
$ $(CC)$(SDS_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)SDS-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(SDS_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
|
@ -1074,24 +1108,49 @@ VAX : $(SIMH_LIB) $(PCAP_LIBD) $(VAX_LIB) $(PCAP_EXECLET)
|
|||
$!
|
||||
$! Building The $(BIN_DIR)VAX-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(VAX_OPTIONS)/OBJECT=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)VAX-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(VAX_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY$(PCAP_LIBR)
|
||||
$ $(CC)$(VAX_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)$(LINK_SECTION_BINDING)-
|
||||
/EXE=$(BIN_DIR)VAX-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(VAX_LIB)/LIBRARY,-
|
||||
$(SIMH_LIB)/LIBRARY$(PCAP_LIBR)
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
|
||||
VAX780 : $(SIMH_LIB) $(PCAP_LIBD) $(VAX780_LIB) $(PCAP_EXECLET)
|
||||
$!
|
||||
$! Building The $(BIN_DIR)VAX780-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(VAX780_OPTIONS)/OBJECT=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)VAX780-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(VAX780_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY$(PCAP_LIBR)
|
||||
$ $(CC)$(VAX780_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)$(LINK_SECTION_BINDING)-
|
||||
/EXE=$(BIN_DIR)VAX780-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(VAX780_LIB)/LIBRARY,-
|
||||
$(SIMH_LIB)/LIBRARY$(PCAP_LIBR)
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
|
||||
#
|
||||
# If Not On VAX, Build The IBM 7094 Simulator.
|
||||
#
|
||||
.IF ALPHA_OR_IA64
|
||||
I7094 : $(SIMH_LIB) $(I7094_LIB)
|
||||
$!
|
||||
$! Building The $(BIN_DIR)I7094-$(ARCH).EXE Simulator.
|
||||
$!
|
||||
$ $(CC)$(I7094_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
|
||||
$ LINK $(LINK_DEBUG)/EXE=$(BIN_DIR)I7094-$(ARCH).EXE -
|
||||
$(BLD_DIR)SCP.OBJ,$(I7094_LIB)/LIBRARY,$(SIMH_LIB)/LIBRARY$(PCAP_LIBR)
|
||||
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
|
||||
.ELSE
|
||||
#
|
||||
# Else We Are On VAX And Tell The User We Can't Build On VAX
|
||||
# Due To The Use Of INT64.
|
||||
#
|
||||
I7094 :
|
||||
$! Sorry, Can't Build $(BIN_DIR)I7094-$(ARCH).EXE Simulator
|
||||
$! Because It Requires The Use Of INT64.
|
||||
.ENDIF
|
||||
|
||||
#
|
||||
# PCAP VCI Components
|
||||
#
|
||||
|
||||
$(PCAP_VCI) : $(PCAP_VCMDIR)PCAPVCM.EXE
|
||||
$!
|
||||
$! Installing the PCAP VCI Execlet in SYS$LOADABLE_IMAGES
|
||||
|
@ -1105,3 +1164,7 @@ $(PCAP_VCMDIR)PCAPVCM.EXE : $(PCAP_VCM_SOURCES)
|
|||
$ @SYS$DISK:[.PCAP-VMS.PCAPVCM]BUILD_PCAPVCM
|
||||
$ DELETE/NOLOG/NOCONFIRM $(PCAP_VCMDIR)*.OBJ;*,$(PCAP_VCMDIR)*.MAP;*
|
||||
|
||||
|
||||
- - -
|
||||
norm lastovica / oracle rdb engineering / salida, colorado, usa
|
||||
reply to: norman.lastovica@oracle.com / phone: 719.339.6749
|
||||
|
|
28
makefile
28
makefile
|
@ -82,7 +82,8 @@ PDP11 = ${PDP11D}pdp11_fp.c ${PDP11D}pdp11_cpu.c ${PDP11D}pdp11_dz.c \
|
|||
${PDP11D}pdp11_rq.c ${PDP11D}pdp11_tq.c ${PDP11D}pdp11_pclk.c \
|
||||
${PDP11D}pdp11_ry.c ${PDP11D}pdp11_pt.c ${PDP11D}pdp11_hk.c \
|
||||
${PDP11D}pdp11_xq.c ${PDP11D}pdp11_xu.c ${PDP11D}pdp11_vh.c \
|
||||
${PDP11D}pdp11_rh.c ${PDP11D}pdp11_tu.c ${PDP11D}pdp11_cpumod.c
|
||||
${PDP11D}pdp11_rh.c ${PDP11D}pdp11_tu.c ${PDP11D}pdp11_cpumod.c \
|
||||
${PDP11D}pdp11_cr.c
|
||||
PDP11_OPT = -DVM_PDP11 -I ${PDP11D} ${NETWORK_OPT}
|
||||
|
||||
|
||||
|
@ -95,19 +96,20 @@ VAX = ${VAXD}vax_cpu.c ${VAXD}vax_cpu1.c ${VAXD}vax_fpa.c ${VAXD}vax_io.c \
|
|||
${PDP11D}pdp11_rl.c ${PDP11D}pdp11_rq.c ${PDP11D}pdp11_ts.c \
|
||||
${PDP11D}pdp11_dz.c ${PDP11D}pdp11_lp.c ${PDP11D}pdp11_tq.c \
|
||||
${PDP11D}pdp11_xq.c ${PDP11D}pdp11_ry.c \
|
||||
${PDP11D}pdp11_vh.c
|
||||
${PDP11D}pdp11_vh.c ${PDP11D}pdp11_cr.c
|
||||
VAX_OPT = -DVM_VAX -DUSE_INT64 -DUSE_ADDR64 -I ${VAXD} -I ${PDP11D} ${NETWORK_OPT}
|
||||
|
||||
|
||||
|
||||
VAX780 = ${VAXD}vax_cpu.c ${VAXD}vax_cpu1.c ${VAXD}vax_fpa.c \
|
||||
${VAXD}vax_cis.c ${VAXD}vax_octa.c ${VAXD}vax_cmode.c \
|
||||
${VAXD}vax_mmu.c ${VAXD}vax780_stddev.c ${VAXD}vax780_sbi.c \
|
||||
${VAXD}vax_mmu.c ${VAXD}vax_sys.c ${VAXD}vax_syscm.c \
|
||||
${VAXD}vax780_stddev.c ${VAXD}vax780_sbi.c \
|
||||
${VAXD}vax780_mem.c ${VAXD}vax780_uba.c ${VAXD}vax780_mba.c \
|
||||
${VAXD}vax_sys.c ${VAXD}vax_syscm.c ${VAXD}vax780_syslist.c \
|
||||
${VAXD}vax780_fload.c ${VAXD}vax780_syslist.c \
|
||||
${PDP11D}pdp11_rl.c ${PDP11D}pdp11_rq.c ${PDP11D}pdp11_ts.c \
|
||||
${PDP11D}pdp11_dz.c ${PDP11D}pdp11_lp.c ${PDP11D}pdp11_tq.c \
|
||||
${PDP11D}pdp11_xu.c ${PDP11D}pdp11_ry.c \
|
||||
${PDP11D}pdp11_xu.c ${PDP11D}pdp11_ry.c ${PDP11D}pdp11_cr.c \
|
||||
${PDP11D}pdp11_rp.c ${PDP11D}pdp11_tu.c ${PDP11D}pdp11_hk.c
|
||||
VAX780_OPT = -DVM_VAX -DVAX_780 -DUSE_INT64 -DUSE_ADDR64 -I ${VAXD} -I ${PDP11D} ${NETWORK_OPT}
|
||||
|
||||
|
@ -169,6 +171,15 @@ I1620_OPT = -I ${I1620D}
|
|||
|
||||
|
||||
|
||||
I7094D = I7094/
|
||||
I7094 = ${I7094D}i7094_cpu.c ${I7094D}i7094_cpu1.c ${I7094D}i7094_io.c \
|
||||
${I7094D}i7094_cd.c ${I7094D}i7094_clk.c ${I7094D}i7094_com.c \
|
||||
${I7094D}i7094_drm.c ${I7094D}i7094_dsk.c ${I7094D}i7094_sys.c \
|
||||
${I7094D}i7094_lp.c ${I7094D}i7094_mt.c
|
||||
I7094_OPT = -DUSE_INT64 -I ${I7094D}
|
||||
|
||||
|
||||
|
||||
IBM1130D = Ibm1130/
|
||||
IBM1130 = ${IBM1130D}ibm1130_cpu.c ${IBM1130D}ibm1130_cr.c \
|
||||
${IBM1130D}ibm1130_disk.c ${IBM1130D}ibm1130_stddev.c \
|
||||
|
@ -247,7 +258,7 @@ ALL = ${BIN}pdp1${EXE} ${BIN}pdp4${EXE} ${BIN}pdp7${EXE} ${BIN}pdp8${EXE} \
|
|||
${BIN}vax${EXE} ${BIN}vax780${EXE} ${BIN}nova${EXE} ${BIN}eclipse${EXE} \
|
||||
${BIN}hp2100${EXE} ${BIN}i1401${EXE} ${BIN}i1620${EXE} ${BIN}s3${EXE} \
|
||||
${BIN}altair${EXE} ${BIN}altairz80${EXE} ${BIN}gri${EXE} \
|
||||
${BIN}i1620${EXE} ${BIN}ibm1130${EXE} ${BIN}id16${EXE} \
|
||||
${BIN}i1620${EXE} ${BIN}i7094${EXE} ${BIN}ibm1130${EXE} ${BIN}id16${EXE} \
|
||||
${BIN}id32${EXE} ${BIN}sds${EXE} ${BIN}lgp${EXE} ${BIN}h316${EXE}
|
||||
|
||||
all : ${ALL}
|
||||
|
@ -338,6 +349,11 @@ ${BIN}i1620${EXE} : ${I1620} ${SIM}
|
|||
${CC} ${I1620} ${SIM} ${I1620_OPT} -o $@ ${LDFLAGS}
|
||||
|
||||
|
||||
${BIN}i7094${EXE} : ${I7094} ${SIM}
|
||||
${CC} ${I7094} ${SIM} ${I7094_OPT} -o $@ ${LDFLAGS}
|
||||
|
||||
|
||||
|
||||
${BIN}ibm1130${EXE} : ${IBM1130}
|
||||
${CC} ${IBM1130} ${SIM} ${IBM1130_OPT} -o $@ ${LDFLAGS}
|
||||
|
||||
|
|
152
scp.c
152
scp.c
|
@ -23,6 +23,7 @@
|
|||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
14-Feb-06 RMS Upgraded save file format to V3.5
|
||||
18-Jan-06 RMS Added fprint_stopped_gen
|
||||
Added breakpoint spaces
|
||||
Fixed unaligned register access (found by Doug Carman)
|
||||
|
@ -317,6 +318,7 @@ t_stat attach_err (UNIT *uptr, t_stat stat);
|
|||
t_stat detach_all (int32 start_device, t_bool shutdown);
|
||||
t_stat assign_device (DEVICE *dptr, char *cptr);
|
||||
t_stat deassign_device (DEVICE *dptr);
|
||||
t_stat run_boot_prep (void);
|
||||
t_stat exdep_reg_loop (FILE *ofile, SCHTAB *schptr, int32 flag, char *cptr,
|
||||
REG *lowr, REG *highr, uint32 lows, uint32 highs);
|
||||
t_stat ex_reg (FILE *ofile, t_value val, int32 flag, REG *rptr, uint32 idx);
|
||||
|
@ -363,12 +365,27 @@ FILE *sim_deb = NULL; /* debug file */
|
|||
static SCHTAB sim_stab;
|
||||
|
||||
static UNIT sim_step_unit = { UDATA (&step_svc, 0, 0) };
|
||||
#if defined USE_INT64
|
||||
static const char *sim_si64 = "64b data";
|
||||
#else
|
||||
static const char *sim_si64 = "32b data";
|
||||
#endif
|
||||
#if defined USE_ADDR64
|
||||
static const char *sim_sa64 = "64b addresses";
|
||||
#else
|
||||
static const char *sim_sa64 = "32b addresses";
|
||||
#endif
|
||||
#if defined USE_NETWORK
|
||||
static const char *sim_snet = "Ethernet support";
|
||||
#else
|
||||
static const char *sim_snet = "no Ethernet";
|
||||
#endif
|
||||
|
||||
/* Tables and strings */
|
||||
|
||||
const char save_vercur[] = "V3.2";
|
||||
const char save_vercur[] = "V3.5";
|
||||
const char save_ver32[] = "V3.2";
|
||||
const char save_ver30[] = "V3.0";
|
||||
const char save_ver210[] = "V2.10";
|
||||
const char *scp_error_messages[] = {
|
||||
"Address space exceeded",
|
||||
"Unit not attached",
|
||||
|
@ -1282,25 +1299,10 @@ return;
|
|||
t_stat show_version (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr)
|
||||
{
|
||||
int32 vmaj = SIM_MAJOR, vmin = SIM_MINOR, vpat = SIM_PATCH;
|
||||
#if defined USE_INT64
|
||||
static const char *si64 = "64b data";
|
||||
#else
|
||||
static const char *si64 = "32b data";
|
||||
#endif
|
||||
#if defined USE_ADDR64
|
||||
static const char *sa64 = "64b addresses";
|
||||
#else
|
||||
static const char *sa64 = "32b addresses";
|
||||
#endif
|
||||
#if defined USE_NETWORK
|
||||
static const char *snet = "Ethernet support";
|
||||
#else
|
||||
static const char *snet = "no Ethernet";
|
||||
#endif
|
||||
|
||||
if (cptr && (*cptr != 0)) return SCPE_2MARG;
|
||||
fprintf (st, "%s simulator V%d.%d-%d", sim_name, vmaj, vmin, vpat);
|
||||
if (flag) fprintf (st, " [%s, %s, %s]", si64, sa64, snet);
|
||||
if (flag) fprintf (st, " [%s, %s, %s]", sim_si64, sim_sa64, sim_snet);
|
||||
fprintf (st, "\n");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
@ -1950,11 +1952,11 @@ REG *rptr;
|
|||
|
||||
#define WRITE_I(xx) sim_fwrite (&(xx), sizeof (xx), 1, sfile)
|
||||
|
||||
fputs (save_vercur, sfile); /* [V2.5] save format */
|
||||
fputc ('\n', sfile);
|
||||
fputs (sim_name, sfile); /* sim name */
|
||||
fputc ('\n', sfile);
|
||||
fprintf (sfile, "%.0f\n", sim_time); /* [V3.2] sim time */
|
||||
fprintf (sfile, "%s\n%s\n%s\n%s\n%s\n%.0f\n",
|
||||
save_vercur, /* [V2.5] save format */
|
||||
sim_name, /* sim name */
|
||||
sim_si64, sim_sa64, sim_snet, /* [V3.5] options */
|
||||
sim_time); /* [V3.2] sim time */
|
||||
WRITE_I (sim_rtime); /* [V2.6] sim rel time */
|
||||
|
||||
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru devices */
|
||||
|
@ -1973,6 +1975,7 @@ for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru devices */
|
|||
WRITE_I (uptr->u5); /* [V3.0] more unit */
|
||||
WRITE_I (uptr->u6);
|
||||
WRITE_I (uptr->flags); /* [V2.10] flags */
|
||||
WRITE_I (uptr->capac); /* [V3.5] capacity */
|
||||
if (uptr->flags & UNIT_ATT) fputs (uptr->filename, sfile);
|
||||
fputc ('\n', sfile);
|
||||
if (((uptr->flags & (UNIT_FIX + UNIT_ATTABLE)) == UNIT_FIX) &&
|
||||
|
@ -2052,11 +2055,11 @@ char buf[CBUFSIZE];
|
|||
void *mbuf;
|
||||
int32 j, blkcnt, limit, unitno, time, flg;
|
||||
uint32 us, depth;
|
||||
t_addr k, high;
|
||||
t_addr k, high, old_capac;
|
||||
t_value val, mask;
|
||||
t_stat r;
|
||||
size_t sz;
|
||||
t_bool v32 = FALSE, v30 = FALSE;
|
||||
t_bool v35, v32;
|
||||
DEVICE *dptr;
|
||||
UNIT *uptr;
|
||||
REG *rptr;
|
||||
|
@ -2067,10 +2070,11 @@ REG *rptr;
|
|||
return SCPE_IOERR;
|
||||
|
||||
READ_S (buf); /* [V2.5+] read version */
|
||||
if (strcmp (buf, save_vercur) == 0) v32 = v30 = TRUE; /* version 3.2? */
|
||||
else if (strcmp (buf, save_ver30) == 0) v30 = TRUE; /* version 3.0? */
|
||||
else if (strcmp (buf, save_ver210) != 0) { /* version 2.10? */
|
||||
printf ("Invalid file version: %s\n", buf); /* no, unknown */
|
||||
v35 = v32 = FALSE;
|
||||
if (strcmp (buf, save_vercur) == 0) v35 = v32 = TRUE; /* version 3.5? */
|
||||
else if (strcmp (buf, save_ver32) == 0) v32 = TRUE; /* version 3.2? */
|
||||
else if (strcmp (buf, save_ver30) != 0) { /* version 3.0? */
|
||||
printf ("Invalid file version: %s\n", buf);
|
||||
return SCPE_INCOMP;
|
||||
}
|
||||
READ_S (buf); /* read sim name */
|
||||
|
@ -2078,7 +2082,20 @@ if (strcmp (buf, sim_name)) { /* name match? */
|
|||
printf ("Wrong system type: %s\n", buf);
|
||||
return SCPE_INCOMP;
|
||||
}
|
||||
if (v32) { /* [V3.2] time as string */
|
||||
if (v35) { /* [V3.5+] options */
|
||||
READ_S (buf); /* integer size */
|
||||
if (strcmp (buf, sim_si64) != 0) {
|
||||
printf ("Incompatible integer size, save file = %s\n", buf);
|
||||
return SCPE_INCOMP;
|
||||
}
|
||||
READ_S (buf); /* address size */
|
||||
if (strcmp (buf, sim_sa64) != 0) {
|
||||
printf ("Incompatible address size, save file = %s\n", buf);
|
||||
return SCPE_INCOMP;
|
||||
}
|
||||
READ_S (buf); /* Ethernet */
|
||||
}
|
||||
if (v32) { /* [V3.2+] time as string */
|
||||
READ_S (buf);
|
||||
sscanf (buf, "%lf", &sim_time);
|
||||
}
|
||||
|
@ -2092,15 +2109,13 @@ for ( ;; ) { /* device loop */
|
|||
printf ("Invalid device name: %s\n", buf);
|
||||
return SCPE_INCOMP;
|
||||
}
|
||||
if (v30) { /* [V3.0+] */
|
||||
READ_S (buf); /* read logical name */
|
||||
READ_S (buf); /* [V3.0+] logical name */
|
||||
deassign_device (dptr); /* delete old name */
|
||||
if ((buf[0] != 0) &&
|
||||
((r = assign_device (dptr, buf)) != SCPE_OK)) return r;
|
||||
}
|
||||
READ_I (flg); /* [V2.10+] ctlr flags */
|
||||
if (!v32) flg = ((flg & DEV_UFMASK_31) << (DEV_V_UF - DEV_V_UF_31)) |
|
||||
(flg & ~DEV_UFMASK_31); /* [V3.2] flags moved */
|
||||
(flg & ~DEV_UFMASK_31); /* [V3.2+] flags moved */
|
||||
dptr->flags = (dptr->flags & ~DEV_RFLAGS) | /* restore ctlr flags */
|
||||
(flg & DEV_RFLAGS);
|
||||
for ( ;; ) { /* unit loop */
|
||||
|
@ -2116,13 +2131,15 @@ for ( ;; ) { /* device loop */
|
|||
if (time > 0) sim_activate (uptr, time - 1);
|
||||
READ_I (uptr->u3); /* device specific */
|
||||
READ_I (uptr->u4);
|
||||
if (v30) { /* [V3.0+] */
|
||||
READ_I (uptr->u5); /* more dev specific */
|
||||
READ_I (uptr->u5); /* [V3.0+] more dev spec */
|
||||
READ_I (uptr->u6);
|
||||
}
|
||||
READ_I (flg); /* [V2.10+] unit flags */
|
||||
old_capac = uptr->capac; /* save current capacity */
|
||||
if (v35) { /* [V3.5+] capacity */
|
||||
READ_I (uptr->capac);
|
||||
}
|
||||
if (!v32) flg = ((flg & UNIT_UFMASK_31) << (UNIT_V_UF - UNIT_V_UF_31)) |
|
||||
(flg & ~UNIT_UFMASK_31); /* [V3.2] flags moved */
|
||||
(flg & ~UNIT_UFMASK_31); /* [V3.2+] flags moved */
|
||||
uptr->flags = (uptr->flags & ~UNIT_RFLAGS) |
|
||||
(flg & UNIT_RFLAGS); /* restore */
|
||||
READ_S (buf); /* attached file */
|
||||
|
@ -2148,12 +2165,13 @@ for ( ;; ) { /* device loop */
|
|||
printf ("Can't restore memory: %s%d\n", sim_dname (dptr), unitno);
|
||||
return SCPE_INCOMP;
|
||||
}
|
||||
if (high != uptr->capac) {
|
||||
if (high != old_capac) {
|
||||
if ((dptr->flags & DEV_DYNM) &&
|
||||
((dptr->msize == NULL) ||
|
||||
(dptr->msize (uptr, (int32) high, NULL, NULL) != SCPE_OK))) {
|
||||
printf ("Can't change memory size: %s%d\n",
|
||||
sim_dname (dptr), unitno);
|
||||
uptr->capac = old_capac;
|
||||
return SCPE_INCOMP;
|
||||
}
|
||||
uptr->capac = high;
|
||||
|
@ -2228,50 +2246,53 @@ void int_handler (int signal);
|
|||
|
||||
GET_SWITCHES (cptr); /* get switches */
|
||||
sim_step = 0;
|
||||
if (((flag == RU_RUN) || (flag == RU_GO)) && (*cptr != 0)) { /* run or go */
|
||||
if ((flag == RU_RUN) || (flag == RU_GO)) { /* run or go */
|
||||
if (*cptr != 0) { /* argument? */
|
||||
cptr = get_glyph (cptr, gbuf, 0); /* get next glyph */
|
||||
if (*cptr != 0) return SCPE_2MARG; /* should be end */
|
||||
if (sim_vm_parse_addr) /* address parser? */
|
||||
pcv = sim_vm_parse_addr (sim_dflt_dev, gbuf, &tptr);
|
||||
else pcv = strtotv (gbuf, &tptr, sim_PC->radix);
|
||||
if ((tptr == gbuf) || (*tptr != 0) ||
|
||||
else pcv = strtotv (gbuf, &tptr, sim_PC->radix);/* parse PC */
|
||||
if ((tptr == gbuf) || (*tptr != 0) || /* error? */
|
||||
(pcv > width_mask[sim_PC->width])) return SCPE_ARG;
|
||||
put_rval (sim_PC, 0, pcv);
|
||||
}
|
||||
if ((flag == RU_RUN) && /* run? */
|
||||
((r = run_boot_prep ()) != SCPE_OK)) return r; /* reset sim */
|
||||
}
|
||||
|
||||
if (flag == RU_STEP) { /* step */
|
||||
if (*cptr == 0) sim_step = 1;
|
||||
else {
|
||||
cptr = get_glyph (cptr, gbuf, 0);
|
||||
else if (flag == RU_STEP) { /* step */
|
||||
if (*cptr != 0) { /* argument? */
|
||||
cptr = get_glyph (cptr, gbuf, 0); /* get next glyph */
|
||||
if (*cptr != 0) return SCPE_2MARG; /* should be end */
|
||||
sim_step = (int32) get_uint (gbuf, 10, INT_MAX, &r);
|
||||
if ((r != SCPE_OK) || (sim_step <= 0)) return SCPE_ARG;
|
||||
if ((r != SCPE_OK) || (sim_step <= 0)) /* error? */
|
||||
return SCPE_ARG;
|
||||
}
|
||||
else sim_step = 1;
|
||||
}
|
||||
|
||||
if (flag == RU_BOOT) { /* boot */
|
||||
else if (flag == RU_BOOT) { /* boot */
|
||||
if (*cptr == 0) return SCPE_2FARG; /* must be more */
|
||||
cptr = get_glyph (cptr, gbuf, 0); /* get next glyph */
|
||||
if (*cptr != 0) return SCPE_2MARG; /* should be end */
|
||||
dptr = find_unit (gbuf, &uptr); /* locate unit */
|
||||
if (dptr == NULL) return SCPE_NXDEV; /* found dev? */
|
||||
if (uptr == NULL) return SCPE_NXUN; /* valid unit? */
|
||||
if (dptr->boot == NULL) return SCPE_NOFNC; /* can it boot? */
|
||||
if (uptr->flags & UNIT_DIS) return SCPE_UDIS; /* disabled? */
|
||||
if ((uptr->flags & UNIT_ATTABLE) &&
|
||||
if ((uptr->flags & UNIT_ATTABLE) && /* if attable, att? */
|
||||
!(uptr->flags & UNIT_ATT)) return SCPE_UNATT;
|
||||
unitno = (int32) (uptr - dptr->units); /* recover unit# */
|
||||
if ((r = dptr->boot (unitno, dptr)) != SCPE_OK) return r;
|
||||
if ((r = run_boot_prep ()) != SCPE_OK) return r; /* reset sim */
|
||||
if ((r = dptr->boot (unitno, dptr)) != SCPE_OK) /* boot device */
|
||||
return r;
|
||||
}
|
||||
|
||||
if (*cptr != 0) return SCPE_2MARG; /* now eol? */
|
||||
else if (flag != RU_CONT) return SCPE_IERR; /* must be cont */
|
||||
|
||||
if ((flag == RU_RUN) || (flag == RU_BOOT)) { /* run or boot */
|
||||
sim_interval = 0; /* reset queue */
|
||||
sim_time = sim_rtime = 0;
|
||||
noqueue_time = 0;
|
||||
sim_clock_queue = NULL;
|
||||
if ((r = reset_all_p (0)) != SCPE_OK) return r;
|
||||
}
|
||||
for (i = 1; (dptr = sim_devices[i]) != NULL; i++) {
|
||||
for (j = 0; j < dptr->numunits; j++) {
|
||||
for (i = 1; (dptr = sim_devices[i]) != NULL; i++) { /* reposition all */
|
||||
for (j = 0; j < dptr->numunits; j++) { /* seq devices */
|
||||
uptr = dptr->units + j;
|
||||
if ((uptr->flags & (UNIT_ATT + UNIT_SEQ)) ==
|
||||
(UNIT_ATT + UNIT_SEQ))
|
||||
|
@ -2326,6 +2347,17 @@ if (sim_log) fprint_stopped (sim_log, r); /* log if enabled */
|
|||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Common setup for RUN or BOOT */
|
||||
|
||||
t_stat run_boot_prep (void)
|
||||
{
|
||||
sim_interval = 0; /* reset queue */
|
||||
sim_time = sim_rtime = 0;
|
||||
noqueue_time = 0;
|
||||
sim_clock_queue = NULL;
|
||||
return reset_all_p (0);
|
||||
}
|
||||
|
||||
/* Print stopped message */
|
||||
|
||||
void fprint_stopped_gen (FILE *st, t_stat v, REG *pc, DEVICE *dptr)
|
||||
|
|
17
sim_fio.c
17
sim_fio.c
|
@ -1,6 +1,6 @@
|
|||
/* sim_fio.c: simulator file I/O library
|
||||
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -23,6 +23,8 @@
|
|||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
15-May-06 RMS Added sim_fsize_name
|
||||
21-Apr-06 RMS Added FreeBSD large file support (from Mark Martinec)
|
||||
19-Nov-05 RMS Added OS/X large file support (from Peter Schorn)
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
17-Jul-04 RMS Fixed bug in optimized sim_fread (reported by Scott Bailey)
|
||||
|
@ -126,6 +128,17 @@ return total;
|
|||
|
||||
/* Get file size */
|
||||
|
||||
uint32 sim_fsize_name (char *fname)
|
||||
{
|
||||
FILE *fp;
|
||||
uint32 sz;
|
||||
|
||||
if ((fp = sim_fopen (fname, "rb")) == NULL) return 0;
|
||||
sz = sim_fsize (fp);
|
||||
fclose (fp);
|
||||
return sz;
|
||||
}
|
||||
|
||||
uint32 sim_fsize (FILE *fp)
|
||||
{
|
||||
uint32 pos, sz;
|
||||
|
@ -279,7 +292,7 @@ return fseeko64 (st, xpos, origin);
|
|||
|
||||
/* Apple OS/X */
|
||||
|
||||
#if defined (__APPLE__)
|
||||
#if defined (__APPLE__) || defined (__FreeBSD__)
|
||||
#define _SIM_IO_FSEEK_EXT_ 1
|
||||
|
||||
int sim_fseek (FILE *st, t_addr xpos, int origin)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* sim_fio.h: simulator file I/O library headers
|
||||
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
Copyright (c) 1993-2006, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -23,6 +23,7 @@
|
|||
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.
|
||||
|
||||
15-May-06 RMS Added sim_fsize_name
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
02-Jan-04 RMS Split out from SCP
|
||||
*/
|
||||
|
@ -40,5 +41,6 @@ int sim_fseek (FILE *st, t_addr offset, int whence);
|
|||
size_t sim_fread (void *bptr, size_t size, size_t count, FILE *fptr);
|
||||
size_t sim_fwrite (void *bptr, size_t size, size_t count, FILE *fptr);
|
||||
uint32 sim_fsize (FILE *fptr);
|
||||
uint32 sim_fsize_name (char *fname);
|
||||
|
||||
#endif
|
||||
|
|
120
sim_rev.h
120
sim_rev.h
|
@ -28,8 +28,124 @@
|
|||
#define _SIM_REV_H_ 0
|
||||
|
||||
#define SIM_MAJOR 3
|
||||
#define SIM_MINOR 5
|
||||
#define SIM_PATCH 2
|
||||
#define SIM_MINOR 6
|
||||
#define SIM_PATCH 0
|
||||
|
||||
/* V3.6 revision history
|
||||
|
||||
patch date module(s) and fix(es)
|
||||
|
||||
0 15-May-06 scp.c:
|
||||
- revised save file format to save options, unit capacity
|
||||
|
||||
sim_tape.c, sim_tape.h:
|
||||
- added support for finite reel size
|
||||
- fixed bug in P7B write record
|
||||
|
||||
most magtapes:
|
||||
- added support for finite reel size
|
||||
|
||||
h316_cpu.c: fixed bugs in LLL, LRL (found by Theo Engel)
|
||||
|
||||
h316_lp.c: fixed bug in blanks backscanning (found by Theo Engel)
|
||||
|
||||
h316_stddev.c: fixed bugs in punch state handling (found by Theo Engel)
|
||||
|
||||
i1401_cpu.c: fixed bug in divide (reported by Van Snyder)
|
||||
|
||||
i16_cpu.c: fixed bug in DH (found by Mark Hittinger)
|
||||
|
||||
i32_cpu.c:
|
||||
- fixed bug in DH (found by Mark Hittinger)
|
||||
- added support for 8 register banks in 8/32
|
||||
|
||||
i7094: first release
|
||||
|
||||
id_io.c: fixed bug, GO preserves EXA and SSTA (found by Davis Johnson)
|
||||
|
||||
id_idc.c:
|
||||
- fixed WD/WH handling (found by Davis Johnson)
|
||||
- fixed bug, nop command should be ignored (found by Davis Johnson)
|
||||
|
||||
nova_cpu.c: fixed bug in DIVS (found by Mark Hittinger)
|
||||
|
||||
pdp11_cis.c: (all reported by John Dundas)
|
||||
- fixed bug in decode table
|
||||
- fixed bug in ASHP
|
||||
- fixed bug in write decimal string with mmgt enabled
|
||||
- fixed bug in 0-length strings in multiply/divide
|
||||
|
||||
pdp11_cpu.c: fixed order of operand fetching in XOR for SDSD models
|
||||
|
||||
pdp11_cr.c: added CR11/CD11 support
|
||||
|
||||
pdp11_tc.c:
|
||||
- fixed READ to set extended data bits in TCST (found by Alan Frisbie)
|
||||
|
||||
vax780_fload.c: added FLOAD command
|
||||
|
||||
vax780_sbi.c: fixed writes to ACCS
|
||||
|
||||
vax780_stddev.c: revised timer logic for EVKAE (reported by Tim Stark)
|
||||
|
||||
vax_cis.c: (all reported by Tim Stark)
|
||||
- fixed MOVTC, MOVTUC to preserve cc's through page faults
|
||||
- fixed MOVTUC to stop on translated == escape
|
||||
- fixed CVTPL to set registers before destination reg write
|
||||
- fixed CVTPL to set correct cc bit on overflow
|
||||
- fixed EDITPC to preserve cc's through page faults
|
||||
- fixed EDITPC EO$BLANK_ZERO count, cc test
|
||||
- fixed EDITPC EO$INSERT to insert fill instead of blank
|
||||
- fixed EDITPC EO$LOAD_PLUS/MINUS to skip character
|
||||
|
||||
vax_cpu.c:
|
||||
- added KESU capability to virtual examine
|
||||
- fixed bugs in virtual examine
|
||||
- rewrote CPU history function for improved usability
|
||||
(bugs below reported by Tim Stark)
|
||||
- fixed fault cleanup to clear PSL<tp>
|
||||
- fixed ADAWI r-mode to preserve dst<31:16>
|
||||
- fixed ACBD/G to test correct operand
|
||||
- fixed access checking on modify-class specifiers
|
||||
- fixed branch address calculation in CPU history
|
||||
- fixed bug in reported VA on faulting cross-page write
|
||||
|
||||
vax_cpu1.c: (all reported by Tim Stark)
|
||||
- added access check on system PTE for 11/780
|
||||
- added mbz check in LDPCTX for 11/780
|
||||
|
||||
vax_cmode.c: (all reported by Tim Stark)
|
||||
- fixed omission of SXT
|
||||
- fixed order of operand fetching in XOR
|
||||
|
||||
vax_fpa.c: (all reported by Tim Stark)
|
||||
- fixed POLYD, POLYG to clear R4, R5
|
||||
- fixed POLYD, POLYG to set R3 correctly
|
||||
- fixed POLYD, POLYG to not exit prematurely if arg = 0
|
||||
- fixed POLYD, POLYG to do full 64b multiply
|
||||
- fixed POLYF, POLYD, POLYG to remove truncation on add
|
||||
- fixed POLYF, POLYD, POLYG to mask mul reslt to 31b/63b/63b
|
||||
- fixed fp add routine to test for zero via fraction
|
||||
to support "denormal" argument from POLYF, POLYD, POLYG
|
||||
- fixed bug in 32b floating multiply routine
|
||||
- fixed bug in 64b extended modulus routine
|
||||
|
||||
vax_mmu.c:
|
||||
- added access check on system PTE for 11/780
|
||||
|
||||
vax_octa.c: (all reported by Tim Stark)
|
||||
- fixed MNEGH to test negated sign, clear C
|
||||
- fixed carry propagation in qp_inc, qp_neg, qp_add
|
||||
- fixed pack routines to test for zero via fraction
|
||||
- fixed ACBH to set cc's on result
|
||||
- fixed POLYH to set R3 correctly
|
||||
- fixed POLYH to not exit prematurely if arg = 0
|
||||
- fixed POLYH to mask mul reslt to 127b
|
||||
- fixed fp add routine to test for zero via fraction
|
||||
to support "denormal" argument from POLYH
|
||||
- fixed EMODH to concatenate 15b of 16b extension
|
||||
- fixed bug in reported VA on faulting cross-page write
|
||||
|
||||
|
||||
/* V3.5 revision history
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue