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:
Bob Supnik 2004-04-06 05:17:00 -07:00 committed by Mark Pizzolato
parent 1da2d9452d
commit 26aa6de663
232 changed files with 17724 additions and 9661 deletions

View file

@ -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
View 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.

View file

@ -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
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
packet reads and writes, since all operating systems talk to real ethernet
cards/controllers differently. The host-dependant Sim_Ether module currently
supports Windows, Linux, NetBSD, OpenBSD, FreeBSD, OS/X, and Alpha VMS.
The XU emulator is a host-independant software emulation of Digital's DEUNA
(M7792/M7793) and DELUA (M7521) Unibus ethernet cards for the SIMH emulator.
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
doesn't want. In Windows, packets having the same source MAC address as the
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
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!
-------------------------------------------------------------------------------
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
'run as root' requirement will be welcomed.
----- WARNING ----- WARNING ----- WARNING ----- WARNING ----- WARNING -----
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.
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:
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
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!
@ -114,7 +149,8 @@ OpenVMS Alpha notes:
no network devices are available
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;
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.
Building on OpenVMS Alpha:
1. Build the PCAP library and execlet. They are in the [.PCAP-VMS]
directory in the simh source distribution. The following builds
both the pcap library and the pcap execlet:
$ set def [.pcap-vms]
$ @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
the SYS$LOADABLE_IMAGES directory.
Build done...
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")
The current descrip.mms file will build simulators capable of using
ethernet support with them automatically. These currently are: VAX,
PDP11, and PDP10. The descrip.mms driven builds will also build the
pcap library and build and install the VCI execlet.
1. Fetch the VMS-PCAP zip file from:
http://simh.trailing-edge.com/sources/vms-pcap.zip
2. Unzip it into the base of the simh distribution directory.
3. Build the simulator(s) with MMS or MMK:
$ MMx {VAX,PDP11,PDP10, etc...}
-------------------------------------------------------------------------------
@ -160,7 +187,28 @@ An RT-11 v5.3 system with a freeware TCP/IP stack has been successfully run.
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
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:
@ -168,7 +216,6 @@ Things planned for future releases:
2. Full MOP implementation
3. DESQA support (if someone can get me the user manuals)
4. DETQA support [DELQA-Turbo] (I have the manual)
5. DEUNA/DELUA support
-------------------------------------------------------------------------------
@ -190,12 +237,21 @@ Dave
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:
1. Added VMS support to Sim_Ether; created pcap-vms port (Anders Ahgren)
2. Added DECNET duplicate detection for Windows (Mark Pizzolato)
3. Added BPF filtering to increase efficiency (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)
7. Added Universal TUN/TAP support (Mark Pizzolato)
8. Added FreeBSD support (Edward Brocklesby)

View file

@ -3,6 +3,7 @@ Altair 8800 Simulator with Z80 support
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)
- 9-Oct-2002, Peter Schorn (added support for simulated hard disk)
- 28-Sep-2002, Peter Schorn (number of tracks per disk can be configured)
@ -842,6 +843,9 @@ following commands:
4. Special simulator features
4.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
@ -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.
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
- Full support for Z80. CP/M software requiring a Z80 CPU now runs
properly. DDTZ and PROLOGZ are included for demonstration purposes.

File diff suppressed because it is too large Load diff

View file

@ -1,90 +1,86 @@
/* altairz80_defs.h: MITS Altair simulator definitions
Copyright (c) 2002-2003, 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
*/
#include "sim_defs.h" /* simulator definitions */
#define MAXMEMSIZE 65536 /* maximum memory size */
#define ADDRMASK (MAXMEMSIZE - 1) /* address mask */
#define bootrom_size 256 /* size of boot rom */
#define MAXBANKS 8 /* max number of memory banks */
#define MAXBANKSLOG2 3 /* log2 of MAXBANKS */
#define BANKMASK (MAXBANKS-1) /* bank mask */
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
#define KB 1024 /* kilo byte */
#define defaultROMLow 0xff00 /* default for lowest addres of ROM */
#define defaultROMHigh 0xffff /* default for highest addres of ROM */
#define NUM_OF_DSK 8 /* NUM_OF_DSK must be power of two */
#define LDAInstruction 0x3e /* op-code for LD A,<8-bit value> instruction */
#define unitNoOffset1 0x37 /* LD A,<unitno> */
#define unitNoOffset2 0xb4 /* LD a,80h | <unitno> */
#define UNIT_V_OPSTOP (UNIT_V_UF+0) /* stop on nvalid operation */
#define UNIT_OPSTOP (1 << UNIT_V_OPSTOP)
#define UNIT_V_CHIP (UNIT_V_UF+1) /* 8080 or Z80 CPU */
#define UNIT_CHIP (1 << UNIT_V_CHIP)
#define UNIT_V_MSIZE (UNIT_V_UF+2) /* memory size */
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
#define UNIT_V_BANKED (UNIT_V_UF+3) /* banked memory is used */
#define UNIT_BANKED (1 << UNIT_V_BANKED)
#define UNIT_V_ROM (UNIT_V_UF+4) /* ROM exists */
#define UNIT_ROM (1 << UNIT_V_ROM)
#define UNIT_V_ALTAIRROM (UNIT_V_UF+5) /* ALTAIR ROM exists */
#define UNIT_ALTAIRROM (1 << UNIT_V_ALTAIRROM)
#define UNIT_V_WARNROM (UNIT_V_UF+6) /* warn if ROM is written to */
#define UNIT_WARNROM (1 << UNIT_V_WARNROM)
#define AddressFormat "[%04xh]"
#define PCformat "\n" AddressFormat " "
#define message1(p1) \
sprintf(messageBuffer,PCformat p1,PCX); printMessage()
#define message2(p1,p2) \
sprintf(messageBuffer,PCformat p1,PCX,p2); printMessage()
#define message3(p1,p2,p3) \
sprintf(messageBuffer,PCformat p1,PCX,p2,p3); printMessage()
#define message4(p1,p2,p3,p4) \
sprintf(messageBuffer,PCformat p1,PCX,p2,p3,p4); printMessage()
#define message5(p1,p2,p3,p4,p5) \
sprintf(messageBuffer,PCformat p1,PCX,p2,p3,p4,p5); printMessage()
#define message6(p1,p2,p3,p4,p5,p6) \
sprintf(messageBuffer,PCformat p1,PCX,p2,p3,p4,p5,p6); printMessage()
/* The Default is to use "inline". In this case the wrapper functions for
GetBYTE and PutBYTE need to be created. Otherwise they are not needed
and the calls map to the original functions. */
#ifdef NO_INLINE
#define INLINE
#define GetBYTEWrapper GetBYTE
#define PutBYTEWrapper PutBYTE
#else
#if defined(__DECC) && defined(VMS)
#define INLINE __inline
#else
#define INLINE inline
#endif
#endif
/* altairz80_defs.h: MITS Altair simulator definitions
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
*/
#include "sim_defs.h" /* simulator definitions */
#define MAXMEMSIZE 65536 /* maximum memory size */
#define ADDRMASK (MAXMEMSIZE - 1) /* address mask */
#define bootrom_size 256 /* size of boot rom */
#define MAXBANKS 8 /* max number of memory banks */
#define MAXBANKSLOG2 3 /* log2 of MAXBANKS */
#define BANKMASK (MAXBANKS-1) /* bank mask */
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
#define KB 1024 /* kilo byte */
#define defaultROMLow 0xff00 /* default for lowest addres of ROM */
#define defaultROMHigh 0xffff /* default for highest addres of ROM */
#define NUM_OF_DSK 8 /* NUM_OF_DSK must be power of two */
#define LDAInstruction 0x3e /* op-code for LD A,<8-bit value> instruction */
#define unitNoOffset1 0x37 /* LD A,<unitno> */
#define unitNoOffset2 0xb4 /* LD a,80h | <unitno> */
#define UNIT_V_OPSTOP (UNIT_V_UF+0) /* stop on nvalid operation */
#define UNIT_OPSTOP (1 << UNIT_V_OPSTOP)
#define UNIT_V_CHIP (UNIT_V_UF+1) /* 8080 or Z80 CPU */
#define UNIT_CHIP (1 << UNIT_V_CHIP)
#define UNIT_V_MSIZE (UNIT_V_UF+2) /* memory size */
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
#define UNIT_V_BANKED (UNIT_V_UF+3) /* banked memory is used */
#define UNIT_BANKED (1 << UNIT_V_BANKED)
#define UNIT_V_ROM (UNIT_V_UF+4) /* ROM exists */
#define UNIT_ROM (1 << UNIT_V_ROM)
#define UNIT_V_ALTAIRROM (UNIT_V_UF+5) /* ALTAIR ROM exists */
#define UNIT_ALTAIRROM (1 << UNIT_V_ALTAIRROM)
#define UNIT_V_WARNROM (UNIT_V_UF+6) /* warn if ROM is written to */
#define UNIT_WARNROM (1 << UNIT_V_WARNROM)
#define AddressFormat "[%04xh]"
#define PCformat "\n" AddressFormat " "
#define message1(p1) \
sprintf(messageBuffer,PCformat p1,PCX); printMessage()
#define message2(p1,p2) \
sprintf(messageBuffer,PCformat p1,PCX,p2); printMessage()
#define message3(p1,p2,p3) \
sprintf(messageBuffer,PCformat p1,PCX,p2,p3); printMessage()
#define message4(p1,p2,p3,p4) \
sprintf(messageBuffer,PCformat p1,PCX,p2,p3,p4); printMessage()
#define message5(p1,p2,p3,p4,p5) \
sprintf(messageBuffer,PCformat p1,PCX,p2,p3,p4,p5); printMessage()
#define message6(p1,p2,p3,p4,p5,p6) \
sprintf(messageBuffer,PCformat p1,PCX,p2,p3,p4,p5,p6); printMessage()
/* The Default is to use "inline". */
#if defined(NO_INLINE)
#define INLINE
#else
#if defined(__DECC) && defined(VMS)
#define INLINE __inline
#else
#define INLINE inline
#endif
#endif

View file

@ -1,6 +1,6 @@
/* 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
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 saved_PC;
extern FILE *sim_log;
extern void PutBYTEWrapper(register uint32 Addr, register uint32 Value);
extern void printMessage(void);
extern char messageBuffer[];
extern int32 install_bootrom(void);
@ -251,7 +250,9 @@ DEVICE dsk_dev = {
"DSK", dsk_unit, dsk_reg, dsk_mod,
8, 10, 31, 1, 8, 8,
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) {
int32 i;
@ -351,7 +352,7 @@ int32 dsk10(const int32 port, const int32 io, const int32 data) {
if (current_disk >= NUM_OF_DSK) {
if (hasVerbose() && (warnDSK10 < warnLevelDSK)) {
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 */
}
@ -363,14 +364,14 @@ int32 dsk10(const int32 port, const int32 io, const int32 data) {
writebuf();
}
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_flags = (dsk_dev.units + current_disk) -> flags;
if ((current_disk_flags & UNIT_ATT) == 0) { /* nothing attached? */
if ( (current_disk_flags & UNIT_DSK_VERBOSE) && (warnAttached[current_disk] < warnLevelDSK) ) {
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;
}
@ -390,7 +391,7 @@ int32 dsk11(const int32 port, const int32 io, const int32 data) {
if (current_disk >= NUM_OF_DSK) {
if (hasVerbose() && (warnDSK11 < warnLevelDSK)) {
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 */
}
@ -400,10 +401,10 @@ int32 dsk11(const int32 port, const int32 io, const int32 data) {
in9_count++;
if ((trace_flag & TRACE_SECTOR_STUCK) && (in9_count > 2 * DSK_SECT) && (!in9_message)) {
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) {
message1("IN 0x09\n");
message1("IN 0x09");
}
if (dirty) {/* implies that current_disk < NUM_OF_DSK */
writebuf();
@ -425,12 +426,12 @@ int32 dsk11(const int32 port, const int32 io, const int32 data) {
/* drive functions */
if (trace_flag & TRACE_IN_OUT) {
message2("OUT 0x09: %x\n", data);
message2("OUT 0x09: %x", data);
}
if (data & 0x01) { /* step head in */
if (trace_flag & TRACE_TRACK_STUCK) {
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]++;
@ -447,7 +448,7 @@ int32 dsk11(const int32 port, const int32 io, const int32 data) {
if (data & 0x02) { /* step head out */
if (trace_flag & TRACE_TRACK_STUCK) {
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]--;
@ -501,7 +502,7 @@ int32 dsk12(const int32 port, const int32 io, const int32 data) {
if (current_disk >= NUM_OF_DSK) {
if (hasVerbose() && (warnDSK12 < warnLevelDSK)) {
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;
}
@ -513,7 +514,7 @@ int32 dsk12(const int32 port, const int32 io, const int32 data) {
if (current_byte[current_disk] >= DSK_SECTSIZE) {
/* physically read the sector */
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++) {
dskbuf[i] = 0;
@ -547,21 +548,21 @@ static void writebuf(void) {
uptr = dsk_dev.units + current_disk;
if (((uptr -> flags) & UNIT_DSKWLK) == 0) { /* write enabled */
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)) {
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);
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) ) {
/* write locked - print warning message if required */
warnLock[current_disk]++;
/*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_byte[current_disk] = 0xff;

View file

@ -1,6 +1,6 @@
/* 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
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_putchar(int32 out);
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 FILE *sim_log;
extern int32 PCX;
@ -119,8 +122,6 @@ extern int32 sim_switches;
extern uint32 sim_os_msec(void);
extern const char *scp_error_messages[];
extern int32 SR;
extern int32 bankSelect;
extern int32 common;
extern uint8 GetBYTEWrapper(register uint32 Addr);
extern UNIT cpu_unit;
@ -184,7 +185,7 @@ static SIO_TERMINAL sio_terminals[Terminals] =
{0, 0, 0x16, 0x17, 0x00},
{0, 0, 0x18, 0x19, 0x00} };
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 };
@ -220,7 +221,9 @@ DEVICE sio_dev = {
"SIO", &sio_unit, sio_reg, sio_mod,
1, 10, 31, 1, 8, 8,
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),
KBD_POLL_WAIT };
@ -235,7 +238,9 @@ DEVICE ptr_dev = {
"PTR", &ptr_unit, ptr_reg, NULL,
1, 10, 31, 1, 8, 8,
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),
KBD_POLL_WAIT };
@ -250,7 +255,9 @@ DEVICE ptp_dev = {
"PTP", &ptp_unit, ptp_reg, NULL,
1, 10, 31, 1, 8, 8,
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
between Altair and SIMH environment using port 0xfe */
@ -301,14 +308,24 @@ DEVICE simh_device = {
"SIMH", &simh_unit, simh_reg, simh_mod,
1, 10, 31, 1, 16, 4,
NULL, NULL, &simh_dev_reset,
NULL, NULL, NULL, NULL, 0, NULL, NULL };
NULL, NULL, NULL,
NULL, 0, 0,
NULL, NULL, NULL };
char messageBuffer[256];
void printMessage(void) {
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) {
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) {
int32 i;
for (i = 0; i < Terminals; i++) {
altairTMXR.ldsc[i] = &TerminalLines[i];
}
reset_sio_terminals(FALSE);
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 */
if (temp >= 0) {
altairTMXR.ldsc[temp] -> rcve = 1; /* enable receive */
TerminalLines[temp].rcve = 1; /* enable receive */
}
tmxr_poll_rx(&altairTMXR); /* poll input */
tmxr_poll_tx(&altairTMXR); /* poll output */
@ -385,8 +398,8 @@ static t_stat sio_reset(DEVICE *dptr) {
resetSIOWarningFlags();
if (sio_unit.flags & UNIT_ATT) {
for (i = 0; i < Terminals; i++) {
if (altairTMXR.ldsc[i] -> conn > 0) {
tmxr_reset_ln(altairTMXR.ldsc[i]);
if (TerminalLines[i].conn > 0) {
tmxr_reset_ln(&TerminalLines[i]);
}
}
reset_sio_terminals(FALSE);
@ -442,9 +455,9 @@ int32 sio0s(const int32 port, const int32 io, const int32 data) {
if (io == 0) { /* IN */
if (sio_unit.flags & UNIT_ATT) {
sio_terminals[ti].status =
(((tmxr_rqln(altairTMXR.ldsc[ti]) > 0 ? 0x01 : 0) |
(((tmxr_rqln(&TerminalLines[ti]) > 0 ? 0x01 : 0) |
/* 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 */
}
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 (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;
if (sio_unit.flags & UNIT_BS) {
@ -493,7 +506,7 @@ int32 sio0d(const int32 port, const int32 io, const int32 data) {
else { /* OUT */
int32 d = sio_unit.flags & UNIT_ANSI ? data & 0x7f : data;
if (sio_unit.flags & UNIT_ATT) {
tmxr_putc_ln(altairTMXR.ldsc[ti], d);
tmxr_putc_ln(&TerminalLines[ti], d); /* status ignored */
}
else {
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 ((sio_unit.flags & UNIT_SIO_VERBOSE) && (warnUnattachedPTR < warnLevelSIO)) {
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;
}
@ -536,14 +549,14 @@ int32 sio1d(const int32 port, const int32 io, const int32 data) {
if (ptr_unit.u3) { /* no more data available */
if ((sio_unit.flags & UNIT_SIO_VERBOSE) && (warnPTREOF < warnLevelSIO)) {
warnPTREOF++;
/*07*/ message1("PTR attempted to read past EOF. 0x00 returned.\n");
/*07*/ message1("PTR attempted to read past EOF. 0x00 returned.");
}
return 0;
}
if ((ptr_unit.flags & UNIT_ATT) == 0) { /* not attached */
if ((sio_unit.flags & UNIT_SIO_VERBOSE) && (warnUnattachedPTR < warnLevelSIO)) {
warnUnattachedPTR++;
/*08*/ message1("Attempt to read from unattached PTR. 0x00 returned.\n");
/*08*/ message1("Attempt to read from unattached PTR. 0x00 returned.");
}
return 0;
}
@ -560,7 +573,7 @@ int32 sio1d(const int32 port, const int32 io, const int32 data) {
} /* else ignore data */
else if ((sio_unit.flags & UNIT_SIO_VERBOSE) && (warnUnattachedPTP < warnLevelSIO)) {
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++;
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)) {
warnUnassignedPort++;
if (io == 0) {
message2("Unassigned IN(%2xh) - ignored.\n", port);
message2("Unassigned IN(%2xh) - ignored.", port);
}
else {
message3("Unassigned OUT(%2xh) -> %2xh - ignored.\n", port, data);
message3("Unassigned OUT(%2xh) -> %2xh - ignored.", port, data);
}
}
return io == 0 ? 0xff : 0;
@ -739,7 +752,7 @@ static void attachCPM(UNIT *uptr) {
}
lastCPMStatus = attach_unit(uptr, cpmCommandLine);
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;
case getBankSelectCmd:
if (cpu_unit.flags & UNIT_BANKED) {
result = bankSelect;
result = getBankSelect();
}
else {
result = 0;
@ -874,11 +887,11 @@ static int32 simh_in(const int32 port) {
break;
case getCommonCmd:
if (getCommonPos == 0) {
result = common & 0xff;
result = getCommon() & 0xff;
getCommonPos = 1;
}
else {
result = (common >> 8) & 0xff;
result = (getCommon() >> 8) & 0xff;
getCommonPos = lastCommand = 0;
}
break;
@ -898,7 +911,7 @@ static int32 simh_in(const int32 port) {
break;
default:
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);
}
result = lastCommand = 0;
@ -933,7 +946,7 @@ static int32 simh_out(const int32 port, const int32 data) {
break;
case setBankSelectCmd:
if (cpu_unit.flags & UNIT_BANKED) {
bankSelect = data & BANKMASK;
setBankSelect(data & BANKMASK);
}
else if (simh_unit.flags & UNIT_SIMH_VERBOSE) {
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) {
case printTimeCmd: /* print time */
if (rtc_avail) {
message2("Current time in milliseconds = %d.\n", sim_os_msec());
message2("Current time in milliseconds = %d.", sim_os_msec());
}
else {
warnNoRealTimeClock();
@ -977,7 +990,7 @@ static int32 simh_out(const int32 port, const int32 data) {
markTime[markTimeSP++] = sim_os_msec();
}
else {
message1("Timer stack overflow.\n");
message1("Timer stack overflow.");
}
}
else {
@ -988,10 +1001,10 @@ static int32 simh_out(const int32 port, const int32 data) {
if (rtc_avail) {
if (markTimeSP > 0) {
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 {
message1("No timer active.\n");
message1("No timer active.");
}
}
else {
@ -1044,10 +1057,10 @@ static int32 simh_out(const int32 port, const int32 data) {
if (rtc_avail) {
if (markTimeSP > 0) {
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 {
message1("No timer active.\n");
message1("No timer active.");
}
}
else {
@ -1091,7 +1104,7 @@ static int32 simh_out(const int32 port, const int32 data) {
break;
default:
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);
}
}

File diff suppressed because it is too large Load diff

972
AltairZ80/altairz80_doc.txt Normal file
View 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

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -111,7 +111,9 @@ DEVICE hdsk_dev = {
"HDSK", hdsk_unit, hdsk_reg, hdsk_mod,
8, 10, 31, 1, 8, 8,
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) {
return SCPE_OK;
@ -224,34 +226,34 @@ static int32 checkParameters(void) {
int32 currentFlag;
if ((selectedDisk < 0) || (selectedDisk >= HDSK_NUMBER)) {
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;
}
currentFlag = (hdsk_dev.units + selectedDisk) -> flags;
if ((currentFlag & UNIT_ATT) == 0) {
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 */
}
if ((selectedSector < 0) || (selectedSector >= HDSK_SECTORS_PER_TRACK)) {
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);
}
selectedSector = 0;
}
if ((selectedTrack < 0) || (selectedTrack >= HDS_MAX_TRACKS)) {
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);
}
selectedTrack = 0;
}
selectedDMA &= ADDRMASK;
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",
selectedDisk, selectedSector, selectedTrack, selectedDMA);
}
@ -263,7 +265,7 @@ static int32 doSeek(void) {
if (fseek(uptr -> fileref,
HDSK_TRACK_SIZE * selectedTrack + HDSK_SECTOR_SIZE * selectedSector, SEEK_SET)) {
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);
}
return CPM_ERROR;
@ -285,7 +287,7 @@ static int32 doRead(void) {
hdskbuf[i] = CPM_EMPTY;
}
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);
}
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 ((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);
}
return CPM_ERROR;
@ -317,7 +319,7 @@ static int32 doWrite(void) {
}
else {
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);
}
return CPM_ERROR;
@ -334,7 +336,7 @@ static int32 hdsk_in(const int32 port) {
return result;
}
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);
}
return CPM_OK;

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,14 +1,14 @@
To: Users
From: Bob Supnik
Subj: GRI-909 Simulator Usage
Date: 20-Apr-2003
Date: 15-Feb-2004
COPYRIGHT NOTICE
The following copyright notice applies to both the SIMH source and binary:
Original code published in 1993-2003, written by Robert M Supnik
Copyright (c) 1993-2003, Robert M Supnik
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"),
@ -36,13 +36,19 @@ This memorandum documents the GRI-909 simulator.
1. Simulator Files
sim/ sim_defs.h
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
scp_tty.c
sim_console.c
sim_fio.c
sim_sock.c
sim_timer.c
sim_tmxr.c
sim/gri/ gri_defs.h

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -25,6 +25,7 @@
cpu H316/H516 CPU
04-Jan-04 RMS Removed unnecessary compare
31-Dec-03 RMS Fixed bug in cpu_set_hist
24-Oct-03 RMS Added DMA/DMC support, instruction history
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 */
if (dibp->chan) { /* DMA/DMC? */
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);
if (sim_log) fprintf (sim_log,
"%s configured for DMA channel %d\n", sim_dname (dptr), chan + 1);

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,14 +1,14 @@
To: Users
From: Bob Supnik
Subj: H316 Simulator Usage
Date: 15-Nov-2003
Date: 15-Feb-2004
COPYRIGHT NOTICE
The following copyright notice applies to both the SIMH source and binary:
Original code published in 1993-2003, written by Robert M Supnik
Copyright (c) 1993-2003, Robert M Supnik
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"),
@ -38,15 +38,21 @@ This memorandum documents the Honeywell 316/516 simulator.
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_sock.h
sim_tape.h
sim_timer.h
sim_tmxr.h
scp.c
scp_tty.c
sim_console.c
sim_fio.c
sim_sock.c
sim_tape.c
sim_timer.c
sim_tmxr.c
sim/h316/ h316_defs.h

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,8 @@
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.
*/
@ -402,14 +404,17 @@ t_stat fhd_attach (UNIT *uptr, char *cptr)
{
uint32 sz, sf;
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;
if (sf >= FH_NUMSF) sf = FH_NUMSF - 1;
uptr->flags = (uptr->flags & ~UNIT_SF) |
(sf << UNIT_V_SF); }
uptr->capac = UNIT_GETSF (uptr->flags) * FH_WDPSF;
return attach_unit (uptr, cptr);
return SCPE_OK;
}
/* Set size routine */

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,14 +1,14 @@
To: Users
From: Bob Supnik
Subj: HP2100 Simulator Usage
Date: 15-Jul-2003
Date: 15-Feb-2004
COPYRIGHT NOTICE
The following copyright notice applies to both the SIMH source and binary:
Original code published in 1993-2002, written by Robert M Supnik
Copyright (c) 1993-2003, Robert M Supnik
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"),
@ -36,15 +36,21 @@ This memorandum documents the HP 2100 simulator.
1. Simulator Files
sim/ sim_defs.h
sim/ scp.h
sim_console.h
sim_defs.h
sim_fio.h
sim_rev.h
sim_sock.h
sim_tape.h
sim_timer.h
sim_tmxr.h
scp.c
scp_tty.c
sim_console.c
sim_fio.c
sim_sock.c
sim_tape.c
sim_timer.c
sim_tmxr.c
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
default mode is UC. In addition, each line supports the DATASET option.
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
lines: data terminal ready and request to send from the computer to the

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
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)
09-May-03 RMS Added network device flag
01-Nov-02 RMS Added 7B/8B support
@ -152,7 +153,7 @@ uint32 muxc_chan = 0; /* ctrl chan */
uint32 muxc_scan = 0; /* ctrl scan */
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;
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_MDM, 0, "no dataset", "NODATASET", 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",
&hp_setdev, &hp_showdev, &muxl_dev },
{ 0 } };
@ -433,7 +438,7 @@ case ioOTX: /* output */
(muxc_ota[ln] & ~OTC_C1) | (dat & OTC_C1);
if ((muxl_unit[ln].flags & UNIT_MDM) && /* modem ctrl? */
(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 */
muxc_lia[ln] = 0; } /* dataset off */
} /* end update */
@ -645,9 +650,7 @@ if (muxu_unit.flags & UNIT_ATT) { /* master att? */
t = sim_rtcn_init (muxu_unit.wait, TMR_MUX);
sim_activate (&muxu_unit, t); } } /* activate */
else sim_cancel (&muxu_unit); /* else stop */
for (i = 0; i < MUX_LINES; i++) {
mux_desc.ldsc[i] = &mux_ldsc[i];
mux_reset_ln (i); }
for (i = 0; i < MUX_LINES; i++) mux_reset_ln (i);
return SCPE_OK;
}

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,14 +1,14 @@
To: Users
From: Bob Supnik
Subj: IBM 1401 Simulator Usage
Date: 15-Jul-2003
Date: 15-Feb-2004
COPYRIGHT NOTICE
The following copyright notice applies to both the SIMH source and binary:
Original code published in 1993-2003, written by Robert M Supnik
Copyright (c) 1993-2003, Robert M Supnik
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"),
@ -36,15 +36,21 @@ This memorandum documents the IBM 1401 simulator.
1. Simulator Files
sim/ sim_defs.h
sim/ scp.h
sim_console.h
sim_defs.h
sim_fio.h
sim_rev.h
sim_sock.h
sim_tape.h
sim_timer.h
sim_tmxr.h
scp.c
scp_tty.c
sim_console.c
sim_fio.c
sim_sock.c
sim_tape.c
sim_timer.c
sim_tmxr.c
sim/i1401/ i1401_defs.h

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
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
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)
21-Aug-03 RMS Fixed bug in immediate index add (found by Michael Short)
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);
void upd_ind (void);
extern tty (uint32 op, uint32 pa, uint32 f0, uint32 f1);
extern ptp (uint32 op, uint32 pa, uint32 f0, uint32 f1);
extern ptr (uint32 op, uint32 pa, uint32 f0, uint32 f1);
extern cdp (uint32 op, uint32 pa, uint32 f0, uint32 f1);
extern cdr (uint32 op, uint32 pa, uint32 f0, uint32 f1);
extern dp (uint32 op, uint32 pa, uint32 f0, uint32 f1);
extern lpt (uint32 op, uint32 pa, uint32 f0, uint32 f1);
extern btp (uint32 op, uint32 pa, uint32 f0, uint32 f1);
extern btr (uint32 op, uint32 pa, uint32 f0, uint32 f1);
extern t_stat tty (uint32 op, uint32 pa, uint32 f0, uint32 f1);
extern t_stat ptp (uint32 op, uint32 pa, uint32 f0, uint32 f1);
extern t_stat ptr (uint32 op, uint32 pa, uint32 f0, uint32 f1);
extern t_stat cdp (uint32 op, uint32 pa, uint32 f0, uint32 f1);
extern t_stat cdr (uint32 op, uint32 pa, uint32 f0, uint32 f1);
extern t_stat dp (uint32 op, uint32 pa, uint32 f0, uint32 f1);
extern t_stat lpt (uint32 op, uint32 pa, uint32 f0, uint32 f1);
extern t_stat btp (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_mul (uint32 d, uint32 s);

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,14 +1,14 @@
To: Users
From: Bob Supnik
Subj: IBM 1620 Simulator Usage
Date: 15-Apr-2003
Date: 15-Feb-2004
COPYRIGHT NOTICE
The following copyright notice applies to both the SIMH source and binary:
Original code published in 1993-2003, written by Robert M Supnik
Copyright (c) 1993-2003, Robert M Supnik
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"),
@ -36,13 +36,19 @@ Geoff Kuenning's 1620 simulator, which is used by permission.
1. Simulator Files
sim/ sim_defs.h
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
scp_tty.c
sim_console.c
sim_fio.c
sim_sock.c
sim_timer.c
sim_tmxr.c
sim/i1620/ i1620_defs.h

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -141,7 +141,7 @@ extern CTAB *sim_vm_cmd;
#define MAX_EXTRA_COMMANDS 10
CTAB x_cmds[MAX_EXTRA_COMMANDS];
#ifdef WIN32
#ifdef _WIN32
# define CRLF "\r\n"
#else
# 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)
{
if (addr < MEMSIZE) {
M[addr] = val & 0xFFFF;
M[addr] = (uint16) (val & 0xFFFF);
return SCPE_OK;
}
return SCPE_NXM;
@ -1476,7 +1476,7 @@ static t_stat cpu_attach (UNIT *uptr, char *cptr)
PSYMENTRY n, prv, s;
FILE *fd;
unlink(cptr); // delete old log file, if present
remove(cptr); // delete old log file, if present
new_log = TRUE;
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;
}
else {
if ((sign = mant & 0x80000000))
if ((sign = mant & 0x80000000) != 0)
mant = -mant;
fac = (float) mant * ((float) 1./ (float) (unsigned long) 0x80000000);
}
sprintf(fltstr, "%c%.5f ", sign ? '-' : ' ', fac);
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);
if ((sign = (mant & 0x00800000)))
if ((sign = (mant & 0x00800000)) != 0)
mant = (-mant) & 0x00FFFFFF;
fac = (float) mant * ((float) 1. / (float) 0x00800000);
@ -1660,7 +1660,7 @@ void debug_print (char *fmt, ...)
}
}
#ifdef WIN32
#ifdef _WIN32
#include <windows.h>
#endif
@ -1668,7 +1668,7 @@ void debug_print (char *fmt, ...)
static t_stat view_cmd (int flag, char *cptr)
{
#ifdef WIN32
#ifdef _WIN32
char cmdline[256];
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_timeout() will be called after cgi_maxsec seconds.
#if defined(WIN32)
#if defined(_WIN32)
static DWORD WINAPI cgi_timer_thread (LPVOID arg)
{
Sleep(cgi_maxsec*1000); // timer thread -- wait, then call timeout routine

View file

@ -1,6 +1,10 @@
#include "ibm1130_defs.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
Based on the SIMH package written by Robert M Supnik
@ -1187,7 +1191,7 @@ static void checkdeck (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;
long fpos;
@ -1204,7 +1208,7 @@ static t_bool nextdeck (void)
cr_unit.fileref = NULL;
if (cr_unit.flags & UNIT_SCRATCH) {
unlink(tempfile);
remove(tempfile);
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 (*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");
break_simulation(STOP_DECK_BREAK);
return 0;
@ -1238,12 +1273,13 @@ static t_bool nextdeck (void)
strcpy(tempfile, tn);
strcat(tempfile, ".tmp");
}
if ((cr_unit.fileref = fopen(tempfile, "wb+")) == NULL) {
// (re)create file
if ((cr_unit.fileref = fopen(tempfile, "w+b")) == NULL) {
printf("Cannot create temporary file %s\n", tempfile);
break_simulation(STOP_DECK_BREAK);
return 0;
}
#endif
SETBIT(cr_unit.flags, UNIT_SCRATCH);
@ -1560,7 +1596,7 @@ t_stat cr_detach (UNIT *uptr)
fclose(cr_unit.fileref);
if (cr_unit.flags & UNIT_SCRATCH) {
unlink(tempfile);
remove(tempfile);
CLRBIT(cr_unit.flags, UNIT_SCRATCH);
}
@ -1677,7 +1713,7 @@ void xio_1142_card (int32 addr, int32 func, int32 modify)
{
char msg[80];
int ch;
int16 wd;
uint16 wd;
t_bool lastcard;
switch (func) {
@ -1763,7 +1799,7 @@ void xio_1142_card (int32 addr, int32 func, int32 modify)
cp_unit.COLUMN = 81;
}
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;
if (wd & 0x0008) /* mark this as last column to be punched */
SETBIT(cp_unit.flags, UNIT_LASTPUNCH);
@ -2052,8 +2088,7 @@ char response_byte;
static DWORD CALLBACK pcr_thread (LPVOID arg)
{
DWORD event;
long nrcvd, nread;
DWORD event, nrcvd, nread;
HANDLE objs[4];
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);
if (nrcvd > 0) {
pcr_nleft -= nrcvd;
pcr_nleft -= (int) nrcvd;
begin_pcr_critical_section();
pcr_nready += nrcvd;
pcr_nready += (int) nrcvd;
end_pcr_critical_section();
}
@ -2210,7 +2245,7 @@ static char lastcmd = '?';
static void pcr_cmd (char cmd)
{
long nwrite, nrcvd;
DWORD nwrite, nrcvd;
if (cmd != '\0') {
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)
{
long nrcvd;
DWORD nrcvd;
static char prev_status = '?';
BOOL show;
@ -2276,7 +2311,7 @@ static void pcr_set_dsw_from_status (BOOL post_pick)
static BOOL pcr_handle_byte (char byte)
{
long nrcvd;
DWORD nrcvd;
GetOverlappedResult(hpcr, &ovRd, &nrcvd, TRUE);

View file

@ -15,6 +15,7 @@
#include "sim_defs.h" /* main SIMH defns (include path should include .., or make a copy) */
#include <setjmp.h>
#include <assert.h>
#include <stdlib.h>
#if defined(VMS)
# include <unistd.h> /* to pick up 'unlink' */
@ -23,7 +24,7 @@
#define MIN(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 strcmpi (char *a, char *b);
#endif

View file

@ -347,7 +347,7 @@ void xio_disk (int32 iocc_addr, int32 func, int32 modify, int drv)
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];
if (modify & 0x01) { /* reset interrupts */
@ -474,7 +474,7 @@ t_stat dsk_reset (DEVICE *dptr)
uptr->CYL = 0;
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();

View file

@ -104,7 +104,7 @@ char cX; // character to test
iO = 0; // init output position
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?
{ // a. yes ..
@ -227,7 +227,7 @@ char *EditToFortran(char* p_pszEdit) // convert line to 1130 assembler
char pszLine[MAXLINE]; // source line
char* pszWork; // work pointer
size_t iI; // work integer
char bContinue; // true if continue
int bContinue; // true if continue
if (p_pszEdit == NULL) // q. null request?
return FMSG; // a. yes .. return display message

View file

@ -169,7 +169,7 @@ void xio_2250_display (int32 addr, int32 func, int32 modify)
WriteW(addr+3, gdu_y & 0x7FF);
WriteW(addr+4, gdu_fkey);
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 */
break;
@ -182,7 +182,7 @@ void xio_2250_display (int32 addr, int32 func, int32 modify)
set_indicators((ReadW(addr) << 16) | ReadW(addr+1));
}
else {
gdu_ar = addr;
gdu_ar = (int16) addr;
gdu_fkey = 0;
gdu_akey = 0;
clear_interrupts();
@ -273,7 +273,7 @@ static int32 read_gduword (void)
int32 w;
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;
}
@ -387,8 +387,8 @@ static void draw (int32 newx, int32 newy, t_bool beam)
#endif
}
gdu_x = newx;
gdu_y = newy;
gdu_x = (int16) newx;
gdu_y = (int16) newy;
}
static void generate_image (void)
@ -419,7 +419,7 @@ static void generate_image (void)
case 0: // short branch
case 1:
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) {
draw_characters(); // in character mode this means we are at character data
gdu_ar = gdu_revert;
@ -443,7 +443,7 @@ static void generate_image (void)
if (instr & 0x0080) // indirect
new_addr = M[new_addr & mem_mask];
gdu_ar = new_addr;
gdu_ar = (int16) new_addr;
if (gdu_dsw & GDU_DSW_CHARACTER_MODE) {
draw_characters();
@ -600,9 +600,9 @@ static void draw_characters (void)
case 7: // new line
gdu_x = 0;
gdu_y -= ci->dy;
gdu_y -= (int16) ci->dy;
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;
}
}
@ -631,7 +631,7 @@ static void draw_characters (void)
gdu_x += ci->dx;
if (gdu_x > 1023 && last_abs) { // line wrap
gdu_x = 0;
gdu_y -= ci->dy;
gdu_y -= (int16) ci->dy;
}
}
} while ((w & 0x0080) == 0); // repeat until we hit revert bit
@ -645,7 +645,7 @@ static void draw_characters (void)
/******* PLATFORM SPECIFIC CODE ***********************************************************/
#ifdef WIN32
#ifdef _WIN32
#include <windows.h>
#include <windowsx.h>
@ -1114,5 +1114,5 @@ static void ShowPenHit (int x, int y)
}
#endif
#endif // WIN32 defined
#endif // _WIN32 defined
#endif // GUI_SUPPORT defined

View file

@ -126,8 +126,8 @@ void scp_panic (char *msg)
exit(1);
}
#ifdef WIN32
/* only WIN32 is defined right now */
#ifdef _WIN32
/* only _WIN32 is defined right now */
#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
// return;
unlink(filename); // delete the file
remove(filename); // delete the file
sprintf(cmd, "attach prt \"%s\"", filename); // reattach
stuff_cmd(cmd);
@ -1634,5 +1634,5 @@ void remark_cmd (char *remark)
}
}
#endif // WIN32 defined
#endif // _WIN32 defined
#endif // GUI_SUPPORT defined

View file

@ -264,7 +264,7 @@ static void flush_prt_line (FILE *fd, int spacemode, t_bool phys_flush)
if (spacemode && ! maxnp) { // spacing only
if (prt_row == 0 && prt_nnl) {
#ifdef WIN32
#ifdef _WIN32
if (! cgi)
putc('\r', fd); // DOS/Windows: end with cr/lf
#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 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
//#ifdef WIN32
//#ifdef _WIN32
// if (! cgi)
// putc('\r', fd); // DOS/Windows: end with cr/lf
//#endif
@ -293,7 +293,7 @@ static void flush_prt_line (FILE *fd, int spacemode, t_bool phys_flush)
// }
// else {
while (prt_nnl > 0) { // spit out queued newlines
#ifdef WIN32
#ifdef _WIN32
if (! cgi)
putc('\r', fd); // DOS/Windows: end with cr/lf
#endif
@ -347,7 +347,7 @@ void xio_1132_printer (int32 iocc_addr, int32 func, int32 modify)
switch (func) {
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 */
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 (*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 */
perror(gbuf);
@ -745,7 +745,7 @@ static t_stat prt_attach (UNIT *uptr, char *cptr)
reset_prt_line();
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))
CLRBIT(PRT_DSW, PRT1132_DSW_NOT_READY);

View file

@ -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 int curcol = 0; /* current typewriter element column, leftmost = 0 */
static int maxcol = 0; /* highest curcol seen in this output line */
static 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 black_ribbon[30]; /* output escape sequence for black 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_map[MAX_OS_MAPPINGS]; /* overstrike mapping entries */
@ -800,8 +800,8 @@ static void set_default_mapping (int32 flags)
reset_mapping();
strcpy(black_ribbon, "\033[30m");
strcpy(red_ribbon, "\033[31m");
strcpy((char *) black_ribbon, "\033[30m");
strcpy((char *) red_ribbon, "\033[31m");
switch (flags & CSET_MASK) {
case CSET_1130:
@ -850,10 +850,10 @@ static t_stat map_conout_character (int ch)
int i, cmp;
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))
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)
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)
{
unsigned char ch = 0, digit;
int ch = 0, digit;
char *c = *pc;
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++;
}
*out = ch; /* return parsed character */
*out = (unsigned char) ch; /* return parsed character */
*pc = c-1; /* make input pointer point to last character seen */
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.
*/
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 */
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'))
return "invalid \\ escape"; /* other \x letters are bad */
else {
*out++ = *c; /* otherwise, accept \x as literal character x */
*out++ = (unsigned char) *c;/* otherwise, accept \x as literal character x */
}
break;
}
@ -1189,18 +1190,18 @@ static char * get_characters (char **pc, char *outstr, int nmax, int *nout)
else if (*c == '^') { /* control character */
c++;
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'))
*out++ = *c - 'z' + 1;
*out++ = (unsigned char) (*c - 'z' + 1);
else /* non alpha is bad */
return "invalid control letter";
}
else if (str_match(c, "IGNORE")) { /* magic word: a character that will never be output */
*out++ = IGNR_;
*out++ = (unsigned char) IGNR_;
c += 6;
}
else {
*out++ = *c; /* save literal character */
*out++ = (unsigned char) *c; /* save literal character */
}
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)
{
char *outstr, *errmsg;
unsigned char *outstr;
char *errmsg;
int n;
if (str_match(*pc, "black")) { /* find which string we're setting */

View file

@ -442,7 +442,7 @@ t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw)
return SCPE_ARG;
}
#ifndef WIN32
#ifndef _WIN32
int strnicmp (char *a, char *b, int n)
{

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
26-Mar-04 RMS Fixed warning with -std=c99
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 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 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

View file

@ -25,6 +25,7 @@
cpu Interdata 32b CPU
25-Jan-04 RMS Revised for device debug support
31-Dec-03 RMS Fixed bug in cpu_set_hist
22-Sep-03 RMS Added additional instruction decode types
Added instruction history
@ -191,6 +192,11 @@ struct InstHistory {
#define ABS(x) (((x) & SIGN32)? NEG (x): (x))
#define DNEG(x,y) y = NEG (y); \
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 *M = NULL; /* memory */
@ -219,7 +225,6 @@ REG *pcq_r = NULL; /* PC queue reg ptr */
uint32 dec_flgs = 0; /* decode flags */
uint32 fp_in_hwre = 0; /* ucode vs hwre fp */
uint32 pawidth = PAWIDTH32; /* addr mask */
uint32 cpu_log = 0; /* debug logging */
uint32 hst_p = 0; /* history pointer */
uint32 hst_lnt = 0; /* history length */
struct InstHistory *hst = NULL; /* instruction history */
@ -231,7 +236,7 @@ extern int32 sim_interval;
extern int32 sim_int_char;
extern int32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
extern UNIT pic_unit, lfc_unit, pas_unit; /* timers */
extern FILE *sim_log;
extern FILE *sim_deb;
uint32 ReadB (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 },
{ HRDATA (PCQP, pcq_p, 6), REG_HRO },
{ HRDATA (WRU, sim_int_char, 8) },
{ HRDATA (DBGLOG, cpu_log, 16), REG_HIDDEN },
{ HRDATA (BLKIOD, blk_io.dfl, 16), REG_HRO },
{ HRDATA (BLKIOC, blk_io.cur, 20), REG_HRO },
{ HRDATA (BLKIOE, blk_io.end, 20), REG_HRO },
@ -561,12 +565,18 @@ MTAB cpu_mod[] = {
&cpu_set_hist, &cpu_show_hist },
{ 0 } };
DEBTAB cpu_deb[] = {
{ "INTEXC", LOG_CPU_I },
{ "CONTEXT", LOG_CPU_C },
{ NULL, 0 } };
DEVICE cpu_dev = {
"CPU", &cpu_unit, cpu_reg, cpu_mod,
1, 16, 20, 1, 16, 8,
&cpu_ex, &cpu_dep, &cpu_reset,
NULL, NULL, NULL,
&cpu_dib, 0 };
&cpu_dib, DEV_DEBUG, 0,
cpu_deb, NULL, NULL };
t_stat sim_instr (void)
{
@ -1307,7 +1317,7 @@ case 0xE1: /* SVC - RX */
R[14] = t; /* old PSW */
R[15] = PC; /* old 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",
pcq[pcq_p], t, PC, PSW);
break;
@ -1341,7 +1351,7 @@ case 0xE3: /* SCP - RXH */
case 0x18: /* LPSWR - RR */
PCQ_ENTRY; /* effective branch */
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",
pcq[pcq_p], BUILD_PSW (cc), PC, opnd);
cc = newPSW (opnd); /* new PSW */
@ -1351,7 +1361,7 @@ case 0x18: /* LPSWR - RR */
case 0xC2: /* LPSW - RXF */
PCQ_ENTRY; /* effective branch */
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",
pcq[pcq_p], BUILD_PSW (cc), PC, opnd);
cc = newPSW (opnd); /* new PSW */
@ -1587,7 +1597,7 @@ if (cpu_unit.flags & UNIT_832) { /* 8/32? */
R[15] = oldPC; } /* PC to new 15 */
else { GREG[14] = oldPSW; /* 7/32, PSW to set 0 14 */
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",
loc, oldPC, oldPSW, PC, PSW | cc | flg);
return cc | flg; /* return CC */
@ -1672,7 +1682,7 @@ newPSW (0x2800); /* new PSW */
R[0] = oldPSW; /* save old PSW */
R[1] = PC; /* save PC */
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",
dev, PC, oldPSW, vec, 0x2800);
if (DEV_ACC (dev)) { /* dev exist? */

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -26,6 +26,7 @@
The author gratefully acknowledges the help of Carl Friend and Al Kossow,
who provided key documents about the Interdata product line.
25-Jan-04 RMS Removed local logging support
22-Sep-03 RMS Added additional instruction decode types
21-Jun-03 RMS Changed subroutine argument for ARM compiler conflict
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 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 */
int32 int_chg (uint32 irq, int32 dat, int32 armdis);

View file

@ -1,14 +1,14 @@
To: Users
From: Bob Supnik
Subj: Interdata 16b/32b Simulator Usage
Date: 15-Jul-2003
Date: 15-Feb-2004
COPYRIGHT NOTICE
The following copyright notice applies to both the SIMH source and binary:
Original code published in 1993-2003, written by Robert M Supnik
Copyright (c) 1993-2003, Robert M Supnik
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"),
@ -36,15 +36,21 @@ This memorandum documents the Interdata 16b and 32b simulators.
1. Simulator Files
sim/ sim_defs.h
sim/ scp.h
sim_console.h
sim_defs.h
sim_fio.h
sim_rev.h
sim_sock.h
sim_tape.h
sim_timer.h
sim_tmxr.h
scp.c
scp_tty.c
sim_console.c
sim_fio.c
sim_sock.c
sim_tape.c
sim_timer.c
sim_tmxr.c
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
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
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
for connections on the specified port. They assume that the incoming

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
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
16-Feb-03 RMS Fixed read to test transfer ok before selch operation
*/
@ -136,7 +137,7 @@ static struct drvtyp drv_tab[] = {
{ 0 } };
extern uint32 int_req[INTSZ], int_enb[INTSZ];
extern FILE *sim_log;
extern FILE *sim_deb;
uint8 dpxb[DP_NUMBY]; /* xfer buffer */
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_rtime = 100; /* rotate latency */
int32 dp_wtime = 1; /* word time */
uint32 dp_log = 0; /* debug log */
uint8 dp_tplte[(2 * DP_NUMDR) + 2]; /* fix/rmv + ctrl + end */
DEVICE dp_dev;
@ -213,7 +213,6 @@ REG dp_reg[] = {
DP_NUMDR, REG_RO) },
{ URDATA (CAPAC, dp_unit[0].capac, 10, T_ADDR_W, 0,
DP_NUMDR, PV_LEFT | REG_HRO) },
{ FLDATA (LOG, dp_log, 0), REG_HIDDEN },
{ HRDATA (DEVNO, dp_dib.dno, 8), REG_HRO },
{ HRDATA (SELCH, dp_dib.sch, 2), REG_HRO },
{ NULL } };
@ -246,7 +245,7 @@ DEVICE dp_dev = {
DP_NUMDR, 16, 24, 1, 16, 8,
NULL, NULL, &dp_reset,
&id_dboot, &dp_attach, &dp_detach,
&dp_dib, DEV_DISABLE };
&dp_dib, DEV_DISABLE | DEV_DEBUG };
/* Controller: IO routine */
@ -266,7 +265,7 @@ case IO_RD: /* read data */
else dp_sta = dp_sta | STA_BSY; /* xfr? set busy */
return dp_db; /* return 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);
if (dp_sta & STC_IDL) dp_hdsc = dat & HS_MASK; /* idle? hdsc */
else { /* data xfer */
@ -278,7 +277,7 @@ case IO_SS: /* status */
if (t & SETC_EX) t = t | STA_EX; /* test for EX */
return t;
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);
f = dat & CMC_MASK; /* get cmd */
if (f & CMC_CLR) { /* clear? */
@ -315,7 +314,7 @@ case IO_ADR: /* select */
if (dp_sta & STC_IDL) dp_svun = dev; /* idle? save unit */
return BY; /* byte only */
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);
if (GET_DTYPE (uptr->flags) == TYPE_2315) /* 2.5MB drive? */
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 */
return t;
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);
dpd_arm[u] = int_chg (v_DPC + u + 1, dat, dpd_arm[u]);
if (dat & CMD_SK) t = dp_cyl; /* seek? get cyl */

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
pas Programmable asynchronous line adapter(s)
05-Jan-04 RMS Revised for tmxr library changes
09-May-03 RMS Added network device flag
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 */
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
uint32 pas (uint32 dev, uint32 op, uint32 dat);
@ -145,16 +146,16 @@ REG pas_reg[] = {
MTAB pas_mod[] = {
{ MTAB_XTD | MTAB_VDV | MTAB_VAL, 0, "lines", "LINES",
&pas_vlines, NULL, &pas_nlreg },
&pas_vlines, NULL, &pas_nlreg },
{ MTAB_XTD | MTAB_VDV, 1, NULL, "DISCONNECT",
&tmxr_dscln, NULL, &pas_desc },
&tmxr_dscln, NULL, &pas_desc },
{ UNIT_ATT, UNIT_ATT, "connections", NULL, NULL, &pas_summ },
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", NULL,
NULL, &pas_show, NULL },
NULL, &pas_show, NULL },
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATISTICS", NULL,
NULL, &pas_show, NULL },
NULL, &pas_show, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO",
&set_dev, &show_dev, NULL },
&set_dev, &show_dev, NULL },
{ 0 } };
DEVICE pas_dev = {
@ -212,6 +213,10 @@ MTAB pasl_mod[] = {
{ UNIT_UC+UNIT_8B, UNIT_8B, "8b", "8B", NULL },
{ UNIT_MDM, 0, "no dataset", "NODATASET", 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 } };
REG pasl_reg[] = {
@ -270,7 +275,7 @@ case IO_OC: /* command */
if ((pas_cmd[ln] & CMD_DTR) && (pas_sta[ln] & STA_RING))
pas_sta[ln] = pas_sta[ln] & ~(STA_CROF | STA_RING);
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 */
pas_sta[ln] = pas_sta[ln] | STA_CROF; /* no carrier */
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);
sim_activate (&pas_unit, t); } } /* activate */
else sim_cancel (&pas_unit); /* else stop */
for (i = 0; i < PAS_LINES; i++) {
pas_desc.ldsc[i] = &pas_ldsc[i];
pas_reset_ln (i); }
for (i = 0; i < PAS_LINES; i++) pas_reset_ln (i);
return SCPE_OK;
}
@ -501,7 +504,7 @@ if (newln < PAS_ENAB) {
return SCPE_OK;
for (i = newln; i < PAS_ENAB; i++) {
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 */
pasl_unit[i].flags = pasl_unit[i].flags | UNIT_DIS;
pas_reset_ln (i); }

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -332,7 +332,7 @@ char *tptr;
extern DEVICE cpu_dev;
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 != 0) return SCPE_2MARG;
for (i = lo, cs = 0; i <= hi; i++) cs = cs ^ IOReadB (i);

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

689
LGP/lgp_cpu.c Normal file
View 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
View 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
View 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
View 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
View 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;
}

View file

@ -3915,7 +3915,7 @@ if ((IR & 0100017) == 0100010) { /* This pattern for all */
j = (IR >> 11) & 3;
i = (AC[0] >> 8) & 0x007F;
FPAC[j] &= 0x80FFFFFFFFFFFFFF; /* clear exponent */
FPAC[j] |= (t_int64)(i << 56);
FPAC[j] |= ((t_int64) i << 56);
if ((FPAC[j] & 0x00ffffffffffffff) == 0)
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].routine = NULL; }
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 */
dev_table[dn].mask = dibp->mask; /* copy entries */
dev_table[dn].pi = dibp->pi;

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
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
03-Oct-02 RMS Added DIB infrastructure
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].routine = NULL; }
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 */
dev_table[dn].mask = dibp->mask; /* copy entries */
dev_table[dn].pi = dibp->pi;

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
14-Jan-04 BKR Added support for QTY and ALM
22-Nov-03 CEO Added support for PIT device
19-Jan-03 RMS Changed CMASK to CDMASK for Apple Dev kit conflict
03-Oct-02 RMS Added device information structure
@ -173,8 +174,10 @@
#define DEV_MTA 022 /* magtape */
#define DEV_DCM 024 /* data comm mux */
#define DEV_ADCV 030 /* A/D converter */
#define DEV_QTY 030 /* 4060 multiplexor */
#define DEV_DKP 033 /* disk pack */
#define DEV_CAS 034 /* cassette */
#define DEV_ALM 034 /* ALM/ULM multiplexor */
#define DEV_PIT 043 /* programmable interval timer */
#define DEV_TTI1 050 /* second console input */
#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_TTI1 13 /* second keyboard */
#define INT_V_TTO1 14 /* second terminal */
#define INT_V_STK 15 /* stack overflow */
#define INT_V_NO_ION_PENDING 16 /* ion delay */
#define INT_V_ION 17 /* interrupts on */
#define INT_V_QTY 15 /* QTY multiplexor */
#define INT_V_ALM 16 /* ALM multiplexor */
#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_DKP (1 << INT_V_DKP)
@ -243,6 +248,8 @@ typedef struct nova_dib DIB;
#define INT_TTO (1 << INT_V_TTO)
#define INT_TTI1 (1 << INT_V_TTI1)
#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_NO_ION_PENDING (1 << INT_V_NO_ION_PENDING)
#define INT_ION (1 << INT_V_ION)
@ -260,6 +267,8 @@ typedef struct nova_dib DIB;
#define PI_PTR 0000020
#define PI_PTP 0000004
#define PI_PLT 0000010
#define PI_QTY 0000002
#define PI_ALM 0000002
#define PI_TTI 0000002
#define PI_TTO 0000001
#define PI_TTI1 PI_TTI

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
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
24-Nov-03 CEO Added support for disk sizing on 6099/6103
19-Nov-03 CEO Corrected major DMA Mapping bug
@ -688,13 +689,12 @@ t_stat dkp_attach (UNIT *uptr, char *cptr)
int32 i, p;
t_stat r;
uptr->capac = drv_tab[GET_DTYPE (uptr->flags)].size;
r = attach_unit (uptr, cptr);
if ((r != SCPE_OK) || ((uptr->flags & UNIT_AUTO) == 0)) return r;
if (fseek (uptr->fileref, 0, SEEK_END)) return SCPE_OK;
if ((p = ftell (uptr->fileref)) == 0) return SCPE_OK;
uptr->capac = drv_tab[GET_DTYPE (uptr->flags)].size; /* restore capac */
r = attach_unit (uptr, cptr); /* attach */
if ((r != SCPE_OK) || !(uptr->flags & UNIT_AUTO)) return r;
if ((p = sim_fsize (uptr->fileref)) == 0) return SCPE_OK; /* get file size */
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->capac = drv_tab[i].size;
return SCPE_OK; } }

View file

@ -1,14 +1,14 @@
To: Users
From: Bob Supnik
Subj: Nova Simulator Usage
Date: 15-Mar-2003
Date: 15-Mar-2004
COPYRIGHT NOTICE
The following copyright notice applies to both the SIMH source and binary:
Original code published in 1993-2003, written by Robert M Supnik
Copyright (c) 1993-2003, Robert M Supnik
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"),
@ -36,15 +36,21 @@ This memorandum documents the Nova simulator.
1. Simulator Files
sim/ sim_defs.h
sim/ scp.h
sim_console.h
sim_defs.h
sim_fio.h
sim_rev.h
sim_sock.h
sim_tape.h
sim_timer.h
sim_tmxr.h
scp.c
scp_tty.c
sim_console.c
sim_fio.c
sim_sock.c
sim_tape.c
sim_timer.c
sim_tmxr.c
sim/nova/ nova_defs.h
@ -55,6 +61,7 @@ sim/nova/ nova_defs.h
nova_lp.c
nova_mta.c
nova_plt.c
nova_qty.c
nova_sys.c
nova_tt.c
nova_tt1.c
@ -66,7 +73,7 @@ The Nova simulator is configured as follows:
device simulates
name(s)
CPU Nova CPU with 32KW of memory
CPU Nova, Nova 3, or Nova 4 CPU with 32KW of memory
- hardware multiply/divide
PTR,PTP paper tape reader/punch
TTI,TTO console terminal
@ -77,6 +84,8 @@ CLK real-time clock
DK head-per-track disk controller
DP moving head disk controller with four drives
MT magnetic tape controller with eight drives
QTY 4060 multiplexor with up to 64 lines
ALM 4255 multiplexor with up to 64 lines
The Nova simulator implements these unique stop conditions:
@ -86,6 +95,11 @@ The Nova simulator implements these unique stop conditions:
- more than INDMAX indirect addresses are detected during
memory reference address decoding
Note that indirect address loop detection does not exist on unmapped
Novas. Some DG diagnostics test thousands of levels of indirect
addressing. INDMAX may have to be set to 32,000 to get diagnostics
to run properly.
The Nova loader supports standard binary format tapes. The DUMP command
is not implemented.
@ -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
portion of memory is lost. Initial memory size is 32K.
The CPU supports the boot command. BOOT CPU simulates the Nova hardware
APL (automatic program load) feature. The switch register (SR) bits 12:17
must contain the device code of the device to be booted. If the device is
a "high-speed" (channel) device, SR bit 0 should also be set.
CPU registers include the visible state of the processor as well as the
control registers for the interrupt system.
@ -363,6 +382,12 @@ setting limited Dasher-compatibility mode or ANSI mode:
Setting either TTI1 or TTO1 changes both devices. In Dasher mode, carriage
return is changed to newline on input, and ^X is changed to backspace.
TTO1 supports output logging. The SET TTO1 LOG command enables logging:
SET TTO1 LOG=filename log output to filename
The SET TTO1 NOLOG command disables logging and closes the open log
file, if any.
The SHOW TTI1 CONNECTIONS command displays the current connection to TTI1.
The SHOW TTI1 STATISTICS command displays statistics for the current connection.
@ -390,6 +415,67 @@ The second terminal output implements these registers:
INT 1 interrupt pending flag
TIME 24 time from I/O initiation to interrupt
2.2.8 Asynchronous Multiplexors (QTY, ALM)
The QTY and ALM are terminal multiplexors with up to 64 lines. Either
the QTY or ALM can be enabled, but not both; the ALM is enabled by
default. The number of lines can be changed with the command
SET {QTY|ALM} LINES=n set line count to n
The line count maximum is 64.
The QTY and ALM support 8-bit input and output of characters. 8-bit I/O
may be incompatible with certain operating systems; 7-bit is the default.
The command
SET {QTY|ALM} 8B
enables 8-bit input and output.
The terminal lines perform input and output through Telnet sessions
connected to a user-specified port. The ATTACH command specifies
the port to be used:
ATTACH {-am} {QTY|ALM} <port> set up listening port
where port is a decimal number between 1 and 65535 that is not being used
for other TCP/IP activities. For the ALM multiplexor, the optional switch
-m turns on the multiplexor modem controls; the optional switch -a turns on
active disconnects (disconnect session if computer clears Data Terminal Ready).
The QTY multiplexor does not support modem control. Without modem control,
the multiplexor behaves as though terminals were directly connected;
disconnecting the Telnet session does not cause any operating system-
visible change in line status.
Once the multiplexor is attached and the simulator is running, it will listen
for connections on the specified port. It assumes that the incoming
connections are Telnet connections. The connection remains open until
disconnected by the simulated program, the Telnet client, a SET {QTY|ALM}
DISCONNECT command, or a DETACH {QTY|ALM} command.
The SHOW {QTY|ALM} CONNECTIONS command displays the current connections to
the multiplexor. The SHOW {QTY|ALM} STATISTICS command displays statistics
for active connections. The SET {QTY|ALM| DISCONNECT=linenumber disconnects
the specified line.
The QTY/ALM implement these registers:
name size comments
BUF 8 character buffer
BUSY 1 device busy flag
DONE 1 device done flag
DISABLE 1 device disable flag
INT 1 interrupt pending flag
MDMCTL 1 modem control flag
AUTODS 1 autodisconnect flag
POLLS 32 number of service polls
STOP_IOE 1 stop on I/O error
The multiplexors do not support save and restore. All open connections are
lost when the simulator shuts down or the multiplexor is detached.
2.3 Fixed Head Disk (DK)
Fixed head disk options include the ability to set the number of platters

View file

@ -1,6 +1,6 @@
/* 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
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,7 @@
dsk fixed head disk
04-Jan-04 RMS Changed sim_fsize calling sequence
26-Jul-03 RMS Fixed bug in set size routine
14-Mar-03 RMS Fixed variable capacity interaction with save/restore
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 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;
if (p >= DSK_NUMDK) p = DSK_NUMDK - 1;
uptr->flags = (uptr->flags & ~UNIT_PLAT) |
(p << UNIT_V_PLAT); }
uptr->capac = UNIT_GETP (uptr->flags) * DSK_DKSIZE; /* set capacity */
return attach_unit (uptr, cptr);
return SCPE_OK;
}
/* Change disk size */

View file

@ -1,6 +1,6 @@
/* 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
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