Notes For V3.2-0
RESTRICTION: The PDP-15 FPP is only partially debugged. Do NOT enable this feature for normal operations. WARNING: The core simulator files (scp.c, sim_*.c) have been reorganized. Unzip V3.2-0 to an empty directory before attempting to compile the source. IMPORTANT: If you are compiling for UNIX, please read the notes for Ethernet very carefully. You may need to download a new version of the pcap library, or make changes to the makefile, to get Ethernet support to work. 1. New Features in 3.2-0 1.1 SCP and libraries - Added SHOW <device> RADIX command. - Added SHOW <device> MODIFIERS command. - Added SHOW <device> NAMES command. - Added SET/SHOW <device> DEBUG command. - Added sim_vm_parse_addr and sim_vm_fprint_addr optional interfaces. - Added REG_VMAD flag. - Split SCP into separate libraries for easier modification. - Added more room to the device and unit flag fields. - Changed terminal multiplexor library to support unlimited. number of async lines. 1.2 All DECtapes - Added STOP_EOR flag to enable end-of-reel error stop - Added device debug support. 1.3 Nova and Eclipse - Added QTY and ALM multiplexors (Bruce Ray). 1.4 LGP-30 - Added LGP-30/LGP-21 simulator. 1.5 PDP-11 - Added format, address increment inhibit, transfer overrun detection to RK. - Added device debug support to HK, RP, TM, TQ, TS. - Added DEUNA/DELUA (XU) support (Dave Hittner). - Add DZ per-line logging. 1.6 18b PDP's - Added support for 1-4 (PDP-9)/1-16 (PDP-15) additional terminals. 1.7 PDP-10 - Added DEUNA/DELUA (XU) support (Dave Hittner). 1.8 VAX - Added extended memory to 512MB (Mark Pizzolato). - Added RXV21 support. 2. Bugs Fixed in 3.2-0 2.1 SCP - Fixed double logging of SHOW BREAK (found by Mark Pizzolato). - Fixed implementation of REG_VMIO. 2.2 Nova and Eclipse - Fixed device enable/disable support (found by Bruce Ray). 2.3 PDP-1 - Fixed bug in LOAD (found by Mark Crispin). 2.4 PDP-10 - Fixed bug in floating point unpack. - Fixed bug in FIXR (found by Phil Stone, fixed by Chris Smith). 2.6 PDP-11 - Fixed bug in RQ interrupt control (found by Tom Evans). 2.6 PDP-18B - Fixed bug in PDP-15 XVM g_mode implementation. - Fixed bug in PDP-15 indexed address calculation. - Fixed bug in PDP-15 autoindexed address calculation. - Fixed bugs in FPP-15 instruction decode. - Fixed clock response to CAF. - Fixed bug in hardware read-in mode bootstrap. - Fixed PDP-15 XVM instruction decoding errors. 2.7 VAX - Fixed PC read fault in EXTxV. - Fixed PC write fault in INSV.
This commit is contained in:
parent
1da2d9452d
commit
26aa6de663
232 changed files with 17724 additions and 9661 deletions
254
0readme_31.txt
254
0readme_31.txt
|
@ -1,254 +0,0 @@
|
||||||
Notes For V3.1-0
|
|
||||||
|
|
||||||
RESTRICTION: The FP15 and XVM features of the PDP-15 are only partially
|
|
||||||
debugged. Do NOT enable these features for normal operations.
|
|
||||||
|
|
||||||
1. New Features in 3.1-0
|
|
||||||
|
|
||||||
1.1 SCP and libraries
|
|
||||||
|
|
||||||
- Added simulated Ethernet support for VMS, FreeBSD, Mac OS/X.
|
|
||||||
- Added status return to tmxr_putc_ln.
|
|
||||||
- Added sim_putchar_s to handle possible output stalls.
|
|
||||||
|
|
||||||
1.2 All DECtapes
|
|
||||||
|
|
||||||
- Added "DECtape off reel" error stop.
|
|
||||||
|
|
||||||
1.3 All Asynchronous Consoles
|
|
||||||
|
|
||||||
- Added support for output congestion stall if using a Telnet connection.
|
|
||||||
|
|
||||||
1.4 PDP-1
|
|
||||||
|
|
||||||
- Added Type 23 parallel drum support.
|
|
||||||
|
|
||||||
1.5 PDP-8
|
|
||||||
|
|
||||||
- Added instruction history.
|
|
||||||
- Added TSC8-75 option support for ETOS.
|
|
||||||
- Added TD8E DECtape support.
|
|
||||||
|
|
||||||
1.6 PDP-18b
|
|
||||||
|
|
||||||
- Added instruction history.
|
|
||||||
- Changed PDP-9, PDP-15 API default to enabled.
|
|
||||||
|
|
||||||
1.7 PDP-11
|
|
||||||
|
|
||||||
- Added support for 18b only Qbus devices.
|
|
||||||
- Formalized bus and addressing definitions.
|
|
||||||
- Added control to enable/disable autoconfiguration.
|
|
||||||
- Added stub support for second Unibus Ethernet controller.
|
|
||||||
|
|
||||||
1.7 Interdata 32b
|
|
||||||
|
|
||||||
- Added instruction history.
|
|
||||||
|
|
||||||
1.8 Eclipse
|
|
||||||
|
|
||||||
- Added floating point support.
|
|
||||||
- Added programmable interval timer support.
|
|
||||||
|
|
||||||
1.9 H316
|
|
||||||
|
|
||||||
- Added DMA/DMC support.
|
|
||||||
- Added fixed head disk support.
|
|
||||||
- Added moving head disk support.
|
|
||||||
- Added magtape support.
|
|
||||||
|
|
||||||
1.10 IBM 1130 (Brian Knittel)
|
|
||||||
|
|
||||||
- Added support for physical card reader, using the Cardread
|
|
||||||
interface (www.ibm1130.org/sim/downloads).
|
|
||||||
- Added support for physical printer (flushes output buffer after
|
|
||||||
each line).
|
|
||||||
|
|
||||||
2. Bugs Fixed in 3.1-0
|
|
||||||
|
|
||||||
2.1 SCP and libraries
|
|
||||||
|
|
||||||
- Fixed numerous bugs in Ethernet library.
|
|
||||||
|
|
||||||
2.2 All DECtapes
|
|
||||||
|
|
||||||
- Fixed reverse checksum value in 'read all' mode.
|
|
||||||
- Simplified (and sped up) timing.
|
|
||||||
|
|
||||||
2.3 PDP-8
|
|
||||||
|
|
||||||
- Fixed bug in RX28 read status (found by Charles Dickman).
|
|
||||||
- Fixed RX28 double density write.
|
|
||||||
|
|
||||||
2.4 PDP-18b
|
|
||||||
|
|
||||||
- Fixed autoincrement bug in PDP-4, PDP-7, PDP-9.
|
|
||||||
|
|
||||||
2.5 PDP-11/VAX
|
|
||||||
|
|
||||||
- Revised RQ MB->LBN conversion for greater accuracy.
|
|
||||||
- Fixed bug in IO configuration (found by David Hittner).
|
|
||||||
- Fixed bug with multiple RQ RAUSER drives.
|
|
||||||
- Fixed bug in second Qbus Ethernet controller interrupts.
|
|
||||||
|
|
||||||
2.6 Nova/Eclipse
|
|
||||||
|
|
||||||
- Fixed bugs in DKP flag clear, map setup, map usage (Charles Owen).
|
|
||||||
- Fixed bug in MT, reset completes despite I/O reset (Charles Owen).
|
|
||||||
- Fixed bug in MT, space operations return word count (Charles Owen).
|
|
||||||
|
|
||||||
2.7 IBM 1130 (Brian Knittel)
|
|
||||||
|
|
||||||
- Fixed bug in setting carry bit in subtract and subtract double.
|
|
||||||
- Fixed timing problem in console printer simulation.
|
|
||||||
|
|
||||||
2.8 1620
|
|
||||||
|
|
||||||
- Fixed bug in branch digit (found by Dave Babcock).
|
|
||||||
|
|
||||||
3. New Features in 3.0 vs prior releases
|
|
||||||
|
|
||||||
3.1 SCP and Libraries
|
|
||||||
|
|
||||||
- Added ASSIGN/DEASSIGN (logical name) commands.
|
|
||||||
- Changed RESTORE to unconditionally detach files.
|
|
||||||
- Added E11 and TPC format support to magtape library.
|
|
||||||
- Fixed bug in SHOW CONNECTIONS.
|
|
||||||
- Added USE_ADDR64 support.
|
|
||||||
|
|
||||||
3.2 All magtapes
|
|
||||||
|
|
||||||
- Magtapes support SIMH format, E11 format, and TPC format (read only).
|
|
||||||
- SET <tape_unit> FORMAT=format sets the specified tape unit's format.
|
|
||||||
- SHOW <tape_unit> FORMAT displays the specified tape unit's format.
|
|
||||||
- Tape format can also be set as part of the ATTACH command, using
|
|
||||||
the -F switch.
|
|
||||||
|
|
||||||
3.3 VAX
|
|
||||||
|
|
||||||
- VAX can be compiled without USE_INT64.
|
|
||||||
- If compiled with USE_INT64 and USE_ADDR64, RQ and TQ controllers support
|
|
||||||
files > 2GB.
|
|
||||||
- VAX ROM has speed control (SET ROM DELAY/NODELAY).
|
|
||||||
|
|
||||||
3.4 PDP-1
|
|
||||||
|
|
||||||
- Added block loader format support to LOAD.
|
|
||||||
- Changed BOOT PTR to allow loading of all of the first bank of memory.
|
|
||||||
- The LOAD command takes an optional argument specifying the memory field
|
|
||||||
to be loaded.
|
|
||||||
- The PTR BOOT command takes its starting memory field from the TA (address
|
|
||||||
switch) register.
|
|
||||||
|
|
||||||
3.5 PDP-18b Family
|
|
||||||
|
|
||||||
- Added PDP-4 EAE support.
|
|
||||||
- Added PDP-15 FP15 support.
|
|
||||||
- Added PDP-15 XVM support.
|
|
||||||
- Added PDP-15 "re-entrancy ECO".
|
|
||||||
- Added PDP-7, PDP-9, PDP-15 hardware RIM loader support in BOOT PTR.
|
|
||||||
|
|
||||||
4. Bugs Fixed in 3.0 vs prior releases
|
|
||||||
|
|
||||||
4.1 SCP and Libraries
|
|
||||||
|
|
||||||
- Fixed end of file problem in dep, idep.
|
|
||||||
- Fixed handling of trailing spaces in dep, idep.
|
|
||||||
|
|
||||||
4.2 VAX
|
|
||||||
|
|
||||||
- Fixed CVTfi bug: integer overflow not set if exponent out of range
|
|
||||||
- Fixed EMODx bugs:
|
|
||||||
o First and second operands reversed
|
|
||||||
o Separated fraction received wrong exponent
|
|
||||||
o Overflow calculation on separated integer incorrect
|
|
||||||
o Fraction not set to zero if exponent out of range
|
|
||||||
- Fixed interval timer and ROM access to pass power-up self-test even on very
|
|
||||||
fast host processors (fixes from Mark Pizzolato).
|
|
||||||
- Fixed bug in user disk size (found by Chaskiel M Grundman).
|
|
||||||
|
|
||||||
4.3 1401
|
|
||||||
|
|
||||||
- Fixed mnemonic, instruction lengths, and reverse scan length check bug for MCS.
|
|
||||||
- Fixed MCE bug, BS off by 1 if zero suppress.
|
|
||||||
- Fixed chaining bug, D lost if return to SCP.
|
|
||||||
- Fixed H branch, branch occurs after continue.
|
|
||||||
- Added check for invalid 8 character MCW, LCA.
|
|
||||||
- Fixed magtape load-mode end of record response.
|
|
||||||
- Revised fetch to model hardware more closely.
|
|
||||||
- Fixed tape read end-of-record handling based on real 1401.
|
|
||||||
- Added diagnostic read (space forward).
|
|
||||||
|
|
||||||
4.4 Nova
|
|
||||||
|
|
||||||
- Fixed DSK variable size interaction with restore.
|
|
||||||
- Fixed bug in DSK set size routine.
|
|
||||||
|
|
||||||
4.5 PDP-1
|
|
||||||
|
|
||||||
- Fixed DT variable size interaction with restore.
|
|
||||||
- Updated CPU, line printer, standard devices to detect indefinite I/O wait.
|
|
||||||
- Fixed incorrect logical, missing activate, break in drum simulator.
|
|
||||||
- Fixed bugs in instruction decoding, overprinting for line printer.
|
|
||||||
- Fixed system hang if continue after PTR error.
|
|
||||||
- Fixed PTR to start/stop on successive rpa instructions.
|
|
||||||
|
|
||||||
4.6 PDP-11
|
|
||||||
|
|
||||||
- Fixed DT variable size interaction with restore.
|
|
||||||
- Fixed bug in MMR1 update (found by Tim Stark).
|
|
||||||
- Added XQ features and fixed bugs:
|
|
||||||
o Corrected XQ interrupts on IE state transition (code by Tom Evans).
|
|
||||||
o Added XQ interrupt clear on soft reset.
|
|
||||||
o Removed XQ interrupt when setting XL or RL (multiple people).
|
|
||||||
o Added SET/SHOW XQ STATS.
|
|
||||||
o Added SHOW XQ FILTERS.
|
|
||||||
o Added ability to split received packet into multiple buffers.
|
|
||||||
o Added explicit runt and giant packet processing.
|
|
||||||
- Fixed bug in user disk size (found by Chaskiel M Grundman).
|
|
||||||
|
|
||||||
4.7 PDP-18B
|
|
||||||
|
|
||||||
- Fixed DT, RF variable size interaction with restore.
|
|
||||||
- Fixed MT bug in MTTR.
|
|
||||||
- Fixed bug in PDP-4 line printer overprinting.
|
|
||||||
- Fixed bug in PDP-15 memory protect/skip interaction.
|
|
||||||
- Fixed bug in RF set size routine.
|
|
||||||
- Increased PTP TIME for PDP-15 operating systems.
|
|
||||||
- Fixed priorities in PDP-15 API (differs from PDP-9).
|
|
||||||
- Fixed sign handling in PDP-15 EAE unsigned mul/div (differs from PDP-9).
|
|
||||||
- Fixed bug in CAF, clears API subsystem.
|
|
||||||
|
|
||||||
4.8 PDP-8
|
|
||||||
|
|
||||||
- Fixed DT, DF, RF, RX variable size interaction with restore.
|
|
||||||
- Fixed MT bug in SKTR.
|
|
||||||
- Fixed bug in DF, RF set size routine.
|
|
||||||
|
|
||||||
4.9 HP2100
|
|
||||||
|
|
||||||
- Fixed bug in DP (13210A controller only), DQ read status.
|
|
||||||
- Fixed bug in DP, DQ seek complete.
|
|
||||||
- Fixed DR drum sizes.
|
|
||||||
- Fixed DR variable capacity interaction with SAVE/RESTORE.
|
|
||||||
|
|
||||||
4.10 GRI
|
|
||||||
|
|
||||||
- Fixed bug in SC queue pointer management.
|
|
||||||
|
|
||||||
4.11 PDP-10
|
|
||||||
|
|
||||||
- Fixed bug in RP read header.
|
|
||||||
|
|
||||||
4.12 Ibm1130
|
|
||||||
|
|
||||||
- Fixed bugs found by APL 1130.
|
|
||||||
|
|
||||||
4.13 Altairz80
|
|
||||||
|
|
||||||
- Fixed bug in real-time clock on Windows host.
|
|
||||||
|
|
||||||
4.14 1620
|
|
||||||
|
|
||||||
- Fixed bug in immediate index add (found by Michael Short).
|
|
||||||
|
|
103
0readme_32.txt
Normal file
103
0readme_32.txt
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
Notes For V3.2-0
|
||||||
|
|
||||||
|
RESTRICTION: The PDP-15 FPP is only partially debugged. Do NOT
|
||||||
|
enable this feature for normal operations.
|
||||||
|
|
||||||
|
WARNING: The core simulator files (scp.c, sim_*.c) have been
|
||||||
|
reorganized. Unzip V3.2-0 to an empty directory before attempting
|
||||||
|
to compile the source.
|
||||||
|
|
||||||
|
IMPORTANT: If you are compiling for UNIX, please read the notes
|
||||||
|
for Ethernet very carefully. You may need to download a new
|
||||||
|
version of the pcap library, or make changes to the makefile,
|
||||||
|
to get Ethernet support to work.
|
||||||
|
|
||||||
|
1. New Features in 3.2-0
|
||||||
|
|
||||||
|
1.1 SCP and libraries
|
||||||
|
|
||||||
|
- Added SHOW <device> RADIX command.
|
||||||
|
- Added SHOW <device> MODIFIERS command.
|
||||||
|
- Added SHOW <device> NAMES command.
|
||||||
|
- Added SET/SHOW <device> DEBUG command.
|
||||||
|
- Added sim_vm_parse_addr and sim_vm_fprint_addr optional interfaces.
|
||||||
|
- Added REG_VMAD flag.
|
||||||
|
- Split SCP into separate libraries for easier modification.
|
||||||
|
- Added more room to the device and unit flag fields.
|
||||||
|
- Changed terminal multiplexor library to support unlimited.
|
||||||
|
number of async lines.
|
||||||
|
|
||||||
|
1.2 All DECtapes
|
||||||
|
|
||||||
|
- Added STOP_EOR flag to enable end-of-reel error stop
|
||||||
|
- Added device debug support.
|
||||||
|
|
||||||
|
1.3 Nova and Eclipse
|
||||||
|
|
||||||
|
- Added QTY and ALM multiplexors (Bruce Ray).
|
||||||
|
|
||||||
|
1.4 LGP-30
|
||||||
|
|
||||||
|
- Added LGP-30/LGP-21 simulator.
|
||||||
|
|
||||||
|
1.5 PDP-11
|
||||||
|
|
||||||
|
- Added format, address increment inhibit, transfer overrun
|
||||||
|
detection to RK.
|
||||||
|
- Added device debug support to HK, RP, TM, TQ, TS.
|
||||||
|
- Added DEUNA/DELUA (XU) support (Dave Hittner).
|
||||||
|
- Add DZ per-line logging.
|
||||||
|
|
||||||
|
1.6 18b PDP's
|
||||||
|
|
||||||
|
- Added support for 1-4 (PDP-9)/1-16 (PDP-15) additional
|
||||||
|
terminals.
|
||||||
|
|
||||||
|
1.7 PDP-10
|
||||||
|
|
||||||
|
- Added DEUNA/DELUA (XU) support (Dave Hittner).
|
||||||
|
|
||||||
|
1.8 VAX
|
||||||
|
|
||||||
|
- Added extended memory to 512MB (Mark Pizzolato).
|
||||||
|
- Added RXV21 support.
|
||||||
|
|
||||||
|
2. Bugs Fixed in 3.2-0
|
||||||
|
|
||||||
|
2.1 SCP
|
||||||
|
|
||||||
|
- Fixed double logging of SHOW BREAK (found by Mark Pizzolato).
|
||||||
|
- Fixed implementation of REG_VMIO.
|
||||||
|
|
||||||
|
2.2 Nova and Eclipse
|
||||||
|
|
||||||
|
- Fixed device enable/disable support (found by Bruce Ray).
|
||||||
|
|
||||||
|
2.3 PDP-1
|
||||||
|
|
||||||
|
- Fixed bug in LOAD (found by Mark Crispin).
|
||||||
|
|
||||||
|
2.4 PDP-10
|
||||||
|
|
||||||
|
- Fixed bug in floating point unpack.
|
||||||
|
- Fixed bug in FIXR (found by Phil Stone, fixed by Chris Smith).
|
||||||
|
|
||||||
|
2.6 PDP-11
|
||||||
|
|
||||||
|
- Fixed bug in RQ interrupt control (found by Tom Evans).
|
||||||
|
|
||||||
|
2.6 PDP-18B
|
||||||
|
|
||||||
|
- Fixed bug in PDP-15 XVM g_mode implementation.
|
||||||
|
- Fixed bug in PDP-15 indexed address calculation.
|
||||||
|
- Fixed bug in PDP-15 autoindexed address calculation.
|
||||||
|
- Fixed bugs in FPP-15 instruction decode.
|
||||||
|
- Fixed clock response to CAF.
|
||||||
|
- Fixed bug in hardware read-in mode bootstrap.
|
||||||
|
- Fixed PDP-15 XVM instruction decoding errors.
|
||||||
|
|
||||||
|
2.7 VAX
|
||||||
|
|
||||||
|
- Fixed PC read fault in EXTxV.
|
||||||
|
- Fixed PC write fault in INSV.
|
||||||
|
|
|
@ -1,16 +1,19 @@
|
||||||
This file contains information about the XQ/SIM_ETHER package.
|
This file contains information about the SIMH Ethernet package.
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
The XQ emulator is a host-independant software emulation of Digital's
|
The XQ emulator is a host-independant software emulation of Digital's
|
||||||
DELQA (M7516) and DEQNA (M7504) Q-bus ethernet cards for the SIMH emulator.
|
DELQA (M7516) and DEQNA (M7504) Q-bus ethernet cards for the SIMH emulator.
|
||||||
|
|
||||||
The XQ emulator uses the Sim_Ether module to execute host-specific ethernet
|
The XU emulator is a host-independant software emulation of Digital's DEUNA
|
||||||
packet reads and writes, since all operating systems talk to real ethernet
|
(M7792/M7793) and DELUA (M7521) Unibus ethernet cards for the SIMH emulator.
|
||||||
cards/controllers differently. The host-dependant Sim_Ether module currently
|
|
||||||
supports Windows, Linux, NetBSD, OpenBSD, FreeBSD, OS/X, and Alpha VMS.
|
|
||||||
|
|
||||||
Currently, the Sim_Ether module sets the selected ethernet card into
|
The XQ and XU simulators use the Sim_Ether module to execute host-specific
|
||||||
|
packet reads and writes, since all operating systems talk to real ethernet
|
||||||
|
cards/controllers differently. See the comments at the top of sim_ether.c
|
||||||
|
for the list of currently supported host platforms.
|
||||||
|
|
||||||
|
The Sim_Ether module sets the selected ethernet card into
|
||||||
promiscuous mode to gather all packets, then filters out the packets that it
|
promiscuous mode to gather all packets, then filters out the packets that it
|
||||||
doesn't want. In Windows, packets having the same source MAC address as the
|
doesn't want. In Windows, packets having the same source MAC address as the
|
||||||
controller are ignored for WinPCAP compatibility (see Windows notes below).
|
controller are ignored for WinPCAP compatibility (see Windows notes below).
|
||||||
|
@ -67,26 +70,58 @@ Building on Windows:
|
||||||
4. If you're using Borland C++, use COFF2OMF to convert the .lib files into
|
4. If you're using Borland C++, use COFF2OMF to convert the .lib files into
|
||||||
a format that can be used by the compiler.
|
a format that can be used by the compiler.
|
||||||
|
|
||||||
5. Define USE_NETWORK if you want the network functionality.
|
5. Define USE_NETWORK.
|
||||||
|
|
||||||
6. Build it!
|
6. Build it!
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
Linux, {Free|Net|Open}BSD, OS/X, and Un*x notes:
|
Linux, {Free|Net|Open}BSD, OS/X, and Un*x notes:
|
||||||
1. You must run SIMH(scp) as root so that the ethernet card can be set into
|
|
||||||
promiscuous mode by the driver. Alternative methods for avoiding the
|
----- WARNING ----- WARNING ----- WARNING ----- WARNING ----- WARNING -----
|
||||||
'run as root' requirement will be welcomed.
|
|
||||||
|
Sim_Ether has been reworked to be more universal; because of this, you will
|
||||||
|
need to get a version of libpcap that is 0.9 or greater. This can be
|
||||||
|
downloaded from www.tcpdump.org - see the comments at the top of Sim_ether.c
|
||||||
|
for details.
|
||||||
|
|
||||||
|
At the time of this release, the "Current Version" available at:
|
||||||
|
http://www.tcpdump.org/daily/libpcap-current.tar.gz is the
|
||||||
|
latest checked-in source code that is actually higher than the released
|
||||||
|
0.8.3 version number. Specifically, for all platforms, it contains code that
|
||||||
|
opens the ethernet device in Read/Write mode instead of the Read-Only mode
|
||||||
|
that previous libpcap versions for platforms which use one of pcap-bpf.c,
|
||||||
|
pcap-pf.c, or pcap-snit.c. This capabiligy now exists to support a newly
|
||||||
|
provided generic packet sending capability.
|
||||||
|
|
||||||
|
----- WARNING ----- WARNING ----- WARNING ----- WARNING ----- WARNING -----
|
||||||
|
|
||||||
|
1. For all platforms, you must run SIMH(scp) with sufficient privilege to
|
||||||
|
allow the ethernet card can be set into promiscuous mode and to write
|
||||||
|
packets through the driver. For most Unix/Unix-like platforms this will
|
||||||
|
mean running as root. For systems which use bpf devices (NetBSD,
|
||||||
|
OpenBSD, FreeBSD and OS/X) it is possible to set permissions on the bpf
|
||||||
|
devices to allow read and write access to users other than root (For
|
||||||
|
example: chmod 666 /dev/bpf*). Doing this, has its own security issues.
|
||||||
|
Additional alternative methods for avoiding the 'run as root' requirement
|
||||||
|
will be welcomed.
|
||||||
|
|
||||||
2. If you want to use TAP devices, they must be created before running SIMH.
|
2. If you want to use TAP devices, they must be created before running SIMH.
|
||||||
|
|
||||||
Linux, {Free|Net|Open}BSD, OS/X, Un*x notes:
|
Building on Linux, {Free|Net|Open}BSD, OS/X, Un*x:
|
||||||
|
|
||||||
1. Get/make/install the libpcap package for your operating system. Sources:
|
1. Get/make/install the libpcap package for your operating system. Sources:
|
||||||
|
All : http://www.tcpdump.org/
|
||||||
|
Older versions of libpcap can be found, for various systems, at:
|
||||||
Linux : search for your variant on http://rpmfind.net
|
Linux : search for your variant on http://rpmfind.net
|
||||||
OS/X : Apple Developer's site?
|
OS/X : Apple Developer's site?
|
||||||
Others : http://sourceforge.net/projects/libpcap/
|
|
||||||
|
|
||||||
2. Use 'make USE_NETWORK=1' if you want the network functionality.
|
NOTE: These repositories will not likely contain a version
|
||||||
|
of libpcap greater than 0.8.1 for several years since
|
||||||
|
other packages in these repositories don't depend on a
|
||||||
|
later version than they currently have.
|
||||||
|
|
||||||
|
2. Use 'make USE_NETWORK=1'
|
||||||
|
|
||||||
3. Build it!
|
3. Build it!
|
||||||
|
|
||||||
|
@ -114,7 +149,8 @@ OpenVMS Alpha notes:
|
||||||
no network devices are available
|
no network devices are available
|
||||||
|
|
||||||
2. You must place the PCAPVCM.EXE execlet in SYS$LOADABLE_IMAGES before
|
2. You must place the PCAPVCM.EXE execlet in SYS$LOADABLE_IMAGES before
|
||||||
running a simulator with ethernet support.
|
running a simulator with ethernet support. Note: This is done by the
|
||||||
|
build commands in descrip.mms.
|
||||||
|
|
||||||
3. You must have CMKRNL privilege to SHOW or ATTACH an ethernet device;
|
3. You must have CMKRNL privilege to SHOW or ATTACH an ethernet device;
|
||||||
alternatively, you can INSTALL the simulator with CMKRNL privilege.
|
alternatively, you can INSTALL the simulator with CMKRNL privilege.
|
||||||
|
@ -125,25 +161,16 @@ OpenVMS Alpha notes:
|
||||||
The execlet is not written to create an I/O structure for the device.
|
The execlet is not written to create an I/O structure for the device.
|
||||||
|
|
||||||
Building on OpenVMS Alpha:
|
Building on OpenVMS Alpha:
|
||||||
1. Build the PCAP library and execlet. They are in the [.PCAP-VMS]
|
The current descrip.mms file will build simulators capable of using
|
||||||
directory in the simh source distribution. The following builds
|
ethernet support with them automatically. These currently are: VAX,
|
||||||
both the pcap library and the pcap execlet:
|
PDP11, and PDP10. The descrip.mms driven builds will also build the
|
||||||
$ set def [.pcap-vms]
|
pcap library and build and install the VCI execlet.
|
||||||
$ @build_all
|
|
||||||
Building VCI version of pcap...
|
|
||||||
Building the PCAP VCM execlet...
|
|
||||||
In order to use it, place PCAPVCM.EXE in the
|
|
||||||
SYS$LOADABLE_IMAGES directory.
|
|
||||||
%DCL-I-SUPERSEDE, previous value of PCAPVCM$OBJ has been superseded
|
|
||||||
|
|
||||||
To use the PCAPVCM.EXE execlet you must copy it to
|
1. Fetch the VMS-PCAP zip file from:
|
||||||
the SYS$LOADABLE_IMAGES directory.
|
http://simh.trailing-edge.com/sources/vms-pcap.zip
|
||||||
|
2. Unzip it into the base of the simh distribution directory.
|
||||||
Build done...
|
3. Build the simulator(s) with MMS or MMK:
|
||||||
|
$ MMx {VAX,PDP11,PDP10, etc...}
|
||||||
2. To build the simulators with ethernet support, you
|
|
||||||
need to build them with MMS or MMK as follows:
|
|
||||||
$ MMx/MACRO=("__ALPHA__=1", "__PCAP__=1")
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -161,6 +188,27 @@ Other testers have reported that RSX with DECNET and the NetBSD operating
|
||||||
systems also work. RSTS/E v10.1 has preliminary support - RSTS/E boots and
|
systems also work. RSTS/E v10.1 has preliminary support - RSTS/E boots and
|
||||||
enables the XH (XQ) device - DECNET and LAT software have not been tested.
|
enables the XH (XQ) device - DECNET and LAT software have not been tested.
|
||||||
|
|
||||||
|
The XU module has been tested by a third party for basic packet functionality
|
||||||
|
under a modified RSX11M environment. I am unable to test it in-house until
|
||||||
|
someone can arrange to send me a disk image containing a stock RSTS/E or
|
||||||
|
RSX11M+ system image that also contains DECNET, LAT, and/or TCP/IP software.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
How to debug problems with the ethernet subsystems:
|
||||||
|
|
||||||
|
PLEASE read the host-specific notes in sim_ether.c!
|
||||||
|
|
||||||
|
While running SCP, the following commands can be used to enable debug messages:
|
||||||
|
|
||||||
|
scp> SET DEBUG STDERR
|
||||||
|
scp> SET XQ DEBUG={ETH|TRC|REG|WRN|CSR|VAR|SAN|SET|PCK}
|
||||||
|
scp> SET XU DEBUG={ETH|TRC|REG|WRN}
|
||||||
|
|
||||||
|
Documentation of the functionality of these debug modifiers can be found in
|
||||||
|
pdp11_xq.h and pdp11_xu.h. Inline debugging has replaced the previous #ifdef
|
||||||
|
style of debugging, which required recompilation before debugging.
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
Things planned for future releases:
|
Things planned for future releases:
|
||||||
|
@ -168,7 +216,6 @@ Things planned for future releases:
|
||||||
2. Full MOP implementation
|
2. Full MOP implementation
|
||||||
3. DESQA support (if someone can get me the user manuals)
|
3. DESQA support (if someone can get me the user manuals)
|
||||||
4. DETQA support [DELQA-Turbo] (I have the manual)
|
4. DETQA support [DELQA-Turbo] (I have the manual)
|
||||||
5. DEUNA/DELUA support
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -190,12 +237,21 @@ Dave
|
||||||
Change Log
|
Change Log
|
||||||
===============================================================================
|
===============================================================================
|
||||||
|
|
||||||
|
19-Mar-04 Release:
|
||||||
|
1. Genericized Sim_Ether code, reduced #ifdefs (David Hittner)
|
||||||
|
2. Further refinement of sim_ether, qualified more platforms (Mark Pizzolato)
|
||||||
|
3. Added XU module (David Hittner)
|
||||||
|
4. Corrected XQ interrupt signalling for PDP11s (David Hittner)
|
||||||
|
5. Added inline debugging support (David Hittner)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
26-Nov-03 Release:
|
26-Nov-03 Release:
|
||||||
1. Added VMS support to Sim_Ether; created pcap-vms port (Anders Ahgren)
|
1. Added VMS support to Sim_Ether; created pcap-vms port (Anders Ahgren)
|
||||||
2. Added DECNET duplicate detection for Windows (Mark Pizzolato)
|
2. Added DECNET duplicate detection for Windows (Mark Pizzolato)
|
||||||
3. Added BPF filtering to increase efficiency (Mark Pizzolato)
|
3. Added BPF filtering to increase efficiency (Mark Pizzolato)
|
||||||
4. Corrected XQ Runt processing (Mark Pizzolato)
|
4. Corrected XQ Runt processing (Mark Pizzolato)
|
||||||
5. Corrected XQ Software Reset (Mark Pizzolato)
|
5. Corrected XQ Sofware Reset (Mark Pizzolato)
|
||||||
6. Corrected XQ Multicast/Promiscuous mode setting/resetting (Mark Pizzolato)
|
6. Corrected XQ Multicast/Promiscuous mode setting/resetting (Mark Pizzolato)
|
||||||
7. Added Universal TUN/TAP support (Mark Pizzolato)
|
7. Added Universal TUN/TAP support (Mark Pizzolato)
|
||||||
8. Added FreeBSD support (Edward Brocklesby)
|
8. Added FreeBSD support (Edward Brocklesby)
|
||||||
|
|
|
@ -3,6 +3,7 @@ Altair 8800 Simulator with Z80 support
|
||||||
|
|
||||||
0. Revision History
|
0. Revision History
|
||||||
|
|
||||||
|
- 26-Jan-2004, Peter Schorn (added support for t-state stepping)
|
||||||
- 25-Feb-2003, Peter Schorn (added support for real time simulation)
|
- 25-Feb-2003, Peter Schorn (added support for real time simulation)
|
||||||
- 9-Oct-2002, Peter Schorn (added support for simulated hard disk)
|
- 9-Oct-2002, Peter Schorn (added support for simulated hard disk)
|
||||||
- 28-Sep-2002, Peter Schorn (number of tracks per disk can be configured)
|
- 28-Sep-2002, Peter Schorn (number of tracks per disk can be configured)
|
||||||
|
@ -842,6 +843,9 @@ following commands:
|
||||||
|
|
||||||
4. Special simulator features
|
4. Special simulator features
|
||||||
|
|
||||||
|
|
||||||
|
4.1 Memory access breakpoints
|
||||||
|
|
||||||
In addition to the regular SIMH features such as PC queue, breakpoints
|
In addition to the regular SIMH features such as PC queue, breakpoints
|
||||||
etc., this simulator supports memory access breakpoints. A memory access
|
etc., this simulator supports memory access breakpoints. A memory access
|
||||||
breakpoint is triggered when a pre-defined memory location is accessed
|
breakpoint is triggered when a pre-defined memory location is accessed
|
||||||
|
@ -855,6 +859,21 @@ a memory access breakpoint is not triggered by fetching code from memory
|
||||||
by using the typing facility of the SIMH breakpoints.
|
by using the typing facility of the SIMH breakpoints.
|
||||||
|
|
||||||
|
|
||||||
|
4.2 T-state stepping
|
||||||
|
|
||||||
|
The SIMH step command supports the "-t" modifier to allow steppping for
|
||||||
|
a predefined number of t-states. For example
|
||||||
|
|
||||||
|
sim> step -t 1000
|
||||||
|
|
||||||
|
will cause the simulated CPU to execute 1000 t-states (note that the shortest
|
||||||
|
instruction will have 4 t-states). On the other hand, the command
|
||||||
|
|
||||||
|
sim> step 1000
|
||||||
|
|
||||||
|
will cause the simulated CPU to execute 1000 instructions.
|
||||||
|
|
||||||
|
|
||||||
5. Brief summary of all major changes to the original Altair simulator
|
5. Brief summary of all major changes to the original Altair simulator
|
||||||
- Full support for Z80. CP/M software requiring a Z80 CPU now runs
|
- Full support for Z80. CP/M software requiring a Z80 CPU now runs
|
||||||
properly. DDTZ and PROLOGZ are included for demonstration purposes.
|
properly. DDTZ and PROLOGZ are included for demonstration purposes.
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
||||||
/* altairz80_defs.h: MITS Altair simulator definitions
|
/* altairz80_defs.h: MITS Altair simulator definitions
|
||||||
|
|
||||||
Copyright (c) 2002-2003, Peter Schorn
|
Copyright (c) 2002-2004, Peter Schorn
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -74,13 +74,9 @@
|
||||||
#define message6(p1,p2,p3,p4,p5,p6) \
|
#define message6(p1,p2,p3,p4,p5,p6) \
|
||||||
sprintf(messageBuffer,PCformat p1,PCX,p2,p3,p4,p5,p6); printMessage()
|
sprintf(messageBuffer,PCformat p1,PCX,p2,p3,p4,p5,p6); printMessage()
|
||||||
|
|
||||||
/* The Default is to use "inline". In this case the wrapper functions for
|
/* The Default is to use "inline". */
|
||||||
GetBYTE and PutBYTE need to be created. Otherwise they are not needed
|
#if defined(NO_INLINE)
|
||||||
and the calls map to the original functions. */
|
|
||||||
#ifdef NO_INLINE
|
|
||||||
#define INLINE
|
#define INLINE
|
||||||
#define GetBYTEWrapper GetBYTE
|
|
||||||
#define PutBYTEWrapper PutBYTE
|
|
||||||
#else
|
#else
|
||||||
#if defined(__DECC) && defined(VMS)
|
#if defined(__DECC) && defined(VMS)
|
||||||
#define INLINE __inline
|
#define INLINE __inline
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* altairz80_dsk.c: MITS Altair 88-DISK Simulator
|
/* altairz80_dsk.c: MITS Altair 88-DISK Simulator
|
||||||
|
|
||||||
Copyright (c) 2002-2003, Peter Schorn
|
Copyright (c) 2002-2004, Peter Schorn
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -142,7 +142,6 @@ static char* selectInOut(const int32 io);
|
||||||
extern int32 PCX;
|
extern int32 PCX;
|
||||||
extern int32 saved_PC;
|
extern int32 saved_PC;
|
||||||
extern FILE *sim_log;
|
extern FILE *sim_log;
|
||||||
extern void PutBYTEWrapper(register uint32 Addr, register uint32 Value);
|
|
||||||
extern void printMessage(void);
|
extern void printMessage(void);
|
||||||
extern char messageBuffer[];
|
extern char messageBuffer[];
|
||||||
extern int32 install_bootrom(void);
|
extern int32 install_bootrom(void);
|
||||||
|
@ -251,7 +250,9 @@ DEVICE dsk_dev = {
|
||||||
"DSK", dsk_unit, dsk_reg, dsk_mod,
|
"DSK", dsk_unit, dsk_reg, dsk_mod,
|
||||||
8, 10, 31, 1, 8, 8,
|
8, 10, 31, 1, 8, 8,
|
||||||
NULL, NULL, &dsk_reset,
|
NULL, NULL, &dsk_reset,
|
||||||
&dsk_boot, NULL, NULL, NULL, 0, NULL, NULL };
|
&dsk_boot, NULL, NULL,
|
||||||
|
NULL, 0, 0,
|
||||||
|
NULL, NULL, NULL };
|
||||||
|
|
||||||
static void resetDSKWarningFlags(void) {
|
static void resetDSKWarningFlags(void) {
|
||||||
int32 i;
|
int32 i;
|
||||||
|
@ -351,7 +352,7 @@ int32 dsk10(const int32 port, const int32 io, const int32 data) {
|
||||||
if (current_disk >= NUM_OF_DSK) {
|
if (current_disk >= NUM_OF_DSK) {
|
||||||
if (hasVerbose() && (warnDSK10 < warnLevelDSK)) {
|
if (hasVerbose() && (warnDSK10 < warnLevelDSK)) {
|
||||||
warnDSK10++;
|
warnDSK10++;
|
||||||
/*01*/ message1("Attempt of IN 0x08 on unattached disk - ignored.\n");
|
/*01*/ message1("Attempt of IN 0x08 on unattached disk - ignored.");
|
||||||
}
|
}
|
||||||
return 0xff; /* no drive selected - can do nothing */
|
return 0xff; /* no drive selected - can do nothing */
|
||||||
}
|
}
|
||||||
|
@ -363,14 +364,14 @@ int32 dsk10(const int32 port, const int32 io, const int32 data) {
|
||||||
writebuf();
|
writebuf();
|
||||||
}
|
}
|
||||||
if (trace_flag & TRACE_IN_OUT) {
|
if (trace_flag & TRACE_IN_OUT) {
|
||||||
message2("OUT 0x08: %x\n", data);
|
message2("OUT 0x08: %x", data);
|
||||||
}
|
}
|
||||||
current_disk = data & NUM_OF_DSK_MASK; /* 0 <= current_disk < NUM_OF_DSK */
|
current_disk = data & NUM_OF_DSK_MASK; /* 0 <= current_disk < NUM_OF_DSK */
|
||||||
current_disk_flags = (dsk_dev.units + current_disk) -> flags;
|
current_disk_flags = (dsk_dev.units + current_disk) -> flags;
|
||||||
if ((current_disk_flags & UNIT_ATT) == 0) { /* nothing attached? */
|
if ((current_disk_flags & UNIT_ATT) == 0) { /* nothing attached? */
|
||||||
if ( (current_disk_flags & UNIT_DSK_VERBOSE) && (warnAttached[current_disk] < warnLevelDSK) ) {
|
if ( (current_disk_flags & UNIT_DSK_VERBOSE) && (warnAttached[current_disk] < warnLevelDSK) ) {
|
||||||
warnAttached[current_disk]++;
|
warnAttached[current_disk]++;
|
||||||
/*02*/message2("Attempt to select unattached DSK%d - ignored.\n", current_disk);
|
/*02*/message2("Attempt to select unattached DSK%d - ignored.", current_disk);
|
||||||
}
|
}
|
||||||
current_disk = NUM_OF_DSK;
|
current_disk = NUM_OF_DSK;
|
||||||
}
|
}
|
||||||
|
@ -390,7 +391,7 @@ int32 dsk11(const int32 port, const int32 io, const int32 data) {
|
||||||
if (current_disk >= NUM_OF_DSK) {
|
if (current_disk >= NUM_OF_DSK) {
|
||||||
if (hasVerbose() && (warnDSK11 < warnLevelDSK)) {
|
if (hasVerbose() && (warnDSK11 < warnLevelDSK)) {
|
||||||
warnDSK11++;
|
warnDSK11++;
|
||||||
/*03*/message2("Attempt of %s 0x09 on unattached disk - ignored.\n", selectInOut(io));
|
/*03*/message2("Attempt of %s 0x09 on unattached disk - ignored.", selectInOut(io));
|
||||||
}
|
}
|
||||||
return 0; /* no drive selected - can do nothing */
|
return 0; /* no drive selected - can do nothing */
|
||||||
}
|
}
|
||||||
|
@ -400,10 +401,10 @@ int32 dsk11(const int32 port, const int32 io, const int32 data) {
|
||||||
in9_count++;
|
in9_count++;
|
||||||
if ((trace_flag & TRACE_SECTOR_STUCK) && (in9_count > 2 * DSK_SECT) && (!in9_message)) {
|
if ((trace_flag & TRACE_SECTOR_STUCK) && (in9_count > 2 * DSK_SECT) && (!in9_message)) {
|
||||||
in9_message = TRUE;
|
in9_message = TRUE;
|
||||||
message2("Looping on sector find %d.\n", current_disk);
|
message2("Looping on sector find %d.", current_disk);
|
||||||
}
|
}
|
||||||
if (trace_flag & TRACE_IN_OUT) {
|
if (trace_flag & TRACE_IN_OUT) {
|
||||||
message1("IN 0x09\n");
|
message1("IN 0x09");
|
||||||
}
|
}
|
||||||
if (dirty) {/* implies that current_disk < NUM_OF_DSK */
|
if (dirty) {/* implies that current_disk < NUM_OF_DSK */
|
||||||
writebuf();
|
writebuf();
|
||||||
|
@ -425,12 +426,12 @@ int32 dsk11(const int32 port, const int32 io, const int32 data) {
|
||||||
/* drive functions */
|
/* drive functions */
|
||||||
|
|
||||||
if (trace_flag & TRACE_IN_OUT) {
|
if (trace_flag & TRACE_IN_OUT) {
|
||||||
message2("OUT 0x09: %x\n", data);
|
message2("OUT 0x09: %x", data);
|
||||||
}
|
}
|
||||||
if (data & 0x01) { /* step head in */
|
if (data & 0x01) { /* step head in */
|
||||||
if (trace_flag & TRACE_TRACK_STUCK) {
|
if (trace_flag & TRACE_TRACK_STUCK) {
|
||||||
if (current_track[current_disk] == (tracks[current_disk] - 1)) {
|
if (current_track[current_disk] == (tracks[current_disk] - 1)) {
|
||||||
message2("Unnecessary step in for disk %d\n", current_disk);
|
message2("Unnecessary step in for disk %d", current_disk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
current_track[current_disk]++;
|
current_track[current_disk]++;
|
||||||
|
@ -447,7 +448,7 @@ int32 dsk11(const int32 port, const int32 io, const int32 data) {
|
||||||
if (data & 0x02) { /* step head out */
|
if (data & 0x02) { /* step head out */
|
||||||
if (trace_flag & TRACE_TRACK_STUCK) {
|
if (trace_flag & TRACE_TRACK_STUCK) {
|
||||||
if (current_track[current_disk] == 0) {
|
if (current_track[current_disk] == 0) {
|
||||||
message2("Unnecessary step out for disk %d\n", current_disk);
|
message2("Unnecessary step out for disk %d", current_disk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
current_track[current_disk]--;
|
current_track[current_disk]--;
|
||||||
|
@ -501,7 +502,7 @@ int32 dsk12(const int32 port, const int32 io, const int32 data) {
|
||||||
if (current_disk >= NUM_OF_DSK) {
|
if (current_disk >= NUM_OF_DSK) {
|
||||||
if (hasVerbose() && (warnDSK12 < warnLevelDSK)) {
|
if (hasVerbose() && (warnDSK12 < warnLevelDSK)) {
|
||||||
warnDSK12++;
|
warnDSK12++;
|
||||||
/*04*/message2("Attempt of %s 0x0a on unattached disk - ignored.\n", selectInOut(io));
|
/*04*/message2("Attempt of %s 0x0a on unattached disk - ignored.", selectInOut(io));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -513,7 +514,7 @@ int32 dsk12(const int32 port, const int32 io, const int32 data) {
|
||||||
if (current_byte[current_disk] >= DSK_SECTSIZE) {
|
if (current_byte[current_disk] >= DSK_SECTSIZE) {
|
||||||
/* physically read the sector */
|
/* physically read the sector */
|
||||||
if (trace_flag & TRACE_READ_WRITE) {
|
if (trace_flag & TRACE_READ_WRITE) {
|
||||||
message4("IN 0x0a (READ) D%d T%d S%d\n", current_disk, current_track[current_disk], current_sector[current_disk]);
|
message4("IN 0x0a (READ) D%d T%d S%d", current_disk, current_track[current_disk], current_sector[current_disk]);
|
||||||
}
|
}
|
||||||
for (i = 0; i < DSK_SECTSIZE; i++) {
|
for (i = 0; i < DSK_SECTSIZE; i++) {
|
||||||
dskbuf[i] = 0;
|
dskbuf[i] = 0;
|
||||||
|
@ -547,21 +548,21 @@ static void writebuf(void) {
|
||||||
uptr = dsk_dev.units + current_disk;
|
uptr = dsk_dev.units + current_disk;
|
||||||
if (((uptr -> flags) & UNIT_DSKWLK) == 0) { /* write enabled */
|
if (((uptr -> flags) & UNIT_DSKWLK) == 0) { /* write enabled */
|
||||||
if (trace_flag & TRACE_READ_WRITE) {
|
if (trace_flag & TRACE_READ_WRITE) {
|
||||||
message4("OUT 0x0a (WRITE) D%d T%d S%d\n", current_disk, current_track[current_disk], current_sector[current_disk]);
|
message4("OUT 0x0a (WRITE) D%d T%d S%d", current_disk, current_track[current_disk], current_sector[current_disk]);
|
||||||
}
|
}
|
||||||
if (dskseek(uptr)) {
|
if (dskseek(uptr)) {
|
||||||
message4("fseek failed D%d T%d S%d\n", current_disk, current_track[current_disk], current_sector[current_disk]);
|
message4("fseek failed D%d T%d S%d", current_disk, current_track[current_disk], current_sector[current_disk]);
|
||||||
}
|
}
|
||||||
rtn = fwrite(dskbuf, DSK_SECTSIZE, 1, uptr -> fileref);
|
rtn = fwrite(dskbuf, DSK_SECTSIZE, 1, uptr -> fileref);
|
||||||
if (rtn != 1) {
|
if (rtn != 1) {
|
||||||
message4("fwrite failed T%d S%d Return=%d\n", current_track[current_disk], current_sector[current_disk], rtn);
|
message4("fwrite failed T%d S%d Return=%d", current_track[current_disk], current_sector[current_disk], rtn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( ((uptr -> flags) & UNIT_DSK_VERBOSE) && (warnLock[current_disk] < warnLevelDSK) ) {
|
else if ( ((uptr -> flags) & UNIT_DSK_VERBOSE) && (warnLock[current_disk] < warnLevelDSK) ) {
|
||||||
/* write locked - print warning message if required */
|
/* write locked - print warning message if required */
|
||||||
warnLock[current_disk]++;
|
warnLock[current_disk]++;
|
||||||
/*05*/
|
/*05*/
|
||||||
message2("Attempt to write to locked DSK%d - ignored.\n", current_disk);
|
message2("Attempt to write to locked DSK%d - ignored.", current_disk);
|
||||||
}
|
}
|
||||||
current_flag[current_disk] &= 0xfe; /* ENWD off */
|
current_flag[current_disk] &= 0xfe; /* ENWD off */
|
||||||
current_byte[current_disk] = 0xff;
|
current_byte[current_disk] = 0xff;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* altairz80_sio: MITS Altair serial I/O card
|
/* altairz80_sio: MITS Altair serial I/O card
|
||||||
|
|
||||||
Copyright (c) 2002-2003, Peter Schorn
|
Copyright (c) 2002-2004, Peter Schorn
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -112,6 +112,9 @@ extern t_stat sim_cancel(UNIT *uptr);
|
||||||
extern t_stat sim_poll_kbd(void);
|
extern t_stat sim_poll_kbd(void);
|
||||||
extern t_stat sim_putchar(int32 out);
|
extern t_stat sim_putchar(int32 out);
|
||||||
extern t_stat attach_unit(UNIT *uptr, char *cptr);
|
extern t_stat attach_unit(UNIT *uptr, char *cptr);
|
||||||
|
extern int32 getBankSelect(void);
|
||||||
|
extern void setBankSelect(int32 b);
|
||||||
|
extern uint32 getCommon(void);
|
||||||
extern t_bool rtc_avail;
|
extern t_bool rtc_avail;
|
||||||
extern FILE *sim_log;
|
extern FILE *sim_log;
|
||||||
extern int32 PCX;
|
extern int32 PCX;
|
||||||
|
@ -119,8 +122,6 @@ extern int32 sim_switches;
|
||||||
extern uint32 sim_os_msec(void);
|
extern uint32 sim_os_msec(void);
|
||||||
extern const char *scp_error_messages[];
|
extern const char *scp_error_messages[];
|
||||||
extern int32 SR;
|
extern int32 SR;
|
||||||
extern int32 bankSelect;
|
|
||||||
extern int32 common;
|
|
||||||
extern uint8 GetBYTEWrapper(register uint32 Addr);
|
extern uint8 GetBYTEWrapper(register uint32 Addr);
|
||||||
extern UNIT cpu_unit;
|
extern UNIT cpu_unit;
|
||||||
|
|
||||||
|
@ -184,7 +185,7 @@ static SIO_TERMINAL sio_terminals[Terminals] =
|
||||||
{0, 0, 0x16, 0x17, 0x00},
|
{0, 0, 0x16, 0x17, 0x00},
|
||||||
{0, 0, 0x18, 0x19, 0x00} };
|
{0, 0, 0x18, 0x19, 0x00} };
|
||||||
static TMLN TerminalLines[Terminals] = { {0} }; /* four terminals */
|
static TMLN TerminalLines[Terminals] = { {0} }; /* four terminals */
|
||||||
static TMXR altairTMXR = {Terminals, 0, 0 }; /* mux descriptor */
|
static TMXR altairTMXR = {Terminals, 0, 0, TerminalLines}; /* mux descriptor */
|
||||||
|
|
||||||
static UNIT sio_unit = { UDATA (&sio_svc, UNIT_ATTABLE, 0), KBD_POLL_WAIT };
|
static UNIT sio_unit = { UDATA (&sio_svc, UNIT_ATTABLE, 0), KBD_POLL_WAIT };
|
||||||
|
|
||||||
|
@ -220,7 +221,9 @@ DEVICE sio_dev = {
|
||||||
"SIO", &sio_unit, sio_reg, sio_mod,
|
"SIO", &sio_unit, sio_reg, sio_mod,
|
||||||
1, 10, 31, 1, 8, 8,
|
1, 10, 31, 1, 8, 8,
|
||||||
NULL, NULL, &sio_reset,
|
NULL, NULL, &sio_reset,
|
||||||
NULL, &sio_attach, &sio_detach, NULL, 0, NULL, NULL };
|
NULL, &sio_attach, &sio_detach,
|
||||||
|
NULL, 0, 0,
|
||||||
|
NULL, NULL, NULL };
|
||||||
|
|
||||||
static UNIT ptr_unit = { UDATA (NULL, UNIT_SEQ + UNIT_ATTABLE + UNIT_ROABLE, 0),
|
static UNIT ptr_unit = { UDATA (NULL, UNIT_SEQ + UNIT_ATTABLE + UNIT_ROABLE, 0),
|
||||||
KBD_POLL_WAIT };
|
KBD_POLL_WAIT };
|
||||||
|
@ -235,7 +238,9 @@ DEVICE ptr_dev = {
|
||||||
"PTR", &ptr_unit, ptr_reg, NULL,
|
"PTR", &ptr_unit, ptr_reg, NULL,
|
||||||
1, 10, 31, 1, 8, 8,
|
1, 10, 31, 1, 8, 8,
|
||||||
NULL, NULL, &ptr_reset,
|
NULL, NULL, &ptr_reset,
|
||||||
NULL, NULL, NULL, NULL, 0, NULL, NULL };
|
NULL, NULL, NULL,
|
||||||
|
NULL, 0, 0,
|
||||||
|
NULL, NULL, NULL };
|
||||||
|
|
||||||
static UNIT ptp_unit = { UDATA (NULL, UNIT_SEQ + UNIT_ATTABLE, 0),
|
static UNIT ptp_unit = { UDATA (NULL, UNIT_SEQ + UNIT_ATTABLE, 0),
|
||||||
KBD_POLL_WAIT };
|
KBD_POLL_WAIT };
|
||||||
|
@ -250,7 +255,9 @@ DEVICE ptp_dev = {
|
||||||
"PTP", &ptp_unit, ptp_reg, NULL,
|
"PTP", &ptp_unit, ptp_reg, NULL,
|
||||||
1, 10, 31, 1, 8, 8,
|
1, 10, 31, 1, 8, 8,
|
||||||
NULL, NULL, &ptp_reset,
|
NULL, NULL, &ptp_reset,
|
||||||
NULL, NULL, NULL, NULL, 0, NULL, NULL };
|
NULL, NULL, NULL,
|
||||||
|
NULL, 0, 0,
|
||||||
|
NULL, NULL, NULL };
|
||||||
|
|
||||||
/* Synthetic device SIMH for communication
|
/* Synthetic device SIMH for communication
|
||||||
between Altair and SIMH environment using port 0xfe */
|
between Altair and SIMH environment using port 0xfe */
|
||||||
|
@ -301,14 +308,24 @@ DEVICE simh_device = {
|
||||||
"SIMH", &simh_unit, simh_reg, simh_mod,
|
"SIMH", &simh_unit, simh_reg, simh_mod,
|
||||||
1, 10, 31, 1, 16, 4,
|
1, 10, 31, 1, 16, 4,
|
||||||
NULL, NULL, &simh_dev_reset,
|
NULL, NULL, &simh_dev_reset,
|
||||||
NULL, NULL, NULL, NULL, 0, NULL, NULL };
|
NULL, NULL, NULL,
|
||||||
|
NULL, 0, 0,
|
||||||
|
NULL, NULL, NULL };
|
||||||
|
|
||||||
char messageBuffer[256];
|
char messageBuffer[256];
|
||||||
|
|
||||||
void printMessage(void) {
|
void printMessage(void) {
|
||||||
printf(messageBuffer);
|
printf(messageBuffer);
|
||||||
|
#if defined(__NetBSD__) || defined (__OpenBSD__) || defined (__FreeBSD__) || defined (__APPLE__)
|
||||||
|
/* need to make sure that carriage return is executed - ttrunstate() of scp_tty.c
|
||||||
|
has disabled \n translation */
|
||||||
|
printf("\r\n");
|
||||||
|
#else
|
||||||
|
printf("\n");
|
||||||
|
#endif
|
||||||
if (sim_log) {
|
if (sim_log) {
|
||||||
fprintf(sim_log, messageBuffer);
|
fprintf(sim_log, messageBuffer);
|
||||||
|
fprintf(sim_log,"\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,10 +342,6 @@ static t_stat sio_set_verbose(UNIT *uptr, int32 value, char *cptr, void *desc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static t_stat sio_attach(UNIT *uptr, char *cptr) {
|
static t_stat sio_attach(UNIT *uptr, char *cptr) {
|
||||||
int32 i;
|
|
||||||
for (i = 0; i < Terminals; i++) {
|
|
||||||
altairTMXR.ldsc[i] = &TerminalLines[i];
|
|
||||||
}
|
|
||||||
reset_sio_terminals(FALSE);
|
reset_sio_terminals(FALSE);
|
||||||
return tmxr_attach(&altairTMXR, uptr, cptr); /* attach mux */
|
return tmxr_attach(&altairTMXR, uptr, cptr); /* attach mux */
|
||||||
}
|
}
|
||||||
|
@ -362,7 +375,7 @@ static t_stat sio_svc(UNIT *uptr) {
|
||||||
}
|
}
|
||||||
temp = tmxr_poll_conn(&altairTMXR); /* poll connection */
|
temp = tmxr_poll_conn(&altairTMXR); /* poll connection */
|
||||||
if (temp >= 0) {
|
if (temp >= 0) {
|
||||||
altairTMXR.ldsc[temp] -> rcve = 1; /* enable receive */
|
TerminalLines[temp].rcve = 1; /* enable receive */
|
||||||
}
|
}
|
||||||
tmxr_poll_rx(&altairTMXR); /* poll input */
|
tmxr_poll_rx(&altairTMXR); /* poll input */
|
||||||
tmxr_poll_tx(&altairTMXR); /* poll output */
|
tmxr_poll_tx(&altairTMXR); /* poll output */
|
||||||
|
@ -385,8 +398,8 @@ static t_stat sio_reset(DEVICE *dptr) {
|
||||||
resetSIOWarningFlags();
|
resetSIOWarningFlags();
|
||||||
if (sio_unit.flags & UNIT_ATT) {
|
if (sio_unit.flags & UNIT_ATT) {
|
||||||
for (i = 0; i < Terminals; i++) {
|
for (i = 0; i < Terminals; i++) {
|
||||||
if (altairTMXR.ldsc[i] -> conn > 0) {
|
if (TerminalLines[i].conn > 0) {
|
||||||
tmxr_reset_ln(altairTMXR.ldsc[i]);
|
tmxr_reset_ln(&TerminalLines[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reset_sio_terminals(FALSE);
|
reset_sio_terminals(FALSE);
|
||||||
|
@ -442,9 +455,9 @@ int32 sio0s(const int32 port, const int32 io, const int32 data) {
|
||||||
if (io == 0) { /* IN */
|
if (io == 0) { /* IN */
|
||||||
if (sio_unit.flags & UNIT_ATT) {
|
if (sio_unit.flags & UNIT_ATT) {
|
||||||
sio_terminals[ti].status =
|
sio_terminals[ti].status =
|
||||||
(((tmxr_rqln(altairTMXR.ldsc[ti]) > 0 ? 0x01 : 0) |
|
(((tmxr_rqln(&TerminalLines[ti]) > 0 ? 0x01 : 0) |
|
||||||
/* read possible if character available */
|
/* read possible if character available */
|
||||||
((altairTMXR.ldsc[ti] -> conn) && (altairTMXR.ldsc[ti] -> xmte) ? 0x02 : 0x00)));
|
((TerminalLines[ti].conn) && (TerminalLines[ti].xmte) ? 0x02 : 0x00)));
|
||||||
/* write possible if connected and transmit enabled */
|
/* write possible if connected and transmit enabled */
|
||||||
}
|
}
|
||||||
return sio_terminals[ti].status;
|
return sio_terminals[ti].status;
|
||||||
|
@ -475,7 +488,7 @@ int32 sio0d(const int32 port, const int32 io, const int32 data) {
|
||||||
}
|
}
|
||||||
if (io == 0) { /* IN */
|
if (io == 0) { /* IN */
|
||||||
if (sio_unit.flags & UNIT_ATT) {
|
if (sio_unit.flags & UNIT_ATT) {
|
||||||
sio_terminals[ti].data = tmxr_getc_ln(altairTMXR.ldsc[ti]) & 0xff;
|
sio_terminals[ti].data = tmxr_getc_ln(&TerminalLines[ti]) & 0xff;
|
||||||
}
|
}
|
||||||
sio_terminals[ti].status &= 0xfe;
|
sio_terminals[ti].status &= 0xfe;
|
||||||
if (sio_unit.flags & UNIT_BS) {
|
if (sio_unit.flags & UNIT_BS) {
|
||||||
|
@ -493,7 +506,7 @@ int32 sio0d(const int32 port, const int32 io, const int32 data) {
|
||||||
else { /* OUT */
|
else { /* OUT */
|
||||||
int32 d = sio_unit.flags & UNIT_ANSI ? data & 0x7f : data;
|
int32 d = sio_unit.flags & UNIT_ANSI ? data & 0x7f : data;
|
||||||
if (sio_unit.flags & UNIT_ATT) {
|
if (sio_unit.flags & UNIT_ATT) {
|
||||||
tmxr_putc_ln(altairTMXR.ldsc[ti], d);
|
tmxr_putc_ln(&TerminalLines[ti], d); /* status ignored */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sim_putchar(d);
|
sim_putchar(d);
|
||||||
|
@ -511,7 +524,7 @@ int32 sio1s(const int32 port, const int32 io, const int32 data) {
|
||||||
if ((ptr_unit.flags & UNIT_ATT) == 0) {
|
if ((ptr_unit.flags & UNIT_ATT) == 0) {
|
||||||
if ((sio_unit.flags & UNIT_SIO_VERBOSE) && (warnUnattachedPTR < warnLevelSIO)) {
|
if ((sio_unit.flags & UNIT_SIO_VERBOSE) && (warnUnattachedPTR < warnLevelSIO)) {
|
||||||
warnUnattachedPTR++;
|
warnUnattachedPTR++;
|
||||||
/*06*/ message1("Attempt to test status of unattached PTR. 0x02 returned.\n");
|
/*06*/ message1("Attempt to test status of unattached PTR. 0x02 returned.");
|
||||||
}
|
}
|
||||||
return 0x02;
|
return 0x02;
|
||||||
}
|
}
|
||||||
|
@ -536,14 +549,14 @@ int32 sio1d(const int32 port, const int32 io, const int32 data) {
|
||||||
if (ptr_unit.u3) { /* no more data available */
|
if (ptr_unit.u3) { /* no more data available */
|
||||||
if ((sio_unit.flags & UNIT_SIO_VERBOSE) && (warnPTREOF < warnLevelSIO)) {
|
if ((sio_unit.flags & UNIT_SIO_VERBOSE) && (warnPTREOF < warnLevelSIO)) {
|
||||||
warnPTREOF++;
|
warnPTREOF++;
|
||||||
/*07*/ message1("PTR attempted to read past EOF. 0x00 returned.\n");
|
/*07*/ message1("PTR attempted to read past EOF. 0x00 returned.");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ((ptr_unit.flags & UNIT_ATT) == 0) { /* not attached */
|
if ((ptr_unit.flags & UNIT_ATT) == 0) { /* not attached */
|
||||||
if ((sio_unit.flags & UNIT_SIO_VERBOSE) && (warnUnattachedPTR < warnLevelSIO)) {
|
if ((sio_unit.flags & UNIT_SIO_VERBOSE) && (warnUnattachedPTR < warnLevelSIO)) {
|
||||||
warnUnattachedPTR++;
|
warnUnattachedPTR++;
|
||||||
/*08*/ message1("Attempt to read from unattached PTR. 0x00 returned.\n");
|
/*08*/ message1("Attempt to read from unattached PTR. 0x00 returned.");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -560,7 +573,7 @@ int32 sio1d(const int32 port, const int32 io, const int32 data) {
|
||||||
} /* else ignore data */
|
} /* else ignore data */
|
||||||
else if ((sio_unit.flags & UNIT_SIO_VERBOSE) && (warnUnattachedPTP < warnLevelSIO)) {
|
else if ((sio_unit.flags & UNIT_SIO_VERBOSE) && (warnUnattachedPTP < warnLevelSIO)) {
|
||||||
warnUnattachedPTP++;
|
warnUnattachedPTP++;
|
||||||
/*09*/message2("Attempt to output '0x%02x' to unattached PTP - ignored.\n", data);
|
/*09*/message2("Attempt to output '0x%02x' to unattached PTP - ignored.", data);
|
||||||
}
|
}
|
||||||
ptp_unit.pos++;
|
ptp_unit.pos++;
|
||||||
return 0; /* ignored since OUT */
|
return 0; /* ignored since OUT */
|
||||||
|
@ -571,10 +584,10 @@ int32 nulldev(const int32 port, const int32 io, const int32 data) {
|
||||||
if ((sio_unit.flags & UNIT_SIO_VERBOSE) && (warnUnassignedPort < warnLevelSIO)) {
|
if ((sio_unit.flags & UNIT_SIO_VERBOSE) && (warnUnassignedPort < warnLevelSIO)) {
|
||||||
warnUnassignedPort++;
|
warnUnassignedPort++;
|
||||||
if (io == 0) {
|
if (io == 0) {
|
||||||
message2("Unassigned IN(%2xh) - ignored.\n", port);
|
message2("Unassigned IN(%2xh) - ignored.", port);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
message3("Unassigned OUT(%2xh) -> %2xh - ignored.\n", port, data);
|
message3("Unassigned OUT(%2xh) -> %2xh - ignored.", port, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return io == 0 ? 0xff : 0;
|
return io == 0 ? 0xff : 0;
|
||||||
|
@ -739,7 +752,7 @@ static void attachCPM(UNIT *uptr) {
|
||||||
}
|
}
|
||||||
lastCPMStatus = attach_unit(uptr, cpmCommandLine);
|
lastCPMStatus = attach_unit(uptr, cpmCommandLine);
|
||||||
if ((lastCPMStatus != SCPE_OK) && (simh_unit.flags & UNIT_SIMH_VERBOSE)) {
|
if ((lastCPMStatus != SCPE_OK) && (simh_unit.flags & UNIT_SIMH_VERBOSE)) {
|
||||||
message3("Cannot open '%s' (%s).\n", cpmCommandLine, scp_error_messages[lastCPMStatus - SCPE_BASE]);
|
message3("Cannot open '%s' (%s).", cpmCommandLine, scp_error_messages[lastCPMStatus - SCPE_BASE]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -862,7 +875,7 @@ static int32 simh_in(const int32 port) {
|
||||||
break;
|
break;
|
||||||
case getBankSelectCmd:
|
case getBankSelectCmd:
|
||||||
if (cpu_unit.flags & UNIT_BANKED) {
|
if (cpu_unit.flags & UNIT_BANKED) {
|
||||||
result = bankSelect;
|
result = getBankSelect();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = 0;
|
result = 0;
|
||||||
|
@ -874,11 +887,11 @@ static int32 simh_in(const int32 port) {
|
||||||
break;
|
break;
|
||||||
case getCommonCmd:
|
case getCommonCmd:
|
||||||
if (getCommonPos == 0) {
|
if (getCommonPos == 0) {
|
||||||
result = common & 0xff;
|
result = getCommon() & 0xff;
|
||||||
getCommonPos = 1;
|
getCommonPos = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = (common >> 8) & 0xff;
|
result = (getCommon() >> 8) & 0xff;
|
||||||
getCommonPos = lastCommand = 0;
|
getCommonPos = lastCommand = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -898,7 +911,7 @@ static int32 simh_in(const int32 port) {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (simh_unit.flags & UNIT_SIMH_VERBOSE) {
|
if (simh_unit.flags & UNIT_SIMH_VERBOSE) {
|
||||||
message2("Unnecessary IN from SIMH pseudo device on port %03xh ignored.\n",
|
message2("Unnecessary IN from SIMH pseudo device on port %03xh ignored.",
|
||||||
port);
|
port);
|
||||||
}
|
}
|
||||||
result = lastCommand = 0;
|
result = lastCommand = 0;
|
||||||
|
@ -933,7 +946,7 @@ static int32 simh_out(const int32 port, const int32 data) {
|
||||||
break;
|
break;
|
||||||
case setBankSelectCmd:
|
case setBankSelectCmd:
|
||||||
if (cpu_unit.flags & UNIT_BANKED) {
|
if (cpu_unit.flags & UNIT_BANKED) {
|
||||||
bankSelect = data & BANKMASK;
|
setBankSelect(data & BANKMASK);
|
||||||
}
|
}
|
||||||
else if (simh_unit.flags & UNIT_SIMH_VERBOSE) {
|
else if (simh_unit.flags & UNIT_SIMH_VERBOSE) {
|
||||||
message2("Set selected bank to %i ignored for non-banked memory.", data & 3);
|
message2("Set selected bank to %i ignored for non-banked memory.", data & 3);
|
||||||
|
@ -965,7 +978,7 @@ static int32 simh_out(const int32 port, const int32 data) {
|
||||||
switch(data) {
|
switch(data) {
|
||||||
case printTimeCmd: /* print time */
|
case printTimeCmd: /* print time */
|
||||||
if (rtc_avail) {
|
if (rtc_avail) {
|
||||||
message2("Current time in milliseconds = %d.\n", sim_os_msec());
|
message2("Current time in milliseconds = %d.", sim_os_msec());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
warnNoRealTimeClock();
|
warnNoRealTimeClock();
|
||||||
|
@ -977,7 +990,7 @@ static int32 simh_out(const int32 port, const int32 data) {
|
||||||
markTime[markTimeSP++] = sim_os_msec();
|
markTime[markTimeSP++] = sim_os_msec();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
message1("Timer stack overflow.\n");
|
message1("Timer stack overflow.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -988,10 +1001,10 @@ static int32 simh_out(const int32 port, const int32 data) {
|
||||||
if (rtc_avail) {
|
if (rtc_avail) {
|
||||||
if (markTimeSP > 0) {
|
if (markTimeSP > 0) {
|
||||||
uint32 delta = sim_os_msec() - markTime[--markTimeSP];
|
uint32 delta = sim_os_msec() - markTime[--markTimeSP];
|
||||||
message2("Timer stopped. Elapsed time in milliseconds = %d.\n", delta);
|
message2("Timer stopped. Elapsed time in milliseconds = %d.", delta);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
message1("No timer active.\n");
|
message1("No timer active.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1044,10 +1057,10 @@ static int32 simh_out(const int32 port, const int32 data) {
|
||||||
if (rtc_avail) {
|
if (rtc_avail) {
|
||||||
if (markTimeSP > 0) {
|
if (markTimeSP > 0) {
|
||||||
uint32 delta = sim_os_msec() - markTime[markTimeSP - 1];
|
uint32 delta = sim_os_msec() - markTime[markTimeSP - 1];
|
||||||
message2("Timer running. Elapsed in milliseconds = %d.\n", delta);
|
message2("Timer running. Elapsed in milliseconds = %d.", delta);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
message1("No timer active.\n");
|
message1("No timer active.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1091,7 +1104,7 @@ static int32 simh_out(const int32 port, const int32 data) {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (simh_unit.flags & UNIT_SIMH_VERBOSE) {
|
if (simh_unit.flags & UNIT_SIMH_VERBOSE) {
|
||||||
message3("Unknown command (%i) to SIMH pseudo device on port %03xh ignored.\n",
|
message3("Unknown command (%i) to SIMH pseudo device on port %03xh ignored.",
|
||||||
data, port);
|
data, port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* altairz80_sys.c: MITS Altair system interface
|
/* altairz80_sys.c: MITS Altair system interface
|
||||||
|
|
||||||
Copyright (c) 2002-2003, Peter Schorn
|
Copyright (c) 2002-2004, Peter Schorn
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -40,14 +40,7 @@ extern DEVICE simh_device;
|
||||||
extern DEVICE ptr_dev;
|
extern DEVICE ptr_dev;
|
||||||
extern DEVICE ptp_dev;
|
extern DEVICE ptp_dev;
|
||||||
extern int32 saved_PC;
|
extern int32 saved_PC;
|
||||||
extern void PutBYTEWrapper(register uint32 Addr, register uint32 Value);
|
|
||||||
extern void PutBYTEForced(register uint32 Addr, register uint32 Value);
|
|
||||||
extern uint8 GetBYTEWrapper(register uint32 Addr);
|
|
||||||
extern int32 addressIsInROM(const uint32 Addr);
|
|
||||||
extern int32 addressExists(const uint32 Addr);
|
|
||||||
extern void printROMMessage(const uint32 cntROM);
|
|
||||||
|
|
||||||
int32 sim_load(FILE *fileref, char *cptr, char *fnam, int32 flag);
|
|
||||||
int32 fprint_sym(FILE *of, int32 addr, uint32 *val, UNIT *uptr, int32 sw);
|
int32 fprint_sym(FILE *of, int32 addr, uint32 *val, UNIT *uptr, int32 sw);
|
||||||
static int32 checkbase(char ch, const char *numString);
|
static int32 checkbase(char ch, const char *numString);
|
||||||
static int32 numok(char ch, const char **numString, const int32 minvalue,
|
static int32 numok(char ch, const char **numString, const int32 minvalue,
|
||||||
|
@ -347,7 +340,7 @@ static int32 DAsm(char *S, const uint32 *val, const int32 useZ80Mnemonics, const
|
||||||
T = Mnemonics8080[val[B++]];
|
T = Mnemonics8080[val[B++]];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (P = strchr(T, '^')) {
|
if ( (P = strchr(T, '^')) ) {
|
||||||
strncpy(R, T, P - T);
|
strncpy(R, T, P - T);
|
||||||
R[P - T] = '\0';
|
R[P - T] = '\0';
|
||||||
sprintf(H, "%02X", val[B++]);
|
sprintf(H, "%02X", val[B++]);
|
||||||
|
@ -357,21 +350,21 @@ static int32 DAsm(char *S, const uint32 *val, const int32 useZ80Mnemonics, const
|
||||||
else {
|
else {
|
||||||
strcpy(R, T);
|
strcpy(R, T);
|
||||||
}
|
}
|
||||||
if (P = strchr(R, '%')) {
|
if ( (P = strchr(R, '%')) ) {
|
||||||
*P = C;
|
*P = C;
|
||||||
if (P = strchr(P + 1, '%')) {
|
if ( (P = strchr(P + 1, '%')) ) {
|
||||||
*P = C;
|
*P = C;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(P = strchr(R, '*')) {
|
if( (P = strchr(R, '*')) ) {
|
||||||
strncpy(S, R, P - R);
|
strncpy(S, R, P - R);
|
||||||
S[P - R] = '\0';
|
S[P - R] = '\0';
|
||||||
sprintf(H, "%02X", val[B++]);
|
sprintf(H, "%02X", val[B++]);
|
||||||
strcat(S, H);
|
strcat(S, H);
|
||||||
strcat(S, P + 1);
|
strcat(S, P + 1);
|
||||||
}
|
}
|
||||||
else if (P = strchr(R, '@')) {
|
else if ( (P = strchr(R, '@')) ) {
|
||||||
strncpy(S, R, P - R);
|
strncpy(S, R, P - R);
|
||||||
S[P - R] = '\0';
|
S[P - R] = '\0';
|
||||||
if(!J) {
|
if(!J) {
|
||||||
|
@ -383,7 +376,7 @@ static int32 DAsm(char *S, const uint32 *val, const int32 useZ80Mnemonics, const
|
||||||
strcat(S, H);
|
strcat(S, H);
|
||||||
strcat(S, P + 1);
|
strcat(S, P + 1);
|
||||||
}
|
}
|
||||||
else if (P = strchr(R, '$')) {
|
else if ( (P = strchr(R, '$')) ) {
|
||||||
strncpy(S, R, P - R);
|
strncpy(S, R, P - R);
|
||||||
S[P - R] = '\0';
|
S[P - R] = '\0';
|
||||||
Offset = val[B++];
|
Offset = val[B++];
|
||||||
|
@ -391,7 +384,7 @@ static int32 DAsm(char *S, const uint32 *val, const int32 useZ80Mnemonics, const
|
||||||
strcat(S, H);
|
strcat(S, H);
|
||||||
strcat(S, P + 1);
|
strcat(S, P + 1);
|
||||||
}
|
}
|
||||||
else if (P = strchr(R, '#')) {
|
else if ( (P = strchr(R, '#')) ) {
|
||||||
strncpy(S, R, P - R);
|
strncpy(S, R, P - R);
|
||||||
S[P - R] = '\0';
|
S[P - R] = '\0';
|
||||||
sprintf(H, "%04X", val[B] + 256 * val[B + 1]);
|
sprintf(H, "%04X", val[B] + 256 * val[B + 1]);
|
||||||
|
@ -724,59 +717,3 @@ int32 parse_sym(char *cptr, int32 addr, UNIT *uptr, uint32 *val, int32 sw) {
|
||||||
}
|
}
|
||||||
return parse_X80(cptr, addr, val, cpu_unit.flags & UNIT_CHIP ? MnemonicsZ80 : Mnemonics8080);
|
return parse_X80(cptr, addr, val, cpu_unit.flags & UNIT_CHIP ? MnemonicsZ80 : Mnemonics8080);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This is the binary loader. The input file is considered to be
|
|
||||||
a string of literal bytes with no format special format. The
|
|
||||||
load starts at the current value of the PC. ROM/NOROM and
|
|
||||||
ALTAIRROM/NOALTAIRROM settings are ignored.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int32 sim_load(FILE *fileref, char *cptr, char *fnam, int32 flag) {
|
|
||||||
int32 i, addr = 0, cnt = 0, org, cntROM = 0, cntNonExist = 0;
|
|
||||||
t_addr j, lo, hi;
|
|
||||||
char *result;
|
|
||||||
t_stat status;
|
|
||||||
if (flag) {
|
|
||||||
result = get_range(cptr, &lo, &hi, 16, ADDRMASK, 0);
|
|
||||||
if (result == NULL) {
|
|
||||||
return SCPE_ARG;
|
|
||||||
}
|
|
||||||
for (j = lo; j <= hi; j++) {
|
|
||||||
if (putc(GetBYTEWrapper(j), fileref) == EOF) {
|
|
||||||
return SCPE_IOERR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("%d bytes dumped [%x - %x].\n", hi + 1 - lo, lo, hi);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (*cptr == 0) {
|
|
||||||
addr = saved_PC;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
addr = get_uint(cptr, 16, ADDRMASK, &status);
|
|
||||||
if (status != SCPE_OK) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
org = addr;
|
|
||||||
while ((addr < MAXMEMSIZE) && ((i = getc(fileref)) != EOF)) {
|
|
||||||
PutBYTEForced(addr, i);
|
|
||||||
if (addressIsInROM(addr)) {
|
|
||||||
cntROM++;
|
|
||||||
}
|
|
||||||
if (!addressExists(addr)) {
|
|
||||||
cntNonExist++;
|
|
||||||
}
|
|
||||||
addr++;
|
|
||||||
cnt++;
|
|
||||||
} /* end while */
|
|
||||||
printf("%d bytes [%d page%s] loaded at %x.\n", cnt, (cnt + 255) >> 8,
|
|
||||||
((cnt + 255) >> 8) == 1 ? "" : "s", org);
|
|
||||||
printROMMessage(cntROM);
|
|
||||||
if (cntNonExist) {
|
|
||||||
printf("Warning: %d bytes written to non-existing memory (for this configuration).\n", cntNonExist);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
972
AltairZ80/altairz80_doc.txt
Normal file
972
AltairZ80/altairz80_doc.txt
Normal file
|
@ -0,0 +1,972 @@
|
||||||
|
To: Users
|
||||||
|
From: Peter Schorn
|
||||||
|
Subj: AltairZ80 Simulator Usage
|
||||||
|
Date: 15-Feb-2004
|
||||||
|
|
||||||
|
COPYRIGHT NOTICE
|
||||||
|
|
||||||
|
The following copyright notice applies to both the SIMH source and binary:
|
||||||
|
|
||||||
|
Copyright (c) 2002-2004, Peter Schorn
|
||||||
|
|
||||||
|
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
|
||||||
|
PETER SCHORN 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 Peter Schorn shall not
|
||||||
|
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
|
in this Software without prior written authorization from Peter Schorn.
|
||||||
|
|
||||||
|
Based on work by Charles E Owen (c) 1997
|
||||||
|
|
||||||
|
This memorandum documents the Altair 8800 Simulator with Z80 support.
|
||||||
|
|
||||||
|
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/AltairZ80/altairz80_defs.h
|
||||||
|
altairz80_cpu.c
|
||||||
|
altairz80_dsk.c
|
||||||
|
altairz80_hdsk.c
|
||||||
|
altairz80_sio.c
|
||||||
|
altairz80_sys.c
|
||||||
|
|
||||||
|
|
||||||
|
2. Revision History
|
||||||
|
|
||||||
|
- 26-Jan-2004, Peter Schorn (added support for t-state stepping)
|
||||||
|
- 25-Feb-2003, Peter Schorn (added support for real time simulation)
|
||||||
|
- 9-Oct-2002, Peter Schorn (added support for simulated hard disk)
|
||||||
|
- 28-Sep-2002, Peter Schorn (number of tracks per disk can be configured)
|
||||||
|
- 19-Sep-2002, Peter Schorn (added WARNROM feature)
|
||||||
|
- 31-Aug-2002, Peter Schorn (added extended ROM features suggested
|
||||||
|
by Scott LaBombard)
|
||||||
|
- 4-May-2002, Peter Schorn (added description of MP/M II sample software)
|
||||||
|
- 28-Apr-2002, Peter Schorn (added periodic timer interrupts and three
|
||||||
|
additional consoles)
|
||||||
|
- 15-Apr-2002, Peter Schorn (added memory breakpoint)
|
||||||
|
- 7-Apr-2002, Peter Schorn (added ROM / NOROM switch)
|
||||||
|
Original version of this document written by Charles E Owen
|
||||||
|
|
||||||
|
|
||||||
|
3. Background.
|
||||||
|
|
||||||
|
The MITS (Micro Instrumentation and Telemetry Systems) Altair 8800 was
|
||||||
|
announced on the January 1975 cover of Popular Electronics, which boasted
|
||||||
|
you could buy and build this powerful computer kit for only $397. The kit
|
||||||
|
consisted at that time of only the parts to build a case, power supply,
|
||||||
|
card cage (18 slots), CPU card, and memory card with 256 *bytes* of memory.
|
||||||
|
Still, thousands were ordered within the first few months after the
|
||||||
|
announcement, starting the personal computer revolution as we know it
|
||||||
|
today.
|
||||||
|
|
||||||
|
Many laugh at the small size of the that first kit, noting there were no
|
||||||
|
peripherals and the 256 byte memory size. But the computer was an open
|
||||||
|
system, and by 1977 MITS and many other small startups had added many
|
||||||
|
expansion cards to make the Altair quite a respectable little computer. The
|
||||||
|
"Altair Bus" that made this possible was soon called the S-100 Bus, later
|
||||||
|
adopted as an industry standard, and eventually became the IEE-696 Bus.
|
||||||
|
|
||||||
|
|
||||||
|
4. Hardware
|
||||||
|
|
||||||
|
We are simulating a fairly "loaded" Altair 8800 from about 1977, with the
|
||||||
|
following configuration:
|
||||||
|
|
||||||
|
device simulates
|
||||||
|
name(s)
|
||||||
|
|
||||||
|
CPU Altair 8800 with Intel 8080 CPU board, 62KB
|
||||||
|
of RAM, 2K of EPROM with start boot ROM.
|
||||||
|
SIO MITS 88-2SIO Dual Serial Interface Board. Port 1
|
||||||
|
is assumed to be connected to a serial "glass
|
||||||
|
TTY" that is your terminal running the Simulator.
|
||||||
|
PTR Paper Tape Reader attached to port 2 of the 2SIO board.
|
||||||
|
PTP Paper Tape Punch attached to port 2 of the
|
||||||
|
2SIO board. This also doubles as a printer port.
|
||||||
|
DSK MITS 88-DISK Floppy Disk controller with up
|
||||||
|
to eight drives.
|
||||||
|
|
||||||
|
|
||||||
|
4.1 CPU
|
||||||
|
|
||||||
|
We have 2 CPU options that were not present on the original machine but
|
||||||
|
are useful in the simulator. We also allow you to select memory sizes, but
|
||||||
|
be aware that some sample software requires the full 64K (i.e. CP/M) and
|
||||||
|
the MITS Disk Basic and Altair DOS require about a minimum of 24K.
|
||||||
|
|
||||||
|
SET CPU 8080 Simulates the 8080 CPU (normal)
|
||||||
|
SET CPU Z80 Simulates the Z80 CPU. Note that some software (e.g. most
|
||||||
|
original Altair software such as 4K Basic) requires an 8080 CPU and
|
||||||
|
will not or not properly run on a Z80. This is mainly due to the use
|
||||||
|
of the parity flag on the 8080 which has not always the same
|
||||||
|
semantics on the Z80.
|
||||||
|
|
||||||
|
SET CPU ITRAP Causes the simulator to halt if an invalid opcode
|
||||||
|
is detected (depending on the chosen CPU).
|
||||||
|
SET CPU NOITRAP Does not stop on an invalid Opcode. This is
|
||||||
|
how the real 8080 works.
|
||||||
|
|
||||||
|
SET CPU 4K
|
||||||
|
SET CPU 8K
|
||||||
|
SET CPU 12K
|
||||||
|
SET CPU 16K
|
||||||
|
...... (in 4K steps)
|
||||||
|
SET CPU 64K All these set various CPU memory configurations.
|
||||||
|
|
||||||
|
SET CPU BANKED Enables the banked memory support. The simulated memory
|
||||||
|
has eight banks with address range 0..'common' (see registers below)
|
||||||
|
and a common area from 'common' to 0xfff which is common to all
|
||||||
|
banks. The currently active bank is determined by register 'bank'
|
||||||
|
(see below). You can only switch to banked memory if the memory
|
||||||
|
is set to 64K. The banked memory is used by CP/M 3.
|
||||||
|
|
||||||
|
SET CPU NONBANKED Disables banked memory support.
|
||||||
|
|
||||||
|
SET CPU ROM Enables the ROM from address 'ROMLOW' to 'ROMHIGH'
|
||||||
|
(see below under CPU Registers) and prevents write access
|
||||||
|
to these locations. This is the default setting.
|
||||||
|
|
||||||
|
SET CPU NOROM Disables the ROM.
|
||||||
|
|
||||||
|
SET CPU ALTAIRROM Enables the slightly modified but downwards compatible
|
||||||
|
Altair boot ROM at addresses 0FF00 to 0FFFF. This is the default.
|
||||||
|
|
||||||
|
SET CPU NOALTAIRROM Disables standard Altair ROM behavior.
|
||||||
|
|
||||||
|
SET CPU WARNROM Enables warning messages to be printed when the CPU
|
||||||
|
attempts to write into ROM or into non-existing memory. Also prints
|
||||||
|
a warning message if the CPU attempts to read from non-existing
|
||||||
|
memory.
|
||||||
|
|
||||||
|
SET CPU NOWARNROM Suppreses all warning message of "WARNROM". Note that
|
||||||
|
some software tries on purpose to write to ROM in order to detect
|
||||||
|
the available RAM.
|
||||||
|
|
||||||
|
The BOOT EPROM card starts at address 0FF00 if it has been enabled by
|
||||||
|
'SET CPU ALTAIRROM'. Jumping to this address will boot drive 0 of the
|
||||||
|
floppy controller (CPU must be set to ROM or equivalent code must be
|
||||||
|
present). If no valid bootable software is present there the machine
|
||||||
|
crashes. This is historically accurate behavior.
|
||||||
|
|
||||||
|
The real 8080, on receiving a HLT (Halt) instruction, freezes the
|
||||||
|
processor and only an interrupt or CPU hardware reset will restore it. The
|
||||||
|
simulator is alot nicer, it will halt but send you back to the simulator
|
||||||
|
command line.
|
||||||
|
|
||||||
|
CPU Registers include the following:
|
||||||
|
|
||||||
|
Name Size Comment
|
||||||
|
|
||||||
|
PC 16 The Program Counter
|
||||||
|
AF 16 The accumulator and the flag register
|
||||||
|
F = S Z - AC - P/V N C
|
||||||
|
S = Sign flag.
|
||||||
|
Z = Zero Flag.
|
||||||
|
AC = Auxillary Carry flag.
|
||||||
|
P/V = Parity flag on 8080
|
||||||
|
Parity / Overflow flag on Z80
|
||||||
|
- = not used (undefined)
|
||||||
|
N = Internal sign flag
|
||||||
|
C = Carry flag.
|
||||||
|
BC 16 The BC register pair.
|
||||||
|
Register B is the high 8 bits, C is the lower 8 bits
|
||||||
|
DE 16 The DE register pair.
|
||||||
|
Register D is the high 8 bits, E is the lower 8 bits.
|
||||||
|
HL 16 The HL register pair.
|
||||||
|
Register H is the high 8 bits, L is the lower 8 bits.
|
||||||
|
AF1 16 The alternate AF register (on Z80 only)
|
||||||
|
BC1 16 The alternate BC register (on Z80 only)
|
||||||
|
DE1 16 The alternate DE register (on Z80 only)
|
||||||
|
HL1 16 The alternate HL register (on Z80 only)
|
||||||
|
IX 16 The IX index register (on Z80 only)
|
||||||
|
IY 16 The IY index register (on Z80 only)
|
||||||
|
IFF 8 Interrupt flag (on Z80 only)
|
||||||
|
INT 8 Interrupt register (on Z80 only)
|
||||||
|
|
||||||
|
SR 16 The front panel switches (use D SR 8 for 4k Basic).
|
||||||
|
WRU 8 The interrupt character. This starts as 5
|
||||||
|
(ctrl-E) but some Altair software uses this
|
||||||
|
keystroke so best to change this to something
|
||||||
|
exotic such as 035 (which is Ctl-]).
|
||||||
|
|
||||||
|
BANK 3 The currently active memory bank (if banked memory
|
||||||
|
is activated - see memory options above)
|
||||||
|
COMMON 16 The starting address of common memory. Originally set
|
||||||
|
to 0xc000 (note this setting must agree with the
|
||||||
|
value supplied to GENCPM for CP/M 3 system generation)
|
||||||
|
ROMLOW 16 The starting address of the ROM. Default is 0FF00.
|
||||||
|
ROMHIGH 16 The final address of the ROM. Default is 0FFFF.
|
||||||
|
CLOCK 32 The clock speed of the simulated CPU in kHz or 0 to run
|
||||||
|
at maximum speed. To set the clock speed for a typical
|
||||||
|
4 MHz Z80 CPU, use D CLOCK 4000. The CP/M utility SPEED
|
||||||
|
measures the clock speed of the simulated CPU.
|
||||||
|
|
||||||
|
|
||||||
|
4.2 The Serial I/O Card (2SIO)
|
||||||
|
|
||||||
|
This simple programmed I/O device provides 2 serial ports to the outside
|
||||||
|
world, which could be hardware jumpered to support RS-232 plugs or a TTY
|
||||||
|
current loop interface. The standard I/O addresses assigned by MITS was
|
||||||
|
10-11 (hex) for the first port, and 12-13 (hex) for the second. We follow
|
||||||
|
this standard in the Simulator.
|
||||||
|
|
||||||
|
The simulator directs I/O to/from the first port to the screen. The
|
||||||
|
second port reads from an attachable "tape reader" file on input, and
|
||||||
|
writes to an attachable "punch file" on output. These files are considered
|
||||||
|
a simple stream of 8-bit bytes.
|
||||||
|
|
||||||
|
The SIO can be configured in SIMH with the following commands:
|
||||||
|
|
||||||
|
SET SIO TTY Bit 8 is set to zero on console output
|
||||||
|
SET SIO ANSI Bit 8 is not touched on console output
|
||||||
|
|
||||||
|
SET SIO ALL Console input support lower- and upper case
|
||||||
|
SET SIO UPPER Console input is transformed to upper case characters only
|
||||||
|
(This feature is useful for most Altair software)
|
||||||
|
|
||||||
|
SET SIO BS Map the delete character to backspace
|
||||||
|
SET SIO DEL Map the backspace character to delete
|
||||||
|
|
||||||
|
SET SIO QUIET Do not print warning messages
|
||||||
|
SET SIO VERBOSE Print warning messages (useful for debugging)
|
||||||
|
The register SIOWL determines how often the same warning
|
||||||
|
is displayed. The default is 3.
|
||||||
|
|
||||||
|
You can also attach the SIO to a port:
|
||||||
|
|
||||||
|
ATTACH SIO 23 Console IO goes via a Telnet connection on port 23
|
||||||
|
DETACH SIO Console IO goes via the regular SIMH console
|
||||||
|
|
||||||
|
|
||||||
|
4.3 The SIMH pseudo device
|
||||||
|
|
||||||
|
The SIMH pseudo device facilitates the communication between the
|
||||||
|
simulated ALTAIR and the simulator environment. This device defines a
|
||||||
|
number of (most R/O) registers (see source code) which are primarily useful
|
||||||
|
for debugging purposes.
|
||||||
|
|
||||||
|
The SIMH pseudo device can be configured with
|
||||||
|
|
||||||
|
SET SIMH QUIET Do not print warning messages
|
||||||
|
SET SIMH VERBOSE Print warning messages (useful for debugging)
|
||||||
|
|
||||||
|
SET SIMH TIMERON Start periodic timer interrupts
|
||||||
|
SET SIMH TIMEROFF Stop the periodic timer interrupts
|
||||||
|
|
||||||
|
The following variables determine the behavior of the timer:
|
||||||
|
|
||||||
|
TIMD This is the delay between consecutive interrupts in milliseconds.
|
||||||
|
Use D TIMD 20 for a 50 Hz clock.
|
||||||
|
TIMH This is the address of the interrupt handler to call for a
|
||||||
|
timer interrupt.
|
||||||
|
|
||||||
|
|
||||||
|
4.4 The 88-DISK controller.
|
||||||
|
|
||||||
|
The MITS 88-DISK is a simple programmed I/O interface to the MITS 8-inch
|
||||||
|
floppy drive, which was basically a Pertec FD-400 with a power supply and
|
||||||
|
buffer board builtin. The controller supports neither interrupts nor DMA,
|
||||||
|
so floppy access required the sustained attention of the CPU. The standard
|
||||||
|
I/O addresses were 8, 9, and 0A (hex), and we follow the standard. Details
|
||||||
|
on controlling this hardware are in the altair_dsk.c source file.
|
||||||
|
|
||||||
|
The only difference is that the simulated disks may be larger than the
|
||||||
|
original ones: The original disk had 77 tracks while the simulated disks
|
||||||
|
support up to 254 tracks (only relevant for CP/M). You can change the
|
||||||
|
number of tracks per disk by setting the appropriate value in TRACKS[..].
|
||||||
|
For example "D TRACKS[0] 77" sets the number of tracks for disk 0 to the
|
||||||
|
original number of 77. The command "D TRACKS[0-7] 77" changes the highest
|
||||||
|
track number for all disks to 77.
|
||||||
|
|
||||||
|
For debugging purposes you can set the trace level of some disk I/O
|
||||||
|
functions. To do so the following bits in TRACE (a register of the disk)
|
||||||
|
have been defined with the following meaning:
|
||||||
|
|
||||||
|
1 Trace all IN and OUT instructions on the disk ports 8 and 9
|
||||||
|
2 Trace all read and writes to full sectors on the disk
|
||||||
|
4 Print a message whenever an unnecessary step-in or step out of the
|
||||||
|
disk head occurs (often an indication of an infinite loop)
|
||||||
|
8 Print a message whenever the disk head appears to be waiting for a
|
||||||
|
sector which does not show up (often an indication of an infinite
|
||||||
|
loop)
|
||||||
|
|
||||||
|
For example the command "D TRACE 10" will trace options 2+8 from above.
|
||||||
|
|
||||||
|
The DSK device can be configured with
|
||||||
|
|
||||||
|
SET DSK<n> QUIET Do not print warning messages for disk <n>
|
||||||
|
SET DSK<n> VERBOSE Print warning messages for disk <n>
|
||||||
|
(useful for debugging)
|
||||||
|
The register DSKWL determines how often the
|
||||||
|
same warning is displayed. The default is 3.
|
||||||
|
|
||||||
|
SET DSK<n> WRITEENABLED Allow write operations for disk <n>
|
||||||
|
SET DSK<n> LOCKED Disk <n> is locked, i.e. no write operations
|
||||||
|
will be allowed.
|
||||||
|
|
||||||
|
|
||||||
|
4.5 The simulated hard disk
|
||||||
|
|
||||||
|
In order to increase the available storage capacity, the simulator
|
||||||
|
features 8 simulated hard disks with a capacity of 8MB (HDSK0 to HDSK7).
|
||||||
|
Currently only CP/M supports two hard disks as devices I: and J:.
|
||||||
|
|
||||||
|
For debugging purposes one can set the trace flag by executing the
|
||||||
|
command "D HDTRACE 1". The default for "HDTRACE" is 0 (no trace).
|
||||||
|
|
||||||
|
The HDSK device can be configured with
|
||||||
|
|
||||||
|
SET HDSK<n> QUIET Do not print warning messages for hard disk <n>
|
||||||
|
SET HDSK<n> VERBOSE Print warning messages for hard disk <n>
|
||||||
|
(useful for debugging)
|
||||||
|
|
||||||
|
SET HDSK<n> WRITEENABLED Allow write operations for hard disk <n>
|
||||||
|
SET HDSK<n> LOCKED Hard disk <n> is locked, i.e. no
|
||||||
|
write operations will be allowed.
|
||||||
|
|
||||||
|
|
||||||
|
5. Sample Software
|
||||||
|
|
||||||
|
Running an Altair in 1977 you would be running either MITS Disk Extended
|
||||||
|
BASIC, or the brand new and sexy CP/M Operating System from Digital
|
||||||
|
Research. Or possibly, you ordered Altair DOS back when it was promised in
|
||||||
|
1975, and are still waiting for it to be delivered in early 1977.
|
||||||
|
|
||||||
|
We have samples of all three for you to check out. We can't go into the
|
||||||
|
details of how they work, but we'll give you a few hints.
|
||||||
|
|
||||||
|
|
||||||
|
5.1 CP/M Version 2.2
|
||||||
|
|
||||||
|
This version is my own port of the standard CP/M to the Altair. There
|
||||||
|
were some "official" versions but I don't have them. None were endorsed or
|
||||||
|
sold by MITS to my knowledge, however.
|
||||||
|
|
||||||
|
To boot CP/M:
|
||||||
|
|
||||||
|
sim> attach dsk cpm2.dsk
|
||||||
|
sim> boot dsk
|
||||||
|
|
||||||
|
CP/M feels like DOS, sort of. DIR will work. I have included all the
|
||||||
|
standard CP/M utilities, plus a few common public-domain ones. I also
|
||||||
|
include the sources to the customized BIOS and some other small programs.
|
||||||
|
TYPE will print an ASCII file. DUMP will dump a binary one. LS is a
|
||||||
|
better DIR than DIR. ASM will assemble .ASM files to Hex, LOAD will "load"
|
||||||
|
them to binary format (.COM). ED is a simple editor, #A command will bring
|
||||||
|
the source file to the buffer, T command will "type" lines, L will move
|
||||||
|
lines, E exits the editor. 20L20T will move down 20 lines, and type 20.
|
||||||
|
Very DECish. DDT is the debugger, DO is a batch-type command processor. A
|
||||||
|
sample batch file that will assemble and write out the bootable CP/M image
|
||||||
|
(on drive A) is "SYSCPM2.SUB". To run it, type "DO SYSCPM2".
|
||||||
|
|
||||||
|
In order to efficiently transfer files into the CP/M environment use the
|
||||||
|
included program R <filename.ext>. If you have a file named foo.ext in the
|
||||||
|
current directory (i.e. the directory where SIMH is), executing R FOO.EXT
|
||||||
|
under CP/M will transfer the file onto the CP/M disk. Transferring a file
|
||||||
|
from the CP/M environment to the SIMH environment is accomplished by
|
||||||
|
W <filename.ext> for text files or by W <filename.ext> B for binary files.
|
||||||
|
The simplest way for transferring multiple files is to create a ".SUB"
|
||||||
|
batch file which contains the necessary R resp. W commands.
|
||||||
|
|
||||||
|
If you need more storage space you can use a simulated hard disk on
|
||||||
|
drives I: and J:. To use do "attach HDSK0 hdi.dsk" and issue the
|
||||||
|
"XFORMAT I:" resp. "XFORMAT J:" command from CP/M do initialize the disk
|
||||||
|
to an empty state.
|
||||||
|
|
||||||
|
The disk "cpm2.dsk" contains the following files:
|
||||||
|
Name Ext Size Comment
|
||||||
|
ASM .COM 8K ; CP/M assembler
|
||||||
|
BDOS .MAC 68K ; Basic Disk Operating System assembler source code
|
||||||
|
BOOT .COM 1K ; transfer control to boot ROM
|
||||||
|
BOOT .MAC 2K ; source for BOOT.COM
|
||||||
|
BOOTGEN .COM 2K ; put a program on the boot sectors
|
||||||
|
CBIOSX .MAC 48K ; CP/M 2 BIOS source for Altair
|
||||||
|
CCP .MAC 26K ; Console Command Processor assembler source code
|
||||||
|
COPY .COM 2K ; copy disks
|
||||||
|
CPMBOOT .COM 12K ; CP/M operating system
|
||||||
|
CPU .COM 2K ; get and set the CPU type (8080 or Z80)
|
||||||
|
CPU .MAC 2K ; source for CPU.COM
|
||||||
|
CREF80 .COM 4K ; cross reference utility
|
||||||
|
DDT .COM 6K ; 8080 debugger
|
||||||
|
DDTZ .COM 10K ; Z80 debugger
|
||||||
|
DIF .COM 4K ; determine differences between two files
|
||||||
|
DO .COM 2K ; batch processing
|
||||||
|
DSKBOOT .MAC 8K ; source for boot ROM
|
||||||
|
DUMP .COM 2K ; hex dump a file
|
||||||
|
ED .COM 8K ; line editor
|
||||||
|
ELIZA .BAS 10K ; Eliza game in Basic
|
||||||
|
EX8080 .COM 12K ; exercise 8080 instruction set
|
||||||
|
EXZ80N .COM 12K ; exercise Z80 instruction set, No undefined status bits
|
||||||
|
EXZ80U .COM 12K ; exercise Z80 instruction set, Undefined status bits
|
||||||
|
EXZ80 .MAC 54K ; source for EX8080.COM, EXZ80N.COM, EXZ80U.COM
|
||||||
|
EX .SUB 2K ; benchmark execution of EX8080.COM, EXZ80N.COM, EXZ80U.COM
|
||||||
|
FORMAT .COM 2K ; format disks
|
||||||
|
GO .COM 0K ; start the currently loaded program at 100H
|
||||||
|
HDSKBOOT.MAC 6K ; boot code for hard disk
|
||||||
|
L80 .COM 12K ; Microsoft linker
|
||||||
|
LADDER .COM 40K ; game
|
||||||
|
LADDER .DAT 2K ; high score file for LADDER.COM
|
||||||
|
LIB80 .COM 6K ; library utility
|
||||||
|
LOAD .COM 2K ; load hex files
|
||||||
|
LS .COM 4K ; directory utility
|
||||||
|
LU .COM 20K ; library utility
|
||||||
|
M80 .COM 20K ; Microsoft macro assembler
|
||||||
|
MBASIC .COM 24K ; Microsoft Basic interpreter
|
||||||
|
MC .SUB 2K ; assemble and link an assembler program
|
||||||
|
MCC .SUB 2K ; read, assemble and link an assembler program
|
||||||
|
MCCL .SUB 2K ; assemble, link and produce listing
|
||||||
|
MEMCFG .LIB 2K ; defines the memory configuration
|
||||||
|
MOVER .MAC 2K ; moves operating system in place
|
||||||
|
OTHELLO .COM 12K ; Othello (Reversi) game
|
||||||
|
PIP .COM 8K ; Peripheral Interchange Program
|
||||||
|
PRELIM .COM 2K ; preliminary CPU tests
|
||||||
|
PRELIM .MAC 6K ; source code for PRELIM.COM
|
||||||
|
R .COM 4K ; read files from SIMH environment
|
||||||
|
RSETSIMH.COM 2K ; reset SIMH interface
|
||||||
|
RSETSIMH.MAC 2K ; assembler source for RSETSIMH.COM
|
||||||
|
SHOWSEC .COM 3K ; show sectors on a disk
|
||||||
|
SID .COM 8K ; debugger for 8080
|
||||||
|
SPEED .COM 2K ; utility to measure the clock speed of the simulated CPU
|
||||||
|
STAT .COM 6K ; provide information about currently logged disks
|
||||||
|
SURVEY .COM 2K ; system survey
|
||||||
|
SURVEY .MAC 16K ; assembler source for SURVEY.COM
|
||||||
|
SYSCOPY .COM 2K ; copy system tracks between disks
|
||||||
|
SYSCPM2 .SUB 2K ; create CP/M 2 on drive A:
|
||||||
|
TIMER .COM 2K ; perform various timer operations
|
||||||
|
TIMER .MAC 2K ; source code for TIMER.COM
|
||||||
|
UNCR .COM 8K ; un-crunch utility
|
||||||
|
UNERA .COM 2K ; un-erase a file
|
||||||
|
UNERA .MAC 16K ; source for UNERA.COM
|
||||||
|
USQ .COM 2K ; un-squeeze utility
|
||||||
|
W .COM 4K ; write files to SIMH environment
|
||||||
|
WM .COM 12K ; word master screen editor
|
||||||
|
WM .HLP 3K ; help file for WM.COM
|
||||||
|
WORM .COM 4K ; worm game for VT100 terminal
|
||||||
|
XFORMAT .COM 2K ; initialise a drive (floppy or hard disk)
|
||||||
|
XSUB .COM 2K ; support for DO.COM
|
||||||
|
ZAP .COM 10K ; SuperZap 5.2 disk editor configured for VT100
|
||||||
|
ZSID .COM 10K ; debugger for Z80
|
||||||
|
ZTRAN4 .COM 4K ; translate 8080 mnemonics into Z80 equivalents
|
||||||
|
|
||||||
|
|
||||||
|
5.2 CP/M Version 3 with banked memory
|
||||||
|
|
||||||
|
CP/M 3 is the successor to CP/M 2.2. A customised BIOS (BIOS3.MAC) is
|
||||||
|
included to facilitate modification if so desired. The defaults supplied in
|
||||||
|
GENCPM.DAT for system generation can be used. BOOTGEN.COM is used to place
|
||||||
|
the CP/M loader (LDR.COM) on the boot tracks of a disk.
|
||||||
|
|
||||||
|
Running CP/M 3 with banked memory:
|
||||||
|
sim> attach dsk cpm3.dsk
|
||||||
|
sim> reset cpu
|
||||||
|
sim> set cpu banked
|
||||||
|
sim> set cpu itrap
|
||||||
|
sim> boot dsk
|
||||||
|
|
||||||
|
Executing "DO SYSCPM3" will re-generate the banked version of CP/M 3. You
|
||||||
|
can boot CP/M 3 with or without a Z80 CPU. The Z80 CPU is needed for both
|
||||||
|
sysgens due to the use of BOOTGEN.COM which requires it.
|
||||||
|
|
||||||
|
The disk "cpm3.dsk" contains the following files:
|
||||||
|
ASM .COM 8K ; CP/M assembler
|
||||||
|
ASSIGN .SYS 2K
|
||||||
|
BDOS3 .SPR 10K
|
||||||
|
BIOS3 .MAC 28K ; CP/M 3 BIOS source for Altair SIMH
|
||||||
|
BIOS3 .SPR 4K
|
||||||
|
BNKBDOS3.SPR 14K
|
||||||
|
BNKBIOS3.SPR 4K
|
||||||
|
BOOT .COM 2K ; transfer control to boot ROM
|
||||||
|
BOOTGEN .COM 2K ; put a program on the boot sectors
|
||||||
|
CCP .COM 4K
|
||||||
|
COPYSYS .COM 2K
|
||||||
|
CPM3 .SYS 18K
|
||||||
|
CPMLDR .MAC 38K ; CP/M 3 loader assembler source
|
||||||
|
DATE .COM 4K ; date utility
|
||||||
|
DDT .COM 6K ; 8080 debugger
|
||||||
|
DDTZ .COM 10K ; Z80 debugger
|
||||||
|
DEFS .LIB 2K ; include file for BIOS3.MAC to create banked CP/M 3
|
||||||
|
DEVICE .COM 8K
|
||||||
|
DIF .COM 4K ; determine differences between two files
|
||||||
|
DIR .COM 16K ; directory utility
|
||||||
|
DO .COM 6K ; batch processing
|
||||||
|
DUMP .COM 2K
|
||||||
|
ED .COM 10K
|
||||||
|
ERASE .COM 4K
|
||||||
|
GENCOM .COM 16K
|
||||||
|
GENCPM .COM 22K
|
||||||
|
GENCPM .DAT 4K ; CP/M generation information for banked version
|
||||||
|
GENCPMNB.DAT 4K ; CP/M generation information for non-banked version
|
||||||
|
GET .COM 8K
|
||||||
|
HELP .COM 8K ; help utility
|
||||||
|
HELP .HLP 62K ; help files
|
||||||
|
HEXCOM .CPM 2K
|
||||||
|
HIST .UTL 2K
|
||||||
|
INITDIR .COM 32K
|
||||||
|
L80 .COM 12K ; Microsoft linker
|
||||||
|
LDR .COM 4K ; CP/M loader with optimised loader BIOS
|
||||||
|
LDRBIOS3.MAC 14K ; optimised (for space) loader BIOS
|
||||||
|
LIB .COM 8K ; Digital Research librarian
|
||||||
|
LINK .COM 16K ; Digital Research linker
|
||||||
|
LOAD .COM 2K
|
||||||
|
M80 .COM 20K ; Microsoft macro assembler
|
||||||
|
MC .SUB 2K ; assemble and link an assmbler program
|
||||||
|
MCC .SUB 2K ; read, assemble and link an assembler program
|
||||||
|
PATCH .COM 4K
|
||||||
|
PIP .COM 10K ; Peripheral Interchange Program
|
||||||
|
PROFILE .SUB 2K ; commands to be executed at start up
|
||||||
|
PUT .COM 8K
|
||||||
|
R .COM 4K ; read files from SIMH environment
|
||||||
|
RENAME .COM 4K
|
||||||
|
RESBDOS3.SPR 2K
|
||||||
|
RMAC .COM 14K ; Digital Research macro assembler
|
||||||
|
RSETSIMH.COM 2K ; reset SIMH interface
|
||||||
|
SAVE .COM 2K
|
||||||
|
SCB .MAC 2K
|
||||||
|
SET .COM 12K
|
||||||
|
SETDEF .COM 6K
|
||||||
|
SHOW .COM 10K
|
||||||
|
SHOWSEC .COM 4K ; show sectors on a disk
|
||||||
|
SID .COM 8K ; 8080 debugger
|
||||||
|
SYSCOPY .COM 2K ; copy system tracks between disks
|
||||||
|
SYSCPM3 .SUB 2K ; create banked CP/M 3 system
|
||||||
|
TRACE .UTL 2K
|
||||||
|
TSHOW .COM 2K ; show split time
|
||||||
|
TSTART .COM 2K ; create timer and start it
|
||||||
|
TSTOP .COM 2K ; show final time and stop timer
|
||||||
|
TYPE .COM 4K
|
||||||
|
UNERA .COM 2K ; un-erase a file
|
||||||
|
W .COM 4K ; write files to SIMH environment
|
||||||
|
XREF .COM 16K ; cross reference utility
|
||||||
|
ZSID .COM 10K ; Z80 debugger
|
||||||
|
|
||||||
|
|
||||||
|
5.3 MP/M II with banked memory
|
||||||
|
|
||||||
|
MP/M II is an acronym for MultiProgramming Monitor Control Program for
|
||||||
|
Microprocessors. It is a multiuser operating system for an eight bit
|
||||||
|
microcomputer. MP/M II supports multiprogramming at each terminal. This
|
||||||
|
version supports four terminals available via Telnet. To boot:
|
||||||
|
|
||||||
|
sim> attach dsk mpm.dsk
|
||||||
|
sim> set cpu itrap
|
||||||
|
sim> set cpu z80
|
||||||
|
sim> set cpu rom
|
||||||
|
sim> set cpu banked
|
||||||
|
sim> attach sio 23
|
||||||
|
sim> d common b000
|
||||||
|
sim> boot dsk
|
||||||
|
|
||||||
|
Now connect a Telnet session to the simulator and type "MPM" at the "A>"
|
||||||
|
prompt. Now you can connect up to three additional terminals via Telnet to
|
||||||
|
the Altair running MP/M II. To re-generate the system perform "DO SYSMPM"
|
||||||
|
in the CP/M environment (not possible under MP/M since XSUB is needed).
|
||||||
|
|
||||||
|
The disk "mpm.dsk" contains the following files:
|
||||||
|
Name Ext Size Comment
|
||||||
|
ABORT .PRL 2K ; abort a process
|
||||||
|
ABORT .RSP 2K
|
||||||
|
ASM .PRL 10K ; MP/M assembler
|
||||||
|
BNKBDOS .SPR 12K ; banked BDOS
|
||||||
|
BNKXDOS .SPR 2K ; banked XDOS
|
||||||
|
BNKXIOS .SPR 4K ; banked XIOS
|
||||||
|
BOOTGEN .COM 2K ; copy an executable to the boot section
|
||||||
|
CONSOLE .PRL 2K ; print console number
|
||||||
|
CPM .COM 2K ; return to CP/M
|
||||||
|
CPM .MAC 2K ; source for CPM.COM
|
||||||
|
DDT .COM 6K ; MP/M DDT
|
||||||
|
DDT2 .COM 6K ; CP/M DDT
|
||||||
|
DDTZ .COM 10K ; CP/M DDT with Z80 support
|
||||||
|
DIF .COM 4K ; difference between two files
|
||||||
|
DIR .PRL 2K ; directory command
|
||||||
|
DO .COM 2K ; CP/M submit
|
||||||
|
DSKRESET.PRL 2K ; disk reset command
|
||||||
|
DUMP .MAC 6K ; source for DUMP.PRL
|
||||||
|
DUMP .PRL 2K ; dump command
|
||||||
|
ED .PRL 10K ; MP/M line editor
|
||||||
|
ERA .PRL 2K ; erase command
|
||||||
|
ERAQ .PRL 4K ; erase comand (verbose)
|
||||||
|
GENHEX .COM 2K
|
||||||
|
GENMOD .COM 2K
|
||||||
|
GENSYS .COM 10K
|
||||||
|
L80 .COM 12K ; Microsoft linker
|
||||||
|
LDRBIOS .MAC 14K ; loader BIOS
|
||||||
|
LIB .COM 8K ; library utility
|
||||||
|
LINK .COM 16K ; linker
|
||||||
|
LOAD .COM 2K ; loader
|
||||||
|
M80 .COM 20K ; Microsoft macro assembler
|
||||||
|
MC .SUB 2K ; assemble and link an assmbler program
|
||||||
|
MCC .SUB 2K ; read, assemble and link an assembler program
|
||||||
|
MPM .COM 8K ; start MP/M II
|
||||||
|
MPM .SYS 26K ; MP/M system file
|
||||||
|
MPMD .LIB 2K ; define a banked system
|
||||||
|
MPMLDR .COM 6K ; MP/M loader without LDRBIOS
|
||||||
|
MPMSTAT .BRS 6K ; status of MP/M system
|
||||||
|
MPMSTAT .PRL 6K
|
||||||
|
MPMSTAT .RSP 2K
|
||||||
|
MPMXIOS .MAC 26K ; XIOS for MP/M
|
||||||
|
PIP .PRL 10K ; MP/M peripheral interchange program
|
||||||
|
PIP2 .COM 8K ; CP/M peripheral interchange program
|
||||||
|
PRINTER .PRL 2K
|
||||||
|
PRLCOM .PRL 4K
|
||||||
|
R .COM 4K ; read a file from the SIMH environment
|
||||||
|
RDT .PRL 8K ; debugger for page relocatable programs
|
||||||
|
REN .PRL 4K ; rename a file
|
||||||
|
RESBDOS .SPR 4K ; non-banked BDOS
|
||||||
|
RMAC .COM 14K ; Digital Research macro assembler
|
||||||
|
RSETSIMH.COM 2K ; reset SIMH interface
|
||||||
|
SCHED .BRS 2K ; schedule a job
|
||||||
|
SCHED .PRL 4K
|
||||||
|
SCHED .RSP 2K
|
||||||
|
SDIR .PRL 18K ; fancy directory command
|
||||||
|
SET .PRL 8K ; set parameters
|
||||||
|
SHOW .PRL 8K ; show status of disks
|
||||||
|
SPOOL .BRS 4K ; spool utility
|
||||||
|
SPOOL .PRL 4K
|
||||||
|
SPOOL .RSP 2K
|
||||||
|
STAT .COM 6K ; CP/M stat command
|
||||||
|
STAT .PRL 10K ; MP/M stat command
|
||||||
|
STOPSPLR.PRL 2K ; stop spooler
|
||||||
|
SUBMIT .PRL 6K ; MP/M submit
|
||||||
|
SYSCOPY .COM 2K ; copy system tracks
|
||||||
|
SYSMPM .SUB 2K ; do a system generation
|
||||||
|
SYSTEM .DAT 2K ; default values for system generation
|
||||||
|
TMP .SPR 2K
|
||||||
|
TOD .PRL 4K ; time of day
|
||||||
|
TSHOW .COM 2K ; show split time
|
||||||
|
TSTART .COM 2K ; create timer and start it
|
||||||
|
TSTOP .COM 2K ; show final time and stop timer
|
||||||
|
TYPE .PRL 2K ; type a file on the screen
|
||||||
|
USER .PRL 2K ; set user area
|
||||||
|
W .COM 4K ; write a file to SIMH environment
|
||||||
|
XDOS .SPR 10K ; XDOS
|
||||||
|
XREF .COM 16K ; cross reference utility
|
||||||
|
XSUB .COM 2K ; for CP/M DO
|
||||||
|
|
||||||
|
|
||||||
|
5.4 CP/M application software
|
||||||
|
|
||||||
|
There is also a small collection of sample application software
|
||||||
|
containing the following items:
|
||||||
|
|
||||||
|
- SPL: a Small Programming Language with a suite of sample programs
|
||||||
|
- PROLOGZ: a Prolog interpreter written in SPL with sources
|
||||||
|
- PASCFORM: a Pascal pretty printer written in Pascal
|
||||||
|
- Pascal MT+: Pascal language system needed to compile PASCFORM
|
||||||
|
|
||||||
|
The sample software comes on "app.dsk" and to use it do
|
||||||
|
|
||||||
|
sim> attach dsk1 app.dsk
|
||||||
|
|
||||||
|
before booting CP/M.
|
||||||
|
|
||||||
|
The disk "app.dsk" contains the following files:
|
||||||
|
Name Ext Size Comment
|
||||||
|
BOOTGEN .COM 2K
|
||||||
|
BOOTGEN .SPL 6K ; SPL source for BOOTGEN.COM
|
||||||
|
C .SUB 2K ; batch file for compiling an SPL source file
|
||||||
|
CALC .PRO 4K ; Prolog demo program: Calculator
|
||||||
|
CC .SUB 2K ; compile an SPL source which is on the underlying
|
||||||
|
file system
|
||||||
|
DECLARAT. 12K ; common include file, SPL source
|
||||||
|
DIF .COM 4K
|
||||||
|
DIF .SPL 10K ; SPL source for DIF.COM
|
||||||
|
EDIT .SPL 10K ; screen editor for PROLOGZ, SPL source
|
||||||
|
FAMILY .PRO 4K ; Prolog demo program: Family relations
|
||||||
|
INTEGER .PRO 2K ; Prolog demo program: Integer arithmetic
|
||||||
|
KNAKE .PRO 2K ; Prolog demo program: Logic puzzle
|
||||||
|
LINKMT .COM 12K ; Pascal MT+ 5.5 linker
|
||||||
|
MAIN .SPL 14K ; main module for PROLOGZ, SPL source
|
||||||
|
MOVE .MAC 4K ; helper functions for PROLOGZ in assembler
|
||||||
|
MTERRS .TXT 6K ; Pascal MT+ error messages
|
||||||
|
MTPLUS .000 14K ; Pascal MT+ 5.5 compiler file
|
||||||
|
MTPLUS .001 12K ; Pascal MT+ 5.5 compiler file
|
||||||
|
MTPLUS .002 8K ; Pascal MT+ 5.5 compiler file
|
||||||
|
MTPLUS .003 8K ; Pascal MT+ 5.5 compiler file
|
||||||
|
MTPLUS .004 18K ; Pascal MT+ 5.5 compiler file
|
||||||
|
MTPLUS .005 8K ; Pascal MT+ 5.5 compiler file
|
||||||
|
MTPLUS .006 6K ; Pascal MT+ 5.5 compiler file
|
||||||
|
MTPLUS .COM 36K ; Pascal MT+ 5.5 compiler
|
||||||
|
PASCFORM.COM 36K ; Pascal formatter
|
||||||
|
PASCFORM.PAS 54K ; Pascal formatter source code
|
||||||
|
PASCFORM.SUB 2K ; create Pascal formatter
|
||||||
|
PASLIB .ERL 24K ; Pascal MT+ 5.5 run time library
|
||||||
|
PINST .COM 4K ; terminal installation program for PROLOGZ
|
||||||
|
PINST .SPL 16K ; terminal installation program for PROLOGZ,
|
||||||
|
SPL source
|
||||||
|
PROLOGZ .COM 18K ; PROLOGZ interpreter and screen editor
|
||||||
|
PROLOGZ .SPL 2K ; PROLOGZ main program, SPL source
|
||||||
|
PROLOGZ .TXT 40K ; PROLOGZ documentation in German
|
||||||
|
PROVE .SPL 16K ; backtrack theorem prover for PROLOGZ, SPL source
|
||||||
|
PZCLEAN .SUB 2K ; PROLOGZ: remove all created ".rel" and ".lst" files
|
||||||
|
PZLINK .SUB 2K ; PROLOGZ: create PINST, PROLOGZ and personalise the
|
||||||
|
serial number
|
||||||
|
PZMAKE .SUB 2K ; PROLOGZ: compiles the sources (you can ignore
|
||||||
|
any compiler errors)
|
||||||
|
QUEEN .PRO 2K ; Prolog demo program: N-queens problem
|
||||||
|
READ .COM 4K
|
||||||
|
READ .SPL 10K ; SPL source for R.COM
|
||||||
|
SHOWSEC .COM 4K
|
||||||
|
SHOWSEC .SPL 6K ; SPL source for SHOWSEC.COM
|
||||||
|
SPEED .COM 2K ; utility to measure the clock speed of the simulated CPU
|
||||||
|
SPEED .SPL 2K ; SPL source for SPEED.COM, requires SWLIB.MAC
|
||||||
|
SPL .COM 38K ; the SPL compiler itself
|
||||||
|
SPL .TXT 56K ; SPL language and compiler documentation in German
|
||||||
|
SPLERROR.DAT 12K ; error messages of the compiler (in German)
|
||||||
|
SPLIB .REL 6K ; SPL runtime library
|
||||||
|
STDIO . 2K ; include file for SPL programs
|
||||||
|
SWLIB .MAC 2K ; assembler utility routines needed by SPEED.SPL
|
||||||
|
SYSCOPY .COM 2K
|
||||||
|
SYSCOPY .SPL 6K ; SPL source for SYSCOPY.COM
|
||||||
|
TERMBDOS.SPL 2K ; terminal interface to CP/M for PROLOGZ, SPL source
|
||||||
|
UTIL .SPL 18K ; utility functions for PROLOGZ, SPL source
|
||||||
|
WRITE .COM 4K
|
||||||
|
WRITE .SPL 8K ; SPL source for W.COM
|
||||||
|
XFORMAT .COM 2K
|
||||||
|
XFORMAT .SPL 6K ; SPL source for XFORMAT.COM
|
||||||
|
|
||||||
|
|
||||||
|
5.5 MITS Disk Extended BASIC Version 4.1
|
||||||
|
|
||||||
|
This was the commonly used software for serious users of the Altair
|
||||||
|
computer. It is a powerful (but slow) BASIC with some extended commands to
|
||||||
|
allow it to access and manage the disk. There was no operating system it
|
||||||
|
ran under. To boot:
|
||||||
|
|
||||||
|
sim> set cpu 8080 ;Z80 will not work
|
||||||
|
sim> attach dsk mbasic.dsk
|
||||||
|
sim> set sio upper
|
||||||
|
sim> go ff00
|
||||||
|
|
||||||
|
MEMORY SIZE? [return]
|
||||||
|
LINEPRINTER? [C return]
|
||||||
|
HIGHEST DISK NUMBER? [0 return] (0 here = 1 drive system)
|
||||||
|
NUMBER OF FILES? [3 return]
|
||||||
|
NUMBER OF RANDOM FILES? [2 return]
|
||||||
|
|
||||||
|
44041 BYTES FREE
|
||||||
|
ALTAIR BASIC REV. 4.1
|
||||||
|
[DISK EXTENDED VERSION]
|
||||||
|
COPYRIGHT 1977 BY MITS INC.
|
||||||
|
OK
|
||||||
|
[MOUNT 0]
|
||||||
|
OK
|
||||||
|
[FILES]
|
||||||
|
|
||||||
|
|
||||||
|
5.6 Altair DOS Version 1.0
|
||||||
|
|
||||||
|
This was long promised but not delivered until it was almost irrelevant.
|
||||||
|
A short attempted tour will reveal it to be a dog, far inferior to CP/M. To
|
||||||
|
boot:
|
||||||
|
|
||||||
|
sim> d tracks[0-7] 77 ;set to Altair settings
|
||||||
|
sim> set cpu altairrom
|
||||||
|
sim> attach dsk altdos.dsk
|
||||||
|
sim> set sio upper
|
||||||
|
sim> go ff00
|
||||||
|
|
||||||
|
MEMORY SIZE? [return]
|
||||||
|
INTERRUPTS? N [return]
|
||||||
|
HIGHEST DISK NUMBER? [0 return] (3 here = 4 drive system)
|
||||||
|
HOW MANY DISK FILES? [3 return]
|
||||||
|
HOW MANY RANDOM FILES? [2 return]
|
||||||
|
|
||||||
|
056449 BYTES AVAILABLE
|
||||||
|
DOS MONITOR VER 1.0
|
||||||
|
COPYRIGHT 1977 BY MITS INC
|
||||||
|
.[MNT 0]
|
||||||
|
|
||||||
|
.[DIR 0]
|
||||||
|
|
||||||
|
|
||||||
|
5.7 Altair Basic 3.2 (4k)
|
||||||
|
|
||||||
|
In order to run the famous 4k Basic, use the following commands (the
|
||||||
|
trick is to get the Switch Register right).
|
||||||
|
|
||||||
|
sim> set cpu 8080 ;note 4k Basic will not run on a Z80 CPU
|
||||||
|
sim> set sio upper ;4k Basic does not like lower case letters as input
|
||||||
|
sim> set sio ansi ;4k Basic produces 8-bit output, strip to seven bits
|
||||||
|
sim> d sr 8 ;good setting for the Switch Register
|
||||||
|
sim> load 4kbas.bin 0 ;load it at 0
|
||||||
|
sim> go 0 ;and start it
|
||||||
|
MEMORY SIZE? [return]
|
||||||
|
TERMINAL WIDTH? [return]
|
||||||
|
WANT SIN? [Y]
|
||||||
|
|
||||||
|
61911 BYTES FREE
|
||||||
|
|
||||||
|
BASIC VERSION 3.2
|
||||||
|
[4K VERSION]
|
||||||
|
|
||||||
|
OK
|
||||||
|
|
||||||
|
|
||||||
|
5.8 Altair 8k Basic
|
||||||
|
Running 8k Basic follows the procedure for 4k Basic.
|
||||||
|
|
||||||
|
sim> set cpu 8080 ;note 8k Basic will not run on a Z80 CPU
|
||||||
|
sim> set sio upper ;8k Basic does not like lower case letters as input
|
||||||
|
sim> set sio ansi ;8k Basic produces 8-bit output, strip to seven bits
|
||||||
|
sim> d sr 8 ;good setting for the Switch Register
|
||||||
|
sim> load 8kbas.bin 0 ;load it at 0
|
||||||
|
sim> go 0 ;and start it
|
||||||
|
MEMORY SIZE? [A]
|
||||||
|
|
||||||
|
WRITTEN FOR ROYALTIES BY MICRO-SOFT
|
||||||
|
|
||||||
|
MEMORY SIZE? [return]
|
||||||
|
TERMINAL WIDTH? [return]
|
||||||
|
WANT SIN-COS-TAN-ATN? [Y]
|
||||||
|
|
||||||
|
58756 BYTES FREE
|
||||||
|
ALTAIR BASIC REV. 4.0
|
||||||
|
[EIGHT-K VERSION]
|
||||||
|
COPYRIGHT 1976 BY MITS INC.
|
||||||
|
OK
|
||||||
|
|
||||||
|
|
||||||
|
5.9 Altair Basic 4.0
|
||||||
|
|
||||||
|
Execute the following commands to run Altair Extended Basic:
|
||||||
|
|
||||||
|
sim> set sio upper ;Extended Basic does not like lower case letters as input
|
||||||
|
sim> set sio ansi ;Extended Basic produces 8-bit output, strip to seven bits
|
||||||
|
sim> d sr 8 ;good setting for the Switch Register
|
||||||
|
sim> load exbas.bin 0 ;load it at 0
|
||||||
|
sim> go 0 ;and start it
|
||||||
|
16384 Bytes loaded at 0.
|
||||||
|
|
||||||
|
MEMORY SIZE? [return]
|
||||||
|
WANT SIN-COS-TAN-ATN? [Y]
|
||||||
|
|
||||||
|
50606 BYTES FREE
|
||||||
|
ALTAIR BASIC REV. 4.0
|
||||||
|
[EXTENDED VERSION]
|
||||||
|
COPYRIGHT 1977 BY MITS INC.
|
||||||
|
OK
|
||||||
|
|
||||||
|
|
||||||
|
5.10 Altair Disk Extended Basic Version 300-5-C
|
||||||
|
|
||||||
|
This version of Basic was provided by Scott LaBombard. To execute use the
|
||||||
|
following commands:
|
||||||
|
|
||||||
|
sim> d tracks[0-7] 77 ;set to Altair settings
|
||||||
|
sim> at dsk extbas5.dsk
|
||||||
|
sim> g 0
|
||||||
|
|
||||||
|
MEMORY SIZE? [return]
|
||||||
|
LINEPRINTER? [C]
|
||||||
|
HIGHEST DISK NUMBER? [0]
|
||||||
|
HOW MANY FILES? [3]
|
||||||
|
HOW MANY RANDOM FILES? [3]
|
||||||
|
|
||||||
|
42082 BYTES FREE
|
||||||
|
|
||||||
|
ALTAIR DISK EXTENDED BASIC
|
||||||
|
VERSION 300-5-C [01NOV78]
|
||||||
|
COPYRIGHT 1978 BY MITS INC.
|
||||||
|
|
||||||
|
OK
|
||||||
|
|
||||||
|
|
||||||
|
6. Special simulator features
|
||||||
|
|
||||||
|
|
||||||
|
6.1 Memory access breakpoints
|
||||||
|
|
||||||
|
In addition to the regular SIMH features such as PC queue, breakpoints
|
||||||
|
etc., this simulator supports memory access breakpoints. A memory access
|
||||||
|
breakpoint is triggered when a pre-defined memory location is accessed
|
||||||
|
(read, write or update). To set a memory location breakpoint enter
|
||||||
|
|
||||||
|
sim> break -m <location>
|
||||||
|
|
||||||
|
Execution will stop whenever an operation accesses <location>. Note that
|
||||||
|
a memory access breakpoint is not triggered by fetching code from memory
|
||||||
|
(this is the job of regular breakpoints). This feature has been implemented
|
||||||
|
by using the typing facility of the SIMH breakpoints.
|
||||||
|
|
||||||
|
|
||||||
|
6.2 T-state stepping
|
||||||
|
|
||||||
|
The SIMH step command supports the "-t" modifier to allow steppping for
|
||||||
|
a predefined number of t-states. For example
|
||||||
|
|
||||||
|
sim> step -t 1000
|
||||||
|
|
||||||
|
will cause the simulated CPU to execute 1000 t-states (note that the shortest
|
||||||
|
instruction will have 4 t-states). On the other hand, the command
|
||||||
|
|
||||||
|
sim> step 1000
|
||||||
|
|
||||||
|
will cause the simulated CPU to execute 1000 instructions.
|
||||||
|
|
||||||
|
|
||||||
|
7. Brief summary of all major changes to the original Altair simulator
|
||||||
|
- Full support for Z80. CP/M software requiring a Z80 CPU now runs
|
||||||
|
properly. DDTZ and PROLOGZ are included for demonstration purposes.
|
||||||
|
- Added banked memory support.
|
||||||
|
- PC queue implemented.
|
||||||
|
- Full assembler and dis-assembler support for Z80 and 8080 mnemonics.
|
||||||
|
Depending on the current setting of the CPU, the appropriate mnemonics
|
||||||
|
are used.
|
||||||
|
- The BOOT ROM was changed to fully load the software from disk. The
|
||||||
|
original code basically loaded a copy of itself from the disk and
|
||||||
|
executed it.
|
||||||
|
- ROM and memory size settings are now fully honored. This means that you
|
||||||
|
cannot write into the ROM or outside the defined RAM (e.g. when the RAM size
|
||||||
|
was truncated with the SET CPU commands). This feature allows programs which
|
||||||
|
check for the size of available RAM to run properly (e.g. 4k Basic). In
|
||||||
|
addition one can enable and disable the ROM which is useful in special cases
|
||||||
|
(e.g. when testing a new version of the ROM).
|
||||||
|
- The console can also be used via Telnet. This is useful when a terminal is
|
||||||
|
needed which supports cursor control such as a VT100. PROLOGZ for example
|
||||||
|
has a built-in screen editor which works under Telnet.
|
||||||
|
- Simplified file exchange for CP/M. Using the READ program under CP/M one
|
||||||
|
can easily import files into CP/M from the regular file system. Note that PIP
|
||||||
|
does not work properly on non-text files on PTR.
|
||||||
|
- The WRITE program can be used to transfer files from the CP/M environment to
|
||||||
|
the regular environment (binary or ASCII transfer).
|
||||||
|
- The last character read from PTR is always Control-Z (the EOF character for
|
||||||
|
CP/M). This makes sure that PIP (Peripheral Interchange Program on CP/M) will
|
||||||
|
terminate properly.
|
||||||
|
- Fixed a bug in the BIOS warm boot routine which caused CP/M to crash.
|
||||||
|
- Modified the BIOS for CP/M to support 8 disks.
|
||||||
|
- Added CP/M 3 banked version as sample software
|
||||||
|
- Changed from octal to hex
|
||||||
|
- Made the DSK and SIO device more robust (previously malicious code could
|
||||||
|
crash the simulator)
|
||||||
|
- Added memory access break points
|
||||||
|
- Added periodic timer interrupts (useful for MP/M)
|
||||||
|
- Added additional consoles (useful for MP/M)
|
||||||
|
- Added MP/M II banked version as sample software
|
|
@ -1,6 +1,6 @@
|
||||||
/* altairz80_hdsk.c: simulated hard disk device to increase capacity
|
/* altairz80_hdsk.c: simulated hard disk device to increase capacity
|
||||||
|
|
||||||
Copyright (c) 2002-2003, Peter Schorn
|
Copyright (c) 2002-2004, Peter Schorn
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -111,7 +111,9 @@ DEVICE hdsk_dev = {
|
||||||
"HDSK", hdsk_unit, hdsk_reg, hdsk_mod,
|
"HDSK", hdsk_unit, hdsk_reg, hdsk_mod,
|
||||||
8, 10, 31, 1, 8, 8,
|
8, 10, 31, 1, 8, 8,
|
||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
&hdsk_boot, NULL, NULL, NULL, 0, NULL, NULL };
|
&hdsk_boot, NULL, NULL,
|
||||||
|
NULL, 0, 0,
|
||||||
|
NULL, NULL, NULL };
|
||||||
|
|
||||||
static t_stat hdsk_svc(UNIT *uptr) {
|
static t_stat hdsk_svc(UNIT *uptr) {
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
@ -224,34 +226,34 @@ static int32 checkParameters(void) {
|
||||||
int32 currentFlag;
|
int32 currentFlag;
|
||||||
if ((selectedDisk < 0) || (selectedDisk >= HDSK_NUMBER)) {
|
if ((selectedDisk < 0) || (selectedDisk >= HDSK_NUMBER)) {
|
||||||
if (hdsk_hasVerbose()) {
|
if (hdsk_hasVerbose()) {
|
||||||
message2("HDSK%d does not exist, will use HDSK0 instead.\n", selectedDisk);
|
message2("HDSK%d does not exist, will use HDSK0 instead.", selectedDisk);
|
||||||
}
|
}
|
||||||
selectedDisk = 0;
|
selectedDisk = 0;
|
||||||
}
|
}
|
||||||
currentFlag = (hdsk_dev.units + selectedDisk) -> flags;
|
currentFlag = (hdsk_dev.units + selectedDisk) -> flags;
|
||||||
if ((currentFlag & UNIT_ATT) == 0) {
|
if ((currentFlag & UNIT_ATT) == 0) {
|
||||||
if (currentFlag & UNIT_HDSK_VERBOSE) {
|
if (currentFlag & UNIT_HDSK_VERBOSE) {
|
||||||
message2("HDSK%d is not attached.\n", selectedDisk);
|
message2("HDSK%d is not attached.", selectedDisk);
|
||||||
}
|
}
|
||||||
return FALSE; /* cannot read or write */
|
return FALSE; /* cannot read or write */
|
||||||
}
|
}
|
||||||
if ((selectedSector < 0) || (selectedSector >= HDSK_SECTORS_PER_TRACK)) {
|
if ((selectedSector < 0) || (selectedSector >= HDSK_SECTORS_PER_TRACK)) {
|
||||||
if (currentFlag & UNIT_HDSK_VERBOSE) {
|
if (currentFlag & UNIT_HDSK_VERBOSE) {
|
||||||
message4("HDSK%d: 0 <= Sector=%02d < %d violated, will use 0 instead.\n",
|
message4("HDSK%d: 0 <= Sector=%02d < %d violated, will use 0 instead.",
|
||||||
selectedDisk, selectedSector, HDSK_SECTORS_PER_TRACK);
|
selectedDisk, selectedSector, HDSK_SECTORS_PER_TRACK);
|
||||||
}
|
}
|
||||||
selectedSector = 0;
|
selectedSector = 0;
|
||||||
}
|
}
|
||||||
if ((selectedTrack < 0) || (selectedTrack >= HDS_MAX_TRACKS)) {
|
if ((selectedTrack < 0) || (selectedTrack >= HDS_MAX_TRACKS)) {
|
||||||
if (currentFlag & UNIT_HDSK_VERBOSE) {
|
if (currentFlag & UNIT_HDSK_VERBOSE) {
|
||||||
message4("HDSK%d: 0 <= Track=%04d < %04d violated, will use 0 instead.\n",
|
message4("HDSK%d: 0 <= Track=%04d < %04d violated, will use 0 instead.",
|
||||||
selectedDisk, selectedTrack, HDS_MAX_TRACKS);
|
selectedDisk, selectedTrack, HDS_MAX_TRACKS);
|
||||||
}
|
}
|
||||||
selectedTrack = 0;
|
selectedTrack = 0;
|
||||||
}
|
}
|
||||||
selectedDMA &= ADDRMASK;
|
selectedDMA &= ADDRMASK;
|
||||||
if (hdskTrace) {
|
if (hdskTrace) {
|
||||||
message6("%s HDSK%d Sector=%02d Track=%04d DMA=%04x\n",
|
message6("%s HDSK%d Sector=%02d Track=%04d DMA=%04x",
|
||||||
(hdskLastCommand == hdsk_read) ? "Read" : "Write",
|
(hdskLastCommand == hdsk_read) ? "Read" : "Write",
|
||||||
selectedDisk, selectedSector, selectedTrack, selectedDMA);
|
selectedDisk, selectedSector, selectedTrack, selectedDMA);
|
||||||
}
|
}
|
||||||
|
@ -263,7 +265,7 @@ static int32 doSeek(void) {
|
||||||
if (fseek(uptr -> fileref,
|
if (fseek(uptr -> fileref,
|
||||||
HDSK_TRACK_SIZE * selectedTrack + HDSK_SECTOR_SIZE * selectedSector, SEEK_SET)) {
|
HDSK_TRACK_SIZE * selectedTrack + HDSK_SECTOR_SIZE * selectedSector, SEEK_SET)) {
|
||||||
if ((uptr -> flags) & UNIT_HDSK_VERBOSE) {
|
if ((uptr -> flags) & UNIT_HDSK_VERBOSE) {
|
||||||
message4("Could not access HDSK%d Sector=%02d Track=%04d.\n",
|
message4("Could not access HDSK%d Sector=%02d Track=%04d.",
|
||||||
selectedDisk, selectedSector, selectedTrack);
|
selectedDisk, selectedSector, selectedTrack);
|
||||||
}
|
}
|
||||||
return CPM_ERROR;
|
return CPM_ERROR;
|
||||||
|
@ -285,7 +287,7 @@ static int32 doRead(void) {
|
||||||
hdskbuf[i] = CPM_EMPTY;
|
hdskbuf[i] = CPM_EMPTY;
|
||||||
}
|
}
|
||||||
if ((uptr -> flags) & UNIT_HDSK_VERBOSE) {
|
if ((uptr -> flags) & UNIT_HDSK_VERBOSE) {
|
||||||
message4("Could not read HDSK%d Sector=%02d Track=%04d.\n",
|
message4("Could not read HDSK%d Sector=%02d Track=%04d.",
|
||||||
selectedDisk, selectedSector, selectedTrack);
|
selectedDisk, selectedSector, selectedTrack);
|
||||||
}
|
}
|
||||||
return CPM_OK; /* allows the creation of empty hard disks */
|
return CPM_OK; /* allows the creation of empty hard disks */
|
||||||
|
@ -309,7 +311,7 @@ static int32 doWrite(void) {
|
||||||
}
|
}
|
||||||
if (fwrite(hdskbuf, HDSK_SECTOR_SIZE, 1, uptr -> fileref) != 1) {
|
if (fwrite(hdskbuf, HDSK_SECTOR_SIZE, 1, uptr -> fileref) != 1) {
|
||||||
if ((uptr -> flags) & UNIT_HDSK_VERBOSE) {
|
if ((uptr -> flags) & UNIT_HDSK_VERBOSE) {
|
||||||
message4("Could not write HDSK%d Sector=%02d Track=%04d.\n",
|
message4("Could not write HDSK%d Sector=%02d Track=%04d.",
|
||||||
selectedDisk, selectedSector, selectedTrack);
|
selectedDisk, selectedSector, selectedTrack);
|
||||||
}
|
}
|
||||||
return CPM_ERROR;
|
return CPM_ERROR;
|
||||||
|
@ -317,7 +319,7 @@ static int32 doWrite(void) {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ((uptr -> flags) & UNIT_HDSK_VERBOSE) {
|
if ((uptr -> flags) & UNIT_HDSK_VERBOSE) {
|
||||||
message4("Could not write to locked HDSK%d Sector=%02d Track=%04d.\n",
|
message4("Could not write to locked HDSK%d Sector=%02d Track=%04d.",
|
||||||
selectedDisk, selectedSector, selectedTrack);
|
selectedDisk, selectedSector, selectedTrack);
|
||||||
}
|
}
|
||||||
return CPM_ERROR;
|
return CPM_ERROR;
|
||||||
|
@ -334,7 +336,7 @@ static int32 hdsk_in(const int32 port) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
else if (hdsk_hasVerbose()) {
|
else if (hdsk_hasVerbose()) {
|
||||||
message4("Illegal IN command detected (port=%03xh, cmd=%d, pos=%d).\n",
|
message4("Illegal IN command detected (port=%03xh, cmd=%d, pos=%d).",
|
||||||
port, hdskLastCommand, hdskCommandPosition);
|
port, hdskLastCommand, hdskCommandPosition);
|
||||||
}
|
}
|
||||||
return CPM_OK;
|
return CPM_OK;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* gri_cpu.c: GRI-909 CPU simulator
|
/* gri_cpu.c: GRI-909 CPU simulator
|
||||||
|
|
||||||
Copyright (c) 2001-2003, Robert M. Supnik
|
Copyright (c) 2001-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* gri_defs.h: GRI-909 simulator definitions
|
/* gri_defs.h: GRI-909 simulator definitions
|
||||||
|
|
||||||
Copyright (c) 2001-2003, Robert M. Supnik
|
Copyright (c) 2001-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
To: Users
|
To: Users
|
||||||
From: Bob Supnik
|
From: Bob Supnik
|
||||||
Subj: GRI-909 Simulator Usage
|
Subj: GRI-909 Simulator Usage
|
||||||
Date: 20-Apr-2003
|
Date: 15-Feb-2004
|
||||||
|
|
||||||
COPYRIGHT NOTICE
|
COPYRIGHT NOTICE
|
||||||
|
|
||||||
The following copyright notice applies to both the SIMH source and binary:
|
The following copyright notice applies to both the SIMH source and binary:
|
||||||
|
|
||||||
Original code published in 1993-2003, written by Robert M Supnik
|
Original code published in 1993-2004, written by Robert M Supnik
|
||||||
Copyright (c) 1993-2003, Robert M Supnik
|
Copyright (c) 1993-2004, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -36,13 +36,19 @@ This memorandum documents the GRI-909 simulator.
|
||||||
|
|
||||||
1. Simulator Files
|
1. Simulator Files
|
||||||
|
|
||||||
sim/ sim_defs.h
|
sim/ scp.h
|
||||||
|
sim_console.h
|
||||||
|
sim_defs.h
|
||||||
|
sim_fio.h
|
||||||
sim_rev.h
|
sim_rev.h
|
||||||
sim_sock.h
|
sim_sock.h
|
||||||
|
sim_timer.h
|
||||||
sim_tmxr.h
|
sim_tmxr.h
|
||||||
scp.c
|
scp.c
|
||||||
scp_tty.c
|
sim_console.c
|
||||||
|
sim_fio.c
|
||||||
sim_sock.c
|
sim_sock.c
|
||||||
|
sim_timer.c
|
||||||
sim_tmxr.c
|
sim_tmxr.c
|
||||||
|
|
||||||
sim/gri/ gri_defs.h
|
sim/gri/ gri_defs.h
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* gri_sys.c: GRI-909 simulator interface
|
/* gri_sys.c: GRI-909 simulator interface
|
||||||
|
|
||||||
Copyright (c) 2001-2003, Robert M Supnik
|
Copyright (c) 2001-2004, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
cpu H316/H516 CPU
|
cpu H316/H516 CPU
|
||||||
|
|
||||||
|
04-Jan-04 RMS Removed unnecessary compare
|
||||||
31-Dec-03 RMS Fixed bug in cpu_set_hist
|
31-Dec-03 RMS Fixed bug in cpu_set_hist
|
||||||
24-Oct-03 RMS Added DMA/DMC support, instruction history
|
24-Oct-03 RMS Added DMA/DMC support, instruction history
|
||||||
30-Dec-01 RMS Added old PC queue
|
30-Dec-01 RMS Added old PC queue
|
||||||
|
@ -1317,7 +1318,7 @@ for (i = 0; dptr = sim_devices[i]; i++) { /* loop thru devices */
|
||||||
} /* end for */
|
} /* end for */
|
||||||
if (dibp->chan) { /* DMA/DMC? */
|
if (dibp->chan) { /* DMA/DMC? */
|
||||||
chan = dibp->chan - 1;
|
chan = dibp->chan - 1;
|
||||||
if ((chan >= 0) && (chan < DMC_V_DMC1) && (chan >= dma_nch)) {
|
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,
|
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);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* h316_defs.h: Honeywell 316/516 simulator definitions
|
/* h316_defs.h: Honeywell 316/516 simulator definitions
|
||||||
|
|
||||||
Copyright (c) 1999-2003, Robert M. Supnik
|
Copyright (c) 1999-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
To: Users
|
To: Users
|
||||||
From: Bob Supnik
|
From: Bob Supnik
|
||||||
Subj: H316 Simulator Usage
|
Subj: H316 Simulator Usage
|
||||||
Date: 15-Nov-2003
|
Date: 15-Feb-2004
|
||||||
|
|
||||||
COPYRIGHT NOTICE
|
COPYRIGHT NOTICE
|
||||||
|
|
||||||
The following copyright notice applies to both the SIMH source and binary:
|
The following copyright notice applies to both the SIMH source and binary:
|
||||||
|
|
||||||
Original code published in 1993-2003, written by Robert M Supnik
|
Original code published in 1993-2004, written by Robert M Supnik
|
||||||
Copyright (c) 1993-2003, Robert M Supnik
|
Copyright (c) 1993-2004, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -38,15 +38,21 @@ This memorandum documents the Honeywell 316/516 simulator.
|
||||||
|
|
||||||
The H316 requires the following files:
|
The H316 requires the following files:
|
||||||
|
|
||||||
sim/ sim_defs.h
|
sim/ scp.h
|
||||||
|
sim_console.h
|
||||||
|
sim_defs.h
|
||||||
|
sim_fio.h
|
||||||
sim_rev.h
|
sim_rev.h
|
||||||
sim_sock.h
|
sim_sock.h
|
||||||
sim_tape.h
|
sim_tape.h
|
||||||
|
sim_timer.h
|
||||||
sim_tmxr.h
|
sim_tmxr.h
|
||||||
scp.c
|
scp.c
|
||||||
scp_tty.c
|
sim_console.c
|
||||||
|
sim_fio.c
|
||||||
sim_sock.c
|
sim_sock.c
|
||||||
sim_tape.c
|
sim_tape.c
|
||||||
|
sim_timer.c
|
||||||
sim_tmxr.c
|
sim_tmxr.c
|
||||||
|
|
||||||
sim/h316/ h316_defs.h
|
sim/h316/ h316_defs.h
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* h316_dp.c: Honeywell 4623, 4651, 4720 disk simulator
|
/* h316_dp.c: Honeywell 4623, 4651, 4720 disk simulator
|
||||||
|
|
||||||
Copyright (c) 2003, Robert M. Supnik
|
Copyright (c) 2003-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* h316_fhd.c: H316/516 fixed head simulator
|
/* h316_fhd.c: H316/516 fixed head simulator
|
||||||
|
|
||||||
Copyright (c) 2003, Robert M. Supnik
|
Copyright (c) 2003-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
fhd 516-4400 fixed head disk
|
fhd 516-4400 fixed head disk
|
||||||
|
|
||||||
|
04-Jan-04 RMS Changed sim_fsize calling sequence
|
||||||
|
|
||||||
These head-per-track devices are buffered in memory, to minimize overhead.
|
These head-per-track devices are buffered in memory, to minimize overhead.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -402,14 +404,17 @@ t_stat fhd_attach (UNIT *uptr, char *cptr)
|
||||||
{
|
{
|
||||||
uint32 sz, sf;
|
uint32 sz, sf;
|
||||||
uint32 ds_bytes = FH_WDPSF * sizeof (int16);
|
uint32 ds_bytes = FH_WDPSF * sizeof (int16);
|
||||||
|
t_stat r;
|
||||||
|
|
||||||
if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize (cptr))) {
|
r = attach_unit (uptr, cptr);
|
||||||
|
if (r != SCPE_OK) return r;
|
||||||
|
if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize (uptr->fileref))) {
|
||||||
sf = (sz + ds_bytes - 1) / ds_bytes;
|
sf = (sz + ds_bytes - 1) / ds_bytes;
|
||||||
if (sf >= FH_NUMSF) sf = FH_NUMSF - 1;
|
if (sf >= FH_NUMSF) sf = FH_NUMSF - 1;
|
||||||
uptr->flags = (uptr->flags & ~UNIT_SF) |
|
uptr->flags = (uptr->flags & ~UNIT_SF) |
|
||||||
(sf << UNIT_V_SF); }
|
(sf << UNIT_V_SF); }
|
||||||
uptr->capac = UNIT_GETSF (uptr->flags) * FH_WDPSF;
|
uptr->capac = UNIT_GETSF (uptr->flags) * FH_WDPSF;
|
||||||
return attach_unit (uptr, cptr);
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set size routine */
|
/* Set size routine */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* h316_lp.c: Honeywell 316/516 line printer
|
/* h316_lp.c: Honeywell 316/516 line printer
|
||||||
|
|
||||||
Copyright (c) 1999-2003, Robert M. Supnik
|
Copyright (c) 1999-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* h316_mt.c: H316/516 magnetic tape simulator
|
/* h316_mt.c: H316/516 magnetic tape simulator
|
||||||
|
|
||||||
Copyright (c) 2003, Robert M. Supnik
|
Copyright (c) 2003-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* h316_stddev.c: Honeywell 316/516 standard devices
|
/* h316_stddev.c: Honeywell 316/516 standard devices
|
||||||
|
|
||||||
Copyright (c) 1999-2003, Robert M. Supnik
|
Copyright (c) 1999-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* h316_sys.c: Honeywell 316/516 simulator interface
|
/* h316_sys.c: Honeywell 316/516 simulator interface
|
||||||
|
|
||||||
Copyright (c) 1999-2003, Robert M Supnik
|
Copyright (c) 1999-2004, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp2100_cpu.c: HP 2100 CPU simulator
|
/* hp2100_cpu.c: HP 2100 CPU simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2003, Robert M. Supnik
|
Copyright (c) 1993-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp2100_defs.h: HP 2100 simulator definitions
|
/* hp2100_defs.h: HP 2100 simulator definitions
|
||||||
|
|
||||||
Copyright (c) 1993-2003, Robert M. Supnik
|
Copyright (c) 1993-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
To: Users
|
To: Users
|
||||||
From: Bob Supnik
|
From: Bob Supnik
|
||||||
Subj: HP2100 Simulator Usage
|
Subj: HP2100 Simulator Usage
|
||||||
Date: 15-Jul-2003
|
Date: 15-Feb-2004
|
||||||
|
|
||||||
COPYRIGHT NOTICE
|
COPYRIGHT NOTICE
|
||||||
|
|
||||||
The following copyright notice applies to both the SIMH source and binary:
|
The following copyright notice applies to both the SIMH source and binary:
|
||||||
|
|
||||||
Original code published in 1993-2002, written by Robert M Supnik
|
Original code published in 1993-2004, written by Robert M Supnik
|
||||||
Copyright (c) 1993-2003, Robert M Supnik
|
Copyright (c) 1993-2004, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -36,15 +36,21 @@ This memorandum documents the HP 2100 simulator.
|
||||||
|
|
||||||
1. Simulator Files
|
1. Simulator Files
|
||||||
|
|
||||||
sim/ sim_defs.h
|
sim/ scp.h
|
||||||
|
sim_console.h
|
||||||
|
sim_defs.h
|
||||||
|
sim_fio.h
|
||||||
sim_rev.h
|
sim_rev.h
|
||||||
sim_sock.h
|
sim_sock.h
|
||||||
sim_tape.h
|
sim_tape.h
|
||||||
|
sim_timer.h
|
||||||
sim_tmxr.h
|
sim_tmxr.h
|
||||||
scp.c
|
scp.c
|
||||||
scp_tty.c
|
sim_console.c
|
||||||
|
sim_fio.c
|
||||||
sim_sock.c
|
sim_sock.c
|
||||||
sim_tape.c
|
sim_tape.c
|
||||||
|
sim_timer.c
|
||||||
sim_tmxr.c
|
sim_tmxr.c
|
||||||
|
|
||||||
sim/hp2100/ hp2100_defs.h
|
sim/hp2100/ hp2100_defs.h
|
||||||
|
@ -450,7 +456,13 @@ automatically to upper case. In 7B mode, input and output characters
|
||||||
are masked to 7 bits. In 8B mode, characters are not modified. The
|
are masked to 7 bits. In 8B mode, characters are not modified. The
|
||||||
default mode is UC. In addition, each line supports the DATASET option.
|
default mode is UC. In addition, each line supports the DATASET option.
|
||||||
DATASET, when set, enables modem control. The default settings are UC
|
DATASET, when set, enables modem control. The default settings are UC
|
||||||
mode and DATASET disabled.
|
mode and DATASET disabled. Finally, each line supports output logging.
|
||||||
|
The SET MUXLn LOG command enables logging on a line:
|
||||||
|
|
||||||
|
SET MUXLn LOG=filename log output of line n to filename
|
||||||
|
|
||||||
|
The SET MUXLn NOLOG command disables logging and closes the open log
|
||||||
|
file, if any.
|
||||||
|
|
||||||
The modem controls model a simplified Bell 103A dataset with just four
|
The modem controls model a simplified Bell 103A dataset with just four
|
||||||
lines: data terminal ready and request to send from the computer to the
|
lines: data terminal ready and request to send from the computer to the
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp2100_dp.c: HP 2100 12557A/13210A disk simulator
|
/* hp2100_dp.c: HP 2100 12557A/13210A disk simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2003, Robert M. Supnik
|
Copyright (c) 1993-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp2100_dq.c: HP 2100 12565A disk simulator
|
/* hp2100_dq.c: HP 2100 12565A disk simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2003, Bill McDermith
|
Copyright (c) 1993-2004, Bill McDermith
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp2100_dr.c: HP 2100 12606B/12610B fixed head disk/drum simulator
|
/* hp2100_dr.c: HP 2100 12606B/12610B fixed head disk/drum simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2003, Robert M. Supnik
|
Copyright (c) 1993-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp2100_fp.c: HP 2100 floating point instructions
|
/* hp2100_fp.c: HP 2100 floating point instructions
|
||||||
|
|
||||||
Copyright (c) 2002-2003, Robert M. Supnik
|
Copyright (c) 2002-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp2100_ipl.c: HP 2000 interprocessor link simulator
|
/* hp2100_ipl.c: HP 2000 interprocessor link simulator
|
||||||
|
|
||||||
Copyright (c) 2002-2003, Robert M Supnik
|
Copyright (c) 2002-2004, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp2100_lps.c: HP 2100 12653A line printer simulator
|
/* hp2100_lps.c: HP 2100 12653A line printer simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2003, Robert M. Supnik
|
Copyright (c) 1993-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp2100_lpt.c: HP 2100 12845A line printer simulator
|
/* hp2100_lpt.c: HP 2100 12845A line printer simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2003, Robert M. Supnik
|
Copyright (c) 1993-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp2100_ms.c: HP 2100 13181A/13183A magnetic tape simulator
|
/* hp2100_ms.c: HP 2100 13181A/13183A magnetic tape simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2003, Robert M. Supnik
|
Copyright (c) 1993-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp2100_mt.c: HP 2100 12559A magnetic tape simulator
|
/* hp2100_mt.c: HP 2100 12559A magnetic tape simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2003, Robert M. Supnik
|
Copyright (c) 1993-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp2100_mux.c: HP 2100 12920A terminal multiplexor simulator
|
/* hp2100_mux.c: HP 2100 12920A terminal multiplexor simulator
|
||||||
|
|
||||||
Copyright (c) 2002-2003, Robert M Supnik
|
Copyright (c) 2002-2004, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
mux,muxl,muxc 12920A terminal multiplexor
|
mux,muxl,muxc 12920A terminal multiplexor
|
||||||
|
|
||||||
|
05-Jan-04 RMS Revised for tmxr library changes
|
||||||
21-Dec-03 RMS Added invalid character screening for TSB (from Mike Gemeny)
|
21-Dec-03 RMS Added invalid character screening for TSB (from Mike Gemeny)
|
||||||
09-May-03 RMS Added network device flag
|
09-May-03 RMS Added network device flag
|
||||||
01-Nov-02 RMS Added 7B/8B support
|
01-Nov-02 RMS Added 7B/8B support
|
||||||
|
@ -152,7 +153,7 @@ uint32 muxc_chan = 0; /* ctrl chan */
|
||||||
uint32 muxc_scan = 0; /* ctrl scan */
|
uint32 muxc_scan = 0; /* ctrl scan */
|
||||||
|
|
||||||
TMLN mux_ldsc[MUX_LINES] = { 0 }; /* line descriptors */
|
TMLN mux_ldsc[MUX_LINES] = { 0 }; /* line descriptors */
|
||||||
TMXR mux_desc = { MUX_LINES, 0, 0, NULL }; /* mux descriptor */
|
TMXR mux_desc = { MUX_LINES, 0, 0, mux_ldsc }; /* mux descriptor */
|
||||||
|
|
||||||
DEVICE muxl_dev, muxu_dev, muxc_dev;
|
DEVICE muxl_dev, muxu_dev, muxc_dev;
|
||||||
int32 muxlio (int32 inst, int32 IR, int32 dat);
|
int32 muxlio (int32 inst, int32 IR, int32 dat);
|
||||||
|
@ -268,6 +269,10 @@ MTAB muxl_mod[] = {
|
||||||
{ UNIT_UC+UNIT_8B, UNIT_8B, "8b", "8B", NULL },
|
{ UNIT_UC+UNIT_8B, UNIT_8B, "8b", "8B", NULL },
|
||||||
{ UNIT_MDM, 0, "no dataset", "NODATASET", NULL },
|
{ UNIT_MDM, 0, "no dataset", "NODATASET", NULL },
|
||||||
{ UNIT_MDM, UNIT_MDM, "dataset", "DATASET", NULL },
|
{ UNIT_MDM, UNIT_MDM, "dataset", "DATASET", NULL },
|
||||||
|
{ MTAB_XTD|MTAB_VUN|MTAB_NC, 0, "LOG", "LOG",
|
||||||
|
&tmxr_set_log, &tmxr_show_log, &mux_desc },
|
||||||
|
{ MTAB_XTD|MTAB_VUN|MTAB_NC, 0, NULL, "NOLOG",
|
||||||
|
&tmxr_set_nolog, NULL, &mux_desc },
|
||||||
{ MTAB_XTD|MTAB_VDV, 1, "DEVNO", "DEVNO",
|
{ MTAB_XTD|MTAB_VDV, 1, "DEVNO", "DEVNO",
|
||||||
&hp_setdev, &hp_showdev, &muxl_dev },
|
&hp_setdev, &hp_showdev, &muxl_dev },
|
||||||
{ 0 } };
|
{ 0 } };
|
||||||
|
@ -433,7 +438,7 @@ case ioOTX: /* output */
|
||||||
(muxc_ota[ln] & ~OTC_C1) | (dat & OTC_C1);
|
(muxc_ota[ln] & ~OTC_C1) | (dat & OTC_C1);
|
||||||
if ((muxl_unit[ln].flags & UNIT_MDM) && /* modem ctrl? */
|
if ((muxl_unit[ln].flags & UNIT_MDM) && /* modem ctrl? */
|
||||||
(old & DTR) && !(muxc_ota[ln] & DTR)) { /* DTR drop? */
|
(old & DTR) && !(muxc_ota[ln] & DTR)) { /* DTR drop? */
|
||||||
tmxr_msg (mux_ldsc[ln].conn, "\r\nLine hangup\r\n");
|
tmxr_linemsg (&mux_ldsc[ln], "\r\nLine hangup\r\n");
|
||||||
tmxr_reset_ln (&mux_ldsc[ln]); /* reset line */
|
tmxr_reset_ln (&mux_ldsc[ln]); /* reset line */
|
||||||
muxc_lia[ln] = 0; } /* dataset off */
|
muxc_lia[ln] = 0; } /* dataset off */
|
||||||
} /* end update */
|
} /* end update */
|
||||||
|
@ -645,9 +650,7 @@ if (muxu_unit.flags & UNIT_ATT) { /* master att? */
|
||||||
t = sim_rtcn_init (muxu_unit.wait, TMR_MUX);
|
t = sim_rtcn_init (muxu_unit.wait, TMR_MUX);
|
||||||
sim_activate (&muxu_unit, t); } } /* activate */
|
sim_activate (&muxu_unit, t); } } /* activate */
|
||||||
else sim_cancel (&muxu_unit); /* else stop */
|
else sim_cancel (&muxu_unit); /* else stop */
|
||||||
for (i = 0; i < MUX_LINES; i++) {
|
for (i = 0; i < MUX_LINES; i++) mux_reset_ln (i);
|
||||||
mux_desc.ldsc[i] = &mux_ldsc[i];
|
|
||||||
mux_reset_ln (i); }
|
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp2100_sys.c: HP 2100 simulator interface
|
/* hp2100_sys.c: HP 2100 simulator interface
|
||||||
|
|
||||||
Copyright (c) 1993-2003, Robert M. Supnik
|
Copyright (c) 1993-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* i1401_cd.c: IBM 1402 card reader/punch
|
/* i1401_cd.c: IBM 1402 card reader/punch
|
||||||
|
|
||||||
Copyright (c) 1993-2003, Robert M. Supnik
|
Copyright (c) 1993-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* i1401_cpu.c: IBM 1401 CPU simulator
|
/* i1401_cpu.c: IBM 1401 CPU simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2003, Robert M. Supnik
|
Copyright (c) 1993-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* i1401_dat.h: IBM 1401 character conversion tables
|
/* i1401_dat.h: IBM 1401 character conversion tables
|
||||||
|
|
||||||
Copyright (c) 1993-2003, Robert M. Supnik
|
Copyright (c) 1993-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* i1401_defs.h: IBM 1401 simulator definitions
|
/* i1401_defs.h: IBM 1401 simulator definitions
|
||||||
|
|
||||||
Copyright (c) 1993-2003, Robert M. Supnik
|
Copyright (c) 1993-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
To: Users
|
To: Users
|
||||||
From: Bob Supnik
|
From: Bob Supnik
|
||||||
Subj: IBM 1401 Simulator Usage
|
Subj: IBM 1401 Simulator Usage
|
||||||
Date: 15-Jul-2003
|
Date: 15-Feb-2004
|
||||||
|
|
||||||
COPYRIGHT NOTICE
|
COPYRIGHT NOTICE
|
||||||
|
|
||||||
The following copyright notice applies to both the SIMH source and binary:
|
The following copyright notice applies to both the SIMH source and binary:
|
||||||
|
|
||||||
Original code published in 1993-2003, written by Robert M Supnik
|
Original code published in 1993-2004, written by Robert M Supnik
|
||||||
Copyright (c) 1993-2003, Robert M Supnik
|
Copyright (c) 1993-2004, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -36,15 +36,21 @@ This memorandum documents the IBM 1401 simulator.
|
||||||
|
|
||||||
1. Simulator Files
|
1. Simulator Files
|
||||||
|
|
||||||
sim/ sim_defs.h
|
sim/ scp.h
|
||||||
|
sim_console.h
|
||||||
|
sim_defs.h
|
||||||
|
sim_fio.h
|
||||||
sim_rev.h
|
sim_rev.h
|
||||||
sim_sock.h
|
sim_sock.h
|
||||||
sim_tape.h
|
sim_tape.h
|
||||||
|
sim_timer.h
|
||||||
sim_tmxr.h
|
sim_tmxr.h
|
||||||
scp.c
|
scp.c
|
||||||
scp_tty.c
|
sim_console.c
|
||||||
|
sim_fio.c
|
||||||
sim_sock.c
|
sim_sock.c
|
||||||
sim_tape.c
|
sim_tape.c
|
||||||
|
sim_timer.c
|
||||||
sim_tmxr.c
|
sim_tmxr.c
|
||||||
|
|
||||||
sim/i1401/ i1401_defs.h
|
sim/i1401/ i1401_defs.h
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* i1401_dp.c: IBM 1311 disk simulator
|
/* i1401_dp.c: IBM 1311 disk simulator
|
||||||
|
|
||||||
Copyright (c) 2002-2003, Robert M. Supnik
|
Copyright (c) 2002-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* i1401_iq.c: IBM 1407 inquiry terminal
|
/* i1401_iq.c: IBM 1407 inquiry terminal
|
||||||
|
|
||||||
Copyright (c) 1993-2003, Robert M. Supnik
|
Copyright (c) 1993-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* i1401_lp.c: IBM 1403 line printer simulator
|
/* i1401_lp.c: IBM 1403 line printer simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2003, Robert M. Supnik
|
Copyright (c) 1993-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* i1401_mt.c: IBM 1401 magnetic tape simulator
|
/* i1401_mt.c: IBM 1401 magnetic tape simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2003, Robert M. Supnik
|
Copyright (c) 1993-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* i1401_sys.c: IBM 1401 simulator interface
|
/* i1401_sys.c: IBM 1401 simulator interface
|
||||||
|
|
||||||
Copyright (c) 1993-2003, Robert M. Supnik
|
Copyright (c) 1993-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* i1620_cd.c: IBM 1622 card reader/punch
|
/* i1620_cd.c: IBM 1622 card reader/punch
|
||||||
|
|
||||||
Copyright (c) 2002-2003, Robert M. Supnik
|
Copyright (c) 2002-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* i1620_cpu.c: IBM 1620 CPU simulator
|
/* i1620_cpu.c: IBM 1620 CPU simulator
|
||||||
|
|
||||||
Copyright (c) 2002-2003, Robert M. Supnik
|
Copyright (c) 2002-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -26,6 +26,7 @@
|
||||||
This CPU module incorporates code and comments from the 1620 simulator by
|
This CPU module incorporates code and comments from the 1620 simulator by
|
||||||
Geoff Kuenning, with his permission.
|
Geoff Kuenning, with his permission.
|
||||||
|
|
||||||
|
26-Mar-04 RMS Fixed warnings with -std=c99
|
||||||
02-Nov-03 RMS Fixed bug in branch digit (found by Dave Babcock)
|
02-Nov-03 RMS Fixed bug in branch digit (found by Dave Babcock)
|
||||||
21-Aug-03 RMS Fixed bug in immediate index add (found by Michael Short)
|
21-Aug-03 RMS Fixed bug in immediate index add (found by Michael Short)
|
||||||
25-Apr-03 RMS Changed t_addr to uint32 throughout
|
25-Apr-03 RMS Changed t_addr to uint32 throughout
|
||||||
|
@ -153,15 +154,15 @@ t_stat xor_field (uint32 d, uint32 s);
|
||||||
t_stat com_field (uint32 d, uint32 s);
|
t_stat com_field (uint32 d, uint32 s);
|
||||||
void upd_ind (void);
|
void upd_ind (void);
|
||||||
|
|
||||||
extern tty (uint32 op, uint32 pa, uint32 f0, uint32 f1);
|
extern t_stat tty (uint32 op, uint32 pa, uint32 f0, uint32 f1);
|
||||||
extern ptp (uint32 op, uint32 pa, uint32 f0, uint32 f1);
|
extern t_stat ptp (uint32 op, uint32 pa, uint32 f0, uint32 f1);
|
||||||
extern ptr (uint32 op, uint32 pa, uint32 f0, uint32 f1);
|
extern t_stat ptr (uint32 op, uint32 pa, uint32 f0, uint32 f1);
|
||||||
extern cdp (uint32 op, uint32 pa, uint32 f0, uint32 f1);
|
extern t_stat cdp (uint32 op, uint32 pa, uint32 f0, uint32 f1);
|
||||||
extern cdr (uint32 op, uint32 pa, uint32 f0, uint32 f1);
|
extern t_stat cdr (uint32 op, uint32 pa, uint32 f0, uint32 f1);
|
||||||
extern dp (uint32 op, uint32 pa, uint32 f0, uint32 f1);
|
extern t_stat dp (uint32 op, uint32 pa, uint32 f0, uint32 f1);
|
||||||
extern lpt (uint32 op, uint32 pa, uint32 f0, uint32 f1);
|
extern t_stat lpt (uint32 op, uint32 pa, uint32 f0, uint32 f1);
|
||||||
extern btp (uint32 op, uint32 pa, uint32 f0, uint32 f1);
|
extern t_stat btp (uint32 op, uint32 pa, uint32 f0, uint32 f1);
|
||||||
extern btr (uint32 op, uint32 pa, uint32 f0, uint32 f1);
|
extern t_stat btr (uint32 op, uint32 pa, uint32 f0, uint32 f1);
|
||||||
|
|
||||||
extern t_stat fp_add (uint32 d, uint32 s, t_bool sub);
|
extern t_stat fp_add (uint32 d, uint32 s, t_bool sub);
|
||||||
extern t_stat fp_mul (uint32 d, uint32 s);
|
extern t_stat fp_mul (uint32 d, uint32 s);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* i1620_defs.h: IBM 1620 simulator definitions
|
/* i1620_defs.h: IBM 1620 simulator definitions
|
||||||
|
|
||||||
Copyright (c) 2002-2003, Robert M. Supnik
|
Copyright (c) 2002-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
To: Users
|
To: Users
|
||||||
From: Bob Supnik
|
From: Bob Supnik
|
||||||
Subj: IBM 1620 Simulator Usage
|
Subj: IBM 1620 Simulator Usage
|
||||||
Date: 15-Apr-2003
|
Date: 15-Feb-2004
|
||||||
|
|
||||||
COPYRIGHT NOTICE
|
COPYRIGHT NOTICE
|
||||||
|
|
||||||
The following copyright notice applies to both the SIMH source and binary:
|
The following copyright notice applies to both the SIMH source and binary:
|
||||||
|
|
||||||
Original code published in 1993-2003, written by Robert M Supnik
|
Original code published in 1993-2004, written by Robert M Supnik
|
||||||
Copyright (c) 1993-2003, Robert M Supnik
|
Copyright (c) 1993-2004, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -36,13 +36,19 @@ Geoff Kuenning's 1620 simulator, which is used by permission.
|
||||||
|
|
||||||
1. Simulator Files
|
1. Simulator Files
|
||||||
|
|
||||||
sim/ sim_defs.h
|
sim/ scp.h
|
||||||
|
sim_console.h
|
||||||
|
sim_defs.h
|
||||||
|
sim_fio.h
|
||||||
sim_rev.h
|
sim_rev.h
|
||||||
sim_sock.h
|
sim_sock.h
|
||||||
|
sim_timer.h
|
||||||
sim_tmxr.h
|
sim_tmxr.h
|
||||||
scp.c
|
scp.c
|
||||||
scp_tty.c
|
sim_console.c
|
||||||
|
sim_fio.c
|
||||||
sim_sock.c
|
sim_sock.c
|
||||||
|
sim_timer.c
|
||||||
sim_tmxr.c
|
sim_tmxr.c
|
||||||
|
|
||||||
sim/i1620/ i1620_defs.h
|
sim/i1620/ i1620_defs.h
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* i1620_dp.c: IBM 1311 disk simulator
|
/* i1620_dp.c: IBM 1311 disk simulator
|
||||||
|
|
||||||
Copyright (c) 2002-2003, Robert M. Supnik
|
Copyright (c) 2002-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* i1620_fp.c: IBM 1620 floating point simulator
|
/* i1620_fp.c: IBM 1620 floating point simulator
|
||||||
|
|
||||||
Copyright (c) 2002-2003, Robert M. Supnik
|
Copyright (c) 2002-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* i1620_lp.c: IBM 1443 line printer simulator
|
/* i1620_lp.c: IBM 1443 line printer simulator
|
||||||
|
|
||||||
Copyright (c) 2002-2003, Robert M. Supnik
|
Copyright (c) 2002-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* i1620_pt.c: IBM 1621/1624 paper tape reader/punch simulator
|
/* i1620_pt.c: IBM 1621/1624 paper tape reader/punch simulator
|
||||||
|
|
||||||
Copyright (c) 2002-2003, Robert M Supnik
|
Copyright (c) 2002-2004, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* i1620_sys.c: IBM 1620 simulator interface
|
/* i1620_sys.c: IBM 1620 simulator interface
|
||||||
|
|
||||||
Copyright (c) 2002-2003, Robert M. Supnik
|
Copyright (c) 2002-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* i1620_tty.c: IBM 1620 typewriter
|
/* i1620_tty.c: IBM 1620 typewriter
|
||||||
|
|
||||||
Copyright (c) 2002-2003, Robert M. Supnik
|
Copyright (c) 2002-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -141,7 +141,7 @@ extern CTAB *sim_vm_cmd;
|
||||||
#define MAX_EXTRA_COMMANDS 10
|
#define MAX_EXTRA_COMMANDS 10
|
||||||
CTAB x_cmds[MAX_EXTRA_COMMANDS];
|
CTAB x_cmds[MAX_EXTRA_COMMANDS];
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
# define CRLF "\r\n"
|
# define CRLF "\r\n"
|
||||||
#else
|
#else
|
||||||
# define CRLF "\n"
|
# define CRLF "\n"
|
||||||
|
@ -1160,7 +1160,7 @@ 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_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw)
|
||||||
{
|
{
|
||||||
if (addr < MEMSIZE) {
|
if (addr < MEMSIZE) {
|
||||||
M[addr] = val & 0xFFFF;
|
M[addr] = (uint16) (val & 0xFFFF);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
return SCPE_NXM;
|
return SCPE_NXM;
|
||||||
|
@ -1476,7 +1476,7 @@ static t_stat cpu_attach (UNIT *uptr, char *cptr)
|
||||||
PSYMENTRY n, prv, s;
|
PSYMENTRY n, prv, s;
|
||||||
FILE *fd;
|
FILE *fd;
|
||||||
|
|
||||||
unlink(cptr); // delete old log file, if present
|
remove(cptr); // delete old log file, if present
|
||||||
new_log = TRUE;
|
new_log = TRUE;
|
||||||
log_fac = sim_switches & SWMASK ('F'); // display the FAC and the ACC/EXT as fixed point.
|
log_fac = sim_switches & SWMASK ('F'); // display the FAC and the ACC/EXT as fixed point.
|
||||||
|
|
||||||
|
@ -1565,16 +1565,16 @@ static void trace_instruction (void)
|
||||||
fac = 1.f;
|
fac = 1.f;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ((sign = mant & 0x80000000))
|
if ((sign = mant & 0x80000000) != 0)
|
||||||
mant = -mant;
|
mant = -mant;
|
||||||
fac = (float) mant * ((float) 1./ (float) (unsigned long) 0x80000000);
|
fac = (float) mant * ((float) 1./ (float) (unsigned long) 0x80000000);
|
||||||
}
|
}
|
||||||
sprintf(fltstr, "%c%.5f ", sign ? '-' : ' ', fac);
|
sprintf(fltstr, "%c%.5f ", sign ? '-' : ' ', fac);
|
||||||
|
|
||||||
if (BETWEEN(M[3], 0x300, MEMSIZE-128)) {
|
if (BETWEEN(M[3], 0x300, MEMSIZE-128)) {
|
||||||
exp = (M[M[3]+125] & 0xFF) - 128;
|
exp = (short) ((M[M[3]+125] & 0xFF) - 128);
|
||||||
mant = (M[M[3]+126] << 8) | ((M[M[3]+127] >> 8) & 0xFF);
|
mant = (M[M[3]+126] << 8) | ((M[M[3]+127] >> 8) & 0xFF);
|
||||||
if ((sign = (mant & 0x00800000)))
|
if ((sign = (mant & 0x00800000)) != 0)
|
||||||
mant = (-mant) & 0x00FFFFFF;
|
mant = (-mant) & 0x00FFFFFF;
|
||||||
|
|
||||||
fac = (float) mant * ((float) 1. / (float) 0x00800000);
|
fac = (float) mant * ((float) 1. / (float) 0x00800000);
|
||||||
|
@ -1660,7 +1660,7 @@ void debug_print (char *fmt, ...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1668,7 +1668,7 @@ void debug_print (char *fmt, ...)
|
||||||
|
|
||||||
static t_stat view_cmd (int flag, char *cptr)
|
static t_stat view_cmd (int flag, char *cptr)
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
char cmdline[256];
|
char cmdline[256];
|
||||||
|
|
||||||
sprintf(cmdline, "notepad %s", cptr);
|
sprintf(cmdline, "notepad %s", cptr);
|
||||||
|
@ -1713,7 +1713,7 @@ static void cgi_clockfail (void)
|
||||||
// cgi_start_timer - OS dependent routine to set things up so that
|
// cgi_start_timer - OS dependent routine to set things up so that
|
||||||
// cgi_timeout() will be called after cgi_maxsec seconds.
|
// cgi_timeout() will be called after cgi_maxsec seconds.
|
||||||
|
|
||||||
#if defined(WIN32)
|
#if defined(_WIN32)
|
||||||
static DWORD WINAPI cgi_timer_thread (LPVOID arg)
|
static DWORD WINAPI cgi_timer_thread (LPVOID arg)
|
||||||
{
|
{
|
||||||
Sleep(cgi_maxsec*1000); // timer thread -- wait, then call timeout routine
|
Sleep(cgi_maxsec*1000); // timer thread -- wait, then call timeout routine
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
#include "ibm1130_defs.h"
|
#include "ibm1130_defs.h"
|
||||||
#include "ibm1130_fmt.h"
|
#include "ibm1130_fmt.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
# include <io.h> // Microsoft puts definition of mktemp into io.h rather than stdlib.h
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ibm1130_cr.c: IBM 1130 1442 Card Reader simulator
|
/* ibm1130_cr.c: IBM 1130 1442 Card Reader simulator
|
||||||
|
|
||||||
Based on the SIMH package written by Robert M Supnik
|
Based on the SIMH package written by Robert M Supnik
|
||||||
|
@ -1187,7 +1191,7 @@ static void checkdeck (void)
|
||||||
|
|
||||||
static t_bool nextdeck (void)
|
static t_bool nextdeck (void)
|
||||||
{
|
{
|
||||||
char buf[200], tmpbuf[200], *fname, *tn, *c, quote, *mode;
|
char buf[200], tmpbuf[200], *fname, *c, quote, *mode;
|
||||||
int code;
|
int code;
|
||||||
long fpos;
|
long fpos;
|
||||||
|
|
||||||
|
@ -1204,7 +1208,7 @@ static t_bool nextdeck (void)
|
||||||
cr_unit.fileref = NULL;
|
cr_unit.fileref = NULL;
|
||||||
|
|
||||||
if (cr_unit.flags & UNIT_SCRATCH) {
|
if (cr_unit.flags & UNIT_SCRATCH) {
|
||||||
unlink(tempfile);
|
remove(tempfile);
|
||||||
CLRBIT(cr_unit.flags, UNIT_SCRATCH);
|
CLRBIT(cr_unit.flags, UNIT_SCRATCH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1229,8 +1233,39 @@ static t_bool nextdeck (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf[0] == '!') { /* literal text line, make a temporary file */
|
if (buf[0] == '!') { /* literal text line, make a temporary file */
|
||||||
if (*tempfile == '\0') {
|
|
||||||
if ((tn = tempnam(".", "1130")) == NULL) {
|
#if defined (__GNUC__) && !defined (_WIN32) // GCC complains about mktemp & always provides mkstemp
|
||||||
|
|
||||||
|
if (*tempfile == '\0') { // first time, open guaranteed-unique file
|
||||||
|
int fh;
|
||||||
|
|
||||||
|
strcpy(tempfile, "tempXXXXXX"); // get modifiable copy of name template
|
||||||
|
|
||||||
|
if ((fh = mkstemp(tempfile)) == -1) { // open file. Actual name is set by side effect
|
||||||
|
printf("Cannot create temporary deck file\n");
|
||||||
|
break_simulation(STOP_DECK_BREAK);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// get FILE * from the file handle
|
||||||
|
if ((cr_unit.fileref = fdopen(fh, "w+b")) == NULL) {
|
||||||
|
printf("Cannot use temporary deck file %s\n", tempfile);
|
||||||
|
break_simulation(STOP_DECK_BREAK);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { // on later opens, just reuse the old name
|
||||||
|
if ((cr_unit.fileref = fopen(tempfile, "w+b")) == NULL) {
|
||||||
|
printf("Cannot create temporary file %s\n", tempfile);
|
||||||
|
break_simulation(STOP_DECK_BREAK);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else // ANSI standard C always provides mktemp
|
||||||
|
|
||||||
|
if (*tempfile == '\0') { // first time, construct unique name
|
||||||
|
char *tn;
|
||||||
|
|
||||||
|
if ((tn = mktemp("crXXXXXX")) == NULL) {
|
||||||
printf("Cannot create temporary card file name\n");
|
printf("Cannot create temporary card file name\n");
|
||||||
break_simulation(STOP_DECK_BREAK);
|
break_simulation(STOP_DECK_BREAK);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1238,12 +1273,13 @@ static t_bool nextdeck (void)
|
||||||
strcpy(tempfile, tn);
|
strcpy(tempfile, tn);
|
||||||
strcat(tempfile, ".tmp");
|
strcat(tempfile, ".tmp");
|
||||||
}
|
}
|
||||||
|
// (re)create file
|
||||||
if ((cr_unit.fileref = fopen(tempfile, "wb+")) == NULL) {
|
if ((cr_unit.fileref = fopen(tempfile, "w+b")) == NULL) {
|
||||||
printf("Cannot create temporary file %s\n", tempfile);
|
printf("Cannot create temporary file %s\n", tempfile);
|
||||||
break_simulation(STOP_DECK_BREAK);
|
break_simulation(STOP_DECK_BREAK);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
SETBIT(cr_unit.flags, UNIT_SCRATCH);
|
SETBIT(cr_unit.flags, UNIT_SCRATCH);
|
||||||
|
|
||||||
|
@ -1560,7 +1596,7 @@ t_stat cr_detach (UNIT *uptr)
|
||||||
fclose(cr_unit.fileref);
|
fclose(cr_unit.fileref);
|
||||||
|
|
||||||
if (cr_unit.flags & UNIT_SCRATCH) {
|
if (cr_unit.flags & UNIT_SCRATCH) {
|
||||||
unlink(tempfile);
|
remove(tempfile);
|
||||||
CLRBIT(cr_unit.flags, UNIT_SCRATCH);
|
CLRBIT(cr_unit.flags, UNIT_SCRATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1677,7 +1713,7 @@ void xio_1142_card (int32 addr, int32 func, int32 modify)
|
||||||
{
|
{
|
||||||
char msg[80];
|
char msg[80];
|
||||||
int ch;
|
int ch;
|
||||||
int16 wd;
|
uint16 wd;
|
||||||
t_bool lastcard;
|
t_bool lastcard;
|
||||||
|
|
||||||
switch (func) {
|
switch (func) {
|
||||||
|
@ -1763,7 +1799,7 @@ void xio_1142_card (int32 addr, int32 func, int32 modify)
|
||||||
cp_unit.COLUMN = 81;
|
cp_unit.COLUMN = 81;
|
||||||
}
|
}
|
||||||
else if (cp_unit.COLUMN < 80) {
|
else if (cp_unit.COLUMN < 80) {
|
||||||
wd = ReadW(addr); /* store one word to punch buffer */
|
wd = (uint16) ReadW(addr); /* store one word to punch buffer */
|
||||||
punchstation[cp_unit.COLUMN] = wd & 0xFFF0;
|
punchstation[cp_unit.COLUMN] = wd & 0xFFF0;
|
||||||
if (wd & 0x0008) /* mark this as last column to be punched */
|
if (wd & 0x0008) /* mark this as last column to be punched */
|
||||||
SETBIT(cp_unit.flags, UNIT_LASTPUNCH);
|
SETBIT(cp_unit.flags, UNIT_LASTPUNCH);
|
||||||
|
@ -2052,8 +2088,7 @@ char response_byte;
|
||||||
|
|
||||||
static DWORD CALLBACK pcr_thread (LPVOID arg)
|
static DWORD CALLBACK pcr_thread (LPVOID arg)
|
||||||
{
|
{
|
||||||
DWORD event;
|
DWORD event, nrcvd, nread;
|
||||||
long nrcvd, nread;
|
|
||||||
HANDLE objs[4];
|
HANDLE objs[4];
|
||||||
BOOL pick_queued = FALSE, reset_queued = FALSE;
|
BOOL pick_queued = FALSE, reset_queued = FALSE;
|
||||||
|
|
||||||
|
@ -2172,10 +2207,10 @@ static DWORD CALLBACK pcr_thread (LPVOID arg)
|
||||||
printf((nrcvd <= 0) ? "PCR: NO RESP!\n" : "PCR: GOT %d BYTES\n", nrcvd);
|
printf((nrcvd <= 0) ? "PCR: NO RESP!\n" : "PCR: GOT %d BYTES\n", nrcvd);
|
||||||
|
|
||||||
if (nrcvd > 0) {
|
if (nrcvd > 0) {
|
||||||
pcr_nleft -= nrcvd;
|
pcr_nleft -= (int) nrcvd;
|
||||||
|
|
||||||
begin_pcr_critical_section();
|
begin_pcr_critical_section();
|
||||||
pcr_nready += nrcvd;
|
pcr_nready += (int) nrcvd;
|
||||||
end_pcr_critical_section();
|
end_pcr_critical_section();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2210,7 +2245,7 @@ static char lastcmd = '?';
|
||||||
|
|
||||||
static void pcr_cmd (char cmd)
|
static void pcr_cmd (char cmd)
|
||||||
{
|
{
|
||||||
long nwrite, nrcvd;
|
DWORD nwrite, nrcvd;
|
||||||
|
|
||||||
if (cmd != '\0') {
|
if (cmd != '\0') {
|
||||||
if (cr_unit.flags & UNIT_DEBUG && (cmd != 'S' || cmd != lastcmd))
|
if (cr_unit.flags & UNIT_DEBUG && (cmd != 'S' || cmd != lastcmd))
|
||||||
|
@ -2231,7 +2266,7 @@ static void pcr_cmd (char cmd)
|
||||||
|
|
||||||
static BOOL pcr_handle_status_byte (char byte)
|
static BOOL pcr_handle_status_byte (char byte)
|
||||||
{
|
{
|
||||||
long nrcvd;
|
DWORD nrcvd;
|
||||||
static char prev_status = '?';
|
static char prev_status = '?';
|
||||||
BOOL show;
|
BOOL show;
|
||||||
|
|
||||||
|
@ -2276,7 +2311,7 @@ static void pcr_set_dsw_from_status (BOOL post_pick)
|
||||||
|
|
||||||
static BOOL pcr_handle_byte (char byte)
|
static BOOL pcr_handle_byte (char byte)
|
||||||
{
|
{
|
||||||
long nrcvd;
|
DWORD nrcvd;
|
||||||
|
|
||||||
GetOverlappedResult(hpcr, &ovRd, &nrcvd, TRUE);
|
GetOverlappedResult(hpcr, &ovRd, &nrcvd, TRUE);
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "sim_defs.h" /* main SIMH defns (include path should include .., or make a copy) */
|
#include "sim_defs.h" /* main SIMH defns (include path should include .., or make a copy) */
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#if defined(VMS)
|
#if defined(VMS)
|
||||||
# include <unistd.h> /* to pick up 'unlink' */
|
# include <unistd.h> /* to pick up 'unlink' */
|
||||||
|
@ -23,7 +24,7 @@
|
||||||
#define MIN(a,b) (((a) <= (b)) ? (a) : (b))
|
#define MIN(a,b) (((a) <= (b)) ? (a) : (b))
|
||||||
#define MAX(a,b) (((a) >= (b)) ? (a) : (b))
|
#define MAX(a,b) (((a) >= (b)) ? (a) : (b))
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef _WIN32
|
||||||
int strnicmp (char *a, char *b, int n);
|
int strnicmp (char *a, char *b, int n);
|
||||||
int strcmpi (char *a, char *b);
|
int strcmpi (char *a, char *b);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -347,7 +347,7 @@ void xio_disk (int32 iocc_addr, int32 func, int32 modify, int drv)
|
||||||
uptr->CYL = 0;
|
uptr->CYL = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dsk_sec[drv] = (dsk_sec[drv] + 1) % 4; /* advance the "next sector" count every time */
|
dsk_sec[drv] = (int16) ((dsk_sec[drv] + 1) % 4); /* advance the "next sector" count every time */
|
||||||
ACC = dsk_dsw[drv] | dsk_sec[drv];
|
ACC = dsk_dsw[drv] | dsk_sec[drv];
|
||||||
|
|
||||||
if (modify & 0x01) { /* reset interrupts */
|
if (modify & 0x01) { /* reset interrupts */
|
||||||
|
@ -474,7 +474,7 @@ t_stat dsk_reset (DEVICE *dptr)
|
||||||
|
|
||||||
uptr->CYL = 0;
|
uptr->CYL = 0;
|
||||||
uptr->FUNC = DSK_FUNC_IDLE;
|
uptr->FUNC = DSK_FUNC_IDLE;
|
||||||
dsk_dsw[drv] = (uptr->flags & UNIT_ATT) ? DSK_DSW_CARRIAGE_HOME : 0;
|
dsk_dsw[drv] = (int16) ((uptr->flags & UNIT_ATT) ? DSK_DSW_CARRIAGE_HOME : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
calc_ints();
|
calc_ints();
|
||||||
|
|
|
@ -104,7 +104,7 @@ char cX; // character to test
|
||||||
iO = 0; // init output position
|
iO = 0; // init output position
|
||||||
iT = 0; // init tab stop
|
iT = 0; // init tab stop
|
||||||
|
|
||||||
while (cX = *(p_szInbuf + iI)) // while there are characters
|
while ((cX = *(p_szInbuf + iI)) != 0) // while there are characters
|
||||||
{
|
{
|
||||||
if (cX == '\t') // q. tab character?
|
if (cX == '\t') // q. tab character?
|
||||||
{ // a. yes ..
|
{ // a. yes ..
|
||||||
|
@ -227,7 +227,7 @@ char *EditToFortran(char* p_pszEdit) // convert line to 1130 assembler
|
||||||
char pszLine[MAXLINE]; // source line
|
char pszLine[MAXLINE]; // source line
|
||||||
char* pszWork; // work pointer
|
char* pszWork; // work pointer
|
||||||
size_t iI; // work integer
|
size_t iI; // work integer
|
||||||
char bContinue; // true if continue
|
int bContinue; // true if continue
|
||||||
|
|
||||||
if (p_pszEdit == NULL) // q. null request?
|
if (p_pszEdit == NULL) // q. null request?
|
||||||
return FMSG; // a. yes .. return display message
|
return FMSG; // a. yes .. return display message
|
||||||
|
|
|
@ -169,7 +169,7 @@ void xio_2250_display (int32 addr, int32 func, int32 modify)
|
||||||
WriteW(addr+3, gdu_y & 0x7FF);
|
WriteW(addr+3, gdu_y & 0x7FF);
|
||||||
WriteW(addr+4, gdu_fkey);
|
WriteW(addr+4, gdu_fkey);
|
||||||
WriteW(addr+5, gdu_akey);
|
WriteW(addr+5, gdu_akey);
|
||||||
gdu_ar = addr+6; /* this alters the channel address register? */
|
gdu_ar = (int16) (addr+6); /* this alters the channel address register? */
|
||||||
|
|
||||||
clear_interrupts(); /* read status clears the interrupts */
|
clear_interrupts(); /* read status clears the interrupts */
|
||||||
break;
|
break;
|
||||||
|
@ -182,7 +182,7 @@ void xio_2250_display (int32 addr, int32 func, int32 modify)
|
||||||
set_indicators((ReadW(addr) << 16) | ReadW(addr+1));
|
set_indicators((ReadW(addr) << 16) | ReadW(addr+1));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
gdu_ar = addr;
|
gdu_ar = (int16) addr;
|
||||||
gdu_fkey = 0;
|
gdu_fkey = 0;
|
||||||
gdu_akey = 0;
|
gdu_akey = 0;
|
||||||
clear_interrupts();
|
clear_interrupts();
|
||||||
|
@ -273,7 +273,7 @@ static int32 read_gduword (void)
|
||||||
int32 w;
|
int32 w;
|
||||||
|
|
||||||
w = M[gdu_ar++ & mem_mask];
|
w = M[gdu_ar++ & mem_mask];
|
||||||
gdu_dsw = (gdu_dsw & ~GDU_DSW_ADDR_DISP) | ((gdu_ar - gdu_instaddr) & GDU_DSW_ADDR_DISP);
|
gdu_dsw = (int16) ((gdu_dsw & ~GDU_DSW_ADDR_DISP) | ((gdu_ar - gdu_instaddr) & GDU_DSW_ADDR_DISP));
|
||||||
|
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
@ -387,8 +387,8 @@ static void draw (int32 newx, int32 newy, t_bool beam)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
gdu_x = newx;
|
gdu_x = (int16) newx;
|
||||||
gdu_y = newy;
|
gdu_y = (int16) newy;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void generate_image (void)
|
static void generate_image (void)
|
||||||
|
@ -419,7 +419,7 @@ static void generate_image (void)
|
||||||
case 0: // short branch
|
case 0: // short branch
|
||||||
case 1:
|
case 1:
|
||||||
gdu_revert = gdu_ar; // save revert address & get new address
|
gdu_revert = gdu_ar; // save revert address & get new address
|
||||||
gdu_ar = read_gduword() & 0x1FFF;
|
gdu_ar = (int16) (read_gduword() & 0x1FFF);
|
||||||
if (gdu_dsw & GDU_DSW_CHARACTER_MODE) {
|
if (gdu_dsw & GDU_DSW_CHARACTER_MODE) {
|
||||||
draw_characters(); // in character mode this means we are at character data
|
draw_characters(); // in character mode this means we are at character data
|
||||||
gdu_ar = gdu_revert;
|
gdu_ar = gdu_revert;
|
||||||
|
@ -443,7 +443,7 @@ static void generate_image (void)
|
||||||
if (instr & 0x0080) // indirect
|
if (instr & 0x0080) // indirect
|
||||||
new_addr = M[new_addr & mem_mask];
|
new_addr = M[new_addr & mem_mask];
|
||||||
|
|
||||||
gdu_ar = new_addr;
|
gdu_ar = (int16) new_addr;
|
||||||
|
|
||||||
if (gdu_dsw & GDU_DSW_CHARACTER_MODE) {
|
if (gdu_dsw & GDU_DSW_CHARACTER_MODE) {
|
||||||
draw_characters();
|
draw_characters();
|
||||||
|
@ -600,9 +600,9 @@ static void draw_characters (void)
|
||||||
|
|
||||||
case 7: // new line
|
case 7: // new line
|
||||||
gdu_x = 0;
|
gdu_x = 0;
|
||||||
gdu_y -= ci->dy;
|
gdu_y -= (int16) ci->dy;
|
||||||
if (gdu_y < 0 && last_abs)
|
if (gdu_y < 0 && last_abs)
|
||||||
gdu_y = 1024 - ci->dy; // this is a guess
|
gdu_y = (int16) (1024 - ci->dy); // this is a guess
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -631,7 +631,7 @@ static void draw_characters (void)
|
||||||
gdu_x += ci->dx;
|
gdu_x += ci->dx;
|
||||||
if (gdu_x > 1023 && last_abs) { // line wrap
|
if (gdu_x > 1023 && last_abs) { // line wrap
|
||||||
gdu_x = 0;
|
gdu_x = 0;
|
||||||
gdu_y -= ci->dy;
|
gdu_y -= (int16) ci->dy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while ((w & 0x0080) == 0); // repeat until we hit revert bit
|
} while ((w & 0x0080) == 0); // repeat until we hit revert bit
|
||||||
|
@ -645,7 +645,7 @@ static void draw_characters (void)
|
||||||
|
|
||||||
/******* PLATFORM SPECIFIC CODE ***********************************************************/
|
/******* PLATFORM SPECIFIC CODE ***********************************************************/
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <windowsx.h>
|
#include <windowsx.h>
|
||||||
|
@ -1114,5 +1114,5 @@ static void ShowPenHit (int x, int y)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // WIN32 defined
|
#endif // _WIN32 defined
|
||||||
#endif // GUI_SUPPORT defined
|
#endif // GUI_SUPPORT defined
|
||||||
|
|
|
@ -126,8 +126,8 @@ void scp_panic (char *msg)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
/* only WIN32 is defined right now */
|
/* only _WIN32 is defined right now */
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
|
@ -1463,7 +1463,7 @@ static void tear_printer (void)
|
||||||
// if (! stuff_and_wait("detach cr", 1000, 0)) // detach the card reader so they can edit the deck file
|
// if (! stuff_and_wait("detach cr", 1000, 0)) // detach the card reader so they can edit the deck file
|
||||||
// return;
|
// return;
|
||||||
|
|
||||||
unlink(filename); // delete the file
|
remove(filename); // delete the file
|
||||||
|
|
||||||
sprintf(cmd, "attach prt \"%s\"", filename); // reattach
|
sprintf(cmd, "attach prt \"%s\"", filename); // reattach
|
||||||
stuff_cmd(cmd);
|
stuff_cmd(cmd);
|
||||||
|
@ -1634,5 +1634,5 @@ void remark_cmd (char *remark)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // WIN32 defined
|
#endif // _WIN32 defined
|
||||||
#endif // GUI_SUPPORT defined
|
#endif // GUI_SUPPORT defined
|
||||||
|
|
|
@ -264,7 +264,7 @@ static void flush_prt_line (FILE *fd, int spacemode, t_bool phys_flush)
|
||||||
|
|
||||||
if (spacemode && ! maxnp) { // spacing only
|
if (spacemode && ! maxnp) { // spacing only
|
||||||
if (prt_row == 0 && prt_nnl) {
|
if (prt_row == 0 && prt_nnl) {
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
if (! cgi)
|
if (! cgi)
|
||||||
putc('\r', fd); // DOS/Windows: end with cr/lf
|
putc('\r', fd); // DOS/Windows: end with cr/lf
|
||||||
#endif
|
#endif
|
||||||
|
@ -283,7 +283,7 @@ static void flush_prt_line (FILE *fd, int spacemode, t_bool phys_flush)
|
||||||
if (prt_nnl) { // there are queued newlines
|
if (prt_nnl) { // there are queued newlines
|
||||||
// if we spaced to top of form, don't emit formfeed. We'd only ever emit the formfeed if we skipped via control tape channels
|
// if we spaced to top of form, don't emit formfeed. We'd only ever emit the formfeed if we skipped via control tape channels
|
||||||
// if (prt_row == 0 && prt_nnl) { // we spaced to top of form
|
// if (prt_row == 0 && prt_nnl) { // we spaced to top of form
|
||||||
//#ifdef WIN32
|
//#ifdef _WIN32
|
||||||
// if (! cgi)
|
// if (! cgi)
|
||||||
// putc('\r', fd); // DOS/Windows: end with cr/lf
|
// putc('\r', fd); // DOS/Windows: end with cr/lf
|
||||||
//#endif
|
//#endif
|
||||||
|
@ -293,7 +293,7 @@ static void flush_prt_line (FILE *fd, int spacemode, t_bool phys_flush)
|
||||||
// }
|
// }
|
||||||
// else {
|
// else {
|
||||||
while (prt_nnl > 0) { // spit out queued newlines
|
while (prt_nnl > 0) { // spit out queued newlines
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
if (! cgi)
|
if (! cgi)
|
||||||
putc('\r', fd); // DOS/Windows: end with cr/lf
|
putc('\r', fd); // DOS/Windows: end with cr/lf
|
||||||
#endif
|
#endif
|
||||||
|
@ -347,7 +347,7 @@ void xio_1132_printer (int32 iocc_addr, int32 func, int32 modify)
|
||||||
|
|
||||||
switch (func) {
|
switch (func) {
|
||||||
case XIO_READ:
|
case XIO_READ:
|
||||||
M[iocc_addr & mem_mask] = codewheel1132[prt_nchar].ebcdic << 8;
|
M[iocc_addr & mem_mask] = (uint16) (codewheel1132[prt_nchar].ebcdic << 8);
|
||||||
|
|
||||||
if ((uptr->flags & UNIT_PRINTING) == 0) /* if we're not printing, advance this after every test */
|
if ((uptr->flags & UNIT_PRINTING) == 0) /* if we're not printing, advance this after every test */
|
||||||
prt_nchar = (prt_nchar + 1) % WHEELCHARS_1132;
|
prt_nchar = (prt_nchar + 1) % WHEELCHARS_1132;
|
||||||
|
@ -631,7 +631,7 @@ static t_stat delete_cmd (int flag, char *cptr)
|
||||||
if (*gbuf == 0) return SCPE_2FARG;
|
if (*gbuf == 0) return SCPE_2FARG;
|
||||||
if (*cptr != 0) return SCPE_2MARG; /* now eol? */
|
if (*cptr != 0) return SCPE_2MARG; /* now eol? */
|
||||||
|
|
||||||
status = unlink(gbuf); /* delete the file */
|
status = remove(gbuf); /* delete the file */
|
||||||
|
|
||||||
if (status != 0 && errno != ENOENT) /* print message if failed and file exists */
|
if (status != 0 && errno != ENOENT) /* print message if failed and file exists */
|
||||||
perror(gbuf);
|
perror(gbuf);
|
||||||
|
@ -745,7 +745,7 @@ static t_stat prt_attach (UNIT *uptr, char *cptr)
|
||||||
reset_prt_line();
|
reset_prt_line();
|
||||||
|
|
||||||
if (IS_1132(uptr)) {
|
if (IS_1132(uptr)) {
|
||||||
PRT_DSW = (PRT_DSW & ~PRT1132_DSW_CHANNEL_MASK) | cc_format_1132(cctape[prt_row]);
|
PRT_DSW = (uint16) ((PRT_DSW & ~PRT1132_DSW_CHANNEL_MASK) | cc_format_1132(cctape[prt_row]));
|
||||||
|
|
||||||
if (IS_ONLINE(uptr))
|
if (IS_ONLINE(uptr))
|
||||||
CLRBIT(PRT_DSW, PRT1132_DSW_NOT_READY);
|
CLRBIT(PRT_DSW, PRT1132_DSW_NOT_READY);
|
||||||
|
|
|
@ -125,8 +125,8 @@ static unsigned char conout_map[256]; /* 1130 console code to ASCII translation
|
||||||
static unsigned char conin_map[256]; /* input mapping */
|
static unsigned char conin_map[256]; /* input mapping */
|
||||||
static int curcol = 0; /* current typewriter element column, leftmost = 0 */
|
static int curcol = 0; /* current typewriter element column, leftmost = 0 */
|
||||||
static int maxcol = 0; /* highest curcol seen in this output line */
|
static int maxcol = 0; /* highest curcol seen in this output line */
|
||||||
static char black_ribbon[30]; /* output escape sequence for black ribbon shift */
|
static unsigned char black_ribbon[30]; /* output escape sequence for black ribbon shift */
|
||||||
static char red_ribbon[30]; /* output escape sequence for red ribbon shift */
|
static unsigned char red_ribbon[30]; /* output escape sequence for red ribbon shift */
|
||||||
|
|
||||||
static OS_MAP os_buf[MAX_OUTPUT_COLUMNS]; /* current typewriter output line, holds character struck in each column */
|
static OS_MAP os_buf[MAX_OUTPUT_COLUMNS]; /* current typewriter output line, holds character struck in each column */
|
||||||
static OS_MAP os_map[MAX_OS_MAPPINGS]; /* overstrike mapping entries */
|
static OS_MAP os_map[MAX_OS_MAPPINGS]; /* overstrike mapping entries */
|
||||||
|
@ -800,8 +800,8 @@ static void set_default_mapping (int32 flags)
|
||||||
|
|
||||||
reset_mapping();
|
reset_mapping();
|
||||||
|
|
||||||
strcpy(black_ribbon, "\033[30m");
|
strcpy((char *) black_ribbon, "\033[30m");
|
||||||
strcpy(red_ribbon, "\033[31m");
|
strcpy((char *) red_ribbon, "\033[31m");
|
||||||
|
|
||||||
switch (flags & CSET_MASK) {
|
switch (flags & CSET_MASK) {
|
||||||
case CSET_1130:
|
case CSET_1130:
|
||||||
|
@ -850,10 +850,10 @@ static t_stat map_conout_character (int ch)
|
||||||
int i, cmp;
|
int i, cmp;
|
||||||
|
|
||||||
if (ch == (COUT_IS_CTRL|COUT_CTRL_BLACK))
|
if (ch == (COUT_IS_CTRL|COUT_CTRL_BLACK))
|
||||||
return (tto_unit.flags & ENABLE_ANSI) ? sim_putstr(black_ribbon) : SCPE_OK;
|
return (tto_unit.flags & ENABLE_ANSI) ? sim_putstr((char *) black_ribbon) : SCPE_OK;
|
||||||
|
|
||||||
if (ch == (COUT_IS_CTRL|COUT_CTRL_RED))
|
if (ch == (COUT_IS_CTRL|COUT_CTRL_RED))
|
||||||
return (tto_unit.flags & ENABLE_ANSI) ? sim_putstr(red_ribbon) : SCPE_OK;
|
return (tto_unit.flags & ENABLE_ANSI) ? sim_putstr((char *) red_ribbon) : SCPE_OK;
|
||||||
|
|
||||||
if ((ch = conout_map[ch & 0xFF]) == 0)
|
if ((ch = conout_map[ch & 0xFF]) == 0)
|
||||||
ch = '?'; // unknown character? print ?
|
ch = '?'; // unknown character? print ?
|
||||||
|
@ -1088,7 +1088,7 @@ static void read_map_file (FILE *fd)
|
||||||
|
|
||||||
static char * get_num_char (char **pc, unsigned char *out, int ndigits, int base, char *errmsg)
|
static char * get_num_char (char **pc, unsigned char *out, int ndigits, int base, char *errmsg)
|
||||||
{
|
{
|
||||||
unsigned char ch = 0, digit;
|
int ch = 0, digit;
|
||||||
char *c = *pc;
|
char *c = *pc;
|
||||||
|
|
||||||
while (--ndigits >= 0) { /* collect specified number of digits */
|
while (--ndigits >= 0) { /* collect specified number of digits */
|
||||||
|
@ -1108,7 +1108,7 @@ static char * get_num_char (char **pc, unsigned char *out, int ndigits, int base
|
||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
|
|
||||||
*out = ch; /* return parsed character */
|
*out = (unsigned char) ch; /* return parsed character */
|
||||||
*pc = c-1; /* make input pointer point to last character seen */
|
*pc = c-1; /* make input pointer point to last character seen */
|
||||||
return NULL; /* no error */
|
return NULL; /* no error */
|
||||||
}
|
}
|
||||||
|
@ -1119,9 +1119,10 @@ static char * get_num_char (char **pc, unsigned char *out, int ndigits, int base
|
||||||
* error encountered. *pc is advanced to next whitespace or whatever followed input.
|
* error encountered. *pc is advanced to next whitespace or whatever followed input.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static char * get_characters (char **pc, char *outstr, int nmax, int *nout)
|
static char * get_characters (char **pc, unsigned char *outstr, int nmax, int *nout)
|
||||||
{
|
{
|
||||||
char *c = *pc, *out = outstr, *errstr;
|
char *c = *pc, *errstr;
|
||||||
|
unsigned char *out = outstr;
|
||||||
|
|
||||||
while (*c && *c <= ' ') /* skip leading whitespace */
|
while (*c && *c <= ' ') /* skip leading whitespace */
|
||||||
c++;
|
c++;
|
||||||
|
@ -1181,7 +1182,7 @@ static char * get_characters (char **pc, char *outstr, int nmax, int *nout)
|
||||||
else if (BETWEEN(*c, 'A', 'Z') || BETWEEN(*c, 'a', 'z'))
|
else if (BETWEEN(*c, 'A', 'Z') || BETWEEN(*c, 'a', 'z'))
|
||||||
return "invalid \\ escape"; /* other \x letters are bad */
|
return "invalid \\ escape"; /* other \x letters are bad */
|
||||||
else {
|
else {
|
||||||
*out++ = *c; /* otherwise, accept \x as literal character x */
|
*out++ = (unsigned char) *c;/* otherwise, accept \x as literal character x */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1189,18 +1190,18 @@ static char * get_characters (char **pc, char *outstr, int nmax, int *nout)
|
||||||
else if (*c == '^') { /* control character */
|
else if (*c == '^') { /* control character */
|
||||||
c++;
|
c++;
|
||||||
if (BETWEEN(*c, 'A', 'Z')) /* convert alpha, e.g. A -> 1 */
|
if (BETWEEN(*c, 'A', 'Z')) /* convert alpha, e.g. A -> 1 */
|
||||||
*out++ = *c - 'A' + 1;
|
*out++ = (unsigned char) (*c - 'A' + 1);
|
||||||
else if (BETWEEN(*c, 'a', 'z'))
|
else if (BETWEEN(*c, 'a', 'z'))
|
||||||
*out++ = *c - 'z' + 1;
|
*out++ = (unsigned char) (*c - 'z' + 1);
|
||||||
else /* non alpha is bad */
|
else /* non alpha is bad */
|
||||||
return "invalid control letter";
|
return "invalid control letter";
|
||||||
}
|
}
|
||||||
else if (str_match(c, "IGNORE")) { /* magic word: a character that will never be output */
|
else if (str_match(c, "IGNORE")) { /* magic word: a character that will never be output */
|
||||||
*out++ = IGNR_;
|
*out++ = (unsigned char) IGNR_;
|
||||||
c += 6;
|
c += 6;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*out++ = *c; /* save literal character */
|
*out++ = (unsigned char) *c; /* save literal character */
|
||||||
}
|
}
|
||||||
|
|
||||||
c++;
|
c++;
|
||||||
|
@ -1219,7 +1220,8 @@ static char * get_characters (char **pc, char *outstr, int nmax, int *nout)
|
||||||
|
|
||||||
static char * handle_map_ansi_definition (char **pc)
|
static char * handle_map_ansi_definition (char **pc)
|
||||||
{
|
{
|
||||||
char *outstr, *errmsg;
|
unsigned char *outstr;
|
||||||
|
char *errmsg;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (str_match(*pc, "black")) { /* find which string we're setting */
|
if (str_match(*pc, "black")) { /* find which string we're setting */
|
||||||
|
|
|
@ -442,7 +442,7 @@ t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw)
|
||||||
return SCPE_ARG;
|
return SCPE_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef _WIN32
|
||||||
|
|
||||||
int strnicmp (char *a, char *b, int n)
|
int strnicmp (char *a, char *b, int n)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* id16_cpu.c: Interdata 16b CPU simulator
|
/* id16_cpu.c: Interdata 16b CPU simulator
|
||||||
|
|
||||||
Copyright (c) 2000-2003, Robert M. Supnik
|
Copyright (c) 2000-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* id16_dboot.c: Interdata 16b simulator disk bootstrap
|
/* id16_dboot.c: Interdata 16b simulator disk bootstrap
|
||||||
|
|
||||||
Copyright (c) 2000-2003, Robert M. Supnik
|
Copyright (c) 2000-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* id16_sys.c: Interdata 16b simulator interface
|
/* id16_sys.c: Interdata 16b simulator interface
|
||||||
|
|
||||||
Copyright (c) 2000-2003, Robert M. Supnik
|
Copyright (c) 2000-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -23,6 +23,7 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
in this Software without prior written authorization from Robert M Supnik.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
26-Mar-04 RMS Fixed warning with -std=c99
|
||||||
27-Feb-03 RMS Added relative addressing support
|
27-Feb-03 RMS Added relative addressing support
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -47,7 +48,7 @@ extern uint16 *M;
|
||||||
t_stat fprint_sym_m (FILE *of, t_addr addr, t_value *val, t_bool cf);
|
t_stat fprint_sym_m (FILE *of, t_addr addr, t_value *val, t_bool cf);
|
||||||
t_stat parse_sym_m (char *cptr, t_addr addr, t_value *val, t_bool cf);
|
t_stat parse_sym_m (char *cptr, t_addr addr, t_value *val, t_bool cf);
|
||||||
extern t_stat lp_load (FILE *fileref, char *cptr, char *fnam);
|
extern t_stat lp_load (FILE *fileref, char *cptr, char *fnam);
|
||||||
extern pt_dump (FILE *of, char *cptr, char *fnam);
|
extern t_stat pt_dump (FILE *of, char *cptr, char *fnam);
|
||||||
|
|
||||||
/* SCP data structures and interface routines
|
/* SCP data structures and interface routines
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
cpu Interdata 32b CPU
|
cpu Interdata 32b CPU
|
||||||
|
|
||||||
|
25-Jan-04 RMS Revised for device debug support
|
||||||
31-Dec-03 RMS Fixed bug in cpu_set_hist
|
31-Dec-03 RMS Fixed bug in cpu_set_hist
|
||||||
22-Sep-03 RMS Added additional instruction decode types
|
22-Sep-03 RMS Added additional instruction decode types
|
||||||
Added instruction history
|
Added instruction history
|
||||||
|
@ -191,6 +192,11 @@ struct InstHistory {
|
||||||
#define ABS(x) (((x) & SIGN32)? NEG (x): (x))
|
#define ABS(x) (((x) & SIGN32)? NEG (x): (x))
|
||||||
#define DNEG(x,y) y = NEG (y); \
|
#define DNEG(x,y) y = NEG (y); \
|
||||||
x = (~(x) + (y == 0)) & DMASK32
|
x = (~(x) + (y == 0)) & DMASK32
|
||||||
|
|
||||||
|
/* Logging */
|
||||||
|
|
||||||
|
#define LOG_CPU_I 0x0001 /* intr/exception */
|
||||||
|
#define LOG_CPU_C 0x0002 /* context change */
|
||||||
|
|
||||||
uint32 GREG[16 * NRSETS] = { 0 }; /* general registers */
|
uint32 GREG[16 * NRSETS] = { 0 }; /* general registers */
|
||||||
uint32 *M = NULL; /* memory */
|
uint32 *M = NULL; /* memory */
|
||||||
|
@ -219,7 +225,6 @@ REG *pcq_r = NULL; /* PC queue reg ptr */
|
||||||
uint32 dec_flgs = 0; /* decode flags */
|
uint32 dec_flgs = 0; /* decode flags */
|
||||||
uint32 fp_in_hwre = 0; /* ucode vs hwre fp */
|
uint32 fp_in_hwre = 0; /* ucode vs hwre fp */
|
||||||
uint32 pawidth = PAWIDTH32; /* addr mask */
|
uint32 pawidth = PAWIDTH32; /* addr mask */
|
||||||
uint32 cpu_log = 0; /* debug logging */
|
|
||||||
uint32 hst_p = 0; /* history pointer */
|
uint32 hst_p = 0; /* history pointer */
|
||||||
uint32 hst_lnt = 0; /* history length */
|
uint32 hst_lnt = 0; /* history length */
|
||||||
struct InstHistory *hst = NULL; /* instruction history */
|
struct InstHistory *hst = NULL; /* instruction history */
|
||||||
|
@ -231,7 +236,7 @@ extern int32 sim_interval;
|
||||||
extern int32 sim_int_char;
|
extern int32 sim_int_char;
|
||||||
extern int32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
|
extern int32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
|
||||||
extern UNIT pic_unit, lfc_unit, pas_unit; /* timers */
|
extern UNIT pic_unit, lfc_unit, pas_unit; /* timers */
|
||||||
extern FILE *sim_log;
|
extern FILE *sim_deb;
|
||||||
|
|
||||||
uint32 ReadB (uint32 loc, uint32 rel);
|
uint32 ReadB (uint32 loc, uint32 rel);
|
||||||
uint32 ReadH (uint32 loc, uint32 rel);
|
uint32 ReadH (uint32 loc, uint32 rel);
|
||||||
|
@ -538,7 +543,6 @@ REG cpu_reg[] = {
|
||||||
{ BRDATA (PCQ, pcq, 16, 20, PCQ_SIZE), REG_RO+REG_CIRC },
|
{ BRDATA (PCQ, pcq, 16, 20, PCQ_SIZE), REG_RO+REG_CIRC },
|
||||||
{ HRDATA (PCQP, pcq_p, 6), REG_HRO },
|
{ HRDATA (PCQP, pcq_p, 6), REG_HRO },
|
||||||
{ HRDATA (WRU, sim_int_char, 8) },
|
{ HRDATA (WRU, sim_int_char, 8) },
|
||||||
{ HRDATA (DBGLOG, cpu_log, 16), REG_HIDDEN },
|
|
||||||
{ HRDATA (BLKIOD, blk_io.dfl, 16), REG_HRO },
|
{ HRDATA (BLKIOD, blk_io.dfl, 16), REG_HRO },
|
||||||
{ HRDATA (BLKIOC, blk_io.cur, 20), REG_HRO },
|
{ HRDATA (BLKIOC, blk_io.cur, 20), REG_HRO },
|
||||||
{ HRDATA (BLKIOE, blk_io.end, 20), REG_HRO },
|
{ HRDATA (BLKIOE, blk_io.end, 20), REG_HRO },
|
||||||
|
@ -561,12 +565,18 @@ MTAB cpu_mod[] = {
|
||||||
&cpu_set_hist, &cpu_show_hist },
|
&cpu_set_hist, &cpu_show_hist },
|
||||||
{ 0 } };
|
{ 0 } };
|
||||||
|
|
||||||
|
DEBTAB cpu_deb[] = {
|
||||||
|
{ "INTEXC", LOG_CPU_I },
|
||||||
|
{ "CONTEXT", LOG_CPU_C },
|
||||||
|
{ NULL, 0 } };
|
||||||
|
|
||||||
DEVICE cpu_dev = {
|
DEVICE cpu_dev = {
|
||||||
"CPU", &cpu_unit, cpu_reg, cpu_mod,
|
"CPU", &cpu_unit, cpu_reg, cpu_mod,
|
||||||
1, 16, 20, 1, 16, 8,
|
1, 16, 20, 1, 16, 8,
|
||||||
&cpu_ex, &cpu_dep, &cpu_reset,
|
&cpu_ex, &cpu_dep, &cpu_reset,
|
||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
&cpu_dib, 0 };
|
&cpu_dib, DEV_DEBUG, 0,
|
||||||
|
cpu_deb, NULL, NULL };
|
||||||
|
|
||||||
t_stat sim_instr (void)
|
t_stat sim_instr (void)
|
||||||
{
|
{
|
||||||
|
@ -1307,7 +1317,7 @@ case 0xE1: /* SVC - RX */
|
||||||
R[14] = t; /* old PSW */
|
R[14] = t; /* old PSW */
|
||||||
R[15] = PC; /* old PC */
|
R[15] = PC; /* old PC */
|
||||||
PC = ReadH (SVNPC + r1 + r1, P); /* new PC */
|
PC = ReadH (SVNPC + r1 + r1, P); /* new PC */
|
||||||
if (DBG_LOG (LOG_CPU_C)) fprintf (sim_log,
|
if (DEBUG_PRI (cpu_dev, LOG_CPU_C)) fprintf (sim_deb,
|
||||||
">>SVC: oPC = %X, oPSW = %X, nPC = %X, nPSW = %X\n",
|
">>SVC: oPC = %X, oPSW = %X, nPC = %X, nPSW = %X\n",
|
||||||
pcq[pcq_p], t, PC, PSW);
|
pcq[pcq_p], t, PC, PSW);
|
||||||
break;
|
break;
|
||||||
|
@ -1341,7 +1351,7 @@ case 0xE3: /* SCP - RXH */
|
||||||
case 0x18: /* LPSWR - RR */
|
case 0x18: /* LPSWR - RR */
|
||||||
PCQ_ENTRY; /* effective branch */
|
PCQ_ENTRY; /* effective branch */
|
||||||
PC = R[(r2 + 1) & 0xF] & VAMASK; /* new PC (old reg set) */
|
PC = R[(r2 + 1) & 0xF] & VAMASK; /* new PC (old reg set) */
|
||||||
if (DBG_LOG (LOG_CPU_C)) fprintf (sim_log,
|
if (DEBUG_PRI (cpu_dev, LOG_CPU_C)) fprintf (sim_deb,
|
||||||
">>LPSWR: oPC = %X, oPSW = %X, nPC = %X, nPSW = %X\n",
|
">>LPSWR: oPC = %X, oPSW = %X, nPC = %X, nPSW = %X\n",
|
||||||
pcq[pcq_p], BUILD_PSW (cc), PC, opnd);
|
pcq[pcq_p], BUILD_PSW (cc), PC, opnd);
|
||||||
cc = newPSW (opnd); /* new PSW */
|
cc = newPSW (opnd); /* new PSW */
|
||||||
|
@ -1351,7 +1361,7 @@ case 0x18: /* LPSWR - RR */
|
||||||
case 0xC2: /* LPSW - RXF */
|
case 0xC2: /* LPSW - RXF */
|
||||||
PCQ_ENTRY; /* effective branch */
|
PCQ_ENTRY; /* effective branch */
|
||||||
PC = ReadF ((ea + 4) & VAMASK, VR) & VAMASK; /* new PC */
|
PC = ReadF ((ea + 4) & VAMASK, VR) & VAMASK; /* new PC */
|
||||||
if (DBG_LOG (LOG_CPU_C)) fprintf (sim_log,
|
if (DEBUG_PRI (cpu_dev, LOG_CPU_C)) fprintf (sim_deb,
|
||||||
">>LPSW: oPC = %X, oPSW = %X, nPC = %X, nPSW = %X\n",
|
">>LPSW: oPC = %X, oPSW = %X, nPC = %X, nPSW = %X\n",
|
||||||
pcq[pcq_p], BUILD_PSW (cc), PC, opnd);
|
pcq[pcq_p], BUILD_PSW (cc), PC, opnd);
|
||||||
cc = newPSW (opnd); /* new PSW */
|
cc = newPSW (opnd); /* new PSW */
|
||||||
|
@ -1587,7 +1597,7 @@ if (cpu_unit.flags & UNIT_832) { /* 8/32? */
|
||||||
R[15] = oldPC; } /* PC to new 15 */
|
R[15] = oldPC; } /* PC to new 15 */
|
||||||
else { GREG[14] = oldPSW; /* 7/32, PSW to set 0 14 */
|
else { GREG[14] = oldPSW; /* 7/32, PSW to set 0 14 */
|
||||||
GREG[15] = oldPC; } /* PC to set 0 15 */
|
GREG[15] = oldPC; } /* PC to set 0 15 */
|
||||||
if (DBG_LOG (LOG_CPU_C)) fprintf (sim_log,
|
if (DEBUG_PRI (cpu_dev, LOG_CPU_I)) fprintf (sim_deb,
|
||||||
">>Exc %X: oPC = %X, oPSW = %X, nPC = %X, nPSW = %X\n",
|
">>Exc %X: oPC = %X, oPSW = %X, nPC = %X, nPSW = %X\n",
|
||||||
loc, oldPC, oldPSW, PC, PSW | cc | flg);
|
loc, oldPC, oldPSW, PC, PSW | cc | flg);
|
||||||
return cc | flg; /* return CC */
|
return cc | flg; /* return CC */
|
||||||
|
@ -1672,7 +1682,7 @@ newPSW (0x2800); /* new PSW */
|
||||||
R[0] = oldPSW; /* save old PSW */
|
R[0] = oldPSW; /* save old PSW */
|
||||||
R[1] = PC; /* save PC */
|
R[1] = PC; /* save PC */
|
||||||
R[2] = dev; /* set dev # */
|
R[2] = dev; /* set dev # */
|
||||||
if (DBG_LOG (LOG_CPU_C)) fprintf (sim_log,
|
if (DEBUG_PRI (cpu_dev, LOG_CPU_I)) fprintf (sim_deb,
|
||||||
">>Int %X: oPC = %X, oPSW = %X, nPC = %X, nPSW = %X\n",
|
">>Int %X: oPC = %X, oPSW = %X, nPC = %X, nPSW = %X\n",
|
||||||
dev, PC, oldPSW, vec, 0x2800);
|
dev, PC, oldPSW, vec, 0x2800);
|
||||||
if (DEV_ACC (dev)) { /* dev exist? */
|
if (DEV_ACC (dev)) { /* dev exist? */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* id32_dboot.c: Interdata 32b simulator disk bootstrap
|
/* id32_dboot.c: Interdata 32b simulator disk bootstrap
|
||||||
|
|
||||||
Copyright (c) 2000-2003, Robert M. Supnik
|
Copyright (c) 2000-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* id32_sys.c: Interdata 32b simulator interface
|
/* id32_sys.c: Interdata 32b simulator interface
|
||||||
|
|
||||||
Copyright (c) 2000-2003, Robert M. Supnik
|
Copyright (c) 2000-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* id_defs.h: Interdata 16b/32b simulator definitions
|
/* id_defs.h: Interdata 16b/32b simulator definitions
|
||||||
|
|
||||||
Copyright (c) 2000-2003, Robert M. Supnik
|
Copyright (c) 2000-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -26,6 +26,7 @@
|
||||||
The author gratefully acknowledges the help of Carl Friend and Al Kossow,
|
The author gratefully acknowledges the help of Carl Friend and Al Kossow,
|
||||||
who provided key documents about the Interdata product line.
|
who provided key documents about the Interdata product line.
|
||||||
|
|
||||||
|
25-Jan-04 RMS Removed local logging support
|
||||||
22-Sep-03 RMS Added additional instruction decode types
|
22-Sep-03 RMS Added additional instruction decode types
|
||||||
21-Jun-03 RMS Changed subroutine argument for ARM compiler conflict
|
21-Jun-03 RMS Changed subroutine argument for ARM compiler conflict
|
||||||
25-Apr-03 RMS Revised for extended file support
|
25-Apr-03 RMS Revised for extended file support
|
||||||
|
@ -457,17 +458,6 @@ typedef struct interdib DIB;
|
||||||
#define MIN(x,y) (((x) < (y))? (x): (y))
|
#define MIN(x,y) (((x) < (y))? (x): (y))
|
||||||
#define MAX(x,y) (((x) > (y))? (x): (y))
|
#define MAX(x,y) (((x) > (y))? (x): (y))
|
||||||
|
|
||||||
/* Logging */
|
|
||||||
|
|
||||||
#define LOG_CPU_I 0x0001 /* instructions */
|
|
||||||
#define LOG_CPU_C 0x0002 /* context change */
|
|
||||||
#define LOG_DP 0x0010
|
|
||||||
#define LOG_IDC 0x0020
|
|
||||||
#define LOG_MT 0x0040
|
|
||||||
#define LOG_FD 0x0080
|
|
||||||
|
|
||||||
#define DBG_LOG(x) (sim_log && (cpu_log & (x)))
|
|
||||||
|
|
||||||
/* Function prototypes */
|
/* Function prototypes */
|
||||||
|
|
||||||
int32 int_chg (uint32 irq, int32 dat, int32 armdis);
|
int32 int_chg (uint32 irq, int32 dat, int32 armdis);
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
To: Users
|
To: Users
|
||||||
From: Bob Supnik
|
From: Bob Supnik
|
||||||
Subj: Interdata 16b/32b Simulator Usage
|
Subj: Interdata 16b/32b Simulator Usage
|
||||||
Date: 15-Jul-2003
|
Date: 15-Feb-2004
|
||||||
|
|
||||||
COPYRIGHT NOTICE
|
COPYRIGHT NOTICE
|
||||||
|
|
||||||
The following copyright notice applies to both the SIMH source and binary:
|
The following copyright notice applies to both the SIMH source and binary:
|
||||||
|
|
||||||
Original code published in 1993-2003, written by Robert M Supnik
|
Original code published in 1993-2004, written by Robert M Supnik
|
||||||
Copyright (c) 1993-2003, Robert M Supnik
|
Copyright (c) 1993-2004, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -36,15 +36,21 @@ This memorandum documents the Interdata 16b and 32b simulators.
|
||||||
|
|
||||||
1. Simulator Files
|
1. Simulator Files
|
||||||
|
|
||||||
sim/ sim_defs.h
|
sim/ scp.h
|
||||||
|
sim_console.h
|
||||||
|
sim_defs.h
|
||||||
|
sim_fio.h
|
||||||
sim_rev.h
|
sim_rev.h
|
||||||
sim_sock.h
|
sim_sock.h
|
||||||
sim_tape.h
|
sim_tape.h
|
||||||
|
sim_timer.h
|
||||||
sim_tmxr.h
|
sim_tmxr.h
|
||||||
scp.c
|
scp.c
|
||||||
scp_tty.c
|
sim_console.c
|
||||||
|
sim_fio.c
|
||||||
sim_sock.c
|
sim_sock.c
|
||||||
sim_tape.c
|
sim_tape.c
|
||||||
|
sim_timer.c
|
||||||
sim_tmxr.c
|
sim_tmxr.c
|
||||||
|
|
||||||
sim/interdata/ id_defs.h
|
sim/interdata/ id_defs.h
|
||||||
|
@ -596,7 +602,13 @@ automatically to upper case. In 7B mode, input and output characters are
|
||||||
masked to 7 bits. In 8B mode, characters are not modified. The default
|
masked to 7 bits. In 8B mode, characters are not modified. The default
|
||||||
mode is UC. Each line (each unit of PASL) can also be set for modem
|
mode is UC. Each line (each unit of PASL) can also be set for modem
|
||||||
control with the command SET PASLn DATASET. The defaults are 7b mode
|
control with the command SET PASLn DATASET. The defaults are 7b mode
|
||||||
and DATASET disabled.
|
and DATASET disabled. Finally, each line supports output logging.
|
||||||
|
The SET PASLn LOG command enables logging on a line:
|
||||||
|
|
||||||
|
SET PASLn LOG=filename log output of line n to filename
|
||||||
|
|
||||||
|
The SET PASLn NOLOG command disables logging and closes the open log
|
||||||
|
file, if any.
|
||||||
|
|
||||||
Once PAS is attached and the simulator is running, the terminals listen
|
Once PAS is attached and the simulator is running, the terminals listen
|
||||||
for connections on the specified port. They assume that the incoming
|
for connections on the specified port. They assume that the incoming
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* id_dp.c: Interdata 2.5MB/10MB cartridge disk simulator
|
/* id_dp.c: Interdata 2.5MB/10MB cartridge disk simulator
|
||||||
|
|
||||||
Copyright (c) 2001-2003, Robert M. Supnik
|
Copyright (c) 2001-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
dp M46-421 2.5MB/10MB cartridge disk
|
dp M46-421 2.5MB/10MB cartridge disk
|
||||||
|
|
||||||
|
25-Jan-04 RMS Revised for device debug support
|
||||||
25-Apr-03 RMS Revised for extended file support
|
25-Apr-03 RMS Revised for extended file support
|
||||||
16-Feb-03 RMS Fixed read to test transfer ok before selch operation
|
16-Feb-03 RMS Fixed read to test transfer ok before selch operation
|
||||||
*/
|
*/
|
||||||
|
@ -136,7 +137,7 @@ static struct drvtyp drv_tab[] = {
|
||||||
{ 0 } };
|
{ 0 } };
|
||||||
|
|
||||||
extern uint32 int_req[INTSZ], int_enb[INTSZ];
|
extern uint32 int_req[INTSZ], int_enb[INTSZ];
|
||||||
extern FILE *sim_log;
|
extern FILE *sim_deb;
|
||||||
|
|
||||||
uint8 dpxb[DP_NUMBY]; /* xfer buffer */
|
uint8 dpxb[DP_NUMBY]; /* xfer buffer */
|
||||||
uint32 dp_bptr = 0; /* buffer ptr */
|
uint32 dp_bptr = 0; /* buffer ptr */
|
||||||
|
@ -152,7 +153,6 @@ uint32 dpd_arm[DP_NUMDR] = { 0 }; /* drives armed */
|
||||||
int32 dp_stime = 100; /* seek latency */
|
int32 dp_stime = 100; /* seek latency */
|
||||||
int32 dp_rtime = 100; /* rotate latency */
|
int32 dp_rtime = 100; /* rotate latency */
|
||||||
int32 dp_wtime = 1; /* word time */
|
int32 dp_wtime = 1; /* word time */
|
||||||
uint32 dp_log = 0; /* debug log */
|
|
||||||
uint8 dp_tplte[(2 * DP_NUMDR) + 2]; /* fix/rmv + ctrl + end */
|
uint8 dp_tplte[(2 * DP_NUMDR) + 2]; /* fix/rmv + ctrl + end */
|
||||||
|
|
||||||
DEVICE dp_dev;
|
DEVICE dp_dev;
|
||||||
|
@ -213,7 +213,6 @@ REG dp_reg[] = {
|
||||||
DP_NUMDR, REG_RO) },
|
DP_NUMDR, REG_RO) },
|
||||||
{ URDATA (CAPAC, dp_unit[0].capac, 10, T_ADDR_W, 0,
|
{ URDATA (CAPAC, dp_unit[0].capac, 10, T_ADDR_W, 0,
|
||||||
DP_NUMDR, PV_LEFT | REG_HRO) },
|
DP_NUMDR, PV_LEFT | REG_HRO) },
|
||||||
{ FLDATA (LOG, dp_log, 0), REG_HIDDEN },
|
|
||||||
{ HRDATA (DEVNO, dp_dib.dno, 8), REG_HRO },
|
{ HRDATA (DEVNO, dp_dib.dno, 8), REG_HRO },
|
||||||
{ HRDATA (SELCH, dp_dib.sch, 2), REG_HRO },
|
{ HRDATA (SELCH, dp_dib.sch, 2), REG_HRO },
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
@ -246,7 +245,7 @@ DEVICE dp_dev = {
|
||||||
DP_NUMDR, 16, 24, 1, 16, 8,
|
DP_NUMDR, 16, 24, 1, 16, 8,
|
||||||
NULL, NULL, &dp_reset,
|
NULL, NULL, &dp_reset,
|
||||||
&id_dboot, &dp_attach, &dp_detach,
|
&id_dboot, &dp_attach, &dp_detach,
|
||||||
&dp_dib, DEV_DISABLE };
|
&dp_dib, DEV_DISABLE | DEV_DEBUG };
|
||||||
|
|
||||||
/* Controller: IO routine */
|
/* Controller: IO routine */
|
||||||
|
|
||||||
|
@ -266,7 +265,7 @@ case IO_RD: /* read data */
|
||||||
else dp_sta = dp_sta | STA_BSY; /* xfr? set busy */
|
else dp_sta = dp_sta | STA_BSY; /* xfr? set busy */
|
||||||
return dp_db; /* return data */
|
return dp_db; /* return data */
|
||||||
case IO_WD: /* write data */
|
case IO_WD: /* write data */
|
||||||
if (sim_log && dp_log) fprintf (sim_log,
|
if (DEBUG_PRS (dp_dev)) fprintf (sim_deb,
|
||||||
">>DPC WD = %02X, STA = %02X\n", dat, dp_sta);
|
">>DPC WD = %02X, STA = %02X\n", dat, dp_sta);
|
||||||
if (dp_sta & STC_IDL) dp_hdsc = dat & HS_MASK; /* idle? hdsc */
|
if (dp_sta & STC_IDL) dp_hdsc = dat & HS_MASK; /* idle? hdsc */
|
||||||
else { /* data xfer */
|
else { /* data xfer */
|
||||||
|
@ -278,7 +277,7 @@ case IO_SS: /* status */
|
||||||
if (t & SETC_EX) t = t | STA_EX; /* test for EX */
|
if (t & SETC_EX) t = t | STA_EX; /* test for EX */
|
||||||
return t;
|
return t;
|
||||||
case IO_OC: /* command */
|
case IO_OC: /* command */
|
||||||
if (sim_log && dp_log) fprintf (sim_log,
|
if (DEBUG_PRS (dp_dev)) fprintf (sim_deb,
|
||||||
">>DPC OC = %02X, STA = %02X\n", dat, dp_sta);
|
">>DPC OC = %02X, STA = %02X\n", dat, dp_sta);
|
||||||
f = dat & CMC_MASK; /* get cmd */
|
f = dat & CMC_MASK; /* get cmd */
|
||||||
if (f & CMC_CLR) { /* clear? */
|
if (f & CMC_CLR) { /* clear? */
|
||||||
|
@ -315,7 +314,7 @@ case IO_ADR: /* select */
|
||||||
if (dp_sta & STC_IDL) dp_svun = dev; /* idle? save unit */
|
if (dp_sta & STC_IDL) dp_svun = dev; /* idle? save unit */
|
||||||
return BY; /* byte only */
|
return BY; /* byte only */
|
||||||
case IO_WD: /* write data */
|
case IO_WD: /* write data */
|
||||||
if (sim_log && dp_log) fprintf (sim_log,
|
if (DEBUG_PRS (dp_dev)) fprintf (sim_deb,
|
||||||
">>DP%d WD = %02X, STA = %02X\n", u, dat, dp_sta);
|
">>DP%d WD = %02X, STA = %02X\n", u, dat, dp_sta);
|
||||||
if (GET_DTYPE (uptr->flags) == TYPE_2315) /* 2.5MB drive? */
|
if (GET_DTYPE (uptr->flags) == TYPE_2315) /* 2.5MB drive? */
|
||||||
dp_cyl = dat & 0xFF; /* cyl is 8b */
|
dp_cyl = dat & 0xFF; /* cyl is 8b */
|
||||||
|
@ -330,7 +329,7 @@ case IO_SS: /* status */
|
||||||
if (t & SETD_EX) t = t | STA_EX; /* test for ex */
|
if (t & SETD_EX) t = t | STA_EX; /* test for ex */
|
||||||
return t;
|
return t;
|
||||||
case IO_OC: /* command */
|
case IO_OC: /* command */
|
||||||
if (sim_log && dp_log) fprintf (sim_log,
|
if (DEBUG_PRS (dp_dev)) fprintf (sim_deb,
|
||||||
">>DP%d OC = %02X, STA = %02X\n", u, dat, dp_sta);
|
">>DP%d OC = %02X, STA = %02X\n", u, dat, dp_sta);
|
||||||
dpd_arm[u] = int_chg (v_DPC + u + 1, dat, dpd_arm[u]);
|
dpd_arm[u] = int_chg (v_DPC + u + 1, dat, dpd_arm[u]);
|
||||||
if (dat & CMD_SK) t = dp_cyl; /* seek? get cyl */
|
if (dat & CMD_SK) t = dp_cyl; /* seek? get cyl */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* id_fd.c: Interdata floppy disk simulator
|
/* id_fd.c: Interdata floppy disk simulator
|
||||||
|
|
||||||
Copyright (c) 2001-2003, Robert M Supnik
|
Copyright (c) 2001-2004, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* id_fp.c: Interdata floating point instructions
|
/* id_fp.c: Interdata floating point instructions
|
||||||
|
|
||||||
Copyright (c) 2000-2003, Robert M. Supnik
|
Copyright (c) 2000-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* id_idc.c: Interdata MSM/IDC disk controller simulator
|
/* id_idc.c: Interdata MSM/IDC disk controller simulator
|
||||||
|
|
||||||
Copyright (c) 2001-2003, Robert M. Supnik
|
Copyright (c) 2001-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* id_io.c: Interdata CPU-independent I/O routines
|
/* id_io.c: Interdata CPU-independent I/O routines
|
||||||
|
|
||||||
Copyright (c) 2001-2003, Robert M. Supnik
|
Copyright (c) 2001-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* id_lp.c: Interdata line printer
|
/* id_lp.c: Interdata line printer
|
||||||
|
|
||||||
Copyright (c) 2001-2003, Robert M. Supnik
|
Copyright (c) 2001-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* id_mt.c: Interdata magnetic tape simulator
|
/* id_mt.c: Interdata magnetic tape simulator
|
||||||
|
|
||||||
Copyright (c) 2001-2003, Robert M Supnik
|
Copyright (c) 2001-2004, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* id_pas.c: Interdata programmable async line adapter simulator
|
/* id_pas.c: Interdata programmable async line adapter simulator
|
||||||
|
|
||||||
Copyright (c) 2001-2003, Robert M Supnik
|
Copyright (c) 2001-2004, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
pas Programmable asynchronous line adapter(s)
|
pas Programmable asynchronous line adapter(s)
|
||||||
|
|
||||||
|
05-Jan-04 RMS Revised for tmxr library changes
|
||||||
09-May-03 RMS Added network device flag
|
09-May-03 RMS Added network device flag
|
||||||
|
|
||||||
This module implements up to 32 individual serial interfaces, representing
|
This module implements up to 32 individual serial interfaces, representing
|
||||||
|
@ -100,7 +101,7 @@ uint32 pas_tps = 50; /* polls/second */
|
||||||
uint8 pas_tplte[PAS_LINES * 2 + 1]; /* template */
|
uint8 pas_tplte[PAS_LINES * 2 + 1]; /* template */
|
||||||
|
|
||||||
TMLN pas_ldsc[PAS_LINES] = { 0 }; /* line descriptors */
|
TMLN pas_ldsc[PAS_LINES] = { 0 }; /* line descriptors */
|
||||||
TMXR pas_desc = { 8, 0, 0, &pas_ldsc[0], NULL }; /* mux descriptor */
|
TMXR pas_desc = { 8, 0, 0, pas_ldsc }; /* mux descriptor */
|
||||||
#define PAS_ENAB pas_desc.lines
|
#define PAS_ENAB pas_desc.lines
|
||||||
|
|
||||||
uint32 pas (uint32 dev, uint32 op, uint32 dat);
|
uint32 pas (uint32 dev, uint32 op, uint32 dat);
|
||||||
|
@ -212,6 +213,10 @@ MTAB pasl_mod[] = {
|
||||||
{ UNIT_UC+UNIT_8B, UNIT_8B, "8b", "8B", NULL },
|
{ UNIT_UC+UNIT_8B, UNIT_8B, "8b", "8B", NULL },
|
||||||
{ UNIT_MDM, 0, "no dataset", "NODATASET", NULL },
|
{ UNIT_MDM, 0, "no dataset", "NODATASET", NULL },
|
||||||
{ UNIT_MDM, UNIT_MDM, "dataset", "DATASET", NULL },
|
{ UNIT_MDM, UNIT_MDM, "dataset", "DATASET", NULL },
|
||||||
|
{ MTAB_XTD|MTAB_VUN|MTAB_NC, 0, "LOG", "LOG",
|
||||||
|
&tmxr_set_log, &tmxr_show_log, &pas_desc },
|
||||||
|
{ MTAB_XTD|MTAB_VUN|MTAB_NC, 0, NULL, "NOLOG",
|
||||||
|
&tmxr_set_nolog, NULL, &pas_desc },
|
||||||
{ 0 } };
|
{ 0 } };
|
||||||
|
|
||||||
REG pasl_reg[] = {
|
REG pasl_reg[] = {
|
||||||
|
@ -270,7 +275,7 @@ case IO_OC: /* command */
|
||||||
if ((pas_cmd[ln] & CMD_DTR) && (pas_sta[ln] & STA_RING))
|
if ((pas_cmd[ln] & CMD_DTR) && (pas_sta[ln] & STA_RING))
|
||||||
pas_sta[ln] = pas_sta[ln] & ~(STA_CROF | STA_RING);
|
pas_sta[ln] = pas_sta[ln] & ~(STA_CROF | STA_RING);
|
||||||
if (old_cmd & ~pas_cmd[ln] & CMD_DTR) {
|
if (old_cmd & ~pas_cmd[ln] & CMD_DTR) {
|
||||||
tmxr_msg (pas_ldsc[ln].conn, "\r\nLine hangup\r\n");
|
tmxr_linemsg (&pas_ldsc[ln], "\r\nLine hangup\r\n");
|
||||||
tmxr_reset_ln (&pas_ldsc[ln]); /* reset line */
|
tmxr_reset_ln (&pas_ldsc[ln]); /* reset line */
|
||||||
pas_sta[ln] = pas_sta[ln] | STA_CROF; /* no carrier */
|
pas_sta[ln] = pas_sta[ln] | STA_CROF; /* no carrier */
|
||||||
if (pas_rarm[ln]) SET_INT (v_PAS + ln + ln); } }
|
if (pas_rarm[ln]) SET_INT (v_PAS + ln + ln); } }
|
||||||
|
@ -424,9 +429,7 @@ if (pas_unit.flags & UNIT_ATT) { /* master att? */
|
||||||
t = sim_rtcn_init (pas_unit.wait, TMR_PAS);
|
t = sim_rtcn_init (pas_unit.wait, TMR_PAS);
|
||||||
sim_activate (&pas_unit, t); } } /* activate */
|
sim_activate (&pas_unit, t); } } /* activate */
|
||||||
else sim_cancel (&pas_unit); /* else stop */
|
else sim_cancel (&pas_unit); /* else stop */
|
||||||
for (i = 0; i < PAS_LINES; i++) {
|
for (i = 0; i < PAS_LINES; i++) pas_reset_ln (i);
|
||||||
pas_desc.ldsc[i] = &pas_ldsc[i];
|
|
||||||
pas_reset_ln (i); }
|
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,7 +504,7 @@ if (newln < PAS_ENAB) {
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
for (i = newln; i < PAS_ENAB; i++) {
|
for (i = newln; i < PAS_ENAB; i++) {
|
||||||
if (pas_ldsc[i].conn) {
|
if (pas_ldsc[i].conn) {
|
||||||
tmxr_msg (pas_ldsc[i].conn, "\r\nOperator disconnected line\r\n");
|
tmxr_linemsg (&pas_ldsc[i], "\r\nOperator disconnected line\r\n");
|
||||||
tmxr_reset_ln (&pas_ldsc[i]); } /* reset line */
|
tmxr_reset_ln (&pas_ldsc[i]); } /* reset line */
|
||||||
pasl_unit[i].flags = pasl_unit[i].flags | UNIT_DIS;
|
pasl_unit[i].flags = pasl_unit[i].flags | UNIT_DIS;
|
||||||
pas_reset_ln (i); }
|
pas_reset_ln (i); }
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* id_pt.c: Interdata paper tape reader
|
/* id_pt.c: Interdata paper tape reader
|
||||||
|
|
||||||
Copyright (c) 2000-2003, Robert M. Supnik
|
Copyright (c) 2000-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -332,7 +332,7 @@ char *tptr;
|
||||||
extern DEVICE cpu_dev;
|
extern DEVICE cpu_dev;
|
||||||
|
|
||||||
if ((cptr == NULL) || (*cptr == 0)) return SCPE_2FARG;
|
if ((cptr == NULL) || (*cptr == 0)) return SCPE_2FARG;
|
||||||
tptr = get_range (cptr, &lo, &hi, cpu_dev.aradix, 0xFFFF, 0);
|
tptr = get_range (NULL, cptr, &lo, &hi, cpu_dev.aradix, 0xFFFF, 0);
|
||||||
if ((tptr == NULL) || (lo < INTSVT)) return SCPE_ARG;
|
if ((tptr == NULL) || (lo < INTSVT)) return SCPE_ARG;
|
||||||
if (*tptr != 0) return SCPE_2MARG;
|
if (*tptr != 0) return SCPE_2MARG;
|
||||||
for (i = lo, cs = 0; i <= hi; i++) cs = cs ^ IOReadB (i);
|
for (i = lo, cs = 0; i <= hi; i++) cs = cs ^ IOReadB (i);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* id_tt.c: Interdata teletype
|
/* id_tt.c: Interdata teletype
|
||||||
|
|
||||||
Copyright (c) 2000-2003, Robert M. Supnik
|
Copyright (c) 2000-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* id_uvc.c: Interdata universal clock
|
/* id_uvc.c: Interdata universal clock
|
||||||
|
|
||||||
Copyright (c) 2001-2003, Robert M. Supnik
|
Copyright (c) 2001-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
689
LGP/lgp_cpu.c
Normal file
689
LGP/lgp_cpu.c
Normal file
|
@ -0,0 +1,689 @@
|
||||||
|
/* lgp_cpu.c: LGP CPU simulator
|
||||||
|
|
||||||
|
Copyright (c) 2004, Robert M. Supnik
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
Except as contained in this notice, the name of Robert M Supnik shall not
|
||||||
|
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
cpu LGP-30 [LGP-21] CPU
|
||||||
|
|
||||||
|
The system state for the LGP-30 [LGP-21] is:
|
||||||
|
|
||||||
|
A<0:31> accumulator
|
||||||
|
C<0:11> counter (PC)
|
||||||
|
OVF overflow flag [LGP-21 only]
|
||||||
|
|
||||||
|
The LGP-30 [LGP-21] has just one instruction format:
|
||||||
|
|
||||||
|
1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
|
||||||
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|S| |opcode | | operand address | |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
|
LGP-30 instructions:
|
||||||
|
|
||||||
|
<0,12:15> operation
|
||||||
|
|
||||||
|
0 stop
|
||||||
|
1 A <- M[ea]
|
||||||
|
2 M[ea]<addr> <- A<addr>
|
||||||
|
3 M[ea]<addr> <- C + 1
|
||||||
|
4 input
|
||||||
|
5 A <- A / M[ea]
|
||||||
|
6 A <- A * M[ea], low result
|
||||||
|
7 A <- A * M[ea], high result
|
||||||
|
8 output
|
||||||
|
9 A <- A & M[ea]
|
||||||
|
A C <- ea
|
||||||
|
B C <- ea if A < 0
|
||||||
|
-B C <- ea if (A < 0) || T-switch set
|
||||||
|
C M[ea] <- A
|
||||||
|
D M[ea] <- A, A <- 0
|
||||||
|
E A <- A + M[ea]
|
||||||
|
F A <- A - M[ea]
|
||||||
|
|
||||||
|
LGP-21 instructions:
|
||||||
|
|
||||||
|
<0,12:15> operation
|
||||||
|
|
||||||
|
0 stop; sense and skip
|
||||||
|
-0 stop; sense overflow and skip
|
||||||
|
1 A <- M[ea]
|
||||||
|
2 M[ea]<addr> <- A<addr>
|
||||||
|
3 M[ea]<addr> <- C + 1
|
||||||
|
4 6b input
|
||||||
|
-4 4b input
|
||||||
|
5 A <- A / M[ea]
|
||||||
|
6 A <- A * M[ea], low result
|
||||||
|
7 A <- A * M[ea], high result
|
||||||
|
8 6b output
|
||||||
|
-8 4b output
|
||||||
|
9 A <- A & M[ea]
|
||||||
|
A C <- ea
|
||||||
|
B C <- ea if A < 0
|
||||||
|
-B C <- ea if (A < 0) || T-switch set
|
||||||
|
C M[ea] <- A
|
||||||
|
D M[ea] <- A, A <- 0
|
||||||
|
E A <- A + M[ea]
|
||||||
|
F A <- A - M[ea]
|
||||||
|
|
||||||
|
The LGP-30 [LGP-21] has 4096 32b words of memory. The low order
|
||||||
|
bit is always read and stored as 0. The LGP-30 uses a drum for
|
||||||
|
memory, with 64 tracks of 64 words. The LGP-21 uses a disk for
|
||||||
|
memory, with 32 tracks of 128 words.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This routine is the instruction decode routine for the LGP-30
|
||||||
|
[LGP-21]. It is called from the simulator control program to
|
||||||
|
execute instructions in simulated memory, starting at the simulated
|
||||||
|
PC. It runs until 'reason' is set non-zero.
|
||||||
|
|
||||||
|
General notes:
|
||||||
|
|
||||||
|
1. Reasons to stop. The simulator can be stopped by:
|
||||||
|
|
||||||
|
STOP instruction
|
||||||
|
breakpoint encountered
|
||||||
|
overflow [LGP-30]
|
||||||
|
I/O error in I/O simulator
|
||||||
|
|
||||||
|
2. Interrupts. There are no interrupts.
|
||||||
|
|
||||||
|
3. Non-existent memory. All of memory always exists.
|
||||||
|
|
||||||
|
4. Adding I/O devices. The LGP-30 could not support additional
|
||||||
|
I/O devices. The LGP-21 could but none are known.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lgp_defs.h"
|
||||||
|
|
||||||
|
#define PCQ_SIZE 64 /* must be 2**n */
|
||||||
|
#define PCQ_MASK (PCQ_SIZE - 1)
|
||||||
|
#define PCQ_ENTRY pcq[pcq_p = (pcq_p - 1) & PCQ_MASK] = (PC - 1) & AMASK;
|
||||||
|
#define M16 0xFFFF
|
||||||
|
#define M32 0xFFFFFFFF
|
||||||
|
#define NEG(x) ((~(x) + 1) & DMASK)
|
||||||
|
#define ABS(x) (((x) & SIGN)? NEG (x): (x))
|
||||||
|
|
||||||
|
uint32 M[MEMSIZE] = { 0 }; /* memory */
|
||||||
|
uint32 PC = 0; /* counter */
|
||||||
|
uint32 A = 0; /* accumulator */
|
||||||
|
uint32 IR = 0; /* instr register */
|
||||||
|
uint32 OVF = 0; /* overflow indicator */
|
||||||
|
uint32 t_switch = 0; /* transfer switch */
|
||||||
|
uint32 bp32 = 0; /* BP32 switch */
|
||||||
|
uint32 bp16 = 0; /* BP16 switch */
|
||||||
|
uint32 bp8 = 0; /* BP8 switch */
|
||||||
|
uint32 bp4 = 0; /* BP4 switch */
|
||||||
|
uint32 inp_strt = 0; /* input started */
|
||||||
|
uint32 inp_done = 0; /* input done */
|
||||||
|
uint32 out_strt = 0; /* output started */
|
||||||
|
uint32 out_done = 0; /* output done */
|
||||||
|
uint32 lgp21_sov = 0; /* LGP-21 sense pending */
|
||||||
|
int32 delay = 0;
|
||||||
|
int16 pcq[PCQ_SIZE] = { 0 }; /* PC queue */
|
||||||
|
int32 pcq_p = 0; /* PC queue ptr */
|
||||||
|
REG *pcq_r = NULL; /* PC queue reg ptr */
|
||||||
|
|
||||||
|
extern int32 sim_interval;
|
||||||
|
extern int32 sim_int_char;
|
||||||
|
extern int32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
|
||||||
|
extern int32 sim_step;
|
||||||
|
|
||||||
|
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_model (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||||
|
t_stat cpu_show_model (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||||
|
t_stat cpu_set_30opt (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||||
|
t_stat cpu_set_30opt_i (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||||
|
t_stat cpu_set_30opt_o (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||||
|
t_stat cpu_set_fill (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||||
|
t_stat cpu_set_exec (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||||
|
t_stat cpu_one_inst (uint32 opc, uint32 ir);
|
||||||
|
uint32 Mul64 (uint32 a, uint32 b, uint32 *low);
|
||||||
|
t_bool Div32 (uint32 dvd, uint32 dvr, uint32 *q);
|
||||||
|
uint32 I_delay (uint32 opc, uint32 ea, uint32 op);
|
||||||
|
uint32 shift_in (uint32 a, uint32 dat, uint32 sh4);
|
||||||
|
|
||||||
|
extern t_stat op_p (uint32 dev, uint32 ch);
|
||||||
|
extern t_stat op_i (uint32 dev, uint32 ch, uint32 sh4);
|
||||||
|
|
||||||
|
/* CPU data structures
|
||||||
|
|
||||||
|
cpu_dev CPU device descriptor
|
||||||
|
cpu_unit CPU unit descriptor
|
||||||
|
cpu_reg CPU register list
|
||||||
|
cpu_mod CPU modifiers list
|
||||||
|
*/
|
||||||
|
|
||||||
|
UNIT cpu_unit = { UDATA (NULL, UNIT_FIX+UNIT_IN4B+UNIT_TTSS_D, MEMSIZE) };
|
||||||
|
|
||||||
|
REG cpu_reg[] = {
|
||||||
|
{ DRDATA (C, PC, 12), REG_VMAD },
|
||||||
|
{ HRDATA (A, A, 32), REG_VMIO },
|
||||||
|
{ HRDATA (IR, IR, 32), REG_VMIO },
|
||||||
|
{ FLDATA (OVF, OVF, 0) },
|
||||||
|
{ FLDATA (TSW, t_switch, 0) },
|
||||||
|
{ FLDATA (BP32, bp32, 0) },
|
||||||
|
{ FLDATA (BP16, bp16, 0) },
|
||||||
|
{ FLDATA (BP8, bp8, 0) },
|
||||||
|
{ FLDATA (BP4, bp4, 0) },
|
||||||
|
{ FLDATA (INPST, inp_strt, 0) },
|
||||||
|
{ FLDATA (INPDN, inp_done, 0) },
|
||||||
|
{ FLDATA (OUTST, out_strt, 0) },
|
||||||
|
{ FLDATA (OUTDN, out_done, 0) },
|
||||||
|
{ DRDATA (DELAY, delay, 7) },
|
||||||
|
{ BRDATA (CQ, pcq, 16, 12, PCQ_SIZE), REG_RO + REG_CIRC },
|
||||||
|
{ HRDATA (CQP, pcq_p, 6), REG_HRO },
|
||||||
|
{ HRDATA (WRU, sim_int_char, 8) },
|
||||||
|
{ NULL } };
|
||||||
|
|
||||||
|
MTAB cpu_mod[] = {
|
||||||
|
{ UNIT_LGP21, UNIT_LGP21, "LGP-21", "LGP21", &cpu_set_model, &cpu_show_model },
|
||||||
|
{ UNIT_LGP21, 0, "LGP-30", "LGP30", &cpu_set_model, &cpu_show_model },
|
||||||
|
{ UNIT_TTSS_D, UNIT_TTSS_D, 0, "TRACK" },
|
||||||
|
{ UNIT_TTSS_D, 0, 0, "NORMAL" },
|
||||||
|
{ UNIT_LGPH_D, UNIT_LGPH_D, 0, "LGPHEX" },
|
||||||
|
{ UNIT_LGPH_D, 0, 0, "STANDARDHEX" },
|
||||||
|
{ UNIT_MANI, UNIT_MANI, NULL, "MANUAL" },
|
||||||
|
{ UNIT_MANI, 0, NULL, "TAPE" },
|
||||||
|
{ UNIT_IN4B, UNIT_IN4B, NULL, "4B", &cpu_set_30opt },
|
||||||
|
{ UNIT_IN4B, 0, NULL, "6B", &cpu_set_30opt },
|
||||||
|
{ MTAB_XTD|MTAB_VDV, 0, NULL, "INPUT", &cpu_set_30opt_i },
|
||||||
|
{ MTAB_XTD|MTAB_VDV, 0, NULL, "OUTPUT", &cpu_set_30opt_o },
|
||||||
|
{ MTAB_XTD|MTAB_VDV, 0, NULL, "EXECUTE", &cpu_set_exec },
|
||||||
|
{ MTAB_XTD|MTAB_VDV, 0, NULL, "FILL", &cpu_set_fill },
|
||||||
|
{ 0 } };
|
||||||
|
|
||||||
|
DEVICE cpu_dev = {
|
||||||
|
"CPU", &cpu_unit, cpu_reg, cpu_mod,
|
||||||
|
1, 10, 12, 1, 16, 32,
|
||||||
|
&cpu_ex, &cpu_dep, &cpu_reset,
|
||||||
|
NULL, NULL, NULL };
|
||||||
|
|
||||||
|
/* Timing tables */
|
||||||
|
|
||||||
|
/* Optimization minima and maxima
|
||||||
|
Z B Y R I D N M P E U T H C A S */
|
||||||
|
|
||||||
|
static const int32 min_30[16] = {
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 };
|
||||||
|
static const int32 max_30[16] = {
|
||||||
|
7, 7, 7, 7, 7, 5, 8, 6, 7, 7, 0, 0, 7, 7, 7, 7 };
|
||||||
|
static const int32 min_21[16] = {
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 };
|
||||||
|
static const int32 max_21[16] = {
|
||||||
|
0, 16, 16, 16, 0, 58, 81, 79, 0, 16, 0, 0, 16, 16, 16, 16 };
|
||||||
|
|
||||||
|
static const uint32 log_to_phys_30[NSC_30] = { /* drum interlace chart */
|
||||||
|
0, 57, 50, 43, 36, 29, 22, 15, 8 ,
|
||||||
|
1, 58, 51, 44, 37, 30, 23, 16, 9 ,
|
||||||
|
2, 59, 52, 45, 38, 31, 24, 17, 10,
|
||||||
|
3, 60, 53, 46, 39, 32, 25, 18, 11,
|
||||||
|
4, 61, 54, 47, 40, 33, 26, 19, 12,
|
||||||
|
5, 62, 55, 48, 41, 32, 27, 20, 13,
|
||||||
|
6, 63, 56, 49, 42, 33, 28, 21, 14,
|
||||||
|
7 };
|
||||||
|
|
||||||
|
static const uint32 log_to_phys_21[NSC_21] = { /* disk interlace chart */
|
||||||
|
0, 64, 57, 121, 50, 114, 43, 107, 36, 100, 29, 93, 22, 86, 15, 79, 8, 72,
|
||||||
|
1, 65, 58, 122, 51, 115, 44, 108, 37, 101, 30, 94, 23, 87, 16, 80, 9, 73,
|
||||||
|
2, 66, 59, 123, 52, 116, 45, 109, 38, 102, 31, 95, 24, 88, 17, 81, 10, 74,
|
||||||
|
3, 67, 60, 124, 53, 117, 46, 110, 39, 103, 32, 96, 25, 89, 18, 82, 11, 75,
|
||||||
|
4, 68, 61, 125, 54, 118, 47, 111, 40, 104, 33, 97, 26, 90, 19, 83, 12, 76,
|
||||||
|
5, 69, 62, 126, 55, 119, 48, 112, 41, 105, 34, 98, 27, 91, 20, 84, 12, 77,
|
||||||
|
6, 70, 63, 127, 56, 120, 49, 113, 42, 106, 35, 99, 28, 92, 21, 85, 13, 78,
|
||||||
|
7, 71 };
|
||||||
|
|
||||||
|
t_stat sim_instr (void)
|
||||||
|
{
|
||||||
|
t_stat r = 0;
|
||||||
|
uint32 oPC;
|
||||||
|
|
||||||
|
/* Restore register state */
|
||||||
|
|
||||||
|
PC = PC & AMASK; /* mask PC */
|
||||||
|
sim_cancel_step (); /* defang SCP step */
|
||||||
|
if (lgp21_sov) { /* stop sense pending? */
|
||||||
|
lgp21_sov = 0;
|
||||||
|
if (!OVF) PC = (PC + 1) & AMASK; /* ovf off? skip */
|
||||||
|
else OVF = 0; } /* on? reset */
|
||||||
|
|
||||||
|
/* Main instruction fetch/decode loop */
|
||||||
|
|
||||||
|
do { if (sim_interval <= 0) { /* check clock queue */
|
||||||
|
if (r = sim_process_event ()) break; }
|
||||||
|
|
||||||
|
if (delay > 0) { /* delay to next instr */
|
||||||
|
delay = delay - 1; /* count down delay */
|
||||||
|
sim_interval = sim_interval - 1;
|
||||||
|
continue; } /* skip execution */
|
||||||
|
|
||||||
|
if (sim_brk_summ && /* breakpoint? */
|
||||||
|
sim_brk_test (PC, SWMASK ('E'))) {
|
||||||
|
r = STOP_IBKPT; /* stop simulation */
|
||||||
|
break; }
|
||||||
|
|
||||||
|
IR = Read (oPC = PC); /* get instruction */
|
||||||
|
PC = (PC + 1) & AMASK; /* increment PC */
|
||||||
|
sim_interval = sim_interval - 1;
|
||||||
|
|
||||||
|
if (r = cpu_one_inst (oPC, IR)) { /* one instr; error? */
|
||||||
|
if (r == STOP_STALL) { /* stall? */
|
||||||
|
PC = oPC; /* back up PC */
|
||||||
|
delay = r = 0; } /* no delay */
|
||||||
|
else break; }
|
||||||
|
|
||||||
|
if (sim_step && (--sim_step <= 0)) /* do step count */
|
||||||
|
r = SCPE_STOP;
|
||||||
|
|
||||||
|
} while (r == 0); /* loop until halted */
|
||||||
|
pcq_r->qptr = pcq_p; /* update pc q ptr */
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Execute one instruction */
|
||||||
|
|
||||||
|
t_stat cpu_one_inst (uint32 opc, uint32 ir)
|
||||||
|
{
|
||||||
|
uint32 ea, op, dat, res, dev, sh4, ch;
|
||||||
|
t_bool ovf_this_cycle = FALSE;
|
||||||
|
t_stat reason = 0;
|
||||||
|
|
||||||
|
op = I_GETOP (ir); /* opcode */
|
||||||
|
ea = I_GETEA (ir); /* address */
|
||||||
|
switch (op) { /* case on opcode */
|
||||||
|
|
||||||
|
/* Loads, stores, transfers instructions */
|
||||||
|
|
||||||
|
case OP_B: /* bring */
|
||||||
|
A = Read (ea); /* A <- M[ea] */
|
||||||
|
delay = I_delay (opc, ea, op);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_H: /* hold */
|
||||||
|
Write (ea, A); /* M[ea] <- A */
|
||||||
|
delay = I_delay (opc, ea, op);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_C: /* clear */
|
||||||
|
Write (ea, A); /* M[ea] <- A */
|
||||||
|
A = 0; /* A <- 0 */
|
||||||
|
delay = I_delay (opc, ea, op);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_Y: /* store address */
|
||||||
|
dat = Read (ea); /* get operand */
|
||||||
|
dat = (dat & ~I_EA) | (A & I_EA); /* merge address */
|
||||||
|
Write (ea, dat);
|
||||||
|
delay = I_delay (opc, ea, op);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_R: /* return address */
|
||||||
|
dat = Read (ea); /* get operand */
|
||||||
|
dat = (dat & ~I_EA) | (((PC + 1) & AMASK) << I_V_EA);
|
||||||
|
Write (ea, dat);
|
||||||
|
delay = I_delay (opc, ea, op);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_U: /* uncond transfer */
|
||||||
|
PCQ_ENTRY;
|
||||||
|
PC = ea; /* transfer */
|
||||||
|
delay = I_delay (opc, ea, op);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_T: /* conditional transfer */
|
||||||
|
if ((A & SIGN) || /* A < 0 or */
|
||||||
|
((ir & SIGN) && t_switch)) { /* -T and Tswitch set? */
|
||||||
|
PCQ_ENTRY;
|
||||||
|
PC = ea; } /* transfer */
|
||||||
|
delay = I_delay (opc, ea, op);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Arithmetic and logical instructions */
|
||||||
|
|
||||||
|
case OP_A: /* add */
|
||||||
|
dat = Read (ea); /* get operand */
|
||||||
|
res = (A + dat) & DMASK; /* add */
|
||||||
|
if ((~A ^ dat) & (dat ^ res) & SIGN) /* calc overflow */
|
||||||
|
ovf_this_cycle = TRUE;
|
||||||
|
A = res; /* save result */
|
||||||
|
delay = I_delay (opc, ea, op);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_S: /* sub */
|
||||||
|
dat = Read (ea); /* get operand */
|
||||||
|
res = (A - dat) & DMASK; /* subtract */
|
||||||
|
if ((A ^ dat) & (~dat ^ res) & SIGN) /* calc overflow */
|
||||||
|
ovf_this_cycle = TRUE;
|
||||||
|
A = res;
|
||||||
|
delay = I_delay (opc, ea, op);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_M: /* multiply high */
|
||||||
|
dat = Read (ea); /* get operand */
|
||||||
|
A = (Mul64 (A, dat, NULL) << 1) & DMASK; /* multiply */
|
||||||
|
delay = I_delay (opc, ea, op);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_N: /* multiply low */
|
||||||
|
dat = Read (ea); /* get operand */
|
||||||
|
Mul64 (A, dat, &res); /* multiply */
|
||||||
|
A = res; /* keep low result */
|
||||||
|
delay = I_delay (opc, ea, op); /* total delay */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_D: /* divide */
|
||||||
|
dat = Read (ea); /* get operand */
|
||||||
|
if (Div32 (A, dat, &A)) ovf_this_cycle = TRUE; /* divide; overflow? */
|
||||||
|
delay = I_delay (opc, ea, op);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_E: /* extract */
|
||||||
|
dat = Read (ea); /* get operand */
|
||||||
|
A = A & dat; /* and */
|
||||||
|
delay = I_delay (opc, ea, op);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* IO instructions */
|
||||||
|
|
||||||
|
case OP_P: /* output */
|
||||||
|
if (Q_LGP21) { /* LGP-21 */
|
||||||
|
ch = A >> 26; /* char, 6b */
|
||||||
|
if (ir & SIGN) ch = (ch & 0x3C) | 2; /* 4b? convert */
|
||||||
|
dev = I_GETTK (ir); } /* device select */
|
||||||
|
else { /* LGP-30 */
|
||||||
|
ch = I_GETTK (ir); /* char, always 6b */
|
||||||
|
dev = Q_OUTPT? DEV_PT: DEV_TT; } /* device select */
|
||||||
|
reason = op_p (dev & DEV_MASK, ch); /* output */
|
||||||
|
delay = I_delay (sim_grtime (), ea, op); /* next instruction */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_I: /* input */
|
||||||
|
if (Q_LGP21) { /* LGP-21 */
|
||||||
|
ch = 0; /* initial shift */
|
||||||
|
sh4 = ir & SIGN; /* 4b/6b select */
|
||||||
|
dev = I_GETTK (ir); } /* device select */
|
||||||
|
else { /* LGP-30 */
|
||||||
|
ch = I_GETTK (ir); /* initial shift */
|
||||||
|
sh4 = Q_IN4B; /* 4b/6b select */
|
||||||
|
dev = Q_INPT? DEV_PT: DEV_TT; } /* device select */
|
||||||
|
if (dev == DEV_SHIFT) /* shift? */
|
||||||
|
A = shift_in (A, 0, sh4); /* shift 4/6b */
|
||||||
|
else reason = op_i (dev & DEV_MASK, ch, sh4); /* input */
|
||||||
|
delay = I_delay (sim_grtime (), ea, op); /* next instruction */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_Z:
|
||||||
|
if (Q_LGP21) { /* LGP-21 */
|
||||||
|
if (ea & 0xF80) { /* no stop? */
|
||||||
|
if (((ea & 0x800) && !bp32) || /* skip if any */
|
||||||
|
((ea & 0x400) && !bp16) || /* selected switch */
|
||||||
|
((ea & 0x200) && !bp8) || /* is off */
|
||||||
|
((ea & 0x100) && !bp4) || /* or if */
|
||||||
|
((ir & SIGN) && !OVF)) /* ovf sel and off */
|
||||||
|
PC = (PC + 1) & AMASK;
|
||||||
|
if (ir & SIGN) OVF = 0; } /* -Z? clr overflow */
|
||||||
|
else { /* stop */
|
||||||
|
lgp21_sov = (ir & SIGN)? 1: 0; /* pending sense? */
|
||||||
|
reason = STOP_STOP; } } /* stop */
|
||||||
|
else { /* LGP-30 */
|
||||||
|
if (out_done) out_done = 0; /* P complete? */
|
||||||
|
else if (((ea & 0x800) && bp32) || /* bpt switch set? */
|
||||||
|
((ea & 0x400) && bp16) ||
|
||||||
|
((ea & 0x200) && bp8) ||
|
||||||
|
((ea & 0x100) && bp4)) ; /* don't stop or stall */
|
||||||
|
else if (out_strt) reason = STOP_STALL; /* P pending? stall */
|
||||||
|
else reason = STOP_STOP; } /* no, stop */
|
||||||
|
delay = I_delay (sim_grtime (), ea, op); /* next instruction */
|
||||||
|
break; } /* end switch */
|
||||||
|
|
||||||
|
if (ovf_this_cycle) {
|
||||||
|
if (Q_LGP21) OVF = 1; /* LGP-21? set OVF */
|
||||||
|
else reason = STOP_OVF; } /* LGP-30? stop */
|
||||||
|
return reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Support routines */
|
||||||
|
|
||||||
|
uint32 Read (uint32 ea)
|
||||||
|
{
|
||||||
|
return M[ea] & MMASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Write (uint32 ea, uint32 dat)
|
||||||
|
{
|
||||||
|
M[ea] = dat & MMASK;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Input shift */
|
||||||
|
|
||||||
|
uint32 shift_in (uint32 a, uint32 dat, uint32 sh4)
|
||||||
|
{
|
||||||
|
if (sh4) return (((a << 4) | (dat >> 2)) & DMASK);
|
||||||
|
return (((a << 6) | dat) & DMASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 32b * 32b multiply, signed */
|
||||||
|
|
||||||
|
uint32 Mul64 (uint32 a, uint32 b, uint32 *low)
|
||||||
|
{
|
||||||
|
uint32 sgn = a ^ b;
|
||||||
|
uint32 ah, bh, al, bl, rhi, rlo, rmid1, rmid2;
|
||||||
|
|
||||||
|
if ((a == 0) || (b == 0)) { /* zero argument? */
|
||||||
|
if (low) *low = 0;
|
||||||
|
return 0; }
|
||||||
|
a = ABS (a);
|
||||||
|
b = ABS (b);
|
||||||
|
ah = (a >> 16) & M16; /* split operands */
|
||||||
|
bh = (b >> 16) & M16; /* into 16b chunks */
|
||||||
|
al = a & M16;
|
||||||
|
bl = b & M16;
|
||||||
|
rhi = ah * bh; /* high result */
|
||||||
|
rmid1 = ah * bl;
|
||||||
|
rmid2 = al * bh;
|
||||||
|
rlo = al * bl;
|
||||||
|
rhi = rhi + ((rmid1 >> 16) & M16) + ((rmid2 >> 16) & M16);
|
||||||
|
rmid1 = (rlo + (rmid1 << 16)) & M32; /* add mid1 to lo */
|
||||||
|
if (rmid1 < rlo) rhi = rhi + 1; /* carry? incr hi */
|
||||||
|
rmid2 = (rmid1 + (rmid2 << 16)) & M32; /* add mid2 to to */
|
||||||
|
if (rmid2 < rmid1) rhi = rhi + 1; /* carry? incr hi */
|
||||||
|
if (sgn & SIGN) { /* result negative? */
|
||||||
|
rmid2 = NEG (rmid2); /* negate */
|
||||||
|
rhi = (~rhi + (rmid2 == 0)) & M32; }
|
||||||
|
if (low) *low = rmid2; /* low result */
|
||||||
|
return rhi & M32;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 32b/32b divide (done as 32b'0/32b) */
|
||||||
|
|
||||||
|
t_bool Div32 (uint32 dvd, uint32 dvr, uint32 *q)
|
||||||
|
{
|
||||||
|
uint32 sgn = dvd ^ dvr;
|
||||||
|
uint32 i, quo;
|
||||||
|
|
||||||
|
dvd = ABS (dvd);
|
||||||
|
dvr = ABS (dvr);
|
||||||
|
if (dvd >= dvr) return TRUE;
|
||||||
|
for (i = quo = 0; i < 31; i++) { /* 31 iterations */
|
||||||
|
quo = quo << 1; /* shift quotient */
|
||||||
|
dvd = dvd << 1; /* shift dividend */
|
||||||
|
if (dvd >= dvr) { /* step work? */
|
||||||
|
dvd = (dvd - dvr) & M32; /* subtract dvr */
|
||||||
|
quo = quo + 1; } }
|
||||||
|
quo = (quo + 1) & MMASK; /* round low bit */
|
||||||
|
if (sgn & SIGN) quo = NEG (quo); /* result -? */
|
||||||
|
if (q) *q = quo; /* return quo */
|
||||||
|
return FALSE; /* no overflow */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rotational delay */
|
||||||
|
|
||||||
|
uint32 I_delay (uint32 opc, uint32 ea, uint32 op)
|
||||||
|
{
|
||||||
|
uint32 tmin = Q_LGP21? min_21[op]: min_30[op];
|
||||||
|
uint32 tmax = Q_LGP21? max_21[op]: max_30[op];
|
||||||
|
uint32 nsc, curp, newp, oprp, pcdelta, opdelta;
|
||||||
|
|
||||||
|
if (Q_LGP21) { /* LGP21 */
|
||||||
|
nsc = NSC_21; /* full rotation delay */
|
||||||
|
curp = log_to_phys_21[opc & SCMASK_21]; /* current phys pos */
|
||||||
|
newp = log_to_phys_21[PC & SCMASK_21]; /* new PC phys pos */
|
||||||
|
oprp = log_to_phys_21[ea & SCMASK_21]; /* ea phys pos */
|
||||||
|
pcdelta = (newp - curp + NSC_21) & SCMASK_21;
|
||||||
|
opdelta = (oprp - curp + NSC_21) & SCMASK_21; }
|
||||||
|
else { nsc = NSC_30;
|
||||||
|
curp = log_to_phys_30[opc & SCMASK_30];
|
||||||
|
newp = log_to_phys_30[PC & SCMASK_30];
|
||||||
|
oprp = log_to_phys_30[ea & SCMASK_30];
|
||||||
|
pcdelta = (newp - curp + NSC_30) & SCMASK_30;
|
||||||
|
opdelta = (oprp - curp + NSC_30) & SCMASK_30; }
|
||||||
|
if (tmax == 0) { /* skip ea calc? */
|
||||||
|
if (pcdelta >= tmin) return pcdelta - 1; /* new PC >= min? */
|
||||||
|
return pcdelta + nsc - 1; }
|
||||||
|
if ((opdelta >= tmin) && (opdelta <= tmax)) return pcdelta - 1;
|
||||||
|
return pcdelta + nsc - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset routine */
|
||||||
|
|
||||||
|
t_stat cpu_reset (DEVICE *dptr)
|
||||||
|
{
|
||||||
|
OVF = 0;
|
||||||
|
inp_strt = 0;
|
||||||
|
inp_done = 0;
|
||||||
|
out_strt = 0;
|
||||||
|
out_done = 0;
|
||||||
|
lgp21_sov = 0;
|
||||||
|
delay = 0;
|
||||||
|
pcq_r = find_reg ("CQ", NULL, dptr);
|
||||||
|
if (pcq_r) pcq_r->qptr = 0;
|
||||||
|
else return SCPE_IERR;
|
||||||
|
sim_brk_types = sim_brk_dflt = SWMASK ('E');
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate option, must be LGP30 */
|
||||||
|
|
||||||
|
t_stat cpu_set_30opt (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||||
|
{
|
||||||
|
if (Q_LGP21) return SCPE_ARG;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate input option, must be LGP30 */
|
||||||
|
|
||||||
|
t_stat cpu_set_30opt_i (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||||
|
{
|
||||||
|
if (Q_LGP21 || (cptr == NULL)) return SCPE_ARG;
|
||||||
|
if (strcmp (cptr, "TTI") == 0) uptr->flags = uptr->flags & ~UNIT_INPT;
|
||||||
|
else if (strcmp (cptr, "PTR") == 0) uptr->flags = uptr->flags | UNIT_INPT;
|
||||||
|
else return SCPE_ARG;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate output option, must be LGP30 */
|
||||||
|
|
||||||
|
t_stat cpu_set_30opt_o (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||||
|
{
|
||||||
|
if (Q_LGP21 || (cptr == NULL)) return SCPE_ARG;
|
||||||
|
if (strcmp (cptr, "TTO") == 0) uptr->flags = uptr->flags & ~UNIT_OUTPT;
|
||||||
|
else if (strcmp (cptr, "PTP") == 0) uptr->flags = uptr->flags | UNIT_OUTPT;
|
||||||
|
else return SCPE_ARG;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set CPU to LGP21 or LPG30 */
|
||||||
|
|
||||||
|
t_stat cpu_set_model (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||||
|
{
|
||||||
|
if (val) uptr->flags = uptr->flags & ~(UNIT_IN4B|UNIT_INPT|UNIT_OUTPT);
|
||||||
|
return reset_all (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Show CPU type and all options */
|
||||||
|
|
||||||
|
t_stat cpu_show_model (FILE *st, UNIT *uptr, int32 val, void *desc)
|
||||||
|
{
|
||||||
|
fputs (Q_LGP21? "LGP-21": "LGP-30", st);
|
||||||
|
if (uptr->flags & UNIT_TTSS_D) fputs (", track/sector", st);
|
||||||
|
if (uptr->flags & UNIT_LGPH_D) fputs (", LGP hex", st);
|
||||||
|
fputs (Q_MANI? ", manual": ", tape", st);
|
||||||
|
if (!Q_LGP21) {
|
||||||
|
fputs (Q_IN4B? ", 4b": ", 6b", st);
|
||||||
|
fputs (Q_INPT? ", in=PTR": ", in=TTI", st);
|
||||||
|
fputs (Q_OUTPT? ", out=PTP": ", out=TTO", st); }
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Memory examine */
|
||||||
|
|
||||||
|
t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw)
|
||||||
|
{
|
||||||
|
if (addr >= MEMSIZE) return SCPE_NXM;
|
||||||
|
if (vptr != NULL) *vptr = Read (addr);
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Memory deposit */
|
||||||
|
|
||||||
|
t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw)
|
||||||
|
{
|
||||||
|
if (addr >= MEMSIZE) return SCPE_NXM;
|
||||||
|
Write (addr, val);
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Execute */
|
||||||
|
|
||||||
|
t_stat cpu_set_exec (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||||
|
{
|
||||||
|
uint32 inst;
|
||||||
|
t_stat r;
|
||||||
|
|
||||||
|
if (cptr) {
|
||||||
|
inst = get_uint (cptr, 16, DMASK, &r);
|
||||||
|
if (r != SCPE_OK) r; }
|
||||||
|
else inst = IR;
|
||||||
|
while ((r = cpu_one_inst (PC, inst)) == STOP_STALL) {
|
||||||
|
sim_interval = 0;
|
||||||
|
if (r = sim_process_event ()) return r; }
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill */
|
||||||
|
|
||||||
|
t_stat cpu_set_fill (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||||
|
{
|
||||||
|
uint32 inst;
|
||||||
|
t_stat r;
|
||||||
|
|
||||||
|
if (cptr) {
|
||||||
|
inst = get_uint (cptr, 16, DMASK, &r);
|
||||||
|
if (r != SCPE_OK) r;
|
||||||
|
IR = inst; }
|
||||||
|
else IR = A;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
134
LGP/lgp_defs.h
Normal file
134
LGP/lgp_defs.h
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
/* lgp_defs.h: LGP simulator definitions
|
||||||
|
|
||||||
|
Copyright (c) 2004, Robert M. Supnik
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
Except as contained in this notice, the name of Robert M Supnik shall not
|
||||||
|
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LGP_DEFS_H_
|
||||||
|
#define _LGP_DEFS_H_ 0
|
||||||
|
|
||||||
|
#include "sim_defs.h" /* simulator defns */
|
||||||
|
|
||||||
|
/* Simulator stop codes */
|
||||||
|
|
||||||
|
#define STOP_STOP 1 /* STOP */
|
||||||
|
#define STOP_IBKPT 2 /* breakpoint */
|
||||||
|
#define STOP_OVF 3 /* overflow */
|
||||||
|
#define STOP_NXDEV 4 /* non-existent device */
|
||||||
|
#define STOP_STALL 5 /* IO stall */
|
||||||
|
|
||||||
|
/* Memory */
|
||||||
|
|
||||||
|
#define MEMSIZE 4096 /* memory size */
|
||||||
|
#define AMASK 0xFFF /* addr mask */
|
||||||
|
#define NTK_30 64
|
||||||
|
#define NSC_30 64
|
||||||
|
#define SCMASK_30 0x03F /* sector mask */
|
||||||
|
#define NTK_21 32
|
||||||
|
#define NSC_21 128
|
||||||
|
#define SCMASK_21 0x07F
|
||||||
|
#define RPM 4000 /* rev/minutes */
|
||||||
|
#define WPS ((NSC_30 * RPM) / 60) /* words/second */
|
||||||
|
|
||||||
|
/* Architectural constants */
|
||||||
|
|
||||||
|
#define SIGN 0x80000000 /* sign */
|
||||||
|
#define DMASK 0xFFFFFFFF /* data mask */
|
||||||
|
#define MMASK 0xFFFFFFFE /* memory mask */
|
||||||
|
|
||||||
|
/* Instruction format */
|
||||||
|
|
||||||
|
#define I_M_OP 0xF /* opcode */
|
||||||
|
#define I_V_OP 16
|
||||||
|
#define I_OP (I_M_OP << I_V_OP)
|
||||||
|
#define I_GETOP(x) (((x) >> I_V_OP) & I_M_OP)
|
||||||
|
#define I_M_EA AMASK /* address */
|
||||||
|
#define I_V_EA 2
|
||||||
|
#define I_EA (I_M_EA << I_V_EA)
|
||||||
|
#define I_GETEA(x) (((x) >> I_V_EA) & I_M_EA)
|
||||||
|
#define I_M_TK 0x3F /* LGP-30 char */
|
||||||
|
#define I_V_TK 8 /* LGP-21 device */
|
||||||
|
#define I_GETTK(x) (((x) >> I_V_TK) & I_M_TK)
|
||||||
|
|
||||||
|
/* Unit flags */
|
||||||
|
|
||||||
|
#define UNIT_V_LGP21 (UNIT_V_UF + 0)
|
||||||
|
#define UNIT_V_MANI (UNIT_V_UF + 1)
|
||||||
|
#define UNIT_V_INPT (UNIT_V_UF + 2)
|
||||||
|
#define UNIT_V_OUTPT (UNIT_V_UF + 3)
|
||||||
|
#define UNIT_V_IN4B (UNIT_V_UF + 4)
|
||||||
|
#define UNIT_V_TTSS_D (UNIT_V_UF + 5)
|
||||||
|
#define UNIT_V_LGPH_D (UNIT_V_UF + 6)
|
||||||
|
#define UNIT_V_FLEX_D (UNIT_V_UF + 7) /* Flex default */
|
||||||
|
#define UNIT_V_FLEX (UNIT_V_UF + 8) /* Flex format */
|
||||||
|
#define UNIT_V_NOCS (UNIT_V_UF + 9) /* ignore cond stop */
|
||||||
|
#define UNIT_LGP21 (1u << UNIT_V_LGP21)
|
||||||
|
#define UNIT_MANI (1u << UNIT_V_MANI)
|
||||||
|
#define UNIT_INPT (1u << UNIT_V_INPT)
|
||||||
|
#define UNIT_OUTPT (1u << UNIT_V_OUTPT)
|
||||||
|
#define UNIT_IN4B (1u << UNIT_V_IN4B)
|
||||||
|
#define UNIT_TTSS_D (1u << UNIT_V_TTSS_D)
|
||||||
|
#define UNIT_LGPH_D (1u << UNIT_V_LGPH_D)
|
||||||
|
#define UNIT_FLEX_D (1u << UNIT_V_FLEX_D)
|
||||||
|
#define UNIT_FLEX (1u << UNIT_V_FLEX)
|
||||||
|
#define UNIT_NOCS (1u << UNIT_V_NOCS)
|
||||||
|
#define Q_LGP21 (cpu_unit.flags & UNIT_LGP21)
|
||||||
|
#define Q_MANI (cpu_unit.flags & UNIT_MANI)
|
||||||
|
#define Q_INPT (cpu_unit.flags & UNIT_INPT)
|
||||||
|
#define Q_OUTPT (cpu_unit.flags & UNIT_OUTPT)
|
||||||
|
#define Q_IN4B (cpu_unit.flags & UNIT_IN4B)
|
||||||
|
|
||||||
|
/* IO return */
|
||||||
|
|
||||||
|
#define IORETURN(f,v) ((f)? (v): SCPE_OK) /* stop on error */
|
||||||
|
|
||||||
|
/* Significant characters */
|
||||||
|
|
||||||
|
#define FLEX_LC 0x04
|
||||||
|
#define FLEX_UC 0x08
|
||||||
|
#define FLEX_CR 0x10
|
||||||
|
#define FLEX_BS 0x14
|
||||||
|
#define FLEX_CSTOP 0x20
|
||||||
|
#define FLEX_DEL 0x3F
|
||||||
|
|
||||||
|
/* LGP-21 device assignments */
|
||||||
|
|
||||||
|
#define DEV_PT 0
|
||||||
|
#define DEV_TT 2
|
||||||
|
#define DEV_MASK 0x1F
|
||||||
|
#define DEV_SHIFT 62
|
||||||
|
|
||||||
|
/* Instructions */
|
||||||
|
|
||||||
|
enum opcodes {
|
||||||
|
OP_Z, OP_B, OP_Y, OP_R,
|
||||||
|
OP_I, OP_D, OP_N, OP_M,
|
||||||
|
OP_P, OP_E, OP_U, OP_T,
|
||||||
|
OP_H, OP_C, OP_A, OP_S };
|
||||||
|
|
||||||
|
/* Prototypes */
|
||||||
|
|
||||||
|
uint32 Read (uint32 ea);
|
||||||
|
void Write (uint32 ea, uint32 dat);
|
||||||
|
|
||||||
|
#endif
|
465
LGP/lgp_doc.txt
Normal file
465
LGP/lgp_doc.txt
Normal file
|
@ -0,0 +1,465 @@
|
||||||
|
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.
|
597
LGP/lgp_stddev.c
Normal file
597
LGP/lgp_stddev.c
Normal file
|
@ -0,0 +1,597 @@
|
||||||
|
/* lgp_stddev.c: LGP-30 standard devices
|
||||||
|
|
||||||
|
Copyright (c) 2004, Robert M Supnik
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
Except as contained in this notice, the name of Robert M Supnik shall not
|
||||||
|
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
tti typewriter input (keyboard and reader)
|
||||||
|
tto typewriter output (printer and punch)
|
||||||
|
ptr high speed reader
|
||||||
|
ptpp high speed punch
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lgp_defs.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
uint32 tt_wait = WPS / 10;
|
||||||
|
uint32 tti_buf = 0;
|
||||||
|
uint32 tti_rdy = 0;
|
||||||
|
uint32 tto_uc = 0;
|
||||||
|
uint32 tto_buf = 0;
|
||||||
|
uint32 ttr_stopioe = 1;
|
||||||
|
uint32 ptr_rdy = 0;
|
||||||
|
uint32 ptr_stopioe = 1;
|
||||||
|
uint32 ptp_stopioe = 1;
|
||||||
|
|
||||||
|
extern uint32 A;
|
||||||
|
extern uint32 inp_strt, inp_done;
|
||||||
|
extern uint32 out_strt, out_done;
|
||||||
|
extern UNIT cpu_unit;
|
||||||
|
extern int32 sim_switches;
|
||||||
|
|
||||||
|
t_stat tti_svc (UNIT *uptr);
|
||||||
|
t_stat ttr_svc (UNIT *uptr);
|
||||||
|
t_stat tto_svc (UNIT *uptr);
|
||||||
|
t_stat tti_reset (DEVICE *uptr);
|
||||||
|
t_stat tto_reset (DEVICE *uptr);
|
||||||
|
t_stat ptr_svc (UNIT *uptr);
|
||||||
|
t_stat ptp_svc (UNIT *uptr);
|
||||||
|
t_stat ptr_reset (DEVICE *uptr);
|
||||||
|
t_stat ptp_reset (DEVICE *uptr);
|
||||||
|
t_stat tap_attach (UNIT *uptr, char *cptr);
|
||||||
|
t_stat tap_attable (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||||
|
t_stat read_reader (UNIT *uptr, int32 stop, int32 *c);
|
||||||
|
t_stat write_tto (int32 flex);
|
||||||
|
t_stat write_punch (UNIT *uptr, int32 flex);
|
||||||
|
t_stat tti_rdrss (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||||
|
t_stat punch_feed (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||||
|
t_stat send_start (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||||
|
|
||||||
|
extern uint32 shift_in (uint32 a, uint32 dat, uint32 sh4);
|
||||||
|
|
||||||
|
/* Conversion tables */
|
||||||
|
|
||||||
|
const int32 flex_to_ascii[128] = {
|
||||||
|
-1 , 'z', '0', ' ', '>', 'b', '1', '-',
|
||||||
|
'<' , 'y', '2', '+', '|', 'r', '3', ';',
|
||||||
|
'\r', 'i', '4', '/','\\', 'd', '5', '.',
|
||||||
|
'\t', 'n', '6', ',', -1 , 'm', '7', 'v',
|
||||||
|
'\'', 'p', '8', 'o', -1 , 'e', '9', 'x',
|
||||||
|
-1 , 'u', 'f', -1 , -1 , 't', 'g', -1 ,
|
||||||
|
-1 , 'h', 'j', -1 , -1 , 'c', 'k', -1 ,
|
||||||
|
-1 , 'a', 'q', -1 , -1 , 's', 'w', 0 ,
|
||||||
|
|
||||||
|
-1 , 'Z', ')', ' ', -1 , 'B', 'L', '_',
|
||||||
|
-1 , 'Y', '*', '=', '|', 'R', '"', ':',
|
||||||
|
'\r', 'I', '^', '?','\\', 'D', '%', ']',
|
||||||
|
'\t', 'N', '$', '[', -1 , 'M', '~', 'V',
|
||||||
|
'\'', 'P', '#', 'O', -1 , 'E', '(', 'X',
|
||||||
|
-1 , 'U', 'F', -1 , -1 , 'T', 'G', -1 ,
|
||||||
|
-1 , 'H', 'J', -1 , -1 , 'C', 'K', -1 ,
|
||||||
|
-1 , 'A', 'Q', -1 , -1 , 'S', 'W', 0 };
|
||||||
|
|
||||||
|
const int32 ascii_to_flex[128] = {
|
||||||
|
-1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
|
||||||
|
024, 030, -1 , -1 , -1 , 020, -1 , -1 ,
|
||||||
|
-1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
|
||||||
|
-1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
|
||||||
|
003, -1 , 016, 042, 032, 026, -1 , 040,
|
||||||
|
046, 001, 012, 013, 033, 007, 027, 023,
|
||||||
|
002, 006, 012, 016, 022, 026, 032, 036,
|
||||||
|
042, 046, 017, 017, 004, 013, 010, 023,
|
||||||
|
-1 , 071, 005, 065, 025, 045, 052, 056,
|
||||||
|
061, 021, 062, 066, 006, 035, 031, 043,
|
||||||
|
041, 072, 015, 075, 055, 051, 037, 076,
|
||||||
|
047, 011, 001, 033, -1 , 027, 022, 007,
|
||||||
|
- 1, 071, 005, 065, 025, 045, 052, 056,
|
||||||
|
061, 021, 062, 066, 006, 035, 031, 043,
|
||||||
|
041, 072, 015, 075, 055, 051, 037, 076,
|
||||||
|
047, 011, 001, -1 , 014, -1 , 036, 077 };
|
||||||
|
|
||||||
|
static const uint8 flex_inp_valid[64] = {
|
||||||
|
1, 1, 1, 1, 0, 1, 1, 1,
|
||||||
|
0, 1, 1, 1, 0, 1, 1, 1,
|
||||||
|
0, 1, 1, 1, 0, 1, 1, 1,
|
||||||
|
0, 1, 1, 1, 0, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 0, 1, 1, 1,
|
||||||
|
0, 1, 1, 1, 0, 1, 1, 1,
|
||||||
|
0, 1, 1, 1, 0, 1, 1, 1,
|
||||||
|
0, 1, 1, 1, 0, 1, 1, 1 };
|
||||||
|
|
||||||
|
/* TTI data structures
|
||||||
|
|
||||||
|
tti_dev TTI device descriptor
|
||||||
|
tti_unit TTI unit descriptor
|
||||||
|
tti_mod TTI modifier list
|
||||||
|
tti_reg TTI register list
|
||||||
|
*/
|
||||||
|
|
||||||
|
UNIT tti_unit[] = {
|
||||||
|
{ UDATA (&tti_svc, 0, 0) },
|
||||||
|
{ UDATA (&ttr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0) } };
|
||||||
|
|
||||||
|
REG tti_reg[] = {
|
||||||
|
{ HRDATA (BUF, tti_buf, 6) },
|
||||||
|
{ FLDATA (RDY, tti_rdy, 0) },
|
||||||
|
{ DRDATA (KPOS, tti_unit[0].pos, T_ADDR_W), PV_LEFT },
|
||||||
|
{ DRDATA (RPOS, tti_unit[1].pos, T_ADDR_W), PV_LEFT },
|
||||||
|
{ DRDATA (TIME, tt_wait, 24), REG_NZ + PV_LEFT },
|
||||||
|
{ FLDATA (STOP_IOE, ttr_stopioe, 0) },
|
||||||
|
{ NULL } };
|
||||||
|
|
||||||
|
MTAB tti_mod[] = {
|
||||||
|
{ UNIT_FLEX_D, UNIT_FLEX_D, NULL, "FLEX", &tap_attable },
|
||||||
|
{ UNIT_FLEX_D, 0, NULL, "ASCII", &tap_attable },
|
||||||
|
{ UNIT_ATT+UNIT_FLEX, UNIT_ATT+UNIT_FLEX,
|
||||||
|
"file is Flex", NULL },
|
||||||
|
{ UNIT_ATT+UNIT_FLEX, UNIT_ATT,
|
||||||
|
"file is ASCII", NULL },
|
||||||
|
{ UNIT_ATTABLE+UNIT_ATT+UNIT_FLEX, UNIT_ATTABLE+UNIT_FLEX,
|
||||||
|
"default is Flex", NULL },
|
||||||
|
{ UNIT_ATTABLE+UNIT_ATT+UNIT_FLEX, UNIT_ATTABLE,
|
||||||
|
"default is ASCII", NULL },
|
||||||
|
{ UNIT_ATTABLE+UNIT_NOCS, UNIT_ATTABLE+UNIT_NOCS,
|
||||||
|
"ignore conditional stop", "NOCSTOP", &tap_attable },
|
||||||
|
{ UNIT_ATTABLE+UNIT_NOCS, UNIT_ATTABLE ,
|
||||||
|
NULL, "CSTOP", &tap_attable },
|
||||||
|
{ MTAB_XTD|MTAB_VDV, 0, NULL, "START", &send_start },
|
||||||
|
{ MTAB_XTD|MTAB_VDV, 1, NULL, "RSTART", &tti_rdrss },
|
||||||
|
{ MTAB_XTD|MTAB_VDV, 0, NULL, "RSTOP", &tti_rdrss },
|
||||||
|
{ 0, 0 } };
|
||||||
|
|
||||||
|
DEVICE tti_dev = {
|
||||||
|
"TTI", tti_unit, tti_reg, tti_mod,
|
||||||
|
2, 10, 31, 1, 16, 7,
|
||||||
|
NULL, NULL, &tti_reset,
|
||||||
|
NULL, &tap_attach, NULL };
|
||||||
|
|
||||||
|
/* TTO data structures
|
||||||
|
|
||||||
|
tto_dev TTO device descriptor
|
||||||
|
tto_unit TTO unit descriptor
|
||||||
|
tto_mod TTO modifier list
|
||||||
|
tto_reg TTO register list
|
||||||
|
*/
|
||||||
|
|
||||||
|
UNIT tto_unit[] = {
|
||||||
|
{ UDATA (&tto_svc, 0, 0) },
|
||||||
|
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) } };
|
||||||
|
|
||||||
|
REG tto_reg[] = {
|
||||||
|
{ HRDATA (BUF, tto_buf, 6) },
|
||||||
|
{ FLDATA (UC, tto_uc, 0) },
|
||||||
|
{ DRDATA (TPOS, tto_unit[0].pos, T_ADDR_W), PV_LEFT },
|
||||||
|
{ DRDATA (PPOS, tto_unit[1].pos, T_ADDR_W), PV_LEFT },
|
||||||
|
{ DRDATA (TIME, tt_wait, 24), PV_LEFT },
|
||||||
|
{ NULL } };
|
||||||
|
|
||||||
|
MTAB tto_mod[] = {
|
||||||
|
{ UNIT_FLEX_D, UNIT_FLEX_D, NULL, "FLEX", &tap_attable },
|
||||||
|
{ UNIT_FLEX_D, 0, NULL, "ASCII", &tap_attable },
|
||||||
|
{ UNIT_ATT+UNIT_FLEX, UNIT_ATT+UNIT_FLEX,
|
||||||
|
"file is Flex", NULL },
|
||||||
|
{ UNIT_ATT+UNIT_FLEX, UNIT_ATT,
|
||||||
|
"file is ASCII", NULL },
|
||||||
|
{ UNIT_ATTABLE+UNIT_ATT+UNIT_FLEX, UNIT_ATTABLE+UNIT_FLEX,
|
||||||
|
"default is Flex", NULL },
|
||||||
|
{ UNIT_ATTABLE+UNIT_ATT+UNIT_FLEX, UNIT_ATTABLE,
|
||||||
|
"default is ASCII", NULL },
|
||||||
|
{ MTAB_XTD|MTAB_VUN, 0, NULL, "FEED", &punch_feed },
|
||||||
|
{ 0, 0 } };
|
||||||
|
|
||||||
|
DEVICE tto_dev = {
|
||||||
|
"TTO", tto_unit, tto_reg, tto_mod,
|
||||||
|
2, 10, 31, 1, 16, 7,
|
||||||
|
NULL, NULL, &tto_reset,
|
||||||
|
NULL, &tap_attach, NULL };
|
||||||
|
|
||||||
|
/* PTR data structures
|
||||||
|
|
||||||
|
ptr_dev PTR device descriptor
|
||||||
|
ptr_unit PTR unit descriptor
|
||||||
|
ptr_mod PTR modifier list
|
||||||
|
ptr_reg PTR register list
|
||||||
|
*/
|
||||||
|
|
||||||
|
UNIT ptr_unit = {
|
||||||
|
UDATA (&ptr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0), WPS / 200 };
|
||||||
|
|
||||||
|
REG ptr_reg[] = {
|
||||||
|
{ HRDATA (BUF, ptr_unit.buf, 6) },
|
||||||
|
{ FLDATA (RDY, ptr_rdy, 0) },
|
||||||
|
{ DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT },
|
||||||
|
{ DRDATA (TIME, ptr_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||||
|
{ FLDATA (STOP_IOE, ptr_stopioe, 0) },
|
||||||
|
{ NULL } };
|
||||||
|
|
||||||
|
MTAB ptr_mod[] = {
|
||||||
|
{ UNIT_FLEX_D, UNIT_FLEX_D, NULL, "FLEX", &tap_attable },
|
||||||
|
{ UNIT_FLEX_D, 0, NULL, "ASCII", &tap_attable },
|
||||||
|
{ UNIT_ATT+UNIT_FLEX, UNIT_ATT+UNIT_FLEX,
|
||||||
|
"file is Flex", NULL },
|
||||||
|
{ UNIT_ATT+UNIT_FLEX, UNIT_ATT,
|
||||||
|
"file is ASCII", NULL },
|
||||||
|
{ UNIT_ATTABLE+UNIT_ATT+UNIT_FLEX, UNIT_ATTABLE+UNIT_FLEX,
|
||||||
|
"default is Flex", NULL },
|
||||||
|
{ UNIT_ATTABLE+UNIT_ATT+UNIT_FLEX, UNIT_ATTABLE,
|
||||||
|
"default is ASCII", NULL },
|
||||||
|
{ 0, 0 } };
|
||||||
|
|
||||||
|
DEVICE ptr_dev = {
|
||||||
|
"PTR", &ptr_unit, ptr_reg, ptr_mod,
|
||||||
|
1, 10, 31, 1, 16, 7,
|
||||||
|
NULL, NULL, &ptr_reset,
|
||||||
|
NULL, &tap_attach, NULL };
|
||||||
|
|
||||||
|
/* PTP data structures
|
||||||
|
|
||||||
|
ptp_dev PTP device descriptor
|
||||||
|
ptp_unit PTP unit descriptor
|
||||||
|
ptp_mod PTP modifier list
|
||||||
|
ptp_reg PTP register list
|
||||||
|
*/
|
||||||
|
|
||||||
|
UNIT ptp_unit = {
|
||||||
|
UDATA (&ptp_svc, UNIT_SEQ+UNIT_ATTABLE, 0), WPS / 20 };
|
||||||
|
|
||||||
|
REG ptp_reg[] = {
|
||||||
|
{ ORDATA (BUF, ptp_unit.buf, 8) },
|
||||||
|
{ DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT },
|
||||||
|
{ DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT },
|
||||||
|
{ FLDATA (STOP_IOE, ptp_stopioe, 0) },
|
||||||
|
{ NULL } };
|
||||||
|
|
||||||
|
MTAB ptp_mod[] = {
|
||||||
|
{ UNIT_FLEX_D, UNIT_FLEX_D, NULL, "FLEX", &tap_attable },
|
||||||
|
{ UNIT_FLEX_D, 0, NULL, "ASCII", &tap_attable },
|
||||||
|
{ UNIT_ATT+UNIT_FLEX, UNIT_ATT+UNIT_FLEX,
|
||||||
|
"file is Flex", NULL },
|
||||||
|
{ UNIT_ATT+UNIT_FLEX, UNIT_ATT,
|
||||||
|
"file is ASCII", NULL },
|
||||||
|
{ UNIT_ATTABLE+UNIT_ATT+UNIT_FLEX, UNIT_ATTABLE+UNIT_FLEX,
|
||||||
|
"default is Flex", NULL },
|
||||||
|
{ UNIT_ATTABLE+UNIT_ATT+UNIT_FLEX, UNIT_ATTABLE,
|
||||||
|
"default is ASCII", NULL },
|
||||||
|
{ 0, 0 } };
|
||||||
|
|
||||||
|
DEVICE ptp_dev = {
|
||||||
|
"PTP", &ptp_unit, ptp_reg, ptp_mod,
|
||||||
|
1, 10, 31, 1, 16, 7,
|
||||||
|
NULL, NULL, &ptp_reset,
|
||||||
|
NULL, &tap_attach, NULL };
|
||||||
|
|
||||||
|
/* Input instruction */
|
||||||
|
|
||||||
|
void op_i_strt (uint32 dev)
|
||||||
|
{
|
||||||
|
switch (dev) { /* case on device */
|
||||||
|
case DEV_PT: /* ptr */
|
||||||
|
sim_activate (&ptr_unit, ptr_unit.wait); /* activate */
|
||||||
|
break;
|
||||||
|
case DEV_TT: /* tti/ttr */
|
||||||
|
if (Q_MANI) sim_putchar ('`'); /* manual input? */
|
||||||
|
else sim_activate (&tti_unit[1], tt_wait); /* no, must be ttr */
|
||||||
|
break; }
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat op_i (uint32 dev, uint32 ch, uint32 sh4)
|
||||||
|
{
|
||||||
|
if (Q_LGP21 && out_strt) return STOP_STALL; /* LGP-21? must be idle */
|
||||||
|
if (!inp_strt) { /* input started? */
|
||||||
|
inp_strt = 1; /* no, set start */
|
||||||
|
inp_done = 0; /* clear done */
|
||||||
|
A = shift_in (A, ch, sh4);
|
||||||
|
tti_rdy = ptr_rdy = 0; /* no input */
|
||||||
|
if (Q_LGP21 || Q_INPT) op_i_strt (dev); } /* LGP-21 or PTR? start */
|
||||||
|
|
||||||
|
switch (dev) { /* case on device */
|
||||||
|
case DEV_PT: /* ptr */
|
||||||
|
if (ptr_rdy) { /* char ready? */
|
||||||
|
ptr_rdy = 0; /* reset ready */
|
||||||
|
if ((ptr_unit.buf != FLEX_DEL) && /* ignore delete and */
|
||||||
|
(!Q_LGP21 || ((ptr_unit.buf & 3) == 2))) /* LGP-21 4b? zone != 2 */
|
||||||
|
A = shift_in (A, ptr_unit.buf, sh4); } /* shift data in */
|
||||||
|
break;
|
||||||
|
case DEV_TT: /* tti/ttr */
|
||||||
|
if (tti_rdy) { /* char ready? */
|
||||||
|
tti_rdy = 0; /* reset ready */
|
||||||
|
if ((tti_buf != FLEX_DEL) && /* ignore delete and */
|
||||||
|
(!Q_LGP21 || ((tti_buf & 3) != 0))) /* LGP-21 4b? zone == 0 */
|
||||||
|
A = shift_in (A, tti_buf, sh4); } /* shift data in */
|
||||||
|
break;
|
||||||
|
default: /* nx device */
|
||||||
|
return STOP_NXDEV; } /* return error */
|
||||||
|
|
||||||
|
if (inp_done) { /* done? */
|
||||||
|
inp_strt = inp_done = 0; /* clear start, done */
|
||||||
|
return SCPE_OK; } /* no stall */
|
||||||
|
return STOP_STALL; /* stall */
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat tti_svc (UNIT *uptr)
|
||||||
|
{
|
||||||
|
int32 c, flex;
|
||||||
|
|
||||||
|
sim_activate (uptr, tt_wait); /* continue poll */
|
||||||
|
if ((c = sim_poll_kbd ()) < SCPE_KFLAG) return c; /* no char or error? */
|
||||||
|
flex = ascii_to_flex[c & 0x1FF]; /* cvt to flex */
|
||||||
|
if (flex > 0) { /* it's a typewriter... */
|
||||||
|
write_tto (flex); /* always echos */
|
||||||
|
if (tto_unit[1].flags & UNIT_ATT) /* ttp attached? */
|
||||||
|
write_punch (&tto_unit[1], tto_buf); } /* punch to ttp */
|
||||||
|
else write_tto ('\a'); /* don't echo bad */
|
||||||
|
if (Q_MANI && (flex > 0) && flex_inp_valid[flex]) { /* wanted, valid? */
|
||||||
|
if (flex == FLEX_CSTOP) inp_done = 1; /* conditional stop? */
|
||||||
|
else tti_rdy = 1; /* no, set ready */
|
||||||
|
tti_buf = flex; /* save char */
|
||||||
|
uptr->pos = uptr->pos + 1; }
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat ttr_svc (UNIT *uptr)
|
||||||
|
{
|
||||||
|
t_stat r;
|
||||||
|
|
||||||
|
if (r = read_reader (uptr, ttr_stopioe, (int32 *) &tti_buf)) return r;
|
||||||
|
if (!(uptr->flags & UNIT_NOCS) && /* cstop enable? */
|
||||||
|
(tti_buf == FLEX_CSTOP)) inp_done = 1; /* cond stop? */
|
||||||
|
else { tti_rdy = 1; /* no, set ready */
|
||||||
|
sim_activate (uptr, tt_wait); } /* cont reading */
|
||||||
|
write_tto (tti_buf); /* echo to tto */
|
||||||
|
if (tto_unit[1].flags & UNIT_ATT) /* ttp attached? */
|
||||||
|
return write_punch (&tto_unit[1], tti_buf); /* punch to ttp */
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat ptr_svc (UNIT *uptr)
|
||||||
|
{
|
||||||
|
t_stat r;
|
||||||
|
|
||||||
|
if (r = read_reader (uptr, ptr_stopioe, &uptr->buf)) return r;
|
||||||
|
if (uptr->buf == FLEX_CSTOP) inp_done = 1; /* cond stop? */
|
||||||
|
else { ptr_rdy = 1; /* no, set ready */
|
||||||
|
sim_activate (uptr, uptr->wait); } /* cont reading */
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output instruction */
|
||||||
|
|
||||||
|
t_stat op_p (uint32 dev, uint32 ch)
|
||||||
|
{
|
||||||
|
switch (dev) { /* case on device */
|
||||||
|
case DEV_PT: /* paper tape punch */
|
||||||
|
if (sim_is_active (&ptp_unit)) /* busy? */
|
||||||
|
return (Q_LGP21? STOP_STALL: SCPE_OK); /* LGP-21: stall */
|
||||||
|
ptp_unit.buf = ch; /* save char */
|
||||||
|
sim_activate (&ptp_unit, ptp_unit.wait); /* activate ptp */
|
||||||
|
break;
|
||||||
|
case DEV_TT: /* typewriter */
|
||||||
|
if (ch == 0) { /* start input? */
|
||||||
|
if (!Q_LGP21 && !Q_INPT) /* ignore if LGP-21, ptr */
|
||||||
|
op_i_strt (DEV_TT); /* start tti */
|
||||||
|
return SCPE_OK; } /* no stall */
|
||||||
|
if (sim_is_active (&tto_unit[0])) /* busy? */
|
||||||
|
return (Q_LGP21? STOP_STALL: SCPE_OK); /* LGP-21: stall */
|
||||||
|
tto_buf = ch; /* save char */
|
||||||
|
sim_activate (&tto_unit[0], tt_wait); /* activate tto */
|
||||||
|
break;
|
||||||
|
default: /* unknown */
|
||||||
|
return STOP_NXDEV; } /* return error */
|
||||||
|
|
||||||
|
if (out_strt == 0) { /* output started? */
|
||||||
|
out_strt = 1; /* flag start */
|
||||||
|
out_done = 0; } /* clear done */
|
||||||
|
return SCPE_OK; /* no stall */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TTO unit service */
|
||||||
|
|
||||||
|
t_stat tto_svc (UNIT *uptr)
|
||||||
|
{
|
||||||
|
t_stat r;
|
||||||
|
|
||||||
|
if ((r = write_tto (tto_buf)) != SCPE_OK) { /* output; error? */
|
||||||
|
sim_activate (uptr, tt_wait); /* try again */
|
||||||
|
return ((r == SCPE_STALL)? SCPE_OK: r); } /* !stall? report */
|
||||||
|
out_strt = 0;
|
||||||
|
out_done = 1;
|
||||||
|
if (tto_unit[1].flags & UNIT_ATT) /* ttp attached? */
|
||||||
|
return write_punch (&tto_unit[1], tto_buf); /* punch to ttp */
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PTP unit service */
|
||||||
|
|
||||||
|
t_stat ptp_svc (UNIT *uptr)
|
||||||
|
{
|
||||||
|
out_strt = 0;
|
||||||
|
out_done = 1;
|
||||||
|
if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */
|
||||||
|
return IORETURN (ptp_stopioe, SCPE_UNATT); /* error */
|
||||||
|
return write_punch (uptr, uptr->buf); /* write to ptp */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Utility routines */
|
||||||
|
|
||||||
|
t_stat read_reader (UNIT *uptr, int32 stop, int32 *fl)
|
||||||
|
{
|
||||||
|
int32 ch, flex;
|
||||||
|
|
||||||
|
if ((uptr->flags & UNIT_ATT) == 0) /* attached? */
|
||||||
|
return IORETURN (stop, SCPE_UNATT);
|
||||||
|
do { if ((ch = getc (uptr->fileref)) == EOF) { /* read char */
|
||||||
|
if (feof (uptr->fileref)) { /* err or eof? */
|
||||||
|
if (stop) printf ("Reader end of file\n");
|
||||||
|
else return SCPE_OK; }
|
||||||
|
else perror ("Reader I/O error");
|
||||||
|
clearerr (uptr->fileref);
|
||||||
|
return SCPE_IOERR; }
|
||||||
|
if (uptr->flags & UNIT_FLEX) /* transposed flex? */
|
||||||
|
flex = ((ch << 1) | (ch >> 5)) & 0x3F; /* undo 612345 */
|
||||||
|
else if (ch == '#') { /* encoded? */
|
||||||
|
int32 d1 = getc (uptr->fileref); /* get 2 digits */
|
||||||
|
int32 d2 = getc (uptr->fileref);
|
||||||
|
if ((d1 == EOF) || (d2 == EOF)) { /* error? */
|
||||||
|
if (feof (uptr->fileref)) { /* eof? */
|
||||||
|
if (stop) printf ("Reader end of file\n");
|
||||||
|
else return SCPE_OK; }
|
||||||
|
else perror ("Reader I/O error");
|
||||||
|
clearerr (uptr->fileref);
|
||||||
|
return SCPE_IOERR; }
|
||||||
|
flex = (((d1 - '0') * 10) + (d2 - '0')) & 0x3F;
|
||||||
|
uptr->pos = uptr->pos + 2; }
|
||||||
|
else flex = ascii_to_flex[ch & 0x7F]; /* convert */
|
||||||
|
uptr->pos = uptr->pos + 1; }
|
||||||
|
while (flex < 0); /* until valid */
|
||||||
|
*fl = flex; /* return char */
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat write_tto (int32 flex)
|
||||||
|
{
|
||||||
|
int32 ch;
|
||||||
|
t_stat r;
|
||||||
|
|
||||||
|
if (flex == FLEX_UC) tto_uc = 1; /* UC? set state */
|
||||||
|
else if (flex == FLEX_LC) tto_uc = 0; /* LC? set state */
|
||||||
|
else { if (flex == FLEX_BS) ch = '\b'; /* backspace? */
|
||||||
|
else ch = flex_to_ascii[flex | (tto_uc << 6)]; /* cvt flex to ascii */
|
||||||
|
if (ch > 0) { /* legit? */
|
||||||
|
if (r = sim_putchar_s (ch)) return r; /* write char */
|
||||||
|
tto_unit[0].pos = tto_unit[0].pos + 1;
|
||||||
|
if (flex == FLEX_CR) { /* cr? */
|
||||||
|
sim_putchar ('\n'); /* add lf */
|
||||||
|
tto_unit[0].pos = tto_unit[0].pos + 1; } } }
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat write_punch (UNIT *uptr, int32 flex)
|
||||||
|
{
|
||||||
|
int32 c, sta;
|
||||||
|
|
||||||
|
if (uptr->flags & UNIT_FLEX) /* transposed flex? */
|
||||||
|
c = ((flex >> 1) | (flex << 5)) & 0x3F; /* reorder to 612345 */
|
||||||
|
else c = flex_to_ascii[flex]; /* convert to ASCII */
|
||||||
|
if (c >= 0) sta = fputc (c, uptr->fileref); /* valid? */
|
||||||
|
else sta = fprintf (uptr->fileref, "#%02d", flex); /* no, encode */
|
||||||
|
if (sta == EOF) { /* error? */
|
||||||
|
perror ("Punch I/O error"); /* error? */
|
||||||
|
clearerr (uptr->fileref);
|
||||||
|
return SCPE_IOERR; }
|
||||||
|
uptr->pos = uptr->pos + ((c >= 0)? 1: 3); /* incr position */
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset routines */
|
||||||
|
|
||||||
|
t_stat tti_reset (DEVICE *dptr)
|
||||||
|
{
|
||||||
|
sim_activate (&tti_unit[0], tt_wait);
|
||||||
|
sim_cancel (&tti_unit[1]);
|
||||||
|
tti_buf = 0;
|
||||||
|
tti_rdy = 0;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat tto_reset (DEVICE *dptr)
|
||||||
|
{
|
||||||
|
sim_cancel (&tto_unit[0]);
|
||||||
|
tto_buf = 0;
|
||||||
|
tto_uc = 0;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat ptr_reset (DEVICE *dptr)
|
||||||
|
{
|
||||||
|
sim_cancel (&ptr_unit);
|
||||||
|
ptr_unit.buf = 0;
|
||||||
|
ptr_rdy = 0;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat ptp_reset (DEVICE *dptr)
|
||||||
|
{
|
||||||
|
sim_cancel (&ptp_unit);
|
||||||
|
ptp_unit.buf = 0;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attach paper tape unit */
|
||||||
|
|
||||||
|
t_stat tap_attach (UNIT *uptr, char *cptr)
|
||||||
|
{
|
||||||
|
t_stat r;
|
||||||
|
|
||||||
|
if ((r = attach_unit (uptr,cptr)) != SCPE_OK) return r;
|
||||||
|
if ((sim_switches & SWMASK ('F')) ||
|
||||||
|
((uptr->flags & UNIT_FLEX_D) && !(sim_switches & SWMASK ('A'))))
|
||||||
|
uptr->flags = uptr->flags | UNIT_FLEX;
|
||||||
|
else uptr->flags = uptr->flags & ~UNIT_FLEX;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate unit is attachable */
|
||||||
|
|
||||||
|
t_stat tap_attable (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||||
|
{
|
||||||
|
if (uptr->flags & UNIT_ATTABLE) return SCPE_OK;
|
||||||
|
return SCPE_NOFNC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Typewriter reader start/stop */
|
||||||
|
|
||||||
|
t_stat tti_rdrss (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||||
|
{
|
||||||
|
if (val) {
|
||||||
|
if ((tti_unit[1].flags & UNIT_ATT) == 0) return SCPE_UNATT;
|
||||||
|
sim_activate (&tti_unit[1], tt_wait); }
|
||||||
|
else sim_cancel (&tti_unit[1]);
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Punch feed routine */
|
||||||
|
|
||||||
|
t_stat punch_feed (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||||
|
{
|
||||||
|
int32 cnt;
|
||||||
|
t_stat r;
|
||||||
|
|
||||||
|
if ((uptr->flags & UNIT_ATT) == 0) return SCPE_UNATT;
|
||||||
|
if (cptr) {
|
||||||
|
cnt = (int32) get_uint (cptr, 10, 512, &r);
|
||||||
|
if ((r != SCPE_OK) || (cnt == 0)) return SCPE_ARG; }
|
||||||
|
else cnt = 10;
|
||||||
|
while (cnt-- > 0) {
|
||||||
|
r = write_punch (uptr, 0);
|
||||||
|
if (r != SCPE_OK) return r; }
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send start signal */
|
||||||
|
|
||||||
|
t_stat send_start (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||||
|
{
|
||||||
|
if (inp_strt) inp_done = 1;
|
||||||
|
else if (out_strt) out_done = 1;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
345
LGP/lgp_sys.c
Normal file
345
LGP/lgp_sys.c
Normal file
|
@ -0,0 +1,345 @@
|
||||||
|
/* lgp_sys.c: LGP-30 simulator interface
|
||||||
|
|
||||||
|
Copyright (c) 2004, Robert M Supnik
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
Except as contained in this notice, the name of Robert M Supnik shall not
|
||||||
|
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lgp_defs.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
t_stat parse_sym_m (char *cptr, t_value *val, int32 sw);
|
||||||
|
void lgp_init (void);
|
||||||
|
|
||||||
|
extern DEVICE cpu_dev;
|
||||||
|
extern UNIT cpu_unit;
|
||||||
|
extern DEVICE tti_dev, tto_dev;
|
||||||
|
extern DEVICE ptr_dev, ptp_dev;
|
||||||
|
extern REG cpu_reg[];
|
||||||
|
extern uint32 M[];
|
||||||
|
extern uint32 PC;
|
||||||
|
extern uint32 ts_flag;
|
||||||
|
extern int32 sim_switches;
|
||||||
|
extern int32 flex_to_ascii[128], ascii_to_flex[128];
|
||||||
|
|
||||||
|
void (*sim_vm_init) (void) = &lgp_init;
|
||||||
|
extern void (*sim_vm_fprint_addr) (FILE *st, DEVICE *dptr, t_addr addr);
|
||||||
|
extern t_addr (*sim_vm_parse_addr) (DEVICE *dptr, char *cptr, char **tptr);
|
||||||
|
|
||||||
|
/* SCP data structures and interface routines
|
||||||
|
|
||||||
|
sim_name simulator name string
|
||||||
|
sim_PC pointer to saved PC register descriptor
|
||||||
|
sim_emax maximum number of words for examine/deposit
|
||||||
|
sim_devices array of pointers to simulated devices
|
||||||
|
sim_stop_messages array of pointers to stop messages
|
||||||
|
sim_load binary loader
|
||||||
|
*/
|
||||||
|
|
||||||
|
char sim_name[] = "LGP30";
|
||||||
|
|
||||||
|
REG *sim_PC = &cpu_reg[0];
|
||||||
|
|
||||||
|
int32 sim_emax = 1;
|
||||||
|
|
||||||
|
DEVICE *sim_devices[] = {
|
||||||
|
&cpu_dev,
|
||||||
|
&tti_dev,
|
||||||
|
&tto_dev,
|
||||||
|
&ptr_dev,
|
||||||
|
&ptp_dev,
|
||||||
|
NULL };
|
||||||
|
|
||||||
|
const char *sim_stop_messages[] = {
|
||||||
|
"Unknown error",
|
||||||
|
"STOP",
|
||||||
|
"Breakpoint",
|
||||||
|
"Arithmetic overflow" };
|
||||||
|
|
||||||
|
/* Binary loader - implements a restricted form of subroutine 10.4
|
||||||
|
|
||||||
|
Switches:
|
||||||
|
-t, input file is transposed Flex
|
||||||
|
-n, no checksums on v commands (10.0 compatible)
|
||||||
|
default is ASCII encoded Flex
|
||||||
|
Commands (in bits 0-3):
|
||||||
|
(blank) instruction
|
||||||
|
+ command (not supported)
|
||||||
|
; start fill
|
||||||
|
/ set modifier
|
||||||
|
. stop and transfer
|
||||||
|
, hex words
|
||||||
|
v hex fill (checksummed unless -n)
|
||||||
|
8 negative instruction
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Utility routine - read characters until ' (conditional stop) */
|
||||||
|
|
||||||
|
t_stat load_getw (FILE *fi, uint32 *wd)
|
||||||
|
{
|
||||||
|
int32 flex, c;
|
||||||
|
|
||||||
|
*wd = 0;
|
||||||
|
while ((c = fgetc (fi)) != EOF) {
|
||||||
|
if (sim_switches & SWMASK ('T'))
|
||||||
|
flex = ((c << 1) | (c >> 5)) & 0x3F;
|
||||||
|
else flex = ascii_to_flex[c & 0x7F];
|
||||||
|
if ((flex == FLEX_CR) || (flex == FLEX_DEL) ||
|
||||||
|
(flex == FLEX_UC) || (flex == FLEX_LC) ||
|
||||||
|
(flex == FLEX_BS) || (flex < 0)) continue;
|
||||||
|
if (flex == FLEX_CSTOP) return SCPE_OK;
|
||||||
|
*wd = (*wd << 4) | ((flex >> 2) & 0xF); }
|
||||||
|
return SCPE_FMT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Utility routine - convert ttss decimal address to binary */
|
||||||
|
|
||||||
|
t_stat load_geta (uint32 wd, uint32 *ad)
|
||||||
|
{
|
||||||
|
uint32 n1, n2, n3, n4, tr, sc;
|
||||||
|
|
||||||
|
n1 = (wd >> 12) & 0xF;
|
||||||
|
n2 = (wd >> 8) & 0xF;
|
||||||
|
n3 = (wd >> 4) & 0xF;
|
||||||
|
n4 = wd & 0xF;
|
||||||
|
if ((n2 > 9) || (n4 > 9)) return SCPE_ARG;
|
||||||
|
tr = (n1 * 10) + n2;
|
||||||
|
sc = (n3 * 10) + n4;
|
||||||
|
if ((tr >= NTK_30) || (sc >= NSC_30)) return SCPE_ARG;
|
||||||
|
*ad = (tr * NSC_30) + sc;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loader proper */
|
||||||
|
|
||||||
|
t_stat sim_load (FILE *fi, char *cptr, char *fnam, int flag)
|
||||||
|
{
|
||||||
|
uint32 wd, origin, amod, csum, cnt, tr, sc, ad, cmd;
|
||||||
|
|
||||||
|
origin = amod = 0;
|
||||||
|
for (;;) { /* until stopped */
|
||||||
|
if (load_getw (fi, &wd)) break; /* get ctrl word */
|
||||||
|
cmd = (wd >> 28) & 0xF; /* get <0:3> */
|
||||||
|
switch (cmd) { /* decode <0:3> */
|
||||||
|
case 0x2: /* + command */
|
||||||
|
return SCPE_FMT;
|
||||||
|
case 0x3: /* ; start fill */
|
||||||
|
if (load_geta (wd, &origin)) return SCPE_FMT; /* origin = addr */
|
||||||
|
break;
|
||||||
|
case 0x4: /* / set modifier */
|
||||||
|
if (load_geta (wd, &amod)) return SCPE_FMT; /* modifier = addr */
|
||||||
|
break;
|
||||||
|
case 0x5: /* . transfer */
|
||||||
|
if (load_geta (wd, &PC)) return SCPE_FMT; /* PC = addr */
|
||||||
|
return SCPE_OK; /* done! */
|
||||||
|
case 0x6: /* hex words */
|
||||||
|
if (load_geta (wd, &cnt)) return SCPE_FMT; /* count = addr */
|
||||||
|
if ((cnt == 0) || (cnt > 63)) return SCPE_FMT;
|
||||||
|
while (cnt--) { /* fill hex words */
|
||||||
|
if (load_getw (fi, &wd)) return SCPE_FMT;
|
||||||
|
Write (origin, wd);
|
||||||
|
origin = (origin + 1) & AMASK; }
|
||||||
|
break;
|
||||||
|
case 0x7: /* hex fill */
|
||||||
|
cnt = (wd >> 16) & 0xFFF; /* hex count */
|
||||||
|
tr = (wd >> 8) & 0xFF; /* hex track */
|
||||||
|
sc = wd & 0xFF; /* hex sector */
|
||||||
|
if ((cnt == 0) || (cnt > 0x7FF) || /* validate */
|
||||||
|
(tr >= NTK_30) || (sc >= NSC_30)) return SCPE_ARG;
|
||||||
|
ad = (tr * NSC_30) + sc; /* decimal addr */
|
||||||
|
for (csum = 0; cnt; cnt--) { /* fill words */
|
||||||
|
if (load_getw (fi, &wd)) return SCPE_FMT;
|
||||||
|
Write (ad, wd);
|
||||||
|
csum = (csum + wd) & MMASK;
|
||||||
|
ad = (ad + 1) & AMASK; }
|
||||||
|
if (!(sim_switches & SWMASK ('N'))) { /* unless -n, csum */
|
||||||
|
if (load_getw (fi, &wd)) return SCPE_FMT;
|
||||||
|
/* if ((csum ^wd) & MMASK) return SCPE_CSUM; */ }
|
||||||
|
break;
|
||||||
|
case 0x0: case 0x8: /* instructions */
|
||||||
|
if (load_geta (wd, &ad)) return SCPE_FMT; /* get address */
|
||||||
|
if ((wd & 0x00F00000) != 0x00900000) /* if not x, */
|
||||||
|
ad = (ad + amod) & AMASK; /* modify */
|
||||||
|
wd = (wd & (SIGN|I_OP)) + (ad << I_V_EA); /* instruction */
|
||||||
|
default: /* data word */
|
||||||
|
Write (origin, wd);
|
||||||
|
origin = (origin + 1) & AMASK;
|
||||||
|
break;
|
||||||
|
} /* end case */
|
||||||
|
} /* end for */
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Symbol tables */
|
||||||
|
|
||||||
|
static const char opcode[] = "ZBYRIDNMPEUTHCAS";
|
||||||
|
|
||||||
|
static const char hex_decode[] = "0123456789FGJKQW";
|
||||||
|
|
||||||
|
void lgp_fprint_addr (FILE *st, DEVICE *dptr, t_addr addr)
|
||||||
|
{
|
||||||
|
if ((dptr == sim_devices[0]) &&
|
||||||
|
((sim_switches & SWMASK ('T')) ||
|
||||||
|
((cpu_unit.flags & UNIT_TTSS_D) && !(sim_switches & SWMASK ('N')))))
|
||||||
|
fprintf (st, "%02d%02d", addr >> 6, addr & SCMASK_30);
|
||||||
|
else fprint_val (st, addr, dptr->aradix, dptr->awidth, PV_LEFT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_addr lgp_parse_addr (DEVICE *dptr, char *cptr, char **tptr)
|
||||||
|
{
|
||||||
|
t_addr ad, ea;
|
||||||
|
|
||||||
|
if ((dptr == sim_devices[0]) &&
|
||||||
|
((sim_switches & SWMASK ('T')) ||
|
||||||
|
((cpu_unit.flags & UNIT_TTSS_D) && !(sim_switches & SWMASK ('N'))))) {
|
||||||
|
ad = (t_addr) strtotv (cptr, tptr, 10);
|
||||||
|
if (((ad / 100) >= NTK_30) || ((ad % 100) >= NSC_30)) {
|
||||||
|
*tptr = cptr;
|
||||||
|
return 0; }
|
||||||
|
ea = ((ad / 100) * NSC_30) | (ad % 100); }
|
||||||
|
else ea = (t_addr) strtotv (cptr, tptr, dptr->aradix);
|
||||||
|
return ea;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lgp_init (void)
|
||||||
|
{
|
||||||
|
sim_vm_fprint_addr = &lgp_fprint_addr;
|
||||||
|
sim_vm_parse_addr = &lgp_parse_addr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Symbolic decode
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
*of = output stream
|
||||||
|
addr = current PC
|
||||||
|
*val = pointer to data
|
||||||
|
*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)
|
||||||
|
{
|
||||||
|
int32 i, c;
|
||||||
|
uint32 inst, op, ea;
|
||||||
|
|
||||||
|
inst = val[0];
|
||||||
|
if (sw & SWMASK ('A')) { /* alphabetic? */
|
||||||
|
if ((uptr == NULL) || !(uptr->flags & UNIT_ATT)) return SCPE_ARG;
|
||||||
|
if (uptr->flags & UNIT_FLEX) { /* Flex file? */
|
||||||
|
c = flex_to_ascii[inst]; /* get ASCII equiv */
|
||||||
|
if (c <= 0) return SCPE_ARG; }
|
||||||
|
else c = inst & 0x7F; /* ASCII file */
|
||||||
|
fputc (c, of);
|
||||||
|
return SCPE_OK; }
|
||||||
|
|
||||||
|
if (uptr && (uptr != &cpu_unit)) return SCPE_ARG; /* must be CPU */
|
||||||
|
if ((sw & SWMASK ('M')) && /* symbolic decode? */
|
||||||
|
((inst & ~(SIGN|I_OP|I_EA)) == 0)) {
|
||||||
|
op = I_GETOP (inst);
|
||||||
|
ea = I_GETEA (inst);
|
||||||
|
if (inst & SIGN) fputc ('-', of);
|
||||||
|
fprintf (of, "%c ", opcode[op]);
|
||||||
|
lgp_fprint_addr (of, sim_devices[0], ea);
|
||||||
|
return SCPE_OK; }
|
||||||
|
|
||||||
|
if ((sw & SWMASK ('L')) || /* LGP hex? */
|
||||||
|
((cpu_unit.flags & UNIT_LGPH_D) && !(sw & SWMASK ('H')))) {
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
c = (inst >> (4 * (7 - i))) & 0xF;
|
||||||
|
fputc (hex_decode[c], of); }
|
||||||
|
return SCPE_OK; }
|
||||||
|
return SCPE_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
int32 i, c;
|
||||||
|
char *tptr;
|
||||||
|
|
||||||
|
while (isspace (*cptr)) cptr++; /* absorb spaces */
|
||||||
|
if ((sw & SWMASK ('A')) || ((*cptr == '\'') && cptr++)) {
|
||||||
|
if ((uptr == NULL) || !(uptr->flags & UNIT_ATT)) return SCPE_ARG;
|
||||||
|
if (uptr->flags & UNIT_FLEX) { /* Flex file? */
|
||||||
|
c = ascii_to_flex[*cptr & 0x7F]; /* get Flex equiv */
|
||||||
|
if (c < 0) return SCPE_ARG;
|
||||||
|
val[0] = ((c >> 1) | (c << 5)) & 0x3F; } /* transpose */
|
||||||
|
else val[0] = *cptr & 0x7F; /* ASCII file */
|
||||||
|
return SCPE_OK; }
|
||||||
|
|
||||||
|
if (uptr && (uptr != &cpu_unit)) return SCPE_ARG; /* must be CPU */
|
||||||
|
if (!parse_sym_m (cptr, val, sw)) return SCPE_OK; /* symbolic parse? */
|
||||||
|
if ((sw & SWMASK ('L')) || /* LGP hex? */
|
||||||
|
((cpu_unit.flags & UNIT_LGPH_D) && !(sw & SWMASK ('H')))) {
|
||||||
|
val[0] = 0;
|
||||||
|
while (isspace (*cptr)) cptr++; /* absorb spaces */
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
c = *cptr++; /* get char */
|
||||||
|
if (c == 0) return SCPE_OK;
|
||||||
|
if (islower (c)) c = toupper (c);
|
||||||
|
if (tptr = strchr (hex_decode, c))
|
||||||
|
val[0] = (val[0] << 4) | (tptr - hex_decode);
|
||||||
|
else return SCPE_ARG; }
|
||||||
|
if (*cptr == 0) return SCPE_OK; }
|
||||||
|
return SCPE_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Instruction parse */
|
||||||
|
|
||||||
|
t_stat parse_sym_m (char *cptr, t_value *val, int32 sw)
|
||||||
|
{
|
||||||
|
uint32 ea, sgn;
|
||||||
|
char *tptr, gbuf[CBUFSIZE];
|
||||||
|
|
||||||
|
if (*cptr == '-') {
|
||||||
|
cptr++;
|
||||||
|
sgn = SIGN; }
|
||||||
|
else sgn = 0;
|
||||||
|
cptr = get_glyph (cptr, gbuf, 0); /* get opcode */
|
||||||
|
if (gbuf[1] != 0) return SCPE_ARG;
|
||||||
|
if (tptr = strchr (opcode, gbuf[0]))
|
||||||
|
val[0] = ((tptr - opcode) << I_V_OP) | sgn; /* merge opcode */
|
||||||
|
else return SCPE_ARG;
|
||||||
|
cptr = get_glyph (cptr, gbuf, 0); /* get address */
|
||||||
|
ea = lgp_parse_addr (sim_devices[0], gbuf, &tptr);
|
||||||
|
if ((tptr == gbuf) || (*tptr != 0) || (ea > AMASK))
|
||||||
|
return SCPE_ARG;
|
||||||
|
val[0] = val[0] | (ea << I_V_EA); /* merge address */
|
||||||
|
if (*cptr != 0) return SCPE_2MARG;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
|
@ -3915,7 +3915,7 @@ if ((IR & 0100017) == 0100010) { /* This pattern for all */
|
||||||
j = (IR >> 11) & 3;
|
j = (IR >> 11) & 3;
|
||||||
i = (AC[0] >> 8) & 0x007F;
|
i = (AC[0] >> 8) & 0x007F;
|
||||||
FPAC[j] &= 0x80FFFFFFFFFFFFFF; /* clear exponent */
|
FPAC[j] &= 0x80FFFFFFFFFFFFFF; /* clear exponent */
|
||||||
FPAC[j] |= (t_int64)(i << 56);
|
FPAC[j] |= ((t_int64) i << 56);
|
||||||
if ((FPAC[j] & 0x00ffffffffffffff) == 0)
|
if ((FPAC[j] & 0x00ffffffffffffff) == 0)
|
||||||
FPAC[j] = 0;
|
FPAC[j] = 0;
|
||||||
if (FPAC[j] == 0)
|
if (FPAC[j] == 0)
|
||||||
|
@ -5996,7 +5996,8 @@ for (i = 0; i < 64; i++) { /* clr dev_table */
|
||||||
dev_table[i].pi = 0;
|
dev_table[i].pi = 0;
|
||||||
dev_table[i].routine = NULL; }
|
dev_table[i].routine = NULL; }
|
||||||
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */
|
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */
|
||||||
if (dibp = (DIB *) dptr->ctxt) { /* get DIB */
|
if (!(dptr->flags & DEV_DIS) && /* enabled and */
|
||||||
|
(dibp = (DIB *) dptr->ctxt)) { /* defined DIB? */
|
||||||
dn = dibp->dnum; /* get dev num */
|
dn = dibp->dnum; /* get dev num */
|
||||||
dev_table[dn].mask = dibp->mask; /* copy entries */
|
dev_table[dn].mask = dibp->mask; /* copy entries */
|
||||||
dev_table[dn].pi = dibp->pi;
|
dev_table[dn].pi = dibp->pi;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* nova_clk.c: NOVA real-time clock simulator
|
/* nova_clk.c: NOVA real-time clock simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2003, Robert M. Supnik
|
Copyright (c) 1993-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* nova_cpu.c: NOVA CPU simulator
|
/* nova_cpu.c: NOVA CPU simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2003, Robert M. Supnik
|
Copyright (c) 1993-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
cpu Nova central processor
|
cpu Nova central processor
|
||||||
|
|
||||||
|
14-Jan-04 RMS Fixed device enable/disable support (found by Bruce Ray)
|
||||||
19-Jan-03 RMS Changed CMASK to CDMASK for Apple Dev Kit conflict
|
19-Jan-03 RMS Changed CMASK to CDMASK for Apple Dev Kit conflict
|
||||||
03-Oct-02 RMS Added DIB infrastructure
|
03-Oct-02 RMS Added DIB infrastructure
|
||||||
30-Dec-01 RMS Added old PC queue
|
30-Dec-01 RMS Added old PC queue
|
||||||
|
@ -831,7 +832,8 @@ for (i = 0; i < 64; i++) { /* clr dev_table */
|
||||||
dev_table[i].pi = 0;
|
dev_table[i].pi = 0;
|
||||||
dev_table[i].routine = NULL; }
|
dev_table[i].routine = NULL; }
|
||||||
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */
|
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */
|
||||||
if (dibp = (DIB *) dptr->ctxt) { /* get DIB */
|
if (!(dptr->flags & DEV_DIS) && /* enabled and */
|
||||||
|
(dibp = (DIB *) dptr->ctxt)) { /* defined DIB? */
|
||||||
dn = dibp->dnum; /* get dev num */
|
dn = dibp->dnum; /* get dev num */
|
||||||
dev_table[dn].mask = dibp->mask; /* copy entries */
|
dev_table[dn].mask = dibp->mask; /* copy entries */
|
||||||
dev_table[dn].pi = dibp->pi;
|
dev_table[dn].pi = dibp->pi;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* nova_defs.h: NOVA/Eclipse simulator definitions
|
/* nova_defs.h: NOVA/Eclipse simulator definitions
|
||||||
|
|
||||||
Copyright (c) 1993-2003, Robert M. Supnik
|
Copyright (c) 1993-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -23,6 +23,7 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
in this Software without prior written authorization from Robert M Supnik.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
14-Jan-04 BKR Added support for QTY and ALM
|
||||||
22-Nov-03 CEO Added support for PIT device
|
22-Nov-03 CEO Added support for PIT device
|
||||||
19-Jan-03 RMS Changed CMASK to CDMASK for Apple Dev kit conflict
|
19-Jan-03 RMS Changed CMASK to CDMASK for Apple Dev kit conflict
|
||||||
03-Oct-02 RMS Added device information structure
|
03-Oct-02 RMS Added device information structure
|
||||||
|
@ -173,8 +174,10 @@
|
||||||
#define DEV_MTA 022 /* magtape */
|
#define DEV_MTA 022 /* magtape */
|
||||||
#define DEV_DCM 024 /* data comm mux */
|
#define DEV_DCM 024 /* data comm mux */
|
||||||
#define DEV_ADCV 030 /* A/D converter */
|
#define DEV_ADCV 030 /* A/D converter */
|
||||||
|
#define DEV_QTY 030 /* 4060 multiplexor */
|
||||||
#define DEV_DKP 033 /* disk pack */
|
#define DEV_DKP 033 /* disk pack */
|
||||||
#define DEV_CAS 034 /* cassette */
|
#define DEV_CAS 034 /* cassette */
|
||||||
|
#define DEV_ALM 034 /* ALM/ULM multiplexor */
|
||||||
#define DEV_PIT 043 /* programmable interval timer */
|
#define DEV_PIT 043 /* programmable interval timer */
|
||||||
#define DEV_TTI1 050 /* second console input */
|
#define DEV_TTI1 050 /* second console input */
|
||||||
#define DEV_TTO1 051 /* second console output */
|
#define DEV_TTO1 051 /* second console output */
|
||||||
|
@ -226,9 +229,11 @@ typedef struct nova_dib DIB;
|
||||||
#define INT_V_TTO 12 /* terminal */
|
#define INT_V_TTO 12 /* terminal */
|
||||||
#define INT_V_TTI1 13 /* second keyboard */
|
#define INT_V_TTI1 13 /* second keyboard */
|
||||||
#define INT_V_TTO1 14 /* second terminal */
|
#define INT_V_TTO1 14 /* second terminal */
|
||||||
#define INT_V_STK 15 /* stack overflow */
|
#define INT_V_QTY 15 /* QTY multiplexor */
|
||||||
#define INT_V_NO_ION_PENDING 16 /* ion delay */
|
#define INT_V_ALM 16 /* ALM multiplexor */
|
||||||
#define INT_V_ION 17 /* interrupts on */
|
#define INT_V_STK 17 /* stack overflow */
|
||||||
|
#define INT_V_NO_ION_PENDING 18 /* ion delay */
|
||||||
|
#define INT_V_ION 19 /* interrupts on */
|
||||||
|
|
||||||
#define INT_PIT (1 << INT_V_PIT)
|
#define INT_PIT (1 << INT_V_PIT)
|
||||||
#define INT_DKP (1 << INT_V_DKP)
|
#define INT_DKP (1 << INT_V_DKP)
|
||||||
|
@ -243,6 +248,8 @@ typedef struct nova_dib DIB;
|
||||||
#define INT_TTO (1 << INT_V_TTO)
|
#define INT_TTO (1 << INT_V_TTO)
|
||||||
#define INT_TTI1 (1 << INT_V_TTI1)
|
#define INT_TTI1 (1 << INT_V_TTI1)
|
||||||
#define INT_TTO1 (1 << INT_V_TTO1)
|
#define INT_TTO1 (1 << INT_V_TTO1)
|
||||||
|
#define INT_QTY (1 << INT_V_QTY)
|
||||||
|
#define INT_ALM (1 << INT_V_ALM)
|
||||||
#define INT_STK (1 << INT_V_STK)
|
#define INT_STK (1 << INT_V_STK)
|
||||||
#define INT_NO_ION_PENDING (1 << INT_V_NO_ION_PENDING)
|
#define INT_NO_ION_PENDING (1 << INT_V_NO_ION_PENDING)
|
||||||
#define INT_ION (1 << INT_V_ION)
|
#define INT_ION (1 << INT_V_ION)
|
||||||
|
@ -260,6 +267,8 @@ typedef struct nova_dib DIB;
|
||||||
#define PI_PTR 0000020
|
#define PI_PTR 0000020
|
||||||
#define PI_PTP 0000004
|
#define PI_PTP 0000004
|
||||||
#define PI_PLT 0000010
|
#define PI_PLT 0000010
|
||||||
|
#define PI_QTY 0000002
|
||||||
|
#define PI_ALM 0000002
|
||||||
#define PI_TTI 0000002
|
#define PI_TTI 0000002
|
||||||
#define PI_TTO 0000001
|
#define PI_TTO 0000001
|
||||||
#define PI_TTI1 PI_TTI
|
#define PI_TTI1 PI_TTI
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* nova_dkp.c: NOVA moving head disk simulator
|
/* nova_dkp.c: NOVA moving head disk simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2003, Robert M. Supnik
|
Copyright (c) 1993-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
dkp moving head disk
|
dkp moving head disk
|
||||||
|
|
||||||
|
04-Jan-04 RMS Changed attach routine to use sim_fsize
|
||||||
28-Nov-03 CEO Boot from DP now puts device address in SR
|
28-Nov-03 CEO Boot from DP now puts device address in SR
|
||||||
24-Nov-03 CEO Added support for disk sizing on 6099/6103
|
24-Nov-03 CEO Added support for disk sizing on 6099/6103
|
||||||
19-Nov-03 CEO Corrected major DMA Mapping bug
|
19-Nov-03 CEO Corrected major DMA Mapping bug
|
||||||
|
@ -688,13 +689,12 @@ t_stat dkp_attach (UNIT *uptr, char *cptr)
|
||||||
int32 i, p;
|
int32 i, p;
|
||||||
t_stat r;
|
t_stat r;
|
||||||
|
|
||||||
uptr->capac = drv_tab[GET_DTYPE (uptr->flags)].size;
|
uptr->capac = drv_tab[GET_DTYPE (uptr->flags)].size; /* restore capac */
|
||||||
r = attach_unit (uptr, cptr);
|
r = attach_unit (uptr, cptr); /* attach */
|
||||||
if ((r != SCPE_OK) || ((uptr->flags & UNIT_AUTO) == 0)) return r;
|
if ((r != SCPE_OK) || !(uptr->flags & UNIT_AUTO)) return r;
|
||||||
if (fseek (uptr->fileref, 0, SEEK_END)) return SCPE_OK;
|
if ((p = sim_fsize (uptr->fileref)) == 0) return SCPE_OK; /* get file size */
|
||||||
if ((p = ftell (uptr->fileref)) == 0) return SCPE_OK;
|
|
||||||
for (i = 0; drv_tab[i].sect != 0; i++) {
|
for (i = 0; drv_tab[i].sect != 0; i++) {
|
||||||
if (p <= (drv_tab[i].size * (int) sizeof (short))) {
|
if (p <= (drv_tab[i].size * (int32) sizeof (uint16))) {
|
||||||
uptr->flags = (uptr->flags & ~UNIT_DTYPE) | (i << UNIT_V_DTYPE);
|
uptr->flags = (uptr->flags & ~UNIT_DTYPE) | (i << UNIT_V_DTYPE);
|
||||||
uptr->capac = drv_tab[i].size;
|
uptr->capac = drv_tab[i].size;
|
||||||
return SCPE_OK; } }
|
return SCPE_OK; } }
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
To: Users
|
To: Users
|
||||||
From: Bob Supnik
|
From: Bob Supnik
|
||||||
Subj: Nova Simulator Usage
|
Subj: Nova Simulator Usage
|
||||||
Date: 15-Mar-2003
|
Date: 15-Mar-2004
|
||||||
|
|
||||||
COPYRIGHT NOTICE
|
COPYRIGHT NOTICE
|
||||||
|
|
||||||
The following copyright notice applies to both the SIMH source and binary:
|
The following copyright notice applies to both the SIMH source and binary:
|
||||||
|
|
||||||
Original code published in 1993-2003, written by Robert M Supnik
|
Original code published in 1993-2004, written by Robert M Supnik
|
||||||
Copyright (c) 1993-2003, Robert M Supnik
|
Copyright (c) 1993-2004, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -36,15 +36,21 @@ This memorandum documents the Nova simulator.
|
||||||
|
|
||||||
1. Simulator Files
|
1. Simulator Files
|
||||||
|
|
||||||
sim/ sim_defs.h
|
sim/ scp.h
|
||||||
|
sim_console.h
|
||||||
|
sim_defs.h
|
||||||
|
sim_fio.h
|
||||||
sim_rev.h
|
sim_rev.h
|
||||||
sim_sock.h
|
sim_sock.h
|
||||||
sim_tape.h
|
sim_tape.h
|
||||||
|
sim_timer.h
|
||||||
sim_tmxr.h
|
sim_tmxr.h
|
||||||
scp.c
|
scp.c
|
||||||
scp_tty.c
|
sim_console.c
|
||||||
|
sim_fio.c
|
||||||
sim_sock.c
|
sim_sock.c
|
||||||
sim_tape.c
|
sim_tape.c
|
||||||
|
sim_timer.c
|
||||||
sim_tmxr.c
|
sim_tmxr.c
|
||||||
|
|
||||||
sim/nova/ nova_defs.h
|
sim/nova/ nova_defs.h
|
||||||
|
@ -55,6 +61,7 @@ sim/nova/ nova_defs.h
|
||||||
nova_lp.c
|
nova_lp.c
|
||||||
nova_mta.c
|
nova_mta.c
|
||||||
nova_plt.c
|
nova_plt.c
|
||||||
|
nova_qty.c
|
||||||
nova_sys.c
|
nova_sys.c
|
||||||
nova_tt.c
|
nova_tt.c
|
||||||
nova_tt1.c
|
nova_tt1.c
|
||||||
|
@ -66,7 +73,7 @@ The Nova simulator is configured as follows:
|
||||||
device simulates
|
device simulates
|
||||||
name(s)
|
name(s)
|
||||||
|
|
||||||
CPU Nova CPU with 32KW of memory
|
CPU Nova, Nova 3, or Nova 4 CPU with 32KW of memory
|
||||||
- hardware multiply/divide
|
- hardware multiply/divide
|
||||||
PTR,PTP paper tape reader/punch
|
PTR,PTP paper tape reader/punch
|
||||||
TTI,TTO console terminal
|
TTI,TTO console terminal
|
||||||
|
@ -77,6 +84,8 @@ CLK real-time clock
|
||||||
DK head-per-track disk controller
|
DK head-per-track disk controller
|
||||||
DP moving head disk controller with four drives
|
DP moving head disk controller with four drives
|
||||||
MT magnetic tape controller with eight 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:
|
The Nova simulator implements these unique stop conditions:
|
||||||
|
|
||||||
|
@ -86,6 +95,11 @@ The Nova simulator implements these unique stop conditions:
|
||||||
- more than INDMAX indirect addresses are detected during
|
- more than INDMAX indirect addresses are detected during
|
||||||
memory reference address decoding
|
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
|
The Nova loader supports standard binary format tapes. The DUMP command
|
||||||
is not implemented.
|
is not implemented.
|
||||||
|
|
||||||
|
@ -122,6 +136,11 @@ If memory size is being reduced, and the memory being truncated contains
|
||||||
non-zero data, the simulator asks for confirmation. Data in the truncated
|
non-zero data, the simulator asks for confirmation. Data in the truncated
|
||||||
portion of memory is lost. Initial memory size is 32K.
|
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
|
CPU registers include the visible state of the processor as well as the
|
||||||
control registers for the interrupt system.
|
control registers for the interrupt system.
|
||||||
|
|
||||||
|
@ -363,6 +382,12 @@ setting limited Dasher-compatibility mode or ANSI mode:
|
||||||
|
|
||||||
Setting either TTI1 or TTO1 changes both devices. In Dasher mode, carriage
|
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.
|
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 CONNECTIONS command displays the current connection to TTI1.
|
||||||
The SHOW TTI1 STATISTICS command displays statistics for the current connection.
|
The SHOW TTI1 STATISTICS command displays statistics for the current connection.
|
||||||
|
@ -390,6 +415,67 @@ The second terminal output implements these registers:
|
||||||
INT 1 interrupt pending flag
|
INT 1 interrupt pending flag
|
||||||
TIME 24 time from I/O initiation to interrupt
|
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)
|
2.3 Fixed Head Disk (DK)
|
||||||
|
|
||||||
Fixed head disk options include the ability to set the number of platters
|
Fixed head disk options include the ability to set the number of platters
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* nova_dsk.c: 4019 fixed head disk simulator
|
/* nova_dsk.c: 4019 fixed head disk simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2003, Robert M. Supnik
|
Copyright (c) 1993-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
dsk fixed head disk
|
dsk fixed head disk
|
||||||
|
|
||||||
|
04-Jan-04 RMS Changed sim_fsize calling sequence
|
||||||
26-Jul-03 RMS Fixed bug in set size routine
|
26-Jul-03 RMS Fixed bug in set size routine
|
||||||
14-Mar-03 RMS Fixed variable capacity interaction with save/restore
|
14-Mar-03 RMS Fixed variable capacity interaction with save/restore
|
||||||
03-Mar-03 RMS Fixed variable capacity and autosizing
|
03-Mar-03 RMS Fixed variable capacity and autosizing
|
||||||
|
@ -276,14 +277,17 @@ t_stat dsk_attach (UNIT *uptr, char *cptr)
|
||||||
{
|
{
|
||||||
uint32 sz, p;
|
uint32 sz, p;
|
||||||
uint32 ds_bytes = DSK_DKSIZE * sizeof (int16);
|
uint32 ds_bytes = DSK_DKSIZE * sizeof (int16);
|
||||||
|
t_stat r;
|
||||||
|
|
||||||
if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize (cptr))) {
|
r = attach_unit (uptr, cptr);
|
||||||
|
if (r != SCPE_OK) return r;
|
||||||
|
if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize (uptr->fileref))) {
|
||||||
p = (sz + ds_bytes - 1) / ds_bytes;
|
p = (sz + ds_bytes - 1) / ds_bytes;
|
||||||
if (p >= DSK_NUMDK) p = DSK_NUMDK - 1;
|
if (p >= DSK_NUMDK) p = DSK_NUMDK - 1;
|
||||||
uptr->flags = (uptr->flags & ~UNIT_PLAT) |
|
uptr->flags = (uptr->flags & ~UNIT_PLAT) |
|
||||||
(p << UNIT_V_PLAT); }
|
(p << UNIT_V_PLAT); }
|
||||||
uptr->capac = UNIT_GETP (uptr->flags) * DSK_DKSIZE; /* set capacity */
|
uptr->capac = UNIT_GETP (uptr->flags) * DSK_DKSIZE; /* set capacity */
|
||||||
return attach_unit (uptr, cptr);
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Change disk size */
|
/* Change disk size */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* nova_lp.c: NOVA line printer simulator
|
/* nova_lp.c: NOVA line printer simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2003, Robert M. Supnik
|
Copyright (c) 1993-2004, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue